summaryrefslogtreecommitdiff
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.gn24
-rw-r--r--chromium/chrome/browser/resources/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/about_version.css63
-rw-r--r--chromium/chrome/browser/resources/about_version.html108
-rw-r--r--chromium/chrome/browser/resources/about_version.js48
-rw-r--r--chromium/chrome/browser/resources/about_version_android.css18
-rw-r--r--chromium/chrome/browser/resources/app_list/start_page.css8
-rw-r--r--chromium/chrome/browser/resources/bookmark_manager/css/bmm.css19
-rw-r--r--chromium/chrome/browser/resources/chromeos/OWNERS10
-rw-r--r--chromium/chrome/browser/resources/chromeos/about_os_credits.html24
-rw-r--r--chromium/chrome/browser/resources/chromeos/bluetooth_options.js31
-rw-r--r--chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.css16
-rw-r--r--chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.html46
-rw-r--r--chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.js76
-rw-r--r--chromium/chrome/browser/resources/chromeos/braille_ime/BUILD.gn14
-rw-r--r--chromium/chrome/browser/resources/chromeos/braille_ime/OWNERS4
-rw-r--r--chromium/chrome/browser/resources/chromeos/braille_ime/PRESUBMIT.py25
-rw-r--r--chromium/chrome/browser/resources/chromeos/braille_ime/braille_ime.js513
-rw-r--r--chromium/chrome/browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs311
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/braille_ime/check_braille_ime.py44
-rw-r--r--chromium/chrome/browser/resources/chromeos/braille_ime/externs.js13
-rw-r--r--chromium/chrome/browser/resources/chromeos/braille_ime/main.js11
-rw-r--r--chromium/chrome/browser/resources/chromeos/browser_options.js55
-rw-r--r--chromium/chrome/browser/resources/chromeos/certificate_manager_dialog.html61
-rw-r--r--chromium/chrome/browser/resources/chromeos/certificate_manager_dialog.js67
-rw-r--r--chromium/chrome/browser/resources/chromeos/choose_mobile_network.css28
-rw-r--r--chromium/chrome/browser/resources/chromeos/choose_mobile_network.html44
-rw-r--r--chromium/chrome/browser/resources/chromeos/choose_mobile_network.js108
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn389
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/OWNERS4
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/PRESUBMIT.py43
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js395
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager_test.unitjs257
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js692
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler_test.unitjs698
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_key_types.js131
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_table.js132
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_table_test.extjs74
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager.js233
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager_test.extjs116
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator.js342
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator_test.unitjs301
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/liblouis.js334
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/liblouis_test.extjs168
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/nav_braille.js111
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/pan_strategy.js220
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/pan_strategy_test.unitjs121
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/braille/spans.js78
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gni203
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gyp63
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.html5
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js472
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/braille_captions_background.js109
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/alert_modal.oggbin7046 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/alert_nonmodal.oggbin11433 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/button.oggbin7550 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/check_off.oggbin11421 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/check_on.oggbin10344 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/editable_text.oggbin5197 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/ellipsis.oggbin12631 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/invalid_keypress.oggbin5353 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/link.oggbin7508 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/list_item.oggbin5664 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/listbox.oggbin7396 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/long_desc.oggbin21030 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/math.oggbin5262 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_close.oggbin9753 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_enter.oggbin10748 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_exit.oggbin11619 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_open.oggbin9749 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_select.oggbin10572 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/page_finish_loading.oggbin13721 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/page_start_loading.oggbin11437 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/recover_focus.oggbin9546 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/selection.oggbin6323 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/selection_reverse.oggbin6263 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/skip.oggbin7146 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/wrap.oggbin9382 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/wrap_edge.oggbin5641 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/externs.js67
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/injected_script_loader.js58
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.html26
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.js61
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer_loader.js13
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/classic_keymap.json5
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/flat_keymap.json5
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/key_map.js450
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json330
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/mathmaps/math_map.js188
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.html120
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js605
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options_loader.js10
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js231
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/tabs_api_handler.js152
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-128.pngbin1977 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-16.pngbin336 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-19.pngbin347 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-48.pngbin1625 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/active_indicator.js1004
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api.js578
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api_implementation.js409
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api_util.js90
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js74
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_suspender.js77
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher.js1530
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs754
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/externs.js215
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/history.js406
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_document.js128
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_globals.js69
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/initial_speech.js86
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/keyboard_handler.js131
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/live_regions.js450
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/live_regions_test.unitjs318
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/loader.js25
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_history.js185
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager.js1250
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager_test.unitjs1395
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_shifter.js269
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_speaker.js140
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/node_breadcrumb.js167
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/pdf_processor.js251
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/script_installer.js109
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/serializer.js40
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/braille_overlay_widget.js184
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/context_menu_widget.js126
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/keyboard_help_widget.js85
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/node_search_widget.js65
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/overlay_widget.js83
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/search_widget.js540
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/select_widget.js82
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/spoken_messages.js90
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/widget.js195
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands.js810
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands_test.unitjs122
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_event_detail.js171
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox_assets.gypi20
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox_tests.gypi8
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox_vars.gypi12
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/closure/closure_preinit.js94
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/aria_util.js978
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/aria_util_test.unitjs142
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/aural_style_util.js209
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/braille_text_handler.js63
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/braille_text_handler_test.unitjs70
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/braille_util.js374
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/braille_util_test.unitjs420
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/buildinfo.js20
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js521
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/chromevox.js290
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/chromevox_json.js368
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/command_store.js784
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/command_store_test.unitjs73
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/composite_tts.js103
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/content_editable_extractor.js235
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/content_editable_extractor_test.unitjs326
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/cursor.js59
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/cursor_selection.js255
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/cursor_selection_test.unitjs97
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/date_widget.js322
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/description_util.js474
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/dom_predicates.js493
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/dom_util.js2608
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/dom_util_test.unitjs1578
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/earcon_util.js67
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text.js649
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_area_shadow.js190
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_area_shadow_test.unitjs67
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js712
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_test.unitjs693
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/externs.js5
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/find_util.js66
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/find_util_test.unitjs51
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/focus_util.js98
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/focuser.js120
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/group_util.js150
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/interframe.js240
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js633
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence_test.unitjs445
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/key_util.js500
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_attr.js1529
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_tree.js1939
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_tree_test.unitjs6188
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_util.js135
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/math_util.js263
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/media_widget.js91
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/memoize.js133
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/msgs.js161
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/nav_description.js163
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/nav_math_description.js48
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/node_state.js52
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/page_selection.js107
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/page_selection_test.unitjs143
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/platform_util.js51
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/selection_util.js611
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/selection_util_test.unitjs31
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/spannable.js434
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/spannable_test.unitjs481
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/string_util.js32
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/string_util_test.unitjs32
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/table_util.js179
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/time_widget.js221
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_content.js482
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_math.js446
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_table.js1309
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_util.js927
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/xpath_util.js152
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js202
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js277
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util_test.extjs102
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.html7
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js810
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs370
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js181
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js397
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs294
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcon_engine.js711
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/control.wavbin14266 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/selection.wavbin13714 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/selection_reverse.wavbin9138 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/skim.wavbin24808 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/small_room_2.wavbin665344 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/static.wavbin304 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/loader.js10
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js1329
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs545
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/abstract_result.js51
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/constants.js30
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/context_menu.js141
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/loader.js48
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/results.js468
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/search.js441
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/search_tools.js208
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/util.js184
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/generate_manifest.gypi3
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille.js110
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js145
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_integration_test.unitjs253
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons.js68
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons_background.js81
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/extension_bridge.js342
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/externs.js51
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js207
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/mathjax.js294
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts.js139
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_background.js731
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_background_test.extjs43
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_base.js33
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_earcons.js86
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_host.js165
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_mathjax.js112
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_tts.js567
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/interface/braille_interface.js29
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/interface/host_factory.js88
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/interface/mathjax_interface.js77
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/interface/tts_interface.js117
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/testing/earcons.js25
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/testing/host.js25
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/testing/mathjax.js71
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/host/testing/tts.js143
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/manifest.json.jinja2297
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/base_rule_store.js426
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/math_simple_store.js181
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/math_store.js268
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store.js44
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store_rules.js879
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store_util.js177
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule.js379
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_engine.js371
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_evaluator.js28
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_functions.js137
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_store.js74
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/store_util.js33
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/BUILD.gn71
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd61
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_am.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ar.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bg.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bn.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ca.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_cs.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_da.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_de.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es-419.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_et.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fi.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fil.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fr.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_gu.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hi.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hr.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hu.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_id.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_it.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ja.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_kn.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ko.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lt.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lv.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ml.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_mr.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ms.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_nl.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_no.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pl.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-BR.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-PT.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ro.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ru.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sk.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sl.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sr.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sv.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sw.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ta.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_th.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_tr.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_uk.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_vi.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-CN.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb748
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/assert_additions.js84
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/callback_helper.js53
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_e2e_test_base.js120
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js58
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_unittest_base.js215
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/common.js58
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/fake_objects.js44
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js363
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback_test.unitjs172
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/spoken_list_builder.js61
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js63
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/testing/tester.js138
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/check_chromevox.py140
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/find_js_files.py34
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/generate_deps.py68
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/generate_manifest.py92
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/generate_test_messages.py45
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/jsbundler.py378
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/jscompilerwrapper.py73
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/print_js_deps.py89
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/publish_webstore_extension.py155
-rwxr-xr-xchromium/chrome/browser/resources/chromeos/chromevox/tools/webstore_extension_util.py168
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_node_walker.js115
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_selection_walker.js159
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_shifter.js166
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_walker.js177
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/bare_object_walker.js32
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/character_walker.js44
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/character_walker_test.unitjs117
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/column_walker.js38
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/group_walker.js59
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/group_walker_test.unitjs89
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker.js245
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker_test.unitjs179
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/math_shifter.js167
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/math_shifter_test.unitjs136
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/object_walker.js56
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/object_walker_test.unitjs97
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/row_walker.js38
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/sentence_walker.js30
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/sentence_walker_test.unitjs111
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/structural_line_walker.js78
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/structural_line_walker_test.unitjs123
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_shifter.js152
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_walker.js422
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_walker_test.unitjs86
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/walker_unittest_base.js234
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/word_walker.js30
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/walkers/word_walker_test.unitjs103
-rw-r--r--chromium/chrome/browser/resources/chromeos/compiled_resources.gyp12
-rw-r--r--chromium/chrome/browser/resources/chromeos/connectivity_diagnostics/OWNERS3
-rw-r--r--chromium/chrome/browser/resources/chromeos/cryptohome.html49
-rw-r--r--chromium/chrome/browser/resources/chromeos/cryptohome.js26
-rw-r--r--chromium/chrome/browser/resources/chromeos/detected_sd.pngbin367 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/detected_usb.pngbin547 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/drive_internals.css28
-rw-r--r--chromium/chrome/browser/resources/chromeos/drive_internals.html141
-rw-r--r--chromium/chrome/browser/resources/chromeos/drive_internals.js300
-rw-r--r--chromium/chrome/browser/resources/chromeos/echo/OWNERS5
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/audio_settings.css120
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/audio_settings.html98
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/audio_settings.js212
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/battery_settings.css31
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/battery_settings.html84
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/battery_settings.js131
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.css120
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html165
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js527
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/device_emulator.css7
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/device_emulator.html124
-rw-r--r--chromium/chrome/browser/resources/chromeos/emulator/device_emulator.js44
-rw-r--r--chromium/chrome/browser/resources/chromeos/fake_bluetooth_overlay_parent.js28
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/background.js13
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/greeting_image_disabled.html1
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/greeting_image_enabled.html5
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/icon/128.pngbin3379 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/icon/16.pngbin559 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/icon/256.pngbin6398 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/icon/32.pngbin931 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/icon/48.pngbin1321 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/icon/64.pngbin1870 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/icon/96.pngbin2623 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/main.html42
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/main.js36
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app/style.css74
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/app_list_step.html11
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/background.svg14
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/bubble.css51
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/first_run.css76
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/first_run.html31
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/first_run.js275
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/help_step.html12
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/preload.css53
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/step.css40
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/step.js300
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/step_bubble.css51
-rw-r--r--chromium/chrome/browser/resources/chromeos/first_run/tray_step.html8
-rw-r--r--chromium/chrome/browser/resources/chromeos/genius_app/OWNERS3
-rw-r--r--chromium/chrome/browser/resources/chromeos/guest_session_tab.html40
-rw-r--r--chromium/chrome/browser/resources/chromeos/image_burner.html9
-rw-r--r--chromium/chrome/browser/resources/chromeos/images/new_charger_au.pngbin46542 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/images/new_charger_uk.pngbin38296 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/images/new_charger_us.pngbin26024 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/images/original_charger_au.pngbin34076 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/images/original_charger_uk.pngbin31199 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/images/original_charger_us.pngbin21461 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/images/safe-charger-checkmark.pngbin1583 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/input_method/OWNERS4
-rw-r--r--chromium/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json15
-rw-r--r--chromium/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json51
-rw-r--r--chromium/chrome/browser/resources/chromeos/input_method/xkb_manifest.json32
-rw-r--r--chromium/chrome/browser/resources/chromeos/insert.pngbin1022 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/keyboard/keyboard_utils.js109
-rw-r--r--chromium/chrome/browser/resources/chromeos/keyboard_overlay.css188
-rw-r--r--chromium/chrome/browser/resources/chromeos/keyboard_overlay.html14
-rw-r--r--chromium/chrome/browser/resources/chromeos/keyboard_overlay.js804
-rw-r--r--chromium/chrome/browser/resources/chromeos/keyboard_overlay_accessibility_helper.js40
-rw-r--r--chromium/chrome/browser/resources/chromeos/keyboard_overlay_data.js15924
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/OWNERS4
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/accessibility_menu.css43
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/accessibility_menu.html35
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/apps_menu.css13
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/apps_menu.js184
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/controller-pairing-screen.html262
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/controller-pairing-screen.js168
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/controller_pairing_page.css104
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/custom_elements_login.html11
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/custom_elements_login.js13
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/custom_elements_oobe.html16
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/custom_elements_oobe.js21
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/demo_user_login.html27
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/enterprise_info.css45
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/enterprise_info.html6
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia.css54
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_button.css40
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_buttons.html58
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_buttons.js70
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_card.css89
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_card.html45
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_header.css14
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_header.html27
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_header.js11
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_icon_button.css8
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_input.css36
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_input.html56
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_input.js77
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_input_form.css17
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_input_form.html41
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_input_form.js44
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.css31
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.html101
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.js84
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/header_bar.css152
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/header_bar.html46
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/header_bar.js451
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/host-pairing-screen.html93
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/host-pairing-screen.js38
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/html-echo.html21
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/html-echo.js18
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/images/chrome_retail_login.pngbin8214 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/login.html19
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/login.js64
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/login_common.js430
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/login_resources.html65
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/login_screens.html16
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/network_dropdown.css146
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/network_dropdown.js443
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/notification_card.css38
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/notification_card.html57
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/notification_card.js46
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/offline_gaia.css35
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/offline_gaia.html110
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/offline_gaia.js134
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe-screen.html6
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe-screen.js234
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe.html25
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe.js294
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_popup_overlay.css46
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen.css175
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.css16
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.html9
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.js15
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.css44
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.html11
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.js96
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.css51
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.html4
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.js15
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.css163
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.html49
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.js166
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.css28
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.html9
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.js114
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.css105
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.html49
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.js143
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula_installation_settings_overlay.css18
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula_installation_settings_overlay.html19
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css95
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.html65
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.js210
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.css56
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.html3
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.js26
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing_page.css20
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.css42
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.html45
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.js146
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css180
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html73
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js303
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.css96
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.html42
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.js238
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.css21
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.html26
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.js37
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.css93
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.html24
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.js111
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.css76
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.html29
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.js157
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css280
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.html45
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js389
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/oobe_screens.html24
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/pairing_device_list.css60
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/roboto_font.css43
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.css30
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.html90
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.js78
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.css73
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.html11
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.js96
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.css61
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.html25
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.js99
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_container.html21
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_context.js140
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_context_test.html207
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.css58
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.html11
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.js80
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_error_message.css154
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_error_message.html145
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_error_message.js431
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.css51
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.html20
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.js82
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.css286
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.html52
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js1040
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_password_changed.css101
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_password_changed.html25
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_password_changed.js210
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css564
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.html164
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js1601
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.css17
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.html15
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.js38
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.css39
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.html15
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.js40
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/test_util.js28
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/throbber_notice.css29
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/throbber_notice.html16
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/throbber_notice.js11
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/version.html4
-rw-r--r--chromium/chrome/browser/resources/chromeos/merge_session_load.html58
-rw-r--r--chromium/chrome/browser/resources/chromeos/mobile_dialogs.css71
-rw-r--r--chromium/chrome/browser/resources/chromeos/mobile_setup.css130
-rw-r--r--chromium/chrome/browser/resources/chromeos/mobile_setup.html48
-rw-r--r--chromium/chrome/browser/resources/chromeos/mobile_setup.js377
-rw-r--r--chromium/chrome/browser/resources/chromeos/mobile_setup_portal.html36
-rw-r--r--chromium/chrome/browser/resources/chromeos/mobile_setup_portal.js219
-rw-r--r--chromium/chrome/browser/resources/chromeos/neterror.css213
-rw-r--r--chromium/chrome/browser/resources/chromeos/neterror.js55
-rw-r--r--chromium/chrome/browser/resources/chromeos/network_ui/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/chromeos/network_ui/compiled_resources.gyp4
-rw-r--r--chromium/chrome/browser/resources/chromeos/network_ui/network_ui.css71
-rw-r--r--chromium/chrome/browser/resources/chromeos/network_ui/network_ui.html82
-rw-r--r--chromium/chrome/browser/resources/chromeos/network_ui/network_ui.js337
-rw-r--r--chromium/chrome/browser/resources/chromeos/nfc_debug.css84
-rw-r--r--chromium/chrome/browser/resources/chromeos/nfc_debug.html131
-rw-r--r--chromium/chrome/browser/resources/chromeos/nfc_debug.js375
-rw-r--r--chromium/chrome/browser/resources/chromeos/power.css72
-rw-r--r--chromium/chrome/browser/resources/chromeos/power.html82
-rw-r--r--chromium/chrome/browser/resources/chromeos/power.js866
-rw-r--r--chromium/chrome/browser/resources/chromeos/proxy_settings.css47
-rw-r--r--chromium/chrome/browser/resources/chromeos/proxy_settings.html41
-rw-r--r--chromium/chrome/browser/resources/chromeos/proxy_settings.js55
-rw-r--r--chromium/chrome/browser/resources/chromeos/salsa.css58
-rw-r--r--chromium/chrome/browser/resources/chromeos/salsa.html48
-rw-r--r--chromium/chrome/browser/resources/chromeos/salsa.js147
-rw-r--r--chromium/chrome/browser/resources/chromeos/set_time.css45
-rw-r--r--chromium/chrome/browser/resources/chromeos/set_time.html39
-rw-r--r--chromium/chrome/browser/resources/chromeos/set_time.js200
-rw-r--r--chromium/chrome/browser/resources/chromeos/sim_unlock.css100
-rw-r--r--chromium/chrome/browser/resources/chromeos/sim_unlock.html143
-rw-r--r--chromium/chrome/browser/resources/chromeos/sim_unlock.js429
-rw-r--r--chromium/chrome/browser/resources/chromeos/slow.css47
-rw-r--r--chromium/chrome/browser/resources/chromeos/slow.html30
-rw-r--r--chromium/chrome/browser/resources/chromeos/slow.js48
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/camera_snap.wavbin45004 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/earcons/enter_screen.wavbin102580 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/earcons/exit_screen.wavbin88244 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/earcons/passthrough.wavbin88244 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/lock.wavbin182040 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/object_delete.wavbin91950 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/shutdown.wavbin237712 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/spoken_feedback_disabled.wavbin198576 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/spoken_feedback_enabled.wavbin176524 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/startup.wavbin289432 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/startup2.wavbin264724 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/unlock.wavbin176524 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/sounds/volume_adjust.wavbin8620 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/user_images_grid.js680
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css378
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon128.pngbin4656 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon16.pngbin596 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon256.pngbin10652 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon32.pngbin1133 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon48.pngbin1700 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon64.pngbin2161 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon96.pngbin3450 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/add-wallpaper-thumbnail-hover.pngbin188 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/add-wallpaper-thumbnail.pngbin169 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/check.pngbin1271 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-overlay-hover.pngbin384 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-overlay.pngbin170 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-white-hover.pngbin369 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-white.pngbin197 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close_bar.pngbin197 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/add-wallpaper-thumbnail-hover.pngbin132 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/add-wallpaper-thumbnail.pngbin132 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/check.pngbin723 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/checkbox_checked.pngbin194 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/checkbox_unchecked.pngbin93 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-overlay-hover.pngbin214 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-overlay.pngbin139 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-white-hover.pngbin206 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-white.pngbin135 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close_bar.pngbin137 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/remember.pngbin341 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/constants.js95
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js404
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/main.js16
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/main_scripts.js33
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/progress_manager.js116
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js386
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_categories_list.js88
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_directories.js85
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_images_grid.js441
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js1130
-rw-r--r--chromium/chrome/browser/resources/chromeos/wallpaper_manager/main.html132
-rw-r--r--chromium/chrome/browser/resources/component_extension_resources.grd33
-rw-r--r--chromium/chrome/browser/resources/crashes.css52
-rw-r--r--chromium/chrome/browser/resources/crashes.html33
-rw-r--r--chromium/chrome/browser/resources/crashes.js112
-rw-r--r--chromium/chrome/browser/resources/downloads/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/downloads/compiled_resources.gyp4
-rw-r--r--chromium/chrome/browser/resources/downloads/compiled_resources2.gyp18
-rw-r--r--chromium/chrome/browser/resources/downloads/constants.html2
-rw-r--r--chromium/chrome/browser/resources/downloads/constants.js38
-rw-r--r--chromium/chrome/browser/resources/downloads/throttled_icon_loader.html (renamed from chromium/chrome/browser/resources/md_downloads/throttled_icon_loader.html)0
-rw-r--r--chromium/chrome/browser/resources/downloads/throttled_icon_loader.js (renamed from chromium/chrome/browser/resources/md_downloads/throttled_icon_loader.js)0
-rw-r--r--chromium/chrome/browser/resources/engagement/engagement_table.css16
-rw-r--r--chromium/chrome/browser/resources/engagement/engagement_table.html12
-rw-r--r--chromium/chrome/browser/resources/engagement/engagement_table.js95
-rw-r--r--chromium/chrome/browser/resources/engagement/site_engagement.js18
-rw-r--r--chromium/chrome/browser/resources/extensions/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.html16
-rw-r--r--chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.js66
-rw-r--r--chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_list.js179
-rw-r--r--chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.css156
-rw-r--r--chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.html54
-rw-r--r--chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.js147
-rw-r--r--chromium/chrome/browser/resources/extensions/compiled_resources.gyp2
-rw-r--r--chromium/chrome/browser/resources/extensions/extension_command_list.js21
-rw-r--r--chromium/chrome/browser/resources/extensions/extension_commands_overlay.js2
-rw-r--r--chromium/chrome/browser/resources/extensions/extension_error.js9
-rw-r--r--chromium/chrome/browser/resources/extensions/extension_error_overlay.js17
-rw-r--r--chromium/chrome/browser/resources/extensions/extension_list.js16
-rw-r--r--chromium/chrome/browser/resources/extensions/extensions.js2
-rw-r--r--chromium/chrome/browser/resources/extensions/pack_extension_overlay.js3
-rw-r--r--chromium/chrome/browser/resources/feedback/html/sys_info.html32
-rw-r--r--chromium/chrome/browser/resources/feedback/js/event_handler.js3
-rw-r--r--chromium/chrome/browser/resources/feedback/js/feedback.js52
-rw-r--r--chromium/chrome/browser/resources/feedback/js/sys_info.js156
-rw-r--r--chromium/chrome/browser/resources/gaia_auth_host/authenticator.js48
-rw-r--r--chromium/chrome/browser/resources/gesture_config.css85
-rw-r--r--chromium/chrome/browser/resources/gesture_config.html33
-rw-r--r--chromium/chrome/browser/resources/gesture_config.js320
-rw-r--r--chromium/chrome/browser/resources/hangout_services/manifest.json2
-rw-r--r--chromium/chrome/browser/resources/hangout_services/thunk.js13
-rw-r--r--chromium/chrome/browser/resources/help/help_content.css5
-rw-r--r--chromium/chrome/browser/resources/help/help_content.html2
-rw-r--r--chromium/chrome/browser/resources/help/help_page.js12
-rw-r--r--chromium/chrome/browser/resources/history/history.js10
-rw-r--r--chromium/chrome/browser/resources/history/other_devices.js12
-rw-r--r--chromium/chrome/browser/resources/inline_login/inline_login.js1
-rw-r--r--chromium/chrome/browser/resources/inspect/inspect.css1
-rw-r--r--chromium/chrome/browser/resources/inspect/inspect.js1
-rw-r--r--chromium/chrome/browser/resources/local_discovery/local_discovery.js7
-rw-r--r--chromium/chrome/browser/resources/local_ntp/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.css11
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.html3
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.js2
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.css2
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.js2
-rw-r--r--chromium/chrome/browser/resources/md_downloads/action_service.html2
-rw-r--r--chromium/chrome/browser/resources/md_downloads/action_service.js50
-rw-r--r--chromium/chrome/browser/resources/md_downloads/action_service_unittest.gtestjs39
-rw-r--r--chromium/chrome/browser/resources/md_downloads/compiled_resources.gyp16
-rw-r--r--chromium/chrome/browser/resources/md_downloads/compiled_resources2.gyp23
-rw-r--r--chromium/chrome/browser/resources/md_downloads/crisper.js17142
-rw-r--r--chromium/chrome/browser/resources/md_downloads/downloads.html13
-rw-r--r--chromium/chrome/browser/resources/md_downloads/downloads.js (renamed from chromium/chrome/browser/resources/chromeos/login/gaia_card.js)4
-rw-r--r--chromium/chrome/browser/resources/md_downloads/externs.js36
-rw-r--r--chromium/chrome/browser/resources/md_downloads/focus_row.html2
-rw-r--r--chromium/chrome/browser/resources/md_downloads/i18n.html2
-rw-r--r--chromium/chrome/browser/resources/md_downloads/i18n_setup.html2
-rw-r--r--chromium/chrome/browser/resources/md_downloads/item.css42
-rw-r--r--chromium/chrome/browser/resources/md_downloads/item.html56
-rw-r--r--chromium/chrome/browser/resources/md_downloads/item.js99
-rw-r--r--chromium/chrome/browser/resources/md_downloads/manager.css21
-rw-r--r--chromium/chrome/browser/resources/md_downloads/manager.html28
-rw-r--r--chromium/chrome/browser/resources/md_downloads/manager.js228
-rw-r--r--chromium/chrome/browser/resources/md_downloads/shared_style.css4
-rw-r--r--chromium/chrome/browser/resources/md_downloads/strings.html2
-rw-r--r--chromium/chrome/browser/resources/md_downloads/toolbar.css31
-rw-r--r--chromium/chrome/browser/resources/md_downloads/toolbar.html14
-rw-r--r--chromium/chrome/browser/resources/md_downloads/toolbar.js12
-rwxr-xr-xchromium/chrome/browser/resources/md_downloads/vulcanize.py76
-rw-r--r--chromium/chrome/browser/resources/md_downloads/vulcanize_readme.md45
-rw-r--r--chromium/chrome/browser/resources/md_downloads/vulcanized.html2853
-rw-r--r--chromium/chrome/browser/resources/md_extensions/compiled_resources.gyp12
-rw-r--r--chromium/chrome/browser/resources/md_extensions/icons.html21
-rw-r--r--chromium/chrome/browser/resources/md_extensions/item.css113
-rw-r--r--chromium/chrome/browser/resources/md_extensions/item.html86
-rw-r--r--chromium/chrome/browser/resources/md_extensions/item.js194
-rw-r--r--chromium/chrome/browser/resources/md_extensions/item_list.css15
-rw-r--r--chromium/chrome/browser/resources/md_extensions/item_list.html22
-rw-r--r--chromium/chrome/browser/resources/md_extensions/item_list.js57
-rw-r--r--chromium/chrome/browser/resources/md_extensions/manager.css11
-rw-r--r--chromium/chrome/browser/resources/md_extensions/manager.html26
-rw-r--r--chromium/chrome/browser/resources/md_extensions/manager.js215
-rw-r--r--chromium/chrome/browser/resources/md_extensions/service.html5
-rw-r--r--chromium/chrome/browser/resources/md_extensions/service.js158
-rw-r--r--chromium/chrome/browser/resources/md_extensions/sidebar.css8
-rw-r--r--chromium/chrome/browser/resources/md_extensions/sidebar.html42
-rw-r--r--chromium/chrome/browser/resources/md_extensions/sidebar.js114
-rw-r--r--chromium/chrome/browser/resources/md_extensions/toolbar.html4
-rw-r--r--chromium/chrome/browser/resources/md_extensions/toolbar.js23
-rw-r--r--chromium/chrome/browser/resources/md_history/OWNERS3
-rw-r--r--chromium/chrome/browser/resources/md_history/history.html21
-rw-r--r--chromium/chrome/browser/resources/md_policy/md_policy.html10
-rw-r--r--chromium/chrome/browser/resources/md_policy/policy_resources.grd21
-rw-r--r--chromium/chrome/browser/resources/media/webrtc_logs.js4
-rw-r--r--chromium/chrome/browser/resources/media_router/compiled_resources.gyp55
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.css23
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html5
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js45
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css113
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html145
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js840
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css72
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.html31
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.js118
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/route_details/route_details.css45
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/route_details/route_details.html31
-rw-r--r--chromium/chrome/browser/resources/media_router/elements/route_details/route_details.js40
-rw-r--r--chromium/chrome/browser/resources/media_router/externs.js15
-rw-r--r--chromium/chrome/browser/resources/media_router/media_router.css7
-rw-r--r--chromium/chrome/browser/resources/media_router/media_router.html2
-rw-r--r--chromium/chrome/browser/resources/media_router/media_router.js236
-rw-r--r--chromium/chrome/browser/resources/media_router/media_router_common.css4
-rw-r--r--chromium/chrome/browser/resources/media_router/media_router_data.js142
-rw-r--r--chromium/chrome/browser/resources/media_router/media_router_ui_interface.js156
-rw-r--r--chromium/chrome/browser/resources/net_internals/hsts_view.html8
-rw-r--r--chromium/chrome/browser/resources/net_internals/import_view.html2
-rw-r--r--chromium/chrome/browser/resources/net_internals/log_util.js2
-rw-r--r--chromium/chrome/browser/resources/net_internals/log_view_painter.js41
-rw-r--r--chromium/chrome/browser/resources/net_internals/quic_view.html12
-rw-r--r--chromium/chrome/browser/resources/net_internals/spdy_view.html13
-rw-r--r--chromium/chrome/browser/resources/net_internals/view.js3
-rw-r--r--chromium/chrome/browser/resources/ntp4/apps_page.js34
-rw-r--r--chromium/chrome/browser/resources/ntp4/guest_tab.css28
-rw-r--r--chromium/chrome/browser/resources/ntp4/guest_tab.html15
-rw-r--r--chromium/chrome/browser/resources/ntp4/incognito_and_guest_tab.css48
-rw-r--r--chromium/chrome/browser/resources/ntp4/incognito_tab.css36
-rw-r--r--chromium/chrome/browser/resources/ntp4/incognito_tab.html15
-rw-r--r--chromium/chrome/browser/resources/ntp4/new_incognito_tab_theme.css9
-rw-r--r--chromium/chrome/browser/resources/ntp4/new_tab.js4
-rw-r--r--chromium/chrome/browser/resources/ntp4/tile_page.js6
-rw-r--r--chromium/chrome/browser/resources/options/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js4
-rw-r--r--chromium/chrome/browser/resources/options/autofill_options.html8
-rw-r--r--chromium/chrome/browser/resources/options/autofill_options.js18
-rw-r--r--chromium/chrome/browser/resources/options/automatic_settings_reset_banner.css (renamed from chromium/chrome/browser/resources/options/settings_banner.css)9
-rw-r--r--chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js86
-rw-r--r--chromium/chrome/browser/resources/options/browser_options.css20
-rw-r--r--chromium/chrome/browser/resources/options/browser_options.html30
-rw-r--r--chromium/chrome/browser/resources/options/browser_options.js290
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/2x/warning.pngbin1037 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/OWNERS14
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/accounts_options.html85
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/accounts_options.js157
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/accounts_options_page.css94
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/accounts_user_list.js197
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/accounts_user_name_edit.js129
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth.css162
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html26
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js124
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth_device_list.js348
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.html28
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js375
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/browser_options.css7
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/change_picture_options.css199
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/change_picture_options.html38
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/change_picture_options.js331
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.css7
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.html37
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.js72
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/display_options.css106
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/display_options.html85
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/display_options.js1051
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/display_overscan.css63
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/display_overscan.html31
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/display_overscan.js160
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/internet_detail.css117
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/internet_detail.html696
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/internet_detail.js1793
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/internet_detail_ip_address_field.js112
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.css26
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html135
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js174
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/network_list.js1523
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/onc_data.js195
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/overscan_arrows.pngbin557 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/overscan_arrows_2x.pngbin946 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/overscan_shift.pngbin482 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/overscan_shift_2x.pngbin895 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/overscan_shift_rtl.pngbin570 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/overscan_shift_rtl_2x.pngbin938 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/pointer_overlay.css11
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/pointer_overlay.html50
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/pointer_overlay.js71
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/power_overlay.html37
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/power_overlay.js172
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/preferred_networks.html17
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/preferred_networks.js161
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/proxy_rules_list.js144
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css8
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html21
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js91
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/warning.pngbin489 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/clear_browser_data_overlay.css4
-rw-r--r--chromium/chrome/browser/resources/options/clear_browser_data_overlay.html33
-rw-r--r--chromium/chrome/browser/resources/options/clear_browser_data_overlay.js24
-rw-r--r--chromium/chrome/browser/resources/options/compiled_resources.gyp7
-rw-r--r--chromium/chrome/browser/resources/options/content_settings.html56
-rw-r--r--chromium/chrome/browser/resources/options/content_settings.js10
-rw-r--r--chromium/chrome/browser/resources/options/content_settings_exceptions_area.html20
-rw-r--r--chromium/chrome/browser/resources/options/content_settings_exceptions_area.js80
-rw-r--r--chromium/chrome/browser/resources/options/language_add_language_overlay.js17
-rw-r--r--chromium/chrome/browser/resources/options/language_options.css7
-rw-r--r--chromium/chrome/browser/resources/options/language_options.html19
-rw-r--r--chromium/chrome/browser/resources/options/language_options.js52
-rw-r--r--chromium/chrome/browser/resources/options/manage_profile_overlay.js54
-rw-r--r--chromium/chrome/browser/resources/options/options.html2
-rw-r--r--chromium/chrome/browser/resources/options/options.js11
-rw-r--r--chromium/chrome/browser/resources/options/options_bundle.js5
-rw-r--r--chromium/chrome/browser/resources/options/options_page.css9
-rw-r--r--chromium/chrome/browser/resources/options/options_settings_app.js3
-rw-r--r--chromium/chrome/browser/resources/options/password_manager.html2
-rw-r--r--chromium/chrome/browser/resources/options/password_manager.js22
-rw-r--r--chromium/chrome/browser/resources/options/password_manager_list.css31
-rw-r--r--chromium/chrome/browser/resources/options/password_manager_list.js307
-rw-r--r--chromium/chrome/browser/resources/options/reset_profile_settings_banner.html18
-rw-r--r--chromium/chrome/browser/resources/options/reset_profile_settings_banner.js66
-rw-r--r--chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html6
-rw-r--r--chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js10
-rw-r--r--chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js2
-rw-r--r--chromium/chrome/browser/resources/options/search_page.css10
-rw-r--r--chromium/chrome/browser/resources/options/search_page.js65
-rw-r--r--chromium/chrome/browser/resources/options/settings_banner.js89
-rw-r--r--chromium/chrome/browser/resources/options/supervised_user_import.js6
-rw-r--r--chromium/chrome/browser/resources/options/sync_setup_overlay.css6
-rw-r--r--chromium/chrome/browser/resources/options/sync_setup_overlay.html8
-rw-r--r--chromium/chrome/browser/resources/options/sync_setup_overlay.js65
-rw-r--r--chromium/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js47
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css4
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css16
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_fit_page.pngbin1410 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_fit_width.pngbin935 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_play.pngbin757 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_print.pngbin654 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_save.pngbin660 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_zoom_in.pngbin1315 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_zoom_out.pngbin1258 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_fit_page.pngbin922 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_fit_width.pngbin442 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_play.pngbin443 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_print.pngbin545 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_save.pngbin447 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_zoom_in.pngbin945 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_zoom_out.pngbin735 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.css37
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.html9
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.js47
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.css22
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.html9
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js14
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html7
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js2
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css14
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html2
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js4
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.css39
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.html15
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.js62
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html11
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js2
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css23
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html50
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js9
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.css71
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.html13
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.js63
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css10
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html2
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.css21
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.html11
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.js74
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css7
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css10
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html16
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js22
-rw-r--r--chromium/chrome/browser/resources/pdf/index-material.css50
-rw-r--r--chromium/chrome/browser/resources/pdf/index-material.html43
-rw-r--r--chromium/chrome/browser/resources/pdf/index.css46
-rw-r--r--chromium/chrome/browser/resources/pdf/index.html57
-rw-r--r--chromium/chrome/browser/resources/pdf/manifest.json16
-rw-r--r--chromium/chrome/browser/resources/pdf/navigator.js14
-rw-r--r--chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js66
-rw-r--r--chromium/chrome/browser/resources/pdf/pdf.js245
-rw-r--r--chromium/chrome/browser/resources/pdf/pdf_scripting_api.js24
-rw-r--r--chromium/chrome/browser/resources/pdf/toolbar_manager.js65
-rw-r--r--chromium/chrome/browser/resources/plugin_metadata/plugins_linux.json6
-rw-r--r--chromium/chrome/browser/resources/plugin_metadata/plugins_mac.json6
-rw-r--r--chromium/chrome/browser/resources/plugin_metadata/plugins_win.json6
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/app_state.js15
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/destination_store.js530
-rw-r--r--chromium/chrome/browser/resources/print_preview/native_layer.js33
-rw-r--r--chromium/chrome/browser/resources/print_preview/pdf_preview.html1
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview.css1
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview.js9
-rw-r--r--chromium/chrome/browser/resources/print_preview/search/destination_search.js6
-rw-r--r--chromium/chrome/browser/resources/settings/OWNERS2
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html114
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js8
-rw-r--r--chromium/chrome/browser/resources/settings/advanced_page/advanced_page.css1
-rw-r--r--chromium/chrome/browser/resources/settings/advanced_page/advanced_page.html110
-rw-r--r--chromium/chrome/browser/resources/settings/advanced_page/advanced_page.js12
-rw-r--r--chromium/chrome/browser/resources/settings/advanced_page/compiled_resources.gyp (renamed from chromium/chrome/browser/resources/settings/checkbox/compiled_resources.gyp)9
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html95
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js236
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_page.css43
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html127
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js131
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_shared.css12
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/compiled_resources.gyp53
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/basic_page.css1
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/basic_page.html91
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/basic_page.js26
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/compiled_resources.gyp (renamed from chromium/chrome/browser/resources/settings/radio_group/compiled_resources.gyp)8
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.html49
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.js71
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.css33
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html37
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js71
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_dialog.css91
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.css32
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html86
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js523
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.html68
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js271
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/compiled_resources.gyp72
-rw-r--r--chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html2
-rw-r--r--chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js10
-rw-r--r--chromium/chrome/browser/resources/settings/checkbox/checkbox.html24
-rw-r--r--chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html66
-rw-r--r--chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js27
-rw-r--r--chromium/chrome/browser/resources/settings/compiled_resources.gyp11
-rw-r--r--chromium/chrome/browser/resources/settings/controls/compiled_resources.gyp67
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_checkbox.css (renamed from chromium/chrome/browser/resources/settings/checkbox/checkbox.css)0
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_checkbox.html27
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_checkbox.js (renamed from chromium/chrome/browser/resources/settings/checkbox/checkbox.js)29
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_dropdown_menu.html28
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_dropdown_menu.js163
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_input.css (renamed from chromium/chrome/browser/resources/settings/input/input.css)0
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_input.html (renamed from chromium/chrome/browser/resources/settings/input/input.html)18
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_input.js (renamed from chromium/chrome/browser/resources/settings/input/input.js)16
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_radio_group.css (renamed from chromium/chrome/browser/resources/settings/radio_group/radio_group.css)6
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_radio_group.html (renamed from chromium/chrome/browser/resources/settings/radio_group/radio_group.html)7
-rw-r--r--chromium/chrome/browser/resources/settings/controls/settings_radio_group.js57
-rw-r--r--chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html10
-rw-r--r--chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js10
-rw-r--r--chromium/chrome/browser/resources/settings/date_time_page/demo.html12
-rw-r--r--chromium/chrome/browser/resources/settings/date_time_page/demo.js9
-rw-r--r--chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.css (renamed from chromium/chrome/browser/resources/settings/location_page/location_page.css)4
-rw-r--r--chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.html24
-rw-r--r--chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.js105
-rw-r--r--chromium/chrome/browser/resources/settings/downloads_page/downloads_page.css2
-rw-r--r--chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html24
-rw-r--r--chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js10
-rw-r--r--chromium/chrome/browser/resources/settings/i18n_setup.html2
-rw-r--r--chromium/chrome/browser/resources/settings/icons.html17
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/compiled_resources.gyp38
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.css49
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html133
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js93
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html6
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js27
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_page.html28
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_page.js19
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_apnlist.css7
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_apnlist.html4
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_apnlist.js6
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_ip_config.html2
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_nameservers.css7
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_nameservers.html4
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_property_list.css17
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_property_list.html9
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_property_list.js32
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy.css14
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy.html36
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy.js19
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html3
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js2
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.css2
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.html1
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_siminfo.css19
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_siminfo.html13
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_siminfo.js20
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary.html3
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary.js184
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html13
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js26
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/compiled_resources.gyp8
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.css25
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html36
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js103
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/language_detail_page.html10
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/language_detail_page.js30
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/languages.html5
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/languages.js463
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/languages_page.html125
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/languages_page.js56
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/languages_types.js127
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.html15
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.js24
-rw-r--r--chromium/chrome/browser/resources/settings/location_page/location_page.html47
-rw-r--r--chromium/chrome/browser/resources/settings/location_page/location_page.js94
-rw-r--r--chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.html57
-rw-r--r--chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.js27
-rw-r--r--chromium/chrome/browser/resources/settings/on_startup_page/on_startup_shared.css9
-rw-r--r--chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html77
-rw-r--r--chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js59
-rw-r--r--chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html45
-rw-r--r--chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js67
-rw-r--r--chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.css27
-rw-r--r--chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html27
-rw-r--r--chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js29
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/change_picture.css13
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/change_picture.html39
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/change_picture.js168
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/change_picture_private_api.html1
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/change_picture_private_api.js74
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/compiled_resources.gyp67
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/manage_profile.css12
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/manage_profile.html26
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/manage_profile.js96
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/people_page.css21
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/people_page.html131
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/people_page.js163
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/sync_page.css (renamed from chromium/chrome/browser/resources/settings/sync_page/sync_page.css)19
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/sync_page.html130
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/sync_page.js265
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/sync_private_api.html1
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/sync_private_api.js294
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/user_list.css (renamed from chromium/chrome/browser/resources/settings/users_page/user_list.css)5
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/user_list.html (renamed from chromium/chrome/browser/resources/settings/users_page/user_list.html)4
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/user_list.js (renamed from chromium/chrome/browser/resources/settings/users_page/user_list.js)10
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/users_page.css (renamed from chromium/chrome/browser/resources/settings/users_page/users_page.css)4
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/users_page.html64
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/users_page.js (renamed from chromium/chrome/browser/resources/settings/users_page/users_page.js)10
-rw-r--r--chromium/chrome/browser/resources/settings/policy_controllable/policy_controllable.html1
-rw-r--r--chromium/chrome/browser/resources/settings/policy_controllable/policy_controllable.js20
-rw-r--r--chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.html2
-rw-r--r--chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.js10
-rw-r--r--chromium/chrome/browser/resources/settings/prefs/compiled_resources.gyp3
-rw-r--r--chromium/chrome/browser/resources/settings/prefs/pref_util.html2
-rw-r--r--chromium/chrome/browser/resources/settings/prefs/pref_util.js57
-rw-r--r--chromium/chrome/browser/resources/settings/prefs/prefs.html1
-rw-r--r--chromium/chrome/browser/resources/settings/prefs/prefs.js100
-rw-r--r--chromium/chrome/browser/resources/settings/prefs/prefs_behavior.html1
-rw-r--r--chromium/chrome/browser/resources/settings/prefs/prefs_behavior.js62
-rw-r--r--chromium/chrome/browser/resources/settings/prefs/prefs_types.js7
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/privacy_page.css6
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html228
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js27
-rw-r--r--chromium/chrome/browser/resources/settings/radio_group/radio_group.js71
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/powerwash_dialog.html37
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/powerwash_dialog.js30
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_page.html26
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_page.js56
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_page_dialog.css (renamed from chromium/chrome/browser/resources/settings/internet_page/network_summary.css)9
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.css42
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.html31
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.js44
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.css14
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html48
-rw-r--r--chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js67
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.css5
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.html50
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js2
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.css16
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html6
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.css12
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html6
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js10
-rw-r--r--chromium/chrome/browser/resources/settings/search_page/search_page.css10
-rw-r--r--chromium/chrome/browser/resources/settings/search_page/search_page.html37
-rw-r--r--chromium/chrome/browser/resources/settings/search_page/search_page.js13
-rw-r--r--chromium/chrome/browser/resources/settings/settings.html9
-rw-r--r--chromium/chrome/browser/resources/settings/settings_dialog.css69
-rw-r--r--chromium/chrome/browser/resources/settings/settings_main/settings_main.html23
-rw-r--r--chromium/chrome/browser/resources/settings/settings_main/settings_main.js25
-rw-r--r--chromium/chrome/browser/resources/settings/settings_menu/settings_menu.css5
-rw-r--r--chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html44
-rw-r--r--chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js10
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/compiled_resources.gyp21
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_animated_pages.js6
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_page.css70
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_page_visibility.html1
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_page_visibility.js49
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_router.js176
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_section.css2
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_section.js8
-rw-r--r--chromium/chrome/browser/resources/settings/settings_resources.grd353
-rw-r--r--chromium/chrome/browser/resources/settings/settings_shared.css115
-rw-r--r--chromium/chrome/browser/resources/settings/settings_ui/settings_ui.css6
-rw-r--r--chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html10
-rw-r--r--chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js8
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/compiled_resources.gyp95
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/constants.html2
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/constants.js40
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details.css19
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details.html53
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details.js74
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details_permission.css36
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details_permission.html40
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js98
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_list.css (renamed from chromium/chrome/browser/resources/options/chromeos/power_overlay.css)12
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_list.html56
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_list.js285
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.html5
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js317
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_settings_category.css15
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_settings_category.html44
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_settings_category.js111
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings_page/compiled_resources.gyp26
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html47
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js80
-rw-r--r--chromium/chrome/browser/resources/settings/sync_page/sync_page.html74
-rw-r--r--chromium/chrome/browser/resources/settings/sync_page/sync_page.js21
-rw-r--r--chromium/chrome/browser/resources/settings/users_page/users_page.html65
-rw-r--r--chromium/chrome/browser/resources/supervised_user_block_interstitial.css152
-rw-r--r--chromium/chrome/browser/resources/supervised_user_block_interstitial.html64
-rw-r--r--chromium/chrome/browser/resources/supervised_user_block_interstitial.js58
-rw-r--r--chromium/chrome/browser/resources/supervised_user_internals.html8
-rw-r--r--chromium/chrome/browser/resources/supervised_user_internals.js6
-rw-r--r--chromium/chrome/browser/resources/uber/uber_frame.css2
-rw-r--r--chromium/chrome/browser/resources/uber/uber_frame.html16
-rw-r--r--chromium/chrome/browser/resources/uber/uber_frame.js13
-rw-r--r--chromium/chrome/browser/resources/webstore_app/OWNERS2
1220 files changed, 35695 insertions, 173644 deletions
diff --git a/chromium/chrome/browser/resources/BUILD.gn b/chromium/chrome/browser/resources/BUILD.gn
index a5949a2136b..d0af3400612 100644
--- a/chromium/chrome/browser/resources/BUILD.gn
+++ b/chromium/chrome/browser/resources/BUILD.gn
@@ -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("//chrome/common/features.gni")
import("//tools/grit/grit_rule.gni")
grit("memory_internals_resources") {
source = "memory_internals_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/memory_internals_resources.h",
"memory_internals_resources.pak",
@@ -15,6 +17,7 @@ grit("memory_internals_resources") {
grit("net_internals_resources") {
source = "net_internals_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/net_internals_resources.h",
"net_internals_resources.pak",
@@ -24,6 +27,7 @@ grit("net_internals_resources") {
grit("invalidations_resources") {
source = "invalidations_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/invalidations_resources.h",
"invalidations_resources.pak",
@@ -33,6 +37,7 @@ grit("invalidations_resources") {
grit("password_manager_internals_resources") {
source = "password_manager_internals_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/password_manager_internals_resources.h",
"password_manager_internals_resources.pak",
@@ -40,8 +45,20 @@ grit("password_manager_internals_resources") {
output_dir = "$root_gen_dir/chrome"
}
+grit("policy_resources") {
+ source = "md_policy/policy_resources.grd"
+ outputs = [
+ "grit/policy_resources.h",
+ "grit/policy_resources_map.cc",
+ "grit/policy_resources_map.h",
+ "policy_resources.pak",
+ ]
+ output_dir = "$root_gen_dir/chrome"
+}
+
grit("signin_internals_resources") {
source = "signin_internals_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/signin_internals_resources.h",
"signin_internals_resources.pak",
@@ -51,6 +68,7 @@ grit("signin_internals_resources") {
grit("translate_internals_resources") {
source = "translate_internals_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/translate_internals_resources.h",
"translate_internals_resources.pak",
@@ -71,6 +89,7 @@ copy("extension_resource_demo") {
if (!is_ios) {
grit("component_extension_resources") {
source = "component_extension_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/component_extension_resources.h",
"grit/component_extension_resources_map.cc",
@@ -82,6 +101,7 @@ if (!is_ios) {
grit("settings_resources") {
source = "settings/settings_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/settings_resources.h",
"grit/settings_resources_map.cc",
@@ -93,6 +113,7 @@ if (!is_ios) {
grit("options_resources") {
source = "options_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/options_resources.h",
"options_resources.pak",
@@ -102,6 +123,7 @@ if (!is_ios) {
grit("options_test_resources") {
source = "options_test_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/options_test_resources.h",
"options_test_resources.pak",
@@ -111,6 +133,7 @@ if (!is_ios) {
grit("quota_internals_resources") {
source = "quota_internals_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/quota_internals_resources.h",
"quota_internals_resources.pak",
@@ -120,6 +143,7 @@ if (!is_ios) {
grit("sync_file_system_internals_resources") {
source = "sync_file_system_internals_resources.grd"
+ defines = chrome_grit_defines
outputs = [
"grit/sync_file_system_internals_resources.h",
"sync_file_system_internals_resources.pak",
diff --git a/chromium/chrome/browser/resources/OWNERS b/chromium/chrome/browser/resources/OWNERS
index 88772418600..dae8b0021ee 100644
--- a/chromium/chrome/browser/resources/OWNERS
+++ b/chromium/chrome/browser/resources/OWNERS
@@ -1,7 +1,6 @@
bauerb@chromium.org
dbeam@chromium.org
estade@chromium.org
-jhawkins@chromium.org
nkostylev@chromium.org
pam@chromium.org
xiyuan@chromium.org
diff --git a/chromium/chrome/browser/resources/about_version.css b/chromium/chrome/browser/resources/about_version.css
deleted file mode 100644
index 6ac70ed9037..00000000000
--- a/chromium/chrome/browser/resources/about_version.css
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-body {
- background-color: white;
- color: black;
- font-size: 100%;
- margin: 0;
-}
-
-#outer {
- margin-left: auto;
- margin-right: auto;
- margin-top: 10px;
- width: 800px;
-}
-
-#inner {
- padding-top: 10px;
- word-break: break-word;
-}
-
-.label {
- -webkit-padding-end: 5px;
- font-size: 0.9em;
- font-weight: bold;
- text-align: end;
- vertical-align: top;
- white-space: nowrap;
-}
-
-.label::after {
- content: ':';
-}
-
-#logo {
- float: right;
- margin-left: 40px;
- text-align: right;
- width: 180px;
-}
-
-#company {
- font-size: 0.7em;
- text-align: right;
-}
-
-#copyright {
- font-size: 0.7em;
- text-align: right;
-}
-
-#useragent {
- font-family: monospace;
-}
-
-.version {
- font-family: monospace;
- max-width: 430px;
- padding-left: 5px;
- vertical-align: bottom;
-}
diff --git a/chromium/chrome/browser/resources/about_version.html b/chromium/chrome/browser/resources/about_version.html
deleted file mode 100644
index 1973db19329..00000000000
--- a/chromium/chrome/browser/resources/about_version.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<!doctype html>
-
-<!--
-about:version template page
--->
-
-<html id="t" i18n-values="dir:textdirection;lang:language">
- <head>
- <meta charset="utf-8">
- <title i18n-content="title"></title>
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<if expr="is_android">
- <meta name="viewport" content="width=device-width">
-</if>
- <link rel="stylesheet" href="chrome://version/about_version.css">
-<if expr="is_android">
- <link rel="stylesheet" href="about_version_android.css">
-</if>
- <script src="chrome://resources/js/cr.js"></script>
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://resources/js/parse_html_subset.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="chrome://version/version.js"></script>
- <script src="chrome://version/strings.js"></script>
- </head>
-
- <body>
- <div id="outer">
- <div id="logo">
-<if expr="enable_themes">
- <img src="chrome://theme/IDR_PRODUCT_LOGO">
-</if>
-<if expr="not enable_themes">
- <img src="../../app/theme/default_100_percent/%DISTRIBUTION%/product_logo.png">
-</if>
- <div id="company" i18n-content="company"></div>
- <div id="copyright" i18n-content="copyright"></div>
- </div>
- <table id="inner" cellpadding="0" cellspacing="0" border="0">
- <tr><td class="label" i18n-content="application_label"></td>
- <td class="version" id="version">
- <span i18n-content="version"></span>
- (<span i18n-content="official"></span>)
- <span i18n-content="version_modifier"></span>
- <span i18n-content="version_bitsize"></span>
- </td>
- </tr>
- <tr>
- <td class="label" i18n-content="revision"></td>
- <td class="version">
- <span i18n-content="cl"></span>
- </td>
- </tr>
-<if expr="not chromeos">
- <tr><td class="label" i18n-content="os_name"></td>
- <td class="version" id="os_type">
- <span i18n-content="os_type"></span>
- <span id="os_version" i18n-content="os_version"></span>
- </td>
-</if>
-<if expr="chromeos">
- <tr><td class="label" i18n-content="platform"></td>
- <td class="version" id="os_type">
- <span id="os_version" i18n-content="os_version"></span>
- </td>
-</if>
- </tr>
- <tr><td class="label">Blink</td>
- <td class="version" id="blink_version" i18n-content="blink_version"></td>
- </tr>
- <tr><td class="label">JavaScript</td>
- <td class="version" id="js_engine">
- <span i18n-content="js_engine"></span>
- <span i18n-content="js_version"></span>
- </td>
- </tr>
-<if expr="not is_android">
- <tr><td class="label" i18n-content="flash_plugin"></td>
- <td class="version" id="flash_version" i18n-content="flash_version"></td>
- </tr>
-</if>
- <tr><td class="label" i18n-content="user_agent_name"></td>
- <td class="version" id="useragent" i18n-content="useragent"></td>
- </tr>
- <tr><td class="label" i18n-content="command_line_name"></td>
- <td class="version" id="command_line" i18n-content="command_line"></td>
- </tr>
- <tr><td class="label" i18n-content="executable_path_name"></td>
- <td class="version" id="executable_path" i18n-content="executable_path"></td>
- </tr>
- <tr><td class="label" i18n-content="profile_path_name"></td>
- <td class="version" id="profile_path" i18n-content="profile_path"></td>
- </tr>
- <tr id="variations-section">
- <td class="label" i18n-content="variations_name"></td>
- <td class="version" id="variations-list"></td>
- </tr>
-<if expr="is_android">
- <tr id="build-id-section">
- <td class="label" i18n-content="build_id_name"></td>
- <td class="version" i18n-content="build_id"></td>
- </tr>
-</if>
- </table>
- </div>
- <script src="chrome://resources/js/i18n_template.js"></script>
- </body>
-</html>
diff --git a/chromium/chrome/browser/resources/about_version.js b/chromium/chrome/browser/resources/about_version.js
deleted file mode 100644
index 476311bfae9..00000000000
--- a/chromium/chrome/browser/resources/about_version.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * Callback from the backend with the list of variations to display.
- * This call will build the variations section of the version page, or hide that
- * section if there are none to display.
- * @param {!Array<string>} variationsList The list of variations.
- */
-function returnVariationInfo(variationsList) {
- $('variations-section').hidden = !variationsList.length;
- $('variations-list').appendChild(
- parseHtmlSubset(variationsList.join('<br>'), ['BR']));
-}
-
-/**
- * Callback from the backend with the executable and profile paths to display.
- * @param {string} execPath The executable path to display.
- * @param {string} profilePath The profile path to display.
- */
-function returnFilePaths(execPath, profilePath) {
- $('executable_path').textContent = execPath;
- $('profile_path').textContent = profilePath;
-}
-
-/**
- * Callback from the backend with the Flash version to display.
- * @param {string} flashVersion The Flash version to display.
- */
-function returnFlashVersion(flashVersion) {
- $('flash_version').textContent = flashVersion;
-}
-
-/**
- * Callback from the backend with the OS version to display.
- * @param {string} osVersion The OS version to display.
- */
-function returnOsVersion(osVersion) {
- $('os_version').textContent = osVersion;
-}
-
-/* All the work we do onload. */
-function onLoadWork() {
- chrome.send('requestVersionInfo');
-}
-
-document.addEventListener('DOMContentLoaded', onLoadWork);
diff --git a/chromium/chrome/browser/resources/about_version_android.css b/chromium/chrome/browser/resources/about_version_android.css
deleted file mode 100644
index b084d149c29..00000000000
--- a/chromium/chrome/browser/resources/about_version_android.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#outer {
- text-align: left;
- width: 90%;
-}
-
-#inner {
- width: auto;
-}
-
-#logo {
- float: none;
- margin-left: auto;
- margin-right: auto;
-}
diff --git a/chromium/chrome/browser/resources/app_list/start_page.css b/chromium/chrome/browser/resources/app_list/start_page.css
index 268feeb6c51..8f6edd09c0d 100644
--- a/chromium/chrome/browser/resources/app_list/start_page.css
+++ b/chromium/chrome/browser/resources/app_list/start_page.css
@@ -18,13 +18,11 @@ body {
}
#default_logo {
- background-image: -webkit-image-set(
- url(chrome://theme/IDR_LOCAL_NTP_IMAGES_LOGO_PNG) 1x,
- url(chrome://theme/IDR_LOCAL_NTP_IMAGES_LOGO_PNG@2x) 2x);
+ background-image: url(../../../../ui/webui/resources/images/google_logo.svg);
background-repeat: no-repeat;
- height: 95px;
+ height: 92px;
margin: auto;
- width: 269px;
+ width: 272px;
}
#logo_container {
diff --git a/chromium/chrome/browser/resources/bookmark_manager/css/bmm.css b/chromium/chrome/browser/resources/bookmark_manager/css/bmm.css
index c928131579c..1d039178d04 100644
--- a/chromium/chrome/browser/resources/bookmark_manager/css/bmm.css
+++ b/chromium/chrome/browser/resources/bookmark_manager/css/bmm.css
@@ -96,9 +96,7 @@ list > .folder > .url:empty::after {
list > * > button {
-webkit-transition: opacity 150ms;
- background: #fff
- url(../../../../../ui/webui/resources/images/drop_down_arrow_black.svg)
- no-repeat center center;
+ background: #fff no-repeat center center;
border: 1px solid hsl(214, 91%, 85%);
border-radius: 3px;
bottom: 1px;
@@ -206,6 +204,7 @@ list > .folder > .label,
border-top: 1px solid rgb(156, 194, 239);
display: flex;
flex: 1;
+ min-height: 0;
}
.pane,
@@ -242,6 +241,7 @@ list > .folder > .label,
#list-pane {
flex: 1;
+ min-width: 0;
}
#list-pane > :first-child {
@@ -343,9 +343,7 @@ list > .drag-above {
-webkit-appearance: none;
-webkit-padding-end: 11px;
-webkit-padding-start: 0;
- background: transparent
- url(../../../../../ui/webui/resources/images/drop_down_arrow_black.svg)
- no-repeat right center;
+ background: transparent no-repeat right center;
border: 0;
font: inherit;
font-weight: bold;
@@ -353,6 +351,15 @@ list > .drag-above {
padding-top: 0;
}
+list > * > button,
+[i18n-processed] #folders-button,
+[i18n-processed] #organize-button,
+[i18n-processed] .splitter button {
+ background-image:
+ url(../../../../../ui/webui/resources/images/drop_down_arrow_black.svg);
+ background-size: 9px 4px;
+}
+
#folders-button {
-webkit-margin-start: 16px;
}
diff --git a/chromium/chrome/browser/resources/chromeos/OWNERS b/chromium/chrome/browser/resources/chromeos/OWNERS
deleted file mode 100644
index 0525500f39f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/OWNERS
+++ /dev/null
@@ -1,10 +0,0 @@
-xiyuan@chromium.org
-nkostylev@chromium.org
-achuith@chromium.org
-zelidrag@chromium.org
-satorux@chromium.org
-stevenjb@chromium.org
-michaelpg@chromium.org
-
-per-file drive_internals*=hashimoto@chromium.org
-per-file drive_internals*=kinaba@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/about_os_credits.html b/chromium/chrome/browser/resources/chromeos/about_os_credits.html
deleted file mode 100644
index 5e7caabffe3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/about_os_credits.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype html>
-<html>
-<head>
-<meta charset="UTF-8">
-<title>Credits</title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<style>
-body {
- background-color:white;
- max-width:1020px;
-}
-</style>
-</head>
-<body>
-<h1>Placeholder</h1>
-<p>See <a href="http://dev.chromium.org/chromium-os/licensing-for-chromiumos-developers">Licensing for Chromium OS Developers</a> and
- <a href="http://dev.chromium.org/chromium-os/licensing-for-chromiumos-package-owners">Licensing for Chromium OS Package Owners</a></p>
-<p>
-If you need to change styles, fonts, layout, etc of <a href="chrome://os_credits">chrome://os_credits</a> page,
-edit <a href="https://chromium.googlesource.com/chromiumos/chromite/+/master/licensing/about_credits.tmpl">chromite/licensing/about_credits.tmpl</a>.
-The template is used to generate
-a device-dependent about_os_credits.html when a CrOS image is built.</p>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/bluetooth_options.js b/chromium/chrome/browser/resources/chromeos/bluetooth_options.js
deleted file mode 100644
index 150592aab3a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/bluetooth_options.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- /** @const */ var Page = cr.ui.pageManager.Page;
-
- /**
- * Encapsulated handling of the BluetoothOptions calls from
- * BluetoothOptionsHandler that is registered by the webUI,
- * ie, BluetoothPairingUI.
- * @constructor
- */
- function BluetoothOptions() {
- Page.call(this, 'bluetooth', '', 'bluetooth-container');
- }
-
- cr.addSingletonGetter(BluetoothOptions);
-
- BluetoothOptions.prototype = {
- __proto__: Page.prototype,
- };
-
- BluetoothOptions.updateDiscovery = function() {
- };
-
- // Export
- return {
- BluetoothOptions: BluetoothOptions
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.css b/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.css
deleted file mode 100644
index 9f39b8476f1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.css
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-.close-button {
- display: none;
-}
-
-#bluetooth-pairing {
- border: 0;
- box-shadow: none;
-}
-
-.overlay .page h1 {
- display: none;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.html b/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.html
deleted file mode 100644
index 5a3bd3925ca..00000000000
--- a/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<meta charset="utf-8">
-<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
-<link rel="stylesheet" href="chrome://resources/css/overlay.css">
-
-<link rel="stylesheet" href="../options/options_page.css">
-<link rel="stylesheet" href="../options/chromeos/bluetooth.css">
-<link rel="stylesheet" href="bluetooth_pair_device.css">
-
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/event_tracker.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/cr/ui.js"></script>
-<script src="chrome://resources/js/cr/ui/array_data_model.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/touch_handler.js"></script>
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="chrome://resources/js/cr/ui/page_manager/page_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/page_manager/page.js"></script>
-<script src="chrome://bluetooth-pairing/strings.js"></script>
-
-<script src="../options/options_page.js"></script>
-<script src="../options/chromeos/bluetooth_pair_device_overlay.js"></script>
-<script src="../uber/uber_utils.js"></script>
-
-<script src="bluetooth_options.js"></script>
-<script src="browser_options.js"></script>
-<script src="fake_bluetooth_overlay_parent.js"></script>
-<script src="bluetooth_pair_device.js"></script>
-</head>
-
-<body>
-<div id="overlay-container" class="overlay">
- <include src="../options/chromeos/bluetooth_pair_device_overlay.html">
-</div>
-<div id="page-container">
- <div id="bluetooth-container"></div>
-</div>
-<div id="searchBox" hidden><input id="search-field" type=text></div>
-<script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.js b/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.js
deleted file mode 100644
index 7cba61d84a1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/bluetooth_pair_device.js
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var PageManager = cr.ui.pageManager.PageManager;
-var BluetoothPairing = options.BluetoothPairing;
-var FakeBluetoothOverlayParent = options.FakeBluetoothOverlayParent;
-
-/** @override */
-PageManager.closeOverlay = function() {
- chrome.send('dialogClose');
-};
-
-/**
- * Listener for the |beforeunload| event.
- */
-window.onbeforeunload = function() {
- PageManager.willClose();
-};
-
-/*
- * Override calls from BluetoothOptionsHandler.
- */
-cr.define('options', function() {
- function BluetoothOptions() {}
-
- BluetoothOptions.startDeviceDiscovery = function() {};
- BluetoothOptions.updateDiscoveryState = function() {};
- BluetoothOptions.dismissOverlay = function() {
- PageManager.closeOverlay();
- };
-
- return {
- BluetoothOptions: BluetoothOptions
- };
-});
-
-/**
- * DOMContentLoaded handler, sets up the page.
- */
-function load() {
- if (cr.isChromeOS)
- document.documentElement.setAttribute('os', 'chromeos');
-
- // Decorate the existing elements in the document.
- cr.ui.decorate('input[pref][type=checkbox]', options.PrefCheckbox);
- cr.ui.decorate('input[pref][type=number]', options.PrefNumber);
- cr.ui.decorate('input[pref][type=radio]', options.PrefRadio);
- cr.ui.decorate('input[pref][type=range]', options.PrefRange);
- cr.ui.decorate('select[pref]', options.PrefSelect);
- cr.ui.decorate('input[pref][type=text]', options.PrefTextField);
- cr.ui.decorate('input[pref][type=url]', options.PrefTextField);
-
- // TODO(ivankr): remove when http://crosbug.com/20660 is resolved.
- var inputs = document.querySelectorAll('input[pref]');
- for (var i = 0, el; el = inputs[i]; i++) {
- el.addEventListener('keyup', function(e) {
- cr.dispatchSimpleEvent(this, 'change');
- });
- }
-
- chrome.send('coreOptionsInitialize');
-
- PageManager.register(FakeBluetoothOverlayParent.getInstance());
- PageManager.registerOverlay(BluetoothPairing.getInstance(),
- FakeBluetoothOverlayParent.getInstance());
-
- var device = {};
- var args = JSON.parse(chrome.getVariableValue('dialogArguments'));
- device = args;
- device.pairing = 'bluetoothStartConnecting';
- BluetoothPairing.showDialog(device);
- chrome.send('updateBluetoothDevice', [device.address, 'connect']);
-}
-
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chromium/chrome/browser/resources/chromeos/braille_ime/BUILD.gn b/chromium/chrome/browser/resources/chromeos/braille_ime/BUILD.gn
deleted file mode 100644
index 092cbce3bc1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/braille_ime/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-assert(is_chromeos)
-
-copy("braille_ime_manifest") {
- sources = [
- "manifest.json",
- ]
- outputs = [
- "$root_out_dir/resources/chromeos/braille_ime/manifest.json",
- ]
-}
diff --git a/chromium/chrome/browser/resources/chromeos/braille_ime/OWNERS b/chromium/chrome/browser/resources/chromeos/braille_ime/OWNERS
deleted file mode 100644
index dfab84a0164..00000000000
--- a/chromium/chrome/browser/resources/chromeos/braille_ime/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-aboxhall@chromium.org
-dmazzoni@chromium.org
-dtseng@chromium.org
-plundblad@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/braille_ime/PRESUBMIT.py b/chromium/chrome/browser/resources/chromeos/braille_ime/PRESUBMIT.py
deleted file mode 100644
index 368c96fc58a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/braille_ime/PRESUBMIT.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# 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.
-
-"""Presubmit script for the Braille IME."""
-
-def CheckChangeOnUpload(input_api, output_api):
- def FileFilter(path):
- return path.endswith('.js') or path.endswith('check_braille_ime.py')
- if not any((FileFilter(p) for p in input_api.LocalPaths())):
- return []
- import sys
- if not sys.platform.startswith('linux'):
- return []
- sys.path.insert(0, input_api.PresubmitLocalPath())
- try:
- from check_braille_ime import CheckBrailleIme
- finally:
- sys.path.pop(0)
- success, output = CheckBrailleIme()
- if not success:
- return [output_api.PresubmitError(
- 'Braille IME closure compilation failed',
- long_text=output)]
- return []
diff --git a/chromium/chrome/browser/resources/chromeos/braille_ime/braille_ime.js b/chromium/chrome/browser/resources/chromeos/braille_ime/braille_ime.js
deleted file mode 100644
index c91257446db..00000000000
--- a/chromium/chrome/browser/resources/chromeos/braille_ime/braille_ime.js
+++ /dev/null
@@ -1,513 +0,0 @@
-// 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.
-
-'use strict';
-
-/**
- * @fileoverview Braille hardware keyboard input method.
- *
- * This method is automatically enabled when a braille display is connected
- * and ChromeVox is turned on. Most of the braille input and editing logic
- * is located in ChromeVox where the braille translation library is available.
- * This IME connects to ChromeVox and communicates using messages as follows:
- *
- * Sent from this IME to ChromeVox:
- * {type: 'activeState', active: boolean}
- * {type: 'inputContext', context: InputContext}
- * Sent on focus/blur to inform ChromeVox of the type of the current field.
- * In the latter case (blur), context is null.
- * {type: 'reset'}
- * Sent when the {@code onReset} IME event fires or uncommitted text is
- * committed without being triggered by ChromeVox (e.g. because of a
- * key press).
- * {type: 'brailleDots', dots: number}
- * Sent when the user typed a braille cell using the standard keyboard.
- * ChromeVox treats this similarly to entering braille input using the
- * braille display.
- * {type: 'backspace', requestId: string}
- * Sent when the user presses the backspace key.
- * ChromeVox must respond with a {@code keyEventHandled} message
- * with the same request id.
- *
- * Sent from ChromeVox to this IME:
- * {type: 'replaceText', contextID: number, deleteBefore: number,
- * newText: string}
- * Deletes {@code deleteBefore} characters before the cursor (or selection)
- * and inserts {@code newText}. {@code contextID} identifies the text field
- * to apply the update to (no change will happen if focus has moved to a
- * different field).
- * {type: 'setUncommitted', contextID: number, text: string}
- * Stores text for the field identified by contextID to be committed
- * either as a result of a 'commitUncommitted' message or a by the IME
- * unhandled key press event. Unlike 'replaceText', this does not send the
- * uncommitted text to the input field, but instead stores it in the IME.
- * {type: 'commitUncommitted', contextID: number}
- * Commits any uncommitted text if it matches the given context ID.
- * See 'setUncommitted' above.
- * {type: 'keyEventHandled', requestId: string, result: boolean}
- * Response to a {@code backspace} message indicating whether the
- * backspace was handled by ChromeVox or should be allowed to propagate
- * through the normal event handling pipeline.
- */
-
-/**
- * @constructor
- */
-var BrailleIme = function() {};
-
-BrailleIme.prototype = {
- /**
- * Whether to enable extra debug logging for the IME.
- * @const {boolean}
- * @private
- */
- DEBUG: false,
-
- /**
- * ChromeVox extension ID.
- * @const {string}
- * @private
- */
- CHROMEVOX_EXTENSION_ID_: 'mndnfokpggljbaajbnioimlmbfngpief',
-
- /**
- * Name of the port used for communication with ChromeVox.
- * @const {string}
- * @private
- */
- PORT_NAME: 'cvox.BrailleIme.Port',
-
- /**
- * Identifier for the use standard keyboard option used in the menu and
- * {@code localStorage}. This can be switched on to type braille using the
- * standard keyboard, or off (default) for the usual keyboard behaviour.
- * @const {string}
- */
- USE_STANDARD_KEYBOARD_ID: 'useStandardKeyboard',
-
- // State related to the support for typing braille using a standrad
- // (qwerty) keyboard.
-
- /** @private {boolean} */
- useStandardKeyboard_: false,
-
- /**
- * Braille dots for keys that are currently pressed.
- * @private {number}
- */
- pressed_: 0,
-
- /**
- * Dots that have been pressed at some point since {@code pressed_} was last
- * {@code 0}.
- * @private {number}
- */
- accumulated_: 0,
-
- /**
- * Bit in {@code pressed_} and {@code accumulated_} that represent
- * the space key.
- * @const {number}
- */
- SPACE: 0x100,
-
- /**
- * Maps key codes on a standard keyboard to the correspodning dots.
- * Keys on the 'home row' correspond to the keys on a Perkins-style keyboard.
- * Note that the mapping below is arranged like the dots in a braille cell.
- * Only 6 dot input is supported.
- * @private
- * @const {Object<number>}
- */
- CODE_TO_DOT_: {'KeyF': 0x01, 'KeyJ': 0x08,
- 'KeyD': 0x02, 'KeyK': 0x10,
- 'KeyS': 0x04, 'KeyL': 0x20,
- 'Space': 0x100 },
-
- /**
- * The current engine ID as set by {@code onActivate}, or the empty string if
- * the IME is not active.
- * @type {string}
- * @private
- */
- engineID_: '',
-
- /**
- * The port used to communicate with ChromeVox.
- * @type {Port} port_
- * @private
- */
- port_: null,
-
- /**
- * Uncommitted text and context ID.
- * @type {?{contextID: number, text: string}}
- * @private
- */
- uncommitted_: null,
-
- /**
- * Registers event listeners in the chrome IME API.
- */
- init: function() {
- chrome.input.ime.onActivate.addListener(this.onActivate_.bind(this));
- chrome.input.ime.onDeactivated.addListener(this.onDeactivated_.bind(this));
- chrome.input.ime.onFocus.addListener(this.onFocus_.bind(this));
- chrome.input.ime.onBlur.addListener(this.onBlur_.bind(this));
- chrome.input.ime.onInputContextUpdate.addListener(
- this.onInputContextUpdate_.bind(this));
- chrome.input.ime.onKeyEvent.addListener(this.onKeyEvent_.bind(this),
- ['async']);
- chrome.input.ime.onReset.addListener(this.onReset_.bind(this));
- chrome.input.ime.onMenuItemActivated.addListener(
- this.onMenuItemActivated_.bind(this));
- this.connectChromeVox_();
- },
-
- /**
- * Called by the IME framework when this IME is activated.
- * @param {string} engineID Engine ID, should be 'braille'.
- * @private
- */
- onActivate_: function(engineID) {
- this.log_('onActivate', engineID);
- this.engineID_ = engineID;
- if (!this.port_) {
- this.connectChromeVox_();
- }
- this.useStandardKeyboard_ =
- localStorage[this.USE_STANDARD_KEYBOARD_ID] === String(true);
- this.accumulated_ = 0;
- this.pressed_ = 0;
- this.updateMenuItems_();
- this.sendActiveState_();
- },
-
- /**
- * Called by the IME framework when this IME is deactivated.
- * @param {string} engineID Engine ID, should be 'braille'.
- * @private
- */
- onDeactivated_: function(engineID) {
- this.log_('onDectivated', engineID);
- this.engineID_ = '';
- this.sendActiveState_();
- },
-
- /**
- * Called by the IME framework when a text field receives focus.
- * @param {InputContext} context Input field context.
- * @private
- */
- onFocus_: function(context) {
- this.log_('onFocus', context);
- this.sendInputContext_(context);
- },
-
- /**
- * Called by the IME framework when a text field looses focus.
- * @param {number} contextID Input field context ID.
- * @private
- */
- onBlur_: function(contextID) {
- this.log_('onBlur', contextID + '');
- this.sendInputContext_(null);
- },
-
- /**
- * Called by the IME framework when the current input context is updated.
- * @param {InputContext} context Input field context.
- * @private
- */
- onInputContextUpdate_: function(context) {
- this.log_('onInputContextUpdate', context);
- this.sendInputContext_(context);
- },
-
- /**
- * Called by the system when this IME is active and a key event is generated.
- * @param {string} engineID Engine ID, should be 'braille'.
- * @param {!ChromeKeyboardEvent} event The keyboard event.
- * @private
- */
- onKeyEvent_: function(engineID, event) {
- var result = this.processKey_(event);
- if (result !== undefined)
- this.keyEventHandled_(event.requestId, event.type, result);
- },
-
- /**
- * Called when chrome ends the current text input session.
- * @param {string} engineID Engine ID, should be 'braille'.
- * @private
- */
- onReset_: function(engineID) {
- this.log_('onReset', engineID);
- this.engineID_ = engineID;
- this.sendToChromeVox_({type: 'reset'});
- },
-
- /**
- * Called by the IME framework when a menu item is activated.
- * @param {string} engineID Engine ID, should be 'braille'.
- * @param {string} itemID Identifies the menu item.
- * @private
- */
- onMenuItemActivated_: function(engineID, itemID) {
- if (engineID === this.engineID_ &&
- itemID === this.USE_STANDARD_KEYBOARD_ID) {
- this.useStandardKeyboard_ = !this.useStandardKeyboard_;
- localStorage[this.USE_STANDARD_KEYBOARD_ID] =
- String(this.useStandardKeyboard_);
- if (!this.useStandardKeyboard_) {
- this.accumulated_ = 0;
- this.pressed_ = 0;
- }
- this.updateMenuItems_();
- }
- },
-
- /**
- * Outputs a log message to the console, only if {@link BrailleIme.DEBUG}
- * is set to true.
- * @param {string} func Name of the caller.
- * @param {Object|string=} message Message to output.
- * @private
- */
- log_: function(func, message) {
- if (this.DEBUG) {
- if (typeof(message) !== 'string') {
- message = JSON.stringify(message);
- }
- console.log('BrailleIme.' + func + ': ' + message);
- }
- },
-
- /**
- * Handles a qwerty key on the home row as a braille key.
- * @param {!ChromeKeyboardEvent} event Keyboard event.
- * @return {boolean|undefined} Whether the event was handled, or
- * {@code undefined} if handling was delegated to ChromeVox.
- * @private
- */
- processKey_: function(event) {
- if (!this.useStandardKeyboard_) {
- return false;
- }
- if (event.code === 'Backspace' && event.type === 'keydown') {
- this.pressed_ = 0;
- this.accumulated_ = 0;
- this.sendToChromeVox_(
- {type: 'backspace', requestId: event.requestId});
- return undefined;
- }
- var dot = this.CODE_TO_DOT_[event.code];
- if (!dot || event.altKey || event.ctrlKey || event.shiftKey ||
- event.capsLock) {
- this.pressed_ = 0;
- this.accumulated_ = 0;
- return false;
- }
- if (event.type === 'keydown') {
- this.pressed_ |= dot;
- this.accumulated_ |= this.pressed_;
- return true;
- } else if (event.type === 'keyup') {
- this.pressed_ &= ~dot;
- if (this.pressed_ === 0 && this.accumulated_ !== 0) {
- var dotsToSend = this.accumulated_;
- this.accumulated_ = 0;
- if (dotsToSend & this.SPACE) {
- if (dotsToSend != this.SPACE) {
- // Can't combine space and actual dot keys.
- return true;
- }
- // Space is sent as a blank cell.
- dotsToSend = 0;
- }
- this.sendToChromeVox_({type: 'brailleDots', dots: dotsToSend});
- }
- return true;
- }
- return false;
- },
-
- /**
- * Connects to the ChromeVox extension for message passing.
- * @private
- */
- connectChromeVox_: function() {
- if (this.port_) {
- this.port_.disconnect();
- this.port_ = null;
- }
- this.port_ = chrome.runtime.connect(
- this.CHROMEVOX_EXTENSION_ID_, {name: this.PORT_NAME});
- this.port_.onMessage.addListener(
- this.onChromeVoxMessage_.bind(this));
- this.port_.onDisconnect.addListener(
- this.onChromeVoxDisconnect_.bind(this));
- },
-
- /**
- * Handles a message from the ChromeVox extension.
- * @param {*} message The message from the extension.
- * @private
- */
- onChromeVoxMessage_: function(message) {
- message = /** @type {{type: string}} */ (message);
- this.log_('onChromeVoxMessage', message);
- switch (message.type) {
- case 'replaceText':
- message =
- /**
- * @type {{contextID: number, deleteBefore: number,
- * newText: string}}
- */
- (message);
- this.replaceText_(message.contextID, message.deleteBefore,
- message.newText);
- break;
- case 'keyEventHandled':
- message =
- /** @type {{requestId: string, result: boolean}} */ (message);
- this.keyEventHandled_(message.requestId, 'keydown', message.result);
- break;
- case 'setUncommitted':
- message =
- /** @type {{contextID: number, text: string}} */ (message);
- this.setUncommitted_(message.contextID, message.text);
- break;
- case 'commitUncommitted':
- message =
- /** @type {{contextID: number}} */ (message);
- this.commitUncommitted_(message.contextID);
- break;
- default:
- console.error('Unknown message from ChromeVox: ' +
- JSON.stringify(message));
- break;
- }
- },
-
- /**
- * Handles a disconnect event from the ChromeVox side.
- * @private
- */
- onChromeVoxDisconnect_: function() {
- this.port_ = null;
- this.log_('onChromeVoxDisconnect', chrome.runtime.lastError);
- },
-
- /**
- * Sends a message to the ChromeVox extension.
- * @param {Object} message The message to send.
- * @private
- */
- sendToChromeVox_: function(message) {
- if (this.port_) {
- this.port_.postMessage(message);
- }
- },
-
- /**
- * Sends the given input context to ChromeVox.
- * @param {InputContext} context Input context, or null when there's no input
- * context.
- * @private
- */
- sendInputContext_: function(context) {
- this.sendToChromeVox_({type: 'inputContext', context: context});
- },
-
- /**
- * Sends the active state to ChromeVox.
- * @private
- */
- sendActiveState_: function() {
- this.sendToChromeVox_({type: 'activeState',
- active: this.engineID_.length > 0});
- },
-
- /**
- * Replaces text in the current text field.
- * @param {number} contextID Context for the input field to replace the
- * text in.
- * @param {number} deleteBefore How many characters to delete before the
- * cursor.
- * @param {string} toInsert Text to insert at the cursor.
- */
- replaceText_: function(contextID, deleteBefore, toInsert) {
- var addText = chrome.input.ime.commitText.bind(
- null, {contextID: contextID, text: toInsert}, function() {});
- if (deleteBefore > 0) {
- var deleteText = chrome.input.ime.deleteSurroundingText.bind(null,
- {engineID: this.engineID_, contextID: contextID,
- offset: -deleteBefore, length: deleteBefore}, addText);
- // Make sure there's no non-zero length selection so that
- // deleteSurroundingText works correctly.
- chrome.input.ime.deleteSurroundingText(
- {engineID: this.engineID_, contextID: contextID,
- offset: 0, length: 0}, deleteText);
- } else {
- addText();
- }
- },
-
- /**
- * Responds to an asynchronous key event, indicating whether it was handled
- * or not. If it wasn't handled, any uncommitted text is committed
- * before sending the response to the IME API.
- * @param {string} requestId Key event request id.
- * @param {string} type Type of key event being responded to.
- * @param {boolean} response Whether the IME handled the event.
- */
- keyEventHandled_: function(requestId, type, response) {
- if (!response && type === 'keydown' && this.uncommitted_) {
- this.commitUncommitted_(this.uncommitted_.contextID);
- this.sendToChromeVox_({type: 'reset'});
- }
- chrome.input.ime.keyEventHandled(requestId, response);
- },
-
- /**
- * Stores uncommitted text that will be committed on any key press or
- * when {@code commitUncommitted_} is called.
- * @param {number} contextID of the current field.
- * @param {string} text to store.
- */
- setUncommitted_: function(contextID, text) {
- this.uncommitted_ = {contextID: contextID, text: text};
- },
-
- /**
- * Commits the last set uncommitted text if it matches the given context id.
- * @param {number} contextID
- */
- commitUncommitted_: function(contextID) {
- if (this.uncommitted_ && contextID === this.uncommitted_.contextID)
- chrome.input.ime.commitText(this.uncommitted_);
- this.uncommitted_ = null;
- },
-
- /**
- * Updates the menu items for this IME.
- */
- updateMenuItems_: function() {
- // TODO(plundblad): Localize when translations available.
- chrome.input.ime.setMenuItems(
- {engineID: this.engineID_,
- items: [
- {
- id: this.USE_STANDARD_KEYBOARD_ID,
- label: 'Use standard keyboard for braille',
- style: 'check',
- visible: true,
- checked: this.useStandardKeyboard_,
- enabled: true
- }
- ]
- });
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs b/chromium/chrome/browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs
deleted file mode 100644
index a0335ab2432..00000000000
--- a/chromium/chrome/browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs
+++ /dev/null
@@ -1,311 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Unit test for the Braille IME.
- */
-
-/**
- * Mock Chrome event supporting one listener.
- * @constructor
- */
-function MockEvent() {}
-
-MockEvent.prototype = {
- /** @type {Function?} */
- listener: null,
-
- /**
- * @param {Function} listener
- */
- addListener: function(listener) {
- assertTrue(this.listener === null);
- this.listener = listener;
- },
-
- /**
- * Dispatches an event to the listener if any.
- * @param {...*} var_args Arguments to pass to the event listener.
- * @return {*} Return value from listener or {@code undefined} if no
- * listener.
- */
- dispatch: function() {
- if (this.listener) {
- return this.listener.apply(null, arguments);
- }
- }
-};
-
-/**
- * Mock port that supports the {@code onMessage} and {@code onDisconnect}
- * events as well as {@code postMessage}.
- * @constructor.
- */
-function MockPort() {
- this.onMessage = new MockEvent();
- this.onDisconnect = new MockEvent();
- /** @type {Array<Object>} */
- this.messages = [];
-}
-
-MockPort.prototype = {
- /**
- * Stores {@code message} in this object.
- * @param {Object} message Message to store.
- */
- postMessage: function(message) {
- this.messages.push(message);
- }
-};
-
-/**
- * Engine ID as specified in manifest.
- * @const {string}
- */
-ENGINE_ID = 'braille';
-
-var localStorage;
-
-/**
- * Test fixture for the braille IME unit test.
- * @constructor
- * @extends {testing.Test}
- */
-function BrailleImeUnitTest() {
- testing.Test.call(this);
-}
-
-BrailleImeUnitTest.prototype = {
- __proto__: testing.Test.prototype,
-
- /** @Override */
- extraLibraries: [
- 'braille_ime.js'
- ],
-
- /** @Override */
- setUp: function() {
- chrome = chrome || {};
- chrome.input = chrome.input || {};
- chrome.input.ime = chrome.input.ime || {};
- chrome.runtime = chrome.runtime || {};
- localStorage = {};
- this.lastSentKeyRequestId_ = 0;
- this.lastHandledKeyRequestId_ = undefined;
- this.lastHandledKeyResult_ = undefined;
- chrome.input.ime.keyEventHandled = function(requestId, result) {
- this.lastHandledKeyRequestId_ = Number(requestId);
- this.lastHandledKeyResult_ = result;
- }.bind(this);
- this.createIme();
- },
-
- createIme: function() {
- var IME_EVENTS = [ 'onActivate', 'onDeactivated', 'onFocus', 'onBlur',
- 'onInputContextUpdate', 'onKeyEvent', 'onReset',
- 'onMenuItemActivated' ];
- for (var i = 0, name; name = IME_EVENTS[i]; ++i) {
- this[name] = chrome.input.ime[name] = new MockEvent();
-
- }
- chrome.input.ime.setMenuItems = function(parameters) {
- this.menuItems = parameters.items;
- }.bind(this);
- chrome.runtime.connect = function() {
- this.port = new MockPort();
- return this.port;
- }.bind(this);
- this.menuItems = null;
- this.port = null;
- this.ime = new BrailleIme();
- this.ime.init();
- },
-
- activateIme: function() {
- this.onActivate.dispatch(ENGINE_ID);
- assertThat(this.port.messages,
- eqJSON([{type: 'activeState', active: true}]));
- this.port.messages.length = 0;
- },
-
- sendKeyEvent_: function(type, code, extra) {
- var event = {type: type,
- code: code,
- requestId: (++this.lastSentKeyRequestId_) + ''};
- for (var key in extra) {
- event[key] = extra[key];
- }
- this.onKeyEvent.dispatch(ENGINE_ID, event);
- if (this.lastSentKeyRequestId_ === this.lastHandledKeyRequestId_) {
- return this.lastHandledKeyResult_;
- }
- },
-
- sendKeyDown: function(code, extra) {
- return this.sendKeyEvent_('keydown', code, extra);
- },
-
- sendKeyUp: function(code, extra) {
- return this.sendKeyEvent_('keyup', code, extra);
- },
-};
-
-TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeyboardDisabled', function() {
- this.activateIme();
- expectFalse(this.sendKeyDown('KeyF'));
- expectFalse(this.sendKeyDown('KeyD'));
- expectFalse(this.sendKeyUp('KeyD'));
- expectFalse(this.sendKeyUp('KeyF'));
- expectEquals(0, this.port.messages.length);
-});
-
-TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeysEnabled', function() {
- this.activateIme();
- assertFalse(this.menuItems[0].checked);
- this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
- assertTrue(this.menuItems[0].checked);
- // Type the letters 'b' and 'c' and verify the right dots get sent.
- expectTrue(this.sendKeyDown('KeyF'));
- expectTrue(this.sendKeyDown('KeyD'));
- expectTrue(this.sendKeyUp('KeyD'));
- expectTrue(this.sendKeyUp('KeyF'));
- expectTrue(this.sendKeyDown('KeyJ'));
- expectTrue(this.sendKeyDown('KeyF'));
- expectTrue(this.sendKeyUp('KeyJ'));
- expectTrue(this.sendKeyUp('KeyF'));
-
- // Make sure that other keys are not handled, either by themselves or while
- // one of the 'braille keys' is pressed.
- expectFalse(this.sendKeyDown('KeyX'));
- expectFalse(this.sendKeyUp('KeyX'));
-
- expectTrue(this.sendKeyDown('KeyS')); // Dot 3
- expectFalse(this.sendKeyDown('KeyG')); // To the right of dot 1.
- expectTrue(this.sendKeyUp('KeyS'));
- expectFalse(this.sendKeyUp('KeyG'));
-
- // Keys like Ctrl L should not be handled, despite L being a dot key.
- var ctrlFlag = {ctrlKey: true};
- expectFalse(this.sendKeyDown('ControlLeft', ctrlFlag));
- expectFalse(this.sendKeyDown('KeyL', ctrlFlag));
- expectFalse(this.sendKeyUp('KeyL', ctrlFlag));
- expectFalse(this.sendKeyUp('ControlLeft', ctrlFlag))
-
- // Space key by itself should send a blank cell.
- expectTrue(this.sendKeyDown('Space'));
- expectTrue(this.sendKeyUp('Space'));
-
- // Space and braille dots results in no event.
- expectTrue(this.sendKeyDown('Space'));
- expectTrue(this.sendKeyDown('KeyF'));
- expectTrue(this.sendKeyUp('Space'));
- expectTrue(this.sendKeyUp('KeyF'));
- // Send the braille key first, still no event should be produced.
- expectTrue(this.sendKeyDown('KeyF'));
- expectTrue(this.sendKeyDown('Space'));
- expectTrue(this.sendKeyUp('Space'));
- expectTrue(this.sendKeyUp('KeyF'));
-
- assertThat(this.port.messages,
- eqJSON([{type: 'brailleDots', dots: 0x03},
- {type: 'brailleDots', dots: 0x09},
- {type: 'brailleDots', dots: 0}]));
-});
-
-TEST_F('BrailleImeUnitTest', 'TestBackspaceKey', function() {
- this.activateIme();
- // Enable standard keyboard feature.
- assertFalse(this.menuItems[0].checked);
- this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
- assertTrue(this.menuItems[0].checked);
-
- expectEquals(undefined, this.sendKeyDown('Backspace'));
- assertThat(this.port.messages,
- eqJSON([{type: 'backspace',
- requestId: this.lastSentKeyRequestId_ + ''}]));
- this.port.onMessage.dispatch(
- {type: 'keyEventHandled',
- requestId: this.lastSentKeyRequestId_ + '',
- result: true});
- expectEquals(this.lastSentKeyRequestId_, this.lastHandledKeyRequestId_);
- expectTrue(this.lastHandledKeyResult_);
-});
-
-TEST_F('BrailleImeUnitTest', 'UseStandardKeyboardSettingPreserved', function() {
- this.activateIme();
- assertFalse(this.menuItems[0].checked);
- this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
- assertTrue(this.menuItems[0].checked);
- // Create a new instance and make sure the setting is still turned on.
- this.createIme();
- this.activateIme();
- assertTrue(this.menuItems[0].checked);
-});
-
-TEST_F('BrailleImeUnitTest', 'ReplaceText', function() {
- var CONTEXT_ID = 1;
- var hasSelection = false;
- var text = 'Hi, ';
- chrome.input.ime.commitText = function(params) {
- assertEquals(CONTEXT_ID, params.contextID);
- text += params.text;
- };
- chrome.input.ime.deleteSurroundingText = function(params, callback) {
- assertEquals(ENGINE_ID, params.engineID);
- assertEquals(CONTEXT_ID, params.contextID);
- assertEquals(0, params.offset + params.length);
- if (hasSelection) {
- assertEquals(0, params.length);
- hasSelection = false;
- } else {
- text = text.slice(0, params.offset);
- }
- callback();
- };
- var sendReplaceText = function(deleteBefore, newText) {
- this.port.onMessage.dispatch(
- {type: 'replaceText', contextID: CONTEXT_ID,
- deleteBefore: deleteBefore, newText: newText});
- }.bind(this);
- this.activateIme();
- sendReplaceText(0, 'hello!');
- assertEquals('Hi, hello!', text);
- hasSelection = true;
- sendReplaceText('hello!'.length, 'good bye!');
- assertFalse(hasSelection);
- assertEquals('Hi, good bye!', text);
-});
-
-TEST_F('BrailleImeUnitTest', 'Uncommitted', function() {
- var CONTEXT_ID = 1;
- var text = '';
- chrome.input.ime.commitText = function(params) {
- assertEquals(CONTEXT_ID, params.contextID);
- text += params.text;
- };
- var sendSetUncommitted = function(text) {
- this.port.onMessage.dispatch(
- {type: 'setUncommitted', contextID: CONTEXT_ID, text: text});
- }.bind(this);
- var sendCommitUncommitted = function(contextID) {
- this.port.onMessage.dispatch(
- {type: 'commitUncommitted', contextID: contextID});
- }.bind(this);
-
- this.activateIme();
- sendSetUncommitted('Hi');
- assertEquals('', text);
- sendSetUncommitted('Hello');
- sendCommitUncommitted(CONTEXT_ID);
- assertEquals('Hello', text);
- sendSetUncommitted(' there!');
- sendCommitUncommitted(CONTEXT_ID + 1);
- assertEquals('Hello', text);
-
- sendSetUncommitted(' you!');
- assertFalse(this.sendKeyDown('KeyY'));
- assertEquals('Hello you!', text);
- assertFalse(this.sendKeyUp('KeyY'));
- assertEquals('Hello you!', text);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/braille_ime/check_braille_ime.py b/chromium/chrome/browser/resources/chromeos/braille_ime/check_braille_ime.py
deleted file mode 100755
index a25cd199e0d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/braille_ime/check_braille_ime.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''Uses the closure compiler to check the braille ime.'''
-
-import os
-import sys
-
-
-_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-
-sys.path.insert(0, os.path.join(_SCRIPT_DIR, '..', 'chromevox', 'tools'))
-from jscompilerwrapper import RunCompiler
-
-
-_CHROME_SOURCE_DIR = os.path.normpath(
- os.path.join(_SCRIPT_DIR, *[os.path.pardir] * 5))
-
-
-def CheckBrailleIme():
- print 'Compiling braille IME.'
- js_files = [
- os.path.join(_SCRIPT_DIR, 'braille_ime.js'),
- os.path.join(_SCRIPT_DIR, 'main.js')]
- externs = [
- os.path.join(
- _CHROME_SOURCE_DIR,
- 'third_party/closure_compiler/externs/chrome_extensions.js'),
- os.path.join(_SCRIPT_DIR, 'externs.js')]
- return RunCompiler(js_files, externs)
-
-
-def main():
- success, output = CheckBrailleIme()
- if len(output) > 0:
- print output
- return int(not success)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/chromium/chrome/browser/resources/chromeos/braille_ime/externs.js b/chromium/chrome/browser/resources/chromeos/braille_ime/externs.js
deleted file mode 100644
index da4b07e871d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/braille_ime/externs.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Externs for the braille IME.
- * @externs
- */
-
-/**
- * @type {Storage}
- */
-var localStorage;
diff --git a/chromium/chrome/browser/resources/chromeos/braille_ime/main.js b/chromium/chrome/browser/resources/chromeos/braille_ime/main.js
deleted file mode 100644
index 603ee2810ed..00000000000
--- a/chromium/chrome/browser/resources/chromeos/braille_ime/main.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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.
-
-/**
- * The Braille IME object. Attached to the window object for ease of
- * debugging.
- * @type {BrailleIme}
- */
-window.ime = new BrailleIme();
-window.ime.init();
diff --git a/chromium/chrome/browser/resources/chromeos/browser_options.js b/chromium/chrome/browser/resources/chromeos/browser_options.js
deleted file mode 100644
index a79f9ffbed2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/browser_options.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- /** @const */ var Page = cr.ui.pageManager.Page;
-
- /**
- * Encapsulated handling of the BrowserOptions calls from
- * BluetoothOptionsHandler that is registered by the webUI,
- * ie, BluetoothPairingUI.
- * @constructor
- */
- function BrowserOptions() {
- Page.call(this, 'bluetooth', '', 'bluetooth-container');
- }
-
- cr.addSingletonGetter(BrowserOptions);
-
- BrowserOptions.prototype = {
- __proto__: Page.prototype,
- };
-
- BrowserOptions.showBluetoothSettings = function() {
- };
-
- BrowserOptions.setBluetoothState = function() {
- };
-
- /**
- * Handles addBluetoothDevice call, display the Bluetooth pairing overlay
- * for the pairing device.
- * @param {{name: string,
- * address: string,
- * paired: boolean,
- * pairing: string | undefined
- * pincode: string | undefined
- * passkey: number | undefined
- * connected: boolean}} device
- */
- BrowserOptions.addBluetoothDevice = function(device) {
- // One device can be in the process of pairing. If found, display
- // the Bluetooth pairing overlay.
- if (device.pairing)
- BluetoothPairing.showDialog(device);
- };
-
- BrowserOptions.removeBluetoothDevice = function(address) {
- };
-
- // Export
- return {
- BrowserOptions: BrowserOptions
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/certificate_manager_dialog.html b/chromium/chrome/browser/resources/chromeos/certificate_manager_dialog.html
deleted file mode 100644
index 4a366dbdeee..00000000000
--- a/chromium/chrome/browser/resources/chromeos/certificate_manager_dialog.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language;highlight:highlightStrength">
-<head>
-<meta charset="utf-8">
-<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
-<link rel="stylesheet" href="chrome://resources/css/list.css">
-<link rel="stylesheet" href="chrome://resources/css/overlay.css">
-<link rel="stylesheet" href="chrome://resources/css/tree.css">
-<link rel="stylesheet" href="chrome://resources/css/widgets.css">
-<link rel="stylesheet" href="../options/options_page.css">
-<link rel="stylesheet" href="../options/certificate_manager.css">
-<link rel="stylesheet" href="../options/alert_overlay.css">
-<link rel="stylesheet" href="../options/certificate_tree.css">
-<link rel="stylesheet" href="../options/subpages_tab_controls.css">
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/event_tracker.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/cr/ui.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/touch_handler.js"></script>
-<script src="chrome://resources/js/cr/ui/array_data_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script>
-<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_item.js"></script>
-<script src="chrome://resources/js/cr/ui/list.js"></script>
-<script src="chrome://resources/js/cr/ui/overlay.js"></script>
-<script src="chrome://resources/js/cr/ui/page_manager/page_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/page_manager/page.js"></script>
-<script src="chrome://resources/js/cr/ui/tree.js"></script>
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-
-<script src="../options/options_page.js"></script>
-<script src="../options/alert_overlay.js"></script>
-<script src="../options/certificate_tree.js"></script>
-<script src="../options/certificate_manager.js"></script>
-<script src="../options/certificate_restore_overlay.js"></script>
-<script src="../options/certificate_backup_overlay.js"></script>
-<script src="../options/certificate_edit_ca_trust_overlay.js"></script>
-<script src="../options/certificate_import_error_overlay.js"></script>
-<script src="keyboard/keyboard_utils.js"></script>
-<script src="../uber/uber_utils.js"></script>
-<script src="certificate_manager_dialog.js"></script>
-<script src="chrome://certificate-manager/strings.js"></script>
-</head>
-
-<body>
- <include src="../options/certificate_manager.html">
- <div id="overlay-container-2" class="overlay transparent" hidden>
- <include src="../options/alert_overlay.html">
- <include src="../options/certificate_restore_overlay.html">
- <include src="../options/certificate_backup_overlay.html">
- <include src="../options/certificate_edit_ca_trust_overlay.html">
- <include src="../options/certificate_import_error_overlay.html">
- </div>
- <div id="page-container" hidden></div>
-<script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/certificate_manager_dialog.js b/chromium/chrome/browser/resources/chromeos/certificate_manager_dialog.js
deleted file mode 100644
index ed35f86f49f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/certificate_manager_dialog.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.
-
-var AlertOverlay = options.AlertOverlay;
-var OptionsPage = options.OptionsPage;
-var PageManager = cr.ui.pageManager.PageManager;
-var CertificateManager = options.CertificateManager;
-var CertificateRestoreOverlay = options.CertificateRestoreOverlay;
-var CertificateBackupOverlay = options.CertificateBackupOverlay;
-var CertificateEditCaTrustOverlay = options.CertificateEditCaTrustOverlay;
-var CertificateImportErrorOverlay = options.CertificateImportErrorOverlay;
-
-/**
- * DOMContentLoaded handler, sets up the page.
- */
-function load() {
- if (cr.isChromeOS)
- document.documentElement.setAttribute('os', 'chromeos');
-
- // Setup tab change handers.
- var subpagesNavTabs = document.querySelectorAll('.subpages-nav-tabs');
- for (var i = 0; i < subpagesNavTabs.length; i++) {
- subpagesNavTabs[i].onclick = function(event) {
- OptionsPage.showTab(event.srcElement);
- };
- }
-
- // Shake the dialog if the user clicks outside the dialog bounds.
- var containers = [$('overlay-container-2')];
- for (var i = 0; i < containers.length; i++) {
- var overlay = containers[i];
- cr.ui.overlay.setupOverlay(overlay);
- overlay.addEventListener('cancelOverlay',
- PageManager.cancelOverlay.bind(PageManager));
- }
-
- // Hide elements that should not be part of the dialog.
- $('certificate-confirm').hidden = true;
- $('cert-manager-header').hidden = true;
-
- PageManager.isDialog = true;
- CertificateManager.getInstance().setIsKiosk(true);
- CertificateManager.getInstance().initializePage();
- PageManager.registerOverlay(AlertOverlay.getInstance(),
- CertificateManager.getInstance());
- PageManager.registerOverlay(CertificateBackupOverlay.getInstance(),
- CertificateManager.getInstance());
- PageManager.registerOverlay(CertificateEditCaTrustOverlay.getInstance(),
- CertificateManager.getInstance());
- PageManager.registerOverlay(CertificateImportErrorOverlay.getInstance(),
- CertificateManager.getInstance());
- PageManager.registerOverlay(CertificateManager.getInstance());
- PageManager.registerOverlay(CertificateRestoreOverlay.getInstance(),
- CertificateManager.getInstance());
-
- PageManager.showPageByName('certificates', false);
-}
-
-disableTextSelectAndDrag(function(e) {
- var src = e.target;
- return src instanceof HTMLTextAreaElement ||
- src instanceof HTMLInputElement &&
- /text|url/.test(src.type);
-});
-
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chromium/chrome/browser/resources/chromeos/choose_mobile_network.css b/chromium/chrome/browser/resources/chromeos/choose_mobile_network.css
deleted file mode 100644
index 6486685b0c7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/choose_mobile_network.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.scanning-msg {
- -webkit-margin-start: 50px;
-}
-
-.spinner {
- float: left;
- height: 18px;
- margin: 7px;
- width: 18px;
-}
-
-[dir='rtl'] .spinner {
- float: right;
-}
-
-.content-area {
- height: 120px;
- overflow: auto;
-}
-
-.disabled {
- opacity: 0.7;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/choose_mobile_network.html b/chromium/chrome/browser/resources/chromeos/choose_mobile_network.html
deleted file mode 100644
index 1d18a75b90f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/choose_mobile_network.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<meta charset="utf-8">
-<title i18n-content="title"></title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<link rel="stylesheet" href="chrome://resources/css/widgets.css">
-<link rel="stylesheet" href="chrome://resources/css/spinner.css">
-<link rel="stylesheet" href="mobile_dialogs.css">
-<link rel="stylesheet" href="choose_mobile_network.css">
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="chrome://choose-mobile-network/strings.js"></script>
-<script src="chrome://choose-mobile-network/choose_mobile_network.js"></script>
-</head>
-<body>
- <div id="container" class="container">
- <div id="choose-mobile-network" class="dialog">
- <h1 i18n-content="chooseNetworkTitle"></h1>
- <div id="scanning" class="content-area">
- <div id="spinner" class="spinner"></div>
- <div class="scanning-msg" i18n-content="scanningMsgLine1"></div>
- <div class="scanning-msg" i18n-content="scanningMsgLine2"></div>
- </div>
- <div id="choosing" class="content-area" hidden>
- </div>
- <div id="no-mobile-networks" class="content-area" hidden>
- <div class="scanning-msg" i18n-content="noMobileNetworks"></div>
- </div>
- <div class="action-area">
- <div class="action-area-right">
- <div class="button-strip">
- <button id="cancel" i18n-content="cancel"></button>
- <button id="connect" i18n-content="connect" ></button>
- </div>
- </div>
- </div>
- </div>
- </div>
- <script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/choose_mobile_network.js b/chromium/chrome/browser/resources/chromeos/choose_mobile_network.js
deleted file mode 100644
index 7181c07a6f4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/choose_mobile_network.js
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('mobile', function() {
-
- function ChooseNetwork() {
- }
-
- cr.addSingletonGetter(ChooseNetwork);
-
- ChooseNetwork.prototype = {
- networks_: [],
- showNetworks_: function(networks) {
- this.networks_ = networks;
-
- if (networks.length == 0) {
- $('scanning').hidden = true;
- $('choosing').hidden = true;
- $('no-mobile-networks').hidden = false;
- return;
- }
-
- var container = $('choosing');
- container.innerHTML = '';
- for (var i in networks) {
- var elem = document.createElement('div');
- elem.innerHTML =
- '<input type="radio" name="network" id="network' + i + '" />' +
- '<label for="network' + i + '" id="label' + i + '"></label>';
- container.appendChild(elem);
- $('label' + i).textContent = networks[i].operatorName;
- if (networks[i].status == 'current') {
- $('network' + i).checked = true;
- $('connect').disabled = false;
- } else if (networks[i].status == 'forbidden') {
- $('network' + i).disabled = true;
- elem.className = 'disabled';
- } else {
- $('network' + i).addEventListener('click', function(event) {
- $('connect').disabled = false;
- });
- }
- }
- $('scanning').hidden = true;
- $('choosing').hidden = false;
- $('no-mobile-networks').hidden = true;
- },
- connect_: function() {
- for (var i in this.networks_) {
- if ($('network' + i).checked) {
- chrome.send('connect', [this.networks_[i].networkId]);
- ChooseNetwork.close();
- return;
- }
- }
- },
- showScanning_: function() {
- $('scanning').hidden = false;
- $('choose').hidden = true;
- $('no-mobile-networks').hidden = true;
- }
- };
-
- ChooseNetwork.cancel = function() {
- chrome.send('cancel');
- ChooseNetwork.close();
- };
-
- ChooseNetwork.close = function() {
- window.close();
- };
-
- ChooseNetwork.connect = function() {
- ChooseNetwork.getInstance().connect_();
- };
-
- ChooseNetwork.showScanning = function() {
- ChooseNetwork.getInstance().showScanning_();
- };
-
- ChooseNetwork.initialize = function() {
- $('cancel').addEventListener('click', function(event) {
- ChooseNetwork.cancel();
- });
-
- $('connect').disabled = true;
- $('connect').addEventListener('click', function(event) {
- ChooseNetwork.connect();
- });
- chrome.send('pageReady');
- };
-
- ChooseNetwork.showNetworks = function(networks) {
- ChooseNetwork.getInstance().showNetworks_(networks);
- };
-
- // Export
- return {
- ChooseNetwork: ChooseNetwork
- };
-});
-
-var ChooseNetwork = mobile.ChooseNetwork;
-
-document.addEventListener('DOMContentLoaded', ChooseNetwork.initialize);
-
-disableTextSelectAndDrag();
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn b/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn
deleted file mode 100644
index 0416c6225e4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn
+++ /dev/null
@@ -1,389 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/features.gni")
-import("//testing/test.gni")
-import("//chrome/test/base/js2gtest.gni")
-import("chromevox.gni")
-
-assert(is_chromeos)
-
-declare_args() {
- # Whether to compress the main Chromevox javascript files or load the
- # modules individually from source files.
- chromevox_compress_js = !is_debug
-}
-
-chromevox_out_dir = "$root_out_dir/resources/chromeos/chromevox"
-
-group("chromevox") {
- deps = [
- "//chrome/browser/resources/chromeos/braille_ime:braille_ime_manifest",
- "//chrome/browser/resources/chromeos/chromevox/strings:chromevox_strings",
- "//chrome/third_party/chromevox:chromevox_third_party_resources",
- "//third_party/liblouis",
-
- #<(DEPTH)/third_party/liblouis/liblouis_nacl.gyp:liblouis_nacl_wrapper_nacl' # TODO(GYP)
- ":chromevox_copied_files",
- ":chromevox_manifest",
- ":chromevox_guest_manifest",
- ]
- if (chromevox_compress_js) {
- deps += [
- ":chromevox1_content_script",
- ":chromevox1_kbexplorer_script",
- ":chromevox1_options_script",
- ":chromevox2_background_script",
- ]
- } else {
- deps += [ ":chromevox_deps_js" ]
- }
-}
-
-template("run_jsbundler") {
- assert(defined(invoker.mode))
- assert(defined(invoker.sources))
- if (defined(invoker.modules)) {
- modules = invoker.modules
- } else {
- modules = []
- }
- if (defined(invoker.rewrite_rules)) {
- rewrite_rules = invoker.rewrite_rules
- } else {
- rewrite_rules = []
- }
- action(target_name) {
- script = "tools/jsbundler.py"
- inputs = jsbundler_modules
- sources = invoker.sources
- if (defined(invoker.output_file)) {
- if (defined(invoker.modules)) {
- depfile = "$target_out_dir/" +
- get_path_info(invoker.output_file, "name") + ".d"
- }
- outputs = [
- invoker.output_file,
- ]
- } else {
- assert(!defined(invoker.modules))
- stampfile = "$target_out_dir/${target_name}_copy.stamp"
- outputs = [
- stampfile,
- ]
- }
- args = [
- "-m",
- invoker.mode,
- ]
- if (defined(depfile)) {
- args += [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- ]
- }
- if (defined(stampfile)) {
- args += [
- "--stampfile",
- rebase_path(stampfile, root_build_dir),
- ]
- }
- if (defined(invoker.output_file)) {
- args += [
- "-o",
- rebase_path(invoker.output_file, root_build_dir),
- ]
- }
- if (defined(invoker.dest_dir)) {
- args += [
- "-d",
- rebase_path(invoker.dest_dir, root_build_dir),
- ]
- }
- foreach(module, modules) {
- args += [
- "-M",
- rebase_path(module, root_build_dir),
- ]
- }
- foreach(rule, rewrite_rules) {
- args += [
- "-w",
- rule,
- ]
- }
- args += rebase_path(sources, root_build_dir)
- }
-}
-
-chromevox_assets_gypi_values =
- exec_script("//build/gypi_to_gn.py",
- [ rebase_path("chromevox_assets.gypi") ],
- "scope",
- [ "chromevox_assets.gypi" ])
-
-chromevox_vars_gypi_values = exec_script("//build/gypi_to_gn.py",
- [ rebase_path("chromevox_vars.gypi") ],
- "scope",
- [ "chromevox_vars.gypi" ])
-
-# Instead of setting up one copy target for each subdirectory, use a script
-# to copy all files.
-run_jsbundler("chromevox_copied_files") {
- mode = "copy"
- dest_dir = chromevox_out_dir
- sources = chromevox_assets_gypi_values.chromevox_assets_chromevox
- sources +=
- chromevox_assets_gypi_values.chromevox_assets_chromevox_background_earcons
- sources +=
- chromevox_assets_gypi_values.chromevox_assets_chromevox_background_keymaps
- sources += chromevox_assets_gypi_values.chromevox_assets_chromevox_background_mathmaps_functions
- sources += chromevox_assets_gypi_values.chromevox_assets_chromevox_background_mathmaps_symbols
- sources +=
- chromevox_assets_gypi_values.chromevox_assets_cvox2_background_earcons
- sources += [
- "chromevox/background/background.html",
- "chromevox/background/kbexplorer.html",
- "chromevox/background/options.html",
- "chromevox/injected/api.js",
- "cvox2/background/background.html",
- ]
- if (chromevox_compress_js) {
- sources += [ "chromevox/injected/api_util.js" ]
- } else {
- sources += chromevox_modules
- sources += [
- "closure/closure_preinit.js",
- chromevox_vars_gypi_values.chromevox1_content_script_loader_file,
- chromevox_vars_gypi_values.chromevox1_kbexplorer_loader_file,
- chromevox_vars_gypi_values.chromevox1_options_script_loader_file,
- chromevox_vars_gypi_values.chromevox2_background_script_loader_file,
- ]
- }
- if (!chromevox_compress_js) {
- sources += closure_library_modules
- }
- rewrite_rules = [
- rebase_path(".", root_build_dir) + ":",
- rebase_path(closure_library_dir, root_build_dir) + ":closure",
- ]
-}
-
-template("manifest") {
- version_file = "//chrome/VERSION"
- version_script = "//build/util/version.py"
- template_file = "manifest.json.jinja2"
- output_file = invoker.output_file
- key = chromevox_vars_gypi_values.chromevox_extension_key
- action(target_name) {
- script = "tools/generate_manifest.py"
- inputs = [
- version_file,
- version_script,
- ]
- sources = [
- template_file,
- ]
- outputs = [
- output_file,
- ]
- args = [
- "--key=$key",
- "--version_file=" + rebase_path(version_file, root_build_dir),
- "--output_manifest=" + rebase_path(output_file, root_build_dir),
- ]
- if (defined(invoker.is_guest_manifest) && invoker.is_guest_manifest) {
- args += [ "--is_guest_manifest=1" ]
- }
- if (!chromevox_compress_js) {
- args += [ "--is_js_compressed=0" ]
- }
- args += rebase_path(sources, root_build_dir)
- }
-}
-
-manifest("chromevox_manifest") {
- output_file = "$chromevox_out_dir/manifest.json"
-}
-
-manifest("chromevox_guest_manifest") {
- output_file = "$chromevox_out_dir/manifest_guest.json"
- is_guest_manifest = true
-}
-
-template("generate_deps_js") {
- if (defined(invoker.rewrite_rules)) {
- rewrite_rules = invoker.rewrite_rules
- } else {
- rewrite_rules = []
- }
- action(target_name) {
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- script = "tools/generate_deps.py"
- inputs = jsbundler_modules
- sources = invoker.sources
- outputs = [
- invoker.output_file,
- ]
- args = [
- "-o",
- rebase_path(invoker.output_file, root_build_dir),
- ]
- foreach(rule, rewrite_rules) {
- args += [
- "-w",
- rule,
- ]
- }
- args += rebase_path(sources, root_build_dir)
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- }
-}
-
-if (chromevox_compress_js) {
- template("compress_js") {
- run_jsbundler(target_name) {
- assert(defined(invoker.output_file))
- mode = "compressed_bundle"
- modules = chromevox_modules + closure_library_modules
- sources = invoker.sources
- output_file = invoker.output_file
- }
- }
-
- compress_js("chromevox1_content_script") {
- sources = [
- chromevox_vars_gypi_values.chromevox1_content_script_loader_file,
- ]
- output_file = "$chromevox_out_dir/chromeVoxChromePageScript.js"
- }
-
- compress_js("chromevox1_kbexplorer_script") {
- sources = [
- chromevox_vars_gypi_values.chromevox1_kbexplorer_loader_file,
- ]
- output_file = "$chromevox_out_dir/chromeVoxKbExplorerScript.js"
- }
-
- compress_js("chromevox1_options_script") {
- sources = [
- chromevox_vars_gypi_values.chromevox1_options_script_loader_file,
- ]
- output_file = "$chromevox_out_dir/chromeVoxChromeOptionsScript.js"
- }
-
- compress_js("chromevox2_background_script") {
- sources = [
- chromevox_vars_gypi_values.chromevox2_background_script_loader_file,
- ]
- output_file = "$chromevox_out_dir/chromeVox2ChromeBackgroundScript.js"
- }
-} else {
- generate_deps_js("chromevox_deps_js") {
- sources = chromevox_modules + closure_library_modules
- output_file = "$chromevox_out_dir/deps.js"
- rewrite_rules = [
- rebase_path(".", root_build_dir) + ":..",
- rebase_path(closure_library_dir, root_build_dir) + ":../closure",
- ]
- }
-}
-
-chromevox_tests_gypi_values =
- exec_script("//build/gypi_to_gn.py",
- [ rebase_path("chromevox_tests.gypi") ],
- "scope",
- [ "chromevox_tests.gypi" ])
-
-test("chromevox_tests") {
- sources = chromevox_tests_gypi_values.chromevox_tests_sources
-
- deps = [
- "//base",
- "//base:i18n",
- "//base/test:test_support",
- "//chrome:browser_tests_pak",
- "//chrome:packed_extra_resources",
- "//chrome:packed_resources",
- "//chrome:resources",
- "//chrome:strings",
- "//chrome/browser",
- "//chrome/renderer",
- "//chrome/test:test_support",
- "//testing/gmock",
- "//testing/gtest",
- ":chromevox_extjs_tests",
- ":chromevox_unitjs_tests",
- ]
- if (cld_version == 0 || cld_version == 2) {
- # Because the browser_tests use translate, they need CLD data.
- deps += [ "//third_party/cld_2:cld2_platform_impl" ]
- }
-}
-
-action("chromevox_test_messages_js") {
- script = "tools/generate_test_messages.py"
- sources = [
- "$chromevox_out_dir/_locales/en/messages.json",
- ]
- output_file = "$root_out_dir/test_data/chrome/browser/resources/chromeos/chromevox/host/testing/test_messages.js"
- outputs = [
- output_file,
- ]
- deps = [
- "strings:chromevox_strings",
- ]
- args = [
- "-o",
- rebase_path(output_file, root_build_dir),
- ] + rebase_path(sources, root_build_dir)
-}
-
-chromevox_test_modules = [
- "host/testing/earcons.js",
- "host/testing/host.js",
- "host/testing/mathjax.js",
- "host/testing/tts.js",
- "testing/spoken_list_builder.js",
- "testing/test_msgs.js",
- "testing/tester.js",
- ] + get_target_outputs(":chromevox_test_messages_js")
-
-generate_deps_js("chromevox_test_deps_js") {
- sources = closure_library_modules + chromevox_modules + chromevox_test_modules
- output_file = "$target_gen_dir/test_deps.js"
- rewrite_rules = [
- rebase_path("//", root_build_dir) + ":",
- rebase_path("$root_out_dir/test_data", root_build_dir) + ":",
- ]
- deps = [
- ":chromevox_test_messages_js",
- ]
-}
-
-js2gtest("chromevox_unitjs_tests") {
- test_type = "webui"
- sources = chromevox_tests_gypi_values.chromevox_tests_unitjs_sources
- gen_include_files =
- chromevox_tests_gypi_values.chromevox_tests_unit_gen_include_sources
- test_deps_js_outputs = get_target_outputs(":chromevox_test_deps_js")
- deps_js = test_deps_js_outputs[0]
- deps = [
- ":chromevox_test_deps_js",
- ]
- defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
-}
-
-js2gtest("chromevox_extjs_tests") {
- test_type = "extension"
- sources = chromevox_tests_gypi_values.chromevox_tests_extjs_sources
- sources -= [ "braille/liblouis_test.extjs" ] # TODO(GYP)
- gen_include_files =
- chromevox_tests_gypi_values.chromevox_tests_ext_gen_include_sources
- defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
-}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/OWNERS b/chromium/chrome/browser/resources/chromeos/chromevox/OWNERS
deleted file mode 100644
index dfab84a0164..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-aboxhall@chromium.org
-dmazzoni@chromium.org
-dtseng@chromium.org
-plundblad@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/PRESUBMIT.py b/chromium/chrome/browser/resources/chromeos/chromevox/PRESUBMIT.py
deleted file mode 100644
index b87797c1b34..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/PRESUBMIT.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# 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.
-
-"""Presubmit script for ChromeVox."""
-
-def CheckChangeOnUpload(input_api, output_api):
- paths = input_api.AbsoluteLocalPaths()
-
- def ShouldCheckFile(path):
- return path.endswith('.js') or path.endswith('.py')
-
- def ScriptFilter(path):
- return (path.endswith('check_chromevox.py') or
- path.endswith('jscompilerwrapper.py') or
- path.endswith('jsbundler.py'))
-
- # Only care about changes to JS files or the scripts that check them.
- paths = [p for p in paths if ShouldCheckFile(p)]
- if not paths:
- return []
-
- # If changing what the presubmit script uses, run the check on all
- # scripts. Otherwise, let CheckChromeVox figure out what scripts to
- # compile, if any, based on the changed paths.
- if any((ScriptFilter(p) for p in paths)):
- paths = None
-
- import sys
- if not sys.platform.startswith('linux'):
- return []
- sys.path.insert(0, input_api.os_path.join(
- input_api.PresubmitLocalPath(), 'tools'))
- try:
- from check_chromevox import CheckChromeVox
- finally:
- sys.path.pop(0)
- success, output = CheckChromeVox(paths)
- if not success:
- return [output_api.PresubmitError(
- 'ChromeVox closure compilation failed',
- long_text=output)]
- return []
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js
deleted file mode 100644
index 1f09ad4083e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js
+++ /dev/null
@@ -1,395 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Puts text on a braille display.
- *
- */
-
-goog.provide('cvox.BrailleDisplayManager');
-
-goog.require('cvox.BrailleCaptionsBackground');
-goog.require('cvox.BrailleDisplayState');
-goog.require('cvox.ExpandingBrailleTranslator');
-goog.require('cvox.LibLouis');
-goog.require('cvox.NavBraille');
-goog.require('cvox.PanStrategy');
-
-
-/**
- * @param {!cvox.BrailleTranslatorManager} translatorManager Keeps track
- * of the current translator to use.
- * @constructor
- */
-cvox.BrailleDisplayManager = function(translatorManager) {
- /**
- * @type {!cvox.BrailleTranslatorManager}
- * @private
- */
- this.translatorManager_ = translatorManager;
- /**
- * @type {!cvox.NavBraille}
- * @private
- */
- this.content_ = new cvox.NavBraille({});
- /**
- * @type {!cvox.ExpandingBrailleTranslator.ExpansionType} valueExpansion
- * @private
- */
- this.expansionType_ =
- cvox.ExpandingBrailleTranslator.ExpansionType.SELECTION;
- /**
- * @type {!ArrayBuffer}
- * @private
- */
- this.translatedContent_ = new ArrayBuffer(0);
- /**
- * @type {!ArrayBuffer}
- * @private
- */
- this.displayedContent_ = this.translatedContent_;
- /**
- * @type {cvox.PanStrategy}
- * @private
- */
- this.panStrategy_ = new cvox.WrappingPanStrategy();
- /**
- * @type {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)}
- * @private
- */
- this.commandListener_ = function() {};
- /**
- * Current display state used for width calculations. This is different from
- * realDisplayState_ if the braille captions feature is enabled and there is
- * no hardware display connected. Otherwise, it is the same object
- * as realDisplayState_.
- * @type {!cvox.BrailleDisplayState}
- * @private
- */
- this.displayState_ = {available: false, textCellCount: undefined};
- /**
- * State reported from the chrome api, reflecting a real hardware
- * display.
- * @type {!cvox.BrailleDisplayState}
- * @private
- */
- this.realDisplayState_ = this.displayState_;
- /**
- * @type {!Array<number>}
- * @private
- */
- this.textToBraille_ = [];
- /**
- * @type {!Array<number>}
- * @private
- */
- this.brailleToText_ = [];
-
- translatorManager.addChangeListener(function() {
- this.translateContent_(this.content_, this.expansionType_);
- }.bind(this));
-
- chrome.storage.onChanged.addListener(function(changes, area) {
- if (area == 'local' && 'brailleWordWrap' in changes) {
- this.updatePanStrategy_(changes.brailleWordWrap.newValue);
- }
- }.bind(this));
- chrome.storage.local.get({brailleWordWrap: true}, function(items) {
- this.updatePanStrategy_(items.brailleWordWrap);
- }.bind(this));
-
- cvox.BrailleCaptionsBackground.init(goog.bind(
- this.onCaptionsStateChanged_, this));
- if (goog.isDef(chrome.brailleDisplayPrivate)) {
- var onDisplayStateChanged = goog.bind(this.refreshDisplayState_, this);
- chrome.brailleDisplayPrivate.getDisplayState(onDisplayStateChanged);
- chrome.brailleDisplayPrivate.onDisplayStateChanged.addListener(
- onDisplayStateChanged);
- chrome.brailleDisplayPrivate.onKeyEvent.addListener(
- goog.bind(this.onKeyEvent_, this));
- } else {
- // Get the initial captions state since we won't refresh the display
- // state in an API callback in this case.
- this.onCaptionsStateChanged_();
- }
-};
-
-
-/**
- * Dots representing a cursor.
- * @const
- * @private
- */
-cvox.BrailleDisplayManager.CURSOR_DOTS_ = 1 << 6 | 1 << 7;
-
-
-/**
- * @param {!cvox.NavBraille} content Content to send to the braille display.
- * @param {!cvox.ExpandingBrailleTranslator.ExpansionType} expansionType
- * If the text has a {@code ValueSpan}, this indicates how that part
- * of the display content is expanded when translating to braille.
- * (See {@code cvox.ExpandingBrailleTranslator}).
- */
-cvox.BrailleDisplayManager.prototype.setContent = function(
- content, expansionType) {
- this.translateContent_(content, expansionType);
-};
-
-
-/**
- * Sets the command listener. When a command is invoked, the listener will be
- * called with the BrailleKeyEvent corresponding to the command and the content
- * that was present on the display when the command was invoked. The content
- * is guaranteed to be identical to an object previously used as the parameter
- * to cvox.BrailleDisplayManager.setContent, or null if no content was set.
- * @param {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} func The listener.
- */
-cvox.BrailleDisplayManager.prototype.setCommandListener = function(func) {
- this.commandListener_ = func;
-};
-
-
-/**
- * @param {!cvox.BrailleDisplayState} newState Display state reported
- * by the extension API.
- * @private
- */
-cvox.BrailleDisplayManager.prototype.refreshDisplayState_ = function(
- newState) {
- var oldSize = this.displayState_.textCellCount || 0;
- this.realDisplayState_ = newState;
- if (newState.available) {
- this.displayState_ = newState;
- } else {
- this.displayState_ =
- cvox.BrailleCaptionsBackground.getVirtualDisplayState();
- }
- var newSize = this.displayState_.textCellCount || 0;
- if (oldSize != newSize) {
- this.panStrategy_.setDisplaySize(newSize);
- }
- this.refresh_();
-};
-
-
-/**
- * Called when the state of braille captions changes.
- * @private
- */
-cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() {
- // Force reevaluation of the display state based on our stored real
- // hardware display state, meaning that if a real display is connected,
- // that takes precedence over the state from the captions 'virtual' display.
- this.refreshDisplayState_(this.realDisplayState_);
-};
-
-
-/** @private */
-cvox.BrailleDisplayManager.prototype.refresh_ = function() {
- if (!this.displayState_.available) {
- return;
- }
- var viewPort = this.panStrategy_.viewPort;
- var buf = this.displayedContent_.slice(viewPort.start, viewPort.end);
- if (this.realDisplayState_.available) {
- chrome.brailleDisplayPrivate.writeDots(buf);
- }
- if (cvox.BrailleCaptionsBackground.isEnabled()) {
- var start = this.brailleToTextPosition_(viewPort.start);
- var end = this.brailleToTextPosition_(viewPort.end);
- cvox.BrailleCaptionsBackground.setContent(
- this.content_.text.toString().substring(start, end), buf);
- }
-};
-
-
-/**
- * @param {!cvox.NavBraille} newContent New display content.
- * @param {cvox.ExpandingBrailleTranslator.ExpansionType} newExpansionType
- * How the value part of of the new content should be expanded
- * with regards to contractions.
- * @private
- */
-cvox.BrailleDisplayManager.prototype.translateContent_ = function(
- newContent, newExpansionType) {
- var writeTranslatedContent = function(cells, textToBraille, brailleToText) {
- this.content_ = newContent;
- this.expansionType_ = newExpansionType;
- this.textToBraille_ = textToBraille;
- this.brailleToText_ = brailleToText;
- var startIndex = this.content_.startIndex;
- var endIndex = this.content_.endIndex;
- var targetPosition;
- if (startIndex >= 0) {
- var translatedStartIndex;
- var translatedEndIndex;
- if (startIndex >= textToBraille.length) {
- // Allow the cells to be extended with one extra cell for
- // a carret after the last character.
- var extCells = new ArrayBuffer(cells.byteLength + 1);
- new Uint8Array(extCells).set(new Uint8Array(cells));
- // Last byte is initialized to 0.
- cells = extCells;
- translatedStartIndex = cells.byteLength - 1;
- } else {
- translatedStartIndex = textToBraille[startIndex];
- }
- if (endIndex >= textToBraille.length) {
- // endIndex can't be past-the-end of the last cell unless
- // startIndex is too, so we don't have to do another
- // extension here.
- translatedEndIndex = cells.byteLength;
- } else {
- translatedEndIndex = textToBraille[endIndex];
- }
- this.translatedContent_ = cells;
- // Copy the transalted content to a separate buffer and add the cursor
- // to it.
- this.displayedContent_ = new ArrayBuffer(cells.byteLength);
- new Uint8Array(this.displayedContent_).set(new Uint8Array(cells));
- this.writeCursor_(this.displayedContent_,
- translatedStartIndex, translatedEndIndex);
- targetPosition = translatedStartIndex;
- } else {
- this.translatedContent_ = this.displayedContent_ = cells;
- targetPosition = 0;
- }
- this.panStrategy_.setContent(this.translatedContent_, targetPosition);
- this.refresh_();
- }.bind(this);
-
- var translator = this.translatorManager_.getExpandingTranslator();
- if (!translator) {
- writeTranslatedContent(new ArrayBuffer(0), [], []);
- } else {
- translator.translate(
- newContent.text,
- newExpansionType,
- writeTranslatedContent);
- }
-};
-
-
-/**
- * @param {cvox.BrailleKeyEvent} event The key event.
- * @private
- */
-cvox.BrailleDisplayManager.prototype.onKeyEvent_ = function(event) {
- switch (event.command) {
- case cvox.BrailleKeyCommand.PAN_LEFT:
- this.panLeft_();
- break;
- case cvox.BrailleKeyCommand.PAN_RIGHT:
- this.panRight_();
- break;
- case cvox.BrailleKeyCommand.ROUTING:
- event.displayPosition = this.brailleToTextPosition_(
- event.displayPosition + this.panStrategy_.viewPort.start);
- // fall through
- default:
- this.commandListener_(event, this.content_);
- break;
- }
-};
-
-
-/**
- * Shift the display by one full display size and refresh the content.
- * Sends the appropriate command if the display is already at the leftmost
- * position.
- * @private
- */
-cvox.BrailleDisplayManager.prototype.panLeft_ = function() {
- if (this.panStrategy_.previous()) {
- this.refresh_();
- } else {
- this.commandListener_({
- command: cvox.BrailleKeyCommand.PAN_LEFT
- }, this.content_);
- }
-};
-
-
-/**
- * Shifts the display position to the right by one full display size and
- * refreshes the content. Sends the appropriate command if the display is
- * already at its rightmost position.
- * @private
- */
-cvox.BrailleDisplayManager.prototype.panRight_ = function() {
- if (this.panStrategy_.next()) {
- this.refresh_();
- } else {
- this.commandListener_({
- command: cvox.BrailleKeyCommand.PAN_RIGHT
- }, this.content_);
- }
-};
-
-
-/**
- * Writes a cursor in the specified range into translated content.
- * @param {ArrayBuffer} buffer Buffer to add cursor to.
- * @param {number} startIndex The start index to place the cursor.
- * @param {number} endIndex The end index to place the cursor (exclusive).
- * @private
- */
-cvox.BrailleDisplayManager.prototype.writeCursor_ = function(
- buffer, startIndex, endIndex) {
- if (startIndex < 0 || startIndex >= buffer.byteLength ||
- endIndex < startIndex || endIndex > buffer.byteLength) {
- return;
- }
- if (startIndex == endIndex) {
- endIndex = startIndex + 1;
- }
- var dataView = new DataView(buffer);
- while (startIndex < endIndex) {
- var value = dataView.getUint8(startIndex);
- value |= cvox.BrailleDisplayManager.CURSOR_DOTS_;
- dataView.setUint8(startIndex, value);
- startIndex++;
- }
-};
-
-
-/**
- * Returns the text position corresponding to an absolute braille position,
- * that is not accounting for the current pan position.
- * @private
- * @param {number} braillePosition Braille position relative to the startof
- * the translated content.
- * @return {number} The mapped position in code units.
- */
-cvox.BrailleDisplayManager.prototype.brailleToTextPosition_ =
- function(braillePosition) {
- var mapping = this.brailleToText_;
- if (braillePosition < 0) {
- // This shouldn't happen.
- console.error('WARNING: Braille position < 0: ' + braillePosition);
- return 0;
- } else if (braillePosition >= mapping.length) {
- // This happens when the user clicks on the right part of the display
- // when it is not entirely filled with content. Allow addressing the
- // position after the last character.
- return this.content_.text.getLength();
- } else {
- return mapping[braillePosition];
- }
-};
-
-
-/**
- * @param {boolean} wordWrap
- * @private
- */
-cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) {
- var newStrategy = wordWrap ? new cvox.WrappingPanStrategy() :
- new cvox.FixedPanStrategy();
- newStrategy.setDisplaySize(this.displayState_.textCellCount || 0);
- newStrategy.setContent(this.translatedContent_,
- this.panStrategy_.viewPort.start);
- this.panStrategy_ = newStrategy;
- this.refresh_();
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager_test.unitjs
deleted file mode 100644
index db4b37fed45..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager_test.unitjs
+++ /dev/null
@@ -1,257 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js',
- '../testing/fake_objects.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxBrailleDisplayManagerUnitTest() {}
-
-CvoxBrailleDisplayManagerUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.BrailleDisplayManager',
- 'cvox.BrailleInterface',
- 'cvox.LibLouis',
- 'cvox.NavBraille',
- ],
-
- /** @override */
- setUp: function() {
- /** @const */
- this.NAV_BRAILLE = new cvox.NavBraille({ text: 'Hello, world!' });
- this.EMPTY_NAV_BRAILLE = new cvox.NavBraille({ text: '' });
- this.translator = new FakeTranslator();
- this.translatorManager = new FakeTranslatorManager();
- /** @const */
- this.DISPLAY_SIZE = 12;
- },
-
- addFakeApi: function() {
- chrome.brailleDisplayPrivate = {};
- chrome.brailleDisplayPrivate.getDisplayState = function(callback) {
- callback(this.displayState);
- }.bind(this);
- this.writtenCells = [];
- chrome.brailleDisplayPrivate.writeDots = function(cells) {
- this.writtenCells.push(cells);
- }.bind(this);
- chrome.brailleDisplayPrivate.onDisplayStateChanged = new FakeChromeEvent();
- chrome.brailleDisplayPrivate.onKeyEvent = new FakeChromeEvent();
- },
-
- displayAvailable: function() {
- this.displayState = {available: true, textCellCount: this.DISPLAY_SIZE};
- },
-
- /**
- * Asserts display pan position and selection markers on the last written
- * display content and clears it. There must be exactly one
- * set of cells written.
- * @param {number} start expected pan position
- * @param {number=} opt_selStart first cell (relative to buffer start that
- * should have a selection
- * @param {number=} opt_selEnd last cell that should have a selection.
- */
- assertDisplayPositionAndClear: function(start, opt_selStart, opt_selEnd) {
- if (opt_selStart !== undefined && opt_selEnd === undefined) {
- opt_selEnd = opt_selStart + 1;
- }
- assertEquals(1, this.writtenCells.length);
- var a = new Uint8Array(this.writtenCells[0]);
- this.writtenCells.length = 0;
- var firstCell = a[0] & ~cvox.BrailleDisplayManager.CURSOR_DOTS_;
- assertEquals(start, firstCell,
- 'Start mismatch: ' + start + ' vs. ' + firstCell);
- if (opt_selStart !== undefined) {
- for (var i = opt_selStart; i < opt_selEnd; ++i) {
- assertEquals(cvox.BrailleDisplayManager.CURSOR_DOTS_,
- a[i] & cvox.BrailleDisplayManager.CURSOR_DOTS_,
- 'Missing cursor marker at position ' + i);
- }
- }
- },
-
- /**
- * Asserts that the last written display content is an empty buffer of
- * of cells and clears the list of written cells.
- * There must be only one buffer in the list.
- */
- assertEmptyDisplayAndClear: function() {
- assertEquals(1, this.writtenCells.length);
- var content = this.writtenCells[0];
- this.writtenCells.length = 0;
- assertTrue(content instanceof ArrayBuffer);
- assertTrue(content.byteLength == 0);
- }
-};
-
-/** @extends {cvox.ExpandingBrailleTranslator} */
-function FakeTranslator() {
-}
-
-FakeTranslator.prototype = {
- /**
- * Does a translation where every other character becomes two cells.
- * @override
- */
- translate: function(spannable, expansionType, callback) {
- text = spannable.toString();
- var buf = new Uint8Array(text.length + text.length / 2);
- var textToBraille = [];
- var brailleToText = [];
- var idx = 0;
- for (var i = 0; i < text.length; ++i) {
- textToBraille.push(idx);
- brailleToText.push(i);
- buf[idx] = idx;
- idx++;
- if ((i % 2) == 1) {
- buf[idx] = idx;
- idx++;
- brailleToText.push(i);
- }
- }
- callback(buf.buffer, textToBraille, brailleToText);
- }
-};
-
-/** @extends {cvox.BrailleTranslatorManager} */
-function FakeTranslatorManager() {
-}
-
-FakeTranslatorManager.prototype = {
- changeListener: null,
- translator: null,
-
- setTranslator: function(translator) {
- this.translator = translator;
- if (this.changeListener) {
- this.changeListener();
- }
- },
-
- addChangeListener: function(listener) {
- assertEquals(null, this.changeListener);
- this.changeListener = listener;
- },
-
- getExpandingTranslator: function() {
- return this.translator;
- }
-};
-
-var chrome = {};
-
-// Fake chrome.storage API.
-chrome.storage = {
- onChanged: new FakeChromeEvent(),
-
- local: {
- get: function(object, callback) {
- callback({brailleWordWrap: false});
- }
- }
-};
-
-
-TEST_F('CvoxBrailleDisplayManagerUnitTest', 'NoApi', function() {
- var manager = new cvox.BrailleDisplayManager(this.translatorManager);
- manager.setContent(this.NAV_BRAILLE);
- this.translatorManager.setTranslator(this.translator);
- manager.setContent(this.NAV_BRAILLE);
-});
-
-/**
- * Test that we don't write to the display when the API is available, but
- * the display is not.
- */
-TEST_F('CvoxBrailleDisplayManagerUnitTest', 'NoDisplay', function() {
- this.addFakeApi();
- this.displayState = {available: false};
-
- var manager = new cvox.BrailleDisplayManager(this.translatorManager);
- manager.setContent(this.NAV_BRAILLE);
- this.translatorManager.setTranslator(this.translator);
- manager.setContent(this.NAV_BRAILLE);
- assertEquals(0, this.writtenCells.length);
-});
-
-
-/**
- * Tests the typical sequence: setContent, setTranslator, setContent.
- */
-TEST_F('CvoxBrailleDisplayManagerUnitTest', 'BasicSetContent', function() {
- this.addFakeApi();
- this.displayAvailable();
- var manager = new cvox.BrailleDisplayManager(this.translatorManager);
- this.assertEmptyDisplayAndClear();
- manager.setContent(this.NAV_BRAILLE);
- this.assertEmptyDisplayAndClear();
- this.translatorManager.setTranslator(this.translator);
- this.assertDisplayPositionAndClear(0);
- manager.setContent(this.NAV_BRAILLE);
- this.assertDisplayPositionAndClear(0);
-});
-
-
-/**
- * Tests that setting empty content clears the display.
- */
-TEST_F('CvoxBrailleDisplayManagerUnitTest', 'SetEmptyContentWithTranslator',
- function() {
- this.addFakeApi();
- this.displayAvailable();
-
- var manager = new cvox.BrailleDisplayManager(this.translatorManager);
- this.assertEmptyDisplayAndClear();
- manager.setContent(this.NAV_BRAILLE);
- this.assertEmptyDisplayAndClear();
- this.translatorManager.setTranslator(this.translator);
- this.assertDisplayPositionAndClear(0);
- manager.setContent(this.EMPTY_NAV_BRAILLE);
- this.assertEmptyDisplayAndClear();
-});
-
-
-TEST_F('CvoxBrailleDisplayManagerUnitTest', 'CursorAndPanning', function() {
- var text = 'This is a test string';
- function createNavBrailleWithCursor(start, end) {
- return new cvox.NavBraille({ text: text, startIndex: start,
- endIndex: end});
- }
-
- var translatedSize = Math.floor(text.length + text.length / 2);
-
- this.addFakeApi();
- this.displayAvailable();
-
- var manager = new cvox.BrailleDisplayManager(this.translatorManager);
- this.assertEmptyDisplayAndClear();
- this.translatorManager.setTranslator(this.translator);
- this.assertEmptyDisplayAndClear();
-
- // Cursor at beginning of line.
- manager.setContent(createNavBrailleWithCursor(0, 0));
- this.assertDisplayPositionAndClear(0, 0);
- // Cursor at end of line.
- manager.setContent(createNavBrailleWithCursor(text.length, text.length));
- this.assertDisplayPositionAndClear(
- 2 * this.DISPLAY_SIZE,
- translatedSize % this.DISPLAY_SIZE);
- // Selection from the end of what fits on the first display to the end of the
- // line.
- manager.setContent(createNavBrailleWithCursor(7, text.length));
- this.assertDisplayPositionAndClear(0, 10, this.DISPLAY_SIZE);
- // Selection on all of the line.
- manager.setContent(createNavBrailleWithCursor(0, text.length));
- this.assertDisplayPositionAndClear(0, 0, this.DISPLAY_SIZE);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js
deleted file mode 100644
index 5dc4c9a0ed9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js
+++ /dev/null
@@ -1,692 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Handles braille input keys when the user is typing or editing
- * text in an input field. This class cooperates with the Braille IME
- * that is built into Chrome OS to do the actual text editing.
- */
-
-goog.provide('cvox.BrailleInputHandler');
-
-goog.require('StringUtil');
-goog.require('cvox.BrailleKeyCommand');
-goog.require('cvox.BrailleKeyEvent');
-goog.require('cvox.ExpandingBrailleTranslator');
-
-/**
- * @param {!cvox.BrailleTranslatorManager} translatorManager Keeps track of
- * the current braille translator(s).
- * @constructor
- */
-cvox.BrailleInputHandler = function(translatorManager) {
- /**
- * Port of the connected IME if any.
- * @type {Port}
- * @private
- */
- this.imePort_ = null;
- /**
- * {code true} when the Braille IME is connected and has signaled that it is
- * active.
- * @type {boolean}
- * @private
- */
- this.imeActive_ = false;
- /**
- * The input context of the current input field, as reported by the IME.
- * {@code null} if no input field has focus.
- * @type {{contextID: number, type: string}?}
- * @private
- */
- this.inputContext_ = null;
- /**
- * @type {!cvox.BrailleTranslatorManager}
- * @private
- */
- this.translatorManager_ = translatorManager;
- /**
- * Text that currently precedes the first selection end-point.
- * @type {string}
- * @private
- */
- this.currentTextBefore_ = '';
- /**
- * Text that currently follows the last selection end-point.
- * @type {string}
- * @private
- */
- this.currentTextAfter_ = '';
- /**
- * Cells that were entered while the IME wasn't active. These will be
- * submitted once the IME becomes active and reports the current input field.
- * This is necessary because the IME is activated on the first braille
- * dots command, but we'll receive the command in parallel. To work around
- * the race, we store the cell entered until we can submit it to the IME.
- * @type {!Array<number>}
- * @private
- */
- this.pendingCells_ = [];
- /**
- * @type {cvox.BrailleInputHandler.EntryState_}
- * @private
- */
- this.entryState_ = null;
- /**
- * @type {cvox.ExtraCellsSpan}
- * @private
- */
- this.uncommittedCellsSpan_ = null;
- /**
- * @type {function()?}
- * @private
- */
- this.uncommittedCellsChangedListener_ = null;
-
- this.translatorManager_.addChangeListener(
- this.commitAndClearEntryState_.bind(this));
-};
-
-/**
- * The ID of the Braille IME extension built into Chrome OS.
- * @const {string}
- * @private
- */
-cvox.BrailleInputHandler.IME_EXTENSION_ID_ =
- 'jddehjeebkoimngcbdkaahpobgicbffp';
-
-/**
- * Name of the port to use for communicating with the Braille IME.
- * @const {string}
- * @private
- */
-cvox.BrailleInputHandler.IME_PORT_NAME_ = 'cvox.BrailleIme.Port';
-
-/**
- * Regular expression that matches a string that starts with at least one
- * non-whitespace character.
- * @const {RegExp}
- * @private
- */
-cvox.BrailleInputHandler.STARTS_WITH_NON_WHITESPACE_RE_ = /^\S/;
-
-/**
- * Regular expression that matches a string that ends with at least one
- * non-whitespace character.
- * @const {RegExp}
- * @private
- */
-cvox.BrailleInputHandler.ENDS_WITH_NON_WHITESPACE_RE_ = /\S$/;
-
-cvox.BrailleInputHandler.prototype = {
- /**
- * Starts to listen for connections from the Chrome OS braille IME.
- */
- init: function() {
- chrome.runtime.onConnectExternal.addListener(this.onImeConnect_.bind(this));
- },
-
- /**
- * Called when the content on the braille display is updated. Modifies the
- * input state according to the new content.
- * @param {cvox.Spannable} text Text, optionally with value and selection
- * spans.
- * @param {function()} listener Called when the uncommitted cells
- * have changed.
- */
- onDisplayContentChanged: function(text, listener) {
- var valueSpan = text.getSpanInstanceOf(cvox.ValueSpan);
- var selectionSpan = text.getSpanInstanceOf(cvox.ValueSelectionSpan);
- if (!(valueSpan && selectionSpan))
- return;
- // Don't call the old listener any further, since new content is being
- // set. If the old listener is not cleared here, it could be called
- // spuriously if the entry state is cleared below.
- this.uncommittedCellsChangedListener_ = null;
- // The type casts are ok because the spans are known to exist.
- var valueStart = /** @type {number} */ (text.getSpanStart(valueSpan));
- var valueEnd = /** @type {number} */ (text.getSpanEnd(valueSpan));
- var selectionStart =
- /** @type {number} */ (text.getSpanStart(selectionSpan));
- var selectionEnd = /** @type {number} */ (text.getSpanEnd(selectionSpan));
- if (selectionStart < valueStart || selectionEnd > valueEnd) {
- console.error('Selection outside of value in braille content');
- this.clearEntryState_();
- return;
- }
- var newTextBefore = text.toString().substring(valueStart, selectionStart);
- if (this.currentTextBefore_ !== newTextBefore && this.entryState_)
- this.entryState_.onTextBeforeChanged(newTextBefore);
- this.currentTextBefore_ = newTextBefore;
- this.currentTextAfter_ = text.toString().substring(selectionEnd, valueEnd);
- this.uncommittedCellsSpan_ = new cvox.ExtraCellsSpan();
- text.setSpan(this.uncommittedCellsSpan_, selectionStart, selectionStart);
- if (this.entryState_ && this.entryState_.usesUncommittedCells) {
- this.updateUncommittedCells_(
- new Uint8Array(this.entryState_.cells_).buffer);
- }
- this.uncommittedCellsChangedListener_ = listener;
- },
-
- /**
- * Handles braille key events used for input by editing the current input
- * field appropriately.
- * @param {!cvox.BrailleKeyEvent} event The key event.
- * @return {boolean} {@code true} if the event was handled, {@code false}
- * if it should propagate further.
- */
- onBrailleKeyEvent: function(event) {
- if (event.command === cvox.BrailleKeyCommand.DOTS)
- return this.onBrailleDots_(/** @type {number} */(event.brailleDots));
- // Any other braille command cancels the pending cells.
- this.pendingCells_.length = 0;
- if (event.command === cvox.BrailleKeyCommand.STANDARD_KEY) {
- if (event.standardKeyCode === 'Backspace' &&
- !event.altKey && !event.ctrlKey && !event.shiftKey &&
- this.onBackspace_()) {
- return true;
- } else {
- this.commitAndClearEntryState_();
- this.sendKeyEventPair_(event);
- return true;
- }
- }
- return false;
- },
-
- /**
- * Returns how the value of the currently displayed content should be
- * expanded given the current input state.
- * @return {cvox.ExpandingBrailleTranslator.ExpansionType}
- * The current expansion type.
- */
- getExpansionType: function() {
- if (this.inAlwaysUncontractedContext_())
- return cvox.ExpandingBrailleTranslator.ExpansionType.ALL;
- if (this.entryState_ &&
- this.entryState_.translator ===
- this.translatorManager_.getDefaultTranslator()) {
- return cvox.ExpandingBrailleTranslator.ExpansionType.NONE;
- }
- return cvox.ExpandingBrailleTranslator.ExpansionType.SELECTION;
- },
-
- /**
- * @return {boolean} {@code true} if we have an input context and
- * uncontracted braille should always be used for that context.
- * @private
- */
- inAlwaysUncontractedContext_: function() {
- var inputType = this.inputContext_ ? this.inputContext_.type : '';
- return inputType === 'url' || inputType === 'email';
- },
-
- /**
- * Called when a user typed a braille cell.
- * @param {number} dots The dot pattern of the cell.
- * @return {boolean} Whether the event was handled or should be allowed to
- * propagate further.
- * @private
- */
- onBrailleDots_: function(dots) {
- if (!this.imeActive_) {
- this.pendingCells_.push(dots);
- return true;
- }
- if (!this.inputContext_)
- return false;
- if (!this.entryState_) {
- if (!(this.entryState_ = this.createEntryState_()))
- return false;
- }
- this.entryState_.appendCell(dots);
- return true;
- },
-
- /**
- * Handles the backspace key by deleting the last typed cell if possible.
- * @return {boolean} {@code true} if the event was handled, {@code false}
- * if it wasn't and should propagate further.
- * @private
- */
- onBackspace_: function() {
- if (this.imeActive_ && this.entryState_) {
- this.entryState_.deleteLastCell();
- return true;
- }
- return false;
- },
-
- /**
- * Creates a new empty {@code EntryState_} based on the current input context
- * and surrounding text.
- * @return {cvox.BrailleInputHandler.EntryState_} The newly created state
- * object, or null if it couldn't be created (e.g. if there's no braille
- * translator available yet).
- * @private
- */
- createEntryState_: function() {
- var translator = this.translatorManager_.getDefaultTranslator();
- if (!translator)
- return null;
- var uncontractedTranslator =
- this.translatorManager_.getUncontractedTranslator();
- var constructor = cvox.BrailleInputHandler.EditsEntryState_;
- if (uncontractedTranslator) {
- var textBefore = this.currentTextBefore_;
- var textAfter = this.currentTextAfter_;
- if (this.inAlwaysUncontractedContext_() ||
- (cvox.BrailleInputHandler.ENDS_WITH_NON_WHITESPACE_RE_.test(
- textBefore)) ||
- (cvox.BrailleInputHandler.STARTS_WITH_NON_WHITESPACE_RE_.test(
- textAfter))) {
- translator = uncontractedTranslator;
- } else {
- constructor = cvox.BrailleInputHandler.LateCommitEntryState_;
- }
- }
-
- return new constructor(this, translator);
- },
-
- /**
- * Commits the current entry state and clears it, if any.
- * @private
- */
- commitAndClearEntryState_: function() {
- if (this.entryState_) {
- this.entryState_.commit();
- this.clearEntryState_();
- }
- },
-
- /**
- * Clears the current entry state without committing it.
- * @private
- */
- clearEntryState_: function() {
- if (this.entryState_) {
- if (this.entryState_.usesUncommittedCells)
- this.updateUncommittedCells_(new ArrayBuffer(0));
- this.entryState_.inputHandler_ = null;
- this.entryState_ = null;
- }
- },
-
- /**
- * @param {ArrayBuffer} cells
- * @private
- */
- updateUncommittedCells_: function(cells) {
- if (this.uncommittedCellsSpan_)
- this.uncommittedCellsSpan_.cells = cells;
- if (this.uncommittedCellsChangedListener_)
- this.uncommittedCellsChangedListener_();
- },
-
- /**
- * Called when another extension connects to this extension. Accepts
- * connections from the ChromeOS builtin Braille IME and ignores connections
- * from other extensions.
- * @param {Port} port The port used to communicate with the other extension.
- * @private
- */
- onImeConnect_: function(port) {
- if (port.name !== cvox.BrailleInputHandler.IME_PORT_NAME_ ||
- port.sender.id !== cvox.BrailleInputHandler.IME_EXTENSION_ID_) {
- return;
- }
- if (this.imePort_)
- this.imePort_.disconnect();
- port.onDisconnect.addListener(this.onImeDisconnect_.bind(this, port));
- port.onMessage.addListener(this.onImeMessage_.bind(this));
- this.imePort_ = port;
- },
-
- /**
- * Called when a message is received from the IME.
- * @param {*} message The message.
- * @private
- */
- onImeMessage_: function(message) {
- if (!goog.isObject(message)) {
- console.error('Unexpected message from Braille IME: ',
- JSON.stringify(message));
- }
- switch (message.type) {
- case 'activeState':
- this.imeActive_ = message.active;
- break;
- case 'inputContext':
- this.inputContext_ = message.context;
- this.clearEntryState_();
- if (this.imeActive_ && this.inputContext_)
- this.pendingCells_.forEach(this.onBrailleDots_, this);
- this.pendingCells_.length = 0;
- break;
- case 'brailleDots':
- this.onBrailleDots_(message['dots']);
- break;
- case 'backspace':
- // Note that we can't send the backspace key through the
- // virtualKeyboardPrivate API in this case because it would then be
- // processed by the IME again, leading to an infinite loop.
- this.postImeMessage_(
- {type: 'keyEventHandled', requestId: message['requestId'],
- result: this.onBackspace_()});
- break;
- case 'reset':
- this.clearEntryState_();
- break;
- default:
- console.error('Unexpected message from Braille IME: ',
- JSON.stringify(message));
- break;
- }
- },
-
- /**
- * Called when the IME port is disconnected.
- * @param {Port} port The port that was disconnected.
- * @private
- */
- onImeDisconnect_: function(port) {
- this.imePort_ = null;
- this.clearEntryState_();
- this.imeActive_ = false;
- this.inputContext_ = null;
- },
-
- /**
- * Posts a message to the IME.
- * @param {Object} message The message.
- * @return {boolean} {@code true} if the message was sent, {@code false} if
- * there was no connection open to the IME.
- * @private
- */
- postImeMessage_: function(message) {
- if (this.imePort_) {
- this.imePort_.postMessage(message);
- return true;
- }
- return false;
- },
-
- /**
- * Sends a {@code keydown} key event followed by a {@code keyup} event
- * corresponding to an event generated by the braille display.
- * @param {!cvox.BrailleKeyEvent} event The braille key event to base the
- * key events on.
- * @private
- */
- sendKeyEventPair_: function(event) {
- // Use the virtual keyboard API instead of the IME key event API
- // so that these keys work even if the Braille IME is not active.
- var keyName = /** @type {string} */ (event.standardKeyCode);
- var numericCode = cvox.BrailleKeyEvent.keyCodeToLegacyCode(keyName);
- if (!goog.isDef(numericCode))
- throw Error('Unknown key code in event: ' + JSON.stringify(event));
- var keyEvent = {
- type: 'keydown',
- keyCode: numericCode,
- keyName: keyName,
- charValue: cvox.BrailleKeyEvent.keyCodeToCharValue(keyName),
- // See chrome/common/extensions/api/virtual_keyboard_private.json for
- // these constants.
- modifiers: (event.shiftKey ? 2 : 0) |
- (event.ctrlKey ? 4 : 0) |
- (event.altKey ? 8 : 0)
- };
- chrome.virtualKeyboardPrivate.sendKeyEvent(keyEvent);
- keyEvent.type = 'keyup';
- chrome.virtualKeyboardPrivate.sendKeyEvent(keyEvent);
- }
-};
-
-/**
- * The entry state is the state related to entering a series of braille cells
- * without 'interruption', where interruption can be things like non braille
- * keyboard input or unexpected changes to the text surrounding the cursor.
- * @param {!cvox.BrailleInputHandler} inputHandler
- * @param {!cvox.LibLouis.Translator} translator
- * @constructor
- * @private
- */
-cvox.BrailleInputHandler.EntryState_ = function(inputHandler, translator) {
- /**
- * @type {cvox.BrailleInputHandler}
- * @private
- */
- this.inputHandler_ = inputHandler;
- /**
- * The translator currently used for typing, if
- * {@code this.cells_.length > 0}.
- * @type {!cvox.LibLouis.Translator}
- * @private
- */
- this.translator_ = translator;
- /**
- * Braille cells that have been typed by the user so far.
- * @type {!Array<number>}
- * @private
- */
- this.cells_ = [];
- /**
- * Text resulting from translating {@code this.cells_}.
- * @type {string}
- * @private
- */
- this.text_ = '';
- /**
- * List of strings that we expect to be set as preceding text of the
- * selection. This is populated when we send text changes to the IME so that
- * our own changes don't reset the pending cells.
- * @type {!Array<string>}
- * @private
- */
- this.pendingTextsBefore_ = [];
-};
-
-cvox.BrailleInputHandler.EntryState_.prototype = {
- /**
- * @return {!cvox.LibLouis.Translator} The translator used by this entry
- * state. This doesn't change for a given object.
- */
- get translator() {
- return this.translator_;
- },
-
- /**
- * Appends a braille cell to the current input and updates the text if
- * necessary.
- * @param {number} cell The braille cell to append.
- */
- appendCell: function(cell) {
- this.cells_.push(cell);
- this.updateText_();
- },
-
- /**
- * Deletes the last cell of the input and updates the text if neccary.
- * If there's no more input in this object afterwards, clears the entry state
- * of the input handler.
- */
- deleteLastCell: function() {
- if (--this.cells_.length <= 0) {
- this.sendTextChange_('');
- this.inputHandler_.clearEntryState_();
- return;
- }
- this.updateText_();
- },
-
- /**
- * Called when the text before the cursor changes giving this object a
- * chance to clear the entry state of the input handler if the change
- * wasn't expected.
- * @param {string} newText New text before the cursor.
- */
- onTextBeforeChanged: function(newText) {
- // See if we are expecting this change as a result of one of our own edits.
- // Allow changes to be coalesced by the input system in an attempt to not
- // be too brittle.
- for (var i = 0; i < this.pendingTextsBefore_.length; ++i) {
- if (newText === this.pendingTextsBefore_[i]) {
- // Delete all previous expected changes and ignore this one.
- this.pendingTextsBefore_.splice(0, i + 1);
- return;
- }
- }
- // There was an actual text change (or cursor movement) that we hadn't
- // caused ourselves, reset any pending input.
- this.inputHandler_.clearEntryState_();
- },
-
- /**
- * Makes sure the current text is permanently added to the edit field.
- * After this call, this object should be abandoned.
- */
- commit: function() {
- },
-
- /**
- * @return {boolean} true if the entry state uses uncommitted cells.
- */
- get usesUncommittedCells() {
- return false;
- },
-
- /**
- * Updates the translated text based on the current cells and sends the
- * delta to the IME.
- * @private
- */
- updateText_: function() {
- var cellsBuffer = new Uint8Array(this.cells_).buffer;
- var commit = this.lastCellIsBlank_;
- if (!commit && this.usesUncommittedCells)
- this.inputHandler_.updateUncommittedCells_(cellsBuffer);
- this.translator_.backTranslate(cellsBuffer, function(result) {
- if (result === null) {
- console.error('Error when backtranslating braille cells');
- return;
- }
- if (!this.inputHandler_)
- return;
- this.sendTextChange_(result);
- this.text_ = result;
- if (commit)
- this.inputHandler_.commitAndClearEntryState_();
- }.bind(this));
- },
-
- /**
- * @return {boolean}
- * @private
- */
- get lastCellIsBlank_() {
- return this.cells_[this.cells_.length - 1] === 0;
- },
-
- /**
- * Sends new text to the IME. This dhould be overriden by subclasses.
- * The old text is still available in the {@code text_} property.
- * @param {string} newText Text to send.
- * @private
- */
- sendTextChange_: function(newText) {
- }
-};
-
-/**
- * Entry state that uses {@code deleteSurroundingText} and {@code commitText}
- * calls to the IME to update the currently enetered text.
- * @param {!cvox.BrailleInputHandler} inputHandler
- * @param {!cvox.LibLouis.Translator} translator
- * @constructor
- * @extends {cvox.BrailleInputHandler.EntryState_}
- * @private
- */
-cvox.BrailleInputHandler.EditsEntryState_ = function(
- inputHandler, translator) {
- cvox.BrailleInputHandler.EntryState_.call(this, inputHandler, translator);
-};
-
-cvox.BrailleInputHandler.EditsEntryState_.prototype = {
- __proto__: cvox.BrailleInputHandler.EntryState_.prototype,
-
- /** @override */
- sendTextChange_: function(newText) {
- var oldText = this.text_;
- // Find the common prefix of the old and new text.
- var commonPrefixLength = StringUtil.longestCommonPrefixLength(
- oldText, newText);
- // How many characters we need to delete from the existing text to replace
- // them with characters from the new text.
- var deleteLength = oldText.length - commonPrefixLength;
- // New text, if any, to insert after deleting the deleteLength characters
- // before the cursor.
- var toInsert = newText.substring(commonPrefixLength);
- if (deleteLength > 0 || toInsert.length > 0) {
- // After deleting, we expect this text to be present before the cursor.
- var textBeforeAfterDelete =
- this.inputHandler_.currentTextBefore_.substring(
- 0, this.inputHandler_.currentTextBefore_.length - deleteLength);
- if (deleteLength > 0) {
- // Queue this text up to be ignored when the change comes in.
- this.pendingTextsBefore_.push(textBeforeAfterDelete);
- }
- if (toInsert.length > 0) {
- // Likewise, queue up what we expect to be before the cursor after
- // the replacement text is inserted.
- this.pendingTextsBefore_.push(textBeforeAfterDelete + toInsert);
- }
- // Send the replace operation to be performed asynchronously by the IME.
- this.inputHandler_.postImeMessage_(
- {type: 'replaceText',
- contextID: this.inputHandler_.inputContext_.contextID,
- deleteBefore: deleteLength,
- newText: toInsert});
- }
- }
-};
-
-/**
- * Entry state that only updates the edit field when a blank cell is entered.
- * During the input of a single 'word', the uncommitted text is stored by the
- * IME.
- * @param {!cvox.BrailleInputHandler} inputHandler
- * @param {!cvox.LibLouis.Translator} translator
- * @constructor
- * @private
- * @extends {cvox.BrailleInputHandler.EntryState_}
- */
-cvox.BrailleInputHandler.LateCommitEntryState_ = function(
- inputHandler, translator) {
- cvox.BrailleInputHandler.EntryState_.call(this, inputHandler, translator);
-};
-
-cvox.BrailleInputHandler.LateCommitEntryState_.prototype = {
- __proto__: cvox.BrailleInputHandler.EntryState_.prototype,
-
- /** @override */
- commit: function() {
- this.inputHandler_.postImeMessage_(
- {type: 'commitUncommitted',
- contextID: this.inputHandler_.inputContext_.contextID});
- },
-
- /** @override */
- get usesUncommittedCells() {
- return true;
- },
-
- /** @override */
- sendTextChange_: function(newText) {
- this.inputHandler_.postImeMessage_(
- {type: 'setUncommitted',
- contextID: this.inputHandler_.inputContext_.contextID,
- text: newText});
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler_test.unitjs
deleted file mode 100644
index aeec1fb08d5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler_test.unitjs
+++ /dev/null
@@ -1,698 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-GEN_INCLUDE(['../testing/fake_objects.js']);
-
-// Fake out the Chrome API namespace we depend on.
-var chrome = {};
-/** Fake chrome.runtime object. */
-chrome.runtime = {};
-/** Fake chrome.virtualKeyboardPrivate object. */
-chrome.virtualKeyboardPrivate = {};
-
-
-/**
- * A fake input field that behaves like the Braille IME and also updates
- * the input manager's knowledge about the display content when text changes
- * in the edit field.
- * @param {FakePort} port A fake port.
- * @param {cvox.BrailleInputHandler} inputHandler to work with.
- * @constructor
- */
-function FakeEditor(port, inputHandler) {
- /** @private {FakePort} */
- this.port_ = port;
- /** @private {cvox.BrailleInputHandler} */
- this.inputHandler_ = inputHandler;
- /** @private {string} */
- this.text_ = '';
- /** @private {number} */
- this.selectionStart_ = 0;
- /** @private {number} */
- this.selectionEnd_ = 0;
- /** @private {number} */
- this.contextID_ = 0;
- /** @private {boolean} */
- this.allowDeletes_ = false;
- /** @private {string} */
- this.uncommittedText_ = '';
- /** @private {?Array<number>} */
- this.extraCells_ = [];
- port.postMessage = goog.bind(this.handleMessage_, this);
-}
-
-
-/**
- * Sets the content and selection (or cursor) of the edit field.
- * This fakes what happens when the field is edited by other means than
- * via the braille keyboard.
- * @param {string} text Text to replace the current content of the field.
- * @param {number} selectionStart Start of the selection or cursor position.
- * @param {number=} opt_selectionEnd End of selection, or ommited if the
- * selection is a cursor.
- */
-FakeEditor.prototype.setContent = function(
- text, selectionStart, opt_selectionEnd) {
- this.text_ = text;
- this.selectionStart_ = selectionStart;
- this.selectionEnd_ = goog.isDef(opt_selectionEnd) ?
- opt_selectionEnd : selectionStart;
- this.callOnDisplayContentChanged_();
-};
-
-
-/**
- * Sets the selection in the editor.
- * @param {number} selectionStart Start of the selection or cursor position.
- * @param {number=} opt_selectionEnd End of selection, or ommited if the
- * selection is a cursor.
- */
-FakeEditor.prototype.select = function(selectionStart, opt_selectionEnd) {
- this.setContent(this.text_, selectionStart, opt_selectionEnd);
-};
-
-
-/**
- * Inserts text into the edit field, optionally selecting the inserted
- * text.
- * @param {string} newText Text to insert.
- * @param {boolean=} opt_select If {@code true}, selects the inserted text,
- * otherwise leaves the cursor at the end of the new text.
- */
-FakeEditor.prototype.insert = function(newText, opt_select) {
- this.text_ =
- this.text_.substring(0, this.selectionStart_) +
- newText +
- this.text_.substring(this.selectionEnd_);
- if (opt_select) {
- this.selectionEnd_ = this.selectionStart_ + newText.length;
- } else {
- this.selectionStart_ += newText.length;
- this.selectionEnd_ = this.selectionStart_;
- }
- this.callOnDisplayContentChanged_();
-};
-
-
-/**
- * Sets whether the editor should cause a test failure if the input handler
- * tries to delete text before the cursor. By default, thi value is
- * {@code false}.
- * @param {boolean} allowDeletes The new value.
- */
-FakeEditor.prototype.setAllowDeletes = function(allowDeletes) {
- this.allowDeletes_ = allowDeletes;
-};
-
-
-/**
- * Signals to the input handler that the Braille IME is active or not active,
- * depending on the argument.
- * @param {boolean} value Whether the IME is active or not.
- */
-FakeEditor.prototype.setActive = function(value) {
- this.message_({type: 'activeState', active: value});
-};
-
-
-/**
- * Fails if the current editor content and selection range don't match
- * the arguments to this function.
- * @param {string} text Text that should be in the field.
- * @param {number} selectionStart Start of selection.
- * @param {number+} opt_selectionEnd End of selection, default to selection
- * start to indicate a cursor.
- */
-FakeEditor.prototype.assertContentIs = function(
- text, selectionStart, opt_selectionEnd) {
- var selectionEnd = goog.isDef(opt_selectionEnd) ? opt_selectionEnd :
- selectionStart;
- assertEquals(text, this.text_);
- assertEquals(selectionStart, this.selectionStart_);
- assertEquals(selectionEnd, this.selectionEnd_);
-};
-
-
-/**
- * Asserts that the uncommitted text last sent to the IME is the given text.
- * @param {string} text
- */
-FakeEditor.prototype.assertUncommittedTextIs = function(text) {
- assertEquals(text, this.uncommittedText_);
-};
-
-
-/**
- * Asserts that the input handler has added 'extra cells' for uncommitted
- * text into the braille content.
- * @param {string} cells Cells as a space-separated list of numbers.
- */
-FakeEditor.prototype.assertExtraCellsAre = function(cells) {
- assertEqualsJSON(cellsToArray(cells), this.extraCells_);
-};
-
-
-/**
- * Sends a message from the IME to the input handler.
- * @param {Object} msg The message to send.
- * @private
- */
-FakeEditor.prototype.message_ = function(msg) {
- var listener = this.port_.onMessage.getListener();
- assertNotEquals(null, listener);
- listener(msg);
-};
-
-
-/**
- * Calls the {@code onDisplayContentChanged} method of the input handler
- * with the current editor content and selection.
- * @private
- */
-FakeEditor.prototype.callOnDisplayContentChanged_ = function() {
- var content = cvox.BrailleUtil.createValue(
- this.text_, this.selectionStart_, this.selectionEnd_)
- var grabExtraCells = function() {
- var span = content.getSpanInstanceOf(cvox.ExtraCellsSpan);
- assertNotEquals(null, span);
- // Convert the ArrayBuffer to a normal array for easier comparision.
- this.extraCells_ = Array.prototype.map.call(new Uint8Array(span.cells),
- function(a) {return a;});
- }.bind(this);
- this.inputHandler_.onDisplayContentChanged(content, grabExtraCells);
- grabExtraCells();
-};
-
-
-/**
- * Informs the input handler that a new text field is focused. The content
- * of the field is not cleared and should be updated separately.
- * @param {string} fieldType The type of the field (see the documentation
- * for the {@code chrome.input.ime} API).
- */
-FakeEditor.prototype.focus = function(fieldType) {
- this.contextID_++;
- this.message_({type: 'inputContext',
- context: {type: fieldType,
- contextID: this.contextID_}});
-};
-
-
-/**
- * Inform the input handler that focus left the input field.
- */
-FakeEditor.prototype.blur = function() {
- this.message_({type: 'inputContext', context: null});
- this.contextID_ = 0;
-};
-
-
-/**
- * Handles a message from the input handler to the IME.
- * @param {Object} msg The message.
- * @private
- */
-FakeEditor.prototype.handleMessage_ = function(msg) {
- assertEquals(this.contextID_, msg.contextID);
- switch(msg.type) {
- case 'replaceText':
- var deleteBefore = msg.deleteBefore;
- var newText = msg.newText;
- assertTrue(goog.isNumber(deleteBefore));
- assertTrue(goog.isString(newText));
- assertTrue(deleteBefore <= this.selectionStart_);
- if (deleteBefore > 0) {
- assertTrue(this.allowDeletes_);
- this.text_ =
- this.text_.substring(0, this.selectionStart_ - deleteBefore) +
- this.text_.substring(this.selectionEnd_);
- this.selectionStart_ -= deleteBefore;
- this.selectionEnd_ = this.selectionStart_;
- this.callOnDisplayContentChanged_();
- }
- this.insert(newText);
- break;
- case 'setUncommitted':
- assertTrue(goog.isString(msg.text));
- this.uncommittedText_ = msg.text;
- break;
- case 'commitUncommitted':
- this.insert(this.uncommittedText_);
- this.uncommittedText_ = '';
- break;
- default:
- throw new Error('Unexpected message to IME: ' + JSON.stringify(msg));
- }
-};
-
-/*
- * Fakes a {@code Port} used for message passing in the Chrome extension APIs.
- * @constructor
- */
-function FakePort() {
- /** @type {FakeChromeEvent} */
- this.onDisconnect = new FakeChromeEvent();
- /** @type {FakeChromeEvent} */
- this.onMessage = new FakeChromeEvent();
- /** @type {string} */
- this.name = cvox.BrailleInputHandler.IME_PORT_NAME_;
- /** @type {{id: string}} */
- this.sender = {id: cvox.BrailleInputHandler.IME_EXTENSION_ID_};
-}
-
-/**
- * Mapping from braille cells to Unicode characters.
- * @const Array<Array<string> >
- */
-var UNCONTRACTED_TABLE = [
- ['0', ' '],
- ['1', 'a'], ['12', 'b'], ['14', 'c'], ['145', 'd'], ['15', 'e'],
- ['124', 'f'], ['1245', 'g'], ['125', 'h'], ['24', 'i'], ['245', 'j'],
- ['13', 'k'], ['123', 'l'], ['134', 'm'], ['1345', 'n'], ['135', 'o'],
- ['1234', 'p'], ['12345', 'q'], ['1235', 'r'], ['234', 's'], ['2345', 't']
-];
-
-
-/**
- * Mapping of braille cells to the corresponding word in Grade 2 US English
- * braille. This table also includes the uncontracted table above.
- * If a match 'pattern' starts with '^', it must be at the beginning of
- * the string or be preceded by a blank cell. Similarly, '$' at the end
- * of a 'pattern' means that the match must be at the end of the string
- * or be followed by a blank cell. Note that order is significant in the
- * table. First match wins.
- * @const
- */
-var CONTRACTED_TABLE = [
- ['12 1235 123', 'braille'],
- ['^12$', 'but'],
- ['1456', 'this']].concat(UNCONTRACTED_TABLE);
-
-/**
- * A fake braille translator that can do back translation according
- * to one of the tables above.
- * @param {Array<Array<number>>} table Backtranslation mapping.
- * @param {boolean=} opt_capitalize Whether the result should be capitalized.
- * @constructor
- */
-function FakeTranslator(table, opt_capitalize) {
- /** @private */
- this.table_ = table.map(function(entry) {
- var cells = entry[0];
- var result = [];
- if (cells[0] === '^') {
- result.start = true;
- cells = cells.substring(1);
- }
- if (cells[cells.length - 1] === '$') {
- result.end = true;
- cells = cells.substring(0, cells.length - 1);
- }
- result[0] = cellsToArray(cells);
- result[1] = entry[1];
- return result;
- });
- /** @private {boolean} */
- this.capitalize_ = opt_capitalize || false;
-}
-
-
-/**
- * Implements the {@code cvox.LibLouis.BrailleTranslator.backTranslate} method.
- * @param {!ArrayBuffer} cells Cells to be translated.
- * @param {function(?string)} callback Callback for result.
- */
-FakeTranslator.prototype.backTranslate = function(cells, callback) {
- var cellsArray = new Uint8Array(cells);
- var result = '';
- var pos = 0;
- while (pos < cellsArray.length) {
- var match = null;
- outer: for (var i = 0, entry; entry = this.table_[i]; ++i) {
- if (pos + entry[0].length > cellsArray.length) {
- continue;
- }
- if (entry.start && pos > 0 && cellsArray[pos - 1] !== 0) {
- continue;
- }
- for (var j = 0; j < entry[0].length; ++j) {
- if (entry[0][j] !== cellsArray[pos + j]) {
- continue outer;
- }
- }
- if (entry.end && pos + j < cellsArray.length &&
- cellsArray[pos + j] !== 0) {
- continue;
- }
- match = entry;
- break;
- }
- assertNotEquals(
- null, match,
- 'Backtranslating ' + cellsArray[pos] + ' at ' + pos);
- result += match[1];
- pos += match[0].length;
- }
- if (this.capitalize_) {
- result = result.toUpperCase();
- }
- callback(result);
-};
-
-/** @extends {cvox.BrailleTranslatorManager} */
-function FakeTranslatorManager() {
-}
-
-FakeTranslatorManager.prototype = {
- defaultTranslator: null,
- uncontractedTranslator: null,
- changeListener: null,
-
- /** @override */
- getDefaultTranslator: function() {
- return this.defaultTranslator;
- },
-
- /** @override */
- getUncontractedTranslator: function() {
- return this.uncontractedTranslator;
- },
-
- /** @override */
- addChangeListener: function(listener) {
- assertEquals(null, this.changeListener);
- },
-
- setTranslators: function(defaultTranslator, uncontractedTranslator) {
- this.defaultTranslator = defaultTranslator;
- this.uncontractedTranslator = uncontractedTranslator;
- if (this.changeListener) {
- this.changeListener();
- }
- }
-};
-
-/**
- * Converts a list of cells, represented as a string, to an array.
- * @param {string} cells A string with space separated groups of digits.
- * Each group corresponds to one braille cell and each digit in a group
- * corresponds to a particular dot in the cell (1 to 8). As a special
- * case, the digit 0 by itself represents a blank cell.
- * @return {Array<number>} An array with each cell encoded as a bit
- * pattern (dot 1 uses bit 0, etc).
- */
-function cellsToArray(cells) {
- if (!cells)
- return [];
- return cells.split(/\s+/).map(function(cellString) {
- var cell = 0;
- assertTrue(cellString.length > 0);
- if (cellString != '0') {
- for (var i = 0; i < cellString.length; ++i) {
- var dot = cellString.charCodeAt(i) - '0'.charCodeAt(0);
- assertTrue(dot >= 1);
- assertTrue(dot <= 8);
- cell |= 1 << (dot - 1);
- }
- }
- return cell;
- });
-}
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxBrailleInputHandlerUnitTest() {}
-
-CvoxBrailleInputHandlerUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.BrailleInputHandler',
- 'cvox.BrailleUtil',
- ],
-
- /**
- * Creates an editor and establishes a connection from the IME.
- * @return {FakeEditor}
- */
- createEditor: function() {
- chrome.runtime.onConnectExternal.getListener()(this.port);
- return new FakeEditor(this.port, this.inputHandler);
- },
-
- /**
- * Sends a series of braille cells to the input handler.
- * @param {string} cells Braille cells, encoded as described in
- * {@code cellsToArray}.
- * @return {boolean} {@code true} iff all cells were sent successfully.
- */
- sendCells: function(cells) {
- return cellsToArray(cells).reduce(function(prevResult, cell) {
- var event = {command: cvox.BrailleKeyCommand.DOTS, brailleDots: cell};
- return prevResult && this.inputHandler.onBrailleKeyEvent(event);
- }.bind(this), true);
- },
-
- /**
- * Sends a standard key event (such as backspace) to the braille input
- * handler.
- * @param {string} keyCode The key code name.
- * @return {boolean} Whether the event was handled.
- */
- sendKeyEvent: function(keyCode) {
- var event = {command: cvox.BrailleKeyCommand.STANDARD_KEY,
- standardKeyCode: keyCode};
- return this.inputHandler.onBrailleKeyEvent(event);
- },
-
- /**
- * Shortcut for asserting that the value expansion mode is {@code NONE}.
- */
- assertExpandingNone: function() {
- assertEquals(cvox.ExpandingBrailleTranslator.ExpansionType.NONE,
- this.inputHandler.getExpansionType());
- },
-
- /**
- * Shortcut for asserting that the value expansion mode is {@code SELECTION}.
- */
- assertExpandingSelection: function() {
- assertEquals(cvox.ExpandingBrailleTranslator.ExpansionType.SELECTION,
- this.inputHandler.getExpansionType());
- },
-
- /**
- * Shortcut for asserting that the value expansion mode is {@code ALL}.
- */
- assertExpandingAll: function() {
- assertEquals(cvox.ExpandingBrailleTranslator.ExpansionType.ALL,
- this.inputHandler.getExpansionType());
- },
-
- storeKeyEvent: function(event, opt_callback) {
- var storedCopy = {keyCode: event.keyCode, keyName: event.keyName,
- charValue: event.charValue};
- if (event.type == 'keydown') {
- this.keyEvents.push(storedCopy);
- } else {
- assertEquals('keyup', event.type);
- assertTrue(this.keyEvents.length > 0);
- assertEqualsJSON(storedCopy, this.keyEvents[this.keyEvents.length - 1]);
- }
- if (goog.isDef(opt_callback)) {
- callback();
- }
- },
-
- /** @override */
- setUp: function() {
- chrome.runtime.onConnectExternal = new FakeChromeEvent();
- this.port = new FakePort();
- this.translatorManager = new FakeTranslatorManager();
- this.inputHandler = new cvox.BrailleInputHandler(this.translatorManager);
- this.inputHandler.init();
- this.uncontractedTranslator = new FakeTranslator(UNCONTRACTED_TABLE);
- this.contractedTranslator = new FakeTranslator(CONTRACTED_TABLE, true);
- chrome.virtualKeyboardPrivate.sendKeyEvent =
- this.storeKeyEvent.bind(this);
- this.keyEvents = [];
- }
-};
-
-TEST_F('CvoxBrailleInputHandlerUnitTest', 'ConnectFromUnknownExtension',
- function() {
- this.port.sender.id = 'your unknown friend';
- chrome.runtime.onConnectExternal.getListener()(this.port);
- this.port.onMessage.assertNoListener();
-});
-
-
-TEST_F('CvoxBrailleInputHandlerUnitTest', 'NoTranslator', function() {
- var editor = this.createEditor();
- editor.setContent('blah', 0);
- editor.setActive(true);
- editor.focus('email');
- assertFalse(this.sendCells('145 135 125'));
- editor.setActive(false);
- editor.blur();
- editor.assertContentIs('blah', 0);
-});
-
-
-TEST_F('CvoxBrailleInputHandlerUnitTest', 'InputUncontracted', function() {
- this.translatorManager.setTranslators(this.uncontractedTranslator, null);
- var editor = this.createEditor();
- editor.setActive(true);
-
- // Focus and type in a text field.
- editor.focus('text');
- assertTrue(this.sendCells('125 15 123 123 135')); // hello
- editor.assertContentIs('hello', 'hello'.length);
- this.assertExpandingNone();
-
- // Move the cursor and type in the middle.
- editor.select(2);
- assertTrue(this.sendCells('0 2345 125 15 1235 15 0')); // ' there '
- editor.assertContentIs('he there llo', 'he there '.length);
-
- // Field changes by some other means.
- editor.insert('you!');
- // Then type on the braille keyboard again.
- assertTrue(this.sendCells('0 125 15')); // ' he'
- editor.assertContentIs('he there you! hello', 'he there you! he'.length);
-
- editor.blur();
- editor.setActive(false);
-});
-
-
-TEST_F('CvoxBrailleInputHandlerUnitTest', 'InputContracted', function() {
- var editor = this.createEditor();
- this.translatorManager.setTranslators(this.contractedTranslator,
- this.uncontractedTranslator);
- editor.setContent('', 0);
- editor.setActive(true);
- editor.focus('text');
- this.assertExpandingSelection();
-
- // First, type a 'b'.
- assertTrue(this.sendCells('12'));
- editor.assertContentIs('', 0);
- // Remember that the contracted translator produces uppercase.
- editor.assertUncommittedTextIs('BUT');
- editor.assertExtraCellsAre('12');
- this.assertExpandingNone();
-
- // Typing 'rl' changes to a different contraction.
- assertTrue(this.sendCells('1235 123'));
- editor.assertUncommittedTextIs('BRAILLE');
- editor.assertContentIs('', 0);
- editor.assertExtraCellsAre('12 1235 123');
- this.assertExpandingNone();
-
- // Now, finish the word.
- assertTrue(this.sendCells('0'));
- editor.assertContentIs('BRAILLE ', 'BRAILLE '.length);
- editor.assertUncommittedTextIs('');
- editor.assertExtraCellsAre('');
- this.assertExpandingSelection();
-
- // Move the cursor to the beginning.
- editor.select(0);
- this.assertExpandingSelection();
-
- // Typing now uses the uncontracted table.
- assertTrue(this.sendCells('12')); // 'b'
- editor.assertContentIs('bBRAILLE ', 1);
- this.assertExpandingSelection();
- editor.select('bBRAILLE'.length);
- this.assertExpandingSelection();
- assertTrue(this.sendCells('12')); // 'b'
- editor.assertContentIs('bBRAILLEb ', 'bBRAILLEb'.length);
- // Move to the end, where contracted typing should work.
- editor.select('bBRAILLEb '.length);
- assertTrue(this.sendCells('1456 0')); // Symbol for 'this', then space.
- this.assertExpandingSelection();
- editor.assertContentIs('bBRAILLEb THIS ', 'bBRAILLEb THIS '.length);
-
- // Move to between the two words.
- editor.select('bBRAILLEb'.length);
- this.assertExpandingSelection();
- assertTrue(this.sendCells('0 12')); // Space plus 'b' for 'but'
- editor.assertUncommittedTextIs('BUT');
- editor.assertExtraCellsAre('12');
- editor.assertContentIs('bBRAILLEb THIS ', 'bBRAILLEb '.length);
- this.assertExpandingNone();
-});
-
-
-TEST_F('CvoxBrailleInputHandlerUnitTest', 'TypingUrlWithContracted',
- function() {
- var editor = this.createEditor();
- this.translatorManager.setTranslators(this.contractedTranslator,
- this.uncontractedTranslator);
- editor.setActive(true);
- editor.focus('url');
- this.assertExpandingAll();
- assertTrue(this.sendCells('1245')); // 'g'
- editor.insert('oogle.com', true /*select*/);
- editor.assertContentIs('google.com', 1, 'google.com'.length);
- this.assertExpandingAll();
- this.sendCells('135'); // 'o'
- editor.insert('ogle.com', true /*select*/);
- editor.assertContentIs('google.com', 2, 'google.com'.length);
- this.assertExpandingAll();
- this.sendCells('0');
- editor.assertContentIs('go ', 'go '.length);
- // In a URL, even when the cursor is in whitespace, all of the value
- // is expanded to uncontracted braille.
- this.assertExpandingAll();
-});
-
-
-TEST_F('CvoxBrailleInputHandlerUnitTest', 'Backspace', function() {
- var editor = this.createEditor();
- this.translatorManager.setTranslators(this.contractedTranslator,
- this.uncontractedTranslator);
- editor.setActive(true);
- editor.focus('text');
-
- // Add some text that we can delete later.
- editor.setContent('Text ', 'Text '.length);
-
- // Type 'brl' to make sure replacement works when deleting text.
- assertTrue(this.sendCells('12 1235 123'));
- editor.assertUncommittedTextIs('BRAILLE');
-
- // Delete what we just typed, one cell at a time.
- this.sendKeyEvent('Backspace');
- editor.assertUncommittedTextIs('BR');
- this.sendKeyEvent('Backspace');
- editor.assertUncommittedTextIs('BUT');
- this.sendKeyEvent('Backspace');
- editor.assertUncommittedTextIs('');
-
- // Now, backspace should be handled as usual, synthetizing key events.
- assertEquals(0, this.keyEvents.length);
- this.sendKeyEvent('Backspace');
- assertEqualsJSON([{keyCode: 8, keyName: 'Backspace', charValue: 8}],
- this.keyEvents);
-});
-
-
-TEST_F('CvoxBrailleInputHandlerUnitTest', 'KeysImeNotActive', function() {
- var editor = this.createEditor();
- this.sendKeyEvent('Enter');
- this.sendKeyEvent('ArrowUp');
- assertEqualsJSON([{keyCode: 13, keyName: 'Enter', charValue: 0x0A},
- {keyCode: 38, keyName: 'ArrowUp', charValue: 0x41}],
- this.keyEvents);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_key_types.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_key_types.js
deleted file mode 100644
index f6e6095d1c0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_key_types.js
+++ /dev/null
@@ -1,131 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Braille command definitions.
- * These types are adapted from Chrome's private braille API.
- * They can be found in the Chrome source repo at:
- * src/chrome/common/extensions/api/braille_display_private.idl
- * We define them here since they don't actually exist as bindings under
- * chrome.brailleDisplayPrivate.*.
- */
-
-goog.provide('cvox.BrailleDisplayState');
-goog.provide('cvox.BrailleKeyCommand');
-goog.provide('cvox.BrailleKeyEvent');
-
-
-/**
- * The set of commands sent from a braille display.
- * @enum {string}
- */
-cvox.BrailleKeyCommand = {
- PAN_LEFT: 'pan_left',
- PAN_RIGHT: 'pan_right',
- LINE_UP: 'line_up',
- LINE_DOWN: 'line_down',
- TOP: 'top',
- BOTTOM: 'bottom',
- ROUTING: 'routing',
- SECONDARY_ROUTING: 'secondary_routing',
- DOTS: 'dots',
- STANDARD_KEY: 'standard_key'
-};
-
-
-/**
- * Represents a key event from a braille display.
- *
- * @typedef {{command: cvox.BrailleKeyCommand,
- * displayPosition: (undefined|number),
- * brailleDots: (undefined|number),
- * standardKeyCode: (undefined|string),
- * standardKeyChar: (undefined|string),
- * altKey: (undefined|boolean),
- * ctrlKey: (undefined|boolean),
- * shiftKey: (undefined|boolean)
- * }}
- * command The name of the command.
- * displayPosition The 0-based position relative to the start of the currently
- * displayed text. Used for commands that involve routing
- * keys or similar. The position is given in characters,
- * not braille cells.
- * brailleDots Dots that were pressed for braille input commands. Bit mask
- * where bit 0 represents dot 1 etc.
- * standardKeyCode DOM level 4 key code.
- * standardKeyChar DOM key event character.
- * altKey Whether the alt key was pressed.
- * ctrlKey Whether the control key was pressed.
- * shiftKey Whether the shift key was pressed.
- */
-cvox.BrailleKeyEvent = {};
-
-
-/**
- * Returns the numeric key code for a DOM level 4 key code string.
- * NOTE: Only the key codes produced by the brailleDisplayPrivate API are
- * supported.
- * @param {string} code DOM level 4 key code.
- * @return {number|undefined} The numeric key code, or {@code undefined}
- * if unknown.
- */
-cvox.BrailleKeyEvent.keyCodeToLegacyCode = function(code) {
- return cvox.BrailleKeyEvent.legacyKeyCodeMap_[code];
-};
-
-
-/**
- * Returns a char value appropriate for a synthezised key event for a given
- * key code.
- * @param {string} keyCode The DOM level 4 key code.
- * @return {number} Integral character code.
- */
-cvox.BrailleKeyEvent.keyCodeToCharValue = function(keyCode) {
- /** @const */
- var SPECIAL_CODES = {
- 'Backspace': 0x08,
- 'Tab': 0x09,
- 'Enter': 0x0A
- };
- // Note, the Chrome virtual keyboard falls back on the first character of the
- // key code if the key is not one of the above. Do the same here.
- return SPECIAL_CODES[keyCode] || keyCode.charCodeAt(0);
-};
-
-
-/**
- * Map from DOM level 4 key codes to legacy numeric key codes.
- * @private {Object<number>}
- */
-cvox.BrailleKeyEvent.legacyKeyCodeMap_ = {
- 'Backspace': 8,
- 'Tab': 9,
- 'Enter': 13,
- 'Escape': 27,
- 'Home': 36,
- 'ArrowLeft': 37,
- 'ArrowUp': 38,
- 'ArrowRight': 39,
- 'ArrowDown': 40,
- 'PageUp': 33,
- 'PageDown': 34,
- 'End': 35,
- 'Insert': 45,
- 'Delete': 46
-};
-
-// Add the F1 to F12 keys.
-(function() {
- for (var i = 0; i < 12; ++i) {
- cvox.BrailleKeyEvent.legacyKeyCodeMap_['F' + (i + 1)] = 112 + i;
- }
-})();
-
-
-/**
- * The state of a braille display as represented in the
- * chrome.brailleDisplayPrivate API.
- * @typedef {{available: boolean, textCellCount: (number|undefined)}}
- */
-cvox.BrailleDisplayState;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_table.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_table.js
deleted file mode 100644
index 8957d1c241f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_table.js
+++ /dev/null
@@ -1,132 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Holds information about a braille table.
- */
-
-goog.provide('cvox.BrailleTable');
-
-
-/**
- * @typedef {{
- * locale:string,
- * dots:string,
- * id:string,
- * grade:(string|undefined),
- * variant:(string|undefined),
- * fileNames:string
- * }}
- */
-cvox.BrailleTable.Table;
-
-
-/**
- * @const {string}
- */
-cvox.BrailleTable.TABLE_PATH = 'braille/tables.json';
-
-
-/**
- * @const {string}
- * @private
- */
-cvox.BrailleTable.COMMON_DEFS_FILENAME_ = 'cvox-common.cti';
-
-
-/**
- * Retrieves a list of all available braille tables.
- * @param {function(!Array<cvox.BrailleTable.Table>)} callback
- * Called asynchronously with an array of tables.
- */
-cvox.BrailleTable.getAll = function(callback) {
- function appendCommonFilename(tables) {
- // Append the common definitions to all table filenames.
- tables.forEach(function(table) {
- table.fileNames += (',' + cvox.BrailleTable.COMMON_DEFS_FILENAME_);
- });
- return tables;
- }
- var url = chrome.extension.getURL(cvox.BrailleTable.TABLE_PATH);
- if (!url) {
- throw 'Invalid path: ' + cvox.BrailleTable.TABLE_PATH;
- }
-
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, true);
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- callback(
- appendCommonFilename(
- /** @type {!Array<cvox.BrailleTable.Table>} */ (
- JSON.parse(xhr.responseText))));
- }
- }
- };
- xhr.send();
-};
-
-
-/**
- * Finds a table in a list of tables by id.
- * @param {!Array<cvox.BrailleTable.Table>} tables tables to search in.
- * @param {string} id id of table to find.
- * @return {cvox.BrailleTable.Table} The found table, or null if not found.
- */
-cvox.BrailleTable.forId = function(tables, id) {
- return tables.filter(function(table) { return table.id === id })[0] || null;
-};
-
-
-/**
- * Returns an uncontracted braille table corresponding to another, possibly
- * contracted, table. If {@code table} is the lowest-grade table for its
- * locale and dot count, {@code table} itself is returned.
- * @param {!Array<cvox.BrailleTable.Table>} tables tables to search in.
- * @param {!cvox.BrailleTable.Table} table Table to match.
- * @return {!cvox.BrailleTable.Table} Corresponding uncontracted table,
- * or {@code table} if it is uncontracted.
- */
-cvox.BrailleTable.getUncontracted = function(tables, table) {
- function mostUncontractedOf(current, candidate) {
- // An 8 dot table for the same language is prefered over a 6 dot table
- // even if the locales differ by region.
- if (current.dots === '6' &&
- candidate.dots === '8' &&
- current.locale.lastIndexOf(candidate.locale, 0) == 0) {
- return candidate;
- }
- if (current.locale === candidate.locale &&
- current.dots === candidate.dots &&
- goog.isDef(current.grade) &&
- goog.isDef(candidate.grade) &&
- candidate.grade < current.grade) {
- return candidate;
- }
- return current;
- }
- return tables.reduce(mostUncontractedOf, table);
-};
-
-
-/**
- * @param {!cvox.BrailleTable.Table} table Table to get name for.
- * @return {string} Localized display name.
- */
-cvox.BrailleTable.getDisplayName = function(table) {
- var localeName = Msgs.getLocaleDisplayName(table.locale);
- if (!table.grade && !table.variant) {
- return localeName;
- } else if (table.grade && !table.variant) {
- return Msgs.getMsg('braille_table_name_with_grade',
- [localeName, table.grade]);
- } else if (!table.grade && table.variant) {
- return Msgs.getMsg('braille_table_name_with_variant',
- [localeName, table.variant]);
- } else {
- return Msgs.getMsg('braille_table_name_with_variant_and_grade',
- [localeName, table.variant, table.grade]);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_table_test.extjs b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_table_test.extjs
deleted file mode 100644
index 6adae043965..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_table_test.extjs
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_e2e_test_base.js',
- '../testing/assert_additions.js']);
-
-/**
- * Test fixture for cvox.BrailleTable tests.
- * This is an E2E test because there's no easy way to load a data file in
- * a webui-style test.
- * @constructor
- * @extends {ChromeVoxE2ETest}
- */
-function CvoxBrailleTableTest() {
- ChromeVoxE2ETest.call(this);
-}
-
-CvoxBrailleTableTest.prototype = {
- __proto__: ChromeVoxE2ETest.prototype,
-};
-
-/**
- * Tests that {@code getAll} can fetch and parse the tables file.
- * NOTE: This will need to be adjusted when more tables are added.
- */
-TEST_F('CvoxBrailleTableTest', 'testGetAllAndValidate', function() {
- cvox.BrailleTable.getAll(this.newCallback(function(tables) {
- expectEquals(68, tables.length);
- assertNotNullNorUndefined(
- cvox.BrailleTable.forId(tables, 'en-US-g1'),
- 'Can\'t find US English grade 1 table');
- for (var i = 0, table; table = tables[i]; ++i) {
- expectEquals('string', typeof table.id);
- expectTrue(table.dots === '6' || table.dots === '8');
- expectTrue(cvox.BrailleTable.getDisplayName(table).length > 0);
- }
- }));
-});
-
-/** Tests getDisplayName for some specific representative cases. */
-TEST_F('CvoxBrailleTableTest', 'testGetDisplayName', function() {
- cvox.BrailleTable.getAll(this.newCallback(function(tables) {
- var table = cvox.BrailleTable.forId(tables, 'bg-comp8');
- expectEquals('Bulgarian', cvox.BrailleTable.getDisplayName(table));
- table = cvox.BrailleTable.forId(tables, 'ar-g1');
- expectEquals('Arabic, Grade 1', cvox.BrailleTable.getDisplayName(table));
- table = cvox.BrailleTable.forId(tables, 'en-UEB-g1');
- expectEquals('English (UEB), Grade 1',
- cvox.BrailleTable.getDisplayName(table));
- }));
-});
-
-/**
- * Tests the getUncontracted function.
- */
-TEST_F('CvoxBrailleTableTest', 'testGetUncontracted', function() {
- cvox.BrailleTable.getAll(this.newCallback(function(tables) {
- function expectUncontracted(uncontractedId, idToCheck) {
- var checkedTable = cvox.BrailleTable.forId(tables, idToCheck);
- var uncontractedTable = cvox.BrailleTable.getUncontracted(
- tables, checkedTable);
- expectNotEquals(null, uncontractedTable);
- expectEquals(uncontractedId, uncontractedTable.id);
- }
- expectUncontracted('en-US-comp8', 'en-US-g2');
- expectUncontracted('en-US-comp8', 'en-US-comp8');
- expectUncontracted('nb-comp8', 'nb-g0');
- expectUncontracted('sv-comp8', 'sv-g1');
- expectUncontracted('ar-g1', 'ar-g1');
- expectUncontracted('de-comp8', 'de-CH-g2');
- }));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager.js
deleted file mode 100644
index 2a152b22837..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager.js
+++ /dev/null
@@ -1,233 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Keeps track of the current braille translators.
- */
-
-goog.provide('cvox.BrailleTranslatorManager');
-
-goog.require('cvox.BrailleTable');
-goog.require('cvox.ExpandingBrailleTranslator');
-goog.require('cvox.LibLouis');
-
-/**
- * @param {cvox.LibLouis=} opt_liblouisForTest Liblouis instance to use
- * for testing.
- * @constructor
- */
-cvox.BrailleTranslatorManager = function(opt_liblouisForTest) {
- /**
- * @type {!cvox.LibLouis}
- * @private
- */
- this.liblouis_ = opt_liblouisForTest || new cvox.LibLouis(
- chrome.extension.getURL('braille/liblouis_nacl.nmf'),
- chrome.extension.getURL('braille/tables'));
- /**
- * @type {!Array<function()>}
- * @private
- */
- this.changeListeners_ = [];
- /**
- * @type {!Array<cvox.BrailleTable.Table>}
- * @private
- */
- this.tables_ = [];
- /**
- * @type {cvox.ExpandingBrailleTranslator}
- * @private
- */
- this.expandingTranslator_ = null;
- /**
- * @type {cvox.LibLouis.Translator}
- * @private
- */
- this.defaultTranslator_ = null;
- /**
- * @type {string?}
- * @private
- */
- this.defaultTableId_ = null;
- /**
- * @type {cvox.LibLouis.Translator}
- * @private
- */
- this.uncontractedTranslator_ = null;
- /**
- * @type {string?}
- * @private
- */
- this.uncontractedTableId_ = null;
-
- if (!opt_liblouisForTest) {
- document.addEventListener('DOMContentLoaded',
- this.loadLiblouis_.bind(this),
- false);
- }
-};
-
-cvox.BrailleTranslatorManager.prototype = {
- /**
- * Adds a listener to be called whenever there is a change in the
- * translator(s) returned by other methods of this instance.
- * @param {function()} listener The listener.
- */
- addChangeListener: function(listener) {
- this.changeListeners_.push(listener);
- },
-
- /**
- * Refreshes the braille translator(s) used for input and output. This
- * should be called when something has changed (such as a preference) to
- * make sure that the correct translator is used.
- */
- refresh: function() {
- var tables = this.tables_;
- if (tables.length == 0)
- return;
-
- // First, see if we have a braille table set previously.
- var table = cvox.BrailleTable.forId(tables, localStorage['brailleTable']);
- if (!table) {
- // Match table against current locale.
- var currentLocale = chrome.i18n.getMessage('@@ui_locale').split(/[_-]/);
- var major = currentLocale[0];
- var minor = currentLocale[1];
- var firstPass = tables.filter(function(table) {
- return table.locale.split(/[_-]/)[0] == major;
- });
- if (firstPass.length > 0) {
- table = firstPass[0];
- if (minor) {
- var secondPass = firstPass.filter(function(table) {
- return table.locale.split(/[_-]/)[1] == minor;
- });
- if (secondPass.length > 0)
- table = secondPass[0];
- }
- }
- }
- if (!table)
- table = cvox.BrailleTable.forId(tables, 'en-US-comp8');
-
- // TODO(plundblad): Only update when user explicitly selects a table
- // so that switching locales changes table by default. crbug.com/441206.
- localStorage['brailleTable'] = table.id;
- if (!localStorage['brailleTable6'])
- localStorage['brailleTable6'] = 'en-US-g1';
- if (!localStorage['brailleTable8'])
- localStorage['brailleTable8'] = 'en-US-comp8';
-
- if (table.dots == '6') {
- localStorage['brailleTableType'] = 'brailleTable6';
- localStorage['brailleTable6'] = table.id;
- } else {
- localStorage['brailleTableType'] = 'brailleTable8';
- localStorage['brailleTable8'] = table.id;
- }
-
- // If the user explicitly set an 8 dot table, use that when looking
- // for an uncontracted table. Otherwise, use the current table and let
- // getUncontracted find an appropriate corresponding table.
- var table8Dot = cvox.BrailleTable.forId(tables,
- localStorage['brailleTable8']);
- var uncontractedTable = cvox.BrailleTable.getUncontracted(
- tables, table8Dot || table);
-
- var newDefaultTableId = table.id;
- var newUncontractedTableId = table.id === uncontractedTable.id ?
- null : uncontractedTable.id;
- if (newDefaultTableId === this.defaultTableId_ &&
- newUncontractedTableId === this.uncontractedTableId_) {
- return;
- }
-
- var finishRefresh = function(defaultTranslator, uncontractedTranslator) {
- this.defaultTableId_ = newDefaultTableId;
- this.uncontractedTableId_ = newUncontractedTableId;
- this.expandingTranslator_ = new cvox.ExpandingBrailleTranslator(
- defaultTranslator, uncontractedTranslator);
- this.defaultTranslator_ = defaultTranslator;
- this.uncontractedTranslator_ = uncontractedTranslator;
- this.changeListeners_.forEach(function(listener) { listener(); });
- }.bind(this);
-
- this.liblouis_.getTranslator(table.fileNames, function(translator) {
- if (!newUncontractedTableId) {
- finishRefresh(translator, null);
- } else {
- this.liblouis_.getTranslator(
- uncontractedTable.fileNames,
- function(uncontractedTranslator) {
- finishRefresh(translator, uncontractedTranslator);
- });
- }
- }.bind(this));
- },
-
- /**
- * @return {cvox.ExpandingBrailleTranslator} The current expanding braille
- * translator, or {@code null} if none is available.
- */
- getExpandingTranslator: function() {
- return this.expandingTranslator_;
- },
-
- /**
- * @return {cvox.LibLouis.Translator} The current braille translator to use
- * by default, or {@code null} if none is available.
- */
- getDefaultTranslator: function() {
- return this.defaultTranslator_;
- },
-
- /**
- * @return {cvox.LibLouis.Translator} The current uncontracted braille
- * translator, or {@code null} if it is the same as the default
- * translator.
- */
- getUncontractedTranslator: function() {
- return this.uncontractedTranslator_;
- },
-
- /**
- * Asynchronously fetches the list of braille tables and refreshes the
- * translators when done.
- * @private
- */
- fetchTables_: function() {
- cvox.BrailleTable.getAll(function(tables) {
- this.tables_ = tables;
- this.refresh();
- }.bind(this));
- },
-
- /**
- * Loads the liblouis instance by attaching it to the document.
- * @private
- */
- loadLiblouis_: function() {
- // Cast away nullability. When the document is loaded, it will always
- // have a body.
- this.liblouis_.attachToElement(
- /** @type {!HTMLBodyElement} */ (document.body));
- this.fetchTables_();
- },
-
- /**
- * @return {!cvox.LibLouis} The liblouis instance used by this object.
- */
- getLibLouisForTest: function() {
- return this.liblouis_;
- },
-
- /**
- * @return {!Array<cvox.BrailleTable.Table>} The currently loaded braille
- * tables, or an empty array if they are not yet loaded.
- */
- getTablesForTest: function() {
- return this.tables_;
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager_test.extjs b/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager_test.extjs
deleted file mode 100644
index 24a414f9ebd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/braille_translator_manager_test.extjs
+++ /dev/null
@@ -1,116 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_e2e_test_base.js',
- '../testing/assert_additions.js']);
-
-/**
- * Test fixture for cvox.BrailleTranslatorManager tests.
- * This is an E2E test because there's no easy way to load a data file in
- * a webui-style test.
- * @constructor
- * @extends {ChromeVoxE2ETest}
- */
-function CvoxBrailleTranslatorManagerTest() {
- ChromeVoxE2ETest.call(this);
-}
-
-CvoxBrailleTranslatorManagerTest.prototype = {
- __proto__: ChromeVoxE2ETest.prototype,
-
- /** @override */
- setUp: function() {
- this.liblouis = new FakeLibLouis();
- this.manager = new cvox.BrailleTranslatorManager(this.liblouis);
- this.liblouis.translatorManager = this.manager;
- // This is called by an event handler in production, but we don't rely
- // on that for this test.
- this.manager.loadLiblouis_();
- },
-
- addChangeListener: function(callback) {
- return this.manager.addChangeListener(callOnce(this.newCallback(callback)));
- },
-};
-
-/** @extends {cvox.LibLouis} */
-function FakeLibLouis() {
-}
-
-FakeLibLouis.prototype = {
- /** @override */
- attachToElement: function() {},
-
- /** @override */
- getTranslator: function(fileNames, callback) {
- var tables = this.translatorManager.getTablesForTest();
- var result = null;
- if (tables != null) {
- var found = tables.filter(function(table) {
- return table.fileNames === fileNames;
- })[0];
- if (found) {
- result = new FakeTranslator(found);
- }
- }
- callback(result);
- }
-};
-
-/**
- * @extends {cvox.LibLouis.Translator}
- * @param {cvox.BrailleTable.Table} table
- * @constructor
- */
-function FakeTranslator(table) {
- this.table = table;
-}
-
-function callOnce(callback) {
- var called = false;
- return function() {
- if (!called) {
- called = true;
- callback.apply(null, arguments);
- }
- };
-}
-
-TEST_F('CvoxBrailleTranslatorManagerTest', 'testInitial', function() {
- assertEquals(null, this.manager.getExpandingTranslator());
- assertEquals(null, this.manager.getDefaultTranslator());
- assertEquals(null, this.manager.getUncontractedTranslator());
- this.addChangeListener(function() {
- assertNotEquals(null, this.manager.getExpandingTranslator());
- assertEquals('en-US-comp8', this.manager.getDefaultTranslator().table.id);
- assertEquals(null, this.manager.getUncontractedTranslator());
- });
-});
-
-TEST_F('CvoxBrailleTranslatorManagerTest', 'testRefreshWithoutChange',
- function() {
- this.addChangeListener(function() {
- assertNotEquals(null, this.manager.getExpandingTranslator());
- // This works because the fake liblouis is actually not asynchonous.
- this.manager.addChangeListener(function() {
- assertNotReached('Refresh should not be called without a change.');
- });
- this.manager.refresh();
- });
-});
-
-TEST_F('CvoxBrailleTranslatorManagerTest', 'testRefreshWithChange',
- function() {
- this.addChangeListener(function() {
- assertNotEquals(null, this.manager.getExpandingTranslator());
- this.addChangeListener(function() {
- assertEquals('en-UEB-g2', this.manager.getDefaultTranslator().table.id);
- assertEquals('en-US-comp8',
- this.manager.getUncontractedTranslator().table.id);
- });
- localStorage['brailleTable'] = 'en-UEB-g2';
- this.manager.refresh();
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator.js
deleted file mode 100644
index 45b5ffb6645..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator.js
+++ /dev/null
@@ -1,342 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Translates text to braille, optionally with some parts
- * uncontracted.
- */
-
-goog.provide('cvox.ExpandingBrailleTranslator');
-
-goog.require('cvox.ExtraCellsSpan');
-goog.require('cvox.LibLouis');
-goog.require('cvox.Spannable');
-goog.require('cvox.ValueSelectionSpan');
-goog.require('cvox.ValueSpan');
-
-
-/**
- * A wrapper around one or two braille translators that uses contracted
- * braille or not based on the selection start- and end-points (if any) in the
- * translated text. If only one translator is provided, then that translator
- * is used for all text regardless of selection. If two translators
- * are provided, then the uncontracted translator is used for some text
- * around the selection end-points and the contracted translator is used
- * for all other text. When determining what text to use uncontracted
- * translation for around a position, a region surrounding that position
- * containing either only whitespace characters or only non-whitespace
- * characters is used.
- * @param {!cvox.LibLouis.Translator} defaultTranslator The translator for all
- * text when the uncontracted translator is not used.
- * @param {cvox.LibLouis.Translator=} opt_uncontractedTranslator
- * Translator to use for uncontracted braille translation.
- * @constructor
- */
-cvox.ExpandingBrailleTranslator =
- function(defaultTranslator, opt_uncontractedTranslator) {
- /**
- * @type {!cvox.LibLouis.Translator}
- * @private
- */
- this.defaultTranslator_ = defaultTranslator;
- /**
- * @type {cvox.LibLouis.Translator}
- * @private
- */
- this.uncontractedTranslator_ = opt_uncontractedTranslator || null;
-};
-
-
-/**
- * What expansion to apply to the part of the translated string marked by the
- * {@code cvox.ValueSpan} spannable.
- * @enum {number}
- */
-cvox.ExpandingBrailleTranslator.ExpansionType = {
- /**
- * Use the default translator all of the value, regardless of any selection.
- * This is typically used when the user is in the middle of typing and the
- * typing started outside of a word.
- */
- NONE: 0,
- /**
- * Expand text around the selection end-points if any. If the selection is
- * a cursor, expand the text that occupies the positions right before and
- * after the cursor. This is typically used when the user hasn't started
- * typing contracted braille or when editing inside a word.
- */
- SELECTION: 1,
- /**
- * Expand all text covered by the value span. this is typically used when
- * the user is editing a text field where it doesn't make sense to use
- * contracted braille (such as a url or email address).
- */
- ALL: 2
-};
-
-
-/**
- * Translates text to braille using the translator(s) provided to the
- * constructor. See {@code cvox.LibLouis.Translator} for further details.
- * @param {!cvox.Spannable} text Text to translate.
- * @param {cvox.ExpandingBrailleTranslator.ExpansionType} expansionType
- * Indicates how the text marked by a value span, if any, is expanded.
- * @param {function(!ArrayBuffer, !Array<number>, !Array<number>)}
- * callback Called when the translation is done. It takes resulting
- * braille cells and positional mappings as parameters.
- */
-cvox.ExpandingBrailleTranslator.prototype.translate =
- function(text, expansionType, callback) {
- var expandRanges = this.findExpandRanges_(text, expansionType);
- var extraCellsSpans = text.getSpansInstanceOf(cvox.ExtraCellsSpan)
- .filter(function(span) { return span.cells.byteLength > 0;});
- var extraCellsPositions = extraCellsSpans.map(function(span) {
- return text.getSpanStart(span);
- });
- if (expandRanges.length == 0 && extraCellsSpans.length == 0) {
- this.defaultTranslator_.translate(
- text.toString(),
- cvox.ExpandingBrailleTranslator.nullParamsToEmptyAdapter_(
- text.getLength(), callback));
- return;
- }
-
- var chunks = [];
- function maybeAddChunkToTranslate(translator, start, end) {
- if (start < end)
- chunks.push({translator: translator, start: start, end: end});
- }
- function addExtraCellsChunk(pos, cells) {
- var chunk = {translator: null,
- start: pos,
- end: pos,
- cells: cells,
- textToBraille: [],
- brailleToText: new Array(cells.byteLength)};
- for (var i = 0; i < cells.byteLength; ++i)
- chunk.brailleToText[i] = 0;
- chunks.push(chunk);
- }
- function addChunk(translator, start, end) {
- while (extraCellsSpans.length > 0 && extraCellsPositions[0] <= end) {
- maybeAddChunkToTranslate(translator, start, extraCellsPositions[0]);
- start = extraCellsPositions.shift();
- addExtraCellsChunk(start, extraCellsSpans.shift().cells);
- }
- maybeAddChunkToTranslate(translator, start, end);
- }
- var lastEnd = 0;
- for (var i = 0; i < expandRanges.length; ++i) {
- var range = expandRanges[i];
- if (lastEnd < range.start) {
- addChunk(this.defaultTranslator_, lastEnd, range.start);
- }
- addChunk(this.uncontractedTranslator_, range.start, range.end);
- lastEnd = range.end;
- }
- addChunk(this.defaultTranslator_, lastEnd, text.getLength());
-
- var chunksToTranslate = chunks.filter(function(chunk) {
- return chunk.translator;
- });
- var numPendingCallbacks = chunksToTranslate.length;
-
- function chunkTranslated(chunk, cells, textToBraille, brailleToText) {
- chunk.cells = cells;
- chunk.textToBraille = textToBraille;
- chunk.brailleToText = brailleToText;
- if (--numPendingCallbacks <= 0)
- finish();
- }
-
- function finish() {
- var totalCells = chunks.reduce(
- function(accum, chunk) { return accum + chunk.cells.byteLength}, 0);
- var cells = new Uint8Array(totalCells);
- var cellPos = 0;
- var textToBraille = [];
- var brailleToText = [];
- function appendAdjusted(array, toAppend, adjustment) {
- array.push.apply(array, toAppend.map(
- function(elem) { return adjustment + elem; }
- ));
- }
- for (var i = 0, chunk; chunk = chunks[i]; ++i) {
- cells.set(new Uint8Array(chunk.cells), cellPos);
- appendAdjusted(textToBraille, chunk.textToBraille, cellPos);
- appendAdjusted(brailleToText, chunk.brailleToText, chunk.start);
- cellPos += chunk.cells.byteLength;
- }
- callback(cells.buffer, textToBraille, brailleToText);
- }
-
- if (chunksToTranslate.length > 0) {
- chunksToTranslate.forEach(function(chunk) {
- chunk.translator.translate(
- text.toString().substring(chunk.start, chunk.end),
- cvox.ExpandingBrailleTranslator.nullParamsToEmptyAdapter_(
- chunk.end - chunk.start, goog.partial(chunkTranslated, chunk)));
- });
- } else {
- finish();
- }
-};
-
-
-/**
- * Expands a position to a range that covers the consecutive range of
- * either whitespace or non whitespace characters around it.
- * @param {string} str Text to look in.
- * @param {number} pos Position to start looking at.
- * @param {number} start Minimum value for the start position of the returned
- * range.
- * @param {number} end Maximum value for the end position of the returned
- * range.
- * @return {!cvox.ExpandingBrailleTranslator.Range_} The claculated range.
- * @private
- */
-cvox.ExpandingBrailleTranslator.rangeForPosition_ = function(
- str, pos, start, end) {
- if (start < 0 || end > str.length) {
- throw RangeError(
- 'End-points out of range looking for braille expansion range');
- }
- if (pos < start || pos >= end) {
- throw RangeError(
- 'Position out of range looking for braille expansion range');
- }
- // Find the last chunk of either whitespace or non-whitespace before and
- // including pos.
- start = str.substring(start, pos + 1).search(/(\s+|\S+)$/) + start;
- // Find the characters to include after pos, starting at pos so that
- // they are the same kind (either whitespace or not) as the
- // characters starting at start.
- end = pos + /^(\s+|\S+)/.exec(str.substring(pos, end))[0].length;
- return {start: start, end: end};
-};
-
-
-/**
- * Finds the ranges in which contracted braille should not be used.
- * @param {!cvox.Spannable} text Text to find expansion ranges in.
- * @param {cvox.ExpandingBrailleTranslator.ExpansionType} expansionType
- * Indicates how the text marked up as the value is expanded.
- * @return {!Array<cvox.ExpandingBrailleTranslator.Range_>} The calculated
- * ranges.
- * @private
- */
-cvox.ExpandingBrailleTranslator.prototype.findExpandRanges_ = function(
- text, expansionType) {
- var result = [];
- if (this.uncontractedTranslator_ &&
- expansionType != cvox.ExpandingBrailleTranslator.ExpansionType.NONE) {
- var value = text.getSpanInstanceOf(cvox.ValueSpan);
- if (value) {
- // The below type casts are valid because the ranges must be valid when
- // the span is known to exist.
- var valueStart = /** @type {number} */ (text.getSpanStart(value));
- var valueEnd = /** @type {number} */ (text.getSpanEnd(value));
- switch (expansionType) {
- case cvox.ExpandingBrailleTranslator.ExpansionType.SELECTION:
- this.addRangesForSelection_(text, valueStart, valueEnd, result);
- break;
- case cvox.ExpandingBrailleTranslator.ExpansionType.ALL:
- result.push({start: valueStart, end: valueEnd});
- break;
- }
- }
- }
-
- return result;
-};
-
-
-/**
- * Finds ranges to expand around selection end points inside the value of
- * a string. If any ranges are found, adds them to {@code outRanges}.
- * @param {cvox.Spannable} text Text to find ranges in.
- * @param {number} valueStart Start of the value in {@code text}.
- * @param {number} valueEnd End of the value in {@code text}.
- * @param {Array<cvox.ExpandingBrailleTranslator.Range_>} outRanges
- * Destination for the expansion ranges. Untouched if no ranges
- * are found. Note that ranges may be coalesced.
- * @private
- */
-cvox.ExpandingBrailleTranslator.prototype.addRangesForSelection_ = function(
- text, valueStart, valueEnd, outRanges) {
- var selection = text.getSpanInstanceOf(cvox.ValueSelectionSpan);
- if (!selection) {
- return;
- }
- var selectionStart = text.getSpanStart(selection);
- var selectionEnd = text.getSpanEnd(selection);
- if (selectionStart < valueStart || selectionEnd > valueEnd) {
- return;
- }
- var expandPositions = [];
- if (selectionStart == valueEnd) {
- if (selectionStart > valueStart) {
- expandPositions.push(selectionStart - 1);
- }
- } else {
- if (selectionStart == selectionEnd && selectionStart > valueStart) {
- expandPositions.push(selectionStart - 1);
- }
- expandPositions.push(selectionStart);
- // Include the selection end if the length of the selection is
- // greater than one (otherwise this position would be redundant).
- if (selectionEnd > selectionStart + 1) {
- // Look at the last actual character of the selection, not the
- // character at the (exclusive) end position.
- expandPositions.push(selectionEnd - 1);
- }
- }
-
- var lastRange = outRanges[outRanges.length - 1] || null;
- for (var i = 0; i < expandPositions.length; ++i) {
- var range = cvox.ExpandingBrailleTranslator.rangeForPosition_(
- text.toString(), expandPositions[i], valueStart, valueEnd);
- if (lastRange && lastRange.end >= range.start) {
- lastRange.end = range.end;
- } else {
- outRanges.push(range);
- lastRange = range;
- }
- }
-};
-
-
-/**
- * Adapts {@code callback} to accept null arguments and treat them as if the
- * translation result is empty.
- * @param {number} inputLength Length of the input to the translation.
- * Used for populating {@code textToBraille} if null.
- * @param {function(!ArrayBuffer, !Array<number>, !Array<number>)} callback
- * The callback to adapt.
- * @return {function(ArrayBuffer, Array<number>, Array<number>)}
- * An adapted version of the callback.
- * @private
- */
-cvox.ExpandingBrailleTranslator.nullParamsToEmptyAdapter_ =
- function(inputLength, callback) {
- return function(cells, textToBraille, brailleToText) {
- if (!textToBraille) {
- textToBraille = new Array(inputLength);
- for (var i = 0; i < inputLength; ++i) {
- textToBraille[i] = 0;
- }
- }
- callback(cells || new ArrayBuffer(0),
- textToBraille,
- brailleToText || []);
- };
-};
-
-
-/**
- * A character range with inclusive start and exclusive end positions.
- * @typedef {{start: number, end: number}}
- * @private
- */
-cvox.ExpandingBrailleTranslator.Range_;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator_test.unitjs
deleted file mode 100644
index 8b4f3137891..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/expanding_braille_translator_test.unitjs
+++ /dev/null
@@ -1,301 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js',
- '../testing/assert_additions.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxExpandingBrailleTranslatorUnitTest() {}
-
-CvoxExpandingBrailleTranslatorUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ExpandingBrailleTranslator',
- 'cvox.LibLouis',
- 'cvox.Spannable',
- 'cvox.ValueSelectionSpan',
- 'cvox.ValueSpan',
- ]
-};
-
-/**
- * An implementation of {@link cvox.LibLouis.Translator} whose translation
- * output is an array buffer of the same byte length as the input and where
- * each byte is equal to the character code of {@code resultChar}. The
- * position mappings are one to one in both directions.
- * @param {string} resultChar A one character string used for each byte of the
- * result.
- * @constructor
- * @extends {cvox.LibLouis.Translator}
- */
-function FakeTranslator(resultChar) {
- /** @private {string} */
- this.resultChar_ = resultChar;
-}
-
-FakeTranslator.prototype = {
- /** @Override */
- translate: function(text, callback) {
- var result = new Uint8Array(text.length);
- var textToBraille = [];
- var brailleToText = [];
- for (var i = 0; i < text.length; ++i) {
- result[i] = this.resultChar_.charCodeAt(0);
- textToBraille.push(i);
- brailleToText.push(i);
- }
- callback(result.buffer, textToBraille, brailleToText);
- }
-};
-
-/**
- * Asserts that a array buffer, viewed as an uint8 array, matches
- * the contents of a string. The character code of each character of the
- * string shall match the corresponding byte in the array buffer.
- * @param {ArrayBuffer} actual Actual array buffer.
- * @param {string} expected Array of expected bytes.
- */
-function assertArrayBufferMatches(expected, actual) {
- assertTrue(actual instanceof ArrayBuffer);
- var a = new Uint8Array(actual);
- assertEquals(expected.length, a.length);
- for (var i = 0; i < a.length; ++i) {
- assertEquals(expected.charCodeAt(i), a[i], 'Position ' + i);
- }
-}
-
-TEST_F('CvoxExpandingBrailleTranslatorUnitTest', 'TranslationError',
- function() {
- var text = new cvox.Spannable('error ok', new cvox.ValueSpan());
- text.setSpan(new cvox.ValueSelectionSpan, 0, 0);
- var contractedTranslator = new FakeTranslator('c');
- // Translator that always results in an error.
- var uncontractedTranslator = {
- translate: function(text, callback) {
- callback(null, null, null);
- }
- };
- var translationResult = null;
-
- var expandingTranslator = new cvox.ExpandingBrailleTranslator(
- contractedTranslator, uncontractedTranslator);
- expandingTranslator.translate(
- text, cvox.ExpandingBrailleTranslator.ExpansionType.SELECTION,
- function(cells, textToBraille, brailleToText) {
- // Expect the string ' ok' to be translated using the contracted
- // translator. The preceding part isn't included because it resulted
- // in a translation error.
- assertArrayBufferMatches('ccc', cells);
- assertEqualsJSON([0, 0, 0, 0, 0, 0, 1, 2], textToBraille);
- assertEqualsJSON([5, 6, 7], brailleToText);
- });
-});
-
-// Test for many variations of successful translations.
-
-var totalRunTranslationTests = 0;
-
-/**
- * Performs the translation and checks the output.
- * @param {string} name Name that describes the input for error messages.
- * @param {boolean} contracted Whether to use a contracted translator
- * in addition to the uncontracted one.
- * @param {cvox.ExpandingBrailleTranslator.ExpansionType} valueExpansion
- * Value expansion argument to pass to the translator.
- * @param {string} text Input string.
- * @param {string} expectedOutput Expected output as a string (see
- * {@code TESTDATA} below for a description of the format).
- */
-function doTranslationTest(name, contracted, valueExpansion, text,
- expectedOutput) {
- try {
- totalRunTranslationTests++;
- var uncontractedTranslator = new FakeTranslator('u');
- var expandingTranslator;
- if (contracted) {
- var contractedTranslator = new FakeTranslator('c');
- expandingTranslator = new cvox.ExpandingBrailleTranslator(
- contractedTranslator, uncontractedTranslator);
- } else {
- expandingTranslator = new cvox.ExpandingBrailleTranslator(
- uncontractedTranslator);
- }
- var extraCellsSpan = text.getSpanInstanceOf(cvox.ExtraCellsSpan);
- if (extraCellsSpan)
- var extraCellsSpanPos = text.getSpanStart(extraCellsSpan);
- var expectedTextToBraille = [];
- var expectedBrailleToText = [];
- for (var i = 0, pos = 0; i < text.getLength(); ++i, ++pos) {
- if (i === extraCellsSpanPos)
- ++pos;
- expectedTextToBraille.push(pos);
- expectedBrailleToText.push(i);
- }
- if (extraCellsSpan)
- expectedBrailleToText.splice(extraCellsSpanPos, 0, extraCellsSpanPos);
-
- expandingTranslator.translate(
- text, valueExpansion, function(cells, textToBraille, brailleToText) {
- assertArrayBufferMatches(expectedOutput, cells, name);
- assertEqualsJSON(expectedTextToBraille, textToBraille, name);
- assertEqualsJSON(expectedBrailleToText, brailleToText, name);
- });
- } catch (e) {
- console.error('Subtest ' + name + ' failed.');
- throw e;
- }
-};
-
-/**
- * Runs two tests, one with the given values and one with the given values
- * where the text is surrounded by a typical name and role.
- * @param {{name: string, input: string, contractedOutput: string}}
- * testCase An entry of {@code TESTDATA}.
- * @param {boolean} contracted Whether to use both uncontracted
- * and contracted translators.
- * @param {cvox.ExpandingBrailleTranslation.ExpansionType} valueExpansion
- * What kind of value expansion to apply.
- * @param {boolean} withExtraCells Whether to insert an extra cells span
- * right before the selection in the input.
- */
-function runTranslationTestVariants(testCase, contracted, valueExpansion,
- withExtraCells) {
- var expType = cvox.ExpandingBrailleTranslator.ExpansionType;
- // Construct the full name.
- var fullName = contracted ? 'Contracted_' : 'Uncontracted_';
- fullName += 'Expansion' + valueExpansion + '_';
- if (withExtraCells)
- fullName += 'ExtraCells_';
- fullName += testCase.name;
- var input = testCase.input;
- if (withExtraCells) {
- input = input.substring(0); // Shallow copy.
- var selectionStart = input.getSpanStart(
- input.getSpanInstanceOf(cvox.ValueSelectionSpan));
- var extraCellsSpan = new cvox.ExtraCellsSpan();
- extraCellsSpan.cells = new Uint8Array(['e'.charCodeAt(0)]).buffer;
- input.setSpan(extraCellsSpan, selectionStart, selectionStart);
- }
- // The expected output depends on the contraction mode and value expansion.
- var outputChar = contracted ? 'c' : 'u';
- var expectedOutput;
- if (contracted && valueExpansion === expType.SELECTION) {
- expectedOutput = testCase.contractedOutput;
- } else if (contracted && valueExpansion === expType.ALL) {
- expectedOutput = new Array(testCase.input.getLength() + 1).join('u');
- } else {
- expectedOutput =
- new Array(testCase.input.getLength() + 1).join(outputChar);
- }
- if (withExtraCells) {
- expectedOutput = expectedOutput.substring(0, selectionStart) + 'e' +
- expectedOutput.substring(selectionStart);
- }
- doTranslationTest(fullName, contracted, valueExpansion, input,
- expectedOutput);
-
- // Run another test, with the value surrounded by some text.
- var surroundedText = new cvox.Spannable('Name: ');
- var surroundedExpectedOutput =
- new Array('Name: '.length + 1).join(outputChar);
- surroundedText.append(input);
- surroundedExpectedOutput += expectedOutput;
- if (testCase.input.getLength() > 0) {
- surroundedText.append(' ');
- surroundedExpectedOutput += outputChar;
- }
- surroundedText.append('edtxt');
- surroundedExpectedOutput +=
- new Array('edtxt'.length + 1).join(outputChar);
- doTranslationTest(fullName + '_Surrounded', contracted, valueExpansion,
- surroundedText, surroundedExpectedOutput);
-}
-
-/**
- * Creates a spannable text with optional selection.
- * @param {string} text The text.
- * @param {=opt_selectionStart} Selection start or caret position. No
- * selection is added if undefined.
- * @param {=opt_selectionEnd} Selection end if selection is not a caret.
- */
-function createText(text, opt_selectionStart, opt_selectionEnd) {
- var result = new cvox.Spannable(text);
-
- result.setSpan(new cvox.ValueSpan, 0, text.length);
- if (goog.isDef(opt_selectionStart)) {
- result.setSpan(
- new cvox.ValueSelectionSpan,
- opt_selectionStart,
- goog.isDef(opt_selectionEnd) ? opt_selectionEnd : opt_selectionStart);
- }
- return result;
-}
-
-
-var TEXT = 'Hello, world!';
-
-TEST_F('CvoxExpandingBrailleTranslatorUnitTest', 'successfulTranslations',
- function() {
- /**
- * Dictionary of test strings, keyed on a descriptive name for the
- * test case. The value is an array of the input string to the translation
- * and the expected output using a translator with both uncontracted
- * and contracted underlying translators. The expected output is
- * in the form of a string of the same length as the input, where an 'u'
- * means that the uncontracted translator was used at this location and a
- * 'c' means that the contracted translator was used.
- */
- var TESTDATA = [
- { name: 'emptyText',
- input: createText(''),
- contractedOutput: '' },
- { name: 'emptyTextWithCaret',
- input: createText('', 0),
- contractedOutput: '' },
- { name: 'textWithNoSelection',
- input: createText(TEXT),
- contractedOutput: 'ccccccccccccc' },
- { name: 'textWithCaretAtStart',
- input: createText(TEXT, 0),
- contractedOutput: 'uuuuuuccccccc' },
- { name: 'textWithCaretAtEnd',
- input: createText(TEXT, TEXT.length),
- contractedOutput: 'cccccccuuuuuu' },
- { name: 'textWithCaretInWhitespace',
- input: createText(TEXT, 6),
- contractedOutput: 'uuuuuuucccccc' },
- { name: 'textWithSelectionEndInWhitespace',
- input: createText(TEXT, 0, 7),
- contractedOutput: 'uuuuuuucccccc' },
- { name: 'textWithSelectionInTwoWords',
- input: createText(TEXT, 2, 9),
- contractedOutput: 'uuuuuucuuuuuu' }
- ];
- var TESTDATA_WITH_SELECTION = TESTDATA.filter(function(testCase) {
- return testCase.input.getSpanInstanceOf(cvox.ValueSelectionSpan);
- });
-
- var expType = cvox.ExpandingBrailleTranslator.ExpansionType;
- for (var i = 0, testCase; testCase = TESTDATA[i]; ++i) {
- runTranslationTestVariants(testCase, false, expType.SELECTION, false);
- runTranslationTestVariants(testCase, true, expType.NONE, false);
- runTranslationTestVariants(testCase, true, expType.SELECTION, false);
- runTranslationTestVariants(testCase, true, expType.ALL, false);
- }
- for (var i = 0, testCase; testCase = TESTDATA_WITH_SELECTION[i]; ++i)
- runTranslationTestVariants(testCase, true, expType.SELECTION, true);
-
- // Make sure that the logic above runs the tests, adjust when adding more
- // test variants.
- var totalExpectedTranslationTests =
- 2 * (TESTDATA.length * 4 + TESTDATA_WITH_SELECTION.length);
- assertEquals(totalExpectedTranslationTests, totalRunTranslationTests);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/liblouis.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/liblouis.js
deleted file mode 100644
index 0b8a2ee0006..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/liblouis.js
+++ /dev/null
@@ -1,334 +0,0 @@
-// 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.
-
-/**
- * @fileoverview JavaScript shim for the liblouis Native Client wrapper.
- */
-
-goog.provide('cvox.LibLouis');
-
-
-/**
- * Encapsulates a liblouis Native Client instance in the page.
- * @constructor
- * @param {string} nmfPath Path to .nmf file for the module.
- * @param {string=} opt_tablesDir Path to tables directory.
- */
-cvox.LibLouis = function(nmfPath, opt_tablesDir) {
- /**
- * Path to .nmf file for the module.
- * @private {string}
- */
- this.nmfPath_ = nmfPath;
-
- /**
- * Path to translation tables.
- * @private {?string}
- */
- this.tablesDir_ = goog.isDef(opt_tablesDir) ? opt_tablesDir : null;
-
- /**
- * Native Client <embed> element.
- * {@code null} when no <embed> is attached to the DOM.
- * @private {HTMLEmbedElement}
- */
- this.embedElement_ = null;
-
- /**
- * Pending RPC callbacks. Maps from message IDs to callbacks.
- * @private {!Object<function(!Object)>}
- */
- this.pendingRpcCallbacks_ = {};
-
- /**
- * Next message ID to be used. Incremented with each sent message.
- * @private {number}
- */
- this.nextMessageId_ = 1;
-};
-
-
-/**
- * Set to {@code true} to enable debug logging of RPC messages.
- * @type {boolean}
- */
-cvox.LibLouis.DEBUG = false;
-
-
-/**
- * Attaches the Native Client wrapper to the DOM as a child of the provided
- * element, assumed to already be in the document.
- * @param {!Element} elem Desired parent element of the instance.
- */
-cvox.LibLouis.prototype.attachToElement = function(elem) {
- if (this.isAttached()) {
- throw Error('Instance already attached');
- }
-
- var embed = document.createElement('embed');
- embed.src = this.nmfPath_;
- embed.type = 'application/x-nacl';
- embed.width = 0;
- embed.height = 0;
- if (!goog.isNull(this.tablesDir_)) {
- embed.setAttribute('tablesdir', this.tablesDir_);
- }
- embed.addEventListener('load', goog.bind(this.onInstanceLoad_, this),
- false /* useCapture */);
- embed.addEventListener('error', goog.bind(this.onInstanceError_, this),
- false /* useCapture */);
- embed.addEventListener('message', goog.bind(this.onInstanceMessage_, this),
- false /* useCapture */);
- elem.appendChild(embed);
- this.embedElement_ = /** @type {!HTMLEmbedElement} */ (embed);
-};
-
-
-/**
- * Detaches the Native Client instance from the DOM.
- */
-cvox.LibLouis.prototype.detach = function() {
- if (!this.isAttached()) {
- throw Error('cannot detach unattached instance');
- }
-
- this.embedElement_.parentNode.removeChild(this.embedElement_);
- this.embedElement_ = null;
- for (var id in this.pendingRpcCallbacks_) {
- this.pendingRpcCallbacks_[id]({});
- }
- this.pendingRpcCallbacks_ = {};
-};
-
-
-/**
- * Determines whether the Native Client instance is attached.
- * @return {boolean} {@code true} if the <embed> element is attached to the DOM.
- */
-cvox.LibLouis.prototype.isAttached = function() {
- return this.embedElement_ !== null;
-};
-
-
-/**
- * Returns a translator for the desired table, asynchronously.
- * This object must be attached to a document when requesting a translator.
- * @param {string} tableNames Comma separated list of braille table names for
- * liblouis.
- * @param {function(cvox.LibLouis.Translator)} callback
- * Callback which will receive the translator, or {@code null} on failure.
- */
-cvox.LibLouis.prototype.getTranslator = function(tableNames, callback) {
- if (!this.isAttached()) {
- callback(null /* translator */);
- return;
- }
- this.rpc_('CheckTable', { 'table_names': tableNames }, function(reply) {
- if (reply['success']) {
- var translator = new cvox.LibLouis.Translator(this, tableNames);
- callback(translator);
- } else {
- callback(null /* translator */);
- }
- }.bind(this));
-};
-
-
-/**
- * Dispatches a message to the remote end and returns the reply asynchronously.
- * A message ID will be automatically assigned (as a side-effect).
- * @param {string} command Command name to be sent.
- * @param {!Object} message JSONable message to be sent.
- * @param {function(!Object)} callback Callback to receive the reply.
- * @private
- */
-cvox.LibLouis.prototype.rpc_ =
- function(command, message, callback) {
- if (!this.isAttached()) {
- throw Error('Cannot send RPC: liblouis instance not loaded');
- }
- var messageId = '' + this.nextMessageId_++;
- message['message_id'] = messageId;
- message['command'] = command;
- var json = JSON.stringify(message);
- if (cvox.LibLouis.DEBUG) {
- window.console.debug('RPC -> ' + json);
- }
- this.embedElement_.postMessage(json);
- this.pendingRpcCallbacks_[messageId] = callback;
-};
-
-
-/**
- * Invoked when the Native Client instance successfully loads.
- * @param {Event} e Event dispatched after loading.
- * @private
- */
-cvox.LibLouis.prototype.onInstanceLoad_ = function(e) {
- window.console.info('loaded liblouis Native Client instance');
-};
-
-
-/**
- * Invoked when the Native Client instance fails to load.
- * @param {Event} e Event dispatched after loading failure.
- * @private
- */
-cvox.LibLouis.prototype.onInstanceError_ = function(e) {
- window.console.error('failed to load liblouis Native Client instance');
- this.detach();
-};
-
-
-/**
- * Invoked when the Native Client instance posts a message.
- * @param {Event} e Event dispatched after the message was posted.
- * @private
- */
-cvox.LibLouis.prototype.onInstanceMessage_ = function(e) {
- if (cvox.LibLouis.DEBUG) {
- window.console.debug('RPC <- ' + e.data);
- }
- var message = /** @type {!Object} */ (JSON.parse(e.data));
- var messageId = message['in_reply_to'];
- if (!goog.isDef(messageId)) {
- window.console.warn('liblouis Native Client module sent message with no ID',
- message);
- return;
- }
- if (goog.isDef(message['error'])) {
- window.console.error('liblouis Native Client error', message['error']);
- }
- var callback = this.pendingRpcCallbacks_[messageId];
- if (goog.isDef(callback)) {
- delete this.pendingRpcCallbacks_[messageId];
- callback(message);
- }
-};
-
-
-/**
- * Braille translator which uses a Native Client instance of liblouis.
- * @constructor
- * @param {!cvox.LibLouis} instance The instance wrapper.
- * @param {string} tableNames Comma separated list of Table names to be passed
- * to liblouis.
- */
-cvox.LibLouis.Translator = function(instance, tableNames) {
- /**
- * The instance wrapper.
- * @private {!cvox.LibLouis}
- */
- this.instance_ = instance;
-
- /**
- * The table name.
- * @private {string}
- */
- this.tableNames_ = tableNames;
-};
-
-
-/**
- * Translates text into braille cells.
- * @param {string} text Text to be translated.
- * @param {function(ArrayBuffer, Array<number>, Array<number>)} callback
- * Callback for result. Takes 3 parameters: the resulting cells,
- * mapping from text to braille positions and mapping from braille to
- * text positions. If translation fails for any reason, all parameters are
- * {@code null}.
- */
-cvox.LibLouis.Translator.prototype.translate = function(text, callback) {
- if (!this.instance_.isAttached()) {
- callback(null /*cells*/, null /*textToBraille*/, null /*brailleToText*/);
- return;
- }
- var message = { 'table_names': this.tableNames_, 'text': text };
- this.instance_.rpc_('Translate', message, function(reply) {
- var cells = null;
- var textToBraille = null;
- var brailleToText = null;
- if (reply['success'] && goog.isString(reply['cells'])) {
- cells = cvox.LibLouis.Translator.decodeHexString_(reply['cells']);
- if (goog.isDef(reply['text_to_braille'])) {
- textToBraille = reply['text_to_braille'];
- }
- if (goog.isDef(reply['braille_to_text'])) {
- brailleToText = reply['braille_to_text'];
- }
- } else if (text.length > 0) {
- // TODO(plundblad): The nacl wrapper currently returns an error
- // when translating an empty string. Address that and always log here.
- console.error('Braille translation error for ' + JSON.stringify(message));
- }
- callback(cells, textToBraille, brailleToText);
- });
-};
-
-
-/**
- * Translates braille cells into text.
- * @param {!ArrayBuffer} cells Cells to be translated.
- * @param {function(?string)} callback Callback for result.
- */
-cvox.LibLouis.Translator.prototype.backTranslate =
- function(cells, callback) {
- if (!this.instance_.isAttached()) {
- callback(null /*text*/);
- return;
- }
- if (cells.byteLength == 0) {
- // liblouis doesn't handle empty input, so handle that trivially
- // here.
- callback('');
- return;
- }
- var message = {
- 'table_names': this.tableNames_,
- 'cells': cvox.LibLouis.Translator.encodeHexString_(cells)
- };
- this.instance_.rpc_('BackTranslate', message, function(reply) {
- if (reply['success'] && goog.isString(reply['text'])) {
- callback(reply['text']);
- } else {
- callback(null /* text */);
- }
- });
-};
-
-
-/**
- * Decodes a hexadecimal string to an {@code ArrayBuffer}.
- * @param {string} hex Hexadecimal string.
- * @return {!ArrayBuffer} Decoded binary data.
- * @private
- */
-cvox.LibLouis.Translator.decodeHexString_ = function(hex) {
- if (!/^([0-9a-f]{2})*$/i.test(hex)) {
- throw Error('invalid hexadecimal string');
- }
- var array = new Uint8Array(hex.length / 2);
- var idx = 0;
- for (var i = 0; i < hex.length; i += 2) {
- array[idx++] = parseInt(hex.substring(i, i + 2), 16);
- }
- return array.buffer;
-};
-
-
-/**
- * Encodes an {@code ArrayBuffer} in hexadecimal.
- * @param {!ArrayBuffer} arrayBuffer Binary data.
- * @return {string} Hexadecimal string.
- * @private
- */
-cvox.LibLouis.Translator.encodeHexString_ = function(arrayBuffer) {
- var array = new Uint8Array(arrayBuffer);
- var hex = '';
- for (var i = 0; i < array.length; i++) {
- var b = array[i];
- hex += (b < 0x10 ? '0' : '') + b.toString(16);
- }
- return hex;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/liblouis_test.extjs b/chromium/chrome/browser/resources/chromeos/chromevox/braille/liblouis_test.extjs
deleted file mode 100644
index 38d1e4b92db..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/liblouis_test.extjs
+++ /dev/null
@@ -1,168 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Tests for the liblouis Native Client wrapper, as seen from
- * the JavaScript interface.
- */
-
-// Include test fixture.
-GEN_INCLUDE(['../testing/chromevox_e2e_test_base.js',
- '../testing/assert_additions.js']);
-
-/**
- * @constructor
- * @extends {ChromeVoxE2ETest}
- */
-function CvoxLibLouisTest() {
- ChromeVoxE2ETest.call(this);
-}
-
-CvoxLibLouisTest.prototype = {
- __proto__: ChromeVoxE2ETest.prototype,
-
- createLiblouis: function() {
- return new cvox.LibLouis(
- chrome.extension.getURL('braille/liblouis_nacl.nmf'),
- chrome.extension.getURL('braille/tables'));
- },
-
- createAndAttachLiblouis: function() {
- var liblouis = this.createLiblouis();
- liblouis.attachToElement(document.body);
- return liblouis;
- },
-
- withTranslator: function(liblouis, tableNames, callback) {
- liblouis.getTranslator(tableNames, this.newCallback(callback));
- },
-};
-
-function assertEqualsUint8Array(expected, actual) {
- var as_array = [];
- var uint8array = new Uint8Array(actual);
- for (var i = 0; i < uint8array.length; ++i) {
- as_array[i] = uint8array[i];
- }
- assertEqualsJSON(expected, as_array);
-}
-
-TEST_F('CvoxLibLouisTest', 'checkAllTables', function() {
- var liblouis = this.createAndAttachLiblouis();
- cvox.BrailleTable.getAll(this.newCallback(function(tables) {
- var i = 0;
- var checkNextTable = function() {
- var table = tables[i++];
- if (table) {
- this.withTranslator(liblouis, table.fileNames, function(translator) {
- assertNotEquals(null, translator,
- 'Table ' + table + ' should be valid');
- checkNextTable();
- });
- }
- }.bind(this);
- checkNextTable();
- }.bind(this)));
-});
-
-TEST_F('CvoxLibLouisTest', 'testTranslateComputerBraille', function() {
- var liblouis = this.createAndAttachLiblouis();
- this.withTranslator(liblouis, 'en-us-comp8.ctb', function(translator) {
- translator.translate('Hello!', this.newCallback(
- function(cells, textToBraille, brailleToText) {
- assertEqualsUint8Array([0x53, 0x11, 0x07, 0x07, 0x15, 0x2e], cells);
- assertEqualsJSON([0, 1, 2, 3, 4, 5], textToBraille);
- assertEqualsJSON([0, 1, 2, 3, 4, 5], brailleToText);
- }));
- });
-});
-
-TEST_F('CvoxLibLouisTest', 'testBackTranslateComputerBraille', function() {
- var liblouis = this.createAndAttachLiblouis();
- this.withTranslator(liblouis, 'en-us-comp8.ctb', function(translator) {
- var cells = new Uint8Array([0x53, 0x11, 0x07, 0x07, 0x15, 0x2e]);
- translator.backTranslate(cells.buffer, this.newCallback(function(text) {
- assertEquals('Hello!', text);
- }));
- });
-});
-
-TEST_F('CvoxLibLouisTest', 'testTranslateGermanGrade2Braille', function() {
- var liblouis = this.createAndAttachLiblouis();
- // This is one of the moderately large tables.
- this.withTranslator(liblouis, 'de-de-g2.ctb', function(translator) {
- translator.translate('München', this.newCallback(
- function(cells, textToBraille, brailleToText) {
- assertEqualsUint8Array([0x0d, 0x33, 0x1d, 0x39, 0x09], cells);
- assertEqualsJSON([0, 1, 2, 3, 3, 4, 4], textToBraille);
- assertEqualsJSON([0, 1, 2, 3, 5], brailleToText);
- }));
- });
-});
-
-TEST_F('CvoxLibLouisTest', 'testBackTranslateGermanComputerBraille', function() {
- var liblouis = this.createAndAttachLiblouis();
- this.withTranslator(liblouis, 'de-de-comp8.ctb', function(translator) {
- var cells = new Uint8Array([0xb3]);
- translator.backTranslate(cells.buffer, this.newCallback(function(text) {
- assertEquals('ü', text);
- }));
- });
-});
-
-TEST_F('CvoxLibLouisTest', 'testBackTranslateEmptyCells', function() {
- var liblouis = this.createAndAttachLiblouis();
- this.withTranslator(liblouis, 'de-de-comp8.ctb', function(translator) {
- translator.backTranslate(
- new Uint8Array().buffer,
- this.newCallback(function(text) {
- assertNotEquals(null, text);
- assertEquals(0, text.length);
- }));
- });
-});
-
-TEST_F('CvoxLibLouisTest', 'testGetTranslatorBeforeAttach', function() {
- var liblouis = this.createLiblouis();
- assertFalse(liblouis.isAttached());
- this.withTranslator(liblouis, 'en-us-comp8.ctb', function(translator) {
- assertEquals(null, translator);
- });
-});
-
-TEST_F('CvoxLibLouisTest', 'testGetInvalidTranslator', function() {
- var liblouis = this.createAndAttachLiblouis();
- this.withTranslator(liblouis, 'nonexistant-table', function(translator) {
- assertEquals(null, translator);
- });
-});
-
-TEST_F('CvoxLibLouisTest', 'testTranslateAfterDetach', function() {
- var liblouis = this.createAndAttachLiblouis();
- this.withTranslator(liblouis, 'de-de-comp8.ctb', function(translator) {
- liblouis.detach();
- translator.translate('Hamburg', this.newCallback(
- function(cells, textToBraille, brailleToText) {
- assertEquals(null, cells);
- assertEquals(null, textToBraille);
- assertEquals(null, brailleToText);
- }));
- });
-});
-
-TEST_F('CvoxLibLouisTest', 'testDetachWithOutstandingCallbacks', function() {
- var liblouis = this.createAndAttachLiblouis();
- this.withTranslator(liblouis, 'de-de-comp8.ctb', function(translator) {
- var called = false;
- translator.translate('Berlin', this.newCallback(
- function(cells, textToBraille, brailleToText) {
- assertEquals(null, cells);
- assertEquals(null, textToBraille);
- assertEquals(null, brailleToText);
- called = true;
- }));
- assertFalse(called);
- liblouis.detach();
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/nav_braille.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/nav_braille.js
deleted file mode 100644
index 4aaa9487ec8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/nav_braille.js
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A simple container object for the brailling of a
- * navigation from one object to another.
- *
- */
-
-
-goog.provide('cvox.NavBraille');
-
-goog.require('cvox.Spannable');
-
-/**
- * A class capturing the braille for navigation from one object to
- * another.
- * @param {{text: (undefined|string|!cvox.Spannable),
- * startIndex: (undefined|number),
- * endIndex: (undefined|number)}} kwargs The arguments for braille.
- * text The text of the object itself, including text from
- * titles, labels, etc.
- * startIndex The beginning of a selection within text.
- * endIndex The end of a selection within text.
- * @constructor
- */
-cvox.NavBraille = function(kwargs) {
- /**
- * Text, annotated with DOM nodes.
- * @type {!cvox.Spannable}
- */
- this.text = (kwargs.text instanceof cvox.Spannable) ?
- kwargs.text : new cvox.Spannable(kwargs.text);
-
- /**
- * Selection start index.
- * @type {number}
- */
- this.startIndex = goog.isDef(kwargs.startIndex) ? kwargs.startIndex : -1;
-
- /**
- * Selection end index.
- * @type {number}
- */
- this.endIndex = goog.isDef(kwargs.endIndex) ?
- kwargs.endIndex : this.startIndex;
-};
-
-/**
- * Convenience for creating simple braille output.
- * @param {string|!cvox.Spannable} text Text to represent in braille.
- * @return {!cvox.NavBraille} Braille output without a cursor.
- */
-cvox.NavBraille.fromText = function(text) {
- return new cvox.NavBraille({'text': text});
-};
-
-
-/**
- * Creates a NavBraille from its serialized json form as created
- * by toJson().
- * @param {!Object} json the serialized json object.
- * @return {!cvox.NavBraille}
- */
-cvox.NavBraille.fromJson = function(json) {
- if (typeof json.startIndex !== 'number' ||
- typeof json.endIndex !== 'number') {
- throw 'Invalid start or end index in serialized NavBraille: ' + json;
- }
- return new cvox.NavBraille({
- text: cvox.Spannable.fromJson(json.spannable),
- startIndex: json.startIndex,
- endIndex: json.endIndex
- });
-};
-
-
-/**
- * @return {boolean} true if this braille description is empty.
- */
-cvox.NavBraille.prototype.isEmpty = function() {
- return this.text.getLength() == 0;
-};
-
-
-/**
- * @return {string} A string representation of this object.
- */
-cvox.NavBraille.prototype.toString = function() {
- return 'NavBraille(text="' + this.text.toString() + '" ' +
- ' startIndex="' + this.startIndex + '" ' +
- ' endIndex="' + this.endIndex + '")';
-};
-
-
-/**
- * Returns a plain old data object with the same data.
- * Suitable for JSON encoding.
- *
- * @return {{spannable: Object,
- * startIndex: number,
- * endIndex: number}} JSON equivalent.
- */
-cvox.NavBraille.prototype.toJson = function() {
- return {
- spannable: this.text.toJson(),
- startIndex: this.startIndex,
- endIndex: this.endIndex
- };
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/pan_strategy.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/pan_strategy.js
deleted file mode 100644
index 9984b263eff..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/pan_strategy.js
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/** @fileoverview Logic for panning a braille display within a line of braille
- * content that might not fit on a single display.
- */
-
-goog.provide('cvox.PanStrategy');
-
-/**
- * @constructor
- *
- * A stateful class that keeps track of the current 'viewport' of a braille
- * display in a line of content.
- */
-cvox.PanStrategy = function() {
- /**
- * @type {number}
- * @private
- */
- this.displaySize_ = 0;
- /**
- * @type {number}
- * @private
- */
- this.contentLength_ = 0;
- /**
- * Points before which it is desirable to break content if it doesn't fit
- * on the display.
- * @type {!Array<number>}
- * @private
- */
- this.breakPoints_ = [];
- /**
- * @type {!cvox.PanStrategy.Range}
- * @private
- */
- this.viewPort_ = {start: 0, end: 0};
-};
-
-/**
- * A range used to represent the viewport with inclusive start and xclusive
- * end position.
- * @typedef {{start: number, end: number}}
- */
-cvox.PanStrategy.Range;
-
-cvox.PanStrategy.prototype = {
- /**
- * Gets the current viewport which is never larger than the current
- * display size and whose end points are always within the limits of
- * the current content.
- * @type {!cvox.PanStrategy.Range}
- */
- get viewPort() {
- return this.viewPort_;
- },
-
- /**
- * Sets the display size. This call may update the viewport.
- * @param {number} size the new display size, or {@code 0} if no display is
- * present.
- */
- setDisplaySize: function(size) {
- this.displaySize_ = size;
- this.panToPosition_(this.viewPort_.start);
- },
-
- /**
- * Sets the current content that panning should happen within. This call may
- * change the viewport.
- * @param {!ArrayBuffer} translatedContent The new content.
- * @param {number} targetPosition Target position. The viewport is changed
- * to overlap this position.
- */
- setContent: function(translatedContent, targetPosition) {
- this.breakPoints_ = this.calculateBreakPoints_(translatedContent);
- this.contentLength_ = translatedContent.byteLength;
- this.panToPosition_(targetPosition);
- },
-
- /**
- * If possible, changes the viewport to a part of the line that follows
- * the current viewport.
- * @return {boolean} {@code true} if the viewport was changed.
- */
- next: function() {
- var newStart = this.viewPort_.end;
- var newEnd;
- if (newStart + this.displaySize_ < this.contentLength_) {
- newEnd = this.extendRight_(newStart);
- } else {
- newEnd = this.contentLength_;
- }
- if (newEnd > newStart) {
- this.viewPort_ = {start: newStart, end: newEnd};
- return true;
- }
- return false;
- },
-
- /**
- * If possible, changes the viewport to a part of the line that precedes
- * the current viewport.
- * @return {boolean} {@code true} if the viewport was changed.
- */
- previous: function() {
- if (this.viewPort_.start > 0) {
- var newStart, newEnd;
- if (this.viewPort_.start <= this.displaySize_) {
- newStart = 0;
- newEnd = this.extendRight_(newStart);
- } else {
- newEnd = this.viewPort_.start;
- var limit = newEnd - this.displaySize_;
- newStart = limit;
- var pos = 0;
- while (pos < this.breakPoints_.length &&
- this.breakPoints_[pos] < limit) {
- pos++;
- }
- if (pos < this.breakPoints_.length &&
- this.breakPoints_[pos] < newEnd) {
- newStart = this.breakPoints_[pos];
- }
- }
- if (newStart < newEnd) {
- this.viewPort_ = {start: newStart, end: newEnd};
- return true;
- }
- }
- return false;
- },
-
- /**
- * Finds the end position for a new viewport start position, considering
- * current breakpoints as well as display size and content length.
- * @param {number} from Start of the region to extend.
- * @return {number}
- * @private
- */
- extendRight_: function(from) {
- var limit = Math.min(from + this.displaySize_, this.contentLength_);
- var pos = 0;
- var result = limit;
- while (pos < this.breakPoints_.length && this.breakPoints_[pos] <= from) {
- pos++;
- }
- while (pos < this.breakPoints_.length && this.breakPoints_[pos] <= limit) {
- result = this.breakPoints_[pos];
- pos++;
- }
- return result;
- },
-
- /**
- * Overridden by subclasses to provide breakpoints given translated
- * braille cell content.
- * @param {!ArrayBuffer} content New display content.
- * @return {!Array<number>} The points before which it is desirable to break
- * content if needed or the empty array if no points are more desirable
- * than any position.
- * @private
- */
- calculateBreakPoints_: function(content) {return [];},
-
- /**
- * Moves the viewport so that it overlaps a target position without taking
- * the current viewport position into consideration.
- * @param {number} position Target position.
- */
- panToPosition_: function(position) {
- if (this.displaySize_ > 0) {
- this.viewPort_ = {start: 0, end: 0};
- while (this.next() && this.viewPort_.end <= position) {
- // Nothing to do.
- }
- } else {
- this.viewPort_ = {start: position, end: position};
- }
- },
-};
-
-/**
- * A pan strategy that fits as much content on the display as possible, that
- * is, it doesn't do any wrapping.
- * @constructor
- * @extends {cvox.PanStrategy}
- */
-cvox.FixedPanStrategy = cvox.PanStrategy;
-/**
- * A pan strategy that tries to wrap 'words' when breaking content.
- * A 'word' in this context is just a chunk of non-blank braille cells
- * delimited by blank cells.
- * @constructor
- * @extends {cvox.PanStrategy}
- */
-cvox.WrappingPanStrategy = function() {
- cvox.PanStrategy.call(this);
-};
-
-cvox.WrappingPanStrategy.prototype = {
- __proto__: cvox.PanStrategy.prototype,
-
- /** @override */
- calculateBreakPoints_: function(content) {
- var view = new Uint8Array(content);
- var newContentLength = view.length;
- var result = [];
- var lastCellWasBlank = false;
- for (var pos = 0; pos < view.length; ++pos) {
- if (lastCellWasBlank && view[pos] != 0) {
- result.push(pos);
- }
- lastCellWasBlank = (view[pos] == 0);
- }
- return result;
- },
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/pan_strategy_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/braille/pan_strategy_test.unitjs
deleted file mode 100644
index 3c7464888ea..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/pan_strategy_test.unitjs
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxPanStrategyUnitTest() {}
-
-CvoxPanStrategyUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.PanStrategy',
- ],
-};
-
-/**
- * @param {string} content String representing the content with spaces
- * representing blank cells and any other character representing
- * arbitrary non-blank cells.
- */
-function createArrayBuffer(content) {
- var result = new ArrayBuffer(content.length);
- var view = new Uint8Array(result);
- for (var i = 0; i < content.length; ++i) {
- view[i] = (content[i] != ' ' ? 1 : 0);
- }
- return result;
-}
-
- TEST_F('CvoxPanStrategyUnitTest', 'FixedPanning', function() {
- var panner = new cvox.FixedPanStrategy();
-
- panner.setDisplaySize(0);
- panner.setContent(createArrayBuffer(''), 0);
- assertEqualsJSON({start: 0, end: 0}, panner.viewPort);
- assertFalse(panner.previous());
- assertFalse(panner.next());
-
- // 25 cells with a blank cell in the first 10 characters.
- var content = createArrayBuffer('01234567 9012345678901234');
- panner.setContent(content, 0);
- assertEqualsJSON({start: 0, end: 0}, panner.viewPort);
- assertFalse(panner.next());
- assertFalse(panner.previous());
-
- panner.setDisplaySize(10);
- assertEqualsJSON({start: 0, end: 10}, panner.viewPort);
- assertTrue(panner.next());
- assertEqualsJSON({start: 10, end: 20}, panner.viewPort);
- assertTrue(panner.next());
- assertEqualsJSON({start: 20, end: 25}, panner.viewPort);
- assertFalse(panner.next());
- assertEqualsJSON({start: 20, end: 25}, panner.viewPort);
- assertTrue(panner.previous());
- assertEqualsJSON({start: 10, end: 20}, panner.viewPort);
- assertTrue(panner.previous());
- assertEqualsJSON({start: 0, end: 10}, panner.viewPort);
-
- panner.setContent(content, 19);
- assertEqualsJSON({start: 10, end: 20}, panner.viewPort);
-
- panner.setContent(content, 20);
- assertEqualsJSON({start: 20, end: 25}, panner.viewPort);
-
- panner.setDisplaySize(8);
- assertEqualsJSON({start: 16, end: 24}, panner.viewPort);
-
- panner.viewPort_ = {start: 2, end: 10};
- assertTrue(panner.previous());
- assertEqualsJSON({start: 0, end: 8}, panner.viewPort);
-});
-
-TEST_F('CvoxPanStrategyUnitTest', 'WrappedPanning', function() {
- var panner = new cvox.WrappingPanStrategy();
-
- // 30 cells with blank cells at positions 8, 22 and 26.
- var content = createArrayBuffer('01234567 9012345678901 345 789');
- panner.setContent(content, 0);
- assertEqualsJSON({start: 0, end: 0}, panner.viewPort);
- assertFalse(panner.next());
- assertFalse(panner.previous());
-
- panner.setDisplaySize(10);
- assertEqualsJSON({start: 0, end: 9}, panner.viewPort);
- assertTrue(panner.next());
- assertEqualsJSON({start: 9, end: 19}, panner.viewPort);
- assertTrue(panner.next());
- assertEqualsJSON({start: 19, end: 27}, panner.viewPort);
- assertTrue(panner.next());
- assertEqualsJSON({start: 27, end: 30}, panner.viewPort);
- assertFalse(panner.next());
- assertEqualsJSON({start: 27, end: 30}, panner.viewPort);
- assertTrue(panner.previous());
- assertEqualsJSON({start: 23, end: 27}, panner.viewPort);
- assertTrue(panner.previous());
- assertEqualsJSON({start: 13, end: 23}, panner.viewPort);
- assertTrue(panner.previous());
- assertEqualsJSON({start: 9, end: 13}, panner.viewPort);
- assertTrue(panner.previous());
- assertEqualsJSON({start: 0, end: 9}, panner.viewPort);
-
- panner.setContent(content, 21);
- assertEqualsJSON({start: 19, end: 27}, panner.viewPort);
-
- panner.setContent(content, 30);
- assertEqualsJSON({start: 27, end: 30}, panner.viewPort);
-
- panner.setDisplaySize(8);
- assertEqualsJSON({start: 23, end: 30}, panner.viewPort);
-
- panner.viewPort_ = {start: 2, end: 10};
- assertTrue(panner.previous());
- assertEqualsJSON({start: 0, end: 8}, panner.viewPort);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/braille/spans.js b/chromium/chrome/browser/resources/chromeos/chromevox/braille/spans.js
deleted file mode 100644
index 39ffea6ce8d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/braille/spans.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Objects used in spannables as annotations for ARIA values
- * and selections.
- */
-
-goog.provide('cvox.ExtraCellsSpan');
-goog.provide('cvox.ValueSelectionSpan');
-goog.provide('cvox.ValueSpan');
-
-goog.require('cvox.Spannable');
-
-/**
- * Attached to the value region of a braille spannable.
- * @param {number} offset The offset of the span into the value.
- * @constructor
- */
-cvox.ValueSpan = function(offset) {
- /**
- * The offset of the span into the value.
- * @type {number}
- */
- this.offset = offset;
-};
-
-
-/**
- * Creates a value span from a json serializable object.
- * @param {!Object} obj The json serializable object to convert.
- * @return {!cvox.ValueSpan} The value span.
- */
-cvox.ValueSpan.fromJson = function(obj) {
- return new cvox.ValueSpan(obj.offset);
-};
-
-
-/**
- * Converts this object to a json serializable object.
- * @return {!Object} The JSON representation.
- */
-cvox.ValueSpan.prototype.toJson = function() {
- return this;
-};
-
-
-cvox.Spannable.registerSerializableSpan(
- cvox.ValueSpan,
- 'cvox.ValueSpan',
- cvox.ValueSpan.fromJson,
- cvox.ValueSpan.prototype.toJson);
-
-
-/**
- * Attached to the selected text within a value.
- * @constructor
- */
-cvox.ValueSelectionSpan = function() {
-};
-
-
-cvox.Spannable.registerStatelessSerializableSpan(
- cvox.ValueSelectionSpan,
- 'cvox.ValueSelectionSpan');
-
-
-/**
- * Causes raw cells to be added when translating from text to braille.
- * This is supported by the {@code cvox.ExpandingBrailleTranslator}
- * class.
- * @constructor
- */
-cvox.ExtraCellsSpan = function() {
- /** @type {ArrayBuffer} */
- this.cells = new Uint8Array(0).buffer;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gni b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gni
deleted file mode 100644
index 99c15e1597b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gni
+++ /dev/null
@@ -1,203 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-# Common variables shared amongst all ChromeVox targets.
-
-assert(is_chromeos)
-
-# TODO(plundblad): Move the below variables to BUILD.gn when crbug.com/395883
-# is resolved.
-
-closure_library_dir =
- "//chrome/third_party/chromevox/third_party/closure-library/closure/goog"
-
-jsbundler_modules = rebase_path([
- "depstree.py",
- "source.py",
- "treescan.py",
- ],
- ".",
- "$closure_library_dir/../bin/build")
-jsbundler_modules += [ "//third_party/WebKit/Source/build/scripts/rjsmin.py" ]
-
-# List of all modules that are included in one or more of the production
-# chromevox scripts.
-chromevox_modules = [
- "braille/braille_display_manager.js",
- "braille/braille_input_handler.js",
- "braille/braille_key_types.js",
- "braille/braille_table.js",
- "braille/braille_translator_manager.js",
- "braille/expanding_braille_translator.js",
- "braille/liblouis.js",
- "braille/nav_braille.js",
- "braille/pan_strategy.js",
- "braille/spans.js",
- "chromevox/background/background.js",
- "chromevox/background/braille_captions_background.js",
- "chromevox/background/injected_script_loader.js",
- "chromevox/background/kbexplorer.js",
- "chromevox/background/keymaps/key_map.js",
- "chromevox/background/mathmaps/math_map.js",
- "chromevox/background/options.js",
- "chromevox/background/prefs.js",
- "chromevox/background/tabs_api_handler.js",
- "chromevox/injected/active_indicator.js",
- "chromevox/injected/api_implementation.js",
- "chromevox/injected/api_util.js",
- "chromevox/injected/console_tts.js",
- "chromevox/injected/event_suspender.js",
- "chromevox/injected/event_watcher.js",
- "chromevox/injected/history.js",
- "chromevox/injected/init_document.js",
- "chromevox/injected/init_globals.js",
- "chromevox/injected/initial_speech.js",
- "chromevox/injected/keyboard_handler.js",
- "chromevox/injected/live_regions.js",
- "chromevox/injected/navigation_history.js",
- "chromevox/injected/navigation_manager.js",
- "chromevox/injected/navigation_shifter.js",
- "chromevox/injected/navigation_speaker.js",
- "chromevox/injected/node_breadcrumb.js",
- "chromevox/injected/pdf_processor.js",
- "chromevox/injected/script_installer.js",
- "chromevox/injected/serializer.js",
- "chromevox/injected/ui/braille_overlay_widget.js",
- "chromevox/injected/ui/context_menu_widget.js",
- "chromevox/injected/ui/keyboard_help_widget.js",
- "chromevox/injected/ui/node_search_widget.js",
- "chromevox/injected/ui/overlay_widget.js",
- "chromevox/injected/ui/search_widget.js",
- "chromevox/injected/ui/select_widget.js",
- "chromevox/injected/ui/spoken_messages.js",
- "chromevox/injected/ui/widget.js",
- "chromevox/injected/user_commands.js",
- "chromevox/injected/user_event_detail.js",
- "common/aria_util.js",
- "common/aural_style_util.js",
- "common/braille_text_handler.js",
- "common/braille_util.js",
- "common/buildinfo.js",
- "common/chromevox.js",
- "common/chromevox_json.js",
- "common/command_store.js",
- "common/composite_tts.js",
- "common/content_editable_extractor.js",
- "common/cursor.js",
- "common/cursor_selection.js",
- "common/date_widget.js",
- "common/description_util.js",
- "common/dom_predicates.js",
- "common/dom_util.js",
- "common/earcon_util.js",
- "common/editable_text.js",
- "common/editable_text_area_shadow.js",
- "common/editable_text_base.js",
- "common/find_util.js",
- "common/focus_util.js",
- "common/focuser.js",
- "common/group_util.js",
- "common/interframe.js",
- "common/key_sequence.js",
- "common/key_util.js",
- "common/math_semantic_attr.js",
- "common/math_semantic_tree.js",
- "common/math_semantic_util.js",
- "common/math_util.js",
- "common/media_widget.js",
- "common/memoize.js",
- "common/msgs.js",
- "common/nav_description.js",
- "common/nav_math_description.js",
- "common/node_state.js",
- "common/page_selection.js",
- "common/platform_util.js",
- "common/selection_util.js",
- "common/spannable.js",
- "common/string_util.js",
- "common/table_util.js",
- "common/time_widget.js",
- "common/traverse_content.js",
- "common/traverse_math.js",
- "common/traverse_table.js",
- "common/traverse_util.js",
- "common/xpath_util.js",
- "cvox2/background/automation_predicate.js",
- "cvox2/background/automation_util.js",
- "cvox2/background/background.js",
- "cvox2/background/classic_compatibility.js",
- "cvox2/background/cursors.js",
- "cvox2/background/earcon_engine.js",
- "cvox2/background/output.js",
- "extensions/searchvox/abstract_result.js",
- "extensions/searchvox/constants.js",
- "extensions/searchvox/context_menu.js",
- "extensions/searchvox/loader.js",
- "extensions/searchvox/results.js",
- "extensions/searchvox/search.js",
- "extensions/searchvox/search_tools.js",
- "extensions/searchvox/util.js",
- "host/chrome/braille.js",
- "host/chrome/braille_background.js",
- "host/chrome/earcons.js",
- "host/chrome/earcons_background.js",
- "host/chrome/extension_bridge.js",
- "host/chrome/host.js",
- "host/chrome/mathjax.js",
- "host/chrome/tts.js",
- "host/chrome/tts_background.js",
- "host/chrome/tts_base.js",
- "host/interface/abstract_earcons.js",
- "host/interface/abstract_host.js",
- "host/interface/abstract_mathjax.js",
- "host/interface/abstract_tts.js",
- "host/interface/braille_interface.js",
- "host/interface/host_factory.js",
- "host/interface/mathjax_interface.js",
- "host/interface/tts_interface.js",
- "speech_rules/base_rule_store.js",
- "speech_rules/math_simple_store.js",
- "speech_rules/math_store.js",
- "speech_rules/mathml_store.js",
- "speech_rules/mathml_store_rules.js",
- "speech_rules/mathml_store_util.js",
- "speech_rules/speech_rule.js",
- "speech_rules/speech_rule_engine.js",
- "speech_rules/speech_rule_evaluator.js",
- "speech_rules/speech_rule_functions.js",
- "speech_rules/speech_rule_store.js",
- "speech_rules/store_util.js",
- "walkers/abstract_node_walker.js",
- "walkers/abstract_selection_walker.js",
- "walkers/abstract_shifter.js",
- "walkers/abstract_walker.js",
- "walkers/bare_object_walker.js",
- "walkers/character_walker.js",
- "walkers/column_walker.js",
- "walkers/group_walker.js",
- "walkers/layout_line_walker.js",
- "walkers/math_shifter.js",
- "walkers/object_walker.js",
- "walkers/row_walker.js",
- "walkers/sentence_walker.js",
- "walkers/structural_line_walker.js",
- "walkers/table_shifter.js",
- "walkers/table_walker.js",
- "walkers/word_walker.js",
-]
-
-# Closure library modules neede by chromevox.
-relative_closure_library_modules = [
- "i18n/pluralrules.js",
- "i18n/ordinalrules.js",
- "i18n/messageformat.js",
- "string/string.js",
- "dom/nodetype.js",
- "base.js",
- "asserts/asserts.js",
- "debug/error.js",
- "object/object.js",
-]
-
-closure_library_modules =
- rebase_path(relative_closure_library_modules, ".", closure_library_dir)
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gyp b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gyp
index 94b33f14d26..5406faf0718 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gyp
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox.gyp
@@ -44,10 +44,12 @@
}],
['chromevox_compress_js==1', {
'dependencies': [
- 'chromevox1_content_script',
- 'chromevox1_kbexplorer_script',
- 'chromevox1_options_script',
- 'chromevox2_background_script',
+ 'chromevox_background_script',
+ 'chromevox_content_script',
+ 'chromevox_kbexplorer_script',
+ 'chromevox_min_content_script',
+ 'chromevox_options_script',
+ 'chromevox_panel_script',
],
}, { # chromevox_compress_js==0
'dependencies': [
@@ -72,6 +74,7 @@
'destination': '<(chromevox_dest_dir)/cvox2/background',
'files': [
'cvox2/background/background.html',
+ 'cvox2/background/panel.html',
],
},
],
@@ -134,10 +137,11 @@
'deps_js_output_file': '<(chromevox_dest_dir)/deps.js',
},
'sources': [
- '<(chromevox1_content_script_loader_file)',
- '<(chromevox1_kbexplorer_loader_file)',
- '<(chromevox1_options_script_loader_file)',
- '<(chromevox2_background_script_loader_file)',
+ '<(chromevox_content_script_loader_file)',
+ '<(chromevox_kbexplorer_loader_file)',
+ '<(chromevox_options_script_loader_file)',
+ '<(chromevox_background_script_loader_file)',
+ '<(chromevox_panel_script_loader_file)',
],
'includes': ['generate_deps.gypi'],
},
@@ -163,43 +167,61 @@
['chromevox_compress_js==1', {
'targets': [
{
- 'target_name': 'chromevox1_content_script',
+ 'target_name': 'chromevox_content_script',
'type': 'none',
'variables': {
'output_file': '<(chromevox_dest_dir)/chromeVoxChromePageScript.js',
},
- 'sources': [ '<(chromevox1_content_script_loader_file)' ],
+ 'sources': [ '<(chromevox_content_script_loader_file)' ],
'includes': [ 'compress_js.gypi', ],
},
{
- 'target_name': 'chromevox1_options_script',
+ 'target_name': 'chromevox_options_script',
'type': 'none',
'variables': {
'output_file': '<(chromevox_dest_dir)/chromeVoxChromeOptionsScript.js',
},
- 'sources': [ '<(chromevox1_options_script_loader_file)' ],
+ 'sources': [ '<(chromevox_options_script_loader_file)' ],
'includes': [ 'compress_js.gypi', ],
},
{
- 'target_name': 'chromevox1_kbexplorer_script',
+ 'target_name': 'chromevox_kbexplorer_script',
'type': 'none',
'variables': {
'output_file': '<(chromevox_dest_dir)/chromeVoxKbExplorerScript.js',
},
- 'sources': [ '<(chromevox1_kbexplorer_loader_file)' ],
+ 'sources': [ '<(chromevox_kbexplorer_loader_file)' ],
'includes': [ 'compress_js.gypi', ],
},
{
- 'target_name': 'chromevox2_background_script',
+ 'target_name': 'chromevox_background_script',
'type': 'none',
'variables': {
'output_file': '<(chromevox_dest_dir)/chromeVox2ChromeBackgroundScript.js',
},
'sources': [
- '<(chromevox2_background_script_loader_file)',
+ '<(chromevox_background_script_loader_file)',
],
'includes': [ 'compress_js.gypi', ],
},
+ {
+ 'target_name': 'chromevox_panel_script',
+ 'type': 'none',
+ 'variables': {
+ 'output_file': '<(chromevox_dest_dir)/chromeVoxPanelScript.js',
+ },
+ 'sources': [ '<(chromevox_panel_script_loader_file)' ],
+ 'includes': [ 'compress_js.gypi', ],
+ },
+ {
+ 'target_name': 'chromevox_min_content_script',
+ 'type': 'none',
+ 'variables': {
+ 'output_file': '<(chromevox_dest_dir)/chromeVox2ChromePageScript.js',
+ },
+ 'sources': [ '<(chromevox_min_content_script_loader_file)' ],
+ 'includes': [ 'compress_js.gypi', ],
+ },
],
}, { # chromevox_compress_js==0
'targets': [
@@ -210,10 +232,11 @@
'dest_dir': '<(chromevox_dest_dir)',
},
'sources': [
- '<(chromevox1_content_script_loader_file)',
- '<(chromevox1_kbexplorer_loader_file)',
- '<(chromevox1_options_script_loader_file)',
- '<(chromevox2_background_script_loader_file)',
+ '<(chromevox_content_script_loader_file)',
+ '<(chromevox_kbexplorer_loader_file)',
+ '<(chromevox_options_script_loader_file)',
+ '<(chromevox_background_script_loader_file)',
+ '<(chromevox_panel_script_loader_file)',
],
'includes': [ 'copy_js.gypi', ],
},
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.html b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.html
deleted file mode 100644
index ede68f23d92..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<script src="../../closure/base.js"></script>
-<script src="../../deps.js"></script>
-<script src="loader.js"></script>
-
-<script src="../../chromeVoxChromeBackgroundScript.js"></script>
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js
deleted file mode 100644
index 9393c4ad33b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js
+++ /dev/null
@@ -1,472 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Script that runs on the background page.
- */
-
-goog.provide('cvox.ChromeVoxBackground');
-
-goog.require('Msgs');
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.BrailleBackground');
-goog.require('cvox.BrailleCaptionsBackground');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxEditableTextBase');
-goog.require('cvox.ChromeVoxPrefs');
-goog.require('cvox.CompositeTts');
-goog.require('cvox.ConsoleTts');
-goog.require('cvox.EarconsBackground');
-goog.require('cvox.ExtensionBridge');
-goog.require('cvox.HostFactory');
-goog.require('cvox.InjectedScriptLoader');
-goog.require('cvox.NavBraille');
-// TODO(dtseng): This is required to prevent Closure from stripping our export
-// prefs on window.
-goog.require('cvox.OptionsPage');
-goog.require('cvox.PlatformFilter');
-goog.require('cvox.PlatformUtil');
-goog.require('cvox.QueueMode');
-goog.require('cvox.TabsApiHandler');
-goog.require('cvox.TtsBackground');
-
-
-/**
- * This object manages the global and persistent state for ChromeVox.
- * It listens for messages from the content scripts on pages and
- * interprets them.
- * @constructor
- */
-cvox.ChromeVoxBackground = function() {
-};
-
-
-/**
- * Initialize the background page: set up TTS and bridge listeners.
- */
-cvox.ChromeVoxBackground.prototype.init = function() {
- // In the case of ChromeOS, only continue initialization if this instance of
- // ChromeVox is as we expect. This prevents ChromeVox from the webstore from
- // running.
- if (cvox.ChromeVox.isChromeOS &&
- chrome.i18n.getMessage('@@extension_id') !=
- 'mndnfokpggljbaajbnioimlmbfngpief') {
- return;
- }
-
- this.prefs = new cvox.ChromeVoxPrefs();
- this.readPrefs();
-
- var consoleTts = cvox.ConsoleTts.getInstance();
- consoleTts.setEnabled(true);
-
- /**
- * Chrome's actual TTS which knows and cares about pitch, volume, etc.
- * @type {cvox.TtsBackground}
- * @private
- */
- this.backgroundTts_ = new cvox.TtsBackground();
-
- /**
- * @type {cvox.TtsInterface}
- */
- this.tts = new cvox.CompositeTts()
- .add(this.backgroundTts_)
- .add(consoleTts);
-
- this.earcons = new cvox.EarconsBackground();
- this.addBridgeListener();
-
- /**
- * The actual Braille service.
- * @type {cvox.BrailleBackground}
- * @private
- */
- this.backgroundBraille_ = new cvox.BrailleBackground();
-
- this.tabsApiHandler_ = new cvox.TabsApiHandler(
- this.tts, this.backgroundBraille_, this.earcons);
-
- // Export globals on cvox.ChromeVox.
- cvox.ChromeVox.tts = this.tts;
- cvox.ChromeVox.braille = this.backgroundBraille_;
- cvox.ChromeVox.earcons = this.earcons;
-
- if (cvox.ChromeVox.isChromeOS &&
- chrome.accessibilityPrivate.onIntroduceChromeVox) {
- chrome.accessibilityPrivate.onIntroduceChromeVox.addListener(
- this.onIntroduceChromeVox);
- }
-
- // Set up a message passing system for goog.provide() calls from
- // within the content scripts.
- chrome.extension.onMessage.addListener(
- function(request, sender, callback) {
- if (request['srcFile']) {
- var srcFile = request['srcFile'];
- cvox.InjectedScriptLoader.fetchCode(
- [srcFile],
- function(code) {
- callback({'code': code[srcFile]});
- });
- }
- return true;
- });
-
- var self = this;
-
- // Inject the content script into all running tabs.
- chrome.windows.getAll({'populate': true}, function(windows) {
- for (var i = 0; i < windows.length; i++) {
- var tabs = windows[i].tabs;
- self.injectChromeVoxIntoTabs(tabs);
- }
- });
-
- if (localStorage['active'] == 'false') {
- // Warn the user when the browser first starts if ChromeVox is inactive.
- this.tts.speak(Msgs.getMsg('chromevox_inactive'),
- cvox.QueueMode.QUEUE);
- } else if (cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.WML)) {
- // Introductory message.
- this.tts.speak(Msgs.getMsg('chromevox_intro'),
- cvox.QueueMode.QUEUE);
- cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(
- Msgs.getMsg('intro_brl')));
- }
-};
-
-
-/**
- * Inject ChromeVox into a tab.
- * @param {Array<Tab>} tabs The tab where ChromeVox scripts should be injected.
- */
-cvox.ChromeVoxBackground.prototype.injectChromeVoxIntoTabs = function(tabs) {
- var listOfFiles;
-
- // These lists of files must match the content_scripts section in
- // the manifest files.
- if (COMPILED) {
- listOfFiles = ['chromeVoxChromePageScript.js'];
- } else {
- listOfFiles = [
- 'closure/closure_preinit.js',
- 'closure/base.js',
- 'deps.js',
- 'chromevox/injected/loader.js'];
- }
-
- var stageTwo = function(code) {
- for (var i = 0, tab; tab = tabs[i]; i++) {
- window.console.log('Injecting into ' + tab.id, tab);
- var sawError = false;
-
- /**
- * A helper function which executes code.
- * @param {string} code The code to execute.
- */
- var executeScript = goog.bind(function(code) {
- chrome.tabs.executeScript(
- tab.id,
- {'code': code,
- 'allFrames': true},
- goog.bind(function() {
- if (!chrome.extension.lastError) {
- return;
- }
- if (sawError) {
- return;
- }
- sawError = true;
- console.error('Could not inject into tab', tab);
- this.tts.speak('Error starting ChromeVox for ' +
- tab.title + ', ' + tab.url, cvox.QueueMode.QUEUE);
- }, this));
- }, this);
-
- // There is a scenario where two copies of the content script can get
- // loaded into the same tab on browser startup - one automatically and one
- // because the background page injects the content script into every tab
- // on startup. To work around potential bugs resulting from this,
- // ChromeVox exports a global function called disableChromeVox() that can
- // be used here to disable any existing running instance before we inject
- // a new instance of the content script into this tab.
- //
- // It's harmless if there wasn't a copy of ChromeVox already running.
- //
- // Also, set some variables so that Closure deps work correctly and so
- // that ChromeVox knows not to announce feedback as if a page just loaded.
- executeScript('try { window.disableChromeVox(); } catch(e) { }\n' +
- 'window.INJECTED_AFTER_LOAD = true;\n' +
- 'window.CLOSURE_NO_DEPS = true\n');
-
- // Now inject the ChromeVox content script code into the tab.
- listOfFiles.forEach(function(file) { executeScript(code[file]); });
- }
- };
-
- // We use fetchCode instead of chrome.extensions.executeFile because
- // executeFile doesn't propagate the file name to the content script
- // which means that script is not visible in Dev Tools.
- cvox.InjectedScriptLoader.fetchCode(listOfFiles, stageTwo);
-};
-
-
-/**
- * Called when a TTS message is received from a page content script.
- * @param {Object} msg The TTS message.
- */
-cvox.ChromeVoxBackground.prototype.onTtsMessage = function(msg) {
- if (msg['action'] == 'speak') {
- this.tts.speak(msg['text'],
- /** cvox.QueueMode */msg['queueMode'],
- msg['properties']);
- } else if (msg['action'] == 'stop') {
- this.tts.stop();
- } else if (msg['action'] == 'increaseOrDecrease') {
- this.tts.increaseOrDecreaseProperty(msg['property'], msg['increase']);
- var property = msg['property'];
- var engine = this.backgroundTts_;
- var valueAsPercent = Math.round(
- this.backgroundTts_.propertyToPercentage(property) * 100);
- var announcement;
- switch (msg['property']) {
- case cvox.AbstractTts.RATE:
- announcement = Msgs.getMsg('announce_rate',
- [valueAsPercent]);
- break;
- case cvox.AbstractTts.PITCH:
- announcement = Msgs.getMsg('announce_pitch',
- [valueAsPercent]);
- break;
- case cvox.AbstractTts.VOLUME:
- announcement = Msgs.getMsg('announce_volume',
- [valueAsPercent]);
- break;
- }
- if (announcement) {
- this.tts.speak(announcement,
- cvox.QueueMode.FLUSH,
- cvox.AbstractTts.PERSONALITY_ANNOTATION);
- }
- } else if (msg['action'] == 'cyclePunctuationEcho') {
- this.tts.speak(Msgs.getMsg(
- this.backgroundTts_.cyclePunctuationEcho()),
- cvox.QueueMode.FLUSH);
- }
-};
-
-
-/**
- * Called when an earcon message is received from a page content script.
- * @param {Object} msg The earcon message.
- */
-cvox.ChromeVoxBackground.prototype.onEarconMessage = function(msg) {
- if (msg.action == 'play') {
- this.earcons.playEarcon(msg.earcon);
- }
-};
-
-
-/**
- * Listen for connections from our content script bridges, and dispatch the
- * messages to the proper destination.
- */
-cvox.ChromeVoxBackground.prototype.addBridgeListener = function() {
- cvox.ExtensionBridge.addMessageListener(goog.bind(function(msg, port) {
- var target = msg['target'];
- var action = msg['action'];
-
- switch (target) {
- case 'OpenTab':
- var destination = {url: msg['url']};
- chrome.tabs.create(destination);
- break;
- case 'KbExplorer':
- var explorerPage = {url: 'chromevox/background/kbexplorer.html'};
- chrome.tabs.create(explorerPage);
- break;
- case 'HelpDocs':
- var helpPage = {url: 'http://chromevox.com/tutorial/index.html'};
- chrome.tabs.create(helpPage);
- break;
- case 'Options':
- if (action == 'open') {
- var optionsPage = {url: 'chromevox/background/options.html'};
- chrome.tabs.create(optionsPage);
- }
- break;
- case 'Data':
- if (action == 'getHistory') {
- var results = {};
- chrome.history.search({text: '', maxResults: 25}, function(items) {
- items.forEach(function(item) {
- if (item.url) {
- results[item.url] = true;
- }
- });
- port.postMessage({
- 'history': results
- });
- });
- }
- break;
- case 'Prefs':
- if (action == 'getPrefs') {
- this.prefs.sendPrefsToPort(port);
- } else if (action == 'setPref') {
- if (msg['pref'] == 'active' &&
- msg['value'] != cvox.ChromeVox.isActive) {
- if (cvox.ChromeVox.isActive) {
- this.tts.speak(Msgs.getMsg('chromevox_inactive'),
- cvox.QueueMode.FLUSH);
- chrome.accessibilityPrivate.setNativeAccessibilityEnabled(
- true);
- } else {
- chrome.accessibilityPrivate.setNativeAccessibilityEnabled(
- false);
- }
- } else if (msg['pref'] == 'earcons') {
- this.earcons.enabled = msg['value'];
- } else if (msg['pref'] == 'sticky' && msg['announce']) {
- if (msg['value']) {
- this.tts.speak(Msgs.getMsg('sticky_mode_enabled'),
- cvox.QueueMode.QUEUE);
- } else {
- this.tts.speak(
- Msgs.getMsg('sticky_mode_disabled'),
- cvox.QueueMode.QUEUE);
- }
- } else if (msg['pref'] == 'typingEcho' && msg['announce']) {
- var announce = '';
- switch (msg['value']) {
- case cvox.TypingEcho.CHARACTER:
- announce = Msgs.getMsg('character_echo');
- break;
- case cvox.TypingEcho.WORD:
- announce = Msgs.getMsg('word_echo');
- break;
- case cvox.TypingEcho.CHARACTER_AND_WORD:
- announce = Msgs.getMsg('character_and_word_echo');
- break;
- case cvox.TypingEcho.NONE:
- announce = Msgs.getMsg('none_echo');
- break;
- default:
- break;
- }
- if (announce) {
- this.tts.speak(announce, cvox.QueueMode.QUEUE);
- }
- } else if (msg['pref'] == 'brailleCaptions') {
- cvox.BrailleCaptionsBackground.setActive(msg['value']);
- }
- this.prefs.setPref(msg['pref'], msg['value']);
- this.readPrefs();
- }
- break;
- case 'Math':
- // TODO (sorge): Put the change of styles etc. here!
- if (msg['action'] == 'getDomains') {
- port.postMessage({'message': 'DOMAINS_STYLES',
- 'domains': this.backgroundTts_.mathmap.allDomains,
- 'styles': this.backgroundTts_.mathmap.allStyles});
- }
- break;
- case 'TTS':
- if (msg['startCallbackId'] != undefined) {
- msg['properties']['startCallback'] = function(opt_cleanupOnly) {
- port.postMessage({'message': 'TTS_CALLBACK',
- 'cleanupOnly': opt_cleanupOnly,
- 'id': msg['startCallbackId']});
- };
- }
- if (msg['endCallbackId'] != undefined) {
- msg['properties']['endCallback'] = function(opt_cleanupOnly) {
- port.postMessage({'message': 'TTS_CALLBACK',
- 'cleanupOnly': opt_cleanupOnly,
- 'id': msg['endCallbackId']});
- };
- }
- try {
- this.onTtsMessage(msg);
- } catch (err) {
- console.log(err);
- }
- break;
- case 'EARCON':
- this.onEarconMessage(msg);
- break;
- case 'BRAILLE':
- try {
- this.backgroundBraille_.onBrailleMessage(msg);
- } catch (err) {
- console.log(err);
- }
- break;
- }
- }, this));
-};
-
-
-/**
- * Read and apply preferences that affect the background context.
- */
-cvox.ChromeVoxBackground.prototype.readPrefs = function() {
- var prefs = this.prefs.getPrefs();
- cvox.ChromeVoxEditableTextBase.useIBeamCursor =
- (prefs['useIBeamCursor'] == 'true');
- cvox.ChromeVox.isActive =
- (prefs['active'] == 'true' || cvox.ChromeVox.isChromeOS);
- cvox.ChromeVox.isStickyPrefOn = (prefs['sticky'] == 'true');
-};
-
-/**
- * Checks if we are currently in an incognito window.
- * @return {boolean} True if incognito or not within a tab context, false
- * otherwise.
- * @private
- */
-cvox.ChromeVoxBackground.prototype.isIncognito_ = function() {
- var incognito = false;
- chrome.tabs.getCurrent(function(tab) {
- // Tab is null if not called from a tab context. In that case, also consider
- // it incognito.
- incognito = tab ? tab.incognito : true;
- });
- return incognito;
-};
-
-
-/**
- * Handles the onIntroduceChromeVox event.
- */
-cvox.ChromeVoxBackground.prototype.onIntroduceChromeVox = function() {
- cvox.ChromeVox.tts.speak(Msgs.getMsg('chromevox_intro'),
- cvox.QueueMode.QUEUE,
- {doNotInterrupt: true});
- cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(
- Msgs.getMsg('intro_brl')));
-};
-
-
-// Create the background page object and export a function window['speak']
-// so that other background pages can access it. Also export the prefs object
-// for access by the options page.
-(function() {
- var background = new cvox.ChromeVoxBackground();
- background.init();
- window['speak'] = goog.bind(background.tts.speak, background.tts);
-
- // Export the prefs object for access by the options page.
- window['prefs'] = background.prefs;
-
- // Export the braille translator manager for access by the options page.
- window['braille_translator_manager'] =
- background.backgroundBraille_.getTranslatorManager();
-
- // Export injection for ChromeVox Next.
- cvox.ChromeVox.injectChromeVoxIntoTabs =
- background.injectChromeVoxIntoTabs.bind(background);
-})();
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/braille_captions_background.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/braille_captions_background.js
deleted file mode 100644
index 2c7fa184355..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/braille_captions_background.js
+++ /dev/null
@@ -1,109 +0,0 @@
-// 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.
-
-/** @fileoverview Sends braille content to a content script if the braille
- * captions feature is enabled.
- */
-
-goog.provide('cvox.BrailleCaptionsBackground');
-
-goog.require('cvox.BrailleDisplayState');
-goog.require('cvox.ExtensionBridge');
-
-/**
- * Key set in local storage when this feature is enabled.
- * @const
- */
-cvox.BrailleCaptionsBackground.PREF_KEY = 'brailleCaptions';
-
-
-/**
- * Unicode block of braille pattern characters. A braille pattern is formed
- * from this value with the low order 8 bits set to the bits representing
- * the dots as per the ISO 11548-1 standard.
- * @const
- */
-cvox.BrailleCaptionsBackground.BRAILLE_UNICODE_BLOCK_START = 0x2800;
-
-
-/**
- * Called once to initialize the class.
- * @param {function()} stateCallback Called when the state of the captions
- * feature changes.
- */
-cvox.BrailleCaptionsBackground.init = function(stateCallback) {
- var self = cvox.BrailleCaptionsBackground;
- /**
- * @type {function()}
- * @private
- */
- self.stateCallback_ = stateCallback;
-};
-
-
-/**
- * Returns whether the braille captions feature is enabled.
- * @return {boolean}
- */
-cvox.BrailleCaptionsBackground.isEnabled = function() {
- var self = cvox.BrailleCaptionsBackground;
- return localStorage[self.PREF_KEY] === String(true);
-};
-
-
-/**
- * @param {string} text Text of the shown braille.
- * @param {ArrayBuffer} cells Braille cells shown on the display.
- */
-cvox.BrailleCaptionsBackground.setContent = function(text, cells) {
- var self = cvox.BrailleCaptionsBackground;
- // Convert the cells to Unicode braille pattern characters.
- var byteBuf = new Uint8Array(cells);
- var brailleChars = '';
- for (var i = 0; i < byteBuf.length; ++i) {
- brailleChars += String.fromCharCode(
- self.BRAILLE_UNICODE_BLOCK_START | byteBuf[i]);
- }
- cvox.ExtensionBridge.send({
- message: 'BRAILLE_CAPTION',
- text: text,
- brailleChars: brailleChars
- });
-};
-
-
-/**
- * Sets whether the overlay should be active.
- * @param {boolean} newValue The new value of the active flag.
- */
-cvox.BrailleCaptionsBackground.setActive = function(newValue) {
- var self = cvox.BrailleCaptionsBackground;
- var oldValue = self.isEnabled();
- window['prefs'].setPref(self.PREF_KEY, String(newValue));
- if (oldValue != newValue) {
- if (self.stateCallback_) {
- self.stateCallback_();
- }
- var msg = newValue ?
- Msgs.getMsg('braille_captions_enabled') :
- Msgs.getMsg('braille_captions_disabled');
- cvox.ChromeVox.tts.speak(msg, cvox.QueueMode.QUEUE);
- cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(msg));
- }
-};
-
-
-/**
- * Returns a display state representing the state of the captions feature.
- * This is used when no actual hardware display is connected.
- * @return {cvox.BrailleDisplayState}
- */
-cvox.BrailleCaptionsBackground.getVirtualDisplayState = function() {
- var self = cvox.BrailleCaptionsBackground;
- if (self.isEnabled()) {
- return {available: true, textCellCount: 40}; // 40, why not?
- } else {
- return {available: false};
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/alert_modal.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/alert_modal.ogg
deleted file mode 100644
index 6eb0f67d08f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/alert_modal.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/alert_nonmodal.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/alert_nonmodal.ogg
deleted file mode 100644
index baacacdc62a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/alert_nonmodal.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/button.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/button.ogg
deleted file mode 100644
index f0d40878867..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/button.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/check_off.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/check_off.ogg
deleted file mode 100644
index 86f4fe9e4da..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/check_off.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/check_on.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/check_on.ogg
deleted file mode 100644
index 9c718d048b5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/check_on.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/editable_text.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/editable_text.ogg
deleted file mode 100644
index 4e4ea3988a4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/editable_text.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/ellipsis.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/ellipsis.ogg
deleted file mode 100644
index e4e4a2bc7b7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/ellipsis.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/invalid_keypress.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/invalid_keypress.ogg
deleted file mode 100644
index 292cefdde6a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/invalid_keypress.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/link.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/link.ogg
deleted file mode 100644
index 0615568ad09..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/link.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/list_item.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/list_item.ogg
deleted file mode 100644
index f810ab89ae5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/list_item.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/listbox.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/listbox.ogg
deleted file mode 100644
index 8267c0d6fa6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/listbox.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/long_desc.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/long_desc.ogg
deleted file mode 100644
index f4e62205349..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/long_desc.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/math.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/math.ogg
deleted file mode 100644
index da293f7b7ba..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/math.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_close.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_close.ogg
deleted file mode 100644
index 0ec85524c61..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_close.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_enter.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_enter.ogg
deleted file mode 100644
index cd7dedc286c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_enter.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_exit.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_exit.ogg
deleted file mode 100644
index f203078c5f1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_exit.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_open.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_open.ogg
deleted file mode 100644
index d0a324c3bb1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_open.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_select.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_select.ogg
deleted file mode 100644
index b9fd70abceb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/object_select.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/page_finish_loading.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/page_finish_loading.ogg
deleted file mode 100644
index 40bc918f1ed..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/page_finish_loading.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/page_start_loading.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/page_start_loading.ogg
deleted file mode 100644
index e53f0dc697d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/page_start_loading.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/recover_focus.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/recover_focus.ogg
deleted file mode 100644
index 012fb57c7b5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/recover_focus.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/selection.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/selection.ogg
deleted file mode 100644
index 95dde349b72..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/selection.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/selection_reverse.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/selection_reverse.ogg
deleted file mode 100644
index 8b04e73dc77..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/selection_reverse.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/skip.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/skip.ogg
deleted file mode 100644
index 708901a7b98..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/skip.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/wrap.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/wrap.ogg
deleted file mode 100644
index edff2552372..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/wrap.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/wrap_edge.ogg b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/wrap_edge.ogg
deleted file mode 100644
index e16ad7d94b9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/earcons/wrap_edge.ogg
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/externs.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/externs.js
deleted file mode 100644
index 9b04b6d9bc9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/externs.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.
-
-// Common external variables when compiling ChromeVox background code
-
-var localStorage = {};
-
-/**
- * @type {Object}
- */
-chrome.accessibilityPrivate = {};
-
-/**
- * @param {boolean} on
- */
-chrome.accessibilityPrivate.setAccessibilityEnabled = function(on) {};
-
-/**
- * @param {boolean} on
- */
-chrome.accessibilityPrivate.setNativeAccessibilityEnabled = function(on) {
-};
-
-/**
- * @param {number} tabId
- * @param {function(Array<!Object>)} callback
- */
-chrome.accessibilityPrivate.getAlertsForTab =
- function(tabId, callback) {};
-
-/**
- * @param {Array<{left: number, top: number, width: number, height: number}>}
- * rects The bounding rects to draw focus ring(s) around, in global
- * screen coordinates.
- */
-chrome.accessibilityPrivate.setFocusRing = function(rects) {
-};
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onWindowOpened;
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onWindowClosed;
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onMenuOpened;
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onMenuClosed;
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onControlFocused;
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onControlAction;
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onControlHover;
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onTextChanged;
-
-/** @type ChromeEvent */
-chrome.accessibilityPrivate.onChromeVoxLoadStateChanged;
-/** @type {function()} */
-chrome.accessibilityPrivate.onChromeVoxLoadStateChanged.destroy_;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/injected_script_loader.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/injected_script_loader.js
deleted file mode 100644
index 1cb54c8760c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/injected_script_loader.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Responsible for loading scripts into the inject context.
- */
-
-goog.provide('cvox.InjectedScriptLoader');
-
-
-
-
-/** @constructor */
-cvox.InjectedScriptLoader = function() { };
-
-
-/**
- * Loads a dictionary of file contents for Javascript files.
- * @param {Array<string>} files A list of file names.
- * @param {function(Object<string,string>)} done A function called when all
- * the files have been loaded. Called with the code map as the first
- * parameter.
- */
-cvox.InjectedScriptLoader.fetchCode = function(files, done) {
- var code = {};
- var waiting = files.length;
- var startTime = new Date();
- var loadScriptAsCode = function(src) {
- // Load the script by fetching its source and running 'eval' on it
- // directly, with a magic comment that makes Chrome treat it like it
- // loaded normally. Wait until it's fetched before loading the
- // next script.
- var xhr = new XMLHttpRequest();
- var url = chrome.extension.getURL(src) + '?' + new Date().getTime();
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- var scriptText = xhr.responseText;
- // Add a magic comment to the bottom of the file so that
- // Chrome knows the name of the script in the JavaScript debugger.
- var debugSrc = src.replace('closure/../', '');
- // The 'chromevox' id is only used in the DevTools instead of a long
- // extension id.
- scriptText += '\n//# sourceURL= chrome-extension://chromevox/' +
- debugSrc + '\n';
- code[src] = scriptText;
- waiting--;
- if (waiting == 0) {
- done(code);
- }
- }
- };
- xhr.open('GET', url);
- xhr.send(null);
- };
-
- files.forEach(function(f) { loadScriptAsCode(f); });
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.html b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.html
deleted file mode 100644
index 468828e6fb7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE HTML>
-<!-- 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. -->
-<html>
-<head>
-<title class="i18n" msg="kbexplorer_title">Chrome OS Keyboard Explorer</title>
-<style type="text/css">
-h2 {
- font-family:arial;
-}
-</style>
-<script type="text/javascript" src="../../closure/base.js"></script>
-<script type="text/javascript" src="../../deps.js"></script>
-<script type="text/javascript" src="kbexplorer_loader.js"></script>
-
-<script type="text/javascript" src="../../chromeVoxKbExplorerScript.js"></script>
-
-</head>
-<body>
- <h2 class="i18n" msgid="kbexplorer_title">ChromeOS Keyboard Explorer</h2>
- <p class="i18n" msgid="kbexplorer_instructions">
- Press any key to learn its name. Ctrl + W will close the keyboard explorer.
- </p>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.js
deleted file mode 100644
index 730f6e7517c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Script for ChromeOS keyboard explorer.
- *
- */
-
-goog.provide('cvox.KbExplorer');
-
-goog.require('cvox.KeyUtil');
-
-
-/**
- * Class to manage the keyboard explorer.
- * @constructor
- */
-cvox.KbExplorer = function() { };
-
-
-/**
- * Initialize keyboard explorer.
- */
-cvox.KbExplorer.init = function() {
- document.addEventListener('keydown', cvox.KbExplorer.onKeyDown, false);
- document.addEventListener('keyup', cvox.KbExplorer.onKeyUp, false);
- document.addEventListener('keypress', cvox.KbExplorer.onKeyPress, false);
-};
-
-
-/**
- * Handles keydown events by speaking the human understandable name of the key.
- * @param {Event} evt key event.
- */
-cvox.KbExplorer.onKeyDown = function(evt) {
- chrome.extension.getBackgroundPage()['speak'](
- cvox.KeyUtil.getReadableNameForKeyCode(evt.keyCode), false, {});
- evt.preventDefault();
- evt.stopPropagation();
-};
-
-
-/**
- * Handles keyup events.
- * @param {Event} evt key event.
- */
-cvox.KbExplorer.onKeyUp = function(evt) {
- evt.preventDefault();
- evt.stopPropagation();
-};
-
-
-/**
- * Handles keypress events.
- * @param {Event} evt key event.
- */
-cvox.KbExplorer.onKeyPress = function(evt) {
- evt.preventDefault();
- evt.stopPropagation();
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer_loader.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer_loader.js
deleted file mode 100644
index 8d67237b0a5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer_loader.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Description of this file.
- */
-
-goog.require('cvox.KbExplorer');
-
-document.addEventListener('DOMContentLoaded', function() {
- cvox.KbExplorer.init();
-}, false);
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/classic_keymap.json b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/classic_keymap.json
index 23afe78f75c..1aec5313c7f 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/classic_keymap.json
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/classic_keymap.json
@@ -190,6 +190,11 @@
"keys": {"keyCode": [65, 65]}
}},
+ {"command": "toggleChromeVoxVersion",
+ "sequence": {"cvoxModifier": true,
+ "keys": {"keyCode": [81, 81]}
+ }},
+
{"command": "readCurrentTitle",
"sequence": {"cvoxModifier": true,
"keys": {"keyCode": [67, 84]}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/flat_keymap.json b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/flat_keymap.json
index a6cee02895e..bde46804d9a 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/flat_keymap.json
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/flat_keymap.json
@@ -604,6 +604,11 @@
"keys": {"keyCode": [115]}
}},
+ {"command": "toggleChromeVoxVersion",
+ "sequence": {"cvoxModifier": true,
+ "keys": {"keyCode": [81, 81]}
+ }},
+
{"command": "enableConsoleTts",
"sequence": {"cvoxModifier": true,
"keys": {"keyCode": [68, 67]}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/key_map.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/key_map.js
deleted file mode 100644
index c3833eca7bc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/key_map.js
+++ /dev/null
@@ -1,450 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview This class provides a stable interface for initializing,
- * querying, and modifying a ChromeVox key map.
- *
- * An instance contains an object-based bi-directional mapping from key binding
- * to a function name of a user command (herein simply called a command).
- * A caller is responsible for providing a JSON keymap (a simple Object key
- * value structure), which has (key, command) key value pairs.
- *
- * Due to execution of user commands within the content script, the function
- * name of the command is not explicitly checked within the background page via
- * Closure. Any errors would only be caught at runtime.
- *
- * To retrieve static data about user commands, see both cvox.CommandStore and
- * cvox.UserCommands.
- */
-
-goog.provide('cvox.KeyMap');
-
-// TODO(dtseng): Only needed for sticky mode.
-goog.require('cvox.KeyUtil');
-goog.require('cvox.PlatformUtil');
-
-/**
- * @param {Array<Object<{command: string, sequence: cvox.KeySequence}>>}
- * commandsAndKeySequences An array of pairs - KeySequences and commands.
- * @constructor
- */
-cvox.KeyMap = function(commandsAndKeySequences) {
- /**
- * An array of bindings - commands and KeySequences.
- * @type {Array<Object<{command: string, sequence: cvox.KeySequence}>>}
- * @private
- */
- this.bindings_ = commandsAndKeySequences;
-
- /**
- * Maps a command to a key. This optimizes the process of searching for a
- * key sequence when you already know the command.
- * @type {Object<cvox.KeySequence>}
- * @private
- */
- this.commandToKey_ = {};
- this.buildCommandToKey_();
-};
-
-
-/**
- * Path to dir containing ChromeVox keymap json definitions.
- * @type {string}
- * @const
- */
-cvox.KeyMap.KEYMAP_PATH = 'chromevox/background/keymaps/';
-
-
-/**
- * An array of available key maps sorted by priority.
- * (The first map is the default, the last is the least important).
- * TODO(dtseng): Not really sure this belongs here, but it doesn't seem to be
- * user configurable, so it doesn't make sense to json-stringify it.
- * Should have class to siwtch among and manage multiple key maps.
- * @type {Object<Object<string>>}
- * @const
- */
-cvox.KeyMap.AVAILABLE_MAP_INFO = {
-'keymap_classic': {
- 'file': 'classic_keymap.json'
- },
-'keymap_flat': {
- 'file': 'flat_keymap.json'
- },
-'keymap_experimental': {
- 'file': 'experimental.json'
- }
-};
-
-
-/**
- * The index of the default key map info in cvox.KeyMap.AVAIABLE_KEYMAP_INFO.
- * @type {number}
- * @const
- */
-cvox.KeyMap.DEFAULT_KEYMAP = 0;
-
-
-/**
- * The number of mappings in the keymap.
- * @return {number} The number of mappings.
- */
-cvox.KeyMap.prototype.length = function() {
- return this.bindings_.length;
-};
-
-
-/**
- * Returns a copy of all KeySequences in this map.
- * @return {Array<cvox.KeySequence>} Array of all keys.
- */
-cvox.KeyMap.prototype.keys = function() {
- return this.bindings_.map(function(binding) {
- return binding.sequence;
- });
-};
-
-
-/**
- * Returns a collection of command, KeySequence bindings.
- * @return {Array<Object<cvox.KeySequence>>} Array of all command, key bindings.
- * @suppress {checkTypes} inconsistent return type
- * found : (Array<(Object<{command: string,
- * sequence: (cvox.KeySequence|null)}>|null)>|null)
- * required: (Array<(Object<(cvox.KeySequence|null)>|null)>|null)
- */
-cvox.KeyMap.prototype.bindings = function() {
- return this.bindings_;
-};
-
-
-/**
- * This method is called when cvox.KeyMap instances are stringified via
- * JSON.stringify.
- * @return {string} The JSON representation of this instance.
- */
-cvox.KeyMap.prototype.toJSON = function() {
- return JSON.stringify({bindings: this.bindings_});
-};
-
-
-/**
- * Writes to local storage.
- */
-cvox.KeyMap.prototype.toLocalStorage = function() {
- localStorage['keyBindings'] = this.toJSON();
-};
-
-
-/**
- * Checks if this key map has a given binding.
- * @param {string} command The command.
- * @param {cvox.KeySequence} sequence The key sequence.
- * @return {boolean} Whether the binding exists.
- */
-cvox.KeyMap.prototype.hasBinding = function(command, sequence) {
- if (this.commandToKey_ != null) {
- return this.commandToKey_[command] == sequence;
- } else {
- for (var i = 0; i < this.bindings_.length; i++) {
- var binding = this.bindings_[i];
- if (binding.command == command && binding.sequence == sequence) {
- return true;
- }
- }
- }
- return false;
-};
-
-
-/**
- * Checks if this key map has a given command.
- * @param {string} command The command to check.
- * @return {boolean} Whether 'command' has a binding.
- */
-cvox.KeyMap.prototype.hasCommand = function(command) {
- if (this.commandToKey_ != null) {
- return this.commandToKey_[command] != undefined;
- } else {
- for (var i = 0; i < this.bindings_.length; i++) {
- var binding = this.bindings_[i];
- if (binding.command == command) {
- return true;
- }
- }
- }
- return false;
-};
-
-
-/**
- * Checks if this key map has a given key.
- * @param {cvox.KeySequence} key The key to check.
- * @return {boolean} Whether 'key' has a binding.
- */
-cvox.KeyMap.prototype.hasKey = function(key) {
- for (var i = 0; i < this.bindings_.length; i++) {
- var binding = this.bindings_[i];
- if (binding.sequence.equals(key)) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Gets a command given a key.
- * @param {cvox.KeySequence} key The key to query.
- * @return {?string} The command, if any.
- */
-cvox.KeyMap.prototype.commandForKey = function(key) {
- if (key != null) {
- for (var i = 0; i < this.bindings_.length; i++) {
- var binding = this.bindings_[i];
- if (binding.sequence.equals(key)) {
- return binding.command;
- }
- }
- }
- return null;
-};
-
-
-/**
- * Gets a key given a command.
- * @param {string} command The command to query.
- * @return {!Array<cvox.KeySequence>} The keys associated with that command,
- * if any.
- */
-cvox.KeyMap.prototype.keyForCommand = function(command) {
- if (this.commandToKey_ != null) {
- return [this.commandToKey_[command]];
- } else {
- var keySequenceArray = [];
- for (var i = 0; i < this.bindings_.length; i++) {
- var binding = this.bindings_[i];
- if (binding.command == command) {
- keySequenceArray.push(binding.sequence);
- }
- }
- }
- return (keySequenceArray.length > 0) ? keySequenceArray : [];
-};
-
-
-/**
- * Merges an input map with this one. The merge preserves this instance's
- * mappings. It only adds new bindings if there isn't one already.
- * If either the incoming binding's command or key exist in this, it will be
- * ignored.
- * @param {!cvox.KeyMap} inputMap The map to merge with this.
- * @return {boolean} True if there were no merge conflicts.
- */
-cvox.KeyMap.prototype.merge = function(inputMap) {
- var keys = inputMap.keys();
- var cleanMerge = true;
- for (var i = 0; i < keys.length; ++i) {
- var key = keys[i];
- var command = inputMap.commandForKey(key);
- if (command == 'toggleStickyMode') {
- // TODO(dtseng): More uglyness because of sticky key.
- continue;
- } else if (key && command &&
- !this.hasKey(key) && !this.hasCommand(command)) {
- this.bind_(command, key);
- } else {
- cleanMerge = false;
- }
- }
- return cleanMerge;
-};
-
-
-/**
- * Changes an existing key binding to a new key. If the key is already bound to
- * a command, the rebind will fail.
- * @param {string} command The command to set.
- * @param {cvox.KeySequence} newKey The new key to assign it to.
- * @return {boolean} Whether the rebinding succeeds.
- */
-cvox.KeyMap.prototype.rebind = function(command, newKey) {
- if (this.hasCommand(command) && !this.hasKey(newKey)) {
- this.bind_(command, newKey);
- return true;
- }
- return false;
-};
-
-
-/**
- * Changes a key binding. Any existing bindings to the given key will be
- * deleted. Use this.rebind to have non-overwrite behavior.
- * @param {string} command The command to set.
- * @param {cvox.KeySequence} newKey The new key to assign it to.
- * @private
- */
-cvox.KeyMap.prototype.bind_ = function(command, newKey) {
- // TODO(dtseng): Need unit test to ensure command is valid for every *.json
- // keymap.
- var bound = false;
- for (var i = 0; i < this.bindings_.length; i++) {
- var binding = this.bindings_[i];
- if (binding.command == command) {
- // Replace the key with the new key.
- delete binding.sequence;
- binding.sequence = newKey;
- if (this.commandToKey_ != null) {
- this.commandToKey_[binding.command] = newKey;
- }
- bound = true;
- }
- }
- if (!bound) {
- var binding = {
- 'command': command,
- 'sequence': newKey
- };
- this.bindings_.push(binding);
- this.commandToKey_[binding.command] = binding.sequence;
- }
-};
-
-
-// TODO(dtseng): Move to a manager class.
-/**
- * Convenience method for getting a default key map.
- * @return {!cvox.KeyMap} The default key map.
- */
-cvox.KeyMap.fromDefaults = function() {
- return /** @type {!cvox.KeyMap} */ (
- cvox.KeyMap.fromPath(cvox.KeyMap.KEYMAP_PATH +
- cvox.KeyMap.AVAILABLE_MAP_INFO['keymap_classic'].file));
-};
-
-
-/**
- * Convenience method for creating a key map based on a JSON (key, value) Object
- * where the key is a literal keyboard string and value is a command string.
- * @param {string} json The JSON.
- * @return {cvox.KeyMap} The resulting object; null if unable to parse.
- */
-cvox.KeyMap.fromJSON = function(json) {
- try {
- var commandsAndKeySequences =
- /** @type {Array<Object<{command: string,
- * sequence: cvox.KeySequence}>>} */
- (JSON.parse(json).bindings);
- commandsAndKeySequences = commandsAndKeySequences.filter(function(value) {
- return value.sequence.platformFilter === undefined ||
- cvox.PlatformUtil.matchesPlatform(value.sequence.platformFilter);
- });
- } catch (e) {
- return null;
- }
-
- // Validate the type of the commandsAndKeySequences array.
- if (typeof(commandsAndKeySequences) != 'object') {
- return null;
- }
- for (var i = 0; i < commandsAndKeySequences.length; i++) {
- if (commandsAndKeySequences[i].command == undefined ||
- commandsAndKeySequences[i].sequence == undefined) {
- return null;
- } else {
- commandsAndKeySequences[i].sequence = /** @type {cvox.KeySequence} */
- (cvox.KeySequence.deserialize(commandsAndKeySequences[i].sequence));
- }
- }
- return new cvox.KeyMap(commandsAndKeySequences);
-};
-
-
-/**
- * Convenience method for creating a map local storage.
- * @return {cvox.KeyMap} A map that reads from local storage.
- */
-cvox.KeyMap.fromLocalStorage = function() {
- if (localStorage['keyBindings']) {
- return cvox.KeyMap.fromJSON(localStorage['keyBindings']);
- }
- return null;
-};
-
-
-/**
- * Convenience method for creating a cvox.KeyMap based on a path.
- * Warning: you should only call this within a background page context.
- * @param {string} path A valid path of the form
- * chromevox/background/keymaps/*.json.
- * @return {cvox.KeyMap} A valid KeyMap object; null on error.
- */
-cvox.KeyMap.fromPath = function(path) {
- return cvox.KeyMap.fromJSON(cvox.KeyMap.readJSON_(path));
-};
-
-
-/**
- * Convenience method for getting a currently selected key map.
- * @return {!cvox.KeyMap} The currently selected key map.
- */
-cvox.KeyMap.fromCurrentKeyMap = function() {
- var map = localStorage['currentKeyMap'];
- if (map && cvox.KeyMap.AVAILABLE_MAP_INFO[map]) {
- return /** @type {!cvox.KeyMap} */ (cvox.KeyMap.fromPath(
- cvox.KeyMap.KEYMAP_PATH + cvox.KeyMap.AVAILABLE_MAP_INFO[map].file));
- } else {
- return cvox.KeyMap.fromDefaults();
- }
-};
-
-
-/**
- * Takes a path to a JSON file and returns a JSON Object.
- * @param {string} path Contains the path to a JSON file.
- * @return {string} JSON.
- * @private
- * @suppress {missingProperties}
- */
-cvox.KeyMap.readJSON_ = function(path) {
- var url = chrome.extension.getURL(path);
- if (!url) {
- throw 'Invalid path: ' + path;
- }
-
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, false);
- xhr.send();
- return xhr.responseText;
-};
-
-
-/**
- * Resets the default modifier keys.
- * TODO(dtseng): Move elsewhere when we figure out our localStorage story.
- */
-cvox.KeyMap.prototype.resetModifier = function() {
- localStorage['cvoxKey'] = cvox.ChromeVox.modKeyStr;
-};
-
-
-/**
- * Builds the map of commands to keys.
- * @private
- */
-cvox.KeyMap.prototype.buildCommandToKey_ = function() {
- // TODO (dtseng): What about more than one sequence mapped to the same
- // command?
- for (var i = 0; i < this.bindings_.length; i++) {
- var binding = this.bindings_[i];
- if (this.commandToKey_[binding.command] != undefined) {
- // There's at least two key sequences mapped to the same
- // command. continue.
- continue;
- }
- this.commandToKey_[binding.command] = binding.sequence;
- }
-};
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
new file mode 100644
index 00000000000..8d0628c980f
--- /dev/null
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json
@@ -0,0 +1,330 @@
+{
+ "bindings": [
+ {
+ "command": "previousElement",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [37]
+ }
+ }
+ },
+ {
+ "command": "previousLine",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [38]
+ }
+ }
+ },
+ {
+ "command": "nextElement",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [39]
+ }
+ }
+ },
+ {
+ "command": "nextLine",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [40]
+ }
+ }
+ },
+ {
+ "command": "nextCharacter",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [39],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "previousCharacter",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [37],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextWord",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [39],
+ "ctrlKey": [true],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "previousWord",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [37],
+ "ctrlKey": [true],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextButton",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [66]
+ }
+ }
+ },
+ {
+ "command": "previousButton",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [66],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextCheckBox",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [88]
+ }
+ }
+ },
+ {
+ "command": "previousCheckBox",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [88],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextCombobox",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [67]
+ }
+ }
+ },
+ {
+ "command": "previousCombobox",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [67],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextEditText",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [69]
+ }
+ }
+ },
+ {
+ "command": "previousEditText",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [69],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextFormField",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [70]
+ }
+ }
+ },
+ {
+ "command": "previousFormField",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [70],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextHeading",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [72]
+ }
+ }
+ },
+ {
+ "command": "previousHeading",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [72],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextLink",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [76]
+ }
+ }
+ },
+ {
+ "command": "previousLink",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [76],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextTable",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [84]
+ }
+ }
+ },
+ {
+ "command": "previousTable",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [84],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextVisitedLink",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [86]
+ }
+ }
+ },
+ {
+ "command": "previousVisitedLink",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [86],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "goToEnd",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [39],
+ "ctrlKey": [true]
+ }
+ }
+ },
+ {
+ "command": "goToBeginning",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [37],
+ "ctrlKey": [true]
+ }
+ }
+ },
+ {
+ "command": "doDefault",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [32]
+ }
+ }
+ },
+ {
+ "command": "showContextMenu",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [32],
+ "shitKey": [true]
+ }
+ }
+ },
+ {
+ "command": "continuousRead",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [82]
+ }
+ }
+ },
+ {
+ "command": "toggleChromeVoxVersion",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [81],
+ "shitKey": [true]
+ }
+ }
+ },
+ {
+ "command": "toggleChromeVox",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [65, 65]
+ }
+ }
+ },
+ {
+ "command": "toggleStickyMode",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [91]
+ },
+ "doubleTap": true
+ }
+ }
+ ]
+}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/mathmaps/math_map.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/mathmaps/math_map.js
deleted file mode 100644
index 0fd5306671b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/mathmaps/math_map.js
+++ /dev/null
@@ -1,188 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for loading and storing the maps for math atoms from
- * JSON files. The class (and entries) can then be used as via the
- * background page.
- */
-
-
-goog.provide('cvox.MathMap');
-
-goog.require('cvox.MathCompoundStore');
-goog.require('cvox.MathUtil');
-
-
-/**
- *
- * @constructor
- */
-cvox.MathMap = function() {
-
- /**
- * The compund store for symbol and function mappings.
- * @type {cvox.MathCompoundStore}
- */
- this.store = cvox.MathCompoundStore.getInstance();
- cvox.MathMap.parseFiles(
- cvox.MathMap.FUNCTIONS_FILES_.map(
- function(file) {
- return cvox.MathMap.FUNCTIONS_PATH_ + file;
- }))
- .forEach(goog.bind(this.store.addFunctionRules, this.store));
- cvox.MathMap.parseFiles(
- cvox.MathMap.SYMBOLS_FILES_.map(
- function(file) {
- return cvox.MathMap.SYMBOLS_PATH_ + file;
- }))
- .forEach(goog.bind(this.store.addSymbolRules, this.store));
-
- var cstrValues = this.store.getDynamicConstraintValues();
- /**
- * Array of domain names.
- * @type {Array<string>}
- */
- this.allDomains = cstrValues.domain;
-
- /**
- * Array of style names.
- * @type {Array<string>}
- */
- this.allStyles = cstrValues.style;
-};
-
-
-/**
- * Stringifies MathMap into JSON object.
- * @return {string} The stringified version of the mapping.
- */
-cvox.MathMap.prototype.stringify = function() {
- return JSON.stringify(this);
-};
-
-
-/**
- * Path to dir containing ChromeVox JSON definitions for math speak.
- * @type {string}
- * @const
- * @private
- */
-cvox.MathMap.MATHMAP_PATH_ = 'chromevox/background/mathmaps/';
-
-
-/**
- * Subpath to dir containing ChromeVox JSON definitions for symbols.
- * @type {string}
- * @const
- * @private
- */
-cvox.MathMap.SYMBOLS_PATH_ = cvox.MathMap.MATHMAP_PATH_ + 'symbols/';
-
-
-/**
- * Subpath to dir containing ChromeVox JSON definitions for functions.
- * @type {string}
- * @const
- * @private
- */
-cvox.MathMap.FUNCTIONS_PATH_ = cvox.MathMap.MATHMAP_PATH_ + 'functions/';
-
-
-/**
- * Array of JSON filenames containing symbol definitions for math speak.
- * @type {Array<string>}
- * @const
- * @private
- */
-cvox.MathMap.SYMBOLS_FILES_ = [
- // Greek
- 'greek-capital.json', 'greek-small.json', 'greek-scripts.json',
- 'greek-mathfonts.json', 'greek-symbols.json',
-
- // Hebrew
- 'hebrew_letters.json',
-
- // Latin
- 'latin-lower-double-accent.json', 'latin-lower-normal.json',
- 'latin-lower-phonetic.json', 'latin-lower-single-accent.json',
- 'latin-rest.json', 'latin-upper-double-accent.json',
- 'latin-upper-normal.json', 'latin-upper-single-accent.json',
- 'latin-mathfonts.json',
-
- // Math Symbols
- 'math_angles.json', 'math_arrows.json', 'math_characters.json',
- 'math_delimiters.json', 'math_digits.json', 'math_geometry.json',
- 'math_harpoons.json', 'math_non_characters.json', 'math_symbols.json',
- 'math_whitespace.json', 'other_stars.json'
-];
-
-
-/**
- * Array of JSON filenames containing symbol definitions for math speak.
- * @type {Array<string>}
- * @const
- * @private
- */
-cvox.MathMap.FUNCTIONS_FILES_ = [
- 'algebra.json', 'elementary.json', 'hyperbolic.json', 'trigonometry.json'
-];
-
-
-/**
- * Loads JSON for a given file name.
- * @param {string} file A valid filename.
- * @return {string} A string representing JSON array.
- */
-cvox.MathMap.loadFile = function(file) {
- try {
- return cvox.MathMap.readJSON_(file);
- } catch (x) {
- console.log('Unable to load file: ' + file + ', error: ' + x);
- }
-};
-
-
-/**
- * Loads a list of JSON files.
- * @param {Array<string>} files An array of valid filenames.
- * @return {Array<string>} A string representing JSON array.
- */
-cvox.MathMap.loadFiles = function(files) {
- return files.map(cvox.MathMap.loadFile);
-};
-
-
-/**
- * Creates an array of JSON objects from a list of files.
- * @param {Array<string>} files An array of filenames.
- * @return {Array<Object>} Array of JSON objects.
- */
-cvox.MathMap.parseFiles = function(files) {
- var strs = cvox.MathMap.loadFiles(files);
-
- return [].concat.apply([], strs.map(
- // Note: As JSON.parse does not expect the value index as the second
- // parameter, we wrap it.
- function(value) { return JSON.parse(value); }));
-};
-
-
-/**
- * Takes path to a JSON file and returns a JSON object.
- * @param {string} path Contains the path to a JSON file.
- * @return {string} JSON.
- * @private
- */
-cvox.MathMap.readJSON_ = function(path) {
- var url = chrome.extension.getURL(path);
- if (!url) {
- throw 'Invalid path: ' + path;
- }
-
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, false);
- xhr.send();
- return xhr.responseText;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.html b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.html
deleted file mode 100644
index 58d0e7c6ab1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!-- 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. -->
-<html>
-
-<head>
-<title class="i18n" msgid="options_page_title">ChromeVox Options</title>
-<link rel="stylesheet" type="text/css" href="chrome_shared2.css" />
-<link rel="stylesheet" type="text/css" href="options_widgets.css" />
-<link rel="stylesheet" type="text/css" href="options.css" />
-
-
-<script type="text/javascript" src="../../closure/base.js"></script>
-<script type="text/javascript" src="../../deps.js"></script>
-<script type="text/javascript" src="options_loader.js"></script>
-<script type="text/javascript" src="../../chromeVoxChromeOptionsScript.js">
-</script>
-</head>
-
-<html>
-
-<body>
-<div>
- <!-- The "with dev msgs" in the title helps when debugging problems with the message
- replacer. -->
- <h1 class="i18n" msgid="options_page_title">ChromeVox (with dev msgs)</h1>
- <p id="version"></p>
-
-
- <div class="option">
- <input id="useVerboseMode" type="checkbox" class="checkbox pref" name="useVerboseMode" />
- <label for="useVerboseMode" class="i18n" msgid="options_verbosity_verbose">
- Enable verbose descriptions.
- </label>
- </div>
-
- <div class="option">
- <input id="useIBeamCursor" type="checkbox" class="checkbox pref" name="useIBeamCursor" />
- <label for="useIBeamCursor" class="i18n" msgid="options_cursor_between_characters">
- Place cursor between characters when editing text (like Mac OS X).
- </label>
- </div>
-
- <div class="option">
- <input id="focusFollowsMouse" type="checkbox" class="checkbox pref" name="focusFollowsMouse" />
- <label for="focusFollowsMouse" class="i18n" msgid="options_mouse_focus_follows">
- Use the mouse to change focus.
- </label>
- </div>
-
- <div class="option">
- <input id="siteSpecificEnhancements" type="checkbox" class="checkbox pref" name="siteSpecificEnhancements" />
- <label for="siteSpecificEnhancements" class="i18n" msgid="options_site_specific_enhancements">
- Enhance specific sites (like Google Search).
- </label>
- </div>
-
- <h2 class="i18n" msgid="options_voices">Voices</h2>
- <p class="i18n description" msgid="options_voices_description" id="voices_description">
- Change the current voice by selecting an option from the list below.
- </p>
-
- <div>
- <select class="pref" id="voices" aria-labelledby="voices_description"></select>
- <br><br>
- </div>
-
-
- <h2 class="chromeos i18n" msgid="options_braille">Braille</h2>
- <div class="chromeos">
- <p class="i18n description" msgid="options_braille_description_6" id="braille_description_6">
- Change the current 6 dot braille table by selecting an option from the list below.
- </p>
- <select class="pref" id="brailleTable6" aria-labelledby="braille_description_6"></select>
- <p class="i18n description" msgid="options_braille_description_8" id="braille_description_8">
- Change the current 8 dot braille table by selecting an option from the list below.
- </p>
- <select class="pref" id="brailleTable8" aria-labelledby="braille_description_8"></select>
- <button id="brailleTableType"></button>
- <div class="option">
- <label>
- <input id="brailleWordWrap" type="checkbox" class="checkbox pref" name="brailleWordWrap" />
- <span class="i18n" msgid="options_braille_word_wrap">
- Enable word wrap
- </span>
- </label>
- </div>
-
- <br><br>
- </div>
-
-
- <h2 class="i18n" msgid="options_keyboard_shortcuts">Keyboard shortcuts</h2>
- <p class="i18n description" msgid="options_keymap_description" id="keymap_description">
- Change the current keymap by selecting an option from the list below.
- </p>
-
- <div>
- <select class="pref" id="cvox_keymaps" aria-labelledby="keymap_description">
- </select>
- <button id="selectKeys" class="i18n" msgid="options_select_keys">
- Select keymap
- </button>
- <br><br>
- </div>
-
- <p class="i18n description" msgid="options_shortcuts_description"
- id="shortcuts_description">
- Customize keyboard shortcuts for frequently used commands by typing them into the
- corresponding fields below.
- </p>
-
- <div id="keysContainer">
-
- </div>
- <div id="status" role="live" aria-live="assertive">
- </div>
-</div>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js
deleted file mode 100644
index ed6dc727493..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options.js
+++ /dev/null
@@ -1,605 +0,0 @@
-// 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.
-
-/**
- * @fileoverview ChromeVox options page.
- *
- */
-
-goog.provide('cvox.OptionsPage');
-
-goog.require('Msgs');
-goog.require('cvox.BrailleTable');
-goog.require('cvox.BrailleTranslatorManager');
-goog.require('cvox.ChromeEarcons');
-goog.require('cvox.ChromeHost');
-goog.require('cvox.ChromeTts');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxPrefs');
-goog.require('cvox.CommandStore');
-goog.require('cvox.ExtensionBridge');
-goog.require('cvox.HostFactory');
-goog.require('cvox.KeyMap');
-goog.require('cvox.KeySequence');
-goog.require('cvox.PlatformFilter');
-goog.require('cvox.PlatformUtil');
-
-/**
- * Class to manage the options page.
- * @constructor
- */
-cvox.OptionsPage = function() {
-};
-
-/**
- * The ChromeVoxPrefs object.
- * @type {cvox.ChromeVoxPrefs}
- */
-cvox.OptionsPage.prefs;
-
-
-/**
- * A mapping from keycodes to their human readable text equivalents.
- * This is initialized in cvox.OptionsPage.init for internationalization.
- * @type {Object<string>}
- */
-cvox.OptionsPage.KEYCODE_TO_TEXT = {
-};
-
-/**
- * A mapping from human readable text to keycode values.
- * This is initialized in cvox.OptionsPage.init for internationalization.
- * @type {Object<string>}
- */
-cvox.OptionsPage.TEXT_TO_KEYCODE = {
-};
-
-/**
- * Initialize the options page by setting the current value of all prefs,
- * building the key bindings table, and adding event listeners.
- * @suppress {missingProperties} Property prefs never defined on Window
- */
-cvox.OptionsPage.init = function() {
- cvox.OptionsPage.prefs = chrome.extension.getBackgroundPage().prefs;
- cvox.OptionsPage.populateKeyMapSelect();
- cvox.OptionsPage.addKeys();
- cvox.OptionsPage.populateVoicesSelect();
- cvox.BrailleTable.getAll(function(tables) {
- /** @type {!Array<cvox.BrailleTable.Table>} */
- cvox.OptionsPage.brailleTables = tables;
- cvox.OptionsPage.populateBrailleTablesSelect();
- });
- chrome.storage.local.get({'brailleWordWrap': true}, function(items) {
- $('brailleWordWrap').checked = items.brailleWordWrap;
- });
-
- Msgs.addTranslatedMessagesToDom(document);
- cvox.OptionsPage.hidePlatformSpecifics();
-
- cvox.OptionsPage.update();
-
- document.addEventListener('change', cvox.OptionsPage.eventListener, false);
- document.addEventListener('click', cvox.OptionsPage.eventListener, false);
- document.addEventListener('keydown', cvox.OptionsPage.eventListener, false);
-
- cvox.ExtensionBridge.addMessageListener(function(message) {
- if (message['keyBindings'] || message['prefs']) {
- cvox.OptionsPage.update();
- }
- });
-
- $('selectKeys').addEventListener(
- 'click', cvox.OptionsPage.reset, false);
-
- if (cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.WML)) {
- $('version').textContent =
- chrome.app.getDetails().version;
- }
-
- // Temporary secret way to enable ChromeVox Next for the current run of
- // ChromeVox.
- var next = 'next';
- document.body.addEventListener('keypress', function(evt) {
- if (next === undefined) {
- return;
- }
- var key = String.fromCharCode(evt.charCode);
- if (next[0] === key) {
- next = next.slice(1);
-
- if (next === '') {
- cvox.OptionsPage.speak(
- 'You are now running ChromeVox Next; open a new tab to start',
- cvox.QueueMode.FLUSH);
- next = undefined;
- chrome.extension.getBackgroundPage()['global']
- .backgroundObj.forceChromeVoxNextActive();
- }
- } else {
- next = 'next';
- }
- return true;
- }, true);
-};
-
-/**
- * Update the value of controls to match the current preferences.
- * This happens if the user presses a key in a tab that changes a
- * pref.
- */
-cvox.OptionsPage.update = function() {
- var prefs = cvox.OptionsPage.prefs.getPrefs();
- for (var key in prefs) {
- // TODO(rshearer): 'active' is a pref, but there's no place in the
- // options page to specify whether you want ChromeVox active.
- var elements = document.querySelectorAll('*[name="' + key + '"]');
- for (var i = 0; i < elements.length; i++) {
- cvox.OptionsPage.setValue(elements[i], prefs[key]);
- }
- }
-};
-
-/**
- * Populate the keymap select element with stored keymaps
- */
-cvox.OptionsPage.populateKeyMapSelect = function() {
- var select = $('cvox_keymaps');
- for (var id in cvox.KeyMap.AVAILABLE_MAP_INFO) {
- var info = cvox.KeyMap.AVAILABLE_MAP_INFO[id];
- var option = document.createElement('option');
- option.id = id;
- option.className = 'i18n';
- option.setAttribute('msgid', id);
- if (cvox.OptionsPage.prefs.getPrefs()['currentKeyMap'] == id) {
- option.setAttribute('selected', '');
- }
- select.appendChild(option);
- }
-
- select.addEventListener('change', cvox.OptionsPage.reset, true);
-};
-
-/**
- * Add the input elements for the key bindings to the container element
- * in the page. They're sorted in order of description.
- */
-cvox.OptionsPage.addKeys = function() {
- var container = $('keysContainer');
- var keyMap = cvox.OptionsPage.prefs.getKeyMap();
-
- cvox.OptionsPage.prevTime = new Date().getTime();
- cvox.OptionsPage.keyCount = 0;
- container.addEventListener('keypress', goog.bind(function(evt) {
- if (evt.target.id == 'cvoxKey') {
- return;
- }
- this.keyCount++;
- var currentTime = new Date().getTime();
- if (currentTime - this.prevTime > 1000 || this.keyCount > 2) {
- if (document.activeElement.id == 'toggleKeyPrefix') {
- this.keySequence = new cvox.KeySequence(evt, false);
- this.keySequence.keys['ctrlKey'][0] = true;
- } else {
- this.keySequence = new cvox.KeySequence(evt, true);
- }
-
- this.keyCount = 1;
- } else {
- this.keySequence.addKeyEvent(evt);
- }
-
- var keySeqStr = cvox.KeyUtil.keySequenceToString(this.keySequence, true);
- var announce = keySeqStr.replace(/\+/g,
- ' ' + Msgs.getMsg('then') + ' ');
- announce = announce.replace(/>/g,
- ' ' + Msgs.getMsg('followed_by') + ' ');
- announce = announce.replace('Cvox',
- ' ' + Msgs.getMsg('modifier_key') + ' ');
-
- // TODO(dtseng): Only basic conflict detection; it does not speak the
- // conflicting command. Nor does it detect prefix conflicts like Cvox+L vs
- // Cvox+L>L.
- if (cvox.OptionsPage.prefs.setKey(document.activeElement.id,
- this.keySequence)) {
- document.activeElement.value = keySeqStr;
- } else {
- announce = Msgs.getMsg('key_conflict', [announce]);
- }
- cvox.OptionsPage.speak(announce, cvox.QueueMode.QUEUE);
- this.prevTime = currentTime;
-
- evt.preventDefault();
- evt.stopPropagation();
- }, cvox.OptionsPage), true);
-
- var categories = cvox.CommandStore.categories();
- for (var i = 0; i < categories.length; i++) {
- // Braille bindings can't be customized, so don't include them.
- if (categories[i] == 'braille') {
- continue;
- }
- var headerElement = document.createElement('h3');
- headerElement.className = 'i18n';
- headerElement.setAttribute('msgid', categories[i]);
- headerElement.id = categories[i];
- container.appendChild(headerElement);
- var commands = cvox.CommandStore.commandsForCategory(categories[i]);
- for (var j = 0; j < commands.length; j++) {
- var command = commands[j];
- // TODO: Someday we may want to have more than one key
- // mapped to a command, so we'll need to figure out how to display
- // that. For now, just take the first key.
- var keySeqObj = keyMap.keyForCommand(command)[0];
-
- // Explicitly skip toggleChromeVox in ChromeOS.
- if (command == 'toggleChromeVox' &&
- cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.CHROMEOS)) {
- continue;
- }
-
- var inputElement = document.createElement('input');
- inputElement.type = 'text';
- inputElement.className = 'key active-key';
- inputElement.id = command;
-
- var displayedCombo;
- if (keySeqObj != null) {
- displayedCombo = cvox.KeyUtil.keySequenceToString(keySeqObj, true);
- } else {
- displayedCombo = '';
- }
- inputElement.value = displayedCombo;
-
- // Don't allow the user to change the sticky mode or stop speaking key.
- if (command == 'toggleStickyMode' || command == 'stopSpeech') {
- inputElement.disabled = true;
- }
- var message = cvox.CommandStore.messageForCommand(command);
- if (!message) {
- // TODO(dtseng): missing message id's.
- message = command;
- }
-
- var labelElement = document.createElement('label');
- labelElement.className = 'i18n';
- labelElement.setAttribute('msgid', message);
- labelElement.setAttribute('for', inputElement.id);
-
- var divElement = document.createElement('div');
- divElement.className = 'key-container';
- container.appendChild(divElement);
- divElement.appendChild(inputElement);
- divElement.appendChild(labelElement);
- }
- var brElement = document.createElement('br');
- container.appendChild(brElement);
- }
-
- if ($('cvoxKey') == null) {
- // Add the cvox key field
- var inputElement = document.createElement('input');
- inputElement.type = 'text';
- inputElement.className = 'key';
- inputElement.id = 'cvoxKey';
-
- var labelElement = document.createElement('label');
- labelElement.className = 'i18n';
- labelElement.setAttribute('msgid', 'options_cvox_modifier_key');
- labelElement.setAttribute('for', 'cvoxKey');
-
- var modifierSectionSibling =
- $('modifier_keys').nextSibling;
- var modifierSectionParent = modifierSectionSibling.parentNode;
- modifierSectionParent.insertBefore(labelElement, modifierSectionSibling);
- modifierSectionParent.insertBefore(inputElement, labelElement);
- var cvoxKey = $('cvoxKey');
- cvoxKey.value = localStorage['cvoxKey'];
-
- cvoxKey.addEventListener('keydown', function(evt) {
- if (!this.modifierSeq_) {
- this.modifierCount_ = 0;
- this.modifierSeq_ = new cvox.KeySequence(evt, false);
- } else {
- this.modifierSeq_.addKeyEvent(evt);
- }
-
- // Never allow non-modified keys.
- if (!this.modifierSeq_.isAnyModifierActive()) {
- // Indicate error and instructions excluding tab.
- if (evt.keyCode != 9) {
- cvox.OptionsPage.speak(
- Msgs.getMsg('modifier_entry_error'),
- cvox.QueueMode.FLUSH, {});
- }
- this.modifierSeq_ = null;
- } else {
- this.modifierCount_++;
- }
-
- // Don't trap tab or shift.
- if (!evt.shiftKey && evt.keyCode != 9) {
- evt.preventDefault();
- evt.stopPropagation();
- }
- }, true);
-
- cvoxKey.addEventListener('keyup', function(evt) {
- if (this.modifierSeq_) {
- this.modifierCount_--;
-
- if (this.modifierCount_ == 0) {
- var modifierStr =
- cvox.KeyUtil.keySequenceToString(this.modifierSeq_, true, true);
- evt.target.value = modifierStr;
- cvox.OptionsPage.speak(
- Msgs.getMsg('modifier_entry_set', [modifierStr]),
- cvox.QueueMode.QUEUE);
- localStorage['cvoxKey'] = modifierStr;
- this.modifierSeq_ = null;
- }
- evt.preventDefault();
- evt.stopPropagation();
- }
- }, true);
- }
-};
-
-/**
- * Populates the voices select with options.
- */
-cvox.OptionsPage.populateVoicesSelect = function() {
- var select = $('voices');
-
- function setVoiceList() {
- chrome.storage.local.get('voiceName', function(items) {
- var selectedVoiceName = items.voiceName;
- chrome.tts.getVoices(function(voices) {
- select.innerHTML = '';
- // TODO(plundblad): voiceName can actually be omitted in the TTS
- // engine. We should generate a name in that case.
- voices.forEach(function(voice) {
- voice.voiceName = voice.voiceName || '';
- });
- voices.sort(function(a, b) {
- return a.voiceName.localeCompare(b.voiceName);
- });
- voices.forEach(function(voice) {
- var option = document.createElement('option');
- option.voiceName = voice.voiceName;
- option.innerText = option.voiceName;
- if (selectedVoiceName === voice.voiceName) {
- option.setAttribute('selected', '');
- }
- select.add(option);
- });
- });
- });
- }
-
- window.speechSynthesis.onvoiceschanged = setVoiceList;
- setVoiceList();
-
- select.addEventListener('change', function(evt) {
- var selIndex = select.selectedIndex;
- var sel = select.options[selIndex];
- chrome.storage.local.set({voiceName: sel.voiceName});
- }, true);
-};
-
-/**
- * Populates the braille select control.
- */
-cvox.OptionsPage.populateBrailleTablesSelect = function() {
- if (!cvox.ChromeVox.isChromeOS) {
- return;
- }
- var tables = cvox.OptionsPage.brailleTables;
- var populateSelect = function(node, dots) {
- var activeTable = localStorage[node.id] || localStorage['brailleTable'];
- // Gather the display names and sort them according to locale.
- var items = [];
- for (var i = 0, table; table = tables[i]; i++) {
- if (table.dots !== dots) {
- continue;
- }
- items.push({id: table.id,
- name: cvox.BrailleTable.getDisplayName(table)});
- }
- items.sort(function(a, b) { return a.name.localeCompare(b.name);});
- for (var i = 0, item; item = items[i]; ++i) {
- var elem = document.createElement('option');
- elem.id = item.id;
- elem.textContent = item.name;
- if (item.id == activeTable) {
- elem.setAttribute('selected', '');
- }
- node.appendChild(elem);
- }
- };
- var select6 = $('brailleTable6');
- var select8 = $('brailleTable8');
- populateSelect(select6, '6');
- populateSelect(select8, '8');
-
- var handleBrailleSelect = function(node) {
- return function(evt) {
- var selIndex = node.selectedIndex;
- var sel = node.options[selIndex];
- localStorage['brailleTable'] = sel.id;
- localStorage[node.id] = sel.id;
- cvox.OptionsPage.getBrailleTranslatorManager().refresh();
- };
- };
-
- select6.addEventListener('change', handleBrailleSelect(select6), true);
- select8.addEventListener('change', handleBrailleSelect(select8), true);
-
- var tableTypeButton = $('brailleTableType');
- var updateTableType = function(setFocus) {
- var currentTableType = localStorage['brailleTableType'] || 'brailleTable6';
- if (currentTableType == 'brailleTable6') {
- select6.removeAttribute('aria-hidden');
- select6.setAttribute('tabIndex', 0);
- select6.style.display = 'block';
- if (setFocus) {
- select6.focus();
- }
- select8.setAttribute('aria-hidden', 'true');
- select8.setAttribute('tabIndex', -1);
- select8.style.display = 'none';
- localStorage['brailleTable'] = localStorage['brailleTable6'];
- localStorage['brailleTableType'] = 'brailleTable6';
- tableTypeButton.textContent =
- Msgs.getMsg('options_braille_table_type_6');
- } else {
- select6.setAttribute('aria-hidden', 'true');
- select6.setAttribute('tabIndex', -1);
- select6.style.display = 'none';
- select8.removeAttribute('aria-hidden');
- select8.setAttribute('tabIndex', 0);
- select8.style.display = 'block';
- if (setFocus) {
- select8.focus();
- }
- localStorage['brailleTable'] = localStorage['brailleTable8'];
- localStorage['brailleTableType'] = 'brailleTable8';
- tableTypeButton.textContent =
- Msgs.getMsg('options_braille_table_type_8');
- }
- cvox.OptionsPage.getBrailleTranslatorManager().refresh();
- };
- updateTableType(false);
-
- tableTypeButton.addEventListener('click', function(evt) {
- var oldTableType = localStorage['brailleTableType'];
- localStorage['brailleTableType'] =
- oldTableType == 'brailleTable6' ? 'brailleTable8' : 'brailleTable6';
- updateTableType(true);
- }, true);
-};
-
-/**
- * Set the html element for a preference to match the given value.
- * @param {Element} element The HTML control.
- * @param {string} value The new value.
- */
-cvox.OptionsPage.setValue = function(element, value) {
- if (element.tagName == 'INPUT' && element.type == 'checkbox') {
- element.checked = (value == 'true');
- } else if (element.tagName == 'INPUT' && element.type == 'radio') {
- element.checked = (String(element.value) == value);
- } else {
- element.value = value;
- }
-};
-
-/**
- * Event listener, called when an event occurs in the page that might
- * affect one of the preference controls.
- * @param {Event} event The event.
- * @return {boolean} True if the default action should occur.
- */
-cvox.OptionsPage.eventListener = function(event) {
- window.setTimeout(function() {
- var target = event.target;
- if (target.id == 'brailleWordWrap') {
- chrome.storage.local.set({brailleWordWrap: target.checked});
- } else if (target.classList.contains('pref')) {
- if (target.tagName == 'INPUT' && target.type == 'checkbox') {
- cvox.OptionsPage.prefs.setPref(target.name, target.checked);
- } else if (target.tagName == 'INPUT' && target.type == 'radio') {
- var key = target.name;
- var elements = document.querySelectorAll('*[name="' + key + '"]');
- for (var i = 0; i < elements.length; i++) {
- if (elements[i].checked) {
- cvox.OptionsPage.prefs.setPref(target.name, elements[i].value);
- }
- }
- }
- } else if (target.classList.contains('key')) {
- var keySeq = cvox.KeySequence.fromStr(target.value);
- var success = false;
- if (target.id == 'cvoxKey') {
- cvox.OptionsPage.prefs.setPref(target.id, target.value);
- cvox.OptionsPage.prefs.sendPrefsToAllTabs(true, true);
- success = true;
- } else {
- success =
- cvox.OptionsPage.prefs.setKey(target.id, keySeq);
-
- // TODO(dtseng): Don't surface conflicts until we have a better
- // workflow.
- }
- }
- }, 0);
- return true;
-};
-
-/**
- * Refreshes all dynamic content on the page.
- * This includes all key related information.
- */
-cvox.OptionsPage.reset = function() {
- var selectKeyMap = $('cvox_keymaps');
- var id = selectKeyMap.options[selectKeyMap.selectedIndex].id;
-
- var msgs = Msgs;
- var announce = cvox.OptionsPage.prefs.getPrefs()['currentKeyMap'] == id ?
- msgs.getMsg('keymap_reset', [msgs.getMsg(id)]) :
- msgs.getMsg('keymap_switch', [msgs.getMsg(id)]);
- cvox.OptionsPage.updateStatus_(announce);
-
- cvox.OptionsPage.prefs.switchToKeyMap(id);
- $('keysContainer').innerHTML = '';
- cvox.OptionsPage.addKeys();
- Msgs.addTranslatedMessagesToDom(document);
-};
-
-/**
- * Updates the status live region.
- * @param {string} status The new status.
- * @private
- */
-cvox.OptionsPage.updateStatus_ = function(status) {
- $('status').innerText = status;
-};
-
-
-/**
- * Hides all elements not matching the current platform.
- */
-cvox.OptionsPage.hidePlatformSpecifics = function() {
- if (!cvox.ChromeVox.isChromeOS) {
- var elements = document.body.querySelectorAll('.chromeos');
- for (var i = 0, el; el = elements[i]; i++) {
- el.setAttribute('aria-hidden', 'true');
- el.style.display = 'none';
- }
- }
-};
-
-
-/**
- * Calls a {@code cvox.TtsInterface.speak} method in the background page to
- * speak an utterance. See that method for further details.
- * @param {string} textString The string of text to be spoken.
- * @param {cvox.QueueMode} queueMode The queue mode to use.
- * @param {Object=} properties Speech properties to use for this utterance.
- */
-cvox.OptionsPage.speak = function(textString, queueMode, properties) {
- var speak =
- /** @type Function} */ (chrome.extension.getBackgroundPage()['speak']);
- speak.apply(null, arguments);
-};
-
-/**
- * @return {cvox.BrailleTranslatorManager}
- */
-cvox.OptionsPage.getBrailleTranslatorManager = function() {
- return chrome.extension.getBackgroundPage()['braille_translator_manager'];
-};
-
-document.addEventListener('DOMContentLoaded', function() {
- cvox.OptionsPage.init();
-}, false);
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options_loader.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options_loader.js
deleted file mode 100644
index ec7999afeab..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/options_loader.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Loads the options script.
- *
- */
-
-goog.require('cvox.OptionsPage');
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js
deleted file mode 100644
index a0d64ef86fa..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/prefs.js
+++ /dev/null
@@ -1,231 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Common page for reading and writing preferences from
- * the background context (background page or options page).
- *
- */
-
-goog.provide('cvox.ChromeVoxPrefs');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ExtensionBridge');
-goog.require('cvox.KeyMap');
-
-
-/**
- * This object has default values of preferences and contains the common
- * code for working with preferences shared by the Options and Background
- * pages.
- * @constructor
- */
-cvox.ChromeVoxPrefs = function() {
- var lastRunVersion = localStorage['lastRunVersion'];
- if (!lastRunVersion) {
- lastRunVersion = '1.16.0';
- }
- var loadExistingSettings = true;
- // TODO(dtseng): Logic below needs clarification. Perhaps needs a
- // 'lastIncompatibleVersion' member.
- if (lastRunVersion == '1.16.0') {
- loadExistingSettings = false;
- }
- localStorage['lastRunVersion'] = chrome.runtime.getManifest().version;
-
- /**
- * The current mapping from keys to command.
- * @type {!cvox.KeyMap}
- * @private
- */
- this.keyMap_ = cvox.KeyMap.fromLocalStorage() || cvox.KeyMap.fromDefaults();
- this.keyMap_.merge(cvox.KeyMap.fromDefaults());
-
- // Clear per session preferences.
- // This is to keep the position dictionary from growing excessively large.
- localStorage['position'] = '{}';
-
- // Default per session sticky to off.
- localStorage['sticky'] = false;
-
- this.init(loadExistingSettings);
-};
-
-
-/**
- * The default value of all preferences except the key map.
- * @const
- * @type {Object<Object>}
- */
-cvox.ChromeVoxPrefs.DEFAULT_PREFS = {
- 'active': true,
- 'brailleCaptions': false,
- // TODO(dtseng): Leaking state about multiple key maps here until we have a
- // class to manage multiple key maps. Also, this doesn't belong as a pref;
- // should just store in local storage.
- 'currentKeyMap' : cvox.KeyMap.DEFAULT_KEYMAP,
- 'cvoxKey': '',
- 'earcons': true,
- 'focusFollowsMouse': false,
- 'granularity': undefined,
- 'position': '{}',
- 'siteSpecificScriptBase':
- 'https://ssl.gstatic.com/accessibility/javascript/ext/',
- 'siteSpecificScriptLoader':
- 'https://ssl.gstatic.com/accessibility/javascript/ext/loader.js',
- 'sticky': false,
- 'typingEcho': 0,
- 'useIBeamCursor': cvox.ChromeVox.isMac,
- 'useVerboseMode': true,
- 'siteSpecificEnhancements': true
-};
-
-
-/**
- * Merge the default values of all known prefs with what's found in
- * localStorage.
- * @param {boolean} pullFromLocalStorage or not to pull prefs from local
- * storage. True if we want to respect changes the user has already made
- * to prefs, false if we want to overwrite them. Set false if we've made
- * changes to keyboard shortcuts and need to make sure they aren't
- * overridden by the old keymap in local storage.
- */
-cvox.ChromeVoxPrefs.prototype.init = function(pullFromLocalStorage) {
- // Set the default value of any pref that isn't already in localStorage.
- for (var pref in cvox.ChromeVoxPrefs.DEFAULT_PREFS) {
- if (localStorage[pref] === undefined) {
- localStorage[pref] = cvox.ChromeVoxPrefs.DEFAULT_PREFS[pref];
- }
- }
-};
-
-/**
- * Switches to another key map.
- * @param {string} selectedKeyMap The id of the keymap in
- * cvox.KeyMap.AVAIABLE_KEYMAP_INFO.
-*/
-cvox.ChromeVoxPrefs.prototype.switchToKeyMap = function(selectedKeyMap) {
- // TODO(dtseng): Leaking state about multiple key maps here until we have a
- // class to manage multiple key maps.
- localStorage['currentKeyMap'] = selectedKeyMap;
- this.keyMap_ = cvox.KeyMap.fromCurrentKeyMap();
- this.keyMap_.toLocalStorage();
- this.keyMap_.resetModifier();
- this.sendPrefsToAllTabs(false, true);
-};
-
-
-/**
- * Get the prefs (not including keys).
- * @return {Object} A map of all prefs except the key map from localStorage.
- */
-cvox.ChromeVoxPrefs.prototype.getPrefs = function() {
- var prefs = {};
- for (var pref in cvox.ChromeVoxPrefs.DEFAULT_PREFS) {
- prefs[pref] = localStorage[pref];
- }
- prefs['version'] = chrome.runtime.getManifest().version;
- return prefs;
-};
-
-
-/**
- * Reloads the key map from local storage.
- */
-cvox.ChromeVoxPrefs.prototype.reloadKeyMap = function() {
- // Get the current key map from localStorage.
- // TODO(dtseng): We currently don't support merges since we write the entire
- // map back to local storage.
- var currentKeyMap = cvox.KeyMap.fromLocalStorage();
- if (!currentKeyMap) {
- currentKeyMap = cvox.KeyMap.fromCurrentKeyMap();
- currentKeyMap.toLocalStorage();
- }
- this.keyMap_ = currentKeyMap;
-};
-
-
-/**
- * Get the key map, from key binding to an array of [command, description].
- * @return {cvox.KeyMap} The key map.
- */
-cvox.ChromeVoxPrefs.prototype.getKeyMap = function() {
- return this.keyMap_;
-};
-
-
-/**
- * Reset to the default key bindings.
- */
-cvox.ChromeVoxPrefs.prototype.resetKeys = function() {
- this.keyMap_ = cvox.KeyMap.fromDefaults();
- this.keyMap_.toLocalStorage();
- this.sendPrefsToAllTabs(false, true);
-};
-
-
-/**
- * Send all of the settings to all tabs.
- * @param {boolean} sendPrefs Whether to send the prefs.
- * @param {boolean} sendKeyBindings Whether to send the key bindings.
- */
-cvox.ChromeVoxPrefs.prototype.sendPrefsToAllTabs =
- function(sendPrefs, sendKeyBindings) {
- var context = this;
- var message = {};
- if (sendPrefs) {
- message['prefs'] = context.getPrefs();
- }
- if (sendKeyBindings) {
- // Note that cvox.KeyMap stringifies to a minimal object when message gets
- // passed to the content script.
- message['keyBindings'] = this.keyMap_.toJSON();
- }
- chrome.windows.getAll({populate: true}, function(windows) {
- for (var i = 0; i < windows.length; i++) {
- var tabs = windows[i].tabs;
- for (var j = 0; j < tabs.length; j++) {
- chrome.tabs.sendMessage(tabs[j].id, message);
- }
- }
- });
-};
-
-/**
- * Send all of the settings over the specified port.
- * @param {Port} port The port representing the connection to a content script.
- */
-cvox.ChromeVoxPrefs.prototype.sendPrefsToPort = function(port) {
- port.postMessage({
- 'keyBindings': this.keyMap_.toJSON(),
- 'prefs': this.getPrefs()});
-};
-
-
-/**
- * Set the value of a pref and update all active tabs if it's changed.
- * @param {string} key The pref key.
- * @param {Object|string} value The new value of the pref.
- */
-cvox.ChromeVoxPrefs.prototype.setPref = function(key, value) {
- if (localStorage[key] != value) {
- localStorage[key] = value;
- this.sendPrefsToAllTabs(true, false);
- }
-};
-
-/**
- * Delegates to cvox.KeyMap.
- * @param {string} command The command to set.
- * @param {cvox.KeySequence} newKey The new key to assign it to.
- * @return {boolean} True if the key was bound to the command.
- */
-cvox.ChromeVoxPrefs.prototype.setKey = function(command, newKey) {
- if (this.keyMap_.rebind(command, newKey)) {
- this.keyMap_.toLocalStorage();
- this.sendPrefsToAllTabs(false, true);
- return true;
- }
- return false;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/tabs_api_handler.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/tabs_api_handler.js
deleted file mode 100644
index 4719c1558ca..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/tabs_api_handler.js
+++ /dev/null
@@ -1,152 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Accesses Chrome's tabs extension API and gives
- * feedback for events that happen in the "Chrome of Chrome".
- */
-
-goog.provide('cvox.TabsApiHandler');
-
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.AbstractTts');
-goog.require('cvox.BrailleInterface');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.NavBraille');
-
-
-/**
- * Class that adds listeners and handles events from the tabs API.
- * @constructor
- * @param {cvox.TtsInterface} tts The TTS to use for speaking.
- * @param {cvox.BrailleInterface} braille The braille interface to use for
- * brailling.
- * @param {cvox.AbstractEarcons} earcons The earcons object to use for playing
- * earcons.
- */
-cvox.TabsApiHandler = function(tts, braille, earcons) {
- /** @type {cvox.TtsInterface} @private */
- this.tts_ = tts;
- /** @type {cvox.BrailleInterface} @private */
- this.braille_ = braille;
- /** @type {cvox.AbstractEarcons} @private */
- this.earcons_ = earcons;
- /** @type {function(string, Array<string>=)} @private */
- this.msg_ = Msgs.getMsg.bind(Msgs);
- /**
- * Tracks whether the active tab has finished loading.
- * @type {boolean}
- * @private
- */
- this.lastActiveTabLoaded_ = false;
-
- chrome.tabs.onCreated.addListener(this.onCreated.bind(this));
- chrome.tabs.onRemoved.addListener(this.onRemoved.bind(this));
- chrome.tabs.onActivated.addListener(this.onActivated.bind(this));
- chrome.tabs.onUpdated.addListener(this.onUpdated.bind(this));
- chrome.windows.onFocusChanged.addListener(this.onFocusChanged.bind(this));
-};
-
-cvox.TabsApiHandler.prototype = {
- /**
- * Handles chrome.tabs.onCreated.
- * @param {Object} tab
- */
- onCreated: function(tab) {
- if (!cvox.ChromeVox.isActive) {
- return;
- }
- this.tts_.speak(this.msg_('chrome_tab_created'),
- cvox.QueueMode.FLUSH,
- cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT);
- this.braille_.write(
- cvox.NavBraille.fromText(this.msg_('chrome_tab_created')));
- this.earcons_.playEarcon(cvox.Earcon.OBJECT_OPEN);
- },
-
- /**
- * Handles chrome.tabs.onRemoved.
- * @param {Object} tab
- */
- onRemoved: function(tab) {
- if (!cvox.ChromeVox.isActive) {
- return;
- }
- this.earcons_.playEarcon(cvox.Earcon.OBJECT_CLOSE);
- },
-
- /**
- * Handles chrome.tabs.onActivated.
- * @param {Object} activeInfo
- */
- onActivated: function(activeInfo) {
- if (!cvox.ChromeVox.isActive) {
- return;
- }
- chrome.tabs.get(activeInfo.tabId, function(tab) {
- this.lastActiveTabLoaded_ = tab.status == 'complete';
- if (tab.status == 'loading') {
- return;
- }
- var title = tab.title ? tab.title : tab.url;
- this.tts_.speak(this.msg_('chrome_tab_selected',
- [title]),
- cvox.QueueMode.FLUSH,
- cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT);
- this.braille_.write(
- cvox.NavBraille.fromText(this.msg_('chrome_tab_selected', [title])));
- this.earcons_.playEarcon(cvox.Earcon.OBJECT_SELECT);
- }.bind(this));
- },
-
- /**
- * Handles chrome.tabs.onUpdated.
- * @param {number} tabId
- * @param {Object} selectInfo
- */
- onUpdated: function(tabId, selectInfo) {
- if (!cvox.ChromeVox.isActive) {
- return;
- }
- chrome.tabs.get(tabId, function(tab) {
- if (!tab.active) {
- return;
- }
- if (tab.status == 'loading') {
- this.lastActiveTabLoaded_ = false;
- this.earcons_.playEarcon(cvox.Earcon.PAGE_START_LOADING);
- } else if (!this.lastActiveTabLoaded_) {
- this.lastActiveTabLoaded_ = true;
- this.earcons_.playEarcon(cvox.Earcon.PAGE_FINISH_LOADING);
- }
- }.bind(this));
- },
-
- /**
- * Handles chrome.windows.onFocusChanged.
- * @param {number} windowId
- */
- onFocusChanged: function(windowId) {
- if (!cvox.ChromeVox.isActive) {
- return;
- }
- if (windowId == chrome.windows.WINDOW_ID_NONE) {
- return;
- }
- chrome.windows.get(windowId, function(window) {
- chrome.tabs.query({active: true, windowId: windowId}, function(tabs) {
- var msgId = window.incognito ? 'chrome_incognito_window_selected' :
- 'chrome_normal_window_selected';
- var tab = tabs[0] || {};
- var title = tab.title ? tab.title : tab.url;
- this.tts_.speak(this.msg_(msgId, [title]),
- cvox.QueueMode.FLUSH,
- cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT);
- this.braille_.write(
- cvox.NavBraille.fromText(this.msg_(msgId, [title])));
- this.earcons_.playEarcon(cvox.Earcon.OBJECT_SELECT);
- }.bind(this));
- }.bind(this));
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-128.png b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-128.png
deleted file mode 100644
index c0b8566dd35..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-128.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-16.png b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-16.png
deleted file mode 100644
index 96239db1a15..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-16.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-19.png b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-19.png
deleted file mode 100644
index 24c8803bf10..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-19.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-48.png b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-48.png
deleted file mode 100644
index 5a23931dc27..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/chromevox-48.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/active_indicator.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/active_indicator.js
deleted file mode 100644
index c945194bbb3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/active_indicator.js
+++ /dev/null
@@ -1,1004 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Draws and animates the graphical indicator around the active
- * object or text range, and handles animation when the indicator is moving.
- */
-
-
-goog.provide('cvox.ActiveIndicator');
-
-goog.require('cvox.Cursor');
-goog.require('cvox.DomUtil');
-
-
-/**
- * Constructs and ActiveIndicator, a glowing outline around whatever
- * node or text range is currently active. Initially it won't display
- * anything; call syncToNode, syncToRange, or syncToCursorSelection to
- * make it animate and move. It only displays when this window/iframe
- * has focus.
- *
- * @constructor
- */
-cvox.ActiveIndicator = function() {
- /**
- * The time when the indicator was most recently moved.
- * @type {number}
- * @private
- */
- this.lastMoveTime_ = 0;
-
- /**
- * An estimate of the current zoom factor of the webpage. This is
- * needed in order to accurately line up the different pieces of the
- * indicator border and avoid rounding errors.
- * @type {number}
- * @private
- */
- this.zoom_ = 1;
-
- /**
- * The parent element of the indicator.
- * @type {?Element}
- * @private
- */
- this.container_ = null;
-
- /**
- * The current indicator rects.
- * @type {Array<ClientRect>}
- * @private
- */
- this.rects_ = null;
-
- /**
- * The most recent target of a call to syncToNode, syncToRange, or
- * syncToCursorSelection.
- * @type {Array<Node>|Range}
- * @private
- */
- this.lastSyncTarget_ = null;
-
- /**
- * The most recent client rects for the active indicator, so we
- * can tell when it moved.
- * @type {ClientRectList|Array<ClientRect>}
- * @private
- */
- this.lastClientRects_ = null;
-
- /**
- * The id from window.setTimeout when updating the indicator if needed.
- * @type {?number}
- * @private
- */
- this.updateIndicatorTimeoutId_ = null;
-
- /**
- * True if this window is blurred and we shouldn't show the indicator.
- * @type {boolean}
- * @private
- */
- this.blurred_ = false;
-
- /**
- * A cached value of window height.
- * @type {number|undefined}
- * @private
- */
- this.innerHeight_;
-
- /**
- * A cached value of window width.
- * @type {number|undefined}
- * @private
- */
- this.innerWidth_;
-
- // Hide the indicator when the window doesn't have focus.
- window.addEventListener('focus', goog.bind(function() {
- this.blurred_ = false;
- if (this.container_) {
- this.container_.classList.remove('cvox_indicator_window_not_focused');
- }
- }, this), false);
- window.addEventListener('blur', goog.bind(function() {
- this.blurred_ = true;
- if (this.container_) {
- this.container_.classList.add('cvox_indicator_window_not_focused');
- }
- }, this), false);
-};
-
-/**
- * CSS for the active indicator. The basic hierarchy looks like this:
- *
- * container (pulsing) (animate_normal, animate_quick)
- * region (visible)
- * top
- * middle_nw
- * middle_ne
- * middle_sw
- * middle_se
- * bottom
- * region (visible)
- * top
- * middle_nw
- * middle_ne
- * middle_sw
- * middle_se
- * bottom
- *
- * @type {string}
- * @const
- */
-cvox.ActiveIndicator.STYLE =
- '.cvox_indicator_container {' +
- ' position: absolute !important;' +
- ' left: 0 !important;' +
- ' top: 0 !important;' +
- ' z-index: 2147483647 !important;' +
- ' pointer-events: none !important;' +
- ' margin: 0px !important;' +
- ' padding: 0px !important;' +
- '}' +
- '.cvox_indicator_window_not_focused {' +
- ' visibility: hidden !important;' +
- '}' +
- '.cvox_indicator_pulsing {' +
- ' -webkit-animation: ' +
- // NOTE(deboer): This animation is 0 seconds long to work around
- // http://crbug.com/128993. Revert it to 2s when the bug is fixed.
- ' cvox_indicator_pulsing_animation 0s 2 alternate !important;' +
- ' -webkit-animation-timing-function: ease-in-out !important;' +
- '}' +
- '.cvox_indicator_region {' +
- ' opacity: 0 !important;' +
- ' -webkit-transition: opacity 1s !important;' +
- '}' +
- '.cvox_indicator_visible {' +
- ' opacity: 1 !important;' +
- '}' +
- '.cvox_indicator_container .cvox_indicator_region * {' +
- ' position:absolute !important;' +
- ' box-shadow: 0 0 4px 4px #f7983a !important;' +
- ' border-radius: 6px !important;' +
- ' margin: 0px !important;' +
- ' padding: 0px !important;' +
- ' -webkit-transition: none !important;' +
- '}' +
- '.cvox_indicator_animate_normal .cvox_indicator_region * {' +
- ' -webkit-transition: all 0.3s !important;' +
- '}' +
- '.cvox_indicator_animate_quick .cvox_indicator_region * {' +
- ' -webkit-transition: all 0.1s !important;' +
- '}' +
- '.cvox_indicator_top {' +
- ' border-radius: inherit inherit 0 0 !important;' +
- '}' +
- '.cvox_indicator_middle_nw {' +
- ' border-radius: inherit 0 0 0 !important;' +
- '}' +
- '.cvox_indicator_middle_ne {' +
- ' border-radius: 0 inherit 0 0 !important;' +
- '}' +
- '.cvox_indicator_middle_se {' +
- ' border-radius: 0 0 inherit 0 !important;' +
- '}' +
- '.cvox_indicator_middle_sw {' +
- ' border-radius: 0 0 0 inherit !important;' +
- '}' +
- '.cvox_indicator_bottom {' +
- ' border-radius: 0 0 inherit inherit !important;' +
- '}' +
- '@-webkit-keyframes cvox_indicator_pulsing_animation {' +
- ' 0% {opacity: 1.0}' +
- ' 50% {opacity: 0.5}' +
- ' 100% {opacity: 1.0}' +
- '}';
-
-/**
- * The minimum number of milliseconds that must have elapsed
- * since the last navigation for a quick animation to be allowed.
- * @type {number}
- * @const
- */
-cvox.ActiveIndicator.QUICK_ANIM_DELAY_MS = 100;
-
-/**
- * The minimum number of milliseconds that must have elapsed
- * since the last navigation for a normal (slower) animation
- * to be allowed.
- * @type {number}
- * @const
- */
-cvox.ActiveIndicator.NORMAL_ANIM_DELAY_MS = 300;
-
-/**
- * Margin between the active object's rect and the indicator border.
- * @type {number}
- * @const
- */
-cvox.ActiveIndicator.MARGIN = 8;
-
-/**
- * Remove the indicator from the DOM.
- */
-cvox.ActiveIndicator.prototype.removeFromDom = function() {
- if (this.container_ && this.container_.parentElement) {
- this.container_.parentElement.removeChild(this.container_);
- }
-};
-
-/**
- * Move the indicator to surround the given node.
- * @param {Node} node The new target of the indicator.
- */
-cvox.ActiveIndicator.prototype.syncToNode = function(node) {
- if (!node) {
- return;
- }
- // In the navigation manager, and specifically the node walkers, focusing
- // on the body means we are before the beginning of the document. In
- // that case, we simply hide the active indicator.
- if (node == document.body) {
- this.removeFromDom();
- return;
- }
- this.syncToNodes([node]);
-};
-
-/**
- * Move the indicator to surround the given nodes.
- * @param {Array<Node>} nodes The new targets of the indicator.
- */
-cvox.ActiveIndicator.prototype.syncToNodes = function(nodes) {
- var clientRects = this.clientRectsFromNodes_(nodes);
- this.moveIndicator_(clientRects, cvox.ActiveIndicator.MARGIN);
- this.lastSyncTarget_ = nodes;
- this.lastClientRects_ = clientRects;
- if (this.updateIndicatorTimeoutId_ != null) {
- window.clearTimeout(this.updateIndicatorTimeoutId_);
- this.updateIndicatorTimeoutId_ = null;
- }
-};
-
-/**
- * Move the indicator to surround the given range.
- * @param {Range} range The range.
- */
-cvox.ActiveIndicator.prototype.syncToRange = function(range) {
- var margin = cvox.ActiveIndicator.MARGIN;
- if (range.startContainer == range.endContainer &&
- range.startOffset + 1 == range.endOffset) {
- margin = 1;
- }
-
- var clientRects = range.getClientRects();
- this.moveIndicator_(clientRects, margin);
- this.lastSyncTarget_ = range;
- this.lastClientRects_ = clientRects;
- if (this.updateIndicatorTimeoutId_ != null) {
- window.clearTimeout(this.updateIndicatorTimeoutId_);
- this.updateIndicatorTimeoutId_ = null;
- }
-};
-
-/**
- * Move the indicator to surround the given cursor range.
- * @param {!cvox.CursorSelection} sel The start cursor position.
- */
-cvox.ActiveIndicator.prototype.syncToCursorSelection = function(sel) {
- if (sel.start.node == sel.end.node && sel.start.index == sel.end.index) {
- this.syncToNode(sel.start.node);
- } else {
- var range = document.createRange();
- range.setStart(sel.start.node, sel.start.index);
- range.setEnd(sel.end.node, sel.end.index);
- this.syncToRange(range);
- }
-};
-
-/**
- * Called when we should check to see if the indicator target has moved.
- * Schedule it after a short delay so that we don't waste a lot of time
- * updating.
- */
-cvox.ActiveIndicator.prototype.updateIndicatorIfChanged = function() {
- if (this.updateIndicatorTimeoutId_) {
- return;
- }
- this.updateIndicatorTimeoutId_ = window.setTimeout(goog.bind(function() {
- this.handleUpdateIndicatorIfChanged_();
- }, this), 100);
-};
-
-/**
- * Called when we should check to see if the indicator target has moved.
- * Schedule it after a short delay so that we don't waste a lot of time
- * updating.
- * @private
- */
-cvox.ActiveIndicator.prototype.handleUpdateIndicatorIfChanged_ = function() {
- this.updateIndicatorTimeoutId_ = null;
- if (!this.lastSyncTarget_) {
- return;
- }
-
- var newClientRects;
- if (this.lastSyncTarget_ instanceof Array) {
- newClientRects = this.clientRectsFromNodes_(this.lastSyncTarget_);
- } else {
- newClientRects = this.lastSyncTarget_.getClientRects();
- }
- if (!newClientRects || newClientRects.length == 0) {
- this.syncToNode(document.body);
- return;
- }
-
- var needsUpdate = false;
- if (newClientRects.length != this.lastClientRects_.length) {
- needsUpdate = true;
- } else {
- for (var i = 0; i < this.lastClientRects_.length; ++i) {
- var last = this.lastClientRects_[i];
- var current = newClientRects[i];
- if (last.top != current.top ||
- last.right != current.right ||
- last.bottom != current.bottom ||
- last.left != last.left) {
- needsUpdate = true;
- break;
- }
- }
- }
- if (needsUpdate) {
- this.moveIndicator_(newClientRects, cvox.ActiveIndicator.MARGIN);
- this.lastClientRects_ = newClientRects;
- }
-};
-
-/**
- * @param {Array<Node>} nodes An array of nodes.
- * @return {Array<ClientRect>} An array of client rects corresponding to
- * those nodes.
- * @private
- */
-cvox.ActiveIndicator.prototype.clientRectsFromNodes_ = function(nodes) {
- var clientRects = [];
- for (var i = 0; i < nodes.length; ++i) {
- var node = nodes[i];
- if (node.constructor == Text) {
- var range = document.createRange();
- range.selectNode(node);
- var rangeRects = range.getClientRects();
- for (var j = 0; j < rangeRects.length; ++j)
- clientRects.push(rangeRects[j]);
- } else {
- while (!node.getClientRects) {
- node = node.parentElement;
- }
- if (!node) {
- return [];
- }
- var nodeRects = node.getClientRects();
- for (var j = 0; j < nodeRects.length; ++j)
- clientRects.push(nodeRects[j]);
- }
- }
- return clientRects;
-};
-
-/**
- * Move the indicator from its current location, if any, to surround
- * the given set of rectanges.
- *
- * The rectangles need not be contiguous - they're automatically
- * grouped into contiguous regions. The first region is "primary" - it
- * gets animated smoothly from the previous location to the new location.
- * Any other region (like, for example, a text range
- * that continues on a second column) gets a temporary outline that
- * disappears as soon as the indicator moves again.
- *
- * A single region does not have to be rectangular - a region outline
- * is designed to handle the slightly non-rectangular shape of a typical
- * text paragraph, but not anything more complicated than that.
- *
- * @param {ClientRectList|Array<ClientRect>} immutableRects The object
- * rectangles.
- * @param {number} margin Margin in pixels.
- * @private
- */
-cvox.ActiveIndicator.prototype.moveIndicator_ = function(
- immutableRects, margin) {
- // Never put the active indicator into the DOM when the whole page is
- // contentEditable; it will end up part of content that the user may
- // be trying to edit.
- if (document.body.isContentEditable) {
- this.removeFromDom();
- return;
- }
-
- var n = immutableRects.length;
- if (n == 0) {
- return;
- }
-
- // Offset the rects by documentElement, body, and/or scroll offsets,
- // while copying them into a new mutable array.
- var offsetX;
- var offsetY;
- if (window.getComputedStyle(document.body, null).position != 'static') {
- offsetX = -document.body.getBoundingClientRect().left;
- offsetY = -document.body.getBoundingClientRect().top;
- } else if (window.getComputedStyle(document.documentElement, null).position !=
- 'static') {
- offsetX = -document.documentElement.getBoundingClientRect().left;
- offsetY = -document.documentElement.getBoundingClientRect().top;
- } else {
- offsetX = window.pageXOffset;
- offsetY = window.pageYOffset;
- }
-
- var rects = [];
- for (var i = 0; i < n; i++) {
- rects.push(
- this.inset_(immutableRects[i], offsetX, offsetY, -offsetX, -offsetY));
- }
-
- // Create and attach the container if it doesn't exist or if it was detached.
- if (!this.container_ || !this.container_.parentElement) {
- // In case there are any detached containers around, clean them up. One case
- // that requires clean up like this is when users download a file on Chrome
- // on Android.
- var oldContainers =
- document.getElementsByClassName('cvox_indicator_container');
- for (var j = 0, oldContainer; oldContainer = oldContainers[j]; j++) {
- if (oldContainer.parentNode) {
- oldContainer.parentNode.removeChild(oldContainer);
- }
- }
- this.container_ = this.createDiv_(
- document.body, 'cvox_indicator_container', document.body.firstChild);
- }
-
- // Add the CSS style to the page if it's not already there.
- var style = document.createElement('style');
- style.id = 'cvox_indicator_style';
- style.innerHTML = cvox.ActiveIndicator.STYLE;
- cvox.DomUtil.addNodeToHead(style, style.id);
-
- // Decide on the animation speed. By default we do a medium-speed
- // animation between the previous and new location. If the user is
- // moving rapidly, we do a fast animation, or no animation.
- var now = new Date().getTime();
- var delta = now - this.lastMoveTime_;
- this.container_.className = 'cvox_indicator_container';
- if (!cvox.ChromeVox.documentHasFocus() || this.blurred_) {
- this.container_.classList.add('cvox_indicator_window_not_focused');
- }
- if (delta > cvox.ActiveIndicator.NORMAL_ANIM_DELAY_MS) {
- this.container_.classList.add('cvox_indicator_animate_normal');
- } else if (delta > cvox.ActiveIndicator.QUICK_ANIM_DELAY_MS) {
- this.container_.classList.add('cvox_indicator_animate_quick');
- }
- this.lastMoveTime_ = now;
-
- // Compute the zoom level of the browser - this is needed to avoid
- // roundoff errors when placing the various pieces of the region
- // outline.
- this.computeZoomLevel_();
-
- // Make it start pulsing after it's drawn the first frame - this is so
- // that the opacity is always 100% when the indicator appears, and only
- // starts pulsing afterwards.
- window.setTimeout(goog.bind(function() {
- this.container_.classList.add('cvox_indicator_pulsing');
- }, this), 0);
-
- // If there was more than one region previously, delete all except
- // the first one.
- while (this.container_.childElementCount > 1) {
- this.container_.removeChild(this.container_.lastElementChild);
- }
-
- // Split the rects into contiguous regions.
- var regions = [[rects[0]]];
- var regionRects = [rects[0]];
- for (i = 1; i < rects.length; i++) {
- var found = false;
- for (var j = 0; j < regions.length && !found; j++) {
- if (this.intersects_(rects[i], regionRects[j])) {
- regions[j].push(rects[i]);
- regionRects[j] = this.union_(regionRects[j], rects[i]);
- found = true;
- }
- }
- if (!found) {
- regions.push([rects[i]]);
- regionRects.push(rects[i]);
- }
- }
-
- // Keep merging regions that intersect.
- // TODO(dmazzoni): reduce the worst-case complexity! This appears like
- // it could be O(n^3), make sure it's not in practice.
- do {
- var merged = false;
- for (i = 0; i < regions.length - 1 && !merged; i++) {
- for (j = i + 1; j < regions.length && !merged; j++) {
- if (this.intersects_(regionRects[i], regionRects[j])) {
- regions[i] = regions[i].concat(regions[j]);
- regionRects[i] = this.union_(regionRects[i], regionRects[j]);
- regions.splice(j, 1);
- regionRects.splice(j, 1);
- merged = true;
- }
- }
- }
- } while (merged);
-
- // Sort rects within each region by y and then x position.
- for (i = 0; i < regions.length; i++) {
- regions[i].sort(function(r1, r2) {
- if (r1.top != r2.top) {
- return r1.top - r2.top;
- } else {
- return r1.left - r2.left;
- }
- });
- }
-
- // Draw each indicator region. The first region attempts to re-use the
- // existing elements (which results in animating the transition).
- for (i = 0; i < regions.length; i++) {
- var parent = null;
- if (i == 0 &&
- this.container_.childElementCount == 1 &&
- this.container_.children[0].childElementCount == 6) {
- parent = this.container_.children[0];
- }
- this.updateIndicatorRegion_(regions[i], parent, margin);
- }
-};
-
-/**
- * Update one indicator region - a set of contiguous rectangles on the
- * page.
- *
- * A region is made up of six pieces, designed to handle the shape of a
- * typical text paragraph:
- *
- * TOP TOP TOP
- * TOP TOP
- * NW NW NW NW NW NE NE NE NE NE NE NE NE NE
- * NW NE
- * NW NE
- * SW SE
- * SW SE
- * SW SW BOTTOM BOTTOM SE SE
- * BOTTOM BOTTOM
- * BOTTOM BOTTOM BOTTOM BOTTOM BOTTOM
- *
- * When there's only a single rectangle - like when outlining something
- * simple like a button, all six pieces are still used - this makes the
- * animation smooth when sliding from a paragraph to a rectangular object
- * and then to another paragraph, for example:
- *
- * TOP TOP TOP TOP TOP TOP TOP
- * TOP TOP
- * NW NE
- * NW NE
- * SW SE
- * SW SE
- * BOTTOM BOTTOM
- * BOTTOM BOTTOM BOTTOM BOTTOM
- *
- * Each piece is just a div that uses CSS to absolutely position itself.
- * The outline effect is done using the 'box-shadow' property around the
- * whole box, with the 'clip' property used to make sure that only 2 - 3
- * sides of the box are actually shown.
- *
- * This code is very subtle! If you want to adjust something by a few
- * pixels, be prepared to do LOTS of testing!
- *
- * Tip: while debugging, comment out the clipping and make each rectangle
- * a different color. That will make it much easier to see where each piece
- * starts and ends.
- *
- * @param {Array<ClientRect>} rects The list of rects in the region.
- * These should already be sorted (top to bottom and left to right).
- * @param {?Element} parent If present, try to reuse the existing element
- * (and animate the transition).
- * @param {number} margin Margin in pixels.
- * @private
- */
-cvox.ActiveIndicator.prototype.updateIndicatorRegion_ = function(
- rects, parent, margin) {
- if (parent) {
- // Reuse the existing element (so we animate to the new location).
- var regionTop = parent.children[0];
- var regionMiddleNW = parent.children[1];
- var regionMiddleNE = parent.children[2];
- var regionMiddleSW = parent.children[3];
- var regionMiddleSE = parent.children[4];
- var regionBottom = parent.children[5];
- } else {
- // Create a new region (when the indicator first appears, or when
- // this is a secondary region, like for text continuing on a second
- // column).
- parent = this.createDiv_(this.container_, 'cvox_indicator_region');
- window.setTimeout(function() {
- parent.classList.add('cvox_indicator_visible');
- }, 0);
- regionTop = this.createDiv_(parent, 'cvox_indicator_top');
- regionMiddleNW = this.createDiv_(parent, 'cvox_indicator_middle_nw');
- regionMiddleNE = this.createDiv_(parent, 'cvox_indicator_middle_ne');
- regionMiddleSW = this.createDiv_(parent, 'cvox_indicator_middle_sw');
- regionMiddleSE = this.createDiv_(parent, 'cvox_indicator_middle_se');
- regionBottom = this.createDiv_(parent, 'cvox_indicator_bottom');
- }
-
- // Grab all of the rectangles in the top row.
- var topRect = rects[0];
- var topMiddle = Math.floor((topRect.top + topRect.bottom) / 2);
- var topIndex = 1;
- var n = rects.length;
- while (topIndex < n && rects[topIndex].top < topMiddle) {
- topRect = this.union_(topRect, rects[topIndex]);
- topMiddle = Math.floor((topRect.top + topRect.bottom) / 2);
- topIndex++;
- }
-
- if (topIndex == n) {
- // Everything fits on one line, so use special case code to form
- // the region into a rectangle.
- var r = this.inset_(topRect, -margin, -margin, -margin, -margin);
- var q1 = Math.floor((3 * r.top + 1 * r.bottom) / 4);
- var q2 = Math.floor((2 * r.top + 2 * r.bottom) / 4);
- var q3 = Math.floor((1 * r.top + 3 * r.bottom) / 4);
- this.setElementCoords_(regionTop, r.left, r.top, r.right, q1,
- true, true, true, false);
- this.setElementCoords_(regionMiddleNW, r.left, q1, r.left, q2,
- true, true, false, false);
- this.setElementCoords_(regionMiddleSW, r.left, q2, r.left, q3,
- true, false, false, true);
- this.setElementCoords_(regionMiddleNE, r.right, q1, r.right, q2,
- false, true, true, false);
- this.setElementCoords_(regionMiddleSE, r.right, q2, r.right, q3,
- false, false, true, true);
- this.setElementCoords_(regionBottom, r.left, q3, r.right, r.bottom,
- true, false, true, true);
- return;
- }
-
- // Start from the end and grab all of the rectangles in the bottom row.
- var bottomRect = rects[n - 1];
- var bottomMiddle = Math.floor((bottomRect.top + bottomRect.bottom) / 2);
- var bottomIndex = n - 2;
- while (bottomIndex >= 0 && rects[bottomIndex].bottom > bottomMiddle) {
- bottomRect = this.union_(bottomRect, rects[bottomIndex]);
- bottomMiddle = Math.floor((bottomRect.top + bottomRect.bottom) / 2);
- bottomIndex--;
- }
-
- // Extend the top and bottom rectangles a bit.
- topRect = this.inset_(topRect, -margin, -margin, -margin, margin);
- bottomRect = this.inset_(bottomRect, -margin, margin, -margin, -margin);
-
- // Whatever's in-between the top and bottom is the "middle".
- var middleRect;
- if (topIndex > bottomIndex) {
- middleRect = this.union_(topRect, bottomRect);
- middleRect.top = topRect.bottom;
- middleRect.bottom = bottomRect.top;
- middleRect.height = Math.floor((middleRect.top + middleRect.bottom) / 2);
- } else {
- middleRect = rects[topIndex];
- var middleIndex = topIndex + 1;
- while (middleIndex <= bottomIndex) {
- middleRect = this.union_(middleRect, rects[middleIndex]);
- middleIndex++;
- }
- middleRect = this.inset_(middleRect, -margin, -margin, -margin, -margin);
- middleRect.left = Math.min(
- middleRect.left, topRect.left, bottomRect.left);
- middleRect.right = Math.max(
- middleRect.right, topRect.right, bottomRect.right);
- middleRect.width = middleRect.right - middleRect.left;
- }
-
- // If the top or bottom is pretty close to the edge of the middle box,
- // make them flush.
- if (topRect.right > middleRect.right - 40) {
- topRect.right = middleRect.right;
- topRect.width = topRect.right - topRect.left;
- }
- if (topRect.left < middleRect.left + 40) {
- topRect.left = middleRect.left;
- topRect.width = topRect.right - topRect.left;
- }
- if (bottomRect.right > middleRect.right - 40) {
- bottomRect.right = middleRect.right;
- bottomRect.width = bottomRect.right - bottomRect.left;
- }
- if (bottomRect.left < middleRect.left + 40) {
- bottomRect.left = middleRect.left;
- bottomRect.width = bottomRect.right - bottomRect.left;
- }
-
- var midline = Math.floor((middleRect.top + middleRect.bottom) / 2);
-
- this.setElementRect_(regionTop, topRect, true, true, true, false);
- this.setElementRect_(regionBottom, bottomRect, true, false, true, true);
-
- this.setElementCoords_(
- regionMiddleNW,
- middleRect.left, topRect.bottom, topRect.left, midline,
- true, true, false, false);
- this.setElementCoords_(
- regionMiddleNE,
- topRect.right, topRect.bottom,
- middleRect.right, midline,
- false, true, true, false);
- this.setElementCoords_(
- regionMiddleSW,
- middleRect.left, midline, bottomRect.left, bottomRect.top,
- true, false, false, true);
- this.setElementCoords_(
- regionMiddleSE,
- bottomRect.right, midline,
- middleRect.right, bottomRect.top,
- false, false, true, true);
-};
-
-/**
- * Given two rectangles, return whether or not they intersect
- * (including a bit of slop, so if they're almost touching, we
- * return true).
- * @param {ClientRect} r1 The first rect.
- * @param {ClientRect} r2 The second rect.
- * @return {boolean} Whether or not they intersect.
- * @private
- */
-cvox.ActiveIndicator.prototype.intersects_ = function(r1, r2) {
- var slop = 2 * cvox.ActiveIndicator.MARGIN;
- return (r2.left <= r1.right + slop &&
- r2.right >= r1.left - slop &&
- r2.top <= r1.bottom + slop &&
- r2.bottom >= r1.top - slop);
-};
-
-/**
- * Given two rectangles, compute their union.
- * @param {ClientRect} r1 The first rect.
- * @param {ClientRect} r2 The second rect.
- * @return {ClientRect} The union of the two rectangles.
- * @private
- * @suppress {invalidCasts} invalid cast - must be a subtype or supertype
- * from: {bottom: number, height: number, left: number, right: number, ...}
- * to : (ClientRect|null)
- */
-cvox.ActiveIndicator.prototype.union_ = function(r1, r2) {
- var result = {
- left: Math.min(r1.left, r2.left),
- top: Math.min(r1.top, r2.top),
- right: Math.max(r1.right, r2.right),
- bottom: Math.max(r1.bottom, r2.bottom)
- };
- result.width = result.right - result.left;
- result.height = result.bottom - result.top;
- return /** @type {ClientRect} */(result);
-};
-
-/**
- * Given a rectangle and four offsets, return a new rectangle inset by
- * the given offsets.
- * @param {ClientRect} r The first rect.
- * @param {number} left The left inset.
- * @param {number} top The top inset.
- * @param {number} right The right inset.
- * @param {number} bottom The bottom inset.
- * @return {ClientRect} The new rectangle.
- * @private
- * @suppress {invalidCasts} invalid cast - must be a subtype or supertype
- * from: {bottom: number, height: number, left: number, right: number, ...}
- * to : (ClientRect|null)
- */
-cvox.ActiveIndicator.prototype.inset_ = function(r, left, top, right, bottom) {
- var result = {
- left: r.left + left,
- top: r.top + top,
- right: r.right - right,
- bottom: r.bottom - bottom
- };
- result.width = result.right - result.left;
- result.height = result.bottom - result.top;
- return /** @type {ClientRect} */(result);
-};
-
-/**
- * Convenience method to create an element of type DIV, give it
- * particular class name, and add it as a child of a given parent.
- * @param {Element} parent The parent element of the new div.
- * @param {string} className The class name of the new div.
- * @param {Node=} opt_before Will insert before this node, if present.
- * @return {Element} The new div.
- * @private
- */
-cvox.ActiveIndicator.prototype.createDiv_ = function(
- parent, className, opt_before) {
- var elem = document.createElement('div');
- elem.setAttribute('aria-hidden', 'true');
-
- // This allows the MutationObserver used for live regions to quickly
- // ignore changes to this element rather than doing a lot of calculations
- // first.
- elem.setAttribute('cvoxIgnore', '');
-
- elem.className = className;
- if (opt_before) {
- parent.insertBefore(elem, opt_before);
- } else {
- parent.appendChild(elem);
- }
- return elem;
-};
-
-/**
- * In WebKit, when the user has zoomed the page, every CSS coordinate is
- * multiplied by the zoom level and rounded down. This can cause objects to
- * fail to line up; for example an object with left position 100 and width
- * 50 may not line up with an object with right position 150 pixels, if the
- * zoom is not equal to 1.0. To fix this, we compute the actual desired
- * coordinate when zoomed, then add a small fractional offset and divide
- * by the zoom factor, and use that value as the item's coordinate instead.
- *
- * @param {number} x A coordinate to be transformed.
- * @return {number} The new coordinate to use.
- * @private
- */
-cvox.ActiveIndicator.prototype.fixZoom_ = function(x) {
- return (Math.round(x * this.zoom_) + 0.1) / this.zoom_;
-};
-
-/**
- * See fixZoom_, above. This method is the same except that it returns the
- * width such that right pos (x + width) is correct when multiplied by the
- * zoom factor.
- *
- * @param {number} x A coordinate to be transformed.
- * @param {number} width The width of the object.
- * @return {number} The new width to use.
- * @private
- */
-cvox.ActiveIndicator.prototype.fixZoomSum_ = function(x, width) {
- var zoomedX = Math.round(x * this.zoom_);
- var zoomedRight = Math.round((x + width) * this.zoom_);
- var zoomedWidth = (zoomedRight - zoomedX);
- return (zoomedWidth + 0.1) / this.zoom_;
-};
-
-/**
- * Set the coordinates of an element to the given left, top, right, and
- * bottom pixel coordinates, taking the browser zoom level into account.
- * Also set the clipping rectangle to exclude some of the edges of the
- * rectangle, based on the value of showLeft, showTop, showRight, and
- * showBottom.
- *
- * @param {Element} element The element to move.
- * @param {number} left The new left coordinate.
- * @param {number} top The new top coordinate.
- * @param {number} right The new right coordinate.
- * @param {number} bottom The new bottom coordinate.
- * @param {boolean} showLeft Whether to show or clip at the left border.
- * @param {boolean} showTop Whether to show or clip at the top border.
- * @param {boolean} showRight Whether to show or clip at the right border.
- * @param {boolean} showBottom Whether to show or clip at the bottom border.
- * @private
- */
-cvox.ActiveIndicator.prototype.setElementCoords_ = function(
- element,
- left, top, right, bottom,
- showLeft, showTop, showRight, showBottom) {
- var origWidth = right - left;
- var origHeight = bottom - top;
-
- var width = right - left;
- var height = bottom - top;
- var clipLeft = showLeft ? -20 : 0;
- var clipTop = showTop ? -20 : 0;
- var clipRight = showRight ? 20 : 0;
- var clipBottom = showBottom ? 20 : 0;
- if (width == 0) {
- if (showRight) {
- left -= 5;
- width += 5;
- } else if (showLeft) {
- width += 10;
- }
- clipTop = 10;
- clipBottom = 10;
- top -= 10;
- height += 20;
- }
- if (!showBottom)
- height += 5;
- if (!showTop) {
- top -= 5;
- height += 5;
- clipTop += 5;
- clipBottom += 5;
- }
- if (clipRight == 0 && origWidth == 0) {
- clipRight = 1;
- } else {
- clipRight = this.fixZoomSum_(left, clipRight + origWidth);
- }
- clipBottom = this.fixZoomSum_(top, clipBottom + origHeight);
-
- element.style.left = this.fixZoom_(left) + 'px';
- element.style.top = this.fixZoom_(top) + 'px';
- element.style.width = this.fixZoomSum_(left, width) + 'px';
- element.style.height = this.fixZoomSum_(top, height) + 'px';
- element.style.clip =
- 'rect(' + [clipTop, clipRight, clipBottom, clipLeft].join('px ') + 'px)';
-};
-
-/**
- * Same as setElementCoords_, but takes a rect instead of coordinates.
- *
- * @param {Element} element The element to move.
- * @param {ClientRect} r The new coordinates.
- * @param {boolean} showLeft Whether to show or clip at the left border.
- * @param {boolean} showTop Whether to show or clip at the top border.
- * @param {boolean} showRight Whether to show or clip at the right border.
- * @param {boolean} showBottom Whether to show or clip at the bottom border.
- * @private
- */
-cvox.ActiveIndicator.prototype.setElementRect_ = function(
- element, r, showLeft, showTop, showRight, showBottom) {
- this.setElementCoords_(element, r.left, r.top, r.right, r.bottom,
- showLeft, showTop, showRight, showBottom);
-};
-
-/**
- * Compute an approximation of the current browser zoom level by
- * comparing the measurement of a large character of text
- * with the -webkit-text-size-adjust:none style to the expected
- * pixel coordinates if it was adjusted.
- * @private
- */
-cvox.ActiveIndicator.prototype.computeZoomLevel_ = function() {
- if (window.innerHeight === this.innerHeight_ &&
- window.innerWidth === this.innerWidth_) {
- return;
- }
-
- this.innerHeight_ = window.innerHeight;
- this.innerWidth_ = window.innerWidth;
-
- var zoomMeasureElement = document.createElement('div');
- zoomMeasureElement.innerHTML = 'X';
- zoomMeasureElement.setAttribute(
- 'style',
- 'font: 5000px/1em sans-serif !important;' +
- ' -webkit-text-size-adjust:none !important;' +
- ' visibility:hidden !important;' +
- ' left: -10000px !important;' +
- ' top: -10000px !important;' +
- ' position:absolute !important;');
- document.body.appendChild(zoomMeasureElement);
-
- var zoomLevel = 5000 / zoomMeasureElement.clientHeight;
- var newZoom = Math.round(zoomLevel * 500) / 500;
- if (newZoom > 0.1 && newZoom < 10) {
- this.zoom_ = newZoom;
- }
-
- // TODO(dmazzoni): warn or log if the computed zoom is bad?
- zoomMeasureElement.parentNode.removeChild(zoomMeasureElement);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api.js
deleted file mode 100644
index 0b0bf75051e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api.js
+++ /dev/null
@@ -1,578 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Public APIs to enable web applications to communicate
- * with ChromeVox.
- */
-
-if (typeof(goog) != 'undefined' && goog.provide) {
- goog.provide('cvox.Api');
- goog.provide('cvox.Api.Math');
-}
-
-if (typeof(goog) != 'undefined' && goog.require) {
- goog.require('cvox.ApiImplementation');
-}
-
-(function() {
- /*
- * Private data and methods.
- */
-
- /**
- * The name of the port between the content script and background page.
- * @type {string}
- * @const
- */
- var PORT_NAME = 'cvox.Port';
-
- /**
- * The name of the message between the page and content script that sets
- * up the bidirectional port between them.
- * @type {string}
- * @const
- */
- var PORT_SETUP_MSG = 'cvox.PortSetup';
-
- /**
- * The message between content script and the page that indicates the
- * connection to the background page has been lost.
- * @type {string}
- * @const
- */
- var DISCONNECT_MSG = 'cvox.Disconnect';
-
- /**
- * The channel between the page and content script.
- * @type {MessageChannel}
- */
- var channel;
-
- /**
- * Tracks whether or not the ChromeVox API should be considered active.
- * @type {boolean}
- */
- var isActive_ = false;
-
- /**
- * The next id to use for async callbacks.
- * @type {number}
- */
- var nextCallbackId_ = 1;
-
- /**
- * Map from callback ID to callback function.
- * @type {Object<number, function(*)>}
- */
- var callbackMap_ = {};
-
- /**
- * Internal function to connect to the content script.
- */
- function connect_() {
- if (channel) {
- // If there is already an existing channel, close the existing ports.
- channel.port1.close();
- channel.port2.close();
- channel = null;
- }
-
- channel = new MessageChannel();
- window.postMessage(PORT_SETUP_MSG, [channel.port2], '*');
- channel.port1.onmessage = function(event) {
- if (event.data == DISCONNECT_MSG) {
- channel = null;
- }
- try {
- var message = JSON.parse(event.data);
- if (message['id'] && callbackMap_[message['id']]) {
- callbackMap_[message['id']](message);
- delete callbackMap_[message['id']];
- }
- } catch (e) {
- }
- };
- }
-
- /**
- * Internal function to send a message to the content script and
- * call a callback with the response.
- * @param {Object} message A serializable message.
- * @param {function(*)} callback A callback that will be called
- * with the response message.
- */
- function callAsync_(message, callback) {
- var id = nextCallbackId_;
- nextCallbackId_++;
- if (message['args'] === undefined) {
- message['args'] = [];
- }
- message['args'] = [id].concat(message['args']);
- callbackMap_[id] = callback;
- channel.port1.postMessage(JSON.stringify(message));
- }
-
- /**
- * Wraps callAsync_ for sending speak requests.
- * @param {Object} message A serializable message.
- * @param {Object=} properties Speech properties to use for this utterance.
- * @private
- */
- function callSpeakAsync_(message, properties) {
- var callback = null;
- /* Use the user supplied callback as callAsync_'s callback. */
- if (properties && properties['endCallback']) {
- callback = properties['endCallback'];
- }
- callAsync_(message, callback);
- };
-
-
- /*
- * Public API.
- */
-
- if (!window['cvox']) {
- window['cvox'] = {};
- }
- var cvox = window.cvox;
-
-
- /**
- * ApiImplementation - this is only visible if all the scripts are compiled
- * together like in the Android case. Otherwise, implementation will remain
- * null which means communication must happen over the bridge.
- *
- * @type {*}
- */
- var implementation = null;
- if (typeof(cvox.ApiImplementation) != 'undefined') {
- implementation = cvox.ApiImplementation;
- }
-
-
- /**
- * @constructor
- */
- cvox.Api = function() {
- };
-
- /**
- * Internal-only function, only to be called by the content script.
- * Enables the API and connects to the content script.
- */
- cvox.Api.internalEnable = function() {
- isActive_ = true;
- if (!implementation) {
- connect_();
- }
- var event = document.createEvent('UIEvents');
- event.initEvent('chromeVoxLoaded', true, false);
- document.dispatchEvent(event);
- };
-
- /**
- * Internal-only function, only to be called by the content script.
- * Disables the ChromeVox API.
- */
- cvox.Api.internalDisable = function() {
- isActive_ = false;
- channel = null;
- var event = document.createEvent('UIEvents');
- event.initEvent('chromeVoxUnloaded', true, false);
- document.dispatchEvent(event);
- };
-
- /**
- * Returns true if ChromeVox is currently running. If the API is available
- * in the JavaScript namespace but this method returns false, it means that
- * the user has (temporarily) disabled ChromeVox.
- *
- * You can listen for the 'chromeVoxLoaded' event to be notified when
- * ChromeVox is loaded.
- *
- * @return {boolean} True if ChromeVox is currently active.
- */
- cvox.Api.isChromeVoxActive = function() {
- if (implementation) {
- return isActive_;
- }
- return !!channel;
- };
-
- /**
- * Speaks the given string using the specified queueMode and properties.
- *
- * @param {string} textString The string of text to be spoken.
- * @param {number=} queueMode Valid modes are 0 for flush; 1 for queue.
- * @param {Object=} properties Speech properties to use for this utterance.
- */
- cvox.Api.speak = function(textString, queueMode, properties) {
- if (!cvox.Api.isChromeVoxActive()) {
- return;
- }
-
- if (implementation) {
- implementation.speak(textString, queueMode, properties);
- } else {
- var message = {
- 'cmd': 'speak',
- 'args': [textString, queueMode, properties]
- };
- callSpeakAsync_(message, properties);
- }
- };
-
- /**
- * Speaks a description of the given node.
- *
- * @param {Node} targetNode A DOM node to speak.
- * @param {number=} queueMode Valid modes are 0 for flush; 1 for queue.
- * @param {Object=} properties Speech properties to use for this utterance.
- */
- cvox.Api.speakNode = function(targetNode, queueMode, properties) {
- if (!cvox.Api.isChromeVoxActive()) {
- return;
- }
-
- if (implementation) {
- implementation.speak(cvox.DomUtil.getName(targetNode),
- queueMode, properties);
- } else {
- var message = {
- 'cmd': 'speakNodeRef',
- 'args': [cvox.ApiUtils.makeNodeReference(targetNode), queueMode,
- properties]
- };
- callSpeakAsync_(message, properties);
- }
- };
-
- /**
- * Stops speech.
- */
- cvox.Api.stop = function() {
- if (!cvox.Api.isChromeVoxActive()) {
- return;
- }
-
- if (implementation) {
- implementation.stop();
- } else {
- var message = {
- 'cmd': 'stop'
- };
- channel.port1.postMessage(JSON.stringify(message));
- }
- };
-
- /**
- * Plays the specified earcon sound.
- *
- * @param {string} earcon An earcon name.
- * Valid names are:
- * ALERT_MODAL
- * ALERT_NONMODAL
- * BUTTON
- * CHECK_OFF
- * CHECK_ON
- * EDITABLE_TEXT
- * INVALID_KEYPRESS
- * LINK
- * LISTBOX
- * LIST_ITEM
- * OBJECT_CLOSE
- * OBJECT_OPEN
- * OBJECT_SELECT
- * PAGE_START_LOADING
- * RECOVER_FOCUS
- * SKIP
- * WRAP
- * WRAP_EDGE
- * This list may expand over time.
- */
- cvox.Api.playEarcon = function(earcon) {
- if (!cvox.Api.isChromeVoxActive()) {
- return;
- }
- if (implementation) {
- implementation.playEarcon(earcon);
- } else {
- var message = {
- 'cmd': 'playEarcon',
- 'args': [earcon]
- };
- channel.port1.postMessage(JSON.stringify(message));
- }
- };
-
- /**
- * Synchronizes ChromeVox's internal cursor to the targetNode.
- * Note that this will NOT trigger reading unless given the
- * optional argument; it is for setting the internal ChromeVox
- * cursor so that when the user resumes reading, they will be
- * starting from a reasonable position.
- *
- * @param {Node} targetNode The node that ChromeVox should be synced to.
- * @param {boolean=} speakNode If true, speaks out the node.
- */
- cvox.Api.syncToNode = function(targetNode, speakNode) {
- if (!cvox.Api.isChromeVoxActive() || !targetNode) {
- return;
- }
-
- if (implementation) {
- implementation.syncToNode(targetNode, speakNode);
- } else {
- var message = {
- 'cmd': 'syncToNodeRef',
- 'args': [cvox.ApiUtils.makeNodeReference(targetNode), speakNode]
- };
- channel.port1.postMessage(JSON.stringify(message));
- }
- };
-
- /**
- * Retrieves the current node and calls the given callback function with it.
- *
- * @param {Function} callback The function to be called.
- */
- cvox.Api.getCurrentNode = function(callback) {
- if (!cvox.Api.isChromeVoxActive() || !callback) {
- return;
- }
-
- if (implementation) {
- callback(cvox.ChromeVox.navigationManager.getCurrentNode());
- } else {
- callAsync_({'cmd': 'getCurrentNode'}, function(response) {
- callback(cvox.ApiUtils.getNodeFromRef(response['currentNode']));
- });
- }
- };
-
- /**
- * Specifies how the targetNode should be spoken using an array of
- * NodeDescriptions.
- *
- * @param {Node} targetNode The node that the NodeDescriptions should be
- * spoken using the given NodeDescriptions.
- * @param {Array<Object>} nodeDescriptions The Array of
- * NodeDescriptions for the given node.
- */
- cvox.Api.setSpeechForNode = function(targetNode, nodeDescriptions) {
- if (!cvox.Api.isChromeVoxActive() || !targetNode || !nodeDescriptions) {
- return;
- }
- targetNode.setAttribute('cvoxnodedesc', JSON.stringify(nodeDescriptions));
- };
-
- /**
- * Simulate a click on an element.
- *
- * @param {Element} targetElement The element that should be clicked.
- * @param {boolean} shiftKey Specifies if shift is held down.
- */
- cvox.Api.click = function(targetElement, shiftKey) {
- if (!cvox.Api.isChromeVoxActive() || !targetElement) {
- return;
- }
-
- if (implementation) {
- cvox.DomUtil.clickElem(targetElement, shiftKey, true);
- } else {
- var message = {
- 'cmd': 'clickNodeRef',
- 'args': [cvox.ApiUtils.makeNodeReference(targetElement), shiftKey]
- };
- channel.port1.postMessage(JSON.stringify(message));
- }
- };
-
- /**
- * Returns the build info.
- *
- * @param {function(string)} callback Function to receive the build info.
- */
- cvox.Api.getBuild = function(callback) {
- if (!cvox.Api.isChromeVoxActive() || !callback) {
- return;
- }
- if (implementation) {
- callback(cvox.BuildInfo.build);
- } else {
- callAsync_({'cmd': 'getBuild'}, function(response) {
- callback(response['build']);
- });
- }
- };
-
- /**
- * Returns the ChromeVox version, a string of the form 'x.y.z',
- * like '1.18.0'.
- *
- * @param {function(string)} callback Function to receive the version.
- */
- cvox.Api.getVersion = function(callback) {
- if (!cvox.Api.isChromeVoxActive() || !callback) {
- return;
- }
- if (implementation) {
- callback(cvox.ChromeVox.version + '');
- } else {
- callAsync_({'cmd': 'getVersion'}, function(response) {
- callback(response['version']);
- });
- }
- };
-
- /**
- * Returns the key codes of the ChromeVox modifier keys.
- * @param {function(Array<number>)} callback Function to receive the keys.
- */
- cvox.Api.getCvoxModifierKeys = function(callback) {
- if (!cvox.Api.isChromeVoxActive() || !callback) {
- return;
- }
- if (implementation) {
- callback(cvox.KeyUtil.cvoxModKeyCodes());
- } else {
- callAsync_({'cmd': 'getCvoxModKeys'}, function(response) {
- callback(response['keyCodes']);
- });
- }
- };
-
- /**
- * Returns if ChromeVox will handle this key event.
- * @param {Event} keyEvent A key event.
- * @param {function(boolean)} callback Function to receive the keys.
- */
- cvox.Api.isKeyShortcut = function(keyEvent, callback) {
- if (!callback) {
- return;
- }
- if (!cvox.Api.isChromeVoxActive()) {
- callback(false);
- return;
- }
- /* TODO(peterxiao): Ignore these keys until we do this in a smarter way. */
- var KEY_IGNORE_LIST = [
- 37, /* Left arrow. */
- 39 /* Right arrow. */
- ];
- if (KEY_IGNORE_LIST.indexOf(keyEvent.keyCode) && !keyEvent.altKey &&
- !keyEvent.shiftKey && !keyEvent.ctrlKey && !keyEvent.metaKey) {
- callback(false);
- return;
- }
-
- if (implementation) {
- var keySeq = cvox.KeyUtil.keyEventToKeySequence(keyEvent);
- callback(cvox.ChromeVoxKbHandler.handlerKeyMap.hasKey(keySeq));
- } else {
- var strippedKeyEvent = {};
- /* Blacklist these props so we can safely stringify. */
- var BLACK_LIST_PROPS = ['target', 'srcElement', 'currentTarget', 'view'];
- for (var prop in keyEvent) {
- if (BLACK_LIST_PROPS.indexOf(prop) === -1) {
- strippedKeyEvent[prop] = keyEvent[prop];
- }
- }
- var message = {
- 'cmd': 'isKeyShortcut',
- 'args': [strippedKeyEvent]
- };
- callAsync_(message, function(response) {
- callback(response['isHandled']);
- });
- }
- };
-
- /**
- * Set key echoing on key press.
- * @param {boolean} keyEcho Whether key echoing should be on or off.
- */
- cvox.Api.setKeyEcho = function(keyEcho) {
- if (!cvox.Api.isChromeVoxActive()) {
- return;
- }
-
- if (implementation) {
- implementation.setKeyEcho(keyEcho);
- } else {
- var message = {
- 'cmd': 'setKeyEcho',
- 'args': [keyEcho]
- };
- channel.port1.postMessage(JSON.stringify(message));
- }
- };
-
- /**
- * Exports the ChromeVox math API.
- * TODO(dtseng, sorge): Requires more detailed documentation for class
- * members.
- * @constructor
- */
- cvox.Api.Math = function() {};
-
- // TODO(dtseng, sorge): This need not be specific to math; once speech engine
- // stabilizes, we can generalize.
- // TODO(dtseng, sorge): This API is way too complicated; consolidate args
- // when re-thinking underlying representation. Some of the args don't have a
- // well-defined purpose especially for a caller.
- /**
- * Defines a math speech rule.
- * @param {string} name Rule name.
- * @param {string} dynamic Dynamic constraint annotation. In the case of a
- * math rule it consists of a domain.style string.
- * @param {string} action An action of rule components.
- * @param {string} prec XPath or custom function constraining match.
- * @param {...string} constraints Additional constraints.
- */
- cvox.Api.Math.defineRule =
- function(name, dynamic, action, prec, constraints) {
- if (!cvox.Api.isChromeVoxActive()) {
- return;
- }
- var constraintList = Array.prototype.slice.call(arguments, 4);
- var args = [name, dynamic, action, prec].concat(constraintList);
- if (implementation) {
- implementation.Math.defineRule.apply(implementation.Math, args);
- } else {
- var msg = {'cmd': 'Math.defineRule', args: args};
- channel.port1.postMessage(JSON.stringify(msg));
- }
- };
-
- cvox.Api.internalEnable();
-
- /**
- * NodeDescription
- * Data structure for holding information on how to speak a particular node.
- * NodeDescriptions will be converted into NavDescriptions for ChromeVox.
- *
- * The string data is separated into context, text, userValue, and annotation
- * to enable ChromeVox to speak each of these with the voice settings that
- * are consistent with how ChromeVox normally presents information about
- * nodes to users.
- *
- * @param {string} context Contextual information that the user should
- * hear first which is not part of main content itself. For example,
- * the user/date of a given post.
- * @param {string} text The main content of the node.
- * @param {string} userValue Anything that the user has entered.
- * @param {string} annotation The role and state of the object.
- */
- // TODO (clchen, deboer): Put NodeDescription into externs for developers
- // building ChromeVox extensions.
- cvox.NodeDescription = function(context, text, userValue, annotation) {
- this.context = context ? context : '';
- this.text = text ? text : '';
- this.userValue = userValue ? userValue : '';
- this.annotation = annotation ? annotation : '';
- };
-})();
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api_implementation.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api_implementation.js
deleted file mode 100644
index 8b8423d76aa..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api_implementation.js
+++ /dev/null
@@ -1,409 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Implentation of ChromeVox's public API.
- *
- */
-
-goog.provide('cvox.ApiImplementation');
-goog.provide('cvox.ApiImplementation.Math');
-
-goog.require('cvox.ApiUtil');
-goog.require('cvox.AriaUtil');
-goog.require('cvox.BuildInfo');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxJSON');
-goog.require('cvox.DomUtil');
-goog.require('cvox.ScriptInstaller');
-
-/**
- * @constructor
- */
-cvox.ApiImplementation = function() {
-};
-
-/**
- * The URL to the script loader.
- * @type {string}
- */
-cvox.ApiImplementation.siteSpecificScriptLoader;
-
-/**
- * The URL base for the site-specific scripts.
- * @type {string}
- */
-cvox.ApiImplementation.siteSpecificScriptBase;
-
-/**
- * Inject the API into the page and set up communication with it.
- * @param {function()=} opt_onload A function called when the script is loaded.
- */
-cvox.ApiImplementation.init = function(opt_onload) {
- window.addEventListener('message', cvox.ApiImplementation.portSetup, true);
- var scripts = new Array();
- scripts.push(cvox.ChromeVox.host.getFileSrc(
- 'chromevox/injected/api_util.js'));
- scripts.push(cvox.ChromeVox.host.getApiSrc());
- scripts.push(cvox.ApiImplementation.siteSpecificScriptLoader);
-
- var didInstall = cvox.ScriptInstaller.installScript(scripts,
- 'cvoxapi', opt_onload, cvox.ApiImplementation.siteSpecificScriptBase);
-
- if (!didInstall) {
- // If the API script is already installed, just re-enable it.
- window.location.href = 'javascript:cvox.Api.internalEnable();';
- }
-};
-
-/**
- * This method is called when the content script receives a message from
- * the page.
- * @param {Event} event The DOM event with the message data.
- * @return {boolean} True if default event processing should continue.
- */
-cvox.ApiImplementation.portSetup = function(event) {
- if (event.data == 'cvox.PortSetup') {
- cvox.ApiImplementation.port = event.ports[0];
- cvox.ApiImplementation.port.onmessage = function(event) {
- cvox.ApiImplementation.dispatchApiMessage(
- cvox.ChromeVoxJSON.parse(event.data));
- };
-
- // Stop propagation since it was our message.
- event.stopPropagation();
- return false;
- }
- return true;
-};
-
-/**
- * Call the appropriate API function given a message from the page.
- * @param {*} message The message.
- */
-cvox.ApiImplementation.dispatchApiMessage = function(message) {
- var method;
- switch (message['cmd']) {
- case 'speak': method = cvox.ApiImplementation.speak; break;
- case 'speakNodeRef': method = cvox.ApiImplementation.speakNodeRef; break;
- case 'stop': method = cvox.ApiImplementation.stop; break;
- case 'playEarcon': method = cvox.ApiImplementation.playEarcon; break;
- case 'syncToNodeRef': method = cvox.ApiImplementation.syncToNodeRef; break;
- case 'clickNodeRef': method = cvox.ApiImplementation.clickNodeRef; break;
- case 'getBuild': method = cvox.ApiImplementation.getBuild; break;
- case 'getVersion': method = cvox.ApiImplementation.getVersion; break;
- case 'getCurrentNode': method = cvox.ApiImplementation.getCurrentNode;
- break;
- case 'getCvoxModKeys': method = cvox.ApiImplementation.getCvoxModKeys;
- break;
- case 'isKeyShortcut': method = cvox.ApiImplementation.isKeyShortcut; break;
- case 'setKeyEcho': method = cvox.ApiImplementation.setKeyEcho; break;
- case 'Math.defineRule':
- method = cvox.ApiImplementation.Math.defineRule; break;
- break;
- }
- if (!method) {
- throw 'Unknown API call: ' + message['cmd'];
- }
-
- method.apply(cvox.ApiImplementation, message['args']);
-};
-
-/**
- * Sets endCallback in properties to call callbackId's function.
- * @param {Object} properties Speech properties to use for this utterance.
- * @param {number} callbackId The callback Id.
- * @private
- */
-function setupEndCallback_(properties, callbackId) {
- var endCallback = function() {
- cvox.ApiImplementation.port.postMessage(cvox.ChromeVoxJSON.stringify(
- {
- 'id': callbackId
- }));
- };
- if (properties) {
- properties['endCallback'] = endCallback;
- }
-}
-
-/**
- * Speaks the given string using the specified queueMode and properties.
- *
- * @param {number} callbackId The callback Id.
- * @param {string} textString The string of text to be spoken.
- * @param {number=} queueMode Valid modes are 0 for flush; 1 for queue.
- * @param {Object=} properties Speech properties to use for this utterance.
- */
-cvox.ApiImplementation.speak = function(
- callbackId, textString, queueMode, properties) {
- if (cvox.ChromeVox.isActive) {
- if (!properties) {
- properties = {};
- }
- setupEndCallback_(properties, callbackId);
- cvox.ChromeVox.tts.speak(textString,
- /** @type {cvox.QueueMode} */ (queueMode),
- properties);
- }
-};
-
-/**
- * Speaks the given node.
- *
- * @param {Node} node The node that ChromeVox should be synced to.
- * @param {number=} queueMode Valid modes are 0 for flush; 1 for queue.
- * @param {Object=} properties Speech properties to use for this utterance.
- */
-cvox.ApiImplementation.speakNode = function(node, queueMode, properties) {
- if (cvox.ChromeVox.isActive) {
- cvox.ChromeVox.tts.speak(
- cvox.DomUtil.getName(node),
- /** @type {cvox.QueueMode} */ (queueMode),
- properties);
- }
-};
-
-/**
- * Speaks the given node.
- *
- * @param {number} callbackId The callback Id.
- * @param {Object} nodeRef A serializable reference to a node.
- * @param {number=} queueMode Valid modes are 0 for flush; 1 for queue.
- * @param {Object=} properties Speech properties to use for this utterance.
- */
-cvox.ApiImplementation.speakNodeRef = function(
- callbackId, nodeRef, queueMode, properties) {
- var node = cvox.ApiUtils.getNodeFromRef(nodeRef);
- if (!properties) {
- properties = {};
- }
- setupEndCallback_(properties, callbackId);
- cvox.ApiImplementation.speakNode(node, queueMode, properties);
-};
-
-/**
- * Stops speech.
- */
-cvox.ApiImplementation.stop = function() {
- if (cvox.ChromeVox.isActive) {
- cvox.ChromeVox.tts.stop();
- }
-};
-
-/**
- * Plays the specified earcon sound.
- *
- * @param {string} earcon An earcon name.
- */
-cvox.ApiImplementation.playEarcon = function(earcon) {
- if (cvox.ChromeVox.isActive && cvox.Earcon[earcon]) {
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon[earcon]);
- }
-};
-
-/**
- * Synchronizes ChromeVox's internal cursor to a node by id.
- *
- * @param {Object} nodeRef A serializable reference to a node.
- * @param {boolean=} speakNode If true, speaks out the node.
- */
-cvox.ApiImplementation.syncToNodeRef = function(nodeRef, speakNode) {
- var node = cvox.ApiUtils.getNodeFromRef(nodeRef);
- cvox.ApiImplementation.syncToNode(node, speakNode);
-};
-
-/**
- * Synchronizes ChromeVox's internal cursor to the targetNode.
- * Note that this will NOT trigger reading unless given the optional argument;
- * it is for setting the internal ChromeVox cursor so that when the user resumes
- * reading, they will be starting from a reasonable position.
- *
- * @param {Node} targetNode The node that ChromeVox should be synced to.
- * @param {boolean=} opt_speakNode If true, speaks out the node.
- * @param {number=} opt_queueMode The queue mode to use for speaking.
- */
-cvox.ApiImplementation.syncToNode = function(
- targetNode, opt_speakNode, opt_queueMode) {
- if (!cvox.ChromeVox.isActive) {
- return;
- }
-
- if (opt_queueMode == undefined) {
- opt_queueMode = cvox.QueueMode.CATEGORY_FLUSH;
- }
-
- cvox.ChromeVox.navigationManager.updateSelToArbitraryNode(targetNode, true);
- cvox.ChromeVox.navigationManager.updateIndicator();
-
- if (opt_speakNode == undefined) {
- opt_speakNode = false;
- }
-
- // Don't speak anything if the node is hidden or invisible.
- if (cvox.AriaUtil.isHiddenRecursive(targetNode)) {
- opt_speakNode = false;
- }
-
- if (opt_speakNode) {
- cvox.ChromeVox.navigationManager.speakDescriptionArray(
- cvox.ApiImplementation.getDesc_(targetNode),
- /** @type {cvox.QueueMode} */ (opt_queueMode),
- null,
- null,
- cvox.TtsCategory.NAV);
- }
-
- cvox.ChromeVox.braille.write(cvox.ChromeVox.navigationManager.getBraille());
-
- cvox.ChromeVox.navigationManager.updatePosition(targetNode);
-};
-
-/**
- * Get the current node that ChromeVox is on.
- * @param {number} callbackId The callback Id.
- */
-cvox.ApiImplementation.getCurrentNode = function(callbackId) {
- var currentNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- cvox.ApiImplementation.port.postMessage(cvox.ChromeVoxJSON.stringify(
- {
- 'id': callbackId,
- 'currentNode': cvox.ApiUtils.makeNodeReference(currentNode)
- }));
-};
-
-/**
- * Gets the predefined description set on a node by an api call, if such
- * a call was made. Otherwise returns the description that the NavigationManager
- * would speak.
- * @param {Node} node The node for which to get the description.
- * @return {Array<cvox.NavDescription>} The description array.
- * @private
- */
-cvox.ApiImplementation.getDesc_ = function(node) {
- if (!node.hasAttribute('cvoxnodedesc')) {
- return cvox.ChromeVox.navigationManager.getDescription();
- }
-
- var preDesc = cvox.ChromeVoxJSON.parse(node.getAttribute('cvoxnodedesc'));
- var currentDesc = new Array();
- for (var i = 0; i < preDesc.length; ++i) {
- var inDesc = preDesc[i];
- // TODO: this can probably be replaced with just NavDescription(inDesc)
- // need test case to ensure this change will work
- currentDesc.push(new cvox.NavDescription({
- context: inDesc.context,
- text: inDesc.text,
- userValue: inDesc.userValue,
- annotation: inDesc.annotation
- }));
- }
- return currentDesc;
-};
-
-/**
- * Simulate a click on an element.
- *
- * @param {Object} nodeRef A serializable reference to a node.
- * @param {boolean} shiftKey Specifies if shift is held down.
- */
-cvox.ApiImplementation.clickNodeRef = function(nodeRef, shiftKey) {
- cvox.DomUtil.clickElem(
- cvox.ApiUtils.getNodeFromRef(nodeRef), shiftKey, false);
-};
-
-/**
- * Get the ChromeVox build info string.
- * @param {number} callbackId The callback Id.
- */
-cvox.ApiImplementation.getBuild = function(callbackId) {
- cvox.ApiImplementation.port.postMessage(cvox.ChromeVoxJSON.stringify(
- {
- 'id': callbackId,
- 'build': cvox.BuildInfo.build
- }));
-};
-
-/**
- * Get the ChromeVox version.
- * @param {number} callbackId The callback Id.
- */
-cvox.ApiImplementation.getVersion = function(callbackId) {
- var version = cvox.ChromeVox.version;
- if (version == null) {
- window.setTimeout(function() {
- cvox.ApiImplementation.getVersion(callbackId);
- }, 1000);
- return;
- }
- cvox.ApiImplementation.port.postMessage(cvox.ChromeVoxJSON.stringify(
- {
- 'id': callbackId,
- 'version': version
- }));
-};
-
-/**
- * Get the ChromeVox modifier keys.
- * @param {number} callbackId The callback Id.
- */
-cvox.ApiImplementation.getCvoxModKeys = function(callbackId) {
- cvox.ApiImplementation.port.postMessage(cvox.ChromeVoxJSON.stringify(
- {
- 'id': callbackId,
- 'keyCodes': cvox.KeyUtil.cvoxModKeyCodes()
- }));
-};
-
-/**
- * Return if the keyEvent has a key binding.
- * @param {number} callbackId The callback Id.
- * @param {Event} keyEvent A key event.
- */
-cvox.ApiImplementation.isKeyShortcut = function(callbackId, keyEvent) {
- var keySeq = cvox.KeyUtil.keyEventToKeySequence(keyEvent);
- cvox.ApiImplementation.port.postMessage(cvox.ChromeVoxJSON.stringify(
- {
- 'id': callbackId,
- 'isHandled': cvox.ChromeVoxKbHandler.handlerKeyMap.hasKey(keySeq)
- }));
-};
-
-/**
-* Set key echoing on key press.
-* @param {boolean} keyEcho Whether key echoing should be on or off.
-*/
-cvox.ApiImplementation.setKeyEcho = function(keyEcho) {
- var msg = cvox.ChromeVox.keyEcho;
- msg[document.location.href] = keyEcho;
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'keyEcho',
- 'value': JSON.stringify(msg)
- });
-};
-
-/**
- * @constructor
- */
-cvox.ApiImplementation.Math = function() {};
-
-/**
- * Defines a math speech rule.
- * @param {string} name Rule name.
- * @param {string} dynamic Dynamic constraint annotation. In the case of a
- * math rule it consists of a domain.style string.
- * @param {string} action An action of rule components.
- * @param {string} prec XPath or custom function constraining match.
- * @param {...string} constraints Additional constraints.
- */
-cvox.ApiImplementation.Math.defineRule =
- function(name, dynamic, action, prec, constraints) {
- var mathStore = cvox.MathmlStore.getInstance();
- var constraintList = Array.prototype.slice.call(arguments, 4);
- var args = [name, dynamic, action, prec].concat(constraintList);
-
- mathStore.defineRule.apply(mathStore, args);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api_util.js
deleted file mode 100644
index 606000b3e48..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/api_util.js
+++ /dev/null
@@ -1,90 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Shared util methods between api.js and api_implementation.js
- * for doing common tasks such as passing node references between page script
- * and ChromeVox.
- */
-
-if (typeof(goog) != 'undefined' && goog.provide){
- goog.provide('cvox.ApiUtil');
-}
-
-
-if (!window['cvox']) {
- window['cvox'] = {};
-}
-
-/**
- * @constructor
- */
-cvox.ApiUtils = function() {
-};
-
-/**
- * The next id to use for the cvoxid attribute that we add to elements
- * in order to be able to find them from the content script.
- * @type {number}
- */
-cvox.ApiUtils.nextCvoxId_ = 1;
-
-/**
- * Makes a serializable reference to a node.
- * If the node or its parent has an ID, reference it directly. Otherwise,
- * add a temporary cvoxid attribute. This has a corresponding method in
- * api_implementation.js to decode this and return a node.
- * @param {Node} targetNode The node to reference.
- * @return {Object} A serializable node reference.
- */
-cvox.ApiUtils.makeNodeReference = function(targetNode) {
- if (targetNode.id && document.getElementById(targetNode.id) == targetNode) {
- return {'id': targetNode.id};
- } else if (targetNode instanceof HTMLElement) {
- var cvoxid = cvox.ApiUtils.nextCvoxId_;
- targetNode.setAttribute('cvoxid', cvoxid);
- cvox.ApiUtils.nextCvoxId_ = (cvox.ApiUtils.nextCvoxId_ + 1) % 100;
- return {'cvoxid': cvoxid};
- } else if (targetNode.parentElement) {
- var parent = targetNode.parentElement;
- var childIndex = -1;
- for (var i = 0; i < parent.childNodes.length; i++) {
- if (parent.childNodes[i] == targetNode) {
- childIndex = i;
- break;
- }
- }
- if (childIndex >= 0) {
- var cvoxid = cvox.ApiUtils.nextCvoxId_;
- parent.setAttribute('cvoxid', cvoxid);
- cvox.ApiUtils.nextCvoxId_ = (cvox.ApiUtils.nextCvoxId_ + 1) % 100;
- return {'cvoxid': cvoxid, 'childIndex': childIndex};
- }
- }
- throw 'Cannot reference node: ' + targetNode;
-};
-
-/**
- * Retrieves a node from its serializable node reference.
- *
- * @param {Object} nodeRef A serializable reference to a node.
- * @return {Node} The node on the page that this object refers to.
- */
-cvox.ApiUtils.getNodeFromRef = function(nodeRef) {
- if (nodeRef['id']) {
- return document.getElementById(nodeRef['id']);
- } else if (nodeRef['cvoxid']) {
- var selector = '*[cvoxid="' + nodeRef['cvoxid'] + '"]';
- var element = document.querySelector(selector);
- if (element && element.removeAttribute) {
- element.removeAttribute('cvoxid');
- }
- if (nodeRef['childIndex'] != null) {
- return element.childNodes[nodeRef['childIndex']];
- } else {
- return element;
- }
- }
- throw 'Bad node reference: ' + cvox.ChromeVoxJSON.stringify(nodeRef);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js
deleted file mode 100644
index 306ab277418..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/console_tts.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A TTS engine that writes to window.console.
- */
-
-goog.provide('cvox.ConsoleTts');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.TtsInterface');
-
-/**
- * @constructor
- * @implements {cvox.TtsInterface}
- */
-cvox.ConsoleTts = function() {
- /**
- * True if the console TTS is enabled by the user.
- * @type {boolean}
- * @private
- */
- this.enabled_ = false;
-};
-goog.addSingletonGetter(cvox.ConsoleTts);
-
-
-/** @override */
-cvox.ConsoleTts.prototype.speak = function(textString, queueMode, properties) {
- if (this.enabled_ && window['console']) {
- var logStr = 'Speak';
- if (queueMode == cvox.QueueMode.FLUSH) {
- logStr += ' (I)';
- } else if (queueMode == cvox.QueueMode.CATEGORY_FLUSH) {
- logStr += ' (C)';
- } else {
- logStr += ' (Q)';
- }
- if (properties && properties.category) {
- logStr += ' category=' + properties.category;
- }
- logStr += ' "' + textString + '"';
- window['console']['log'](logStr);
- }
- return this;
-};
-
-/** @override */
-cvox.ConsoleTts.prototype.isSpeaking = function() { return false; };
-
-/** @override */
-cvox.ConsoleTts.prototype.stop = function() {
- if (this.enabled_) {
- window['console']['log']('Stop');
- }
-};
-
-/** @override */
-cvox.ConsoleTts.prototype.addCapturingEventListener = function(listener) { };
-
-/** @override */
-cvox.ConsoleTts.prototype.increaseOrDecreaseProperty = function() { };
-
-/**
- * Sets the enabled bit.
- * @param {boolean} enabled The new enabled bit.
- */
-cvox.ConsoleTts.prototype.setEnabled = function(enabled) {
- this.enabled_ = enabled;
-};
-
-/** @override */
-cvox.ConsoleTts.prototype.getDefaultProperty = function(property) { };
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_suspender.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_suspender.js
deleted file mode 100644
index 2cd7865eaae..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_suspender.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Allows events to be suspended.
- *
- */
-
-goog.provide('cvox.ChromeVoxEventSuspender');
-
-/**
- * @namespace
- */
-cvox.ChromeVoxEventSuspender = function() {};
-
-/**
- * A nestable variable to keep track of whether events are suspended.
- *
- * @type {number}
- * @private
- */
-cvox.ChromeVoxEventSuspender.suspendLevel_ = 0;
-
-/**
- * Enters a (nested) suspended state.
- */
-cvox.ChromeVoxEventSuspender.enterSuspendEvents = function() {
- cvox.ChromeVoxEventSuspender.suspendLevel_ += 1;
-}
-
-/**
- * Exits a (nested) suspended state.
- */
-cvox.ChromeVoxEventSuspender.exitSuspendEvents = function() {
- cvox.ChromeVoxEventSuspender.suspendLevel_ -= 1;
-}
-
-/**
- * Returns true if events are currently suspended.
- *
- * @return {boolean} True if events are suspended.
- */
-cvox.ChromeVoxEventSuspender.areEventsSuspended = function() {
- return cvox.ChromeVoxEventSuspender.suspendLevel_ > 0;
-};
-
-/**
- * Returns a function that runs the argument with all events suspended.
- *
- * @param {Function} f Function to run with suspended events.
- * @return {?} Returns a function that wraps f.
- */
-cvox.ChromeVoxEventSuspender.withSuspendedEvents = function(f) {
- return function() {
- cvox.ChromeVoxEventSuspender.enterSuspendEvents();
- var ret = f.apply(this, arguments);
- cvox.ChromeVoxEventSuspender.exitSuspendEvents();
- return ret;
- };
-};
-
-/**
- * Returns a handler that only runs the argument if events are not suspended.
- *
- * @param {Function} handler Function that will be used as an event handler.
- * @param {boolean} ret Return value if events are suspended.
- * @return {Function} Function wrapping the handler.
- */
-cvox.ChromeVoxEventSuspender.makeSuspendableHandler = function(handler, ret) {
- return function() {
- if (cvox.ChromeVoxEventSuspender.areEventsSuspended()) {
- return ret;
- }
- return handler();
- };
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher.js
deleted file mode 100644
index f27e3e73719..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher.js
+++ /dev/null
@@ -1,1530 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Watches for events in the browser such as focus changes.
- *
- */
-
-goog.provide('cvox.ChromeVoxEventWatcher');
-goog.provide('cvox.ChromeVoxEventWatcherUtil');
-
-goog.require('cvox.ActiveIndicator');
-goog.require('cvox.ApiImplementation');
-goog.require('cvox.AriaUtil');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxEditableTextBase');
-goog.require('cvox.ChromeVoxEventSuspender');
-goog.require('cvox.ChromeVoxHTMLDateWidget');
-goog.require('cvox.ChromeVoxHTMLMediaWidget');
-goog.require('cvox.ChromeVoxHTMLTimeWidget');
-goog.require('cvox.ChromeVoxKbHandler');
-goog.require('cvox.ChromeVoxUserCommands');
-goog.require('cvox.DomUtil');
-goog.require('cvox.Focuser');
-goog.require('cvox.History');
-goog.require('cvox.LiveRegions');
-goog.require('cvox.Memoize');
-goog.require('cvox.NavigationSpeaker');
-goog.require('cvox.PlatformFilter'); // TODO: Find a better place for this.
-goog.require('cvox.PlatformUtil');
-goog.require('cvox.QueueMode');
-goog.require('cvox.TextHandlerInterface');
-goog.require('cvox.UserEventDetail');
-
-/**
- * @constructor
- */
-cvox.ChromeVoxEventWatcher = function() {
-};
-
-/**
- * The maximum amount of time to wait before processing events.
- * A max time is needed so that even if a page is constantly updating,
- * events will still go through.
- * @const
- * @type {number}
- * @private
- */
-cvox.ChromeVoxEventWatcher.MAX_WAIT_TIME_MS_ = 50;
-
-/**
- * As long as the MAX_WAIT_TIME_ has not been exceeded, the event processor
- * will wait this long after the last event was received before starting to
- * process events.
- * @const
- * @type {number}
- * @private
- */
-cvox.ChromeVoxEventWatcher.WAIT_TIME_MS_ = 10;
-
-/**
- * Maximum number of live regions that we will attempt to process.
- * @const
- * @type {number}
- * @private
- */
-cvox.ChromeVoxEventWatcher.MAX_LIVE_REGIONS_ = 5;
-
-
-/**
- * Whether or not ChromeVox should echo keys.
- * It is useful to turn this off in case the system is already echoing keys (for
- * example, in Android).
- *
- * @type {boolean}
- */
-cvox.ChromeVoxEventWatcher.shouldEchoKeys = true;
-
-
-/**
- * Whether or not the next utterance should flush all previous speech.
- * Immediately after a key down or user action, we make the next speech
- * flush, but otherwise it's better to do a category flush, so if a single
- * user action generates both a focus change and a live region change,
- * both get spoken.
- * @type {boolean}
- */
-cvox.ChromeVoxEventWatcher.shouldFlushNextUtterance = false;
-
-
-/**
- * Inits the event watcher and adds listeners.
- * @param {!Document|!Window} doc The DOM document to add event listeners to.
- */
-cvox.ChromeVoxEventWatcher.init = function(doc) {
- /**
- * @type {Object}
- */
- cvox.ChromeVoxEventWatcher.lastFocusedNode = null;
-
- /**
- * @type {Object}
- */
- cvox.ChromeVoxEventWatcher.announcedMouseOverNode = null;
-
- /**
- * @type {Object}
- */
- cvox.ChromeVoxEventWatcher.pendingMouseOverNode = null;
-
- /**
- * @type {number?}
- */
- cvox.ChromeVoxEventWatcher.mouseOverTimeoutId = null;
-
- /**
- * @type {string?}
- */
- cvox.ChromeVoxEventWatcher.lastFocusedNodeValue = null;
-
- /**
- * @type {Object}
- */
- cvox.ChromeVoxEventWatcher.eventToEat = null;
-
- /**
- * @type {Element}
- */
- cvox.ChromeVoxEventWatcher.currentTextControl = null;
-
- /**
- * @type {cvox.ChromeVoxEditableTextBase}
- */
- cvox.ChromeVoxEventWatcher.currentTextHandler = null;
-
- /**
- * Array of event listeners we've added so we can unregister them if needed.
- * @type {Array}
- * @private
- */
- cvox.ChromeVoxEventWatcher.listeners_ = [];
-
- /**
- * The mutation observer we use to listen for live regions.
- * @type {MutationObserver}
- * @private
- */
- cvox.ChromeVoxEventWatcher.mutationObserver_ = null;
-
- /**
- * Whether or not mouse hover events should trigger focusing.
- * @type {boolean}
- */
- cvox.ChromeVoxEventWatcher.focusFollowsMouse = false;
-
- /**
- * The delay before a mouseover triggers focusing or announcing anything.
- * @type {number}
- */
- cvox.ChromeVoxEventWatcher.mouseoverDelayMs = 500;
-
- /**
- * Array of events that need to be processed.
- * @type {Array<Event>}
- * @private
- */
- cvox.ChromeVoxEventWatcher.events_ = new Array();
-
- /**
- * The time when the last event was received.
- * @type {number}
- */
- cvox.ChromeVoxEventWatcher.lastEventTime = 0;
-
- /**
- * The timestamp for the first unprocessed event.
- * @type {number}
- */
- cvox.ChromeVoxEventWatcher.firstUnprocessedEventTime = -1;
-
- /**
- * Whether or not queue processing is scheduled to run.
- * @type {boolean}
- * @private
- */
- cvox.ChromeVoxEventWatcher.queueProcessingScheduled_ = false;
-
- /**
- * A list of callbacks to be called when the EventWatcher has
- * completed processing all events in its queue.
- * @type {Array<function()>}
- * @private
- */
- cvox.ChromeVoxEventWatcher.readyCallbacks_ = new Array();
-
-
-/**
- * tracks whether we've received two or more key up's while pass through mode
- * is active.
- * @type {boolean}
- * @private
- */
-cvox.ChromeVoxEventWatcher.secondPassThroughKeyUp_ = false;
-
- /**
- * Whether or not the ChromeOS Search key (keyCode == 91) is being held.
- *
- * We must track this manually because on ChromeOS, the Search key being held
- * down does not cause keyEvent.metaKey to be set.
- *
- * TODO (clchen, dmazzoni): Refactor this since there are edge cases
- * where manually tracking key down and key up can fail (such as when
- * the user switches tabs before letting go of the key being held).
- *
- * @type {boolean}
- */
- cvox.ChromeVox.searchKeyHeld = false;
-
- /**
- * The mutation observer that listens for changes to text controls
- * that might not send other events.
- * @type {MutationObserver}
- * @private
- */
- cvox.ChromeVoxEventWatcher.textMutationObserver_ = null;
-
- cvox.ChromeVoxEventWatcher.addEventListeners_(doc);
-};
-
-
-/**
- * Stores state variables in a provided object.
- *
- * @param {Object} store The object.
- */
-cvox.ChromeVoxEventWatcher.storeOn = function(store) {
- store['searchKeyHeld'] = cvox.ChromeVox.searchKeyHeld;
-};
-
-/**
- * Updates the object with state variables from an earlier storeOn call.
- *
- * @param {Object} store The object.
- */
-cvox.ChromeVoxEventWatcher.readFrom = function(store) {
- cvox.ChromeVox.searchKeyHeld = store['searchKeyHeld'];
-};
-
-/**
- * Adds an event to the events queue and updates the time when the last
- * event was received.
- *
- * @param {Event} evt The event to be added to the events queue.
- */
-cvox.ChromeVoxEventWatcher.addEvent = function(evt) {
- // Don't add any events to the events queue if ChromeVox is inactive or the
- // document isn't focused.
- if (!cvox.ChromeVox.isActive || !cvox.ChromeVox.documentHasFocus()) {
- if (evt.type == 'focus') {
- // If it's a focus event, update the active indicator so that it
- // properly shows and hides as focus moves to iframe and webview
- // elements.
- cvox.ChromeVox.navigationManager.activeIndicator.syncToNode(evt.target);
- }
- return;
- }
- cvox.ChromeVoxEventWatcher.events_.push(evt);
- cvox.ChromeVoxEventWatcher.lastEventTime = new Date().getTime();
- if (cvox.ChromeVoxEventWatcher.firstUnprocessedEventTime == -1) {
- cvox.ChromeVoxEventWatcher.firstUnprocessedEventTime = new Date().getTime();
- }
- if (!cvox.ChromeVoxEventWatcher.queueProcessingScheduled_) {
- cvox.ChromeVoxEventWatcher.queueProcessingScheduled_ = true;
- window.setTimeout(cvox.ChromeVoxEventWatcher.processQueue_,
- cvox.ChromeVoxEventWatcher.WAIT_TIME_MS_);
- }
-};
-
-/**
- * Adds a callback to be called when the event watcher has finished
- * processing all pending events.
- * @param {Function} cb The callback.
- */
-cvox.ChromeVoxEventWatcher.addReadyCallback = function(cb) {
- cvox.ChromeVoxEventWatcher.readyCallbacks_.push(cb);
- cvox.ChromeVoxEventWatcher.maybeCallReadyCallbacks_();
-};
-
-/**
- * Returns whether or not there are pending events.
- * @return {boolean} Whether or not there are pending events.
- * @private
- */
-cvox.ChromeVoxEventWatcher.hasPendingEvents_ = function() {
- return cvox.ChromeVoxEventWatcher.firstUnprocessedEventTime != -1 ||
- cvox.ChromeVoxEventWatcher.queueProcessingScheduled_;
-};
-
-
-/**
- * A bit used to make sure only one ready callback is pending at a time.
- * @private
- */
-cvox.ChromeVoxEventWatcher.readyCallbackRunning_ = false;
-
-/**
- * Checks if the event watcher has pending events. If not, call the oldest
- * readyCallback in a loop until exhausted or until there are pending events.
- * @private
- */
-cvox.ChromeVoxEventWatcher.maybeCallReadyCallbacks_ = function() {
- if (!cvox.ChromeVoxEventWatcher.readyCallbackRunning_) {
- cvox.ChromeVoxEventWatcher.readyCallbackRunning_ = true;
- window.setTimeout(function() {
- cvox.ChromeVoxEventWatcher.readyCallbackRunning_ = false;
- if (!cvox.ChromeVoxEventWatcher.hasPendingEvents_() &&
- !cvox.ChromeVoxEventWatcher.queueProcessingScheduled_ &&
- cvox.ChromeVoxEventWatcher.readyCallbacks_.length > 0) {
- cvox.ChromeVoxEventWatcher.readyCallbacks_.shift()();
- cvox.ChromeVoxEventWatcher.maybeCallReadyCallbacks_();
- }
- }, 5);
- }
-};
-
-
-/**
- * Add all of our event listeners to the document.
- * @param {!Document|!Window} doc The DOM document to add event listeners to.
- * @private
- */
-cvox.ChromeVoxEventWatcher.addEventListeners_ = function(doc) {
- // We always need key down listeners to intercept activate/deactivate.
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'keydown', cvox.ChromeVoxEventWatcher.keyDownEventWatcher, true);
-
- // If ChromeVox isn't active, skip all other event listeners.
- if (!cvox.ChromeVox.isActive || cvox.ChromeVox.entireDocumentIsHidden) {
- return;
- }
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'keypress', cvox.ChromeVoxEventWatcher.keyPressEventWatcher, true);
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'keyup', cvox.ChromeVoxEventWatcher.keyUpEventWatcher, true);
- // Listen for our own events to handle public user commands if the web app
- // doesn't do it for us.
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- cvox.UserEventDetail.Category.JUMP,
- cvox.ChromeVoxUserCommands.handleChromeVoxUserEvent,
- false);
-
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'focus', cvox.ChromeVoxEventWatcher.focusEventWatcher, true);
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'blur', cvox.ChromeVoxEventWatcher.blurEventWatcher, true);
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'change', cvox.ChromeVoxEventWatcher.changeEventWatcher, true);
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'copy', cvox.ChromeVoxEventWatcher.clipboardEventWatcher, true);
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'cut', cvox.ChromeVoxEventWatcher.clipboardEventWatcher, true);
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'paste', cvox.ChromeVoxEventWatcher.clipboardEventWatcher, true);
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'select', cvox.ChromeVoxEventWatcher.selectEventWatcher, true);
-
- // TODO(dtseng): Experimental, see:
- // https://developers.google.com/chrome/whitepapers/pagevisibility
- cvox.ChromeVoxEventWatcher.addEventListener_(doc, 'webkitvisibilitychange',
- cvox.ChromeVoxEventWatcher.visibilityChangeWatcher, true);
- cvox.ChromeVoxEventWatcher.events_ = new Array();
- cvox.ChromeVoxEventWatcher.queueProcessingScheduled_ = false;
-
- // Handle mouse events directly without going into the events queue.
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'mouseover', cvox.ChromeVoxEventWatcher.mouseOverEventWatcher, true);
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'mouseout', cvox.ChromeVoxEventWatcher.mouseOutEventWatcher, true);
-
- // With the exception of non-Android, click events go through the event queue.
- cvox.ChromeVoxEventWatcher.addEventListener_(doc,
- 'click', cvox.ChromeVoxEventWatcher.mouseClickEventWatcher, true);
-
- cvox.ChromeVoxEventWatcher.mutationObserver_ =
- new window.WebKitMutationObserver(
- cvox.ChromeVoxEventWatcher.mutationHandler);
- var observerTarget = null;
- if (doc.documentElement) {
- observerTarget = doc.documentElement;
- } else if (doc.document && doc.document.documentElement) {
- observerTarget = doc.document.documentElement;
- }
- if (observerTarget) {
- cvox.ChromeVoxEventWatcher.mutationObserver_.observe(
- observerTarget,
- /** @type {!MutationObserverInit} */ ({
- childList: true,
- attributes: true,
- characterData: true,
- subtree: true,
- attributeOldValue: true,
- characterDataOldValue: true
- }));
- }
-};
-
-
-/**
- * Remove all registered event watchers.
- * @param {!Document|!Window} doc The DOM document to add event listeners to.
- */
-cvox.ChromeVoxEventWatcher.cleanup = function(doc) {
- for (var i = 0; i < cvox.ChromeVoxEventWatcher.listeners_.length; i++) {
- var listener = cvox.ChromeVoxEventWatcher.listeners_[i];
- doc.removeEventListener(
- listener.type, listener.listener, listener.useCapture);
- }
- cvox.ChromeVoxEventWatcher.listeners_ = [];
- if (cvox.ChromeVoxEventWatcher.currentDateHandler) {
- cvox.ChromeVoxEventWatcher.currentDateHandler.shutdown();
- }
- if (cvox.ChromeVoxEventWatcher.currentTimeHandler) {
- cvox.ChromeVoxEventWatcher.currentTimeHandler.shutdown();
- }
- if (cvox.ChromeVoxEventWatcher.currentMediaHandler) {
- cvox.ChromeVoxEventWatcher.currentMediaHandler.shutdown();
- }
- if (cvox.ChromeVoxEventWatcher.mutationObserver_) {
- cvox.ChromeVoxEventWatcher.mutationObserver_.disconnect();
- }
- cvox.ChromeVoxEventWatcher.mutationObserver_ = null;
-};
-
-/**
- * Add one event listener and save the data so it can be removed later.
- * @param {!Document|!Window} doc The DOM document to add event listeners to.
- * @param {string} type The event type.
- * @param {EventListener|function(Event):(boolean|undefined)} listener
- * The function to be called when the event is fired.
- * @param {boolean} useCapture Whether this listener should capture events
- * before they're sent to targets beneath it in the DOM tree.
- * @private
- */
-cvox.ChromeVoxEventWatcher.addEventListener_ = function(doc, type,
- listener, useCapture) {
- cvox.ChromeVoxEventWatcher.listeners_.push(
- {'type': type, 'listener': listener, 'useCapture': useCapture});
- doc.addEventListener(type, listener, useCapture);
-};
-
-/**
- * Return the last focused node.
- * @return {Object} The last node that was focused.
- */
-cvox.ChromeVoxEventWatcher.getLastFocusedNode = function() {
- return cvox.ChromeVoxEventWatcher.lastFocusedNode;
-};
-
-/**
- * Sets the last focused node.
- * @param {Element} element The last focused element.
- *
- * @private
- */
-cvox.ChromeVoxEventWatcher.setLastFocusedNode_ = function(element) {
- cvox.ChromeVoxEventWatcher.lastFocusedNode = element;
- cvox.ChromeVoxEventWatcher.lastFocusedNodeValue = !element ? null :
- cvox.DomUtil.getControlValueAndStateString(element);
-};
-
-/**
- * Called when there's any mutation of the document. We use this to
- * handle live region updates.
- * @param {Array<MutationRecord>} mutations The mutations.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.mutationHandler = function(mutations) {
- if (cvox.ChromeVoxEventSuspender.areEventsSuspended()) {
- return true;
- }
-
- cvox.ChromeVox.navigationManager.updateIndicatorIfChanged();
-
- cvox.LiveRegions.processMutations(
- mutations,
- function(assertive, navDescriptions) {
- var evt = new window.Event('LiveRegion');
- evt.navDescriptions = navDescriptions;
- evt.assertive = assertive;
- cvox.ChromeVoxEventWatcher.addEvent(evt);
- return true;
- });
-};
-
-
-/**
- * Handles mouseclick events.
- * Mouseclick events are only triggered if the user touches the mouse;
- * we use it to determine whether or not we should bother trying to sync to a
- * selection.
- * @param {Event} evt The mouseclick event to process.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.mouseClickEventWatcher = function(evt) {
- if (evt.fromCvox) {
- return true;
- }
-
- if (cvox.ChromeVox.host.mustRedispatchClickEvent()) {
- cvox.ChromeVoxUserCommands.wasMouseClicked = true;
- evt.stopPropagation();
- evt.preventDefault();
- // Since the click event was caught and we are re-dispatching it, we also
- // need to refocus the current node because the current node has already
- // been blurred by the window getting the click event in the first place.
- // Failing to restore focus before clicking can cause odd problems such as
- // the soft IME not coming up in Android (it only shows up if the click
- // happens in a focused text field).
- cvox.Focuser.setFocus(cvox.ChromeVox.navigationManager.getCurrentNode());
- cvox.ChromeVox.tts.speak(
- Msgs.getMsg('element_clicked'),
- cvox.ChromeVoxEventWatcher.queueMode_(),
- cvox.AbstractTts.PERSONALITY_ANNOTATION);
- var targetNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- // If the targetNode has a defined onclick function, just call it directly
- // rather than try to generate a click event and dispatching it.
- // While both work equally well on standalone Chrome, when dealing with
- // embedded WebViews, generating a click event and sending it is not always
- // reliable since the framework may swallow the event.
- cvox.DomUtil.clickElem(targetNode, false, true);
- return false;
- } else {
- cvox.ChromeVoxEventWatcher.addEvent(evt);
- }
- cvox.ChromeVoxUserCommands.wasMouseClicked = true;
- return true;
-};
-
-/**
- * Handles mouseover events.
- * Mouseover events are only triggered if the user touches the mouse, so
- * for users who only use the keyboard, this will have no effect.
- *
- * @param {Event} evt The mouseover event to process.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.mouseOverEventWatcher = function(evt) {
- // Chrome simulates the meta key for mouse events generated from
- // touch exploration.
- var isTouchEvent = (evt.metaKey);
-
- var mouseoverDelayMs = cvox.ChromeVoxEventWatcher.mouseoverDelayMs;
- if (isTouchEvent) {
- mouseoverDelayMs = 0;
- } else if (!cvox.ChromeVoxEventWatcher.focusFollowsMouse) {
- return true;
- }
-
- if (cvox.DomUtil.isDescendantOfNode(
- cvox.ChromeVoxEventWatcher.announcedMouseOverNode, evt.target)) {
- return true;
- }
-
- if (evt.target == cvox.ChromeVoxEventWatcher.pendingMouseOverNode) {
- return true;
- }
-
- cvox.ChromeVoxEventWatcher.pendingMouseOverNode = evt.target;
- if (cvox.ChromeVoxEventWatcher.mouseOverTimeoutId) {
- window.clearTimeout(cvox.ChromeVoxEventWatcher.mouseOverTimeoutId);
- cvox.ChromeVoxEventWatcher.mouseOverTimeoutId = null;
- }
-
- if (evt.target.tagName && (evt.target.tagName == 'BODY')) {
- cvox.ChromeVoxEventWatcher.pendingMouseOverNode = null;
- cvox.ChromeVoxEventWatcher.announcedMouseOverNode = null;
- return true;
- }
-
- // Only focus and announce if the mouse stays over the same target
- // for longer than the given delay.
- cvox.ChromeVoxEventWatcher.mouseOverTimeoutId = window.setTimeout(
- function() {
- cvox.ChromeVoxEventWatcher.mouseOverTimeoutId = null;
- if (evt.target != cvox.ChromeVoxEventWatcher.pendingMouseOverNode) {
- return;
- }
-
- cvox.Memoize.scope(function() {
- cvox.ChromeVoxEventWatcher.shouldFlushNextUtterance = true;
- cvox.ChromeVox.navigationManager.stopReading(true);
- var target = /** @type {Node} */(evt.target);
- cvox.Focuser.setFocus(target);
- cvox.ApiImplementation.syncToNode(
- target, true, cvox.ChromeVoxEventWatcher.queueMode_());
- cvox.ChromeVoxEventWatcher.announcedMouseOverNode = target;
- });
- }, mouseoverDelayMs);
-
- return true;
-};
-
-/**
- * Handles mouseout events.
- *
- * @param {Event} evt The mouseout event to process.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.mouseOutEventWatcher = function(evt) {
- if (evt.target == cvox.ChromeVoxEventWatcher.pendingMouseOverNode) {
- cvox.ChromeVoxEventWatcher.pendingMouseOverNode = null;
- if (cvox.ChromeVoxEventWatcher.mouseOverTimeoutId) {
- window.clearTimeout(cvox.ChromeVoxEventWatcher.mouseOverTimeoutId);
- cvox.ChromeVoxEventWatcher.mouseOverTimeoutId = null;
- }
- }
-
- return true;
-};
-
-
-/**
- * Watches for focus events.
- *
- * @param {Event} evt The focus event to add to the queue.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.focusEventWatcher = function(evt) {
- // First remove any dummy spans. We create dummy spans in UserCommands in
- // order to sync the browser's default tab action with the user's current
- // navigation position.
- cvox.ChromeVoxUserCommands.removeTabDummySpan();
-
- if (!cvox.ChromeVoxEventSuspender.areEventsSuspended()) {
- cvox.ChromeVoxEventWatcher.addEvent(evt);
- } else if (evt.target && evt.target.nodeType == Node.ELEMENT_NODE) {
- cvox.ChromeVoxEventWatcher.setLastFocusedNode_(
- /** @type {Element} */(evt.target));
- }
- return true;
-};
-
-/**
- * Handles for focus events passed to it from the events queue.
- *
- * @param {Event} evt The focus event to handle.
- */
-cvox.ChromeVoxEventWatcher.focusHandler = function(evt) {
- if (!cvox.ChromeVox.documentHasFocus()) {
- return;
- }
- if (evt.target &&
- evt.target.hasAttribute &&
- evt.target.getAttribute('aria-hidden') == 'true' &&
- evt.target.getAttribute('chromevoxignoreariahidden') != 'true') {
- cvox.ChromeVoxEventWatcher.setLastFocusedNode_(null);
- cvox.ChromeVoxEventWatcher.setUpTextHandler();
- return;
- }
- if (evt.target && evt.target != window) {
- var target = /** @type {Element} */(evt.target);
- var parentControl = cvox.DomUtil.getSurroundingControl(target);
- if (parentControl &&
- parentControl == cvox.ChromeVoxEventWatcher.lastFocusedNode) {
- cvox.ChromeVoxEventWatcher.handleControlChanged(target);
- return;
- }
-
- if (parentControl) {
- cvox.ChromeVoxEventWatcher.setLastFocusedNode_(
- /** @type {Element} */(parentControl));
- } else {
- cvox.ChromeVoxEventWatcher.setLastFocusedNode_(target);
- }
-
- var queueMode = cvox.ChromeVoxEventWatcher.queueMode_();
-
- if (cvox.ChromeVoxEventWatcher.getInitialVisibility() ||
- cvox.ChromeVoxEventWatcher.handleDialogFocus(target)) {
- queueMode = cvox.QueueMode.QUEUE;
- }
-
- if (cvox.ChromeVox.navigationManager.clearPageSel(true)) {
- queueMode = cvox.QueueMode.QUEUE;
- }
-
- // Navigate to this control so that it will be the same for focus as for
- // regular navigation.
- cvox.ApiImplementation.syncToNode(
- target, !document.webkitHidden, queueMode);
-
- if ((evt.target.constructor == HTMLVideoElement) ||
- (evt.target.constructor == HTMLAudioElement)) {
- cvox.ChromeVoxEventWatcher.setUpMediaHandler_();
- return;
- }
- if (evt.target.hasAttribute) {
- var inputType = evt.target.getAttribute('type');
- switch (inputType) {
- case 'time':
- cvox.ChromeVoxEventWatcher.setUpTimeHandler_();
- return;
- case 'date':
- case 'month':
- case 'week':
- cvox.ChromeVoxEventWatcher.setUpDateHandler_();
- return;
- }
- }
- cvox.ChromeVoxEventWatcher.setUpTextHandler();
- } else {
- cvox.ChromeVoxEventWatcher.setLastFocusedNode_(null);
- }
- return;
-};
-
-/**
- * Watches for blur events.
- *
- * @param {Event} evt The blur event to add to the queue.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.blurEventWatcher = function(evt) {
- window.setTimeout(function() {
- if (!document.activeElement) {
- cvox.ChromeVoxEventWatcher.setLastFocusedNode_(null);
- cvox.ChromeVoxEventWatcher.addEvent(evt);
- }
- }, 0);
- return true;
-};
-
-/**
- * Watches for key down events.
- *
- * @param {Event} evt The keydown event to add to the queue.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.keyDownEventWatcher = function(evt) {
- return /** @type {boolean} */ (cvox.Memoize.scope(
- cvox.ChromeVoxEventWatcher.doKeyDownEventWatcher_.bind(this, evt)));
-};
-
-/**
- * Implementation of |keyDownEventWatcher|.
- *
- * @param {Event} evt The keydown event to add to the queue.
- * @return {boolean} True if the default action should be performed.
- * @private
- */
-cvox.ChromeVoxEventWatcher.doKeyDownEventWatcher_ = function(evt) {
- cvox.ChromeVoxEventWatcher.shouldFlushNextUtterance = true;
-
- if (cvox.ChromeVox.passThroughMode) {
- return true;
- }
-
- if (cvox.ChromeVox.isChromeOS && evt.keyCode == 91) {
- cvox.ChromeVox.searchKeyHeld = true;
- }
-
- // Store some extra ChromeVox-specific properties in the event.
- evt.searchKeyHeld =
- cvox.ChromeVox.searchKeyHeld && cvox.ChromeVox.isActive;
- evt.stickyMode = cvox.ChromeVox.isStickyModeOn() && cvox.ChromeVox.isActive;
- evt.keyPrefix = cvox.ChromeVox.keyPrefixOn && cvox.ChromeVox.isActive;
-
- cvox.ChromeVox.keyPrefixOn = false;
-
- cvox.ChromeVoxEventWatcher.eventToEat = null;
- if (!cvox.ChromeVoxKbHandler.basicKeyDownActionsListener(evt) ||
- cvox.ChromeVoxEventWatcher.handleControlAction(evt)) {
- // Swallow the event immediately to prevent the arrow keys
- // from driving controls on the web page.
- evt.preventDefault();
- evt.stopPropagation();
- // Also mark this as something to be swallowed when the followup
- // keypress/keyup counterparts to this event show up later.
- cvox.ChromeVoxEventWatcher.eventToEat = evt;
- return false;
- }
- cvox.ChromeVoxEventWatcher.addEvent(evt);
- return true;
-};
-
-/**
- * Watches for key up events.
- *
- * @param {Event} evt The event to add to the queue.
- * @return {boolean} True if the default action should be performed.
- * @this {cvox.ChromeVoxEventWatcher}
- */
-cvox.ChromeVoxEventWatcher.keyUpEventWatcher = function(evt) {
- if (evt.keyCode == 91) {
- cvox.ChromeVox.searchKeyHeld = false;
- }
-
- if (cvox.ChromeVox.passThroughMode) {
- if (!evt.ctrlKey && !evt.altKey && !evt.metaKey && !evt.shiftKey &&
- !cvox.ChromeVox.searchKeyHeld) {
- // Only reset pass through on the second key up without modifiers since
- // the first one is from the pass through shortcut itself.
- if (this.secondPassThroughKeyUp_) {
- this.secondPassThroughKeyUp_ = false;
- cvox.ChromeVox.passThroughMode = false;
- } else {
- this.secondPassThroughKeyUp_ = true;
- }
- }
- return true;
- }
-
- if (cvox.ChromeVoxEventWatcher.eventToEat &&
- evt.keyCode == cvox.ChromeVoxEventWatcher.eventToEat.keyCode) {
- evt.stopPropagation();
- evt.preventDefault();
- return false;
- }
-
- cvox.ChromeVoxEventWatcher.addEvent(evt);
-
- return true;
-};
-
-/**
- * Watches for key press events.
- *
- * @param {Event} evt The event to add to the queue.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.keyPressEventWatcher = function(evt) {
- var url = document.location.href;
- // Use ChromeVox.typingEcho as default value.
- var speakChar = cvox.TypingEcho.shouldSpeakChar(cvox.ChromeVox.typingEcho);
-
- if (typeof cvox.ChromeVox.keyEcho[url] !== 'undefined') {
- speakChar = cvox.ChromeVox.keyEcho[url];
- }
-
- // Directly handle typed characters here while key echo is on. This
- // skips potentially costly computations (especially for content editable).
- // This is done deliberately for the sake of responsiveness and in some cases
- // (e.g. content editable), to have characters echoed properly.
- if (cvox.ChromeVoxEditableTextBase.eventTypingEcho && (speakChar &&
- cvox.DomPredicates.editTextPredicate([document.activeElement])) &&
- document.activeElement.type !== 'password') {
- cvox.ChromeVox.tts.speak(String.fromCharCode(evt.charCode),
- cvox.QueueMode.FLUSH);
- }
- cvox.ChromeVoxEventWatcher.addEvent(evt);
- if (cvox.ChromeVoxEventWatcher.eventToEat &&
- evt.keyCode == cvox.ChromeVoxEventWatcher.eventToEat.keyCode) {
- evt.preventDefault();
- evt.stopPropagation();
- return false;
- }
- return true;
-};
-
-/**
- * Watches for change events.
- *
- * @param {Event} evt The event to add to the queue.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.changeEventWatcher = function(evt) {
- cvox.ChromeVoxEventWatcher.addEvent(evt);
- return true;
-};
-
-// TODO(dtseng): ChromeVoxEditableText interrupts cut and paste announcements.
-/**
- * Watches for cut, copy, and paste events.
- *
- * @param {Event} evt The event to process.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.clipboardEventWatcher = function(evt) {
- // Don't announce anything unless this document has focus and the
- // editable element that's the target of the clipboard event is visible.
- var targetNode = /** @type {Node} */(evt.target);
- if (!cvox.ChromeVox.documentHasFocus() ||
- !targetNode ||
- !cvox.DomUtil.isVisible(targetNode) ||
- cvox.AriaUtil.isHidden(targetNode)) {
- return true;
- }
-
- cvox.ChromeVox.tts.speak(Msgs.getMsg(evt.type).toLowerCase(),
- cvox.QueueMode.QUEUE);
- var text = '';
- switch (evt.type) {
- case 'paste':
- text = evt.clipboardData.getData('text');
- break;
- case 'copy':
- case 'cut':
- text = window.getSelection().toString();
- break;
- }
- cvox.ChromeVox.tts.speak(text, cvox.QueueMode.QUEUE);
- cvox.ChromeVox.navigationManager.clearPageSel();
- return true;
-};
-
-/**
- * Handles change events passed to it from the events queue.
- *
- * @param {Event} evt The event to handle.
- */
-cvox.ChromeVoxEventWatcher.changeHandler = function(evt) {
- if (cvox.ChromeVoxEventWatcher.setUpTextHandler()) {
- return;
- }
- if (document.activeElement == evt.target) {
- cvox.ChromeVoxEventWatcher.handleControlChanged(document.activeElement);
- }
-};
-
-/**
- * Watches for select events.
- *
- * @param {Event} evt The event to add to the queue.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxEventWatcher.selectEventWatcher = function(evt) {
- cvox.ChromeVoxEventWatcher.addEvent(evt);
- return true;
-};
-
-/**
- * Listens for WebKit visibility change events.
- */
-cvox.ChromeVoxEventWatcher.visibilityChangeWatcher = function() {
- cvox.ChromeVoxEventWatcher.initialVisibility = !document.webkitHidden;
- if (document.webkitHidden) {
- cvox.ChromeVox.navigationManager.stopReading(true);
- }
-};
-
-/**
- * Gets the initial visibility of the page.
- * @return {boolean} True if the page is visible and this is the first request
- * for visibility state.
- */
-cvox.ChromeVoxEventWatcher.getInitialVisibility = function() {
- var ret = cvox.ChromeVoxEventWatcher.initialVisibility;
- cvox.ChromeVoxEventWatcher.initialVisibility = false;
- return ret;
-};
-
-/**
- * Speaks the text of one live region.
- * @param {boolean} assertive True if it's an assertive live region.
- * @param {Array<cvox.NavDescription>} messages An array of navDescriptions
- * representing the description of the live region changes.
- * @private
- */
-cvox.ChromeVoxEventWatcher.speakLiveRegion_ = function(
- assertive, messages) {
- var queueMode = cvox.ChromeVoxEventWatcher.queueMode_();
- var descSpeaker = new cvox.NavigationSpeaker();
- descSpeaker.speakDescriptionArray(messages, queueMode, null);
-};
-
-/**
- * Sets up the text handler.
- * @return {boolean} True if an editable text control has focus.
- */
-cvox.ChromeVoxEventWatcher.setUpTextHandler = function() {
- var currentFocus = document.activeElement;
- if (currentFocus &&
- currentFocus.hasAttribute &&
- currentFocus.getAttribute('aria-hidden') == 'true' &&
- currentFocus.getAttribute('chromevoxignoreariahidden') != 'true') {
- currentFocus = null;
- }
-
- if (currentFocus != cvox.ChromeVoxEventWatcher.currentTextControl) {
- if (cvox.ChromeVoxEventWatcher.currentTextControl) {
- cvox.ChromeVoxEventWatcher.currentTextControl.removeEventListener(
- 'input', cvox.ChromeVoxEventWatcher.changeEventWatcher, false);
- cvox.ChromeVoxEventWatcher.currentTextControl.removeEventListener(
- 'click', cvox.ChromeVoxEventWatcher.changeEventWatcher, false);
- if (cvox.ChromeVoxEventWatcher.textMutationObserver_) {
- cvox.ChromeVoxEventWatcher.textMutationObserver_.disconnect();
- cvox.ChromeVoxEventWatcher.textMutationObserver_ = null;
- }
- }
- cvox.ChromeVoxEventWatcher.currentTextControl = null;
- if (cvox.ChromeVoxEventWatcher.currentTextHandler) {
- cvox.ChromeVoxEventWatcher.currentTextHandler.teardown();
- cvox.ChromeVoxEventWatcher.currentTextHandler = null;
- }
- if (currentFocus == null) {
- return false;
- }
- if (currentFocus.constructor == HTMLInputElement &&
- cvox.DomUtil.isInputTypeText(currentFocus) &&
- cvox.ChromeVoxEventWatcher.shouldEchoKeys) {
- cvox.ChromeVoxEventWatcher.currentTextControl = currentFocus;
- cvox.ChromeVoxEventWatcher.currentTextHandler =
- new cvox.ChromeVoxEditableHTMLInput(currentFocus, cvox.ChromeVox.tts);
- } else if ((currentFocus.constructor == HTMLTextAreaElement) &&
- cvox.ChromeVoxEventWatcher.shouldEchoKeys) {
- cvox.ChromeVoxEventWatcher.currentTextControl = currentFocus;
- cvox.ChromeVoxEventWatcher.currentTextHandler =
- new cvox.ChromeVoxEditableTextArea(currentFocus, cvox.ChromeVox.tts);
- } else if (currentFocus.isContentEditable ||
- currentFocus.getAttribute('role') == 'textbox') {
- cvox.ChromeVoxEventWatcher.currentTextControl = currentFocus;
- cvox.ChromeVoxEventWatcher.currentTextHandler =
- new cvox.ChromeVoxEditableContentEditable(currentFocus,
- cvox.ChromeVox.tts);
- }
-
- if (cvox.ChromeVoxEventWatcher.currentTextControl) {
- cvox.ChromeVoxEventWatcher.currentTextControl.addEventListener(
- 'input', cvox.ChromeVoxEventWatcher.changeEventWatcher, false);
- cvox.ChromeVoxEventWatcher.currentTextControl.addEventListener(
- 'click', cvox.ChromeVoxEventWatcher.changeEventWatcher, false);
- if (window.WebKitMutationObserver) {
- cvox.ChromeVoxEventWatcher.textMutationObserver_ =
- new window.WebKitMutationObserver(
- cvox.ChromeVoxEventWatcher.onTextMutation);
- cvox.ChromeVoxEventWatcher.textMutationObserver_.observe(
- cvox.ChromeVoxEventWatcher.currentTextControl,
- /** @type {!MutationObserverInit} */ ({
- childList: true,
- attributes: true,
- subtree: true,
- attributeOldValue: false,
- characterDataOldValue: false
- }));
- }
- if (!cvox.ChromeVoxEventSuspender.areEventsSuspended()) {
- cvox.ChromeVox.navigationManager.updateSel(
- cvox.CursorSelection.fromNode(
- cvox.ChromeVoxEventWatcher.currentTextControl));
- }
- }
-
- return (null != cvox.ChromeVoxEventWatcher.currentTextHandler);
- }
-};
-
-/**
- * Speaks updates to editable text controls as needed.
- *
- * @param {boolean} isKeypress Was this change triggered by a keypress?
- * @return {boolean} True if an editable text control has focus.
- */
-cvox.ChromeVoxEventWatcher.handleTextChanged = function(isKeypress) {
- if (cvox.ChromeVoxEventWatcher.currentTextHandler) {
- var handler = cvox.ChromeVoxEventWatcher.currentTextHandler;
- var shouldFlush = false;
- if (isKeypress && cvox.ChromeVoxEventWatcher.shouldFlushNextUtterance) {
- shouldFlush = true;
- cvox.ChromeVoxEventWatcher.shouldFlushNextUtterance = false;
- }
- handler.update(shouldFlush);
- cvox.ChromeVoxEventWatcher.shouldFlushNextUtterance = false;
- return true;
- }
- return false;
-};
-
-/**
- * Called when an editable text control has focus, because many changes
- * to a text box don't ever generate events - e.g. if the page's javascript
- * changes the contents of the text box after some delay, or if it's
- * contentEditable or a generic div with role="textbox".
- */
-cvox.ChromeVoxEventWatcher.onTextMutation = function() {
- if (cvox.ChromeVoxEventWatcher.currentTextHandler) {
- window.setTimeout(function() {
- cvox.ChromeVoxEventWatcher.handleTextChanged(false);
- }, cvox.ChromeVoxEventWatcher.MAX_WAIT_TIME_MS_);
- }
-};
-
-/**
- * Speaks updates to other form controls as needed.
- * @param {Element} control The target control.
- */
-cvox.ChromeVoxEventWatcher.handleControlChanged = function(control) {
- var newValue = cvox.DomUtil.getControlValueAndStateString(control);
- var parentControl = cvox.DomUtil.getSurroundingControl(control);
- var announceChange = false;
-
- if (control != cvox.ChromeVoxEventWatcher.lastFocusedNode &&
- (parentControl == null ||
- parentControl != cvox.ChromeVoxEventWatcher.lastFocusedNode)) {
- cvox.ChromeVoxEventWatcher.setLastFocusedNode_(control);
- } else if (newValue == cvox.ChromeVoxEventWatcher.lastFocusedNodeValue) {
- return;
- }
-
- cvox.ChromeVoxEventWatcher.lastFocusedNodeValue = newValue;
- if (cvox.DomPredicates.checkboxPredicate([control]) ||
- cvox.DomPredicates.radioPredicate([control])) {
- // Always announce changes to checkboxes and radio buttons.
- announceChange = true;
- // Play earcons for checkboxes and radio buttons
- if (control.checked) {
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.CHECK_ON);
- } else {
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.CHECK_OFF);
- }
- }
-
- if (control.tagName == 'SELECT') {
- announceChange = true;
- }
-
- if (control.tagName == 'INPUT') {
- switch (control.type) {
- case 'color':
- case 'datetime':
- case 'datetime-local':
- case 'range':
- announceChange = true;
- break;
- default:
- break;
- }
- }
-
- // Always announce changes for anything with an ARIA role.
- if (control.hasAttribute && control.hasAttribute('role')) {
- announceChange = true;
- }
-
- var activeDescendant = cvox.AriaUtil.getActiveDescendant(control);
- if ((parentControl &&
- parentControl != control &&
- document.activeElement == control)) {
- // Sync ChromeVox to the newly selected control.
- cvox.ApiImplementation.syncToNode(
- activeDescendant || control, true,
- cvox.ChromeVoxEventWatcher.queueMode_());
- announceChange = false;
- } else if (activeDescendant) {
- cvox.ChromeVox.navigationManager.updateSelToArbitraryNode(
- activeDescendant,
- true);
-
- announceChange = true;
- }
-
- if (announceChange && !cvox.ChromeVoxEventSuspender.areEventsSuspended()) {
- cvox.ChromeVox.tts.speak(newValue,
- cvox.ChromeVoxEventWatcher.queueMode_(),
- null);
- cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(newValue));
- }
-};
-
-/**
- * Handle actions on form controls triggered by key presses.
- * @param {Object} evt The event.
- * @return {boolean} True if this key event was handled.
- */
-cvox.ChromeVoxEventWatcher.handleControlAction = function(evt) {
- // Ignore the control action if ChromeVox is not active.
- if (!cvox.ChromeVox.isActive) {
- return false;
- }
- var control = evt.target;
-
- if (control.tagName == 'SELECT' && (control.size <= 1) &&
- (evt.keyCode == 13 || evt.keyCode == 32)) { // Enter or Space
- // TODO (dmazzoni, clchen): Remove this workaround once accessibility
- // APIs make browser based popups accessible.
- //
- // Do nothing, but eat this keystroke when the SELECT control
- // has a dropdown style since if we don't, it will generate
- // a browser popup menu which is not accessible.
- // List style SELECT controls are fine and don't need this workaround.
- evt.preventDefault();
- evt.stopPropagation();
- return true;
- }
-
- if (control.tagName == 'INPUT' && control.type == 'range') {
- var value = parseFloat(control.value);
- var step;
- if (control.step && control.step > 0.0) {
- step = control.step;
- } else if (control.min && control.max) {
- var range = (control.max - control.min);
- if (range > 2 && range < 31) {
- step = 1;
- } else {
- step = (control.max - control.min) / 10;
- }
- } else {
- step = 1;
- }
-
- if (evt.keyCode == 37 || evt.keyCode == 38) { // left or up
- value -= step;
- } else if (evt.keyCode == 39 || evt.keyCode == 40) { // right or down
- value += step;
- }
-
- if (control.max && value > control.max) {
- value = control.max;
- }
- if (control.min && value < control.min) {
- value = control.min;
- }
-
- control.value = value;
- }
- return false;
-};
-
-/**
- * When an element receives focus, see if we've entered or left a dialog
- * and return a string describing the event.
- *
- * @param {Element} target The element that just received focus.
- * @return {boolean} True if an announcement was spoken.
- */
-cvox.ChromeVoxEventWatcher.handleDialogFocus = function(target) {
- var dialog = target;
- var role = '';
- while (dialog) {
- if (dialog.hasAttribute) {
- role = dialog.getAttribute('role');
- if (role == 'dialog' || role == 'alertdialog') {
- break;
- }
- }
- dialog = dialog.parentElement;
- }
-
- if (dialog == cvox.ChromeVox.navigationManager.currentDialog) {
- return false;
- }
-
- if (cvox.ChromeVox.navigationManager.currentDialog && !dialog) {
- if (!cvox.DomUtil.isDescendantOfNode(
- document.activeElement,
- cvox.ChromeVox.navigationManager.currentDialog)) {
- cvox.ChromeVox.navigationManager.currentDialog = null;
-
- cvox.ChromeVoxEventWatcher.speakAnnotationWithCategory_(
- Msgs.getMsg('exiting_dialog'),
- cvox.TtsCategory.NAV);
- return true;
- }
- } else {
- if (dialog) {
- cvox.ChromeVox.navigationManager.currentDialog = dialog;
- cvox.ChromeVoxEventWatcher.speakAnnotationWithCategory_(
- Msgs.getMsg('entering_dialog'),
- cvox.TtsCategory.NAV);
-
- if (role == 'alertdialog') {
- var dialogDescArray =
- cvox.DescriptionUtil.getFullDescriptionsFromChildren(null, dialog);
- var descSpeaker = new cvox.NavigationSpeaker();
- descSpeaker.speakDescriptionArray(dialogDescArray,
- cvox.QueueMode.QUEUE,
- null);
- }
- return true;
- }
- }
- return false;
-};
-
-/**
- * Speak the given text with the annotation personality and the given
- * speech queue utterance category.
- * @param {string} text The text to speak.
- * @param {string} category The category of text, used by the speech queue
- * when flushing all speech from the same category while leaving other
- * speech in the queue.
- * @private
- */
-cvox.ChromeVoxEventWatcher.speakAnnotationWithCategory_ = function(
- text, category) {
- var properties = {};
- var src = cvox.AbstractTts.PERSONALITY_ANNOTATION;
- for (var key in src) {
- properties[key] = src[key];
- }
- properties['category'] = category;
- cvox.ChromeVox.tts.speak(
- text,
- cvox.ChromeVoxEventWatcher.queueMode_(),
- properties);
-};
-
-/**
- * Returns true if we should wait to process events.
- * @param {number} lastFocusTimestamp The timestamp of the last focus event.
- * @param {number} firstTimestamp The timestamp of the first event.
- * @param {number} currentTime The current timestamp.
- * @return {boolean} True if we should wait to process events.
- */
-cvox.ChromeVoxEventWatcherUtil.shouldWaitToProcess = function(
- lastFocusTimestamp, firstTimestamp, currentTime) {
- var timeSinceFocusEvent = currentTime - lastFocusTimestamp;
- var timeSinceFirstEvent = currentTime - firstTimestamp;
- return timeSinceFocusEvent < cvox.ChromeVoxEventWatcher.WAIT_TIME_MS_ &&
- timeSinceFirstEvent < cvox.ChromeVoxEventWatcher.MAX_WAIT_TIME_MS_;
-};
-
-
-/**
- * Returns the queue mode to use for the next utterance spoken as
- * a result of an event or navigation. The first utterance that's spoken
- * after an explicit user action like a key press will flush, and
- * subsequent events will return a category flush.
- * @return {cvox.QueueMode} The queue mode.
- * @private
- */
-cvox.ChromeVoxEventWatcher.queueMode_ = function() {
- if (cvox.ChromeVoxEventWatcher.shouldFlushNextUtterance) {
- cvox.ChromeVoxEventWatcher.shouldFlushNextUtterance = false;
- return cvox.QueueMode.FLUSH;
- }
- return cvox.QueueMode.CATEGORY_FLUSH;
-};
-
-
-/**
- * Processes the events queue.
- *
- * @private
- */
-cvox.ChromeVoxEventWatcher.processQueue_ = function() {
- cvox.Memoize.scope(cvox.ChromeVoxEventWatcher.doProcessQueue_);
-};
-
-/**
- * Implementation of |processQueue_|.
- *
- * @private
- */
-cvox.ChromeVoxEventWatcher.doProcessQueue_ = function() {
- // Return now if there are no events in the queue.
- if (cvox.ChromeVoxEventWatcher.events_.length == 0) {
- return;
- }
-
- // Look for the most recent focus event and delete any preceding event
- // that applied to whatever was focused previously.
- var events = cvox.ChromeVoxEventWatcher.events_;
- var lastFocusIndex = -1;
- var lastFocusTimestamp = 0;
- var evt;
- var i;
- for (i = 0; evt = events[i]; i++) {
- if (evt.type == 'focus') {
- lastFocusIndex = i;
- lastFocusTimestamp = evt.timeStamp;
- }
- }
- cvox.ChromeVoxEventWatcher.events_ = [];
- for (i = 0; evt = events[i]; i++) {
- var prevEvt = events[i - 1] || {};
- if ((i >= lastFocusIndex || evt.type == 'LiveRegion') &&
- (prevEvt.type != 'focus' || evt.type != 'change')) {
- cvox.ChromeVoxEventWatcher.events_.push(evt);
- }
- }
-
- cvox.ChromeVoxEventWatcher.events_.sort(function(a, b) {
- if (b.type != 'LiveRegion' && a.type == 'LiveRegion') {
- return 1;
- }
- return -1;
- });
-
- // If the most recent focus event was very recent, wait for things to
- // settle down before processing events, unless the max wait time has
- // passed.
- var currentTime = new Date().getTime();
- if (lastFocusIndex >= 0 &&
- cvox.ChromeVoxEventWatcherUtil.shouldWaitToProcess(
- lastFocusTimestamp,
- cvox.ChromeVoxEventWatcher.firstUnprocessedEventTime,
- currentTime)) {
- window.setTimeout(cvox.ChromeVoxEventWatcher.processQueue_,
- cvox.ChromeVoxEventWatcher.WAIT_TIME_MS_);
- return;
- }
-
- // Process the remaining events in the queue, in order.
- for (i = 0; evt = cvox.ChromeVoxEventWatcher.events_[i]; i++) {
- cvox.ChromeVoxEventWatcher.handleEvent_(evt);
- }
- cvox.ChromeVoxEventWatcher.events_ = new Array();
- cvox.ChromeVoxEventWatcher.firstUnprocessedEventTime = -1;
- cvox.ChromeVoxEventWatcher.queueProcessingScheduled_ = false;
- cvox.ChromeVoxEventWatcher.maybeCallReadyCallbacks_();
-};
-
-/**
- * Handle events from the queue by routing them to their respective handlers.
- *
- * @private
- * @param {Event} evt The event to be handled.
- */
-cvox.ChromeVoxEventWatcher.handleEvent_ = function(evt) {
- switch (evt.type) {
- case 'keydown':
- case 'input':
- cvox.ChromeVoxEventWatcher.setUpTextHandler();
- if (cvox.ChromeVoxEventWatcher.currentTextControl) {
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
-
- var editableText = /** @type {cvox.ChromeVoxEditableTextBase} */
- (cvox.ChromeVoxEventWatcher.currentTextHandler);
- if (editableText && editableText.lastChangeDescribed) {
- break;
- }
- }
- // We're either not on a text control, or we are on a text control but no
- // text change was described. Let's try describing the state instead.
- cvox.ChromeVoxEventWatcher.handleControlChanged(document.activeElement);
- break;
- case 'keyup':
- // Some controls change only after key up.
- cvox.ChromeVoxEventWatcher.handleControlChanged(document.activeElement);
- break;
- case 'keypress':
- cvox.ChromeVoxEventWatcher.setUpTextHandler();
- break;
- case 'click':
- cvox.ApiImplementation.syncToNode(/** @type {Node} */(evt.target), true);
- break;
- case 'focus':
- cvox.ChromeVoxEventWatcher.focusHandler(evt);
- break;
- case 'blur':
- cvox.ChromeVoxEventWatcher.setUpTextHandler();
- break;
- case 'change':
- cvox.ChromeVoxEventWatcher.changeHandler(evt);
- break;
- case 'select':
- cvox.ChromeVoxEventWatcher.setUpTextHandler();
- break;
- case 'LiveRegion':
- cvox.ChromeVoxEventWatcher.speakLiveRegion_(
- evt.assertive, evt.navDescriptions);
- break;
- }
-};
-
-
-/**
- * Sets up the time handler.
- * @return {boolean} True if a time control has focus.
- * @private
- */
-cvox.ChromeVoxEventWatcher.setUpTimeHandler_ = function() {
- var currentFocus = document.activeElement;
- if (currentFocus &&
- currentFocus.hasAttribute &&
- currentFocus.getAttribute('aria-hidden') == 'true' &&
- currentFocus.getAttribute('chromevoxignoreariahidden') != 'true') {
- currentFocus = null;
- }
- if (currentFocus.constructor == HTMLInputElement &&
- currentFocus.type && (currentFocus.type == 'time')) {
- cvox.ChromeVoxEventWatcher.currentTimeHandler =
- new cvox.ChromeVoxHTMLTimeWidget(currentFocus, cvox.ChromeVox.tts);
- } else {
- cvox.ChromeVoxEventWatcher.currentTimeHandler = null;
- }
- return (null != cvox.ChromeVoxEventWatcher.currentTimeHandler);
-};
-
-
-/**
- * Sets up the media (video/audio) handler.
- * @return {boolean} True if a media control has focus.
- * @private
- */
-cvox.ChromeVoxEventWatcher.setUpMediaHandler_ = function() {
- var currentFocus = document.activeElement;
- if (currentFocus &&
- currentFocus.hasAttribute &&
- currentFocus.getAttribute('aria-hidden') == 'true' &&
- currentFocus.getAttribute('chromevoxignoreariahidden') != 'true') {
- currentFocus = null;
- }
- if ((currentFocus.constructor == HTMLVideoElement) ||
- (currentFocus.constructor == HTMLAudioElement)) {
- cvox.ChromeVoxEventWatcher.currentMediaHandler =
- new cvox.ChromeVoxHTMLMediaWidget(currentFocus, cvox.ChromeVox.tts);
- } else {
- cvox.ChromeVoxEventWatcher.currentMediaHandler = null;
- }
- return (null != cvox.ChromeVoxEventWatcher.currentMediaHandler);
-};
-
-/**
- * Sets up the date handler.
- * @return {boolean} True if a date control has focus.
- * @private
- */
-cvox.ChromeVoxEventWatcher.setUpDateHandler_ = function() {
- var currentFocus = document.activeElement;
- if (currentFocus &&
- currentFocus.hasAttribute &&
- currentFocus.getAttribute('aria-hidden') == 'true' &&
- currentFocus.getAttribute('chromevoxignoreariahidden') != 'true') {
- currentFocus = null;
- }
- if (currentFocus.constructor == HTMLInputElement &&
- currentFocus.type &&
- ((currentFocus.type == 'date') ||
- (currentFocus.type == 'month') ||
- (currentFocus.type == 'week'))) {
- cvox.ChromeVoxEventWatcher.currentDateHandler =
- new cvox.ChromeVoxHTMLDateWidget(currentFocus, cvox.ChromeVox.tts);
- } else {
- cvox.ChromeVoxEventWatcher.currentDateHandler = null;
- }
- return (null != cvox.ChromeVoxEventWatcher.currentDateHandler);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs
deleted file mode 100644
index a934d41a7bd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs
+++ /dev/null
@@ -1,754 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxEventWatcherUnitTest() {
- ChromeVoxUnitTestBase.call(this);
-}
-
-CvoxEventWatcherUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- isAsync: true,
-
- /** @override */
- closureModuleDeps: ChromeVoxUnitTestBase.prototype.closureModuleDeps.concat([
- 'cvox.ChromeVoxTester',
- ]),
-
- /** @override */
- setUp: function() {
- cvox.ChromeVoxTester.setUp(document);
- },
-
- /** @override */
- tearDown: function() {
- cvox.ChromeVoxTester.tearDown(document);
- },
-
- /**
- * Create mock event object.
- * @param {Element} target The event target.
- * @param {number=} opt_keyCode The event key code (i.e. 13 for Enter).
- * @param {string=} opt_type The event type (i.e. 'keydown' or
- * 'focus').
- * @param {number=} opt_timeStamp The event timeStamp.
- * @return {Event} The mock event.
- * @suppress {invalidCasts}
- */
- createMockEvent: function(target, opt_keyCode, opt_type, opt_timeStamp) {
- var mockEvent = {};
- mockEvent.target = target;
- if (opt_keyCode) {
- mockEvent.keyCode = opt_keyCode;
- }
- if (opt_type) {
- mockEvent.type = opt_type;
- }
- if (opt_timeStamp) {
- mockEvent.timeStamp = opt_timeStamp;
- }
-
- return /** @type {Event} */ (mockEvent);
- },
-
- /**
- * Simulate typing a key into an text field by modifying a given field and
- * dispatching a keydown event to ChromeVoxEventWatcher. Allows modifying the
- * selection so arrow keypresses can be simulated.
- * @param {Element} textField The text field.
- * @param {string} newValue The new value for the text field.
- * @param {number} newSelStart The new selection start.
- * @param {number} newSelEnd The new selection end.
- * @param {number} keyCode The key code for the keydown event.
- * @return {Element} The modified text field.
- */
- changeTextField: function(
- textField, newValue, newSelStart, newSelEnd, keyCode) {
- textField.value = newValue;
- textField.selectionStart = newSelStart;
- textField.selectionEnd = newSelEnd;
-
- cvox.ChromeVoxEventWatcher.keyDownEventWatcher(
- this.createMockEvent(textField, keyCode, 'keydown'));
- return textField;
- }
-};
-
-TEST_F('CvoxEventWatcherUnitTest', 'ButtonFocusFeedback', function() {
- this.loadHtml('<div> <button id="alpha">Alpha</button> </div>');
- this.setFocus('alpha');
- this.waitForCalm(this.assertSpoken, 'Alpha Button');
-});
-
-/**
- * Test feedback when focusing links backwards (like shift-tabbing).
- */
-TEST_F('CvoxEventWatcherUnitTest', 'FocusLinksBackwards', function() {
- this.loadHtml('<div> <p>before</p>' +
- '<p><a href="#" id="l1">1</a></p>' +
- '<p><a href="#" id="l2">2</a></p>' +
- '<p><a href="#" id="l3">3</a></p>' +
- '</div>');
-
- this.waitForCalm(this.setFocus, 'l1')
- .waitForCalm(this.setFocus, 'l2')
- .waitForCalm(this.setFocus, 'l3')
- .waitForCalm(this.setFocus, 'l2')
- .waitForCalm(this.setFocus, 'l1')
- .waitForCalm(this.assertSpoken,
- '1 Internal link 2 Internal link 3 Internal link ' +
- '2 Internal link 1 Internal link');
-});
-
-/**
- * Test feedback when an editable text field gets focus.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'TextFocusFeedback', function() {
- this.loadHtml('<div>' +
- '<label for="mytext">Label</label>' +
- '<input id="mytext" value="Value" title="Title" />' +
- '</div>');
-
- this.setFocus('mytext');
- this.waitForCalm(this.assertSpoken, 'Label Value Edit text');
-});
-
-/**
- * Test feedback when a contenteditable field gets focus.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'ContentEditableFocusFeedback', function() {
- this.loadHtml('<div>' +
- '<label for="mytext">Label</label>' +
- '<div id="mytext" contentEditable>This is editable</div>' +
- '</div>');
-
- this.setFocus('mytext');
- this.waitForCalm(this.assertSpoken, 'Label This is editable Edit text');
-});
-
-/**
- * Test feedback when an item in an dialog receives focus and then focus
- * leaves the dialog.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'DialogFeedback', function() {
- this.loadHtml('<div>' +
- '<button id="show">Show</button>' +
- '<div aria-label="compose message" role="dialog">' +
- ' <button id="ok">OK</button>' +
- ' <button id="cancel">Cancel</button>' +
- '</div>' +
- '</div>');
-
- // Enter the dialog by focusing an element inside it.
- this.setFocus('ok');
-
- this.waitForCalm(this.assertSpoken,
- 'Entered dialog compose message Dialog OK Button')
- .waitForCalm(function() {
- this.setFocus('show')
- .setFocus('ok');
- })
- .waitForCalm(this.assertSpoken, 'OK Button')
- .waitForCalm(this.setFocus, 'show')
- .waitForCalm(this.assertSpoken, 'Exited dialog. Show Button');
-});
-
-/**
- * Test feedback when an item in an alert dialog receives focus.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'AlertDialogFeedback', function() {
- this.loadHtml('<div>' +
- '<div role="alertdialog">' +
- ' <p>Are you sure you want to install Windows?</p>' +
- ' <button id="yes">Yes</button>' +
- ' <button id="no">No</button>' +
- '</div> </div>');
-
- // Enter the dialog by focusing an element inside it.
- this.setFocus('no');
- this.waitForCalm(this.assertSpoken,
- 'Entered dialog ' +
- 'Are you sure you want to install Windows? Yes Button No Button ' +
- 'No Button');
-});
-
-/**
- * Test feedback when focus moves to two different items in a alertdialog
- * quickly - make sure the notification that we entered the dialog
- * isn't interrupted.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'DoubleFocusAlertDialogFeedback',
- function() {
- this.loadHtml('<div>' +
- '<div role="alertdialog">' +
- ' <p>Are these the droids you\'re looking for?</p>' +
- ' <button id="yes">Yes</button>' +
- ' <button id="no">No</button>' +
- '</div>' +
- '<button id="outside">Outside</button>' +
- '</div>');
-
- // Enter the dialog by focusing an element inside it, but then the Jedi
- // mind trick quickly changes the default answer.
- this.setFocus('yes')
- .setFocus('no');
-
- this.waitForCalm(this.assertSpokenList,
- this.spokenList()
- .categoryFlush('Entered dialog')
- .queue('Are these the droids you\'re looking for?')
- .queue('Yes')
- .queue('Button'))
- .waitForCalm(this.setFocus, 'outside')
- .waitForCalm(this.assertSpoken, 'Exited dialog. Outside Button');
-});
-
-/**
- * Test recovery when a dialog box closes and the user sends a tab event.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'CloseDialogTabRecovery', function() {
- this.loadHtml('<div id="container">' +
- '<p id="first">first node</p>' +
- '<button id="button">valid button before</button>' +
- '<p id="before">valid text before</p>' +
- '<p id="dialog">invalid after click</p>' +
- '<p id="last">valid text after</p>' +
- '</div>');
-
- var first = $('first');
- var dialog = $('dialog');
- var displayNone = function() {
- dialog.style.display = 'none';
- };
-
- this.waitForCalm(cvox.ChromeVoxTester.syncToNode, first)
- .waitForCalm(cvox.ChromeVoxTester.setStrategy, 'lineardom')
- .waitForCalm(this.userCommand, 'forward')
- .waitForCalm(this.assertSpoken, 'valid button before Button')
- .waitForCalm(this.userCommand, 'forward')
- .waitForCalm(this.assertSpoken, 'valid text before')
- .waitForCalm(this.userCommand, 'forward')
- .waitForCalm(this.assertSpoken, 'invalid after click')
- .waitForCalm(displayNone)
- .waitForCalm(this.userCommand, 'forward')
- .waitForCalm(this.assertSpoken, 'valid text after');
-});
-
-/**
- * Test feedback when a list box with an active descendant receives focus.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'ListBoxFeedback', function() {
- this.loadHtml('<div>' +
- '<p id="before">My listbox</p>' +
- '<div id="listbox" role="listbox" tabindex="0"' +
- ' aria-activedescendant="red">' +
- ' <div id="red" aria-selected="true" role="option">Red</div>' +
- ' <div id="yellow" role="option">Yellow</div>' +
- ' <div id="green" role="option">Green</div>' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
-
- // Focus the listbox.
- this.setFocus('listbox');
- this.waitForCalm(this.assertSpoken, 'Red List box Selected 1 of 3')
- .waitForCalm(function() {
- // Set the activeDescendant and fire a keydown event.
- // TODO(dmazzoni): replace with a higher-level API that's
- // less brittle.
- var listbox = $('listbox');
- listbox.setAttribute('aria-activeDescendant', 'yellow');
- cvox.ChromeVoxEventWatcher.keyDownEventWatcher(/** @type {Event} */ (
- { 'target': listbox,
- 'type': 'keydown' }));
- })
- .waitForCalm(this.assertSpoken, 'Yellow 2 of 3');
-});
-
-/**
- * Test feedback when the items of a list box receive focus.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'ListBoxOptionFeedback', function() {
- this.loadHtml('<div>' +
- '<p id="before">My listbox</p>' +
- '<div id="listbox" role="listbox">' +
- ' <div id="red" tabindex="0" aria-selected="true" role="option">' +
- 'Red</div>' +
- ' <div id="yellow" tabindex="-1" role="option">Yellow</div>' +
- ' <div id="green" tabindex="-1" role="option">Green</div>' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
-
- // Focus the second item.
- this.setFocus('yellow');
-
- this.waitForCalm(this.assertSpoken, 'List box Yellow 2 of 3')
- .waitForCalm(this.setFocus, 'red')
- .waitForCalm(this.assertSpoken, 'Red Selected 1 of 3');
-});
-
-/**
- * Test feedback when the list box is setting focus in response to arrow
- * (or some other) keypress and the user is also using ChromeVox navigation.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'ListBoxOptionFeedbackWithFocus', function() {
- this.loadHtml('<div>' +
- '<p id="before">My listbox</p>' +
- '<div id="listbox" role="listbox">' +
- ' <div id="red" tabindex="0" aria-selected="true" role="option">' +
- 'Red</div>' +
- ' <div id="yellow" tabindex="-1" role="option">Yellow</div>' +
- ' <div id="green" tabindex="-1" role="option">Green</div>' +
- ' <div id="blue" tabindex="-1" role="option">Blue</div>' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
-
- // Simulate the user using ChromeVox navigation to move forward in the listbox
- this.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'lineardom')
- .waitForCalm(cvox.ChromeVoxTester.syncToFirstNode)
- .waitForCalm(this.userCommand, 'forward')
- .waitForCalm(this.assertSpoken, 'List box Red Selected 1 of 4')
- .waitForCalm(this.setFocus, 'yellow')
- .waitForCalm(this.assertSpoken, 'Yellow 2 of 4')
- .waitForCalm(this.setFocus, 'green')
- .waitForCalm(this.assertSpoken, 'Green 3 of 4')
- .waitForCalm(this.userCommand, 'forward')
- .waitForCalm(this.assertSpoken, 'Blue 4 of 4');
-});
-
-/**
- * Test feedback when interacting with an editable text field.
- * The low-level details are tested in editable_text_test.js, this is
- * a higher-level test of how that code interacts with the event watcher.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'EditableText', function() {
- cvox.ChromeVoxEditableTextBase.eventTypingEcho = false;
- this.loadHtml('<div>' +
- '<button id="before">Before</button>' +
- '<label for="input">Query</label>' +
- '<input id="input" value="abc">' +
- '<p>After</p>' +
- '</div>');
-
- var before = $('before');
- var input = $('input');
-
- // Focus the button first.
- before.focus();
-
- // Then focus the text field.
- input.focus();
- input.setSelectionRange(3, 3);
-
- this.waitForCalm(this.changeTextField, input, 'abcd', 3, 3, 68) // 'd'
- .waitForCalm(this.changeTextField, input, 'abcde', 4, 4, 69) // 'e'
- .waitForCalm(this.assertSpokenList,
- this.spokenList()
- .categoryFlush('Query')
- .queue('abc')
- .queue('Edit text')
- .flush('d')
- .flush('e'));
-});
-
-/**
- * Test feedback when interacting with an editable text field that drives
- * an listbox (to form an auto-complete combobox) but doesn't get updated.
- * The low-level details are tested in editable_text_test.js, this is
- * a higher-level test of how that code interacts with the event watcher.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'EditableTextListbox', function() {
- this.loadHtml('<div>' +
- '<button id="before">Before</button>' +
- '<label for="input">Query</label>' +
- '<input id="input" value="" role="combobox" aria-autocomplete="list"' +
- ' aria-activedescendant>' +
- '<div role="listbox">' +
- ' <div id="option1" role="option">First pick</div>' +
- ' <div id="option2" role="option">Second pick</div>' +
- '</div>' +
- '<p>After</p>' +
- '</div>');
-
- var before = $('before');
- var input = $('input');
-
- // Focus the text field.
- this.waitForCalm(this.setFocus, 'input')
- .waitForCalm(this.assertSpoken, 'Query Combo box Autocompletion list');
-
- this.waitForCalm(function() {
- input.setAttribute('aria-activedescendant', 'option1');
- this.changeTextField(input, '', 0, 0, 40); // 'down'
- })
- .waitForCalm(this.assertSpoken, 'First pick 1 of 2');
-});
-
-/**
- * Test feedback when interacting with an editable text field that drives
- * an listbox (to form an auto-complete combobox) and *does* get updated.
- * The low-level details are tested in editable_text_test.js, this is
- * a higher-level test of how that code interacts with the event watcher.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'EditableTextListboxUpdatingInput',
- function() {
- this.loadHtml('<div>' +
- '<button id="before">Before</button>' +
- '<label for="input">Query</label>' +
- '<input id="input" value="" role="combobox" aria-autocomplete="list"' +
- ' aria-activedescendant>' +
- '<div role="listbox">' +
- ' <div id="option1" role="option">First pick</div>' +
- ' <div id="option2" role="option">Second pick</div>' +
- '</div>' +
- '<p>After</p>' +
- '</div>');
-
- var before = $('before');
- var input = $('input');
-
- // Focus the text field.
- this.waitForCalm(this.setFocus, 'input')
- .waitForCalm(this.assertSpoken, 'Query Combo box Autocompletion list');
-
- this.waitForCalm(function() {
- input.setAttribute('aria-activedescendant', 'option1');
- this.changeTextField(input, 'First pick', 9, 9, 40); // 'down'
- })
- .waitForCalm(this.assertSpoken, 'First pick');
-});
-
-/**
- * Tests navigating through a multiline text area.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'MultilineNavigation', function() {
- this.loadHtml('<div> <textarea id="area">' +
- 'one' +
- '\n\n' +
- 'two' +
- '\n\n' +
- 'three</textarea>' +
- '</div>');
-
- var area = $('area');
-
- function setAreaCursor(pos) {
- area.setSelectionRange(pos, pos);
- cvox.ChromeVoxEventWatcher.keyDownEventWatcher(/** @type {Event} */ (
- { 'target': area,
- 'type': 'keydown' }));
- }
-
- area.focus();
- this.waitForCalm(this.assertSpoken, 'one two three Text area')
- .waitForCalm(setAreaCursor, 0)
- // The cursor did not move, so don't say anything -- even though we
- // did press a key.
- .waitForCalm(this.assertSpoken, '')
- .waitForCalm(setAreaCursor, 5) // in front on the 'two'
- .waitForCalm(this.assertSpoken, 'two')
- .waitForCalm(setAreaCursor, 10) // in front of the 'three'
- .waitForCalm(this.assertSpoken, 'three')
- .waitForCalm(setAreaCursor, 0) // back to the first line
- .waitForCalm(this.assertSpoken, 'one')
- .waitForCalm(setAreaCursor, 4) // on the first new line
- .waitForCalm(this.assertSpoken, 'Blank')
- .waitForCalm(setAreaCursor, 5)
- .waitForCalm(this.assertSpoken, 'two')
- .waitForCalm(setAreaCursor, 9)
- .waitForCalm(this.assertSpoken, 'Blank')
- .waitForCalm(setAreaCursor, 10)
- .waitForCalm(this.assertSpoken, 'three');
-});
-
-SYNC_TEST_F('CvoxEventWatcherUnitTest', 'ShouldWaitToProcess', function() {
- // The focus event just happened, wait.
- assertTrue(
- cvox.ChromeVoxEventWatcherUtil.shouldWaitToProcess(100, 100, 100));
- // The focus event just happened, but the first event is old, don't wait.
- assertFalse(
- cvox.ChromeVoxEventWatcherUtil.shouldWaitToProcess(100, 0, 100));
- // The focus event is old, don't wait.
- assertFalse(
- cvox.ChromeVoxEventWatcherUtil.shouldWaitToProcess(0, 0, 100));
-
-});
-
-/**
- * Test that no feedback is received for events that fire on elements
- * that are hidden (or the descendant of a hidden element).
- */
-TEST_F('CvoxEventWatcherUnitTest', 'AriaHiddenFeedback', function() {
- this.loadHtml('<div>' +
- '<div>' +
- ' <button id="button1">Button 1</button>' +
- ' <button id="button2" aria-hidden="true">Button 2</button>' +
- '</div>' +
- '<div aria-hidden="true">' +
- ' <h3>Random header</h3>' +
- ' <div>' +
- ' <button id="button3">Button 3</button>' +
- ' </div>' +
- ' <h3>Random header</h3>' +
- '</div>' +
- '<div>' +
- ' <button id="button4">Button 4</button>' +
- '</div>' +
- '</div>');
-
- this.setFocus('button1')
- .waitForCalm(this.assertSpoken, 'Button 1 Button')
- .waitForCalm(this.setFocus, 'button2')
- .waitForCalm(this.assertSpoken, '')
- .waitForCalm(this.setFocus, 'button3')
- .waitForCalm(this.assertSpoken, '')
- .waitForCalm(this.setFocus, 'button4')
- .waitForCalm(this.assertSpoken, 'Button 4 Button');
-});
-
-/**
- * Test that key down events don't cause excessive value and state announcements
- * when arrowing around radiobuttons.
- */
-TEST_F('CvoxEventWatcherUnitTest',
- 'DISABLED_RadioButtonAnnouncements',
- function() {
- this.loadHtml(
- '<input id="radio1" type="radio" aria-label="green" tabindex=0>' +
- '<input id="radio2" type="radio" aria-label="blue" tabindex=0>');
- function performKeyDown(dir) {
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keydown', true, true, window, dir, 0, false, false, false, false);
-
- document.activeElement.dispatchEvent(evt);
- };
-
- var radio1 = $('radio1');
- radio1.focus();
-
- // TODO(dtseng): Repeated actual spoken text here; this is most certainly a
- // test framework bug.
- this.waitForCalm(this.assertSpoken, 'green Radio button unselected')
- .waitForCalm(performKeyDown, 'Right') // right arrow
- // Moves to next radiobutton.
- .waitForCalm(this.assertSpoken,
- 'blue Radio button selected blue Radio button selected')
- .waitForCalm(performKeyDown, 'Right') // right arrow
- // Arrowed beyond end. Should be quiet.
- .waitForCalm(this.assertSpoken, '');
-
- this.waitForCalm(performKeyDown, 'Left') // left arrow
- // Moves back to first radio.
- .waitForCalm(this.assertSpoken,
- 'green Radio button selected green Radio button selected')
- .waitForCalm(performKeyDown, 'Left') // left arrow
- // Arrowed beyond beginning. Should be quiet.
- .waitForCalm(this.assertSpoken, '');
-});
-
-/**
- * Test time widget.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'TimeWidget', function() {
- this.loadHtml(
- '<label for="timewidget">Set alarm for:</label>' +
- '<input id="timewidget" type="time" value="12:00">');
- var performKeyDown = function(dir) {
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keydown', true, true, window, dir, 0, false, false, false, false);
-
- document.activeElement.dispatchEvent(evt);
- };
- var performKeyUp = function(dir) {
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keyup', true, true, window, dir, 0, false, false, false, false);
-
- document.activeElement.dispatchEvent(evt);
- };
-
- var timewidget = $('timewidget');
- timewidget.focus();
-
- this.waitForCalm(this.assertSpoken,
- 'Set alarm for: 12:00 Set alarm for: 12 hours 00 minutes PM');
-
- this.waitForCalm(performKeyDown, 'Down') // down arrow
- .waitForCalm(performKeyUp, 'Down') // down arrow
- .waitForCalm(this.assertSpoken,
- '11 hours');
-
- this.waitForCalm(performKeyDown, 'Down') // down arrow
- .waitForCalm(performKeyUp, 'Down') // down arrow
- .waitForCalm(this.assertSpoken,
- '10 hours');
-
- this.waitForCalm(performKeyDown, 'Right') // right arrow
- .waitForCalm(performKeyUp, 'Right') // right arrow
- .waitForCalm(performKeyDown, 'Up') // right arrow
- .waitForCalm(performKeyUp, 'Up') // right arrow
- .waitForCalm(this.assertSpoken,
- '01 minutes');
-
- this.waitForCalm(performKeyDown, 'Down') // down arrow
- .waitForCalm(performKeyUp, 'Down') // down arrow
- .waitForCalm(this.assertSpoken,
- '00 minutes');
-
- this.waitForCalm(performKeyDown, 'Right') // right arrow
- .waitForCalm(performKeyUp, 'Right') // right arrow
- .waitForCalm(performKeyDown, 'Up') // right arrow
- .waitForCalm(performKeyUp, 'Up') // right arrow
- .waitForCalm(this.assertSpoken,
- 'AM');
-
- this.waitForCalm(performKeyDown, 'Down') // down arrow
- .waitForCalm(performKeyUp, 'Down') // down arrow
- .waitForCalm(this.assertSpoken,
- 'PM');
-});
-
-/**
- * Test date widget.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'DateWidget', function() {
- this.loadHtml(
- '<label for="datewidget">Set birthdate:</label>' +
- '<input id="datewidget" type="date" value="1998-09-04"/>');
- var performKeyDown = function(dir) {
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keydown', true, true, window, dir, 0, false, false, false, false);
-
- document.activeElement.dispatchEvent(evt);
- };
- var performKeyUp = function(dir) {
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keyup', true, true, window, dir, 0, false, false, false, false);
-
- document.activeElement.dispatchEvent(evt);
- };
-
- var datewidget = $('datewidget');
- datewidget.focus();
-
- this.waitForCalm(this.assertSpoken,
- 'Set birthdate: 1998-09-04 Date control Set birthdate: September 4 1998')
-
- .waitForCalm(performKeyDown, 'Down') // down arrow
- .waitForCalm(performKeyUp, 'Down') // down arrow
- .waitForCalm(this.assertSpoken,
- 'August')
-
- .waitForCalm(performKeyDown, 'Down') // down arrow
- .waitForCalm(performKeyUp, 'Down') // down arrow
- .waitForCalm(this.assertSpoken, 'July')
-
- .waitForCalm(performKeyDown, 'Right') // right arrow
- .waitForCalm(performKeyUp, 'Right') // right arrow
- .waitForCalm(performKeyDown, 'Up') // right arrow
- .waitForCalm(performKeyUp, 'Up') // right arrow
- .waitForCalm(this.assertSpoken, '5')
-
- .waitForCalm(performKeyDown, 'Down') // down arrow
- .waitForCalm(performKeyUp, 'Down') // down arrow
- .waitForCalm(this.assertSpoken, '4')
-
- .waitForCalm(performKeyDown, 'Right') // right arrow
- .waitForCalm(performKeyUp, 'Right') // right arrow
- .waitForCalm(performKeyDown, 'Up') // right arrow
- .waitForCalm(performKeyUp, 'Up') // right arrow
- .waitForCalm(this.assertSpoken,
- '1999')
-
- .waitForCalm(performKeyDown, 'Down') // down arrow
- .waitForCalm(performKeyUp, 'Down') // down arrow
- .waitForCalm(this.assertSpoken,
- '1998');
-});
-
-/**
- * Test that ChromeVox speaks the correct state when a focused control
- * changes as the result of a key up, not just key down.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'ToggleOnKeyUp', function() {
- this.loadHtml('<div>' +
- '<div tabIndex=0 id="pressable" role="button" aria-pressed="false">' +
- 'Toggle' +
- '</div>' +
- '</div>');
-
- // Focus on the button.
- this.setFocus('pressable');
- this.waitForCalm(this.assertSpoken, 'Toggle Button Not pressed');
-
- function keyupSpace() {
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keyup', true, true, window, ' ', 0, false, false, false, false);
- document.activeElement.dispatchEvent(evt);
- }
-
- function keyupSpaceAndMarkPressed() {
- keyupSpace();
- $('pressable').setAttribute('aria-pressed', 'true');
- };
-
- function keyupSpaceAndMarkNotPressed() {
- keyupSpace();
- $('pressable').setAttribute('aria-pressed', 'false');
- };
-
- this.waitForCalm(keyupSpaceAndMarkPressed)
- .waitForCalm(this.assertSpoken, 'Pressed')
- .waitForCalm(keyupSpaceAndMarkNotPressed)
- .waitForCalm(this.assertSpoken, 'Not pressed');
-});
-
-/**
- * Exiting dialog message should not interrupt a live region.
- */
-TEST_F('CvoxEventWatcherUnitTest', 'DISABLED_ExitDialogWithLiveRegion', function() {
- this.loadHtml(
- '<div role="dialog" aria-label="MyAlert">' +
- ' <h1>Heading</h1>' +
- ' <button id="initial">Initial focus</button>' +
- '</div>' +
- '<div>' +
- ' <button id="final">Final focus</button>' +
- '</div>' +
- '<div id="live" aria-live="polite"></div>');
-
- // Focus on the button in the dialog.
- this.setFocus('initial');
- this.waitForCalm(this.assertSpoken,
- 'Entered dialog MyAlert Dialog Initial focus Button')
- .waitForCalm(function() {
- $('live').innerText = 'Live region changed';
- })
- .waitForCalm(function() {
- this.setFocus('final');
- })
- .waitForCalm(function() {
- var ulist = cvox.ChromeVoxTester.testTts().getSpeechQueueOutput();
- assertEquals('Live region changed', ulist[0]);
- assertEquals('Exited dialog.', ulist[1]);
- assertEquals('Final focus', ulist[2]);
- assertEquals('Button', ulist[3]);
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/externs.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/externs.js
deleted file mode 100644
index 2cf06d22ba2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/externs.js
+++ /dev/null
@@ -1,215 +0,0 @@
-// 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.
-
-/**
- * External functions for MathJax bridge.
- * @typedef {Object}
- */
-function MathJax() {}
-
-/**
- * @type {Function}
- */
-MathJax.Callback;
-
-/**
- * @param {Array<*>} args
- * @param {string} err
- */
-MathJax.Callback.After = function(args, err) { };
-
-
-/**
- * @typedef {{root: MathJax.RootElement,
- * inputID: string}}
- */
-MathJax.Jax;
-
-
-/**
- * @typedef {{inputID: string,
- * spanID: number,
- * data: Array<Object>,
- * id: string,
- * texClass: string}}
- */
-MathJax.RootElement;
-MathJax.RootElement.prototype;
-
-/**
- * @param {string} name
- */
-MathJax.RootElement.prototype.toMathML = function(name) { };
-
-/**
- */
-MathJax.RootElement.prototype.toMathMLattributes = function() { };
-
-
-/**
- * @typedef {Object}
- */
-MathJax.Hub;
-
-/**
- * @param {string} id
- */
-MathJax.Hub.getJaxFor = function(id) { };
-
-/**
- */
-MathJax.Hub.getAllJax = function() { };
-
-/**
- * @type {{PreProcessor: Function,
- * MessageHook: function(string, function(Array<string>)):
- * function(Array<string>),
- * StartupHook: function(string, function(Array<string>)):
- * function(Array<string>),
- * LoadHook: function(string, function(Array<string>)):
- * function(Array<string>)}}
- */
-MathJax.Hub.Register;
-
-
-/**
- * @typedef {Object}
- */
-MathJax.OutputJax;
-
-
-/**
- * @typedef {Object}
- */
-MathJax.ElementJax;
-MathJax.ElementJax.prototype.mml;
-
-/**
- * @param {?string} mml MathML expression.
- */
-MathJax.ElementJax.mml = function(mml) { };
-
-
-/**
- * @type {MathJax.RootElement}
- */
-MathJax.ElementJax.mml.mbase;
-MathJax.ElementJax.mml.mbase.prototype;
-
-
-/**
- * @type {MathJax.RootElement}
- */
-MathJax.ElementJax.mml.mfenced;
-MathJax.ElementJax.mml.mfenced.prototype;
-
-
-/**
- * @param {string} err
- */
-MathJax.ElementJax.mml.merror = function(err) { };
-
-
-/**
- * @type {{DOUBLESTRUCK: string,
- * NORMAL: string}}
- */
-MathJax.ElementJax.mml.VARIANT;
-
-
-/**
- * @type {{OP: number}}
- */
-MathJax.ElementJax.mml.TEXCLASS;
-
-
-/**
- * @typedef {Object}
- */
-MathJax.InputJax;
-
-
-/**
- * @typedef {Object}
- */
-MathJax.HTML;
-
-
-/**
- * Creates an HTML element from a node tag, an object with attributes and an
- * array of text content.
- * @param {string} tag
- * @param {Object<string>} attribs
- * @param {Array<string>} text
- */
-MathJax.HTML.Element = function(tag, attribs, text) { };
-
-
-/**
- * @type {{Parse: function(string): MathJax.ElementJax,
- * postfilterHooks: {Execute:
- * function({math: MathJax.RootElement, display: boolean, script: Element})},
- * prefilterHooks: {Execute:
- * function({math: string, display: boolean, script: Element})},
- * Definitions: Object}}
- */
-MathJax.InputJax.TeX;
-
-
-/**
- * MediaWiki object.
- * @typedef {Object}
- */
-function mediaWiki() {}
-
-
-/**
- * This is the definition of the type that's returned from the PDF plug-in.
- * @constructor
- */
-var PDFAccessibilityJSONReply = function() {};
-
-/**
- * Whether the PDF has finished loading or not.
- * @type {boolean}
- */
-PDFAccessibilityJSONReply.prototype.loaded;
-
-/**
- * Whether the PDF allows accessible text access. Unfortunately PDFs can
- * mark themselves as not copyable even for accessibility.
- * @type {boolean}
- */
-PDFAccessibilityJSONReply.prototype.copyable;
-
-/**
- * The number of pages in the PDF.
- * @type {number}
- */
-PDFAccessibilityJSONReply.prototype.numberOfPages;
-
-/**
- * The height of each PDF page in points.
- * @type {number}
- */
-PDFAccessibilityJSONReply.prototype.height;
-
-/**
- * The width of each PDF page in points.
- * @type {number}
- */
-PDFAccessibilityJSONReply.prototype.width;
-
-/**
- * The text boxes in the PDF, this is where most of the content is returned.
- * Each text box has a bounding box (left, top, width, height) and
- * each of these contains an array of nodes of type 'text' or 'url'.
- * @type {Array<
- * {left: number, top: number, width: number, height: number,
- * textNodes: Array<
- * {type: string, text: string, url: string}>
- * }>
- * }
- */
-PDFAccessibilityJSONReply.prototype.textBox;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/history.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/history.js
deleted file mode 100644
index 6db9d0de41f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/history.js
+++ /dev/null
@@ -1,406 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Stores the history of a ChromeVox session.
- */
-
-goog.provide('cvox.History');
-
-goog.require('cvox.DomUtil');
-goog.require('cvox.NodeBreadcrumb');
-
-/**
- * A history event is stored in the cvox.History object and contains all the
- * information about a single ChromeVox event.
- * @param {Object=} opt_json A simple initializer object.
- * @constructor
- */
-cvox.HistoryEvent = function(opt_json) {
- /**
- * The start time of this event, in msec since epoch.
- * @type {number}
- * @private
- */
- this.startTime_;
-
- /**
- * The end time of this event, in msec since epoch.
- * @type {number}
- * @private
- */
- this.endTime_;
-
- /**
- * The user command executed in this event.
- * @type {string}
- * @private
- */
- this.userCommand_;
-
- /**
- * An array of spoken output.
- * @type {Array<string>}
- * @private
- */
- this.spoken_ = [];
-
- /**
- * The ChromeVox tag for the current node at the end of this event.
- * @type {number}
- * @private
- */
- this.cvTag_;
-
- /**
- * True if replayed.
- * @type {boolean}
- * @private
- */
- this.replayed_ = false;
-
- if (opt_json) {
- this.replayed_ = true;
- this.userCommand_ = opt_json['cmd'];
- } else {
- this.startTime_ = new Date().getTime();
- }
-};
-
-/**
- * @param {string} functionName The name of the user command.
- * @return {cvox.HistoryEvent} this for chaining.
- */
-cvox.HistoryEvent.prototype.withUserCommand = function(functionName) {
- if (this.userCommand_) {
- window.console.error('Two user commands on ' + functionName, this);
- return this;
- }
- this.userCommand_ = functionName;
- return this;
-};
-
-/**
- * @param {string} str The text spoken.
- * @return {cvox.HistoryEvent} this for chaining.
- */
-cvox.HistoryEvent.prototype.speak = function(str) {
- this.spoken_.push(str);
- return this;
-};
-
-/**
- * Called when the event is done. We can expect nothing else will be added to
- * the event after this call.
- * @return {cvox.HistoryEvent} this for chaining.
- */
-cvox.HistoryEvent.prototype.done = function() {
- this.endTime_ = new Date().getTime();
-
- this.cvTag_ = cvox.NodeBreadcrumb.getInstance().tagCurrentNode();
-
- window.console.log('User command done.', this);
- return this;
-};
-
-/**
- * Outputs the event as a simple object
- * @return {Object} A object representation of the event.
- */
-cvox.HistoryEvent.prototype.outputObject = function() {
- return {
- 'start': this.startTime_,
- 'end': this.endTime_,
- 'cmd': this.userCommand_,
- 'spoken': this.spoken_
- };
-};
-
-/**
- * Outputs a HTML element that can be added to the DOM.
- * @return {Element} The HTML element.
- */
-cvox.HistoryEvent.prototype.outputHTML = function() {
- var div = document.createElement('div');
- div.className = 'cvoxHistoryEvent';
- var dur = this.endTime_ - this.startTime_;
- div.innerHTML = this.userCommand_ + ' (' + dur + 'ms)';
- for (var i = 0; i < this.spoken_.length; i++) {
- var sdiv = document.createElement('div');
- sdiv.className = 'cvoxHistoryEventSpoken';
- sdiv.innerHTML = this.spoken_[i].substr(0, 20);
- if (this.spoken_[i].length > 20) {
- sdiv.innerHTML += '...';
- }
- div.appendChild(sdiv);
- }
- return div;
-};
-
-/**
- * Outputs Javascript to replay the command and assert the output.
- * @return {string} The Javascript.
- */
-cvox.HistoryEvent.prototype.outputJs = function() {
- var o = 'this.waitForCalm(this.userCommand, \'' + this.userCommand_ + '\')';
- if (this.spoken_.length > 0) {
- o += '\n .waitForCalm(this.assertSpoken, \'' +
- cvox.DomUtil.collapseWhitespace(this.spoken_.join(' ')) + '\');\n';
- } else {
- o += ';\n';
- }
- return o;
-};
-
-
-/**
- * @constructor
- * @implements {cvox.TtsInterface}
- */
-cvox.History = function() {
- this.recording_ = false;
-
- this.events_ = [];
- this.markers_ = {};
- this.currentEvent_ = null;
-
- this.mainDiv_ = null;
- this.listDiv_ = null;
- this.styleDiv_ = null;
-
- this.bigBoxDiv_ = null;
-
- // NOTE(deboer): Currently we only ever have one cvox.History, but
- // if we ever have more than one, we need multiple NodeBreadcrumbs as well.
- this.nodeBreadcrumb_ = cvox.NodeBreadcrumb.getInstance();
-
-};
-goog.addSingletonGetter(cvox.History);
-
-/**
- * Adds a list div to the DOM for debugging.
- * @private
- */
-cvox.History.prototype.addListDiv_ = function() {
- this.mainDiv_ = document.createElement('div');
- this.mainDiv_.style.position = 'fixed';
- this.mainDiv_.style.bottom = '0';
- this.mainDiv_.style.right = '0';
- this.mainDiv_.style.zIndex = '999';
-
- this.listDiv_ = document.createElement('div');
- this.listDiv_.id = 'cvoxEventList';
- this.mainDiv_.appendChild(this.listDiv_);
-
- var buttonDiv = document.createElement('div');
- var button = document.createElement('button');
- button.onclick = cvox.History.sendToFeedback;
- button.innerHTML = 'Create bug';
- buttonDiv.appendChild(button);
- this.mainDiv_.appendChild(buttonDiv);
-
- var dumpDiv = document.createElement('div');
- var dumpButton = document.createElement('button');
- dumpButton.onclick = cvox.History.dumpJs;
- dumpButton.innerHTML = 'Dump test case';
- dumpDiv.appendChild(dumpButton);
- this.mainDiv_.appendChild(dumpDiv);
-
- document.body.appendChild(this.mainDiv_);
-
- this.styleDiv_ = document.createElement('style');
- this.styleDiv_.innerHTML =
- '.cvoxHistoryEventSpoken { color: gray; font-size: 75% }';
- document.body.appendChild(this.styleDiv_);
-};
-
-
-/**
- * Removes the list div.
- * @private
- */
-cvox.History.prototype.removeListDiv_ = function() {
- document.body.removeChild(this.mainDiv_);
- document.body.removeChild(this.styleDiv_);
- this.mainDiv_ = null;
- this.listDiv_ = null;
- this.styleDiv_ = null;
-};
-
-
-/**
- * Adds a big text box in the middle of the screen
- * @private
- */
-cvox.History.prototype.addBigTextBox_ = function() {
- var bigBoxDiv = document.createElement('div');
- bigBoxDiv.style.position = 'fixed';
- bigBoxDiv.style.top = '0';
- bigBoxDiv.style.left = '0';
- bigBoxDiv.style.zIndex = '999';
-
- var textarea = document.createElement('textarea');
- textarea.style.width = '500px';
- textarea.style.height = '500px';
- textarea.innerHTML = this.dumpJsOutput_();
- bigBoxDiv.appendChild(textarea);
-
- var buttons = document.createElement('div');
- bigBoxDiv.appendChild(buttons);
-
- function link(name, func) {
- var linkElt = document.createElement('button');
- linkElt.onclick = func;
- linkElt.innerHTML = name;
- buttons.appendChild(linkElt);
- }
- link('Close dialog', function() {
- document.body.removeChild(bigBoxDiv);
- });
- link('Remove fluff', goog.bind(function() {
- textarea.innerHTML = this.dumpJsOutput_(['stopSpeech', 'toggleKeyPrefix']);
- }, this));
- document.body.appendChild(bigBoxDiv);
-};
-
-
-
-/**
- * Start recording and show the debugging list div.
- */
-cvox.History.prototype.startRecording = function() {
- this.recording_ = true;
- this.addListDiv_();
-};
-
-
-/**
- * Stop recording and clear the events array.
- */
-cvox.History.prototype.stopRecording = function() {
- this.recording_ = false;
- this.removeListDiv_();
- this.events_ = [];
- this.currentEvent_ = null;
-};
-
-
-/**
- * Called by ChromeVox when it enters a user command.
- * @param {string} functionName The function name.
- */
-cvox.History.prototype.enterUserCommand = function(functionName) {
- if (!this.recording_) {
- return;
- }
- if (this.currentEvent_) {
- window.console.error(
- 'User command ' + functionName + ' overlaps current event',
- this.currentEvent_);
- }
- this.currentEvent_ = new cvox.HistoryEvent()
- .withUserCommand(functionName);
- this.events_.push(this.currentEvent_);
-};
-
-
-/**
- * Called by ChromeVox when it exits a user command.
- * @param {string} functionName The function name, useful for debugging.
- */
-cvox.History.prototype.exitUserCommand = function(functionName) {
- if (!this.recording_ || !this.currentEvent_) {
- return;
- }
- this.currentEvent_.done();
- this.listDiv_.appendChild(this.currentEvent_.outputHTML());
- this.currentEvent_ = null;
-};
-
-
-/** @override */
-cvox.History.prototype.speak = function(str, mode, props) {
- if (!this.recording_) {
- return this;
- }
- if (!this.currentEvent_) {
- window.console.error('Speak called outside of a user command.');
- return this;
- }
- this.currentEvent_.speak(str);
- return this;
-};
-
-
-/** @override */
-cvox.History.prototype.isSpeaking = function() { return false; };
-/** @override */
-cvox.History.prototype.stop = function() { };
-/** @override */
-cvox.History.prototype.addCapturingEventListener = function(listener) { };
-/** @override */
-cvox.History.prototype.increaseOrDecreaseProperty =
- function(propertyName, increase) { };
-/** @override */
-cvox.History.prototype.getDefaultProperty = function(property) { };
-
-
-/** TODO: add doc comment. */
-cvox.History.dumpJs = function() {
- var history = cvox.History.getInstance();
- history.addBigTextBox_();
- window.console.log(history.dumpJsOutput_());
-};
-
-
-/**
- * @param {Array<string>=} opt_skipCommands
- * @return {string} A string of Javascript output.
- * @private
- */
-cvox.History.prototype.dumpJsOutput_ = function(opt_skipCommands) {
- var skipMap = {};
- if (opt_skipCommands) {
- opt_skipCommands.forEach(function(e) { skipMap[e] = 1; });
- }
- // TODO: pretty print
- return ['/*DOC: += ',
- this.nodeBreadcrumb_.dumpWalkedDom().innerHTML, '*/\n']
- .concat(this.events_
- .filter(function(e) { return ! (e.userCommand_ in skipMap); })
- .map(function(e) { return e.outputJs(); })).join('');
-};
-
-
-/**
- * Send the history to Google Feedback.
- */
-cvox.History.sendToFeedback = function() {
- var history = cvox.History.getInstance();
- var output = history.events_.map(function(e) {
- return e.outputObject();
- });
-
- var feedbackScript = document.createElement('script');
- feedbackScript.type = 'text/javascript';
- feedbackScript.src = 'https://www.gstatic.com/feedback/api.js';
-
- var runFeedbackScript = document.createElement('script');
- runFeedbackScript.type = 'text/javascript';
- runFeedbackScript.innerHTML =
- 'userfeedback.api.startFeedback(' +
- '{ productId: \'76092\' }, ' +
- '{ cvoxHistory: ' + cvox.ChromeVoxJSON.stringify(
- cvox.ChromeVoxJSON.stringify(output)) + ' });';
-
- feedbackScript.onload = function() {
- document.body.appendChild(runFeedbackScript);
- };
-
- document.body.appendChild(feedbackScript);
-};
-
-
-// Add more events: key press, DOM
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_document.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_document.js
deleted file mode 100644
index 1e6ed9e4d7b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_document.js
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Initializes the injected content script on the document.
- *
- * NOTE(deboer): This file will automatically initialize ChromeVox. If you can
- * control when ChromeVox starts, consider using cvox.InitGlobals instead.
- *
- */
-
-goog.provide('cvox.ChromeVoxInit');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ExtensionBridge');
-goog.require('cvox.HostFactory');
-goog.require('cvox.InitGlobals');
-
-/**
- * The time to pause before trying again to initialize, in ms. This
- * number starts small and keeps growing so that we don't waste CPU
- * time on a page that takes a long time to load.
- * @type {number}
- * @private
- */
-cvox.ChromeVox.initTimeout_ = 100;
-
-
-/**
- * Flag indicating if ChromeVox Classic is enabled based on the Next
- * background page. Initializes to true for non-top level
- * (i.e. iframes) windows. For top level windows, left undefined and
- * set when background page replies.
- * @type {boolean|undefined}
- * @private
- */
-cvox.ChromeVox.isClassicEnabled_ = window.top == window ? undefined : true;
-
-
-/**
- * Call the init function later, safely.
- * @param {string} reason A developer-readable string to log to the console
- * explaining why we're trying again.
- * @private
- */
-cvox.ChromeVox.recallInit_ = function(reason) {
- window.console.log(reason +
- ' Will try again in ' +
- cvox.ChromeVox.initTimeout_ + 'ms');
- window.setTimeout(cvox.ChromeVox.initDocument, cvox.ChromeVox.initTimeout_);
- cvox.ChromeVox.initTimeout_ *= 2;
-};
-
-
-/**
- * Initializes cvox.ChromeVox when the document is ready.
- */
-cvox.ChromeVox.initDocument = function() {
- // Don't start the content script on the ChromeVox background page.
- if (/^chrome-extension:\/\/.*background\.html$/.test(window.location.href)) {
- return;
- }
-
- cvox.ExtensionBridge.send({
- target: 'next',
- action: 'getIsClassicEnabled',
- url: location.href
- });
-
- if (!document.body || cvox.ChromeVox.isClassicEnabled_ === undefined) {
- cvox.ChromeVox.recallInit_('ChromeVox not starting on unloaded page or' +
- ' waiting for background page: ' +
- document.location.href + '.');
- return;
- }
-
- if (!cvox.ChromeVox.isClassicEnabled_) {
- return;
- }
-
- // Setup globals
- cvox.ChromeVox.host = cvox.HostFactory.getHost();
-
- if (!cvox.ChromeVox.host.ttsLoaded()) {
- cvox.ChromeVox.recallInit_('ChromeVox not starting; waiting for TTS. ' +
- document.location.href + '.');
- return;
- }
-
- window.console.log('Starting ChromeVox.');
-
- cvox.InitGlobals.initGlobals();
-
- // Add a global function to disable this instance of ChromeVox.
- // There is a scenario where two copies of the content script can get
- // loaded into the same tab on browser startup - one automatically
- // and one because the background page injects the content script into
- // every tab on startup. This allows the background page to first deactivate
- // any existing copy of the content script (if any) before loading it again,
- // otherwise there can be duplicate event listeners.
- window.disableChromeVox = function() {
- cvox.ChromeVox.host.killChromeVox();
- };
-};
-
-
-/**
- * Reinitialize ChromeVox, if the extension is disabled and then enabled
- * again, but our injected page script has remained.
- */
-cvox.ChromeVox.reinit = function() {
- cvox.ChromeVox.host.reinit();
- cvox.ChromeVox.initDocument();
-};
-
-if (!COMPILED) {
- // NOTE(deboer): This is called when this script is loaded, automatically
- // starting ChromeVox. If this isn't the uncompiled script, it will be
- // called in loader.js.
- cvox.ChromeVox.initDocument();
-}
-
-cvox.ExtensionBridge.addMessageListener(goog.bind(function(msg, port) {
- if (msg['target'] == 'next') {
- cvox.ChromeVox.isClassicEnabled_ = msg['isClassicEnabled'];
- }
-}, this));
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_globals.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_globals.js
deleted file mode 100644
index 9601a62f17a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/init_globals.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Initializes the injected content script.
- *
- */
-
-goog.provide('cvox.InitGlobals');
-
-goog.require('cvox.ApiImplementation');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxEventWatcher');
-goog.require('cvox.CompositeTts');
-goog.require('cvox.ConsoleTts');
-goog.require('cvox.HostFactory');
-goog.require('cvox.NavigationManager');
-goog.require('cvox.Serializer');
-
-
-
-/**
- * @constructor
- */
-cvox.InitGlobals = function() { };
-
-
-/**
- * Initializes cvox.ChromeVox.
- */
-cvox.InitGlobals.initGlobals = function() {
- if (!cvox.ChromeVox.host) {
- cvox.ChromeVox.host = cvox.HostFactory.getHost();
- }
-
- cvox.ChromeVox.tts = new cvox.CompositeTts()
- .add(cvox.HostFactory.getTts())
- .add(cvox.History.getInstance())
- .add(cvox.ConsoleTts.getInstance());
-
- if (!cvox.ChromeVox.braille) {
- cvox.ChromeVox.braille = cvox.HostFactory.getBraille();
- }
- cvox.ChromeVox.mathJax = cvox.HostFactory.getMathJax();
-
- cvox.ChromeVox.earcons = cvox.HostFactory.getEarcons();
- cvox.ChromeVox.isActive = true;
- cvox.ChromeVox.navigationManager = new cvox.NavigationManager();
- cvox.ChromeVox.navigationManager.updateIndicator();
- cvox.ChromeVox.syncToNode = cvox.ApiImplementation.syncToNode;
- cvox.ChromeVox.speakNode = cvox.ApiImplementation.speakNode;
-
- cvox.ChromeVox.serializer = new cvox.Serializer();
-
- // Do platform specific initialization here.
- cvox.ChromeVox.host.init();
-
- // Start the event watchers
- cvox.ChromeVoxEventWatcher.init(window);
-
- // Provide a way for modules that can't depend on cvox.ChromeVoxUserCommands
- // to execute commands.
- cvox.ChromeVox.executeUserCommand = function(commandName) {
- cvox.ChromeVoxUserCommands.commands[commandName]();
- };
-
- cvox.ChromeVox.host.onPageLoad();
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/initial_speech.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/initial_speech.js
deleted file mode 100644
index fa1fcf63f9f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/initial_speech.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Defines the initial speech call.
- */
-
-goog.provide('cvox.InitialSpeech');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.BrailleOverlayWidget');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.DescriptionUtil');
-goog.require('cvox.DomUtil');
-goog.require('cvox.LiveRegions');
-
-// INJECTED_AFTER_LOAD is set true by ChromeVox itself or ChromeOS when this
-// script is injected after page load (i.e. when manually enabling ChromeVox).
-if (!window['INJECTED_AFTER_LOAD'])
- window['INJECTED_AFTER_LOAD'] = false;
-
-
-/**
- * Initial speech when the page loads. This may happen only after we get
- * prefs back, so we can make sure ChromeVox is active.
- */
-cvox.InitialSpeech.speak = function() {
- // Don't speak page title and other information if this script is not injected
- // at the time of page load. This global is set by Chrome OS.
- var disableSpeak = window['INJECTED_AFTER_LOAD'];
-
- if (!cvox.ChromeVox.isActive || document.webkitHidden) {
- disableSpeak = true;
- }
-
- // If we're the top-level frame, speak the title of the page +
- // the active element if it is a user control.
- if (window.top == window) {
- var title = document.title;
-
- // Allow the web author to disable reading the page title on load
- // by adding aria-hidden=true to the <title> element.
- var titleElement = document.querySelector('head > title');
- if (titleElement && titleElement.getAttribute('aria-hidden') == 'true') {
- title = null;
- }
-
- if (title && !disableSpeak) {
- cvox.ChromeVox.tts.speak(
- title, cvox.QueueMode.FLUSH);
- }
- cvox.BrailleOverlayWidget.getInstance().init();
- }
-
- // Initialize live regions and speak alerts.
- cvox.LiveRegions.init(
- new Date(), cvox.QueueMode.QUEUE, disableSpeak);
-
- // If our activeElement is on body, try to sync to the first element. This
- // actually happens inside of NavigationManager.reset, which doesn't get
- // called until AbstractHost.onPageLoad, but we need to speak and braille the
- // initial node here.
- if (cvox.ChromeVox.documentHasFocus() &&
- document.activeElement == document.body) {
- cvox.ChromeVox.navigationManager.syncToBeginning();
- }
-
- // If we had a previous position recorded, update to it.
- if (cvox.ChromeVox.position[document.location.href]) {
- var pos = cvox.ChromeVox.position[document.location.href];
- cvox.ChromeVox.navigationManager.updateSelToArbitraryNode(
- document.elementFromPoint(pos.x, pos.y));
- }
-
- // If this iframe has focus, speak and braille the current focused element.
- if (cvox.ChromeVox.documentHasFocus()) {
- if (!disableSpeak) {
- cvox.ChromeVoxEventSuspender.withSuspendedEvents(function() {
- cvox.ChromeVox.navigationManager.finishNavCommand(
- '', true, cvox.QueueMode.QUEUE);
- })();
- }
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/keyboard_handler.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/keyboard_handler.js
deleted file mode 100644
index d9b8aeb8159..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/keyboard_handler.js
+++ /dev/null
@@ -1,131 +0,0 @@
-// 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.
-
-goog.provide('cvox.ChromeVoxKbHandler');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxUserCommands');
-goog.require('cvox.History');
-goog.require('cvox.KeyMap');
-goog.require('cvox.KeySequence');
-goog.require('cvox.KeyUtil');
-goog.require('cvox.KeyboardHelpWidget');
-
-/**
- * @fileoverview Handles user keyboard input events.
- *
- */
-cvox.ChromeVoxKbHandler = {};
-
-/**
- * The key map
- *
- * @type {cvox.KeyMap}
- */
-cvox.ChromeVoxKbHandler.handlerKeyMap;
-
-/**
- * Loads the key bindings into the keyToFunctionsTable.
- *
- * @param {string} keyToFunctionsTable The key bindings table in JSON form.
- */
-cvox.ChromeVoxKbHandler.loadKeyToFunctionsTable = function(
- keyToFunctionsTable) {
- if (!window.JSON) {
- return;
- }
-
- cvox.ChromeVoxKbHandler.handlerKeyMap =
- cvox.KeyMap.fromJSON(keyToFunctionsTable);
-};
-
-/**
- * Converts the key bindings table into an array that is sorted by the lengths
- * of the key bindings. After the sort, the key bindings that describe single
- * keys will come before the key bindings that describe multiple keys.
- * @param {Object<string>} keyToFunctionsTable Contains each key binding and its
- * associated function name.
- * @return {Array<Array<string>>} The sorted key bindings table in
- * array form. Each entry in the array is itself an array containing the
- * key binding and its associated function name.
- * @private
- */
-cvox.ChromeVoxKbHandler.sortKeyToFunctionsTable_ = function(
- keyToFunctionsTable) {
- var sortingArray = [];
-
- for (var keySeqStr in keyToFunctionsTable) {
- sortingArray.push([keySeqStr, keyToFunctionsTable[keySeqStr]]);
- }
-
- function compareKeyStr(a, b) {
- // Compare the lengths of the key bindings.
- if (a[0].length < b[0].length) {
- return -1;
- } else if (b[0].length < a[0].length) {
- return 1;
- } else {
- // The keys are the same length. Sort lexicographically.
- return a[0].localeCompare(b[0]);
- }
- };
-
- sortingArray.sort(compareKeyStr);
- return sortingArray;
-};
-
-
-/**
- * Handles key down events.
- *
- * @param {Event} evt The key down event to process.
- * @return {boolean} True if the default action should be performed.
- */
-cvox.ChromeVoxKbHandler.basicKeyDownActionsListener = function(evt) {
- var keySequence = cvox.KeyUtil.keyEventToKeySequence(evt);
- var functionName;
- if (cvox.ChromeVoxKbHandler.handlerKeyMap != undefined) {
- functionName =
- cvox.ChromeVoxKbHandler.handlerKeyMap.commandForKey(keySequence);
- } else {
- functionName = null;
- }
-
- // TODO (clchen): Disambiguate why functions are null. If the user pressed
- // something that is not a valid combination, make an error noise so there
- // is some feedback.
-
- if (!functionName) {
- return !cvox.KeyUtil.sequencing;
- }
-
- // If ChromeVox isn't active, ignore every command except the one
- // to toggle ChromeVox active again.
- if (!cvox.ChromeVox.isActive && functionName != 'toggleChromeVox') {
- return true;
- }
-
- // This is the key event handler return value - true if the event should
- // propagate and the default action should be performed, false if we eat
- // the key.
- var returnValue = true;
-
- var func = cvox.ChromeVoxUserCommands.commands[functionName];
- if (func) {
- var history = cvox.History.getInstance();
- history.enterUserCommand(functionName);
- returnValue = func();
- history.exitUserCommand(functionName);
- } else if (keySequence.cvoxModifier) {
- // Modifier/prefix is active -- prevent default action
- returnValue = false;
- }
-
- // If the whole document is hidden from screen readers, let the app
- // catch keys as well.
- if (cvox.ChromeVox.entireDocumentIsHidden) {
- returnValue = true;
- }
- return returnValue;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/live_regions.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/live_regions.js
deleted file mode 100644
index 3eedf086ab7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/live_regions.js
+++ /dev/null
@@ -1,450 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Keeps track of live regions on the page and speaks updates
- * when they change.
- *
- */
-
-goog.provide('cvox.LiveRegions');
-
-goog.require('cvox.AriaUtil');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.DescriptionUtil');
-goog.require('cvox.DomUtil');
-goog.require('cvox.Interframe');
-goog.require('cvox.NavDescription');
-goog.require('cvox.NavigationSpeaker');
-
-/**
- * @constructor
- */
-cvox.LiveRegions = function() {
-};
-
-/**
- * @type {Date}
- */
-cvox.LiveRegions.pageLoadTime = null;
-
-/**
- * Time in milliseconds after initial page load to ignore live region
- * updates, to avoid announcing regions as they're initially created.
- * The exception is alerts, they're announced when a page is loaded.
- * @type {number}
- * @const
- */
-cvox.LiveRegions.INITIAL_SILENCE_MS = 2000;
-
-/**
- * Time in milliseconds to wait for a node to become visible after a
- * mutation. Needed to allow live regions to fade in and have an initial
- * opacity of zero.
- * @type {number}
- * @const
- */
-cvox.LiveRegions.VISIBILITY_TIMEOUT_MS = 50;
-
-/**
- * A mapping from announced text to the time it was last spoken.
- * @type {Object<Date>}
- */
-cvox.LiveRegions.lastAnnouncedMap = {};
-
-/**
- * Maximum time interval in which to discard duplicate live region announcement.
- * @type {number}
- * @const
- */
-cvox.LiveRegions.MAX_DISCARD_DUPS_MS = 2000;
-
-/**
- * @type {Date}
-*/
-cvox.LiveRegions.lastAnnouncedTime = null;
-
-/**
- * Tracks nodes handled during mutation processing.
- * @type {!Array<Node>}
- */
-cvox.LiveRegions.nodesAlreadyHandled = [];
-
-/**
- * @param {Date} pageLoadTime The time the page was loaded. Live region
- * updates within the first INITIAL_SILENCE_MS milliseconds are ignored.
- * @param {cvox.QueueMode} queueMode Interrupt or flush. Polite live region
- * changes always queue.
- * @param {boolean} disableSpeak true if change announcement should be disabled.
- * @return {boolean} true if any regions announced.
- */
-cvox.LiveRegions.init = function(pageLoadTime, queueMode, disableSpeak) {
- cvox.LiveRegions.pageLoadTime = pageLoadTime;
-
- if (disableSpeak || !cvox.ChromeVox.documentHasFocus()) {
- return false;
- }
-
- // Speak any live regions already on the page. The logic below will
- // make sure that only alerts are actually announced.
- var anyRegionsAnnounced = false;
- var regions = cvox.AriaUtil.getLiveRegions(document.body);
- for (var i = 0; i < regions.length; i++) {
- cvox.LiveRegions.handleOneChangedNode(
- regions[i],
- regions[i],
- false,
- false,
- function(assertive, navDescriptions) {
- if (!assertive && queueMode == cvox.QueueMode.FLUSH) {
- queueMode = cvox.QueueMode.QUEUE;
- }
- var descSpeaker = new cvox.NavigationSpeaker();
- descSpeaker.speakDescriptionArray(navDescriptions, queueMode, null);
- anyRegionsAnnounced = true;
- });
- }
-
- cvox.Interframe.addListener(function(message) {
- if (message['command'] != 'speakLiveRegion') {
- return;
- }
- var iframes = document.getElementsByTagName('iframe');
- for (var i = 0, iframe; iframe = iframes[i]; i++) {
- if (iframe.src == message['src']) {
- if (!cvox.DomUtil.isVisible(iframe)) {
- return;
- }
- var structs = JSON.parse(message['content']);
- var descriptions = [];
- for (var j = 0, description; description = structs[j]; j++) {
- descriptions.push(new cvox.NavDescription(description));
- }
- new cvox.NavigationSpeaker()
- .speakDescriptionArray(descriptions, message['queueMode'], null);
- }
- }
- });
-
- return anyRegionsAnnounced;
-};
-
-/**
- * See if any mutations pertain to a live region, and speak them if so.
- *
- * This function is not reentrant, it uses some global state to keep
- * track of nodes it's already spoken once.
- *
- * @param {Array<MutationRecord>} mutations The mutations.
- * @param {function(boolean, Array<cvox.NavDescription>)} handler
- * A callback function that handles each live region description found.
- * The function is passed a boolean indicating if the live region is
- * assertive, and an array of navdescriptions to speak.
- */
-cvox.LiveRegions.processMutations = function(mutations, handler) {
- cvox.LiveRegions.nodesAlreadyHandled = [];
- mutations.forEach(function(mutation) {
- if (mutation.target.hasAttribute &&
- mutation.target.hasAttribute('cvoxIgnore')) {
- return;
- }
- if (mutation.addedNodes) {
- for (var i = 0; i < mutation.addedNodes.length; i++) {
- if (mutation.addedNodes[i].hasAttribute &&
- mutation.addedNodes[i].hasAttribute('cvoxIgnore')) {
- continue;
- }
- cvox.LiveRegions.handleOneChangedNode(
- mutation.addedNodes[i], mutation.target, false, true, handler);
- }
- }
- if (mutation.removedNodes) {
- for (var i = 0; i < mutation.removedNodes.length; i++) {
- if (mutation.removedNodes[i].hasAttribute &&
- mutation.removedNodes[i].hasAttribute('cvoxIgnore')) {
- continue;
- }
- cvox.LiveRegions.handleOneChangedNode(
- mutation.removedNodes[i], mutation.target, true, false, handler);
- }
- }
- if (mutation.type == 'characterData') {
- cvox.LiveRegions.handleOneChangedNode(
- mutation.target, mutation.target, false, false, handler);
- }
- if (mutation.attributeName == 'class' ||
- mutation.attributeName == 'style' ||
- mutation.attributeName == 'hidden') {
- var attr = mutation.attributeName;
- var target = mutation.target;
- var newInvisible = !cvox.DomUtil.isVisible(target);
-
- // Create a fake element on the page with the old values of
- // class, style, and hidden for this element, to see if that test
- // element would have had different visibility.
- var testElement = document.createElement('div');
- testElement.setAttribute('cvoxIgnore', '1');
- testElement.setAttribute('class', target.getAttribute('class'));
- testElement.setAttribute('style', target.getAttribute('style'));
- testElement.setAttribute('hidden', target.getAttribute('hidden'));
- testElement.setAttribute(attr, /** @type {string} */ (mutation.oldValue));
-
- var oldInvisible = true;
- if (target.parentElement) {
- target.parentElement.appendChild(testElement);
- oldInvisible = !cvox.DomUtil.isVisible(testElement);
- target.parentElement.removeChild(testElement);
- } else {
- oldInvisible = !cvox.DomUtil.isVisible(testElement);
- }
-
- if (oldInvisible === true && newInvisible === false) {
- cvox.LiveRegions.handleOneChangedNode(
- mutation.target, mutation.target, false, true, handler);
- } else if (oldInvisible === false && newInvisible === true) {
- cvox.LiveRegions.handleOneChangedNode(
- mutation.target, mutation.target, true, false, handler);
- }
- }
- });
- cvox.LiveRegions.nodesAlreadyHandled.length = 0;
-};
-
-/**
- * Handle one changed node. First check if this node is itself within
- * a live region, and if that fails see if there's a live region within it
- * and call this method recursively. For each actual live region, call a
- * method to recursively announce all changes.
- *
- * @param {Node} node A node that's changed.
- * @param {Node} parent The parent node.
- * @param {boolean} isRemoval True if this node was removed.
- * @param {boolean} subtree True if we should check the subtree.
- * @param {function(boolean, Array<cvox.NavDescription>)} handler
- * Callback function to be called for each live region found.
- */
-cvox.LiveRegions.handleOneChangedNode = function(
- node, parent, isRemoval, subtree, handler) {
- var liveRoot = isRemoval ? parent : node;
- if (!(liveRoot instanceof Element)) {
- liveRoot = liveRoot.parentElement;
- }
- while (liveRoot) {
- if (cvox.AriaUtil.getAriaLive(liveRoot)) {
- break;
- }
- liveRoot = liveRoot.parentElement;
- }
- if (!liveRoot) {
- if (subtree && node != document.body) {
- var subLiveRegions = cvox.AriaUtil.getLiveRegions(node);
- for (var i = 0; i < subLiveRegions.length; i++) {
- cvox.LiveRegions.handleOneChangedNode(
- subLiveRegions[i], parent, isRemoval, false, handler);
- }
- }
- return;
- }
-
- // If the page just loaded and this is any region type other than 'alert',
- // skip it. Alerts are the exception, they're announced on page load.
- var deltaTime = new Date() - cvox.LiveRegions.pageLoadTime;
- if (cvox.AriaUtil.getRoleAttribute(liveRoot) != 'alert' &&
- deltaTime < cvox.LiveRegions.INITIAL_SILENCE_MS) {
- return;
- }
-
- if (cvox.LiveRegions.nodesAlreadyHandled.indexOf(node) >= 0) {
- return;
- }
- cvox.LiveRegions.nodesAlreadyHandled.push(node);
-
- if (cvox.AriaUtil.getAriaBusy(liveRoot)) {
- return;
- }
-
- if (isRemoval) {
- if (!cvox.AriaUtil.getAriaRelevant(liveRoot, 'removals')) {
- return;
- }
- } else {
- if (!cvox.AriaUtil.getAriaRelevant(liveRoot, 'additions')) {
- return;
- }
- }
-
- cvox.LiveRegions.announceChangeIfVisible(node, liveRoot, isRemoval, handler);
-};
-
-/**
- * Announce one node within a live region if it's visible.
- * In order to handle live regions that fade in, if the node isn't currently
- * visible, check again after a short timeout.
- *
- * @param {Node} node A node in a live region.
- * @param {Node} liveRoot The root of the live region this node is in.
- * @param {boolean} isRemoval True if this node was removed.
- * @param {function(boolean, Array<cvox.NavDescription>)} handler
- * Callback function to be called for each live region found.
- */
-cvox.LiveRegions.announceChangeIfVisible = function(
- node, liveRoot, isRemoval, handler) {
- if (cvox.DomUtil.isVisible(liveRoot)) {
- cvox.LiveRegions.announceChange(node, liveRoot, isRemoval, handler);
- } else {
- window.setTimeout(function() {
- if (cvox.DomUtil.isVisible(liveRoot)) {
- cvox.LiveRegions.announceChange(node, liveRoot, isRemoval, handler);
- }
- }, cvox.LiveRegions.VISIBILITY_TIMEOUT_MS);
- }
-};
-
-/**
- * Announce one node within a live region.
- *
- * @param {Node} node A node in a live region.
- * @param {Node} liveRoot The root of the live region this node is in.
- * @param {boolean} isRemoval True if this node was removed.
- * @param {function(boolean, Array<cvox.NavDescription>)} handler
- * Callback function to be called for each live region found.
- */
-cvox.LiveRegions.announceChange = function(
- node, liveRoot, isRemoval, handler) {
- // If this node is in an atomic container, announce the whole container.
- // This includes aria-atomic, but also ARIA controls and other nodes
- // whose ARIA roles make them leaves.
- if (node != liveRoot) {
- var atomicContainer = node.parentElement;
- while (atomicContainer) {
- if ((cvox.AriaUtil.getAriaAtomic(atomicContainer) ||
- cvox.AriaUtil.isLeafElement(atomicContainer) ||
- cvox.AriaUtil.isControlWidget(atomicContainer)) &&
- !cvox.AriaUtil.isCompositeControl(atomicContainer)) {
- node = atomicContainer;
- }
- if (atomicContainer == liveRoot) {
- break;
- }
- atomicContainer = atomicContainer.parentElement;
- }
- }
-
- var navDescriptions = cvox.LiveRegions.getNavDescriptionsRecursive(node);
- if (isRemoval) {
- navDescriptions = [cvox.DescriptionUtil.getDescriptionFromAncestors(
- [node], true, cvox.ChromeVox.verbosity)];
- navDescriptions = [new cvox.NavDescription({
- context: Msgs.getMsg('live_regions_removed'), text: ''
- })].concat(navDescriptions);
- }
-
- if (navDescriptions.length == 0) {
- return;
- }
-
- // Don't announce alerts on page load if their text and values consist of
- // just whitespace.
- var deltaTime = new Date() - cvox.LiveRegions.pageLoadTime;
- if (cvox.AriaUtil.getRoleAttribute(liveRoot) == 'alert' &&
- deltaTime < cvox.LiveRegions.INITIAL_SILENCE_MS) {
- var regionText = '';
- for (var i = 0; i < navDescriptions.length; i++) {
- regionText += navDescriptions[i].text;
- regionText += navDescriptions[i].userValue;
- }
- if (cvox.DomUtil.collapseWhitespace(regionText) == '') {
- return;
- }
- }
-
- // First, evict expired entries.
- var now = new Date();
- for (var announced in cvox.LiveRegions.lastAnnouncedMap) {
- if (now - cvox.LiveRegions.lastAnnouncedMap[announced] >
- cvox.LiveRegions.MAX_DISCARD_DUPS_MS) {
- delete cvox.LiveRegions.lastAnnouncedMap[announced];
- }
- }
-
- // Then, skip announcement if it was already spoken in the past 2000 ms.
- var key = navDescriptions.reduce(function(prev, navDescription) {
- return prev + '|' + navDescription.text;
- }, '');
-
- if (cvox.LiveRegions.lastAnnouncedMap[key]) {
- return;
- }
- cvox.LiveRegions.lastAnnouncedMap[key] = now;
-
- var assertive = cvox.AriaUtil.getAriaLive(liveRoot) == 'assertive';
- if (cvox.Interframe.isIframe() && !cvox.ChromeVox.documentHasFocus()) {
- cvox.Interframe.sendMessageToParentWindow(
- {'command': 'speakLiveRegion',
- 'content': JSON.stringify(navDescriptions),
- 'queueMode': assertive ? 0 : 1,
- 'src': window.location.href }
- );
- return;
- }
-
- // Set a category on the NavDescriptions - that way live regions
- // interrupt other live regions but not anything else.
- navDescriptions.forEach(function(desc) {
- if (!desc.category) {
- desc.category = cvox.TtsCategory.LIVE;
- }
- });
-
- // TODO(dmazzoni): http://crbug.com/415679 Temporary design decision;
- // until we have a way to tell the speech queue to group the nav
- // descriptions together, collapse them into one.
- // Otherwise, one nav description could be spoken, then something unrelated,
- // then the rest.
- if (navDescriptions.length > 1) {
- var allStrings = [];
- navDescriptions.forEach(function(desc) {
- if (desc.context) {
- allStrings.push(desc.context);
- }
- if (desc.text) {
- allStrings.push(desc.text);
- }
- if (desc.userValue) {
- allStrings.push(desc.userValue);
- }
- });
- navDescriptions = [new cvox.NavDescription({
- text: allStrings.join(', '),
- category: cvox.TtsCategory.LIVE
- })];
- }
-
- handler(assertive, navDescriptions);
-};
-
-/**
- * Recursively build up the value of a live region and return it as
- * an array of NavDescriptions. Each atomic portion of the region gets a
- * single string, otherwise each leaf node gets its own string.
- *
- * @param {Node} node A node in a live region.
- * @return {Array<cvox.NavDescription>} An array of NavDescriptions
- * describing atomic nodes or leaf nodes in the subtree rooted
- * at this node.
- */
-cvox.LiveRegions.getNavDescriptionsRecursive = function(node) {
- if (cvox.AriaUtil.getAriaAtomic(node) ||
- cvox.DomUtil.isLeafNode(node)) {
- var description = cvox.DescriptionUtil.getDescriptionFromAncestors(
- [node], true, cvox.ChromeVox.verbosity);
- if (!description.isEmpty()) {
- return [description];
- } else {
- return [];
- }
- }
- return cvox.DescriptionUtil.getFullDescriptionsFromChildren(null,
- /** @type {!Element} */ (node));
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/live_regions_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/live_regions_test.unitjs
deleted file mode 100644
index e43e82a4200..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/live_regions_test.unitjs
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Include test fixture.
-GEN_INCLUDE(['../../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxLiveRegionsUnitTest() {
- ChromeVoxUnitTestBase.call(this);
-}
-
-CvoxLiveRegionsUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- isAsync: true,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ChromeVoxTester',
- 'cvox.SpokenListBuilder',
- ],
-
- /** @override */
- setUp: function() {
- cvox.ChromeVoxTester.setUp(document);
- },
-
- /** @override */
- tearDown: function() {
- cvox.ChromeVoxTester.tearDown(document);
- }
-};
-
-TEST_F('CvoxLiveRegionsUnitTest', 'InsertNonLiveRegion', function() {
- var region = document.createElement('div');
- region.innerHTML = '<div role="button">Alpha</div>';
- document.body.appendChild(region);
-
- this.waitForCalm(function() {
- assertEquals(0, cvox.ChromeVoxTester.getUtteranceList().length);
- });
-});
-
-
-/**
- * Test inserting an 'alert' live region.
- */
-// Flaky on Chromium OS: crbug.com/498881.
-TEST_F('CvoxLiveRegionsUnitTest', 'DISABLED_InsertAlertLiveRegion', function() {
- var region = document.createElement('div');
- region.innerHTML = '<div role="alert">Alpha</div>';
- document.body.appendChild(region);
-
- this.waitForCalm(function() {
- var utterances = cvox.ChromeVoxTester.getUtteranceList();
- assertEquals('Alpha', utterances[0]);
- assertEquals('Alert', utterances[1]);
- });
-});
-
-
-/**
- * Test making text appear inside an 'alert' live region by setting its
- * display to something other than 'none'.
- */
-TEST_F('CvoxLiveRegionsUnitTest', 'RevealAlertLiveRegion', function() {
- this.loadDoc(function() {/*!
- <div role="alert">
- <style>
- .invisible {
- display: none;
- }
- </style>
- <div id="mymessage" class="invisible">
- I just appeared!
- </div>
- </div>
- */});
- $('mymessage').className = '';
-
- this.waitForCalm(function() {
- var utterances = cvox.ChromeVoxTester.getUtteranceList();
- assertEquals('I just appeared!', utterances[0]);
- });
-});
-
-
-/**
- * Test inserting a 'polite' live region.
- */
-// Flaky on Chromium OS: crbug.com/498881.
-TEST_F('CvoxLiveRegionsUnitTest', 'DISABLED_InsertPoliteLiveRegion', function() {
- var region = document.createElement('div');
- region.innerHTML = '<div aria-live="polite">Beta</div>';
- document.body.appendChild(region);
-
- this.waitForCalm(function() {
- var utterances = cvox.ChromeVoxTester.getUtteranceList();
- assertEquals('Beta', utterances[0]);
- });
-});
-
-
-/**
- * Test modifying an existing status live region.
- */
-TEST_F('CvoxLiveRegionsUnitTest', 'ModifyStatusLiveRegion', function() {
- var region = document.createElement('div');
- region.innerHTML = '<div id="status" role="status">Gamma</div>';
- document.body.appendChild(region);
-
- this.waitForCalm(function() {
- $('status').innerText = 'Delta';
- // Wait for this to make it through the event queue and
- // trigger the live region change announcement.
- this.waitForCalm(function() {
- var utterances = cvox.ChromeVoxTester.getUtteranceList();
- assertEquals('Delta', utterances[utterances.length - 1]);
- });
- });
-});
-
-
-/**
- * Test adding element to a atomic and non-atomic live regions.
- */
-TEST_F('CvoxLiveRegionsUnitTest', 'AddToLiveRegion', function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="non_atomic_buddylist" aria-live="polite">
- <div>Larry</div>
- <div>Sergey</div>
- </div>
- <div id="atomic_buddylist" aria-live="polite" aria-atomic="true">
- <div>Larry</div>
- <div>Sergey</div>
- </div>
- </div>
- */});
-
- this.waitForCalm(function() {
- var eric1 = document.createElement('div');
- eric1.innerHTML = 'Eric';
- $('non_atomic_buddylist').appendChild(eric1);
- var eric2 = document.createElement('div');
- eric2.innerHTML = 'Eric';
- $('atomic_buddylist').appendChild(eric2);
- this.waitForCalm(function() {
- var utterances = cvox.ChromeVoxTester.getUtteranceList();
- assertEquals('Eric', utterances[utterances.length - 2]);
- assertEquals('Larry Sergey Eric', utterances[utterances.length - 1]);
- });
- });
-});
-
-/**
- * Test removing elements from live regions.
- */
-// Flaky on Chromium OS: crbug.com/498881.
-TEST_F('CvoxLiveRegionsUnitTest', 'DISABLED_RemoveFromLiveRegion', function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="buddylist2" aria-relevant="removals">
- <div id="jack">Jack</div>
- <div id="janet">Janet</div>
- <div id="chrissy">Chrissy</div>
- </div>
- </div>
- */});
-
- $('buddylist2').setAttribute('aria-live', 'polite');
- $('buddylist2').removeChild($('jack'));
- this.waitForCalm(function() {
- var utterances = cvox.ChromeVoxTester.getUtteranceList();
- assertEquals(1, utterances.length);
- assertEquals('removed:, Jack', utterances[0]);
- });
-});
-
-
-/**
- * Test live region that's a progress bar through the event watcher.
- */
-TEST_F('CvoxLiveRegionsUnitTest', 'ProgressBarLiveRegionEvents', function() {
- this.loadDoc(function() {/*!
- <div id="progress" role="progressbar" aria-live="polite" aria-valuenow="1">
- <div id="ptext">
- 1% complete.
- </div>
- </div>
- */});
-
- $('progress').setAttribute('aria-valuenow', '2');
- $('ptext').innerText = '2% complete';
- this.waitForCalm(function() {
- var utterances = cvox.ChromeVoxTester.getUtteranceList();
- assertEquals('Progress bar 2', utterances[utterances.length - 1]);
- });
-});
-
-
-/**
- * Test 'alert' live region inserted as a result of focus change, like
- * when there's an error message when filling out a form.
- */
-TEST_F('CvoxLiveRegionsUnitTest', 'FocusTriggeredAlertLiveRegion', function() {
- this.loadDoc(function() {/*!
- <form id="form">
- <label>
- Name
- <input id="name">
- </label>
- <label>
- Address
- <input id="address">
- </label>
- </form>
- */});
-
- // Suppress EventWatcher's artificial limit on the number of DOM subtree
- // modified events that can happen in a row.
- cvox.ChromeVoxEventWatcher.SUBTREE_MODIFIED_BURST_COUNT_LIMIT_ = 999;
-
- var form = $('form');
- var name = $('name');
- var address = $('address');
-
- name.addEventListener(
- 'blur',
- function() {
- var region = document.createElement('div');
- region.innerHTML = '<div role="alert">Not a valid name!</div>';
- form.appendChild(region);
- }, false);
-
- this.waitForCalm(function() { name.focus(); })
- .waitForCalm(function() { address.focus(); })
- .waitForCalm(this.assertSpokenList,
- new cvox.SpokenListBuilder()
- .categoryFlush('Name')
- .queue('Edit text')
- .categoryFlush('Address')
- .queue('Edit text')
- .categoryFlush('Not a valid name!')
- .queue('Alert'));
-});
-
-
-/**
- * Test focus followed by live region change, make sure both are spoken.
- */
-// Flaky on Chromium OS: crbug.com/498881.
-TEST_F('CvoxLiveRegionsUnitTest', 'DISABLED_FocusThenLiveRegion', function() {
- this.loadDoc(function() {/*!
- <button id="button_to_focus">Button To Focus</button>
- <div id="live" aria-live="polite"></div>
- */});
-
- $('button_to_focus').focus();
- $('live').innerText = 'Live region text';
-
- this.waitForCalm(this.assertSpokenList,
- new cvox.SpokenListBuilder()
- .categoryFlush('Button To Focus')
- .queue('Button')
- .categoryFlush('Live region text'));
-});
-
-
-/**
- * Test live region change followed by focus, make sure both are spoken.
- */
-// Flaky on Chromium OS: crbug.com/498881.
-TEST_F('CvoxLiveRegionsUnitTest', 'DISABLED_LiveRegionThenFocus', function() {
- this.loadDoc(function() {/*!
- <button id="button_to_focus">Button To Focus</button>
- <div id="live" aria-live="polite"></div>
- */});
-
- $('live').innerText = 'Live region text';
-
- this.waitForCalm(function() {
- $('button_to_focus').focus();
- })
- .waitForCalm(this.assertSpokenList,
- new cvox.SpokenListBuilder()
- .categoryFlush('Live region text')
- .categoryFlush('Button To Focus')
- .queue('Button'));
-});
-
-
-/**
- * Two elements inside a live region. These are all combined into
- * one utterance until this bug is fixed: http://crbug.com/415679
- */
-// Flaky on Chromium OS: crbug.com/498881.
-TEST_F('CvoxLiveRegionsUnitTest', 'DISABLED_TwoElementsInLiveRegion', function() {
- this.loadDoc(function() {/*!
- <div id="live" aria-live="polite">
- <div id="hidden" style="display:none">
- <button>L1</button>
- <button>L2</button>
- </div>
- </div>
- */});
-
- $('hidden').style.display = 'block';
- this.waitForCalm(this.assertSpokenList,
- new cvox.SpokenListBuilder()
- .categoryFlush('L1, L2'));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/loader.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/loader.js
deleted file mode 100644
index bdd683f2ae6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/loader.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Defines the ChromeVox app.
- */
-
-window.CLOSURE_USE_EXT_MESSAGES = true;
-
-goog.require('Msgs');
-goog.require('cvox.ChromeBraille');
-goog.require('cvox.ChromeEarcons');
-goog.require('cvox.ChromeHost');
-goog.require('cvox.ChromeMathJax');
-goog.require('cvox.ChromeTts');
-goog.require('cvox.ChromeVoxInit');
-
-if (COMPILED) {
- // NOTE(deboer): This is called when this script is loaded, automatically
- // starting ChromeVox. If this isn't the compiled script, it will be
- // called in init_document.js.
- cvox.ChromeVox.initDocument();
-}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_history.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_history.js
deleted file mode 100644
index 968564cdc27..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_history.js
+++ /dev/null
@@ -1,185 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Navigation history tracks recently visited nodes. The
- * state of this class (the node history), is used to ensure the user is
- * navigating to and from valid nodes.
- * NOTE: The term "valid node" is simply a heuristic, defined in isValidNode_.
- *
- */
-
-
-goog.provide('cvox.NavigationHistory');
-
-goog.require('cvox.DomUtil');
-
-
-/**
- * @constructor
- */
-cvox.NavigationHistory = function() {
- this.reset_();
-};
-
-
-/**
- * The maximum length of history tracked for recently visited nodes.
- * @const
- * @type {number}
- * @private
- */
-cvox.NavigationHistory.MAX_HISTORY_LEN_ = 30;
-
-
-/**
- * Resets the navigation history.
- * @private
- */
-cvox.NavigationHistory.prototype.reset_ = function() {
- var startNode = document.body;
-
- /**
- * An array of nodes ordered from newest to oldest in the history.
- * The most recent nodes are at the start of the array.
- * @type {Array<Node>}
- * @private
- */
- this.history_ = [startNode];
-
- /**
- * A flag to keep track of whether the last node added to the history was
- * valid or not. If false, something strange might be going on, and we
- * can react to this in the code.
- * @type {boolean}
- * @private
- */
- this.arrivedValid_ = true;
-
-};
-
-
-/**
- * Update the navigation history with the current element.
- * The most recent elements are at the start of the array.
- * @param {Node} newNode The new node to update the history with.
- */
-cvox.NavigationHistory.prototype.update = function(newNode) {
- var previousNode = this.history_[0];
-
- // Avoid pushing consecutive duplicate elements.
- if (newNode && newNode != previousNode) {
- this.history_.unshift(newNode);
- }
-
- // If list is too long, pop the last (oldest) item.
- if (this.history_.length >
- cvox.NavigationHistory.MAX_HISTORY_LEN_) {
- this.history_.pop();
- }
-
- // Check if the node is valid upon arrival. If not, set a flag because
- // something fishy is probably going on.
- this.arrivedValid_ = this.isValidNode_(newNode);
-};
-
-
-/**
- * Routinely clean out history and determine if the given node has become
- * invalid since we arrived there (during the update call). If the node
- * was already invalid, we will return false.
- * @param {Node} node The node to check for validity change.
- * @return {boolean} True if node changed state to invalid.
- */
-cvox.NavigationHistory.prototype.becomeInvalid = function(node) {
- // Remove any invalid nodes from history_.
- this.clean_();
-
- // If node was somehow already invalid on arrival, the page was probably
- // changing very quickly. Be defensive here and allow the default
- // navigation action by returning true.
- if (!this.arrivedValid_) {
- this.arrivedValid_ = true; // Reset flag.
- return false;
- }
-
- // Run the validation method on the given node.
- return !this.isValidNode_(node);
-};
-
-
-/**
- * Determine a valid reversion for the current navigation track. A reversion
- * provides both a current node to sync to and a previous node as context.
- * @param {function(Node)=} opt_predicate A function that takes in a node and
- * returns true if it is a valid recovery candidate. Nodes that do not
- * match the predicate are removed as we search for a match. If no
- * predicate is provided, return the two most recent nodes.
- * @return {{current: ?Node, previous: ?Node}}
- * The two nodes to override default navigation behavior with. Returning
- * null or undefined means the history is empty.
- */
-cvox.NavigationHistory.prototype.revert = function(opt_predicate) {
- // If the currently active element is valid, it is probably the best
- // recovery target. Add it to the history before computing the reversion.
- var active = document.activeElement;
- if (active != document.body && this.isValidNode_(active)) {
- this.update(active);
- }
-
- // Remove the most-recent-nodes that do not match the predicate.
- if (opt_predicate) {
- while (this.history_.length > 0) {
- var node = this.history_[0];
- if (opt_predicate(node)) {
- break;
- }
- this.history_.shift();
- }
- }
-
- // The reversion is just the first two nodes in the history.
- return {current: this.history_[0], previous: this.history_[1]};
-};
-
-
-/**
- * Remove any and all nodes from history_ that are no longer valid.
- * @return {boolean} True if any changes were made to the history.
- * @private
- */
-cvox.NavigationHistory.prototype.clean_ = function() {
- var changed = false;
- for (var i = this.history_.length - 1; i >= 0; i--) {
- var valid = this.isValidNode_(this.history_[i]);
- if (!valid) {
- this.history_.splice(i, 1);
- changed = true;
- }
- }
- return changed;
-};
-
-
-/**
- * Determine if the given node is valid based on a heuristic.
- * A valid node must be attached to the DOM and visible.
- * @param {Node} node The node to validate.
- * @return {boolean} True if node is valid.
- * @private
- */
-cvox.NavigationHistory.prototype.isValidNode_ = function(node) {
- // Confirm that the element is in the DOM.
- if (!cvox.DomUtil.isAttachedToDocument(node)) {
- return false;
- }
-
- // TODO (adu): In the future we may change this to just let users know the
- // node is invisible instead of restoring focus.
- if (!cvox.DomUtil.isVisible(node)) {
- return false;
- }
-
- return true;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager.js
deleted file mode 100644
index a7ed82ff6d0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager.js
+++ /dev/null
@@ -1,1250 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Manages navigation within a page.
- * This unifies navigation by the DOM walker and by WebKit selection.
- * NOTE: the purpose of this class is only to hold state
- * and delegate all of its functionality to mostly stateless classes that
- * are easy to test.
- *
- */
-
-
-goog.provide('cvox.NavigationManager');
-
-goog.require('cvox.ActiveIndicator');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxEventSuspender');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.DescriptionUtil');
-goog.require('cvox.DomUtil');
-goog.require('cvox.FindUtil');
-goog.require('cvox.Focuser');
-goog.require('cvox.Interframe');
-goog.require('cvox.MathShifter');
-goog.require('cvox.NavBraille');
-goog.require('cvox.NavDescription');
-goog.require('cvox.NavigationHistory');
-goog.require('cvox.NavigationShifter');
-goog.require('cvox.NavigationSpeaker');
-goog.require('cvox.PageSelection');
-goog.require('cvox.SelectionUtil');
-goog.require('cvox.TableShifter');
-goog.require('cvox.TraverseMath');
-goog.require('cvox.Widget');
-
-
-/**
- * @constructor
- */
-cvox.NavigationManager = function() {
- this.addInterframeListener_();
-
- this.reset();
-
- this.iframeRetries_ = 0;
-};
-
-/**
- * Stores state variables in a provided object.
- *
- * @param {Object} store The object.
- */
-cvox.NavigationManager.prototype.storeOn = function(store) {
- store['reversed'] = this.isReversed();
- store['keepReading'] = this.keepReading_;
- store['findNext'] = this.predicate_;
- this.shifter_.storeOn(store);
-};
-
-/**
- * Updates the object with state variables from an earlier storeOn call.
- *
- * @param {Object} store The object.
- */
-cvox.NavigationManager.prototype.readFrom = function(store) {
- this.curSel_.setReversed(store['reversed']);
- this.shifter_.readFrom(store);
- this.keepReading_ = store['keepReading'];
-};
-
-/**
- * Resets the navigation manager to the top of the page.
- */
-cvox.NavigationManager.prototype.reset = function() {
- /**
- * @type {!cvox.NavigationSpeaker}
- * @private
- */
- this.navSpeaker_ = new cvox.NavigationSpeaker();
-
- /**
- * @type {!Array<Object>}
- * @private
- */
- this.shifterTypes_ = [cvox.NavigationShifter,
- cvox.TableShifter,
- cvox.MathShifter];
-
- /**
- * @type {!Array<!cvox.AbstractShifter>}
- */
- this.shifterStack_ = [];
-
- /**
- * The active shifter.
- * @type {!cvox.AbstractShifter}
- * @private
- */
- this.shifter_ = new cvox.NavigationShifter();
-
- // NOTE(deboer): document.activeElement can not be null (c.f.
- // https://developer.mozilla.org/en-US/docs/DOM/document.activeElement)
- // Instead, if there is no active element, activeElement is set to
- // document.body.
- /**
- * If there is an activeElement, use it. Otherwise, sync to the page
- * beginning.
- * @type {!cvox.CursorSelection}
- * @private
- */
- this.curSel_ = document.activeElement != document.body ?
- /** @type {!cvox.CursorSelection} */
- (cvox.CursorSelection.fromNode(document.activeElement)) :
- this.shifter_.begin(this.curSel_, {reversed: false});
-
- /**
- * @type {!cvox.CursorSelection}
- * @private
- */
- this.prevSel_ = this.curSel_.clone();
-
- /**
- * Keeps track of whether we have skipped while "reading from here"
- * so that we can insert an earcon.
- * @type {boolean}
- * @private
- */
- this.skipped_ = false;
-
- /**
- * Keeps track of whether we have recovered from dropped focus
- * so that we can insert an earcon.
- * @type {boolean}
- * @private
- */
- this.recovered_ = false;
-
- /**
- * True if in "reading from here" mode.
- * @type {boolean}
- * @private
- */
- this.keepReading_ = false;
-
- /**
- * True if we are at the end of the page and we wrap around.
- * @type {boolean}
- * @private
- */
- this.pageEnd_ = false;
-
- /**
- * True if we have already announced that we will wrap around.
- * @type {boolean}
- * @private
- */
- this.pageEndAnnounced_ = false;
-
- /**
- * True if we entered into a shifter.
- * @type {boolean}
- * @private
- */
- this.enteredShifter_ = false;
-
- /**
- * True if we exited a shifter.
- * @type {boolean}
- * @private
- */
- this.exitedShifter_ = false;
-
- /**
- * True if we want to ignore iframes no matter what.
- * @type {boolean}
- * @private
- */
- this.ignoreIframesNoMatterWhat_ = false;
-
- /**
- * @type {cvox.PageSelection}
- * @private
- */
- this.pageSel_ = null;
-
- /** @type {string} */
- this.predicate_ = '';
-
- /** @type {cvox.CursorSelection} */
- this.saveSel_ = null;
-
- // TODO(stoarca): This seems goofy. Why are we doing this?
- if (this.activeIndicator) {
- this.activeIndicator.removeFromDom();
- }
- this.activeIndicator = new cvox.ActiveIndicator();
-
- /**
- * Makes sure focus doesn't get lost.
- * @type {!cvox.NavigationHistory}
- * @private
- */
- this.navigationHistory_ = new cvox.NavigationHistory();
-
- /** @type {boolean} */
- this.focusRecovery_ = window.location.protocol != 'chrome:';
-
- this.iframeIdMap = {};
- this.nextIframeId = 1;
-
- // Only sync if the activeElement is not document.body; which is shorthand for
- // 'no selection'. Currently the walkers don't deal with the no selection
- // case -- and it is not clear that they should.
- if (document.activeElement != document.body) {
- this.sync();
- }
-
- // This object is effectively empty when no math is in the page.
- cvox.TraverseMath.getInstance();
-};
-
-
-/**
- * Determines if we are navigating from a valid node. If not, ask navigation
- * history for an acceptable restart point and go there.
- * @param {function(Node)=} opt_predicate A function that takes in a node and
- * returns true if it is a valid recovery candidate.
- * @return {boolean} True if we should continue navigation normally.
- */
-cvox.NavigationManager.prototype.resolve = function(opt_predicate) {
- if (!this.getFocusRecovery()) {
- return true;
- }
-
- var current = this.getCurrentNode();
-
- if (!this.navigationHistory_.becomeInvalid(current)) {
- return true;
- }
-
- // Only attempt to revert if going next will cause us to restart at the top
- // of the page.
- if (this.hasNext_()) {
- return true;
- }
-
- // Our current node was invalid. Revert to history.
- var revert = this.navigationHistory_.revert(opt_predicate);
-
- // If the history is empty, revert.current will be null. In that case,
- // it is best to continue navigating normally.
- if (!revert.current) {
- return true;
- }
-
- // Convert to selections.
- var newSel = cvox.CursorSelection.fromNode(revert.current);
- var context = cvox.CursorSelection.fromNode(revert.previous);
-
- // Default to document body if selections are null.
- newSel = newSel || cvox.CursorSelection.fromBody();
- context = context || cvox.CursorSelection.fromBody();
- newSel.setReversed(this.isReversed());
-
- this.updateSel(newSel, context);
- this.recovered_ = true;
- return false;
-};
-
-
-/**
- * Gets the state of focus recovery.
- * @return {boolean} True if focus recovery is on; false otherwise.
- */
-cvox.NavigationManager.prototype.getFocusRecovery = function() {
- return this.focusRecovery_;
-};
-
-
-/**
- * Enables or disables focus recovery.
- * @param {boolean} value True to enable, false to disable.
- */
-cvox.NavigationManager.prototype.setFocusRecovery = function(value) {
- this.focusRecovery_ = value;
-};
-
-
-/**
- * Delegates to NavigationShifter with current page state.
- * @param {boolean=} iframes Jump in and out of iframes if true. Default false.
- * @return {boolean} False if end of document has been reached.
- * @private
- */
-cvox.NavigationManager.prototype.next_ = function(iframes) {
- if (this.tryBoundaries_(this.shifter_.next(this.curSel_), iframes)) {
- // TODO(dtseng): An observer interface would help to keep logic like this
- // to a minimum.
- this.pageSel_ && this.pageSel_.extend(this.curSel_);
- return true;
- }
- return false;
-};
-
-/**
- * Looks ahead to see if it is possible to navigate forward from the current
- * position.
- * @return {boolean} True if it is possible to navigate forward.
- * @private
- */
-cvox.NavigationManager.prototype.hasNext_ = function() {
- // Non-default shifters validly end before page end.
- if (this.shifterStack_.length > 0) {
- return true;
- }
- var dummySel = this.curSel_.clone();
- var result = false;
- var dummyNavShifter = new cvox.NavigationShifter();
- dummyNavShifter.setGranularity(this.shifter_.getGranularity());
- dummyNavShifter.sync(dummySel);
- if (dummyNavShifter.next(dummySel)) {
- result = true;
- }
- return result;
-};
-
-
-/**
- * Delegates to NavigationShifter with current page state.
- * @param {function(Array<Node>)} predicate A function taking an array
- * of unique ancestor nodes as a parameter and returning a desired node.
- * It returns null if that node can't be found.
- * @param {string=} opt_predicateName The programmatic name that exists in
- * cvox.DomPredicates. Used to dispatch calls across iframes since functions
- * cannot be stringified.
- * @param {boolean=} opt_initialNode Whether to start the search from node
- * (true), or the next node (false); defaults to false.
- * @return {cvox.CursorSelection} The newly found selection.
- */
-cvox.NavigationManager.prototype.findNext = function(
- predicate, opt_predicateName, opt_initialNode) {
- this.predicate_ = opt_predicateName || '';
- this.resolve();
- this.shifter_ = this.shifterStack_[0] || this.shifter_;
- this.shifterStack_ = [];
- var ret = cvox.FindUtil.findNext(this.curSel_, predicate, opt_initialNode);
- if (!this.ignoreIframesNoMatterWhat_) {
- this.tryIframe_(ret && ret.start.node);
- }
- if (ret) {
- this.updateSelToArbitraryNode(ret.start.node);
- }
- this.predicate_ = '';
- return ret;
-};
-
-
-/**
- * Delegates to NavigationShifter with current page state.
- */
-cvox.NavigationManager.prototype.sync = function() {
- this.resolve();
- var ret = this.shifter_.sync(this.curSel_);
- if (ret) {
- this.curSel_ = ret;
- }
-};
-
-/**
- * Sync's all possible cursors:
- * - focus
- * - ActiveIndicator
- * - CursorSelection
- * @param {boolean=} opt_skipText Skips focus on text nodes; defaults to false.
- */
-cvox.NavigationManager.prototype.syncAll = function(opt_skipText) {
- this.sync();
- this.setFocus(opt_skipText);
- this.updateIndicator();
-};
-
-
-/**
- * Clears a DOM selection made via a CursorSelection.
- * @param {boolean=} opt_announce True to announce the clearing.
- * @return {boolean} If a selection was cleared.
- */
-cvox.NavigationManager.prototype.clearPageSel = function(opt_announce) {
- var hasSel = !!this.pageSel_;
- if (hasSel && opt_announce) {
- var announcement = Msgs.getMsg('clear_page_selection');
- cvox.ChromeVox.tts.speak(announcement, cvox.QueueMode.FLUSH,
- cvox.AbstractTts.PERSONALITY_ANNOTATION);
- }
- this.pageSel_ = null;
- return hasSel;
-};
-
-
-/**
- * Begins or finishes a DOM selection at the current CursorSelection in the
- * document.
- * @return {boolean} Whether selection is on or off after this call.
- */
-cvox.NavigationManager.prototype.togglePageSel = function() {
- this.pageSel_ = this.pageSel_ ? null :
- new cvox.PageSelection(this.curSel_.setReversed(false));
- return !!this.pageSel_;
-};
-
-
-// TODO(stoarca): getDiscription is split awkwardly between here and the
-// walkers. The walkers should have getBaseDescription() which requires
-// very little context, and then this method should tack on everything
-// which requires any extensive knowledge.
-/**
- * Delegates to NavigationShifter with the current page state.
- * @return {Array<cvox.NavDescription>} The summary of the current position.
- */
-cvox.NavigationManager.prototype.getDescription = function() {
- // Handle description of special content. Consider moving to DescriptionUtil.
- // Specially annotated nodes.
- if (this.getCurrentNode().hasAttribute &&
- this.getCurrentNode().hasAttribute('cvoxnodedesc')) {
- var preDesc = cvox.ChromeVoxJSON.parse(
- this.getCurrentNode().getAttribute('cvoxnodedesc'));
- var currentDesc = new Array();
- for (var i = 0; i < preDesc.length; ++i) {
- var inDesc = preDesc[i];
- // TODO: this can probably be replaced with just NavDescription(inDesc)
- // need test case to ensure this change will work
- currentDesc.push(new cvox.NavDescription({
- context: inDesc.context,
- text: inDesc.text,
- userValue: inDesc.userValue,
- annotation: inDesc.annotation
- }));
- }
- return currentDesc;
- }
-
- // Selected content.
- var desc = this.pageSel_ ? this.pageSel_.getDescription(
- this.shifter_, this.prevSel_, this.curSel_) :
- this.shifter_.getDescription(this.prevSel_, this.curSel_);
- var earcons = [];
-
- // Earcons.
- if (this.skipped_) {
- earcons.push(cvox.Earcon.SKIP);
- this.skipped_ = false;
- }
- if (this.recovered_) {
- earcons.push(cvox.Earcon.RECOVER_FOCUS);
- this.recovered_ = false;
- }
- if (this.pageEnd_) {
- earcons.push(cvox.Earcon.WRAP);
- this.pageEnd_ = false;
- }
- if (this.enteredShifter_) {
- earcons.push(cvox.Earcon.OBJECT_ENTER);
- this.enteredShifter_ = false;
- }
- if (this.exitedShifter_) {
- earcons.push(cvox.Earcon.OBJECT_EXIT);
- this.exitedShifter_ = false;
- }
- if (earcons.length > 0 && desc.length > 0) {
- earcons.forEach(function(earcon) {
- desc[0].pushEarcon(earcon);
- });
- }
- return desc;
-};
-
-
-/**
- * Delegates to NavigationShifter with the current page state.
- * @return {!cvox.NavBraille} The braille description.
- */
-cvox.NavigationManager.prototype.getBraille = function() {
- return this.shifter_.getBraille(this.prevSel_, this.curSel_);
-};
-
-/**
- * Delegates an action to the current walker.
- * @param {string} name Action name.
- * @return {boolean} True if action performed.
- */
-cvox.NavigationManager.prototype.performAction = function(name) {
- var newSel = null;
- switch (name) {
- case 'enterShifter':
- case 'enterShifterSilently':
- for (var i = this.shifterTypes_.length - 1, shifterType;
- shifterType = this.shifterTypes_[i];
- i--) {
- var shifter = shifterType.create(this.curSel_);
- if (shifter && shifter.getName() != this.shifter_.getName()) {
- this.shifterStack_.push(this.shifter_);
- this.shifter_ = shifter;
- this.sync();
- this.enteredShifter_ = name != 'enterShifterSilently';
- break;
- } else if (shifter && this.shifter_.getName() == shifter.getName()) {
- break;
- }
- }
- break;
- case 'exitShifter':
- if (this.shifterStack_.length == 0) {
- return false;
- }
- this.shifter_ = this.shifterStack_.pop();
- this.sync();
- this.exitedShifter_ = true;
- break;
- case 'exitShifterContent':
- if (this.shifterStack_.length == 0) {
- return false;
- }
- this.updateSel(this.shifter_.performAction(name, this.curSel_));
- this.shifter_ = this.shifterStack_.pop() || this.shifter_;
- this.sync();
- this.exitedShifter_ = true;
- break;
- default:
- if (this.shifter_.hasAction(name)) {
- return this.updateSel(
- this.shifter_.performAction(name, this.curSel_));
- } else {
- return false;
- }
- }
- return true;
-};
-
-
-/**
- * Returns the current navigation strategy.
- *
- * @return {string} The name of the strategy used.
- */
-cvox.NavigationManager.prototype.getGranularityMsg = function() {
- return this.shifter_.getGranularityMsg();
-};
-
-
-/**
- * Delegates to NavigationShifter.
- * @param {boolean=} opt_persist Persist the granularity to all running tabs;
- * defaults to true.
- */
-cvox.NavigationManager.prototype.makeMoreGranular = function(opt_persist) {
- this.shifter_.makeMoreGranular();
- this.sync();
- this.persistGranularity_(opt_persist);
-};
-
-
-/**
- * Delegates to current shifter.
- * @param {boolean=} opt_persist Persist the granularity to all running tabs;
- * defaults to true.
- */
-cvox.NavigationManager.prototype.makeLessGranular = function(opt_persist) {
- this.shifter_.makeLessGranular();
- this.sync();
- this.persistGranularity_(opt_persist);
-};
-
-
-/**
- * Delegates to navigation shifter. Behavior is not defined if granularity
- * was not previously gotten from a call to getGranularity(). This method is
- * only supported by NavigationShifter which exposes a random access
- * iterator-like interface. The caller has the option to force granularity
- which results in exiting any entered shifters. If not forced, and there has
- * been a shifter entered, setting granularity is a no-op.
- * @param {number} granularity The desired granularity.
- * @param {boolean=} opt_force Forces current shifter to NavigationShifter;
- * false by default.
- * @param {boolean=} opt_persist Persists setting to all running tabs; defaults
- * to false.
- */
-cvox.NavigationManager.prototype.setGranularity = function(
- granularity, opt_force, opt_persist) {
- if (!opt_force && this.shifterStack_.length > 0) {
- return;
- }
- this.shifter_ = this.shifterStack_.shift() || this.shifter_;
- this.shifters_ = [];
- this.shifter_.setGranularity(granularity);
- this.persistGranularity_(opt_persist);
-};
-
-
-/**
- * Delegates to NavigationShifter.
- * @return {number} The current granularity.
- */
-cvox.NavigationManager.prototype.getGranularity = function() {
- var shifter = this.shifterStack_[0] || this.shifter_;
- return shifter.getGranularity();
-};
-
-
-/**
- * Delegates to NavigationShifter.
- */
-cvox.NavigationManager.prototype.ensureSubnavigating = function() {
- if (!this.shifter_.isSubnavigating()) {
- this.shifter_.ensureSubnavigating();
- this.sync();
- }
-};
-
-
-/**
- * Stops subnavigating, specifying that we should navigate at a less granular
- * level than the current navigation strategy.
- */
-cvox.NavigationManager.prototype.ensureNotSubnavigating = function() {
- if (this.shifter_.isSubnavigating()) {
- this.shifter_.ensureNotSubnavigating();
- this.sync();
- }
-};
-
-
-/**
- * Delegates to NavigationSpeaker.
- * @param {Array<cvox.NavDescription>} descriptionArray The array of
- * NavDescriptions to speak.
- * @param {cvox.QueueMode} initialQueueMode The initial queue mode.
- * @param {Function} completionFunction Function to call when finished speaking.
- * @param {Object=} opt_personality Optional personality for all descriptions.
- * @param {string=} opt_category Optional category for all descriptions.
- */
-cvox.NavigationManager.prototype.speakDescriptionArray = function(
- descriptionArray,
- initialQueueMode,
- completionFunction,
- opt_personality,
- opt_category) {
- if (opt_personality) {
- descriptionArray.forEach(function(desc) {
- if (!desc.personality) {
- desc.personality = opt_personality;
- }
- });
- }
- if (opt_category) {
- descriptionArray.forEach(function(desc) {
- if (!desc.category) {
- desc.category = opt_category;
- }
- });
- }
-
- this.navSpeaker_.speakDescriptionArray(
- descriptionArray, initialQueueMode, completionFunction);
-};
-
-/**
- * Add the position of the node on the page.
- * @param {Node} node The node that ChromeVox should update the position.
- */
-cvox.NavigationManager.prototype.updatePosition = function(node) {
- var msg = cvox.ChromeVox.position;
- msg[document.location.href] =
- cvox.DomUtil.elementToPoint(node);
-
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'position',
- 'value': JSON.stringify(msg)
- });
-};
-
-
-// TODO(stoarca): The stuff below belongs in its own layer.
-/**
- * Perform all of the actions that should happen at the end of any
- * navigation operation: update the lens, play earcons, and speak the
- * description of the object that was navigated to.
- *
- * @param {string=} opt_prefix The string to be prepended to what
- * is spoken to the user.
- * @param {boolean=} opt_setFocus Whether or not to focus the current node.
- * Defaults to true.
- * @param {cvox.QueueMode=} opt_queueMode Initial queue mode to use.
- * @param {function(): ?=} opt_callback Function to call after speaking.
- */
-cvox.NavigationManager.prototype.finishNavCommand = function(
- opt_prefix, opt_setFocus, opt_queueMode, opt_callback) {
- if (this.pageEnd_ && !this.pageEndAnnounced_) {
- this.pageEndAnnounced_ = true;
- cvox.ChromeVox.tts.stop();
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP);
- if (cvox.ChromeVox.verbosity === cvox.VERBOSITY_VERBOSE) {
- var msg = Msgs.getMsg('wrapped_to_top');
- if (this.isReversed()) {
- msg = Msgs.getMsg('wrapped_to_bottom');
- }
- cvox.ChromeVox.tts.speak(msg, cvox.QueueMode.QUEUE,
- cvox.AbstractTts.PERSONALITY_ANNOTATION);
- }
- return;
- }
-
- if (this.enteredShifter_ || this.exitedShifter_) {
- opt_prefix = Msgs.getMsg('enter_content_say', [this.shifter_.getName()]);
- }
-
- var descriptionArray = cvox.ChromeVox.navigationManager.getDescription();
-
- opt_setFocus = opt_setFocus === undefined ? true : opt_setFocus;
-
- if (opt_setFocus) {
- this.setFocus();
- }
- this.updateIndicator();
-
- var queueMode = opt_queueMode || cvox.QueueMode.FLUSH;
-
- if (opt_prefix) {
- cvox.ChromeVox.tts.speak(
- opt_prefix, queueMode, cvox.AbstractTts.PERSONALITY_ANNOTATION);
- queueMode = cvox.QueueMode.QUEUE;
- }
- this.speakDescriptionArray(descriptionArray,
- queueMode,
- opt_callback || null,
- null,
- cvox.TtsCategory.NAV);
-
- cvox.ChromeVox.braille.write(this.getBraille());
-
- this.updatePosition(this.getCurrentNode());
-};
-
-
-/**
- * Moves forward. Stops any subnavigation.
- * @param {boolean=} opt_ignoreIframes Ignore iframes when navigating. Defaults
- * to not ignore iframes.
- * @param {number=} opt_granularity Optionally, switches to granularity before
- * navigation.
- * @return {boolean} False if end of document reached.
- */
-cvox.NavigationManager.prototype.navigate = function(
- opt_ignoreIframes, opt_granularity) {
- this.pageEndAnnounced_ = false;
- if (this.pageEnd_) {
- this.pageEnd_ = false;
- this.syncToBeginning(opt_ignoreIframes);
- return true;
- }
- if (!this.resolve()) {
- return false;
- }
- this.ensureNotSubnavigating();
- if (opt_granularity !== undefined &&
- (opt_granularity !== this.getGranularity() ||
- this.shifterStack_.length > 0)) {
- this.setGranularity(opt_granularity, true);
- this.sync();
- }
- return this.next_(!opt_ignoreIframes);
-};
-
-
-/**
- * Moves forward after switching to a lower granularity until the next
- * call to navigate().
- */
-cvox.NavigationManager.prototype.subnavigate = function() {
- this.pageEndAnnounced_ = false;
- if (!this.resolve()) {
- return;
- }
- this.ensureSubnavigating();
- this.next_(true);
-};
-
-
-/**
- * Moves forward. Starts reading the page from that node.
- * Uses QUEUE_MODE_FLUSH to flush any previous speech.
- * @return {boolean} False if not "reading from here". True otherwise.
- */
-cvox.NavigationManager.prototype.skip = function() {
- if (!this.keepReading_) {
- return false;
- }
- if (cvox.ChromeVox.host.hasTtsCallback()) {
- this.skipped_ = true;
- this.setReversed(false);
- this.startCallbackReading_(cvox.QueueMode.FLUSH);
- }
- return true;
-};
-
-
-/**
- * Starts reading the page from the current selection.
- * @param {cvox.QueueMode} queueMode Either flush or queue.
- */
-cvox.NavigationManager.prototype.startReading = function(queueMode) {
- this.keepReading_ = true;
- if (cvox.ChromeVox.host.hasTtsCallback()) {
- this.startCallbackReading_(queueMode);
- } else {
- this.startNonCallbackReading_(queueMode);
- }
- cvox.ChromeVox.stickyOverride = true;
-};
-
-/**
- * Stops continuous read.
- * @param {boolean} stopTtsImmediately True if the TTS should immediately stop
- * speaking.
- */
-cvox.NavigationManager.prototype.stopReading = function(stopTtsImmediately) {
- this.keepReading_ = false;
- this.navSpeaker_.stopReading = true;
- if (stopTtsImmediately) {
- cvox.ChromeVox.tts.stop();
- }
- cvox.ChromeVox.stickyOverride = null;
-};
-
-
-/**
- * The current current state of continuous read.
- * @return {boolean} The state.
- */
-cvox.NavigationManager.prototype.isReading = function() {
- return this.keepReading_;
-};
-
-
-/**
- * Starts reading the page from the current selection if there are callbacks.
- * @param {cvox.QueueMode} queueMode Either flush or queue.
- * @private
- */
-cvox.NavigationManager.prototype.startCallbackReading_ =
- cvox.ChromeVoxEventSuspender.withSuspendedEvents(function(queueMode) {
- this.finishNavCommand('', true, queueMode, goog.bind(function() {
- if (this.prevReadingSel_ == this.curSel_) {
- this.stopReading();
- return;
- }
- this.prevReadingSel_ = this.curSel_;
- if (this.next_(true) && this.keepReading_) {
- this.startCallbackReading_(cvox.QueueMode.QUEUE);
- }
- }, this));
-});
-
-
-/**
- * Starts reading the page from the current selection if there are no callbacks.
- * With this method, we poll the keepReading_ var and stop when it is false.
- * @param {cvox.QueueMode} queueMode Either flush or queue.
- * @private
- */
-cvox.NavigationManager.prototype.startNonCallbackReading_ =
- cvox.ChromeVoxEventSuspender.withSuspendedEvents(function(queueMode) {
- if (!this.keepReading_) {
- return;
- }
-
- if (!cvox.ChromeVox.tts.isSpeaking()) {
- this.finishNavCommand('', true, queueMode, null);
- if (!this.next_(true)) {
- this.keepReading_ = false;
- }
- }
- window.setTimeout(goog.bind(this.startNonCallbackReading_, this), 1000);
-});
-
-
-/**
- * Returns a complete description of the current position, including
- * the text content and annotations such as "link", "button", etc.
- * Unlike getDescription, this does not shorten the position based on the
- * previous position.
- *
- * @return {Array<cvox.NavDescription>} The summary of the current position.
- */
-cvox.NavigationManager.prototype.getFullDescription = function() {
- if (this.pageSel_) {
- return this.pageSel_.getFullDescription();
- }
- return [cvox.DescriptionUtil.getDescriptionFromAncestors(
- cvox.DomUtil.getAncestors(this.curSel_.start.node),
- true,
- cvox.ChromeVox.verbosity)];
-};
-
-
-/**
- * Sets the browser's focus to the current node.
- * @param {boolean=} opt_skipText Skips focusing text nodes or any of their
- * ancestors; defaults to false.
- */
-cvox.NavigationManager.prototype.setFocus = function(opt_skipText) {
- // TODO(dtseng): cvox.DomUtil.setFocus() totally destroys DOM ranges that have
- // been set on the page; this requires further investigation, but
- // PageSelection won't work without this.
- if (this.pageSel_ ||
- (opt_skipText && this.curSel_.start.node.constructor == Text)) {
- return;
- }
- cvox.Focuser.setFocus(this.curSel_.start.node);
-};
-
-
-/**
- * Returns the node of the directed start of the selection.
- * @return {Node} The current node.
- */
-cvox.NavigationManager.prototype.getCurrentNode = function() {
- return this.curSel_.absStart().node;
-};
-
-
-/**
- * Listen to messages from other frames and respond to messages that
- * tell our frame to take focus and preseve the navigation granularity
- * from the other frame.
- * @private
- */
-cvox.NavigationManager.prototype.addInterframeListener_ = function() {
- /**
- * @type {!cvox.NavigationManager}
- */
- var self = this;
-
- cvox.Interframe.addListener(function(message) {
- if (message['command'] != 'enterIframe' &&
- message['command'] != 'exitIframe') {
- return;
- }
- cvox.ChromeVox.serializer.readFrom(message);
-
- cvox.ChromeVoxEventSuspender.withSuspendedEvents(function() {
- window.focus();
- if (message['findNext']) {
- var predicateName = message['findNext'];
- var predicate = cvox.DomPredicates[predicateName];
- var found = self.findNext(predicate, predicateName, true);
- if (predicate && (!found || found.start.node.tagName == 'IFRAME')) {
- return;
- }
- } else if (message['command'] == 'exitIframe') {
- var id = message['sourceId'];
- var iframeElement = self.iframeIdMap[id];
- var reversed = message['reversed'];
- var granularity = message['granularity'];
- if (iframeElement) {
- self.updateSel(cvox.CursorSelection.fromNode(iframeElement));
- }
- self.setReversed(reversed);
- self.sync();
- self.navigate();
- } else {
- self.syncToBeginning();
-
- // if we have an empty body, then immediately exit the iframe
- if (!cvox.DomUtil.hasContent(document.body)) {
- self.tryIframe_(null);
- return;
- }
- }
-
- // Now speak what ended up being selected.
- // TODO(deboer): Some of this could be moved to readFrom
- self.finishNavCommand('', true);
- if (self.keepReading_) {
- self.startReading(cvox.QueueMode.FLUSH);
- }
- })();
- });
-};
-
-
-/**
- * Update the active indicator to reflect the current node or selection.
- */
-cvox.NavigationManager.prototype.updateIndicator = function() {
- this.activeIndicator.syncToCursorSelection(this.curSel_);
-};
-
-
-/**
- * Update the active indicator in case the active object moved or was
- * removed from the document.
- */
-cvox.NavigationManager.prototype.updateIndicatorIfChanged = function() {
- this.activeIndicator.updateIndicatorIfChanged();
-};
-
-
-/**
- * Show or hide the active indicator based on whether ChromeVox is
- * active or not.
- *
- * If 'active' is true, cvox.NavigationManager does not do anything.
- * However, callers to showOrHideIndicator also need to call updateIndicator
- * to update the indicator -- which also does the work to show the
- * indicator.
- *
- * @param {boolean} active True if we should show the indicator, false
- * if we should hide the indicator.
- */
-cvox.NavigationManager.prototype.showOrHideIndicator = function(active) {
- if (!active) {
- this.activeIndicator.removeFromDom();
- }
-};
-
-
-/**
- * Collapses the selection to directed cursor start.
- */
-cvox.NavigationManager.prototype.collapseSelection = function() {
- this.curSel_.collapse();
-};
-
-
-/**
- * This is used to update the selection to arbitrary nodes because there are
- * browser events, cvox API's, and user commands that require selection around a
- * precise node. As a consequence, calling this method will result in a shift to
- * object granularity without explicit user action or feedback. Also, note that
- * this selection will be sync'ed to ObjectWalker by default unless explicitly
- * ttold not to. We assume object walker can describe the node in the latter
- * case.
- * @param {Node} node The node to update to.
- * @param {boolean=} opt_precise Whether selection will sync exactly to the
- * given node. Defaults to false (and selection will sync according to object
- * walker).
- */
-cvox.NavigationManager.prototype.updateSelToArbitraryNode = function(
- node, opt_precise) {
- if (node) {
- this.setGranularity(cvox.NavigationShifter.GRANULARITIES.OBJECT, true);
- this.updateSel(cvox.CursorSelection.fromNode(node));
- if (!opt_precise) {
- this.sync();
- }
- } else {
- this.syncToBeginning();
- }
-};
-
-
-/**
- * Updates curSel_ to the new selection and sets prevSel_ to the old curSel_.
- * This should be called exactly when something user-perceivable happens.
- * @param {cvox.CursorSelection} sel The selection to update to.
- * @param {cvox.CursorSelection=} opt_context An optional override for prevSel_.
- * Used to override both curSel_ and prevSel_ when jumping back in nav history.
- * @return {boolean} False if sel is null. True otherwise.
- */
-cvox.NavigationManager.prototype.updateSel = function(sel, opt_context) {
- if (sel) {
- this.prevSel_ = opt_context || this.curSel_;
- this.curSel_ = sel;
- }
- // Only update the history if we aren't just trying to peek ahead.
- var currentNode = this.getCurrentNode();
- this.navigationHistory_.update(currentNode);
- return !!sel;
-};
-
-
-/**
- * Sets the direction.
- * @param {!boolean} r True to reverse.
- */
-cvox.NavigationManager.prototype.setReversed = function(r) {
- this.curSel_.setReversed(r);
-};
-
-
-/**
- * Returns true if currently reversed.
- * @return {boolean} True if reversed.
- */
-cvox.NavigationManager.prototype.isReversed = function() {
- return this.curSel_.isReversed();
-};
-
-
-/**
- * Checks if boundary conditions are met and updates the selection.
- * @param {cvox.CursorSelection} sel The selection.
- * @param {boolean=} iframes If true, tries to enter iframes. Default false.
- * @return {boolean} False if end of page is reached.
- * @private
- */
-cvox.NavigationManager.prototype.tryBoundaries_ = function(sel, iframes) {
- iframes = (!!iframes && !this.ignoreIframesNoMatterWhat_) || false;
- this.pageEnd_ = false;
- if (iframes && this.tryIframe_(sel && sel.start.node)) {
- return true;
- }
- if (sel) {
- this.updateSel(sel);
- return true;
- }
- if (this.shifterStack_.length > 0) {
- return true;
- }
- this.syncToBeginning(!iframes);
- this.clearPageSel(true);
- this.stopReading(true);
- this.pageEnd_ = true;
- return false;
-};
-
-
-/**
- * Given a node that we just navigated to, try to jump in and out of iframes
- * as needed. If the node is an iframe, jump into it. If the node is null,
- * assume we reached the end of an iframe and try to jump out of it.
- * @param {Node} node The node to try to jump into.
- * @return {boolean} True if we jumped into an iframe.
- * @private
- */
-cvox.NavigationManager.prototype.tryIframe_ = function(node) {
- if (node == null && cvox.Interframe.isIframe()) {
- var message = {
- 'command': 'exitIframe',
- 'reversed': this.isReversed(),
- 'granularity': this.getGranularity()
- };
- cvox.ChromeVox.serializer.storeOn(message);
- cvox.Interframe.sendMessageToParentWindow(message);
- this.keepReading_ = false;
- return true;
- }
-
- if (node == null || node.tagName != 'IFRAME' || !node.src) {
- return false;
- }
- var iframeElement = /** @type {HTMLIFrameElement} */(node);
-
- var iframeId = undefined;
- for (var id in this.iframeIdMap) {
- if (this.iframeIdMap[id] == iframeElement) {
- iframeId = id;
- break;
- }
- }
- if (iframeId == undefined) {
- iframeId = this.nextIframeId;
- this.nextIframeId++;
- cvox.Interframe.sendIdToIFrame(iframeId, iframeElement, function() {
- this.iframeIdMap[iframeId] = iframeElement;
- this.iframeRetries_ = 0;
- }.bind(this));
- }
-
- // We never received an ack from the iframe.
- if (!this.iframeIdMap[iframeId]) {
- this.iframeRetries_++;
- if (this.iframeRetries_ > 5) {
- // Give up.
- this.iframeRetries_ = 0;
- return false;
- }
- }
-
- var message = {
- 'command': 'enterIframe',
- 'id': iframeId
- };
- cvox.ChromeVox.serializer.storeOn(message);
- cvox.Interframe.sendMessageToIFrame(message, iframeElement);
- return true;
-};
-
-
-/**
- * Delegates to NavigationShifter. Tries to enter any iframes or tables if
- * requested.
- * @param {boolean=} opt_skipIframe True to skip iframes.
- */
-cvox.NavigationManager.prototype.syncToBeginning = function(opt_skipIframe) {
- var ret = this.shifter_.begin(this.curSel_, {
- reversed: this.curSel_.isReversed()
- });
- if (!opt_skipIframe && this.tryIframe_(ret && ret.start.node)) {
- return;
- }
- this.updateSel(ret);
-};
-
-
-/**
- * Used during testing since there are iframes and we don't always want to
- * interact with them so that we can test certain features.
- */
-cvox.NavigationManager.prototype.ignoreIframesNoMatterWhat = function() {
- this.ignoreIframesNoMatterWhat_ = true;
-};
-
-
-/**
- * Save a cursor selection during an excursion.
- */
-cvox.NavigationManager.prototype.saveSel = function() {
- this.saveSel_ = this.curSel_;
-};
-
-
-/**
- * Save a cursor selection after an excursion.
- */
-cvox.NavigationManager.prototype.restoreSel = function() {
- this.curSel_ = this.saveSel_ || this.curSel_;
-};
-
-
-/**
- * @param {boolean=} opt_persist Persist the granularity to all running tabs;
- * defaults to false.
- * @private
- */
-cvox.NavigationManager.prototype.persistGranularity_ = function(opt_persist) {
- opt_persist = opt_persist === undefined ? false : opt_persist;
- if (opt_persist) {
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'granularity',
- 'value': this.getGranularity()
- });
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager_test.unitjs
deleted file mode 100644
index f807f25b5e6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager_test.unitjs
+++ /dev/null
@@ -1,1395 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxNavigationManagerUnitTest() {
- ChromeVoxUnitTestBase.call(this);
-}
-
-CvoxNavigationManagerUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- isAsync: true,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ChromeVoxTester',
- 'cvox.NavigationShifter',
- 'cvox.TestTts',
- ],
-
- /** @override */
- setUp: function() {
- cvox.ChromeVoxTester.setUp(document);
- },
-
- /** @override */
- tearDown: function() {
- cvox.ChromeVoxTester.tearDown(document);
- },
-
- /**
- * Check a sequence of navigations.
- *
- * @param {Array<string>} strategies A list of nav strategies to try.
- * @param {Array<Object>} commandsAndExpectations An array of objects,
- * each one of which should contain:
- * 'command': The UserCommands command to execute.
- * 'text': The expected text of the node that's navigated to.
- * 'annotation': The expected annotation of the node navigated to.
- */
- checkNavSequence: function(strategies, commandsAndExpectations) {
- if (strategies.length == 0)
- return;
-
- var strategy = strategies.shift();
- this.waitForCalm(cvox.ChromeVoxTester.setStrategy, strategy)
- .waitForCalm(cvox.ChromeVoxTester.syncToFirstNode);
-
- var depth = 0;
- commandsAndExpectations.forEach((function(ce) {
- this.waitForCalm(function() {
- if (ce.command) {
- this.userCommand(ce.command);
- depth = 0;
- }
- });
- this.waitForCalm(function() {
- if (ce.context)
- this.assertNodeContext(ce.context, depth);
- if (ce.text)
- this.assertNodeText(ce.text, depth);
- if (ce.userValue)
- this.assertNodeUserValue(ce.userValue, depth);
- if (ce.annotation)
- this.assertNodeAnnotation(ce.annotation, depth);
- depth++;
- });
- }).bind(this));
- this.waitForCalm(function() {
- this.checkNavSequence(strategies, commandsAndExpectations);
- });
- },
-
- currentDescription_: function(opt_depth) {
- var depth = opt_depth || 0;
- return cvox.ChromeVox.navigationManager.getDescription()[depth] ||
- new cvox.NavDescription({text: ''});
- },
-
- assertTextEquals: function(expected, actual) {
- try {
- assertEquals(expected, actual);
- } catch (e) {
- throw new Error('Expecting ' + expected + ' Actual ' + actual);
- }
- },
-
- assertNodeText: function(expectedText, opt_depth) {
- this.assertTextEquals(expectedText,
- this.currentDescription_(opt_depth).text);
- return this;
- },
-
- assertNodeAnnotation: function(expectedAnnotation, opt_depth) {
- this.assertTextEquals(expectedAnnotation,
- this.currentDescription_(opt_depth).annotation);
- return this;
- },
-
- assertNodeContext: function(expectedContext, opt_depth) {
- this.assertTextEquals(expectedContext,
- this.currentDescription_(opt_depth).context);
- return this;
- },
-
- assertNodeUserValue: function(expectedUserValue, opt_depth) {
- this.assertTextEquals(expectedUserValue,
- this.currentDescription_(opt_depth).userValue);
- return this;
- }
-};
-
-TEST_F('CvoxNavigationManagerUnitTest', 'SimpleStaticHTML', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<h1>FirstHeading</h1>' +
- '<h2>SecondHeading</h2>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom', 'smart', 'selection'],
- [
- { 'command': 'forward',
- 'text': 'FirstHeading',
- 'annotation': 'Heading 1'
- },
- { 'command': 'forward',
- 'text': 'SecondHeading',
- 'annotation': 'Heading 2'
- }
- ]);
-});
-
-
-/**
- * Test navigation of simple static HTML with some control elements to validate
- * the text and annotation returned when doing navigation.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'ControlElements', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<p>Some text</p>' +
- '<input type="text"/>' +
- '<p>Some more text</p>' +
- '<input type="button"/>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom', 'smart', 'selection'],
- [
- { 'command': 'forward',
- 'text': 'Some text',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'text': '',
- 'annotation': 'Edit text'
- },
- { 'command': 'forward',
- 'text': 'Some more text',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'text': '',
- 'annotation': 'Button'
- }
- ]);
-});
-
-
-/**
- * Test navigation of simple static HTML with some control elements inside a
- * fieldset to validate the text and annotation returned when doing
- * navigation.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'ControlElementsWithFieldset', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<p>Some text</p>' +
- '<fieldset id="Fieldset">' +
- '<legend>This is a legend inside a fieldset</legend>' +
- '<input type="text"/>' +
- '<p>Some more text</p>' +
- '<input type="button"/>' +
- '</fieldset>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom', 'selection'],
- [
- { 'command': 'forward',
- 'text': 'Some text',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'text': 'This is a legend inside a fieldset'
- },
- { 'command': 'forward',
- 'annotation': 'Edit text'
- },
- { 'command': 'forward',
- 'text': 'Some more text',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'text': '',
- 'annotation': 'Button'
- }
- ]);
-});
-
-
-/**
- * Test skip to next/prev element navigation.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'SkipNavigation', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<h1> <i>FirstHeading</i> </h1>' +
- 'asdf' +
- '<p>Here is some text</p>' +
- 'asdf' +
- '<h2>SecondHeading</h2>' +
- '</div>');
-
- cvox.ChromeVoxUserCommands.enableCommandDispatchingToPage = false;
-
- this.checkNavSequence(
- ['smart'],
- [
- { 'command': 'forward',
- 'text': 'FirstHeading',
- 'annotation': 'Heading 1'
- },
- { 'command': 'forward',
- 'text': 'asdf',
- 'annotation': ''
- },
- { 'command': 'nextHeading',
- 'text': 'SecondHeading',
- 'annotation': 'Heading 2'
- },
- { 'command': 'previousHeading',
- 'text': 'FirstHeading',
- 'annotation': 'Heading 1'
- }
- ]);
-});
-
-
-/**
- * Test finding the next heading.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'FindNextHeading', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- 'Some text.' +
- '<h1>A heading</h1>' +
- 'More text after the heading.' +
- '<p>Even more text after the heading.</p>' +
- '<p id="after">After</p>' +
- '</div>');
- cvox.ChromeVox.navigationManager.ignoreIframesNoMatterWhat();
- this.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'lineardom');
- this.waitForCalm(cvox.ChromeVoxTester.syncToFirstNode);
-
- this.waitForCalm(this.userCommand, 'forward');
- this.waitForCalm(this.assertSpoken, 'Some text.');
-
- this.waitForCalm(this.userCommand, 'nextHeading');
- this.waitForCalm(this.assertSpoken, 'A heading Heading 1');
-
- this.waitForCalm(this.userCommand, 'nextHeading');
- this.waitForCalm(this.assertSpoken,
- 'Wrapped to top A heading Heading 1');
-
- this.waitForCalm(this.userCommand, 'forward');
- this.waitForCalm(this.assertSpoken, 'More text after the heading.');
-
- this.waitForCalm(this.userCommand, 'previousHeading');
- this.waitForCalm(this.assertSpoken, 'A heading Heading 1');
-
- this.waitForCalm(this.userCommand, 'previousHeading');
- this.waitForCalm(this.assertSpoken,
- 'Wrapped to bottom A heading Heading 1');
-
- this.waitForCalm(this.userCommand, 'backward');
- this.waitForCalm(this.assertSpoken, 'Some text.');
-
- this.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'smart');
- this.waitForCalm(cvox.ChromeVoxTester.syncToFirstNode);
-
- this.waitForCalm(this.userCommand, 'forward');
- this.waitForCalm(this.assertSpoken, 'Some text.');
-
- this.waitForCalm(this.userCommand, 'nextHeading');
- this.waitForCalm(this.assertSpoken, 'A heading Heading 1');
-
- this.waitForCalm(this.userCommand, 'nextHeading');
- this.waitForCalm(this.assertSpoken,
- 'Wrapped to top A heading Heading 1');
-
- this.waitForCalm(this.userCommand, 'forward');
- this.waitForCalm(this.assertSpoken, 'More text after the heading.');
-
- this.waitForCalm(this.userCommand, 'previousHeading');
- this.waitForCalm(this.assertSpoken, 'A heading Heading 1');
-
- this.waitForCalm(this.userCommand, 'previousHeading');
- this.waitForCalm(this.assertSpoken,
- 'Wrapped to bottom A heading Heading 1');
-
- this.waitForCalm(this.userCommand, 'backward');
- this.waitForCalm(this.assertSpoken, 'Some text.');
-
-});
-
-
-/**
- * Test navigation of HTML and ARIA lists.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'ListLinearNav', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<ul>' +
- '<li>First' +
- '<li><div>Second</div></li>' +
- '<div role="listitem"><a href="#">Third</a></div>' +
- '</ul>' +
- '<div role="list">' +
- '<div role="listitem"><a href="#">First</a></div>' +
- '<li>Second' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom'],
- [
- { 'command': 'forward',
- 'context': 'List with 3 items',
- 'text': 'First',
- 'annotation': 'List item'
- },
- { 'command': 'forward',
- 'context': '',
- 'text': 'Second',
- 'annotation': 'List item'
- },
- { 'command': 'forward',
- 'context': '',
- 'text': 'Third',
- 'annotation': 'Internal link List item'
- },
- { 'command': 'forward',
- 'context': 'List with 2 items',
- 'text': 'First',
- 'annotation': 'Internal link List item'
- },
- { 'command': 'forward',
- 'context': '',
- 'text': 'Second',
- 'annotation': 'List item'
- },
- { 'command': 'forward',
- 'context': '',
- 'text': 'After',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'context': 'List with 2 items',
- 'text': 'Second',
- 'annotation': 'List item'
- },
- { 'command': 'backward',
- 'context': '',
- 'text': 'First',
- 'annotation': 'Internal link List item'
- }
- ]);
-});
-
-
-/**
- * Test navigation of HTML and ARIA lists.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'ListSmartNav', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<ul>' +
- '<li>First</li>' +
- '<li>Second</li>' +
- '<div role="listitem">Third</div>' +
- '</ul>' +
- '<div role="list">' +
- '<div role="listitem"><a href="#">First</a></div>' +
- '<li>Second' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['smart'],
- [
- { 'command': 'forward',
- 'context': 'List with 3 items',
- 'text': 'First',
- 'annotation': 'List item'
- },
- { 'text': 'Second',
- 'annotation': 'List item'
- },
- { 'text': 'Third',
- 'annotation': 'List item'
- },
- { 'command': 'forward',
- 'context': 'List with 2 items',
- 'text': 'First',
- 'annotation': 'Internal link List item'
- },
- { 'text': 'Second',
- 'annotation': 'List item'
- },
- { 'command': 'forward',
- 'text': 'After'
- },
- { 'command': 'backward',
- 'context': 'List with 2 items',
- 'text': 'First',
- 'annotation': 'Internal link List item'
- },
- { 'text': 'Second',
- 'annotation': 'List item'
- }
- ]);
-});
-
-
-/**
- * Test smart navigation of link collections.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'LinkCollectionSmartNav', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<p>' +
- '<a href="#">First</a>' +
- '<a href="#">Second</a>' +
- '<a href="#">Third</a>' +
- '</p>' +
- '<p>' +
- '<a href="#">First</a> and' +
- '<a href="#">Second</a> and' +
- '<a href="#">Third</a>' +
- '</p>' +
- '<p id="after">After</p>' +
- '</div>');
-
- // TODO: The way we implemented this feature breaks the i18n_check.
- if (cvox.I18nCheck)
- return;
-
- this.checkNavSequence(
- ['smart'],
- [
- { 'command': 'forward',
- 'annotation': 'Link collection with 3 items'
- },
- { 'text': 'First'
- },
- { 'text': 'Second'
- },
- { 'text': 'Third'
- },
- { 'command': 'forward',
- 'text': 'First',
- 'annotation': 'Internal link'
- },
- { 'text': 'and'
- },
- { 'text': 'Second',
- 'annotation': 'Internal link'
- },
- { 'text': 'and'
- },
- { 'text': 'Third',
- 'annotation': 'Internal link'
- },
- { 'command': 'forward',
- 'text': 'After'
- }
- ]);
-});
-
-
-/**
- * Test navigation of a control followed by its label.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'ControlThenLabel', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<input type="checkbox" id="aaa">' +
- '<label for="aaa">Alpha</label>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom'],
- [
- { 'command': 'forward',
- 'text': 'Alpha',
- 'annotation': 'Check box not checked'
- },
- { 'command': 'forward',
- 'text': 'After',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'text': 'Alpha',
- 'annotation': 'Check box not checked'
- },
- { 'command': 'backward',
- 'text': 'Before',
- 'annotation': ''
- }
- ]);
-});
-
-
-/**
- * Test navigation of a label followed by its control.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'LabelThenControl', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<label for="bbb">Beta</label>' +
- '<input type="checkbox" id="bbb">' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom'],
- [
- { 'command': 'forward',
- 'text': 'Beta',
- 'annotation': 'Check box not checked'
- },
- { 'command': 'forward',
- 'text': 'After',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'text': 'Beta',
- 'annotation': 'Check box not checked'
- },
- { 'command': 'backward',
- 'text': 'Before',
- 'annotation': ''
- }
- ]);
-});
-
-
-/**
- * Test navigation of a control inside a label element (yes, this is
- * valid HTML and should be supported).
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'ControlInsideLabel', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<label>' +
- 'First name:' +
- '<input type="text" name="name" value="Linus">' +
- '</label>' +
- '<p>' +
- '<label>Remember me' +
- '<input type="checkbox" id="remember" />' +
- '</label>' +
- '</p>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom'],
- [
- { 'command': 'forward',
- 'text': 'First name:',
- 'userValue': 'Linus',
- 'annotation': 'Edit text'
- },
- { 'command': 'forward',
- 'text': 'Remember me',
- 'annotation': 'Check box not checked'
- },
- { 'command': 'forward',
- 'text': 'After',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'text': 'Remember me',
- 'annotation': 'Check box not checked'
- },
- { 'command': 'backward',
- 'text': 'First name:',
- 'userValue': 'Linus',
- 'annotation': 'Edit text'
- },
- { 'command': 'backward',
- 'text': 'Before',
- 'annotation': ''
- }
- ]);
-});
-
-
-/**
- * Test navigation of two controls inside a single label element - this
- * is nonstandard but we should make sure we don't totally fail!
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'TwoControlsInsideLabel', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<label>' +
- 'LabelText' +
- '<input type="text" value="Value">' +
- '<input type="checkbox">' +
- '</label>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom'],
- [
- { 'command': 'forward',
- 'text': 'LabelText',
- 'userValue': 'Value',
- 'annotation': 'Edit text'
- },
- { 'command': 'forward',
- 'text': 'LabelText',
- 'annotation': 'Check box not checked'
- },
- { 'command': 'forward',
- 'text': 'After',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'text': 'LabelText',
- 'annotation': 'Check box not checked'
- },
- { 'command': 'backward',
- 'text': 'LabelText',
- 'userValue': 'Value',
- 'annotation': 'Edit text'
- },
- { 'command': 'backward',
- 'text': 'Before',
- 'annotation': ''
- }
- ]);
-});
-
-
-/**
- * Test invalid labels - if a label doesn't point to a control, it
- * should just be read as if it wasn't a label.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'InvalidLabels', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<label for="xxx">Label for nonexistent control</label>' +
- '<label>Label with no associated control</label>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom'],
- [
- { 'command': 'forward',
- 'text': 'Label for nonexistent control',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'text': 'Label with no associated control',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'text': 'After',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'text': 'Label with no associated control',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'text': 'Label for nonexistent control',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'text': 'Before',
- 'annotation': ''
- }
- ]);
-});
-
-
-/**
- * Test scrollbar value readout.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'Scrollbar', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<div id="progress1" role="progressbar" class="range"' +
- 'aria-valuemin="0" aria-valuenow="1" aria-valuemax="5">' +
- '<div>[==&nbsp;&nbsp;&nbsp;]</div>' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom', 'smart'],
- [
- { 'command': 'forward',
- 'text': '',
- 'annotation': 'Progress bar 20%'
- }
- ]);
-});
-
-
-/**
- * Test ARIA listbox where the whole box gets focus.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'AriaListboxActiveDescendant', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<select size="3">' +
- '<option selected>Red</option>' +
- '<option>Yellow</option>' +
- '<option>Green</option>' +
- '</select>' +
- '<p id="middle1">Middle 1</p>' +
- '<div id="listbox" role="listbox" tabindex="0" aria-activedescendant="red">' +
- '<div id="red" aria-selected="true" role="option">Red</div>' +
- '<div id="yellow" role="option">Yellow</div>' +
- '<div id="green" role="option">Green</div>' +
- '</div>' +
- '<p id="middle2">Middle 2</p>' +
- '<div id="listbox2" role="listbox" tabindex="0"' +
- 'aria-activedescendant="red2">' +
- '<div id="red2" aria-selected="true" role="option"' +
- 'aria-posinset="10" aria-setsize="30">Red</div>' +
- '<div id="yellow2" role="option"' +
- 'aria-posinset="20" aria-setsize="30">Yellow</div>' +
- '<div id="green2" role="option"' +
- 'aria-posinset="30" aria-setsize="30">Green</div>' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom', 'smart'],
- [
- { 'command': 'forward',
- 'userValue': 'Red',
- 'annotation': 'Combo box 1 of 3'
- },
- { 'command': 'forward',
- 'text': 'Middle 1',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'userValue': 'Red',
- 'annotation': 'List box Selected 1 of 3'
- },
- { 'command': 'forward',
- 'text': 'Middle 2',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'userValue': 'Red',
- 'annotation': 'List box Selected 10 of 30'
- },
- { 'command': 'forward',
- 'text': 'After',
- 'annotation': ''
- }
- ]);
-});
-
-
-/**
- * Test ARIA listbox where each option gets focus.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'AriaListboxOption', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<div id="listbox" role="listbox">' +
- '<div id="red" tabindex="0" aria-selected="true" role="option">Red</div>' +
- '<div id="yellow" tabindex="-1" role="option">Yellow</div>' +
- '<div id="green" tabindex="-1" role="option">Green</div>' +
- '</div>' +
- '<p id="before">Middle</p>' +
- '<div id="listbox2" role="listbox">' +
- '<div id="red2" tabindex="0" aria-selected="true" role="option"' +
- 'aria-posinset="2" aria-setsize="6">Red</div>' +
- '<div id="yellow2" tabindex="-1" role="option"' +
- 'aria-posinset="4" aria-setsize="6">Yellow</div>' +
- '<div id="green2" tabindex="-1" role="option"' +
- 'aria-posinset="6" aria-setsize="6">Green</div>' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom', 'smart'],
- [
- { 'command': 'forward',
- 'context': 'List box',
- 'text': 'Red',
- 'annotation': 'Selected 1 of 3'
- },
- { 'command': 'forward',
- 'text': 'Yellow',
- 'annotation': '2 of 3'
- },
- { 'command': 'forward',
- 'text': 'Green',
- 'annotation': '3 of 3'
- },
- { 'command': 'forward',
- 'text': 'Middle',
- 'annotation': ''
- },
- { 'command': 'forward',
- 'context': 'List box',
- 'text': 'Red',
- 'annotation': 'Selected 2 of 6'
- },
- { 'command': 'forward',
- 'text': 'Yellow',
- 'annotation': '4 of 6'
- },
- { 'command': 'forward',
- 'text': 'Green',
- 'annotation': '6 of 6'
- },
- { 'command': 'forward',
- 'text': 'After',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'context': 'List box',
- 'text': 'Green',
- 'annotation': '6 of 6'
- },
- { 'command': 'backward',
- 'text': 'Yellow',
- 'annotation': '4 of 6'
- },
- { 'command': 'backward',
- 'text': 'Red',
- 'annotation': 'Selected 2 of 6'
- },
- { 'command': 'backward',
- 'text': 'Middle',
- 'annotation': ''
- },
- { 'command': 'backward',
- 'context': 'List box',
- 'text': 'Green',
- 'annotation': '3 of 3'
- },
- { 'command': 'backward',
- 'text': 'Yellow',
- 'annotation': '2 of 3'
- },
- { 'command': 'backward',
- 'text': 'Red',
- 'annotation': 'Selected 1 of 3'
- }
- ]);
-});
-
-
-/**
- * Test ARIA listbox where each option gets focus and the outer container has
- * tabindex="-1"
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'AriaListboxOptionOuterFocus', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<div id="listbox" role="listbox" tabindex="-1">' +
- '<div id="red" tabindex="0" aria-selected="true" role="option">Red</div>' +
- '<div id="yellow" tabindex="-1" role="option">Yellow</div>' +
- '<div id="green" tabindex="-1" role="option">Green</div>' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['smart'],
- [
- { 'command': 'forward',
- 'context': 'List box',
- 'text': 'Red',
- 'annotation': 'Selected 1 of 3'
- },
- { 'command': 'forward',
- 'text': 'Yellow',
- 'annotation': '2 of 3'
- },
- { 'command': 'forward',
- 'text': 'Green',
- 'annotation': '3 of 3'
- },
- { 'command': 'forward',
- 'text': 'After',
- 'annotation': ''
- }
- ]);
-});
-
-
-
-/**
- * Test ARIA menus.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'AriaMenus', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<div role="menubar">' +
- '<div role="menuitem">File</div>' +
- '<div role="menuitem">Edit</div>' +
- '</div>' +
- '<div role="menu">' +
- '<div role="menuitem">New</div>' +
- '<div role="menuitem">Open</div>' +
- '</div>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom', 'smart'],
- [
- { 'command': 'forward',
- 'context': 'Menu bar',
- 'text': 'File',
- 'annotation': 'Menu'
- },
- { 'command': 'forward',
- 'text': 'Edit',
- 'annotation': 'Menu'
- },
- { 'command': 'forward',
- 'text': 'New',
- 'annotation': 'Menu item 1 of 2'
- },
- { 'command': 'forward',
- 'text': 'Open',
- 'annotation': 'Menu item 2 of 2'
- }
- ]);
-});
-
-/**
- * Test left and right navigation at the group level.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'LeftRightGroupNavigation', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<h1>Alphabetical Fruits</h1>' +
- 'Apple <a href=\'#\'>Banana</a> Cranberry <a href=\'#\'>Date</a> Eggplant' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['smart'],
- [
- { 'command': 'forward',
- 'text': 'Alphabetical Fruits',
- 'annotation': 'Heading 1'
- },
- { 'command': 'right',
- 'text': 'Apple'
- },
- { 'command': 'right',
- 'text': 'Banana',
- 'annotation': 'Internal link'
- },
- { 'command': 'left',
- 'text': 'Apple'
- },
- { 'command': 'forward',
- 'text': 'Banana',
- 'annotation': 'Internal link'
- },
- { 'command': 'right',
- 'text': 'Cranberry'
- },
- { 'command': 'backward',
- 'text': 'Banana',
- 'annotation': 'Internal link'
- }
- ]);
-});
-
-/**
- * Test left and right navigation at the sentence level.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'LeftRightSentenceNavigation', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<h1>Alphabetical Fruits</h1>' +
- 'Apples are delicious. An apple a day keeps the doctor away.' +
- '<a href="#">Banana</a> Cranberries are delicious. ' +
- 'A cranberry a day keeps the doctor away.' +
- '<p id="after">After</p>' +
- '</div>');
-
- // TODO(dtseng): This is here until we can remove or fix all tests relating to
- // sentences. This test framework holds state across runs, so only this
- // expression is needed.
- cvox.NavigationShifter.allowSentence = true;
- this.checkNavSequence(
- ['lineardom'],
- [
- { 'command': 'forward',
- 'text': 'Alphabetical Fruits',
- 'annotation': 'Heading 1'
- },
- { 'command': 'forward',
- 'text': 'Apples are delicious. An apple a day keeps the doctor away.'
- },
- { 'command': 'right',
- 'text': 'An apple a day keeps the doctor away.'
- },
- { 'command': 'right',
- 'text': 'Banana',
- 'annotation': 'Internal link'
- },
- { 'command': 'right',
- 'text': 'Cranberries are delicious.'
- },
- { 'command': 'right',
- 'text': 'A cranberry a day keeps the doctor away.'
- },
- { 'command': 'left',
- 'text': 'Cranberries are delicious.'
- },
- { 'command': 'left',
- 'text': 'Banana',
- 'annotation': 'Internal link'
- },
- { 'command': 'forward',
- 'text': 'Cranberries are delicious. A cranberry a day keeps the doctor away.'
- }
- ]);
-});
-
-/**
- * Test left and right navigation at the word level.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'LeftRightWordNavigation', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<h1>Alphabetical Fruits</h1>' +
- 'Apples are delicious. An apple a day keeps the doctor away.' +
- '<h2><a href="#">Banana</a></h2> Cranberries are delicious. ' +
- 'A cranberry a day keeps the doctor away.' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['selection'],
- [
- { 'command': 'forward',
- 'text': 'Alphabetical Fruits',
- 'annotation': 'Heading 1'
- },
- { 'command': 'forward',
- 'text': 'Apples are delicious.'
- },
- { 'command': 'nextGranularity' },
- { 'command': 'right',
- 'text': 'are'
- },
- { 'command': 'right',
- 'text': 'delicious.'
- },
- { 'command': 'right',
- 'text': 'An'
- },
- { 'command': 'right',
- 'text': 'apple'
- },
- { 'command': 'right',
- 'text': 'a'
- },
- { 'command': 'left',
- 'text': 'apple'
- },
- { 'command': 'left',
- 'text': 'An'
- },
- { 'command': 'forward',
- 'text': 'Banana'
- },
- { 'command': 'right',
- 'text': 'Cranberries'
- },
- { 'command': 'previousGranularity' },
- { 'command': 'previousGranularity',
- 'text': 'Cranberries are delicious. A cranberry a day keeps the doctor away.'
- }
- ]);
-});
-
-/**
- * Test left and right navigation at the character level.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'LeftRightCharacterNavigation', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<h1>Alphabetical Fruits</h1>' +
- 'Apples are delicious. An apple a day keeps the doctor away.' +
- '<a href="#">Banana</a> Cranberries are delicious. ' +
- 'A cranberry a day keeps ' +
- 'the doctor away.' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['selection'],
- [
- { 'command': 'forward',
- 'text': 'Alphabetical Fruits',
- 'annotation': 'Heading 1'
- },
- { 'command': 'forward',
- 'text': 'Apples are delicious.'
- },
- { 'command': 'nextGranularity' },
- { 'command': 'nextGranularity',
- 'text': 'Apples'
- },
- { 'command': 'right',
- 'text': 'p'
- },
- { 'command': 'right',
- 'text': 'p'
- },
- { 'command': 'right',
- 'text': 'l'
- },
- { 'command': 'right',
- 'text': 'e'
- },
- { 'command': 'right',
- 'text': 's'
- },
- { 'command': 'right',
- 'text': ' '
- },
- { 'command': 'right',
- 'text': 'a'
- },
- { 'command': 'right',
- 'text': 'r'
- },
- { 'command': 'right',
- 'text': 'e'
- },
- { 'command': 'left',
- 'text': 'r'
- },
- { 'command': 'left',
- 'text': 'a'
- },
- { 'command': 'forward',
- 'text': 'delicious.'
- },
- { 'command': 'right',
- 'text': 'e'
- },
- { 'command': 'nextGranularity' },
- { 'command': 'previousGranularity',
- 'text': 'elicious.'
- }
- ]);
-});
-
-/**
- * Test whether fullyDescribe works
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'FullyDescribe', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<ul>' +
- '<li>A</li>' +
- '<ul>' +
- '<li>1</li>' +
- '<li>2</li>' +
- '</ul>' +
- '</ul>' +
- '<p id="after">After</p>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom'],
- [
- { 'command': 'forward',
- 'context': 'List with 1 items',
- 'text': 'A',
- 'annotation': 'List item'
- },
- { 'command': 'forward',
- 'context': 'List with 2 items',
- 'text': '1',
- 'annotation': 'List item'
- },
- { 'command': 'forward',
- 'context': '',
- 'text': '2',
- 'annotation': 'List item'
- },
- { 'command': 'fullyDescribe',
- 'context': '',
- 'text': '2',
- 'annotation': 'List item'
- }
- ]);
- this.waitForCalm(this.assertSpoken,
- 'List with 1 items A List item ' +
- 'List with 2 items 1 List item 2 List item ' +
- 'List with 1 items List with 2 items 2 List item');
-});
-
-
-/**
- * Test continuous reading mode.
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'ContinuousReading', function() {
- this.loadHtml(
- '<div id="continuousTest">' +
- '<p id="before">Before</p>' +
- '<div>Some text.</div>' +
- '<div>First</div>' +
- '<div>Second</div>' +
- '<a href="#">Third</a>' +
- '<p id="after">After</p>' +
- '</div>');
- cvox.ChromeVox.navigationManager.ignoreIframesNoMatterWhat();
- this.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'lineardom')
- .waitForCalm(cvox.ChromeVoxTester.syncToFirstNode)
- .waitForCalm(cvox.ChromeVoxTester.readFromHere)
- .waitForCalm(this.assertSpoken,
- 'Before Some text. First Second Third Internal link After');
-});
-
-
-/**
- * Test HTML5 semantic elements
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'SemanticElts', function() {
- this.loadHtml(
- '<p id="before">Before</p>' +
- '<article>' +
- '<header>' +
- '<time datetime="2009-10-22" pubdate="">October 22, 2009</time>' +
- '<h1>' +
- '<a href="#">Travel day</a>' +
- '</h1>' +
- '</header>' +
- '<p>Blah blah blah</p>' +
- '</article>' +
- '<div>' +
- '<p>October 17, 2009</p>' +
- '<h2>' +
- '<a href="#">I am going to Prague!</a>' +
- '</h2>' +
- '<p>More blah blah blah</p>' +
- '</div>' +
- '<p id="after">After</p>');
-
- this.checkNavSequence(
- ['smart'],
- [
- { 'command': 'forward',
- 'text': 'October 22, 2009',
- 'context': 'Article Header',
- 'annotation': 'Time'
- },
- {
- 'text': 'Travel day',
- 'context': '',
- 'annotation': 'Internal link Heading 1'
- },
- {
- 'text': 'Blah blah blah'
- },
- { 'command': 'forward',
- 'text': 'October 17, 2009'
- },
- {
- 'command': 'forward',
- 'text': 'I am going to Prague!',
- 'context': '',
- 'annotation': 'Internal link Heading 2'
- },
- {
- 'command': 'forward',
- 'text': 'More blah blah blah'
- }
- ]);
-});
-
-
-/**
- * Test aria-haspopup
- */
-TEST_F('CvoxNavigationManagerUnitTest', 'AriaHasPopup', function() {
- this.loadHtml(
- '<div>' +
- '<p id="before">Before</p>' +
- '<button>Alpha</button>' +
- '<button aria-haspopup="true">Bravo</button>' +
- '<div role="button" tabindex="0">Charlie</div>' +
- '<div role="button" aria-haspopup="true" tabindex="0">Delta</div>' +
- '<div role="menuitem" tabindex="0">Echo</div>' +
- '<div role="menuitem" aria-haspopup="true" tabindex="0">Foxtrot</div>' +
- '</div>');
- this.checkNavSequence(
- ['lineardom', 'smart'],
- [
- { 'command': 'forward',
- 'text': 'Alpha',
- 'annotation': 'Button'
- },
- { 'command': 'forward',
- 'text': 'Bravo',
- 'annotation': 'Pop-up button'
- },
- { 'command': 'forward',
- 'text': 'Charlie',
- 'annotation': 'Button'
- },
- { 'command': 'forward',
- 'text': 'Delta',
- 'annotation': 'Pop-up button'
- },
- { 'command': 'forward',
- 'text': 'Echo',
- 'annotation': 'Menu item'
- },
- { 'command': 'forward',
- 'text': 'Foxtrot',
- 'annotation': 'Menu item with submenu'
- }
- ]);
-});
-
-
-/** Test Aria Math Roles. */
-TEST_F('CvoxNavigationManagerUnitTest', 'AriaMathRoles', function() {
- this.loadHtml(
- '<p><div role="math"' +
- 'aria-label="a times x squared plus b times x plus c equals 0">' +
- '<math xmlns="http://www.w3.org/1998/Math/MathML">' +
- '<mrow><mrow><mrow><mi>a</mi><mo> &InvisibleTimes; </mo>' +
- ' <msup id="foo"><mi>x</mi><mn>2</mn></msup>' +
- '</mrow><mo>+</mo><mrow><mi>b</mi><mo> &InvisibleTimes; </mo>' +
- '<mi>x</mi></mrow><mo>+</mo><mi>c</mi></mrow><mo>=</mo><mn>0</mn></mrow>' +
- '</math></div></p>' +
- '<p><div role="math" aria-label="square root of n cube">' +
- '<math><msqrt><msup><mi>n</mi><mn>3</mn></msup></msqrt></math></div></p>'
- );
-
- this.waitForCalm(this.userCommand, 'forward')
- .waitForCalm(this.assertSpoken, 'Math a times x squared plus b times x plus c equals 0')
- .waitForCalm(this.userCommand, 'forward')
- .waitForCalm(this.assertSpoken, 'Math square root of n cube');
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_shifter.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_shifter.js
deleted file mode 100644
index 61e11ca419b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_shifter.js
+++ /dev/null
@@ -1,269 +0,0 @@
-// 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.
-
-/**
- * @fileoverview The purpose of this class is to delegate to the correct walker
- * based on the navigation state that it is in. The navigation state is a
- * simplified view of the external environment; the smallest amount of knowledge
- * needed to correctly delegate. One example is whether the user
- * is subnavigating. Note that while this class does
- * decide which walker to delegate to, it does NOT decide when its state
- * should be changed. This is done by the layer above. The reason for this
- * separation is that trying to make the decision here would require a lot
- * of knowledge about the environment, making this class harder to
- * test and maintain.
- *
- * This class knows about the public interfaces of all the walkers (rather
- * than just of the abstract class) since there are currently walker operations
- * which apply only to specific walkers.
- *
- * The navigation model is organized around having a chain of walkers with
- * increasing "granularity". This means (with a few exceptions), that if
- * walker A is more granular than walker B, then every valid selection in A
- * is a subset of a valid selection in B. For example, characters are
- * more granular than words, because every character is either a word or
- * inside a word.
- *
- * Note that while any callers may assume the granularity chain exists (after
- * all, there is a method makeMoreGranular()), they may not assume anything
- * about the order in which the walkers occur in this chain. This is because
- * the order may depend on the navigation state, and having external interaction
- * would slow down the changes we could make to this class (which is a problem,
- * since this is one of the core classes that impacts user-perceptible
- * navigation).
- *
- * Thinking of adding something here? Ask these questions:
- * Is it exposing functionality in some walker, the execution of which depends
- * on navigation state?
- * Then it is a good candidate.
- * Does it require knowing more about the environment?
- * If you are sure that it belongs here, then the minimum amount of knowledge
- * to make the delegation decision should be added as state to this class.
- * The decision for when this state changes should not be made in this class.
- *
- */
-
-
-goog.provide('cvox.NavigationShifter');
-
-goog.require('cvox.AbstractShifter');
-goog.require('cvox.CharacterWalker');
-goog.require('cvox.GroupWalker');
-goog.require('cvox.LayoutLineWalker');
-goog.require('cvox.ObjectWalker');
-goog.require('cvox.SentenceWalker');
-goog.require('cvox.TraverseContent');
-goog.require('cvox.WordWalker');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractShifter}
- */
-cvox.NavigationShifter = function() {
- this.reset_();
- goog.base(this);
-};
-goog.inherits(cvox.NavigationShifter, cvox.AbstractShifter);
-
-// These "const" literals may be used, but no order may be assumed
-// between them by any outside callers.
-/**
- * @type {Object<number>}
- */
-cvox.NavigationShifter.GRANULARITIES = {
- 'CHARACTER': 0,
- 'WORD': 1,
- 'LINE': 2,
- 'SENTENCE': 3,
- 'OBJECT': 4,
- 'GROUP': 5
-};
-
-
-/**
- * Stores state variables in a provided object.
- *
- * @param {Object} store The object.
- */
-cvox.NavigationShifter.prototype.storeOn = function(store) {
- store['granularity'] = this.getGranularity();
-};
-
-
-/**
- * Updates the object with state variables from an earlier storeOn call.
- *
- * @param {Object} store The object.
- */
-cvox.NavigationShifter.prototype.readFrom = function(store) {
- this.setGranularity(store['granularity']);
-};
-
-
-/**
- * @override
- */
-cvox.NavigationShifter.prototype.next = function(sel) {
- var ret = this.currentWalker_.next(sel);
- if (this.currentWalkerIndex_ <= cvox.NavigationShifter.GRANULARITIES.LINE &&
- ret) {
- cvox.TraverseContent.getInstance().syncToCursorSelection(
- ret.clone().setReversed(false));
- cvox.TraverseContent.getInstance().updateSelection();
- }
- return ret;
-};
-
-
-/**
- * @override
- */
-cvox.NavigationShifter.prototype.sync = function(sel) {
- return this.currentWalker_.sync(sel);
-};
-
-
-/**
- * @override
- */
-cvox.NavigationShifter.prototype.getName = function() {
- return Msgs.getMsg('navigation_shifter');
-};
-
-
-/**
- * @override
- */
-cvox.NavigationShifter.prototype.getDescription = function(prevSel, sel) {
- return this.currentWalker_.getDescription(prevSel, sel);
-};
-
-
-/**
- * Gets the braille representation of a node-based selection.
- * @override
- */
-cvox.NavigationShifter.prototype.getBraille = function(prevSel, sel) {
- return this.lineWalker_.getBraille(prevSel, sel);
-};
-
-
-/**
- * Delegates to currentWalker_.
- * @return {string} The message string.
- */
-cvox.NavigationShifter.prototype.getGranularityMsg = function() {
- return this.currentWalker_.getGranularityMsg();
-};
-
-
-/**
- * @override
- */
-cvox.NavigationShifter.prototype.makeMoreGranular = function() {
- goog.base(this, 'makeMoreGranular');
- this.currentWalkerIndex_ = Math.max(this.currentWalkerIndex_ - 1, 0);
- if (!cvox.NavigationShifter.allowSentence && this.currentWalkerIndex_ ==
- cvox.NavigationShifter.GRANULARITIES.SENTENCE) {
- this.currentWalkerIndex_--;
- }
- this.currentWalker_ = this.walkers_[this.currentWalkerIndex_];
-};
-
-/**
- * @override
- */
-cvox.NavigationShifter.prototype.makeLessGranular = function() {
- goog.base(this, 'makeLessGranular');
- this.currentWalkerIndex_ =
- Math.min(this.currentWalkerIndex_ + 1, this.walkers_.length - 1);
- if (!cvox.NavigationShifter.allowSentence && this.currentWalkerIndex_ ==
- cvox.NavigationShifter.GRANULARITIES.SENTENCE) {
- this.currentWalkerIndex_++;
- }
- this.currentWalker_ = this.walkers_[this.currentWalkerIndex_];
-};
-
-/**
- * Shift to a specified granularity.
- * NOTE: after a shift, we are no longer subnavigating, if we were.
- * @param {number} granularity The granularity to shift to.
- */
-cvox.NavigationShifter.prototype.setGranularity = function(granularity) {
- this.ensureNotSubnavigating();
- this.currentWalkerIndex_ = granularity;
- this.currentWalker_ = this.walkers_[this.currentWalkerIndex_];
-};
-
-/**
- * Gets the granularity.
- * @return {number} The current granularity.
- *
- */
-cvox.NavigationShifter.prototype.getGranularity = function() {
- var wasSubnavigating = this.isSubnavigating();
- this.ensureNotSubnavigating();
- var ret = this.currentWalkerIndex_;
- if (wasSubnavigating) {
- this.ensureSubnavigating();
- }
- return ret;
-};
-
-
-/** Actions. */
-/**
- * @override
- */
-cvox.NavigationShifter.prototype.hasAction = function(name) {
- if (name == 'toggleLineType') {
- return true;
- }
- return goog.base(this, 'hasAction', name);
-};
-
-
-/**
- * @override
- */
-cvox.NavigationShifter.create = function(sel) {
- return new cvox.NavigationShifter();
-};
-
-
-/**
- * Resets navigation shifter to a "new" state. Makes testing easier.
- * @private
- */
-cvox.NavigationShifter.prototype.reset_ = function() {
- this.groupWalker_ = new cvox.GroupWalker();
- this.objectWalker_ = new cvox.ObjectWalker();
- this.sentenceWalker_ = new cvox.SentenceWalker();
- this.lineWalker_ = new cvox.LayoutLineWalker();
- this.wordWalker_ = new cvox.WordWalker();
- this.characterWalker_ = new cvox.CharacterWalker();
-
- this.walkers_ = [
- this.characterWalker_,
- this.wordWalker_,
- this.lineWalker_,
- this.sentenceWalker_,
- this.objectWalker_,
- this.groupWalker_
- ];
- this.currentWalkerIndex_ = this.walkers_.indexOf(this.groupWalker_);
-
- /**
- * @type {cvox.AbstractWalker}
- * @private
- */
- this.currentWalker_ = this.walkers_[this.currentWalkerIndex_];
-};
-
-
-/**
- * @type {boolean}
- */
-cvox.NavigationShifter.allowSentence = false;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_speaker.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_speaker.js
deleted file mode 100644
index 6de2b8559d7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_speaker.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for speaking navigation information.
- */
-
-
-goog.provide('cvox.NavigationSpeaker');
-
-goog.require('cvox.NavDescription');
-
-/**
- * @constructor
- */
-cvox.NavigationSpeaker = function() {
- /**
- * This member indicates to this speaker to cancel any pending callbacks.
- * This is needed primarily to support cancelling a chain of callbacks by an
- * outside caller. There's currently no way to cancel a chain of callbacks in
- * any other way. Consider removing this if we ever get silence at the tts
- * layer.
- * @type {boolean}
- */
- this.stopReading = false;
-
- /**
- * An identifier that tracks the calls to speakDescriptionArray. Used to
- * cancel a chain of callbacks that is stale.
- * @type {number}
- * @private
- */
- this.id_ = 1;
-};
-
-/**
- * Speak all of the NavDescriptions in the given array (as returned by
- * getDescription), including playing earcons.
- *
- * @param {Array<cvox.NavDescription>} descriptionArray The array of
- * NavDescriptions to speak.
- * @param {number} initialQueueMode The initial queue mode.
- * @param {Function} completionFunction Function to call when finished speaking.
- */
-cvox.NavigationSpeaker.prototype.speakDescriptionArray = function(
- descriptionArray, initialQueueMode, completionFunction) {
- descriptionArray = this.reorderAnnotations(descriptionArray);
-
- this.stopReading = false;
- this.id_ = (this.id_ + 1) % 10000;
-
- // Using self rather than goog.bind in order to get debug symbols.
- var self = this;
- var speakDescriptionChain = function(i, queueMode, id) {
- var description = descriptionArray[i];
- if (!description || self.stopReading || self.id_ != id) {
- return;
- }
- var startCallback = function() {
- for (var j = 0; j < description.earcons.length; j++) {
- cvox.ChromeVox.earcons.playEarcon(description.earcons[j]);
- }
- };
- var endCallbackHelper = function() {
- speakDescriptionChain(i + 1, cvox.QueueMode.QUEUE, id);
- };
- var endCallback = function() {
- // We process content-script specific properties here for now.
- if (description.personality &&
- description.personality[cvox.AbstractTts.PAUSE] &&
- typeof(description.personality[cvox.AbstractTts.PAUSE]) == 'number') {
- setTimeout(
- endCallbackHelper, description.personality[cvox.AbstractTts.PAUSE]);
- } else {
- endCallbackHelper();
- }
- if ((i == descriptionArray.length - 1) && completionFunction) {
- completionFunction();
- }
- };
- if (!description.isEmpty()) {
- description.speak(queueMode, startCallback, endCallback);
- } else {
- startCallback();
- endCallback();
- return;
- }
- if (!cvox.ChromeVox.host.hasTtsCallback()) {
- startCallback();
- endCallback();
- }
- };
-
- speakDescriptionChain(0, initialQueueMode, this.id_);
-
- if ((descriptionArray.length == 0) && completionFunction) {
- completionFunction();
- }
-};
-
-
-/**
- * Checks for an annotation of a structured elements.
- * @param {string} annon The annotation.
- * @return {boolean} True if annotating a structured element.
- */
-cvox.NavigationSpeaker.structuredElement = function(annon) {
- // TODO(dtseng, sorge): This doesn't work for languages other than English.
- switch (annon) {
- case 'table':
- case 'Math':
- return true;
- }
- return false;
-};
-
-
-/**
- * Reorder special annotations for structured elements to be spoken first.
- * @param {Array<cvox.NavDescription>} descriptionArray The array of
- * NavDescriptions to speak.
- * @return {Array<cvox.NavDescription>} The reordered array.
- */
-cvox.NavigationSpeaker.prototype.reorderAnnotations = function(
- descriptionArray) {
- var descs = new Array;
- for (var i = 0; i < descriptionArray.length; i++) {
- var descr = descriptionArray[i];
- if (cvox.NavigationSpeaker.structuredElement(descr.annotation)) {
- descs.push(new cvox.NavDescription({
- text: '',
- annotation: descr.annotation
- }));
- descr.annotation = '';
- }
- descs.push(descr);
- }
- return descs;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/node_breadcrumb.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/node_breadcrumb.js
deleted file mode 100644
index e61b11a4079..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/node_breadcrumb.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Responsible for tagging nodes used by ChromeVox.
- */
-
-goog.provide('cvox.NodeBreadcrumb');
-
-goog.require('cvox.ChromeVox');
-
-
-
-/**
- * Responsible for tagging nodes and tracking those nodes.
- * @constructor
- */
-cvox.NodeBreadcrumb = function() {
- /**
- * Counter to be incremented each time HistoryEvent tries to tag a previously
- * untagged node.
- * @type {number}
- */
- this.cvTagCounter_ = 0;
-};
-goog.addSingletonGetter(cvox.NodeBreadcrumb);
-
-/**
- * The attribute to mark nodes that have been touched, and in what order.
- * @type {string}
- * @const
- * NOTE: not private because tester is using this
- */
-cvox.NodeBreadcrumb.TOUCHED_TAG = 'chromevoxtag';
-
-/**
- * The attribute to mark nodes needed to replicate results with.
- * @type {string}
- * @const
- * @private
- */
-cvox.NodeBreadcrumb.NEEDED_TAG_ = 'chromevoxneeded';
-
-
-/**
- * Tags the current node.
- * @return {number} The tag number.
- */
-cvox.NodeBreadcrumb.prototype.tagCurrentNode = function() {
- var cvTag;
- var currentNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- while (currentNode && !currentNode.hasAttribute) {
- currentNode = currentNode.parentNode;
- }
- if (!currentNode) {
- cvTag = -1;
- } else if (currentNode.hasAttribute(cvox.NodeBreadcrumb.TOUCHED_TAG)) {
- cvTag = currentNode.getAttribute(cvox.NodeBreadcrumb.TOUCHED_TAG);
- } else {
- cvTag = this.cvTagCounter_;
- currentNode.setAttribute(cvox.NodeBreadcrumb.TOUCHED_TAG, cvTag);
- this.cvTagCounter_++;
- }
- return cvTag;
-};
-
-
-/**
- * Marks all elements that need to be in the test case, starting at the
- * elements that have been tagged.
- * @param {Node} node Root of the subtree which to mark.
- * @private
- */
-cvox.NodeBreadcrumb.prototype.smartStart_ = function(node) {
- for (var i = 0; i < node.children.length; ++i) {
- var child = node.children[i];
- this.smartStart_(child);
- if (child.getAttribute &&
- !goog.isNull(child.getAttribute(cvox.NodeBreadcrumb.TOUCHED_TAG))) {
- this.setNeeded_(child);
- }
- }
-};
-
-
-/**
- * Recursively marks all elements that need to be in the test case.
- * Note: modifies the node passed in.
- * @param {Node} node The node to mark.
- * @private
- */
-cvox.NodeBreadcrumb.prototype.setNeeded_ = function(node) {
- if (!node) {
- return;
- }
-
- if (node.getAttribute &&
- goog.isNull(node.getAttribute(cvox.NodeBreadcrumb.NEEDED_TAG_))) {
- node.setAttribute(cvox.NodeBreadcrumb.NEEDED_TAG_, true);
-
- // only the parent needs to be added
- // if the siblings are needed, then some ancestor
- // would have had chromevoxtag set, in which case
- // we copy the whole subtree of that ancestor anyways
- if (node.nodeName !== 'body') {
- this.setNeeded_(node.parentElement);
- }
- }
-};
-
-
-/**
- * Clones the part of the dom that is needed to recreate the test case.
- * The nodes must have been marked first by calling smartStart_.
- * @param {Node|Text} node The root of the subtree to clone.
- * @return {Node|Text} The cloned subtree.
- * @private
- */
-cvox.NodeBreadcrumb.prototype.smartClone_ = function(node) {
- var skipattrs = {};
- skipattrs[cvox.NodeBreadcrumb.TOUCHED_TAG] = true;
- skipattrs[cvox.NodeBreadcrumb.NEEDED_TAG_] = true;
-
- if (node.getAttribute && node.getAttribute(cvox.NodeBreadcrumb.TOUCHED_TAG)) {
- return cvox.DomUtil.deepClone(node, skipattrs);
- }
-
- var ret = cvox.DomUtil.shallowChildlessClone(node, skipattrs);
-
- for (var i = 0; i < node.childNodes.length; ++i) {
- var child = node.childNodes[i];
- if (child.getAttribute &&
- !goog.isNull(child.getAttribute(cvox.NodeBreadcrumb.NEEDED_TAG_))) {
- ret.appendChild(this.smartClone_(child));
- }
- }
- return ret;
-};
-
-
-/**
- * Returns a sting containing the html needed to replicate the test.
- * @return {Node} The subset of the dom that was walked.
- */
-cvox.NodeBreadcrumb.prototype.dumpWalkedDom = function() {
- this.smartStart_(document.body);
- return this.smartClone_(document.body);
-};
-
-
-/**
- * Retrieves the ChromeVox tag for the current node.
- *
- * @return {number} The ChromeVox tag or -1 if there is an error.
- */
-cvox.NodeBreadcrumb.getCurrentNodeTag = function() {
- var currentNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- while (currentNode && !currentNode.hasAttribute) {
- currentNode = currentNode.parentNode;
- }
- if (currentNode && currentNode.hasAttribute(cvox.NodeBreadcrumb.TOUCHED_TAG)) {
- return currentNode.getAttribute(cvox.NodeBreadcrumb.TOUCHED_TAG);
- } else {
- return -1;
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/pdf_processor.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/pdf_processor.js
deleted file mode 100644
index 92650ce0bb2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/pdf_processor.js
+++ /dev/null
@@ -1,251 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Logic to process PDFs
- */
-
-goog.provide('cvox.PdfProcessor');
-goog.require('cvox.QueueMode');
-
-/**
- * The array of PDFs yet to process.
- * @type {Array<HTMLEmbedElement>}
- */
-cvox.PdfProcessor.pdfEmbeds = [];
-
-/**
- * The current PDF we're processing, or null if we're not processing one.
- * @type {HTMLEmbedElement}
- */
-cvox.PdfProcessor.pdfEmbed = null;
-
-/**
- * The number of pages in the current PDF, or null if we haven't
- * retreived that yet.
- * @type {?number}
- */
-cvox.PdfProcessor.pageCount = null;
-
-/**
- * The 0-based index of the page we're currently retrieving, or null
- * if we don't know how many pages there are yet.
- * @type {?number}
- */
-cvox.PdfProcessor.pageIndex = null;
-
-/**
- * The element on the page where all of the generated content from the PDF
- * will go, or null if we're not currently processing a PDF.
- * @type {Element}
- */
-cvox.PdfProcessor.documentDiv = null;
-
-/**
- * Process PDFs created with Chrome's built-in PDF plugin, which has an
- * accessibility hook.
- */
-cvox.PdfProcessor.processEmbeddedPdfs = function() {
- if (window.location.hash == '#original') {
- return;
- }
-
- var pdfEmbeds = document.querySelectorAll('embed[type="application/pdf"]');
- if (pdfEmbeds.length == 0) {
- return;
- }
-
- // Convert it to an Array so we can slice off one at a time, and stick
- // it in a class variable. The responses from the plug-in come as a
- // generic 'message' event to the window with no context, so we have
- // to use global state to keep track of progress.
- cvox.PdfProcessor.pdfEmbeds = Array.prototype.slice.call(pdfEmbeds);
-
- // Install our event listener for responses.
- window.addEventListener('message',
- /** @type {EventListener} */(cvox.PdfProcessor.onMessage));
-
- // Start processing the first one.
- cvox.PdfProcessor.processNextPdf();
-};
-
-/**
- * Pull off the next <embed> element from |cvox.PdfProcessor.pdfEmbeds|
- * and send a message to it to begin processing. If there are no more
- * elements in the array, remove the event listener and reset
- * NavigationManager so that it lands at the top of the now-modified page.
- */
-cvox.PdfProcessor.processNextPdf = function() {
- if (cvox.PdfProcessor.pdfEmbeds.length == 0) {
- window.removeEventListener('message',
- /** @type {EventListener} */(cvox.PdfProcessor.onMessage));
- cvox.PdfProcessor.pdfEmbeds = null;
- cvox.PdfProcessor.pdfEmbed = null;
-
- cvox.ChromeVox.navigationManager.reset();
- return;
- }
-
- cvox.PdfProcessor.pdfEmbed = cvox.PdfProcessor.pdfEmbeds.shift();
- cvox.PdfProcessor.pageCount = null;
- cvox.PdfProcessor.pageIndex = null;
- cvox.PdfProcessor.pdfEmbed.postMessage({'type': 'getAccessibilityJSON'});
-};
-
-/**
- * Handler for the 'message' event on the window, which is how we get responses
- * from Chrome's PDF plugin.
- *
- * @param {{data: {type: string, json: string}}} message The message from the
- * PDF plugin containing a type identifier and JSON string.
- */
-cvox.PdfProcessor.onMessage = function(message) {
- // Exit if it's not an accessibility JSON reply message.
- if (message.data.type != 'getAccessibilityJSONReply') {
- return;
- }
-
- // Exit if we aren't in the middle of processing a PDF.
- if (!cvox.PdfProcessor.pdfEmbed) {
- return;
- }
-
- // Parse the JSON.
- var info = /** @type {PDFAccessibilityJSONReply} */(
- JSON.parse(message.data.json));
-
- // If we already know how many pages are in the doc, we expect this message
- // contains the data for one particular page.
- if (cvox.PdfProcessor.pageCount !== null) {
- cvox.PdfProcessor.processOnePage(info);
- return;
- }
-
- // If not, we expect this message contains the info about the PDF overall:
- // whether it's loaded, whether it's copyable, and how many total pages
- // there are.
- if (!info.loaded) {
- cvox.PdfProcessor.pdfEmbeds.unshift(cvox.PdfProcessor.pdfEmbed);
- cvox.PdfProcessor.pdfEmbed = null;
- window.setTimeout(cvox.PdfProcessor.processNextPdf, 100);
- return;
- }
-
- // Create the initial HTML skeleton.
- cvox.PdfProcessor.documentDiv = document.createElement('DIV');
- var headerDiv = document.createElement('DIV');
- headerDiv.style.position = 'relative';
- headerDiv.style.background = 'white';
- headerDiv.style.margin = '20pt';
- headerDiv.style.padding = '20pt';
- headerDiv.style.border = '1px solid #000';
- var src = cvox.PdfProcessor.pdfEmbed.src;
- var filename = src.substr(src.lastIndexOf('/') + 1);
- document.title = filename;
- var html = Msgs.getMsg('pdf_header', [filename, src + '#original']);
- headerDiv.innerHTML = html;
- // Set up a handler to reload the page when 'Show original' is clicked.
- var showLink = headerDiv.getElementsByTagName('a')[0];
- showLink.addEventListener('click', function() {
- window.location.href = src + '#original';
- window.location.reload();
- }, true);
- cvox.PdfProcessor.documentDiv.appendChild(headerDiv);
- cvox.PdfProcessor.documentDiv.style.position = 'relative';
- cvox.PdfProcessor.documentDiv.style.background = '#CCC';
- cvox.PdfProcessor.documentDiv.style.paddingTop = '1pt';
- cvox.PdfProcessor.documentDiv.style.paddingBottom = '1pt';
- cvox.PdfProcessor.documentDiv.style.width = '100%';
- cvox.PdfProcessor.documentDiv.style.minHeight = '100%';
-
- if (!info.copyable) {
- var alert = document.createElement('div');
- alert.setAttribute('role', 'alert');
- alert.innerText = Msgs.getMsg('copy_protected_pdf');
- cvox.PdfProcessor.documentDiv.appendChild(alert);
- cvox.PdfProcessor.pdfEmbed.parentElement.appendChild(
- cvox.PdfProcessor.documentDiv);
- return;
- }
-
- // Start processing the first page.
- cvox.PdfProcessor.pageCount = info.numberOfPages;
- cvox.PdfProcessor.pageIndex = -1;
- cvox.PdfProcessor.getNextPage();
-};
-
-/**
- * Send a message to the PDF plugin to get the next page. If we've finished
- * getting all of the pages, clean up and get the next PDF in the document.
- */
-cvox.PdfProcessor.getNextPage = function() {
- cvox.PdfProcessor.pageIndex++;
- if (cvox.PdfProcessor.pageIndex >= cvox.PdfProcessor.pageCount) {
- cvox.PdfProcessor.pdfEmbed.style.display = 'none';
- cvox.PdfProcessor.pdfEmbed.parentElement.appendChild(
- cvox.PdfProcessor.documentDiv);
- cvox.PdfProcessor.processNextPdf();
- return;
- }
-
- cvox.PdfProcessor.pdfEmbed.postMessage(
- {'type': 'getAccessibilityJSON',
- 'page': cvox.PdfProcessor.pageIndex});
-};
-
-/**
- * Process one page in the PDF file and turn it into HTML.
- * @param {PDFAccessibilityJSONReply} info The data from one page of the PDF.
- */
-cvox.PdfProcessor.processOnePage = function(info) {
- var pageDiv = document.createElement('DIV');
- var pageAnchor = document.createElement('A');
-
- // Page Achor Setup
- pageAnchor.name = 'page' + cvox.PdfProcessor.pageIndex;
-
- // Page Styles
- pageDiv.style.position = 'relative';
- pageDiv.style.background = 'white';
- pageDiv.style.margin = 'auto';
- pageDiv.style.marginTop = '20pt';
- pageDiv.style.marginBottom = '20pt';
- pageDiv.style.height = info.height + 'pt';
- pageDiv.style.width = info.width + 'pt';
- pageDiv.style.boxShadow = '0pt 0pt 10pt #333';
-
- // Text Nodes
- var texts = info.textBox;
- for (var j = 0; j < texts.length; j++) {
- var text = texts[j];
- var textSpan = document.createElement('Span');
-
- // Text Styles
- textSpan.style.position = 'absolute';
- textSpan.style.left = text.left + 'pt';
- textSpan.style.top = text.top + 'pt';
- textSpan.style.fontSize = (0.8 * text.height) + 'pt';
-
- // Text Content
- for (var k = 0; k < text.textNodes.length; k++) {
- var node = text.textNodes[k];
- if (node.type == 'text') {
- textSpan.appendChild(document.createTextNode(node.text));
- } else if (node.type == 'url') {
- var a = document.createElement('A');
- a.href = node.url;
- a.appendChild(document.createTextNode(node.text));
- textSpan.appendChild(a);
- }
- }
-
- pageDiv.appendChild(textSpan);
- }
- cvox.PdfProcessor.documentDiv.appendChild(pageAnchor);
- cvox.PdfProcessor.documentDiv.appendChild(pageDiv);
-
- // Now get the next page.
- cvox.PdfProcessor.getNextPage();
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/script_installer.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/script_installer.js
deleted file mode 100644
index a76e503688c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/script_installer.js
+++ /dev/null
@@ -1,109 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Defines the ScriptInstaller functions which install scripts
- * into the web page (not a content script)
- *
- */
-
-goog.provide('cvox.ScriptInstaller');
-
-goog.require('cvox.DomUtil');
-
-/**
- * URL pattern where we do not allow script installation.
- * @type {RegExp}
- */
-cvox.ScriptInstaller.blacklistPattern = /chrome:\/\/|chrome-extension:\/\//;
-
-/**
- * Installs a script in the web page.
- * @param {Array<string>} srcs An array of URLs of scripts.
- * @param {string} uid A unique id. This function won't install the same set of
- * scripts twice.
- * @param {function()=} opt_onload A function called when the last script
- * has loaded.
- * @param {string=} opt_chromevoxScriptBase An optional chromevoxScriptBase
- * attribute to add.
- * @return {boolean} False if the script already existed and this function
- * didn't do anything.
- */
-cvox.ScriptInstaller.installScript = function(srcs, uid, opt_onload,
- opt_chromevoxScriptBase) {
- if (cvox.ScriptInstaller.blacklistPattern.test(document.URL)) {
- return false;
- }
- if (document.querySelector('script[' + uid + ']')) {
- return false;
- }
- if (!srcs || srcs.length == 0) {
- return false;
- }
-
- cvox.ScriptInstaller.installScriptHelper_(srcs, uid, opt_onload,
- opt_chromevoxScriptBase);
- return true;
-};
-
-/**
- * Helper that installs one script and calls itself recursively when each
- * script loads.
- * @param {Array<string>} srcs An array of URLs of scripts.
- * @param {string} uid A unique id. This function won't install the same set of
- * scripts twice.
- * @param {function()=} opt_onload A function called when the
- * last script has loaded.
- * @param {string=} opt_chromevoxScriptBase An optional chromevoxScriptBase
- * attribute to add.
- * @private
- */
-cvox.ScriptInstaller.installScriptHelper_ = function(srcs, uid, opt_onload,
- opt_chromevoxScriptBase) {
- function next() {
- if (srcs.length > 0) {
- cvox.ScriptInstaller.installScriptHelper_(srcs, uid, opt_onload,
- opt_chromevoxScriptBase);
- } else if (opt_onload) {
- opt_onload();
- }
- }
-
- var scriptSrc = srcs.shift();
- if (!scriptSrc) {
- next();
- return;
- }
-
- var xhr = new XMLHttpRequest();
- var url = scriptSrc + '?' + new Date().getTime();
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- var scriptText = xhr.responseText;
- // Add a magic comment to the bottom of the file so that
- // Chrome knows the name of the script in the JavaScript debugger.
- scriptText += '\n//# sourceURL=' + scriptSrc + '\n';
-
- var apiScript = document.createElement('script');
- apiScript.type = 'text/javascript';
- apiScript.setAttribute(uid, '1');
- apiScript.textContent = scriptText;
- if (opt_chromevoxScriptBase) {
- apiScript.setAttribute('chromevoxScriptBase',
- opt_chromevoxScriptBase);
- }
- cvox.DomUtil.addNodeToHead(apiScript);
- next();
- }
- };
-
- try {
- xhr.open('GET', url, true);
- xhr.send(null);
- } catch (exception) {
- console.log('Warning: ChromeVox external script loading for ' +
- document.location + ' stopped after failing to install ' + scriptSrc);
- next();
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/serializer.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/serializer.js
deleted file mode 100644
index 619533686b5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/serializer.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A global serializer object which returns the current
- * ChromeVox system state.
- */
-
-goog.provide('cvox.Serializer');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxEventWatcher');
-
-/**
- * @constructor
- */
-cvox.Serializer = function() { };
-
-/**
- * Stores state variables in a provided object.
- *
- * @param {Object} store The object.
- */
-cvox.Serializer.prototype.storeOn = function(store) {
- cvox.ChromeVox.storeOn(store);
- cvox.ChromeVoxEventWatcher.storeOn(store);
- cvox.ChromeVox.navigationManager.storeOn(store);
-};
-
-/**
- * Updates the object with state variables from an earlier storeOn call.
- *
- * @param {Object} store The object.
- */
-cvox.Serializer.prototype.readFrom = function(store) {
- cvox.ChromeVox.readFrom(store);
- cvox.ChromeVoxEventWatcher.readFrom(store);
- cvox.ChromeVox.navigationManager.readFrom(store);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/braille_overlay_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/braille_overlay_widget.js
deleted file mode 100644
index cf3e5933d6b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/braille_overlay_widget.js
+++ /dev/null
@@ -1,184 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Overlay that shows the current braille display contents,
- * both as text and braille, on screen in a document.
- */
-
-goog.provide('cvox.BrailleOverlayWidget');
-
-goog.require('cvox.ExtensionBridge');
-
-/**
- * @constructor
- */
-cvox.BrailleOverlayWidget = function() {
- /**
- * Whether the widget is active in the prefs.
- * @type {boolean}
- * @private
- */
- this.active_ = false;
- /**
- * @type {Element}
- * @private
- */
- this.containerNode_ = null;
- /**
- * @type {Element}
- * @private
- */
- this.contentNode_ = null;
- /**
- * @type {Element}
- * @private
- */
- this.brailleNode_ = null;
-};
-goog.addSingletonGetter(cvox.BrailleOverlayWidget);
-
-
-/**
- * One-time initializer, to be called in a top-level document. Adds a
- * listener for braille content messages from the background page.
- */
-cvox.BrailleOverlayWidget.prototype.init = function() {
- cvox.ExtensionBridge.addMessageListener(goog.bind(
- this.onMessage_, this));
-};
-
-
-/**
- * Sets whether the overlay is active and hides it if it is not active.
- * @param {boolean} value Whether the overlay is active.
- */
-cvox.BrailleOverlayWidget.prototype.setActive = function(value) {
- this.active_ = value;
- if (!value) {
- this.hide_();
- }
-};
-
-
-/**
- * @return {boolean} Whether the overlay is active according to prefs.
- */
-cvox.BrailleOverlayWidget.prototype.isActive = function() {
- return this.active_;
-};
-
-
-/** @private */
-cvox.BrailleOverlayWidget.prototype.show_ = function() {
- var containerNode = this.createContainerNode_();
- this.containerNode_ = containerNode;
-
- var overlayNode = this.createOverlayNode_();
- containerNode.appendChild(overlayNode);
-
- this.contentNode_ = document.createElement('div');
- this.brailleNode_ = document.createElement('div');
-
- overlayNode.appendChild(this.contentNode_);
- overlayNode.appendChild(this.brailleNode_);
-
- document.body.appendChild(containerNode);
-
- window.setTimeout(function() {
- containerNode.style['opacity'] = '1.0';
- }, 0);
-};
-
-
-/**
- * Hides the overlay if it is shown.
- * @private
- */
-// TODO(plundblad): Call when chromevox is deactivated and on some
-// window focus changes.
-cvox.BrailleOverlayWidget.prototype.hide_ = function() {
- if (this.containerNode_) {
- var containerNode = this.containerNode_;
- containerNode.style.opacity = '0.0';
- window.setTimeout(function() {
- document.body.removeChild(containerNode);
- }, 1000);
- this.containerNode_ = null;
- this.contentNode_ = null;
- this.brailleNode_ = null;
- }
-};
-
-
-/**
- * @param {string} text The text represnting what was output on the display.
- * @param {string} brailleChars The Unicode characters representing the
- * braille patterns currently on the display.
- * @private
- */
-cvox.BrailleOverlayWidget.prototype.setContent_ = function(text, brailleChars) {
- if (!this.contentNode_) {
- this.show_();
- }
- this.contentNode_.textContent = text;
- this.brailleNode_.textContent = brailleChars;
-};
-
-
-/**
- * Create the container node for the braille overlay.
- *
- * @return {!Element} The new element, not yet added to the document.
- * @private
- */
-cvox.BrailleOverlayWidget.prototype.createContainerNode_ = function() {
- var containerNode = document.createElement('div');
- containerNode.id = 'cvox-braille-overlay';
- containerNode.style['position'] = 'fixed';
- containerNode.style['top'] = '50%';
- containerNode.style['left'] = '50%';
- containerNode.style['-webkit-transition'] = 'all 0.3s ease-in';
- containerNode.style['opacity'] = '0.0';
- containerNode.style['z-index'] = '2147483647';
- containerNode.setAttribute('aria-hidden', 'true');
- return containerNode;
-};
-
-
-/**
- * Create the braille overlay. This should be a child of the node
- * returned from createContainerNode.
- *
- * @return {!Element} The new element, not yet added to the document.
- * @private
- */
-cvox.BrailleOverlayWidget.prototype.createOverlayNode_ = function() {
- var overlayNode = document.createElement('div');
- overlayNode.style['position'] = 'fixed';
- overlayNode.style['left'] = '40px';
- overlayNode.style['bottom'] = '20px';
- overlayNode.style['line-height'] = '1.2em';
- overlayNode.style['font-size'] = '20px';
- overlayNode.style['font-family'] = 'monospace';
- overlayNode.style['padding'] = '30px';
- overlayNode.style['min-width'] = '150px';
- overlayNode.style['color'] = '#fff';
- overlayNode.style['background-color'] = 'rgba(0, 0, 0, 0.7)';
- overlayNode.style['border-radius'] = '10px';
- return overlayNode;
-};
-
-
-/**
- * Listens for background page messages and show braille content when it
- * arrives.
- * @param {Object} msg Message from background page.
- * @private
- */
-cvox.BrailleOverlayWidget.prototype.onMessage_ = function(msg) {
- if (msg['message'] == 'BRAILLE_CAPTION') {
- this.setContent_(msg['text'], msg['brailleChars']);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/context_menu_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/context_menu_widget.js
deleted file mode 100644
index 7ea962a15a1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/context_menu_widget.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Widget presenting context menus.
- */
-
-goog.provide('cvox.ContextMenuWidget');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.OverlayWidget');
-goog.require('cvox.UserEventDetail');
-
-var CONTEXT_MENU_ATTR = 'contextMenuActions';
-/**
- * Return the list from a node or an ancestor.
- * Note: If there are multiple lists, this well return the closest.
- * @private
- * @param {Object} node Node to extract from.
- * @return {*} Extracted list.
- */
-var extractMenuList_ = function(node) {
- var curr = node;
- while (curr !== document) {
- var menuListJSON = curr.getAttribute(CONTEXT_MENU_ATTR);
- if (menuListJSON) {
- return JSON.parse(menuListJSON);
- }
- curr = curr.parentNode;
- }
- return null;
-};
-
-/**
- * Gets the current element node.
- * @private
- * @return {Node} Current element node.
- */
-var getCurrentElement_ = function() {
- var currNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- while (currNode.nodeType !== Node.ELEMENT_NODE) {
- currNode = currNode.parentNode;
- }
- return currNode;
-};
-
-/**
- * @constructor
- * @extends {cvox.OverlayWidget}
- */
-cvox.ContextMenuWidget = function() {
- goog.base(this, '');
- this.container_ = document.createElement('div');
-
- /**
- * The element that triggered the ContextMenu.
- * @private
- * @type {Node}
- */
- this.triggerElement_ = getCurrentElement_();
-
- /**
- * List of menu items in the context menu.
- */
- this.menuList = extractMenuList_(this.triggerElement_);
-
- if (!this.menuList) {
- console.log('No context menu found.');
- return;
- }
-
- this.menuList.forEach(goog.bind(function(menuItem) {
- if (menuItem['desc'] || menuItem['cmd']) {
- var desc = menuItem['desc'];
- var cmd = menuItem['cmd'];
-
- var menuElem = document.createElement('p');
- menuElem.id = cmd;
- menuElem.textContent = desc;
- menuElem.setAttribute('role', 'menuitem');
- this.container_.appendChild(menuElem);
- }
- }, this));
-};
-goog.inherits(cvox.ContextMenuWidget, cvox.OverlayWidget);
-
-/**
- * @override
- */
-cvox.ContextMenuWidget.prototype.show = function() {
- if (this.menuList) {
- goog.base(this, 'show');
- this.host_.appendChild(this.container_);
- }
-};
-
-/**
- * @override
- */
-cvox.ContextMenuWidget.prototype.getNameMsg = function() {
- return ['context_menu_intro'];
-};
-
-/**
- * @override
- */
-cvox.ContextMenuWidget.prototype.onKeyDown = function(evt) {
- var ENTER_KEYCODE = 13;
- if (evt.keyCode == ENTER_KEYCODE) {
- var currentNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- var cmd = currentNode.parentNode.id;
-
- /* Dispatch the event. */
- var detail = new cvox.UserEventDetail({customCommand: cmd});
- var userEvt = detail.createEventObject();
- this.triggerElement_.dispatchEvent(userEvt);
- this.hide();
-
- evt.preventDefault();
- evt.stopPropagation();
- return true;
- } else {
- return goog.base(this, 'onKeyDown', evt);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/keyboard_help_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/keyboard_help_widget.js
deleted file mode 100644
index bde0aab057d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/keyboard_help_widget.js
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Widget presenting all keyboard commands.
- */
-
-goog.provide('cvox.KeyboardHelpWidget');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.CommandStore');
-goog.require('cvox.KeyUtil');
-goog.require('cvox.OverlayWidget');
-
-/**
- * @constructor
- * @extends {cvox.OverlayWidget}
- */
-cvox.KeyboardHelpWidget = function() {
- goog.base(this, '');
- this.container_ = document.createElement('div');
- var list = [];
- var callbacks = [];
- var keymap = cvox.ChromeVoxKbHandler.handlerKeyMap;
-
- keymap.bindings().forEach(goog.bind(function(pair) {
- var command = pair.command;
- var keySeq = pair.sequence;
- var message = command;
- try {
- var id = cvox.CommandStore.messageForCommand(command);
- if (!id) {
- return;
- }
- message = Msgs.getMsg(id);
- } catch (e) {
- // TODO(dtseng): We have some commands that don't have valid message id's.
- }
-
- var commandElement = document.createElement('p');
- commandElement.id = command;
- commandElement.setAttribute('role', 'menuitem');
- commandElement.textContent =
- message + ' - ' + cvox.KeyUtil.keySequenceToString(keySeq, true);
- this.container_.appendChild(commandElement);
- }, this));
-};
-goog.inherits(cvox.KeyboardHelpWidget, cvox.OverlayWidget);
-goog.addSingletonGetter(cvox.KeyboardHelpWidget);
-
-
-/**
- * @override
- */
-cvox.KeyboardHelpWidget.prototype.show = function() {
- goog.base(this, 'show');
- this.host_.appendChild(this.container_);
-};
-
-
-/**
- * @override
- */
-cvox.KeyboardHelpWidget.prototype.getNameMsg = function() {
- return ['keyboard_help_intro'];
-};
-
-/**
- * @override
- */
-cvox.KeyboardHelpWidget.prototype.onKeyDown = function(evt) {
- if (evt.keyCode == 13) { // Enter
- var currentCommand =
- cvox.ChromeVox.navigationManager.getCurrentNode().parentNode.id;
- this.hide();
- cvox.ChromeVoxEventSuspender.withSuspendedEvents(
- cvox.ChromeVoxUserCommands.commands[currentCommand])();
- evt.preventDefault();
- evt.stopPropagation();
- return true;
- } else {
- return goog.base(this, 'onKeyDown', evt);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/node_search_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/node_search_widget.js
deleted file mode 100644
index 93adad76da4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/node_search_widget.js
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A search Widget presenting a list of nodes with the ability
- * to sync selection when chosen.
- */
-
-goog.provide('cvox.NodeSearchWidget');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.DomUtil');
-goog.require('cvox.SearchWidget');
-
-
-/**
- * @constructor
- * @param {string} typeMsg A message id identifying the type of items
- * contained in the list.
- * @param {?function(Array<Node>)} predicate A predicate; if null, no predicate
- * applies.
- * @extends {cvox.SearchWidget}
- */
-cvox.NodeSearchWidget = function(typeMsg, predicate) {
- this.typeMsg_ = typeMsg;
- this.predicate_ = predicate;
- goog.base(this);
-};
-goog.inherits(cvox.NodeSearchWidget, cvox.SearchWidget);
-
-
-/**
- * @override
- */
-cvox.NodeSearchWidget.prototype.getNameMsg = function() {
- return ['choice_widget_name', [Msgs.getMsg(this.typeMsg_)]];
-};
-
-
-/**
- * @override
- */
-cvox.NodeSearchWidget.prototype.getHelpMsg = function() {
- return 'choice_widget_help';
-};
-
-
-/**
- * @override
- */
-cvox.NodeSearchWidget.prototype.getPredicate = function() {
- return this.predicate_;
-};
-
-
-/**
- * Shows a list generated dynamic satisfying some predicate.
- * @param {string} typeMsg The message id of the type contained in nodes.
- * @param {function(Array<Node>)} predicate The predicate.
- * @return {cvox.NodeSearchWidget} The widget.
- */
-cvox.NodeSearchWidget.create = function(typeMsg, predicate) {
- return new cvox.NodeSearchWidget(typeMsg, predicate);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/overlay_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/overlay_widget.js
deleted file mode 100644
index d40c7af406b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/overlay_widget.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A widget hosting an HTML snippet.
- */
-
-goog.provide('cvox.OverlayWidget');
-
-goog.require('cvox.DomUtil');
-goog.require('cvox.SearchWidget');
-
-
-/**
- * @param {string} snippet The HTML snippet to render.
- * @constructor
- * @extends {cvox.SearchWidget}
- */
-cvox.OverlayWidget = function(snippet) {
- goog.base(this);
- this.snippet_ = snippet;
-};
-goog.inherits(cvox.OverlayWidget, cvox.SearchWidget);
-
-
-/**
- * @override
- */
-cvox.OverlayWidget.prototype.show = function() {
- goog.base(this, 'show');
- var host = document.createElement('DIV');
- host.innerHTML = this.snippet_;
-
- // Position the overlay over the current ChromeVox selection.
- var hitPoint = cvox.DomUtil.elementToPoint(
- cvox.ChromeVox.navigationManager.getCurrentNode());
- host.style.position = 'absolute';
- host.style.left = hitPoint.x;
- host.style.top = hitPoint.y;
-
- document.body.appendChild(host);
- cvox.ChromeVox.navigationManager.updateSelToArbitraryNode(host);
- this.host_ = host;
-};
-
-
-/**
- * @override
- */
-cvox.OverlayWidget.prototype.hide = function(opt_noSync) {
- this.host_.remove();
- goog.base(this, 'hide');
-};
-
-
-/**
- * @override
- */
-cvox.OverlayWidget.prototype.onKeyDown = function(evt) {
- // Allow the base class to handle all keys first.
- goog.base(this, 'onKeyDown', evt);
-
- // Do not interfere with any key that exits the widget.
- if (evt.keyCode == 13 || evt.keyCode == 27) { // Enter or escape.
- return true;
- }
-
- // Bound navigation within the snippet for any other key.
- var r = cvox.ChromeVox.navigationManager.isReversed();
- if (!cvox.DomUtil.isDescendantOfNode(
- cvox.ChromeVox.navigationManager.getCurrentNode(), this.host_)) {
- if (r) {
- cvox.ChromeVox.navigationManager.syncToBeginning();
- } else {
- cvox.ChromeVox.navigationManager.updateSelToArbitraryNode(this.host_);
- }
- this.onNavigate();
- cvox.ChromeVox.navigationManager.speakDescriptionArray(
- cvox.ChromeVox.navigationManager.getDescription(),
- cvox.QueueMode.FLUSH, null);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/search_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/search_widget.js
deleted file mode 100644
index 410813aaed0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/search_widget.js
+++ /dev/null
@@ -1,540 +0,0 @@
-// 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.
-
-/**
- * @fileoverview JavaScript for poppup up a search widget and performing
- * search within a page.
- */
-
-goog.provide('cvox.SearchWidget');
-
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.ApiImplementation');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.NavigationManager');
-goog.require('cvox.SpokenMessages');
-goog.require('cvox.Widget');
-
-
-/**
- * Initializes the search widget.
- * @constructor
- * @extends {cvox.Widget}
- */
-cvox.SearchWidget = function() {
- /**
- * @type {Element}
- * @private
- */
- this.containerNode_ = null;
-
- /**
- * @type {Element}
- * @private
- */
- this.txtNode_ = null;
-
- /**
- * @type {string}
- * @const
- * @private
- */
- this.PROMPT_ = 'Search:';
-
- /**
- * @type {boolean}
- * @private
- */
- this.caseSensitive_ = false;
-
- /**
- * @type {boolean}
- * @private
- */
- this.hasMatch_ = false;
- goog.base(this);
-};
-goog.inherits(cvox.SearchWidget, cvox.Widget);
-goog.addSingletonGetter(cvox.SearchWidget);
-
-
-/**
- * @override
- */
-cvox.SearchWidget.prototype.show = function() {
- goog.base(this, 'show');
- this.active = true;
- this.hasMatch_ = false;
- cvox.ChromeVox.navigationManager.setGranularity(
- cvox.NavigationShifter.GRANULARITIES.OBJECT, true, false);
-
- // Always start search forward.
- cvox.ChromeVox.navigationManager.setReversed(false);
-
- // During profiling, NavigationHistory was found to have a serious performance
- // impact on search.
- this.focusRecovery_ = cvox.ChromeVox.navigationManager.getFocusRecovery();
- cvox.ChromeVox.navigationManager.setFocusRecovery(false);
-
- var containerNode = this.createContainerNode_();
- this.containerNode_ = containerNode;
-
- var overlayNode = this.createOverlayNode_();
- containerNode.appendChild(overlayNode);
-
- var promptNode = document.createElement('span');
- promptNode.innerHTML = this.PROMPT_;
- overlayNode.appendChild(promptNode);
-
- this.txtNode_ = this.createTextAreaNode_();
-
- overlayNode.appendChild(this.txtNode_);
-
- document.body.appendChild(containerNode);
-
- this.txtNode_.focus();
-
- window.setTimeout(function() {
- containerNode.style['opacity'] = '1.0';
- }, 0);
-};
-
-
-/**
- * @override
- */
-cvox.SearchWidget.prototype.hide = function(opt_noSync) {
- if (this.isActive()) {
- var containerNode = this.containerNode_;
- containerNode.style.opacity = '0.0';
- window.setTimeout(function() {
- document.body.removeChild(containerNode);
- }, 1000);
- this.txtNode_ = null;
- cvox.SearchWidget.containerNode = null;
- cvox.ChromeVox.navigationManager.setFocusRecovery(this.focusRecovery_);
- this.active = false;
- }
-
- cvox.$m('choice_widget_exited').
- andPause().
- andMessage(this.getNameMsg()).
- speakFlush();
-
- if (!this.hasMatch_ || !opt_noSync) {
- cvox.ChromeVox.navigationManager.updateSelToArbitraryNode(
- this.initialNode);
- }
- cvox.ChromeVoxEventSuspender.withSuspendedEvents(goog.bind(
- cvox.ChromeVox.navigationManager.syncAll,
- cvox.ChromeVox.navigationManager))(true);
- cvox.ChromeVox.navigationManager.speakDescriptionArray(
- cvox.ChromeVox.navigationManager.getDescription(),
- cvox.QueueMode.QUEUE,
- null,
- cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT);
-
- // Update on Braille too.
- // TODO: Use line granularity in search so we can simply call
- // cvox.ChromeVox.navigationManager.getBraille().write() instead.
- var text = this.textFromCurrentDescription_();
- cvox.ChromeVox.braille.write(new cvox.NavBraille({
- text: text,
- startIndex: 0,
- endIndex: 0
- }));
-
- goog.base(this, 'hide', true);
-};
-
-
-/**
- * @override
- */
-cvox.SearchWidget.prototype.getNameMsg = function() {
- return ['search_widget_intro'];
-};
-
-
-/**
- * @override
- */
-cvox.SearchWidget.prototype.getHelpMsg = function() {
- return 'search_widget_intro_help';
-};
-
-
-/**
- * @override
- */
-cvox.SearchWidget.prototype.onKeyDown = function(evt) {
- if (!this.isActive()) {
- return false;
- }
- var searchStr = this.txtNode_.value;
- if (evt.keyCode == 8) { // Backspace
- if (searchStr.length > 0) {
- searchStr = searchStr.substring(0, searchStr.length - 1);
- this.txtNode_.value = searchStr;
- this.beginSearch_(searchStr);
- } else {
- cvox.ChromeVox.navigationManager.updateSelToArbitraryNode(
- this.initialNode);
- cvox.ChromeVox.navigationManager.syncAll();
- }
- } else if (evt.keyCode == 40) { // Down arrow
- this.next_(searchStr, false);
- } else if (evt.keyCode == 38) { // Up arrow
- this.next_(searchStr, true);
- } else if (evt.keyCode == 13) { // Enter
- this.hide(true);
- } else if (evt.keyCode == 27) { // Escape
- this.hide(false);
- } else if (evt.ctrlKey && evt.keyCode == 67) { // ctrl + c
- this.toggleCaseSensitivity_();
- } else {
- return goog.base(this, 'onKeyDown', evt);
- }
- evt.preventDefault();
- evt.stopPropagation();
- return true;
-};
-
-
-/**
- * Adds the letter the user typed to the search string and updates the search.
- * @override
- */
-cvox.SearchWidget.prototype.onKeyPress = function(evt) {
- if (!this.isActive()) {
- return false;
- }
-
- this.txtNode_.value += String.fromCharCode(evt.charCode);
- var searchStr = this.txtNode_.value;
- this.beginSearch_(searchStr);
- evt.preventDefault();
- evt.stopPropagation();
- return true;
-};
-
-
-/**
- * Called when navigation occurs.
- * Override this method to react to navigation caused by user input.
- */
-cvox.SearchWidget.prototype.onNavigate = function() {
-};
-
-
-/**
- * Gets the predicate to apply to every search.
- * @return {?function(Array<Node>)} A predicate; if null, no predicate applies.
- */
-cvox.SearchWidget.prototype.getPredicate = function() {
- return null;
-};
-
-
-/**
- * Goes to the next or previous result. For use in AndroidVox.
- * @param {boolean=} opt_reverse Whether to find the next result in reverse.
- * @return {Array<cvox.NavDescription>} The next result.
- */
-cvox.SearchWidget.prototype.nextResult = function(opt_reverse) {
- if (!this.isActive()) {
- return null;
- }
- var searchStr = this.txtNode_.value;
- return this.next_(searchStr, opt_reverse);
-};
-
-
-/**
- * Create the container node for the search overlay.
- *
- * @return {!Element} The new element, not yet added to the document.
- * @private
- */
-cvox.SearchWidget.prototype.createContainerNode_ = function() {
- var containerNode = document.createElement('div');
- containerNode.id = 'cvox-search';
- containerNode.style['position'] = 'fixed';
- containerNode.style['top'] = '50%';
- containerNode.style['left'] = '50%';
- containerNode.style['-webkit-transition'] = 'all 0.3s ease-in';
- containerNode.style['opacity'] = '0.0';
- containerNode.style['z-index'] = '2147483647';
- containerNode.setAttribute('aria-hidden', 'true');
- return containerNode;
-};
-
-
-/**
- * Create the search overlay. This should be a child of the node
- * returned from createContainerNode.
- *
- * @return {!Element} The new element, not yet added to the document.
- * @private
- */
-cvox.SearchWidget.prototype.createOverlayNode_ = function() {
- var overlayNode = document.createElement('div');
- overlayNode.style['position'] = 'relative';
- overlayNode.style['left'] = '-50%';
- overlayNode.style['top'] = '-40px';
- overlayNode.style['line-height'] = '1.2em';
- overlayNode.style['font-size'] = '20px';
- overlayNode.style['padding'] = '30px';
- overlayNode.style['min-width'] = '150px';
- overlayNode.style['color'] = '#fff';
- overlayNode.style['background-color'] = 'rgba(0, 0, 0, 0.7)';
- overlayNode.style['border-radius'] = '10px';
- return overlayNode;
-};
-
-
-/**
- * Create the text area node. This should be the child of the node
- * returned from createOverlayNode.
- *
- * @return {!Element} The new element, not yet added to the document.
- * @private
- */
-cvox.SearchWidget.prototype.createTextAreaNode_ = function() {
- var textNode = document.createElement('textarea');
- textNode.setAttribute('aria-hidden', 'true');
- textNode.setAttribute('rows', '1');
- textNode.style['color'] = '#fff';
- textNode.style['background-color'] = 'rgba(0, 0, 0, 0.7)';
- textNode.style['vertical-align'] = 'middle';
- textNode.addEventListener('textInput',
- this.handleSearchChanged_, false);
- return textNode;
-};
-
-
-/**
- * Toggles whether or not searches are case sensitive.
- * @private
- */
-cvox.SearchWidget.prototype.toggleCaseSensitivity_ = function() {
- if (this.caseSensitive_) {
- cvox.SearchWidget.caseSensitive_ = false;
- cvox.ChromeVox.tts.speak(
- Msgs.getMsg('ignoring_case'),
- cvox.QueueMode.FLUSH, null);
- } else {
- this.caseSensitive_ = true;
- cvox.ChromeVox.tts.speak(
- Msgs.getMsg('case_sensitive'),
- cvox.QueueMode.FLUSH, null);
- }
-};
-
-
-/**
- * Gets the next result.
- *
- * @param {string} searchStr The text to search for.
- * @return {Array<cvox.NavDescription>} The next result, in the form of
- * NavDescriptions.
- * @private
- */
-cvox.SearchWidget.prototype.getNextResult_ = function(searchStr) {
- var r = cvox.ChromeVox.navigationManager.isReversed();
- if (!this.caseSensitive_) {
- searchStr = searchStr.toLowerCase();
- }
-
- cvox.ChromeVox.navigationManager.setGranularity(
- cvox.NavigationShifter.GRANULARITIES.OBJECT, true, false);
-
- do {
- if (this.getPredicate()) {
- var retNode = this.getPredicate()(cvox.DomUtil.getAncestors(
- cvox.ChromeVox.navigationManager.getCurrentNode()));
- if (!retNode) {
- continue;
- }
- }
-
- var descriptions = cvox.ChromeVox.navigationManager.getDescription();
- for (var i = 0; i < descriptions.length; i++) {
- var targetStr = this.caseSensitive_ ? descriptions[i].text :
- descriptions[i].text.toLowerCase();
- var targetIndex = targetStr.indexOf(searchStr);
-
- // Surround search hit with pauses.
- if (targetIndex != -1 && targetStr.length > searchStr.length) {
- descriptions[i].text =
- cvox.DomUtil.collapseWhitespace(
- targetStr.substring(0, targetIndex)) +
- ', ' + searchStr + ', ' +
- targetStr.substring(targetIndex + searchStr.length);
- descriptions[i].text =
- cvox.DomUtil.collapseWhitespace(descriptions[i].text);
- }
- if (targetIndex != -1) {
- return descriptions;
- }
- }
- cvox.ChromeVox.navigationManager.setReversed(r);
- } while (cvox.ChromeVox.navigationManager.navigate(true,
- cvox.NavigationShifter.GRANULARITIES.OBJECT));
-};
-
-
-/**
- * Performs the search starting from the initial position.
- *
- * @param {string} searchStr The text to search for.
- * @private
- */
-cvox.SearchWidget.prototype.beginSearch_ = function(searchStr) {
- var result = this.getNextResult_(searchStr);
- this.outputSearchResult_(result, searchStr);
- this.onNavigate();
-};
-
-
-/**
- * Goes to the next (directed) matching result.
- *
- * @param {string} searchStr The text to search for.
- * @param {boolean=} opt_reversed The direction.
- * @return {Array<cvox.NavDescription>} The next result.
- * @private
- */
-cvox.SearchWidget.prototype.next_ = function(searchStr, opt_reversed) {
- cvox.ChromeVox.navigationManager.setReversed(!!opt_reversed);
-
- var success = false;
- if (this.getPredicate()) {
- success = cvox.ChromeVox.navigationManager.findNext(
- /** @type {function(Array<Node>)} */ (this.getPredicate()));
- // TODO(dtseng): findNext always seems to point direction forward!
- cvox.ChromeVox.navigationManager.setReversed(!!opt_reversed);
- if (!success) {
- cvox.ChromeVox.navigationManager.syncToBeginning();
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP);
- success = true;
- }
- } else {
- success = cvox.ChromeVox.navigationManager.navigate(true);
- }
- var result = success ? this.getNextResult_(searchStr) : null;
- this.outputSearchResult_(result, searchStr);
- this.onNavigate();
- return result;
-};
-
-
-/**
- * Given a range corresponding to a search result, highlight the result,
- * speak it, focus the node if applicable, and speak some instructions
- * at the end.
- *
- * @param {Array<cvox.NavDescription>} result The description of the next
- * result. If null, no more results were found and an error will be presented.
- * @param {string} searchStr The text to search for.
- * @private
- */
-cvox.SearchWidget.prototype.outputSearchResult_ = function(result, searchStr) {
- cvox.ChromeVox.tts.stop();
- if (!result) {
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP);
- this.hasMatch_ = false;
- return;
- }
-
- this.hasMatch_ = true;
-
- // Speak the modified description and some instructions.
- cvox.ChromeVoxEventSuspender.withSuspendedEvents(goog.bind(
- cvox.ChromeVox.navigationManager.syncAll,
- cvox.ChromeVox.navigationManager))(true);
-
- cvox.ChromeVox.navigationManager.speakDescriptionArray(
- result,
- cvox.QueueMode.FLUSH,
- null,
- cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT);
-
- cvox.ChromeVox.tts.speak(Msgs.getMsg('search_help_item'),
- cvox.QueueMode.QUEUE,
- cvox.AbstractTts.PERSONALITY_ANNOTATION);
-
- // Output to Braille.
- // TODO: Use line granularity in search so we can simply call
- // cvox.ChromeVox.navigationManager.getBraille().write() instead.
- this.outputSearchResultToBraille_(searchStr);
-};
-
-
-/**
- * Writes the currently selected search result to Braille, with description
- * text formatted for Braille display instead of speech.
- *
- * @param {string} searchStr The text to search for.
- * Should be in navigation manager's description.
- * @private
- */
-cvox.SearchWidget.prototype.outputSearchResultToBraille_ = function(searchStr) {
- // Construct object we can pass to Chromevox.braille to write.
- // We concatenate the text together and set the "cursor"
- // position to be at the end of search query string
- // (consistent with editing text in a field).
- var text = this.textFromCurrentDescription_();
- var targetStr = this.caseSensitive_ ? text :
- text.toLowerCase();
- searchStr = this.caseSensitive_ ? searchStr : searchStr.toLowerCase();
- var targetIndex = targetStr.indexOf(searchStr);
- if (targetIndex == -1) {
- console.log('Search string not in result when preparing for Braille.');
- return;
- }
-
- // Mark the string as a search result by adding a prefix
- // and adjust the targetIndex accordingly.
- var oldLength = text.length;
- text = Msgs.getMsg('mark_as_search_result_brl', [text]);
- var newLength = text.length;
- targetIndex += (newLength - oldLength);
-
- // Write to Braille with cursor at the end of the search hit.
- cvox.ChromeVox.braille.write(new cvox.NavBraille({
- text: text,
- startIndex: (targetIndex + searchStr.length),
- endIndex: (targetIndex + searchStr.length)
- }));
-};
-
-
-/**
- * Returns the concatenated text from the current description in the
- * NavigationManager.
- * TODO: May not be needed after we just simply use line granularity in search,
- * since this is mostly used to display the long search result descriptions on
- * Braille.
- * @return {string} The concatenated text from the current description.
- * @private
- */
-cvox.SearchWidget.prototype.textFromCurrentDescription_ = function() {
- var descriptions = cvox.ChromeVox.navigationManager.getDescription();
- var text = '';
- for (var i = 0; i < descriptions.length; i++) {
- text += descriptions[i].text + ' ';
- }
- return text;
-};
-
-/**
- * @param {Object} evt The onInput event that the function is handling.
- * @private
- */
-cvox.SearchWidget.prototype.handleSearchChanged_ = function(evt) {
- var searchStr = evt.target.value + evt.data;
- cvox.SearchWidget.prototype.beginSearch_(searchStr);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/select_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/select_widget.js
deleted file mode 100644
index b2decc2bf68..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/select_widget.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A widget hosting an HTML <select> element.
- * In most cases, the browser's native key-driven usage model works for user
- * interaction and manipulation of a <select>. However, on platforms like Mac
- * OS X where <select> elements get their own renderer, users can still interact
- * with <select> elements via a ChromeVox overlay/context widget.
- */
-
-goog.provide('cvox.SelectWidget');
-
-
-goog.require('cvox.OverlayWidget');
-
-
-/**
- * @param {Node} node The select node.
- * @constructor
- * @extends {cvox.OverlayWidget}
- */
-cvox.SelectWidget = function(node) {
- goog.base(this, '');
- this.selectNode_ = node;
-};
-goog.inherits(cvox.SelectWidget, cvox.OverlayWidget);
-
-
-/**
- * @override
- */
-cvox.SelectWidget.prototype.show = function() {
- goog.base(this, 'show');
- var container = document.createElement('div');
- container.setAttribute('role', 'menu');
- for (var i = 0, item = null; item = this.selectNode_.options[i]; i++) {
- var newItem = document.createElement('p');
- newItem.innerHTML = item.innerHTML;
- newItem.id = i;
- newItem.setAttribute('role', 'menuitem');
- container.appendChild(newItem);
- }
- this.host_.appendChild(container);
- var currentSelection = this.selectNode_.selectedIndex;
- if (typeof(currentSelection) == 'number') {
- cvox.ChromeVox.syncToNode(container.children[currentSelection], true);
- }
-};
-
-
-/**
- * @override
- */
-cvox.SelectWidget.prototype.hide = function(opt_noSync) {
- var evt = document.createEvent('Event');
- evt.initEvent('change', false, false);
- this.selectNode_.dispatchEvent(evt);
- goog.base(this, 'hide', true);
-};
-
-
-/**
- * @override
- */
-cvox.SelectWidget.prototype.onNavigate = function() {
- var self = this;
- cvox.ChromeVoxEventSuspender.withSuspendedEvents(function() {
- var selectedIndex =
- cvox.ChromeVox.navigationManager.getCurrentNode().parentNode.id;
- self.selectNode_.selectedIndex = selectedIndex;
- })();
-};
-
-
-/**
- * @override
- */
-cvox.SelectWidget.prototype.getNameMsg = function() {
- return ['role_menu'];
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/spoken_messages.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/spoken_messages.js
deleted file mode 100644
index dc72579c805..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/spoken_messages.js
+++ /dev/null
@@ -1,90 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Useful abstraction when speaking messages.
- *
- * Usage:
- * $m('role_link')
- * .andPause()
- * .andMessage('role_forms')
- * .speakFlush();
- *
- */
-
-goog.provide('cvox.SpokenMessage');
-goog.provide('cvox.SpokenMessages');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.ChromeVox');
-
-/**
- * @constructor
- */
-cvox.SpokenMessage = function() {
- /** @type {Array} */
- this.id = null;
-};
-
-/**
- * @type {Array}
- */
-cvox.SpokenMessages.messages = [];
-
-/**
- * Speaks the message chain and interrupts any on-going speech.
- */
-cvox.SpokenMessages.speakFlush = function() {
- cvox.SpokenMessages.speak(cvox.QueueMode.FLUSH);
-};
-
-/**
- * Speak the message chain.
- * @param {cvox.QueueMode} mode The speech queue mode.
- */
-cvox.SpokenMessages.speak = function(mode) {
- for (var i = 0; i < cvox.SpokenMessages.messages.length; ++i) {
- var message = cvox.SpokenMessages.messages[i];
-
- // An invalid message format.
- if (!message || !message.id)
- throw 'Invalid message received.';
-
- var finalText = Msgs.getMsg.apply(Msgs, message.id);
- cvox.ChromeVox.tts.speak(finalText, mode,
- cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT);
-
- // Always queue after the first message.
- mode = cvox.QueueMode.QUEUE;
- }
-
- cvox.SpokenMessages.messages = [];
-};
-
-/**
- * Adds a message.
- * @param {string|Array} messageId The id of the message.
- * @return {Object} This object, useful for chaining.
- */
-cvox.SpokenMessages.andMessage = function(messageId) {
- var newMessage = new cvox.SpokenMessage();
- newMessage.id = typeof(messageId) == 'string' ? [messageId] : messageId;
- cvox.SpokenMessages.messages.push(newMessage);
- return cvox.SpokenMessages;
-};
-
-/**
- * Pauses after the message, with an appropriate marker.
- * @return {Object} This object, useful for chaining.
- */
-cvox.SpokenMessages.andPause = function() {
- return cvox.SpokenMessages.andMessage('pause');
-};
-
-/**
- * Adds a message.
- * @param {string|Array} messageId The id of the message.
- * @return {Object} This object, useful for chaining.
- */
-cvox.$m = cvox.SpokenMessages.andMessage;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/widget.js
deleted file mode 100644
index 66a18e247a8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/ui/widget.js
+++ /dev/null
@@ -1,195 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Base class for all ChromeVox widgets.
- *
- * Widgets are keyboard driven and modal mediums for ChromeVox to expose
- * additional features such as lists, interactive search, or grids.
- */
-
-goog.provide('cvox.Widget');
-
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.ApiImplementation');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.SpokenMessages');
-
-/**
- * Keeps a reference to a currently or formerly active widget. This enforces
- * the singleton nature of widgets.
- * @type {cvox.Widget}
- * @private
- */
-cvox.Widget.ref_;
-
-
-/**
- * @constructor
- */
-cvox.Widget = function() {
- /**
- * @type {boolean}
- * @protected
- */
- this.active = false;
-
-
- /**
- * Keeps a reference to a node which should receive focus once a widget hides.
- * @type {Node}
- * @protected
- */
- this.initialFocus = null;
-
- /**
- * Keeps a reference to a node which should receive selection once a widget
- * hides.
- * @type {Node}
- * @protected
- */
- this.initialNode = null;
-
- // Checks to see if there is a current widget in use.
- if (!cvox.Widget.ref_ || !cvox.Widget.ref_.isActive()) {
- cvox.Widget.ref_ = this;
- }
-};
-
-
-/**
- * Returns whether or not the widget is active.
- * @return {boolean} Whether the widget is active.
- */
-cvox.Widget.prototype.isActive = function() {
- return this.active;
-};
-
-
-/**
- * Visual/aural display of this widget.
- */
-cvox.Widget.prototype.show = function() {
- if (this.isActive()) {
- // Only one widget should be shown at any given time.
- this.hide(true);
- }
- this.onKeyDown = goog.bind(this.onKeyDown, this);
- this.onKeyPress = goog.bind(this.onKeyPress, this);
- window.addEventListener('keydown', this.onKeyDown, true);
- window.addEventListener('keypress', this.onKeyPress, true);
-
- this.initialNode =
- cvox.ChromeVox.navigationManager.getCurrentNode();
- this.initialFocus = document.activeElement;
-
- // Widgets do not respond to sticky key.
- cvox.ChromeVox.stickyOverride = false;
-
- if (this.getNameMsg() && this.getHelpMsg()) {
- cvox.$m(this.getNameMsg()).
- andPause().
- andMessage(this.getHelpMsg()).
- speakFlush();
- }
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_OPEN);
-
- this.active = true;
-};
-
-
-/**
- * Visual/aural hide of this widget.
- * @param {boolean=} opt_noSync Whether to attempt to sync to the node before
- * this widget was first shown. If left unspecified or false, an attempt to sync
- * will be made.
- */
-cvox.Widget.prototype.hide = function(opt_noSync) {
- window.removeEventListener('keypress', this.onKeyPress, true);
- window.removeEventListener('keydown', this.onKeyDown, true);
- cvox.ChromeVox.stickyOverride = null;
-
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_CLOSE);
- if (!opt_noSync) {
- this.initialNode = this.initialNode.nodeType == 1 ?
- this.initialNode : this.initialNode.parentNode;
- cvox.ApiImplementation.syncToNode(this.initialNode,
- true,
- cvox.QueueMode.QUEUE);
- }
-
- this.active = false;
-};
-
-
-/**
- * Toggle between showing and hiding.
- */
-cvox.Widget.prototype.toggle = function() {
- if (this.isActive()) {
- this.hide();
- } else {
- this.show();
- }
-};
-
-
-/**
- * The name of the widget.
- * @return {!Array} The message id referencing the name of the widget in an
- * array argument form passable to Msgs.getMsg.apply.
- */
-cvox.Widget.prototype.getNameMsg = goog.abstractMethod;
-
-
-/**
- * Gets the help message for the widget.
- * The help message succintly describes how to use the widget.
- * @return {string} The message id referencing the help for the widget.
- */
-cvox.Widget.prototype.getHelpMsg = goog.abstractMethod;
-
-
-/**
- * The default widget key down handler.
- *
- * @param {Event} evt The keyDown event.
- * @return {boolean} Whether or not the event was handled.
- *
- * @protected
- */
-cvox.Widget.prototype.onKeyDown = function(evt) {
- if (evt.keyCode == 27) { // Escape
- this.hide();
- evt.preventDefault();
- return true;
- } else if (evt.keyCode == 9) { // Tab
- this.hide();
- return true;
- } else if (evt.keyCode == 17) {
- cvox.ChromeVox.tts.stop();
- }
-
- evt.stopPropagation();
- return true;
-};
-
-
-/**
- * The default widget key press handler.
- *
- * @param {Event} evt The keyPress event.
- * @return {boolean} Whether or not the event was handled.
- *
- * @protected
- */
-cvox.Widget.prototype.onKeyPress = function(evt) {
- return false;
-};
-/**
- * @return {boolean} True if any widget is currently active.
- */
-cvox.Widget.isActive = function() {
- return (cvox.Widget.ref_ && cvox.Widget.ref_.isActive()) || false;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands.js
deleted file mode 100644
index db2c7243cb1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands.js
+++ /dev/null
@@ -1,810 +0,0 @@
-// 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.
-
-/**
- * @fileoverview High level commands that the user can invoke using hotkeys.
- *
- * Usage:
- * If you are here, you probably want to add a new user command. Here are some
- * general steps to get you started.
- * - Go to command_store.js, where all static data about a command lives. Follow
- * the instructions there.
- * - Add the logic of the command to doCommand_ below. Try to reuse or group
- * your command with related commands.
- */
-
-
-goog.provide('cvox.ChromeVoxUserCommands');
-
-goog.require('cvox.BrailleKeyCommand');
-goog.require('cvox.BrailleOverlayWidget');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.CommandStore');
-goog.require('cvox.ConsoleTts');
-goog.require('cvox.ContextMenuWidget');
-goog.require('cvox.DomPredicates');
-goog.require('cvox.DomUtil');
-goog.require('cvox.FocusUtil');
-goog.require('cvox.KeyboardHelpWidget');
-goog.require('cvox.NodeSearchWidget');
-goog.require('cvox.PlatformUtil');
-goog.require('cvox.SearchWidget');
-goog.require('cvox.SelectWidget');
-goog.require('cvox.TypingEcho');
-goog.require('cvox.UserEventDetail');
-goog.require('goog.object');
-
-
-/**
- * Initializes commands map.
- * Initializes global members.
- * @private
- */
-cvox.ChromeVoxUserCommands.init_ = function() {
- if (cvox.ChromeVoxUserCommands.commands) {
- return;
- } else {
- cvox.ChromeVoxUserCommands.commands = {};
- }
- for (var cmd in cvox.CommandStore.CMD_WHITELIST) {
- cvox.ChromeVoxUserCommands.commands[cmd] =
- cvox.ChromeVoxUserCommands.createCommand_(cmd);
- }
-};
-
-
-/**
- * @type {!Object<function(Object=): boolean>}
- */
-cvox.ChromeVoxUserCommands.commands;
-
-
-/**
- * @type {boolean}
- * TODO (clchen, dmazzoni): Implement syncing on click to avoid needing this.
- */
-cvox.ChromeVoxUserCommands.wasMouseClicked = false;
-
-
-/**
- * @type {boolean} Flag to set whether or not certain user commands will be
- * first dispatched to the underlying web page. Some commands (such as finding
- * the next/prev structural element) may be better implemented by the web app
- * than by ChromeVox.
- *
- * By default, this is enabled; however, for testing, we usually disable this to
- * reduce flakiness caused by event timing issues.
- *
- * TODO (clchen, dtseng): Fix testing framework so that we don't need to turn
- * this feature off at all.
- */
-cvox.ChromeVoxUserCommands.enableCommandDispatchingToPage = true;
-
-
-/**
- * Handles any tab navigation by putting focus at the user's position.
- * This function will create dummy nodes if there is nothing that is focusable
- * at the current position.
- * TODO (adu): This function is too long. We need to break it up into smaller
- * helper functions.
- * @return {boolean} True if default action should be taken.
- * @private
- */
-cvox.ChromeVoxUserCommands.handleTabAction_ = function() {
- cvox.ChromeVox.tts.stop();
-
- // If we are tabbing from an invalid location, prevent the default action.
- // We pass the isFocusable function as a predicate to specify we only want to
- // revert to focusable nodes.
- if (!cvox.ChromeVox.navigationManager.resolve(cvox.DomUtil.isFocusable)) {
- cvox.ChromeVox.navigationManager.setFocus();
- return false;
- }
-
- // If the user is already focused on anything, nothing more needs to be done.
- if (document.activeElement != document.body) {
- return true;
- }
-
- // Try to find something reasonable to focus on.
- // Use selection if it exists because it means that the user has probably
- // clicked with their mouse and we should respect their position.
- // If there is no selection, then use the last known position based on
- // NavigationManager's currentNode.
- var anchorNode = null;
- var focusNode = null;
- var sel = window.getSelection();
- if (!cvox.ChromeVoxUserCommands.wasMouseClicked) {
- sel = null;
- } else {
- cvox.ChromeVoxUserCommands.wasMouseClicked = false;
- }
- if (sel == null || sel.anchorNode == null || sel.focusNode == null) {
- anchorNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- focusNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- } else {
- anchorNode = sel.anchorNode;
- focusNode = sel.focusNode;
- }
-
- // See if we can set focus to either anchorNode or focusNode.
- // If not, try the parents. Otherwise give up and create a dummy span.
- if (anchorNode == null || focusNode == null) {
- return true;
- }
- if (cvox.DomUtil.isFocusable(anchorNode)) {
- anchorNode.focus();
- return true;
- }
- if (cvox.DomUtil.isFocusable(focusNode)) {
- focusNode.focus();
- return true;
- }
- if (cvox.DomUtil.isFocusable(anchorNode.parentNode)) {
- anchorNode.parentNode.focus();
- return true;
- }
- if (cvox.DomUtil.isFocusable(focusNode.parentNode)) {
- focusNode.parentNode.focus();
- return true;
- }
-
- // Insert and focus a dummy span immediately before the current position
- // so that the default tab action will start off as close to the user's
- // current position as possible.
- var bestGuess = anchorNode;
- var dummySpan = cvox.ChromeVoxUserCommands.createTabDummySpan_();
- bestGuess.parentNode.insertBefore(dummySpan, bestGuess);
- dummySpan.focus();
- return true;
-};
-
-
-/**
- * If a lingering tab dummy span exists, remove it.
- */
-cvox.ChromeVoxUserCommands.removeTabDummySpan = function() {
- // Break the following line to get around a Chromium js linter warning.
- // TODO(plundblad): Find a better solution.
- var previousDummySpan = document.
- getElementById('ChromeVoxTabDummySpan');
- if (previousDummySpan && document.activeElement != previousDummySpan) {
- previousDummySpan.parentNode.removeChild(previousDummySpan);
- }
-};
-
-
-/**
- * Create a new tab dummy span.
- * @return {Element} The dummy span element to be inserted.
- * @private
- */
-cvox.ChromeVoxUserCommands.createTabDummySpan_ = function() {
- var span = document.createElement('span');
- span.id = 'ChromeVoxTabDummySpan';
- span.tabIndex = -1;
- return span;
-};
-
-
-/**
- * @param {string} cmd The programmatic command name.
- * @return {function(Object=): boolean} The callable command taking an optional
- * args dictionary.
- * @private
- */
-cvox.ChromeVoxUserCommands.createCommand_ = function(cmd) {
- return goog.bind(function(opt_kwargs) {
- var cmdStruct = cvox.ChromeVoxUserCommands.lookupCommand_(cmd, opt_kwargs);
- return cvox.ChromeVoxUserCommands.dispatchCommand_(cmdStruct);
- }, cvox.ChromeVoxUserCommands);
-};
-
-
-/**
- * @param {Object} cmdStruct The command to do.
- * @return {boolean} False to prevent the default action. True otherwise.
- * @private
- */
-cvox.ChromeVoxUserCommands.dispatchCommand_ = function(cmdStruct) {
- if (cvox.Widget.isActive()) {
- return true;
- }
- if (!cvox.PlatformUtil.matchesPlatform(cmdStruct.platformFilter) ||
- (cmdStruct.skipInput && cvox.FocusUtil.isFocusInTextInputField())) {
- return true;
- }
- // Handle dispatching public command events
- if (cvox.ChromeVoxUserCommands.enableCommandDispatchingToPage &&
- (cvox.UserEventDetail.JUMP_COMMANDS.indexOf(cmdStruct.command) != -1)) {
- var detail = new cvox.UserEventDetail({command: cmdStruct.command});
- var evt = detail.createEventObject();
- var currentNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- if (!currentNode) {
- currentNode = document.body;
- }
- currentNode.dispatchEvent(evt);
- return false;
- }
- // Not a public command; act on this command directly.
- return cvox.ChromeVoxUserCommands.doCommand_(cmdStruct);
-};
-
-
-/**
- * @param {Object} cmdStruct The command to do.
- * @return {boolean} False to prevent the default action. True otherwise.
- * @private
- */
-cvox.ChromeVoxUserCommands.doCommand_ = function(cmdStruct) {
- if (cvox.Widget.isActive()) {
- return true;
- }
-
- if (!cvox.PlatformUtil.matchesPlatform(cmdStruct.platformFilter) ||
- (cmdStruct.skipInput && cvox.FocusUtil.isFocusInTextInputField())) {
- return true;
- }
-
- if (cmdStruct.disallowOOBE && document.URL.match(/^chrome:\/\/oobe/i)) {
- return true;
- }
-
- var cmd = cmdStruct.command;
-
- if (!cmdStruct.allowEvents) {
- cvox.ChromeVoxEventSuspender.enterSuspendEvents();
- }
-
- if (cmdStruct.disallowContinuation) {
- cvox.ChromeVox.navigationManager.stopReading(true);
- }
-
- if (cmdStruct.forward) {
- cvox.ChromeVox.navigationManager.setReversed(false);
- } else if (cmdStruct.backward) {
- cvox.ChromeVox.navigationManager.setReversed(true);
- }
-
- if (cmdStruct.findNext) {
- cmd = 'find';
- cmdStruct.announce = true;
- }
-
- var errorMsg = '';
- var prefixMsg = '';
- var ret = false;
- switch (cmd) {
- case 'handleTab':
- case 'handleTabPrev':
- ret = cvox.ChromeVoxUserCommands.handleTabAction_();
- break;
- case 'forward':
- case 'backward':
- ret = !cvox.ChromeVox.navigationManager.navigate();
- break;
- case 'right':
- case 'left':
- cvox.ChromeVox.navigationManager.subnavigate();
- break;
- case 'find':
- if (!cmdStruct.findNext) {
- throw 'Invalid find command.';
- }
- var NodeInfoStruct =
- cvox.CommandStore.NODE_INFO_MAP[cmdStruct.findNext];
- var predicateName = NodeInfoStruct.predicate;
- var predicate = cvox.DomPredicates[predicateName];
- var error = '';
- var wrap = '';
- if (cmdStruct.forward) {
- wrap = Msgs.getMsg('wrapped_to_top');
- error = Msgs.getMsg(NodeInfoStruct.forwardError);
- } else if (cmdStruct.backward) {
- wrap = Msgs.getMsg('wrapped_to_bottom');
- error = Msgs.getMsg(NodeInfoStruct.backwardError);
- }
- var found = null;
- var status = cmdStruct.status || cvox.UserEventDetail.Status.PENDING;
- var resultNode = cmdStruct.resultNode || null;
- switch (status) {
- case cvox.UserEventDetail.Status.SUCCESS:
- if (resultNode) {
- cvox.ChromeVox.navigationManager.updateSelToArbitraryNode(
- resultNode, true);
- }
- break;
- case cvox.UserEventDetail.Status.FAILURE:
- prefixMsg = error;
- break;
- default:
- found = cvox.ChromeVox.navigationManager.findNext(
- predicate, predicateName);
- if (!found) {
- cvox.ChromeVox.navigationManager.saveSel();
- prefixMsg = wrap;
- cvox.ChromeVox.navigationManager.syncToBeginning();
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP);
- found = cvox.ChromeVox.navigationManager.findNext(
- predicate, predicateName, true);
- if (!found) {
- prefixMsg = error;
- cvox.ChromeVox.navigationManager.restoreSel();
- }
- }
- break;
- }
- // NavigationManager performs announcement inside of frames when finding.
- if (found && found.start.node.tagName == 'IFRAME') {
- cmdStruct.announce = false;
- }
- break;
- // TODO(stoarca): Bad naming. Should be less instead of previous.
- case 'previousGranularity':
- cvox.ChromeVox.navigationManager.makeLessGranular(true);
- prefixMsg = cvox.ChromeVox.navigationManager.getGranularityMsg();
- break;
- case 'nextGranularity':
- cvox.ChromeVox.navigationManager.makeMoreGranular(true);
- prefixMsg = cvox.ChromeVox.navigationManager.getGranularityMsg();
- break;
-
- case 'previousCharacter':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.CHARACTER);
- break;
- case 'nextCharacter':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.CHARACTER);
- break;
-
- case 'previousWord':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.WORD);
- break;
- case 'nextWord':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.WORD);
- break;
-
- case 'previousSentence':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.SENTENCE);
- break;
- case 'nextSentence':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.SENTENCE);
- break;
-
- case 'previousLine':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.LINE);
- break;
- case 'nextLine':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.LINE);
- break;
-
- case 'previousObject':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.OBJECT);
- break;
- case 'nextObject':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.OBJECT);
- break;
-
- case 'previousGroup':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.GROUP);
- break;
- case 'nextGroup':
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.GROUP);
- break;
-
- case 'previousRow':
- case 'previousCol':
- // Fold these commands to their "next" equivalents since we already set
- // isReversed above.
- cmd = cmd == 'previousRow' ? 'nextRow' : 'nextCol';
- case 'nextRow':
- case 'nextCol':
- cvox.ChromeVox.navigationManager.performAction('enterShifterSilently');
- cvox.ChromeVox.navigationManager.performAction(cmd);
- break;
-
- case 'moveToStartOfLine':
- case 'moveToEndOfLine':
- cvox.ChromeVox.navigationManager.setGranularity(
- cvox.NavigationShifter.GRANULARITIES.LINE);
- cvox.ChromeVox.navigationManager.sync();
- cvox.ChromeVox.navigationManager.collapseSelection();
- break;
-
- case 'readFromHere':
- cvox.ChromeVox.navigationManager.setGranularity(
- cvox.NavigationShifter.GRANULARITIES.OBJECT, true, true);
- cvox.ChromeVox.navigationManager.startReading(
- cvox.QueueMode.FLUSH);
- break;
- case 'cycleTypingEcho':
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'typingEcho',
- 'value': cvox.TypingEcho.cycle(cvox.ChromeVox.typingEcho),
- 'announce': true
- });
- break;
- case 'jumpToTop':
- case cvox.BrailleKeyCommand.TOP:
- cvox.ChromeVox.navigationManager.syncToBeginning();
- break;
- case 'jumpToBottom':
- case cvox.BrailleKeyCommand.BOTTOM:
- cvox.ChromeVox.navigationManager.syncToBeginning();
- break;
- case 'stopSpeech':
- cvox.ChromeVox.navigationManager.stopReading(true);
- break;
- case 'toggleKeyboardHelp':
- cvox.KeyboardHelpWidget.getInstance().toggle();
- break;
- case 'help':
- cvox.ChromeVox.tts.stop();
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'HelpDocs',
- 'action': 'open'
- });
- break;
- case 'contextMenu':
- // Move this logic to a central dispatching class if it grows any bigger.
- var node = cvox.ChromeVox.navigationManager.getCurrentNode();
- if (node.tagName == 'SELECT' && !node.multiple) {
- new cvox.SelectWidget(node).show();
- } else {
- var contextMenuWidget = new cvox.ContextMenuWidget();
- contextMenuWidget.toggle();
- }
- break;
- case 'showBookmarkManager':
- // TODO(stoarca): Should this have tts.stop()??
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'BookmarkManager',
- 'action': 'open'
- });
- break;
- case 'showOptionsPage':
- cvox.ChromeVox.tts.stop();
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Options',
- 'action': 'open'
- });
- break;
- case 'showKbExplorerPage':
- cvox.ChromeVox.tts.stop();
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'KbExplorer',
- 'action': 'open'
- });
- break;
- case 'readLinkURL':
- var activeElement = document.activeElement;
- var currentSelectionAnchor = window.getSelection().anchorNode;
-
- var url = '';
- if (activeElement.tagName == 'A') {
- url = cvox.DomUtil.getLinkURL(activeElement);
- } else if (currentSelectionAnchor) {
- url = cvox.DomUtil.getLinkURL(currentSelectionAnchor.parentNode);
- }
-
- if (url != '') {
- cvox.ChromeVox.tts.speak(url, cvox.QueueMode.QUEUE);
- } else {
- cvox.ChromeVox.tts.speak(Msgs.getMsg('no_url_found'),
- cvox.QueueMode.QUEUE);
- }
- break;
- case 'readCurrentTitle':
- cvox.ChromeVox.tts.speak(document.title, cvox.QueueMode.QUEUE);
- break;
- case 'readCurrentURL':
- cvox.ChromeVox.tts.speak(document.URL, cvox.QueueMode.QUEUE);
- break;
- case 'performDefaultAction':
- if (cvox.DomPredicates.linkPredicate([document.activeElement])) {
- if (cvox.DomUtil.isInternalLink(document.activeElement)) {
- // First, sync our selection to the destination of the internal link.
- cvox.DomUtil.syncInternalLink(document.activeElement);
- // Now, sync our selection based on the current granularity.
- cvox.ChromeVox.navigationManager.sync();
- // Announce this new selection.
- cmdStruct.announce = true;
- }
- }
- break;
- case 'forceClickOnCurrentItem':
- prefixMsg = Msgs.getMsg('element_clicked');
- var targetNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- cvox.DomUtil.clickElem(targetNode, false, false);
- break;
- case 'forceDoubleClickOnCurrentItem':
- prefixMsg = Msgs.getMsg('element_double_clicked');
- var targetNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- cvox.DomUtil.clickElem(targetNode, false, false, true);
- break;
- case 'toggleChromeVox':
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'active',
- 'value': !cvox.ChromeVox.isActive
- });
- break;
- case 'fullyDescribe':
- var descs = cvox.ChromeVox.navigationManager.getFullDescription();
- cvox.ChromeVox.navigationManager.speakDescriptionArray(
- descs,
- cvox.QueueMode.FLUSH,
- null);
- break;
- case 'speakTimeAndDate':
- var dateTime = new Date();
- cvox.ChromeVox.tts.speak(
- dateTime.toLocaleTimeString() + ', ' + dateTime.toLocaleDateString(),
- cvox.QueueMode.QUEUE);
- break;
- case 'toggleSelection':
- var selState = cvox.ChromeVox.navigationManager.togglePageSel();
- prefixMsg = Msgs.getMsg(
- selState ? 'begin_selection' : 'end_selection');
- break;
- case 'startHistoryRecording':
- cvox.History.getInstance().startRecording();
- break;
- case 'stopHistoryRecording':
- cvox.History.getInstance().stopRecording();
- break;
- case 'enableConsoleTts':
- cvox.ConsoleTts.getInstance().setEnabled(true);
- break;
- case 'toggleBrailleCaptions':
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'brailleCaptions',
- 'value': !cvox.BrailleOverlayWidget.getInstance().isActive()
- });
- break;
-
- // Table actions.
- case 'goToFirstCell':
- case 'goToLastCell':
- case 'goToRowFirstCell':
- case 'goToRowLastCell':
- case 'goToColFirstCell':
- case 'goToColLastCell':
- case 'announceHeaders':
- case 'speakTableLocation':
- case 'exitShifterContent':
- if (!cvox.DomPredicates.tablePredicate(cvox.DomUtil.getAncestors(
- cvox.ChromeVox.navigationManager.getCurrentNode()))) {
- errorMsg = 'not_inside_table';
- } else if (!cvox.ChromeVox.navigationManager.performAction(cmd)) {
- errorMsg = 'not_in_table_mode';
- }
- break;
-
- // Generic actions.
- case 'enterShifter':
- case 'exitShifter':
- cvox.ChromeVox.navigationManager.performAction(cmd);
- break;
- // TODO(stoarca): Code repetition.
- case 'decreaseTtsRate':
- // TODO(stoarca): This function name is way too long.
- cvox.ChromeVox.tts.increaseOrDecreaseProperty(
- cvox.AbstractTts.RATE, false);
- break;
- case 'increaseTtsRate':
- cvox.ChromeVox.tts.increaseOrDecreaseProperty(
- cvox.AbstractTts.RATE, true);
- break;
- case 'decreaseTtsPitch':
- cvox.ChromeVox.tts.increaseOrDecreaseProperty(
- cvox.AbstractTts.PITCH, false);
- break;
- case 'increaseTtsPitch':
- cvox.ChromeVox.tts.increaseOrDecreaseProperty(
- cvox.AbstractTts.PITCH, true);
- break;
- case 'decreaseTtsVolume':
- cvox.ChromeVox.tts.increaseOrDecreaseProperty(
- cvox.AbstractTts.VOLUME, false);
- break;
- case 'increaseTtsVolume':
- cvox.ChromeVox.tts.increaseOrDecreaseProperty(
- cvox.AbstractTts.VOLUME, true);
- break;
- case 'cyclePunctuationEcho':
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'TTS',
- 'action': 'cyclePunctuationEcho'
- });
- break;
-
- case 'toggleStickyMode':
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'sticky',
- 'value': !cvox.ChromeVox.isStickyPrefOn,
- 'announce': true
- });
- break;
- case 'toggleKeyPrefix':
- cvox.ChromeVox.keyPrefixOn = !cvox.ChromeVox.keyPrefixOn;
- break;
- case 'passThroughMode':
- cvox.ChromeVox.passThroughMode = true;
- cvox.ChromeVox.tts.speak(
- Msgs.getMsg('pass_through_key'), cvox.QueueMode.QUEUE);
- break;
- case 'toggleSearchWidget':
- cvox.SearchWidget.getInstance().toggle();
- break;
-
- case 'toggleEarcons':
- prefixMsg = cvox.ChromeVox.earcons.toggle() ?
- Msgs.getMsg('earcons_on') :
- Msgs.getMsg('earcons_off');
- break;
-
- case 'showHeadingsList':
- case 'showLinksList':
- case 'showFormsList':
- case 'showTablesList':
- case 'showLandmarksList':
- if (!cmdStruct.nodeList) {
- break;
- }
- var nodeListStruct =
- cvox.CommandStore.NODE_INFO_MAP[cmdStruct.nodeList];
-
- cvox.NodeSearchWidget.create(nodeListStruct.typeMsg,
- cvox.DomPredicates[nodeListStruct.predicate]).show();
- break;
-
- case 'openLongDesc':
- var currentNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- if (cvox.DomUtil.hasLongDesc(currentNode)) {
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'OpenTab',
- 'url': currentNode.longDesc // Use .longDesc instead of getAttribute
- // since we want Chrome to convert the
- // longDesc to an absolute URL.
- });
- } else {
- cvox.ChromeVox.tts.speak(
- Msgs.getMsg('no_long_desc'),
- cvox.QueueMode.FLUSH,
- cvox.AbstractTts.PERSONALITY_ANNOTATION);
- }
- break;
-
- case 'pauseAllMedia':
- var videos = document.getElementsByTagName('VIDEO');
- for (var i = 0, mediaElem; mediaElem = videos[i]; i++) {
- mediaElem.pause();
- }
- var audios = document.getElementsByTagName('AUDIO');
- for (var i = 0, mediaElem; mediaElem = audios[i]; i++) {
- mediaElem.pause();
- }
- break;
-
- // Math specific commands.
- case 'toggleSemantics':
- if (cvox.TraverseMath.toggleSemantic()) {
- cvox.ChromeVox.tts.speak(Msgs.getMsg('semantics_on'),
- cvox.QueueMode.QUEUE);
- } else {
- cvox.ChromeVox.tts.speak(Msgs.getMsg('semantics_off'),
- cvox.QueueMode.QUEUE);
- }
- break;
-
- // Braille specific commands.
- case cvox.BrailleKeyCommand.ROUTING:
- var braille = cmdStruct.content;
- if (braille) {
- cvox.BrailleUtil.click(braille, cmdStruct.event.displayPosition);
- }
- break;
- case cvox.BrailleKeyCommand.PAN_LEFT:
- case cvox.BrailleKeyCommand.LINE_UP:
- case cvox.BrailleKeyCommand.PAN_RIGHT:
- case cvox.BrailleKeyCommand.LINE_DOWN:
- // TODO(dtseng, plundblad): This needs to sync to the last pan position
- // after line up/pan left and move the display to the far right on the
- // line in case the synced to node is longer than one display line.
- // Should also work with all widgets.
- cvox.ChromeVox.navigationManager.navigate(false,
- cvox.NavigationShifter.GRANULARITIES.LINE);
- break;
-
- case 'debug':
- // TODO(stoarca): This doesn't belong here.
- break;
-
- case 'nop':
- break;
- default:
- throw 'Command behavior not defined: ' + cmd;
- }
-
- if (errorMsg != '') {
- cvox.ChromeVox.tts.speak(
- Msgs.getMsg(errorMsg),
- cvox.QueueMode.FLUSH,
- cvox.AbstractTts.PERSONALITY_ANNOTATION);
- } else if (cvox.ChromeVox.navigationManager.isReading()) {
- if (cmdStruct.disallowContinuation) {
- cvox.ChromeVox.navigationManager.stopReading(true);
- } else if (cmd != 'readFromHere') {
- cvox.ChromeVox.navigationManager.skip();
- }
- } else {
- if (cmdStruct.announce) {
- cvox.ChromeVox.navigationManager.finishNavCommand(prefixMsg);
- }
- }
- if (!cmdStruct.allowEvents) {
- cvox.ChromeVoxEventSuspender.exitSuspendEvents();
- }
- return !!cmdStruct.doDefault || ret;
-};
-
-
-/**
- * Default handler for public user commands that are dispatched to the web app
- * first so that the web developer can handle these commands instead of
- * ChromeVox if they decide they can do a better job than the default algorithm.
- *
- * @param {Object} cvoxUserEvent The cvoxUserEvent to handle.
- */
-cvox.ChromeVoxUserCommands.handleChromeVoxUserEvent = function(cvoxUserEvent) {
- var detail = new cvox.UserEventDetail(cvoxUserEvent.detail);
- if (detail.command) {
- cvox.ChromeVoxUserCommands.doCommand_(
- cvox.ChromeVoxUserCommands.lookupCommand_(detail.command, detail));
- }
-};
-
-
-/**
- * Returns an object containing information about the given command.
- * @param {string} cmd The name of the command.
- * @param {Object=} opt_kwargs Optional key values to add to the command
- * structure.
- * @return {Object} A key value mapping.
- * @private
- */
-cvox.ChromeVoxUserCommands.lookupCommand_ = function(cmd, opt_kwargs) {
- var cmdStruct = cvox.CommandStore.CMD_WHITELIST[cmd];
- if (!cmdStruct) {
- throw 'Invalid command: ' + cmd;
- }
- cmdStruct = goog.object.clone(cmdStruct);
- cmdStruct.command = cmd;
- if (opt_kwargs) {
- goog.object.extend(cmdStruct, opt_kwargs);
- }
- return cmdStruct;
-};
-
-
-cvox.ChromeVoxUserCommands.init_();
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands_test.unitjs
deleted file mode 100644
index f425d10719d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands_test.unitjs
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Include test fixture.
-GEN_INCLUDE(['../../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxUserCommandsUnitTest() {
- ChromeVoxUnitTestBase.call(this);
-}
-
-CvoxUserCommandsUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- isAsync: true,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ChromeVoxTester',
- ],
-
- /** @override */
- setUp: function() {
- cvox.ChromeVoxTester.setUp(document);
- },
-
- /** @override */
- tearDown: function() {
- cvox.ChromeVoxTester.tearDown(document);
- }
-};
-
-TEST_F('CvoxUserCommandsUnitTest', 'TabHandling', function() {
- this.loadDoc(function() {/*!
- <div>
- <p id="before">Before</p>
- <a href="http://google.com" id="linka">Here is a link</a>
- <input type="text"></input>
- <h1 id="foo">FirstHeading</h1>
- <a href="http://google.com" id="linkb">Here is another link</a>
- <h2>SecondHeading</h2>
- </div>
- */});
-
- this.waitForCalm(cvox.ChromeVoxTester.syncToFirstNode);
- this.waitForCalm(this.userCommand, 'forward');
- this.waitForCalm(this.userCommand, 'forward');
- this.waitForCalm(this.userCommand, 'forward');
- this.waitForCalm(this.userCommand, 'handleTab');
- this.waitForCalm(function() {
- // handleTab should place focus on a dummy node immediately in front of
- // current position so that tab will jump reasonably.
- var id = document.activeElement.nextSibling.id;
- assertEquals('foo', id);
- });
-});
-
-/**
- * Tests everything in the find next map to make sure there are no
- * typos and everything is valid.
- */
-SYNC_TEST_F('CvoxUserCommandsUnitTest', 'FindNextMap', function() {
- var findMap = cvox.ChromeVoxUserCommands.FIND_NEXT_MAP_;
- for (var find in findMap) {
- assertTrue(
- 'no predicate ' + findMap[find].predicate + ' in ' + find,
- cvox.DomPredicates.hasOwnProperty(findMap[find].predicate));
- // Probably a typo if it's not one of these types.
- for (var j in findMap[find]) {
- assertTrue(
- 'typo in ' + find,
- j == 'predicate' ||
- j == 'forwardError' ||
- j == 'backwardError');
- }
- }
-});
-
-/**
- * Tests the command maps to make sure there are no typos and everything
- * is valid.
- * @export
- */
-SYNC_TEST_F('CvoxUserCommandsUnitTest', 'CommandsMap', function() {
- var cmdMap = cvox.ChromeVoxUserCommands.CMD_WHITELIST_;
- var findMap = cvox.ChromeVoxUserCommands.FIND_NEXT_MAP_;
- for (var cmd in cmdMap) {
- assertTrue(
- 'cant have both forward and backward in ' + cmd,
- !cmdMap[cmd].forward || !cmdMap[cmd].backward);
- for (var j in cmdMap[cmd]) {
- // Probably a typo if it's not one of these types.
- assertTrue(
- 'typo in ' + cmd,
- j == 'forward' ||
- j == 'backward' ||
- j == 'announce' ||
- j == 'findNext' ||
- j == 'doDefault' ||
- j == 'nodeList' ||
- j == 'platformFilter' ||
- j == 'skipInput' ||
- j == 'disallowOOBE' ||
- j == 'allowEvents' ||
- j == 'disallowContinuation');
- }
- if (cmd.findNext) {
- assertTrue(
- 'typo in ' + cmd + ' for findNext id',
- findMap.hasOwnProperty(cmdMap[cmd].findNext));
- assertTrue(
- 'must supply direction for findNext in ' + cmd,
- cmdMap[cmd].forward || cmdMap[cmd].backward);
- }
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_event_detail.js b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_event_detail.js
deleted file mode 100644
index b5276997763..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_event_detail.js
+++ /dev/null
@@ -1,171 +0,0 @@
-// 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.
-
-/**
- * @fileoverview The ChromeVox User Event Detail object.
- *
- * This is the detail object for a CustomEvent that ChromeVox sends to the
- * current node in the DOM when the user wants to perform a ChromeVox action
- * that could potentially be handled better by the underlying web app.
- *
- * ChromeVox events are sent with status "PENDING" and an action that maps to
- * the command list in ChromeVoxUserCommands.
- *
- * If a web app wishes to handle the action, it can perform the action then set
- * the status of the event to either "SUCCESS" or "FAILURE".
- *
- * When the event bubbles back up to the document, ChromeVox will process it.
- * If the status is "PENDING", ChromeVox will perform the action itself.
- * If the status is "FAILURE", ChromeVox will speak the associated error message
- * for that action. (For example: "No next heading.")
- * If the status is "SUCCESS", then ChromeVox will check to see if an associated
- * resultNode is added to the event. If this node exists, then ChromeVox will
- * treat this node as the result of the action and sync/speak it as if it had
- * gotten to this node through ChromeVox's default algorithm. If this field is
- * left as null, then ChromeVox assumes that the web app has already handled
- * speaking/syncing to the result and will do nothing more for this action.
- *
- */
-
-goog.provide('cvox.UserEventDetail');
-
-goog.require('cvox.ChromeVox');
-
-
-
-/**
- * Enables web apps to use its own algorithms to handle certain ChromeVox
- * actions where the web app may be able to do a better job than the default
- * ChromeVox algorithms because it has much more information about its own
- * content and functionality.
- * @constructor
- *
- * @param {Object<{command: (string),
- * status: (undefined|string),
- * resultNode: (undefined|Node),
- * customCommand: (undefined|string)
- * }>} detailObj
- * command: The ChromeVox UserCommand to be performed.
- * status: The status of the event. If the status is left at PENDING, ChromeVox
- * will run its default algorithm for performing the action. Otherwise, it means
- * the underlying web app has performed the action itself. If the status is set
- * to FAILURE, ChromeVox will speak the default error message for this command
- * to the user.
- * resultNode: The result of the action if it has been performed and there is a
- * result. If this is a valid node and the status is set to SUCCESS, ChromeVox
- * will sync to this node and speak it.
- * customCommand: The custom command to be performed. This is designed to allow
- * web apps / other extensions to define custom actions that can be shown in
- * ChromeVox (for example, inside the context menu) and then dispatched back to
- * the page.
- */
-cvox.UserEventDetail = function(detailObj) {
- /**
- * The category of command that should be performed.
- * @type {string}
- */
- this.category = '';
-
- /**
- * The user command that should be performed.
- * @type {string}
- */
- this.command = '';
- if (cvox.UserEventDetail.JUMP_COMMANDS.indexOf(detailObj.command) != -1) {
- this.command = detailObj.command;
- this.category = cvox.UserEventDetail.Category.JUMP;
- }
-
- /**
- * The custom command that should be performed.
- * @type {string}
- */
- this.customCommand = '';
- if (detailObj.customCommand) {
- this.customCommand = detailObj.customCommand;
- this.category = cvox.UserEventDetail.Category.CUSTOM;
- }
-
- /**
- * The status of the event.
- * @type {string}
- */
- this.status = cvox.UserEventDetail.Status.PENDING;
- switch (detailObj.status) {
- case cvox.UserEventDetail.Status.SUCCESS:
- this.status = cvox.UserEventDetail.Status.SUCCESS;
- break;
- case cvox.UserEventDetail.Status.FAILURE:
- this.status = cvox.UserEventDetail.Status.FAILURE;
- break;
- }
-
- /**
- * The result of performing the command.
- *
- * @type {Node}
- */
- this.resultNode = null;
- if (detailObj.resultNode &&
- cvox.DomUtil.isAttachedToDocument(detailObj.resultNode)) {
- this.resultNode = detailObj.resultNode;
- }
-};
-
-/**
- * Category of the user event. This is the event name that the web app should
- * be listening for.
- * @enum {string}
- */
-cvox.UserEventDetail.Category = {
- JUMP: 'ATJumpEvent',
- CUSTOM: 'ATCustomEvent'
-};
-
-/**
- * Status of the cvoxUserEvent. Events start off as PENDING. If the underlying
- * web app has handled this event, it should set the event to either SUCCESS or
- * FAILURE to prevent ChromeVox from trying to redo the same command.
- * @enum {string}
- */
-cvox.UserEventDetail.Status = {
- PENDING: 'PENDING',
- SUCCESS: 'SUCCESS',
- FAILURE: 'FAILURE'
-};
-
-
-/**
- * List of commands that are dispatchable to the page.
- *
- * @type {Array}
- */
-// TODO (clchen): Integrate this with command_store.js.
-cvox.UserEventDetail.JUMP_COMMANDS = [
- 'nextCheckbox', 'previousCheckbox', 'nextRadio', 'previousRadio',
- 'nextSlider', 'previousSlider', 'nextGraphic', 'previousGraphic',
- 'nextButton', 'previousButton', 'nextComboBox', 'previousComboBox',
- 'nextEditText', 'previousEditText', 'nextHeading', 'previousHeading',
- 'nextHeading1', 'previousHeading1', 'nextHeading2', 'previousHeading2',
- 'nextHeading3', 'previousHeading3', 'nextHeading4', 'previousHeading4',
- 'nextHeading5', 'previousHeading5', 'nextHeading6', 'previousHeading6',
- 'nextLink', 'previousLink', 'nextMath', 'previousMath', 'nextTable',
- 'previousTable', 'nextList', 'previousList', 'nextListItem',
- 'previousListItem', 'nextFormField', 'previousFormField', 'nextLandmark',
- 'previousLandmark', 'nextSection', 'previousSection', 'nextControl',
- 'previousControl'
-];
-
-/**
- * Creates a custom event object from the UserEventDetail.
- *
- * @return {!Event} A custom event object that can be dispatched to the page.
- */
-cvox.UserEventDetail.prototype.createEventObject = function() {
- // We use CustomEvent so that it will go all the way to the page and come back
- // into the ChromeVox context correctly.
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent(this.category, true, true, this);
- return evt;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_assets.gypi b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_assets.gypi
index 47a67a44dd7..f7a523463dc 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_assets.gypi
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_assets.gypi
@@ -4,11 +4,16 @@
{
'variables': {
- 'chromevox_assets_chromevox': [
- 'chromevox/chromevox-128.png',
- 'chromevox/chromevox-16.png',
- 'chromevox/chromevox-19.png',
- 'chromevox/chromevox-48.png',
+ 'chromevox_assets_images': [
+ 'images/chromevox-128.png',
+ 'images/chromevox-16.png',
+ 'images/chromevox-19.png',
+ 'images/chromevox-48.png',
+ 'images/close-19.png',
+ 'images/close-hover-19.png',
+ 'images/options-19.png',
+ 'images/options-hover-19.png',
+ 'images/triangle-6.png',
],
'chromevox_assets_chromevox_background_earcons': [
'chromevox/background/earcons/alert_modal.ogg',
@@ -41,6 +46,7 @@
'chromevox/background/keymaps/classic_keymap.json',
'chromevox/background/keymaps/experimental.json',
'chromevox/background/keymaps/flat_keymap.json',
+ 'chromevox/background/keymaps/next_keymap.json',
],
'chromevox_assets_chromevox_background_mathmaps_functions': [
'chromevox/background/mathmaps/functions/algebra.json',
@@ -91,9 +97,9 @@
'type': 'none',
'copies': [
{
- 'destination': '<(chromevox_dest_dir)/chromevox',
+ 'destination': '<(chromevox_dest_dir)/images',
'files': [
- '<@(chromevox_assets_chromevox)',
+ '<@(chromevox_assets_images)',
],
},
{
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_tests.gypi b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_tests.gypi
index ca47324e340..15127ca4555 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_tests.gypi
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_tests.gypi
@@ -83,7 +83,9 @@
'cvox2/background/automation_util_test.extjs',
'cvox2/background/background_test.extjs',
'cvox2/background/cursors_test.extjs',
+ 'cvox2/background/live_regions_test.extjs',
'cvox2/background/output_test.extjs',
+ 'cvox2/background/tree_walker_test.extjs',
'host/chrome/tts_background_test.extjs',
],
},
@@ -98,6 +100,7 @@
'<(DEPTH)/chrome/chrome.gyp:browser',
'<(DEPTH)/chrome/chrome.gyp:renderer',
'<(DEPTH)/chrome/chrome.gyp:test_support_common',
+ '<(DEPTH)/chrome/chrome.gyp:test_support_ui',
'<(DEPTH)/chrome/chrome_resources.gyp:chrome_resources',
'<(DEPTH)/chrome/chrome_resources.gyp:chrome_strings',
'<(DEPTH)/chrome/chrome_resources.gyp:packed_extra_resources',
@@ -121,6 +124,11 @@
'<(DEPTH)/native_client/src/trusted/service_runtime/linux/nacl_bootstrap.gyp:nacl_helper_bootstrap',
],
}],
+ ['OS=="win" and win_use_allocator_shim==1', {
+ 'dependencies': [
+ '<(DEPTH)/base/allocator/allocator.gyp:allocator',
+ ],
+ }],
],
'defines': [
'HAS_OUT_OF_PROC_TEST_RUNNER',
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_vars.gypi b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_vars.gypi
index c6997cec600..c38d599fa5b 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_vars.gypi
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox_vars.gypi
@@ -6,10 +6,12 @@
{
'variables': {
- 'chromevox1_content_script_loader_file': 'chromevox/injected/loader.js',
- 'chromevox1_kbexplorer_loader_file': 'chromevox/background/kbexplorer_loader.js',
- 'chromevox1_options_script_loader_file': 'chromevox/background/options_loader.js',
- 'chromevox2_background_script_loader_file': 'cvox2/background/loader.js',
+ 'chromevox_background_script_loader_file': 'cvox2/background/loader.js',
+ 'chromevox_content_script_loader_file': 'chromevox/injected/loader.js',
'chromevox_extension_key': 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDltVl1k15pjRzuZfMc3B69inxwm2bZeZ2O8/zFO+NluHnBm3GJ3fzdOoFGJd+M16I8p7zxxQyHeDMfWYASyCeB8XnUEDKjqNLQfCnncsANzHsYoEbYj2nEUML2P13b9q+AAvpCBpAJ4cZp81e9n1y/vbSXHE4385cgkKueItzikQIDAQAB',
- }
+ 'chromevox_kbexplorer_loader_file': 'chromevox/background/kbexplorer_loader.js',
+ 'chromevox_min_content_script_loader_file': 'cvox2/injected/loader.js',
+ 'chromevox_options_script_loader_file': 'chromevox/background/options_loader.js',
+ 'chromevox_panel_script_loader_file': 'cvox2/background/panel_loader.js',
+ }
}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/closure/closure_preinit.js b/chromium/chrome/browser/resources/chromeos/chromevox/closure/closure_preinit.js
deleted file mode 100644
index f82d980bcc8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/closure/closure_preinit.js
+++ /dev/null
@@ -1,94 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Code to execute before Closure's base.js.
- *
- */
-
-/**
- * Tell Closure to load JavaScript code from the extension root directory.
- * @type {boolean}
- */
-window.CLOSURE_BASE_PATH = chrome.extension.getURL('/closure/');
-
-/**
- * Tell Closure not to load deps.js; it's included by manifest.json already.
- * @type {boolean}
- */
-window.CLOSURE_NO_DEPS = true;
-
-/**
- * Array of urls that should be included next, in order.
- * @type {Array}
- * @private
- */
-window.queue_ = [];
-
-/**
- * Custom function for importing ChromeVox scripts.
- * @param {string} src The JS file to import.
- * @return {boolean} Whether the script was imported.
- */
-window.CLOSURE_IMPORT_SCRIPT = function(src) {
- // Only run our version of the import script
- // when trying to inject ChromeVox scripts.
- if (src.indexOf('chrome-extension://') == 0) {
- if (!goog.inHtmlDocument_() ||
- goog.dependencies_.written[src]) {
- return false;
- }
- goog.dependencies_.written[src] = true;
- function loadNextScript() {
- if (goog.global.queue_.length == 0)
- return;
-
- var src = goog.global.queue_[0];
-
- if (window.CLOSURE_USE_EXT_MESSAGES) {
- var relativeSrc = src.substr(src.indexOf('closure/..') + 11);
- chrome.extension.sendMessage(
- {'srcFile': relativeSrc},
- function(response) {
- try {
- eval(response['code']);
- } catch (e) {
- console.error('Script error: ' + e + ' in ' + src);
- }
- goog.global.queue_ = goog.global.queue_.slice(1);
- loadNextScript();
- });
- return;
- }
- window.console.log('Using XHR');
-
- // Load the script by fetching its source and running 'eval' on it
- // directly, with a magic comment that makes Chrome treat it like it
- // loaded normally. Wait until it's fetched before loading the
- // next script.
- var xhr = new XMLHttpRequest();
- var url = src + '?' + new Date().getTime();
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- var scriptText = xhr.responseText;
- // Add a magic comment to the bottom of the file so that
- // Chrome knows the name of the script in the JavaScript debugger.
- scriptText += '\n//# sourceURL=' + src + '\n';
- eval(scriptText);
- goog.global.queue_ = goog.global.queue_.slice(1);
- loadNextScript();
- }
- };
- xhr.open('GET', url, false);
- xhr.send(null);
- }
- goog.global.queue_.push(src);
- if (goog.global.queue_.length == 1) {
- loadNextScript();
- }
- return true;
- } else {
- return goog.writeScriptTag_(src);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/aria_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/aria_util.js
deleted file mode 100644
index 09b36bdf1a1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/aria_util.js
+++ /dev/null
@@ -1,978 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A collection of JavaScript utilities used to simplify working
- * with ARIA (http://www.w3.org/TR/wai-aria).
- */
-
-
-goog.provide('cvox.AriaUtil');
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.NodeState');
-goog.require('cvox.NodeStateUtil');
-
-
-/**
- * Create the namespace
- * @constructor
- */
-cvox.AriaUtil = function() {
-};
-
-
-/**
- * A mapping from ARIA role names to their message ids.
- * Note: If you are adding a new mapping, the new message identifier needs a
- * corresponding braille message. For example, a message id 'tag_button'
- * requires another message 'tag_button_brl' within messages.js.
- * @type {Object<string>}
- */
-cvox.AriaUtil.WIDGET_ROLE_TO_NAME = {
- 'alert' : 'role_alert',
- 'alertdialog' : 'role_alertdialog',
- 'button' : 'role_button',
- 'checkbox' : 'role_checkbox',
- 'columnheader' : 'role_columnheader',
- 'combobox' : 'role_combobox',
- 'dialog' : 'role_dialog',
- 'grid' : 'role_grid',
- 'gridcell' : 'role_gridcell',
- 'link' : 'role_link',
- 'listbox' : 'role_listbox',
- 'log' : 'role_log',
- 'marquee' : 'role_marquee',
- 'menu' : 'role_menu',
- 'menubar' : 'role_menubar',
- 'menuitem' : 'role_menuitem',
- 'menuitemcheckbox' : 'role_menuitemcheckbox',
- 'menuitemradio' : 'role_menuitemradio',
- 'option' : 'role_option',
- 'progressbar' : 'role_progressbar',
- 'radio' : 'role_radio',
- 'radiogroup' : 'role_radiogroup',
- 'rowheader' : 'role_rowheader',
- 'scrollbar' : 'role_scrollbar',
- 'slider' : 'role_slider',
- 'spinbutton' : 'role_spinbutton',
- 'status' : 'role_status',
- 'tab' : 'role_tab',
- 'tablist' : 'role_tablist',
- 'tabpanel' : 'role_tabpanel',
- 'textbox' : 'role_textbox',
- 'timer' : 'role_timer',
- 'toolbar' : 'role_toolbar',
- 'tooltip' : 'role_tooltip',
- 'treeitem' : 'role_treeitem'
-};
-
-
-/**
- * Note: If you are adding a new mapping, the new message identifier needs a
- * corresponding braille message. For example, a message id 'tag_button'
- * requires another message 'tag_button_brl' within messages.js.
- * @type {Object<string>}
- */
-cvox.AriaUtil.STRUCTURE_ROLE_TO_NAME = {
- 'article' : 'role_article',
- 'application' : 'role_application',
- 'banner' : 'role_banner',
- 'columnheader' : 'role_columnheader',
- 'complementary' : 'role_complementary',
- 'contentinfo' : 'role_contentinfo',
- 'definition' : 'role_definition',
- 'directory' : 'role_directory',
- 'document' : 'role_document',
- 'form' : 'role_form',
- 'group' : 'role_group',
- 'heading' : 'role_heading',
- 'img' : 'role_img',
- 'list' : 'role_list',
- 'listitem' : 'role_listitem',
- 'main' : 'role_main',
- 'math' : 'role_math',
- 'navigation' : 'role_navigation',
- 'note' : 'role_note',
- 'region' : 'role_region',
- 'rowheader' : 'role_rowheader',
- 'search' : 'role_search',
- 'separator' : 'role_separator'
-};
-
-
-/**
- * @type {Array<Object>}
- */
-cvox.AriaUtil.ATTRIBUTE_VALUE_TO_STATUS = [
- { name: 'aria-autocomplete', values:
- {'inline' : 'aria_autocomplete_inline',
- 'list' : 'aria_autocomplete_list',
- 'both' : 'aria_autocomplete_both'} },
- { name: 'aria-checked', values:
- {'true' : 'aria_checked_true',
- 'false' : 'aria_checked_false',
- 'mixed' : 'aria_checked_mixed'} },
- { name: 'aria-disabled', values:
- {'true' : 'aria_disabled_true'} },
- { name: 'aria-expanded', values:
- {'true' : 'aria_expanded_true',
- 'false' : 'aria_expanded_false'} },
- { name: 'aria-invalid', values:
- {'true' : 'aria_invalid_true',
- 'grammar' : 'aria_invalid_grammar',
- 'spelling' : 'aria_invalid_spelling'} },
- { name: 'aria-multiline', values:
- {'true' : 'aria_multiline_true'} },
- { name: 'aria-multiselectable', values:
- {'true' : 'aria_multiselectable_true'} },
- { name: 'aria-pressed', values:
- {'true' : 'aria_pressed_true',
- 'false' : 'aria_pressed_false',
- 'mixed' : 'aria_pressed_mixed'} },
- { name: 'aria-readonly', values:
- {'true' : 'aria_readonly_true'} },
- { name: 'aria-required', values:
- {'true' : 'aria_required_true'} },
- { name: 'aria-selected', values:
- {'true' : 'aria_selected_true',
- 'false' : 'aria_selected_false'} }
-];
-
-
-/**
- * Checks if a node should be treated as a hidden node because of its ARIA
- * markup.
- *
- * @param {Node} targetNode The node to check.
- * @return {boolean} True if the targetNode should be treated as hidden.
- */
-cvox.AriaUtil.isHiddenRecursive = function(targetNode) {
- if (cvox.AriaUtil.isHidden(targetNode)) {
- return true;
- }
- var parent = targetNode.parentElement;
- while (parent) {
- if ((parent.getAttribute('aria-hidden') == 'true') &&
- (parent.getAttribute('chromevoxignoreariahidden') != 'true')) {
- return true;
- }
- parent = parent.parentElement;
- }
- return false;
-};
-
-
-/**
- * Checks if a node should be treated as a hidden node because of its ARIA
- * markup. Does not check parents, so if you need to know if this is a
- * descendant of a hidden node, call isHiddenRecursive.
- *
- * @param {Node} targetNode The node to check.
- * @return {boolean} True if the targetNode should be treated as hidden.
- */
-cvox.AriaUtil.isHidden = function(targetNode) {
- if (!targetNode) {
- return true;
- }
- if (targetNode.getAttribute) {
- if ((targetNode.getAttribute('aria-hidden') == 'true') &&
- (targetNode.getAttribute('chromevoxignoreariahidden') != 'true')) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Checks if a node should be treated as a visible node because of its ARIA
- * markup, regardless of whatever other styling/attributes it may have.
- * It is possible to force a node to be visible by setting aria-hidden to
- * false.
- *
- * @param {Node} targetNode The node to check.
- * @return {boolean} True if the targetNode should be treated as visible.
- */
-cvox.AriaUtil.isForcedVisibleRecursive = function(targetNode) {
- var node = targetNode;
- while (node) {
- if (node.getAttribute) {
- // Stop and return the result based on the closest node that has
- // aria-hidden set.
- if (node.hasAttribute('aria-hidden') &&
- (node.getAttribute('chromevoxignoreariahidden') != 'true')) {
- return node.getAttribute('aria-hidden') == 'false';
- }
- }
- node = node.parentElement;
- }
- return false;
-};
-
-
-/**
- * Checks if a node should be treated as a leaf node because of its ARIA
- * markup. Does not check recursively, and does not check isControlWidget.
- * Note that elements with aria-label are treated as leaf elements. See:
- * http://www.w3.org/TR/wai-aria/roles#textalternativecomputation
- *
- * @param {Element} targetElement The node to check.
- * @return {boolean} True if the targetNode should be treated as a leaf node.
- */
-cvox.AriaUtil.isLeafElement = function(targetElement) {
- var role = targetElement.getAttribute('role');
- var hasArialLabel = targetElement.hasAttribute('aria-label') &&
- (targetElement.getAttribute('aria-label').length > 0);
- return (role == 'img' || role == 'progressbar' || hasArialLabel);
-};
-
-
-/**
- * Determines whether or not a node is or is the descendant of a node
- * with a particular role.
- *
- * @param {Node} node The node to be checked.
- * @param {string} roleName The role to check for.
- * @return {boolean} True if the node or one of its ancestor has the specified
- * role.
- */
-cvox.AriaUtil.isDescendantOfRole = function(node, roleName) {
- while (node) {
- if (roleName && node && (node.getAttribute('role') == roleName)) {
- return true;
- }
- node = node.parentNode;
- }
- return false;
-};
-
-
-/**
- * Helper function to return the role name message identifier for a role.
- * @param {string} role The role.
- * @return {?string} The role name message identifier.
- * @private
- */
-cvox.AriaUtil.getRoleNameMsgForRole_ = function(role) {
- var msgId = cvox.AriaUtil.WIDGET_ROLE_TO_NAME[role];
- if (!msgId) {
- return null;
- }
- return msgId;
-};
-
-/**
- * Returns true is the node is any kind of button.
- *
- * @param {Node} node The node to check.
- * @return {boolean} True if the node is a button.
- */
-cvox.AriaUtil.isButton = function(node) {
- var role = cvox.AriaUtil.getRoleAttribute(node);
- if (role == 'button') {
- return true;
- }
- if (node.tagName == 'BUTTON') {
- return true;
- }
- if (node.tagName == 'INPUT') {
- return (node.type == 'submit' ||
- node.type == 'reset' ||
- node.type == 'button');
- }
- return false;
-};
-
-/**
- * Returns a role message identifier for a node.
- * For a localized string, see cvox.AriaUtil.getRoleName.
- * @param {Node} targetNode The node to get the role name for.
- * @return {string} The role name message identifier for the targetNode.
- */
-cvox.AriaUtil.getRoleNameMsg = function(targetNode) {
- var roleName;
- if (targetNode && targetNode.getAttribute) {
- var role = cvox.AriaUtil.getRoleAttribute(targetNode);
-
- // Special case for pop-up buttons.
- if (targetNode.getAttribute('aria-haspopup') == 'true' &&
- cvox.AriaUtil.isButton(targetNode)) {
- return 'role_popup_button';
- }
-
- if (role) {
- roleName = cvox.AriaUtil.getRoleNameMsgForRole_(role);
- if (!roleName) {
- roleName = cvox.AriaUtil.STRUCTURE_ROLE_TO_NAME[role];
- }
- }
-
- // To a user, a menu item within a menu bar is called a "menu";
- // any other menu item is called a "menu item".
- //
- // TODO(deboer): This block feels like a hack. dmazzoni suggests
- // using css-like syntax for names. Investigate further if
- // we need more of these hacks.
- if (role == 'menuitem') {
- var container = targetNode.parentElement;
- while (container) {
- if (container.getAttribute &&
- (cvox.AriaUtil.getRoleAttribute(container) == 'menu' ||
- cvox.AriaUtil.getRoleAttribute(container) == 'menubar')) {
- break;
- }
- container = container.parentElement;
- }
- if (container && cvox.AriaUtil.getRoleAttribute(container) == 'menubar') {
- roleName = cvox.AriaUtil.getRoleNameMsgForRole_('menu');
- } // else roleName is already 'Menu item', no need to change it.
- }
- }
- if (!roleName) {
- roleName = '';
- }
- return roleName;
-};
-
-/**
- * Returns a string to be presented to the user that identifies what the
- * targetNode's role is.
- *
- * @param {Node} targetNode The node to get the role name for.
- * @return {string} The role name for the targetNode.
- */
-cvox.AriaUtil.getRoleName = function(targetNode) {
- var roleMsg = cvox.AriaUtil.getRoleNameMsg(targetNode);
- var roleName = Msgs.getMsg(roleMsg);
- var role = cvox.AriaUtil.getRoleAttribute(targetNode);
- if ((role == 'heading') && (targetNode.hasAttribute('aria-level'))) {
- roleName += ' ' + targetNode.getAttribute('aria-level');
- }
- return roleName ? roleName : '';
-};
-
-/**
- * Returns a string that gives information about the state of the targetNode.
- *
- * @param {Node} targetNode The node to get the state information for.
- * @param {boolean} primary Whether this is the primary node we're
- * interested in, where we might want extra information - as
- * opposed to an ancestor, where we might be more brief.
- * @return {cvox.NodeState} The status information about the node.
- */
-cvox.AriaUtil.getStateMsgs = function(targetNode, primary) {
- var state = [];
- if (!targetNode || !targetNode.getAttribute) {
- return state;
- }
-
- for (var i = 0, attr; attr = cvox.AriaUtil.ATTRIBUTE_VALUE_TO_STATUS[i];
- i++) {
- var value = targetNode.getAttribute(attr.name);
- var msgId = attr.values[value];
- if (msgId) {
- state.push([msgId]);
- }
- }
- if (targetNode.getAttribute('role') == 'grid') {
- return cvox.AriaUtil.getGridState_(targetNode, targetNode);
- }
-
- var role = cvox.AriaUtil.getRoleAttribute(targetNode);
- if (targetNode.getAttribute('aria-haspopup') == 'true') {
- if (role == 'menuitem') {
- state.push(['has_submenu']);
- } else if (cvox.AriaUtil.isButton(targetNode)) {
- // Do nothing - the role name will be 'pop-up button'.
- } else {
- state.push(['has_popup']);
- }
- }
-
- var valueText = targetNode.getAttribute('aria-valuetext');
- if (valueText) {
- // If there is a valueText, that always wins.
- state.push(['aria_value_text', valueText]);
- return state;
- }
-
- var valueNow = targetNode.getAttribute('aria-valuenow');
- var valueMin = targetNode.getAttribute('aria-valuemin');
- var valueMax = targetNode.getAttribute('aria-valuemax');
-
- // Scrollbar and progressbar should speak the percentage.
- // http://www.w3.org/TR/wai-aria/roles#scrollbar
- // http://www.w3.org/TR/wai-aria/roles#progressbar
- if ((valueNow != null) && (valueMin != null) && (valueMax != null)) {
- if ((role == 'scrollbar') || (role == 'progressbar')) {
- var percent = Math.round((valueNow / (valueMax - valueMin)) * 100);
- state.push(['state_percent', percent]);
- return state;
- }
- }
-
- // Return as many of the value attributes as possible.
- if (valueNow != null) {
- state.push(['aria_value_now', valueNow]);
- }
- if (valueMin != null) {
- state.push(['aria_value_min', valueMin]);
- }
- if (valueMax != null) {
- state.push(['aria_value_max', valueMax]);
- }
-
- // If this is a composite control or an item within a composite control,
- // get the index and count of the current descendant or active
- // descendant.
- var parentControl = targetNode;
- var currentDescendant = null;
-
- if (cvox.AriaUtil.isCompositeControl(parentControl) && primary) {
- currentDescendant = cvox.AriaUtil.getActiveDescendant(parentControl);
- } else {
- role = cvox.AriaUtil.getRoleAttribute(targetNode);
- if (role == 'option' ||
- role == 'menuitem' ||
- role == 'menuitemcheckbox' ||
- role == 'menuitemradio' ||
- role == 'radio' ||
- role == 'tab' ||
- role == 'treeitem') {
- currentDescendant = targetNode;
- parentControl = targetNode.parentElement;
- while (parentControl &&
- !cvox.AriaUtil.isCompositeControl(parentControl)) {
- parentControl = parentControl.parentElement;
- if (parentControl &&
- cvox.AriaUtil.getRoleAttribute(parentControl) == 'treeitem') {
- break;
- }
- }
- }
- }
-
- if (parentControl &&
- (cvox.AriaUtil.isCompositeControl(parentControl) ||
- cvox.AriaUtil.getRoleAttribute(parentControl) == 'treeitem') &&
- currentDescendant) {
- var parentRole = cvox.AriaUtil.getRoleAttribute(parentControl);
- var descendantRoleList;
- switch (parentRole) {
- case 'combobox':
- case 'listbox':
- descendantRoleList = ['option'];
- break;
- case 'menu':
- descendantRoleList = ['menuitem',
- 'menuitemcheckbox',
- 'menuitemradio'];
- break;
- case 'radiogroup':
- descendantRoleList = ['radio'];
- break;
- case 'tablist':
- descendantRoleList = ['tab'];
- break;
- case 'tree':
- case 'treegrid':
- case 'treeitem':
- descendantRoleList = ['treeitem'];
- break;
- }
-
- if (descendantRoleList) {
- var listLength;
- var currentIndex;
-
- var ariaLength =
- parseInt(currentDescendant.getAttribute('aria-setsize'), 10);
- if (!isNaN(ariaLength)) {
- listLength = ariaLength;
- }
- var ariaIndex =
- parseInt(currentDescendant.getAttribute('aria-posinset'), 10);
- if (!isNaN(ariaIndex)) {
- currentIndex = ariaIndex;
- }
-
- if (listLength == undefined || currentIndex == undefined) {
- var descendants = cvox.AriaUtil.getNextLevel(parentControl,
- descendantRoleList);
- if (listLength == undefined) {
- listLength = descendants.length;
- }
- if (currentIndex == undefined) {
- for (var j = 0; j < descendants.length; j++) {
- if (descendants[j] == currentDescendant) {
- currentIndex = j + 1;
- }
- }
- }
- }
- if (currentIndex && listLength) {
- state.push(['list_position', currentIndex, listLength]);
- }
- }
- }
- return state;
-};
-
-
-/**
- * Returns a string that gives information about the state of the grid node.
- *
- * @param {Node} targetNode The node to get the state information for.
- * @param {Node} parentControl The parent composite control.
- * @return {cvox.NodeState} The status information about the node.
- * @private
- */
-cvox.AriaUtil.getGridState_ = function(targetNode, parentControl) {
- var activeDescendant = cvox.AriaUtil.getActiveDescendant(parentControl);
-
- if (activeDescendant) {
- var descendantSelector = '*[role~="row"]';
- var rows = parentControl.querySelectorAll(descendantSelector);
- var currentIndex = null;
- for (var j = 0; j < rows.length; j++) {
- var gridcells = rows[j].querySelectorAll('*[role~="gridcell"]');
- for (var k = 0; k < gridcells.length; k++) {
- if (gridcells[k] == activeDescendant) {
- return /** @type {cvox.NodeState} */ (
- [['role_gridcell_pos', j + 1, k + 1]]);
- }
- }
- }
- }
- return [];
-};
-
-
-/**
- * Returns the id of a node's active descendant
- * @param {Node} targetNode The node.
- * @return {?string} The id of the active descendant.
- * @private
- */
-cvox.AriaUtil.getActiveDescendantId_ = function(targetNode) {
- if (!targetNode.getAttribute) {
- return null;
- }
-
- var activeId = targetNode.getAttribute('aria-activedescendant');
- if (!activeId) {
- return null;
- }
- return activeId;
-};
-
-
-/**
- * Returns the list of elements that are one aria-level below.
- *
- * @param {Node} parentControl The node whose descendants should be analyzed.
- * @param {Array<string>} role The role(s) of descendant we are looking for.
- * @return {Array<Node>} The array of matching nodes.
- */
-cvox.AriaUtil.getNextLevel = function(parentControl, role) {
- var result = [];
- var children = parentControl.childNodes;
- var length = children.length;
- for (var i = 0; i < children.length; i++) {
- if (cvox.AriaUtil.isHidden(children[i]) ||
- !cvox.DomUtil.isVisible(children[i])) {
- continue;
- }
- var nextLevel = cvox.AriaUtil.getNextLevelItems(children[i], role);
- if (nextLevel.length > 0) {
- result = result.concat(nextLevel);
- }
- }
- return result;
-};
-
-
-/**
- * Recursively finds the first node(s) that match the role.
- *
- * @param {Element} current The node to start looking at.
- * @param {Array<string>} role The role(s) to match.
- * @return {Array<Element>} The array of matching nodes.
- */
-cvox.AriaUtil.getNextLevelItems = function(current, role) {
- if (current.nodeType != 1) { // If reached a node that is not an element.
- return [];
- }
- if (role.indexOf(cvox.AriaUtil.getRoleAttribute(current)) != -1) {
- return [current];
- } else {
- var children = current.childNodes;
- var length = children.length;
- if (length == 0) {
- return [];
- } else {
- var resultArray = [];
- for (var i = 0; i < length; i++) {
- var result = cvox.AriaUtil.getNextLevelItems(children[i], role);
- if (result.length > 0) {
- resultArray = resultArray.concat(result);
- }
- }
- return resultArray;
- }
- }
-};
-
-
-/**
- * If the node is an object with an active descendant, returns the
- * descendant node.
- *
- * This function will fully resolve an active descendant chain. If a circular
- * chain is detected, it will return null.
- *
- * @param {Node} targetNode The node to get descendant information for.
- * @return {Node} The descendant node or null if no node exists.
- */
-cvox.AriaUtil.getActiveDescendant = function(targetNode) {
- var seenIds = {};
- var node = targetNode;
-
- while (node) {
- var activeId = cvox.AriaUtil.getActiveDescendantId_(node);
- if (!activeId) {
- break;
- }
- if (activeId in seenIds) {
- // A circlar activeDescendant is an error, so return null.
- return null;
- }
- seenIds[activeId] = true;
- node = document.getElementById(activeId);
- }
-
- if (node == targetNode) {
- return null;
- }
- return node;
-};
-
-
-/**
- * Given a node, returns true if it's an ARIA control widget. Control widgets
- * are treated as leaf nodes.
- *
- * @param {Node} targetNode The node to be checked.
- * @return {boolean} Whether the targetNode is an ARIA control widget.
- */
-cvox.AriaUtil.isControlWidget = function(targetNode) {
- if (targetNode && targetNode.getAttribute) {
- var role = cvox.AriaUtil.getRoleAttribute(targetNode);
- switch (role) {
- case 'button':
- case 'checkbox':
- case 'combobox':
- case 'listbox':
- case 'menu':
- case 'menuitemcheckbox':
- case 'menuitemradio':
- case 'radio':
- case 'slider':
- case 'progressbar':
- case 'scrollbar':
- case 'spinbutton':
- case 'tab':
- case 'tablist':
- case 'textbox':
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Given a node, returns true if it's an ARIA composite control.
- *
- * @param {Node} targetNode The node to be checked.
- * @return {boolean} Whether the targetNode is an ARIA composite control.
- */
-cvox.AriaUtil.isCompositeControl = function(targetNode) {
- if (targetNode && targetNode.getAttribute) {
- var role = cvox.AriaUtil.getRoleAttribute(targetNode);
- switch (role) {
- case 'combobox':
- case 'grid':
- case 'listbox':
- case 'menu':
- case 'menubar':
- case 'radiogroup':
- case 'tablist':
- case 'tree':
- case 'treegrid':
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Given a node, returns its 'aria-live' value if it's a live region, or
- * null otherwise.
- *
- * @param {Node} node The node to be checked.
- * @return {?string} The live region value, like 'polite' or
- * 'assertive', or null if 'off' or none.
- */
-cvox.AriaUtil.getAriaLive = function(node) {
- if (!node.hasAttribute)
- return null;
- var value = node.getAttribute('aria-live');
- if (value == 'off') {
- return null;
- } else if (value) {
- return value;
- }
- var role = cvox.AriaUtil.getRoleAttribute(node);
- switch (role) {
- case 'alert':
- return 'assertive';
- case 'log':
- case 'status':
- return 'polite';
- default:
- return null;
- }
-};
-
-
-/**
- * Given a node, returns its 'aria-atomic' value.
- *
- * @param {Node} node The node to be checked.
- * @return {boolean} The aria-atomic live region value, either true or false.
- */
-cvox.AriaUtil.getAriaAtomic = function(node) {
- if (!node.hasAttribute)
- return false;
- var value = node.getAttribute('aria-atomic');
- if (value) {
- return (value === 'true');
- }
- var role = cvox.AriaUtil.getRoleAttribute(node);
- if (role == 'alert') {
- return true;
- }
- return false;
-};
-
-
-/**
- * Given a node, returns its 'aria-busy' value.
- *
- * @param {Node} node The node to be checked.
- * @return {boolean} The aria-busy live region value, either true or false.
- */
-cvox.AriaUtil.getAriaBusy = function(node) {
- if (!node.hasAttribute)
- return false;
- var value = node.getAttribute('aria-busy');
- if (value) {
- return (value === 'true');
- }
- return false;
-};
-
-
-/**
- * Given a node, checks its aria-relevant attribute (with proper inheritance)
- * and determines whether the given change (additions, removals, text, all)
- * is relevant and should be announced.
- *
- * @param {Node} node The node to be checked.
- * @param {string} change The name of the change to check - one of
- * 'additions', 'removals', 'text', 'all'.
- * @return {boolean} True if that change is relevant to that node as part of
- * a live region.
- */
-cvox.AriaUtil.getAriaRelevant = function(node, change) {
- if (!node.hasAttribute)
- return false;
- var value;
- if (node.hasAttribute('aria-relevant')) {
- value = node.getAttribute('aria-relevant');
- } else {
- value = 'additions text';
- }
- if (value == 'all') {
- value = 'additions removals text';
- }
-
- var tokens = value.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '').split(' ');
-
- if (change == 'all') {
- return (tokens.indexOf('additions') >= 0 &&
- tokens.indexOf('text') >= 0 &&
- tokens.indexOf('removals') >= 0);
- } else {
- return (tokens.indexOf(change) >= 0);
- }
-};
-
-
-/**
- * Given a node, return all live regions that are either rooted at this
- * node or contain this node.
- *
- * @param {Node} node The node to be checked.
- * @return {Array<Element>} All live regions affected by this node changing.
- */
-cvox.AriaUtil.getLiveRegions = function(node) {
- var result = [];
- if (node.querySelectorAll) {
- var nodes = node.querySelectorAll(
- '[role="alert"], [role="log"], [role="marquee"], ' +
- '[role="status"], [role="timer"], [aria-live]');
- if (nodes) {
- for (var i = 0; i < nodes.length; i++) {
- result.push(nodes[i]);
- }
- }
- }
-
- while (node) {
- if (cvox.AriaUtil.getAriaLive(node)) {
- result.push(node);
- return result;
- }
- node = node.parentElement;
- }
-
- return result;
-};
-
-
-/**
- * Checks to see whether or not a node is an ARIA landmark.
- *
- * @param {Node} node The node to be checked.
- * @return {boolean} Whether or not the node is an ARIA landmark.
- */
-cvox.AriaUtil.isLandmark = function(node) {
- if (!node || !node.getAttribute) {
- return false;
- }
- var role = cvox.AriaUtil.getRoleAttribute(node);
- switch (role) {
- case 'application':
- case 'banner':
- case 'complementary':
- case 'contentinfo':
- case 'form':
- case 'main':
- case 'navigation':
- case 'search':
- return true;
- }
- return false;
-};
-
-
-/**
- * Checks to see whether or not a node is an ARIA grid.
- *
- * @param {Node} node The node to be checked.
- * @return {boolean} Whether or not the node is an ARIA grid.
- */
-cvox.AriaUtil.isGrid = function(node) {
- if (!node || !node.getAttribute) {
- return false;
- }
- var role = cvox.AriaUtil.getRoleAttribute(node);
- switch (role) {
- case 'grid':
- case 'treegrid':
- return true;
- }
- return false;
-};
-
-
-/**
- * Returns the id of an earcon to play along with the description for a node.
- *
- * @param {Node} node The node to get the earcon for.
- * @return {cvox.Earcon?} The earcon id, or null if none applies.
- */
-cvox.AriaUtil.getEarcon = function(node) {
- if (!node || !node.getAttribute) {
- return null;
- }
- var role = cvox.AriaUtil.getRoleAttribute(node);
- switch (role) {
- case 'button':
- return cvox.Earcon.BUTTON;
- case 'checkbox':
- case 'radio':
- case 'menuitemcheckbox':
- case 'menuitemradio':
- var checked = node.getAttribute('aria-checked');
- if (checked == 'true') {
- return cvox.Earcon.CHECK_ON;
- } else {
- return cvox.Earcon.CHECK_OFF;
- }
- case 'combobox':
- case 'listbox':
- return cvox.Earcon.LISTBOX;
- case 'textbox':
- return cvox.Earcon.EDITABLE_TEXT;
- case 'listitem':
- return cvox.Earcon.LIST_ITEM;
- case 'link':
- return cvox.Earcon.LINK;
- }
-
- return null;
-};
-
-
-/**
- * Returns the role of the node.
- *
- * This is equivalent to targetNode.getAttribute('role')
- * except it also takes into account cases where ChromeVox
- * itself has changed the role (ie, adding role="application"
- * to BODY elements for better screen reader compatibility.
- *
- * @param {Node} targetNode The node to get the role for.
- * @return {string} role of the targetNode.
- */
-cvox.AriaUtil.getRoleAttribute = function(targetNode) {
- if (!targetNode.getAttribute) {
- return '';
- }
- var role = targetNode.getAttribute('role');
- if (targetNode.hasAttribute('chromevoxoriginalrole')) {
- role = targetNode.getAttribute('chromevoxoriginalrole');
- }
- return role;
-};
-
-
-/**
- * Checks to see whether or not a node is an ARIA math node.
- *
- * @param {Node} node The node to be checked.
- * @return {boolean} Whether or not the node is an ARIA math node.
- */
-cvox.AriaUtil.isMath = function(node) {
- if (!node || !node.getAttribute) {
- return false;
- }
- var role = cvox.AriaUtil.getRoleAttribute(node);
- return role == 'math';
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/aria_util_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/aria_util_test.unitjs
deleted file mode 100644
index bf13830445b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/aria_util_test.unitjs
+++ /dev/null
@@ -1,142 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture for aria_util.js.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxAriaUtilUnitTest() {}
-
-CvoxAriaUtilUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.AriaUtil',
- 'cvox.ChromeVox',
- 'cvox.DomUtil',]
-};
-
-TEST_F('CvoxAriaUtilUnitTest', 'GetStateGridWithActiveCell', function() {
- this.loadDoc(function() {/*!
- <div id="grid" role="grid" aria-activedescendant="cell">
- <div role="row">
- <div id="cell" role="gridcell">
- </div>
- </div>
- */});
- assertThat(
- cvox.AriaUtil.getStateMsgs($('grid'), true),
- eqJSON([['role_gridcell_pos', 1, 1]]));
-});
-
-TEST_F('CvoxAriaUtilUnitTest', 'GetActiveDescendant', function() {
- this.loadDoc(function() {/*!
- <div id="top" aria-activedescendant="child">
- <div id="child" />
- </div>
- <div id="top_2" aria-activedescendant="child_2">
- <div id="child_2" aria-activedescendant="grandchild_2">
- <div id="grandchild_2" />
- </div>
- </div>
-
- <h1>The buggy cases.</h1>
- <div id="loop" aria-activedescendant="loop" />
- <div id="circleA" aria-activedescendant="circleB">
- <div id="circleB" aria-activedescendant="circleA" />
- </div>
- */});
-
- // The typical case.
- var topElt = $('top');
- var childElt = $('child');
- assertEquals(childElt, cvox.AriaUtil.getActiveDescendant(topElt));
-
- // childElt has not aria-activedescendant, so return null.
- assertEquals(null, cvox.AriaUtil.getActiveDescendant(childElt));
-
- // The chained case.
- var top2Elt = $('top_2');
- var grandchild2Elt = $('grandchild_2');
- assertEquals(grandchild2Elt, cvox.AriaUtil.getActiveDescendant(top2Elt));
-
- // The buggy cases. These are invalid, so return null as if the
- // aria-activedescendant tags did not exist.
- var loopElt = $('loop');
- assertEquals(null, cvox.AriaUtil.getActiveDescendant(loopElt));
-
- var circleAElt = $('circleA');
- assertEquals(null, cvox.AriaUtil.getActiveDescendant(circleAElt));
-});
-
-TEST_F('CvoxAriaUtilUnitTest', 'ListIndexAndState', function() {
- this.loadDoc(function() {/*!
- <div id="l" role="listbox" tabindex="0" aria-activedescendant="l2">
- <div id="l1" role="option">A</div>
- <div id="l2" role="option">B</div>
- <div id="l3" role="option">C</div>
- </div>
- <div id="a" role="listbox" tabindex="0" aria-activedescendant="a2">
- <div id="a1" role="option" aria-setsize="10" aria-posinset="5">A</div>
- <div id="a2" role="option" aria-setsize="20" aria-posinset="15">B</div>
- <div id="a3" role="option" aria-setsize="30" aria-posinset="25">C</div>
- </div>
- <div id="b" role="listbox" tabindex="0" aria-activedescendant="b2">
- <div id="b1" role="option" aria-posinset="3">A</div>
- <div id="b2" role="option" aria-posinset="2">B</div>
- <div id="b3" role="option" aria-posinset="1">C</div>
- </div>
- */});
-
- var optionElt = $('l2');
- assertThat(
- cvox.AriaUtil.getStateMsgs(optionElt),
- eqJSON([['list_position', 2, 3]]));
-
- var ariaOptionElt = $('a2');
- assertThat(
- cvox.AriaUtil.getStateMsgs(ariaOptionElt),
- eqJSON([['list_position', 15, 20]]));
-
- ariaOptionElt = $('b3');
- assertThat(
- cvox.AriaUtil.getStateMsgs(ariaOptionElt),
- eqJSON([['list_position', 1, 3]]));
-});
-
-TEST_F('CvoxAriaUtilUnitTest', 'GetLiveRegions', function() {
- this.loadDoc(function() {/*!
- <div id="outer">
- <div id="progress" role="progressbar" aria-live="polite" aria-valuenow="1">
- <div id="ptext">
- 1% complete.
- </div>
- </div>
- <div id="progress2" role="progressbar" aria-live="polite" aria-valuenow="1">
- <div id="ptext2">
- 1% complete.
- </div>
- </div>
- </div>
- */});
-
- var progressLiveRegions = cvox.AriaUtil.getLiveRegions(progress);
- assertEquals(1, progressLiveRegions.length);
- assertNotEquals(-1, progressLiveRegions.indexOf(progress));
-
- var outerLiveRegions = cvox.AriaUtil.getLiveRegions(outer);
- assertEquals(2, outerLiveRegions.length);
- assertNotEquals(-1, outerLiveRegions.indexOf(progress));
- assertNotEquals(-1, outerLiveRegions.indexOf(progress2));
-
- // getLiveRegions works walking up the tree as well.
- var ptextLiveRegions = cvox.AriaUtil.getLiveRegions(ptext);
- assertEquals(1, ptextLiveRegions.length);
- assertNotEquals(-1, ptextLiveRegions.indexOf(progress));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/aural_style_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/aural_style_util.js
deleted file mode 100644
index 0e8c3b5cf57..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/aural_style_util.js
+++ /dev/null
@@ -1,209 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A set of classes to support aural CSS.
- */
-
-
-goog.provide('cvox.AuralProperty');
-goog.provide('cvox.AuralStyleConverter');
-goog.provide('cvox.AuralStyleUtil');
-
-// This seems the only way to lay out an enum and use it as a key.
-/**
- * @enum {string}
- */
-cvox.AuralProperty = {
- VOLUME: 'VOLUME',
- SPEAK: 'SPEAK',
- PAUSE_BEFORE: 'PAUSE_BEFORE',
- PAUSE_AFTER: 'PAUSE_AFTER',
- PAUSE: 'PAUSE',
- CUE_BEFORE: 'CUE_BEFORE',
- CUE_AFTER: 'CUE_AFTER',
- CUE: 'CUE',
- PLAY_DURING: 'PLAY_DURING',
- AZIMUTH: 'AZIMUTH',
- ELEVATION: 'ELEVATION',
- SPEECH_RATE: 'SPEECH_RATE',
- VOICE_FAMILY: 'VOICE_FAMILY',
- PITCH: 'PITCH',
- PITCH_RANGE: 'PITCH_RANGE',
- STRESS: 'STRESS',
- RICHNESS: 'RICHNESS',
- SPEAK_PUNCTUATION: 'SPEAK_PUNCTUATION',
- SPEAK_NUMERIAL: 'SPEAK_NUMERIAL',
- SPEAK_HEADER: 'SPEAK_HEADER',
- NONE: 'NONE'
-};
-
-
-/* A series of conversion functions. */
-/**
- * An identity conversion.
- * @param {number} value The aural CSS value to convert.
- * @return {number} The resulting tts property value.
- */
-cvox.AuralStyleConverter.identity = function(value) {
- return value;
-};
-
-
-/**
- * Conversion from an aural style property to Chrome TTS property.
- * TODO(dtseng): no-op's below need to be supported by the extension API itself
- * or by ChromeVox.
- * @type {Object<cvox.AuralProperty, string>}
- */
-cvox.AuralStyleConverter.propertyTable = {
- VOLUME: 'volume',
- SPEAK: 'no-op',
- PAUSE_BEFORE: 'no-op',
- PAUSE_AFTER: 'no-op',
- PAUSE: 'no-op',
- CUE_BEFORE: 'no-op',
- CUE_AFTER: 'no-op',
- CUE: 'no-op',
- PLAY_DURING: 'no-op',
- AZIMUTH: 'no-op',
- ELEVATION: 'no-op',
- SPEECH_RATE: 'relativeRate',
- VOICE_FAMILY: 'no-op',
- PITCH: 'relativePitch',
- PITCH_RANGE: 'no-op',
- STRESS: 'no-op',
- RICHNESS: 'no-op',
- SPEAK_PUNCTUATION: 'no-op',
- SPEAK_NUMERIAL: 'no-op',
- SPEAK_HEADER: 'no-op',
- NONE: 'no-op'
-};
-
-
-/**
- * Conversion from an aural style value to Chrome TTS value.
- * TODO(dtseng): Conversion of aural CSS values is incomplete; everything is an
- * identity conversion at the moment.
- * @type {Object<cvox.AuralProperty, function(*)>}
- */
-cvox.AuralStyleConverter.valueTable = {
- VOLUME: cvox.AuralStyleConverter.identity,
- SPEAK: cvox.AuralStyleConverter.identity,
- PAUSE_BEFORE: cvox.AuralStyleConverter.identity,
- PAUSE_AFTER: cvox.AuralStyleConverter.identity,
- PAUSE: cvox.AuralStyleConverter.identity,
- CUE_BEFORE: cvox.AuralStyleConverter.identity,
- CUE_AFTER: cvox.AuralStyleConverter.identity,
- CUE: cvox.AuralStyleConverter.identity,
- PLAY_DURING: cvox.AuralStyleConverter.identity,
- AZIMUTH: cvox.AuralStyleConverter.identity,
- ELEVATION: cvox.AuralStyleConverter.identity,
- SPEECH_RATE: cvox.AuralStyleConverter.identity,
- VOICE_FAMILY: cvox.AuralStyleConverter.identity,
- PITCH: cvox.AuralStyleConverter.identity,
- PITCH_RANGE: cvox.AuralStyleConverter.identity,
- STRESS: cvox.AuralStyleConverter.identity,
- RICHNESS: cvox.AuralStyleConverter.identity,
- SPEAK_PUNCTUATION: cvox.AuralStyleConverter.identity,
- SPEAK_NUMERIAL: cvox.AuralStyleConverter.identity,
- SPEAK_HEADER: cvox.AuralStyleConverter.identity,
- NONE: cvox.AuralStyleConverter.identity
-};
-
-
-/**
- * Converts a given aural property/value rule to a tts property/value.
- * @param {cvox.AuralProperty} property The property.
- * @param {*} value The CSS-based value.
- * @return {Object} An object holding tts property and value.
- */
-cvox.AuralStyleConverter.convertRule = function(property, value) {
- return {
- property: cvox.AuralStyleConverter.propertyTable[property],
- value: cvox.AuralStyleConverter.valueTable[property](value)
- };
-};
-
-
-/**
- * Converts an aural CSS style block to a TTS property object.
- * @param {Object<cvox.AuralProperty, *>} style The style.
- * @return {Object} The tts property object.
- */
-cvox.AuralStyleConverter.convertStyle = function(style) {
- var ttsProperties = {};
- for (var property in style) {
- var ttsProperty =
- cvox.AuralStyleConverter.convertRule(property, style[property]);
- ttsProperties[ttsProperty.property] = ttsProperty.value;
- }
- return ttsProperties;
-};
-
-
-/**
- * Gets the aural style for a node.
- * @param {Node} node The node.
- * @return {Object} The aural style, converted to tts properties.
-*/
-cvox.AuralStyleUtil.getStyleForNode = function(node) {
- var style = cvox.AuralStyleUtil.defaultStyles[node.tagName];
- if (!style) {
- return null;
- }
- return cvox.AuralStyleConverter.convertStyle(style);
-};
-
-
-/**
- * A list of default aural styles.
- */
-cvox.AuralStyleUtil.defaultStyles = {
- 'ARTICLE': {
- PITCH: -0.1
- },
- 'ASIDE': {
- PITCH: -0.1
- },
- 'FOOTER': {
- PITCH: -0.1
- },
- 'H1': {
- PITCH: -0.3
- },
- 'H2': {
- PITCH: -0.25
- },
- 'H3': {
- PITCH: -0.2
- },
- 'H4': {
- PITCH: -0.15
- },
- 'H5': {
- PITCH: -0.1
- },
- 'H6': {
- PITCH: -0.05
- },
- 'HEADER': {
- PITCH: -0.1
- },
- 'HGROUP': {
- PITCH: -0.1
- },
- 'MARK': {
- PITCH: -0.1
- },
- 'NAV': {
- PITCH: -0.1
- },
- 'SECTION': {
- PITCH: -0.1
- },
- 'TIME': {
- PITCH: -0.1
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_text_handler.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_text_handler.js
deleted file mode 100644
index 36d3e04cba8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_text_handler.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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.
-
-goog.provide('cvox.BrailleTextHandler');
-
-goog.require('cvox.BrailleInterface');
-goog.require('cvox.BrailleUtil');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.NavBraille');
-
-/**
- * @fileoverview Updates braille display contents following text changes.
- *
- */
-
-/**
- * Represents an editable text region.
- *
- * @constructor
- * @param {!cvox.BrailleInterface} braille Braille interface.
- */
-cvox.BrailleTextHandler = function(braille) {
- /**
- * Braille interface used to produce output.
- * @type {!cvox.BrailleInterface}
- * @private
- */
- this.braille_ = braille;
-};
-
-
-/**
- * Called by controller class when text changes.
- * @param {string} line The text of the line.
- * @param {number} start The 0-based index starting selection.
- * @param {number} end The 0-based index ending selection.
- * @param {boolean} multiline True if the text comes from a multi line text
- * field.
- * @param {Element} element DOM node which line comes from.
- * @param {number} lineStart Start offset of line (might be > 0 for multiline
- * fields).
- */
-cvox.BrailleTextHandler.prototype.changed = function(
- line, start, end, multiline, element, lineStart) {
- var content;
- if (multiline) {
- var spannable = cvox.BrailleUtil.createValue(line, start, end, lineStart);
- if (element) {
- spannable.setSpan(element, 0, line.length);
- }
- content = new cvox.NavBraille({text: spannable,
- startIndex: start,
- endIndex: end});
- } else {
- if (cvox.ChromeVox.navigationManager) {
- content = cvox.ChromeVox.navigationManager.getBraille();
- }
- }
- if (content) {
- this.braille_.write(content);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_text_handler_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_text_handler_test.unitjs
deleted file mode 100644
index 3f53422bd38..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_text_handler_test.unitjs
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * @extends {cvox.BrailleInterface}
- * @constructor
- */
-function FakeBraille() {
-}
-
-FakeBraille.prototype = {
- /** @override */
- write: function(content) {
- this.content = content;
- }
-};
-
-/** @constructor */
-function FakeNavigationManager() {
-}
-
-FakeNavigationManager.prototype = {
- getBraille: function() {
- return this.navBraille;
- },
-
- setNavBraille: function(navBraille) {
- this.navBraille = navBraille;
- }
-};
-
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxBrailleTextHandlerUnitTest() {}
-
-CvoxBrailleTextHandlerUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.BrailleInterface',
- 'cvox.BrailleTextHandler',
- 'cvox.NavBraille',
- 'cvox.NavigationManager',
- ],
-
- /** @override */
- setUp: function() {
- this.navigationManager = new FakeNavigationManager();
- this.braille = new FakeBraille();
- cvox.ChromeVox.navigationManager = this.navigationManager;
- this.brailleTextHandler = new cvox.BrailleTextHandler(this.braille);
- }
-};
-
-TEST_F('CvoxBrailleTextHandlerUnitTest', 'UpdateByUser', function() {
- var navBraille = new cvox.NavBraille({ text: 'Hello, world!' });
- this.navigationManager.setNavBraille(navBraille);
-
- this.brailleTextHandler.changed('', 0, 0, false);
- assertEquals(navBraille, this.braille.content);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_util.js
deleted file mode 100644
index 77ace8dcfc0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_util.js
+++ /dev/null
@@ -1,374 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A utility class for general braille functionality.
- */
-
-
-goog.provide('cvox.BrailleUtil');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.DomUtil');
-goog.require('cvox.EditableTextAreaShadow');
-goog.require('cvox.Focuser');
-goog.require('cvox.NavBraille');
-goog.require('cvox.NodeStateUtil');
-goog.require('cvox.Spannable');
-goog.require('cvox.ValueSelectionSpan');
-goog.require('cvox.ValueSpan');
-
-
-/**
- * Trimmable whitespace character that appears between consecutive items in
- * braille.
- * @const {string}
- */
-cvox.BrailleUtil.ITEM_SEPARATOR = ' ';
-
-
-/**
- * Messages considered as containers in braille.
- * Containers are distinguished from roles by their appearance higher up in the
- * DOM tree of a selected node.
- * This list should be very short.
- * @type {!Array<string>}
- */
-cvox.BrailleUtil.CONTAINER = [
- 'tag_h1_brl',
- 'tag_h2_brl',
- 'tag_h3_brl',
- 'tag_h4_brl',
- 'tag_h5_brl',
- 'tag_h6_brl'
-];
-
-
-/**
- * Maps a ChromeVox message id to a braille template.
- * The template takes one-character specifiers:
- * n: replaced with braille name.
- * r: replaced with braille role.
- * s: replaced with braille state.
- * c: replaced with braille container role; this potentially returns whitespace,
- * so place at the beginning or end of templates for trimming.
- * v: replaced with braille value.
- * @type {Object<string>}
- */
-cvox.BrailleUtil.TEMPLATE = {
- 'base': 'c n v r s',
- 'role_alert': 'r: n',
- 'role_button': 'n r s',
- 'role_checkbox': 'n r s',
- 'role_menuitemcheckbox': 'n r s',
- 'role_menuitemradio': 'n r s',
- 'role_radio': 'n r s',
- 'role_textbox': 'n: v r s',
- 'input_type_email': 'n: v r s',
- 'input_type_number': 'n: v r s',
- 'input_type_password': 'n: v r s',
- 'input_type_search': 'n: v r s',
- 'input_type_text': 'n: v r s',
- 'input_type_url': 'n: v r s',
- 'tag_textarea': 'n: v r s'
-};
-
-
-/**
- * Gets the braille name for a node.
- * See DomUtil for a more precise definition of 'name'.
- * Additionally, whitespace is trimmed.
- * @param {Node} node The node.
- * @return {string} The string representation.
- */
-cvox.BrailleUtil.getName = function(node) {
- if (!node) {
- return '';
- }
- return cvox.DomUtil.getName(node).trim();
-};
-
-
-/**
- * Gets the braille role message id for a node.
- * See DomUtil for a more precise definition of 'role'.
- * @param {Node} node The node.
- * @return {string} The string representation.
- */
-cvox.BrailleUtil.getRoleMsg = function(node) {
- if (!node) {
- return '';
- }
- var roleMsg = cvox.DomUtil.getRoleMsg(node, cvox.VERBOSITY_VERBOSE);
- if (roleMsg) {
- roleMsg = cvox.DomUtil.collapseWhitespace(roleMsg);
- }
- if (roleMsg && (roleMsg.length > 0)) {
- if (Msgs.getMsg(roleMsg + '_brl')) {
- roleMsg += '_brl';
- }
- }
- return roleMsg;
-};
-
-
-/**
- * Transforms a {@code cvox.NodeState} list of state messages to the
- * corresponding messages for braille and expands them into a localized
- * string suitable for output on a braille display.
- * @param {cvox.NodeState} stateMsgs The states to expand. The content of this
- * array is modified.
- * @return {string} The string representation.
- * @private
- */
-cvox.BrailleUtil.expandStateMsgs_ = function(stateMsgs) {
- stateMsgs.forEach(function(state) {
- // Check to see if a variant of the message with '_brl' exists,
- // and use it if so.
- //
- // Note: many messages are templatized, and if we don't pass any
- // argument to substitute, getMsg might throw an error if the
- // resulting string is empty. To avoid this, we pass a dummy
- // substitution string array here.
- var dummySubs = ['dummy', 'dummy', 'dummy'];
- if (Msgs.getMsg(state[0] + '_brl', dummySubs)) {
- state[0] += '_brl';
- }
- });
- return cvox.NodeStateUtil.expand(stateMsgs);
-};
-
-
-/**
- * Gets the braille container role of a node.
- * @param {Node} prev The previous node in navigation.
- * @param {Node} node The node.
- * @return {string} The string representation.
- */
-cvox.BrailleUtil.getContainer = function(prev, node) {
- if (!prev || !node) {
- return '';
- }
- var ancestors = cvox.DomUtil.getUniqueAncestors(prev, node);
- for (var i = 0, container; container = ancestors[i]; i++) {
- var msg = cvox.BrailleUtil.getRoleMsg(container);
- if (msg && cvox.BrailleUtil.CONTAINER.indexOf(msg) != -1) {
- return Msgs.getMsg(msg);
- }
- }
- return '';
-};
-
-
-/**
- * Gets the braille value of a node. A {@code cvox.ValueSpan} will be
- * attached, along with (possibly) a {@code cvox.ValueSelectionSpan}.
- * @param {Node} node The node.
- * @return {!cvox.Spannable} The value spannable.
- */
-cvox.BrailleUtil.getValue = function(node) {
- if (!node) {
- return new cvox.Spannable();
- }
- var valueSpan = new cvox.ValueSpan(0 /* offset */);
- if (cvox.DomUtil.isInputTypeText(node)) {
- var value = node.value;
- if (node.type === 'password') {
- value = value.replace(/./g, '*');
- }
- var spannable = new cvox.Spannable(value, valueSpan);
- if (node === document.activeElement &&
- cvox.DomUtil.doesInputSupportSelection(node)) {
- var selectionStart = cvox.BrailleUtil.clamp_(
- node.selectionStart, 0, spannable.getLength());
- var selectionEnd = cvox.BrailleUtil.clamp_(
- node.selectionEnd, 0, spannable.getLength());
- spannable.setSpan(new cvox.ValueSelectionSpan(),
- Math.min(selectionStart, selectionEnd),
- Math.max(selectionStart, selectionEnd));
- }
- return spannable;
- } else if (node instanceof HTMLTextAreaElement) {
- var shadow = new cvox.EditableTextAreaShadow();
- shadow.update(node);
- var lineIndex = shadow.getLineIndex(node.selectionEnd);
- var lineStart = shadow.getLineStart(lineIndex);
- var lineEnd = shadow.getLineEnd(lineIndex);
- var lineText = node.value.substring(lineStart, lineEnd);
- valueSpan.offset = lineStart;
- var spannable = new cvox.Spannable(lineText, valueSpan);
- if (node === document.activeElement) {
- var selectionStart = cvox.BrailleUtil.clamp_(
- node.selectionStart - lineStart, 0, spannable.getLength());
- var selectionEnd = cvox.BrailleUtil.clamp_(
- node.selectionEnd - lineStart, 0, spannable.getLength());
- spannable.setSpan(new cvox.ValueSelectionSpan(),
- Math.min(selectionStart, selectionEnd),
- Math.max(selectionStart, selectionEnd));
- }
- return spannable;
- } else {
- return new cvox.Spannable(cvox.DomUtil.getValue(node), valueSpan);
- }
-};
-
-
-/**
- * Gets the templated representation of braille.
- * @param {Node} prev The previous node (during navigation).
- * @param {Node} node The node.
- * @param {{name:(undefined|string),
- * role:(undefined|string),
- * roleMsg:(undefined|string),
- * state:(undefined|string),
- * container:(undefined|string),
- * value:(undefined|cvox.Spannable)}|Object=} opt_override Override a
- * specific property for the given node.
- * @return {!cvox.Spannable} The string representation.
- */
-cvox.BrailleUtil.getTemplated = function(prev, node, opt_override) {
- opt_override = opt_override ? opt_override : {};
- var roleMsg = opt_override.roleMsg ||
- (node ? cvox.DomUtil.getRoleMsg(node, cvox.VERBOSITY_VERBOSE) : '');
- var template = cvox.BrailleUtil.TEMPLATE[roleMsg] ||
- cvox.BrailleUtil.TEMPLATE['base'];
- var state = opt_override.state;
- if (!state) {
- if (node) {
- state = cvox.BrailleUtil.expandStateMsgs_(
- cvox.DomUtil.getStateMsgs(node, true));
- } else {
- state = '';
- }
- }
- var role = opt_override.role || '';
- if (!role && roleMsg) {
- role = Msgs.getMsg(roleMsg + '_brl') ||
- Msgs.getMsg(roleMsg);
- }
-
- var templated = new cvox.Spannable();
- var mapChar = function(c) {
- switch (c) {
- case 'n':
- return opt_override.name || cvox.BrailleUtil.getName(node);
- case 'r':
- return role;
- case 's':
- return state;
- case 'c':
- return opt_override.container ||
- cvox.BrailleUtil.getContainer(prev, node);
- case 'v':
- return opt_override.value || cvox.BrailleUtil.getValue(node);
- default:
- return c;
- }
- };
- for (var i = 0; i < template.length; i++) {
- var component = mapChar(template[i]);
- templated.append(component);
- // Ignore the next whitespace separator if the current component is empty,
- // unless the empty value has a selection, in which case the cursor
- // should be placed on the empty space after the empty value.
- if (!component.toString() && template[i + 1] == ' ' &&
- (!(component instanceof cvox.Spannable) ||
- !/**@type {cvox.Spannable}*/(component).getSpanInstanceOf(
- cvox.ValueSelectionSpan))) {
- i++;
- }
- }
- return templated.trimRight();
-};
-
-
-/**
- * Creates a braille value from a string and, optionally, a selection range.
- * A {@code cvox.ValueSpan} will be attached, along with a
- * {@code cvox.ValueSelectionSpan} if applicable.
- * @param {string} text The text to display as the value.
- * @param {number=} opt_selStart Selection start.
- * @param {number=} opt_selEnd Selection end if different from selection start.
- * @param {number=} opt_textOffset Start offset of text.
- * @return {!cvox.Spannable} The value spannable.
- */
-cvox.BrailleUtil.createValue = function(text, opt_selStart, opt_selEnd,
- opt_textOffset) {
- var spannable = new cvox.Spannable(
- text, new cvox.ValueSpan(opt_textOffset || 0));
- if (goog.isDef(opt_selStart)) {
- opt_selEnd = goog.isDef(opt_selEnd) ? opt_selEnd : opt_selStart;
- // TODO(plundblad): This looses the distinction between the selection
- // anchor (start) and focus (end). We should use that information to
- // decide where to pan the braille display.
- if (opt_selStart > opt_selEnd) {
- var temp = opt_selStart;
- opt_selStart = opt_selEnd;
- opt_selEnd = temp;
- }
-
- spannable.setSpan(new cvox.ValueSelectionSpan(), opt_selStart, opt_selEnd);
- }
- return spannable;
-};
-
-
-/**
- * Activates a position in a nav braille. Moves the caret in text fields
- * and simulates a mouse click on the node at the position.
- *
- * @param {!cvox.NavBraille} braille the nav braille representing the display
- * content that was active when the user issued the key command.
- * The annotations in the spannable are used to decide what
- * node to activate and what part of the node value (if any) to
- * move the caret to.
- * @param {number=} opt_displayPosition position of the display that the user
- * activated, relative to the start of braille.
- */
-cvox.BrailleUtil.click = function(braille, opt_displayPosition) {
- var handled = false;
- var spans = braille.text.getSpans(opt_displayPosition || 0);
- var node = spans.filter(function(n) { return n instanceof Node; })[0];
- if (node) {
- if (goog.isDef(opt_displayPosition) &&
- (cvox.DomUtil.isInputTypeText(node) ||
- node instanceof HTMLTextAreaElement)) {
- var valueSpan = spans.filter(
- function(s) {
- return s instanceof cvox.ValueSpan;
- })[0];
- if (valueSpan) {
- if (document.activeElement !== node) {
- cvox.Focuser.setFocus(node);
- }
- var cursorPosition = opt_displayPosition -
- braille.text.getSpanStart(valueSpan) +
- valueSpan.offset;
- cvox.ChromeVoxEventWatcher.setUpTextHandler();
- node.selectionStart = node.selectionEnd = cursorPosition;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- handled = true;
- }
- }
- }
- if (!handled) {
- cvox.DomUtil.clickElem(
- node || cvox.ChromeVox.navigationManager.getCurrentNode(),
- false, false, false, true);
- }
-};
-
-
-/**
- * Clamps a number so it is within the given boundaries.
- * @param {number} number The number to clamp.
- * @param {number} min The minimum value to return.
- * @param {number} max The maximum value to return.
- * @return {number} {@code number} if it is within the bounds, or the nearest
- * number within the bounds otherwise.
- * @private
- */
-cvox.BrailleUtil.clamp_ = function(number, min, max) {
- return Math.min(Math.max(number, min), max);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_util_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_util_test.unitjs
deleted file mode 100644
index be935d5df48..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/braille_util_test.unitjs
+++ /dev/null
@@ -1,420 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxBrailleUtilUnitTest() {}
-
-CvoxBrailleUtilUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.BrailleUtil',
- 'cvox.CursorSelection',
- 'cvox.NavigationShifter',
- 'TestMsgs',
- ],
-
- /** @override */
- setUp: function() {
- Msgs = TestMsgs;
- },
-
- /**
- * @param {!Node} expectedParent Expected parent node.
- * @param {!Node} node Node to examine.
- * @private
- */
- assertTextNodeChildOf_: function(expectedParent, node) {
- assertEquals(Node.TEXT_NODE, node.nodeType);
- assertEquals(expectedParent, node.parentNode);
- },
-
- /**
- * Helper to retrieve braille for testing.
- * @param {!cvox.CursorSelection} prevSel Previous selection.
- * @param {!cvox.CursorSelection} sel Current selection.
- * @return {!cvox.NavBraille} Resulting braille.
- * @private
- */
- getBraille_: function(prevSel, sel) {
- return (new cvox.NavigationShifter).getBraille(prevSel, sel);
- },
-
- /**
- * Asserts that two NavBraille objects are equal, ignoring spans.
- * @param {Object} expected Expected result, should have no spans.
- * @param {cvox.NavBraille} actual Actual result.
- */
- assertBrailleEquals: function(expected, actual) {
- actual = new cvox.NavBraille({
- text: actual.text.toString(),
- startIndex: actual.startIndex,
- endIndex: actual.endIndex
- });
- assertThat(actual, eqJSON(new cvox.NavBraille(expected)));
- }
-};
-
-TEST_F('CvoxBrailleUtilUnitTest', 'BrailleName', function() {
- this.loadHtml(
- '<div id="navbar">' +
- '<a id="1" href="one.com">one</a>' +
- '<a id="2" href="two.com">two</a>' +
- '<a id="3" href="three.com">three</a>' +
- '</div>');
- var navbar = cvox.CursorSelection.fromNode($('navbar'));
- var braille = this.getBraille_(navbar, navbar);
- this.assertBrailleEquals(
- {text: 'one lnk two lnk three lnk',
- startIndex: 0,
- endIndex: 1
- }, braille);
-
- var one =
- cvox.CursorSelection.fromNode($('1').firstChild);
- braille = this.getBraille_(one, one);
- this.assertBrailleEquals(
- {text: 'one lnk two lnk three lnk',
- startIndex: 0,
- endIndex: 1
- }, braille);
-
- var two =
- cvox.CursorSelection.fromNode($('2').firstChild);
- braille = this.getBraille_(one, two);
- this.assertBrailleEquals(
- {text: 'one lnk two lnk three lnk',
- startIndex: 8,
- endIndex: 9
- }, braille);
-
- var three =
- cvox.CursorSelection.fromNode($('3').firstChild);
- braille = this.getBraille_(two, three);
- this.assertBrailleEquals(
- {text: 'one lnk two lnk three lnk',
- startIndex: 16,
- endIndex: 17
- }, braille);
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'NameTemplate', function() {
- this.loadHtml(
- '<button id="1">Submit</button>' +
- '<input id="2" type="text" aria-label="Search">'
- );
-
- var button = cvox.CursorSelection.fromNode($('1'));
-
- this.assertBrailleEquals(
- {text: 'Submit btn',
- startIndex: 0,
- endIndex: 1
- }, this.getBraille_(button, button));
-
- var inputElement = $('2');
- var input = cvox.CursorSelection.fromNode(inputElement);
-
- // Note: the cursor appears where text would be typed.
- this.assertBrailleEquals(
- {text: 'Search: ed',
- startIndex: 0,
- endIndex: 1
- }, this.getBraille_(input, input));
- inputElement.focus();
- this.assertBrailleEquals(
- {text: 'Search: ed',
- startIndex: 8,
- endIndex: 8
- }, this.getBraille_(input, input));
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'TextField', function() {
- this.loadHtml(
- '<input id="1" type="text" aria-label="Search" value="larry">'
- );
-
- var inputElement = $('1');
- var input = cvox.CursorSelection.fromNode(inputElement);
-
- // Note: the cursor appears where text would be typed.
- // The cursor is at the beginning by default.
- this.assertBrailleEquals(
- {text: 'Search: larry ed',
- startIndex: 0,
- endIndex: 1
- }, this.getBraille_(input, input));
- inputElement.focus();
- inputElement.selectionStart = 0;
- inputElement.selectionEnd = 5;
- this.assertBrailleEquals(
- {text: 'Search: larry ed',
- startIndex: 8,
- endIndex: 13
- }, this.getBraille_(input, input));
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'TextFieldEmpty', function() {
- this.loadHtml(
- '<input id="1" type="text">'
- );
-
- var inputElement = $('1');
- var input = cvox.CursorSelection.fromNode($('1'));
-
- this.assertBrailleEquals(
- {text: ': ed',
- startIndex: 0,
- endIndex: 1
- }, this.getBraille_(input, input));
- inputElement.focus();
- this.assertBrailleEquals(
- {text: ': ed',
- startIndex: 2,
- endIndex: 2
- }, this.getBraille_(input, input));
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'TextFieldSelection', function() {
- this.loadHtml(
- '<input id="1" type="text" value="strawberry">'
- );
-
- var inputElem = $('1');
- inputElem.focus();
- var input = cvox.CursorSelection.fromNode(inputElem);
-
- // Selection.
- inputElem.selectionStart = 2;
- inputElem.selectionEnd = 5;
- this.assertBrailleEquals(
- {text: ': strawberry ed',
- startIndex: 4,
- endIndex: 7
- }, this.getBraille_(input, input));
-
- // Cursor at end.
- inputElem.selectionStart = 10;
- inputElem.selectionEnd = 10;
- this.assertBrailleEquals(
- {text: ': strawberry ed',
- startIndex: 12,
- endIndex: 12
- }, this.getBraille_(input, input));
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'StateTemplate', function() {
- this.loadHtml(
- '<input id="1" type="checkbox" aria-label="Save">');
-
- var checkbox = cvox.CursorSelection.fromNode($('1'));
-
- this.assertBrailleEquals(
- {text: 'Save chk ( )',
- startIndex: 0,
- endIndex: 1
- }, this.getBraille_(checkbox, checkbox));
-
- $('1').checked = true;
-
- this.assertBrailleEquals(
- {text: 'Save chk (x)',
- startIndex: 0,
- endIndex: 1
- }, this.getBraille_(checkbox, checkbox));
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'AccessKey', function() {
- this.loadHtml(
- '<a href="http://www.google.com" id="1" accesskey="g">Google</a>');
-
- var link = cvox.CursorSelection.fromNode($('1'));
-
- this.assertBrailleEquals(
- {text: 'Google lnk access key:g',
- startIndex: 0,
- endIndex: 1
- }, this.getBraille_(link, link));
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'ContainerTemplate', function() {
- this.loadHtml(
- '<h1>' +
- '<a id="1" href="#menu">Skip To Menu</a>' +
- '</h1>'
- );
-
- var link = cvox.CursorSelection.fromNode($('1'));
-
- var navBraille = this.getBraille_(
- cvox.CursorSelection.fromBody(), link);
- this.assertBrailleEquals(
- {text: 'h1 Skip To Menu intlnk',
- startIndex: 0,
- endIndex: 1
- }, navBraille);
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'LinkSpans', function() {
- this.loadHtml('<p><a id="1" href="#1">Hello</a> from' +
- ' <a id="2" href="//www.google.com/">ChromeVox</a>');
- var link1 = $('1');
- var link2 = $('2');
- var navBraille = this.getBraille_(
- cvox.CursorSelection.fromBody(), cvox.CursorSelection.fromNode(link1));
- assertEquals('Hello intlnk from ChromeVox lnk',
- navBraille.text.toString());
- assertEquals(link1, navBraille.text.getSpan(0));
- assertEquals(link1, navBraille.text.getSpan(11));
- assertEquals('undefined', typeof navBraille.text.getSpan(12));
- assertEquals('undefined', typeof navBraille.text.getSpan(17));
- assertEquals(link2, navBraille.text.getSpan(18));
- assertEquals(link2, navBraille.text.getSpan(30));
-});
-
-
-TEST_F('CvoxBrailleUtilUnitTest', 'VisitedLink', function() {
- this.loadHtml('<p><a id="1" href="http://visited.link">Hello</a> there.');
- var link = $('1');
- var navBraille = this.getBraille_(
- cvox.CursorSelection.fromBody(), cvox.CursorSelection.fromNode(link));
- this.assertBrailleEquals({text: 'Hello lnk there.',
- startIndex: 0,
- endIndex: 1},
- navBraille);
- cvox.ChromeVox.visitedUrls[link.href] = true;
- navBraille = this.getBraille_(
- cvox.CursorSelection.fromBody(), cvox.CursorSelection.fromNode(link));
- this.assertBrailleEquals({text: 'Hello vlnk there.',
- startIndex: 0,
- endIndex: 1},
- navBraille);
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'NestedElements', function() {
- this.loadHtml('<h1 id="test-h1">Larry, ' +
- '<a href="#batman" id="batman-link">Sergey</a> and Eric</h1>');
- var h1 = $('test-h1');
- var link = $('batman-link');
- var navBraille = this.getBraille_(
- cvox.CursorSelection.fromBody(), cvox.CursorSelection.fromNode(h1));
- assertEquals('h1 Larry, Sergey intlnk and Eric',
- navBraille.text.toString());
- this.assertTextNodeChildOf_(h1, navBraille.text.getSpan(0));
- this.assertTextNodeChildOf_(h1, navBraille.text.getSpan(5));
- assertEquals(link, navBraille.text.getSpan(15));
- this.assertTextNodeChildOf_(h1, navBraille.text.getSpan(30));
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'GetTemplatedOverride', function() {
- assertEquals('Menu mnu',
- cvox.BrailleUtil.getTemplated(null, null,
- { 'name': 'Menu',
- 'roleMsg': 'role_menu' }).
- toString());
- assertEquals('alrt: Watch out!',
- cvox.BrailleUtil.getTemplated(null, null,
- { 'name': 'Watch out!',
- 'roleMsg': 'role_alert' }).
- toString());
- // Test all properties. role, if present, overrides roleMsg.
- assertEquals('Name Value Role State',
- cvox.BrailleUtil.getTemplated(null, null,
- { 'name': 'Name',
- 'role': 'Role',
- 'roleMsg': 'excluded',
- 'value': 'Value',
- 'state': 'State'
- }).toString());
-});
-
-
-/**
- * @export
- */
-TEST_F('CvoxBrailleUtilUnitTest', 'CreateValue', function() {
- var s;
- var valueSpan;
- var selectiponSpan;
-
- // Value without a selection.
- s = cvox.BrailleUtil.createValue('value');
- assertEquals('value', s.toString());
- assertUndefined(s.getSpanInstanceOf(cvox.ValueSelectionSpan));
- valueSpan = s.getSpanInstanceOf(cvox.ValueSpan);
- assertEquals(0, s.getSpanStart(valueSpan));
- assertEquals(s.getLength(), s.getSpanEnd(valueSpan));
-
- // Value with a carret at the start of the text.
- s = cvox.BrailleUtil.createValue('value', 0);
- selectionSpan = s.getSpanInstanceOf(cvox.ValueSelectionSpan);
- assertEquals(0, s.getSpanStart(selectionSpan));
- assertEquals(0, s.getSpanEnd(selectionSpan));
-
- // Value with a carret inside the text.
- s = cvox.BrailleUtil.createValue('value', 1);
- selectionSpan = s.getSpanInstanceOf(cvox.ValueSelectionSpan);
- assertEquals(1, s.getSpanStart(selectionSpan));
- assertEquals(1, s.getSpanEnd(selectionSpan));
-
- // Value with a carret at the end of the text.
- s = cvox.BrailleUtil.createValue('value', 5);
- selectionSpan = s.getSpanInstanceOf(cvox.ValueSelectionSpan);
- assertEquals(5, s.getSpanStart(selectionSpan));
- assertEquals(5, s.getSpanEnd(selectionSpan));
-
- // All of the value selected selected with reversed start and end.
- s = cvox.BrailleUtil.createValue('value', 5, 0);
- selectionSpan = s.getSpanInstanceOf(cvox.ValueSelectionSpan);
- assertEquals(0, s.getSpanStart(selectionSpan));
- assertEquals(5, s.getSpanEnd(selectionSpan));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/buildinfo.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/buildinfo.js
deleted file mode 100644
index 47ee49d4581..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/buildinfo.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Build info for ChromeVox.
- *
- * This file may be replaced in package.py for dev builds.
- * For releases, it is updated by hand with meaningful values.
- *
- */
-
-goog.provide('cvox.BuildInfo');
-
-/**
- * An identified for this build.
- * @type {string}
- */
-cvox.BuildInfo.build = 'development build';
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js
deleted file mode 100644
index 6ba315b3fcf..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js
+++ /dev/null
@@ -1,521 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Definitions for the Chromium extensions API used by ChromeVox.
- *
- * @externs
- */
-
-
-// TODO: Move these to //third_party/closure_compiler/externs.
-
-// Begin auto generated externs; do not edit.
-// The following was generated from:
-//
-// python tools/json_schema_compiler/compiler.py
-// -g externs
-// chrome/common/extensions/api/automation.idl
-
-/**
- * @const
- */
-chrome.automation = {};
-
-/**
- * @enum {string}
- */
-chrome.automation.EventType = {
- activedescendantchanged: 'activedescendantchanged',
- alert: 'alert',
- ariaAttributeChanged: 'ariaAttributeChanged',
- autocorrectionOccured: 'autocorrectionOccured',
- blur: 'blur',
- checkedStateChanged: 'checkedStateChanged',
- childrenChanged: 'childrenChanged',
- focus: 'focus',
- hide: 'hide',
- hover: 'hover',
- invalidStatusChanged: 'invalidStatusChanged',
- layoutComplete: 'layoutComplete',
- liveRegionChanged: 'liveRegionChanged',
- loadComplete: 'loadComplete',
- locationChanged: 'locationChanged',
- menuEnd: 'menuEnd',
- menuListItemSelected: 'menuListItemSelected',
- menuListValueChanged: 'menuListValueChanged',
- menuPopupEnd: 'menuPopupEnd',
- menuPopupStart: 'menuPopupStart',
- menuStart: 'menuStart',
- rowCollapsed: 'rowCollapsed',
- rowCountChanged: 'rowCountChanged',
- rowExpanded: 'rowExpanded',
- scrollPositionChanged: 'scrollPositionChanged',
- scrolledToAnchor: 'scrolledToAnchor',
- selectedChildrenChanged: 'selectedChildrenChanged',
- selection: 'selection',
- selectionAdd: 'selectionAdd',
- selectionRemove: 'selectionRemove',
- show: 'show',
- textChanged: 'textChanged',
- textSelectionChanged: 'textSelectionChanged',
- treeChanged: 'treeChanged',
- valueChanged: 'valueChanged',
-};
-
-/**
- * @enum {string}
- */
-chrome.automation.RoleType = {
- alertDialog: 'alertDialog',
- alert: 'alert',
- annotation: 'annotation',
- application: 'application',
- article: 'article',
- banner: 'banner',
- blockquote: 'blockquote',
- busyIndicator: 'busyIndicator',
- button: 'button',
- buttonDropDown: 'buttonDropDown',
- canvas: 'canvas',
- caption: 'caption',
- cell: 'cell',
- checkBox: 'checkBox',
- client: 'client',
- colorWell: 'colorWell',
- columnHeader: 'columnHeader',
- column: 'column',
- comboBox: 'comboBox',
- complementary: 'complementary',
- contentInfo: 'contentInfo',
- date: 'date',
- dateTime: 'dateTime',
- definition: 'definition',
- descriptionListDetail: 'descriptionListDetail',
- descriptionList: 'descriptionList',
- descriptionListTerm: 'descriptionListTerm',
- desktop: 'desktop',
- details: 'details',
- dialog: 'dialog',
- directory: 'directory',
- disclosureTriangle: 'disclosureTriangle',
- div: 'div',
- document: 'document',
- embeddedObject: 'embeddedObject',
- figcaption: 'figcaption',
- figure: 'figure',
- footer: 'footer',
- form: 'form',
- grid: 'grid',
- group: 'group',
- heading: 'heading',
- iframe: 'iframe',
- iframePresentational: 'iframePresentational',
- ignored: 'ignored',
- imageMapLink: 'imageMapLink',
- imageMap: 'imageMap',
- image: 'image',
- inlineTextBox: 'inlineTextBox',
- labelText: 'labelText',
- legend: 'legend',
- lineBreak: 'lineBreak',
- link: 'link',
- listBoxOption: 'listBoxOption',
- listBox: 'listBox',
- listItem: 'listItem',
- listMarker: 'listMarker',
- list: 'list',
- locationBar: 'locationBar',
- log: 'log',
- main: 'main',
- marquee: 'marquee',
- math: 'math',
- menuBar: 'menuBar',
- menuButton: 'menuButton',
- menuItem: 'menuItem',
- menuItemCheckBox: 'menuItemCheckBox',
- menuItemRadio: 'menuItemRadio',
- menuListOption: 'menuListOption',
- menuListPopup: 'menuListPopup',
- menu: 'menu',
- meter: 'meter',
- navigation: 'navigation',
- note: 'note',
- outline: 'outline',
- pane: 'pane',
- paragraph: 'paragraph',
- popUpButton: 'popUpButton',
- pre: 'pre',
- presentational: 'presentational',
- progressIndicator: 'progressIndicator',
- radioButton: 'radioButton',
- radioGroup: 'radioGroup',
- region: 'region',
- rootWebArea: 'rootWebArea',
- rowHeader: 'rowHeader',
- row: 'row',
- ruby: 'ruby',
- ruler: 'ruler',
- svgRoot: 'svgRoot',
- scrollArea: 'scrollArea',
- scrollBar: 'scrollBar',
- seamlessWebArea: 'seamlessWebArea',
- search: 'search',
- searchBox: 'searchBox',
- slider: 'slider',
- sliderThumb: 'sliderThumb',
- spinButtonPart: 'spinButtonPart',
- spinButton: 'spinButton',
- splitter: 'splitter',
- staticText: 'staticText',
- status: 'status',
- switch: 'switch',
- tabGroup: 'tabGroup',
- tabList: 'tabList',
- tabPanel: 'tabPanel',
- tab: 'tab',
- tableHeaderContainer: 'tableHeaderContainer',
- table: 'table',
- textField: 'textField',
- time: 'time',
- timer: 'timer',
- titleBar: 'titleBar',
- toggleButton: 'toggleButton',
- toolbar: 'toolbar',
- treeGrid: 'treeGrid',
- treeItem: 'treeItem',
- tree: 'tree',
- unknown: 'unknown',
- tooltip: 'tooltip',
- webArea: 'webArea',
- webView: 'webView',
- window: 'window',
-};
-
-/**
- * @enum {string}
- */
-chrome.automation.StateType = {
- busy: 'busy',
- checked: 'checked',
- collapsed: 'collapsed',
- default: 'default',
- disabled: 'disabled',
- editable: 'editable',
- enabled: 'enabled',
- expanded: 'expanded',
- focusable: 'focusable',
- focused: 'focused',
- haspopup: 'haspopup',
- horizontal: 'horizontal',
- hovered: 'hovered',
- indeterminate: 'indeterminate',
- invisible: 'invisible',
- linked: 'linked',
- multiselectable: 'multiselectable',
- offscreen: 'offscreen',
- pressed: 'pressed',
- protected: 'protected',
- readOnly: 'readOnly',
- required: 'required',
- selectable: 'selectable',
- selected: 'selected',
- vertical: 'vertical',
- visited: 'visited',
-};
-
-/**
- * @enum {string}
- */
-chrome.automation.TreeChangeType = {
- nodeCreated: 'nodeCreated',
- subtreeCreated: 'subtreeCreated',
- nodeChanged: 'nodeChanged',
- nodeRemoved: 'nodeRemoved',
-};
-
-/**
- * @typedef {{
- * left: number,
- * top: number,
- * width: number,
- * height: number
- * }}
- */
-chrome.automation.Rect;
-
-/**
- * @typedef {{
- * role: (!chrome.automation.RoleType|undefined),
- * state: (Object|undefined),
- * attributes: (Object|undefined)
- * }}
- */
-chrome.automation.FindParams;
-
-/**
- * @constructor
- */
-chrome.automation.AutomationEvent = function() {};
-
-/**
- * @typedef {{
- * target: chrome.automation.AutomationNode,
- * type: !chrome.automation.TreeChangeType
- * }}
- */
-chrome.automation.TreeChange;
-
-/**
- * @constructor
- */
-chrome.automation.AutomationNode = function() {};
-
-
-/**
- * Get the automation tree for the tab with the given tabId, or the current tab
- * if no tabID is given, enabling automation if necessary. Returns a tree with a
- * placeholder root node; listen for the "loadComplete" event to get a
- * notification that the tree has fully loaded (the previous root node reference
- * will stop working at or before this point).
- * @param {number} tabId
- * @param {function(chrome.automation.AutomationNode):void} callback
- * Called when the <code>AutomationNode</code> for the page is available.
- */
-chrome.automation.getTree = function(tabId, callback) {};
-
-/**
- * Get the automation tree for the whole desktop which consists of all on screen
- * views. Note this API is currently only supported on Chrome OS.
- * @param {function(chrome.automation.AutomationNode):void} callback
- * Called when the <code>AutomationNode</code> for the page is available.
- */
-chrome.automation.getDesktop = function(callback) {};
-
-/**
- * Add a tree change observer. Tree change observers are static/global,
- * they listen to tree changes across all trees.
- * @param {function(chrome.automation.TreeChange):void} observer
- * A listener for tree changes on the <code>AutomationNode</code> tree.
- */
-chrome.automation.addTreeChangeObserver = function(observer) {};
-
-/**
- * Remove a tree change observer.
- * @param {function(chrome.automation.TreeChange):void} observer
- * A listener for tree changes on the <code>AutomationNode</code> tree.
- */
-chrome.automation.removeTreeChangeObserver = function(observer) {};
-
-//
-// End auto generated externs; do not edit.
-//
-
-
-
-/**
- * @type {chrome.automation.RoleType}
- */
-chrome.automation.AutomationNode.prototype.role;
-
-
-/**
- * @type {!Object<chrome.automation.StateType, boolean>}
- */
-chrome.automation.AutomationNode.prototype.state;
-
-
-/**
- * @type {number}
- */
-chrome.automation.AutomationNode.prototype.indexInParent;
-
-
-/**
- * @type {string}
- */
-chrome.automation.AutomationNode.prototype.name;
-
-/**
- * @type {string}
- */
-chrome.automation.AutomationNode.prototype.description;
-
-
-/**
- * @type {string}
- */
-chrome.automation.AutomationNode.prototype.url;
-
-
-/**
- * @type {string}
- */
-chrome.automation.AutomationNode.prototype.docUrl;
-
-
-/**
- * @type {string}
- */
-chrome.automation.AutomationNode.prototype.value;
-
-
-/**
- * @type {number}
- */
-chrome.automation.AutomationNode.prototype.textSelStart;
-
-
-/**
- * @type {number}
- */
-chrome.automation.AutomationNode.prototype.textSelEnd;
-
-
-/**
- * @type {Array<number>}
- */
-chrome.automation.AutomationNode.prototype.wordStarts;
-
-
-/**
- * @type {Array<number>}
- */
-chrome.automation.AutomationNode.prototype.wordEnds;
-
-
-/**
- * @type {!chrome.automation.AutomationNode}
- */
-chrome.automation.AutomationNode.prototype.root;
-
-
-/**
- * @type {chrome.automation.AutomationNode}
- */
-chrome.automation.AutomationNode.prototype.firstChild;
-
-
-/**
- * @type {chrome.automation.AutomationNode}
- */
-chrome.automation.AutomationNode.prototype.lastChild;
-
-
-/**
- * @type {chrome.automation.AutomationNode}
- */
-chrome.automation.AutomationNode.prototype.nextSibling;
-
-
-/**
- * @type {chrome.automation.AutomationNode}
- */
-chrome.automation.AutomationNode.prototype.previousSibling;
-
-
-/**
- * @type {chrome.automation.AutomationNode}
- */
-chrome.automation.AutomationNode.prototype.parent;
-
-
-/**
- * @type {!Array<chrome.automation.AutomationNode>}
- */
-chrome.automation.AutomationNode.prototype.children;
-
-
-/**
- * @type {{top: number, left: number, height: number, width: number}}
- */
-chrome.automation.AutomationNode.prototype.location;
-
-
-/**
- * @param {chrome.automation.EventType} eventType
- * @param {function(!chrome.automation.AutomationEvent) : void} callback
- * @param {boolean} capture
- */
-chrome.automation.AutomationNode.prototype.addEventListener =
- function(eventType, callback, capture) {};
-
-
-/**
- * @param {chrome.automation.EventType} eventType
- * @param {function(chrome.automation.AutomationNode) : void} callback
- * @param {boolean} capture
- */
-chrome.automation.AutomationNode.prototype.removeEventListener =
- function(eventType, callback, capture) {};
-
-
-/**
- * @type {chrome.automation.AutomationNode}
- */
-chrome.automation.TreeChange.prototype.target;
-
-
-/**
- * @type {chrome.automation.TreeChangeType}
- */
-chrome.automation.TreeChange.prototype.type;
-
-
-/**
- * @param {function(chrome.automation.TreeChange) : void}
- * callback
- */
-chrome.automation.AutomationNode.prototype.addTreeChangeObserver =
- function(callback) {};
-
-
-/**
- * @param {function(chrome.automation.TreeChange) : void}
- * callback
- */
-chrome.automation.AutomationNode.prototype.removeTreeChangeObserver =
- function(callback) {};
-
-
-chrome.automation.AutomationNode.prototype.doDefault = function() {};
-
-
-chrome.automation.AutomationNode.prototype.focus = function() {};
-
-
-chrome.automation.AutomationNode.prototype.showContextMenu = function() {};
-
-
-/**
- * @param {number} start
- * @param {number} end
- */
-chrome.automation.AutomationNode.prototype.setSelection =
- function(start, end) {};
-
-
-/** @type {string} */
-chrome.automation.AutomationNode.prototype.containerLiveStatus;
-
-/** @type {string} */
-chrome.automation.AutomationNode.prototype.containerLiveRelevant;
-
-/** @type {boolean} */
-chrome.automation.AutomationNode.prototype.containerLiveAtomic;
-
-/** @type {boolean} */
-chrome.automation.AutomationNode.prototype.containerLiveBusy;
-
-
-/**
- * @param {Object} findParams
- */
-chrome.automation.AutomationNode.prototype.find = function(findParams) {};
-
-/**
- * @type {string}
- */
-chrome.automation.AutomationNode.prototype.inputType;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/chromevox.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/chromevox.js
deleted file mode 100644
index 88bfbc54a59..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/chromevox.js
+++ /dev/null
@@ -1,290 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Defines a global object. The initialization of this
- * object happens in init.js.
- *
- */
-
-goog.provide('cvox.ChromeVox');
-
-// Forward declarations.
-// TODO (stoarca): Put these in a separate file and pass that
-// into the build system instead of having it here. This will allow
-// us to group all of the forward declarations for each file without
-// having them overwrite the mapping in deps.js
-goog.addDependency(
- '../host/interface/abstract_host.js',
- ['cvox.AbstractHost'],
- []);
-
-goog.addDependency(
- '../host/interface/tts_interface.js',
- ['cvox.TtsInterface'],
- []);
-
-goog.addDependency(
- '../host/interface/braille_interface.js',
- ['cvox.BrailleInterface'],
- []);
-
-goog.addDependency(
- '../host/interface/mathjax_interface.js',
- ['cvox.MathJaxInterface'],
- []);
-
-goog.addDependency(
- '../chromevox/messages/msgs.js',
- ['Msgs'],
- []);
-
-goog.addDependency(
- '../host/interface/abstract_earcons.js',
- ['cvox.AbstractEarcons'],
- []);
-
-goog.addDependency(
- '../chromevox/common/key_sequence.js',
- ['cvox.KeySequence'],
- []);
-
-goog.addDependency(
- '../chromevox/injected/navigation_manager.js',
- ['cvox.NavigationManager'],
- []);
-
-goog.addDependency(
- '../chromevox/injected/serializer.js',
- ['cvox.Serializer'],
- []);
-
-// Constants
-/**
- * Constant for verbosity setting (cvox.ChromeVox.verbosity).
- * @const
- * @type {number}
- */
-cvox.VERBOSITY_VERBOSE = 0;
-/**
- * Constant for verbosity setting (cvox.ChromeVox.verbosity).
- * @const
- * @type {number}
- */
-cvox.VERBOSITY_BRIEF = 1;
-
-
-/**
- * @constructor
- */
-cvox.ChromeVox = function() {};
-
-/**
- * @type {cvox.AbstractHost}
- */
-cvox.ChromeVox.host = null;
-/**
- * @type {cvox.TtsInterface}
- */
-cvox.ChromeVox.tts;
-/**
- * @type {cvox.BrailleInterface}
- */
-cvox.ChromeVox.braille;
-/**
- * @type {cvox.MathJaxInterface}
- */
-cvox.ChromeVox.mathJax;
-/**
- * @type {boolean}
- */
-cvox.ChromeVox.isActive = true;
-/**
- * @type {?string}
- */
-cvox.ChromeVox.version = null;
-/**
- * @type {cvox.AbstractEarcons}
- */
-cvox.ChromeVox.earcons = null;
-/**
- * @type {cvox.NavigationManager}
- */
-cvox.ChromeVox.navigationManager = null;
-/**
- * @type {cvox.Serializer}
- */
-cvox.ChromeVox.serializer = null;
-/**
- * This indicates whether or not the sticky mode pref is toggled on.
- * Use cvox.ChromeVox.isStickyModeOn() to test if sticky mode is enabled
- * either through the pref or due to being temporarily toggled on.
- * @type {boolean}
- */
-cvox.ChromeVox.isStickyPrefOn = false;
-/**
- * If set to true or false, this value overrides cvox.ChromeVox.isStickyPrefOn
- * temporarily - in order to temporarily enable sticky mode while doing
- * 'read from here' or to temporarily disable it while using a widget.
- * @type {?boolean}
- */
-cvox.ChromeVox.stickyOverride = null;
-/**
- * @type {boolean}
- */
-cvox.ChromeVox.keyPrefixOn = false;
-/**
- * Verbosity setting.
- * See: cvox.VERBOSITY_VERBOSE and cvox.VERBOSITY_BRIEF
- * @type {number}
- */
-cvox.ChromeVox.verbosity = cvox.VERBOSITY_VERBOSE;
-/**
- * @type {number}
- */
-cvox.ChromeVox.typingEcho = 0;
-/**
- * Echoing on key press events.
- * @type {Object<boolean>}
- */
-cvox.ChromeVox.keyEcho = {};
-/**
- * @type {Object<{x:number, y:number}>}
- */
-cvox.ChromeVox.position = {};
-/**
- * @type {boolean}
- */
-cvox.ChromeVox.isChromeOS = navigator.userAgent.indexOf('CrOS') != -1;
-/**
- * @type {boolean}
- */
-cvox.ChromeVox.isMac = navigator.platform.indexOf('Mac') != -1;
-/**
- * @type {string}
- */
-cvox.ChromeVox.modKeyStr;
-if (cvox.ChromeVox.isChromeOS) {
- cvox.ChromeVox.modKeyStr = 'Shift+Search';
-} else if (cvox.ChromeVox.isMac) {
- cvox.ChromeVox.modKeyStr = 'Ctrl+Cmd';
-} else {
- cvox.ChromeVox.modKeyStr = 'Shift+Alt';
-}
-/**
- * If any of these keys is pressed with the modifier key, we go in sequence mode
- * where the subsequent independent key downs (while modifier keys are down)
- * are a part of the same shortcut. This array is populated in
- * cvox.ChromeVoxKbHandler.loadKeyToFunctionsTable().
- * @type {!Array<cvox.KeySequence>}
- */
-cvox.ChromeVox.sequenceSwitchKeyCodes = [];
-/** @type {Object<boolean>} */
-cvox.ChromeVox.visitedUrls = {};
-/**
- * This function can be called before doing an operation that may trigger
- * focus events and other events that would normally be announced. This
- * tells the event manager that these events should be ignored, they're
- * a result of another command that's already announced them. This is
- * a temporary state that's automatically reverted after a few milliseconds,
- * there's no way to explicitly "un-mark".
- * @type {Function}
- */
-cvox.ChromeVox.markInUserCommand = function() {};
-/**
- * Synchronizes ChromeVox's internal cursor to the targetNode.
- * @param {Node} targetNode The node that ChromeVox should be synced to.
- * @param {boolean=} speakNode If true, speaks out the node.
- * @param {number=} opt_queueMode The queue mode to use for speaking.
- */
-cvox.ChromeVox.syncToNode = function(
- targetNode, speakNode, opt_queueMode) {};
-
-/**
- * Speaks the given node.
- * @param {Node} targetNode The node that ChromeVox should be synced to.
- * @param {number=} queueMode The queue mode to use for speaking.
- * @param {Object=} properties Speech properties to use for this utterance.
- */
-cvox.ChromeVox.speakNode = function(targetNode, queueMode, properties) {};
-
-/**
- * Provide a way for modules that can't depend on cvox.ChromeVoxUserCommands
- * to execute commands.
- *
- * @param {string} commandName The command name as a string.
- */
-cvox.ChromeVox.executeUserCommand = function(commandName) {};
-
-/**
- * True if the document body has aria-hidden='true' when we first load.
- * ChromeVox will disallow any navigation and not eat any keystrokes.
- * @type {boolean}
- */
-cvox.ChromeVox.entireDocumentIsHidden = false;
-
-/**
- * Stores state variables in a provided object.
- *
- * @param {Object} store The object.
- */
-cvox.ChromeVox.storeOn = function(store) {
- store['isStickyPrefOn'] = cvox.ChromeVox.isStickyPrefOn;
- cvox.ChromeVox.navigationManager.storeOn(store);
-};
-
-/**
- * Updates the object with state variables from an earlier storeOn call.
- *
- * @param {Object} store The object.
- */
-cvox.ChromeVox.readFrom = function(store) {
- cvox.ChromeVox.isStickyPrefOn = store['isStickyPrefOn'];
- cvox.ChromeVox.navigationManager.readFrom(store);
-};
-
-/**
- * Returns whether sticky mode is on, taking both the global sticky mode
- * pref and the temporary sticky mode override into account.
- *
- * @return {boolean} Whether sticky mode is on.
- */
-cvox.ChromeVox.isStickyModeOn = function() {
- if (cvox.ChromeVox.stickyOverride !== null) {
- return cvox.ChromeVox.stickyOverride;
- } else {
- return cvox.ChromeVox.isStickyPrefOn;
- }
-};
-
-/**
- * Shortcut for document.getElementById.
- * @param {string} id of the element.
- * @return {HTMLElement} with the id.
- */
-function $(id) {
- return document.getElementById(id);
-}
-
-/**
- * @param {Array} tabs
- */
-cvox.ChromeVox.injectChromeVoxIntoTabs = function(tabs) {};
-
-/**
- * Returns whether the document has focus, taking into account whether
- * it's hidden and also that if an iframe or webview element has focus,
- * the focus is really inside that frame and not in this document.
- * @return {boolean} True if the document has focus.
- */
-cvox.ChromeVox.documentHasFocus = function() {
- if (!document.hasFocus() || document.hidden) {
- return false;
- }
- if (document.activeElement.tagName == 'IFRAME' ||
- document.activeElement.tagName == 'WEBVIEW') {
- return false;
- }
- return true;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/chromevox_json.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/chromevox_json.js
deleted file mode 100644
index 96c78ca9f31..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/chromevox_json.js
+++ /dev/null
@@ -1,368 +0,0 @@
-// 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.
-
-goog.provide('cvox.ChromeVoxJSON');
-
-
-/**
- * @fileoverview A simple wrapper around the JSON APIs.
- * If it is possible to use the browser's built in native JSON, then
- * cvox.ChromeVoxJSON is the same as JSON.
- * If the page has its own version of JSON, cvox.ChromeVoxJSON will use its
- * own implementation (rather than the version of JSON on the page
- * which may be outdated/broken).
- */
-
-if (!cvox.ChromeVoxJSON) {
- /** Placeholder object. */
- cvox.ChromeVoxJSON = {};
-}
-
-if (window.JSON && window.JSON.toString() == '[object JSON]') {
- cvox.ChromeVoxJSON = window.JSON;
-} else {
- /*
- * JSON implementation renamed to cvox.ChromeVoxJSON.
- * This only gets called if the page has its own version of JSON.
- *
- * Based on:
- * http://www.JSON.org/json2.js
- * 2010-03-20
- *
- * Public Domain.
- *
- * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
- *
- * See http://www.JSON.org/js.html
- */
- (function() {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function(key) {
-
- return isFinite(this.valueOf()) ?
- this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z' : 'null';
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function(key) {
- return /** @type {string} */ (this.valueOf());
- };
- }
-
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
- rep;
-
-
- function quote(string) {
-
- // If the string contains no control characters, no quote characters, and
- // no backslash characters, then we can safely slap some quotes around it.
- // Otherwise we must also replace the offending characters with safe
- // escape sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ?
- '"' + string.replace(escapable, function(a) {
- var c = meta[a];
- return typeof c === 'string' ? c :
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' :
- '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
- // Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
- // If the value has a toJSON method, call it to obtain a replacement
- // value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
- // If we were called with a replacer function, then call the replacer to
- // obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
- // What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
- // JSON numbers must be finite. Encode non-finite numbers as null.
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
- // If the value is a boolean or null, convert it to a string. Note:
- // typeof null does not produce 'null'. The case is included here in
- // the remote chance that this gets fixed someday.
- return String(value);
-
- // If the type is 'object', we might be dealing with an object or an
- // array or null.
-
- case 'object':
-
- // Due to a specification blunder in ECMAScript, typeof null is
- // 'object', so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
- // Make an array to hold the partial results of stringifying this
- // object value.
-
- gap += indent;
- partial = [];
-
- // Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
- // The value is an array. Stringify every element. Use null as a
- // placeholder for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
- // Join all of the elements together, separated with commas, and
- // wrap them in brackets.
-
- v = partial.length === 0 ? '[]' :
- gap ? '[\n' + gap +
- partial.join(',\n' + gap) + '\n' +
- mind + ']' :
- '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
- // If the replacer is an array, use it to select the members to be
- // stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- k = rep[i];
- if (typeof k === 'string') {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
- // Otherwise, iterate through all of the keys in the object.
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
- // Join all of the member texts together, separated with commas,
- // and wrap them in braces.
-
- v = partial.length === 0 ? '{}' :
- gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
- mind + '}' : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
- // If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof cvox.ChromeVoxJSON.stringify !== 'function') {
- /**
- * @param {*} value Input object.
- * @param {(Array<string>|(function(string, *) : *)|null)=} replacer
- * Replacer array or function.
- * @param {(number|string|null)=} space Whitespace character.
- * @return {string} json string which represents jsonObj.
- */
- cvox.ChromeVoxJSON.stringify = function(value, replacer, space) {
-
- // The stringify method takes a value and an optional replacer, and an
- // optional space parameter, and returns a JSON text. The replacer can
- // be a function that can replace values, or an array of strings that
- // will select the keys. A default replacer method can be provided. Use
- // of the space parameter can produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
- // If the space parameter is a number, make an indent string containing
- // that many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
- // If the space parameter is a string, it will be used as the indent
- // string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
- // If there is a replacer, it must be a function or an array.
- // Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
- // Make a fake root object containing our value under the key of ''.
- // Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
- // If the JSON object does not yet have a parse method, give it one.
-
- if (typeof cvox.ChromeVoxJSON.parse !== 'function') {
- /**
- * @param {string} text The string to parse.
- * @param {(function(string, *) : *|null)=} reviver Reviver function.
- * @return {*} The JSON object.
- */
- cvox.ChromeVoxJSON.parse = function(text, reviver) {
-
- // The parse method takes a text and an optional reviver function, and
- // returns a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
- // The walk method is used to recursively walk the resulting structure
- // so that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
- // Parsing happens in four stages. In the first stage, we replace
- // certain Unicode characters with escape sequences. JavaScript handles
- // many characters incorrectly, either silently deleting them, or
- // treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function(a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
- // In the second stage, we run the text against regular expressions that
- // look for non-JSON patterns. We are especially concerned with '()' and
- // 'new' because they can cause invocation, and '=' because it can cause
- // mutation. But just to be safe, we want to reject all unexpected
- // forms.
- // We split the second stage into 4 regexp operations in order to work
- // around crippling inefficiencies in IE's and Safari's regexp engines.
- // First we replace the JSON backslash pairs with '@' (a non-JSON
- // character). Second, we replace all simple value tokens with ']'
- // characters. Third, we delete all open brackets that follow a colon or
- // comma or that begin the text. Finally, we look to see that the
- // remaining characters are only whitespace or ']' or ',' or ':' or '{'
- // or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/.
- test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
- replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
- replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
- // In the third stage we use the eval function to compile the text
- // into a JavaScript structure. The '{' operator is subject to a
- // syntactic ambiguity in JavaScript: it can begin a block or an
- // object literal. We wrap the text in parens to eliminate the
- // ambiguity.
-
- j = eval('(' + text + ')');
-
- // In the optional fourth stage, we recursively walk the new
- // structure, passing each name/value pair to a reviver function for
- // possible transformation.
- return typeof reviver === 'function' ? walk({'': j}, '') : j;
- }
-
- // If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
- }());
-}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/command_store.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/command_store.js
deleted file mode 100644
index 05e02731933..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/command_store.js
+++ /dev/null
@@ -1,784 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview This class acts as the persistent store for all static data
- * about commands.
- *
- * This store can safely be used within either a content or background script
- * context.
- *
- * If you are looking to add a user command, follow the below steps for best
- * integration with existing components:
- * 1. Add a command below in cvox.CommandStore.CMD_WHITELIST. Pick a
- * programmatic name and fill in each of the relevant JSON keys.
- * Be sure to add a msg id and define it in chromevox/messages/messages.js which
- * describes the command. Please also add a category msg id so that the command
- * will show up in the options page.
- * 2. Add the command's logic to cvox.UserCommands inside of our switch-based
- * dispatch method (doCommand_).
- * 3. Add a key binding in chromevox/background/keymaps/classic_keymap.json and
- * chromevox/background/keymaps/flat_keymap.json.
- *
- * Class description:
- * This class is entirely static and holds a JSON structure that stores
- * commands and their associated metadata.
- *
- * From this metadata, we compute relevant subsets of data such as all present
- * categories.
- */
-
-
-goog.provide('cvox.CommandStore');
-
-goog.require('cvox.PlatformFilter');
-
-
-/**
- * Returns all of the categories in the store as an array.
- * @return {Array<string>} The collection of categories.
- */
-cvox.CommandStore.categories = function() {
- var categorySet = {};
- for (var cmd in cvox.CommandStore.CMD_WHITELIST) {
- var struct = cvox.CommandStore.CMD_WHITELIST[cmd];
- if (struct.category) {
- categorySet[struct.category] = true;
- }
- }
- var ret = [];
- for (var category in categorySet) {
- ret.push(category);
- }
- return ret;
-};
-
-
-/**
- * Gets a message given a command.
- * @param {string} command The command to query.
- * @return {string|undefined} The message id, if any.
- */
-cvox.CommandStore.messageForCommand = function(command) {
- return (cvox.CommandStore.CMD_WHITELIST[command] || {}).msgId;
-};
-
-
-/**
- * Gets a category given a command.
- * @param {string} command The command to query.
- * @return {string|undefined} The command, if any.
- */
-cvox.CommandStore.categoryForCommand = function(command) {
- return (cvox.CommandStore.CMD_WHITELIST[command] || {}).category;
-};
-
-
-/**
- * Gets all commands for a category.
- * @param {string} category The category to query.
- * @return {Array<string>} The commands, if any.
- */
-cvox.CommandStore.commandsForCategory = function(category) {
- var ret = [];
- for (var cmd in cvox.CommandStore.CMD_WHITELIST) {
- var struct = cvox.CommandStore.CMD_WHITELIST[cmd];
- if (category == struct.category) {
- ret.push(cmd);
- }
- }
- return ret;
-};
-
-
-/**
- * List of commands and their properties
- * @type {Object<{forward: (undefined|boolean),
- * backward: (undefined|boolean),
- * announce: boolean,
- * category: (undefined|string),
- * findNext: (undefined|string),
- * doDefault: (undefined|boolean),
- * msgId: (undefined|string),
- * nodeList: (undefined|string),
- * platformFilter: (undefined|cvox.PlatformFilter),
- * skipInput: (undefined|boolean),
- * allowEvents: (undefined|boolean),
- * disallowContinuation: (undefined|boolean)}>}
- * forward: Whether this command points forward.
- * backward: Whether this command points backward. If neither forward or
- * backward are specified, it stays facing in the current direction.
- * announce: Whether to call finishNavCommand and announce the current
- * position after the command is done.
- * findNext: The id from the map above if this command is used for
- * finding next/previous of something.
- * category: The message resource describing the command's category.
- * doDefault: Whether to do the default action. This means that keys will be
- * passed through to the usual DOM capture/bubble phases.
- * msgId: The message resource describing the command.
- * nodeList: The id from the map above if this command is used for
- * showing a list of nodes.
- * platformFilter: Specifies to which platforms this command applies. If left
- * undefined, the command applies to all platforms.
- * skipInput: Explicitly skips this command when text input has focus.
- * Defaults to false.
- * disallowOOBE: Explicitly disallows this command when on chrome://oobe/*.
- * Defaults to false.
- * allowEvents: Allows EventWatcher to continue processing events which can
- * trump TTS.
- * disallowContinuation: Disallows continuous read to proceed. Defaults to
- * false.
- */
-cvox.CommandStore.CMD_WHITELIST = {
- 'toggleStickyMode': {announce: false,
- msgId: 'toggle_sticky_mode',
- 'disallowOOBE': true,
- category: 'modifier_keys'},
- 'toggleKeyPrefix': {announce: false,
- skipInput: true,
- msgId: 'prefix_key',
- 'disallowOOBE': true,
- category: 'modifier_keys'},
- 'passThroughMode': {announce: false,
- msgId: 'pass_through_key_description',
- category: 'modifier_keys'},
-
- 'stopSpeech': {announce: false,
- disallowContinuation: true,
- doDefault: true,
- msgId: 'stop_speech_key',
- category: 'controlling_speech'},
- 'toggleChromeVox': {announce: false,
- platformFilter: cvox.PlatformFilter.WML,
- msgId: 'toggle_chromevox_active',
- category: 'controlling_speech'},
- 'decreaseTtsRate': {announce: false,
- msgId: 'decrease_tts_rate',
- category: 'controlling_speech'},
- 'increaseTtsRate': {announce: false,
- msgId: 'increase_tts_rate',
- category: 'controlling_speech'},
- 'decreaseTtsPitch': {announce: false,
- msgId: 'decrease_tts_pitch',
- category: 'controlling_speech'},
- 'increaseTtsPitch': {announce: false,
- msgId: 'increase_tts_pitch',
- category: 'controlling_speech'},
- 'decreaseTtsVolume': {announce: false,
- msgId: 'decrease_tts_volume',
- category: 'controlling_speech'},
- 'increaseTtsVolume': {announce: false,
- msgId: 'increase_tts_volume',
- category: 'controlling_speech'},
- 'cyclePunctuationEcho': {announce: false,
- msgId: 'cycle_punctuation_echo',
- category: 'controlling_speech'},
- 'cycleTypingEcho': {announce: false,
- msgId: 'cycle_typing_echo',
- category: 'controlling_speech'},
-
-
- 'toggleEarcons': {announce: true,
- msgId: 'toggle_earcons',
- category: 'controlling_speech'},
-
- 'handleTab': {
- allowEvents: true,
- msgId: 'handle_tab_next',
- disallowContinuation: true,
- category: 'navigation'},
- 'handleTabPrev': {
- allowEvents: true,
- msgId: 'handle_tab_prev',
- disallowContinuation: true,
- category: 'navigation'},
- 'forward': {forward: true,
- announce: true,
- msgId: 'forward',
- category: 'navigation'},
- 'backward': {backward: true,
- announce: true,
- msgId: 'backward',
- category: 'navigation'},
- 'right': {forward: true,
- announce: true,
- msgId: 'right',
- category: 'navigation'},
- 'left': {backward: true,
- announce: true,
- msgId: 'left',
- category: 'navigation'},
- 'previousGranularity': {announce: true,
- msgId: 'previous_granularity',
- category: 'navigation'},
- 'nextGranularity': {announce: true,
- msgId: 'next_granularity',
- category: 'navigation'},
-
- 'previousCharacter': {backward: true,
- announce: true,
- msgId: 'previous_character',
- skipInput: true,
- category: 'navigation'},
- 'nextCharacter': {forward: true,
- announce: true,
- msgId: 'next_character',
- skipInput: true,
- category: 'navigation'},
- 'previousWord': {backward: true,
- announce: true,
- msgId: 'previous_word',
- skipInput: true,
- category: 'navigation'},
- 'nextWord': {forward: true,
- announce: true,
- msgId: 'next_word',
- skipInput: true,
- category: 'navigation'},
- 'previousLine': {backward: true,
- announce: true,
- msgId: 'previous_line',
- category: 'navigation'},
- 'nextLine': {forward: true,
- announce: true,
- msgId: 'next_line',
- category: 'navigation'},
- 'previousSentence': {backward: true,
- announce: true,
- msgId: 'previous_sentence',
- skipInput: true,
- category: 'navigation'},
- 'nextSentence': {forward: true,
- announce: true,
- msgId: 'next_sentence',
- skipInput: true,
- category: 'navigation'},
- 'previousObject': {backward: true,
- announce: true,
- msgId: 'previous_object',
- skipInput: true,
- category: 'navigation'},
- 'nextObject': {forward: true,
- announce: true,
- msgId: 'next_object',
- skipInput: true,
- category: 'navigation'},
- 'previousGroup': {backward: true,
- announce: true,
- msgId: 'previous_group',
- skipInput: true,
- category: 'navigation'},
- 'nextGroup': {forward: true,
- announce: true,
- msgId: 'next_group',
- skipInput: true,
- category: 'navigation'},
-
- 'jumpToTop': {forward: true,
- announce: true,
- msgId: 'jump_to_top',
- category: 'navigation'
-},
- 'jumpToBottom': {backward: true,
- announce: true,
- msgId: 'jump_to_bottom',
- category: 'navigation'},
- // Intentionally uncategorized.
- 'moveToStartOfLine': {forward: true, announce: true},
- 'moveToEndOfLine': {backward: true, announce: true},
-
- 'readFromHere': {forward: true,
- announce: false,
- msgId: 'read_from_here',
- category: 'navigation'},
-
- 'performDefaultAction': {disallowContinuation: true,
- msgId: 'perform_default_action',
- doDefault: true,
- skipInput: true,
- category: 'navigation'},
- 'forceClickOnCurrentItem': {announce: true,
- disallowContinuation: true,
- allowEvents: true,
- msgId: 'force_click_on_current_item',
- category: 'navigation'},
- 'forceDoubleClickOnCurrentItem': {announce: true,
- allowEvents: true,
- disallowContinuation: true},
-
- 'readLinkURL': {announce: false,
- msgId: 'read_link_url',
- category: 'information'},
- 'readCurrentTitle': {announce: false,
- msgId: 'read_current_title',
- category: 'information'},
- 'readCurrentURL': {announce: false,
- msgId: 'read_current_url',
- category: 'information'},
-
- 'fullyDescribe': {announce: false,
- msgId: 'fully_describe',
- category: 'information'},
- 'speakTimeAndDate': {announce: false,
- msgId: 'speak_time_and_date',
- category: 'information'},
- 'toggleSelection': {announce: true,
- msgId: 'toggle_selection',
- category: 'information'},
-
- 'toggleSearchWidget': {announce: false,
- disallowContinuation: true,
- msgId: 'toggle_search_widget',
- category: 'information'},
-
- 'toggleKeyboardHelp': {announce: false,
- disallowContinuation: true,
- msgId: 'show_power_key',
- category: 'help_commands'},
- 'help': {announce: false,
- msgId: 'help',
- 'disallowOOBE': true,
- disallowContinuation: true,
- category: 'help_commands'},
- 'contextMenu': {announce: false,
- disallowContinuation: true},
-
- 'showOptionsPage': {announce: false,
- disallowContinuation: true,
- msgId: 'show_options_page',
- 'disallowOOBE': true,
- category: 'help_commands'},
- 'showKbExplorerPage': {announce: false,
- disallowContinuation: true,
- msgId: 'show_kb_explorer_page',
- 'disallowOOBE': true,
- category: 'help_commands'},
-
-
- 'showFormsList': {announce: false,
- disallowContinuation: true,
- nodeList: 'formField',
- msgId: 'show_forms_list',
- category: 'overview'},
- 'showHeadingsList': {announce: false, nodeList: 'heading',
- disallowContinuation: true,
- msgId: 'show_headings_list',
- category: 'overview'},
- 'showLandmarksList': {announce: false, nodeList: 'landmark',
- disallowContinuation: true,
- msgId: 'show_landmarks_list',
- category: 'overview'},
- 'showLinksList': {announce: false, nodeList: 'link',
- disallowContinuation: true,
- msgId: 'show_links_list',
- category: 'overview'},
- 'showTablesList': {announce: false, nodeList: 'table',
- disallowContinuation: true,
- msgId: 'show_tables_list',
- category: 'overview'},
-
- 'nextArticle': {forward: true,
- findNext: 'article'},
-
- 'nextButton': {forward: true,
- findNext: 'button',
- msgId: 'next_button',
- category: 'jump_commands'},
- 'nextCheckbox': {forward: true,
- findNext: 'checkbox',
- msgId: 'next_checkbox',
- category: 'jump_commands'},
- 'nextComboBox': {forward: true,
- findNext: 'combobox',
- msgId: 'next_combo_box',
- category: 'jump_commands'},
- 'nextControl': {forward: true, findNext: 'control'},
- 'nextEditText': {forward: true,
- findNext: 'editText',
- msgId: 'next_edit_text',
- category: 'jump_commands'},
- 'nextFormField': {forward: true,
- findNext: 'formField',
- msgId: 'next_form_field',
- category: 'jump_commands'},
- 'nextGraphic': {forward: true,
- findNext: 'graphic',
- msgId: 'next_graphic',
- category: 'jump_commands'},
- 'nextHeading': {forward: true,
- findNext: 'heading',
- msgId: 'next_heading',
- category: 'jump_commands'},
- 'nextHeading1': {forward: true,
- findNext: 'heading1',
- msgId: 'next_heading1',
- category: 'jump_commands'},
- 'nextHeading2': {forward: true,
- findNext: 'heading2',
- msgId: 'next_heading2',
- category: 'jump_commands'},
- 'nextHeading3': {forward: true,
- findNext: 'heading3',
- msgId: 'next_heading3',
- category: 'jump_commands'},
- 'nextHeading4': {forward: true,
- findNext: 'heading4',
- msgId: 'next_heading4',
- category: 'jump_commands'},
- 'nextHeading5': {forward: true,
- findNext: 'heading5',
- msgId: 'next_heading5',
- category: 'jump_commands'},
- 'nextHeading6': {forward: true,
- findNext: 'heading6',
- msgId: 'next_heading6',
- category: 'jump_commands'},
-
- 'nextLandmark': {forward: true,
- findNext: 'landmark',
- msgId: 'next_landmark',
- category: 'jump_commands'},
- 'nextLink': {forward: true,
- findNext: 'link',
- msgId: 'next_link',
- category: 'jump_commands'},
- 'nextList': {forward: true,
- findNext: 'list',
- msgId: 'next_list',
- category: 'jump_commands'},
- 'nextListItem': {forward: true,
- findNext: 'listItem',
- msgId: 'next_list_item',
- category: 'jump_commands'},
- 'nextMath': {forward: true,
- findNext: 'math',
- msgId: 'next_math',
- category: 'jump_commands'},
- 'nextMedia': {forward: true,
- findNext: 'media',
- msgId: 'next_media',
- category: 'jump_commands'},
- 'nextRadio': {forward: true,
- findNext: 'radio',
- msgId: 'next_radio',
- category: 'jump_commands'},
- 'nextSection': {forward: true, findNext: 'section'},
- 'nextSlider': {forward: true, findNext: 'slider'},
- 'nextTable': {forward: true,
- findNext: 'table',
- msgId: 'next_table',
- category: 'jump_commands'},
- 'nextVisitedLink': {forward: true,
- findNext: 'visitedLink',
- msgId: 'next_visited_link',
- category: 'jump_commands'},
-
-
- 'previousArticle': {backward: true,
- findNext: 'article'},
-
- 'previousButton': {backward: true,
- findNext: 'button',
- msgId: 'previous_button',
- category: 'jump_commands'},
- 'previousCheckbox': {backward: true,
- findNext: 'checkbox',
- msgId: 'previous_checkbox',
- category: 'jump_commands'},
- 'previousComboBox': {backward: true,
- findNext: 'combobox',
- msgId: 'previous_combo_box',
- category: 'jump_commands'},
- 'previousControl': {backward: true, findNext: 'control'},
- 'previousEditText': {backward: true,
- findNext: 'editText',
- msgId: 'previous_edit_text',
- category: 'jump_commands'},
- 'previousFormField': {backward: true,
- findNext: 'formField',
- msgId: 'previous_form_field',
- category: 'jump_commands'},
- 'previousGraphic': {backward: true,
- findNext: 'graphic',
- msgId: 'previous_graphic',
- category: 'jump_commands'},
- 'previousHeading': {backward: true,
- findNext: 'heading',
- msgId: 'previous_heading',
- category: 'jump_commands'},
- 'previousHeading1': {backward: true,
- findNext: 'heading1',
- msgId: 'previous_heading1',
- category: 'jump_commands'},
- 'previousHeading2': {backward: true,
- findNext: 'heading2',
- msgId: 'previous_heading2',
- category: 'jump_commands'},
- 'previousHeading3': {backward: true,
- findNext: 'heading3',
- msgId: 'previous_heading3',
- category: 'jump_commands'},
- 'previousHeading4': {backward: true,
- findNext: 'heading4',
- msgId: 'previous_heading4',
- category: 'jump_commands'},
- 'previousHeading5': {backward: true,
- findNext: 'heading5',
- msgId: 'previous_heading5',
- category: 'jump_commands'},
- 'previousHeading6': {backward: true,
- findNext: 'heading6',
- msgId: 'previous_heading6',
- category: 'jump_commands'},
-
- 'previousLandmark': {backward: true,
- findNext: 'landmark',
- msgId: 'previous_landmark',
- category: 'jump_commands'},
- 'previousLink': {backward: true,
- findNext: 'link',
- msgId: 'previous_link',
- category: 'jump_commands'},
- 'previousList': {backward: true,
- findNext: 'list',
- msgId: 'previous_list',
- category: 'jump_commands'},
- 'previousListItem': {backward: true,
- findNext: 'listItem',
- msgId: 'previous_list_item',
- category: 'jump_commands'},
- 'previousMath': {backward: true,
- findNext: 'math',
- msgId: 'previous_math',
- category: 'jump_commands'},
- 'previousMedia': {backward: true,
- findNext: 'media',
- msgId: 'previous_media',
- category: 'jump_commands'},
- 'previousRadio': {backward: true,
- findNext: 'radio',
- msgId: 'previous_radio',
- category: 'jump_commands'},
- 'previousSection': {backward: true, findNext: 'section'},
- 'previousSlider': {backward: true, findNext: 'slider'},
- 'previousTable': {backward: true,
- findNext: 'table',
- msgId: 'previous_table',
- category: 'jump_commands'},
- 'previousVisitedLink': {backward: true,
- findNext: 'visitedLink',
- msgId: 'previous_visited_link',
- category: 'jump_commands'},
-
-
- // Table Actions.
- 'announceHeaders': {announce: false,
- msgId: 'announce_headers',
- category: 'tables'},
- 'speakTableLocation': {announce: false,
- msgId: 'speak_table_location',
- category: 'tables'},
- 'goToFirstCell': {announce: true,
- msgId: 'skip_to_beginning',
- category: 'tables'},
- 'goToLastCell': {announce: true,
- msgId: 'skip_to_end',
- category: 'tables'},
- 'goToRowFirstCell': {announce: true,
- msgId: 'skip_to_row_beginning',
- category: 'tables'},
- 'goToRowLastCell': {announce: true,
- msgId: 'skip_to_row_end',
- category: 'tables'},
- 'goToColFirstCell': {announce: true,
- msgId: 'skip_to_col_beginning',
- category: 'tables'},
- 'goToColLastCell': {announce: true,
- msgId: 'skip_to_col_end',
- category: 'tables'},
- // These commands are left out of the options page because they involve
- // multiple, non-user configurable modifiers.
- 'previousRow': {backward: true, announce: true, skipInput: true},
- 'previousCol': {backward: true, announce: true, skipInput: true},
- 'nextRow': {forward: true, announce: true, skipInput: true},
- 'nextCol': {forward: true, announce: true, skipInput: true},
-
- // Generic Actions.
- 'enterShifter': {announce: true,
- msgId: 'enter_content',
- category: 'navigation'},
- 'exitShifter': {announce: true,
- msgId: 'exit_content',
- category: 'navigation'},
- 'exitShifterContent': {announce: true},
-
- 'openLongDesc': {announce: false,
- msgId: 'open_long_desc',
- category: 'information'},
-
- 'pauseAllMedia': {announce: false,
- msgId: 'pause_all_media',
- category: 'information'},
-
- // Math specific commands.
- 'toggleSemantics': {announce: false,
- msgId: 'toggle_semantics',
- category: 'information'},
-
- // Braille specific commands.
- 'routing': {announce: false,
- allowEvents: true,
- msgId: 'braille_routing',
- category: 'braille'},
- 'pan_left': {backward: true,
- announce: true,
- msgId: 'braille_pan_left',
- category: 'braille'},
- 'pan_right': {forward: true,
- announce: true,
- msgId: 'braille_pan_right',
- category: 'braille'},
- 'line_up': {backward: true,
- announce: true,
- msgId: 'braille_line_up',
- category: 'braille'},
- 'line_down': {forward: true,
- announce: true,
- msgId: 'braille_line_down',
- category: 'braille'},
- 'top': {forward: true,
- announce: true,
- msgId: 'braille_top',
- category: 'braille'},
- 'bottom': {backward: true,
- announce: true,
- msgId: 'braille_bottom',
- category: 'braille'},
-
- // Developer commands.
- 'enableConsoleTts': {announce: false,
- msgId: 'enable_tts_log',
- category: 'developer'},
- 'toggleBrailleCaptions': {announce: false,
- msgId: 'braille_captions',
- category: 'developer'},
-
- 'startHistoryRecording': {announce: false},
- 'stopHistoryRecording': {announce: false},
- 'autorunner': {announce: false},
-
- 'debug': {announce: false},
-
- 'nop': {announce: false}
-};
-
-
-/**
- * List of find next commands and their associated data.
- * @type {Object<{predicate: string,
- * forwardError: string,
- * backwardError: string}>}
- * predicate: The name of the predicate. This must be defined in DomPredicates.
- * forwardError: The message id of the error string when moving forward.
- * backwardError: The message id of the error string when moving backward.
- */
-cvox.CommandStore.NODE_INFO_MAP = {
- 'checkbox': {predicate: 'checkboxPredicate',
- forwardError: 'no_next_checkbox',
- backwardError: 'no_previous_checkbox',
- typeMsg: 'role_checkbox'},
- 'radio': {predicate: 'radioPredicate',
- forwardError: 'no_next_radio_button',
- backwardError: 'no_previous_radio_button',
- typeMsg: 'role_radio'},
- 'slider': {predicate: 'sliderPredicate',
- forwardError: 'no_next_slider',
- backwardError: 'no_previous_slider',
- typeMsg: 'role_slider'},
- 'graphic': {predicate: 'graphicPredicate',
- forwardError: 'no_next_graphic',
- backwardError: 'no_previous_graphic',
- typeMsg: 'UNUSED'},
- 'article': {predicate: 'articlePredicate',
- forwardError: 'no_next_ARTICLE',
- backwardError: 'no_previous_ARTICLE',
- typeMsg: 'TAG_ARTICLE'},
- 'button': {predicate: 'buttonPredicate',
- forwardError: 'no_next_button',
- backwardError: 'no_previous_button',
- typeMsg: 'role_button'},
- 'combobox': {predicate: 'comboBoxPredicate',
- forwardError: 'no_next_combo_box',
- backwardError: 'no_previous_combo_box',
- typeMsg: 'role_combobox'},
- 'editText': {predicate: 'editTextPredicate',
- forwardError: 'no_next_edit_text',
- backwardError: 'no_previous_edit_text',
- typeMsg: 'input_type_text'},
- 'heading': {predicate: 'headingPredicate',
- forwardError: 'no_next_heading',
- backwardError: 'no_previous_heading',
- typeMsg: 'role_heading'},
- 'heading1': {predicate: 'heading1Predicate',
- forwardError: 'no_next_heading_1',
- backwardError: 'no_previous_heading_1'},
- 'heading2': {predicate: 'heading2Predicate',
- forwardError: 'no_next_heading_2',
- backwardError: 'no_previous_heading_2'},
- 'heading3': {predicate: 'heading3Predicate',
- forwardError: 'no_next_heading_3',
- backwardError: 'no_previous_heading_3'},
- 'heading4': {predicate: 'heading4Predicate',
- forwardError: 'no_next_heading_4',
- backwardError: 'no_previous_heading_4'},
- 'heading5': {predicate: 'heading5Predicate',
- forwardError: 'no_next_heading_5',
- backwardError: 'no_previous_heading_5'},
- 'heading6': {predicate: 'heading6Predicate',
- forwardError: 'no_next_heading_6',
- backwardError: 'no_previous_heading_6'},
-
- 'link': {predicate: 'linkPredicate',
- forwardError: 'no_next_link',
- backwardError: 'no_previous_link',
- typeMsg: 'role_link'},
- 'table': {predicate: 'tablePredicate',
- forwardError: 'no_next_table',
- backwardError: 'no_previous_table',
- typeMsg: 'table_strategy'},
- 'visitedLink': {predicate: 'visitedLinkPredicate',
- forwardError: 'no_next_visited_link',
- backwardError: 'no_previous_visited_link',
- typeMsg: 'role_link'},
- 'list': {predicate: 'listPredicate',
- forwardError: 'no_next_list',
- backwardError: 'no_previous_list',
- typeMsg: 'role_list'},
- 'listItem': {predicate: 'listItemPredicate',
- forwardError: 'no_next_list_item',
- backwardError: 'no_previous_list_item',
- typeMsg: 'role_listitem'},
- 'formField': {predicate: 'formFieldPredicate',
- forwardError: 'no_next_form_field',
- backwardError: 'no_previous_form_field',
- typeMsg: 'role_form'},
- 'landmark': {predicate: 'landmarkPredicate',
- forwardError: 'no_next_landmark',
- backwardError: 'no_previous_landmark',
- typeMsg: 'role_landmark'},
- 'math': {predicate: 'mathPredicate',
- forwardError: 'no_next_math',
- backwardError: 'no_previous_math',
- typeMsg: 'math_expr'},
- 'media': {predicate: 'mediaPredicate',
- forwardError: 'no_next_media_widget',
- backwardError: 'no_previous_media_widget'},
- 'section': {predicate: 'sectionPredicate',
- forwardError: 'no_next_section',
- backwardError: 'no_previous_section'},
- 'control': {predicate: 'controlPredicate',
- forwardError: 'no_next_control',
- backwardError: 'no_previous_control'}
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/command_store_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/command_store_test.unitjs
deleted file mode 100644
index 66ef0081254..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/command_store_test.unitjs
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxCommandStoreUnitTest() {}
-
-CvoxCommandStoreUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ChromeVoxUserCommands',
- 'cvox.CommandStore',
- ]
-};
-
-TEST_F('CvoxCommandStoreUnitTest', 'TableData', function() {
- var categories = cvox.CommandStore.categories();
- assertEquals(10, categories.length);
- assertEquals('modifier_keys', categories[0]);
- assertEquals('controlling_speech', categories[1]);
- assertEquals('navigation', categories[2]);
- assertEquals('information', categories[3]);
- assertEquals('help_commands', categories[4]);
- assertEquals('overview', categories[5]);
- assertEquals('jump_commands', categories[6]);
- assertEquals('tables', categories[7]);
-
- assertEquals('stop_speech_key',
- cvox.CommandStore.messageForCommand('stopSpeech'));
- assertEquals('controlling_speech',
- cvox.CommandStore.categoryForCommand('stopSpeech'));
-
- var controllingSpeechCmds =
- cvox.CommandStore.commandsForCategory('controlling_speech');
- assertEquals(11, controllingSpeechCmds.length);
- assertEquals('stopSpeech', controllingSpeechCmds[0]);
- assertEquals('toggleChromeVox', controllingSpeechCmds[1]);
- assertEquals('decreaseTtsRate', controllingSpeechCmds[2]);
- assertEquals('increaseTtsRate', controllingSpeechCmds[3]);
- assertEquals('decreaseTtsPitch', controllingSpeechCmds[4]);
- assertEquals('increaseTtsPitch', controllingSpeechCmds[5]);
-});
-
-
-/** Tests that undefined is returned for bad queries. */
-TEST_F('CvoxCommandStoreUnitTest', 'InvalidQueries', function() {
- assertThat(cvox.CommandStore.commandsForCategory('foo'), eqJSON([]));
- assertTrue(undefined == cvox.CommandStore.categoryForCommand('foo'));
- assertTrue(undefined == cvox.CommandStore.messageForCommand('foo'));
-});
-
-
-/** Tests the validity of every command. */
-TEST_F('CvoxCommandStoreUnitTest', 'CommandValidity', function() {
- var categories = cvox.CommandStore.categories();
- for (var i = 0; i < categories.length; i++) {
- var commands = cvox.CommandStore.commandsForCategory(categories[i]);
- for (j = 0; j < commands.length; j++) {
- var command = commands[j];
- assertEquals(command + ' function',
- command + ' ' + typeof(cvox.ChromeVoxUserCommands.commands[command]));
- }
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/composite_tts.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/composite_tts.js
deleted file mode 100644
index bba28401525..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/composite_tts.js
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A composite TTS sends allows ChromeVox to use
- * multiple TTS engines at the same time.
- *
- */
-
-goog.provide('cvox.CompositeTts');
-
-goog.require('cvox.TtsInterface');
-
-/**
- * A Composite Tts
- * @constructor
- * @implements {cvox.TtsInterface}
- */
-cvox.CompositeTts = function() {
- /**
- * @type {Array<cvox.TtsInterface>}
- * @private
- */
- this.ttsEngines_ = [];
-};
-
-
-/**
- * Adds a TTS engine to the composite TTS
- * @param {cvox.TtsInterface} tts The TTS to add.
- * @return {cvox.CompositeTts} this.
- */
-cvox.CompositeTts.prototype.add = function(tts) {
- this.ttsEngines_.push(tts);
- return this;
-};
-
-
-/**
- * @override
- */
-cvox.CompositeTts.prototype.speak =
- function(textString, queueMode, properties) {
- this.ttsEngines_.forEach(function(engine) {
- engine.speak(textString, queueMode, properties);
- });
-};
-
-
-/**
- * Returns true if any of the TTSes are still speaking.
- * @override
- */
-cvox.CompositeTts.prototype.isSpeaking = function() {
- return this.ttsEngines_.some(function(engine) {
- return engine.isSpeaking();
- });
-};
-
-
-/**
- * @override
- */
-cvox.CompositeTts.prototype.stop = function() {
- this.ttsEngines_.forEach(function(engine) {
- engine.stop();
- });
-};
-
-
-/**
- * @override
- */
-cvox.CompositeTts.prototype.addCapturingEventListener = function(listener) {
- this.ttsEngines_.forEach(function(engine) {
- engine.addCapturingEventListener(listener);
- });
-};
-
-
-/**
- * @override
- */
-cvox.CompositeTts.prototype.increaseOrDecreaseProperty =
- function(propertyName, increase) {
- this.ttsEngines_.forEach(function(engine) {
- engine.increaseOrDecreaseProperty(propertyName, increase);
- });
-};
-
-
-/**
- * @override
- */
-cvox.CompositeTts.prototype.getDefaultProperty = function(property) {
- for (var i = 0, engine; engine = this.ttsEngines_[i]; i++) {
- var value = engine.getDefaultProperty(property);
- if (value) {
- return value;
- }
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/content_editable_extractor.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/content_editable_extractor.js
deleted file mode 100644
index ce0d9415f0d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/content_editable_extractor.js
+++ /dev/null
@@ -1,235 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Defines the ContentEditableExtractor class.
- */
-
-goog.provide('cvox.ContentEditableExtractor');
-
-goog.require('cvox.Cursor');
-goog.require('cvox.TraverseUtil');
-
-/**
- * Extracts the text and line break information from a contenteditable region.
- * @constructor
- */
-cvox.ContentEditableExtractor = function() {
- /**
- * The extracted, flattened, text.
- * @type {string}
- * @private
- */
- this.text_ = '';
-
- /**
- * The start cursor/selection index.
- * @type {number}
- * @private
- */
- this.start_ = 0;
-
- /**
- * The end cursor/selection index.
- * @type {number}
- * @private
- */
- this.end_ = 0;
-
- /**
- * Map from line index to a data structure containing the start
- * and end index within the line.
- * @type {Object<number, {startIndex: number, endIndex: number}>}
- * @private
- */
- this.lines_ = {};
-
- /**
- * Map from 0-based character index to 0-based line index.
- * @type {Array<number>}
- * @private
- */
- this.characterToLineMap_ = [];
-};
-
-/**
- * Update the metadata.
- * @param {Element} element The DOM element that's contentEditable.
- */
-cvox.ContentEditableExtractor.prototype.update = function(element) {
- /**
- * Map from line index to a data structure containing the start
- * and end index within the line.
- * @type {Object<number, {startIndex: number, endIndex: number}>}
- */
- var lines = {0: {startIndex: 0, endIndex: 0}};
- var startCursor = new cvox.Cursor(element, 0, '');
- var endCursor = startCursor.clone();
- var range = document.createRange();
- var rect;
- var lineIndex = 0;
- var lastBottom = null;
- var text = '';
- var textSize = 0;
- var selectionStartIndex = -1;
- var selectionEndIndex = -1;
- var sel = window.getSelection();
- var selectionStart = new cvox.Cursor(sel.baseNode, sel.baseOffset, '');
- var selectionEnd = new cvox.Cursor(sel.extentNode, sel.extentOffset, '');
- var setStart = false;
- var setEnd = false;
- while (true) {
- var entered = [];
- var left = [];
- var c = cvox.TraverseUtil.forwardsChar(endCursor, entered, left);
- var done = false;
- if (!c) {
- done = true;
- }
- for (var i = 0; i < left.length && !done; i++) {
- if (left[i] == element) {
- done = true;
- }
- }
- if (done) {
- break;
- }
-
- range.setStart(startCursor.node, startCursor.index);
- range.setEnd(endCursor.node, endCursor.index);
- rect = range.getBoundingClientRect();
- if (!rect || rect.width == 0 || rect.height == 0) {
- continue;
- }
-
- if (lastBottom !== null &&
- rect.bottom != lastBottom &&
- textSize > 0 &&
- text.substr(-1).match(/\S/) &&
- c.match(/\S/)) {
- text += '\n';
- textSize++;
- }
-
- if (startCursor.node != endCursor.node && endCursor.index > 0) {
- range.setStart(endCursor.node, endCursor.index - 1);
- rect = range.getBoundingClientRect();
- if (!rect || rect.width == 0 || rect.height == 0) {
- continue;
- }
- }
-
- if (!setStart &&
- selectionStartIndex == -1 &&
- endCursor.node == selectionStart.node &&
- endCursor.index >= selectionStart.index) {
- if (endCursor.index > selectionStart.index) {
- selectionStartIndex = textSize;
- } else {
- setStart = true;
- }
- }
- if (!setEnd &&
- selectionEndIndex == -1 &&
- endCursor.node == selectionEnd.node &&
- endCursor.index >= selectionEnd.index) {
- if (endCursor.index > selectionEnd.index) {
- selectionEndIndex = textSize;
- } else {
- setEnd = true;
- }
- }
-
- if (lastBottom === null) {
- // This is the first character we've successfully measured on this
- // line. Save the vertical position but don't do anything else.
- lastBottom = rect.bottom;
- } else if (rect.bottom != lastBottom) {
- lines[lineIndex].endIndex = textSize;
- lineIndex++;
- lines[lineIndex] = {startIndex: textSize, endIndex: textSize};
- lastBottom = rect.bottom;
- }
- text += c;
- textSize++;
- startCursor = endCursor.clone();
-
- if (setStart) {
- selectionStartIndex = textSize;
- setStart = false;
- }
- if (setEnd) {
- selectionEndIndex = textSize;
- setEnd = false;
- }
- }
-
- // Finish up the last line.
- lines[lineIndex].endIndex = textSize;
-
- // Create a map from character index to line number.
- var characterToLineMap = [];
- for (var i = 0; i <= lineIndex; i++) {
- for (var j = lines[i].startIndex; j <= lines[i].endIndex; j++) {
- characterToLineMap[j] = i;
- }
- }
-
- // Finish updating fields.
- this.text_ = text;
- this.characterToLineMap_ = characterToLineMap;
- this.lines_ = lines;
-
- this.start_ = selectionStartIndex >= 0 ? selectionStartIndex : text.length;
- this.end_ = selectionEndIndex >= 0 ? selectionEndIndex : text.length;
-};
-
-/**
- * Get the text.
- * @return {string} The extracted, flattened, text.
- */
-cvox.ContentEditableExtractor.prototype.getText = function() {
- return this.text_;
-};
-
-/**
- * @return {number} The start cursor/selection index.
- */
-cvox.ContentEditableExtractor.prototype.getStartIndex = function() {
- return this.start_;
-};
-
-/**
- * @return {number} The end cursor/selection index.
- */
-cvox.ContentEditableExtractor.prototype.getEndIndex = function() {
- return this.end_;
-};
-
-/**
- * Get the line number corresponding to a particular index.
- * @param {number} index The 0-based character index.
- * @return {number} The 0-based line number corresponding to that character.
- */
-cvox.ContentEditableExtractor.prototype.getLineIndex = function(index) {
- return this.characterToLineMap_[index];
-};
-
-/**
- * Get the start character index of a line.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the first character in this line.
- */
-cvox.ContentEditableExtractor.prototype.getLineStart = function(index) {
- return this.lines_[index].startIndex;
-};
-
-/**
- * Get the end character index of a line.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the end of this line.
- */
-cvox.ContentEditableExtractor.prototype.getLineEnd = function(index) {
- return this.lines_[index].endIndex;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/content_editable_extractor_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/content_editable_extractor_test.unitjs
deleted file mode 100644
index c5f0fa3ba57..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/content_editable_extractor_test.unitjs
+++ /dev/null
@@ -1,326 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxContentEditableExtractorUnitTest() {}
-
-CvoxContentEditableExtractorUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ContentEditableExtractor',
- ]
-};
-
-/**
- * Helper function to set the selection
- * @param {Node} startNode The base/start node of the range.
- * @param {number} startOffset The 0-based character index of the start.
- * @param {Node} endNode The extent/end node of the range.
- * @param {number} endOffset The 0-based character index of the end.
- */
-function setSelection(startNode, startOffset, endNode, endOffset) {
- var r = document.createRange();
- r.setStart(startNode, startOffset);
- r.setEnd(endNode, endOffset);
- var sel = window.getSelection();
- sel.removeAllRanges();
- sel.addRange(r);
-}
-
-TEST_F('CvoxContentEditableExtractorUnitTest', 'EmptyElement', function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="textbox" contentEditable="true"></div>
- </div>
- */});
-
- var textbox = $('textbox');
- var extractor = new cvox.ContentEditableExtractor();
- extractor.update(textbox);
- assertEquals('', extractor.getText());
- assertEquals(0, extractor.getStartIndex());
- assertEquals(0, extractor.getEndIndex(0));
- assertEquals(0, extractor.getLineIndex(0));
- assertEquals(0, extractor.getLineStart(0));
- assertEquals(0, extractor.getLineEnd(0));
-});
-
-/**
- * Test getting text and selections from a single contenteditable node.
- */
-TEST_F('CvoxContentEditableExtractorUnitTest', 'SingleTextNode', function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="textbox" contentEditable="true">Hello</div>
- </div>
- */});
- var textbox = $('textbox');
-
- var extractor = new cvox.ContentEditableExtractor();
- extractor.update(textbox);
- assertEquals('Hello', extractor.getText());
- assertEquals(0, extractor.getLineIndex(0));
- assertEquals(0, extractor.getLineStart(0));
- assertEquals(5, extractor.getLineEnd(0));
- assertEquals(5, extractor.getStartIndex());
- assertEquals(5, extractor.getEndIndex());
-
- // Test all possible cursor positions.
- for (var i = 0; i <= 5; i++) {
- setSelection(textbox.firstChild, i, textbox.firstChild, i);
- extractor.update(textbox);
- assertEquals(i, extractor.getStartIndex());
- assertEquals(i, extractor.getEndIndex());
- }
-
- // Test all possible ways to select one character.
- for (i = 0; i < 5; i++) {
- setSelection(textbox.firstChild, i, textbox.firstChild, i + 1);
- extractor.update(textbox);
- assertEquals(i, extractor.getStartIndex());
- assertEquals(i + 1, extractor.getEndIndex());
- }
-
- // Test selecting everything.
- setSelection(textbox.firstChild, 0, textbox.firstChild, 5);
- extractor.update(textbox);
- assertEquals(0, extractor.getStartIndex());
- assertEquals(5, extractor.getEndIndex());
-});
-
-/**
- * Test getting text and selections from a contenteditable node with
- * nonprinted whitespace.
- */
-TEST_F('CvoxContentEditableExtractorUnitTest', 'TextWithWhitespace',
- function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="textbox" contentEditable="true"> Hello World </div>
- </div>
- */});
- var textbox = $('textbox');
-
- var extractor = new cvox.ContentEditableExtractor();
- extractor.update(textbox);
- assertEquals('Hello World', extractor.getText());
- assertEquals(0, extractor.getLineIndex(0));
- assertEquals(0, extractor.getLineStart(0));
- assertEquals(11, extractor.getLineEnd(0));
- assertEquals(11, extractor.getStartIndex());
- assertEquals(11, extractor.getEndIndex());
-
- // Test all *reasonable* indexes of a selection into this text node
- // and the logical index into the text that these should result in.
- var expectedIndexMap = {
- 0: 0,
- 1: 0,
- 2: 1,
- 3: 2,
- 4: 3,
- 5: 4,
- 6: 5,
- // Note: index=7 should never happen
- 8: 6,
- 9: 7,
- 10: 8,
- 11: 9,
- 12: 10,
- 13: 11,
- 14: 11
- };
- for (var srcIndex in expectedIndexMap) {
- var dstIndex = expectedIndexMap[srcIndex];
- setSelection(textbox.firstChild, srcIndex, textbox.firstChild, srcIndex);
- extractor.update(textbox);
- assertEquals(dstIndex, extractor.getStartIndex());
- assertEquals(dstIndex, extractor.getEndIndex());
- }
-});
-
-/**
- * Test getting text and selections from a contenteditable node with
- * preformatted text.
- */
-TEST_F('CvoxContentEditableExtractorUnitTest', 'Preformatted', function() {
- this.loadDoc(function() {/*!
- <div>
- <pre id="textbox" contentEditable="true">aaaaaaaaaa
-bbbbbbbbbb
-cccccccccc</pre>
- </div>
- */});
- var textbox = $('textbox');
-
- var extractor = new cvox.ContentEditableExtractor();
- extractor.update(textbox);
- assertEquals('aaaaaaaaaa\nbbbbbbbbbb\ncccccccccc', extractor.getText());
- assertEquals(0, extractor.getLineStart(0));
- assertEquals(11, extractor.getLineEnd(0));
- assertEquals(11, extractor.getLineStart(1));
- assertEquals(22, extractor.getLineEnd(1));
- assertEquals(22, extractor.getLineStart(2));
- assertEquals(32, extractor.getLineEnd(2));
-
- // Test all possible cursor positions.
- for (var i = 0; i <= 32; i++) {
- setSelection(textbox.firstChild, i, textbox.firstChild, i);
- extractor.update(textbox);
- assertEquals(i, extractor.getStartIndex());
- assertEquals(i, extractor.getEndIndex());
- }
-});
-
-/**
- * Test getting text and selections from a contenteditable node with
- * wrapping.
- */
-TEST_F('CvoxContentEditableExtractorUnitTest', 'WordWrap', function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="textbox"
- style="width: 1em; word-wrap: normal"
- contentEditable="true">One two three</div>
- </div>
- */});
- var textbox = $('textbox');
-
- var extractor = new cvox.ContentEditableExtractor();
- extractor.update(textbox);
- assertEquals('One\ntwo\nthree', extractor.getText());
- assertEquals(0, extractor.getLineStart(0));
- assertEquals(4, extractor.getLineEnd(0));
- assertEquals(4, extractor.getLineStart(1));
- assertEquals(8, extractor.getLineEnd(1));
- assertEquals(8, extractor.getLineStart(2));
- assertEquals(13, extractor.getLineEnd(2));
-
- // Test all possible cursor positions.
- for (var i = 0; i <= 13; i++) {
- setSelection(textbox.firstChild, i, textbox.firstChild, i);
- extractor.update(textbox);
- assertEquals(i, extractor.getStartIndex());
- assertEquals(i, extractor.getEndIndex());
- }
-});
-
-/**
- * Test getting text and lines from a contenteditable region
- * containing two paragraphs and an explicit line break.
- */
-TEST_F('CvoxContentEditableExtractorUnitTest', 'TwoParas', function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="textbox" contentEditable="true">
- <p>One</p>
- <p>Two<br>Three</p>
- </div>
- </div>
- */});
- var textbox = $('textbox');
-
- var extractor = new cvox.ContentEditableExtractor();
- extractor.update(textbox);
- assertEquals('One\nTwo\nThree',
- extractor.getText());
- assertEquals(0, extractor.getLineStart(0));
- assertEquals(4, extractor.getLineEnd(0));
- assertEquals(4, extractor.getLineStart(1));
- assertEquals(8, extractor.getLineEnd(1));
- assertEquals(8, extractor.getLineStart(2));
- assertEquals(13, extractor.getLineEnd(2));
-});
-
-/**
- * Test getting text and lines from a contenteditable region
- * containing two paragraphs, this time with added whitespace.
- */
-TEST_F('CvoxContentEditableExtractorUnitTest', 'TwoParasWithWhitespace',
- function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="textbox" contentEditable="true">
- <p> One </p>
- <p> Two <br> Three </p>
- </div>
- </div>
- */});
- var textbox = $('textbox');
-
- var extractor = new cvox.ContentEditableExtractor();
- extractor.update(textbox);
- assertEquals('One\nTwo Three',
- extractor.getText());
- assertEquals(0, extractor.getLineStart(0));
- assertEquals(4, extractor.getLineEnd(0));
- assertEquals(4, extractor.getLineStart(1));
- assertEquals(8, extractor.getLineEnd(1));
- assertEquals(8, extractor.getLineStart(2));
- assertEquals(13, extractor.getLineEnd(2));
-});
-
-/**
- * Test getting text and lines from a contenteditable region
- * containing some raw text and then some text in a block-level element.
- */
-TEST_F('CvoxContentEditableExtractorUnitTest', 'NodePlusElement', function() {
- this.loadDoc(function() {/*!
- <div>
- <div id="textbox"
- contentEditable="true">One<div>Two<br>Three</div></div>
- </div>
- */});
- var textbox = $('textbox');
-
- var extractor = new cvox.ContentEditableExtractor();
- extractor.update(textbox);
- assertEquals('One\nTwo\nThree',
- extractor.getText());
- assertEquals(0, extractor.getLineStart(0));
- assertEquals(4, extractor.getLineEnd(0));
- assertEquals(4, extractor.getLineStart(1));
- assertEquals(8, extractor.getLineEnd(1));
- assertEquals(8, extractor.getLineStart(2));
- assertEquals(13, extractor.getLineEnd(2));
-
- var oneTextNode = textbox.firstChild;
- assertEquals('One', oneTextNode.data);
- var twoTextNode = textbox.firstElementChild.firstChild;
- assertEquals('Two', twoTextNode.data);
- var threeTextNode = twoTextNode.nextSibling.nextSibling;
- assertEquals('Three', threeTextNode.data);
-
- // End of first line.
- setSelection(oneTextNode, 3, oneTextNode, 3);
- extractor.update(textbox);
- assertEquals(3, extractor.getStartIndex());
- assertEquals(3, extractor.getEndIndex());
-
- // Beginning of second line.
- setSelection(twoTextNode, 0, twoTextNode, 0);
- extractor.update(textbox);
- assertEquals(4, extractor.getStartIndex());
- assertEquals(4, extractor.getEndIndex());
-
- // End of second line.
- setSelection(twoTextNode, 3, twoTextNode, 3);
- extractor.update(textbox);
- assertEquals(7, extractor.getStartIndex());
- assertEquals(7, extractor.getEndIndex());
-
- // Beginning of third line.
- setSelection(threeTextNode, 0, threeTextNode, 0);
- extractor.update(textbox);
- assertEquals(8, extractor.getStartIndex());
- assertEquals(8, extractor.getEndIndex());
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor.js
deleted file mode 100644
index 1cf59633647..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Simple class to represent a cursor location in the document.
- */
-
-goog.provide('cvox.Cursor');
-
-/**
- * A class to represent a cursor location in the document,
- * like the start position or end position of a selection range.
- *
- * Later this may be extended to support "virtual text" for an object,
- * like the ALT text for an image.
- *
- * Note: we cache the text of a particular node at the time we
- * traverse into it. Later we should add support for dynamically
- * reloading it.
- * NOTE: Undefined behavior if node is null
- * @param {Node} node The DOM node.
- * @param {number} index The index of the character within the node.
- * @param {string} text The cached text contents of the node.
- * @constructor
- */
-cvox.Cursor = function(node, index, text) {
- this.node = node;
- this.index = index;
- this.text = text;
-};
-
-/**
- * @return {!cvox.Cursor} A new cursor pointing to the same location.
- */
-cvox.Cursor.prototype.clone = function() {
- return new cvox.Cursor(this.node, this.index, this.text);
-};
-
-/**
- * Modify this cursor to point to the location that another cursor points to.
- * @param {!cvox.Cursor} otherCursor The cursor to copy from.
- */
-cvox.Cursor.prototype.copyFrom = function(otherCursor) {
- this.node = otherCursor.node;
- this.index = otherCursor.index;
- this.text = otherCursor.text;
-};
-
-/**
- * Check for equality.
- * @param {!cvox.Cursor} rhs The cursor to compare against.
- * @return {boolean} True if equal.
- */
-cvox.Cursor.prototype.equals = function(rhs) {
- return this.node == rhs.node &&
- this.index == rhs.index &&
- this.text == rhs.text;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor_selection.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor_selection.js
deleted file mode 100644
index f04351633c1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor_selection.js
+++ /dev/null
@@ -1,255 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Simple class to represent a cursor selection.
- * A cursor selection is just two cursors; one for the start and one for
- * the end of some interval in the document.
- */
-
-goog.provide('cvox.CursorSelection');
-
-goog.require('cvox.Cursor');
-goog.require('cvox.SelectionUtil');
-goog.require('cvox.TraverseUtil');
-
-
-/**
- * If the start node and end node are the same, and the indexes are the same,
- * the selection is interpreted to be a node. Otherwise, it is interpreted
- * to be a range.
- * @param {!cvox.Cursor} start The starting cursor.
- * @param {!cvox.Cursor} end The ending cursor.
- * @param {boolean=} opt_reverse Whether to make it a reversed selection or
- * not. Default is selection is not reversed. If start and end are in the
- * wrong order, they will be swapped automatically.
- * NOTE: Can't infer automatically whether the selection is reversed because
- * for a selection on a single node, the start and end are equal.
- * @constructor
- */
-cvox.CursorSelection = function(start, end, opt_reverse) {
- this.start = start.clone();
- this.end = end.clone();
-
- if (opt_reverse == undefined) {
- opt_reverse = false;
- }
- /** @private */
- this.isReversed_ = opt_reverse;
-
- if ((this.isReversed_ &&
- this.start.node.compareDocumentPosition(this.end.node) ==
- cvox.CursorSelection.BEFORE) ||
- (!this.isReversed_ &&
- this.end.node.compareDocumentPosition(this.start.node) ==
- cvox.CursorSelection.BEFORE)) {
- var oldStart = this.start;
- this.start = this.end;
- this.end = oldStart;
- }
-};
-
-
-/**
- * From http://www.w3schools.com/jsref/met_node_comparedocumentposition.asp
- */
-cvox.CursorSelection.BEFORE = 4;
-
-
-/**
- * If true, ensures that this selection is reversed. Otherwise, ensures that
- * it is not reversed.
- * @param {boolean} reversed True to reverse. False to nonreverse.
- * @return {!cvox.CursorSelection} For chaining.
- */
-cvox.CursorSelection.prototype.setReversed = function(reversed) {
- if (reversed == this.isReversed_) {
- return this;
- }
- var oldStart = this.start;
- this.start = this.end;
- this.end = oldStart;
- this.isReversed_ = reversed;
- return this;
-};
-
-
-/**
- * Returns true if this selection is a reverse selection.
- * @return {boolean} true if reversed.
- */
-cvox.CursorSelection.prototype.isReversed = function() {
- return this.isReversed_;
-};
-
-
-/**
- * Returns start if not reversed, end if reversed.
- * @return {!cvox.Cursor} start if not reversed, end if reversed.
- */
-cvox.CursorSelection.prototype.absStart = function() {
- return this.isReversed_ ? this.end : this.start;
-};
-
-/**
- * Returns end if not reversed, start if reversed.
- * @return {!cvox.Cursor} end if not reversed, start if reversed.
- */
-cvox.CursorSelection.prototype.absEnd = function() {
- return this.isReversed_ ? this.start : this.end;
-};
-
-
-/**
- * Clones the selection.
- * @return {!cvox.CursorSelection} The cloned selection.
- */
-cvox.CursorSelection.prototype.clone = function() {
- return new cvox.CursorSelection(this.start, this.end, this.isReversed_);
-};
-
-
-/**
- * Places a DOM selection around this CursorSelection.
- */
-cvox.CursorSelection.prototype.select = function() {
- var sel = window.getSelection();
- sel.removeAllRanges();
- this.normalize();
- sel.addRange(this.getRange());
-};
-
-
-/**
- * Creates a new cursor selection that starts and ends at the node.
- * Returns null if node is null.
- * @param {Node} node The node.
- * @return {cvox.CursorSelection} The selection.
- */
-cvox.CursorSelection.fromNode = function(node) {
- if (!node) {
- return null;
- }
- var text = cvox.TraverseUtil.getNodeText(node);
-
- return new cvox.CursorSelection(
- new cvox.Cursor(node, 0, text),
- new cvox.Cursor(node, 0, text));
-};
-
-
-/**
- * Creates a new cursor selection that starts and ends at document.body.
- * @return {!cvox.CursorSelection} The selection.
- */
-cvox.CursorSelection.fromBody = function() {
- return /** @type {!cvox.CursorSelection} */ (
- cvox.CursorSelection.fromNode(document.body));
-};
-
-/**
- * Returns the text that the selection spans.
- * @return {string} Text within the selection. '' if it is a node selection.
- */
-cvox.CursorSelection.prototype.getText = function() {
- if (this.start.equals(this.end)) {
- return cvox.TraverseUtil.getNodeText(this.start.node);
- }
- return cvox.SelectionUtil.getRangeText(this.getRange());
-};
-
-/**
- * Returns a range from the given selection.
- * @return {Range} The range.
- */
-cvox.CursorSelection.prototype.getRange = function() {
- var range = document.createRange();
- if (this.isReversed_) {
- range.setStart(this.end.node, this.end.index);
- range.setEnd(this.start.node, this.start.index);
- } else {
- range.setStart(this.start.node, this.start.index);
- range.setEnd(this.end.node, this.end.index);
- }
- return range;
-};
-
-/**
- * Check for equality.
- * @param {!cvox.CursorSelection} rhs The CursorSelection to compare against.
- * @return {boolean} True if equal.
- */
-cvox.CursorSelection.prototype.equals = function(rhs) {
- return this.start.equals(rhs.start) && this.end.equals(rhs.end);
-};
-
-/**
- * Check for equality regardless of direction.
- * @param {!cvox.CursorSelection} rhs The CursorSelection to compare against.
- * @return {boolean} True if equal.
- */
-cvox.CursorSelection.prototype.absEquals = function(rhs) {
- return ((this.start.equals(rhs.start) && this.end.equals(rhs.end)) ||
- (this.end.equals(rhs.start) && this.start.equals(rhs.end)));
-};
-
-/**
- * Determines if this starts before another CursorSelection in document order.
- * If this is reversed, then a reversed document order is checked.
- * In the case that this and rhs start at the same position, we return true.
- * @param {!cvox.CursorSelection} rhs The selection to compare.
- * @return {boolean} True if this is before rhs.
- */
-cvox.CursorSelection.prototype.directedBefore = function(rhs) {
- var leftToRight = this.start.node.compareDocumentPosition(rhs.start.node) ==
- cvox.CursorSelection.BEFORE;
- return this.start.node == rhs.start.node ||
- (this.isReversed() ? !leftToRight : leftToRight);
-};
-/**
- * Normalizes this selection.
- * Use this routine to adjust CursorSelection's that have been collapsed due to
- * convention such as when a CursorSelection references a node without attention
- * to its endpoints.
- * The result is to surround the node with this cursor.
- * @return {!cvox.CursorSelection} The normalized selection.
- */
-cvox.CursorSelection.prototype.normalize = function() {
- if (this.absEnd().index == 0 && this.absEnd().node) {
- var node = this.absEnd().node;
-
- // DOM ranges use different conventions when surrounding a node. For
- // instance, input nodes endOffset is always 0 while h1's endOffset is 1
- //with both having no children. Use a range to compute the endOffset.
- var testRange = document.createRange();
- testRange.selectNodeContents(node);
- this.absEnd().index = testRange.endOffset;
- }
- return this;
-};
-
-/**
- * Collapses to the directed start of the selection.
- * @return {!cvox.CursorSelection} For chaining.
- */
-cvox.CursorSelection.prototype.collapse = function() {
- // Not a selection.
- if (this.start.equals(this.end)) {
- return this;
- }
- this.end.copyFrom(this.start);
- if (this.start.text.length == 0) {
- return this;
- }
- if (this.isReversed()) {
- if (this.end.index > 0) {
- this.end.index--;
- }
- } else {
- if (this.end.index < this.end.text.length) {
- this.end.index++;
- }
- }
- return this;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor_selection_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor_selection_test.unitjs
deleted file mode 100644
index d4a72beba4a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/cursor_selection_test.unitjs
+++ /dev/null
@@ -1,97 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxCursorSelectionUnitTest() {}
-
-CvoxCursorSelectionUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.CursorSelection'
- ]
-};
-
-TEST_F('CvoxCursorSelectionUnitTest', 'Reverse', function() {
- this.loadDoc(function() {/*!
- <div>
- <p id="a">a</p>
- <p id="b">b</p>
- </div>
- */});
- var a = new cvox.Cursor($('a'), 0, '');
- var b = new cvox.Cursor($('b'), 0, '');
-
- var aa = new cvox.CursorSelection(a, a);
- assertEquals(false, aa.isReversed());
- aa.setReversed(true);
- assertEquals(true, aa.isReversed());
-
- var ab = new cvox.CursorSelection(a, b);
- assertEquals(false, ab.isReversed());
- ab.setReversed(true);
- assertEquals(true, ab.isReversed());
- assertEquals(true, ab.start.equals(b));
- assertEquals(true, ab.end.equals(a));
- ab.setReversed(false);
- assertEquals(false, ab.isReversed());
- assertEquals(true, ab.start.equals(a));
- assertEquals(true, ab.end.equals(b));
-
- ab = new cvox.CursorSelection(b, a);
- assertEquals(false, ab.isReversed());
- assertEquals(true, ab.start.equals(a));
- assertEquals(true, ab.end.equals(b));
-
- var ba = new cvox.CursorSelection(b, a, true);
- assertEquals(true, ba.isReversed());
- assertEquals(true, ba.start.equals(b));
- assertEquals(true, ba.end.equals(a));
-
- ba = new cvox.CursorSelection(a, b, true);
- assertEquals(true, ba.isReversed());
- assertEquals(true, ba.start.equals(b));
- assertEquals(true, ba.end.equals(a));
-});
-
-
-/** Tests correctness of collapsing selections. */
-TEST_F('CvoxCursorSelectionUnitTest', 'Collapse', function() {
- this.loadDoc(function() {/*!
- <p id='1'>This is a test.</p>
- */});
- var text = $('1').firstChild;
- var a = new cvox.Cursor(text, 0, 'This is a test.');
- var b = new cvox.Cursor(text, 13, 'This is a test.');
- var c = new cvox.Cursor(text, 5, 'This is a test.');
- var d = new cvox.Cursor(text, 8, 'This is a test.');
-
- var aa = new cvox.CursorSelection(a, a).collapse();
- assertEquals(0, aa.start.index);
- assertEquals(0, aa.end.index);
-
- var ab = new cvox.CursorSelection(a, b).collapse();
- assertEquals(0, ab.start.index);
- assertEquals(1, ab.end.index);
-
- var ba = new cvox.CursorSelection(b, a, true).collapse();
- assertEquals(12, ba.absStart().index);
- assertEquals(13, ba.absEnd().index);
-
- var cd = new cvox.CursorSelection(c, d).collapse();
- assertEquals(5, cd.start.index);
- assertEquals(6, cd.end.index);
-
- var dc = new cvox.CursorSelection(d, c, true).collapse();
- assertEquals(7, dc.absStart().index);
- assertEquals(8, dc.absEnd().index);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/date_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/date_widget.js
deleted file mode 100644
index b494db9282e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/date_widget.js
+++ /dev/null
@@ -1,322 +0,0 @@
-// 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.
-
-goog.provide('cvox.ChromeVoxHTMLDateWidget');
-
-goog.require('Msgs');
-
-/**
- * @fileoverview Gives the user spoken feedback as they interact with the date
- * widget (input type=date).
- *
- */
-
-/**
- * A class containing the information needed to speak
- * a text change event to the user.
- *
- * @constructor
- * @param {Element} dateElem The time widget element.
- * @param {cvox.TtsInterface} tts The TTS object from ChromeVox.
- */
-cvox.ChromeVoxHTMLDateWidget = function(dateElem, tts) {
- var self = this;
- /**
- * Currently selected field in the widget.
- * @type {number}
- * @private
- */
- this.pos_ = 0;
- var maxpos = 2;
- if (dateElem.type == 'month' || dateElem.type == 'week') {
- maxpos = 1;
- }
- /**
- * The maximum number of fields in the widget.
- * @type {number}
- * @private
- */
- this.maxPos_ = maxpos;
- /**
- * The HTML node of the widget.
- * @type {Node}
- * @private
- */
- this.dateElem_ = dateElem;
- /**
- * A handle to the ChromeVox TTS object.
- * @type {Object}
- * @private
- */
- this.dateTts_ = tts;
- /**
- * The previous value of the year field.
- * @type {number}
- * @private
- */
- this.pYear_ = -1;
- /**
- * The previous value of the month field.
- * @type {number}
- * @private
- */
- this.pMonth_ = -1;
- /**
- * The previous value of the week field.
- * @type {number}
- * @private
- */
- this.pWeek_ = -1;
- /**
- * The previous value of the day field.
- * @type {number}
- * @private
- */
- this.pDay_ = -1;
-
- // Use listeners to make this work when running tests inside of ChromeVox.
- this.keyListener_ = function(evt) {
- self.eventHandler_(evt);
- };
- this.blurListener_ = function(evt) {
- self.shutdown();
- };
-
- // Ensure we have a reasonable value to start with.
- if (this.dateElem_.value.length == 0) {
- this.forceInitTime_();
- }
-
- // Move the cursor to the first position so that we are guaranteed to start
- // off at the hours position.
- for (var i = 0; i < this.maxPos_; i++) {
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keydown', true, true, window, 'Left', 0, false, false, false, false);
- this.dateElem_.dispatchEvent(evt);
- evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keyup', true, true, window, 'Left', 0, false, false, false, false);
- this.dateElem_.dispatchEvent(evt);
- }
-
- this.dateElem_.addEventListener('keydown', this.keyListener_, false);
- this.dateElem_.addEventListener('keyup', this.keyListener_, false);
- this.dateElem_.addEventListener('blur', this.blurListener_, false);
- this.update_(true);
-};
-
-/**
- * Removes the key listeners for the time widget.
- *
- */
-cvox.ChromeVoxHTMLDateWidget.prototype.shutdown = function() {
- this.dateElem_.removeEventListener('blur', this.blurListener_, false);
- this.dateElem_.removeEventListener('keydown', this.keyListener_, false);
- this.dateElem_.removeEventListener('keyup', this.keyListener_, false);
-};
-
-/**
- * Forces a sensible default value so that there is something there that can
- * be inspected with JS.
- * @private
- */
-cvox.ChromeVoxHTMLDateWidget.prototype.forceInitTime_ = function() {
- var currentDate = new Date();
- var valueString = '';
- var yearString = currentDate.getFullYear() + '';
- // Date.getMonth starts at 0, but the value for the HTML5 date widget needs to
- // start at 1.
- var monthString = currentDate.getMonth() + 1 + '';
- if (monthString.length < 2) {
- monthString = '0' + monthString; // Month format is MM.
- }
- var dayString = currentDate.getDate() + '';
-
- switch (this.dateElem_.type) {
- case 'month':
- valueString = yearString + '-' + monthString;
- break;
- case 'week':
- // Based on info from: http://www.merlyn.demon.co.uk/weekcalc.htm#WNR
- currentDate.setHours(0, 0, 0);
- // Set to nearest Thursday: current date + 4 - current day number
- // Make Sunday's day number 7
- currentDate.setDate(
- currentDate.getDate() + 4 - (currentDate.getDay() || 7));
- // Get first day of year
- var yearStart = new Date(currentDate.getFullYear(), 0, 1);
- // Calculate full weeks to nearest Thursday
- var weekString =
- Math.ceil((((currentDate - yearStart) / 86400000) + 1) / 7) + '';
- if (weekString.length < 2) {
- weekString = '0' + weekString; // Week format is WXX.
- }
- weekString = 'W' + weekString;
- valueString = yearString + '-' + weekString;
- break;
- default:
- valueString = yearString + '-' + monthString + '-' + dayString;
- break;
- }
- this.dateElem_.setAttribute('value', valueString);
-};
-
-/**
- * Ensure that the position stays within bounds.
- * @private
- */
-cvox.ChromeVoxHTMLDateWidget.prototype.handlePosChange_ = function() {
- this.pos_ = Math.max(this.pos_, 0);
- this.pos_ = Math.min(this.pos_, this.maxPos_);
- // TODO (clchen, dtseng): Make this logic i18n once there is a way to
- // determine what the date format actually is. For now, assume that:
- // date == mm/dd/yyyy
- // week == ww/yyyy
- // month == mm/yyyy.
- switch (this.pos_) {
- case 0:
- if (this.dateElem_.type == 'week') {
- this.pWeek_ = -1;
- } else {
- this.pMonth_ = -1;
- }
- break;
- case 1:
- if (this.dateElem_.type == 'date') {
- this.pDay_ = -1;
- } else {
- this.pYear_ = -1;
- }
- break;
- case 2:
- this.pYear_ = -1;
- break;
- }
-};
-
-/**
- * Speaks any changes to the control.
- * @private
- * @param {boolean} shouldSpeakLabel Whether or not to speak the label.
- */
-cvox.ChromeVoxHTMLDateWidget.prototype.update_ = function(shouldSpeakLabel) {
- var splitDate = this.dateElem_.value.split('-');
- if (splitDate.length < 1) {
- this.forceInitTime_();
- return;
- }
-
- var year = -1;
- var month = -1;
- var week = -1;
- var day = -1;
-
- year = parseInt(splitDate[0], 10);
-
- if (this.dateElem_.type == 'week') {
- week = parseInt(splitDate[1].replace('W', ''), 10);
- } else if (this.dateElem_.type == 'date') {
- month = parseInt(splitDate[1], 10);
- day = parseInt(splitDate[2], 10);
- } else {
- month = parseInt(splitDate[1], 10);
- }
-
- var changeMessage = '';
-
- if (shouldSpeakLabel) {
- changeMessage = cvox.DomUtil.getName(this.dateElem_, true, true) + '\n';
- }
-
- if (week != this.pWeek_) {
- changeMessage = changeMessage +
- Msgs.getMsg('datewidget_week') + week + '\n';
- this.pWeek_ = week;
- }
-
- if (month != this.pMonth_) {
- var monthName = '';
- switch (month) {
- case 1:
- monthName = Msgs.getMsg('datewidget_january');
- break;
- case 2:
- monthName = Msgs.getMsg('datewidget_february');
- break;
- case 3:
- monthName = Msgs.getMsg('datewidget_march');
- break;
- case 4:
- monthName = Msgs.getMsg('datewidget_april');
- break;
- case 5:
- monthName = Msgs.getMsg('datewidget_may');
- break;
- case 6:
- monthName = Msgs.getMsg('datewidget_june');
- break;
- case 7:
- monthName = Msgs.getMsg('datewidget_july');
- break;
- case 8:
- monthName = Msgs.getMsg('datewidget_august');
- break;
- case 9:
- monthName = Msgs.getMsg('datewidget_september');
- break;
- case 10:
- monthName = Msgs.getMsg('datewidget_october');
- break;
- case 11:
- monthName = Msgs.getMsg('datewidget_november');
- break;
- case 12:
- monthName = Msgs.getMsg('datewidget_december');
- break;
- }
- changeMessage = changeMessage + monthName + '\n';
- this.pMonth_ = month;
- }
-
- if (day != this.pDay_) {
- changeMessage = changeMessage + day + '\n';
- this.pDay_ = day;
- }
-
- if (year != this.pYear_) {
- changeMessage = changeMessage + year + '\n';
- this.pYear_ = year;
- }
-
- if (changeMessage.length > 0) {
- this.dateTts_.speak(changeMessage, 0, null);
- }
-};
-
-/**
- * Handles user key events.
- * @private
- * @param {Event} evt The event to be handled.
- */
-cvox.ChromeVoxHTMLDateWidget.prototype.eventHandler_ = function(evt) {
- var shouldSpeakLabel = false;
- if (evt.type == 'keydown') {
- // Handle tab/right arrow
- if (((evt.keyCode == 9) && !evt.shiftKey) || (evt.keyCode == 39)) {
- this.pos_++;
- this.handlePosChange_();
- shouldSpeakLabel = true;
- }
- // Handle shift+tab/left arrow
- if (((evt.keyCode == 9) && evt.shiftKey) || (evt.keyCode == 37)) {
- this.pos_--;
- this.handlePosChange_();
- shouldSpeakLabel = true;
- }
- // For all other cases, fall through and let update_ decide if there are any
- // changes that need to be spoken.
- }
- this.update_(shouldSpeakLabel);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/description_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/description_util.js
deleted file mode 100644
index d7bece47b98..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/description_util.js
+++ /dev/null
@@ -1,474 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A utility class for building NavDescriptions from the dom.
- */
-
-
-goog.provide('cvox.DescriptionUtil');
-
-goog.require('cvox.AriaUtil');
-goog.require('cvox.AuralStyleUtil');
-goog.require('cvox.BareObjectWalker');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.DomUtil');
-goog.require('cvox.EarconUtil');
-goog.require('cvox.MathmlStore');
-goog.require('cvox.NavDescription');
-goog.require('cvox.SpeechRuleEngine');
-goog.require('cvox.TraverseMath');
-
-
-/**
- * Lists all Node tagName's who's description is derived from its subtree.
- * @type {Object<boolean>}
- */
-cvox.DescriptionUtil.COLLECTION_NODE_TYPE = {
- 'H1': true,
- 'H2': true,
- 'H3': true,
- 'H4': true,
- 'H5': true,
- 'H6': true
-};
-
-/**
- * Get a control's complete description in the same format as if you
- * navigated to the node.
- * @param {Element} control A control.
- * @param {Array<Node>=} opt_changedAncestors The changed ancestors that will
- * be used to determine what needs to be spoken. If this is not provided, the
- * ancestors used to determine what needs to be spoken will just be the control
- * itself and its surrounding control if it has one.
- * @return {cvox.NavDescription} The description of the control.
- */
-cvox.DescriptionUtil.getControlDescription =
- function(control, opt_changedAncestors) {
- var ancestors = [control];
- if (opt_changedAncestors && (opt_changedAncestors.length > 0)) {
- ancestors = opt_changedAncestors;
- } else {
- var surroundingControl = cvox.DomUtil.getSurroundingControl(control);
- if (surroundingControl) {
- ancestors = [surroundingControl, control];
- }
- }
-
- var description = cvox.DescriptionUtil.getDescriptionFromAncestors(
- ancestors, true, cvox.VERBOSITY_VERBOSE);
-
- // Use heuristics if the control doesn't otherwise have a name.
- if (surroundingControl) {
- var name = cvox.DomUtil.getName(surroundingControl);
- if (name.length == 0) {
- name = cvox.DomUtil.getControlLabelHeuristics(surroundingControl);
- if (name.length > 0) {
- description.context = name + ' ' + description.context;
- }
- }
- } else {
- var name = cvox.DomUtil.getName(control);
- if (name.length == 0) {
- name = cvox.DomUtil.getControlLabelHeuristics(control);
- if (name.length > 0) {
- description.text = cvox.DomUtil.collapseWhitespace(name);
- }
- }
- var value = cvox.DomUtil.getValue(control);
- if (value.length > 0) {
- description.userValue = cvox.DomUtil.collapseWhitespace(value);
- }
- }
-
- return description;
-};
-
-
-/**
- * Returns a description of a navigation from an array of changed
- * ancestor nodes. The ancestors are in order from the highest in the
- * tree to the lowest, i.e. ending with the current leaf node.
- *
- * @param {Array<Node>} ancestorsArray An array of ancestor nodes.
- * @param {boolean} recursive Whether or not the element's subtree should
- * be used; true by default.
- * @param {number} verbosity The verbosity setting.
- * @return {cvox.NavDescription} The description of the navigation action.
- */
-cvox.DescriptionUtil.getDescriptionFromAncestors = function(
- ancestorsArray, recursive, verbosity) {
- if (typeof(recursive) === 'undefined') {
- recursive = true;
- }
- var len = ancestorsArray.length;
- var context = '';
- var text = '';
- var userValue = '';
- var annotation = '';
- var earcons = [];
- var personality = null;
- var hint = '';
-
- if (len > 0) {
- text = cvox.DomUtil.getName(ancestorsArray[len - 1], recursive);
-
- userValue = cvox.DomUtil.getValue(ancestorsArray[len - 1]);
- }
- for (var i = len - 1; i >= 0; i--) {
- var node = ancestorsArray[i];
-
- hint = cvox.DomUtil.getHint(node);
-
- // Don't speak dialogs here, they're spoken when events occur.
- var role = node.getAttribute ? node.getAttribute('role') : null;
- if (role == 'alertdialog') {
- continue;
- }
-
- var roleText = cvox.DomUtil.getRole(node, verbosity);
-
- // Use the ancestor closest to the target to be the personality.
- if (!personality) {
- personality = cvox.AuralStyleUtil.getStyleForNode(node);
- }
- // TODO(dtseng): Is this needed?
- if (i < len - 1 && node.hasAttribute('role')) {
- var name = cvox.DomUtil.getName(node, false);
- if (name) {
- roleText = name + ' ' + roleText;
- }
- }
- if (roleText.length > 0) {
- // Since we prioritize reading of context in reading order, only populate
- // it for larger ancestry changes.
- if (context.length > 0 ||
- (annotation.length > 0 && node.childElementCount > 1)) {
- context = roleText + ' ' + cvox.DomUtil.getState(node, false) +
- ' ' + context;
- } else {
- if (annotation.length > 0) {
- annotation +=
- ' ' + roleText + ' ' + cvox.DomUtil.getState(node, true);
- } else {
- annotation = roleText + ' ' + cvox.DomUtil.getState(node, true);
- }
- }
- }
- var earcon = cvox.EarconUtil.getEarcon(node);
- if (earcon != null && earcons.indexOf(earcon) == -1) {
- earcons.push(earcon);
- }
- }
- return new cvox.NavDescription({
- context: cvox.DomUtil.collapseWhitespace(context),
- text: cvox.DomUtil.collapseWhitespace(text),
- userValue: cvox.DomUtil.collapseWhitespace(userValue),
- annotation: cvox.DomUtil.collapseWhitespace(annotation),
- earcons: earcons,
- personality: personality,
- hint: cvox.DomUtil.collapseWhitespace(hint)
- });
-};
-
-/**
- * Returns a description of a navigation from an array of changed
- * ancestor nodes. The ancestors are in order from the highest in the
- * tree to the lowest, i.e. ending with the current leaf node.
- *
- * @param {Node} prevNode The previous node in navigation.
- * @param {Node} node The current node in navigation.
- * @param {boolean} recursive Whether or not the element's subtree should
- * be used; true by default.
- * @param {number} verbosity The verbosity setting.
- * @return {!Array<cvox.NavDescription>} The description of the navigation
- * action.
- */
-cvox.DescriptionUtil.getDescriptionFromNavigation =
- function(prevNode, node, recursive, verbosity) {
- if (!prevNode || !node) {
- return [];
- }
-
- // Specialized math descriptions.
- if (cvox.DomUtil.isMath(node) &&
- !cvox.AriaUtil.isMath(node)) {
- return cvox.DescriptionUtil.getMathDescription(node);
- }
-
- // Next, check to see if the current node is a collection type.
- if (cvox.DescriptionUtil.COLLECTION_NODE_TYPE[node.tagName]) {
- return cvox.DescriptionUtil.getCollectionDescription(
- /** @type {!cvox.CursorSelection} */(
- cvox.CursorSelection.fromNode(prevNode)),
- /** @type {!cvox.CursorSelection} */(
- cvox.CursorSelection.fromNode(node)));
- }
-
- // Now, generate a description for all other elements.
- var ancestors = cvox.DomUtil.getUniqueAncestors(prevNode, node, true);
- var desc = cvox.DescriptionUtil.getDescriptionFromAncestors(
- ancestors, recursive, verbosity);
- var prevAncestors = cvox.DomUtil.getUniqueAncestors(node, prevNode);
- if (cvox.DescriptionUtil.shouldDescribeExit_(prevAncestors)) {
- var prevDesc = cvox.DescriptionUtil.getDescriptionFromAncestors(
- prevAncestors, recursive, verbosity);
- if (prevDesc.context && !desc.context) {
- desc.context =
- Msgs.getMsg('exited_container', [prevDesc.context]);
- }
- }
- return [desc];
-};
-
-
-/**
- * Returns an array of NavDescriptions that includes everything that would be
- * spoken by an object walker while traversing from prevSel to sel.
- * It also includes any necessary annotations and context about the set of
- * descriptions. This function is here because most (currently all) walkers
- * that iterate over non-leaf nodes need this sort of description.
- * This is an awkward design, and should be changed in the future.
- * @param {!cvox.CursorSelection} prevSel The previous selection.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {!Array<!cvox.NavDescription>} The descriptions as described above.
- */
-cvox.DescriptionUtil.getCollectionDescription = function(prevSel, sel) {
- var descriptions = cvox.DescriptionUtil.getRawDescriptions_(prevSel, sel);
- cvox.DescriptionUtil.insertCollectionDescription_(descriptions);
- return descriptions;
-};
-
-
-/**
- * Used for getting collection descriptions.
- * @type {!cvox.BareObjectWalker}
- * @private
- */
-cvox.DescriptionUtil.subWalker_ = new cvox.BareObjectWalker();
-
-
-/**
- * Returns the descriptions that would be gotten by an object walker.
- * @param {!cvox.CursorSelection} prevSel The previous selection.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {!Array<!cvox.NavDescription>} The descriptions.
- * @private
- */
-cvox.DescriptionUtil.getRawDescriptions_ = function(prevSel, sel) {
- // Use a object walker in non-smart mode to traverse all of the
- // nodes inside the current smart node and return their annotations.
- var descriptions = [];
-
- // We want the descriptions to be in forward order whether or not the
- // selection is reversed.
- sel = sel.clone().setReversed(false);
- var node = cvox.DescriptionUtil.subWalker_.sync(sel).start.node;
-
- var prevNode = prevSel.end.node;
- var curSel = cvox.CursorSelection.fromNode(node);
-
- if (!curSel) {
- return [];
- }
-
- while (cvox.DomUtil.isDescendantOfNode(node, sel.start.node)) {
- var ancestors = cvox.DomUtil.getUniqueAncestors(prevNode, node);
- // Specialized math descriptions.
- if (cvox.DomUtil.isMath(node) &&
- !cvox.AriaUtil.isMath(node)) {
- descriptions =
- descriptions.concat(cvox.DescriptionUtil.getMathDescription(node));
- } else {
- var description = cvox.DescriptionUtil.getDescriptionFromAncestors(
- ancestors, true, cvox.ChromeVox.verbosity);
- descriptions.push(description);
- }
- curSel = cvox.DescriptionUtil.subWalker_.next(curSel);
- if (!curSel) {
- break;
- }
-
- curSel = /** @type {!cvox.CursorSelection} */ (curSel);
- prevNode = node;
- node = curSel.start.node;
- }
-
- return descriptions;
-};
-
-/**
- * Returns the full descriptions of the child nodes that would be gotten by an
- * object walker.
- * @param {?Element} prevnode The previous element if there is one.
- * @param {!Element} node The target element.
- * @return {!Array<!cvox.NavDescription>} The descriptions.
- */
-cvox.DescriptionUtil.getFullDescriptionsFromChildren =
- function(prevnode, node) {
- var descriptions = [];
- if (!node) {
- return descriptions;
- }
- var desc;
- if (cvox.DomUtil.isLeafNode(node)) {
- var ancestors;
- if (prevnode) {
- ancestors = cvox.DomUtil.getUniqueAncestors(prevnode, node);
- } else {
- ancestors = new Array();
- ancestors.push(node);
- }
- desc = cvox.DescriptionUtil.getDescriptionFromAncestors(
- ancestors, true, cvox.ChromeVox.verbosity);
- descriptions.push(desc);
- return descriptions;
- }
- var originalNode = node;
- var curSel = cvox.CursorSelection.fromNode(node);
- if (!curSel) {
- return descriptions;
- }
- node = cvox.DescriptionUtil.subWalker_.sync(curSel).start.node;
- curSel = cvox.CursorSelection.fromNode(node);
- if (!curSel) {
- return descriptions;
- }
- while (cvox.DomUtil.isDescendantOfNode(node, originalNode)) {
- descriptions = descriptions.concat(
- cvox.DescriptionUtil.getFullDescriptionsFromChildren(prevnode, node));
- curSel = cvox.DescriptionUtil.subWalker_.next(curSel);
- if (!curSel) {
- break;
- }
- curSel = /** @type {!cvox.CursorSelection} */ (curSel);
- prevnode = node;
- node = curSel.start.node;
- }
- return descriptions;
-};
-
-
-/**
- * Modify the descriptions to say that it is a collection.
- * @param {Array<cvox.NavDescription>} descriptions The descriptions.
- * @private
- */
-cvox.DescriptionUtil.insertCollectionDescription_ = function(descriptions) {
- var annotations = cvox.DescriptionUtil.getAnnotations_(descriptions);
- // If all of the items have the same annotation, describe it as a
- // <annotation> collection with <n> items. Currently only enabled
- // for links, but support should be added for any other type that
- // makes sense.
- if (descriptions.length >= 3 &&
- descriptions[0].context.length == 0 &&
- annotations.length == 1 &&
- annotations[0].length > 0 &&
- cvox.DescriptionUtil.isAnnotationCollection_(annotations[0])) {
- var commonAnnotation = annotations[0];
- var firstContext = descriptions[0].context;
- descriptions[0].context = '';
- for (var i = 0; i < descriptions.length; i++) {
- descriptions[i].annotation = '';
- }
-
- descriptions.splice(0, 0, new cvox.NavDescription({
- context: firstContext,
- text: '',
- annotation: Msgs.getMsg(
- 'collection',
- [commonAnnotation,
- Msgs.getNumber(descriptions.length)])
- }));
- }
-};
-
-
-/**
- * Pulls the annotations from a description array.
- * @param {Array<cvox.NavDescription>} descriptions The descriptions.
- * @return {Array<string>} The annotations.
- * @private
- */
-cvox.DescriptionUtil.getAnnotations_ = function(descriptions) {
- var annotations = [];
- for (var i = 0; i < descriptions.length; ++i) {
- var description = descriptions[i];
- if (annotations.indexOf(description.annotation) == -1) {
- // If we have an Internal link collection, call it Link collection.
- // NOTE(deboer): The message comparison is a symptom of a bad design.
- // I suspect this code belongs elsewhere but I don't know where, yet.
- var linkMsg = Msgs.getMsg('role_link');
- if (description.annotation.toLowerCase().indexOf(linkMsg.toLowerCase()) !=
- -1) {
- if (annotations.indexOf(linkMsg) == -1) {
- annotations.push(linkMsg);
- }
- } else {
- annotations.push(description.annotation);
- }
- }
- }
- return annotations;
-};
-
-
-/**
- * Returns true if this annotation should be grouped as a collection,
- * meaning that instead of repeating the annotation for each item, we
- * just announce <annotation> collection with <n> items at the front.
- *
- * Currently enabled for links, but could be extended to support other
- * roles that make sense.
- *
- * @param {string} annotation The annotation text.
- * @return {boolean} If this annotation should be a collection.
- * @private
- */
-cvox.DescriptionUtil.isAnnotationCollection_ = function(annotation) {
- return (annotation == Msgs.getMsg('role_link'));
-};
-
-/**
- * Determines whether to describe the exit of an ancestor chain.
- * @param {Array<Node>} ancestors The ancestors exited during navigation.
- * @return {boolean} The result.
- * @private
- */
-cvox.DescriptionUtil.shouldDescribeExit_ = function(ancestors) {
- return ancestors.some(function(node) {
- switch (node.tagName) {
- case 'TABLE':
- case 'MATH':
- return true;
- }
- return cvox.AriaUtil.isLandmark(node);
- });
-};
-
-
-// TODO(sorge): Bad naming...this thing returns *multiple* descriptions.
-/**
- * Generates a description for a math node.
- * @param {!Node} node The given node.
- * @return {!Array<cvox.NavDescription>} A list of Navigation descriptions.
- */
-cvox.DescriptionUtil.getMathDescription = function(node) {
- // TODO (sorge) This function should evantually be removed. Descriptions
- // should come directly from the speech rule engine, taking information on
- // verbosity etc. into account.
- var speechEngine = cvox.SpeechRuleEngine.getInstance();
- var traverse = cvox.TraverseMath.getInstance();
- speechEngine.parameterize(cvox.MathmlStore.getInstance());
- traverse.initialize(node);
- var ret = speechEngine.evaluateNode(traverse.activeNode);
- if (ret == []) {
- return [new cvox.NavDescription({'text': 'empty math'})];
- }
- if (cvox.ChromeVox.verbosity == cvox.VERBOSITY_VERBOSE) {
- ret[ret.length - 1].annotation = 'math';
- }
- ret[0].pushEarcon(cvox.Earcon.MATH);
- return ret;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_predicates.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_predicates.js
deleted file mode 100644
index 685a8ecf8f4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_predicates.js
+++ /dev/null
@@ -1,493 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A bunch of predicates that take as input an array of
- * nodes with the unique ancestors of a node. They output true if a
- * certain category of node has been found.
- *
- */
-
-goog.provide('cvox.DomPredicates');
-
-
-/**
- * Checkbox.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a checkbox.
- */
-cvox.DomPredicates.checkboxPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute &&
- nodes[i].getAttribute('role') == 'checkbox') ||
- (nodes[i].tagName == 'INPUT' && nodes[i].type == 'checkbox')) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Radio button.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a radio button.
- */
-cvox.DomPredicates.radioPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute && nodes[i].getAttribute('role') == 'radio') ||
- (nodes[i].tagName == 'INPUT' && nodes[i].type == 'radio')) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Slider.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a slider.
- */
-cvox.DomPredicates.sliderPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute && nodes[i].getAttribute('role') == 'slider') ||
- (nodes[i].tagName == 'INPUT' && nodes[i].type == 'range')) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Graphic.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a graphic.
- */
-cvox.DomPredicates.graphicPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].tagName == 'IMG' ||
- (nodes[i].tagName == 'INPUT' && nodes[i].type == 'img')) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Button.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a button.
- */
-cvox.DomPredicates.buttonPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute && nodes[i].getAttribute('role') == 'button') ||
- nodes[i].tagName == 'BUTTON' ||
- (nodes[i].tagName == 'INPUT' && nodes[i].type == 'submit') ||
- (nodes[i].tagName == 'INPUT' && nodes[i].type == 'button') ||
- (nodes[i].tagName == 'INPUT' && nodes[i].type == 'reset')) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Combo box.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a combo box.
- */
-cvox.DomPredicates.comboBoxPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute &&
- nodes[i].getAttribute('role') == 'combobox') ||
- nodes[i].tagName == 'SELECT') {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Editable text field.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is an editable text field.
- */
-cvox.DomPredicates.editTextPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute && nodes[i].getAttribute('role') == 'textbox') ||
- nodes[i].tagName == 'TEXTAREA' ||
- nodes[i].isContentEditable ||
- (nodes[i].tagName == 'INPUT' &&
- cvox.DomUtil.isInputTypeText(nodes[i]))) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Heading.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a heading.
- */
-cvox.DomPredicates.headingPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].getAttribute &&
- nodes[i].getAttribute('role') == 'heading') {
- return nodes[i];
- }
- switch (nodes[i].tagName) {
- case 'H1':
- case 'H2':
- case 'H3':
- case 'H4':
- case 'H5':
- case 'H6':
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Heading level 1.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a heading level 1.
- * TODO: handle ARIA headings with ARIA heading levels?
- */
-cvox.DomPredicates.heading1Predicate = function(nodes) {
- return cvox.DomPredicates.containsTagName_(nodes, 'H1');
-};
-
-
-/**
- * Heading level 2.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a heading level 2.
- */
-cvox.DomPredicates.heading2Predicate = function(nodes) {
- return cvox.DomPredicates.containsTagName_(nodes, 'H2');
-};
-
-
-/**
- * Heading level 3.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a heading level 3.
- */
-cvox.DomPredicates.heading3Predicate = function(nodes) {
- return cvox.DomPredicates.containsTagName_(nodes, 'H3');
-};
-
-
-/**
- * Heading level 4.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a heading level 4.
- */
-cvox.DomPredicates.heading4Predicate = function(nodes) {
- return cvox.DomPredicates.containsTagName_(nodes, 'H4');
-};
-
-
-/**
- * Heading level 5.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a heading level 5.
- */
-cvox.DomPredicates.heading5Predicate = function(nodes) {
- return cvox.DomPredicates.containsTagName_(nodes, 'H5');
-};
-
-
-/**
- * Heading level 6.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a heading level 6.
- */
-cvox.DomPredicates.heading6Predicate = function(nodes) {
- return cvox.DomPredicates.containsTagName_(nodes, 'H6');
-};
-
-
-/**
- * Link.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a link.
- */
-cvox.DomPredicates.linkPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute && nodes[i].getAttribute('role') == 'link') ||
- (nodes[i].tagName == 'A' && nodes[i].href)) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Table.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a data table.
- */
-cvox.DomPredicates.tablePredicate = function(nodes) {
- // TODO(stoarca): Captions should always be allowed!!
- var node = cvox.DomUtil.findTableNodeInList(nodes, {allowCaptions: true});
- if (node && !cvox.DomUtil.isLayoutTable(node)) {
- return node;
- } else {
- return null;
- }
-};
-
-/**
- * Table Cell.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a table cell.
- */
-cvox.DomPredicates.cellPredicate = function(nodes) {
- for (var i = nodes.length - 1; i >= 0; --i) {
- var node = nodes[i];
- if (node.tagName == 'TD' ||
- node.tagName == 'TH' ||
- (node.getAttribute && node.getAttribute('role') == 'gridcell')) {
- return node;
- }
- }
- return null;
-};
-
-
-/**
- * Visited link.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a visited link.
- */
-cvox.DomPredicates.visitedLinkPredicate = function(nodes) {
- for (var i = nodes.length - 1; i >= 0; --i) {
- if (cvox.DomPredicates.linkPredicate([nodes[i]]) &&
- cvox.ChromeVox.visitedUrls[nodes[i].href]) {
- return nodes[i];
- }
- }
-};
-
-
-/**
- * List.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a list.
- */
-cvox.DomPredicates.listPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute && nodes[i].getAttribute('role') == 'list') ||
- nodes[i].tagName == 'UL' ||
- nodes[i].tagName == 'OL') {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * List item.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a list item.
- */
-cvox.DomPredicates.listItemPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute &&
- nodes[i].getAttribute('role') == 'listitem') ||
- nodes[i].tagName == 'LI') {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Blockquote.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a blockquote.
- */
-cvox.DomPredicates.blockquotePredicate = function(nodes) {
- return cvox.DomPredicates.containsTagName_(nodes, 'BLOCKQUOTE');
-};
-
-
-/**
- * Form field.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is any type of form field.
- */
-cvox.DomPredicates.formFieldPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (cvox.DomUtil.isControl(nodes[i])) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * ARIA landmark.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is an ARIA landmark.
- */
-cvox.DomPredicates.landmarkPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (cvox.AriaUtil.isLandmark(nodes[i])) {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * @param {Array} arr Array of nodes.
- * @param {string} tagName The name of the tag.
- * @return {?Node} Node if obj is in the array.
- * @private
- */
-cvox.DomPredicates.containsTagName_ = function(arr, tagName) {
- var i = arr.length;
- while (i--) {
- if (arr[i].tagName == tagName) {
- return arr[i];
- }
- }
- return null;
-};
-
-
-/**
- * MathML expression
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a math expression.
- */
-cvox.DomPredicates.mathPredicate = function(nodes) {
- return cvox.DomUtil.findMathNodeInList(nodes);
-};
-
-/**
- * SECTION: A section is anything that indicates a new section. This includes
- * headings and landmarks.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is considered a section marker.
- */
-cvox.DomPredicates.sectionPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (cvox.DomUtil.isSemanticElt(nodes[i])) {
- return nodes[i];
- }
- if (cvox.AriaUtil.isLandmark(nodes[i])) {
- return nodes[i];
- }
- if (nodes[i].getAttribute &&
- nodes[i].getAttribute('role') == 'heading') {
- return nodes[i];
- }
- switch (nodes[i].tagName) {
- case 'H1':
- case 'H2':
- case 'H3':
- case 'H4':
- case 'H5':
- case 'H6':
- return nodes[i];
- }
- }
- return null;
-};
-
-/**
- * CONTROL: A control is anything that the user can interact with. This includes
- * form fields and links.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is considered a control.
- */
-cvox.DomPredicates.controlPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (cvox.DomUtil.isControl(nodes[i])) {
- return nodes[i];
- }
- if ((nodes[i].getAttribute && nodes[i].getAttribute('role') == 'link') ||
- (nodes[i].tagName == 'A' && nodes[i].href)) {
- return nodes[i];
- }
- }
- return null;
-};
-
-/**
- * Caption.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a caption.
- */
-cvox.DomPredicates.captionPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].tagName == 'CAPTION') {
- return nodes[i];
- }
- }
- return null;
-};
-
-/**
- * Article.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a article.
- */
-cvox.DomPredicates.articlePredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if ((nodes[i].getAttribute &&
- nodes[i].getAttribute('role') == 'article') ||
- nodes[i].tagName == 'ARTICLE') {
- return nodes[i];
- }
- }
- return null;
-};
-
-/**
- * Media.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a media widget (video or audio).
- */
-cvox.DomPredicates.mediaPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].tagName == 'AUDIO' ||
- nodes[i].tagName == 'VIDEO') {
- return nodes[i];
- }
- }
- return null;
-};
-
-
-/**
- * Ordered List.
- * @param {Array<Node>} nodes An array of nodes to check.
- * @return {?Node} Node in the array that is a ordered list.
- */
-cvox.DomPredicates.orderedListPredicate = function(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].tagName == 'OL') {
- return nodes[i];
- }
- }
- return null;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_util.js
deleted file mode 100644
index cea00b5f612..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_util.js
+++ /dev/null
@@ -1,2608 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A collection of JavaScript utilities used to simplify working
- * with the DOM.
- */
-
-
-goog.provide('cvox.DomUtil');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.AriaUtil');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.DomPredicates');
-goog.require('cvox.Memoize');
-goog.require('cvox.NodeState');
-goog.require('cvox.XpathUtil');
-
-
-
-/**
- * Create the namespace
- * @constructor
- */
-cvox.DomUtil = function() {
-};
-
-
-/**
- * Note: If you are adding a new mapping, the new message identifier needs a
- * corresponding braille message. For example, a message id 'tag_button'
- * requires another message 'tag_button_brl' within messages.js.
- * @type {Object}
- */
-cvox.DomUtil.INPUT_TYPE_TO_INFORMATION_TABLE_MSG = {
- 'button' : 'role_button',
- 'checkbox' : 'role_checkbox',
- 'color' : 'input_type_color',
- 'datetime' : 'input_type_datetime',
- 'datetime-local' : 'input_type_datetime_local',
- 'date' : 'input_type_date',
- 'email' : 'input_type_email',
- 'file' : 'input_type_file',
- 'image' : 'role_button',
- 'month' : 'input_type_month',
- 'number' : 'input_type_number',
- 'password' : 'input_type_password',
- 'radio' : 'role_radio',
- 'range' : 'role_slider',
- 'reset' : 'input_type_reset',
- 'search' : 'input_type_search',
- 'submit' : 'role_button',
- 'tel' : 'input_type_number',
- 'text' : 'input_type_text',
- 'url' : 'input_type_url',
- 'week' : 'input_type_week'
-};
-
-
-/**
- * Note: If you are adding a new mapping, the new message identifier needs a
- * corresponding braille message. For example, a message id 'tag_button'
- * requires another message 'tag_button_brl' within messages.js.
- * @type {Object}
- */
-cvox.DomUtil.TAG_TO_INFORMATION_TABLE_VERBOSE_MSG = {
- 'A' : 'role_link',
- 'ARTICLE' : 'tag_article',
- 'ASIDE' : 'tag_aside',
- 'AUDIO' : 'tag_audio',
- 'BUTTON' : 'role_button',
- 'FOOTER' : 'tag_footer',
- 'H1' : 'tag_h1',
- 'H2' : 'tag_h2',
- 'H3' : 'tag_h3',
- 'H4' : 'tag_h4',
- 'H5' : 'tag_h5',
- 'H6' : 'tag_h6',
- 'HEADER' : 'tag_header',
- 'HGROUP' : 'tag_hgroup',
- 'LI' : 'tag_li',
- 'MARK' : 'tag_mark',
- 'NAV' : 'tag_nav',
- 'OL' : 'tag_ol',
- 'SECTION' : 'tag_section',
- 'SELECT' : 'tag_select',
- 'TABLE' : 'tag_table',
- 'TEXTAREA' : 'tag_textarea',
- 'TIME' : 'tag_time',
- 'UL' : 'tag_ul',
- 'VIDEO' : 'tag_video'
-};
-
-/**
- * ChromeVox does not speak the omitted tags.
- * @type {Object}
- */
-cvox.DomUtil.TAG_TO_INFORMATION_TABLE_BRIEF_MSG = {
- 'AUDIO' : 'tag_audio',
- 'BUTTON' : 'role_button',
- 'SELECT' : 'tag_select',
- 'TABLE' : 'tag_table',
- 'TEXTAREA' : 'tag_textarea',
- 'VIDEO' : 'tag_video'
-};
-
-/**
- * These tags are treated as text formatters.
- * @type {Array<string>}
- */
-cvox.DomUtil.FORMATTING_TAGS =
- ['B', 'BIG', 'CITE', 'CODE', 'DFN', 'EM', 'I', 'KBD', 'SAMP', 'SMALL',
- 'SPAN', 'STRIKE', 'STRONG', 'SUB', 'SUP', 'U', 'VAR'];
-
-/**
- * Determine if the given node is visible on the page. This does not check if
- * it is inside the document view-port as some sites try to communicate with
- * screen readers with such elements.
- * @param {Node} node The node to determine as visible or not.
- * @param {{checkAncestors: (boolean|undefined),
- checkDescendants: (boolean|undefined)}=} opt_options
- * In certain cases, we already have information
- * on the context of the node. To improve performance and avoid redundant
- * operations, you may wish to turn certain visibility checks off by
- * passing in an options object. The following properties are configurable:
- * checkAncestors: {boolean=} True if we should check the ancestor chain
- * for forced invisibility traits of descendants. True by default.
- * checkDescendants: {boolean=} True if we should consider descendants of
- * the given node for visible elements. True by default.
- * @return {boolean} True if the node is visible.
- */
-cvox.DomUtil.isVisible = function(node, opt_options) {
- var checkAncestors = true;
- var checkDescendants = true;
- if (opt_options) {
- if (opt_options.checkAncestors !== undefined) {
- checkAncestors = opt_options.checkAncestors;
- }
- if (opt_options.checkDescendants !== undefined) {
- checkDescendants = opt_options.checkDescendants;
- }
- }
-
- // Generate a unique function name based on the arguments, and
- // memoize the result of the internal visibility computation so that
- // within the same call stack, we don't need to recompute the visibility
- // of the same node.
- var fname = 'isVisible-' + checkAncestors + '-' + checkDescendants;
- return /** @type {boolean} */ (cvox.Memoize.memoize(
- cvox.DomUtil.computeIsVisible_.bind(
- this, node, checkAncestors, checkDescendants), fname, node));
-};
-
-/**
- * Implementation of |cvox.DomUtil.isVisible|.
- * @param {Node} node The node to determine as visible or not.
- * @param {boolean} checkAncestors True if we should check the ancestor chain
- * for forced invisibility traits of descendants.
- * @param {boolean} checkDescendants True if we should consider descendants of
- * the given node for visible elements.
- * @return {boolean} True if the node is visible.
- * @private
- */
-cvox.DomUtil.computeIsVisible_ = function(
- node, checkAncestors, checkDescendants) {
- // If the node is an iframe that we can never inject into, consider it hidden.
- if (node.tagName == 'IFRAME' && !node.src) {
- return false;
- }
-
- // If the node is being forced visible by ARIA, ARIA wins.
- if (cvox.AriaUtil.isForcedVisibleRecursive(node)) {
- return true;
- }
-
- // Confirm that no subtree containing node is invisible.
- if (checkAncestors &&
- cvox.DomUtil.hasInvisibleAncestor_(node)) {
- return false;
- }
-
- // If the node's subtree has a visible node, we declare it as visible.
- if (cvox.DomUtil.hasVisibleNodeSubtree_(node, checkDescendants)) {
- return true;
- }
-
- return false;
-};
-
-
-/**
- * Checks the ancestor chain for the given node for invisibility. If an
- * ancestor is invisible and this cannot be overriden by a descendant,
- * we return true. If the element is not a descendant of the document
- * element it will return true (invisible).
- * @param {Node} node The node to check the ancestor chain for.
- * @return {boolean} True if a descendant is invisible.
- * @private
- */
-cvox.DomUtil.hasInvisibleAncestor_ = function(node) {
- var ancestor = node;
- while (ancestor = ancestor.parentElement) {
- var style = document.defaultView.getComputedStyle(ancestor, null);
- if (cvox.DomUtil.isInvisibleStyle(style, true)) {
- return true;
- }
- // Once we reach the document element and we haven't found anything
- // invisible yet, we're done. If we exit the while loop and never found
- // the document element, the element wasn't part of the DOM and thus it's
- // invisible.
- if (ancestor == document.documentElement) {
- return false;
- }
- }
- return true;
-};
-
-
-/**
- * Checks for a visible node in the subtree defined by root.
- * @param {Node} root The root of the subtree to check.
- * @param {boolean} recursive Whether or not to check beyond the root of the
- * subtree for visible nodes. This option exists for performance tuning.
- * Sometimes we already have information about the descendants, and we do
- * not need to check them again.
- * @return {boolean} True if the subtree contains a visible node.
- * @private
- */
-cvox.DomUtil.hasVisibleNodeSubtree_ = function(root, recursive) {
- if (!(root instanceof Element)) {
- if (!root.parentElement) {
- return false;
- }
- var parentStyle = document.defaultView
- .getComputedStyle(root.parentElement, null);
- var isVisibleParent = !cvox.DomUtil.isInvisibleStyle(parentStyle);
- return isVisibleParent;
- }
-
- var rootStyle = document.defaultView.getComputedStyle(root, null);
- var isRootVisible = !cvox.DomUtil.isInvisibleStyle(rootStyle);
- if (isRootVisible) {
- return true;
- }
- var isSubtreeInvisible = cvox.DomUtil.isInvisibleStyle(rootStyle, true);
- if (!recursive || isSubtreeInvisible) {
- return false;
- }
-
- // Carry on with a recursive check of the descendants.
- var children = root.childNodes;
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- if (cvox.DomUtil.hasVisibleNodeSubtree_(child, recursive)) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Determines whether or a node is not visible according to any CSS criteria
- * that can hide it.
- * @param {CSSStyleDeclaration} style The style of the node to determine as
- * invsible or not.
- * @param {boolean=} opt_strict If set to true, we do not check the visibility
- * style attribute. False by default.
- * CAUTION: Checking the visibility style attribute can result in returning
- * true (invisible) even when an element has have visible descendants. This
- * is because an element with visibility:hidden can have descendants that
- * are visible.
- * @return {boolean} True if the node is invisible.
- */
-cvox.DomUtil.isInvisibleStyle = function(style, opt_strict) {
- if (!style) {
- return false;
- }
- if (style.display == 'none') {
- return true;
- }
- // Opacity values range from 0.0 (transparent) to 1.0 (fully opaque).
- if (parseFloat(style.opacity) == 0) {
- return true;
- }
- // Visibility style tests for non-strict checking.
- if (!opt_strict &&
- (style.visibility == 'hidden' || style.visibility == 'collapse')) {
- return true;
- }
- return false;
-};
-
-
-/**
- * Determines whether a control should be announced as disabled.
- *
- * @param {Node} node The node to be examined.
- * @return {boolean} Whether or not the node is disabled.
- */
-cvox.DomUtil.isDisabled = function(node) {
- if (node.disabled) {
- return true;
- }
- var ancestor = node;
- while (ancestor = ancestor.parentElement) {
- if (ancestor.tagName == 'FIELDSET' && ancestor.disabled) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Determines whether a node is an HTML5 semantic element
- *
- * @param {Node} node The node to be checked.
- * @return {boolean} True if the node is an HTML5 semantic element.
- */
-cvox.DomUtil.isSemanticElt = function(node) {
- if (node.tagName) {
- var tag = node.tagName;
- if ((tag == 'SECTION') || (tag == 'NAV') || (tag == 'ARTICLE') ||
- (tag == 'ASIDE') || (tag == 'HGROUP') || (tag == 'HEADER') ||
- (tag == 'FOOTER') || (tag == 'TIME') || (tag == 'MARK')) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Determines whether or not a node is a leaf node.
- * TODO (adu): This function is doing a lot more than just checking for the
- * presence of descendants. We should be more precise in the documentation
- * about what we mean by leaf node.
- *
- * @param {Node} node The node to be checked.
- * @param {boolean=} opt_allowHidden Allows hidden nodes during descent.
- * @return {boolean} True if the node is a leaf node.
- */
-cvox.DomUtil.isLeafNode = function(node, opt_allowHidden) {
- // If it's not an Element, then it's a leaf if it has no first child.
- if (!(node instanceof Element)) {
- return (node.firstChild == null);
- }
-
- // Now we know for sure it's an element.
- var element = /** @type {Element} */(node);
- if (!opt_allowHidden &&
- !cvox.DomUtil.isVisible(element, {checkAncestors: false})) {
- return true;
- }
- if (!opt_allowHidden && cvox.AriaUtil.isHidden(element)) {
- return true;
- }
- if (cvox.AriaUtil.isLeafElement(element)) {
- return true;
- }
- switch (element.tagName) {
- case 'OBJECT':
- case 'EMBED':
- case 'VIDEO':
- case 'AUDIO':
- case 'IFRAME':
- case 'FRAME':
- return true;
- }
-
- if (!!cvox.DomPredicates.linkPredicate([element])) {
- return !cvox.DomUtil.findNode(element, function(node) {
- return !!cvox.DomPredicates.headingPredicate([node]);
- });
- }
- if (cvox.DomUtil.isLeafLevelControl(element)) {
- return true;
- }
- if (!element.firstChild) {
- return true;
- }
- if (cvox.DomUtil.isMath(element)) {
- return true;
- }
- if (cvox.DomPredicates.headingPredicate([element])) {
- return !cvox.DomUtil.findNode(element, function(n) {
- return !!cvox.DomPredicates.controlPredicate([n]);
- });
- }
- return false;
-};
-
-
-/**
- * Determines whether or not a node is or is the descendant of a node
- * with a particular tag or class name.
- *
- * @param {Node} node The node to be checked.
- * @param {?string} tagName The tag to check for, or null if the tag
- * doesn't matter.
- * @param {?string=} className The class to check for, or null if the class
- * doesn't matter.
- * @return {boolean} True if the node or one of its ancestor has the specified
- * tag.
- */
-cvox.DomUtil.isDescendantOf = function(node, tagName, className) {
- while (node) {
-
- if (tagName && className &&
- (node.tagName && (node.tagName == tagName)) &&
- (node.className && (node.className == className))) {
- return true;
- } else if (tagName && !className &&
- (node.tagName && (node.tagName == tagName))) {
- return true;
- } else if (!tagName && className &&
- (node.className && (node.className == className))) {
- return true;
- }
- node = node.parentNode;
- }
- return false;
-};
-
-
-/**
- * Determines whether or not a node is or is the descendant of another node.
- *
- * @param {Object} node The node to be checked.
- * @param {Object} ancestor The node to see if it's a descendant of.
- * @return {boolean} True if the node is ancestor or is a descendant of it.
- */
-cvox.DomUtil.isDescendantOfNode = function(node, ancestor) {
- while (node && ancestor) {
- if (node.isSameNode(ancestor)) {
- return true;
- }
- node = node.parentNode;
- }
- return false;
-};
-
-
-/**
- * Remove all whitespace from the beginning and end, and collapse all
- * inner strings of whitespace to a single space.
- * @param {string} str The input string.
- * @return {string} The string with whitespace collapsed.
- */
-cvox.DomUtil.collapseWhitespace = function(str) {
- return str.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '');
-};
-
-/**
- * Gets the base label of a node. I don't know exactly what this is.
- *
- * @param {Node} node The node to get the label from.
- * @param {boolean=} recursive Whether or not the element's subtree
- * should be used; true by default.
- * @param {boolean=} includeControls Whether or not controls in the subtree
- * should be included; true by default.
- * @return {string} The base label of the node.
- * @private
- */
-cvox.DomUtil.getBaseLabel_ = function(node, recursive, includeControls) {
- var label = '';
- if (node.hasAttribute) {
- if (node.hasAttribute('aria-labelledby')) {
- var labelNodeIds = node.getAttribute('aria-labelledby').split(' ');
- for (var labelNodeId, i = 0; labelNodeId = labelNodeIds[i]; i++) {
- var labelNode = document.getElementById(labelNodeId);
- if (labelNode) {
- label += ' ' + cvox.DomUtil.getName(
- labelNode, true, includeControls, true);
- }
- }
- } else if (node.hasAttribute('aria-label')) {
- label = node.getAttribute('aria-label');
- } else if (node.constructor == HTMLImageElement) {
- label = cvox.DomUtil.getImageTitle(node);
- } else if (node.tagName == 'FIELDSET') {
- // Other labels will trump fieldset legend with this implementation.
- // Depending on how this works out on the web, we may later switch this
- // to appending the fieldset legend to any existing label.
- var legends = node.getElementsByTagName('LEGEND');
- label = '';
- for (var legend, i = 0; legend = legends[i]; i++) {
- label += ' ' + cvox.DomUtil.getName(legend, true, includeControls);
- }
- }
-
- if (label.length == 0 && node && node.id) {
- var labelFor = document.querySelector('label[for="' + node.id + '"]');
- if (labelFor) {
- label = cvox.DomUtil.getName(labelFor, recursive, includeControls);
- }
- }
- }
- return cvox.DomUtil.collapseWhitespace(label);
-};
-
-/**
- * Gets the nearest label in the ancestor chain, if one exists.
- * @param {Node} node The node to start from.
- * @return {string} The label.
- * @private
- */
-cvox.DomUtil.getNearestAncestorLabel_ = function(node) {
- var label = '';
- var enclosingLabel = node;
- while (enclosingLabel && enclosingLabel.tagName != 'LABEL') {
- enclosingLabel = enclosingLabel.parentElement;
- }
- if (enclosingLabel && !enclosingLabel.hasAttribute('for')) {
- // Get all text from the label but don't include any controls.
- label = cvox.DomUtil.getName(enclosingLabel, true, false);
- }
- return label;
-};
-
-
-/**
- * Gets the name for an input element.
- * @param {Node} node The node.
- * @return {string} The name.
- * @private
- */
-cvox.DomUtil.getInputName_ = function(node) {
- var label = '';
- if (node.type == 'image') {
- label = cvox.DomUtil.getImageTitle(node);
- } else if (node.type == 'submit') {
- if (node.hasAttribute('value')) {
- label = node.getAttribute('value');
- } else {
- label = 'Submit';
- }
- } else if (node.type == 'reset') {
- if (node.hasAttribute('value')) {
- label = node.getAttribute('value');
- } else {
- label = 'Reset';
- }
- } else if (node.type == 'button') {
- if (node.hasAttribute('value')) {
- label = node.getAttribute('value');
- }
- }
- return label;
-};
-
-/**
- * Wraps getName_ with marking and unmarking nodes so that infinite loops
- * don't occur. This is the ugly way to solve this; getName should not ever
- * do a recursive call somewhere above it in the tree.
- * @param {Node} node See getName_.
- * @param {boolean=} recursive See getName_.
- * @param {boolean=} includeControls See getName_.
- * @param {boolean=} opt_allowHidden Allows hidden nodes in name computation.
- * @return {string} See getName_.
- */
-cvox.DomUtil.getName = function(
- node, recursive, includeControls, opt_allowHidden) {
- if (!node || node.cvoxGetNameMarked == true) {
- return '';
- }
- node.cvoxGetNameMarked = true;
- var ret =
- cvox.DomUtil.getName_(node, recursive, includeControls, opt_allowHidden);
- node.cvoxGetNameMarked = false;
- var prefix = cvox.DomUtil.getPrefixText(node);
- return prefix + ret;
-};
-
-// TODO(dtseng): Seems like this list should be longer...
-/**
- * Determines if a node has a name obtained from concatinating the names of its
- * children.
- * @param {!Node} node The node under consideration.
- * @param {boolean=} opt_allowHidden Allows hidden nodes in name computation.
- * @return {boolean} True if node has name based on children.
- * @private
- */
-cvox.DomUtil.hasChildrenBasedName_ = function(node, opt_allowHidden) {
- if (!!cvox.DomPredicates.linkPredicate([node]) ||
- !!cvox.DomPredicates.headingPredicate([node]) ||
- node.tagName == 'BUTTON' ||
- cvox.AriaUtil.isControlWidget(node) ||
- !cvox.DomUtil.isLeafNode(node, opt_allowHidden)) {
- return true;
- } else {
- return false;
- }
-};
-
-/**
- * Get the name of a node: this includes all static text content and any
- * HTML-author-specified label, title, alt text, aria-label, etc. - but
- * does not include:
- * - the user-generated control value (use getValue)
- * - the current state (use getState)
- * - the role (use getRole)
- *
- * Order of precedence:
- * Text content if it's a text node.
- * aria-labelledby
- * aria-label
- * alt (for an image)
- * title
- * label (for a control)
- * placeholder (for an input element)
- * recursive calls to getName on all children
- *
- * @param {Node} node The node to get the name from.
- * @param {boolean=} recursive Whether or not the element's subtree should
- * be used; true by default.
- * @param {boolean=} includeControls Whether or not controls in the subtree
- * should be included; true by default.
- * @param {boolean=} opt_allowHidden Allows hidden nodes in name computation.
- * @return {string} The name of the node.
- * @private
- */
-cvox.DomUtil.getName_ = function(
- node, recursive, includeControls, opt_allowHidden) {
- if (typeof(recursive) === 'undefined') {
- recursive = true;
- }
- if (typeof(includeControls) === 'undefined') {
- includeControls = true;
- }
-
- if (node.constructor == Text) {
- return node.data;
- }
-
- var label = cvox.DomUtil.getBaseLabel_(node, recursive, includeControls);
-
- if (label.length == 0 && cvox.DomUtil.isControl(node)) {
- label = cvox.DomUtil.getNearestAncestorLabel_(node);
- }
-
- if (label.length == 0 && node.constructor == HTMLInputElement) {
- label = cvox.DomUtil.getInputName_(node);
- }
-
- if (cvox.DomUtil.isInputTypeText(node) && node.hasAttribute('placeholder')) {
- var placeholder = node.getAttribute('placeholder');
- if (label.length > 0) {
- if (cvox.DomUtil.getValue(node).length > 0) {
- return label;
- } else {
- return label + ' with hint ' + placeholder;
- }
- } else {
- return placeholder;
- }
- }
-
- if (label.length > 0) {
- return label;
- }
-
- // Fall back to naming via title only if there is no text content.
- if (cvox.DomUtil.collapseWhitespace(node.textContent).length == 0 &&
- node.hasAttribute &&
- node.hasAttribute('title')) {
- return node.getAttribute('title');
- }
-
- if (!recursive) {
- return '';
- }
-
- if (cvox.AriaUtil.isCompositeControl(node)) {
- return '';
- }
- if (cvox.DomUtil.hasChildrenBasedName_(node, opt_allowHidden)) {
- return cvox.DomUtil.getNameFromChildren(
- node, includeControls, opt_allowHidden);
- }
- return '';
-};
-
-
-/**
- * Get the name from the children of a node, not including the node itself.
- *
- * @param {Node} node The node to get the name from.
- * @param {boolean=} includeControls Whether or not controls in the subtree
- * should be included; true by default.
- * @param {boolean=} opt_allowHidden Allow hidden nodes in name computation.
- * @return {string} The concatenated text of all child nodes.
- */
-cvox.DomUtil.getNameFromChildren = function(
- node, includeControls, opt_allowHidden) {
- if (includeControls == undefined) {
- includeControls = true;
- }
- var name = '';
- var delimiter = '';
- for (var i = 0; i < node.childNodes.length; i++) {
- var child = node.childNodes[i];
- var prevChild = node.childNodes[i - 1] || child;
- if (!includeControls && cvox.DomUtil.isControl(child)) {
- continue;
- }
- var isVisible = cvox.DomUtil.isVisible(child, {checkAncestors: false});
- if (opt_allowHidden || (isVisible && !cvox.AriaUtil.isHidden(child))) {
- delimiter = (prevChild.tagName == 'SPAN' ||
- child.tagName == 'SPAN' ||
- child.parentNode.tagName == 'SPAN') ?
- '' : ' ';
- name += delimiter + cvox.DomUtil.getName(child, true, includeControls);
- }
- }
-
- return name;
-};
-
-/**
- * Get any prefix text for the given node.
- * This includes list style text for the leftmost leaf node under a listitem.
- * @param {Node} node Compute prefix for this node.
- * @param {number=} opt_index Starting offset into the given node's text.
- * @return {string} Prefix text, if any.
- */
-cvox.DomUtil.getPrefixText = function(node, opt_index) {
- opt_index = opt_index || 0;
-
- // Generate list style text.
- var ancestors = cvox.DomUtil.getAncestors(node);
- var prefix = '';
- var firstListitem = cvox.DomPredicates.listItemPredicate(ancestors);
-
- var leftmost = firstListitem;
- while (leftmost && leftmost.firstChild) {
- leftmost = leftmost.firstChild;
- }
-
- // Do nothing if we're not at the leftmost leaf.
- if (firstListitem &&
- firstListitem.parentNode &&
- opt_index == 0 &&
- firstListitem.parentNode.tagName == 'OL' &&
- node == leftmost &&
- document.defaultView.getComputedStyle(firstListitem.parentNode)
- .listStyleType != 'none') {
- var items = cvox.DomUtil.toArray(firstListitem.parentNode.children).filter(
- function(li) { return li.tagName == 'LI'; });
- var position = items.indexOf(firstListitem) + 1;
- // TODO(dtseng): Support all list style types.
- if (document.defaultView.getComputedStyle(
- firstListitem.parentNode).listStyleType.indexOf('latin') != -1) {
- position--;
- prefix = String.fromCharCode('A'.charCodeAt(0) + position % 26);
- } else {
- prefix = position;
- }
- prefix += '. ';
- }
- return prefix;
-};
-
-
-/**
- * Use heuristics to guess at the label of a control, to be used if one
- * is not explicitly set in the DOM. This is useful when a control
- * field gets focus, but probably not useful when browsing the page
- * element at a time.
- * @param {Node} node The node to get the label from.
- * @return {string} The name of the control, using heuristics.
- */
-cvox.DomUtil.getControlLabelHeuristics = function(node) {
- // If the node explicitly has aria-label or title set to '',
- // treat it the same way as alt='' and do not guess - just assume
- // the web developer knew what they were doing and wanted
- // no title/label for that control.
- if (node.hasAttribute &&
- ((node.hasAttribute('aria-label') &&
- (node.getAttribute('aria-label') == '')) ||
- (node.hasAttribute('aria-title') &&
- (node.getAttribute('aria-title') == '')))) {
- return '';
- }
-
- // TODO (clchen, rshearer): Implement heuristics for getting the label
- // information from the table headers once the code for getting table
- // headers quickly is implemented.
-
- // If no description has been found yet and heuristics are enabled,
- // then try getting the content from the closest node.
- var prevNode = cvox.DomUtil.previousLeafNode(node);
- var prevTraversalCount = 0;
- while (prevNode && (!cvox.DomUtil.hasContent(prevNode) ||
- cvox.DomUtil.isControl(prevNode))) {
- prevNode = cvox.DomUtil.previousLeafNode(prevNode);
- prevTraversalCount++;
- }
- var nextNode = cvox.DomUtil.directedNextLeafNode(node);
- var nextTraversalCount = 0;
- while (nextNode && (!cvox.DomUtil.hasContent(nextNode) ||
- cvox.DomUtil.isControl(nextNode))) {
- nextNode = cvox.DomUtil.directedNextLeafNode(nextNode);
- nextTraversalCount++;
- }
- var guessedLabelNode;
- if (prevNode && nextNode) {
- var parentNode = node;
- // Count the number of parent nodes until there is a shared parent; the
- // label is most likely in the same branch of the DOM as the control.
- // TODO (chaitanyag): Try to generalize this algorithm and move it to
- // its own function in DOM Utils.
- var prevCount = 0;
- while (parentNode) {
- if (cvox.DomUtil.isDescendantOfNode(prevNode, parentNode)) {
- break;
- }
- parentNode = parentNode.parentNode;
- prevCount++;
- }
- parentNode = node;
- var nextCount = 0;
- while (parentNode) {
- if (cvox.DomUtil.isDescendantOfNode(nextNode, parentNode)) {
- break;
- }
- parentNode = parentNode.parentNode;
- nextCount++;
- }
- guessedLabelNode = nextCount < prevCount ? nextNode : prevNode;
- } else {
- guessedLabelNode = prevNode || nextNode;
- }
- if (guessedLabelNode) {
- return cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(guessedLabelNode) + ' ' +
- cvox.DomUtil.getName(guessedLabelNode));
- }
-
- return '';
-};
-
-
-/**
- * Get the text value of a node: the selected value of a select control or the
- * current text of a text control. Does not return the state of a checkbox
- * or radio button.
- *
- * Not recursive.
- *
- * @param {Node} node The node to get the value from.
- * @return {string} The value of the node.
- */
-cvox.DomUtil.getValue = function(node) {
- var activeDescendant = cvox.AriaUtil.getActiveDescendant(node);
- if (activeDescendant) {
- return cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(activeDescendant) + ' ' +
- cvox.DomUtil.getName(activeDescendant));
- }
-
- if (node.constructor == HTMLSelectElement) {
- node = /** @type {HTMLSelectElement} */(node);
- var value = '';
- var start = node.selectedOptions ? node.selectedOptions[0] : null;
- var end = node.selectedOptions ?
- node.selectedOptions[node.selectedOptions.length - 1] : null;
- // TODO(dtseng): Keeping this stateless means we describe the start and end
- // of the selection only since we don't know which was added or
- // removed. Once we keep the previous selection, we can read the diff.
- if (start && end && start != end) {
- value = Msgs.getMsg(
- 'selected_options_value', [start.text, end.text]);
- } else if (start) {
- value = start.text + '';
- }
- return value;
- }
-
- if (node.constructor == HTMLTextAreaElement) {
- return node.value;
- }
-
- if (node.constructor == HTMLInputElement) {
- switch (node.type) {
- // Returning '' for inputs that are covered by getName.
- case 'hidden':
- case 'image':
- case 'submit':
- case 'reset':
- case 'button':
- case 'checkbox':
- case 'radio':
- return '';
- case 'password':
- return node.value.replace(/./g, 'dot ');
- default:
- return node.value;
- }
- }
-
- if (node.isContentEditable) {
- return cvox.DomUtil.getNameFromChildren(node, true);
- }
-
- return '';
-};
-
-
-/**
- * Given an image node, return its title as a string. The preferred title
- * is always the alt text, and if that's not available, then the title
- * attribute. If neither of those are available, it attempts to construct
- * a title from the filename, and if all else fails returns the word Image.
- * @param {Node} node The image node.
- * @return {string} The title of the image.
- */
-cvox.DomUtil.getImageTitle = function(node) {
- var text;
- if (node.hasAttribute('alt')) {
- text = node.alt;
- } else if (node.hasAttribute('title')) {
- text = node.title;
- } else {
- var url = node.src;
- if (url.substring(0, 4) != 'data') {
- var filename = url.substring(
- url.lastIndexOf('/') + 1, url.lastIndexOf('.'));
-
- // Hack to not speak the filename if it's ridiculously long.
- if (filename.length >= 1 && filename.length <= 16) {
- text = filename + ' Image';
- } else {
- text = 'Image';
- }
- } else {
- text = 'Image';
- }
- }
- return text;
-};
-
-
-/**
- * Search the whole page for any aria-labelledby attributes and collect
- * the complete set of ids they map to, so that we can skip elements that
- * just label other elements and not double-speak them. We cache this
- * result and then throw it away at the next event loop.
- * @return {Object<boolean>} Set of all ids that are mapped by aria-labelledby.
- */
-cvox.DomUtil.getLabelledByTargets = function() {
- if (cvox.labelledByTargets) {
- return cvox.labelledByTargets;
- }
-
- // Start by getting all elements with
- // aria-labelledby on the page since that's probably a short list,
- // then see if any of those ids overlap with an id in this element's
- // ancestor chain.
- var labelledByElements = document.querySelectorAll('[aria-labelledby]');
- var labelledByTargets = {};
- for (var i = 0; i < labelledByElements.length; ++i) {
- var element = labelledByElements[i];
- var attrValue = element.getAttribute('aria-labelledby');
- var ids = attrValue.split(/ +/);
- for (var j = 0; j < ids.length; j++) {
- labelledByTargets[ids[j]] = true;
- }
- }
- cvox.labelledByTargets = labelledByTargets;
-
- window.setTimeout(function() {
- cvox.labelledByTargets = null;
- }, 0);
-
- return labelledByTargets;
-};
-
-
-/**
- * Determines whether or not a node has content.
- *
- * @param {Node} node The node to be checked.
- * @return {boolean} True if the node has content.
- */
-cvox.DomUtil.hasContent = function(node) {
- // Memoize the result of the internal content computation so that
- // within the same call stack, we don't need to redo the computation
- // on the same node twice.
- return /** @type {boolean} */ (cvox.Memoize.memoize(
- cvox.DomUtil.computeHasContent_.bind(this), 'hasContent', node));
-};
-
-/**
- * Internal implementation of |cvox.DomUtil.hasContent|.
- *
- * @param {Node} node The node to be checked.
- * @return {boolean} True if the node has content.
- * @private
- */
-cvox.DomUtil.computeHasContent_ = function(node) {
- // nodeType:8 == COMMENT_NODE
- if (node.nodeType == 8) {
- return false;
- }
-
- // Exclude anything in the head
- if (cvox.DomUtil.isDescendantOf(node, 'HEAD')) {
- return false;
- }
-
- // Exclude script nodes
- if (cvox.DomUtil.isDescendantOf(node, 'SCRIPT')) {
- return false;
- }
-
- // Exclude noscript nodes
- if (cvox.DomUtil.isDescendantOf(node, 'NOSCRIPT')) {
- return false;
- }
-
- // Exclude noembed nodes since NOEMBED is deprecated. We treat
- // noembed as having not content rather than try to get its content since
- // Chrome will return raw HTML content rather than a valid DOM subtree.
- if (cvox.DomUtil.isDescendantOf(node, 'NOEMBED')) {
- return false;
- }
-
- // Exclude style nodes that have been dumped into the body.
- if (cvox.DomUtil.isDescendantOf(node, 'STYLE')) {
- return false;
- }
-
- // Check the style to exclude undisplayed/hidden nodes.
- if (!cvox.DomUtil.isVisible(node)) {
- return false;
- }
-
- // Ignore anything that is hidden by ARIA.
- if (cvox.AriaUtil.isHidden(node)) {
- return false;
- }
-
- // We need to speak controls, including those with no value entered. We
- // therefore treat visible controls as if they had content, and return true
- // below.
- if (cvox.DomUtil.isControl(node)) {
- return true;
- }
-
- // Videos are always considered to have content so that we can navigate to
- // and use the controls of the video widget.
- if (cvox.DomUtil.isDescendantOf(node, 'VIDEO')) {
- return true;
- }
- // Audio elements are always considered to have content so that we can
- // navigate to and use the controls of the audio widget.
- if (cvox.DomUtil.isDescendantOf(node, 'AUDIO')) {
- return true;
- }
-
- // We want to try to jump into an iframe iff it has a src attribute.
- // For right now, we will avoid iframes without any content in their src since
- // ChromeVox is not being injected in those cases and will cause the user to
- // get stuck.
- // TODO (clchen, dmazzoni): Manually inject ChromeVox for iframes without src.
- if ((node.tagName == 'IFRAME') && (node.src) &&
- (node.src.indexOf('javascript:') != 0)) {
- return true;
- }
-
- var controlQuery = 'button,input,select,textarea';
-
- // Skip any non-control content inside of a label if the label is
- // correctly associated with a control, the label text will get spoken
- // when the control is reached.
- var enclosingLabel = node.parentElement;
- while (enclosingLabel && enclosingLabel.tagName != 'LABEL') {
- enclosingLabel = enclosingLabel.parentElement;
- }
- if (enclosingLabel) {
- var embeddedControl = enclosingLabel.querySelector(controlQuery);
- if (enclosingLabel.hasAttribute('for')) {
- var targetId = enclosingLabel.getAttribute('for');
- var targetNode = document.getElementById(targetId);
- if (targetNode &&
- cvox.DomUtil.isControl(targetNode) &&
- !embeddedControl) {
- return false;
- }
- } else if (embeddedControl) {
- return false;
- }
- }
-
- // Skip any non-control content inside of a legend if the legend is correctly
- // nested within a fieldset. The legend text will get spoken when the fieldset
- // is reached.
- var enclosingLegend = node.parentElement;
- while (enclosingLegend && enclosingLegend.tagName != 'LEGEND') {
- enclosingLegend = enclosingLegend.parentElement;
- }
- if (enclosingLegend) {
- var legendAncestor = enclosingLegend.parentElement;
- while (legendAncestor && legendAncestor.tagName != 'FIELDSET') {
- legendAncestor = legendAncestor.parentElement;
- }
- var embeddedControl =
- legendAncestor && legendAncestor.querySelector(controlQuery);
- if (legendAncestor && !embeddedControl) {
- return false;
- }
- }
-
- if (!!cvox.DomPredicates.linkPredicate([node])) {
- return true;
- }
-
- // At this point, any non-layout tables are considered to have content.
- // For layout tables, it is safe to consider them as without content since the
- // sync operation would select a descendant of a layout table if possible. The
- // only instance where |hasContent| gets called on a layout table is if no
- // descendants have content (see |AbstractNodeWalker.next|).
- if (node.tagName == 'TABLE' && !cvox.DomUtil.isLayoutTable(node)) {
- return true;
- }
-
- // Math is always considered to have content.
- if (cvox.DomUtil.isMath(node)) {
- return true;
- }
-
- if (cvox.DomPredicates.headingPredicate([node])) {
- return true;
- }
-
- if (cvox.DomUtil.isFocusable(node)) {
- return true;
- }
-
- // Skip anything referenced by another element on the page
- // via aria-labelledby.
- var labelledByTargets = cvox.DomUtil.getLabelledByTargets();
- var enclosingNodeWithId = node;
- while (enclosingNodeWithId) {
- if (enclosingNodeWithId.id &&
- labelledByTargets[enclosingNodeWithId.id]) {
- // If we got here, some element on this page has an aria-labelledby
- // attribute listing this node as its id. As long as that "some" element
- // is not this element, we should return false, indicating this element
- // should be skipped.
- var attrValue = enclosingNodeWithId.getAttribute('aria-labelledby');
- if (attrValue) {
- var ids = attrValue.split(/ +/);
- if (ids.indexOf(enclosingNodeWithId.id) == -1) {
- return false;
- }
- } else {
- return false;
- }
- }
- enclosingNodeWithId = enclosingNodeWithId.parentElement;
- }
-
- var text = cvox.DomUtil.getValue(node) + ' ' + cvox.DomUtil.getName(node);
- var state = cvox.DomUtil.getState(node, true);
- if (text.match(/^\s+$/) && state === '') {
- // Text only contains whitespace
- return false;
- }
-
- return true;
-};
-
-
-/**
- * Returns a list of all the ancestors of a given node. The last element
- * is the current node.
- *
- * @param {Node} targetNode The node to get ancestors for.
- * @return {Array<Node>} An array of ancestors for the targetNode.
- */
-cvox.DomUtil.getAncestors = function(targetNode) {
- var ancestors = new Array();
- while (targetNode) {
- ancestors.push(targetNode);
- targetNode = targetNode.parentNode;
- }
- ancestors.reverse();
- while (ancestors.length && !ancestors[0].tagName && !ancestors[0].nodeValue) {
- ancestors.shift();
- }
- return ancestors;
-};
-
-
-/**
- * Compares Ancestors of A with Ancestors of B and returns
- * the index value in B at which B diverges from A.
- * If there is no divergence, the result will be -1.
- * Note that if B is the same as A except B has more nodes
- * even after A has ended, that is considered a divergence.
- * The first node that B has which A does not have will
- * be treated as the divergence point.
- *
- * @param {Object} ancestorsA The array of ancestors for Node A.
- * @param {Object} ancestorsB The array of ancestors for Node B.
- * @return {number} The index of the divergence point (the first node that B has
- * which A does not have in B's list of ancestors).
- */
-cvox.DomUtil.compareAncestors = function(ancestorsA, ancestorsB) {
- var i = 0;
- while (ancestorsA[i] && ancestorsB[i] && (ancestorsA[i] == ancestorsB[i])) {
- i++;
- }
- if (!ancestorsA[i] && !ancestorsB[i]) {
- i = -1;
- }
- return i;
-};
-
-
-/**
- * Returns an array of ancestors that are unique for the currentNode when
- * compared to the previousNode. Having such an array is useful in generating
- * the node information (identifying when interesting node boundaries have been
- * crossed, etc.).
- *
- * @param {Node} previousNode The previous node.
- * @param {Node} currentNode The current node.
- * @param {boolean=} opt_fallback True returns node's ancestors in the case
- * where node's ancestors is a subset of previousNode's ancestors.
- * @return {Array<Node>} An array of unique ancestors for the current node
- * (inclusive).
- */
-cvox.DomUtil.getUniqueAncestors = function(
- previousNode, currentNode, opt_fallback) {
- var prevAncestors = cvox.DomUtil.getAncestors(previousNode);
- var currentAncestors = cvox.DomUtil.getAncestors(currentNode);
- var divergence = cvox.DomUtil.compareAncestors(prevAncestors,
- currentAncestors);
- var diff = currentAncestors.slice(divergence);
- return (diff.length == 0 && opt_fallback) ? currentAncestors : diff;
-};
-
-
-/**
- * Returns a role message identifier for a node.
- * For a localized string, see cvox.DomUtil.getRole.
- * @param {Node} targetNode The node to get the role name for.
- * @param {number} verbosity The verbosity setting to use.
- * @return {string} The role message identifier for the targetNode.
- */
-cvox.DomUtil.getRoleMsg = function(targetNode, verbosity) {
- var info;
- info = cvox.AriaUtil.getRoleNameMsg(targetNode);
- if (!info) {
- if (targetNode.tagName == 'INPUT') {
- info = cvox.DomUtil.INPUT_TYPE_TO_INFORMATION_TABLE_MSG[targetNode.type];
- } else if (targetNode.tagName == 'A' &&
- cvox.DomUtil.isInternalLink(targetNode)) {
- info = 'internal_link';
- } else if (targetNode.tagName == 'A' &&
- targetNode.getAttribute('href') &&
- cvox.ChromeVox.visitedUrls[targetNode.href]) {
- info = 'visited_link';
- } else if (targetNode.tagName == 'A' &&
- targetNode.getAttribute('name')) {
- info = ''; // Don't want to add any role to anchors.
- } else if (targetNode.isContentEditable) {
- info = 'input_type_text';
- } else if (cvox.DomUtil.isMath(targetNode)) {
- info = 'math_expr';
- } else if (targetNode.tagName == 'TABLE' &&
- cvox.DomUtil.isLayoutTable(targetNode)) {
- info = '';
- } else {
- if (verbosity == cvox.VERBOSITY_BRIEF) {
- info =
- cvox.DomUtil.TAG_TO_INFORMATION_TABLE_BRIEF_MSG[targetNode.tagName];
- } else {
- info = cvox.DomUtil.TAG_TO_INFORMATION_TABLE_VERBOSE_MSG[
- targetNode.tagName];
-
- if (cvox.DomUtil.hasLongDesc(targetNode)) {
- info = 'image_with_long_desc';
- }
-
- if (!info && targetNode.onclick) {
- info = 'clickable';
- }
- }
- }
- }
-
- return info;
-};
-
-
-/**
- * Returns a string to be presented to the user that identifies what the
- * targetNode's role is.
- * ARIA roles are given priority; if there is no ARIA role set, the role
- * will be determined by the HTML tag for the node.
- *
- * @param {Node} targetNode The node to get the role name for.
- * @param {number} verbosity The verbosity setting to use.
- * @return {string} The role name for the targetNode.
- */
-cvox.DomUtil.getRole = function(targetNode, verbosity) {
- var roleMsg = cvox.DomUtil.getRoleMsg(targetNode, verbosity) || '';
- var role = roleMsg && roleMsg != ' ' ?
- Msgs.getMsg(roleMsg) : '';
- return role ? role : roleMsg;
-};
-
-
-/**
- * Count the number of items in a list node.
- *
- * @param {Node} targetNode The list node.
- * @return {number} The number of items in the list.
- */
-cvox.DomUtil.getListLength = function(targetNode) {
- var count = 0;
- for (var node = targetNode.firstChild;
- node;
- node = node.nextSibling) {
- if (cvox.DomUtil.isVisible(node) &&
- (node.tagName == 'LI' ||
- (node.getAttribute && node.getAttribute('role') == 'listitem'))) {
- if (node.hasAttribute('aria-setsize')) {
- var ariaLength = parseInt(node.getAttribute('aria-setsize'), 10);
- if (!isNaN(ariaLength)) {
- return ariaLength;
- }
- }
- count++;
- }
- }
- return count;
-};
-
-
-/**
- * Returns a NodeState that gives information about the state of the targetNode.
- *
- * @param {Node} targetNode The node to get the state information for.
- * @param {boolean} primary Whether this is the primary node we're
- * interested in, where we might want extra information - as
- * opposed to an ancestor, where we might be more brief.
- * @return {cvox.NodeState} The status information about the node.
- */
-cvox.DomUtil.getStateMsgs = function(targetNode, primary) {
- var activeDescendant = cvox.AriaUtil.getActiveDescendant(targetNode);
- if (activeDescendant) {
- return cvox.DomUtil.getStateMsgs(activeDescendant, primary);
- }
- var info = [];
- var role = targetNode.getAttribute ? targetNode.getAttribute('role') : '';
- info = cvox.AriaUtil.getStateMsgs(targetNode, primary);
- if (!info) {
- info = [];
- }
-
- if (targetNode.tagName == 'INPUT') {
- if (!targetNode.hasAttribute('aria-checked')) {
- var INPUT_MSGS = {
- 'checkbox-true': 'checkbox_checked_state',
- 'checkbox-false': 'checkbox_unchecked_state',
- 'radio-true': 'radio_selected_state',
- 'radio-false': 'radio_unselected_state' };
- var msgId = INPUT_MSGS[targetNode.type + '-' + !!targetNode.checked];
- if (msgId) {
- info.push([msgId]);
- }
- }
- } else if (targetNode.tagName == 'SELECT') {
- if (targetNode.selectedOptions && targetNode.selectedOptions.length <= 1) {
- info.push(['list_position',
- Msgs.getNumber(targetNode.selectedIndex + 1),
- Msgs.getNumber(targetNode.options.length)]);
- } else {
- info.push(['selected_options_state',
- Msgs.getNumber(targetNode.selectedOptions.length)]);
- }
- } else if (targetNode.tagName == 'UL' ||
- targetNode.tagName == 'OL' ||
- role == 'list') {
- info.push(['list_with_items_not_pluralized',
- Msgs.getNumber(
- cvox.DomUtil.getListLength(targetNode))]);
- }
-
- if (cvox.DomUtil.isDisabled(targetNode)) {
- info.push(['aria_disabled_true']);
- }
-
- if (targetNode.accessKey) {
- info.push(['access_key', targetNode.accessKey]);
- }
-
- return info;
-};
-
-
-/**
- * Returns a string that gives information about the state of the targetNode.
- *
- * @param {Node} targetNode The node to get the state information for.
- * @param {boolean} primary Whether this is the primary node we're
- * interested in, where we might want extra information - as
- * opposed to an ancestor, where we might be more brief.
- * @return {string} The status information about the node.
- */
-cvox.DomUtil.getState = function(targetNode, primary) {
- return cvox.NodeStateUtil.expand(
- cvox.DomUtil.getStateMsgs(targetNode, primary));
-};
-
-
-/**
- * Return whether a node is focusable. This includes nodes whose tabindex
- * attribute is set to "-1" explicitly - these nodes are not in the tab
- * order, but they should still be focused if the user navigates to them
- * using linear or smart DOM navigation.
- *
- * Note that when the tabIndex property of an Element is -1, that doesn't
- * tell us whether the tabIndex attribute is missing or set to "-1" explicitly,
- * so we have to check the attribute.
- *
- * @param {Object} targetNode The node to check if it's focusable.
- * @return {boolean} True if the node is focusable.
- */
-cvox.DomUtil.isFocusable = function(targetNode) {
- if (!targetNode || typeof(targetNode.tabIndex) != 'number') {
- return false;
- }
-
- // Workaround for http://code.google.com/p/chromium/issues/detail?id=153904
- if ((targetNode.tagName == 'A') && !targetNode.hasAttribute('href') &&
- !targetNode.hasAttribute('tabindex')) {
- return false;
- }
-
- if (targetNode.tabIndex >= 0) {
- return true;
- }
-
- if (targetNode.hasAttribute &&
- targetNode.hasAttribute('tabindex') &&
- targetNode.getAttribute('tabindex') == '-1') {
- return true;
- }
-
- return false;
-};
-
-
-/**
- * Find a focusable descendant of a given node. This includes nodes whose
- * tabindex attribute is set to "-1" explicitly - these nodes are not in the
- * tab order, but they should still be focused if the user navigates to them
- * using linear or smart DOM navigation.
- *
- * @param {Node} targetNode The node whose descendants to check if focusable.
- * @return {Node} The focusable descendant node. Null if no descendant node
- * was found.
- */
-cvox.DomUtil.findFocusableDescendant = function(targetNode) {
- // Search down the descendants chain until a focusable node is found
- if (targetNode) {
- var focusableNode =
- cvox.DomUtil.findNode(targetNode, cvox.DomUtil.isFocusable);
- if (focusableNode) {
- return focusableNode;
- }
- }
- return null;
-};
-
-
-/**
- * Returns the number of focusable nodes in root's subtree. The count does not
- * include root.
- *
- * @param {Node} targetNode The node whose descendants to check are focusable.
- * @return {number} The number of focusable descendants.
- */
-cvox.DomUtil.countFocusableDescendants = function(targetNode) {
- return targetNode ?
- cvox.DomUtil.countNodes(targetNode, cvox.DomUtil.isFocusable) : 0;
-};
-
-
-/**
- * Checks if the targetNode is still attached to the document.
- * A node can become detached because of AJAX changes.
- *
- * @param {Object} targetNode The node to check.
- * @return {boolean} True if the targetNode is still attached.
- */
-cvox.DomUtil.isAttachedToDocument = function(targetNode) {
- while (targetNode) {
- if (targetNode.tagName && (targetNode.tagName == 'HTML')) {
- return true;
- }
- targetNode = targetNode.parentNode;
- }
- return false;
-};
-
-
-/**
- * Dispatches a left click event on the element that is the targetNode.
- * Clicks go in the sequence of mousedown, mouseup, and click.
- * @param {Node} targetNode The target node of this operation.
- * @param {boolean} shiftKey Specifies if shift is held down.
- * @param {boolean} callOnClickDirectly Specifies whether or not to directly
- * invoke the onclick method if there is one.
- * @param {boolean=} opt_double True to issue a double click.
- * @param {boolean=} opt_handleOwnEvents Whether to handle the generated
- * events through the normal event processing.
- */
-cvox.DomUtil.clickElem = function(
- targetNode, shiftKey, callOnClickDirectly, opt_double,
- opt_handleOwnEvents) {
- // If there is an activeDescendant of the targetNode, then that is where the
- // click should actually be targeted.
- var activeDescendant = cvox.AriaUtil.getActiveDescendant(targetNode);
- if (activeDescendant) {
- targetNode = activeDescendant;
- }
- if (callOnClickDirectly) {
- var onClickFunction = null;
- if (targetNode.onclick) {
- onClickFunction = targetNode.onclick;
- }
- if (!onClickFunction && (targetNode.nodeType != 1) &&
- targetNode.parentNode && targetNode.parentNode.onclick) {
- onClickFunction = targetNode.parentNode.onclick;
- }
- var keepGoing = true;
- if (onClickFunction) {
- try {
- keepGoing = onClickFunction();
- } catch (exception) {
- // Something went very wrong with the onclick method; we'll ignore it
- // and just dispatch a click event normally.
- }
- }
- if (!keepGoing) {
- // The onclick method ran successfully and returned false, meaning the
- // event should not bubble up, so we will return here.
- return;
- }
- }
-
- // Send a mousedown (or simply a double click if requested).
- var evt = document.createEvent('MouseEvents');
- var evtType = opt_double ? 'dblclick' : 'mousedown';
- evt.initMouseEvent(evtType, true, true, document.defaultView,
- 1, 0, 0, 0, 0, false, false, shiftKey, false, 0, null);
- // Unless asked not to, Mark any events we generate so we don't try to
- // process our own events.
- evt.fromCvox = !opt_handleOwnEvents;
- try {
- targetNode.dispatchEvent(evt);
- } catch (e) {}
- //Send a mouse up
- evt = document.createEvent('MouseEvents');
- evt.initMouseEvent('mouseup', true, true, document.defaultView,
- 1, 0, 0, 0, 0, false, false, shiftKey, false, 0, null);
- evt.fromCvox = !opt_handleOwnEvents;
- try {
- targetNode.dispatchEvent(evt);
- } catch (e) {}
- //Send a click
- evt = document.createEvent('MouseEvents');
- evt.initMouseEvent('click', true, true, document.defaultView,
- 1, 0, 0, 0, 0, false, false, shiftKey, false, 0, null);
- evt.fromCvox = !opt_handleOwnEvents;
- try {
- targetNode.dispatchEvent(evt);
- } catch (e) {}
-
- if (cvox.DomUtil.isInternalLink(targetNode)) {
- cvox.DomUtil.syncInternalLink(targetNode);
- }
-};
-
-
-/**
- * Syncs to an internal link.
- * @param {Node} node A link whose href's target we want to sync.
- */
-cvox.DomUtil.syncInternalLink = function(node) {
- var targetNode;
- var targetId = node.href.split('#')[1];
- targetNode = document.getElementById(targetId);
- if (!targetNode) {
- var nodes = document.getElementsByName(targetId);
- if (nodes.length > 0) {
- targetNode = nodes[0];
- }
- }
- if (targetNode) {
- // Insert a dummy node to adjust next Tab focus location.
- var parent = targetNode.parentNode;
- var dummyNode = document.createElement('div');
- dummyNode.setAttribute('tabindex', '-1');
- parent.insertBefore(dummyNode, targetNode);
- dummyNode.setAttribute('chromevoxignoreariahidden', 1);
- dummyNode.focus();
- cvox.ChromeVox.syncToNode(targetNode, false);
- }
-};
-
-
-/**
- * Given an HTMLInputElement, returns true if it's an editable text type.
- * This includes input type='text' and input type='password' and a few
- * others.
- *
- * @param {Node} node The node to check.
- * @return {boolean} True if the node is an INPUT with an editable text type.
- */
-cvox.DomUtil.isInputTypeText = function(node) {
- if (!node || node.constructor != HTMLInputElement) {
- return false;
- }
-
- switch (node.type) {
- case 'email':
- case 'number':
- case 'password':
- case 'search':
- case 'text':
- case 'tel':
- case 'url':
- case '':
- return true;
- default:
- return false;
- }
-};
-
-
-/**
- * Given a node, returns true if it's a control. Controls are *not necessarily*
- * leaf-level given that some composite controls may have focusable children
- * if they are managing focus with tabindex:
- * ( http://www.w3.org/TR/2010/WD-wai-aria-practices-20100916/#visualfocus ).
- *
- * @param {Node} node The node to check.
- * @return {boolean} True if the node is a control.
- */
-cvox.DomUtil.isControl = function(node) {
- if (cvox.AriaUtil.isControlWidget(node) &&
- cvox.DomUtil.isFocusable(node)) {
- return true;
- }
- if (node.tagName) {
- switch (node.tagName) {
- case 'BUTTON':
- case 'TEXTAREA':
- case 'SELECT':
- return true;
- case 'INPUT':
- return node.type != 'hidden';
- }
- }
- if (node.isContentEditable) {
- return true;
- }
- return false;
-};
-
-
-/**
- * Given a node, returns true if it's a leaf-level control. This includes
- * composite controls thare are managing focus for children with
- * activedescendant, but not composite controls with focusable children:
- * ( http://www.w3.org/TR/2010/WD-wai-aria-practices-20100916/#visualfocus ).
- *
- * @param {Node} node The node to check.
- * @return {boolean} True if the node is a leaf-level control.
- */
-cvox.DomUtil.isLeafLevelControl = function(node) {
- if (cvox.DomUtil.isControl(node)) {
- return !(cvox.AriaUtil.isCompositeControl(node) &&
- cvox.DomUtil.findFocusableDescendant(node));
- }
- return false;
-};
-
-
-/**
- * Given a node that might be inside of a composite control like a listbox,
- * return the surrounding control.
- * @param {Node} node The node from which to start looking.
- * @return {Node} The surrounding composite control node, or null if none.
- */
-cvox.DomUtil.getSurroundingControl = function(node) {
- var surroundingControl = null;
- if (!cvox.DomUtil.isControl(node) && node.hasAttribute &&
- node.hasAttribute('role')) {
- surroundingControl = node.parentElement;
- while (surroundingControl &&
- !cvox.AriaUtil.isCompositeControl(surroundingControl)) {
- surroundingControl = surroundingControl.parentElement;
- }
- }
- return surroundingControl;
-};
-
-
-/**
- * Given a node and a function for determining when to stop
- * descent, return the next leaf-like node.
- *
- * @param {!Node} node The node from which to start looking,
- * this node *must not* be above document.body.
- * @param {boolean} r True if reversed. False by default.
- * @param {function(!Node):boolean} isLeaf A function that
- * returns true if we should stop descending.
- * @return {Node} The next leaf-like node or null if there is no next
- * leaf-like node. This function will always return a node below
- * document.body and never document.body itself.
- */
-cvox.DomUtil.directedNextLeafLikeNode = function(node, r, isLeaf) {
- if (node != document.body) {
- // if not at the top of the tree, we want to find the next possible
- // branch forward in the dom, so we climb up the parents until we find a
- // node that has a nextSibling
- while (!cvox.DomUtil.directedNextSibling(node, r)) {
- if (!node) {
- return null;
- }
- // since node is never above document.body, it always has a parent.
- // so node.parentNode will never be null.
- node = /** @type {!Node} */(node.parentNode);
- if (node == document.body) {
- // we've readed the end of the document.
- return null;
- }
- }
- if (cvox.DomUtil.directedNextSibling(node, r)) {
- // we just checked that next sibling is non-null.
- node = /** @type {!Node} */(cvox.DomUtil.directedNextSibling(node, r));
- }
- }
- // once we're at our next sibling, we want to descend down into it as
- // far as the child class will allow
- while (cvox.DomUtil.directedFirstChild(node, r) && !isLeaf(node)) {
- node = /** @type {!Node} */(cvox.DomUtil.directedFirstChild(node, r));
- }
-
- // after we've done all that, if we are still at document.body, this must
- // be an empty document.
- if (node == document.body) {
- return null;
- }
- return node;
-};
-
-
-/**
- * Given a node, returns the next leaf node.
- *
- * @param {!Node} node The node from which to start looking
- * for the next leaf node.
- * @param {boolean=} reverse True if reversed. False by default.
- * @return {Node} The next leaf node.
- * Null if there is no next leaf node.
- */
-cvox.DomUtil.directedNextLeafNode = function(node, reverse) {
- reverse = !!reverse;
- return cvox.DomUtil.directedNextLeafLikeNode(
- node, reverse, cvox.DomUtil.isLeafNode);
-};
-
-
-/**
- * Given a node, returns the previous leaf node.
- *
- * @param {!Node} node The node from which to start looking
- * for the previous leaf node.
- * @return {Node} The previous leaf node.
- * Null if there is no previous leaf node.
- */
-cvox.DomUtil.previousLeafNode = function(node) {
- return cvox.DomUtil.directedNextLeafNode(node, true);
-};
-
-
-/**
- * Computes the outer most leaf node of a given node, depending on value
- * of the reverse flag r.
- * @param {!Node} node in the DOM.
- * @param {boolean} r True if reversed. False by default.
- * @param {function(!Node):boolean} pred Predicate to decide
- * what we consider a leaf.
- * @return {Node} The outer most leaf node of that node.
- */
-cvox.DomUtil.directedFindFirstNode = function(node, r, pred) {
- var child = cvox.DomUtil.directedFirstChild(node, r);
- while (child) {
- if (pred(child)) {
- return child;
- } else {
- var leaf = cvox.DomUtil.directedFindFirstNode(child, r, pred);
- if (leaf) {
- return leaf;
- }
- }
- child = cvox.DomUtil.directedNextSibling(child, r);
- }
- return null;
-};
-
-
-/**
- * Moves to the deepest node satisfying a given predicate under the given node.
- * @param {!Node} node in the DOM.
- * @param {boolean} r True if reversed. False by default.
- * @param {function(!Node):boolean} pred Predicate deciding what a leaf is.
- * @return {Node} The deepest node satisfying pred.
- */
-cvox.DomUtil.directedFindDeepestNode = function(node, r, pred) {
- var next = cvox.DomUtil.directedFindFirstNode(node, r, pred);
- if (!next) {
- if (pred(node)) {
- return node;
- } else {
- return null;
- }
- } else {
- return cvox.DomUtil.directedFindDeepestNode(next, r, pred);
- }
-};
-
-
-/**
- * Computes the next node wrt. a predicate that is a descendant of ancestor.
- * @param {!Node} node in the DOM.
- * @param {!Node} ancestor of the given node.
- * @param {boolean} r True if reversed. False by default.
- * @param {function(!Node):boolean} pred Predicate to decide
- * what we consider a leaf.
- * @param {boolean=} above True if the next node can live in the subtree
- * directly above the start node. False by default.
- * @param {boolean=} deep True if we are looking for the next node that is
- * deepest in the tree. Otherwise the next shallow node is returned.
- * False by default.
- * @return {Node} The next node in the DOM that satisfies the predicate.
- */
-cvox.DomUtil.directedFindNextNode = function(
- node, ancestor, r, pred, above, deep) {
- above = !!above;
- deep = !!deep;
- if (!cvox.DomUtil.isDescendantOfNode(node, ancestor) || node == ancestor) {
- return null;
- }
- var next = cvox.DomUtil.directedNextSibling(node, r);
- while (next) {
- if (!deep && pred(next)) {
- return next;
- }
- var leaf = (deep ?
- cvox.DomUtil.directedFindDeepestNode :
- cvox.DomUtil.directedFindFirstNode)(next, r, pred);
- if (leaf) {
- return leaf;
- }
- if (deep && pred(next)) {
- return next;
- }
- next = cvox.DomUtil.directedNextSibling(next, r);
- }
- var parent = /** @type {!Node} */(node.parentNode);
- if (above && pred(parent)) {
- return parent;
- }
- return cvox.DomUtil.directedFindNextNode(
- parent, ancestor, r, pred, above, deep);
-};
-
-
-/**
- * Get a string representing a control's value and state, i.e. the part
- * that changes while interacting with the control
- * @param {Element} control A control.
- * @return {string} The value and state string.
- */
-cvox.DomUtil.getControlValueAndStateString = function(control) {
- var parentControl = cvox.DomUtil.getSurroundingControl(control);
- if (parentControl) {
- return cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(control) + ' ' +
- cvox.DomUtil.getName(control) + ' ' +
- cvox.DomUtil.getState(control, true));
- } else {
- return cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(control) + ' ' +
- cvox.DomUtil.getState(control, true));
- }
-};
-
-
-/**
- * Determine whether the given node is an internal link.
- * @param {Node} node The node to be examined.
- * @return {boolean} True if the node is an internal link, false otherwise.
- */
-cvox.DomUtil.isInternalLink = function(node) {
- if (node.nodeType == 1) { // Element nodes only.
- var href = node.getAttribute('href');
- if (href && href.indexOf('#') != -1) {
- var path = href.split('#')[0];
- return path == '' || path == window.location.pathname;
- }
- }
- return false;
-};
-
-
-/**
- * Get a string containing the currently selected link's URL.
- * @param {Node} node The link from which URL needs to be extracted.
- * @return {string} The value of the URL.
- */
-cvox.DomUtil.getLinkURL = function(node) {
- if (node.tagName == 'A') {
- if (node.getAttribute('href')) {
- if (cvox.DomUtil.isInternalLink(node)) {
- return Msgs.getMsg('internal_link');
- } else {
- return node.getAttribute('href');
- }
- } else {
- return '';
- }
- } else if (cvox.AriaUtil.getRoleName(node) ==
- Msgs.getMsg('role_link')) {
- return Msgs.getMsg('unknown_link');
- }
-
- return '';
-};
-
-
-/**
- * Checks if a given node is inside a table and returns the table node if it is
- * @param {Node} node The node.
- * @param {{allowCaptions: (undefined|boolean)}=} kwargs Optional named args.
- * allowCaptions: If true, will return true even if inside a caption. False
- * by default.
- * @return {Node} If the node is inside a table, the table node. Null if it
- * is not.
- */
-cvox.DomUtil.getContainingTable = function(node, kwargs) {
- var ancestors = cvox.DomUtil.getAncestors(node);
- return cvox.DomUtil.findTableNodeInList(ancestors, kwargs);
-};
-
-
-/**
- * Extracts a table node from a list of nodes.
- * @param {Array<Node>} nodes The list of nodes.
- * @param {{allowCaptions: (undefined|boolean)}=} kwargs Optional named args.
- * allowCaptions: If true, will return true even if inside a caption. False
- * by default.
- * @return {Node} The table node if the list of nodes contains a table node.
- * Null if it does not.
- */
-cvox.DomUtil.findTableNodeInList = function(nodes, kwargs) {
- kwargs = kwargs || {allowCaptions: false};
- // Don't include the caption node because it is actually rendered outside
- // of the table.
- for (var i = nodes.length - 1, node; node = nodes[i]; i--) {
- if (node.constructor != Text) {
- if (!kwargs.allowCaptions && node.tagName == 'CAPTION') {
- return null;
- }
- if ((node.tagName == 'TABLE') || cvox.AriaUtil.isGrid(node)) {
- return node;
- }
- }
- }
- return null;
-};
-
-
-/**
- * Determines whether a given table is a data table or a layout table
- * @param {Node} tableNode The table node.
- * @return {boolean} If the table is a layout table, returns true. False
- * otherwise.
- */
-cvox.DomUtil.isLayoutTable = function(tableNode) {
- // TODO(stoarca): Why are we returning based on this inaccurate heuristic
- // instead of first trying the better heuristics below?
- if (tableNode.rows && (tableNode.rows.length <= 1 ||
- (tableNode.rows[0].childElementCount == 1))) {
- // This table has either 0 or one rows, or only "one" column.
- // This is a quick check for column count and may not be accurate. See
- // TraverseTable.getW3CColCount_ for a more accurate
- // (but more complicated) way to determine column count.
- return true;
- }
-
- // These heuristics are adapted from the Firefox data and layout table.
- // heuristics: http://asurkov.blogspot.com/2011/10/data-vs-layout-table.html
- if (cvox.AriaUtil.isGrid(tableNode)) {
- // This table has an ARIA role identifying it as a grid.
- // Not a layout table.
- return false;
- }
- if (cvox.AriaUtil.isLandmark(tableNode)) {
- // This table has an ARIA landmark role - not a layout table.
- return false;
- }
-
- if (tableNode.caption || tableNode.summary) {
- // This table has a caption or a summary - not a layout table.
- return false;
- }
-
- if ((cvox.XpathUtil.evalXPath('tbody/tr/th', tableNode).length > 0) &&
- (cvox.XpathUtil.evalXPath('tbody/tr/td', tableNode).length > 0)) {
- // This table at least one column and at least one column header.
- // Not a layout table.
- return false;
- }
-
- if (cvox.XpathUtil.evalXPath('colgroup', tableNode).length > 0) {
- // This table specifies column groups - not a layout table.
- return false;
- }
-
- if ((cvox.XpathUtil.evalXPath('thead', tableNode).length > 0) ||
- (cvox.XpathUtil.evalXPath('tfoot', tableNode).length > 0)) {
- // This table has header or footer rows - not a layout table.
- return false;
- }
-
- if ((cvox.XpathUtil.evalXPath('tbody/tr/td/embed', tableNode).length > 0) ||
- (cvox.XpathUtil.evalXPath('tbody/tr/td/object', tableNode).length > 0) ||
- (cvox.XpathUtil.evalXPath('tbody/tr/td/iframe', tableNode).length > 0) ||
- (cvox.XpathUtil.evalXPath('tbody/tr/td/applet', tableNode).length > 0)) {
- // This table contains embed, object, applet, or iframe elements. It is
- // a layout table.
- return true;
- }
-
- // These heuristics are loosely based on Okada and Miura's "Detection of
- // Layout-Purpose TABLE Tags Based on Machine Learning" (2007).
- // http://books.google.com/books?id=kUbmdqasONwC&lpg=PA116&ots=Lb3HJ7dISZ&lr&pg=PA116
-
- // Increase the points for each heuristic. If there are 3 or more points,
- // this is probably a layout table.
- var points = 0;
-
- if (! cvox.DomUtil.hasBorder(tableNode)) {
- // This table has no border.
- points++;
- }
-
- if (tableNode.rows.length <= 6) {
- // This table has a limited number of rows.
- points++;
- }
-
- if (cvox.DomUtil.countPreviousTags(tableNode) <= 12) {
- // This table has a limited number of previous tags.
- points++;
- }
-
- if (cvox.XpathUtil.evalXPath('tbody/tr/td/table', tableNode).length > 0) {
- // This table has nested tables.
- points++;
- }
- return (points >= 3);
-};
-
-
-/**
- * Count previous tags, which we dfine as the number of HTML tags that
- * appear before the given node.
- * @param {Node} node The given node.
- * @return {number} The number of previous tags.
- */
-cvox.DomUtil.countPreviousTags = function(node) {
- var ancestors = cvox.DomUtil.getAncestors(node);
- return ancestors.length + cvox.DomUtil.countPreviousSiblings(node);
-};
-
-
-/**
- * Counts previous siblings, not including text nodes.
- * @param {Node} node The given node.
- * @return {number} The number of previous siblings.
- */
-cvox.DomUtil.countPreviousSiblings = function(node) {
- var count = 0;
- var prev = node.previousSibling;
- while (prev != null) {
- if (prev.constructor != Text) {
- count++;
- }
- prev = prev.previousSibling;
- }
- return count;
-};
-
-
-/**
- * Whether a given table has a border or not.
- * @param {Node} tableNode The table node.
- * @return {boolean} If the table has a border, return true. False otherwise.
- */
-cvox.DomUtil.hasBorder = function(tableNode) {
- // If .frame contains "void" there is no border.
- if (tableNode.frame) {
- return (tableNode.frame.indexOf('void') == -1);
- }
-
- // If .border is defined and == "0" then there is no border.
- if (tableNode.border) {
- if (tableNode.border.length == 1) {
- return (tableNode.border != '0');
- } else {
- return (tableNode.border.slice(0, -2) != 0);
- }
- }
-
- // If .style.border-style is 'none' there is no border.
- if (tableNode.style.borderStyle && tableNode.style.borderStyle == 'none') {
- return false;
- }
-
- // If .style.border-width is specified in units of length
- // ( https://developer.mozilla.org/en/CSS/border-width ) then we need
- // to check if .style.border-width starts with 0[px,em,etc]
- if (tableNode.style.borderWidth) {
- return (tableNode.style.borderWidth.slice(0, -2) != 0);
- }
-
- // If .style.border-color is defined, then there is a border
- if (tableNode.style.borderColor) {
- return true;
- }
- return false;
-};
-
-
-/**
- * Return the first leaf node, starting at the top of the document.
- * @return {Node?} The first leaf node in the document, if found.
- */
-cvox.DomUtil.getFirstLeafNode = function() {
- var node = document.body;
- while (node && node.firstChild) {
- node = node.firstChild;
- }
- while (node && !cvox.DomUtil.hasContent(node)) {
- node = cvox.DomUtil.directedNextLeafNode(node);
- }
- return node;
-};
-
-
-/**
- * Finds the first descendant node that matches the filter function, using
- * a depth first search. This function offers the most general purpose way
- * of finding a matching element. You may also wish to consider
- * {@code goog.dom.query} which can express many matching criteria using
- * CSS selector expressions. These expressions often result in a more
- * compact representation of the desired result.
- * This is the findNode function from goog.dom:
- * http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/dom/dom.js
- *
- * @param {Node} root The root of the tree to search.
- * @param {function(Node) : boolean} p The filter function.
- * @return {Node|undefined} The found node or undefined if none is found.
- */
-cvox.DomUtil.findNode = function(root, p) {
- var rv = [];
- var found = cvox.DomUtil.findNodes_(root, p, rv, true, 10000);
- return found ? rv[0] : undefined;
-};
-
-
-/**
- * Finds the number of nodes matching the filter.
- * @param {Node} root The root of the tree to search.
- * @param {function(Node) : boolean} p The filter function.
- * @return {number} The number of nodes selected by filter.
- */
-cvox.DomUtil.countNodes = function(root, p) {
- var rv = [];
- cvox.DomUtil.findNodes_(root, p, rv, false, 10000);
- return rv.length;
-};
-
-
-/**
- * Finds the first or all the descendant nodes that match the filter function,
- * using a depth first search.
- * @param {Node} root The root of the tree to search.
- * @param {function(Node) : boolean} p The filter function.
- * @param {Array<Node>} rv The found nodes are added to this array.
- * @param {boolean} findOne If true we exit after the first found node.
- * @param {number} maxChildCount The max child count. This is used as a kill
- * switch - if there are more nodes than this, terminate the search.
- * @return {boolean} Whether the search is complete or not. True in case
- * findOne is true and the node is found. False otherwise. This is the
- * findNodes_ function from goog.dom:
- * http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/dom/dom.js.
- * @private
- */
-cvox.DomUtil.findNodes_ = function(root, p, rv, findOne, maxChildCount) {
- if ((root != null) || (maxChildCount == 0)) {
- var child = root.firstChild;
- while (child) {
- if (p(child)) {
- rv.push(child);
- if (findOne) {
- return true;
- }
- }
- maxChildCount = maxChildCount - 1;
- if (cvox.DomUtil.findNodes_(child, p, rv, findOne, maxChildCount)) {
- return true;
- }
- child = child.nextSibling;
- }
- }
- return false;
-};
-
-
-/**
- * Converts a NodeList into an array
- * @param {NodeList} nodeList The nodeList.
- * @return {Array} The array of nodes in the nodeList.
- */
-cvox.DomUtil.toArray = function(nodeList) {
- var nodeArray = [];
- for (var i = 0; i < nodeList.length; i++) {
- nodeArray.push(nodeList[i]);
- }
- return nodeArray;
-};
-
-
-/**
- * Creates a new element with the same attributes and no children.
- * @param {Node|Text} node A node to clone.
- * @param {Object<boolean>} skipattrs Set the attribute to true to skip it
- * during cloning.
- * @return {Node|Text} The cloned node.
- */
-cvox.DomUtil.shallowChildlessClone = function(node, skipattrs) {
- if (node.nodeName == '#text') {
- return document.createTextNode(node.nodeValue);
- }
-
- if (node.nodeName == '#comment') {
- return document.createComment(node.nodeValue);
- }
-
- var ret = document.createElement(node.nodeName);
- for (var i = 0; i < node.attributes.length; ++i) {
- var attr = node.attributes[i];
- if (skipattrs && skipattrs[attr.nodeName]) {
- continue;
- }
- ret.setAttribute(attr.nodeName, attr.nodeValue);
- }
- return ret;
-};
-
-
-/**
- * Creates a new element with the same attributes and clones of children.
- * @param {Node|Text} node A node to clone.
- * @param {Object<boolean>} skipattrs Set the attribute to true to skip it
- * during cloning.
- * @return {Node|Text} The cloned node.
- */
-cvox.DomUtil.deepClone = function(node, skipattrs) {
- var ret = cvox.DomUtil.shallowChildlessClone(node, skipattrs);
- for (var i = 0; i < node.childNodes.length; ++i) {
- ret.appendChild(cvox.DomUtil.deepClone(node.childNodes[i], skipattrs));
- }
- return ret;
-};
-
-
-/**
- * Returns either node.firstChild or node.lastChild, depending on direction.
- * @param {Node|Text} node The node.
- * @param {boolean} reverse If reversed.
- * @return {Node|Text} The directed first child or null if the node has
- * no children.
- */
-cvox.DomUtil.directedFirstChild = function(node, reverse) {
- if (reverse) {
- return node.lastChild;
- }
- return node.firstChild;
-};
-
-/**
- * Returns either node.nextSibling or node.previousSibling, depending on
- * direction.
- * @param {Node|Text} node The node.
- * @param {boolean=} reverse If reversed.
- * @return {Node|Text} The directed next sibling or null if there are
- * no more siblings in that direction.
- */
-cvox.DomUtil.directedNextSibling = function(node, reverse) {
- if (!node) {
- return null;
- }
- if (reverse) {
- return node.previousSibling;
- }
- return node.nextSibling;
-};
-
-/**
- * Creates a function that sends a click. This is because loop closures
- * are dangerous.
- * See: http://joust.kano.net/weblog/archive/2005/08/08/
- * a-huge-gotcha-with-javascript-closures/
- * @param {Node} targetNode The target node to click on.
- * @return {function()} A function that will click on the given targetNode.
- */
-cvox.DomUtil.createSimpleClickFunction = function(targetNode) {
- var target = targetNode.cloneNode(true);
- return function() { cvox.DomUtil.clickElem(target, false, false); };
-};
-
-/**
- * Adds a node to document.head if that node has not already been added.
- * If document.head does not exist, this will add the node to the body.
- * @param {Node} node The node to add.
- * @param {string=} opt_id The id of the node to ensure the node is only
- * added once.
- */
-cvox.DomUtil.addNodeToHead = function(node, opt_id) {
- if (opt_id && document.getElementById(opt_id)) {
- return;
- }
- var p = document.head || document.body;
- p.appendChild(node);
-};
-
-
-/**
- * Checks if a given node is inside a math expressions and
- * returns the math node if one exists.
- * @param {Node} node The node.
- * @return {Node} The math node, if the node is inside a math expression.
- * Null if it is not.
- */
-cvox.DomUtil.getContainingMath = function(node) {
- var ancestors = cvox.DomUtil.getAncestors(node);
- return cvox.DomUtil.findMathNodeInList(ancestors);
-};
-
-
-/**
- * Extracts a math node from a list of nodes.
- * @param {Array<Node>} nodes The list of nodes.
- * @return {Node} The math node if the list of nodes contains a math node.
- * Null if it does not.
- */
-cvox.DomUtil.findMathNodeInList = function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++) {
- if (cvox.DomUtil.isMath(node)) {
- return node;
- }
- }
- return null;
-};
-
-
-/**
- * Checks to see wether a node is a math node.
- * @param {Node} node The node to be tested.
- * @return {boolean} Whether or not a node is a math node.
- */
-cvox.DomUtil.isMath = function(node) {
- return cvox.DomUtil.isMathml(node) ||
- cvox.DomUtil.isMathJax(node) ||
- cvox.DomUtil.isMathImg(node) ||
- cvox.AriaUtil.isMath(node);
-};
-
-
-/**
- * Specifies node classes in which we expect maths expressions a alt text.
- * @type {{tex: Array<string>,
- * asciimath: Array<string>}}
- */
-// These are the classes for which we assume they contain Maths in the ALT or
-// TITLE attribute.
-// tex: Wikipedia;
-// latex: Wordpress;
-// numberedequation, inlineformula, displayformula: MathWorld;
-cvox.DomUtil.ALT_MATH_CLASSES = {
- tex: ['tex', 'latex'],
- asciimath: ['numberedequation', 'inlineformula', 'displayformula']
-};
-
-
-/**
- * Composes a query selector string for image nodes with alt math content by
- * type of content.
- * @param {string} contentType The content type, e.g., tex, asciimath.
- * @return {!string} The query elector string.
- */
-cvox.DomUtil.altMathQuerySelector = function(contentType) {
- var classes = cvox.DomUtil.ALT_MATH_CLASSES[contentType];
- if (classes) {
- return classes.map(function(x) {return 'img.' + x;}).join(', ');
- }
- return '';
-};
-
-
-/**
- * Check if a given node is potentially a math image with alternative text in
- * LaTeX.
- * @param {Node} node The node to be tested.
- * @return {boolean} Whether or not a node has an image with class TeX or LaTeX.
- */
-cvox.DomUtil.isMathImg = function(node) {
- if (!node || !node.tagName || !node.className) {
- return false;
- }
- if (node.tagName != 'IMG') {
- return false;
- }
- for (var i = 0, className; className = node.classList.item(i); i++) {
- className = className.toLowerCase();
- if (cvox.DomUtil.ALT_MATH_CLASSES.tex.indexOf(className) != -1 ||
- cvox.DomUtil.ALT_MATH_CLASSES.asciimath.indexOf(className) != -1) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Checks to see whether a node is a MathML node.
- * !! This is necessary as Chrome currently does not upperCase Math tags !!
- * @param {Node} node The node to be tested.
- * @return {boolean} Whether or not a node is a MathML node.
- */
-cvox.DomUtil.isMathml = function(node) {
- if (!node || !node.tagName) {
- return false;
- }
- return node.tagName.toLowerCase() == 'math';
-};
-
-
-/**
- * Checks to see wether a node is a MathJax node.
- * @param {Node} node The node to be tested.
- * @return {boolean} Whether or not a node is a MathJax node.
- */
-cvox.DomUtil.isMathJax = function(node) {
- if (!node || !node.tagName || !node.className) {
- return false;
- }
-
- function isSpanWithClass(n, cl) {
- return (n.tagName == 'SPAN' &&
- n.className.split(' ').some(function(x) {
- return x.toLowerCase() == cl;}));
- };
- if (isSpanWithClass(node, 'math')) {
- var ancestors = cvox.DomUtil.getAncestors(node);
- return ancestors.some(function(x) {return isSpanWithClass(x, 'mathjax');});
- }
- return false;
-};
-
-
-/**
- * Computes the id of the math span in a MathJax DOM element.
- * @param {string} jaxId The id of the MathJax node.
- * @return {string} The id of the span node.
- */
-cvox.DomUtil.getMathSpanId = function(jaxId) {
- var node = document.getElementById(jaxId + '-Frame');
- if (node) {
- var span = node.querySelector('span.math');
- if (span) {
- return span.id;
- }
- }
-};
-
-
-/**
- * Returns true if the node has a longDesc.
- * @param {Node} node The node to be tested.
- * @return {boolean} Whether or not a node has a longDesc.
- */
-cvox.DomUtil.hasLongDesc = function(node) {
- if (node && node.longDesc) {
- return true;
- }
- return false;
-};
-
-
-/**
- * Returns tag name of a node if it has one.
- * @param {Node} node A node.
- * @return {string} A the tag name of the node.
- */
-cvox.DomUtil.getNodeTagName = function(node) {
- if (node.nodeType == Node.ELEMENT_NODE) {
- return node.tagName;
- }
- return '';
-};
-
-
-/**
- * Cleaning up a list of nodes to remove empty text nodes.
- * @param {NodeList} nodes The nodes list.
- * @return {!Array<Node|string|null>} The cleaned up list of nodes.
- */
-cvox.DomUtil.purgeNodes = function(nodes) {
- return cvox.DomUtil.toArray(nodes).
- filter(function(node) {
- return node.nodeType != Node.TEXT_NODE ||
- !node.textContent.match(/^\s+$/);});
-};
-
-
-/**
- * Calculates a hit point for a given node.
- * @return {{x:(number), y:(number)}} The position.
- */
-cvox.DomUtil.elementToPoint = function(node) {
- if (!node) {
- return {x: 0, y: 0};
- }
- if (node.constructor == Text) {
- node = node.parentNode;
- }
- var r = node.getBoundingClientRect();
- return {
- x: r.left + (r.width / 2),
- y: r.top + (r.height / 2)
- };
-};
-
-
-/**
- * Checks if an input node supports HTML5 selection.
- * If the node is not an input element, returns false.
- * @param {Node} node The node to check.
- * @return {boolean} True if HTML5 selection supported.
- */
-cvox.DomUtil.doesInputSupportSelection = function(node) {
- return goog.isDef(node) &&
- node.tagName == 'INPUT' &&
- node.type != 'email' &&
- node.type != 'number';
-};
-
-
-/**
- * Gets the hint text for a given element.
- * @param {Node} node The target node.
- * @return {string} The hint text.
- */
-cvox.DomUtil.getHint = function(node) {
- var desc = '';
- if (node.hasAttribute) {
- if (node.hasAttribute('aria-describedby')) {
- var describedByIds = node.getAttribute('aria-describedby').split(' ');
- for (var describedById, i = 0; describedById = describedByIds[i]; i++) {
- var describedNode = document.getElementById(describedById);
- if (describedNode) {
- desc += ' ' + cvox.DomUtil.getName(
- describedNode, true, true, true);
- }
- }
- }
- }
- return desc;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_util_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_util_test.unitjs
deleted file mode 100644
index b77b36676fa..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/dom_util_test.unitjs
+++ /dev/null
@@ -1,1578 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxDomUtilUnitTest() {}
-
-CvoxDomUtilUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ChromeVox',
- 'cvox.DescriptionUtil',
- 'cvox.DomUtil',
- 'TestMsgs',
- ],
-
- /** @override */
- setUp: function() {
- Msgs = TestMsgs;
- },
-
- asText_: function(node) {
- var temp = document.createElement('div');
- temp.appendChild(node);
- return temp.innerHTML;
- },
-
- assertEqualsAsText_: function(node1, node2) {
- assertEquals(this.asText_(node1), this.asText_(node2));
- },
-
- loadDomUtilTestDoc_: function() {
- this.loadDoc(function() {/*!
- <style type="text/css">
- #display_none { display: none; }
- #visibility_hidden { visibility: hidden; }
- #forced_visible { visibility: hidden; }
- #visibility_collapse { visibility: collapse; }
- #opacity_zero { opacity: 0; }
- #opacity_partial { opacity: 0.5; }
- #opacity_undefined { }
- #nested_visibility_hide { visibility: hidden; }
- #nested_visibility_show { visibility: visible; }
- #nested_display_none { display: none; }
- #nested_display_block { display: block; }
- </style>
- <form action="">
-
- <div id="normal_node">1</div>
- <div id="display_none">2</div>
- <div id="visibility_hidden">3</div>
- <div id="visibility_collapse">3b</div>
- <div id="opacity_zero">4</div>
- <div id="opacity_partial">4b</div>
- <div id="opacity_undefined">5</div>
- <select id="select_node"><option>5</option></select>
- <textarea id="textarea">6</textarea>
- <div id="forced_visible" aria-hidden="false">7</div>
- <p id="normal_para">----</p>
- <p id="presentation" role="presentation">----</p>
- <p id="aria_hidden" aria-hidden="true">----</p>
- <p id="only_spaces"> </p>
- <p id="only_tabs"> </p>
- <p id="only_newlines">
-
- </p>
- <p id="only_nbsp">&nbsp;</p>
- <p id="other_entity">&amp;</p>
- <img id="img">
- <img id="img_alt" alt="tree">
- <img id="img_blankalt" alt="">
-
- <input id="check" type="checkbox">
- <input id="check_checked" type="checkbox" checked>
-
- <span><p id="a">a</p></span>
- <span><p id="b">b</p><p id="c">c</p></span>
- </form>
-
- <a id="special_link1" href="http://google.com"><span id="empty_span"></span>
- </a>
- <a id="special_link2" href="http://google.com"><span>Text content</span></a>
- <a id="special_link3"><span></span></a>
-
- <div id="nested_visibility_hide">
- hide<div id="nested_visibility_show">show</div>me
- </div>
- <div id="nested_display_none">
- nothing<div id="nested_display_block">will</div>show
- </div>
- */});
- },
-};
-
-TEST_F('CvoxDomUtilUnitTest', 'IsVisible', function() {
- this.loadDomUtilTestDoc_();
-
- // Simple tests.
- var node = $('normal_node');
- assertEquals(true, cvox.DomUtil.isVisible(node));
- node = $('display_none');
- assertEquals(false, cvox.DomUtil.isVisible(node));
- node = $('visibility_hidden');
- assertEquals(false, cvox.DomUtil.isVisible(node));
- node = $('visibility_collapse');
- assertEquals(false, cvox.DomUtil.isVisible(node));
- node = $('opacity_zero');
- assertEquals(false, cvox.DomUtil.isVisible(node));
- node = $('opacity_partial');
- assertEquals(true, cvox.DomUtil.isVisible(node));
- node = $('opacity_undefined');
- assertEquals(true, cvox.DomUtil.isVisible(node));
- node = $('forced_visible');
- assertEquals(true, cvox.DomUtil.isVisible(node));
-
- // Nested visibility tests.
- node = $('nested_visibility_hide');
- assertEquals(true, cvox.DomUtil.isVisible(node)); // Has visible child.
- node = $('nested_visibility_hide').childNodes[0];
- assertEquals(false, cvox.DomUtil.isVisible(node)); // TextNode is invisible.
- node = $('nested_visibility_show');
- assertEquals(true, cvox.DomUtil.isVisible(node));
- node = $('nested_visibility_show').childNodes[0];
- assertEquals(true, cvox.DomUtil.isVisible(node)); // TextNode is visible.
- node = $('nested_display_block');
- assertEquals(false, cvox.DomUtil.isVisible(node));
-
- // Options tests (for performance).
- node = $('nested_display_block');
- assertEquals(true,
- cvox.DomUtil.isVisible(node, {checkAncestors: false}));
- node = $('nested_visibility_hide');
- assertEquals(false,
- cvox.DomUtil.isVisible(node, {checkDescendants: false}));
-
- // Test that an element not part of the DOM is treated as invisible.
- var div = document.createElement('div');
- assertEquals(false, cvox.DomUtil.isVisible(div));
- document.body.appendChild(div);
- assertEquals(true, cvox.DomUtil.isVisible(div));
-});
-
-/** Test determining if a node is a leaf node or not. @export */
-TEST_F('CvoxDomUtilUnitTest', 'IsLeafNode', function() {
- this.loadDomUtilTestDoc_();
-
- var node = $('normal_node');
- assertEquals(false, cvox.DomUtil.isLeafNode(node));
- node = $('display_none');
- assertEquals(true, cvox.DomUtil.isLeafNode(node));
- node = $('visibility_hidden');
- assertEquals(true, cvox.DomUtil.isLeafNode(node));
- node = $('opacity_zero');
- assertEquals(true, cvox.DomUtil.isLeafNode(node));
- node = $('select_node');
- assertEquals(true, cvox.DomUtil.isLeafNode(node));
- node = $('textarea');
- assertEquals(true, cvox.DomUtil.isLeafNode(node));
- node = $('normal_para');
- assertEquals(false, cvox.DomUtil.isLeafNode(node));
- node = $('aria_hidden');
- assertEquals(true, cvox.DomUtil.isLeafNode(node));
- node = $('special_link1');
- assertEquals(true, cvox.DomUtil.isLeafNode(node));
- node = $('special_link2');
- assertEquals(true, cvox.DomUtil.isLeafNode(node));
- node = $('special_link3');
- assertEquals(false, cvox.DomUtil.isLeafNode(node));
- node = $('nested_visibility_hide');
- assertEquals(false, cvox.DomUtil.isLeafNode(node));
-});
-
-/** Test determining if a node has content or not. @export */
-TEST_F('CvoxDomUtilUnitTest', 'HasContent', function() {
- this.loadDomUtilTestDoc_();
-
- var node = $('normal_node');
- cvox.DomUtil.hasContent(node);
- assertEquals(true, cvox.DomUtil.hasContent(node));
- node = $('display_none');
- assertEquals(false, cvox.DomUtil.hasContent(node));
- node = $('visibility_hidden');
- assertEquals(false, cvox.DomUtil.hasContent(node));
- node = $('opacity_zero');
- assertEquals(false, cvox.DomUtil.hasContent(node));
- node = $('select_node');
- assertEquals(true, cvox.DomUtil.hasContent(node));
- node = $('textarea');
- assertEquals(true, cvox.DomUtil.hasContent(node));
- node = $('normal_para');
- assertEquals(true, cvox.DomUtil.hasContent(node));
- // TODO (adu): This test fails. Will inspect.
- // node = $('presentation');
- // assertEquals(false, cvox.DomUtil.hasContent(node));
- node = $('aria_hidden');
- assertEquals(false, cvox.DomUtil.hasContent(node));
- node = $('only_spaces');
- assertEquals(false, cvox.DomUtil.hasContent(node));
- node = $('only_tabs');
- assertEquals(false, cvox.DomUtil.hasContent(node));
- node = $('only_newlines');
- assertEquals(false, cvox.DomUtil.hasContent(node));
- node = $('other_entity');
- assertEquals(true, cvox.DomUtil.hasContent(node));
- node = $('img');
- assertEquals(true, cvox.DomUtil.hasContent(node));
- node = $('img_alt');
- assertEquals(true, cvox.DomUtil.hasContent(node));
- node = $('img_blankalt');
- assertEquals(false, cvox.DomUtil.hasContent(node));
-});
-
-/** Test getting a node's state. @export */
-TEST_F('CvoxDomUtilUnitTest', 'NodeState', function() {
- this.loadDomUtilTestDoc_();
- this.appendDoc(function() {/*!
- <input id="state1_enabled">
- <input id="state1_disabled" disabled>
- <button id="state2_enabled">Button</button>
- <button id="state2_disabled" disabled>Button</button>
- <textarea id="state3_enabled">Textarea</textarea>
- <textarea id="state3_disabled" disabled>Textarea</textarea>
- <select id="state4_enabled"><option>Select</option></select>
- <select id="state4_disabled" disabled><option>Select</option></select>
- <div role="button" id="state5_enabled" tabindex="0">ARIAButton</div>
- <div role="button" id="state5_disabled" tabindex="0" disabled>ARIAButton</div>
- <fieldset>
- <input id="state6_enabled">
- </fieldset>
- <fieldset disabled>
- <input id="state6_disabled">
- </fieldset>
- */});
- var node = $('check');
- assertEquals('not checked', cvox.DomUtil.getState(node, true));
- node = $('check_checked');
- assertEquals('checked', cvox.DomUtil.getState(node, true));
- node = $('state1_enabled');
- assertEquals('', cvox.DomUtil.getState(node, true));
- node = $('state1_disabled');
- assertEquals('Disabled', cvox.DomUtil.getState(node, true));
- node = $('state2_enabled');
- assertEquals('', cvox.DomUtil.getState(node, true));
- node = $('state2_disabled');
- assertEquals('Disabled', cvox.DomUtil.getState(node, true));
- node = $('state3_enabled');
- assertEquals('', cvox.DomUtil.getState(node, true));
- node = $('state3_disabled');
- assertEquals('Disabled', cvox.DomUtil.getState(node, true));
- node = $('state4_enabled');
- assertEquals('1 of 1', cvox.DomUtil.getState(node, true));
- node = $('state4_disabled');
- assertEquals('1 of 1 Disabled', cvox.DomUtil.getState(node, true));
- node = $('state5_enabled');
- assertEquals('', cvox.DomUtil.getState(node, true));
- node = $('state5_disabled');
- assertEquals('', cvox.DomUtil.getState(node, true));
- node = $('state6_enabled');
- assertEquals('', cvox.DomUtil.getState(node, true));
- node = $('state6_disabled');
- assertEquals('Disabled', cvox.DomUtil.getState(node, true));
-});
-
-/** Test finding the next/previous leaf node. @export */
-TEST_F('CvoxDomUtilUnitTest', 'LeafNodeTraversal', function() {
- this.loadDomUtilTestDoc_();
-
- var node = $('a');
- node = cvox.DomUtil.directedNextLeafNode(node);
- assertEquals('\n ', node.textContent);
- node = cvox.DomUtil.directedNextLeafNode(node);
- assertEquals('b', node.textContent);
- node = cvox.DomUtil.directedNextLeafNode(node);
- assertEquals('c', node.textContent);
- node = cvox.DomUtil.previousLeafNode(node);
- assertEquals('b', node.textContent);
- node = cvox.DomUtil.previousLeafNode(node);
- assertEquals('\n ', node.textContent);
- node = cvox.DomUtil.previousLeafNode(node);
- assertEquals('a', node.textContent);
-});
-
-/** Test finding the label for controls. @export */
-TEST_F('CvoxDomUtilUnitTest', 'GetLabel', function() {
- this.loadDoc(function() {/*!
- <fieldset id="Fieldset">
- <legend>This is a legend inside a fieldset</legend>
- <div align="right">
- <span>
- Username:
- </span>
- </div>
- <input name="Email" id="Email" size="18" value="" type="text">
- <span>
- Password:
- </span>
- <input name="Passwd" id="Passwd" size="18" type="password">
- <input name="PersistentCookie" id="PersistentCookie" type="checkbox">
- <label for="PersistentCookie" id="PersistentCookieLabel">
- Stay signed in
- </label>
- <input name="signIn" id="signIn" value="Sign in" type="submit">
- <input id="dummyA" size="18" value="" type="text" title="">
- <input id="dummyB" size="18" value="" type="text" aria-label="">
- </fieldset>
- */});
-
- function getControlText(control) {
- var description = cvox.DescriptionUtil.getControlDescription(control);
- return cvox.DomUtil.collapseWhitespace(
- description.context + ' ' +
- description.text + ' ' +
- description.userValue + ' ' +
- description.annotation);
- }
-
- var fieldsetElement = $('Fieldset');
- assertEquals('This is a legend inside a fieldset',
- cvox.DomUtil.getName(fieldsetElement, false, false));
-
- var usernameField = $('Email');
- assertEquals('', cvox.DomUtil.getValue(usernameField));
- assertEquals('Username:',
- cvox.DomUtil.getControlLabelHeuristics(usernameField));
- assertEquals('Username: Edit text', getControlText(usernameField));
- var passwordField = $('Passwd');
- assertEquals('', cvox.DomUtil.getValue(passwordField));
- assertEquals('Password:',
- cvox.DomUtil.getControlLabelHeuristics(passwordField));
- assertEquals('Password: Password edit text', getControlText(passwordField));
- var cookieCheckbox = $('PersistentCookie');
- assertEquals('Stay signed in', cvox.DomUtil.getName(cookieCheckbox));
- assertEquals('Stay signed in Check box not checked',
- getControlText(cookieCheckbox));
- var signinButton = $('signIn');
- assertEquals('Sign in', cvox.DomUtil.getName(signinButton));
- assertEquals('Sign in Button', getControlText(signinButton));
- var dummyInputA = $('dummyA');
- assertEquals('', cvox.DomUtil.getName(dummyInputA));
- var dummyInputB = $('dummyB');
- assertEquals('', cvox.DomUtil.getName(dummyInputB));
-
- // The heuristic no longer returns 'Stay signed in' as the label for
- // the signIn button because 'Stay signed in' is in a label that's
- // explicitly associated with another control.
- //assertEquals('Stay signed in ',
- // cvox.DomUtil.getControlLabelHeuristics(signinButton));
-});
-
-/** Test finding the label for controls with a more complex setup. @export */
-TEST_F('CvoxDomUtilUnitTest', 'GetLabelComplex', function() {
- this.loadDoc(function() {/*!
- <table class="bug-report-table">
- <tbody><tr>
- <td class="bug-report-fieldlabel">
- <input id="page-url-checkbox" type="checkbox">
- <span id="page-url-label" i18n-content="page-url">Include this URL:</span>
- </td>
- <td>
- <input id="page-url-text" class="bug-report-field" maxlength="200">
- </td>
- </tr>
- </tbody></table>
- <table id="user-email-table" class="bug-report-table">
- <tbody><tr>
- <td class="bug-report-fieldlabel">
- <input id="user-email-checkbox" checked="checked" type="checkbox">
- <span id="user-email-label">Include this email:</span>
- </td>
- <td>
- <label id="user-email-text" class="bug-report-field"></label>
- </td>
- </tr>
- </tbody></table>
- <table class="bug-report-table">
- <tbody><tr>
- <td class="bug-report-fieldlabel">
- <input id="sys-info-checkbox" checked="checked" type="checkbox">
- <span id="sysinfo-label">
- <a id="sysinfo-url" href="#">Send system information</a>
- </span>
- </td>
- </tr>
- </tbody></table>
- <table class="bug-report-table">
- <tbody><tr>
- <td class="bug-report-fieldlabel">
- <input id="screenshot-checkbox" type="checkbox">
- <span id="screenshot-label-current">Include the current screenshot:</span>
- </td>
- </tr>
- </tbody></table>
- */});
- var urlCheckbox = $('page-url-checkbox');
- assertEquals('Include this URL:',
- cvox.DomUtil.getControlLabelHeuristics(urlCheckbox));
- var emailCheckbox = $('user-email-checkbox');
- assertEquals('Include this email:',
- cvox.DomUtil.getControlLabelHeuristics(emailCheckbox));
- var sysCheckbox = $('sys-info-checkbox');
- assertEquals('Send system information',
- cvox.DomUtil.getControlLabelHeuristics(sysCheckbox));
-});
-
-/**************************************************************/
-
-TEST_F('CvoxDomUtilUnitTest', 'EscapedNames', function() {
- this.loadDoc(function() {/*!
- <p id="en-title" title="&lt;&gt;"></p>
- <p id="en-arialabel" aria-label="&lt;&gt;"></p>
- <img id="en-img" title="&lt;&gt;"></img>
- <p id="en-double" title="&amp;lt;&amp;gt;"></p>
- */});
- assertEquals('<>', cvox.DomUtil.getName(
- $('en-title')));
- assertEquals('<>', cvox.DomUtil.getName(
- $('en-arialabel')));
- assertEquals('<>', cvox.DomUtil.getName(
- $('en-img')));
- assertEquals('&lt;&gt;', cvox.DomUtil.getName(
- $('en-double')));
-});
-
-/** Test a paragraph with plain text. @export */
-TEST_F('CvoxDomUtilUnitTest', 'SimplePara', function() {
- this.loadDoc(function() {/*!
- <p id="simplepara">This is a simple paragraph.</p>
- */});
- var node = $('simplepara');
- var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
- assertEquals('This is a simple paragraph.', text);
-});
-
-/** Test a paragraph with nested tags. @export */
-TEST_F('CvoxDomUtilUnitTest', 'NestedPara', function() {
- this.loadDoc(function() {/*!
- <p id="nestedpara">This is a <b>paragraph</b> with <i>nested</i> tags.</p>
- */});
- var node = $('nestedpara');
- var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
- assertEquals('This is a paragraph with nested tags.', text);
-});
-
-/**
- * Test a paragraph with nested tags and varying visibility.
- * @export
- */
-TEST_F('CvoxDomUtilUnitTest', 'NestedVisibilityPara', function() {
- this.loadDoc(function() {/*!
- <style type="text/css">
- #nested_visibility_paragraph { }
- #nested_visibility_paragraph .hide { visibility: hidden; }
- #nested_visibility_paragraph .show { visibility: visible; }
- </style>
- <p id="nested_visibility_paragraph">
- This is
- <span class="hide">
- not
- <span class="show"> a sentence.</span>
- </span>
- </p>
- */});
- var node = $('nested_visibility_paragraph');
- var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
- assertEquals('This is a sentence.', text);
-});
-
-/** Test getting text from an IMG node. @export */
-TEST_F('CvoxDomUtilUnitTest', 'Image', function() {
- this.loadDoc(function() {/*!
- <img id="img">
- <img id="img_noalt" src="rose.png">
- <img id="img_alt" alt="flower" src="rose.png">
- <img id="img_title" title="a Flower" src="rose.png">
- <img id="img_noalt_long"
- src="777777777777777777777777777777777.png">
- */});
-
- var node = $('img');
- assertEquals('Image', cvox.DomUtil.getName(node));
- node = $('img_noalt');
- assertEquals('rose Image', cvox.DomUtil.getName(node));
- node = $('img_alt');
- assertEquals('flower', cvox.DomUtil.getName(node));
- node = $('img_title');
- assertEquals('a Flower', cvox.DomUtil.getName(node));
- node = $('img_noalt_long');
- assertEquals('Image', cvox.DomUtil.getName(node));
-});
-
-/** Test getting text from a select box. @export */
-TEST_F('CvoxDomUtilUnitTest', 'Select', function() {
- this.loadDoc(function() {/*!
- <select id="select_noneselected">
- <option>Apple</option>
- <option>Banana</option>
- <option>Pear</option>
- </select>
- <select id="select_bananaselected">
- <option>Apple</option>
- <option selected>Banana</option>
- <option>Pear</option>
- </select>
- */});
-
- $('select_noneselected').selectedIndex = -1;
- var node = $('select_noneselected');
- assertEquals('', cvox.DomUtil.getValue(node));
- node = $('select_bananaselected');
- assertEquals('Banana', cvox.DomUtil.getValue(node));
-});
-
-/** Test whether funky html causes getName to go into infinite loop. */
-TEST_F('CvoxDomUtilUnitTest', 'GetNameInfiniteLoop', function() {
- this.loadDoc(function() {/*!
- <div>
- <label for="a">
- <p id="a">asdf</p>
- </label>
- </div>
- */});
- // intentionally no asserts; if there is an infinite (recursive) loop,
- // the stack will blow up
- var node = $('a');
- var label = cvox.DomUtil.getName(node);
-});
-
-/** Test getting text from an INPUT control. @export */
-TEST_F('CvoxDomUtilUnitTest', 'Input', function() {
- this.loadDoc(function() {/*!
- <form action="">
- <input id="hidden" type="hidden" value="hidden1">
- <input id="input_img" type="image" src="rose.png">
- <input id="input_img_alt" type="image" alt="flower" src="rose.png">
- <input id="submit" type="submit">
- <input id="submit_withvalue" type="submit" value="Go">
- <input id="reset" type="reset">
- <input id="reset_withvalue" type="reset" value="Stop">
- <input id="button" type="button" value="Button">
- <input id="checkbox" type="checkbox" value="ignore1">
- <input id="checkbox_title" type="checkbox" value="ignore1" title="toggle">
- <input id="radio" type="radio" value="ignore2">
- <input id="password" type="password" value="dragon">
- <input id="text" value="my text">
- <input id="placeholder0" placeholder="Phone number">
- <input id="placeholder1" title="Phone number">
- <input id="placeholder2" title="Phone number" placeholder="xxx-yyy-zzzz">
- <input id="placeholder3" title="Phone number" placeholder="xxx-yyy-zzzz"
- value="310-555-1212">
- </form>
- */});
-
- var node = $('hidden');
- assertEquals('', cvox.DomUtil.getName(node));
- node = $('input_img');
- assertEquals('rose Image', cvox.DomUtil.getName(node));
- node = $('input_img_alt');
- assertEquals('flower', cvox.DomUtil.getName(node));
- node = $('submit');
- assertEquals('Submit', cvox.DomUtil.getName(node));
- node = $('submit_withvalue');
- assertEquals('Go', cvox.DomUtil.getName(node));
- node = $('reset');
- assertEquals('Reset', cvox.DomUtil.getName(node));
- node = $('reset_withvalue');
- assertEquals('Stop', cvox.DomUtil.getName(node));
- node = $('button');
- assertEquals('Button', cvox.DomUtil.getName(node));
- node = $('checkbox');
- assertEquals('', cvox.DomUtil.getName(node));
- node = $('checkbox_title');
- assertEquals('toggle', cvox.DomUtil.getName(node));
- node = $('radio');
- assertEquals('', cvox.DomUtil.getName(node));
- node = $('password');
- assertEquals('dot dot dot dot dot dot ', cvox.DomUtil.getValue(node));
- node = $('text');
- assertEquals('my text', cvox.DomUtil.getValue(node));
- node = $('placeholder0');
- assertEquals('Phone number', cvox.DomUtil.getName(node));
- node = $('placeholder1');
- assertEquals('Phone number', cvox.DomUtil.getName(node));
- node = $('placeholder2');
- assertEquals('xxx-yyy-zzzz',
- cvox.DomUtil.getName(node));
- node = $('placeholder3');
- assertEquals('310-555-1212 xxx-yyy-zzzz',
- cvox.DomUtil.getValue(node) + ' ' + cvox.DomUtil.getName(node));
-});
-
-
-/** Test checking if something is a control. @export */
-TEST_F('CvoxDomUtilUnitTest', 'IsControl', function() {
- this.loadDoc(function() {/*!
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td>&nbsp;</td>
-
- <td nowrap="nowrap">
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td bgcolor="#3366CC"><img alt="" width="1" height="1"></td>
- </tr>
- </tbody>
- </table>
-
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td bgcolor="#E5ECF9" nowrap="nowrap"><font color="#000000"
- face="arial,sans-serif" size="+1"><b>&nbsp;Preferences</b>
- </font></td>
-
- <td align="right" bgcolor="#E5ECF9" nowrap="nowrap">
- <font color="#000000" face="arial,sans-serif" size="-1">
- <a href="http://www.google.com/accounts/ManageAccount">Google
- Account settings</a> | <a href="http://www.google.com/">
- Preferences Help</a> | <a href="/about.html">About
- Google</a>&nbsp;</font></td>
- </tr>
- </tbody>
- </table>
- </td>
- </tr>
- </tbody>
- </table>
-
- <table width="100%" border="0" cellpadding="2" cellspacing="0">
- <tbody>
- <tr bgcolor="#E5ECF9">
- <td><font face="arial,sans-serif" size="-1"><b>Save</b> your
- preferences when finished and <b>return to search</b>.</font></td>
-
- <td align="right"><font face="arial,sans-serif" size="-1">
- <input value="Save Preferences " name="submit2" type="submit">
- </font></td>
- </tr>
- </tbody>
- </table>
-
- <h1>Global Preferences</h1><font size="-1">(changes apply to all Google
- services)</font><br>
-
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td bgcolor="#CBDCED"><img alt="" width="1" height="2"></td>
- </tr>
- </tbody>
- </table>
-
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
-
- <td valign="top" width="175" nowrap="nowrap">
- &nbsp;<br>
- &nbsp;
-
- <h2>Interface Language</h2>
- </td>
-
- <td colspan="2"><br>
- <font face="arial,sans-serif" size="-1">Display Google tips and
- messages in: <select name="hl">
- <option value="af">
- Afrikaans
- </option>
-
- <option value="ak">
- Akan
- </option>
-
- <option value="sq">
- Albanian
- </option>
-
- <option value="am">
- Amharic
- </option>
-
- <option value="ar">
- Arabic
- </option>
- </select><br>
- If you do not find your native language in the pulldown above, you
- can<br>
- help Google create it through our
- <a href="http://services.google.com/">Google in Your Language
- program</a>.<br>
- &nbsp;</font></td>
- </tr>
- </tbody>
- </table>
-
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
- </tr>
-
- <tr>
- <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
-
- <td valign="top" width="175" nowrap="nowrap">
- &nbsp;<br>
- &nbsp;
-
- <h2>Search Language</h2>
- </td>
-
- <td>
- &nbsp;<br>
- <font face="arial,sans-serif" size="-1">Prefer pages written in these
- language(s):</font><br>
-
- <table border="0" cellpadding="5" cellspacing="10">
- <tbody>
- <tr>
- <td valign="top" nowrap="nowrap"><font face="arial,sans-serif"
- size="-1"><label><input name="lr" value="lang_af"
- onclick="tick()" id="paf" type="checkbox">
- <span id="taf">Afrikaans</span></label><br>
- <label><input name="lr" value="lang_ar" onclick="tick()"
- id="par" type="checkbox"> <span id="tar">Arabic</span></label>
- <br>
- <label><input name="lr" value="lang_hy" onclick="tick()"
- id="phy" type="checkbox"> <span id="thy">Armenian</span>
- </label><br>
- <label><input name="lr" value="lang_be" onclick="tick()"
- id="pbe" type="checkbox"> <span id="tbe">Belarusian</span>
- </label><br>
- <label><input name="lr" value="lang_bg" onclick="tick()"
- id="pbg" type="checkbox"> <span id="tbg">Bulgarian</span>
- </label><br>
- <label><input name="lr" value="lang_ca" onclick="tick()"
- id="pca" type="checkbox"> <span id="tca">Catalan</span>
- </label><br>
- <label><input name="lr" value="lang_zh-CN" onclick="tick()"
- id="pzh-CN" type="checkbox"> <span id="tzh-CN">
- Chinese&nbsp;(Simplified)</span></label><br>
- <label><input name="lr" value="lang_zh-TW" onclick="tick()"
- id="pzh-TW" type="checkbox"> <span id="tzh-TW">
- Chinese&nbsp;(Traditional)</span></label><br>
- <label><input name="lr" value="lang_hr" onclick="tick()"
- id="phr" type="checkbox"> <span id="thr">Croatian</span>
- </label><br>
- <label><input name="lr" value="lang_cs" onclick="tick()"
- id="pcs" type="checkbox"> <span id="tcs">Czech</span>
- </label><br>
- <label><input name="lr" value="lang_da" onclick="tick()"
- id="pda" type="checkbox"> <span id="tda">Danish</span>
- </label><br>
- <label><input name="lr" value="lang_nl" onclick="tick()"
- id="pnl" type="checkbox"> <span id="tnl">Dutch</span>
- </label></font></td>
- </tr>
- </tbody>
- </table>
- </td>
- </tr>
- </tbody>
- </table><a name="loc" id="loc"></a>
-
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
- </tr>
-
- <tr>
- <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
-
- <td valign="top" width="175" nowrap="nowrap">
- &nbsp;<br>
- &nbsp;
-
- <h2>Location</h2>
- </td>
-
- <td>
- <br>
-
- <div style="color: rgb(204, 0, 0); display: none;" id="locerr">
- <span id="lem"><font face="arial,sans-serif" size="-1">The location
- <b>X</b> was not recognized.</font></span>
- <font face="arial,sans-serif" size="-1"><br>
- <br>
- Suggestions:<br></font>
-
- <ul>
- <li><font face="arial,sans-serif" size="-1">Make sure all street
- and city names are spelled correctly.</font></li>
-
- <li><font face="arial,sans-serif" size="-1">Make sure the address
- included a city and state.</font></li>
-
- <li><font face="arial,sans-serif" size="-1">Try entering a Zip
- code.</font></li>
- </ul>
- </div>
-
- <div style="color: rgb(204, 0, 0); display: none;" id="locterr">
- <font face="arial,sans-serif" size="-1">Please enter a valid US
- city or zip code<br>
- <br></font>
- </div>
-
- <div style="color: rgb(204, 0, 0); display: none;" id="locserr">
- <font face="arial,sans-serif" size="-1">Server error. Please try
- again.<br>
- <br></font>
- </div><font face="arial,sans-serif" size="-1">Use as the default
- location in Google Maps, customized search results, and other Google
- products:<br>
- <input name="uulo" value="1" type="hidden"><input name="muul"
- value="4_20" type="hidden"><input name="luul" size="60" value=""
- type="text"><br>
- This location is saved on this computer.
- <a href="/support/websearch/bin/answer.py?answer=35892&amp;hl=en">
- Learn more</a><br>
- <br></font>
- </td>
- </tr>
- </tbody>
- </table>
-
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
- </tr>
-
- <tr>
- <td rowspan="2" width="1" bgcolor="#CBDCED">
- <img alt="" width="2" height="1"></td>
-
- <td width="175" nowrap="nowrap">
- &nbsp;<br>
- &nbsp;
- <h2>SafeSearch Filtering</h2>
- </td>
- <td><br>
- <font face="arial,sans-serif" size="-1">
- <a href="http://www.google.com/">
- Google's SafeSearch</a> blocks web pages containing explicit sexual
- content from appearing in search results.</font></td>
- </tr>
- <tr valign="top">
- <td width="175" nowrap="nowrap">&nbsp;</td>
- <td>
- <div style="margin-bottom: 1.2em; font: smaller arial,sans-serif;">
- <input id="stf" name="safeui" value="on" type="radio">
- <label for="stf">Use strict filtering&nbsp;(Filter both explicit
- text and explicit images)</label><br>
- <input id="modf" name="safeui" value="images" checked="checked"
- type="radio"><label for="modf">Use moderate
- filtering&nbsp;(Filter explicit images only - default
- behavior)</label><br>
- <input id="nof" name="safeui" value="off" type="radio">
- <label for="nof">Do not filter my search results</label>
- </div>
- <p style="margin-bottom: 1.2em; font-size: smaller;">This will apply
- strict filtering to all searches from this computer using Firefox.
- <a href="http://www.google.com/">Learn more</a></p>
- </td>
- </tr>
- </tbody>
- </table>
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
- </tr>
-
- <tr>
- <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
-
- <td valign="top" width="175" nowrap="nowrap">
- &nbsp;<br>
- &nbsp;
-
- <h2>Number of Results</h2>
- </td>
-
- <td>&nbsp;<br>
- <font face="arial,sans-serif" size="-1">Google's default (10 results)
- provides the fastest results.<br>
- Display <select name="num">
- <option value="10" selected="selected">
- 10
- </option>
-
- <option value="20">
- 20
- </option>
-
- <option value="30">
- 30
- </option>
-
- <option value="50">
- 50
- </option>
-
- <option value="100">
- 100
- </option>
- </select> results per page.<br>
- &nbsp;</font></td>
- </tr>
- </tbody>
- </table>
-
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
- </tr>
-
- <tr>
- <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
-
- <td valign="top" width="175" nowrap="nowrap">
- &nbsp;<br>
- &nbsp;
-
- <h2>Results Window</h2><a name="safeui" id="safeui">&nbsp;</a>
- </td>
-
- <td>&nbsp;<br>
- <font face="arial,sans-serif" size="-1"><input id="nwc" name="newwindow"
- value="1" type="checkbox">&nbsp; <label for="nwc">Open
- search results in a new browser window.</label></font><br>
- &nbsp;</td>
- </tr>
- </tbody>
- </table>
-
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
- </tr>
-
- <tr>
- <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
-
- <td valign="top" width="175" nowrap="nowrap">
- &nbsp;<br>
- &nbsp;
-
- <h2>Google Instant</h2>
- </td>
-
- <td>&nbsp;<br>
- <font face="arial,sans-serif" size="-1"><input id="suggon" name="suggon"
- value="1" checked="checked" type="radio"><label for="suggon">Use Google
- Instant predictions and results appear while typing</label><br>
- <input id="suggmid" name="suggon" value="2" type="radio">
- <label for="suggmid">Do not use Google Instant</label><br>
- <br>
- Signed-in users can remove personalized predictions from their
- <a href="/history">Web History</a>. <a href="http://www.google.com/">
- Learn more</a><br>
- <br>
- &nbsp;</font></td>
- </tr>
-
- <tr>
- <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="2"></td>
- </tr>
- </tbody>
- </table><br>
- */});
- var submitButton = document.getElementsByName('submit2')[0];
- assertEquals(true, cvox.DomUtil.isControl(submitButton));
- var selectControl = document.getElementsByName('hl')[0];
- assertEquals(true, cvox.DomUtil.isControl(selectControl));
- var checkbox = $('paf');
- assertEquals(true, cvox.DomUtil.isControl(checkbox));
- var textInput = document.getElementsByName('luul')[0];
- assertEquals(true, cvox.DomUtil.isControl(textInput));
- var radioButton = $('suggmid');
- assertEquals(true, cvox.DomUtil.isControl(radioButton));
- var h1Elem = document.getElementsByTagName('h1');
- assertEquals(false, cvox.DomUtil.isControl(h1Elem));
-});
-
-/** Test if something is an ARIA control. @export */
-TEST_F('CvoxDomUtilUnitTest', 'IsAriaControl', function() {
- this.loadDoc(function() {/*!
- <li id="cb1" role="checkbox" tabindex="0" aria-checked="false"
- aria-describedby="cond desc1">
- Lettuce
- </li>
- <li id="larger1" role="button" tabindex="0" aria-pressed="false"
- aria-labelledby="larger_label">+</li>
- <li id="r1" role="radio" tabindex="-1" aria-checked="false">Thai</li>
- <li id="treeitem1" role="treeitem" tabindex="-1">Oranges</li>
- */});
- var checkbox = $('cb1');
- assertEquals(true, cvox.DomUtil.isControl(checkbox));
- var button = $('larger1');
- assertEquals(true, cvox.DomUtil.isControl(button));
- var radio = $('r1');
- assertEquals(true, cvox.DomUtil.isControl(radio));
- var treeitem = $('treeitem1');
- assertEquals(false, cvox.DomUtil.isControl(treeitem));
-});
-
-/** Test if something is an focusable. @export */
-TEST_F('CvoxDomUtilUnitTest', 'IsFocusable', function() {
- this.loadDoc(function() {/*!
- <a id="focus_link" href="#">Link</a>
- <a id="focus_anchor">Unfocusable anchor</a>
- <input id="focus_input" value="Input" />
- <select id="focus_select"><option>Select</option></select>
- <button id="focus_button1">Button</button>
- <button id="focus_button2" tabindex="-1">Button 2</button>
- <button id="focus_button3" tabindex="0">Button 3</button>
- <button id="focus_button4" tabindex="1">Button 4</button>
- <div id="focus_div1">Div</div>
- <div id="focus_div2" tabindex="-1">Div 2</div>
- <div id="focus_div3" tabindex="0">Div 3</div>
- <div id="focus_div4" tabindex="1">Div 4</div>
- */});
- var node;
- node = $('focus_link');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_anchor');
- assertEquals(false, cvox.DomUtil.isFocusable(node));
- node = $('focus_input');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_select');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_button1');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_button2');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_button3');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_button4');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_div1');
- assertEquals(false, cvox.DomUtil.isFocusable(node));
- node = $('focus_div2');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_div3');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
- node = $('focus_div4');
- assertEquals(true, cvox.DomUtil.isFocusable(node));
-
- // Test it with null.
- assertEquals(false, cvox.DomUtil.isFocusable(null));
-
- // Test it with something that's not an element.
- assertEquals(false, cvox.DomUtil.isFocusable(new Object()));
-
- // Test it with a Text node.
- node = $('focus_button1').firstChild;
- assertEquals(false, cvox.DomUtil.isFocusable(node));
-});
-
-/** Some additional tests for getName function. */
-TEST_F('CvoxDomUtilUnitTest', 'GetName', function() {
- this.loadDoc(function() {/*!
- <span id="test-span" aria-labelledby="fake-id">Some text</span>
- <label id="label1">One</label>
- <label id="label3">Label</label>
- <div id="test-div" aria-labelledby="label1 label2 label3"></div>
- */});
- var node = $('test-span');
- // Makes sure we can deal with invalid ids in aria-labelledby.
- var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
- assertEquals('Some text', text);
- node = $('test-div');
- text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
- assertEquals('One Label', cvox.DomUtil.getName(node));
-});
-
-/** Test for getLinkURL. */
-TEST_F('CvoxDomUtilUnitTest', 'GetLinkURL', function() {
- this.loadDoc(function() {/*!
- <a id="l1" name="nohref">Anchor</a>
- <a id="l2" href="">Empty link</a>
- <a id="l3" href="#">Link to self</a>
- <a id="l4" href="http://google.com">Google</a>
- <span id="l5" role="link" onClick="javascript:alert('?')">Something</span>
- <div id="l6" role="link">Div with link role</a>
- */});
- var node = $('l1');
- assertEquals('', cvox.DomUtil.getLinkURL(node));
- node = $('l2');
- assertEquals('', cvox.DomUtil.getLinkURL(node));
- node = $('l3');
- assertEquals('Internal link', cvox.DomUtil.getLinkURL(node));
- node = $('l4');
- assertEquals('http://google.com', cvox.DomUtil.getLinkURL(node));
- node = $('l5');
- assertEquals('Unknown link', cvox.DomUtil.getLinkURL(node));
- node = $('l6');
- assertEquals('Unknown link', cvox.DomUtil.getLinkURL(node));
-});
-
-/** Test for isDisabled. */
-TEST_F('CvoxDomUtilUnitTest', 'IsDisabled', function() {
- this.loadDoc(function() {/*!
- <input id="button1" type="button" value="Press me!"/>
- <input id="button2" type="button" value="Don't touch me!" disabled/>
- */});
- var node = $('button1');
- assertEquals(false, cvox.DomUtil.isDisabled(node));
- node = $('button2');
- assertEquals(true, cvox.DomUtil.isDisabled(node));
-});
-
-/** Test for a tree with aria-expanded attribute. */
-TEST_F('CvoxDomUtilUnitTest', 'Tree', function() {
- this.loadDoc(function() {/*!
- <div id=":0" role="tree" aria-selected="false" aria-expanded="true"
- aria-level="0" aria-labelledby=":0.label" tabindex="0"
- aria-activedescendant=":1">
- <span id=":0.label">Countries</span>
- <div class="goog-tree-item" id=":1" role="treeitem" aria-selected="true"
- aria-expanded="false" aria-labelledby=":1.label" aria-level="1">
- <span id=":1.label">A</span>
- </div>
- <div class="goog-tree-item" id=":2" role="treeitem" aria-selected="false"
- aria-expanded="false" aria-labelledby=":2.label" aria-level="1">
- <span id=":2.label">B<span>
- </div>
- <div class="goog-tree-item" id=":3" role="treeitem" aria-selected="false"
- aria-expanded="true" aria-labelledby=":3.label" aria-level="1">
- <span id=":3.label">C</span>
- <div class="goog-tree-children" role="group">
- <div class="goog-tree-item" id=":3a" role="treeitem"
- aria-selected="false" aria-expanded="false"
- aria-labelledby=":3a.label" aria-level="2">
- <span id=":3a.label">Chile</span>
- </div>
- <div class="goog-tree-item" id=":3b" role="treeitem"
- aria-selected="false" aria-expanded="false"
- aria-labelledby=":3b.label" aria-level="2">
- <span id=":3b.label">China</span>
- </div>
- <div class="goog-tree-item" id=":3c" role="treeitem"
- aria-selected="false" aria-expanded="false"
- aria-labelledby=":3c.label" aria-level="2">
- <span id=":3c.label">Christmas Island</span>
- </div>
- <div class="goog-tree-item" id=":3d" role="treeitem"
- aria-selected="false" aria-expanded="false"
- aria-labelledby=":3d.label" aria-level="2">
- <span id=":3d.label">Cocos (Keeling) Islands</span>
- </div>
- </div>
- </div>
- </div>
- */});
- var node = $(':0');
- assertEquals('A Collapsed Selected 1 of 3',
- cvox.DomUtil.getControlValueAndStateString(node));
- node = $(':1');
- assertEquals('A Collapsed Selected 1 of 3',
- cvox.DomUtil.getControlValueAndStateString(node));
- node = $(':2');
- assertEquals('B Collapsed Not selected 2 of 3',
- cvox.DomUtil.getControlValueAndStateString(node));
- node = $(':3');
- assertEquals('C Expanded Not selected 3 of 3',
- cvox.DomUtil.getControlValueAndStateString(node));
- node = $(':3b');
- assertEquals('China Collapsed Not selected 2 of 4',
- cvox.DomUtil.getControlValueAndStateString(node));
-});
-
-/** Test for tables with different border specifications */
-TEST_F('CvoxDomUtilUnitTest', 'TableBorders', function() {
- this.loadDoc(function() {/*!
- <table id=":0" border="1">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":1" border="0">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":2" border="0px">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":3" frame="box">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":4" frame="void">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":5" style="border-width: medium">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":6" style="border-width: medium; border-style: none">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":7" style="border-color: red">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":8" style="border-style: dotted; border-width: 0px">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":9" style="border-width: 0px">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":10" style="border: 0px">
- <tr>
- <td>A</td>
- </tr>
- </table>
- <table id=":11" style="border: 0">
- <tr>
- <td>A</td>
- </tr>
- </table>
- */});
- var node = $(':0');
- assertTrue(cvox.DomUtil.hasBorder(node));
-
- node = $(':1');
- assertFalse(cvox.DomUtil.hasBorder(node));
-
- node = $(':2');
- assertFalse(cvox.DomUtil.hasBorder(node));
-
- node = $(':3');
- assertTrue(cvox.DomUtil.hasBorder(node));
-
- node = $(':4');
- assertFalse(cvox.DomUtil.hasBorder(node));
-
- node = $(':5');
- assertTrue(cvox.DomUtil.hasBorder(node));
-
- node = $(':6');
- assertFalse(cvox.DomUtil.hasBorder(node));
-
- node = $(':7');
- assertTrue(cvox.DomUtil.hasBorder(node));
-
- node = $(':8');
- assertFalse(cvox.DomUtil.hasBorder(node));
-
- node = $(':9');
- assertFalse(cvox.DomUtil.hasBorder(node));
-
- node = $(':10');
- assertFalse(cvox.DomUtil.hasBorder(node));
-
- node = $(':11');
- assertFalse(cvox.DomUtil.hasBorder(node));
-});
-
-/** Tests for shallowChildlessClone */
-TEST_F('CvoxDomUtilUnitTest', 'ShallowChildlessClone', function() {
- this.loadDoc(function() {/*!
- <div id='simple'>asdf</div>
- <div id='expectedSimpleClone'>asdf</div>
- <div id='oneLevel'><div>asdf</div></div>
- <div id='expectedOneLevelClone'><div></div></div>
- <div id='withAttrs'><div class="asdf">asdf</div></div>
- <div id='expectedWithAttrsClone'><div class="asdf"></div></div>
- */});
-
- var simple = $('simple').firstChild;
- var expectedSimpleClone = $('expectedSimpleClone').firstChild;
- var oneLevel = $('oneLevel').firstChild;
- var expectedOneLevelClone = $('expectedOneLevelClone').firstChild;
- var withAttrs = $('withAttrs').firstChild;
- var expectedWithAttrsClone = $('expectedWithAttrsClone').firstChild;
-
- var simpleClone = cvox.DomUtil.shallowChildlessClone(simple);
- this.assertEqualsAsText_(simpleClone, expectedSimpleClone);
-
- var oneLevelClone = cvox.DomUtil.shallowChildlessClone(oneLevel);
- this.assertEqualsAsText_(oneLevelClone, expectedOneLevelClone);
-
- var withAttrsClone = cvox.DomUtil.shallowChildlessClone(withAttrs);
- this.assertEqualsAsText_(withAttrsClone, expectedWithAttrsClone);
-});
-
-/** Tests for deepClone */
-TEST_F('CvoxDomUtilUnitTest', 'DeepClone', function() {
- this.loadDoc(function() {/*!
- <div id='simple'>asdf</div>
- */});
- var simpleClone = cvox.DomUtil.deepClone($('simple'));
- this.assertEqualsAsText_(simpleClone, $('simple'));
-
- this.loadDoc(function() {/*!
- <div id="withAttrs" class="asdf">asdf</div>
- */});
- var withAttrsClone = cvox.DomUtil.deepClone($('withAttrs'));
- this.assertEqualsAsText_(withAttrsClone, $('withAttrs'));
-});
-
-/** Tests for findNode */
-TEST_F('CvoxDomUtilUnitTest', 'FindNode', function() {
- this.loadDoc(function() {/*!
- <div id="root">
- <p id="a">a</p>
- <a href="#" id="b">b</a>
- </div>
- */});
- var f = cvox.DomUtil.findNode;
- var node = f($('root'), function(n) {return n.id == 'b';});
- assertEquals('b', node.id);
-});
-
-/** Tests for getState for a list */
-TEST_F('CvoxDomUtilUnitTest', 'ListLength', function() {
- this.loadDoc(function() {/*!
- <ul id="ul1">
- <li>A
- <li>B
- <li>C
- </ul>
- <ul id="ul2">
- <li aria-setsize="10">A
- <li aria-setsize="10">B
- <li aria-setsize="10">C
- </ul>
- */});
- var ul1 = $('ul1');
- assertEquals('with 3 items',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getState(ul1)));
-
- var ul2 = $('ul2');
- assertEquals('with 10 items',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getState(ul2)));
-});
-
-/** Tests for hasLongDesc */
-TEST_F('CvoxDomUtilUnitTest', 'HasLongDesc', function() {
- this.loadDoc(function() {/*!
- <img id="img0" longdesc="desc.html" src="img0.jpg"></img>
- <img id="img1" src="img1.jpg"></img>
- */});
- var img0 = $('img0');
- assertEquals(true, cvox.DomUtil.hasLongDesc(img0));
-
- var img1 = $('img1');
- assertEquals(false, cvox.DomUtil.hasLongDesc(img1));
-});
-
-/** Tests for various link leaf types. */
-TEST_F('CvoxDomUtilUnitTest', 'LinkLeaf', function() {
- this.loadDoc(function() {/*!
- <a id='leaf' href='google.com'><strong>Click</strong><div>here</div></a>
- <a id='non-leaf' href='google.com'>Click <h2>here</h2></a>
- */});
- var leaf = $('leaf');
- var nonLeaf = $('non-leaf');
- assertTrue(cvox.DomUtil.isLeafNode(leaf));
- assertFalse(cvox.DomUtil.isLeafNode(nonLeaf));
-});
-
-
-/** Test the value and state of a multiple select. */
-TEST_F('CvoxDomUtilUnitTest', 'MultipleSelectValue', function() {
- this.loadDoc(function() {/*!
- <select id='cars' multiple>
- <option value="volvo">Volvo</option>
- <option value="saab">Saab</option>
- <option value="opel" selected>Opel</option>
- <option value="audi" selected>Audi</option>
- </select>
- */});
- var cars = $('cars');
- assertEquals('Opel to Audi', cvox.DomUtil.getValue(cars));
- assertEquals('selected 2 items', cvox.DomUtil.getState(cars));
-});
-
-
-/**
- * Test correctness of elementToPoint.
- *
- * Absolute positioning of the container is used to avoid the window of the
- * browser being too small to contain the test elements.
- */
-TEST_F('CvoxDomUtilUnitTest', 'ElementToPoint', function() {
- this.loadDoc(function() {/*!
- <div style="position: absolute; top: 0; left: 0">
- <a id='one' href='#a'>First</a>
- <p id='two'>Some text</p>
- <ul><li id='three'>LI</li><li>LI2</li></ul>
- </div>
- */});
- var one = $('one');
- var two = $('two');
- var three = $('three');
-
- var oneHitPoint = cvox.DomUtil.elementToPoint(one);
- var twoHitPoint = cvox.DomUtil.elementToPoint(two);
- var threeHitPoint = cvox.DomUtil.elementToPoint(three);
-
- assertEquals(one, document.elementFromPoint(oneHitPoint.x, oneHitPoint.y));
- assertEquals(two, document.elementFromPoint(twoHitPoint.x, twoHitPoint.y));
- assertEquals(three,
- document.elementFromPoint(threeHitPoint.x, threeHitPoint.y));
-});
-
-/** Tests we compute the correct name for hidden aria labelledby nodes. */
-TEST_F('CvoxDomUtilUnitTest', 'HiddenAriaLabelledby', function() {
- this.loadDoc(function() {/*!
- <span id="acc_name" style="display: none">
- hello world!
- </span>
- <button id="button" aria-labelledby="acc_name">
- */});
- assertEquals('hello world!',
- cvox.DomUtil.getName($('button')));
-});
-
-/** Tests that we compute the correct state for accesskeys. */
-TEST_F('CvoxDomUtilUnitTest', 'AccessKey', function() {
- this.loadDoc(function() {/*!
- <a id='accessKey' href="#f" title="Next page" accesskey="n">Next page</a>
- */});
- var a = $('accessKey');
- assertEquals('has access key, n', cvox.DomUtil.getState(a));
-});
-
-
-/** Tests that we compute the correct name for ordered listitems. */
-TEST_F('CvoxDomUtilUnitTest', 'OrderedListitem', function() {
- this.loadDoc(function() {/*!
- <ol id="fruits_ol">
- <li id='ol_li1'>apple
- <li id='ol_li2'>orange
- <li id='ol_li3'>strawberry
- <li id='ol_li4'>banana
- </ol>
- */});
- var li1 = $('ol_li1');
- var li2 = $('ol_li2');
- var li3 = $('ol_li3');
- var li4 = $('ol_li4');
- // Note that whitespace processing happens at a higher layer
- // (DescriptionUtil).
- assertEquals('1. apple',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li1)));
- assertEquals('2. orange',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li2)));
- assertEquals('3. strawberry',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li3)));
- assertEquals('4. banana',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li4)));
-
- $('fruits_ol').style.listStyleType = 'lower-latin';
-
- assertEquals('A. apple',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li1)));
- assertEquals('B. orange',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li2)));
- assertEquals('C. strawberry',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li3)));
- assertEquals('D. banana',
- cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li4)));
-});
-
-/** Tests a node with title, and textContent containing only whitespace. */
-TEST_F('CvoxDomUtilUnitTest', 'TitleOverridesInnerWhitespace', function() {
- this.loadDoc(function() {/*!
- <button id="btn1" title="Remove from Chrome">
- <span class="lid"></span>
- <span class="can"></span>
- </button>
- */});
- var btn1 = $('btn1');
- assertEquals('Remove from Chrome', cvox.DomUtil.getName(btn1));
-});
-
-/** Test memoization. **/
-TEST_F('CvoxDomUtilUnitTest', 'Memoization', function() {
- this.loadDoc(function() {/*!
- <div id="container">
- </div>
- */});
-
- // Nest divs 100 levels deep.
- var container = $('container');
- var outer = container;
- for (var i = 0; i < 100; i++) {
- var inner = document.createElement('div');
- outer.appendChild(inner);
- outer = inner;
- }
- var target = document.createElement('p');
- target.innerHTML = 'Text';
- outer.appendChild(target);
-
- var iterations = 200;
-
- function logTime(msg, fn) {
- var t0 = new Date();
- fn();
- console.log(msg + ' elapsed time: ' + (new Date() - t0) + ' ms');
- }
-
- // First, test without memoization.
- logTime('No memoization', function() {
- container.style.visibility = 'hidden';
- for (var i = 0; i < iterations; i++) {
- assertFalse(cvox.DomUtil.isVisible(target));
- }
- container.style.visibility = 'visible';
- for (var i = 0; i < iterations; i++) {
- assertTrue(cvox.DomUtil.isVisible(target));
- }
- });
-
- // Now test with memoization enabled.
- logTime('With memoization', function() {
- cvox.Memoize.scope(function() {
- container.style.visibility = 'hidden';
- for (var i = 0; i < iterations; i++) {
- assertFalse(cvox.DomUtil.isVisible(target));
- }
- });
- cvox.Memoize.scope(function() {
- container.style.visibility = 'visible';
- for (var i = 0; i < iterations; i++) {
- assertTrue(cvox.DomUtil.isVisible(target));
- }
- });
- });
-
- // Finally as a sanity check that things are being memoized, turn on
- // memoization and show that we get the wrong result if we change the
- // DOM and call isVisible again.
- cvox.Memoize.scope(function() {
- container.style.visibility = 'hidden';
- assertFalse(cvox.DomUtil.isVisible(target));
-
- container.style.visibility = 'visible';
- // This should be true! It will return the wrong answer because
- // we're deliberately leaving memoization on while modifying the DOM.
- assertFalse(cvox.DomUtil.isVisible(target));
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/earcon_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/earcon_util.js
deleted file mode 100644
index 51679ab007e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/earcon_util.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Earcon utils.
- */
-
-goog.provide('cvox.EarconUtil');
-
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.AriaUtil');
-goog.require('cvox.DomUtil');
-
-/**
- * Returns the id of an earcon to play along with the description for a node.
- *
- * @param {Node} node The node to get the earcon for.
- * @return {cvox.Earcon?} The earcon id, or null if none applies.
- */
-cvox.EarconUtil.getEarcon = function(node) {
- var earcon = cvox.AriaUtil.getEarcon(node);
- if (earcon != null) {
- return earcon;
- }
-
- switch (node.tagName) {
- case 'BUTTON':
- return cvox.Earcon.BUTTON;
- case 'A':
- if (node.hasAttribute('href')) {
- return cvox.Earcon.LINK;
- }
- break;
- case 'IMG':
- if (cvox.DomUtil.hasLongDesc(node)) {
- return cvox.Earcon.LONG_DESC;
- }
- break;
- case 'LI':
- return cvox.Earcon.LIST_ITEM;
- case 'SELECT':
- return cvox.Earcon.LISTBOX;
- case 'TEXTAREA':
- return cvox.Earcon.EDITABLE_TEXT;
- case 'INPUT':
- switch (node.type) {
- case 'button':
- case 'submit':
- case 'reset':
- return cvox.Earcon.BUTTON;
- case 'checkbox':
- case 'radio':
- if (node.checked) {
- return cvox.Earcon.CHECK_ON;
- } else {
- return cvox.Earcon.CHECK_OFF;
- }
- default:
- if (cvox.DomUtil.isInputTypeText(node)) {
- // 'text', 'password', etc.
- return cvox.Earcon.EDITABLE_TEXT;
- }
- }
- }
- return null;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text.js
deleted file mode 100644
index 9d116d24ed4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text.js
+++ /dev/null
@@ -1,649 +0,0 @@
-// 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.
-
-goog.provide('cvox.ChromeVoxEditableContentEditable');
-goog.provide('cvox.ChromeVoxEditableElement');
-goog.provide('cvox.ChromeVoxEditableHTMLInput');
-goog.provide('cvox.ChromeVoxEditableTextArea');
-goog.provide('cvox.TextHandlerInterface');
-
-
-goog.require('cvox.BrailleTextHandler');
-goog.require('cvox.ChromeVoxEditableTextBase');
-goog.require('cvox.ContentEditableExtractor');
-goog.require('cvox.DomUtil');
-goog.require('cvox.EditableTextAreaShadow');
-goog.require('cvox.TextChangeEvent');
-goog.require('cvox.TtsInterface');
-
-/**
- * @fileoverview Gives the user spoken and braille feedback as they type,
- * select text, and move the cursor in editable HTML text controls, including
- * multiline controls and contenteditable regions.
- *
- * The two subclasses, ChromeVoxEditableHTMLInput and
- * ChromeVoxEditableTextArea, take a HTML input (type=text) or HTML
- * textarea node (respectively) in the constructor, and automatically
- * handle retrieving the current state of the control, including
- * computing line break information for a textarea using an offscreen
- * shadow object. It is the responsibility of the user of these classes to
- * trap key and focus events and call the update method as needed.
- *
- */
-
-
-/**
- * An interface for being notified when the text changes.
- * @interface
- */
-cvox.TextHandlerInterface = function() {};
-
-
-/**
- * Called when text changes.
- * @param {cvox.TextChangeEvent} evt The text change event.
- */
-cvox.TextHandlerInterface.prototype.changed = function(evt) {};
-
-
-/**
- * A subclass of ChromeVoxEditableTextBase a text element that's part of
- * the webpage DOM. Contains common code shared by both EditableHTMLInput
- * and EditableTextArea, but that might not apply to a non-DOM text box.
- * @param {Element} node A DOM node which allows text input.
- * @param {string} value The string value of the editable text control.
- * @param {number} start The 0-based start cursor/selection index.
- * @param {number} end The 0-based end cursor/selection index.
- * @param {boolean} isPassword Whether the text control if a password field.
- * @param {cvox.TtsInterface} tts A TTS object.
- * @extends {cvox.ChromeVoxEditableTextBase}
- * @constructor
- */
-cvox.ChromeVoxEditableElement = function(node, value, start, end, isPassword,
- tts) {
- goog.base(this, value, start, end, isPassword, tts);
-
- /**
- * An optional handler for braille output.
- * @type {cvox.BrailleTextHandler|undefined}
- * @private
- */
- this.brailleHandler_ = cvox.ChromeVox.braille ?
- new cvox.BrailleTextHandler(cvox.ChromeVox.braille) : undefined;
-
- /**
- * The DOM node which allows text input.
- * @type {Element}
- * @protected
- */
- this.node = node;
-
- /**
- * True if the description was just spoken.
- * @type {boolean}
- * @private
- */
- this.justSpokeDescription_ = false;
-};
-goog.inherits(cvox.ChromeVoxEditableElement,
- cvox.ChromeVoxEditableTextBase);
-
-
-/** @override */
-cvox.ChromeVoxEditableElement.prototype.changed = function(evt) {
- // Ignore changes to the cursor and selection if they happen immediately
- // after the description was just spoken. This avoid double-speaking when,
- // for example, a text field is focused and then a moment later the
- // contents are selected. If the value changes, though, this change will
- // not be ignored.
- if (this.justSpokeDescription_ && this.value == evt.value) {
- this.value = evt.value;
- this.start = evt.start;
- this.end = evt.end;
- this.justSpokeDescription_ = false;
- }
- goog.base(this, 'changed', evt);
- if (this.lastChangeDescribed) {
- this.brailleCurrentLine_();
- }
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableElement.prototype.speak = function(
- str, opt_triggeredByUser, opt_personality) {
- // If there is a node associated with the editable text object,
- // make sure that node has focus before speaking it.
- if (this.node && (document.activeElement != this.node)) {
- return;
- }
- goog.base(this, 'speak', str, opt_triggeredByUser, opt_personality);
-};
-
-/** @override */
-cvox.ChromeVoxEditableElement.prototype.moveCursorToNextCharacter = function() {
- var node = this.node;
- node.selectionEnd++;
- node.selectionStart = node.selectionEnd;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableElement.prototype.moveCursorToPreviousCharacter =
- function() {
- var node = this.node;
- node.selectionStart--;
- node.selectionEnd = node.selectionStart;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableElement.prototype.moveCursorToNextWord = function() {
- var node = this.node;
- var length = node.value.length;
- var re = /\W+/gm;
- var substring = node.value.substring(node.selectionEnd);
- var match = re.exec(substring);
- if (match !== null && match.index == 0) {
- // Ignore word-breaking sequences right next to the cursor.
- match = re.exec(substring);
- }
- var index = (match === null) ? length : match.index + node.selectionEnd;
- node.selectionStart = node.selectionEnd = index;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableElement.prototype.moveCursorToPreviousWord = function() {
- var node = this.node;
- var length = node.value.length;
- var re = /\W+/gm;
- var substring = node.value.substring(0, node.selectionStart);
- var index = 0;
- while (re.exec(substring) !== null) {
- if (re.lastIndex < node.selectionStart) {
- index = re.lastIndex;
- }
- }
- node.selectionStart = node.selectionEnd = index;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableElement.prototype.moveCursorToNextParagraph =
- function() {
- var node = this.node;
- var length = node.value.length;
- var index = node.selectionEnd >= length ? length :
- node.value.indexOf('\n', node.selectionEnd);
- if (index < 0) {
- index = length;
- }
- node.selectionStart = node.selectionEnd = index + 1;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableElement.prototype.moveCursorToPreviousParagraph =
- function() {
- var node = this.node;
- var index = node.selectionStart <= 0 ? 0 :
- node.value.lastIndexOf('\n', node.selectionStart - 2) + 1;
- if (index < 0) {
- index = 0;
- }
- node.selectionStart = node.selectionEnd = index;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-/**
- * Shows the current line on the braille display.
- * @private
- */
-cvox.ChromeVoxEditableElement.prototype.brailleCurrentLine_ = function() {
- if (this.brailleHandler_) {
- var lineIndex = this.getLineIndex(this.start);
- var line = this.getLine(lineIndex);
- // Collapsable whitespace inside the contenteditable is represented
- // as non-breaking spaces. This confuses braille input (which relies on
- // the text being added to be the same as the text in the input field).
- // Since the non-breaking spaces are just an artifact of how
- // contenteditable is implemented, normalize to normal spaces instead.
- if (this instanceof cvox.ChromeVoxEditableContentEditable) {
- line = line.replace(/\u00A0/g, ' ');
- }
- var lineStart = this.getLineStart(lineIndex);
- var start = this.start - lineStart;
- var end = Math.min(this.end - lineStart, line.length);
- this.brailleHandler_.changed(line, start, end, this.multiline, this.node,
- lineStart);
- }
-};
-
-/******************************************/
-
-
-/**
- * A subclass of ChromeVoxEditableElement for an HTMLInputElement.
- * @param {HTMLInputElement} node The HTMLInputElement node.
- * @param {cvox.TtsInterface} tts A TTS object.
- * @extends {cvox.ChromeVoxEditableElement}
- * @implements {cvox.TextHandlerInterface}
- * @constructor
- */
-cvox.ChromeVoxEditableHTMLInput = function(node, tts) {
- this.node = node;
- this.setup();
- goog.base(this,
- node,
- node.value,
- node.selectionStart,
- node.selectionEnd,
- node.type === 'password',
- tts);
-};
-goog.inherits(cvox.ChromeVoxEditableHTMLInput,
- cvox.ChromeVoxEditableElement);
-
-
-/**
- * Performs setup for this input node.
- * This accounts for exception-throwing behavior introduced by crbug.com/324360.
- * @override
- */
-cvox.ChromeVoxEditableHTMLInput.prototype.setup = function() {
- if (!this.node) {
- return;
- }
- if (!cvox.DomUtil.doesInputSupportSelection(this.node)) {
- this.originalType = this.node.type;
- this.node.type = 'text';
- }
-};
-
-
-/**
- * Performs teardown for this input node.
- * This accounts for exception-throwing behavior introduced by crbug.com/324360.
- * @override
- */
-cvox.ChromeVoxEditableHTMLInput.prototype.teardown = function() {
- if (this.node && this.originalType) {
- this.node.type = this.originalType;
- }
-};
-
-
-/**
- * Update the state of the text and selection and describe any changes as
- * appropriate.
- *
- * @param {boolean} triggeredByUser True if this was triggered by a user action.
- */
-cvox.ChromeVoxEditableHTMLInput.prototype.update = function(triggeredByUser) {
- var newValue = this.node.value;
- var textChangeEvent = new cvox.TextChangeEvent(newValue,
- this.node.selectionStart,
- this.node.selectionEnd,
- triggeredByUser);
- this.changed(textChangeEvent);
-};
-
-
-/******************************************/
-
-
-/**
- * A subclass of ChromeVoxEditableElement for an HTMLTextAreaElement.
- * @param {HTMLTextAreaElement} node The HTMLTextAreaElement node.
- * @param {cvox.TtsInterface} tts A TTS object.
- * @extends {cvox.ChromeVoxEditableElement}
- * @implements {cvox.TextHandlerInterface}
- * @constructor
- */
-cvox.ChromeVoxEditableTextArea = function(node, tts) {
- goog.base(this, node, node.value, node.selectionStart, node.selectionEnd,
- false /* isPassword */, tts);
- this.multiline = true;
-
- /**
- * True if the shadow is up-to-date with the current value of this text area.
- * @type {boolean}
- * @private
- */
- this.shadowIsCurrent_ = false;
-};
-goog.inherits(cvox.ChromeVoxEditableTextArea,
- cvox.ChromeVoxEditableElement);
-
-
-/**
- * An offscreen div used to compute the line numbers. A single div is
- * shared by all instances of the class.
- * @type {!cvox.EditableTextAreaShadow|undefined}
- * @private
- */
-cvox.ChromeVoxEditableTextArea.shadow_;
-
-
-/**
- * Update the state of the text and selection and describe any changes as
- * appropriate.
- *
- * @param {boolean} triggeredByUser True if this was triggered by a user action.
- */
-cvox.ChromeVoxEditableTextArea.prototype.update = function(triggeredByUser) {
- if (this.node.value != this.value) {
- this.shadowIsCurrent_ = false;
- }
- var textChangeEvent = new cvox.TextChangeEvent(this.node.value,
- this.node.selectionStart, this.node.selectionEnd, triggeredByUser);
- this.changed(textChangeEvent);
-};
-
-
-/**
- * Get the line number corresponding to a particular index.
- * @param {number} index The 0-based character index.
- * @return {number} The 0-based line number corresponding to that character.
- */
-cvox.ChromeVoxEditableTextArea.prototype.getLineIndex = function(index) {
- return this.getShadow().getLineIndex(index);
-};
-
-
-/**
- * Get the start character index of a line.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the first character in this line.
- */
-cvox.ChromeVoxEditableTextArea.prototype.getLineStart = function(index) {
- return this.getShadow().getLineStart(index);
-};
-
-
-/**
- * Get the end character index of a line.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the end of this line.
- */
-cvox.ChromeVoxEditableTextArea.prototype.getLineEnd = function(index) {
- return this.getShadow().getLineEnd(index);
-};
-
-
-/**
- * Update the shadow object, an offscreen div used to compute line numbers.
- * @return {!cvox.EditableTextAreaShadow} The shadow object.
- */
-cvox.ChromeVoxEditableTextArea.prototype.getShadow = function() {
- var shadow = cvox.ChromeVoxEditableTextArea.shadow_;
- if (!shadow) {
- shadow = cvox.ChromeVoxEditableTextArea.shadow_ =
- new cvox.EditableTextAreaShadow();
- }
- if (!this.shadowIsCurrent_) {
- shadow.update(this.node);
- this.shadowIsCurrent_ = true;
- }
- return shadow;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableTextArea.prototype.moveCursorToNextLine = function() {
- var node = this.node;
- var length = node.value.length;
- if (node.selectionEnd >= length) {
- return false;
- }
- var shadow = this.getShadow();
- var lineIndex = shadow.getLineIndex(node.selectionEnd);
- var lineStart = shadow.getLineStart(lineIndex);
- var offset = node.selectionEnd - lineStart;
- var lastLine = (length == 0) ? 0 : shadow.getLineIndex(length - 1);
- var newCursorPosition = (lineIndex >= lastLine) ? length :
- Math.min(shadow.getLineStart(lineIndex + 1) + offset,
- shadow.getLineEnd(lineIndex + 1));
- node.selectionStart = node.selectionEnd = newCursorPosition;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableTextArea.prototype.moveCursorToPreviousLine = function() {
- var node = this.node;
- if (node.selectionStart <= 0) {
- return false;
- }
- var shadow = this.getShadow();
- var lineIndex = shadow.getLineIndex(node.selectionStart);
- var lineStart = shadow.getLineStart(lineIndex);
- var offset = node.selectionStart - lineStart;
- var newCursorPosition = (lineIndex <= 0) ? 0 :
- Math.min(shadow.getLineStart(lineIndex - 1) + offset,
- shadow.getLineEnd(lineIndex - 1));
- node.selectionStart = node.selectionEnd = newCursorPosition;
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/******************************************/
-
-
-/**
- * A subclass of ChromeVoxEditableElement for elements that are contentEditable.
- * This is also used for a region of HTML with the ARIA role of "textbox",
- * so that an author can create a pure-JavaScript editable text object - this
- * will work the same as contentEditable as long as the DOM selection is
- * updated properly within the textbox when it has focus.
- * @param {Element} node The root contentEditable node.
- * @param {cvox.TtsInterface} tts A TTS object.
- * @extends {cvox.ChromeVoxEditableElement}
- * @implements {cvox.TextHandlerInterface}
- * @constructor
- */
-cvox.ChromeVoxEditableContentEditable = function(node, tts) {
- goog.base(this, node, '', 0, 0, false /* isPassword */, tts);
-
-
- /**
- * True if the ContentEditableExtractor is current with this field's data.
- * @type {boolean}
- * @private
- */
- this.extractorIsCurrent_ = false;
-
- var extractor = this.getExtractor();
- this.value = extractor.getText();
- this.start = extractor.getStartIndex();
- this.end = extractor.getEndIndex();
- this.multiline = true;
-};
-goog.inherits(cvox.ChromeVoxEditableContentEditable,
- cvox.ChromeVoxEditableElement);
-
-/**
- * A helper used to compute the line numbers. A single object is
- * shared by all instances of the class.
- * @type {!cvox.ContentEditableExtractor|undefined}
- * @private
- */
-cvox.ChromeVoxEditableContentEditable.extractor_;
-
-
-/**
- * Update the state of the text and selection and describe any changes as
- * appropriate.
- *
- * @param {boolean} triggeredByUser True if this was triggered by a user action.
- */
-cvox.ChromeVoxEditableContentEditable.prototype.update =
- function(triggeredByUser) {
- this.extractorIsCurrent_ = false;
- var textChangeEvent = new cvox.TextChangeEvent(
- this.getExtractor().getText(),
- this.getExtractor().getStartIndex(),
- this.getExtractor().getEndIndex(),
- triggeredByUser);
- this.changed(textChangeEvent);
-};
-
-
-/**
- * Get the line number corresponding to a particular index.
- * @param {number} index The 0-based character index.
- * @return {number} The 0-based line number corresponding to that character.
- */
-cvox.ChromeVoxEditableContentEditable.prototype.getLineIndex = function(index) {
- return this.getExtractor().getLineIndex(index);
-};
-
-
-/**
- * Get the start character index of a line.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the first character in this line.
- */
-cvox.ChromeVoxEditableContentEditable.prototype.getLineStart = function(index) {
- return this.getExtractor().getLineStart(index);
-};
-
-
-/**
- * Get the end character index of a line.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the end of this line.
- */
-cvox.ChromeVoxEditableContentEditable.prototype.getLineEnd = function(index) {
- return this.getExtractor().getLineEnd(index);
-};
-
-
-/**
- * Update the extractor object, an offscreen div used to compute line numbers.
- * @return {!cvox.ContentEditableExtractor} The extractor object.
- */
-cvox.ChromeVoxEditableContentEditable.prototype.getExtractor = function() {
- var extractor = cvox.ChromeVoxEditableContentEditable.extractor_;
- if (!extractor) {
- extractor = cvox.ChromeVoxEditableContentEditable.extractor_ =
- new cvox.ContentEditableExtractor();
- }
- if (!this.extractorIsCurrent_) {
- extractor.update(this.node);
- this.extractorIsCurrent_ = true;
- }
- return extractor;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableContentEditable.prototype.changed =
- function(evt) {
- if (!evt.triggeredByUser) {
- return;
- }
- // Take over here if we can't describe a change; assume it's a blank line.
- if (!this.shouldDescribeChange(evt)) {
- this.speak(Msgs.getMsg('text_box_blank'), true);
- if (this.brailleHandler_) {
- this.brailleHandler_.changed('' /*line*/, 0 /*start*/, 0 /*end*/,
- true /*multiline*/, null /*element*/,
- evt.start /*lineStart*/);
- }
- } else {
- goog.base(this, 'changed', evt);
- }
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableContentEditable.prototype.moveCursorToNextCharacter =
- function() {
- window.getSelection().modify('move', 'forward', 'character');
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableContentEditable.prototype.moveCursorToPreviousCharacter =
- function() {
- window.getSelection().modify('move', 'backward', 'character');
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/** @override */
-cvox.ChromeVoxEditableContentEditable.prototype.moveCursorToNextParagraph =
- function() {
- window.getSelection().modify('move', 'forward', 'paragraph');
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-/** @override */
-cvox.ChromeVoxEditableContentEditable.prototype.moveCursorToPreviousParagraph =
- function() {
- window.getSelection().modify('move', 'backward', 'paragraph');
- cvox.ChromeVoxEventWatcher.handleTextChanged(true);
- return true;
-};
-
-
-/**
- * @override
- */
-cvox.ChromeVoxEditableContentEditable.prototype.shouldDescribeChange =
- function(evt) {
- var sel = window.getSelection();
- var cursor = new cvox.Cursor(sel.baseNode, sel.baseOffset, '');
-
- // This is a very specific work around because of our buggy content editable
- // support. Blank new lines are not captured in the line indexing data
- // structures.
- // Scenario: given a piece of text like:
- //
- // Some Title
- //
- // Description
- // Footer
- //
- // The new lines after Title are not traversed to by TraverseUtil. A root fix
- // would make changes there. However, considering the fickle nature of that
- // code, we specifically detect for new lines here.
- if (Math.abs(this.start - evt.start) != 1 &&
- this.start == this.end &&
- evt.start == evt.end &&
- sel.baseNode == sel.extentNode &&
- sel.baseOffset == sel.extentOffset &&
- sel.baseNode.nodeType == Node.ELEMENT_NODE &&
- sel.baseNode.querySelector('BR') &&
- cvox.TraverseUtil.forwardsChar(cursor, [], [])) {
- // This case detects if the range selection surrounds a new line,
- // but there is still content after the new line (like the example
- // above after "Title"). In these cases, we "pretend" we're the
- // last character so we speak "blank".
- return false;
- }
-
- // Otherwise, we should never speak "blank" no matter what (even if
- // we're at the end of a content editable).
- return true;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_area_shadow.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_area_shadow.js
deleted file mode 100644
index bd381156c69..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_area_shadow.js
+++ /dev/null
@@ -1,190 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Defines the EditableTextAreaShadow class.
- */
-
-goog.provide('cvox.EditableTextAreaShadow');
-
-/**
- * Creates a shadow element for an editable text area used to compute line
- * numbers.
- * @constructor
- */
-cvox.EditableTextAreaShadow = function() {
- /**
- * @type {Element}
- * @private
- */
- this.shadowElement_ = document.createElement('div');
-
- /**
- * Map from line index to a data structure containing the start
- * and end index within the line.
- * @type {Object<number, {startIndex: number, endIndex: number}>}
- * @private
- */
- this.lines_ = {};
-
- /**
- * Map from 0-based character index to 0-based line index.
- * @type {Array<number>}
- * @private
- */
- this.characterToLineMap_ = [];
-};
-
-/**
- * Update the shadow element.
- * @param {Element} element The textarea element.
- */
-cvox.EditableTextAreaShadow.prototype.update = function(element) {
- document.body.appendChild(this.shadowElement_);
-
- while (this.shadowElement_.childNodes.length) {
- this.shadowElement_.removeChild(this.shadowElement_.childNodes[0]);
- }
- this.shadowElement_.style.cssText =
- window.getComputedStyle(element, null).cssText;
- this.shadowElement_.style.position = 'absolute';
- this.shadowElement_.style.top = -9999;
- this.shadowElement_.style.left = -9999;
- this.shadowElement_.setAttribute('aria-hidden', 'true');
-
- // Add the text to the shadow element, but with an extra character to the
- // end so that we can get the bounding box of the last line - we can't
- // measure blank lines otherwise.
- var text = element.value;
- var textNode = document.createTextNode(text + '.');
- this.shadowElement_.appendChild(textNode);
-
- /**
- * For extra speed, try to skip this many characters at a time - if
- * none of the characters are newlines and they're all at the same
- * vertical position, we don't have to examine each one. If not,
- * fall back to moving by one character at a time.
- * @const
- */
- var SKIP = 8;
-
- /**
- * Map from line index to a data structure containing the start
- * and end index within the line.
- * @type {Object<number, {startIndex: number, endIndex: number}>}
- */
- var lines = {0: {startIndex: 0, endIndex: 0}};
-
- var range = document.createRange();
- var offset = 0;
- var lastGoodOffset = 0;
- var lineIndex = 0;
- var lastBottom = null;
- var nearNewline = false;
- var rect;
- while (offset <= text.length) {
- range.setStart(textNode, offset);
-
- // If we're near the end or if there's an explicit newline character,
- // don't even try to skip.
- if (offset + SKIP > text.length ||
- text.substr(offset, SKIP).indexOf('\n') >= 0) {
- nearNewline = true;
- }
-
- if (nearNewline) {
- // Move by one character.
- offset++;
- range.setEnd(textNode, offset);
- rect = range.getBoundingClientRect();
- } else {
- // Try to move by |SKIP| characters.
- range.setEnd(textNode, offset + SKIP);
- rect = range.getBoundingClientRect();
- if (rect.bottom == lastBottom) {
- // Great, they all seem to be on the same line.
- offset += SKIP;
- } else {
- // Nope, there might be a newline, better go one at a time to be safe.
- if (rect && lastBottom !== null) {
- nearNewline = true;
- }
- offset++;
- range.setEnd(textNode, offset);
- rect = range.getBoundingClientRect();
- }
- }
-
- if (offset > 0 && text[offset - 1] == '\n') {
- // Handle an explicit newline character - that always results in
- // a new line.
- lines[lineIndex].endIndex = offset - 1;
- lineIndex++;
- lines[lineIndex] = {startIndex: offset, endIndex: offset};
- lastBottom = null;
- nearNewline = false;
- lastGoodOffset = offset;
- } else if (rect && (lastBottom === null)) {
- // This is the first character we've successfully measured on this
- // line. Save the vertical position but don't do anything else.
- lastBottom = rect.bottom;
- } else if (rect && rect.bottom != lastBottom) {
- // This character is at a different vertical position, so place an
- // implicit newline immediately after the *previous* good character
- // we found (which we now know was the last character of the previous
- // line).
- lines[lineIndex].endIndex = lastGoodOffset;
- lineIndex++;
- lines[lineIndex] = {startIndex: lastGoodOffset, endIndex: lastGoodOffset};
- lastBottom = rect ? rect.bottom : null;
- nearNewline = false;
- }
-
- if (rect) {
- lastGoodOffset = offset;
- }
- }
- // Finish up the last line.
- lines[lineIndex].endIndex = text.length;
-
- // Create a map from character index to line number.
- var characterToLineMap = [];
- for (var i = 0; i <= lineIndex; i++) {
- for (var j = lines[i].startIndex; j <= lines[i].endIndex; j++) {
- characterToLineMap[j] = i;
- }
- }
-
- // Finish updating fields and remove the shadow element.
- this.characterToLineMap_ = characterToLineMap;
- this.lines_ = lines;
- document.body.removeChild(this.shadowElement_);
-};
-
-/**
- * Get the line number corresponding to a particular index.
- * @param {number} index The 0-based character index.
- * @return {number} The 0-based line number corresponding to that character.
- */
-cvox.EditableTextAreaShadow.prototype.getLineIndex = function(index) {
- return this.characterToLineMap_[index];
-};
-
-/**
- * Get the start character index of a line.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the first character in this line.
- */
-cvox.EditableTextAreaShadow.prototype.getLineStart = function(index) {
- return this.lines_[index].startIndex;
-};
-
-/**
- * Get the end character index of a line.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the end of this line.
- */
-cvox.EditableTextAreaShadow.prototype.getLineEnd = function(index) {
- return this.lines_[index].endIndex;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_area_shadow_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_area_shadow_test.unitjs
deleted file mode 100644
index ce874225246..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_area_shadow_test.unitjs
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxShadowUnitTest() {}
-
-CvoxShadowUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.EditableTextAreaShadow'
- ]
-};
-
-TEST_F('CvoxShadowUnitTest', 'MultilineLines', function() {
- this.loadDoc(function() {/*!
- <div><textarea id="area">
-one
-
-two
-
-three
-</textarea></div> */});
-
- var area = $('area');
-
- var shadow = new cvox.EditableTextAreaShadow();
- shadow.update(area);
- assertEquals(0, shadow.getLineIndex(0));
- assertEquals(0, shadow.getLineIndex(3));
- assertEquals(1, shadow.getLineIndex(4));
- assertEquals(2, shadow.getLineIndex(5));
- assertEquals(2, shadow.getLineIndex(8));
- assertEquals(3, shadow.getLineIndex(9));
- assertEquals(4, shadow.getLineIndex(10));
- assertEquals(4, shadow.getLineIndex(14));
-});
-
-/**
- * Test the get line of a multiline textarea with wrapping instead of
- * explicit newlines.
- * Test disabled due to not being reliable if font size changes.
- * See https://codereview.chromium.org/549303004/
- */
-TEST_F('CvoxShadowUnitTest', 'DISABLED_MultilineWrap', function() {
- this.loadDoc(function() {/*!
- <div><textarea id="area"
- cols=4 rows=20>One two thr fou fiv six sev eig</textarea>
- </div> */});
-
- var area = $('area');
-
- var shadow = new cvox.EditableTextAreaShadow();
- shadow.update(area);
- for (var i = 0; i < 32; i++) {
- assertEquals(Math.floor(i / 4), shadow.getLineIndex(i));
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js
deleted file mode 100644
index e1f3c27ba38..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js
+++ /dev/null
@@ -1,712 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-goog.provide('cvox.ChromeVoxEditableTextBase');
-goog.provide('cvox.TextChangeEvent');
-goog.provide('cvox.TypingEcho');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.TtsInterface');
-goog.require('goog.i18n.MessageFormat');
-
-
-/**
- * @fileoverview Generalized logic for providing spoken feedback when editing
- * text fields, both single and multiline fields.
- *
- * {@code ChromeVoxEditableTextBase} is a generalized class that takes the
- * current state in the form of a text string, a cursor start location and a
- * cursor end location, and calls a speak method with the resulting text to
- * be spoken. This class can be used directly for single line fields or
- * extended to override methods that extract lines for multiline fields
- * or to provide other customizations.
- */
-
-
-/**
- * A class containing the information needed to speak
- * a text change event to the user.
- *
- * @constructor
- * @param {string} newValue The new string value of the editable text control.
- * @param {number} newStart The new 0-based start cursor/selection index.
- * @param {number} newEnd The new 0-based end cursor/selection index.
- * @param {boolean} triggeredByUser .
- */
-cvox.TextChangeEvent = function(newValue, newStart, newEnd, triggeredByUser) {
- this.value = newValue;
- this.start = newStart;
- this.end = newEnd;
- this.triggeredByUser = triggeredByUser;
-
- // Adjust offsets to be in left to right order.
- if (this.start > this.end) {
- var tempOffset = this.end;
- this.end = this.start;
- this.start = tempOffset;
- }
-};
-
-
-/**
- * A list of typing echo options.
- * This defines the way typed characters get spoken.
- * CHARACTER: echoes typed characters.
- * WORD: echoes a word once a breaking character is typed (i.e. spacebar).
- * CHARACTER_AND_WORD: combines CHARACTER and WORD behavior.
- * NONE: speaks nothing when typing.
- * COUNT: The number of possible echo levels.
- * @enum
- */
-cvox.TypingEcho = {
- CHARACTER: 0,
- WORD: 1,
- CHARACTER_AND_WORD: 2,
- NONE: 3,
- COUNT: 4
-};
-
-
-/**
- * @param {number} cur Current typing echo.
- * @return {number} Next typing echo.
- */
-cvox.TypingEcho.cycle = function(cur) {
- return (cur + 1) % cvox.TypingEcho.COUNT;
-};
-
-
-/**
- * Return if characters should be spoken given the typing echo option.
- * @param {number} typingEcho Typing echo option.
- * @return {boolean} Whether the character should be spoken.
- */
-cvox.TypingEcho.shouldSpeakChar = function(typingEcho) {
- return typingEcho == cvox.TypingEcho.CHARACTER_AND_WORD ||
- typingEcho == cvox.TypingEcho.CHARACTER;
-};
-
-
-/**
- * A class representing an abstracted editable text control.
- * @param {string} value The string value of the editable text control.
- * @param {number} start The 0-based start cursor/selection index.
- * @param {number} end The 0-based end cursor/selection index.
- * @param {boolean} isPassword Whether the text control if a password field.
- * @param {cvox.TtsInterface} tts A TTS object.
- * @constructor
- */
-cvox.ChromeVoxEditableTextBase = function(value, start, end, isPassword, tts) {
- /**
- * Current value of the text field.
- * @type {string}
- * @protected
- */
- this.value = value;
-
- /**
- * 0-based selection start index.
- * @type {number}
- * @protected
- */
- this.start = start;
-
- /**
- * 0-based selection end index.
- * @type {number}
- * @protected
- */
- this.end = end;
-
- /**
- * True if this is a password field.
- * @type {boolean}
- * @protected
- */
- this.isPassword = isPassword;
-
- /**
- * Text-to-speech object implementing speak() and stop() methods.
- * @type {cvox.TtsInterface}
- * @protected
- */
- this.tts = tts;
-
- /**
- * Whether or not the text field is multiline.
- * @type {boolean}
- * @protected
- */
- this.multiline = false;
-
- /**
- * Whether or not the last update to the text and selection was described.
- *
- * Some consumers of this flag like |ChromeVoxEventWatcher| depend on and
- * react to when this flag is false by generating alternative feedback.
- * @type {boolean}
- */
- this.lastChangeDescribed = false;
-
-};
-
-
-/**
- * Performs setup for this element.
- */
-cvox.ChromeVoxEditableTextBase.prototype.setup = function() {};
-
-
-/**
- * Performs teardown for this element.
- */
-cvox.ChromeVoxEditableTextBase.prototype.teardown = function() {};
-
-
-/**
- * Whether or not moving the cursor from one character to another considers
- * the cursor to be a block (false) or an i-beam (true).
- *
- * If the cursor is a block, then the value of the character to the right
- * of the cursor index is always read when the cursor moves, no matter what
- * the previous cursor location was - this is how PC screenreaders work.
- *
- * If the cursor is an i-beam, moving the cursor by one character reads the
- * character that was crossed over, which may be the character to the left or
- * right of the new cursor index depending on the direction.
- *
- * If the current platform is a Mac, we will use an i-beam cursor. If not,
- * then we will use the block cursor.
- *
- * @type {boolean}
- */
-cvox.ChromeVoxEditableTextBase.useIBeamCursor = cvox.ChromeVox.isMac;
-
-
-/**
- * Switches on or off typing echo based on events. When set, editable text
- * updates for single-character insertions are handled in event watcher's key
- * press handler.
- * @type {boolean}
- */
-cvox.ChromeVoxEditableTextBase.eventTypingEcho = false;
-
-
-/**
- * The maximum number of characters that are short enough to speak in response
- * to an event. For example, if the user selects "Hello", we will speak
- * "Hello, selected", but if the user selects 1000 characters, we will speak
- * "text selected" instead.
- *
- * @type {number}
- */
-cvox.ChromeVoxEditableTextBase.prototype.maxShortPhraseLen = 60;
-
-
-/**
- * Get the line number corresponding to a particular index.
- * Default implementation that can be overridden by subclasses.
- * @param {number} index The 0-based character index.
- * @return {number} The 0-based line number corresponding to that character.
- */
-cvox.ChromeVoxEditableTextBase.prototype.getLineIndex = function(index) {
- return 0;
-};
-
-
-/**
- * Get the start character index of a line.
- * Default implementation that can be overridden by subclasses.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the first character in this line.
- */
-cvox.ChromeVoxEditableTextBase.prototype.getLineStart = function(index) {
- return 0;
-};
-
-
-/**
- * Get the end character index of a line.
- * Default implementation that can be overridden by subclasses.
- * @param {number} index The 0-based line index.
- * @return {number} The 0-based index of the end of this line.
- */
-cvox.ChromeVoxEditableTextBase.prototype.getLineEnd = function(index) {
- return this.value.length;
-};
-
-
-/**
- * Get the full text of the current line.
- * @param {number} index The 0-based line index.
- * @return {string} The text of the line.
- */
-cvox.ChromeVoxEditableTextBase.prototype.getLine = function(index) {
- var lineStart = this.getLineStart(index);
- var lineEnd = this.getLineEnd(index);
- return this.value.substr(lineStart, lineEnd - lineStart);
-};
-
-
-/**
- * @param {string} ch The character to test.
- * @return {boolean} True if a character is whitespace.
- */
-cvox.ChromeVoxEditableTextBase.prototype.isWhitespaceChar = function(ch) {
- return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
-};
-
-
-/**
- * @param {string} ch The character to test.
- * @return {boolean} True if a character breaks a word, used to determine
- * if the previous word should be spoken.
- */
-cvox.ChromeVoxEditableTextBase.prototype.isWordBreakChar = function(ch) {
- return !!ch.match(/^\W$/);
-};
-
-
-/**
- * @param {cvox.TextChangeEvent} evt The new text changed event to test.
- * @return {boolean} True if the event, when compared to the previous text,
- * should trigger description.
- */
-cvox.ChromeVoxEditableTextBase.prototype.shouldDescribeChange = function(evt) {
- if (evt.value == this.value &&
- evt.start == this.start &&
- evt.end == this.end) {
- return false;
- }
- return true;
-};
-
-
-/**
- * Speak text, but if it's a single character, describe the character.
- * @param {string} str The string to speak.
- * @param {boolean=} opt_triggeredByUser True if the speech was triggered by a
- * user action.
- * @param {Object=} opt_personality Personality used to speak text.
- */
-cvox.ChromeVoxEditableTextBase.prototype.speak =
- function(str, opt_triggeredByUser, opt_personality) {
- var queueMode = cvox.QueueMode.QUEUE;
- if (opt_triggeredByUser === true) {
- queueMode = cvox.QueueMode.FLUSH;
- }
- this.tts.speak(str, queueMode, opt_personality || {});
-};
-
-
-/**
- * Update the state of the text and selection and describe any changes as
- * appropriate.
- *
- * @param {cvox.TextChangeEvent} evt The text change event.
- */
-cvox.ChromeVoxEditableTextBase.prototype.changed = function(evt) {
- if (!this.shouldDescribeChange(evt)) {
- this.lastChangeDescribed = false;
- return;
- }
-
- if (evt.value == this.value) {
- this.describeSelectionChanged(evt);
- } else {
- this.describeTextChanged(evt);
- }
- this.lastChangeDescribed = true;
-
- this.value = evt.value;
- this.start = evt.start;
- this.end = evt.end;
-};
-
-
-/**
- * Describe a change in the selection or cursor position when the text
- * stays the same.
- * @param {cvox.TextChangeEvent} evt The text change event.
- */
-cvox.ChromeVoxEditableTextBase.prototype.describeSelectionChanged =
- function(evt) {
- // TODO(deboer): Factor this into two function:
- // - one to determine the selection event
- // - one to speak
-
- if (this.isPassword) {
- this.speak((new goog.i18n.MessageFormat(Msgs.getMsg('dot'))
- .format({'COUNT': 1})), evt.triggeredByUser);
- return;
- }
- if (evt.start == evt.end) {
- // It's currently a cursor.
- if (this.start != this.end) {
- // It was previously a selection, so just announce 'unselected'.
- this.speak(Msgs.getMsg('Unselected'), evt.triggeredByUser);
- } else if (this.getLineIndex(this.start) !=
- this.getLineIndex(evt.start)) {
- // Moved to a different line; read it.
- var lineValue = this.getLine(this.getLineIndex(evt.start));
- if (lineValue == '') {
- lineValue = Msgs.getMsg('text_box_blank');
- } else if (/^\s+$/.test(lineValue)) {
- lineValue = Msgs.getMsg('text_box_whitespace');
- }
- this.speak(lineValue, evt.triggeredByUser);
- } else if (this.start == evt.start + 1 ||
- this.start == evt.start - 1) {
- // Moved by one character; read it.
- if (!cvox.ChromeVoxEditableTextBase.useIBeamCursor) {
- if (evt.start == this.value.length) {
- if (cvox.ChromeVox.verbosity == cvox.VERBOSITY_VERBOSE) {
- this.speak(Msgs.getMsg('end_of_text_verbose'),
- evt.triggeredByUser);
- } else {
- this.speak(Msgs.getMsg('end_of_text_brief'),
- evt.triggeredByUser);
- }
- } else {
- this.speak(this.value.substr(evt.start, 1),
- evt.triggeredByUser,
- {'phoneticCharacters': evt.triggeredByUser});
- }
- } else {
- this.speak(this.value.substr(Math.min(this.start, evt.start), 1),
- evt.triggeredByUser,
- {'phoneticCharacters': evt.triggeredByUser});
- }
- } else {
- // Moved by more than one character. Read all characters crossed.
- this.speak(this.value.substr(Math.min(this.start, evt.start),
- Math.abs(this.start - evt.start)), evt.triggeredByUser);
- }
- } else {
- // It's currently a selection.
- if (this.start + 1 == evt.start &&
- this.end == this.value.length &&
- evt.end == this.value.length) {
- // Autocomplete: the user typed one character of autocompleted text.
- this.speak(this.value.substr(this.start, 1), evt.triggeredByUser);
- this.speak(this.value.substr(evt.start));
- } else if (this.start == this.end) {
- // It was previously a cursor.
- this.speak(this.value.substr(evt.start, evt.end - evt.start),
- evt.triggeredByUser);
- this.speak(Msgs.getMsg('selected'));
- } else if (this.start == evt.start && this.end < evt.end) {
- this.speak(this.value.substr(this.end, evt.end - this.end),
- evt.triggeredByUser);
- this.speak(Msgs.getMsg('added_to_selection'));
- } else if (this.start == evt.start && this.end > evt.end) {
- this.speak(this.value.substr(evt.end, this.end - evt.end),
- evt.triggeredByUser);
- this.speak(Msgs.getMsg('removed_from_selection'));
- } else if (this.end == evt.end && this.start > evt.start) {
- this.speak(this.value.substr(evt.start, this.start - evt.start),
- evt.triggeredByUser);
- this.speak(Msgs.getMsg('added_to_selection'));
- } else if (this.end == evt.end && this.start < evt.start) {
- this.speak(this.value.substr(this.start, evt.start - this.start),
- evt.triggeredByUser);
- this.speak(Msgs.getMsg('removed_from_selection'));
- } else {
- // The selection changed but it wasn't an obvious extension of
- // a previous selection. Just read the new selection.
- this.speak(this.value.substr(evt.start, evt.end - evt.start),
- evt.triggeredByUser);
- this.speak(Msgs.getMsg('selected'));
- }
- }
-};
-
-
-/**
- * Describe a change where the text changes.
- * @param {cvox.TextChangeEvent} evt The text change event.
- */
-cvox.ChromeVoxEditableTextBase.prototype.describeTextChanged = function(evt) {
- var personality = {};
- if (evt.value.length < this.value.length) {
- personality = cvox.AbstractTts.PERSONALITY_DELETED;
- }
- if (this.isPassword) {
- this.speak((new goog.i18n.MessageFormat(Msgs.getMsg('dot'))
- .format({'COUNT': 1})), evt.triggeredByUser, personality);
- return;
- }
-
- var value = this.value;
- var len = value.length;
- var newLen = evt.value.length;
- var autocompleteSuffix = '';
- // Make a copy of evtValue and evtEnd to avoid changing anything in
- // the event itself.
- var evtValue = evt.value;
- var evtEnd = evt.end;
-
- // First, see if there's a selection at the end that might have been
- // added by autocomplete. If so, strip it off into a separate variable.
- if (evt.start < evtEnd && evtEnd == newLen) {
- autocompleteSuffix = evtValue.substr(evt.start);
- evtValue = evtValue.substr(0, evt.start);
- evtEnd = evt.start;
- }
-
- // Now see if the previous selection (if any) was deleted
- // and any new text was inserted at that character position.
- // This would handle pasting and entering text by typing, both from
- // a cursor and from a selection.
- var prefixLen = this.start;
- var suffixLen = len - this.end;
- if (newLen >= prefixLen + suffixLen + (evtEnd - evt.start) &&
- evtValue.substr(0, prefixLen) == value.substr(0, prefixLen) &&
- evtValue.substr(newLen - suffixLen) == value.substr(this.end)) {
- // However, in a dynamic content editable, defer to authoritative events
- // (clipboard, key press) to reduce guess work when observing insertions.
- // Only use this logic when observing deletions (and insertion of word
- // breakers).
- // TODO(dtseng): Think about a more reliable way to do this.
- if (!(this instanceof cvox.ChromeVoxEditableContentEditable) ||
- newLen < len ||
- this.isWordBreakChar(evt.value[newLen - 1] || '')) {
- this.describeTextChangedHelper(
- evt, prefixLen, suffixLen, autocompleteSuffix, personality);
- }
- return;
- }
-
- // Next, see if one or more characters were deleted from the previous
- // cursor position and the new cursor is in the expected place. This
- // handles backspace, forward-delete, and similar shortcuts that delete
- // a word or line.
- prefixLen = evt.start;
- suffixLen = newLen - evtEnd;
- if (this.start == this.end &&
- evt.start == evtEnd &&
- evtValue.substr(0, prefixLen) == value.substr(0, prefixLen) &&
- evtValue.substr(newLen - suffixLen) ==
- value.substr(len - suffixLen)) {
- this.describeTextChangedHelper(
- evt, prefixLen, suffixLen, autocompleteSuffix, personality);
- return;
- }
-
- // If all else fails, we assume the change was not the result of a normal
- // user editing operation, so we'll have to speak feedback based only
- // on the changes to the text, not the cursor position / selection.
- // First, restore the autocomplete text if any.
- evtValue += autocompleteSuffix;
-
- // Try to do a diff between the new and the old text. If it is a one character
- // insertion/deletion at the start or at the end, just speak that character.
- if ((evtValue.length == (value.length + 1)) ||
- ((evtValue.length + 1) == value.length)) {
- // The user added text either to the beginning or the end.
- if (evtValue.length > value.length) {
- if (evtValue.indexOf(value) == 0) {
- this.speak(evtValue[evtValue.length - 1], evt.triggeredByUser,
- personality);
- return;
- } else if (evtValue.indexOf(value) == 1) {
- this.speak(evtValue[0], evt.triggeredByUser, personality);
- return;
- }
- }
- // The user deleted text either from the beginning or the end.
- if (evtValue.length < value.length) {
- if (value.indexOf(evtValue) == 0) {
- this.speak(value[value.length - 1], evt.triggeredByUser, personality);
- return;
- } else if (value.indexOf(evtValue) == 1) {
- this.speak(value[0], evt.triggeredByUser, personality);
- return;
- }
- }
- }
-
- if (this.multiline) {
- // Fall back to announce deleted but omit the text that was deleted.
- if (evt.value.length < this.value.length) {
- this.speak(Msgs.getMsg('text_deleted'),
- evt.triggeredByUser, personality);
- }
- // The below is a somewhat loose way to deal with non-standard
- // insertions/deletions. Intentionally skip for multiline since deletion
- // announcements are covered above and insertions are non-standard (possibly
- // due to auto complete). Since content editable's often refresh content by
- // removing and inserting entire chunks of text, this type of logic often
- // results in unintended consequences such as reading all text when only one
- // character has been entered.
- return;
- }
-
- // If the text is short, just speak the whole thing.
- if (newLen <= this.maxShortPhraseLen) {
- this.describeTextChangedHelper(evt, 0, 0, '', personality);
- return;
- }
-
- // Otherwise, look for the common prefix and suffix, but back up so
- // that we can speak complete words, to be minimally confusing.
- prefixLen = 0;
- while (prefixLen < len &&
- prefixLen < newLen &&
- value[prefixLen] == evtValue[prefixLen]) {
- prefixLen++;
- }
- while (prefixLen > 0 && !this.isWordBreakChar(value[prefixLen - 1])) {
- prefixLen--;
- }
-
- suffixLen = 0;
- while (suffixLen < (len - prefixLen) &&
- suffixLen < (newLen - prefixLen) &&
- value[len - suffixLen - 1] == evtValue[newLen - suffixLen - 1]) {
- suffixLen++;
- }
- while (suffixLen > 0 && !this.isWordBreakChar(value[len - suffixLen])) {
- suffixLen--;
- }
-
- this.describeTextChangedHelper(evt, prefixLen, suffixLen, '', personality);
-};
-
-
-/**
- * The function called by describeTextChanged after it's figured out
- * what text was deleted, what text was inserted, and what additional
- * autocomplete text was added.
- * @param {cvox.TextChangeEvent} evt The text change event.
- * @param {number} prefixLen The number of characters in the common prefix
- * of this.value and newValue.
- * @param {number} suffixLen The number of characters in the common suffix
- * of this.value and newValue.
- * @param {string} autocompleteSuffix The autocomplete string that was added
- * to the end, if any. It should be spoken at the end of the utterance
- * describing the change.
- * @param {Object=} opt_personality Personality to speak the text.
- */
-cvox.ChromeVoxEditableTextBase.prototype.describeTextChangedHelper = function(
- evt, prefixLen, suffixLen, autocompleteSuffix, opt_personality) {
- var len = this.value.length;
- var newLen = evt.value.length;
- var deletedLen = len - prefixLen - suffixLen;
- var deleted = this.value.substr(prefixLen, deletedLen);
- var insertedLen = newLen - prefixLen - suffixLen;
- var inserted = evt.value.substr(prefixLen, insertedLen);
- var utterance = '';
- var triggeredByUser = evt.triggeredByUser;
-
- if (insertedLen > 1) {
- utterance = inserted;
- } else if (insertedLen == 1) {
- if ((cvox.ChromeVox.typingEcho == cvox.TypingEcho.WORD ||
- cvox.ChromeVox.typingEcho == cvox.TypingEcho.CHARACTER_AND_WORD) &&
- this.isWordBreakChar(inserted) &&
- prefixLen > 0 &&
- !this.isWordBreakChar(evt.value.substr(prefixLen - 1, 1))) {
- // Speak previous word.
- var index = prefixLen;
- while (index > 0 && !this.isWordBreakChar(evt.value[index - 1])) {
- index--;
- }
- if (index < prefixLen) {
- utterance = evt.value.substr(index, prefixLen + 1 - index);
- } else {
- utterance = inserted;
- triggeredByUser = false; // Implies QUEUE_MODE_QUEUE.
- }
- } else if (cvox.ChromeVox.typingEcho == cvox.TypingEcho.CHARACTER ||
- cvox.ChromeVox.typingEcho == cvox.TypingEcho.CHARACTER_AND_WORD) {
- // This particular case is handled in event watcher. See the key press
- // handler for more details.
- utterance = cvox.ChromeVoxEditableTextBase.eventTypingEcho ? '' :
- inserted;
- }
- } else if (deletedLen > 1 && !autocompleteSuffix) {
- utterance = deleted + ', deleted';
- } else if (deletedLen == 1) {
- utterance = deleted;
- }
-
- if (autocompleteSuffix && utterance) {
- utterance += ', ' + autocompleteSuffix;
- } else if (autocompleteSuffix) {
- utterance = autocompleteSuffix;
- }
-
- if (utterance) {
- this.speak(utterance, triggeredByUser, opt_personality);
- }
-};
-
-
-/**
- * Moves the cursor forward by one character.
- * @return {boolean} True if the action was handled.
- */
-cvox.ChromeVoxEditableTextBase.prototype.moveCursorToNextCharacter =
- function() { return false; };
-
-
-/**
- * Moves the cursor backward by one character.
- * @return {boolean} True if the action was handled.
- */
-cvox.ChromeVoxEditableTextBase.prototype.moveCursorToPreviousCharacter =
- function() { return false; };
-
-
-/**
- * Moves the cursor forward by one word.
- * @return {boolean} True if the action was handled.
- */
-cvox.ChromeVoxEditableTextBase.prototype.moveCursorToNextWord =
- function() { return false; };
-
-
-/**
- * Moves the cursor backward by one word.
- * @return {boolean} True if the action was handled.
- */
-cvox.ChromeVoxEditableTextBase.prototype.moveCursorToPreviousWord =
- function() { return false; };
-
-
-/**
- * Moves the cursor forward by one line.
- * @return {boolean} True if the action was handled.
- */
-cvox.ChromeVoxEditableTextBase.prototype.moveCursorToNextLine =
- function() { return false; };
-
-
-/**
- * Moves the cursor backward by one line.
- * @return {boolean} True if the action was handled.
- */
-cvox.ChromeVoxEditableTextBase.prototype.moveCursorToPreviousLine =
- function() { return false; };
-
-
-/**
- * Moves the cursor forward by one paragraph.
- * @return {boolean} True if the action was handled.
- */
-cvox.ChromeVoxEditableTextBase.prototype.moveCursorToNextParagraph =
- function() { return false; };
-
-
-/**
- * Moves the cursor backward by one paragraph.
- * @return {boolean} True if the action was handled.
- */
-cvox.ChromeVoxEditableTextBase.prototype.moveCursorToPreviousParagraph =
- function() { return false; };
-
-
-/******************************************/
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_test.unitjs
deleted file mode 100644
index a122d096cb8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/editable_text_test.unitjs
+++ /dev/null
@@ -1,693 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * A TTS class implementing speak and stop methods intended only for testing.
- * @constructor
- * @implements cvox.TtsInterface
- */
-function TestTts() {
- this.strings = [];
-}
-
-/**
- * The strings that were spoken since the last call to get().
- * @type {Array<string>}
- */
-TestTts.prototype.strings;
-
-/**
- * Returns the list of strings spoken since the last time this method was
- * called, and then clears the list.
- * @return {Array<string>} The list of strings.
- */
-TestTts.prototype.get = function() {
- var result = this.strings;
- this.strings = [];
- return result;
-};
-
-/** @override */
-TestTts.prototype.speak = function(text, queueMode, properties) {
- this.strings.push(text);
-};
-
-/** @override */
-TestTts.prototype.isSpeaking = function() {
- return false;
-};
-
-/** @override */
-TestTts.prototype.stop = function() {
- // Do nothing.
-};
-
-/** @override */
-TestTts.prototype.increaseOrDecreaseProperty =
- function(propertyName, increase) {
- // Do nothing.
-};
-
-/**
- * Stores the last braille content.
- * @constructor
- * @implements cvox.BrailleInterface
- */
-function TestBraille() {
- this.content = null;
-}
-
-/** @override */
-TestBraille.prototype.write = function(params) {
- this.content = params;
-};
-
-/**
- * Asserts the current braille content.
- *
- * @param {string} text Braille text.
- * @param {number=} opt_start Selection start.
- * @param {number=} opt_end Selection end.
- */
-TestBraille.assertContent = function(text, opt_start, opt_end) {
- var c = cvox.ChromeVox.braille.content;
- assertTrue(c != null);
- opt_start = opt_start !== undefined ? opt_start : -1;
- opt_end = opt_end !== undefined ? opt_end : opt_start;
- assertEquals(text, c.text.toString());
- assertEquals(opt_start, c.startIndex);
- assertEquals(opt_end, c.endIndex);
-};
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxEditableTextUnitTest() {}
-
-CvoxEditableTextUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ChromeVoxEditableElement',
- 'cvox.ChromeVoxEditableHTMLInput',
- 'cvox.ChromeVoxEditableTextBase',
- 'cvox.ChromeVoxEventWatcher',
- 'cvox.TextChangeEvent',
- 'cvox.TtsInterface',
- 'cvox.TypingEcho',
- ],
-
- /** @override */
- setUp: function() {
- // TODO: These tests are all assuming we used the IBeam cursor.
- // We need to add coverage for block cursor.
- cvox.ChromeVoxEditableTextBase.useIBeamCursor = true;
- cvox.ChromeVox.typingEcho = cvox.TypingEcho.CHARACTER_AND_WORD;
- cvox.ChromeVoxEditableTextBase.eventTypingEcho = false;
- cvox.ChromeVox.braille = new TestBraille();
-
- /** Simple mock. */
- Msgs = {};
-
- /**
- * Simply return the message id.
- * @param {string} msg Message id.
- * @return {string} Message id.
- */
- Msgs.getMsg = function(msg) {
- return msg;
- };
- },
-
- /**
- * Sets up for a cursor movement test.
- * @param {string} tagName Desired tag name, "input" or "textarea".
- * @return {Object} object containing the editable element, and functions
- * to prepare, run the test, and tear down.
- * @private
- */
- setUpForCursorTest_: function(tagName) {
- var element, editable;
- switch (tagName) {
- case 'input':
- element = document.createElement('input');
- editable = new cvox.ChromeVoxEditableHTMLInput(element, new TestTts());
- break;
- case 'textarea':
- element = document.createElement('textarea');
- editable = new cvox.ChromeVoxEditableTextArea(element, new TestTts());
- break;
- default:
- throw 'invalid tagName in setUpForCursorTest_';
- }
- document.body.appendChild(element);
- element.focus();
-
- var expect = function(str) {
- assertEquals(element.selectionStart, element.selectionEnd);
- assertEquals(str, element.value.substring(0, element.selectionStart) +
- '|' + element.value.substring(element.selectionEnd));
- };
- return {
- editable: editable,
- expect: expect,
- prepare: function(str) {
- var position = str.indexOf('|');
- var value = str.substring(0, position) + str.substring(position + 1);
- element.value = value;
- element.selectionStart = element.selectionEnd = position;
- editable.update(true /* triggeredByUser */);
- expect(str);
- },
- tearDown: function() {
- document.body.removeChild(element);
- }
- };
- }
-};
-
-TEST_F('CvoxEditableTextUnitTest', 'CursorNavigation', function() {
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableTextBase('Hello', 0, 0, false, tts);
-
- obj.changed(new cvox.TextChangeEvent('Hello', 1, 1));
- obj.changed(new cvox.TextChangeEvent('Hello', 2, 2));
- obj.changed(new cvox.TextChangeEvent('Hello', 3, 3));
- obj.changed(new cvox.TextChangeEvent('Hello', 4, 4));
- obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
- obj.changed(new cvox.TextChangeEvent('Hello', 4, 4));
- obj.changed(new cvox.TextChangeEvent('Hello', 3, 3));
- assertEqualStringArrays(['H', 'e', 'l', 'l', 'o',
- 'o', 'l'], tts.get());
- obj.changed(new cvox.TextChangeEvent('Hello', 0, 0));
- obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
- assertEqualStringArrays(['Hel', 'Hello'], tts.get());
-});
-
-/** Test typing words. */
-TEST_F('CvoxEditableTextUnitTest', 'TypingWords', function() {
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
- obj.changed(new cvox.TextChangeEvent('H', 1, 1));
- obj.changed(new cvox.TextChangeEvent('He', 2, 2));
- obj.changed(new cvox.TextChangeEvent('Hel', 3, 3));
- obj.changed(new cvox.TextChangeEvent('Hell', 4, 4));
- obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
- obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6));
- obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
- obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8));
- obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9));
- obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
- obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
- obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
- obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13));
- assertEqualStringArrays(['H', 'e', 'l', 'l', 'o', 'Hello,',
- ' ',
- 'W', 'o', 'r', 'l', 'd', 'World.'],
- tts.get());
-
- // Backspace
- obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
- obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
- obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
- assertEqualStringArrays(['.', 'd', 'l'], tts.get());
-
- // Forward-delete
- obj.changed(new cvox.TextChangeEvent('Hello, Wor', 9, 9));
- obj.changed(new cvox.TextChangeEvent('Hello, Wor', 8, 8));
- obj.changed(new cvox.TextChangeEvent('Hello, Wor', 7, 7));
- obj.changed(new cvox.TextChangeEvent('Hello, or', 7, 7));
- obj.changed(new cvox.TextChangeEvent('Hello, r', 7, 7));
- obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
- assertEqualStringArrays(['r', 'o', 'W', 'W', 'o', 'r'], tts.get());
-
- // Clear all
- obj.changed(new cvox.TextChangeEvent('', 0, 0));
- assertEqualStringArrays(['Hello, , deleted'], tts.get());
-
- // Paste / insert a whole word
- obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
- assertEqualStringArrays(['Hello'], tts.get());
- obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
- assertEqualStringArrays([', World'], tts.get());
-});
-
-/** Test selection. */
-TEST_F('CvoxEditableTextUnitTest', 'Selection', function() {
- var tts = new TestTts();
- var obj =
- new cvox.ChromeVoxEditableTextBase('Hello, world.', 0, 0, false, tts);
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 1));
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 2));
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 3));
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 4));
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 5));
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 6));
- assertEqualStringArrays(['H', 'selected',
- 'e', 'added_to_selection',
- 'l', 'added_to_selection',
- 'l', 'added_to_selection',
- 'o', 'added_to_selection',
- ',', 'added_to_selection'],
- tts.get());
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 12));
- assertEqualStringArrays([' world', 'added_to_selection'],
- tts.get());
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 1, 12));
- assertEqualStringArrays(['H', 'removed_from_selection'],
- tts.get());
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 2, 5));
- assertEqualStringArrays(['llo', 'selected'],
- tts.get());
- obj.changed(new cvox.TextChangeEvent('Hello, world.', 2, 2));
- assertEqualStringArrays(['Unselected'],
- tts.get());
-});
-
-
-/** Test multi-line text. */
-TEST_F('CvoxEditableTextUnitTest', 'MultiLineText', function() {
- var str = 'This string\nspans\nfive lines.\n \n';
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableElement(null, str, 0, 0, false, tts);
- obj.multiline = true;
- obj.getLineIndex = function(index) {
- if (index >= 33) {
- return 4;
- } else if (index >= 30) {
- return 3;
- } else if (index >= 18) {
- return 2;
- } else if (index >= 12) {
- return 1;
- } else {
- return 0;
- }
- };
- obj.getLineStart = function(index) {
- return [0, 12, 18, 30, 33][index];
- };
- obj.getLineEnd = function(index) {
- return [11, 17, 29, 32, 33][index];
- };
- assertEquals('This string', obj.getLine(0));
- obj.changed(new cvox.TextChangeEvent(str, 12, 12));
- assertEqualStringArrays(['spans'], tts.get());
- TestBraille.assertContent('spans', 0);
- obj.changed(new cvox.TextChangeEvent(str, 18, 18));
- assertEqualStringArrays(['five lines.'], tts.get());
- TestBraille.assertContent('five lines.', 0);
- obj.changed(new cvox.TextChangeEvent(str, 30, 30));
- assertEqualStringArrays(['text_box_whitespace'], tts.get());
- TestBraille.assertContent(' ', 0);
- obj.changed(new cvox.TextChangeEvent(str, 33, 33));
- assertEqualStringArrays(['text_box_blank'], tts.get());
- TestBraille.assertContent('', 0);
- obj.changed(new cvox.TextChangeEvent(str, 0, 1));
- assertEqualStringArrays(['T', 'selected'], tts.get());
- TestBraille.assertContent('This string', 0, 1);
- obj.changed(new cvox.TextChangeEvent(str, 0, 12));
- assertEqualStringArrays(['his string\n', 'added_to_selection'],
- tts.get());
- // Newline stripped, thus 11, not 12.
- TestBraille.assertContent('This string', 0, 11);
- obj.changed(new cvox.TextChangeEvent(str, 0, str.length));
- assertEqualStringArrays([str.substr(12), 'added_to_selection'],
- tts.get());
- TestBraille.assertContent('This string', 0, 11);
- obj.changed(new cvox.TextChangeEvent(str, 12, 19));
- assertEqualStringArrays(['spans\nf', 'selected'], tts.get());
- TestBraille.assertContent('spans', 0, 5);
-});
-
-
-/**
- * Test autocomplete; suppose a user is typing "google.com/firefox" into an
- * address bar, and it's being autocompleted. Sometimes it's autocompleted
- * as they type, sometimes there's a short delay.
- */
-TEST_F('CvoxEditableTextUnitTest', 'Autocomplete', function() {
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
-
- // User types 'g'
- obj.changed(new cvox.TextChangeEvent('g', 1, 1));
- assertEqualStringArrays(['g'], tts.get());
-
- // The rest of 'google.com' is autocompleted and automatically selected.
- obj.changed(new cvox.TextChangeEvent('google.com', 1, 10));
- assertEqualStringArrays(['oogle.com, oogle.com'], tts.get());
-
- // The user doesn't realize it and types a few more characters of 'google.com'
- // and this changes the selection (unselecting) as the user types them.
- obj.changed(new cvox.TextChangeEvent('google.com', 2, 10));
- assertEqualStringArrays(['o', 'ogle.com'], tts.get());
- obj.changed(new cvox.TextChangeEvent('google.com', 3, 10));
- assertEqualStringArrays(['o', 'gle.com'], tts.get());
- obj.changed(new cvox.TextChangeEvent('google.com', 4, 10));
- assertEqualStringArrays(['g', 'le.com'], tts.get());
-
- // The user presses right-arrow, which fully unselects the remaining text.
- obj.changed(new cvox.TextChangeEvent('google.com', 10, 10));
- assertEqualStringArrays(['Unselected'], tts.get());
-
- // The user types '/'
- obj.changed(new cvox.TextChangeEvent('google.com/', 11, 11));
- assertEqualStringArrays(['com/'], tts.get());
-
- // The user types 'f', and 'finance' is autocompleted
- obj.changed(new cvox.TextChangeEvent('google.com/finance', 12, 18));
- assertEqualStringArrays(['finance, inance'], tts.get());
-
- // The user types 'i'
- obj.changed(new cvox.TextChangeEvent('google.com/finance', 13, 18));
- assertEqualStringArrays(['i', 'nance'], tts.get());
-
- // The user types 'r', now 'firefox' is autocompleted
- obj.changed(new cvox.TextChangeEvent('google.com/firefox', 14, 18));
- assertEqualStringArrays(['refox, efox'], tts.get());
-
- // The user presses right-arrow to accept the completion.
- obj.changed(new cvox.TextChangeEvent('google.com/firefox', 18, 18));
- assertEqualStringArrays(['Unselected'], tts.get());
-});
-
-
-/**
- * Test a few common scenarios where text is replaced.
- */
-TEST_F('CvoxEditableTextUnitTest', 'ReplacingText', function() {
- // Initial value is Alabama.
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableTextBase('Alabama', 0, 0, false, tts);
-
- // Entire text replaced with Alaska.
- obj.changed(new cvox.TextChangeEvent('Alaska', 0, 0));
- assertEqualStringArrays(['Alaska'], tts.get());
-
- // Entire text selected.
- obj.changed(new cvox.TextChangeEvent('Alaska', 0, 6));
- assertEqualStringArrays(['Alaska', 'selected'], tts.get());
-
- // Entire text replaced with Arizona.
- obj.changed(new cvox.TextChangeEvent('Arizona', 7, 7));
- assertEqualStringArrays(['Arizona'], tts.get());
-
- // Entire text selected.
- obj.changed(new cvox.TextChangeEvent('Arizona', 0, 7));
- assertEqualStringArrays(['Arizona', 'selected'], tts.get());
-
- // Click between 'r' and 'i'.
- obj.changed(new cvox.TextChangeEvent('Arizona', 2, 2));
- assertEqualStringArrays(['Unselected'], tts.get());
-
- // Next character removed from selection.
- obj.changed(new cvox.TextChangeEvent('Arizona', 2, 7));
- assertEqualStringArrays(['izona', 'selected'], tts.get());
-
- // Selection replaced with "kansas" to make Arkansas. This time it
- // says "kansas" because the deleted text was selected.
- obj.changed(new cvox.TextChangeEvent('Arkansas', 8, 8));
- assertEqualStringArrays(['kansas'], tts.get());
-});
-
-
-/**
- * Test feedback when text changes in a long sentence.
- */
-TEST_F('CvoxEditableTextUnitTest', 'ReplacingLongText', function() {
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableTextBase(
- 'I love deadlines. I like the whooshing sound they make as they fly by.',
- 0, 0, false, tts);
-
- // Change the whole sentence without moving the cursor. It should speak
- // only the part that changed, but it should speak whole words.
- obj.changed(new cvox.TextChangeEvent(
- 'I love deadlines. I love the whooshing sounds they make as they fly by.',
- 0, 0));
- assertEqualStringArrays(['love the whooshing sounds'], tts.get());
-});
-
-/** Tests character echo. */
-TEST_F('CvoxEditableTextUnitTest', 'CharacterEcho', function() {
- cvox.ChromeVox.typingEcho = cvox.TypingEcho.CHARACTER;
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
- obj.changed(new cvox.TextChangeEvent('H', 1, 1));
- obj.changed(new cvox.TextChangeEvent('He', 2, 2));
- obj.changed(new cvox.TextChangeEvent('Hel', 3, 3));
- obj.changed(new cvox.TextChangeEvent('Hell', 4, 4));
- obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
- obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6));
- obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
- obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8));
- obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9));
- obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
- obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
- obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
- obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13));
- assertEqualStringArrays(
- ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '.'],
- tts.get());
-});
-
-
-/** Tests word echo. */
-TEST_F('CvoxEditableTextUnitTest', 'WordEcho', function() {
- cvox.ChromeVox.typingEcho = cvox.TypingEcho.WORD;
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
- obj.changed(new cvox.TextChangeEvent('H', 1, 1));
- obj.changed(new cvox.TextChangeEvent('He', 2, 2));
- obj.changed(new cvox.TextChangeEvent('Hel', 3, 3));
- obj.changed(new cvox.TextChangeEvent('Hell', 4, 4));
- obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
- obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6));
- obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
- obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8));
- obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9));
- obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
- obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
- obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
- obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13));
- assertEqualStringArrays(
- ['Hello,', 'World.'],
- tts.get());
-});
-
-
-/** Tests no echo. */
-TEST_F('CvoxEditableTextUnitTest', 'NoEcho', function() {
- cvox.ChromeVox.typingEcho = cvox.TypingEcho.NONE;
- var tts = new TestTts();
- var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
- obj.changed(new cvox.TextChangeEvent('H', 1, 1));
- obj.changed(new cvox.TextChangeEvent('He', 2, 2));
- obj.changed(new cvox.TextChangeEvent('Hel', 3, 3));
- obj.changed(new cvox.TextChangeEvent('Hell', 4, 4));
- obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
- obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6));
- obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
- obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8));
- obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9));
- obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
- obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
- obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
- obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13));
- assertEqualStringArrays(
- [],
- tts.get());
-});
-
-/** Tests cursor movement in an input field by character. */
-TEST_F('CvoxEditableTextUnitTest', 'CursorMovementByCharacter', function() {
- var test = this.setUpForCursorTest_('input');
- var editable = test.editable, prepare = test.prepare, expect = test.expect;
- try {
- // Moving near the beginning of the text.
- prepare('|"Hello," says Sally.');
- editable.moveCursorToPreviousCharacter();
- expect('|"Hello," says Sally.');
- editable.moveCursorToNextCharacter();
- expect('"|Hello," says Sally.');
- editable.moveCursorToNextCharacter();
- expect('"H|ello," says Sally.');
-
- // Moving near the end of the text.
- prepare('"Hello," says Sally|.');
- editable.moveCursorToPreviousCharacter();
- expect('"Hello," says Sall|y.');
- editable.moveCursorToNextCharacter();
- expect('"Hello," says Sally|.');
- editable.moveCursorToNextCharacter();
- expect('"Hello," says Sally.|');
- editable.moveCursorToNextCharacter();
- expect('"Hello," says Sally.|');
- } finally {
- test.tearDown();
- }
-});
-
-/** Tests cursor movement in an input field by word. */
-TEST_F('CvoxEditableTextUnitTest', 'CursorMovementByWord', function() {
- var test = this.setUpForCursorTest_('input');
- var editable = test.editable, prepare = test.prepare, expect = test.expect;
- try {
- // Moving forward.
- prepare('"He|llo," says Sally.');
- editable.moveCursorToNextWord();
- expect('"Hello|," says Sally.');
- editable.moveCursorToNextWord();
- expect('"Hello," says| Sally.');
- editable.moveCursorToNextWord();
- expect('"Hello," says Sally|.');
- editable.moveCursorToNextWord();
- expect('"Hello," says Sally.|');
- editable.moveCursorToNextWord();
- expect('"Hello," says Sally.|');
-
- // Moving backward.
- prepare('"Hello," says S|ally.');
- editable.moveCursorToPreviousWord();
- expect('"Hello," says |Sally.');
- editable.moveCursorToPreviousWord();
- expect('"Hello," |says Sally.');
- editable.moveCursorToPreviousWord();
- expect('"|Hello," says Sally.');
- editable.moveCursorToPreviousWord();
- expect('|"Hello," says Sally.');
- editable.moveCursorToPreviousWord();
- expect('|"Hello," says Sally.');
- } finally {
- test.tearDown();
- }
-});
-
-/** Tests that character and word movement still work in <textarea>. */
-TEST_F('CvoxEditableTextUnitTest', 'CursorMovementTextArea', function() {
- var test = this.setUpForCursorTest_('textarea');
- var editable = test.editable, prepare = test.prepare, expect = test.expect;
- try {
- prepare('|Hello, Larry.\nHello, Sergey.');
- editable.moveCursorToNextCharacter();
- expect('H|ello, Larry.\nHello, Sergey.');
- editable.moveCursorToNextWord();
- expect('Hello|, Larry.\nHello, Sergey.');
- editable.moveCursorToNextWord();
- expect('Hello, Larry|.\nHello, Sergey.');
- editable.moveCursorToNextWord();
- expect('Hello, Larry.\nHello|, Sergey.');
- editable.moveCursorToNextCharacter();
- expect('Hello, Larry.\nHello,| Sergey.');
- editable.moveCursorToPreviousWord();
- expect('Hello, Larry.\n|Hello, Sergey.');
- editable.moveCursorToPreviousCharacter();
- expect('Hello, Larry.|\nHello, Sergey.');
- } finally {
- test.tearDown();
- }
-});
-
-/** Tests that line navigation works. */
-TEST_F('CvoxEditableTextUnitTest', 'CursorMovementByLine', function() {
- var test = this.setUpForCursorTest_('textarea');
- var editable = test.editable, prepare = test.prepare, expect = test.expect;
- try {
- prepare('123\n1234\n1234|5\n\nHi');
- editable.moveCursorToPreviousLine();
- expect('123\n1234|\n12345\n\nHi');
- editable.moveCursorToPreviousLine();
- expect('123|\n1234\n12345\n\nHi');
- editable.moveCursorToNextLine();
- expect('123\n123|4\n12345\n\nHi');
- editable.moveCursorToNextLine();
- expect('123\n1234\n123|45\n\nHi');
- editable.moveCursorToNextLine();
- expect('123\n1234\n12345\n|\nHi');
- editable.moveCursorToNextLine();
- expect('123\n1234\n12345\n\n|Hi');
- editable.moveCursorToNextLine();
- expect('123\n1234\n12345\n\nHi|');
-
- prepare('foo|bar');
- editable.moveCursorToPreviousLine();
- expect('|foobar');
- editable.moveCursorToPreviousLine();
- expect('|foobar');
- editable.moveCursorToNextLine();
- expect('foobar|');
- editable.moveCursorToNextLine();
- expect('foobar|');
- } finally {
- test.tearDown();
- }
-});
-
-/** Tests that paragraph navigation works. */
-TEST_F('CvoxEditableTextUnitTest', 'CursorMovementByParagraph', function() {
- var test = this.setUpForCursorTest_('textarea');
- var editable = test.editable, prepare = test.prepare, expect = test.expect;
- try {
- prepare('Para|graph 1\nParagraph 2\nParagraph 3');
- editable.moveCursorToNextParagraph();
- expect('Paragraph 1\n|Paragraph 2\nParagraph 3');
- editable.moveCursorToNextParagraph();
- expect('Paragraph 1\nParagraph 2\n|Paragraph 3');
- editable.moveCursorToNextParagraph();
- expect('Paragraph 1\nParagraph 2\nParagraph 3|');
- editable.moveCursorToPreviousParagraph();
- expect('Paragraph 1\nParagraph 2\n|Paragraph 3');
- editable.moveCursorToPreviousParagraph();
- expect('Paragraph 1\n|Paragraph 2\nParagraph 3');
- editable.moveCursorToPreviousParagraph();
- expect('|Paragraph 1\nParagraph 2\nParagraph 3');
- } finally {
- test.tearDown();
- }
-});
-
-/** Tests normalization of TextChangeEvent's */
-TEST_F('CvoxEditableTextUnitTest', 'TextChangeEvent', function() {
- var event1 = new cvox.TextChangeEvent('foo', 0, 1, true);
- var event2 = new cvox.TextChangeEvent('foo', 1, 0, true);
- var event3 = new cvox.TextChangeEvent('foo', 1, 1, true);
-
- assertEquals(0, event1.start);
- assertEquals(1, event1.end);
-
- assertEquals(0, event2.start);
- assertEquals(1, event2.end);
-
- assertEquals(1, event3.start);
- assertEquals(1, event3.end);
-});
-
-TEST_F('CvoxEditableTextUnitTest', 'ContentEditableBraille', function() {
- this.loadDoc(function() {/*!
- <div id='1' contenteditable='true'>
- Some &nbsp; text.<br><br>
- After blank line.
- </div>
- */});
- var element = $('1');
- element.focus();
- var editable = new cvox.ChromeVoxEditableContentEditable(
- element, new TestTts());
- var firstLine = 'Some text.\n';
- for (var i = 0; i < firstLine.length; ++i) {
- editable.update(true);
- TestBraille.assertContent(firstLine, i, i);
- window.getSelection().modify('move', 'forward', 'character');
- }
- // We should have crossed the line break to the second line which is blank.
- editable.update(true);
- TestBraille.assertContent('', 0, 0);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/externs.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/externs.js
deleted file mode 100644
index 6ae51f423b0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/externs.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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.
-
-Document.prototype.documentElement.innerWidth;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/find_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/find_util.js
deleted file mode 100644
index a5ac8a6b371..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/find_util.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Utilities for finding DOM nodes and CursorSelection's.
- */
-
-
-goog.provide('cvox.FindUtil');
-
-goog.require('cvox.BareObjectWalker');
-goog.require('cvox.CursorSelection');
-
-
-/**
- * @type {!cvox.BareObjectWalker}
- * @private
- */
-cvox.FindUtil.objectWalker_ = new cvox.BareObjectWalker();
-
-
-/**
- * Finds the next selection that matches the predicate function starting from
- * sel. Undefined if the nodes in sel are not attached to the document.
- * @param {!cvox.CursorSelection} sel The selection from which to start.
- * @param {function(Array<Node>):Node} predicate A function taking a
- * unique ancestor tree and outputting Node if the ancestor tree matches
- * the desired node to find.
- * @param {boolean=} opt_initialNode Whether to start the search from node
- * (true), or the next node (false); defaults to false.
- * @return {cvox.CursorSelection} The selection that was found.
- * null if end of document reached.
- */
-cvox.FindUtil.findNext = function(sel, predicate, opt_initialNode) {
- var r = sel.isReversed();
- var cur = new cvox.CursorSelection(sel.absStart(), sel.absStart())
- .setReversed(r);
-
- // We may have been sync'ed into a subtree of the current predicate match.
- // Find our ancestor that matches the predicate.
- var ancestor;
- if (ancestor = predicate(cvox.DomUtil.getAncestors(cur.start.node))) {
- cur = cvox.CursorSelection.fromNode(ancestor).setReversed(r);
- if (opt_initialNode) {
- return cur;
- }
- }
-
- while (cur) {
- // Use ObjectWalker's traversal which guarantees us a stable iteration of
- // the DOM including returning null at page bounds.
- cur = cvox.FindUtil.objectWalker_.next(cur);
- var retNode = null;
- if (!cur ||
- (retNode = predicate(cvox.DomUtil.getAncestors(cur.start.node)))) {
- return retNode ? cvox.CursorSelection.fromNode(retNode) : null;
- }
-
- // Iframes require inter-frame messaging.
- if (cur.start.node.tagName == 'IFRAME') {
- return cur;
- }
- }
- return null;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/find_util_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/find_util_test.unitjs
deleted file mode 100644
index 707fdcb331e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/find_util_test.unitjs
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxFindUtilUnitTest() {}
-
-CvoxFindUtilUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.FindUtil',
- ]
-};
-
-TEST_F('CvoxFindUtilUnitTest', 'Links', function() {
- this.loadDoc(function() {/*!
- <div>
- <p id="before">Before</p>
- <h2>Chapter 1</h2>
- <h2>Chapter 2</h2>
- <a href="#c3" id="c3" name="chapter_3"></a>
- <h2 id="c3_2">Chapter 3</h2>
- <h2 id="c4">Chapter 4</h2>
- <h2>Chapter 5</h2>
- <h2>Chapter 6</h2>
- <a href='#c7' id="c7" name="chapter_7"><h2 id="c7_2">Chapter 7</h2></a>
- <h2 id="c8">Chapter 8</h2>
- <p id="after">After</p>
- </div>
- */});
-
- var sel = cvox.CursorSelection.fromNode($('before'));
-
- var ret = cvox.FindUtil.findNext(sel, cvox.DomPredicates.linkPredicate);
- assertEquals('c3', ret.start.node.id);
- ret = cvox.FindUtil.findNext(ret, cvox.DomPredicates.linkPredicate);
- assertEquals('c7', ret.start.node.id);
-
- ret.setReversed(true);
- ret = cvox.FindUtil.findNext(ret, cvox.DomPredicates.linkPredicate);
- assertEquals('c3', ret.start.node.id);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/focus_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/focus_util.js
deleted file mode 100644
index 4c00595a954..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/focus_util.js
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A collection of JavaScript utilities used to manage focus
- * within a document.
- */
-
-
-goog.provide('cvox.FocusUtil');
-
-
-/**
- * Utilities for managing focus.
- * @constructor
- */
-cvox.FocusUtil = function() {
-};
-
-/**
- * Maps whether an input element of specified type accepts text selection or
- * not. True if the element does accept text selection, false if it does not.
- * This can be used to determine whether a visitor to that element should
- * provide interactive text editing to the user.
- * From the W3C table of possible type keywords:
- * http://www.w3.org/TR/html5/the-input-element.html#attr-input-type
- *
- * TODO(dmazzoni): merge this with cvox.DomUtil.isInputTypeText
- *
- * @type {Object}
- */
-cvox.FocusUtil.INPUT_TYPE_ACCEPTS_SELECTION_TABLE = {
- 'hidden' : false,
- 'text' : true,
- 'search' : true,
- 'tel' : true,
- 'url' : true,
- 'email' : true,
- 'password' : true,
- 'datetime' : false,
- 'date' : false,
- 'month' : false,
- 'week' : false,
- 'time' : false,
- 'datetime-local' : false,
- 'number' : false,
- 'range' : false,
- 'color' : false,
- 'checkbox' : false,
- 'radio' : false,
- 'file' : false,
- 'submit' : false,
- 'image' : false,
- 'reset' : false,
- 'button' : false
-};
-
-/**
- * Checks if the currently focused element is a field that accepts text input
- * (This can include text fields and selectors)
- *
- * @return {boolean} True if the currently focused element accepts text input.
- */
-cvox.FocusUtil.isFocusInTextInputField = function() {
- var activeElement = document.activeElement;
-
- if (!activeElement) {
- return false;
- }
-
- if (activeElement.isContentEditable) {
- return true;
- }
-
- if (activeElement.getAttribute('role') == 'textbox') {
- return true;
- }
-
- if (activeElement.getAttribute('readOnly') == 'true') {
- return false;
- }
-
- if (activeElement.tagName === 'TEXTAREA' ||
- activeElement.tagName === 'SELECT') {
- return true;
- }
-
- if (activeElement.tagName === 'INPUT') {
- if (!activeElement.hasAttribute('type')) {
- return true;
- } else {
- var activeType = activeElement.getAttribute('type').toLowerCase();
- return cvox.FocusUtil.INPUT_TYPE_ACCEPTS_SELECTION_TABLE[activeType];
- }
- }
- return false;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/focuser.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/focuser.js
deleted file mode 100644
index f0a29d87c43..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/focuser.js
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Implements the setFocus function.
- */
-
-goog.provide('cvox.Focuser');
-
-goog.require('cvox.ChromeVoxEventSuspender');
-goog.require('cvox.DomUtil');
-
-
-/**
- * Sets the browser focus to the targetNode or its closest ancestor that is
- * focusable.
- *
- * @param {Node} targetNode The node to move the browser focus to.
- * @param {boolean=} opt_focusDescendants Whether or not we check descendants
- * of the target node to see if they are focusable. If true, sets focus on the
- * first focusable descendant. If false, only sets focus on the targetNode or
- * its closest ancestor. Default is false.
- */
-cvox.Focuser.setFocus = function(targetNode, opt_focusDescendants) {
- // Save the selection because Chrome will lose it if there's a focus or blur.
- var sel = window.getSelection();
- var range;
- if (sel.rangeCount > 0) {
- range = sel.getRangeAt(0);
- }
- // Blur the currently-focused element if the target node is not a descendant.
- if (document.activeElement &&
- !cvox.DomUtil.isDescendantOfNode(targetNode, document.activeElement)) {
- document.activeElement.blur();
- }
-
- // Video elements should always be focusable.
- if (targetNode && (targetNode.constructor == HTMLVideoElement)) {
- if (!cvox.DomUtil.isFocusable(targetNode)) {
- targetNode.setAttribute('tabIndex', 0);
- }
- }
-
- if (opt_focusDescendants && !cvox.DomUtil.isFocusable(targetNode)) {
- var focusableDescendant = cvox.DomUtil.findFocusableDescendant(targetNode);
- if (focusableDescendant) {
- targetNode = focusableDescendant;
- }
- } else {
- // Search up the parent chain until a focusable node is found.
- while (targetNode && !cvox.DomUtil.isFocusable(targetNode)) {
- targetNode = targetNode.parentNode;
- }
- }
-
- // If we found something focusable, focus it - otherwise, blur it.
- if (cvox.DomUtil.isFocusable(targetNode)) {
- // Don't let the instance of ChromeVox in the parent focus iframe children
- // - instead, let the instance of ChromeVox in the iframe focus itself to
- // avoid getting trapped in iframes that have no ChromeVox in them.
- // This self focusing is performed by calling window.focus() in
- // cvox.NavigationManager.prototype.addInterframeListener_
- if (targetNode.tagName != 'IFRAME') {
- // setTimeout must be used because there's a bug (in Chrome, I think)
- // with .focus() which causes the page to be redrawn incorrectly if
- // not in setTimeout.
- if (cvox.ChromeVoxEventSuspender.areEventsSuspended()) {
- if (cvox.Focuser.shouldEnterSuspendEvents_(targetNode)) {
- cvox.ChromeVoxEventSuspender.enterSuspendEvents();
- }
- window.setTimeout(function() {
- targetNode.focus();
- cvox.ChromeVoxEventSuspender.exitSuspendEvents();
- }, 0);
- }
- else {
- window.setTimeout(function() {
- targetNode.focus();
- }, 0);
- }
- }
- } else if (document.activeElement &&
- document.activeElement.tagName != 'BODY') {
- document.activeElement.blur();
- }
-
- // Restore the selection, unless the focused item is a text box.
- if (cvox.DomUtil.isInputTypeText(targetNode)) {
- targetNode.select();
- } else if (range) {
- sel.removeAllRanges();
- sel.addRange(range);
- }
-};
-
-/**
- * Rules for whether or not enterSuspendEvents should be called.
- * In general, we should not enterSuspendEvents if the targetNode will get some
- * special handlers attached when a focus event is received for it; otherwise,
- * the special handlers will not get attached.
- *
- * @param {Node} targetNode The node that is being focused.
- * @return {boolean} True if enterSuspendEvents should be called.
- */
-cvox.Focuser.shouldEnterSuspendEvents_ = function(targetNode){
- if (targetNode.constructor && targetNode.constructor == HTMLVideoElement) {
- return false;
- }
- if (targetNode.hasAttribute) {
- switch (targetNode.getAttribute('type')) {
- case 'time':
- case 'date':
- case 'week':
- case 'month':
- return false;
- }
- }
- return true;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/group_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/group_util.js
deleted file mode 100644
index d2a8ff1959b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/group_util.js
+++ /dev/null
@@ -1,150 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Some utilities for defining what groups are.
- */
-
-
-goog.provide('cvox.GroupUtil');
-
-goog.require('cvox.AriaUtil');
-goog.require('cvox.DomUtil');
-
-
-/**
- * If a node contains more characters than this, it should not be treated
- * as a leaf node by the smart navigation algorithm.
- *
- * This number was determined by looking at the average number of
- * characters in a paragraph:
- * http://www.fullondesign.co.uk/design/usability/
- * 285-how-many-characters-per-a-page-is-normal.htm
- * and then trying it out on a few popular websites (CNN, BBC,
- * Google Search, etc.) and making sure it made sense.
- * @type {number}
- * @private
- * @const
- */
-cvox.GroupUtil.MAX_CHARCOUNT_ = 1500;
-
-
-/**
- * If a node contains any of these elements, it should not be treated
- * as a leaf node by the smart navigation algorithm.
- * @type {string}
- * @private
- * @const
- */
-cvox.GroupUtil.BREAKOUT_SELECTOR_ = 'blockquote,' +
- 'button,' +
- 'code,' +
- 'form,' +
- 'frame,' +
- 'h1,' +
- 'h2,' +
- 'h3,' +
- 'h4,' +
- 'h5,' +
- 'h6,' +
- 'hr,' +
- 'iframe,' +
- 'input,' +
- 'object,' +
- 'ol,' +
- 'p,' +
- 'pre,' +
- 'select,' +
- 'table,' +
- 'tr,' +
- 'ul,' +
- 'math,' +
- // This takes care of MathJax expressions.
- 'span.math,' +
-// TODO (sorge) Do we want to group all math or only display math?
-// '[mode="display"],' +
- // Aria widget roles
- '[role~="alert ' +
- 'alertdialog ' +
- 'button ' +
- 'checkbox ' +
- 'combobox ' +
- 'dialog ' +
- 'log ' +
- 'marquee ' +
- 'menubar ' +
- 'progressbar ' +
- 'radio ' +
- 'radiogroup ' +
- 'scrollbar ' +
- 'slider ' +
- 'spinbutton ' +
- 'status ' +
- 'tab ' +
- 'tabpanel ' +
- 'textbox ' +
- 'toolbar ' +
- 'tooltip ' +
- 'treeitem ' +
- // Aria structure roles
- 'article ' +
- 'document ' +
- 'group ' +
- 'heading ' +
- 'img ' +
- 'list ' +
- 'math ' +
- 'region ' +
- 'row ' +
- 'separator"]';
-
-
-/**
- * Returns true if this is a leaf node for groups.
- * true for a node => true for all child nodes
- * true if node has no children
- * @param {!Node} node The node to check.
- * @return {boolean} true if this is at the "leaf node" level or lower
- * for this granularity.
- */
-cvox.GroupUtil.isLeafNode = function(node) {
- // TODO (stoarca): Write test to make sure that this function satisfies
- // the restriction given above.
- if (node.tagName == 'LABEL') {
- return cvox.DomUtil.isLeafNode(node);
- }
- if (cvox.DomUtil.isLeafNode(node)) {
- return true;
- }
-
- if (!cvox.DomUtil.isSemanticElt(node)) {
- var breakingNodes = node.querySelectorAll(
- cvox.GroupUtil.BREAKOUT_SELECTOR_);
-
- for (var i = 0; i < breakingNodes.length; ++i) {
- if (cvox.DomUtil.hasContent(breakingNodes[i])) {
- return false;
- }
- }
- }
-
- if (cvox.AriaUtil.isCompositeControl(node) &&
- !cvox.DomUtil.isFocusable(node)) {
- return false;
- }
-
- var content = cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(node) + ' ' +
- cvox.DomUtil.getName(node));
- if (content.length > cvox.GroupUtil.MAX_CHARCOUNT_) {
- return false;
- }
-
- if (content.replace(/\s/g, '') === '') {
- // Text only contains whitespace
- return false;
- }
-
- return true;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/interframe.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/interframe.js
deleted file mode 100644
index 8d7b7fc117f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/interframe.js
+++ /dev/null
@@ -1,240 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Tools for interframe communication. To use this class, every
- * window that wants to communicate with its child iframes should enumerate
- * them using document.getElementsByTagName('iframe'), create an ID to
- * associate with that iframe, then call cvox.Interframe.sendIdToIFrame
- * on each of them. Then use cvox.Interframe.sendMessageToIFrame to send
- * messages to that iframe and cvox.Interframe.addListener to receive
- * replies. When a reply is received, it will automatically contain the ID of
- * that iframe as a parameter.
- *
- */
-
-goog.provide('cvox.Interframe');
-
-goog.require('cvox.ChromeVoxJSON');
-goog.require('cvox.DomUtil');
-
-/**
- * @constructor
- */
-cvox.Interframe = function() {
-};
-
-/**
- * The prefix of all interframe messages.
- * @type {string}
- * @const
- */
-cvox.Interframe.IF_MSG_PREFIX = 'cvox.INTERFRAME:';
-
-/**
- * The message used to set the ID of a child frame so that it can send replies
- * to its parent frame.
- * @type {string}
- * @const
- */
-cvox.Interframe.SET_ID = 'cvox.INTERFRAME_SET_ID';
-
-/**
- * The message used by a child frame to acknowledge an id was set (sent to its
- * parent frame.
- * @type {string}
- * @const
- */
-cvox.Interframe.ACK_SET_ID = 'cvox.INTERFRAME_ACK_SET_ID';
-
-/**
- * The ID of this window (relative to its parent farme).
- * @type {number|string|undefined}
- */
-cvox.Interframe.id;
-
-/**
- * Array of functions that have been registered as listeners to interframe
- * messages send to this window.
- * @type {Array<function(Object)>}
- */
-cvox.Interframe.listeners = [];
-
-/**
- * Maps an id to a function which gets called when a frame first sends an ack
- * for a set id msg.
- @dict {!Object<number|string, function()>}
- * @private
- */
-cvox.Interframe.idToCallback_ = {};
-
-/**
- * Flag for unit testing. When false, skips over iframe.contentWindow check
- * in sendMessageToIframe. This is needed because in the wild, ChromeVox may
- * not have access to iframe.contentWindow due to the same-origin security
- * policy. There is no reason to set this outside of a test.
- * @type {boolean}
- */
-cvox.Interframe.allowAccessToIframeContentWindow = true;
-
-/**
- * Initializes the cvox.Interframe module. (This is called automatically.)
- */
-cvox.Interframe.init = function() {
- cvox.Interframe.messageListener = function(event) {
- if (typeof event.data === 'string' &&
- event.data.indexOf(cvox.Interframe.IF_MSG_PREFIX) == 0) {
- var suffix = event.data.substr(cvox.Interframe.IF_MSG_PREFIX.length);
- var message = /** @type {Object} */ (
- cvox.ChromeVoxJSON.parse(suffix));
- if (message['command'] == cvox.Interframe.SET_ID) {
- cvox.Interframe.id = message['id'];
- message['command'] = cvox.Interframe.ACK_SET_ID;
- cvox.Interframe.sendMessageToParentWindow(message);
- } else if (message['command'] == cvox.Interframe.ACK_SET_ID) {
- cvox.Interframe.id = message['id'];
- var callback = cvox.Interframe.idToCallback_[cvox.Interframe.id];
- callback();
- }
- for (var i = 0, listener; listener = cvox.Interframe.listeners[i]; i++) {
- listener(message);
- }
- }
- return false;
- };
- window.addEventListener('message', cvox.Interframe.messageListener, true);
-};
-
-/**
- * Unregister the main window event listener. Intended for clean unit testing;
- * normally there's no reason to call this outside of a test.
- */
-cvox.Interframe.shutdown = function() {
- window.removeEventListener('message', cvox.Interframe.messageListener, true);
-};
-
-/**
- * Register a function to listen to all interframe communication messages.
- * Messages from a child frame will have a parameter 'id' that you assigned
- * when you called cvox.Interframe.sendIdToIFrame.
- * @param {function(Object)} listener The listener function.
- */
-cvox.Interframe.addListener = function(listener) {
- cvox.Interframe.listeners.push(listener);
-};
-
-/**
- * Send a message to another window.
- * @param {Object} message The message to send.
- * @param {Window} window The window to receive the message.
- */
-cvox.Interframe.sendMessageToWindow = function(message, window) {
- var encodedMessage = cvox.Interframe.IF_MSG_PREFIX +
- cvox.ChromeVoxJSON.stringify(message, null, null);
- window.postMessage(encodedMessage, '*');
-};
-
-/**
- * Send a message to another iframe.
- * @param {Object} message The message to send. The message must have an 'id'
- * parameter in order to be sent.
- * @param {HTMLIFrameElement} iframe The iframe to send the message to.
- */
-cvox.Interframe.sendMessageToIFrame = function(message, iframe) {
- if (cvox.Interframe.allowAccessToIframeContentWindow &&
- iframe.contentWindow) {
- cvox.Interframe.sendMessageToWindow(message, iframe.contentWindow);
- return;
- }
-
- // A content script can't access window.parent, but the page can, so
- // inject a tiny bit of javascript into the page.
- var encodedMessage = cvox.Interframe.IF_MSG_PREFIX +
- cvox.ChromeVoxJSON.stringify(message, null, null);
- var script = document.createElement('script');
- script.type = 'text/javascript';
-
- // TODO: Make this logic more like makeNodeReference_ inside api.js
- // (line 126) so we can use an attribute instead of a classname
- if (iframe.hasAttribute('id') &&
- document.getElementById(iframe.id) == iframe) {
- // Ideally, try to send it based on the iframe's existing id.
- script.innerHTML =
- 'document.getElementById(decodeURI(\'' +
- encodeURI(iframe.id) + '\')).contentWindow.postMessage(decodeURI(\'' +
- encodeURI(encodedMessage) + '\'), \'*\');';
- } else {
- // If not, add a style name and send it based on that.
- var styleName = 'cvox_iframe' + message['id'];
- if (iframe.className === '') {
- iframe.className = styleName;
- } else if (iframe.className.indexOf(styleName) == -1) {
- iframe.className += ' ' + styleName;
- }
-
- script.innerHTML =
- 'document.getElementsByClassName(decodeURI(\'' +
- encodeURI(styleName) +
- '\'))[0].contentWindow.postMessage(decodeURI(\'' +
- encodeURI(encodedMessage) + '\'), \'*\');';
- }
-
- // Remove the script so we don't leave any clutter.
- document.head.appendChild(script);
- window.setTimeout(function() {
- document.head.removeChild(script);
- }, 1000);
-};
-
-/**
- * Send a message to the parent window of this window, if any. If the parent
- * assigned this window an ID, sends back the ID in the reply automatically.
- * @param {Object} message The message to send.
- */
-cvox.Interframe.sendMessageToParentWindow = function(message) {
- if (!cvox.Interframe.isIframe()) {
- return;
- }
-
- message['sourceId'] = cvox.Interframe.id;
- if (window.parent) {
- cvox.Interframe.sendMessageToWindow(message, window.parent);
- return;
- }
-
- // A content script can't access window.parent, but the page can, so
- // use window.location.href to execute a simple line of javascript in
- // the page context.
- var encodedMessage = cvox.Interframe.IF_MSG_PREFIX +
- cvox.ChromeVoxJSON.stringify(message, null, null);
- window.location.href =
- 'javascript:window.parent.postMessage(\'' +
- encodeURI(encodedMessage) + '\', \'*\');';
-};
-
-/**
- * Send the given ID to a child iframe.
- * @param {number|string} id The ID you want to receive in replies from
- * this iframe.
- * @param {HTMLIFrameElement} iframe The iframe to assign.
- * @param {function()=} opt_callback Called when a ack msg arrives from the
- *frame.
- */
-cvox.Interframe.sendIdToIFrame = function(id, iframe, opt_callback) {
- if (opt_callback) {
- cvox.Interframe.idToCallback_[id] = opt_callback;
- }
- var message = {'command': cvox.Interframe.SET_ID, 'id': id};
- cvox.Interframe.sendMessageToIFrame(message, iframe);
-};
-
-/**
- * Returns true if inside iframe
- * @return {boolean} true if inside iframe.
- */
-cvox.Interframe.isIframe = function() {
- return (window != window.parent);
-};
-
-cvox.Interframe.init();
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js
deleted file mode 100644
index 0a6f3d51c01..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js
+++ /dev/null
@@ -1,633 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A JavaScript class that represents a sequence of keys entered
- * by the user.
- */
-
-
-goog.provide('cvox.KeySequence');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.PlatformFilter');
-
-
-/**
- * A class to represent a sequence of keys entered by a user or affiliated with
- * a ChromeVox command.
- * This class can represent the data from both types of key sequences:
- *
- * COMMAND KEYS SPECIFIED IN A KEYMAP:
- * - Two discrete keys (at most): [Down arrow], [A, A] or [O, W] etc. Can
- * specify one or both.
- * - Modifiers (like ctrl, alt, meta, etc)
- * - Whether or not the ChromeVox modifier key is required with the command.
- *
- * USER INPUT:
- * - Two discrete keys (at most): [Down arrow], [A, A] or [O, W] etc.
- * - Modifiers (like ctlr, alt, meta, etc)
- * - Whether or not the ChromeVox modifier key was active when the keys were
- * entered.
- * - Whether or not a prefix key was entered before the discrete keys.
- * - Whether sticky mode was active.
- * @param {Event|Object} originalEvent The original key event entered by a user.
- * The originalEvent may or may not have parameters stickyMode and keyPrefix
- * specified. We will also accept an event-shaped object.
- * @param {boolean=} opt_cvoxModifier Whether or not the ChromeVox modifier key
- * is active. If not specified, we will try to determine whether the modifier
- * was active by looking at the originalEvent.
- * @param {boolean=} opt_skipStripping Skips stripping of ChromeVox modifiers
- * from key events when the cvox modifiers are set. Defaults to false.
- * @param {boolean=} opt_doubleTap Whether this is triggered via double tap.
- * @constructor
- */
-cvox.KeySequence = function(
- originalEvent, opt_cvoxModifier, opt_skipStripping, opt_doubleTap) {
- /** @type {boolean} */
- this.doubleTap = !!opt_doubleTap;
-
- /** @type {cvox.PlatformFilter} */
- this.platformFilter;
-
- if (opt_cvoxModifier == undefined) {
- this.cvoxModifier = this.isCVoxModifierActive(originalEvent);
- } else {
- this.cvoxModifier = opt_cvoxModifier;
- }
- this.stickyMode = !!originalEvent['stickyMode'];
- this.prefixKey = !!originalEvent['keyPrefix'];
- this.skipStripping = !!opt_skipStripping;
-
- if (this.stickyMode && this.prefixKey) {
- throw 'Prefix key and sticky mode cannot both be enabled: ' + originalEvent;
- }
-
- var event = this.resolveChromeOSSpecialKeys_(originalEvent);
-
- // TODO (rshearer): We should take the user out of sticky mode if they
- // try to use the CVox modifier or prefix key.
-
- /**
- * Stores the key codes and modifiers for the keys in the key sequence.
- * TODO(rshearer): Consider making this structure an array of minimal
- * keyEvent-like objects instead so we don't have to worry about what happens
- * when ctrlKey.length is different from altKey.length.
- *
- * NOTE: If a modifier key is pressed by itself, we will store the keyCode
- * *and* set the appropriate modKey to be true. This mirrors the way key
- * events are created on Mac and Windows. For example, if the Meta key was
- * pressed by itself, the keys object will have:
- * {metaKey: [true], keyCode:[91]}
- *
- * @type {Object}
- */
- this.keys = {
- ctrlKey: [],
- searchKeyHeld: [],
- altKey: [],
- altGraphKey: [],
- shiftKey: [],
- metaKey: [],
- keyCode: []
- };
-
- this.extractKey_(event);
-};
-
-
-// TODO(dtseng): This is incomplete; pull once we have appropriate libs.
-/**
- * Maps a keypress keycode to a keydown or keyup keycode.
- * @type {Object<number, number>}
- */
-cvox.KeySequence.KEY_PRESS_CODE = {
- 39: 222,
- 44: 188,
- 45: 189,
- 46: 190,
- 47: 191,
- 59: 186,
- 91: 219,
- 92: 220,
- 93: 221
-};
-
-/**
- * A cache of all key sequences that have been set as double-tappable. We need
- * this cache because repeated key down computations causes ChromeVox to become
- * less responsive. This list is small so we currently use an array.
- * @type {!Array<cvox.KeySequence>}
- */
-cvox.KeySequence.doubleTapCache = [];
-
-
-/**
- * Adds an additional key onto the original sequence, for use when the user
- * is entering two shortcut keys. This happens when the user presses a key,
- * releases it, and then presses a second key. Those two keys together are
- * considered part of the sequence.
- * @param {Event|Object} additionalKeyEvent The additional key to be added to
- * the original event. Should be an event or an event-shaped object.
- * @return {boolean} Whether or not we were able to add a key. Returns false
- * if there are already two keys attached to this event.
- */
-cvox.KeySequence.prototype.addKeyEvent = function(additionalKeyEvent) {
- if (this.keys.keyCode.length > 1) {
- return false;
- }
- this.extractKey_(additionalKeyEvent);
- return true;
-};
-
-
-/**
- * Check for equality. Commands are matched based on the actual key codes
- * involved and on whether or not they both require a ChromeVox modifier key.
- *
- * If sticky mode or a prefix is active on one of the commands but not on
- * the other, then we try and match based on key code first.
- * - If both commands have the same key code and neither of them have the
- * ChromeVox modifier active then we have a match.
- * - Next we try and match with the ChromeVox modifier. If both commands have
- * the same key code, and one of them has the ChromeVox modifier and the other
- * has sticky mode or an active prefix, then we also have a match.
- * @param {!cvox.KeySequence} rhs The key sequence to compare against.
- * @return {boolean} True if equal.
- */
-cvox.KeySequence.prototype.equals = function(rhs) {
- // Check to make sure the same keys with the same modifiers were pressed.
- if (!this.checkKeyEquality_(rhs)) {
- return false;
- }
-
- if (this.doubleTap != rhs.doubleTap) {
- return false;
- }
-
- // So now we know the actual keys are the same.
- // If they both have the ChromeVox modifier, or they both don't have the
- // ChromeVox modifier, then they are considered equal.
- if (this.cvoxModifier === rhs.cvoxModifier) {
- return true;
- }
-
- // So only one of them has the ChromeVox modifier. If the one that doesn't
- // have the ChromeVox modifier has sticky mode or the prefix key then the
- // keys are still considered equal.
- var unmodified = this.cvoxModifier ? rhs : this;
- return unmodified.stickyMode || unmodified.prefixKey;
-};
-
-
-/**
- * Utility method that extracts the key code and any modifiers from a given
- * event and adds them to the object map.
- * @param {Event|Object} keyEvent The keyEvent or event-shaped object to extract
- * from.
- * @private
- */
-cvox.KeySequence.prototype.extractKey_ = function(keyEvent) {
- for (var prop in this.keys) {
- if (prop == 'keyCode') {
- var keyCode;
- // TODO (rshearer): This is temporary until we find a library that can
- // convert between ASCII charcodes and keycodes.
- if (keyEvent.type == 'keypress' && keyEvent[prop] >= 97 &&
- keyEvent[prop] <= 122) {
- // Alphabetic keypress. Convert to the upper case ASCII code.
- keyCode = keyEvent[prop] - 32;
- } else if (keyEvent.type == 'keypress') {
- keyCode = cvox.KeySequence.KEY_PRESS_CODE[keyEvent[prop]];
- }
- this.keys[prop].push(keyCode || keyEvent[prop]);
- } else {
- if (this.isKeyModifierActive(keyEvent, prop)) {
- this.keys[prop].push(true);
- } else {
- this.keys[prop].push(false);
- }
- }
- }
- if (this.cvoxModifier) {
- this.rationalizeKeys_();
- }
-};
-
-
-/**
- * Rationalizes the key codes and the ChromeVox modifier for this keySequence.
- * This means we strip out the key codes and key modifiers stored for this
- * KeySequence that are also present in the ChromeVox modifier. For example, if
- * the ChromeVox modifier keys are Ctrl+Alt, and we've determined that the
- * ChromeVox modifier is active (meaning the user has pressed Ctrl+Alt), we
- * don't want this.keys.ctrlKey = true also because that implies that this
- * KeySequence involves the ChromeVox modifier and the ctrl key being held down
- * together, which doesn't make any sense.
- * @private
- */
-cvox.KeySequence.prototype.rationalizeKeys_ = function() {
- if (this.skipStripping) {
- return;
- }
-
- // TODO (rshearer): This is a hack. When the modifier key becomes customizable
- // then we will not have to deal with strings here.
- var modifierKeyCombo = cvox.ChromeVox.modKeyStr.split(/\+/g);
-
- var index = this.keys.keyCode.length - 1;
- // For each modifier that is part of the CVox modifier, remove it from keys.
- if (modifierKeyCombo.indexOf('Ctrl') != -1) {
- this.keys.ctrlKey[index] = false;
- }
- if (modifierKeyCombo.indexOf('Alt') != -1) {
- this.keys.altKey[index] = false;
- }
- if (modifierKeyCombo.indexOf('Shift') != -1) {
- this.keys.shiftKey[index] = false;
- }
- var metaKeyName = this.getMetaKeyName_();
- if (modifierKeyCombo.indexOf(metaKeyName) != -1) {
- if (metaKeyName == 'Search') {
- this.keys.searchKeyHeld[index] = false;
- // TODO(dmazzoni): http://crbug.com/404763 Get rid of the code that
- // tracks the search key and just use meta everywhere.
- this.keys.metaKey[index] = false;
- } else if (metaKeyName == 'Cmd' || metaKeyName == 'Win') {
- this.keys.metaKey[index] = false;
- }
- }
-};
-
-
-/**
- * Get the user-facing name for the meta key (keyCode = 91), which varies
- * depending on the platform.
- * @return {string} The user-facing string name for the meta key.
- * @private
- */
-cvox.KeySequence.prototype.getMetaKeyName_ = function() {
- if (cvox.ChromeVox.isChromeOS) {
- return 'Search';
- } else if (cvox.ChromeVox.isMac) {
- return 'Cmd';
- } else {
- return 'Win';
- }
-};
-
-
-/**
- * Utility method that checks for equality of the modifiers (like shift and alt)
- * and the equality of key codes.
- * @param {!cvox.KeySequence} rhs The key sequence to compare against.
- * @return {boolean} True if the modifiers and key codes in the key sequence are
- * the same.
- * @private
- */
-cvox.KeySequence.prototype.checkKeyEquality_ = function(rhs) {
- for (var i in this.keys) {
- for (var j = this.keys[i].length; j--;) {
- if (this.keys[i][j] !== rhs.keys[i][j])
- return false;
- }
- }
- return true;
-};
-
-
-/**
- * Gets first key code
- * @return {number} The first key code.
- */
-cvox.KeySequence.prototype.getFirstKeyCode = function() {
- return this.keys.keyCode[0];
-};
-
-
-/**
- * Gets the number of keys in the sequence. Should be 1 or 2.
- * @return {number} The number of keys in the sequence.
- */
-cvox.KeySequence.prototype.length = function() {
- return this.keys.keyCode.length;
-};
-
-
-
-/**
- * Checks if the specified key code represents a modifier key, i.e. Ctrl, Alt,
- * Shift, Search (on ChromeOS) or Meta.
- *
- * @param {number} keyCode key code.
- * @return {boolean} true if it is a modifier keycode, false otherwise.
- */
-cvox.KeySequence.prototype.isModifierKey = function(keyCode) {
- // Shift, Ctrl, Alt, Search/LWin
- return keyCode == 16 || keyCode == 17 || keyCode == 18 || keyCode == 91 ||
- keyCode == 93;
-};
-
-
-/**
- * Determines whether the Cvox modifier key is active during the keyEvent.
- * @param {Event|Object} keyEvent The keyEvent or event-shaped object to check.
- * @return {boolean} Whether or not the modifier key was active during the
- * keyEvent.
- */
-cvox.KeySequence.prototype.isCVoxModifierActive = function(keyEvent) {
- // TODO (rshearer): Update this when the modifier key becomes customizable
- var modifierKeyCombo = cvox.ChromeVox.modKeyStr.split(/\+/g);
-
- // For each modifier that is held down, remove it from the combo.
- // If the combo string becomes empty, then the user has activated the combo.
- if (this.isKeyModifierActive(keyEvent, 'ctrlKey')) {
- modifierKeyCombo = modifierKeyCombo.filter(function(modifier) {
- return modifier != 'Ctrl';
- });
- }
- if (this.isKeyModifierActive(keyEvent, 'altKey')) {
- modifierKeyCombo = modifierKeyCombo.filter(function(modifier) {
- return modifier != 'Alt';
- });
- }
- if (this.isKeyModifierActive(keyEvent, 'shiftKey')) {
- modifierKeyCombo = modifierKeyCombo.filter(function(modifier) {
- return modifier != 'Shift';
- });
- }
- if (this.isKeyModifierActive(keyEvent, 'metaKey') ||
- this.isKeyModifierActive(keyEvent, 'searchKeyHeld')) {
- var metaKeyName = this.getMetaKeyName_();
- modifierKeyCombo = modifierKeyCombo.filter(function(modifier) {
- return modifier != metaKeyName;
- });
- }
- return (modifierKeyCombo.length == 0);
-};
-
-
-/**
- * Determines whether a particular key modifier (for example, ctrl or alt) is
- * active during the keyEvent.
- * @param {Event|Object} keyEvent The keyEvent or Event-shaped object to check.
- * @param {string} modifier The modifier to check.
- * @return {boolean} Whether or not the modifier key was active during the
- * keyEvent.
- */
-cvox.KeySequence.prototype.isKeyModifierActive = function(keyEvent, modifier) {
- // We need to check the key event modifier and the keyCode because Linux will
- // not set the keyEvent.modKey property if it is the modKey by itself.
- // This bug filed as crbug.com/74044
- switch (modifier) {
- case 'ctrlKey':
- return (keyEvent.ctrlKey || keyEvent.keyCode == 17);
- break;
- case 'altKey':
- return (keyEvent.altKey || (keyEvent.keyCode == 18));
- break;
- case 'shiftKey':
- return (keyEvent.shiftKey || (keyEvent.keyCode == 16));
- break;
- case 'metaKey':
- return (keyEvent.metaKey || (keyEvent.keyCode == 91));
- break;
- case 'searchKeyHeld':
- return ((cvox.ChromeVox.isChromeOS && keyEvent.keyCode == 91) ||
- keyEvent['searchKeyHeld']);
- break;
- }
- return false;
-};
-
-/**
- * Returns if any modifier is active in this sequence.
- * @return {boolean} The result.
- */
-cvox.KeySequence.prototype.isAnyModifierActive = function() {
- for (var modifierType in this.keys) {
- for (var i = 0; i < this.length(); i++) {
- if (this.keys[modifierType][i] && modifierType != 'keyCode') {
- return true;
- }
- }
- }
- return false;
-};
-
-
-/**
- * Creates a KeySequence event from a generic object.
- * @param {Object} sequenceObject The object.
- * @return {cvox.KeySequence} The created KeySequence object.
- */
-cvox.KeySequence.deserialize = function(sequenceObject) {
- var firstSequenceEvent = {};
-
- firstSequenceEvent['stickyMode'] = (sequenceObject.stickyMode == undefined) ?
- false : sequenceObject.stickyMode;
- firstSequenceEvent['prefixKey'] = (sequenceObject.prefixKey == undefined) ?
- false : sequenceObject.prefixKey;
-
-
- var secondKeyPressed = sequenceObject.keys.keyCode.length > 1;
- var secondSequenceEvent = {};
-
- for (var keyPressed in sequenceObject.keys) {
- firstSequenceEvent[keyPressed] = sequenceObject.keys[keyPressed][0];
- if (secondKeyPressed) {
- secondSequenceEvent[keyPressed] = sequenceObject.keys[keyPressed][1];
- }
- }
-
- var keySeq = new cvox.KeySequence(firstSequenceEvent,
- sequenceObject.cvoxModifier, true, sequenceObject.doubleTap);
- if (secondKeyPressed) {
- cvox.ChromeVox.sequenceSwitchKeyCodes.push(
- new cvox.KeySequence(firstSequenceEvent, sequenceObject.cvoxModifier));
- keySeq.addKeyEvent(secondSequenceEvent);
- }
-
- if (sequenceObject.doubleTap) {
- cvox.KeySequence.doubleTapCache.push(keySeq);
- }
-
- return keySeq;
-};
-
-
-/**
- * Creates a KeySequence event from a given string. The string should be in the
- * standard key sequence format described in keyUtil.keySequenceToString and
- * used in the key map JSON files.
- * @param {string} keyStr The string representation of a key sequence.
- * @return {!cvox.KeySequence} The created KeySequence object.
- */
-cvox.KeySequence.fromStr = function(keyStr) {
- var sequenceEvent = {};
- var secondSequenceEvent = {};
-
- var secondKeyPressed;
- if (keyStr.indexOf('>') == -1) {
- secondKeyPressed = false;
- } else {
- secondKeyPressed = true;
- }
-
- var cvoxPressed = false;
- sequenceEvent['stickyMode'] = false;
- sequenceEvent['prefixKey'] = false;
-
- var tokens = keyStr.split('+');
- for (var i = 0; i < tokens.length; i++) {
- var seqs = tokens[i].split('>');
- for (var j = 0; j < seqs.length; j++) {
- if (seqs[j].charAt(0) == '#') {
- var keyCode = parseInt(seqs[j].substr(1), 10);
- if (j > 0) {
- secondSequenceEvent['keyCode'] = keyCode;
- } else {
- sequenceEvent['keyCode'] = keyCode;
- }
- }
- var keyName = seqs[j];
- if (seqs[j].length == 1) {
- // Key is A/B/C...1/2/3 and we don't need to worry about setting
- // modifiers.
- if (j > 0) {
- secondSequenceEvent['keyCode'] = seqs[j].charCodeAt(0);
- } else {
- sequenceEvent['keyCode'] = seqs[j].charCodeAt(0);
- }
- } else {
- // Key is a modifier key
- if (j > 0) {
- cvox.KeySequence.setModifiersOnEvent_(keyName, secondSequenceEvent);
- if (keyName == 'Cvox') {
- cvoxPressed = true;
- }
- } else {
- cvox.KeySequence.setModifiersOnEvent_(keyName, sequenceEvent);
- if (keyName == 'Cvox') {
- cvoxPressed = true;
- }
- }
- }
- }
- }
- var keySeq = new cvox.KeySequence(sequenceEvent, cvoxPressed);
- if (secondKeyPressed) {
- keySeq.addKeyEvent(secondSequenceEvent);
- }
- return keySeq;
-};
-
-
-/**
- * Utility method for populating the modifiers on an event object that will be
- * used to create a KeySequence.
- * @param {string} keyName A particular modifier key name (such as 'Ctrl').
- * @param {Object} seqEvent The event to populate.
- * @private
- */
-cvox.KeySequence.setModifiersOnEvent_ = function(keyName, seqEvent) {
- if (keyName == 'Ctrl') {
- seqEvent['ctrlKey'] = true;
- seqEvent['keyCode'] = 17;
- } else if (keyName == 'Alt') {
- seqEvent['altKey'] = true;
- seqEvent['keyCode'] = 18;
- } else if (keyName == 'Shift') {
- seqEvent['shiftKey'] = true;
- seqEvent['keyCode'] = 16;
- } else if (keyName == 'Search') {
- seqEvent['searchKeyHeld'] = true;
- seqEvent['keyCode'] = 91;
- } else if (keyName == 'Cmd') {
- seqEvent['metaKey'] = true;
- seqEvent['keyCode'] = 91;
- } else if (keyName == 'Win') {
- seqEvent['metaKey'] = true;
- seqEvent['keyCode'] = 91;
- } else if (keyName == 'Insert') {
- seqEvent['keyCode'] = 45;
- }
-};
-
-
-/**
- * Used to resolve special ChromeOS keys (see link for more detail).
- * http://crbug.com/162268
- * @param {Object} originalEvent The event.
- * @return {Object} The resolved event.
- * @private
- */
-cvox.KeySequence.prototype.resolveChromeOSSpecialKeys_ =
- function(originalEvent) {
- if (!this.cvoxModifier || this.stickyMode || this.prefixKey ||
- !cvox.ChromeVox.isChromeOS) {
- return originalEvent;
- }
- var evt = {};
- for (var key in originalEvent) {
- evt[key] = originalEvent[key];
- }
- switch (evt['keyCode']) {
- case 33: // Page up.
- evt['keyCode'] = 38; // Up arrow.
- break;
- case 34: // Page down.
- evt['keyCode'] = 40; // Down arrow.
- break;
- case 35: // End.
- evt['keyCode'] = 39; // Right arrow.
- break;
- case 36: // Home.
- evt['keyCode'] = 37; // Left arrow.
- break;
- case 45: // Insert.
- evt['keyCode'] = 190; // Period.
- break;
- case 46: // Delete.
- evt['keyCode'] = 8; // Backspace.
- break;
- case 112: // F1.
- evt['keyCode'] = 49; // 1.
- break;
- case 113: // F2.
- evt['keyCode'] = 50; // 2.
- break;
- case 114: // F3.
- evt['keyCode'] = 51; // 3.
- break;
- case 115: // F4.
- evt['keyCode'] = 52; // 4.
- break;
- case 116: // F5.
- evt['keyCode'] = 53; // 5.
- break;
- case 117: // F6.
- evt['keyCode'] = 54; // 6.
- break;
- case 118: // F7.
- evt['keyCode'] = 55; // 7.
- break;
- case 119: // F8.
- evt['keyCode'] = 56; // 8.
- break;
- case 120: // F9.
- evt['keyCode'] = 57; // 9.
- break;
- case 121: // F10.
- evt['keyCode'] = 48; // 0.
- break;
- case 122: // F11
- evt['keyCode'] = 189; // Hyphen.
- break;
- case 123: // F12
- evt['keyCode'] = 187; // Equals.
- break;
- }
- return evt;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence_test.unitjs
deleted file mode 100644
index 14419b5595c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence_test.unitjs
+++ /dev/null
@@ -1,445 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxKeySequenceUnitTest() {}
-
-CvoxKeySequenceUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ChromeVox',
- 'cvox.KeySequence',
- ],
-
- /**
- * Create mock event object.
- * @param {number} keyCode The event key code (i.e. 13 for Enter).
- * @param {{altGraphKey: boolean=,
- * altKey: boolean=,
- * ctrlKey: boolean=,
- * metaKey: boolean=,
- * searchKeyHeld: boolean=,
- * shiftKey: boolean=,
- * stickyMode: boolean=,
- * prefixKey: boolean=}} eventParams The parameters on the event.
- * altGraphKey: Whether or not the altGraph key was held down.
- * altKey: Whether or not the alt key was held down.
- * ctrlKey: Whether or not the ctrl key was held down.
- * metaKey: Whether or not the meta key was held down.
- * searchKeyHeld: Whether or not the search key was held down.
- * shiftKey: Whether or not the shift key was held down.
- * stickyMode: Whether or not sticky mode is enabled.
- * prefixKey: Whether or not the prefix key was entered.
- * @return {Object} The mock event.
- */
- createMockEvent: function(keyCode, eventParams) {
- var mockEvent = {};
- mockEvent.keyCode = keyCode;
-
- if (eventParams == null) {
- return mockEvent;
- }
- if (eventParams.hasOwnProperty('altGraphKey')) {
- mockEvent.altGraphKey = eventParams.altGraphKey;
- }
- if (eventParams.hasOwnProperty('altKey')) {
- mockEvent.altKey = eventParams.altKey;
- }
- if (eventParams.hasOwnProperty('ctrlKey')) {
- mockEvent.ctrlKey = eventParams.ctrlKey;
- }
- if (eventParams.hasOwnProperty('metaKey')) {
- mockEvent.metaKey = eventParams.metaKey;
- }
- if (eventParams.hasOwnProperty('shiftKey')) {
- mockEvent.shiftKey = eventParams.shiftKey;
- }
-
- if (eventParams.hasOwnProperty('searchKeyHeld')) {
- mockEvent.searchKeyHeld = eventParams.searchKeyHeld;
- }
- if (eventParams.hasOwnProperty('stickyMode')) {
- mockEvent.stickyMode = eventParams.stickyMode;
- }
- if (eventParams.hasOwnProperty('prefixKey')) {
- mockEvent.keyPrefix = eventParams.prefixKey;
- }
-
- return mockEvent;
- },
-
- /** @override */
- setUp: function() {
- // Set up mock ChromeVox modifier
- cvox.ChromeVox.modKeyStr = 'Alt';
-
- // Use these mock events in the tests:
-
- // Down arrow, no modifiers
- this.downArrowEvent = this.createMockEvent(40);
-
- // Down arrow key with alt held down. We specified 'Alt' as the
- // mock ChromeVox modifier string, so this means that KeySequence
- // should interpret this as the ChromeVox modifier being active.
- this.altDownArrowEvent = this.createMockEvent(40, {altKey: true});
-
- // Right arrow, no modifiers
- this.rightArrowEvent = this.createMockEvent(39);
-
- // Ctrl key, no modifiers
- this.ctrlEvent = this.createMockEvent(17);
-
- // Ctrl key with sticky mode
- this.ctrlStickyEvent = this.createMockEvent(17, {stickyMode: true});
-
- // Ctrl key with prefix mode
- this.ctrlPrefixEvent = this.createMockEvent(17, {prefixKey: true});
-
- // 'a' key, no modifiers
- this.aEvent = this.createMockEvent(65);
-
- // 'a' key with ctrl held down
- this.ctrlAEvent = this.createMockEvent(65, {ctrlKey: true});
-
- // 'a' key with meta held down
- this.metaAEvent = this.createMockEvent(65, {metaKey: true});
-
- // 'a' key with shift held down
- this.shiftAEvent = this.createMockEvent(65, {shiftKey: true});
-
- // 'a' key with alt (which is the mock ChromeVox modifier) and shift held
- // down.
- this.altShiftAEvent = this.createMockEvent(65, {altKey: true,
- shiftKey: true});
-
- // 'a' key with shift and prefix held down
- this.shiftAPrefixEvent = this.createMockEvent(65, {shiftKey: true,
- prefixKey: true});
-
- // 'a' key with shift and sticky mode
- this.shiftAStickyEvent = this.createMockEvent(65, {shiftKey: true,
- stickyMode: true});
-
- // 'a' key with sticky mode
- this.aEventSticky = this.createMockEvent(65, {stickyMode: true});
-
- // 'a' key with prefix key
- this.aEventPrefix = this.createMockEvent(65, {prefixKey: true});
-
- // 'a' key with alt (which is the mock ChromeVox modifier) held down
- this.altAEvent = this.createMockEvent(65, {altKey: true});
-
- // 'b' key, no modifiers
- this.bEvent = this.createMockEvent(66);
-
- // 'b' key, with ctrl held down
- this.ctrlBEvent = this.createMockEvent(66, {ctrlKey: true});
-
- // 'c' key, no modifiers
- this.cEvent = this.createMockEvent(67);
-
- // Shift key with ctrl held down
- this.ctrlShiftEvent = this.createMockEvent(60, {ctrlKey: true});
-
- // Ctrl key with shift held down
- this.shiftCtrlEvent = this.createMockEvent(17, {shiftKey: true});
- }
-};
-
-TEST_F('CvoxKeySequenceUnitTest', 'SimpleSequenceNoModifier', function() {
- var downKey = new cvox.KeySequence(this.downArrowEvent, false);
-
- assertEqualsJSON([40], downKey.keys.keyCode);
- assertFalse(downKey.stickyMode);
- assertFalse(downKey.prefixKey);
- assertFalse(downKey.cvoxModifier);
-
- assertEqualsJSON([false], downKey.keys.altGraphKey);
- assertEqualsJSON([false], downKey.keys.altKey);
- assertEqualsJSON([false], downKey.keys.ctrlKey);
- assertEqualsJSON([false], downKey.keys.metaKey);
- assertEqualsJSON([false], downKey.keys.searchKeyHeld);
- assertEqualsJSON([false], downKey.keys.shiftKey);
-
- assertEquals(1, downKey.length());
-});
-
-
-/** Test another key sequence, this time with the modifier */
-TEST_F('CvoxKeySequenceUnitTest', 'SimpleSequenceWithModifier', function() {
- var downKey = new cvox.KeySequence(this.downArrowEvent, true);
-
- assertEqualsJSON([40], downKey.keys.keyCode);
- assertFalse(downKey.stickyMode);
- assertFalse(downKey.prefixKey);
- assertTrue(downKey.cvoxModifier);
-
- assertEqualsJSON([false], downKey.keys.altGraphKey);
- assertEqualsJSON([false], downKey.keys.altKey);
- assertEqualsJSON([false], downKey.keys.ctrlKey);
- assertEqualsJSON([false], downKey.keys.metaKey);
- assertEqualsJSON([false], downKey.keys.searchKeyHeld);
- assertEqualsJSON([false], downKey.keys.shiftKey);
-
- assertEquals(1, downKey.length());
-});
-
-
-/** Test a key sequence that includes the modifier */
-TEST_F('CvoxKeySequenceUnitTest', 'ModifiedSequence', function() {
- var cvoxDownKey = new cvox.KeySequence(this.altDownArrowEvent, true);
-
- assertEqualsJSON([40], cvoxDownKey.keys.keyCode);
- assertFalse(cvoxDownKey.stickyMode);
- assertFalse(cvoxDownKey.prefixKey);
- assertTrue(cvoxDownKey.cvoxModifier);
-
- assertEqualsJSON([false], cvoxDownKey.keys.altGraphKey);
- assertEqualsJSON([false], cvoxDownKey.keys.altKey);
- assertEqualsJSON([false], cvoxDownKey.keys.ctrlKey);
- assertEqualsJSON([false], cvoxDownKey.keys.metaKey);
- assertEqualsJSON([false], cvoxDownKey.keys.searchKeyHeld);
- assertEqualsJSON([false], cvoxDownKey.keys.shiftKey);
-
- assertEquals(1, cvoxDownKey.length());
-});
-
-
-/**
- * Test equality - Ctrl key vs. Ctrl key with sticky mode on
- * These should be equal because Ctrl should still function even with
- * sticky mode on.
-*/
-TEST_F('CvoxKeySequenceUnitTest', 'StickyEquality', function() {
- var ctrlKey = new cvox.KeySequence(this.ctrlEvent, false);
- var ctrlSticky = new cvox.KeySequence(this.ctrlStickyEvent, false);
-
- assertTrue(ctrlKey.equals(ctrlSticky));
-});
-
-
-/**
- * Test equality - 'a' key with Shift modifier vs. 'a' key without Shift
- * modifier.
- * These should not be equal because they do not have the same modifiers.
-*/
-TEST_F('CvoxKeySequenceUnitTest', 'ShiftEquality', function() {
- var aKey = new cvox.KeySequence(this.aEvent, false);
- var shiftA = new cvox.KeySequence(this.shiftAEvent, false);
-
- assertFalse(aKey.equals(shiftA));
-});
-
-
-/**
- * Test equality - 'a' with ChromeVox modifier specified, 'a' with sticky mode
- * on, 'a' with prefix key, and 'a' with ChromeVox modifier held down. These
- * should all be equal to each other.
- */
-TEST_F('CvoxKeySequenceUnitTest', 'FourWayEquality', function() {
- var commandSequence = new cvox.KeySequence(this.aEvent, true);
- var stickySequence = new cvox.KeySequence(this.aEventSticky, false);
- var prefixSequence = new cvox.KeySequence(this.aEventPrefix, false);
- var cvoxModifierSequence = new cvox.KeySequence(this.altAEvent);
-
- assertTrue(commandSequence.equals(stickySequence));
- assertTrue(commandSequence.equals(prefixSequence));
- assertTrue(commandSequence.equals(cvoxModifierSequence));
-
- assertTrue(stickySequence.equals(commandSequence));
- assertTrue(stickySequence.equals(prefixSequence));
- assertTrue(stickySequence.equals(cvoxModifierSequence));
-
- assertTrue(prefixSequence.equals(commandSequence));
- assertTrue(prefixSequence.equals(stickySequence));
- assertTrue(prefixSequence.equals(cvoxModifierSequence));
-
- assertTrue(cvoxModifierSequence.equals(commandSequence));
- assertTrue(cvoxModifierSequence.equals(stickySequence));
- assertTrue(cvoxModifierSequence.equals(prefixSequence));
-});
-
-
-/**
- * Test equality - 'a' key with Shift modifier and prefix vs. 'a' key with Shift
- * modifier and sticky mode vs. 'a' key with Shift modifier and ChromeVox
- * modifier specified vs. 'a' key with ChromeVox modifier held down.
- * These should all be equal to each other..
-*/
-TEST_F('CvoxKeySequenceUnitTest', 'ShiftPrefixEquality', function() {
- var shiftAWithModifier = new cvox.KeySequence(this.shiftAEvent, true);
- var shiftAWithPrefix = new cvox.KeySequence(this.shiftAPrefixEvent, false);
- var shiftASticky = new cvox.KeySequence(this.shiftAStickyEvent, false);
- var cvoxShiftA = new cvox.KeySequence(this.altShiftAEvent);
-
- assertTrue(shiftAWithModifier.equals(shiftAWithPrefix));
- assertTrue(shiftAWithModifier.equals(shiftASticky));
- assertTrue(shiftAWithModifier.equals(cvoxShiftA));
-
- assertTrue(shiftAWithPrefix.equals(shiftAWithModifier));
- assertTrue(shiftAWithPrefix.equals(shiftASticky));
- assertTrue(shiftAWithPrefix.equals(cvoxShiftA));
-
- assertTrue(shiftASticky.equals(shiftAWithPrefix));
- assertTrue(shiftASticky.equals(shiftAWithModifier));
- assertTrue(shiftASticky.equals(cvoxShiftA));
-
- assertTrue(cvoxShiftA.equals(shiftAWithModifier));
- assertTrue(cvoxShiftA.equals(shiftAWithPrefix));
- assertTrue(cvoxShiftA.equals(shiftASticky));
-});
-
-
-/**
- * Test inequality - 'a' with modifier key vs. 'a' without modifier key.
- * These should not be equal.
-*/
-TEST_F('CvoxKeySequenceUnitTest', 'Inequality', function() {
- var aNoModifier = new cvox.KeySequence(this.aEvent, false);
- var aWithModifier = new cvox.KeySequence(this.aEvent, true);
-
- assertFalse(aNoModifier.equals(aWithModifier));
- assertFalse(aWithModifier.equals(aNoModifier));
-});
-
-
-/**
- * Test equality - adding an additional key onto a sequence.
- */
-TEST_F('CvoxKeySequenceUnitTest', 'CvoxCtrl', function() {
- var cvoxCtrlSequence = new cvox.KeySequence(this.ctrlEvent, true);
- assertTrue(cvoxCtrlSequence.addKeyEvent(this.rightArrowEvent));
-
- assertEquals(2, cvoxCtrlSequence.length());
-
- // Can't add more than two key events.
- assertFalse(cvoxCtrlSequence.addKeyEvent(this.rightArrowEvent));
-
- var cvoxCtrlStickySequence = new cvox.KeySequence(this.ctrlStickyEvent,
- false);
- assertTrue(cvoxCtrlStickySequence.addKeyEvent(this.rightArrowEvent));
-
- var mockCtrlPrefixSequence = new cvox.KeySequence(this.ctrlPrefixEvent,
- false);
- assertTrue(mockCtrlPrefixSequence.addKeyEvent(this.rightArrowEvent));
-
- assertTrue(cvoxCtrlSequence.equals(cvoxCtrlStickySequence));
- assertTrue(cvoxCtrlStickySequence.equals(cvoxCtrlSequence));
-
- assertTrue(cvoxCtrlSequence.equals(mockCtrlPrefixSequence));
- assertTrue(mockCtrlPrefixSequence.equals(cvoxCtrlSequence));
-
- assertTrue(cvoxCtrlStickySequence.equals(mockCtrlPrefixSequence));
- assertTrue(mockCtrlPrefixSequence.equals(cvoxCtrlStickySequence));
-});
-
-
-/**
- * Test for inequality - key sequences in different orders.
- */
-TEST_F('CvoxKeySequenceUnitTest', 'DifferentSequences', function() {
- var cvoxBSequence = new cvox.KeySequence(this.bEvent, true);
- assertTrue(cvoxBSequence.addKeyEvent(this.cEvent));
-
- var cvoxCSequence = new cvox.KeySequence(this.cEvent, false);
- assertTrue(cvoxCSequence.addKeyEvent(this.bEvent));
-
- assertFalse(cvoxBSequence.equals(cvoxCSequence));
- assertFalse(cvoxCSequence.equals(cvoxBSequence));
-});
-
-
-/**
- * Tests modifiers (ctrl, alt, etc) - if two sequences have different modifiers
- * held down then they aren't equal.
- */
-TEST_F('CvoxKeySequenceUnitTest', 'MoreModifiers', function() {
- var ctrlASequence = new cvox.KeySequence(this.ctrlAEvent, false);
- var ctrlModifierKeyASequence = new cvox.KeySequence(this.ctrlAEvent, true);
-
- var ctrlBSequence = new cvox.KeySequence(this.ctrlBEvent, false);
-
- var metaASequence = new cvox.KeySequence(this.metaAEvent, false);
-
- assertFalse(ctrlASequence.equals(metaASequence));
- assertFalse(ctrlASequence.equals(ctrlModifierKeyASequence));
- assertFalse(ctrlASequence.equals(ctrlBSequence));
-});
-
-
-/**
- * Tests modifier (ctrl, alt, etc) order - if two sequences have the same
- * modifiers but held down in a different order then they aren't equal.
- */
-TEST_F('CvoxKeySequenceUnitTest', 'ModifierOrder', function() {
- var ctrlShiftSequence = new cvox.KeySequence(this.ctrlShiftEvent, false);
- var shiftCtrlSequence = new cvox.KeySequence(this.shiftCtrlEvent, true);
-
- assertFalse(ctrlShiftSequence.equals(shiftCtrlSequence));
-});
-
-
-/**
- * Tests converting from a string to a KeySequence object.
- */
-TEST_F('CvoxKeySequenceUnitTest', 'FromStr', function() {
- var ctrlString = cvox.KeySequence.fromStr('Ctrl');
- assertEqualsJSON(ctrlString.keys.ctrlKey, [true]);
- assertEqualsJSON(ctrlString.keys.keyCode, [17]);
-
- var modifiedLetterString = cvox.KeySequence.fromStr('Ctrl+Z');
- assertEqualsJSON(modifiedLetterString.keys.ctrlKey, [true]);
- assertEqualsJSON(modifiedLetterString.keys.keyCode, [90]);
-
- var keyCodeString = cvox.KeySequence.fromStr('#9');
- assertEqualsJSON(keyCodeString.keys.keyCode, [9]);
-
- var modifiedKeyCodeString = cvox.KeySequence.fromStr('Shift+#9');
- assertEqualsJSON(modifiedKeyCodeString.keys.shiftKey, [true]);
- assertEqualsJSON(modifiedKeyCodeString.keys.keyCode, [9]);
-
- var cvoxLetterString = cvox.KeySequence.fromStr('Cvox+U');
- assertTrue(cvoxLetterString.cvoxModifier);
- assertEqualsJSON(cvoxLetterString.keys.keyCode, [85]);
-
- var cvoxSequenceString = cvox.KeySequence.fromStr('Cvox+C>T');
- assertTrue(cvoxSequenceString.cvoxModifier);
- assertEqualsJSON(cvoxSequenceString.keys.keyCode, [67, 84]);
-
- var cvoxSequenceKeyCodeString = cvox.KeySequence.fromStr('Cvox+L>#186');
- assertTrue(cvoxSequenceKeyCodeString.cvoxModifier);
- assertEqualsJSON(cvoxSequenceKeyCodeString.keys.keyCode, [76, 186]);
-
- var stickyString = cvox.KeySequence.fromStr('Insert>Insert+');
- assertEqualsJSON(stickyString.keys.keyCode, [45, 45]);
-});
-
-
-/**
- * Tests converting from a JSON string to a KeySequence object.
- */
-TEST_F('CvoxKeySequenceUnitTest', 'Deserialize', function() {
- var forwardSequence = cvox.KeySequence.deserialize({'cvoxModifier': true,
- 'stickyMode': false, 'prefixKey': false, 'keys': {'ctrlKey': [false],
- 'searchKeyHeld': [false], 'altKey': [false], 'altGraphKey': [false],
- 'shiftKey': [false], 'metaKey': [false], 'keyCode': [40]}});
- assertTrue(forwardSequence.cvoxModifier);
- assertEqualsJSON(forwardSequence.keys.keyCode, [40]);
-
- var ctrlSequence = cvox.KeySequence.deserialize({'cvoxModifier': false,
- 'stickyMode': true, 'prefixKey': false, 'keys': {'ctrlKey': [true],
- 'searchKeyHeld': [false], 'altKey': [false], 'altGraphKey': [false],
- 'shiftKey': [false], 'metaKey': [false], 'keyCode': [17]}});
- assertEqualsJSON(ctrlSequence.keys.ctrlKey, [true]);
- assertEqualsJSON(ctrlSequence.keys.keyCode, [17]);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/key_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/key_util.js
deleted file mode 100644
index 5ff64d01d7a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/key_util.js
+++ /dev/null
@@ -1,500 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A collection of JavaScript utilities used to simplify working
- * with keyboard events.
- */
-
-
-goog.provide('cvox.KeyUtil');
-goog.provide('cvox.SimpleKeyEvent');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.KeySequence');
-
-/**
- * @typedef {{ctrlKey: (boolean|undefined),
- * altKey: (boolean|undefined),
- * shiftKey: (boolean|undefined),
- * keyCode: (number|undefined)}}
- */
-cvox.SimpleKeyEvent;
-
-/**
- * Create the namespace
- * @constructor
- */
-cvox.KeyUtil = function() {
-};
-
-/**
- * The time in ms at which the ChromeVox Sticky Mode key was pressed.
- * @type {number}
- */
-cvox.KeyUtil.modeKeyPressTime = 0;
-
-/**
- * Indicates if sequencing is currently active for building a keyboard shortcut.
- * @type {boolean}
- */
-cvox.KeyUtil.sequencing = false;
-
-/**
- * The previous KeySequence when sequencing is ON.
- * @type {cvox.KeySequence}
- */
-cvox.KeyUtil.prevKeySequence = null;
-
-
-/**
- * The sticky key sequence.
- * @type {cvox.KeySequence}
- */
-cvox.KeyUtil.stickyKeySequence = null;
-
-/**
- * Maximum number of key codes the sequence buffer may hold. This is the max
- * length of a sequential keyboard shortcut, i.e. the number of key that can be
- * pressed one after the other while modifier keys (Cros+Shift) are held down.
- * @const
- * @type {number}
- */
-cvox.KeyUtil.maxSeqLength = 2;
-
-
-/**
- * Convert a key event into a Key Sequence representation.
- *
- * @param {Event|cvox.SimpleKeyEvent} keyEvent The keyEvent to convert.
- * @return {cvox.KeySequence} A key sequence representation of the key event.
- */
-cvox.KeyUtil.keyEventToKeySequence = function(keyEvent) {
- var util = cvox.KeyUtil;
- if (util.prevKeySequence &&
- (util.maxSeqLength == util.prevKeySequence.length())) {
- // Reset the sequence buffer if max sequence length is reached.
- util.sequencing = false;
- util.prevKeySequence = null;
- }
- // Either we are in the middle of a key sequence (N > H), or the key prefix
- // was pressed before (Ctrl+Z), or sticky mode is enabled
- var keyIsPrefixed = util.sequencing || keyEvent['keyPrefix'] ||
- keyEvent['stickyMode'];
-
- // Create key sequence.
- var keySequence = new cvox.KeySequence(keyEvent);
-
- // Check if the Cvox key should be considered as pressed because the
- // modifier key combination is active.
- var keyWasCvox = keySequence.cvoxModifier;
-
- if (keyIsPrefixed || keyWasCvox) {
- if (!util.sequencing && util.isSequenceSwitchKeyCode(keySequence)) {
- // If this is the beginning of a sequence.
- util.sequencing = true;
- util.prevKeySequence = keySequence;
- return keySequence;
- } else if (util.sequencing) {
- if (util.prevKeySequence.addKeyEvent(keyEvent)) {
- keySequence = util.prevKeySequence;
- util.prevKeySequence = null;
- util.sequencing = false;
- return keySequence;
- } else {
- throw 'Think sequencing is enabled, yet util.prevKeySequence already' +
- 'has two key codes' + util.prevKeySequence;
- }
- }
- } else {
- util.sequencing = false;
- }
-
- // Repeated keys pressed.
- var currTime = new Date().getTime();
- if (cvox.KeyUtil.isDoubleTapKey(keySequence) &&
- util.prevKeySequence &&
- keySequence.equals(util.prevKeySequence)) {
- var prevTime = util.modeKeyPressTime;
- if (prevTime > 0 && currTime - prevTime < 300) { // Double tap
- keySequence = util.prevKeySequence;
- keySequence.doubleTap = true;
- util.prevKeySequence = null;
- util.sequencing = false;
- // Resets the search key state tracked for ChromeOS because in OOBE,
- // we never get a key up for the key down (keyCode 91).
- if (cvox.ChromeVox.isChromeOS &&
- keyEvent.keyCode == cvox.KeyUtil.getStickyKeyCode()) {
- cvox.ChromeVox.searchKeyHeld = false;
- }
- return keySequence;
- }
- // The user double tapped the sticky key but didn't do it within the
- // required time. It's possible they will try again, so keep track of the
- // time the sticky key was pressed and keep track of the corresponding
- // key sequence.
- }
- util.prevKeySequence = keySequence;
- util.modeKeyPressTime = currTime;
- return keySequence;
-};
-
-/**
- * Returns the string representation of the specified key code.
- *
- * @param {number} keyCode key code.
- * @return {string} A string representation of the key event.
- */
-cvox.KeyUtil.keyCodeToString = function(keyCode) {
- if (keyCode == 17) {
- return 'Ctrl';
- }
- if (keyCode == 18) {
- return 'Alt';
- }
- if (keyCode == 16) {
- return 'Shift';
- }
- if ((keyCode == 91) || (keyCode == 93)) {
- if (cvox.ChromeVox.isChromeOS) {
- return 'Search';
- } else if (cvox.ChromeVox.isMac) {
- return 'Cmd';
- } else {
- return 'Win';
- }
- }
- // TODO(rshearer): This is a hack to work around the special casing of the
- // sticky mode string that used to happen in keyEventToString. We won't need
- // it once we move away from strings completely.
- if (keyCode == 45) {
- return 'Insert';
- }
- if (keyCode >= 65 && keyCode <= 90) {
- // A - Z
- return String.fromCharCode(keyCode);
- } else if (keyCode >= 48 && keyCode <= 57) {
- // 0 - 9
- return String.fromCharCode(keyCode);
- } else {
- // Anything else
- return '#' + keyCode;
- }
-};
-
-/**
- * Returns the keycode of a string representation of the specified modifier.
- *
- * @param {string} keyString Modifier key.
- * @return {number} Key code.
- */
-cvox.KeyUtil.modStringToKeyCode = function(keyString) {
- switch (keyString) {
- case 'Ctrl':
- return 17;
- case 'Alt':
- return 18;
- case 'Shift':
- return 16;
- case 'Cmd':
- case 'Win':
- return 91;
- }
- return -1;
-};
-
-/**
- * Returns the key codes of a string respresentation of the ChromeVox modifiers.
- *
- * @return {Array<number>} Array of key codes.
- */
-cvox.KeyUtil.cvoxModKeyCodes = function() {
- var modKeyCombo = cvox.ChromeVox.modKeyStr.split(/\+/g);
- var modKeyCodes = modKeyCombo.map(function(keyString) {
- return cvox.KeyUtil.modStringToKeyCode(keyString);
- });
- return modKeyCodes;
-};
-
-/**
- * Checks if the specified key code is a key used for switching into a sequence
- * mode. Sequence switch keys are specified in
- * cvox.KeyUtil.sequenceSwitchKeyCodes
- *
- * @param {!cvox.KeySequence} rhKeySeq The key sequence to check.
- * @return {boolean} true if it is a sequence switch keycode, false otherwise.
- */
-cvox.KeyUtil.isSequenceSwitchKeyCode = function(rhKeySeq) {
- for (var i = 0; i < cvox.ChromeVox.sequenceSwitchKeyCodes.length; i++) {
- var lhKeySeq = cvox.ChromeVox.sequenceSwitchKeyCodes[i];
- if (lhKeySeq.equals(rhKeySeq)) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Get readable string description of the specified keycode.
- *
- * @param {number} keyCode The key code.
- * @return {string} Returns a string description.
- */
-cvox.KeyUtil.getReadableNameForKeyCode = function(keyCode) {
- if (keyCode == 0) {
- return 'Power button';
- } else if (keyCode == 17) {
- return 'Control';
- } else if (keyCode == 18) {
- return 'Alt';
- } else if (keyCode == 16) {
- return 'Shift';
- } else if (keyCode == 9) {
- return 'Tab';
- } else if ((keyCode == 91) || (keyCode == 93)) {
- if (cvox.ChromeVox.isChromeOS) {
- return 'Search';
- } else if (cvox.ChromeVox.isMac) {
- return 'Cmd';
- } else {
- return 'Win';
- }
- } else if (keyCode == 8) {
- return 'Backspace';
- } else if (keyCode == 32) {
- return 'Space';
- } else if (keyCode == 35) {
- return'end';
- } else if (keyCode == 36) {
- return 'home';
- } else if (keyCode == 37) {
- return 'Left arrow';
- } else if (keyCode == 38) {
- return 'Up arrow';
- } else if (keyCode == 39) {
- return 'Right arrow';
- } else if (keyCode == 40) {
- return 'Down arrow';
- } else if (keyCode == 45) {
- return 'Insert';
- } else if (keyCode == 13) {
- return 'Enter';
- } else if (keyCode == 27) {
- return 'Escape';
- } else if (keyCode == 112) {
- return cvox.ChromeVox.isChromeOS ? 'Back' : 'F1';
- } else if (keyCode == 113) {
- return cvox.ChromeVox.isChromeOS ? 'Forward' : 'F2';
- } else if (keyCode == 114) {
- return cvox.ChromeVox.isChromeOS ? 'Refresh' : 'F3';
- } else if (keyCode == 115) {
- return cvox.ChromeVox.isChromeOS ? 'Toggle full screen' : 'F4';
- } else if (keyCode == 116) {
- return 'F5';
- } else if (keyCode == 117) {
- return 'F6';
- } else if (keyCode == 118) {
- return 'F7';
- } else if (keyCode == 119) {
- return 'F8';
- } else if (keyCode == 120) {
- return 'F9';
- } else if (keyCode == 121) {
- return 'F10';
- } else if (keyCode == 122) {
- return 'F11';
- } else if (keyCode == 123) {
- return 'F12';
- } else if (keyCode == 186) {
- return 'Semicolon';
- } else if (keyCode == 187) {
- return 'Equal sign';
- } else if (keyCode == 188) {
- return 'Comma';
- } else if (keyCode == 189) {
- return 'Dash';
- } else if (keyCode == 190) {
- return 'Period';
- } else if (keyCode == 191) {
- return 'Forward slash';
- } else if (keyCode == 192) {
- return 'Grave accent';
- } else if (keyCode == 219) {
- return 'Open bracket';
- } else if (keyCode == 220) {
- return 'Back slash';
- } else if (keyCode == 221) {
- return 'Close bracket';
- } else if (keyCode == 222) {
- return 'Single quote';
- } else if (keyCode == 115) {
- return 'Toggle full screen';
- } else if (keyCode >= 48 && keyCode <= 90) {
- return String.fromCharCode(keyCode);
- }
-};
-
-/**
- * Get the platform specific sticky key keycode.
- *
- * @return {number} The platform specific sticky key keycode.
- */
-cvox.KeyUtil.getStickyKeyCode = function() {
- // TODO (rshearer): This should not be hard-coded here.
- var stickyKeyCode = 45; // Insert for Linux and Windows
- if (cvox.ChromeVox.isChromeOS || cvox.ChromeVox.isMac) {
- stickyKeyCode = 91; // GUI key (Search/Cmd) for ChromeOs and Mac
- }
- return stickyKeyCode;
-};
-
-
-/**
- * Get readable string description for an internal string representation of a
- * key or a keyboard shortcut.
- *
- * @param {string} keyStr The internal string repsentation of a key or
- * a keyboard shortcut.
- * @return {?string} Readable string representation of the input.
- */
-cvox.KeyUtil.getReadableNameForStr = function(keyStr) {
- // TODO (clchen): Refactor this function away since it is no longer used.
- return null;
-};
-
-
-/**
- * Creates a string representation of a KeySequence.
- * A KeySequence with a keyCode of 76 ('L') and the control and alt keys down
- * would return the string 'Ctrl+Alt+L', for example. A key code that doesn't
- * correspond to a letter or number will typically return a string with a
- * pound and then its keyCode, like '#39' for Right Arrow. However,
- * if the opt_readableKeyCode option is specified, the key code will return a
- * readable string description like 'Right Arrow' instead of '#39'.
- *
- * The modifiers always come in this order:
- *
- * Ctrl
- * Alt
- * Shift
- * Meta
- *
- * @param {cvox.KeySequence} keySequence The KeySequence object.
- * @param {boolean=} opt_readableKeyCode Whether or not to return a readable
- * string description instead of a string with a pound symbol and a keycode.
- * Default is false.
- * @param {boolean=} opt_modifiers Restrict printout to only modifiers. Defaults
- * to false.
- * @return {string} Readable string representation of the KeySequence object.
- */
-cvox.KeyUtil.keySequenceToString = function(
- keySequence, opt_readableKeyCode, opt_modifiers) {
- // TODO(rshearer): Move this method and the getReadableNameForKeyCode and the
- // method to KeySequence after we refactor isModifierActive (when the modifie
- // key becomes customizable and isn't stored as a string). We can't do it
- // earlier because isModifierActive uses KeyUtil.getReadableNameForKeyCode,
- // and I don't want KeySequence to depend on KeyUtil.
- var str = '';
-
- var numKeys = keySequence.length();
-
- for (var index = 0; index < numKeys; index++) {
- if (str != '' && !opt_modifiers) {
- str += '>';
- } else if (str != '') {
- str += '+';
- }
-
- // This iterates through the sequence. Either we're on the first key
- // pressed or the second
- var tempStr = '';
- for (var keyPressed in keySequence.keys) {
- // This iterates through the actual key, taking into account any
- // modifiers.
- if (!keySequence.keys[keyPressed][index]) {
- continue;
- }
- var modifier = '';
- switch (keyPressed) {
- case 'ctrlKey':
- // TODO(rshearer): This is a hack to work around the special casing
- // of the Ctrl key that used to happen in keyEventToString. We won't
- // need it once we move away from strings completely.
- modifier = 'Ctrl';
- break;
- case 'searchKeyHeld':
- var searchKey = cvox.KeyUtil.getReadableNameForKeyCode(91);
- modifier = searchKey;
- break;
- case 'altKey':
- modifier = 'Alt';
- break;
- case 'altGraphKey':
- modifier = 'AltGraph';
- break;
- case 'shiftKey':
- modifier = 'Shift';
- break;
- case 'metaKey':
- var metaKey = cvox.KeyUtil.getReadableNameForKeyCode(91);
- modifier = metaKey;
- break;
- case 'keyCode':
- var keyCode = keySequence.keys[keyPressed][index];
- // We make sure the keyCode isn't for a modifier key. If it is, then
- // we've already added that into the string above.
- if (!keySequence.isModifierKey(keyCode) && !opt_modifiers) {
- if (opt_readableKeyCode) {
- tempStr += cvox.KeyUtil.getReadableNameForKeyCode(keyCode);
- } else {
- tempStr += cvox.KeyUtil.keyCodeToString(keyCode);
- }
- }
- }
- if (str.indexOf(modifier) == -1) {
- tempStr += modifier + '+';
- }
- }
- str += tempStr;
-
- // Strip trailing +.
- if (str[str.length - 1] == '+') {
- str = str.slice(0, -1);
- }
- }
-
- if (keySequence.cvoxModifier || keySequence.prefixKey) {
- if (str != '') {
- str = 'Cvox+' + str;
- } else {
- str = 'Cvox';
- }
- } else if (keySequence.stickyMode) {
- if (str[str.length - 1] == '>') {
- str = str.slice(0, -1);
- }
- str = str + '+' + str;
- }
- return str;
-};
-
-/**
- * Looks up if the given key sequence is triggered via double tap.
- * @param {cvox.KeySequence} key The key.
- * @return {boolean} True if key is triggered via double tap.
- */
-cvox.KeyUtil.isDoubleTapKey = function(key) {
- var isSet = false;
- var originalState = key.doubleTap;
- key.doubleTap = true;
- for (var i = 0, keySeq; keySeq = cvox.KeySequence.doubleTapCache[i]; i++) {
- if (keySeq.equals(key)) {
- isSet = true;
- break;
- }
- }
- key.doubleTap = originalState;
- return isSet;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_attr.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_attr.js
deleted file mode 100644
index 940121dc852..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_attr.js
+++ /dev/null
@@ -1,1529 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Semantic attributes of Math symbols and expressions.
- *
- * This file contains the basic functionality to lookup and assign semantic
- * attributes for mathematical expressions. Since there is no such thing as a
- * well-defined semantics for all of mathematics we compute a default semantics
- * that closely models mathematical expressions found in K-12 mathematics as
- * well as in general undergraduate curriculum (i.e., calculus, linear algebra,
- * etc).
- *
- * Currently semantic attributes of symbols consist of the following two parts:
- *
- * type -- An unmutable property of an expression, regardless of its position in
- * the math expression. For example, the letter 'f' will always have the
- * type identifier, regardless of its use in context, e.g. as function
- * symbol or variable.
- *
- * role -- A mutable description of the role an expression plays in the context
- * of the overall mathematical expression. For instance, the symbol '|'
- * is of type punctuation, but depending on context it has the role of a
- * neutral fence or of a single vertical bar.
- *
- * In addition for some symbols we record the font as a further attribute.
- *
- * When a semantically interpreted expression is transformed into a XML
- * representation, types become tag names, while role, font, etc. are added as
- * attributes.
- *
- * This file is part of the content script as we do not want to call out to the
- * background page every time we need to look up the semantic of a symbol.
- *
- * TODO (sorge) Move semantic tree translation into the background page
- * alongside MathJax.
- *
- */
-
-goog.provide('cvox.SemanticAttr');
-
-goog.require('cvox.SemanticUtil');
-
-
-/**
- * Contains the basic mappings of characters/symbols and functions to semantic
- * attributes.
- *
- * Observe that all characters are given as hex code number in order to ease the
- * comparison with those in the JSON files that define speech rules per
- * character.
- * @constructor
- */
-cvox.SemanticAttr = function() {
- // Punctuation Characters.
- /**
- * @type {Array<string>}
- */
- this.generalPunctuations =
- [
- '!', '"', '#', '%', '&', '\'', '*', ',', ':', ';', '?', '@', '\\',
- '¡', '§', '¶', '·', '¿', '‗', '†', '‡', '•', '‣', '․', '‥', '‧',
- '‰', '‱', '‸', '※', '‼', '‽', '‾', '⁁', '⁂', '⁃', '⁇', '⁈', '⁉',
- '⁋', '⁌', '⁍', '⁎', '⁏', '⁐', '⁑', '⁓', '⁕', '⁖', '⁘', '⁙', '⁚',
- '⁛', '⁜', '⁝', '⁞', '︐', '︓', '︔', '︕', '︖', '︰', '﹅', '﹆',
- '﹉', '﹊', '﹋', '﹌', '﹐', '﹔', '﹕', '﹖', '﹗', '﹟', '﹠', '﹡', '﹨',
- '﹪', '﹫', '!', '"', '#', '%', '&', ''', '*', ',', '/', ':',
- ';', '?', '@', '\'
- ];
- /**
- * @type {string}
- * @private
- */
- this.invisibleComma_ = cvox.SemanticUtil.numberToUnicode(0x2063);
- this.generalPunctuations.push(this.invisibleComma_);
- /**
- * @type {Array<string>}
- */
- this.ellipses =
- [
- '…', '⋮', '⋯', '⋰', '⋱', '︙'
- ];
- /**
- * @type {Array<string>}
- */
- this.fullStops =
- [
- '.', '﹒', '.'
- ];
- /**
- * @type {Array<string>}
- */
- this.dashes =
- [
- '‒', '–', '—', '―', '〜', '︱', '︲', '﹘'
- ];
- /**
- * @type {Array<string>}
- */
- this.primes =
- [
- '′', '″', '‴', '‵', '‶', '‷', '⁗'
- ];
-
- // Fences.
- // Fences are treated slightly differently from other symbols as we want to
- // record pairs of opening/closing and top/bottom fences.
- /**
- * Mapping opening to closing fences.
- * @type {Object<string>}
- */
- this.openClosePairs =
- {
- // Unicode categories Ps and Pe.
- // Observe that left quotation 301D could also be matched to 301F,
- // but is currently matched to 301E.
- '(': ')', '[': ']', '{': '}', '⁅': '⁆', '〈': '〉', '❨': '❩',
- '❪': '❫', '❬': '❭', '❮': '❯', '❰': '❱', '❲': '❳', '❴': '❵',
- '⟅': '⟆', '⟦': '⟧', '⟨': '⟩', '⟪': '⟫', '⟬': '⟭', '⟮': '⟯',
- '⦃': '⦄', '⦅': '⦆', '⦇': '⦈', '⦉': '⦊', '⦋': '⦌', '⦍': '⦎',
- '⦏': '⦐', '⦑': '⦒', '⦓': '⦔', '⦕': '⦖', '⦗': '⦘', '⧘': '⧙',
- '⧚': '⧛', '⧼': '⧽', '⸢': '⸣', '⸤': '⸥', '⸦': '⸧', '⸨': '⸩',
- '〈': '〉', '《': '》', '「': '」', '『': '』', '【': '】',
- '〔': '〕', '〖': '〗', '〘': '〙', '〚': '〛', '〝': '〞',
- '﴾': '﴿', '︗': '︘', '﹙': '﹚', '﹛': '﹜', '﹝': '﹞', '(': ')',
- '[': ']', '{': '}', '⦅': '⦆', '「': '」',
- // Unicode categories Sm and So.
- '⌈': '⌉', '⌊': '⌋', '⌌': '⌍', '⌎': '⌏', '⌜': '⌝', '⌞': '⌟',
- // Extender fences.
- // Parenthesis.
- '⎛': '⎞', '⎜': '⎟', '⎝': '⎠',
- // Square bracket.
- '⎡': '⎤', '⎢': '⎥', '⎣': '⎦',
- // Curly bracket.
- '⎧': '⎫', '⎨': '⎬', '⎩': '⎭', '⎰': '⎱', '⎸': '⎹'
- };
- /**
- * Mapping top to bottom fences.
- * @type {Object<string>}
- */
- this.topBottomPairs =
- {
- '⎴': '⎵', '⏜': '⏝', '⏞': '⏟', '⏠': '⏡', '︵': '︶', '︷': '︸',
- '︹': '︺', '︻': '︼', '︽': '︾', '︿': '﹀', '﹁': '﹂',
- '﹃': '﹄', '﹇': '﹈'
- };
- /**
- * @type {Array<string>}
- */
- this.leftFences = cvox.SemanticUtil.objectsToKeys(this.openClosePairs);
- /**
- * @type {Array<string>}
- */
- this.rightFences = cvox.SemanticUtil.objectsToValues(this.openClosePairs);
- this.rightFences.push('〟');
- /**
- * @type {Array<string>}
- */
- this.topFences = cvox.SemanticUtil.objectsToKeys(this.topBottomPairs);
- /**
- * @type {Array<string>}
- */
- this.bottomFences = cvox.SemanticUtil.objectsToValues(this.topBottomPairs);
- /**
- * @type {Array<string>}
- */
- this.neutralFences =
- [
- '|', '¦', '‖', '❘', '⦀', '⫴', '¦', '|'
- ];
- /** Array of all fences.
- * @type {Array<string>}
- */
- this.fences = this.neutralFences.concat(
- this.leftFences, this.rightFences, this.topFences, this.bottomFences);
-
- // Identifiers.
- // Latin Alphabets.
- /**
- * @type {Array<string>}
- */
- this.capitalLatin =
- [
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatin =
- [
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- // dotless i and j.
- 'ı', 'ȷ'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinFullWidth =
- [
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinFullWidth =
- [
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinBold =
- [
- '𝐀', '𝐁', '𝐂', '𝐃', '𝐄', '𝐅', '𝐆', '𝐇', '𝐈', '𝐉', '𝐊', '𝐋', '𝐌',
- '𝐍', '𝐎', '𝐏', '𝐐', '𝐑', '𝐒', '𝐓', '𝐔', '𝐕', '𝐖', '𝐗', '𝐘', '𝐙'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinBold =
- [
- '𝐚', '𝐛', '𝐜', '𝐝', '𝐞', '𝐟', '𝐠', '𝐡', '𝐢', '𝐣', '𝐤', '𝐥', '𝐦',
- '𝐧', '𝐨', '𝐩', '𝐪', '𝐫', '𝐬', '𝐭', '𝐮', '𝐯', '𝐰', '𝐱', '𝐲', '𝐳'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinItalic =
- [
- '𝐴', '𝐵', '𝐶', '𝐷', '𝐸', '𝐹', '𝐺', '𝐻', '𝐼', '𝐽', '𝐾', '𝐿', '𝑀',
- '𝑁', '𝑂', '𝑃', '𝑄', '𝑅', '𝑆', '𝑇', '𝑈', '𝑉', '𝑊', '𝑋', '𝑌', '𝑍'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinItalic =
- [
- '𝑎', '𝑏', '𝑐', '𝑑', '𝑒', '𝑓', '𝑔', 'ℎ', '𝑖', '𝑗', '𝑘', '𝑙', '𝑚',
- '𝑛', '𝑜', '𝑝', '𝑞', '𝑟', '𝑠', '𝑡', '𝑢', '𝑣', '𝑤', '𝑥', '𝑦', '𝑧',
- // dotless i and j.
- '𝚤', '𝚥'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinScript =
- [
- '𝒜', 'ℬ', '𝒞', '𝒟', 'ℰ', 'ℱ', '𝒢', 'ℋ', 'ℐ', '𝒥', '𝒦', 'ℒ', 'ℳ',
- '𝒩', '𝒪', '𝒫', '𝒬', 'ℛ', '𝒮', '𝒯', '𝒰', '𝒱', '𝒲', '𝒳', '𝒴', '𝒵',
- // Powerset Cap P.
- '℘'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinScript =
- [
- '𝒶', '𝒷', '𝒸', '𝒹', 'ℯ', '𝒻', 'ℊ', '𝒽', '𝒾', '𝒿', '𝓀', '𝓁', '𝓂',
- '𝓃', 'ℴ', '𝓅', '𝓆', '𝓇', '𝓈', '𝓉', '𝓊', '𝓋', '𝓌', '𝓍', '𝓎', '𝓏',
- // script small l
- 'ℓ'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinBoldScript =
- [
- '𝓐', '𝓑', '𝓒', '𝓓', '𝓔', '𝓕', '𝓖', '𝓗', '𝓘', '𝓙', '𝓚', '𝓛', '𝓜',
- '𝓝', '𝓞', '𝓟', '𝓠', '𝓡', '𝓢', '𝓣', '𝓤', '𝓥', '𝓦', '𝓧', '𝓨', '𝓩'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinBoldScript =
- [
- '𝓪', '𝓫', '𝓬', '𝓭', '𝓮', '𝓯', '𝓰', '𝓱', '𝓲', '𝓳', '𝓴', '𝓵', '𝓶',
- '𝓷', '𝓸', '𝓹', '𝓺', '𝓻', '𝓼', '𝓽', '𝓾', '𝓿', '𝔀', '𝔁', '𝔂', '𝔃'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinFraktur =
- [
- '𝔄', '𝔅', 'ℭ', '𝔇', '𝔈', '𝔉', '𝔊', 'ℌ', 'ℑ', '𝔍', '𝔎', '𝔏', '𝔐',
- '𝔑', '𝔒', '𝔓', '𝔔', 'ℜ', '𝔖', '𝔗', '𝔘', '𝔙', '𝔚', '𝔛', '𝔜', 'ℨ'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinFraktur =
- [
- '𝔞', '𝔟', '𝔠', '𝔡', '𝔢', '𝔣', '𝔤', '𝔥', '𝔦', '𝔧', '𝔨', '𝔩', '𝔪',
- '𝔫', '𝔬', '𝔭', '𝔮', '𝔯', '𝔰', '𝔱', '𝔲', '𝔳', '𝔴', '𝔵', '𝔶', '𝔷'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinDoubleStruck =
- [
- '𝔸', '𝔹', 'ℂ', '𝔻', '𝔼', '𝔽', '𝔾', 'ℍ', '𝕀', '𝕁', '𝕂', '𝕃', '𝕄',
- 'ℕ', '𝕆', 'ℙ', 'ℚ', 'ℝ', '𝕊', '𝕋', '𝕌', '𝕍', '𝕎', '𝕏', '𝕐', 'ℤ'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinDoubleStruck =
- [
- '𝕒', '𝕓', '𝕔', '𝕕', '𝕖', '𝕗', '𝕘', '𝕙', '𝕚', '𝕛', '𝕜', '𝕝', '𝕞',
- '𝕟', '𝕠', '𝕡', '𝕢', '𝕣', '𝕤', '𝕥', '𝕦', '𝕧', '𝕨', '𝕩', '𝕪', '𝕫'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinBoldFraktur =
- [
- '𝕬', '𝕭', '𝕮', '𝕯', '𝕰', '𝕱', '𝕲', '𝕳', '𝕴', '𝕵', '𝕶', '𝕷', '𝕸',
- '𝕹', '𝕺', '𝕻', '𝕼', '𝕽', '𝕾', '𝕿', '𝖀', '𝖁', '𝖂', '𝖃', '𝖄', '𝖅'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinBoldFraktur =
- [
- '𝖆', '𝖇', '𝖈', '𝖉', '𝖊', '𝖋', '𝖌', '𝖍', '𝖎', '𝖏', '𝖐', '𝖑', '𝖒',
- '𝖓', '𝖔', '𝖕', '𝖖', '𝖗', '𝖘', '𝖙', '𝖚', '𝖛', '𝖜', '𝖝', '𝖞', '𝖟'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinSansSerif =
- [
- '𝖠', '𝖡', '𝖢', '𝖣', '𝖤', '𝖥', '𝖦', '𝖧', '𝖨', '𝖩', '𝖪', '𝖫', '𝖬',
- '𝖭', '𝖮', '𝖯', '𝖰', '𝖱', '𝖲', '𝖳', '𝖴', '𝖵', '𝖶', '𝖷', '𝖸', '𝖹'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinSansSerif =
- [
- '𝖺', '𝖻', '𝖼', '𝖽', '𝖾', '𝖿', '𝗀', '𝗁', '𝗂', '𝗃', '𝗄', '𝗅', '𝗆',
- '𝗇', '𝗈', '𝗉', '𝗊', '𝗋', '𝗌', '𝗍', '𝗎', '𝗏', '𝗐', '𝗑', '𝗒', '𝗓'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinSansSerifBold =
- [
- '𝗔', '𝗕', '𝗖', '𝗗', '𝗘', '𝗙', '𝗚', '𝗛', '𝗜', '𝗝', '𝗞', '𝗟', '𝗠',
- '𝗡', '𝗢', '𝗣', '𝗤', '𝗥', '𝗦', '𝗧', '𝗨', '𝗩', '𝗪', '𝗫', '𝗬', '𝗭'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinSansSerifBold =
- [
- '𝗮', '𝗯', '𝗰', '𝗱', '𝗲', '𝗳', '𝗴', '𝗵', '𝗶', '𝗷', '𝗸', '𝗹', '𝗺',
- '𝗻', '𝗼', '𝗽', '𝗾', '𝗿', '𝘀', '𝘁', '𝘂', '𝘃', '𝘄', '𝘅', '𝘆', '𝘇'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinSansSerifItalic =
- [
- '𝘈', '𝘉', '𝘊', '𝘋', '𝘌', '𝘍', '𝘎', '𝘏', '𝘐', '𝘑', '𝘒', '𝘓', '𝘔',
- '𝘕', '𝘖', '𝘗', '𝘘', '𝘙', '𝘚', '𝘛', '𝘜', '𝘝', '𝘞', '𝘟', '𝘠', '𝘡'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinSansSerifItalic =
- [
- '𝘢', '𝘣', '𝘤', '𝘥', '𝘦', '𝘧', '𝘨', '𝘩', '𝘪', '𝘫', '𝘬', '𝘭', '𝘮',
- '𝘯', '𝘰', '𝘱', '𝘲', '𝘳', '𝘴', '𝘵', '𝘶', '𝘷', '𝘸', '𝘹', '𝘺', '𝘻'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalLatinMonospace =
- [
- '𝙰', '𝙱', '𝙲', '𝙳', '𝙴', '𝙵', '𝙶', '𝙷', '𝙸', '𝙹', '𝙺', '𝙻', '𝙼',
- '𝙽', '𝙾', '𝙿', '𝚀', '𝚁', '𝚂', '𝚃', '𝚄', '𝚅', '𝚆', '𝚇', '𝚈', '𝚉'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallLatinMonospace =
- [
- '𝚊', '𝚋', '𝚌', '𝚍', '𝚎', '𝚏', '𝚐', '𝚑', '𝚒', '𝚓', '𝚔', '𝚕', '𝚖',
- '𝚗', '𝚘', '𝚙', '𝚚', '𝚛', '𝚜', '𝚝', '𝚞', '𝚟', '𝚠', '𝚡', '𝚢', '𝚣'
- ];
- /**
- * @type {Array<string>}
- */
- this.latinDoubleStruckItalic =
- [
- 'ⅅ', 'ⅆ', 'ⅇ', 'ⅈ', 'ⅉ'
- ];
-
- // Greek Alphabets
- /**
- * @type {Array<string>}
- */
- this.capitalGreek =
- [
- 'Α', 'Β', 'Γ', 'Δ', 'Ε', 'Ζ', 'Η', 'Θ', 'Ι', 'Κ', 'Λ', 'Μ', 'Ν',
- 'Ξ', 'Ο', 'Π', 'Ρ', 'Σ', 'Τ', 'Υ', 'Φ', 'Χ', 'Ψ', 'Ω'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallGreek =
- [
- 'α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν',
- 'ξ', 'ο', 'π', 'ρ', 'ς', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalGreekBold =
- [
- '𝚨', '𝚩', '𝚪', '𝚫', '𝚬', '𝚭', '𝚮', '𝚯', '𝚰', '𝚱', '𝚲', '𝚳', '𝚴',
- '𝚵', '𝚶', '𝚷', '𝚸', '𝚺', '𝚻', '𝚼', '𝚽', '𝚾', '𝚿', '𝛀'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallGreekBold =
- [
- '𝛂', '𝛃', '𝛄', '𝛅', '𝛆', '𝛇', '𝛈', '𝛉', '𝛊', '𝛋', '𝛌', '𝛍', '𝛎',
- '𝛏', '𝛐', '𝛑', '𝛒', '𝛓', '𝛔', '𝛕', '𝛖', '𝛗', '𝛘', '𝛙', '𝛚'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalGreekItalic =
- [
- '𝛢', '𝛣', '𝛤', '𝛥', '𝛦', '𝛧', '𝛨', '𝛩', '𝛪', '𝛫', '𝛬', '𝛭', '𝛮',
- '𝛯', '𝛰', '𝛱', '𝛲', '𝛴', '𝛵', '𝛶', '𝛷', '𝛸', '𝛹', '𝛺'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallGreekItalic =
- [
- '𝛼', '𝛽', '𝛾', '𝛿', '𝜀', '𝜁', '𝜂', '𝜃', '𝜄', '𝜅', '𝜆', '𝜇', '𝜈',
- '𝜉', '𝜊', '𝜋', '𝜌', '𝜍', '𝜎', '𝜏', '𝜐', '𝜑', '𝜒', '𝜓', '𝜔'
- ];
- /**
- * @type {Array<string>}
- */
- this.capitalGreekSansSerifBold =
- [
- '𝝖', '𝝗', '𝝘', '𝝙', '𝝚', '𝝛', '𝝜', '𝝝', '𝝞', '𝝟', '𝝠', '𝝡', '𝝢',
- '𝝣', '𝝤', '𝝥', '𝝦', '𝝨', '𝝩', '𝝪', '𝝫', '𝝬', '𝝭', '𝝮'
- ];
- /**
- * @type {Array<string>}
- */
- this.smallGreekSansSerifBold =
- [
- '𝝰', '𝝱', '𝝲', '𝝳', '𝝴', '𝝵', '𝝶', '𝝷', '𝝸', '𝝹', '𝝺', '𝝻', '𝝼',
- '𝝽', '𝝾', '𝝿', '𝞀', '𝞁', '𝞂', '𝞃', '𝞄', '𝞅', '𝞆', '𝞇', '𝞈'
- ];
- /**
- * @type {Array<string>}
- */
- this.greekDoubleStruck =
- [
- 'ℼ', 'ℽ', 'ℾ', 'ℿ'
- ];
-
- // Other alphabets.
- /**
- * @type {Array<string>}
- */
- this.hebrewLetters =
- [
- 'ℵ', 'ℶ', 'ℷ', 'ℸ'
- ];
-
- //Operator symbols
- /**
- * @type {Array<string>}
- */
- this.additions =
- [
- '+', '±', '∓', '∔', '∧', '∨', '∩', '∪', '⊌', '⊓', '⊔', '⊝', '⊞',
- '⊤', '⊥', '⊺', '⊻', '⊼', '⋄', '⋎', '⋏', '⋒', '⋓', '△', '▷', '▽',
- '◁', '⩞', '⊕'
- ];
- /**
- * @type {Array<string>}
- */
- /**
- * Invisible operator for plus.
- * @type {string}
- * @private
- */
- this.invisiblePlus_ = cvox.SemanticUtil.numberToUnicode(0x2064);
- this.additions.push(this.invisiblePlus_);
- /**
- * @type {Array<string>}
- */
- this.multiplications =
- [
- '†', '‡', '∐', '∗', '∘', '∙', '≀', '⊚', '⊛', '⊠', '⊡', '⋅', '⋆', '⋇',
- '⋉', '⋊', '⋋', '⋌', '○'
- ];
- /**
- * Invisible operator for multiplication.
- * @type {string}
- * @private
- */
- this.invisibleTimes_ = cvox.SemanticUtil.numberToUnicode(0x2062);
- this.multiplications.push(this.invisibleTimes_);
- /**
- * @type {Array<string>}
- */
- this.subtractions =
- [
- '-', '⁒', '⁻', '₋', '−', '∖', '∸', '≂', '⊖', '⊟', '➖', '⨩', '⨪',
- '⨫', '⨬', '⨺', '⩁', '⩬', '﹣', '-', '‐', '‑'
- ];
- /**
- * @type {Array<string>}
- */
- this.divisions =
- [
- '/', '÷', '⁄', '∕', '⊘', '⟌', '⦼', '⨸'
- ];
- /**
- * Invisible operator for function application.
- * @type {string}
- * @private
- */
- this.functionApplication_ = cvox.SemanticUtil.numberToUnicode(0x2061);
-
- //Relation symbols
- /**
- * @type {Array<string>}
- */
- this.equalities =
- [
- '=', '~', '⁼', '₌', '∼', '∽', '≃', '≅', '≈', '≊', '≋', '≌', '≍',
- '≎', '≑', '≒', '≓', '≔', '≕', '≖', '≗', '≘', '≙', '≚', '≛', '≜',
- '≝', '≞', '≟', '≡', '≣', '⧤', '⩦', '⩮', '⩯', '⩰', '⩱', '⩲', '⩳',
- '⩴', '⩵', '⩶', '⩷', '⩸', '⋕', '⩭', '⩪', '⩫', '⩬', '﹦', '='
- ];
- /**
- * @type {Array<string>}
- */
- this.inequalities =
- [
- '<', '>', '≁', '≂', '≄', '≆', '≇', '≉', '≏', '≐', '≠', '≢', '≤',
- '≥', '≦', '≧', '≨', '≩', '≪', '≫', '≬', '≭', '≮', '≯', '≰', '≱',
- '≲', '≳', '≴', '≵', '≶', '≷', '≸', '≹', '≺', '≻', '≼', '≽', '≾',
- '≿', '⊀', '⊁', '⋖', '⋗', '⋘', '⋙', '⋚', '⋛', '⋜', '⋝', '⋞', '⋟',
- '⋠', '⋡', '⋢', '⋣', '⋤', '⋥', '⋦', '⋧', '⋨', '⋩', '⩹', '⩺', '⩻',
- '⩼', '⩽', '⩾', '⩿', '⪀', '⪁', '⪂', '⪃', '⪄', '⪅', '⪆', '⪇', '⪈',
- '⪉', '⪊', '⪋', '⪌', '⪍', '⪎', '⪏', '⪐', '⪑', '⪒', '⪓', '⪔', '⪕',
- '⪖', '⪗', '⪘', '⪙', '⪚', '⪛', '⪜', '⪝', '⪞', '⪟', '⪠', '⪡', '⪢',
- '⪣', '⪤', '⪥', '⪦', '⪧', '⪨', '⪩', '⪪', '⪫', '⪬', '⪭', '⪮', '⪯',
- '⪰', '⪱', '⪲', '⪳', '⪴', '⪵', '⪶', '⪷', '⪸', '⪹', '⪺', '⪻', '⪼',
- '⫷', '⫸', '⫹', '⫺', '⧀', '⧁', '﹤', '﹥', '<', '>'
- ];
- /**
- * @type {Array<string>}
- */
- this.relations =
- [
- // TODO (sorge): Add all the other relations.
- ];
- /**
- * @type {Array<string>}
- */
- this.arrows =
- [
- '←', '↑', '→', '↓', '↔', '↕', '↖', '↗', '↘', '↙', '↚', '↛', '↜',
- '↝', '↞', '↟', '↠', '↡', '↢', '↣', '↤', '↥', '↦', '↧', '↨', '↩',
- '↪', '↫', '↬', '↭', '↮', '↯', '↰', '↱', '↲', '↳', '↴', '↵', '↶',
- '↷', '↸', '↹', '↺', '↻', '⇄', '⇅', '⇆', '⇇', '⇈', '⇉', '⇊', '⇍',
- '⇎', '⇏', '⇐', '⇑', '⇒', '⇓', '⇔', '⇕', '⇖', '⇗', '⇘', '⇙', '⇚',
- '⇛', '⇜', '⇝', '⇞', '⇟', '⇠', '⇡', '⇢', '⇣', '⇤', '⇥', '⇦', '⇧',
- '⇨', '⇩', '⇪', '⇫', '⇬', '⇭', '⇮', '⇯', '⇰', '⇱', '⇲', '⇳', '⇴',
- '⇵', '⇶', '⇷', '⇸', '⇹', '⇺', '⇻', '⇼', '⇽', '⇾', '⇿', '⌁', '⌃',
- '⌄', '⌤', '⎋', '➔', '➘', '➙', '➚', '➛', '➜', '➝', '➞', '➟', '➠',
- '➡', '➢', '➣', '➤', '➥', '➦', '➧', '➨', '➩', '➪', '➫', '➬', '➭',
- '➮', '➯', '➱', '➲', '➳', '➴', '➵', '➶', '➷', '➸', '➹', '➺', '➻',
- '➼', '➽', '➾', '⟰', '⟱', '⟲', '⟳', '⟴', '⟵', '⟶', '⟷', '⟸', '⟹',
- '⟺', '⟻', '⟼', '⟽', '⟾', '⟿', '⤀', '⤁', '⤂', '⤃', '⤄', '⤅', '⤆',
- '⤇', '⤈', '⤉', '⤊', '⤋', '⤌', '⤍', '⤎', '⤏', '⤐', '⤑', '⤒', '⤓',
- '⤔', '⤕', '⤖', '⤗', '⤘', '⤙', '⤚', '⤛', '⤜', '⤝', '⤞', '⤟', '⤠',
- '⤡', '⤢', '⤣', '⤤', '⤥', '⤦', '⤧', '⤨', '⤩', '⤪', '⤭', '⤮', '⤯',
- '⤰', '⤱', '⤲', '⤳', '⤴', '⤵', '⤶', '⤷', '⤸', '⤹', '⤺', '⤻', '⤼',
- '⤽', '⤾', '⤿', '⥀', '⥁', '⥂', '⥃', '⥄', '⥅', '⥆', '⥇', '⥈', '⥉',
- '⥰', '⥱', '⥲', '⥳', '⥴', '⥵', '⥶', '⥷', '⥸', '⥹', '⥺', '⥻', '⦳',
- '⦴', '⦽', '⧪', '⧬', '⧭', '⨗', '⬀', '⬁', '⬂', '⬃', '⬄', '⬅', '⬆',
- '⬇', '⬈', '⬉', '⬊', '⬋', '⬌', '⬍', '⬎', '⬏', '⬐', '⬑', '⬰', '⬱',
- '⬲', '⬳', '⬴', '⬵', '⬶', '⬷', '⬸', '⬹', '⬺', '⬻', '⬼', '⬽', '⬾',
- '⬿', '⭀', '⭁', '⭂', '⭃', '⭄', '⭅', '⭆', '⭇', '⭈', '⭉', '⭊', '⭋',
- '⭌', '←', '↑', '→', '↓',
- // Harpoons
- '↼', '↽', '↾', '↿', '⇀', '⇁', '⇂', '⇃', '⇋', '⇌', '⥊', '⥋', '⥌',
- '⥍', '⥎', '⥏', '⥐', '⥑', '⥒', '⥓', '⥔', '⥕', '⥖', '⥗', '⥘', '⥙',
- '⥚', '⥛', '⥜', '⥝', '⥞', '⥟', '⥠', '⥡', '⥢', '⥣', '⥤', '⥥', '⥦',
- '⥧', '⥨', '⥩', '⥪', '⥫', '⥬', '⥭', '⥮', '⥯', '⥼', '⥽', '⥾', '⥿'
- ];
-
- //Big operation symbols
- /**
- * @type {Array<string>}
- */
- this.sumOps =
- [
- '⅀', // double struck
- '∏', '∐', '∑', '⋀', '⋁', '⋂', '⋃', '⨀', '⨁', '⨂', '⨃', '⨄', '⨅',
- '⨆', '⨇', '⨈', '⨉', '⨊', '⨋', '⫼', '⫿'
- ];
- /**
- * @type {Array<string>}
- */
- this.intOps =
- [
- '∫', '∬', '∭', '∮', '∯', '∰', '∱', '∲', '∳', '⨌', '⨍', '⨎', '⨏',
- '⨐', '⨑', '⨒', '⨓', '⨔', '⨕', '⨖', '⨗', '⨘', '⨙', '⨚', '⨛', '⨜'
- ];
- /**
- * @type {Array<string>}
- */
- this.prefixOps =
- // TODO (sorge) Insert nabla, differential operators etc.
- [
- '∀', '∃'
- ];
- /**
- * @type {Array<string>}
- */
- this.operatorBits =
- // TODO (sorge) What to do if single glyphs of big ops occur on their own.
- [
- '⌠', '⌡', '⎶', '⎪', '⎮', '⎯', '⎲', '⎳', '⎷'
- ];
-
- // Accents.
- // TODO (sorge) Add accented characters.
-
- // Numbers.
- // Digits.
- /**
- * @type {Array<string>}
- */
- this.digitsNormal =
- [
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
- ];
- /**
- * @type {Array<string>}
- */
- this.digitsFullWidth =
- [
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
- ];
- /**
- * @type {Array<string>}
- */
- this.digitsBold =
- [
- '𝟎', '𝟏', '𝟐', '𝟑', '𝟒', '𝟓', '𝟔', '𝟕', '𝟖', '𝟗'
- ];
- /**
- * @type {Array<string>}
- */
- this.digitsDoubleStruck =
- [
- '𝟘', '𝟙', '𝟚', '𝟛', '𝟜', '𝟝', '𝟞', '𝟟', '𝟠', '𝟡'
- ];
- /**
- * @type {Array<string>}
- */
- this.digitsSansSerif =
- [
- '𝟢', '𝟣', '𝟤', '𝟥', '𝟦', '𝟧', '𝟨', '𝟩', '𝟪', '𝟫'
- ];
- /**
- * @type {Array<string>}
- */
- this.digitsSansSerifBold =
- [
- '𝟬', '𝟭', '𝟮', '𝟯', '𝟰', '𝟱', '𝟲', '𝟳', '𝟴', '𝟵'
- ];
- /**
- * @type {Array<string>}
- */
- this.digitsMonospace =
- [
- '𝟶', '𝟷', '𝟸', '𝟹', '𝟺', '𝟻', '𝟼', '𝟽', '𝟾', '𝟿'
- ];
- /**
- * @type {Array<string>}
- */
- this.digitsSuperscript =
- [
- '²', '³', '¹', '⁰', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹'
- ];
- /**
- * @type {Array<string>}
- */
- this.digitsSubscript =
- [
- '₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉'
- ];
- /**
- * @type {Array<string>}
- */
- this.fractions =
- [
- '¼', '½', '¾', '⅐', '⅑', '⅒', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙',
- '⅚', '⅛', '⅜', '⅝', '⅞', '⅟', '↉'
- ];
- /**
- * @type {Array<string>}
- */
- this.enclosedNumbers =
- // Encircled numbers.
- [
- '①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬',
- '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳', '⓪', '⓫', '⓬', '⓭', '⓮', '⓯',
- '⓰', '⓱', '⓲', '⓳', '⓴', '⓵', '⓶', '⓷', '⓸', '⓹', '⓺', '⓻', '⓼',
- '⓽', '⓾', '⓿', '❶', '❷', '❸', '❹', '❺', '❻', '❼', '❽', '❾', '❿',
- '➀', '➁', '➂', '➃', '➄', '➅', '➆', '➇', '➈', '➉', '➊', '➋', '➌',
- '➍', '➎', '➏', '➐', '➑', '➒', '➓', '㉈', '㉉', '㉊', '㉋', '㉌',
- '㉍', '㉎', '㉏', '㉑', '㉒', '㉓', '㉔', '㉕', '㉖', '㉗', '㉘',
- '㉙', '㉚', '㉛', '㉜', '㉝', '㉞', '㉟', '㊱', '㊲', '㊳', '㊴',
- '㊵', '㊶', '㊷', '㊸', '㊹', '㊺', '㊻', '㊼', '㊽', '㊾', '㊿'];
- /**
- * @type {Array<string>}
- */
- this.fencedNumbers =
- // Numbers in Parenthesis.
- [
- '⑴', '⑵', '⑶', '⑷', '⑸', '⑹', '⑺', '⑻', '⑼', '⑽', '⑾', '⑿', '⒀',
- '⒁', '⒂', '⒃', '⒄', '⒅', '⒆', '⒇'
- ];
- /**
- * @type {Array<string>}
- */
- this.punctuatedNumbers =
- // Numbers with other punctuation.
- ['⒈', '⒉', '⒊', '⒋', '⒌', '⒍', '⒎', '⒏', '⒐', '⒑', '⒒', '⒓', '⒔',
- '⒕', '⒖', '⒗', '⒘', '⒙', '⒚', '⒛', // full stop.
- '🄀', '🄁', '🄂', '🄃', '🄄', '🄅', '🄆', '🄇', '🄈', '🄉', '🄊' // comma.
- ];
- /** Array of all single digits.
- * @type {Array<string>}
- */
- this.digits = this.digitsNormal.concat(
- this.digitsFullWidth, this.digitsBold, this.digitsDoubleStruck,
- this.digitsSansSerif, this.digitsSansSerifBold, this.digitsMonospace);
- /** Array of all non-digit number symbols.
- * @type {Array<string>}
- */
- this.numbers = this.fractions.concat(
- this.digitsSuperscript, this.digitsSubscript,
- this.enclosedNumbers, this.fencedNumbers, this.punctuatedNumbers);
- /** Array of all number symbols.
- * @type {Array<string>}
- */
- this.allNumbers = this.digits.concat(this.numbers);
-
- // Functions.
- /**
- * @type {Array<string>}
- */
- this.trigonometricFunctions =
- [
- 'cos', 'cot', 'csc', 'sec', 'sin', 'tan', 'arccos', 'arccot',
- 'arccsc', 'arcsec', 'arcsin', 'arctan'
- ];
- /**
- * @type {Array<string>}
- */
- this.hyperbolicFunctions =
- [
- 'cosh', 'coth', 'csch', 'sech', 'sinh', 'tanh',
- 'arcosh', 'arcoth', 'arcsch', 'arsech', 'arsinh', 'artanh',
- 'arccosh', 'arccoth', 'arccsch', 'arcsech', 'arcsinh', 'arctanh'
- ];
- /**
- * @type {Array<string>}
- */
- this.algebraicFunctions =
- [
- 'deg', 'det', 'dim', 'hom', 'ker', 'Tr', 'tr'
- ];
- /**
- * @type {Array<string>}
- */
- this.elementaryFunctions =
- [
- 'log', 'ln', 'lg', 'exp', 'expt', 'gcd', 'gcd', 'arg', 'im', 're', 'Pr'
- ];
- /** All predefined prefix functions.
- * @type {Array<string>}
- */
- this.prefixFunctions = this.trigonometricFunctions.concat(
- this.hyperbolicFunctions,
- this.algebraicFunctions,
- this.elementaryFunctions
- );
- /** Limit functions are handled separately as they can have lower (and upper)
- * limiting expressions.
- * @type {Array<string>}
- */
- this.limitFunctions =
- [
- 'inf', 'lim', 'liminf', 'limsup', 'max', 'min', 'sup', 'injlim',
- 'projlim'
- ];
- /**
- * @type {Array<string>}
- */
- this.infixFunctions =
- [
- 'mod', 'rem'
- ];
- /**
- * Default assignments of semantic attributes.
- * @type {Array<{set: Array<string>,
- * role: cvox.SemanticAttr.Role,
- * type: cvox.SemanticAttr.Type,
- * font: cvox.SemanticAttr.Font}>} The semantic meaning of the symbol.
- * @private
- */
- this.symbolSetToSemantic_ = [
- // Punctuation
- {set: this.generalPunctuations,
- type: cvox.SemanticAttr.Type.PUNCTUATION,
- role: cvox.SemanticAttr.Role.UNKNOWN
- },
- {set: this.ellipses,
- type: cvox.SemanticAttr.Type.PUNCTUATION,
- role: cvox.SemanticAttr.Role.ELLIPSIS
- },
- {set: this.fullStops,
- type: cvox.SemanticAttr.Type.PUNCTUATION,
- role: cvox.SemanticAttr.Role.FULLSTOP
- },
- {set: this.dashes,
- type: cvox.SemanticAttr.Type.PUNCTUATION,
- role: cvox.SemanticAttr.Role.DASH
- },
- {set: this.primes,
- type: cvox.SemanticAttr.Type.PUNCTUATION,
- role: cvox.SemanticAttr.Role.PRIME
- },
- // Fences
- {set: this.leftFences,
- type: cvox.SemanticAttr.Type.FENCE,
- role: cvox.SemanticAttr.Role.OPEN
- },
- {set: this.rightFences,
- type: cvox.SemanticAttr.Type.FENCE,
- role: cvox.SemanticAttr.Role.CLOSE
- },
- {set: this.topFences,
- type: cvox.SemanticAttr.Type.FENCE,
- role: cvox.SemanticAttr.Role.TOP
- },
- {set: this.bottomFences,
- type: cvox.SemanticAttr.Type.FENCE,
- role: cvox.SemanticAttr.Role.BOTTOM
- },
- {set: this.neutralFences,
- type: cvox.SemanticAttr.Type.FENCE,
- role: cvox.SemanticAttr.Role.NEUTRAL
- },
- // Single characters.
- // Latin alphabets.
- {set: this.smallLatin,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- {set: this.capitalLatin,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- {set: this.smallLatinFullWidth,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- {set: this.capitalLatinFullWidth,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- {set: this.smallLatinBold,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.BOLD
- },
- {set: this.capitalLatinBold,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.BOLD
- },
- {set: this.smallLatinItalic,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.ITALIC
- },
- {set: this.capitalLatinItalic,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.ITALIC
- },
- {set: this.smallLatinScript,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.SCRIPT
- },
- {set: this.capitalLatinScript,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.SCRIPT
- },
- {set: this.smallLatinBoldScript,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.BOLDSCRIPT
- },
- {set: this.capitalLatinBoldScript,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.BOLDSCRIPT
- },
- {set: this.smallLatinFraktur,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.FRAKTUR
- },
- {set: this.capitalLatinFraktur,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.FRAKTUR
- },
- {set: this.smallLatinDoubleStruck,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.DOUBLESTRUCK
- },
- {set: this.capitalLatinDoubleStruck,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.DOUBLESTRUCK
- },
- {set: this.smallLatinBoldFraktur,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.BOLDFRAKTUR
- },
- {set: this.capitalLatinBoldFraktur,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.BOLDFRAKTUR
- },
- {set: this.smallLatinSansSerif,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.SANSSERIF
- },
- {set: this.capitalLatinSansSerif,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.SANSSERIF
- },
- {set: this.smallLatinSansSerifBold,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.SANSSERIFBOLD
- },
- {set: this.capitalLatinSansSerifBold,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.SANSSERIFBOLD
- },
- {set: this.smallLatinSansSerifItalic,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.SANSSERIFITALIC
- },
- {set: this.capitalLatinSansSerifItalic,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.SANSSERIFITALIC
- },
- {set: this.smallLatinMonospace,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.MONOSPACE
- },
- {set: this.capitalLatinMonospace,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.MONOSPACE
- },
- {set: this.latinDoubleStruckItalic,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.LATINLETTER,
- font: cvox.SemanticAttr.Font.DOUBLESTRUCKITALIC
- },
- // Greek alphabets.
- {set: this.smallGreek,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- {set: this.capitalGreek,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- {set: this.smallGreekBold,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.BOLD
- },
- {set: this.capitalGreekBold,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.BOLD
- },
- {set: this.smallGreekItalic,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.ITALIC
- },
- {set: this.capitalGreekItalic,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.ITALIC
- },
- {set: this.smallGreekSansSerifBold,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.SANSSERIFBOLD
- },
- {set: this.capitalGreekSansSerifBold,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.SANSSERIFBOLD
- },
- {set: this.greekDoubleStruck,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.GREEKLETTER,
- font: cvox.SemanticAttr.Font.DOUBLESTRUCK
- },
- // Other alphabets.
- {set: this.hebrewLetters,
- type: cvox.SemanticAttr.Type.IDENTIFIER,
- role: cvox.SemanticAttr.Role.OTHERLETTER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- // Numbers.
- {set: this.digitsNormal,
- type: cvox.SemanticAttr.Type.NUMBER,
- role: cvox.SemanticAttr.Role.INTEGER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- {set: this.digitsFullWidth,
- type: cvox.SemanticAttr.Type.NUMBER,
- role: cvox.SemanticAttr.Role.INTEGER,
- font: cvox.SemanticAttr.Font.NORMAL
- },
- {set: this.digitsBold,
- type: cvox.SemanticAttr.Type.NUMBER,
- role: cvox.SemanticAttr.Role.INTEGER,
- font: cvox.SemanticAttr.Font.BOLD
- },
- {set: this.digitsDoubleStruck,
- type: cvox.SemanticAttr.Type.NUMBER,
- role: cvox.SemanticAttr.Role.INTEGER,
- font: cvox.SemanticAttr.Font.DOUBLESTRUCK
- },
- {set: this.digitsSansSerif,
- type: cvox.SemanticAttr.Type.NUMBER,
- role: cvox.SemanticAttr.Role.INTEGER,
- font: cvox.SemanticAttr.Font.SANSSERIF
- },
- {set: this.digitsSansSerifBold,
- type: cvox.SemanticAttr.Type.NUMBER,
- role: cvox.SemanticAttr.Role.INTEGER,
- font: cvox.SemanticAttr.Font.SANSSERIFBOLD
- },
- {set: this.digitsMonospace,
- type: cvox.SemanticAttr.Type.NUMBER,
- role: cvox.SemanticAttr.Role.INTEGER,
- font: cvox.SemanticAttr.Font.MONOSPACE
- },
- {set: this.numbers,
- type: cvox.SemanticAttr.Type.NUMBER,
- role: cvox.SemanticAttr.Role.INTEGER
- },
- // Operators.
- {set: this.additions,
- type: cvox.SemanticAttr.Type.OPERATOR,
- role: cvox.SemanticAttr.Role.ADDITION
- },
- {set: this.multiplications,
- type: cvox.SemanticAttr.Type.OPERATOR,
- role: cvox.SemanticAttr.Role.MULTIPLICATION
- },
- {set: this.subtractions,
- type: cvox.SemanticAttr.Type.OPERATOR,
- role: cvox.SemanticAttr.Role.SUBTRACTION
- },
- {set: this.divisions,
- type: cvox.SemanticAttr.Type.OPERATOR,
- role: cvox.SemanticAttr.Role.DIVISION
- },
- {set: this.prefixOps,
- type: cvox.SemanticAttr.Type.PREFIXOP,
- role: cvox.SemanticAttr.Role.PREFIXFUNC
- },
- // Relations
- {set: this.equalities,
- type: cvox.SemanticAttr.Type.RELATION,
- role: cvox.SemanticAttr.Role.EQUALITY
- },
- {set: this.inequalities,
- type: cvox.SemanticAttr.Type.RELATION,
- role: cvox.SemanticAttr.Role.INEQUALITY
- },
- {set: this.relations,
- type: cvox.SemanticAttr.Type.RELATION,
- role: cvox.SemanticAttr.Role.UNKNOWN
- },
- {set: this.arrows,
- type: cvox.SemanticAttr.Type.RELATION,
- role: cvox.SemanticAttr.Role.ARROW
- },
- // Large operators
- {set: this.sumOps,
- type: cvox.SemanticAttr.Type.LARGEOP,
- role: cvox.SemanticAttr.Role.SUM},
- {set: this.intOps,
- type: cvox.SemanticAttr.Type.LARGEOP,
- role: cvox.SemanticAttr.Role.INTEGRAL},
- // Functions
- {set: this.limitFunctions,
- type: cvox.SemanticAttr.Type.FUNCTION,
- role: cvox.SemanticAttr.Role.LIMFUNC},
- {set: this.prefixFunctions,
- type: cvox.SemanticAttr.Type.FUNCTION,
- role: cvox.SemanticAttr.Role.PREFIXFUNC},
- {set: this.infixFunctions,
- type: cvox.SemanticAttr.Type.OPERATOR,
- role: cvox.SemanticAttr.Role.MULTIPLICATION
- }
- // TODO (sorge) Add some of the remaining elements.
- ];
-};
-goog.addSingletonGetter(cvox.SemanticAttr);
-
-
-/**
- * Union type of semantic attributes.
- * @typedef {cvox.SemanticAttr.Type|cvox.SemanticAttr.Role}
- */
-cvox.SemanticAttr.Attr;
-
-
-/**
- * Mapping for types of elements.
- * @enum {string}
- */
-cvox.SemanticAttr.Type = {
- // Leafs.
- // Punctuation like comma, dot, ellipses.
- PUNCTUATION: 'punctuation',
- // Fence symbol.
- FENCE: 'fence',
- // One or several digits, plus some punctuation.
- NUMBER: 'number',
- // Single or multiple letters.
- IDENTIFIER: 'identifier',
- // Regular text in a math expression.
- TEXT: 'text',
- // e.g. +, *.
- OPERATOR: 'operator',
- // Relation symbol, e.g. equals.
- RELATION: 'relation',
- // e.g. Sum, product, integral.
- LARGEOP: 'largeop',
- // Some named function.
- FUNCTION: 'function',
-
- // Branches.
- // Compound Symbols.
- ACCENT: 'accent',
- FENCED: 'fenced',
- FRACTION: 'fraction',
- PUNCTUATED: 'punctuated',
-
- // Relations.
- // Relation sequence of a single relation.
- RELSEQ: 'relseq',
- // Relation sequence containing at least two different relations.
- MULTIREL: 'multirel',
- // Operations.
- INFIXOP: 'infixop',
- PREFIXOP: 'prefixop',
- POSTFIXOP: 'postfixop',
-
- // Function and Bigop Application.
- APPL: 'appl',
- INTEGRAL: 'integral',
- BIGOP: 'bigop',
-
- SQRT: 'sqrt',
- ROOT: 'root',
- // These are bigops or functions with limits.
- LIMUPPER: 'limupper',
- LIMLOWER: 'limlower',
- LIMBOTH: 'limboth',
- SUBSCRIPT: 'subscript',
- SUPERSCRIPT: 'superscript',
- UNDERSCORE: 'underscore',
- OVERSCORE: 'overscore',
-
- // Tables and their elements.
- TABLE: 'table',
- MULTILINE: 'multiline',
- MATRIX: 'matrix',
- VECTOR: 'vector',
- CASES: 'cases',
- ROW: 'row',
- // Lines are effectively single cell rows.
- LINE: 'line',
- CELL: 'cell',
-
- // General.
- UNKNOWN: 'unknown',
- EMPTY: 'empty'
-};
-
-
-/**
- * Mapping for roles of nodes.
- * Roles are more specific than types.
- * @enum {string}
- */
-cvox.SemanticAttr.Role = {
- // Punctuation.
- ELLIPSIS: 'ellipsis',
- FULLSTOP: 'fullstop',
- DASH: 'dash',
- PRIME: 'prime', // Superscript.
- VBAR: 'vbar', // A vertical bar.
- OPENFENCE: 'openfence',
- CLOSEFENCE: 'closefence',
- APPLICATION: 'application', // Function Application.
-
- // Fences.
- OPEN: 'open',
- CLOSE: 'close',
- TOP: 'top',
- BOTTOM: 'bottom',
- NEUTRAL: 'neutral',
-
- // Letters.
- LATINLETTER: 'latinletter',
- GREEKLETTER: 'greekletter',
- OTHERLETTER: 'otherletter',
-
- // Numbers.
- INTEGER: 'integer',
- FLOAT: 'float',
- OTHERNUMBER: 'othernumber',
-
- // Accents.
- MULTIACCENT: 'multiaccent',
- OVERACCENT: 'overaccent',
- UNDERACCENT: 'underaccent',
-
- // Fenced.
- LEFTRIGHT: 'leftright',
- ABOVEBELOW: 'abovebelow',
-
- // Punctuated elements.
- SEQUENCE: 'sequence',
- ENDPUNCT: 'endpunct',
- STARTPUNCT: 'startpunct',
-
- // Operators.
- NEGATIVE: 'negative',
- NEGATION: 'negation',
- MULTIOP: 'multiop',
-
- // Functions.
- LIMFUNC: 'limit function',
- INFIXFUNC: 'infix function',
- PREFIXFUNC: 'prefix function',
- POSTFIXFUNC: 'postfix function',
-
- // Large operators.
- SUM: 'sum',
- INTEGRAL: 'integral',
-
- // Binary operations.
- ADDITION: 'addition',
- MULTIPLICATION: 'multiplication',
- DIVISION: 'division',
- SUBTRACTION: 'subtraction',
- IMPLICIT: 'implicit',
-
- // Relations.
- EQUALITY: 'equality',
- INEQUALITY: 'inequality',
- ELEMENT: 'element',
- BINREL: 'binrel',
- ARROW: 'arrow',
-
- // Roles of rows, lines, cells.
- // They mirror the different types for tables.
- MULTILINE: 'multiline',
- MATRIX: 'matrix',
- VECTOR: 'vector',
- CASES: 'cases',
- TABLE: 'table',
-
- // General
- UNKNOWN: 'unknown'
-};
-
-
-/**
- * Mapping for font annotations. (Taken from MathML2 section 3.2.2, with the
- * exception of double-struck-italic.)
- * @enum {string}
- */
-cvox.SemanticAttr.Font = {
- BOLD: 'bold',
- BOLDFRAKTUR: 'bold-fraktur',
- BOLDITALIC: 'bold-italic',
- BOLDSCRIPT: 'bold-script',
- DOUBLESTRUCK: 'double-struck',
- DOUBLESTRUCKITALIC: 'double-struck-italic',
- FRAKTUR: 'fraktur',
- ITALIC: 'italic',
- MONOSPACE: 'monospace',
- NORMAL: 'normal',
- SCRIPT: 'script',
- SANSSERIF: 'sans-serif',
- SANSSERIFITALIC: 'sans-serif-italic',
- SANSSERIFBOLD: 'sans-serif-bold',
- SANSSERIFBOLDITALIC: 'sans-serif-bold-italic',
- UNKNOWN: 'unknown'
-};
-
-
-/**
- * Lookup the semantic type of a symbol.
- * @param {string} symbol The symbol to which we want to determine the type.
- * @return {cvox.SemanticAttr.Type} The semantic type of the symbol.
- */
-cvox.SemanticAttr.prototype.lookupType = function(symbol) {
- return cvox.SemanticAttr.Type.UNKNOWN;
-};
-
-
-/**
- * Lookup the semantic role of a symbol.
- * @param {string} symbol The symbol to which we want to determine the role.
- * @return {cvox.SemanticAttr.Role} The semantic role of the symbol.
- */
-cvox.SemanticAttr.prototype.lookupRole = function(symbol) {
- return cvox.SemanticAttr.Role.UNKNOWN;
-};
-
-
-/**
- * Lookup the semantic meaning of a symbol in terms of type and role.
- * @param {string} symbol The symbol to which we want to determine the meaning.
- * @return {{role: cvox.SemanticAttr.Role,
- * type: cvox.SemanticAttr.Type}} The semantic meaning of the symbol.
- */
-cvox.SemanticAttr.lookupMeaning = function(symbol) {
- return cvox.SemanticAttr.getInstance().lookupMeaning_(symbol);
-};
-
-
-/**
- * String representation of the invisible times unicode character.
- * @return {string} The invisible times character.
- */
-cvox.SemanticAttr.invisibleTimes = function() {
- return cvox.SemanticAttr.getInstance().invisibleTimes_;
-};
-
-
-/**
- * String representation of the invisible comma unicode character.
- * @return {string} The invisible comma character.
- */
-cvox.SemanticAttr.invisibleComma = function() {
- return cvox.SemanticAttr.getInstance().invisibleComma_;
-};
-
-
-/**
- * String representation of the function application character.
- * @return {string} The invisible function application character.
- */
-cvox.SemanticAttr.functionApplication = function() {
- return cvox.SemanticAttr.getInstance().functionApplication_;
-};
-
-
-/**
- * Decide when two fences match. Currently we match any right to left
- * or bottom to top fence and neutral to neutral.
- * @param {cvox.SemanticAttr.Role} open Opening fence.
- * @param {cvox.SemanticAttr.Role} close Closing fence.
- * @return {boolean} True if the fences are matching.
- */
-cvox.SemanticAttr.isMatchingFenceRole = function(open, close) {
- return (open == cvox.SemanticAttr.Role.OPEN &&
- close == cvox.SemanticAttr.Role.CLOSE) ||
- (open == cvox.SemanticAttr.Role.NEUTRAL &&
- close == cvox.SemanticAttr.Role.NEUTRAL) ||
- (open == cvox.SemanticAttr.Role.TOP &&
- close == cvox.SemanticAttr.Role.BOTTOM);
-};
-
-
-/**
- * Decide when opening and closing fences match. For neutral fences they have to
- * be the same.
- * @param {string} open Opening fence.
- * @param {string} close Closing fence.
- * @return {boolean} True if the fences are matching.
- */
-cvox.SemanticAttr.isMatchingFence = function(open, close) {
- return cvox.SemanticAttr.getInstance().isMatchingFence_(open, close);
-};
-
-
-/**
- * Determines if a fence is an opening fence.
- * @param {cvox.SemanticAttr.Role} fence Opening fence.
- * @return {boolean} True if the fence is open or neutral.
- */
-cvox.SemanticAttr.isOpeningFence = function(fence) {
- return (fence == cvox.SemanticAttr.Role.OPEN ||
- fence == cvox.SemanticAttr.Role.NEUTRAL);
-};
-
-
-/**
- * Determines if a fence is a closing fence.
- * @param {cvox.SemanticAttr.Role} fence Closing fence.
- * @return {boolean} True if the fence is close or neutral.
- */
-cvox.SemanticAttr.isClosingFence = function(fence) {
- return (fence == cvox.SemanticAttr.Role.CLOSE ||
- fence == cvox.SemanticAttr.Role.NEUTRAL);
-};
-
-
-// TODO (sorge) Make this depended on position in the alphabets.
-/**
- * Check if a character is a small 'd' in some font.
- * @param {!string} chr The character string.
- * @return {boolean} True if the character is indeed a single small d.
- */
-cvox.SemanticAttr.isCharacterD = function(chr) {
- var Ds = ['d', 'ⅆ', 'd', '𝐝', '𝑑', '𝒹', '𝓭', '𝔡',
- '𝕕', '𝖉', '𝖽', '𝗱', '𝘥', '𝚍'];
- return Ds.indexOf(chr) != -1;
-};
-
-
-/**
- * Decide when opening and closing fences match. For neutral fences they have to
- * be the same.
- * @param {!string} open Opening fence.
- * @param {!string} close Closing fence.
- * @return {boolean} True if the fences are matching.
- * @private
- */
-cvox.SemanticAttr.prototype.isMatchingFence_ = function(open, close) {
- if (this.neutralFences.indexOf(open) != -1) {
- return open == close;
- }
- return this.openClosePairs[open] == close ||
- this.topBottomPairs[open] == close;
-};
-
-
-/**
- * Lookup the semantic meaning of a symbol in terms of type and role.
- * @param {!string} symbol The symbol to which we want to determine the meaning.
- * @return {{role: cvox.SemanticAttr.Role,
- * type: cvox.SemanticAttr.Type,
- * font: cvox.SemanticAttr.Font}} The semantic meaning of the symbol.
- * @private
- */
-cvox.SemanticAttr.prototype.lookupMeaning_ = function(symbol) {
- for (var i = 0, set; set = this.symbolSetToSemantic_[i]; i++) {
- if (set.set.indexOf(symbol) != -1) {
- return {role: set.role || cvox.SemanticAttr.Role.UNKNOWN,
- type: set.type || cvox.SemanticAttr.Type.UNKNOWN,
- font: set.font || cvox.SemanticAttr.Font.UNKNOWN
- };
- }
- }
- return {role: cvox.SemanticAttr.Role.UNKNOWN,
- type: cvox.SemanticAttr.Type.UNKNOWN,
- font: cvox.SemanticAttr.Font.UNKNOWN
- };
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_tree.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_tree.js
deleted file mode 100644
index 991ae3244ca..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_tree.js
+++ /dev/null
@@ -1,1939 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A semantic tree for MathML expressions.
- *
- * This file contains functionality to compute a semantic interpretation from a
- * given MathML expression. This is a very heuristic approach that assumes a
- * fairly simple default semantic which is suitable for K-12 and simple UG
- * mathematics.
- *
- */
-
-goog.provide('cvox.SemanticTree');
-goog.provide('cvox.SemanticTree.Node');
-
-goog.require('cvox.DomUtil');
-goog.require('cvox.SemanticAttr');
-goog.require('cvox.SemanticUtil');
-
-
-/**
- * Create an initial semantic tree.
- * @param {!Element} mml The original MathML node.
- * @constructor
- */
-cvox.SemanticTree = function(mml) {
- /** ID counter.
- * @type {number}
- * @private
- */
- this.idCounter_ = 0;
-
- /** Original MathML tree.
- * @type {Node}
- */
- this.mathml = mml;
-
- /** @type {cvox.SemanticTree.Node} */
- this.root = this.parseMathml_(mml);
-};
-
-
-/**
- * @param {number} id Node id.
- * @constructor
- */
-cvox.SemanticTree.Node = function(id) {
- /** @type {number} */
- this.id = id;
-
- /** @type {Array<Element>} */
- this.mathml = [];
-
- /** @type {cvox.SemanticTree.Node} */
- this.parent = null;
-
- /** @type {cvox.SemanticAttr.Type} */
- this.type = cvox.SemanticAttr.Type.UNKNOWN;
-
- /** @type {cvox.SemanticAttr.Role} */
- this.role = cvox.SemanticAttr.Role.UNKNOWN;
-
- /** @type {cvox.SemanticAttr.Font} */
- this.font = cvox.SemanticAttr.Font.UNKNOWN;
-
- /** @type {!Array<cvox.SemanticTree.Node>} */
- this.childNodes = [];
-
- /** @type {string} */
- this.textContent = '';
-
- /** Branch nodes can store additional nodes that can be useful.
- * E.g. a node of type FENCED can have the opening and closing fences here.
- * @type {!Array<cvox.SemanticTree.Node>}
- */
- this.contentNodes = [];
-};
-
-
-/**
- * Retrieve all subnodes (including the node itself) that satisfy a given
- * predicate.
- * @param {function(cvox.SemanticTree.Node): boolean} pred The predicate.
- * @return {!Array<cvox.SemanticTree.Node>} The nodes in the tree for which the
- * predicate holds.
- */
-cvox.SemanticTree.Node.prototype.querySelectorAll = function(pred) {
- var result = [];
- for (var i = 0, child; child = this.childNodes[i]; i++) {
- result = result.concat(child.querySelectorAll(pred));
- }
- if (pred(this)) {
- result.unshift(this);
- }
- return result;
-};
-
-
- /**
- * Returns an XML representation of the tree.
- * @param {boolean=} brief If set attributes are omitted.
- * @return {Node} The XML representation of the tree.
- */
- cvox.SemanticTree.prototype.xml = function(brief) {
- var dp = new DOMParser();
- var xml = dp.parseFromString('<stree></stree>', 'text/xml');
-
- var xmlRoot = this.root.xml(xml, brief);
- xml.childNodes[0].appendChild(xmlRoot);
-
- return xml.childNodes[0];
- };
-
-
- /**
- * An XML tree representation of the current node.
- * @param {Document} xml The XML document.
- * @param {boolean=} brief If set attributes are omitted.
- * @return {Node} The XML representation of the node.
- */
- cvox.SemanticTree.Node.prototype.xml = function(xml, brief) {
- /**
- * Translates a list of nodes into XML representation.
- * @param {string} tag Name of the enclosing tag.
- * @param {!Array<!cvox.SemanticTree.Node>} nodes A list of nodes.
- * @return {Node} An XML representation of the node list.
- */
- var xmlNodeList = function(tag, nodes) {
- var xmlNodes = nodes.map(function(x) {return x.xml(xml, brief);});
- var tagNode = xml.createElement(tag);
- for (var i = 0, child; child = xmlNodes[i]; i++) {
- tagNode.appendChild(child);
- }
- return tagNode;
- };
- var node = xml.createElement(this.type);
- if (!brief) {
- this.xmlAttributes_(node);
- }
- node.textContent = this.textContent;
- if (this.contentNodes.length > 0) {
- node.appendChild(xmlNodeList('content', this.contentNodes));
- }
- if (this.childNodes.length > 0) {
- node.appendChild(xmlNodeList('children', this.childNodes));
- }
- return node;
- };
-
-
-/**
- * Serializes the XML representation of the tree.
- * @param {boolean=} brief If set attributes are omitted.
- * @return {string} Serialized string.
- */
-cvox.SemanticTree.prototype.toString = function(brief) {
- var xmls = new XMLSerializer();
- return xmls.serializeToString(this.xml(brief));
-};
-
-
-/**
- * Pretty print the XML representation of the tree.
- * @param {boolean=} brief If set attributes are omitted.
- * @return {string} The formatted string.
- */
-cvox.SemanticTree.prototype.formatXml = function(brief) {
- var xml = this.toString(brief);
- return cvox.SemanticTree.formatXml(xml);
-};
-
-
-/**
- * Pretty prints an XML representation.
- * @param {string} xml The serialised XML string.
- * @return {string} The formatted string.
- */
-cvox.SemanticTree.formatXml = function(xml) {
- var reg = /(>)(<)(\/*)/g;
- xml = xml.replace(reg, '$1\r\n$2$3');
- reg = /(>)(.+)(<c)/g;
- xml = xml.replace(reg, '$1\r\n$2\r\n$3');
- var formatted = '';
- var padding = '';
- xml.split('\r\n')
- .forEach(function(node) {
- if (node.match(/.+<\/\w[^>]*>$/)) {
- // Node with content.
- formatted += padding + node + '\r\n';
- } else if (node.match(/^<\/\w/)) {
- if (padding) {
- // Closing tag
- padding = padding.slice(2);
- formatted += padding + node + '\r\n';
- }
- } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) {
- // Opening tag
- formatted += padding + node + '\r\n';
- padding += ' ';
- } else {
- // Empty tag
- formatted += padding + node + '\r\n';
- }
- });
- return formatted;
-};
-
-
-/**
- * Serializes the XML representation of a node.
- * @param {boolean=} brief If attributes are to be omitted.
- * @return {string} Serialized string.
- */
-cvox.SemanticTree.Node.prototype.toString = function(brief) {
- var xmls = new XMLSerializer();
- var dp = new DOMParser();
- var xml = dp.parseFromString('', 'text/xml');
- return xmls.serializeToString(this.xml(xml, brief));
-};
-
-
-/**
- * Adds attributes to the XML representation of the current node.
- * @param {Node} node The XML node.
- * @private
- */
-cvox.SemanticTree.Node.prototype.xmlAttributes_ = function(node) {
- node.setAttribute('role', this.role);
- if (this.font != cvox.SemanticAttr.Font.UNKNOWN) {
- node.setAttribute('font', this.font);
- }
- node.setAttribute('id', this.id);
-};
-
-
-/** Creates a new node object.
- * @return {cvox.SemanticTree.Node} The newly created node.
- * @private
- */
-cvox.SemanticTree.prototype.createNode_ = function() {
- return new cvox.SemanticTree.Node(this.idCounter_++);
-};
-
-
-/**
- * Replaces a node in the tree. Updates the root node if necessary.
- * @param {!cvox.SemanticTree.Node} oldNode The node to be replaced.
- * @param {!cvox.SemanticTree.Node} newNode The new node.
- * @private
- */
-cvox.SemanticTree.prototype.replaceNode_ = function(oldNode, newNode) {
- var parent = oldNode.parent;
- if (!parent) {
- this.root = newNode;
- return;
- }
- parent.replaceChild_(oldNode, newNode);
-};
-
-
-/**
- * Updates the content of the node thereby possibly changing type and role.
- * @param {string} content The new content string.
- * @private
- */
-cvox.SemanticTree.Node.prototype.updateContent_ = function(content) {
- // Remove superfluous whitespace!
- content = content.trim();
- if (this.textContent == content) {
- return;
- }
- var meaning = cvox.SemanticAttr.lookupMeaning(content);
- this.textContent = content;
- this.role = meaning.role;
- this.type = meaning.type;
- this.font = meaning.font;
-};
-
-
-/**
- * Adds MathML nodes to the node's store of MathML nodes if necessary only, as
- * we can not necessarily assume that the MathML of the content nodes and
- * children are all disjoint.
- * @param {Array<Node>} mmlNodes List of MathML nodes.
- * @private
- */
-cvox.SemanticTree.Node.prototype.addMathmlNodes_ = function(mmlNodes) {
- for (var i = 0, mml; mml = mmlNodes[i]; i++) {
- if (this.mathml.indexOf(mml) == -1) {
- this.mathml.push(mml);
- }
- }
-};
-
-
-/**
- * Removes MathML nodes from the node's store of MathML nodes.
- * @param {Array<Node>} mmlNodes List of MathML nodes.
- * @private
- */
-cvox.SemanticTree.Node.prototype.removeMathmlNodes_ = function(mmlNodes) {
- var mmlList = this.mathml;
- for (var i = 0, mml; mml = mmlNodes[i]; i++) {
- var index = mmlList.indexOf(mml);
- if (index != -1) {
- mmlList.splice(index, 1);
- }
- }
- this.mathml = mmlList;
-};
-
-
-/**
- * Appends a child to the node.
- * @param {cvox.SemanticTree.Node} child The new child.
- * @private
- */
-cvox.SemanticTree.Node.prototype.appendChild_ = function(child) {
- this.childNodes.push(child);
- this.addMathmlNodes_(child.mathml);
- child.parent = this;
-};
-
-
-/**
- * Replaces a child node of the node.
- * @param {!cvox.SemanticTree.Node} oldNode The node to be replaced.
- * @param {!cvox.SemanticTree.Node} newNode The new node.
- * @private
- */
-cvox.SemanticTree.Node.prototype.replaceChild_ = function(oldNode, newNode) {
- var index = this.childNodes.indexOf(oldNode);
- if (index == -1) {
- return;
- }
- newNode.parent = this;
- oldNode.parent = null;
- this.childNodes[index] = newNode;
- // To not mess up the order of MathML elements more than necessary, we only
- // remove and add difference lists. The hope is that we might end up with
- // little change.
- var removeMathml = oldNode.mathml.filter(
- function(x) {return newNode.mathml.indexOf(x) == -1;});
- var addMathml = newNode.mathml.filter(
- function(x) {return oldNode.mathml.indexOf(x) == -1;});
- this.removeMathmlNodes_(removeMathml);
- this.addMathmlNodes_(addMathml);
-};
-
-
-/**
- * Appends a content node to the node.
- * @param {cvox.SemanticTree.Node} node The new content node.
- * @private
- */
-cvox.SemanticTree.Node.prototype.appendContentNode_ = function(node) {
- if (node) {
- this.contentNodes.push(node);
- this.addMathmlNodes_(node.mathml);
- node.parent = this;
- }
-};
-
-
-/**
- * Removes a content node from the node.
- * @param {cvox.SemanticTree.Node} node The content node to be removed.
- * @private
- */
-cvox.SemanticTree.Node.prototype.removeContentNode_ = function(node) {
- if (node) {
- var index = this.contentNodes.indexOf(node);
- if (index != -1) {
- this.contentNodes.splice(index, 1);
- }
- }
-};
-
-
-/**
- * This is the main function that creates the semantic tree by recursively
- * parsing the initial MathML tree and bottom up assembling the tree.
- * @param {!Element} mml The MathML tree.
- * @return {!cvox.SemanticTree.Node} The root of the new tree.
- * @private
- */
-cvox.SemanticTree.prototype.parseMathml_ = function(mml) {
- var children = cvox.DomUtil.toArray(mml.children);
- switch (cvox.SemanticUtil.tagName(mml)) {
- case 'MATH':
- case 'MROW':
- case 'MPADDED':
- case 'MSTYLE':
- children = cvox.SemanticUtil.purgeNodes(children);
- // Single child node, i.e. the row is meaningless.
- if (children.length == 1) {
- return this.parseMathml_(/** @type {!Element} */(children[0]));
- }
- // Case of a 'meaningful' row, even if they are empty.
- return this.processRow_(this.parseMathmlChildren_(children));
- break;
- case 'MFRAC':
- var newNode = this.makeBranchNode_(
- cvox.SemanticAttr.Type.FRACTION,
- [this.parseMathml_(children[0]), this.parseMathml_(children[1])],
- []);
- newNode.role = cvox.SemanticAttr.Role.DIVISION;
- return newNode;
- break;
- case 'MSUB':
- case 'MSUP':
- case 'MSUBSUP':
- case 'MOVER':
- case 'MUNDER':
- case 'MUNDEROVER':
- return this.makeLimitNode_(cvox.SemanticUtil.tagName(mml),
- this.parseMathmlChildren_(children));
- break;
- case 'MROOT':
- return this.makeBranchNode_(
- cvox.SemanticAttr.Type.ROOT,
- [this.parseMathml_(children[0]), this.parseMathml_(children[1])],
- []);
- break;
- case 'MSQRT':
- children = this.parseMathmlChildren_(
- cvox.SemanticUtil.purgeNodes(children));
- return this.makeBranchNode_(
- cvox.SemanticAttr.Type.SQRT, [this.processRow_(children)], []);
- break;
- case 'MTABLE':
- newNode = this.makeBranchNode_(
- cvox.SemanticAttr.Type.TABLE,
- this.parseMathmlChildren_(children), []);
- if (cvox.SemanticTree.tableIsMultiline_(newNode)) {
- this.tableToMultiline_(newNode);
- }
- return newNode;
- break;
- case 'MTR':
- newNode = this.makeBranchNode_(
- cvox.SemanticAttr.Type.ROW,
- this.parseMathmlChildren_(children), []);
- newNode.role = cvox.SemanticAttr.Role.TABLE;
- return newNode;
- break;
- case 'MTD':
- children = this.parseMathmlChildren_(
- cvox.SemanticUtil.purgeNodes(children));
- newNode = this.makeBranchNode_(
- cvox.SemanticAttr.Type.CELL, [this.processRow_(children)], []);
- newNode.role = cvox.SemanticAttr.Role.TABLE;
- return newNode;
- break;
- case 'MTEXT':
- var leaf = this.makeLeafNode_(mml);
- leaf.type = cvox.SemanticAttr.Type.TEXT;
- return leaf;
- break;
- // TODO (sorge) Role and font of multi-character and digits unicode strings.
- // TODO (sorge) Reclassify wrongly tagged numbers or identifiers.
- // TODO (sorge) Put this all in a single clean reclassification method.
- case 'MI':
- leaf = this.makeLeafNode_(mml);
- if (leaf.type == cvox.SemanticAttr.Type.UNKNOWN) {
- leaf.type = cvox.SemanticAttr.Type.IDENTIFIER;
- }
- return leaf;
- break;
- case 'MN':
- leaf = this.makeLeafNode_(mml);
- if (leaf.type == cvox.SemanticAttr.Type.UNKNOWN) {
- leaf.type = cvox.SemanticAttr.Type.NUMBER;
- }
- return leaf;
- break;
- case 'MO':
- leaf = this.makeLeafNode_(mml);
- if (leaf.type == cvox.SemanticAttr.Type.UNKNOWN) {
- leaf.type = cvox.SemanticAttr.Type.OPERATOR;
- }
- return leaf;
- break;
- // TODO (sorge) Do something useful with error and phantom symbols.
- default:
- // Ordinarilly at this point we should not get any other tag.
- return this.makeUnprocessed_(mml);
- }
-};
-
-
-/**
- * Parse a list of MathML nodes into the semantic tree.
- * @param {Array<Element>} mmls A list of MathML nodes.
- * @return {!Array<cvox.SemanticTree.Node>} The list of resulting semantic
- * node.
- * @private
- */
-cvox.SemanticTree.prototype.parseMathmlChildren_ = function(mmls) {
- var result = [];
- for (var i = 0, mml; mml = mmls[i]; i++) {
- result.push(this.parseMathml_(mml));
- }
- return result;
-};
-
-/**
- * Create a node that is to be processed at a later point in time.
- * @param {Node} mml The MathML tree.
- * @return {!cvox.SemanticTree.Node} The new node.
- * @private
- */
-cvox.SemanticTree.prototype.makeUnprocessed_ = function(mml) {
- var node = this.createNode_();
- node.mathml = [mml];
- return node;
-};
-
-
-/**
- * Create an empty leaf node.
- * @return {!cvox.SemanticTree.Node} The new node.
- * @private
- */
-cvox.SemanticTree.prototype.makeEmptyNode_ = function() {
- var node = this.createNode_();
- node.type = cvox.SemanticAttr.Type.EMPTY;
- return node;
-};
-
-
-/**
- * Create a leaf node.
- * @param {Node} mml The MathML tree.
- * @return {!cvox.SemanticTree.Node} The new node.
- * @private
- */
-cvox.SemanticTree.prototype.makeLeafNode_ = function(mml) {
- var node = this.createNode_();
- node.mathml = [mml];
- node.updateContent_(mml.textContent);
- node.font = mml.getAttribute('mathvariant') || node.font;
- return node;
-};
-
-
-/**
- * Create a branching node.
- * @param {!cvox.SemanticAttr.Type} type The type of the node.
- * @param {!Array<cvox.SemanticTree.Node>} children The child nodes.
- * @param {!Array<cvox.SemanticTree.Node>} contentNodes The content Nodes.
- * @param {string=} content Content string if there is any.
- * @return {!cvox.SemanticTree.Node} The new node.
- * @private
- */
-cvox.SemanticTree.prototype.makeBranchNode_ = function(
- type, children, contentNodes, content) {
- var node = this.createNode_();
- if (content) {
- node.updateContent_(content);
- }
- node.type = type;
- node.childNodes = children;
- node.contentNodes = contentNodes;
- children.concat(contentNodes)
- .forEach(
- function(x) {
- x.parent = node;
- node.addMathmlNodes_(x.mathml);
- });
- return node;
-};
-
-
-/**
- * Create a branching node for an implicit operation, currently assumed to
- * be of multiplicative type.
- * @param {!Array<!cvox.SemanticTree.Node>} nodes The operands.
- * @return {!cvox.SemanticTree.Node} The new branch node.
- * @private
- */
-cvox.SemanticTree.prototype.makeImplicitNode_ = function(nodes) {
- if (nodes.length == 1) {
- return nodes[0];
- }
- var operator = this.createNode_();
- // For now we assume this is a multiplication using invisible times.
- operator.updateContent_(cvox.SemanticAttr.invisibleTimes());
- var newNode = this.makeInfixNode_(nodes, operator);
- newNode.role = cvox.SemanticAttr.Role.IMPLICIT;
- return newNode;
-};
-
-
-/**
- * Create a branching node for an infix operation.
- * @param {!Array<cvox.SemanticTree.Node>} children The operands.
- * @param {!cvox.SemanticTree.Node} opNode The operator.
- * @return {!cvox.SemanticTree.Node} The new branch node.
- * @private
- */
-cvox.SemanticTree.prototype.makeInfixNode_ = function(children, opNode) {
- return this.makeBranchNode_(
- cvox.SemanticAttr.Type.INFIXOP, children, [opNode], opNode.textContent);
-};
-
-
-/**
- * Creates a node of the specified type by collapsing the given node list into
- * one content (thereby concatenating the content of each node into a single
- * content string) with the inner node as a child.
- * @param {!cvox.SemanticTree.Node} inner The inner node.
- * @param {!Array<cvox.SemanticTree.Node>} nodeList List of nodes.
- * @param {!cvox.SemanticAttr.Type} type The new type of the node.
- * @return {!cvox.SemanticTree.Node} The new branch node.
- * @private
- */
-cvox.SemanticTree.prototype.makeConcatNode_ = function(inner, nodeList, type) {
- if (nodeList.length == 0) {
- return inner;
- }
- var content = nodeList.map(function(x) {return x.textContent;}).join(' ');
- var newNode = this.makeBranchNode_(type, [inner], nodeList, content);
- if (nodeList.length > 0) {
- newNode.role = cvox.SemanticAttr.Role.MULTIOP;
- }
- return newNode;
-};
-
-
-/**
- * Wraps a node into prefix operators.
- * Example: + - a becomes (+ (- (a)))
- * Input: a [+, -] -> Output: content: '+ -', child: a
- * @param {!cvox.SemanticTree.Node} node The inner node.
- * @param {!Array<cvox.SemanticTree.Node>} prefixes Prefix operators
- * from the outermost to the innermost.
- * @return {!cvox.SemanticTree.Node} The new branch node.
- * @private
- */
-cvox.SemanticTree.prototype.makePrefixNode_ = function(node, prefixes) {
- var negatives = cvox.SemanticTree.partitionNodes_(
- prefixes, cvox.SemanticTree.attrPred_('role', 'SUBTRACTION'));
- var newNode = this.makeConcatNode_(
- node, negatives.comp.pop(), cvox.SemanticAttr.Type.PREFIXOP);
-
- while (negatives.rel.length > 0) {
- newNode = this.makeConcatNode_(
- newNode, [negatives.rel.pop()], cvox.SemanticAttr.Type.PREFIXOP);
- newNode.role = cvox.SemanticAttr.Role.NEGATIVE;
- newNode = this.makeConcatNode_(
- newNode, negatives.comp.pop(), cvox.SemanticAttr.Type.PREFIXOP);
- }
- return newNode;
-};
-
-
-/**
- * Wraps a node into postfix operators.
- * Example: a - + becomes (((a) -) +)
- * Input: a [-, +] -> Output: content: '- +', child: a
- * @param {!cvox.SemanticTree.Node} node The inner node.
- * @param {!Array<cvox.SemanticTree.Node>} postfixes Postfix operators from
- * innermost to outermost.
- * @return {!cvox.SemanticTree.Node} The new branch node.
- * @private
- */
-cvox.SemanticTree.prototype.makePostfixNode_ = function(node, postfixes) {
- return this.makeConcatNode_(
- node, postfixes, cvox.SemanticAttr.Type.POSTFIXOP);
-};
-
-
-// TODO (sorge) Separate out interspersed text before the relations in row
-// heuristic otherwise we get them as implicit operations!
-// Currently we handle that later in the rules, which is rather messy.
-/**
- * Processes a list of nodes, combining expressions by delimiters, tables,
- * punctuation sequences, function/big operator/integral applications to
- * generate a syntax tree with relation and operator precedence.
- *
- * This is the main heuristic to rewrite a flat row of terms into a meaningful
- * term tree.
- * @param {!Array<cvox.SemanticTree.Node>} nodes The list of nodes.
- * @return {!cvox.SemanticTree.Node} The root node of the syntax tree.
- * @private
- */
-cvox.SemanticTree.prototype.processRow_ = function(nodes) {
- if (nodes.length == 0) {
- return this.makeEmptyNode_();
- }
- nodes = this.getFencesInRow_(nodes);
- nodes = this.processTablesInRow_(nodes);
- nodes = this.getPunctuationInRow_(nodes);
- nodes = this.getFunctionsInRow_(nodes);
- return this.processRelationsInRow_(nodes);
-};
-
-
-/**
- * Constructs a syntax tree with relation and operator precedence from a list
- * of nodes.
- * @param {!Array<!cvox.SemanticTree.Node>} nodes The list of nodes.
- * @return {!cvox.SemanticTree.Node} The root node of the syntax tree.
- * @private
- */
-cvox.SemanticTree.prototype.processRelationsInRow_ = function(nodes) {
- var partition = cvox.SemanticTree.partitionNodes_(
- nodes, cvox.SemanticTree.attrPred_('type', 'RELATION'));
- var firstRel = partition.rel[0];
-
- if (!firstRel) {
- return this.processOperationsInRow_(nodes);
- }
- if (nodes.length == 1) {
- return nodes[0];
- }
- var children = partition.comp.map(
- goog.bind(this.processOperationsInRow_, this));
- if (partition.rel.every(
- function(x) {return x.textContent == firstRel.textContent;})) {
- return this.makeBranchNode_(
- cvox.SemanticAttr.Type.RELSEQ, children, partition.rel,
- firstRel.textContent);
- }
- return this.makeBranchNode_(
- cvox.SemanticAttr.Type.MULTIREL, children, partition.rel);
-};
-
-
-/**
- * Constructs a syntax tree with operator precedence from a list nodes.
- * @param {!Array<!cvox.SemanticTree.Node>} nodes The list of nodes.
- * @return {!cvox.SemanticTree.Node} The root node of the syntax tree.
- * @private
- */
-cvox.SemanticTree.prototype.processOperationsInRow_ = function(nodes) {
- if (nodes.length == 0) {
- return this.makeEmptyNode_();
- }
- if (nodes.length == 1) {
- return nodes[0];
- }
-
- var prefix = [];
- while (nodes.length > 0 &&
- nodes[0].type == cvox.SemanticAttr.Type.OPERATOR) {
- prefix.push(nodes.shift());
- }
- // Pathological case: only operators in row.
- if (nodes.length == 0) {
- return this.makePrefixNode_(prefix.pop(), prefix);
- }
- if (nodes.length == 1) {
- return this.makePrefixNode_(nodes[0], prefix);
- }
-
- var split = cvox.SemanticTree.sliceNodes_(
- nodes, cvox.SemanticTree.attrPred_('type', 'OPERATOR'));
- // At this point, we know that split.head is not empty!
- var node = this.makePrefixNode_(
- this.makeImplicitNode_(
- /** @type {!Array<!cvox.SemanticTree.Node>} */ (split.head)),
- prefix);
- if (!split.div) {
- return node;
- }
- return this.makeOperationsTree_(split.tail, node, split.div);
-};
-
-
-/**
- * Recursively constructs syntax tree with operator precedence from a list nodes
- * given a initial root node.
- * @param {!Array<cvox.SemanticTree.Node>} nodes The list of nodes.
- * @param {!cvox.SemanticTree.Node} root Initial tree.
- * @param {!cvox.SemanticTree.Node} lastop Last operator that has not been
- * processed yet.
- * @param {Array<cvox.SemanticTree.Node>=} prefixes Operator nodes that will
- * become prefix operation (or postfix in case they come after last operand).
- * @return {!cvox.SemanticTree.Node} The root node of the syntax tree.
- * @private
- */
-cvox.SemanticTree.prototype.makeOperationsTree_ = function(
- nodes, root, lastop, prefixes) {
- prefixes = prefixes || [];
-
- if (nodes.length == 0) {
- // Left over prefixes become postfixes.
- prefixes.unshift(lastop);
- if (root.type == cvox.SemanticAttr.Type.INFIXOP) {
- // We assume prefixes bind stronger than postfixes.
- var node = this.makePostfixNode_(
- // Here we know that the childNodes are not empty!
- /** @type {!cvox.SemanticTree.Node} */ (root.childNodes.pop()),
- prefixes);
- root.appendChild_(node);
- return root;
- }
- return this.makePostfixNode_(root, prefixes);
- }
-
- var split = cvox.SemanticTree.sliceNodes_(
- nodes, cvox.SemanticTree.attrPred_('type', 'OPERATOR'));
-
- if (split.head.length == 0) {
- prefixes.push(split.div);
- return this.makeOperationsTree_(split.tail, root, lastop, prefixes);
- }
-
- var node = this.makePrefixNode_(
- this.makeImplicitNode_(split.head), prefixes);
- var newNode = this.appendOperand_(root, lastop, node);
- if (!split.div) {
- return newNode;
- }
-
- return this.makeOperationsTree_(split.tail, newNode, split.div, []);
-};
-
-// TODO (sorge) The following four functions could be combined into
-// a single one. Currently it is clearer the way it is, though.
-/**
- * Appends an operand at the right place in an operator tree.
- * @param {!cvox.SemanticTree.Node} root The operator tree.
- * @param {!cvox.SemanticTree.Node} op The operator node.
- * @param {!cvox.SemanticTree.Node} node The node to be added.
- * @return {!cvox.SemanticTree.Node} The modified root node.
- * @private
- */
-cvox.SemanticTree.prototype.appendOperand_ = function(root, op, node) {
- // In general our operator tree will have the form that additions and
- // subtractions are stacked, while multiplications are subordinate.
- if (root.type != cvox.SemanticAttr.Type.INFIXOP) {
- return this.makeInfixNode_([root, node], op);
- }
- if (this.appendExistingOperator_(root, op, node)) {
- return root;
- }
- return op.role == cvox.SemanticAttr.Role.MULTIPLICATION ?
- this.appendMultiplicativeOp_(root, op, node) :
- this.appendAdditiveOp_(root, op, node);
-};
-
-
-/**
- * Appends a multiplicative operator and operand.
- * @param {!cvox.SemanticTree.Node} root The root node.
- * @param {!cvox.SemanticTree.Node} op The operator node.
- * @param {!cvox.SemanticTree.Node} node The operand node to be added.
- * @return {!cvox.SemanticTree.Node} The modified root node.
- * @private
- */
-cvox.SemanticTree.prototype.appendMultiplicativeOp_ = function(root, op, node) {
- var lastRoot = root;
- var lastChild = root.childNodes[root.childNodes.length - 1];
- while (lastChild && lastChild.type == cvox.SemanticAttr.Type.INFIXOP) {
- lastRoot = lastChild;
- lastChild = lastRoot.childNodes[root.childNodes.length - 1];
- }
- var newNode = this.makeInfixNode_([lastRoot.childNodes.pop(), node], op);
- lastRoot.appendChild_(newNode);
- return root;
-};
-
-
-/**
- * Appends an additive/substractive operator and operand.
- * @param {!cvox.SemanticTree.Node} root The old root node.
- * @param {!cvox.SemanticTree.Node} op The operator node.
- * @param {!cvox.SemanticTree.Node} node The operand node to be added.
- * @return {!cvox.SemanticTree.Node} The new root node.
- * @private
- */
-cvox.SemanticTree.prototype.appendAdditiveOp_ = function(root, op, node) {
- return this.makeInfixNode_([root, node], op);
-};
-
-
-/**
- * Adds an operand to an operator node if it is the continuation of an existing
- * operation.
- * @param {!cvox.SemanticTree.Node} root The root node.
- * @param {!cvox.SemanticTree.Node} op The operator node.
- * @param {!cvox.SemanticTree.Node} node The operand node to be added.
- * @return {boolean} True if operator was successfully appended.
- * @private
- */
-cvox.SemanticTree.prototype.appendExistingOperator_ = function(root, op, node) {
- if (!root || root.type != cvox.SemanticAttr.Type.INFIXOP) {
- return false;
- }
- if (root.textContent == op.textContent) {
- root.appendContentNode_(op);
- root.appendChild_(node);
- return true;
- }
- this.appendExistingOperator_(
- // Again, if this is an INFIXOP node, we know it has a child!
- /** @type {!cvox.SemanticTree.Node} */
- (root.childNodes[root.childNodes.length - 1]),
- op, node);
-};
-
-
-// TODO (sorge) The following procedure needs a rational reconstruction. It
-// contains a number of similar cases which should be combined.
-/**
- * Combines delimited expressions in a list of nodes.
- *
- * The basic idea of the heuristic is as follows:
- * 1. Opening and closing delimiters are matched regardless of the actual shape
- * of the fence. These are turned into fenced nodes.
- * 2. Neutral fences are matched only with neutral fences of the same shape.
- * 3. For a collection of unmatched neutral fences we try to get a maximum
- * number of matching fences. E.g. || a|b || would be turned into a fenced
- * node with fences || and content a|b.
- * 4. Any remaining unmatched delimiters are turned into punctuation nodes.
- * @param {!Array<!cvox.SemanticTree.Node>} nodes The list of nodes.
- * @return {!Array<!cvox.SemanticTree.Node>} The new list of nodes.
- * @private
- */
-cvox.SemanticTree.prototype.getFencesInRow_ = function(nodes) {
- var partition = cvox.SemanticTree.partitionNodes_(
- nodes, cvox.SemanticTree.attrPred_('type', 'FENCE'));
- var felem = partition.comp.shift();
- return this.processFences_(partition.rel, partition.comp, [], [felem]);
-};
-
-
-/**
- * Recursively processes a list of nodes and combines all the fenced expressions
- * into single nodes. It also processes singular fences, building expressions
- * that are only fenced left or right.
- * @param {!Array<cvox.SemanticTree.Node>} fences FIFO queue of fence nodes.
- * @param {!Array<Array<cvox.SemanticTree.Node>>} content FIFO queue content
- * between fences.
- * @param {!Array<cvox.SemanticTree.Node>} openStack LIFO stack of open fences.
- * @param {!Array<!Array<cvox.SemanticTree.Node>>} contentStack LIFO stack of
- * content between fences yet to be processed.
- * @return {!Array<cvox.SemanticTree.Node>} A list of nodes with all fenced
- * expressions processed.
- * @private
- */
-cvox.SemanticTree.prototype.processFences_ = function(
- fences, content, openStack, contentStack) {
- // Base case 1: Everything is used up.
- if (fences.length == 0 && openStack.length == 0) {
- return contentStack[0];
- }
- var openPred = cvox.SemanticTree.attrPred_('role', 'OPEN');
- // Base case 2: Only open and neutral fences are left on the stack.
- if (fences.length == 0) {
- // Basic idea:
- // - make punctuation nodes from open fences
- // - combine as many neutral fences as possible, if the are not separated by
- // open fences.
- // The idea is to allow for things like case statements etc. and not bury
- // them inside a neutral fenced expression.
- //
- // 0. We process the list from left to right. Hence the first element on the
- // content stack are actually left most elements in the expression.
- // 1. Slice at open fence.
- // 2. On tail optimize for neutral fences.
- // 3. Repeat until fence stack is exhausted.
- // Push rightmost elements onto the result.
- var result = contentStack.shift();
- while (openStack.length > 0) {
- if (openPred(openStack[0])) {
- var firstOpen = openStack.shift();
- cvox.SemanticTree.fenceToPunct_(firstOpen);
- result.push(firstOpen);
- } else {
- var split = cvox.SemanticTree.sliceNodes_(openStack, openPred);
- var cutLength = split.head.length - 1;
- var innerNodes = this.processNeutralFences_(
- split.head, contentStack.slice(0, cutLength));
- contentStack = contentStack.slice(cutLength);
- //var rightContent = contentStack.shift();
- result.push.apply(result, innerNodes);
- //result.push.apply(result, rightContent);
- if (split.div) {
- split.tail.unshift(split.div);
- }
- openStack = split.tail;
- }
- result.push.apply(result, contentStack.shift());
- }
- return result;
- }
- var lastOpen = openStack[openStack.length - 1];
- var firstRole = fences[0].role;
- // General opening case.
- // Either we have an open fence.
- if (firstRole == cvox.SemanticAttr.Role.OPEN ||
- // Or we have a neutral fence that does not have a counter part.
- (firstRole == cvox.SemanticAttr.Role.NEUTRAL &&
- (!lastOpen ||
- fences[0].textContent != lastOpen.textContent))) {
- openStack.push(fences.shift());
- contentStack.push(content.shift());
- return this.processFences_(fences, content, openStack, contentStack);
- }
- // General closing case.
- if (lastOpen && (
- // Closing fence for some opening fence.
- (firstRole == cvox.SemanticAttr.Role.CLOSE &&
- lastOpen.role == cvox.SemanticAttr.Role.OPEN) ||
- // Netural fence with exact counter part.
- (firstRole == cvox.SemanticAttr.Role.NEUTRAL &&
- fences[0].textContent == lastOpen.textContent))) {
- var fenced = this.makeHorizontalFencedNode_(
- openStack.pop(), fences.shift(), contentStack.pop());
- contentStack.push(contentStack.pop().concat([fenced], content.shift()));
- return this.processFences_(fences, content, openStack, contentStack);
- }
- // Closing with a neutral fence on the stack.
- if (lastOpen && firstRole == cvox.SemanticAttr.Role.CLOSE &&
- lastOpen.role == cvox.SemanticAttr.Role.NEUTRAL &&
- openStack.some(openPred)) {
- // Steps of the algorithm:
- // 1. Split list at right most opening bracket.
- // 2. Cut content list at corresponding length.
- // 3. Optimise the neutral fences.
- // 4. Make fenced node.
- //
- // Careful, this reverses openStack!
- var split = cvox.SemanticTree.sliceNodes_(openStack, openPred, true);
- // We know that
- // (a) div & tail exist,
- // (b) all are combined in this step into a single fenced node,
- // (c) head is the new openStack,
- // (d) the new contentStack is remainder of contentStack + new fenced node +
- // shift of content.
- var rightContent = contentStack.pop();
- var cutLength = contentStack.length - split.tail.length + 1;
- var innerNodes = this.processNeutralFences_(
- split.tail, contentStack.slice(cutLength));
- contentStack = contentStack.slice(0, cutLength);
- var fenced = this.makeHorizontalFencedNode_(
- split.div, fences.shift(),
- contentStack.pop().concat(innerNodes, rightContent));
- contentStack.push(contentStack.pop().concat([fenced], content.shift()));
- return this.processFences_(fences, content, split.head, contentStack);
- }
- // Final Case: A singular closing fence.
- // We turn the fence into a punctuation.
- var fenced = fences.shift();
- cvox.SemanticTree.fenceToPunct_(fenced);
- contentStack.push(contentStack.pop().concat([fenced], content.shift()));
- return this.processFences_(fences, content, openStack, contentStack);
-};
-
-
-// TODO (sorge) The following could be done with linear programming.
-/**
- * Trys to combine neutral fences as much as possible.
- * @param {!Array<!cvox.SemanticTree.Node>} fences A list of neutral fences.
- * @param {!Array<!Array<cvox.SemanticTree.Node>>} content Intermediate
- * content. Observe that |content| = |fences| - 1
- * @return {!Array<cvox.SemanticTree.Node>} List of node with fully fenced
- * nodes.
- * @private
- */
-cvox.SemanticTree.prototype.processNeutralFences_ = function(fences, content) {
- if (fences.length == 0) {
- return fences;
- }
- if (fences.length == 1) {
- cvox.SemanticTree.fenceToPunct_(fences[0]);
- return fences;
- }
- var firstFence = fences.shift();
- var split = cvox.SemanticTree.sliceNodes_(
- fences, function(x) {return x.textContent == firstFence.textContent;});
- if (!split.div) {
- cvox.SemanticTree.fenceToPunct_(firstFence);
- var restContent = content.shift();
- restContent.unshift(firstFence);
- return restContent.concat(this.processNeutralFences_(fences, content));
- }
- var newContent = this.combineFencedContent_(
- firstFence, split.div, split.head, content);
- if (split.tail.length > 0) {
- var leftContent = newContent.shift();
- var result = this.processNeutralFences_(split.tail, newContent);
- return leftContent.concat(result);
- }
- return newContent[0];
-};
-
-
-/**
- * Combines nodes framed by two matching fences using the given content.
- * Example: leftFence: [, rightFence: ], midFences: |, |
- * content: c1, c2, c3, c4, ... cn
- * return: [c1 | c2 | c3 ], c4, ... cn
- * @param {!cvox.SemanticTree.Node} leftFence The left fence.
- * @param {!cvox.SemanticTree.Node} rightFence The right fence.
- * @param {!Array<cvox.SemanticTree.Node>} midFences A list of intermediate
- * fences.
- * @param {!Array<!Array<cvox.SemanticTree.Node>>} content Intermediate
- * content. Observe that |content| = |fences| - 1 + k where k >= 0 is the
- * remainder.
- * @return {!Array<!Array<cvox.SemanticTree.Node>>} List of content nodes
- * where the first is the fully fenced node wrt. the given left and right
- * fence.
- * @private
- */
-cvox.SemanticTree.prototype.combineFencedContent_ = function(
- leftFence, rightFence, midFences, content) {
-
- if (midFences.length == 0) {
- var fenced = this.makeHorizontalFencedNode_(
- leftFence, rightFence, content.shift());
- content.unshift(fenced);
- return content;
- }
-
- var leftContent = content.shift();
- var cutLength = midFences.length - 1;
- var midContent = content.slice(0, cutLength);
- content = content.slice(cutLength);
- var rightContent = content.shift();
- var innerNodes = this.processNeutralFences_(midFences, midContent);
- leftContent.push.apply(leftContent, innerNodes);
- leftContent.push.apply(leftContent, rightContent);
- var fenced = this.makeHorizontalFencedNode_(
- leftFence, rightFence, leftContent);
- if (content.length > 0) {
- content[0].unshift(fenced);
- } else {
- content = [[fenced]];
- }
- return content;
- };
-
-
-/**
- * Rewrite fences into punctuation. This is done with any "leftover" fence.
- * @param {cvox.SemanticTree.Node} fence Fence.
- * @private
- */
-cvox.SemanticTree.fenceToPunct_ = function(fence) {
- fence.type = cvox.SemanticAttr.Type.PUNCTUATION;
- switch (fence.role) {
- case cvox.SemanticAttr.Role.NEUTRAL:
- fence.role = cvox.SemanticAttr.Role.VBAR;
- break;
- case cvox.SemanticAttr.Role.OPEN:
- fence.role = cvox.SemanticAttr.Role.OPENFENCE;
- break;
- case cvox.SemanticAttr.Role.CLOSE:
- fence.role = cvox.SemanticAttr.Role.CLOSEFENCE;
- break;
- }
-};
-
-
-/**
- * Create a fenced node.
- * @param {cvox.SemanticTree.Node} ofence Opening fence.
- * @param {cvox.SemanticTree.Node} cfence Closing fence.
- * @param {!Array<cvox.SemanticTree.Node>} content The content
- * between the fences.
- * @return {!cvox.SemanticTree.Node} The new node.
- * @private
- */
-cvox.SemanticTree.prototype.makeHorizontalFencedNode_ = function(
- ofence, cfence, content) {
- var childNode = this.processRow_(content);
- var newNode = this.makeBranchNode_(
- cvox.SemanticAttr.Type.FENCED, [childNode], [ofence, cfence]);
- if (ofence.role == cvox.SemanticAttr.Role.OPEN) {
- newNode.role = cvox.SemanticAttr.Role.LEFTRIGHT;
- } else {
- newNode.role = ofence.role;
- }
- return newNode;
-};
-
-
-/**
- * Combines sequences of punctuated expressions in a list of nodes.
- * @param {!Array<cvox.SemanticTree.Node>} nodes The list of nodes.
- * @return {!Array<cvox.SemanticTree.Node>} The new list of nodes.
- * @private
- */
-cvox.SemanticTree.prototype.getPunctuationInRow_ = function(nodes) {
- // For now we just make a punctuation node with a particular role. This is
- // similar to an mrow. The only exception are ellipses, which we assume to be
- // in lieu of identifiers.
- // In addition we keep the single punctuation nodes as content.
- var partition = cvox.SemanticTree.partitionNodes_(
- nodes, function(x) {
- return cvox.SemanticTree.attrPred_('type', 'PUNCTUATION')(x) &&
- !cvox.SemanticTree.attrPred_('role', 'ELLIPSIS')(x);});
- if (partition.rel.length == 0) {
- return nodes;
- }
- var newNodes = [];
- var firstComp = partition.comp.shift();
- if (firstComp.length > 0) {
- newNodes.push(this.processRow_(firstComp));
- }
- var relCounter = 0;
- while (partition.comp.length > 0) {
- newNodes.push(partition.rel[relCounter++]);
- firstComp = partition.comp.shift();
- if (firstComp.length > 0) {
- newNodes.push(this.processRow_(firstComp));
- }
- }
- return [this.makePunctuatedNode_(newNodes, partition.rel)];
-};
-
-
-/**
- * Create a punctuated node.
- * @param {!Array<!cvox.SemanticTree.Node>} nodes List of all nodes separated
- * by punctuations.
- * @param {!Array<!cvox.SemanticTree.Node>} punctuations List of all separating
- * punctations. Observe that punctations is a subset of nodes.
- * @return {!cvox.SemanticTree.Node}
- * @private
- */
-cvox.SemanticTree.prototype.makePunctuatedNode_ = function(
- nodes, punctuations) {
- var newNode = this.makeBranchNode_(
- cvox.SemanticAttr.Type.PUNCTUATED, nodes, punctuations);
-
- if (punctuations.length == 1 &&
- nodes[0].type == cvox.SemanticAttr.Type.PUNCTUATION) {
- newNode.role = cvox.SemanticAttr.Role.STARTPUNCT;
- } else if (punctuations.length == 1 &&
- nodes[nodes.length - 1].type == cvox.SemanticAttr.Type.PUNCTUATION) {
- newNode.role = cvox.SemanticAttr.Role.ENDPUNCT;
- } else {
- newNode.role = cvox.SemanticAttr.Role.SEQUENCE;
- }
- return newNode;
-};
-
-
-/**
- * Creates a limit node from a sub/superscript or over/under node if the central
- * element is a big operator. Otherwise it creates the standard elements.
- * @param {string} mmlTag The tag name of the original node.
- * @param {!Array<!cvox.SemanticTree.Node>} children The children of the
- * original node.
- * @return {!cvox.SemanticTree.Node} The newly created limit node.
- * @private
- */
-cvox.SemanticTree.prototype.makeLimitNode_ = function(mmlTag, children) {
- var center = children[0];
- var isFunction = cvox.SemanticTree.attrPred_('type', 'FUNCTION')(center);
- // TODO (sorge) Put this into a single function.
- var isLimit = cvox.SemanticTree.attrPred_('type', 'LARGEOP')(center) ||
- cvox.SemanticTree.attrPred_('type', 'LIMBOTH')(center) ||
- cvox.SemanticTree.attrPred_('type', 'LIMLOWER')(center) ||
- cvox.SemanticTree.attrPred_('type', 'LIMUPPER')(center) ||
- (isFunction && cvox.SemanticTree.attrPred_('role', 'LIMFUNC')(center));
- var type = cvox.SemanticAttr.Type.UNKNOWN;
- // TODO (sorge) Make use of the difference in information on sub vs under etc.
- if (isLimit) {
- switch (mmlTag) {
- case 'MSUB':
- case 'MUNDER':
- type = cvox.SemanticAttr.Type.LIMLOWER;
- break;
- case 'MSUP':
- case 'MOVER':
- type = cvox.SemanticAttr.Type.LIMUPPER;
- break;
- case 'MSUBSUP':
- case 'MUNDEROVER':
- type = cvox.SemanticAttr.Type.LIMBOTH;
- break;
- }
- } else {
- switch (mmlTag) {
- case 'MSUB':
- type = cvox.SemanticAttr.Type.SUBSCRIPT;
- break;
- case 'MSUP':
- type = cvox.SemanticAttr.Type.SUPERSCRIPT;
- break;
- case 'MSUBSUP':
- var innerNode = this.makeBranchNode_(cvox.SemanticAttr.Type.SUBSCRIPT,
- [center, children[1]], []);
- innerNode.role = center.role;
- children = [innerNode, children[2]];
- type = cvox.SemanticAttr.Type.SUPERSCRIPT;
- break;
- case 'MOVER':
- type = cvox.SemanticAttr.Type.OVERSCORE;
- break;
- case 'MUNDER':
- type = cvox.SemanticAttr.Type.UNDERSCORE;
- break;
- case 'MUNDEROVER':
- default:
- var innerNode = this.makeBranchNode_(cvox.SemanticAttr.Type.UNDERSCORE,
- [center, children[1]], []);
- innerNode.role = center.role;
- children = [innerNode, children[2]];
- type = cvox.SemanticAttr.Type.OVERSCORE;
- break;
- }
- }
- var newNode = this.makeBranchNode_(type, children, []);
- newNode.role = center.role;
- return newNode;
-};
-
-
-/**
- * Recursive method to accumulate function expressions.
- *
- * The idea is to process functions in a row from left to right combining them
- * with there arguments. Thereby we take the notion of a function rather broadly
- * as a functional expressions that consists of a prefix and some arguments.
- * In particular we distinguish four types of functional expressions:
- * - integral: Integral expression.
- * - bigop: A big operator expression like a sum.
- * - prefix: A well defined prefix function such as sin, cos or a limit
- * functions like lim, max.
- * - simple: An expression consisting of letters that are potentially a function
- * symbol. If we have an explicit function application symbol
- * following the expression we turn into a prefix function. Otherwise
- * we decide heuristically if we could have a function application.
- * @param {!Array<cvox.SemanticTree.Node>} restNodes The remainder list of
- * nodes.
- * @param {!Array<cvox.SemanticTree.Node>=} result The result node list.
- * @return {!Array<!cvox.SemanticTree.Node>} The fully processed list.
- * @private
- */
-cvox.SemanticTree.prototype.getFunctionsInRow_ = function(restNodes, result) {
- result = result || [];
- // Base case.
- if (restNodes.length == 0) {
- return result;
- }
- var firstNode = /** @type {!cvox.SemanticTree.Node} */ (restNodes.shift());
- var heuristic = cvox.SemanticTree.classifyFunction_(firstNode, restNodes);
- // First node is not a function node.
- if (!heuristic) {
- result.push(firstNode);
- return this.getFunctionsInRow_(restNodes, result);
- }
- // Combine functions in the rest of the row.
- var processedRest = this.getFunctionsInRow_(restNodes, []);
- var newRest = this.getFunctionArgs_(firstNode, processedRest, heuristic);
- return result.concat(newRest);
-};
-
-
-/**
- * Classifies a function wrt. the heuristic that should be applied.
- * @param {!cvox.SemanticTree.Node} funcNode The node to be classified.
- * @param {!Array<cvox.SemanticTree.Node>} restNodes The remainder list of
- * nodes. They can useful to look ahead if there is an explicit function
- * application. If there is one, it will be destructively removed!
- * @return {!string} The string specifying the heuristic.
- * @private
- */
-cvox.SemanticTree.classifyFunction_ = function(funcNode, restNodes) {
- // We do not allow double function application. This is not lambda calculus!
- if (funcNode.type == cvox.SemanticAttr.Type.APPL ||
- funcNode.type == cvox.SemanticAttr.Type.BIGOP ||
- funcNode.type == cvox.SemanticAttr.Type.INTEGRAL) {
- return '';
- }
- // Find and remove explicit function applications.
- // We now treat funcNode as a prefix function, regardless of what its actual
- // content is.
- if (restNodes[0] &&
- restNodes[0].textContent == cvox.SemanticAttr.functionApplication()) {
- // Remove explicit function application. This is destructive on the
- // underlying list.
- restNodes.shift();
- cvox.SemanticTree.propagatePrefixFunc_(funcNode);
- return 'prefix';
- }
- switch (funcNode.role) {
- case cvox.SemanticAttr.Role.INTEGRAL:
- return 'integral';
- break;
- case cvox.SemanticAttr.Role.SUM:
- return 'bigop';
- break;
- case cvox.SemanticAttr.Role.PREFIXFUNC:
- case cvox.SemanticAttr.Role.LIMFUNC:
- return 'prefix';
- break;
- default:
- if (funcNode.type == cvox.SemanticAttr.Type.IDENTIFIER) {
- return 'simple';
- }
- }
- return '';
-};
-
-
-/**
- * Propagates a prefix function role in a node.
- * @param {cvox.SemanticTree.Node} funcNode The node whose role is to be
- * rewritten.
- * @private
- */
-cvox.SemanticTree.propagatePrefixFunc_ = function(funcNode) {
- if (funcNode) {
- funcNode.role = cvox.SemanticAttr.Role.PREFIXFUNC;
- cvox.SemanticTree.propagatePrefixFunc_(funcNode.childNodes[0]);
- }
-};
-
-
-/**
- * Computes the arguments for a function from a list of nodes depending on the
- * given heuristic.
- * @param {!cvox.SemanticTree.Node} func A function node.
- * @param {!Array<cvox.SemanticTree.Node>} rest List of nodes to choose
- * arguments from.
- * @param {string} heuristic The heuristic to follow.
- * @return {!Array<!cvox.SemanticTree.Node>} The function and the remainder of
- * the rest list.
- * @private
- */
-cvox.SemanticTree.prototype.getFunctionArgs_ = function(func, rest, heuristic) {
- switch (heuristic) {
- case 'integral':
- var components = this.getIntegralArgs_(rest);
- var integrand = this.processRow_(components.integrand);
- var funcNode = this.makeIntegralNode_(func, integrand, components.intvar);
- components.rest.unshift(funcNode);
- return components.rest;
- break;
- case 'prefix':
- if (rest[0] && rest[0].type == cvox.SemanticAttr.Type.FENCED) {
- funcNode = this.makeFunctionNode_(
- func, /** @type {!cvox.SemanticTree.Node} */ (rest.shift()));
- rest.unshift(funcNode);
- return rest;
- }
- case 'bigop':
- var partition = cvox.SemanticTree.sliceNodes_(
- rest, cvox.SemanticTree.prefixFunctionBoundary_);
- var arg = this.processRow_(partition.head);
- if (heuristic == 'prefix') {
- funcNode = this.makeFunctionNode_(func, arg);
- } else {
- funcNode = this.makeBigOpNode_(func, arg);
- }
- if (partition.div) {
- partition.tail.unshift(partition.div);
- }
- partition.tail.unshift(funcNode);
- return partition.tail;
- break;
- case 'simple':
- if (rest.length == 0) {
- return [func];
- }
- var firstArg = rest[0];
- if (firstArg.type == cvox.SemanticAttr.Type.FENCED &&
- firstArg.role != cvox.SemanticAttr.Role.NEUTRAL &&
- this.simpleFunctionHeuristic_(firstArg)) {
- funcNode = this.makeFunctionNode_(
- func, /** @type {!cvox.SemanticTree.Node} */ (rest.shift()));
- rest.unshift(funcNode);
- return rest;
- }
- rest.unshift(func);
- return rest;
- break;
- }
-};
-
-
-/**
- * Tail recursive function to obtain integral arguments.
- * @param {!Array<cvox.SemanticTree.Node>} nodes List of nodes to take
- * arguments from.
- * @param {Array<cvox.SemanticTree.Node>=} args List of integral arguments.
- * @return {{integrand: !Array<cvox.SemanticTree.Node>,
- * intvar: cvox.SemanticTree.Node,
- * rest: !Array<cvox.SemanticTree.Node>}}
- * Result split into integrand, integral variable and the remaining
- * elements.
- * @private
- */
-cvox.SemanticTree.prototype.getIntegralArgs_ = function(nodes, args) {
- args = args || [];
- if (nodes.length == 0) {
- return {integrand: args, intvar: null, rest: nodes};
- }
- var firstNode = nodes[0];
- if (cvox.SemanticTree.generalFunctionBoundary_(firstNode)) {
- return {integrand: args, intvar: null, rest: nodes};
- }
- if (cvox.SemanticTree.integralDxBoundarySingle_(firstNode)) {
- return {integrand: args, intvar: firstNode, rest: nodes.slice(1)};
- }
- if (nodes[1] && cvox.SemanticTree.integralDxBoundary_(firstNode, nodes[1])) {
- var comma = this.createNode_();
- comma.updateContent_(cvox.SemanticAttr.invisibleComma());
- var intvar = this.makePunctuatedNode_(
- [firstNode, comma, nodes[1]], [comma]);
- intvar.role = cvox.SemanticAttr.Role.INTEGRAL;
- return {integrand: args, intvar: intvar, rest: nodes.slice(2)};
- }
- args.push(nodes.shift());
- return this.getIntegralArgs_(nodes, args);
-};
-
-
-/**
- * Create a function node.
- * @param {!cvox.SemanticTree.Node} func The function operator.
- * @param {!cvox.SemanticTree.Node} arg The argument.
- * @return {!cvox.SemanticTree.Node} The new function node.
- * @private
- */
-cvox.SemanticTree.prototype.makeFunctionNode_ = function(func, arg) {
- var applNode = this.createNode_();
- applNode.updateContent_(cvox.SemanticAttr.functionApplication());
- applNode.type = cvox.SemanticAttr.Type.PUNCTUATION;
- applNode.role = cvox.SemanticAttr.Role.APPLICATION;
- var newNode = this.makeBranchNode_(cvox.SemanticAttr.Type.APPL, [func, arg],
- [applNode]);
- newNode.role = func.role;
- return newNode;
-};
-
-
-/**
- * Create a big operator node.
- * @param {!cvox.SemanticTree.Node} bigOp The big operator.
- * @param {!cvox.SemanticTree.Node} arg The argument.
- * @return {!cvox.SemanticTree.Node} The new big operator node.
- * @private
- */
-cvox.SemanticTree.prototype.makeBigOpNode_ = function(bigOp, arg) {
- var newNode = this.makeBranchNode_(
- cvox.SemanticAttr.Type.BIGOP, [bigOp, arg], []);
- newNode.role = bigOp.role;
- return newNode;
-};
-
-
-/**
- * Create an integral node. It has three children: integral, integrand and
- * integration variable. The latter two can be omitted.
- * @param {!cvox.SemanticTree.Node} integral The integral operator.
- * @param {cvox.SemanticTree.Node} integrand The integrand.
- * @param {cvox.SemanticTree.Node} intvar The integral variable.
- * @return {!cvox.SemanticTree.Node} The new integral node.
- * @private
- */
-cvox.SemanticTree.prototype.makeIntegralNode_ = function(
- integral, integrand, intvar) {
- integrand = integrand || this.makeEmptyNode_();
- intvar = intvar || this.makeEmptyNode_();
- var newNode = this.makeBranchNode_(cvox.SemanticAttr.Type.INTEGRAL,
- [integral, integrand, intvar], []);
- newNode.role = integral.role;
- return newNode;
-};
-
-
-/**
- * Predicate implementing the boundary criteria for simple functions:
- *
- * @param {!cvox.SemanticTree.Node} node A semantic node of type fenced.
- * @return {boolean} True if the node meets the boundary criteria.
- * @private
- */
-cvox.SemanticTree.prototype.simpleFunctionHeuristic_ = function(node) {
- var children = node.childNodes;
- if (children.length == 0) {
- return true;
- }
- if (children.length > 1) {
- return false;
- }
- var child = children[0];
- if (child.type == cvox.SemanticAttr.Type.INFIXOP) {
- if (child.role != cvox.SemanticAttr.Role.IMPLICIT) {
- return false;
- }
- if (child.childNodes.some(cvox.SemanticTree.attrPred_('type', 'INFIXOP'))) {
- return false;
- }
- }
- return true;
-};
-
-
-/**
- * Predicate implementing the boundary criteria for prefix functions and big
- * operators:
- * 1. an explicit operator,
- * 2. a relation symbol, or
- * 3. some punctuation.
- * @param {cvox.SemanticTree.Node} node A semantic node.
- * @return {boolean} True if the node meets the boundary criteria.
- * @private
- */
-cvox.SemanticTree.prefixFunctionBoundary_ = function(node) {
- return cvox.SemanticTree.attrPred_('type', 'OPERATOR')(node) ||
- cvox.SemanticTree.generalFunctionBoundary_(node);
-};
-
-
-/**
- * Predicate implementing the boundary criteria for integrals dx on two nodes.
- * @param {cvox.SemanticTree.Node} firstNode A semantic node.
- * @param {cvox.SemanticTree.Node} secondNode The direct neighbour of first
- * Node.
- * @return {boolean} True if the second node exists and the first node is a 'd'.
- * @private
- */
-cvox.SemanticTree.integralDxBoundary_ = function(
- firstNode, secondNode) {
- return !!secondNode &&
- cvox.SemanticTree.attrPred_('type', 'IDENTIFIER')(secondNode) &&
- cvox.SemanticAttr.isCharacterD(firstNode.textContent);
-};
-
-
-/**
- * Predicate implementing the boundary criteria for integrals dx on a single
- * node.
- * @param {cvox.SemanticTree.Node} node A semantic node.
- * @return {boolean} True if the node meets the boundary criteria.
- * @private
- */
-cvox.SemanticTree.integralDxBoundarySingle_ = function(node) {
- if (cvox.SemanticTree.attrPred_('type', 'IDENTIFIER')(node)) {
- var firstChar = node.textContent[0];
- return firstChar && node.textContent[1] &&
- cvox.SemanticAttr.isCharacterD(firstChar);
- }
- return false;
-};
-
-
-/**
- * Predicate implementing the general boundary criteria for function operators:
- * 1. a relation symbol,
- * 2. some punctuation.
- * @param {cvox.SemanticTree.Node} node A semantic node.
- * @return {boolean} True if the node meets the boundary criteria.
- * @private
- */
-cvox.SemanticTree.generalFunctionBoundary_ = function(node) {
- return cvox.SemanticTree.attrPred_('type', 'RELATION')(node) ||
- cvox.SemanticTree.attrPred_('type', 'PUNCTUATION')(node);
-};
-
-
-/**
- * Rewrites tables into matrices or case statements in a list of nodes.
- * @param {!Array<cvox.SemanticTree.Node>} nodes List of nodes to rewrite.
- * @return {!Array<cvox.SemanticTree.Node>} The new list of nodes.
- * @private
- */
-cvox.SemanticTree.prototype.processTablesInRow_ = function(nodes) {
- // First we process all matrices:
- var partition = cvox.SemanticTree.partitionNodes_(
- nodes, cvox.SemanticTree.tableIsMatrixOrVector_);
- var result = [];
- for (var i = 0, matrix; matrix = partition.rel[i]; i++) {
- result = result.concat(partition.comp.shift());
- result.push(this.tableToMatrixOrVector_(matrix));
- }
- result = result.concat(partition.comp.shift());
- // Process the remaining tables for cases.
- partition = cvox.SemanticTree.partitionNodes_(
- result, cvox.SemanticTree.isTableOrMultiline_);
- result = [];
- for (var i = 0, table; table = partition.rel[i]; i++) {
- var prevNodes = partition.comp.shift();
- if (cvox.SemanticTree.tableIsCases_(table, prevNodes)) {
- this.tableToCases_(
- table, /** @type {!cvox.SemanticTree.Node} */ (prevNodes.pop()));
- }
- result = result.concat(prevNodes);
- result.push(table);
- }
- return result.concat(partition.comp.shift());
-};
-
-
-/**
- * Decides if a node is a table or multiline element.
- * @param {cvox.SemanticTree.Node} node A node.
- * @return {boolean} True if node is either table or multiline.
- * @private
- */
-cvox.SemanticTree.isTableOrMultiline_ = function(node) {
- return !!node && (cvox.SemanticTree.attrPred_('type', 'TABLE')(node) ||
- cvox.SemanticTree.attrPred_('type', 'MULTILINE')(node));
-};
-
-
-/**
- * Heuristic to decide if we have a matrix: An expression fenced on both sides
- * without any other content is considered a fenced node.
- * @param {cvox.SemanticTree.Node} node A node.
- * @return {boolean} True if we believe we have a matrix.
- * @private
- */
-cvox.SemanticTree.tableIsMatrixOrVector_ = function(node) {
- return !!node && cvox.SemanticTree.attrPred_('type', 'FENCED')(node) &&
- cvox.SemanticTree.attrPred_('role', 'LEFTRIGHT')(node) &&
- node.childNodes.length == 1 &&
- cvox.SemanticTree.isTableOrMultiline_(node.childNodes[0]);
-};
-
-
-/**
- * Replaces a fenced node by a matrix or vector node.
- * @param {!cvox.SemanticTree.Node} node The fenced node to be rewritten.
- * @return {!cvox.SemanticTree.Node} The matrix or vector node.
- * @private
- */
-cvox.SemanticTree.prototype.tableToMatrixOrVector_ = function(node) {
- var matrix = node.childNodes[0];
- var type = cvox.SemanticTree.attrPred_('type', 'MULTILINE')(matrix) ?
- 'VECTOR' : 'MATRIX';
- matrix.type = cvox.SemanticAttr.Type[type];
- node.contentNodes.forEach(goog.bind(matrix.appendContentNode_, matrix));
- for (var i = 0, row; row = matrix.childNodes[i]; i++) {
- cvox.SemanticTree.assignRoleToRow_(row, cvox.SemanticAttr.Role[type]);
- }
- return matrix;
-};
-
-
-/**
- * Heuristic to decide if we have a case statement: An expression with a
- * singular open fence before it.
- * @param {!cvox.SemanticTree.Node} table A table node.
- * @param {!Array<cvox.SemanticTree.Node>} prevNodes A list of previous nodes.
- * @return {boolean} True if we believe we have a case statement.
- * @private
- */
-cvox.SemanticTree.tableIsCases_ = function(table, prevNodes) {
- return prevNodes.length > 0 &&
- cvox.SemanticTree.attrPred_('role', 'OPENFENCE')(
- prevNodes[prevNodes.length - 1]);
-};
-
-
-/**
- * Makes case node out of a table and a fence.
- * @param {!cvox.SemanticTree.Node} table The table containing the cases.
- * @param {!cvox.SemanticTree.Node} openFence The left delimiter of the case
- * statement.
- * @return {!cvox.SemanticTree.Node} The cases node.
- * @private
- */
-cvox.SemanticTree.prototype.tableToCases_ = function(table, openFence) {
- for (var i = 0, row; row = table.childNodes[i]; i++) {
- cvox.SemanticTree.assignRoleToRow_(row, cvox.SemanticAttr.Role.CASES);
- // }
- }
- table.type = cvox.SemanticAttr.Type.CASES;
- table.appendContentNode_(openFence);
- return table;
-};
-
-
-// TODO (sorge) This heuristic is very primitive. We could start reworking
-// multilines, by combining all cells, semantically rewriting the entire line
-// and see if there are any similarities. Alternatively, we could look for
-// similarities in columns (e.g., single relation symbols, like equalities or
-// inequalities in the same column could indicate an equation array).
-/**
- * Heuristic to decide if we have a multiline formula. A table is considered a
- * multiline formula if it does not have any separate cells.
- * @param {!cvox.SemanticTree.Node} table A table node.
- * @return {boolean} True if we believe we have a mulitline formula.
- * @private
- */
-cvox.SemanticTree.tableIsMultiline_ = function(table) {
- return table.childNodes.every(
- function(row) {
- var length = row.childNodes.length;
- return length <= 1;});
-};
-
-
-/**
- * Rewrites a table to multiline structure, simplifying it by getting rid of the
- * cell hierarchy level.
- * @param {!cvox.SemanticTree.Node} table The node to be rewritten a multiline.
- * @private
- */
-cvox.SemanticTree.prototype.tableToMultiline_ = function(table) {
- table.type = cvox.SemanticAttr.Type.MULTILINE;
- for (var i = 0, row; row = table.childNodes[i]; i++) {
- cvox.SemanticTree.rowToLine_(row, cvox.SemanticAttr.Role.MULTILINE);
- }
-};
-
-
-/**
- * Converts a row that only contains one cell into a single line.
- * @param {!cvox.SemanticTree.Node} row The row to convert.
- * @param {cvox.SemanticAttr.Role=} role The new role for the line.
- * @private
- */
-cvox.SemanticTree.rowToLine_ = function(row, role) {
- role = role || cvox.SemanticAttr.Role.UNKNOWN;
- if (cvox.SemanticTree.attrPred_('type', 'ROW')(row) &&
- row.childNodes.length == 1 &&
- cvox.SemanticTree.attrPred_('type', 'CELL')(row.childNodes[0])) {
- row.type = cvox.SemanticAttr.Type.LINE;
- row.role = role;
- row.childNodes = row.childNodes[0].childNodes;
- }
-};
-
-
-/**
- * Assign a row and its contained cells a new role value.
- * @param {!cvox.SemanticTree.Node} row The row to be updated.
- * @param {!cvox.SemanticAttr.Role} role The new role for the row and its cells.
- * @private
- */
-cvox.SemanticTree.assignRoleToRow_ = function(row, role) {
- if (cvox.SemanticTree.attrPred_('type', 'LINE')(row)) {
- row.role = role;
- return;
- }
- if (cvox.SemanticTree.attrPred_('type', 'ROW')(row)) {
- row.role = role;
- var cellPred = cvox.SemanticTree.attrPred_('type', 'CELL');
- row.childNodes.forEach(function(cell) {
- if (cellPred(cell)) {
- cell.role = role;
- }
- });
- }
-};
-
-
-/**
- * Splits a list of nodes wrt. to a given predicate.
- * @param {Array<cvox.SemanticTree.Node>} nodes A list of nodes.
- * @param {!function(cvox.SemanticTree.Node): boolean} pred Predicate for the
- * partitioning relation.
- * @param {boolean=} reverse If true slicing is done from the end.
- * @return {{head: !Array<cvox.SemanticTree.Node>,
- * div: cvox.SemanticTree.Node,
- * tail: !Array<cvox.SemanticTree.Node>}} The split list.
- * @private
- */
-cvox.SemanticTree.sliceNodes_ = function(nodes, pred, reverse) {
- if (reverse) {
- nodes.reverse();
- }
- var head = [];
- for (var i = 0, node; node = nodes[i]; i++) {
- if (pred(node)) {
- if (reverse) {
- return {head: nodes.slice(i + 1).reverse(),
- div: node,
- tail: head.reverse()};
- }
- return {head: head,
- div: node,
- tail: nodes.slice(i + 1)};
- }
- head.push(node);
- }
- if (reverse) {
- return {head: [], div: null, tail: head.reverse()};
- }
- return {head: head, div: null, tail: []};
-};
-
-
-/**
- * Partitions a list of nodes wrt. to a given predicate. Effectively works like
- * a PER on the ordered set of nodes.
- * @param {!Array<!cvox.SemanticTree.Node>} nodes A list of nodes.
- * @param {!function(cvox.SemanticTree.Node): boolean} pred Predicate for the
- * partitioning relation.
- * @return {{rel: !Array<cvox.SemanticTree.Node>,
- * comp: !Array<!Array<cvox.SemanticTree.Node>>}}
- * The partitioning given in terms of a collection of elements satisfying
- * the predicate and a collection of complementary sets lying inbetween the
- * related elements. Observe that we always have |comp| = |rel| + 1.
- *
- * Example: On input [a, r_1, b, c, r_2, d, e, r_3] where P(r_i) holds, we
- * get as output: {rel: [r_1, r_2, r_3], comp: [[a], [b, c], [d, e], []].
- * @private
- */
-cvox.SemanticTree.partitionNodes_ = function(nodes, pred) {
- var restNodes = nodes;
- var rel = [];
- var comp = [];
-
- do {
- var result = cvox.SemanticTree.sliceNodes_(restNodes, pred);
- comp.push(result.head);
- rel.push(result.div);
- restNodes = result.tail;
- } while (result.div);
- rel.pop();
- return {rel: rel, comp: comp};
-};
-
-
-/**
- * Constructs a predicate to check the semantic attribute of a node.
- * @param {!string} prop The property of a node.
- * @param {!string} attr The attribute.
- * @return {function(cvox.SemanticTree.Node): boolean} The predicate.
- * @private
- */
-
-cvox.SemanticTree.attrPred_ = function(prop, attr) {
- var getAttr = function(prop) {
- switch (prop) {
- case 'type': return cvox.SemanticAttr.Type[attr];
- case 'role': return cvox.SemanticAttr.Role[attr];
- case 'font': return cvox.SemanticAttr.Font[attr];
- }
- };
-
- return function(node) {return node[prop] == getAttr(prop);};
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_tree_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_tree_test.unitjs
deleted file mode 100644
index d6948aebd65..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_tree_test.unitjs
+++ /dev/null
@@ -1,6188 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxSemanticTreeUnitTest() {}
-
-CvoxSemanticTreeUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.SemanticAttr',
- 'cvox.SemanticTree',
- 'cvox.SemanticUtil',
- 'cvox.XpathUtil'
- ],
-
- /** @override */
- setUp: function() {
- this.nodeCounter = 0;
- this.xpathBlacklist = [];
- this.brief = true;
- this.setupAttributes();
- },
-
- /**
- * Adds some unicode characters via hex code to the right category.
- *
- * This method is necessary as the test framework can not handle code
- * containing utf-8 encoded characters.
- */
- setupAttributes: function() {
- var attr = cvox.SemanticAttr.getInstance();
- attr.neutralFences.unshift(cvox.SemanticUtil.numberToUnicode(0x00A6));
- attr.dashes.unshift(cvox.SemanticUtil.numberToUnicode(0x2015));
- attr.neutralFences.unshift(cvox.SemanticUtil.numberToUnicode(0x2016));
- attr.arrows.unshift(cvox.SemanticUtil.numberToUnicode(0x2192));
- attr.sumOps.unshift(cvox.SemanticUtil.numberToUnicode(0x2211));
- attr.additions.unshift(cvox.SemanticUtil.numberToUnicode(0x2213));
- attr.multiplications.unshift(cvox.SemanticUtil.numberToUnicode(0x2218));
- attr.intOps.unshift(cvox.SemanticUtil.numberToUnicode(0x222B));
- attr.inequalities.unshift(cvox.SemanticUtil.numberToUnicode(0x2264));
- attr.additions.unshift(cvox.SemanticUtil.numberToUnicode(0x2295));
- var open = cvox.SemanticUtil.numberToUnicode(0x3008);
- var close = cvox.SemanticUtil.numberToUnicode(0x3009);
- attr.openClosePairs[open] = close;
- attr.leftFences.unshift(open);
- attr.rightFences.unshift(close);
- },
-
- /**
- * Removes XML nodes according to the XPath elements in the blacklist.
- * @param {Node} xml Xml representation of the semantic node.
- */
- customizeXml: function(xml) {
- this.xpathBlacklist.forEach(
- function(xpath) {
- var removes = cvox.XpathUtil.evalXPath(xpath, xml);
- removes.forEach(
- function(node) {
- node.parentNode.removeChild(node);
- });
- });
- },
-
- /**
- * Tests if for a given mathml snippet results in a particular semantic tree.
- * @param {string} mml MathML expression.
- * @param {string} sml XML snippet for the semantic tree.
- */
- executeTreeTest: function(mml, sml) {
- var mathMl = '<math id=' + this.nodeCounter + '>' + mml + '';
- this.loadHtml(mathMl);
- var node = document.getElementById((this.nodeCounter++).toString());
- var stree = new cvox.SemanticTree(/** @type {!Element} */(node));
- var sxml = stree.xml(this.brief);
- this.customizeXml(sxml);
- var dp = new DOMParser();
- var xml = dp.parseFromString('<stree>' + sml + '</stree>', 'text/xml');
- var xmls = new XMLSerializer();
- assertEquals(xmls.serializeToString(xml),
- xmls.serializeToString(sxml));
- }
-};
-
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeRelations', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mo>=</mo>',
- '<relation>=</relation>');
- this.executeTreeTest(
- '<mi>a</mi><mo>=</mo><mi>b</mi>',
- '<relseq>=' +
- '<content><relation>=</relation></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</relseq>');
- this.executeTreeTest(
- '<mi>a</mi><mo>=</mo><mi>b</mi><mo>=</mo><mi>c</mi>',
- '<relseq>=' +
- '<content><relation>=</relation><relation>=</relation></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</relseq>');
- this.executeTreeTest(
- '<mi>a</mi><mo>=</mo><mi>b</mi><mo>=</mo><mi>c</mi>' +
- '<mo>\u2264</mo><mi>d</mi>',
- '<multirel>' +
- '<content><relation>=</relation><relation>=</relation>' +
- '<relation>\u2264</relation></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</multirel>');
-});
-
-
-// Operators.
-/**
- * Test operator trees with pre- and postfixes.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrePostfixOperators', function() {
- this.brief = true;
- // Pathological operator only case.
- this.executeTreeTest(
- '<mo>+</mo><mo>-</mo><mo>+</mo>',
- '<prefixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<prefixop>-' +
- '<content><operator>-</operator></content>' +
- '<children>' +
- '<operator>+</operator>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</prefixop>');
- // Single identifier with prefixes.
- this.executeTreeTest(
- '<mo>+</mo><mo>+</mo><mi>a</mi>',
- '<prefixop>+ +' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</prefixop>');
- // Single identifier with prefix and negative.
- this.executeTreeTest(
- '<mo>+</mo><mo>-</mo><mi>a</mi>',
- '<prefixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<prefixop>-' +
- '<content><operator>-</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</prefixop>');
- // Single identifier with postfixes.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mo>-</mo>',
- '<postfixop>+ -' +
- '<content><operator>+</operator><operator>-</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</postfixop>');
- // Single identifier with pre- and postfixes.
- this.executeTreeTest(
- '<mo>+</mo><mo>+</mo><mi>a</mi><mo>+</mo><mo>+</mo>',
- '<postfixop>+ +' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<prefixop>+ +' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</postfixop>');
- // Single identifier with mixed pre- and postfixes.
- this.executeTreeTest(
- '<mo>\u2213</mo><mo>+</mo><mi>a</mi><mo>\u2213</mo><mo>+</mo>',
- '<postfixop>\u2213 +' +
- '<content>' +
- '<operator>\u2213</operator><operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<prefixop>\u2213 +' +
- '<content>' +
- '<operator>\u2213</operator><operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</postfixop>');
- // Two identifiers with pre- and postfixes.
- this.executeTreeTest(
- '<mo>+</mo><mo>+</mo><mi>a</mi><mo>\u2213</mo><mo>+</mo>' +
- '<mi>b</mi><mo>+</mo>',
- '<infixop>\u2213' +
- '<content><operator>\u2213</operator></content>' +
- '<children>' +
- '<prefixop>+ +' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</prefixop>' +
- '<postfixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<prefixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</postfixop>' +
- '</children>' +
- '</infixop>');
- // Three identifiers with pre- and postfixes.
- this.executeTreeTest(
- '<mo>+</mo><mo>+</mo><mi>a</mi><mo>\u2213</mo><mo>+</mo>' +
- '<mi>b</mi><mo>+</mo><mo>\u2213</mo><mi>c</mi><mo>+</mo>',
- '<infixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<infixop>\u2213' +
- '<content><operator>\u2213</operator></content>' +
- '<children>' +
- '<prefixop>+ +' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</prefixop>' +
- '<prefixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</infixop>' +
- '<postfixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<prefixop>\u2213' +
- '<content><operator>\u2213</operator></content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</postfixop>' +
- '</children>' +
- '</infixop>');
-});
-
-
-/**
- * Test operator trees with single operator.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeSingleOperators', function() {
- this.brief = true;
- // Single identifier.
- this.executeTreeTest(
- '<mi>a</mi>',
- '<identifier>a</identifier>');
- // Single implicit node.
- this.executeTreeTest(
- '<mi>a</mi><mi>b</mi>',
- '<infixop>\u2062' +
- '<content><operator>\u2062</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
- // Implicit multi node.
- this.executeTreeTest(
- '<mi>a</mi><mi>b</mi><mi>c</mi>',
- '<infixop>\u2062' +
- '<content><operator>\u2062</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>');
- // Single addition.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mi>b</mi>',
- '<infixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
- // Multi addition.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>c</mi>',
- '<infixop>+' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>');
- // Multi addition with implicit node.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mi>b</mi><mi>c</mi><mo>+</mo><mi>d</mi>',
- '<infixop>+' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<infixop>\u2062' +
- '<content><operator>\u2062</operator></content>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>');
-});
-
-
-/**
- * Test operator trees with multiple operators.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeMultipleOperators', function() {
- this.brief = true;
- // Addition and subtraction.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mi>b</mi><mo>-</mo><mi>c</mi><mo>+</mo><mi>d</mi>',
- '<infixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<infixop>-' +
- '<content><operator>-</operator></content>' +
- '<children>' +
- '<infixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>');
- // Addition and subtraction.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>c</mi><mo>-</mo>' +
- '<mi>d</mi><mo>-</mo><mi>e</mi>',
- '<infixop>-' +
- '<content><operator>-</operator><operator>-</operator></content>' +
- '<children>' +
- '<infixop>+' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '<identifier>d</identifier>' +
- '<identifier>e</identifier>' +
- '</children>' +
- '</infixop>');
- // Addition and explicit multiplication.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mi>b</mi><mo>\u2218</mo><mi>c</mi><mo>+</mo>' +
- '<mi>d</mi>',
- '<infixop>+' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<infixop>\u2218' +
- '<content><operator>\u2218</operator></content>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>');
- // Addition with explicit and implicit multiplication.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mi>b</mi><mo>\u2218</mo><mi>c</mi><mi>d</mi>' +
- '<mo>+</mo><mi>e</mi><mo>\u2218</mo><mi>f</mi>',
- '<infixop>+' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<infixop>\u2218' +
- '<content><operator>\u2218</operator></content>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '<infixop>\u2062' +
- '<content><operator>\u2062</operator></content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</infixop>' +
- '<infixop>\u2218' +
- '<content><operator>\u2218</operator></content>' +
- '<children>' +
- '<identifier>e</identifier>' +
- '<identifier>f</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</infixop>');
- // Two Additions, subtraction plus explicit and implicit multiplication,
- // one prefix and one postfix.
- this.executeTreeTest(
- '<mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>c</mi><mi>d</mi>' +
- '<mo>+</mo><mi>e</mi><mo>\u2218</mo><mi>f</mi><mo>-</mo><mi>g</mi>' +
- '<mo>+</mo><mo>+</mo><mi>h</mi><mo>\u2295</mo><mi>i</mi>' +
- '<mo>\u2295</mo><mi>j</mi><mo>+</mo><mo>+</mo>',
- '<infixop>\u2295' +
- '<content><operator>\u2295</operator>' +
- '<operator>\u2295</operator></content>' +
- '<children>' +
- '<infixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<infixop>-' +
- '<content><operator>-</operator></content>' +
- '<children>' +
- '<infixop>+' +
- '<content><operator>+</operator>' +
- '<operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '<infixop>\u2062' +
- '<content><operator>\u2062</operator></content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '<infixop>\u2218' +
- '<content><operator>\u2218</operator></content>' +
- '<children>' +
- '<identifier>e</identifier>' +
- '<identifier>f</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</infixop>' +
- '<identifier>g</identifier>' +
- '</children>' +
- '</infixop>' +
- '<prefixop>+' +
- '<content><operator>+</operator></content>' +
- '<children>' +
- '<identifier>h</identifier>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</infixop>' +
- '<identifier>i</identifier>' +
- '<postfixop>+ +' +
- '<content><operator>+</operator><operator>+</operator></content>' +
- '<children>' +
- '<identifier>j</identifier>' +
- '</children>' +
- '</postfixop>' +
- '</children>' +
- '</infixop>');
-});
-
-
-// Fences.
-/**
- * Test regular directed fences.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeRegularFences', function() {
- this.brief = true;
- // No fence.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
- // Empty parentheses.
- this.executeTreeTest(
- '<mrow><mo>(</mo><mo>)</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<empty/>' +
- '</children>' +
- '</fenced>');
- // Single Fenced Expression.
- this.executeTreeTest(
- '<mrow><mo>(</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>)</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>');
- // Single Fenced Expression and operators.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>+</mo><mo>(</mo><mi>b</mi><mo>+</mo><mi>c</mi>' +
- '<mo>)</mo><mo>+</mo><mi>d</mi></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>');
- // Parallel Parenthesis.
- this.executeTreeTest(
- '<mrow><mo>(</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>)</mo><mo>(</mo>' +
- '<mi>c</mi><mo>+</mo><mi>d</mi><mo>)</mo></mrow>',
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>');
- // Nested Parenthesis.
- this.executeTreeTest(
- '<mrow><mo>(</mo><mo>(</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>)</mo>' +
- '<mo>(</mo><mi>c</mi><mo>+</mo><mi>d</mi><mo>)</mo><mo>)</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>');
- // Nested parenthesis and brackets.
- this.executeTreeTest(
- '<mrow><mo>(</mo><mo>[</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo>' +
- '<mi>c</mi><mo>]</mo><mo>+</mo><mi>d</mi><mo>)</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>');
- // Nested parenthesis, brackets, braces and superscript operator.
- this.executeTreeTest(
- '<mrow><mo>(</mo><msup><mi>a</mi><mrow><mn>2</mn><mo>[</mo><mi>i</mi>' +
- '<mo>+</mo><mi>n</mi><mo>]</mo></mrow></msup><mo>+</mo><mi>b</mi>' +
- '<mo>)</mo><mo>+</mo><mo>{</mo><mi>c</mi><mi>d</mi><mo>-</mo><mo>[</mo>' +
- '<mi>e</mi><mo>+</mo><mi>f</mi><mo>]</mo><mo>}</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<number>2</number>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>i</identifier>' +
- '<identifier>n</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</superscript>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '<fenced>' +
- '<content>' +
- '<fence>{</fence>' +
- '<fence>}</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>-' +
- '<content>' +
- '<operator>-</operator>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>e</identifier>' +
- '<identifier>f</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>');
-});
-
-
-/**
- * Test neutral fences.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeNeutralFences', function() {
- this.brief = true;
- // Empty bars.
- this.executeTreeTest(
- '<mrow><mo>|</mo><mo>|</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<empty/>' +
- '</children>' +
- '</fenced>');
- // Simple bar fence.
- this.executeTreeTest(
- '<mrow><mo>|</mo><mi>a</mi><mo>|</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</fenced>');
- // Parallel bar fences.
- this.executeTreeTest(
- '<mrow><mo>|</mo><mi>a</mi><mo>|</mo><mi>b</mi><mo>+</mo>' +
- '<mo>\u00A6</mo><mi>c</mi><mo>\u00A6</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</fenced>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '<fenced>' +
- '<content>' +
- '<fence>\u00A6</fence>' +
- '<fence>\u00A6</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>');
- // Nested bar fences.
- this.executeTreeTest(
- '<mrow><mo>\u00A6</mo><mo>|</mo><mi>a</mi><mo>|</mo><mi>b</mi>' +
- '<mo>+</mo><mi>c</mi><mo>\u00A6</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>\u00A6</fence>' +
- '<fence>\u00A6</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</fenced>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>');
-});
-
-
-/**
- * Mixed neutral and regular fences.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeMixedFences', function() {
- this.brief = true;
- // Empty parenthsis inside bars.
- this.executeTreeTest(
- '<mrow><mo>|</mo><mo>(</mo><mo>)</mo><mo>|</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<empty/>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</fenced>');
- // Bars inside parentheses.
- this.executeTreeTest(
- '<mrow><mo>(</mo><mo>|</mo><mi>a</mi><mo>|</mo><mi>b</mi>' +
- '<mo>&#x00A6;</mo><mi>c</mi><mo>&#x00A6;</mo><mi>d</mi>' +
- '<mo>)</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '</children>' +
- '</fenced>' +
- '<identifier>b</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>\u00A6</fence>' +
- '<fence>\u00A6</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</fenced>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>');
- // Parentheses inside bards.
- this.executeTreeTest(
- '<mrow><mo>|</mo><mo>(</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>)</mo>' +
- '<mo>&#x00A6;</mo><mi>c</mi><mo>&#x00A6;</mo><mi>d</mi><mo>|</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '<fenced>' +
- '<content>' +
- '<fence>\u00A6</fence>' +
- '<fence>\u00A6</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</fenced>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>');
- // Parentheses inside bards.
- this.executeTreeTest(
- '<mrow><mo>[</mo><mo>|</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>|</mo>' +
- '<mo>+</mo><mi>c</mi><mo>]</mo><mo>+</mo><mo>\u00A6</mo><mi>d</mi>' +
- '<mo>+</mo><mo>(</mo><mi>e</mi><mo>+</mo><mi>f</mi><mo>)</mo>' +
- '<mo>\u00A6</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '<fenced>' +
- '<content>' +
- '<fence>\u00A6</fence>' +
- '<fence>\u00A6</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>d</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>e</identifier>' +
- '<identifier>f</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>');
-});
-
-
-/**
- * Mixed with isolated bars.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeMixedFencesWithBars', function() {
- this.brief = true;
- this.xpathBlacklist = ['descendant::punctuated/content'];
- // Set notation.
- this.executeTreeTest(
- '<mrow><mo>{</mo><mo>(</mo><mi>x</mi><mo>,</mo><mi>y</mi><mo>,</mo>' +
- '<mi>z</mi><mo>)</mo><mo>|</mo><mi>x</mi><mi>y</mi><mo>=</mo>' +
- '<mo>z</mo><mo>}</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>{</fence>' +
- '<fence>}</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<punctuation>,</punctuation>' +
- '<identifier>y</identifier>' +
- '<punctuation>,</punctuation>' +
- '<identifier>z</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>|</punctuation>' +
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '<identifier>z</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>');
- // Disjunction of bracketed parallel statements.
- this.executeTreeTest(
- '<mrow><mo>[</mo><mi>a</mi><mo>&#x2016;</mo><mi>b</mi><mo>]</mo>' +
- '<mo>|</mo><mo>[</mo><mi>x</mi><mo>&#x2016;</mo><mi>y</mi><mo>]</mo>' +
- '</mrow>',
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>|</punctuation>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</punctuated>'
- );
- // Metric over the above.
- this.executeTreeTest(
- '<mrow><mo>&#x2016;</mo><mo>[</mo><mi>a</mi><mo>&#x2016;</mo>' +
- '<mi>b</mi><mo>]</mo><mo>|</mo><mo>[</mo><mi>x</mi><mo>&#x2016;</mo>' +
- '<mi>y</mi><mo>]</mo><mo>&#x2016;</mo></mrow>',
- '<fenced>' +
- '<content>' +
- '<fence>\u2016</fence>' +
- '<fence>\u2016</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>|</punctuation>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>');
- // Mix of metrics and bracketed expression and single bars.
- this.executeTreeTest(
- '<mrow><mo>&#x2016;</mo><mo>[</mo><mi>a</mi><mo>&#x2016;</mo><mi>b</mi>' +
- '<mo>]</mo><mo>|</mo><mo>[</mo><mi>c</mi><mo>&#x2016;</mo>' +
- '<mo>&#x00A6;</mo><mi>d</mi><mo>]</mo><mo>&#x2016;</mo><mo>[</mo>' +
- '<mi>u</mi><mo>&#x2016;</mo><mi>v</mi><mo>]</mo><mo>|</mo><mi>x</mi>' +
- '<mo>&#x2016;</mo><mi>y</mi><mo>&#x00A6;</mo><mi>z</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>\u2016</fence>' +
- '<fence>\u2016</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>|</punctuation>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>u</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>v</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>' +
- '<punctuation>|</punctuation>' +
- '<identifier>x</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>y</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>z</identifier>' +
- '</children>' +
- '</punctuated>');
- this.xpathBlacklist = [];
-});
-
-
-/**
- * Pathological cases with only opening fences.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeOpeningFencesOnly', function() {
- this.brief = true;
- this.xpathBlacklist = ['descendant::punctuated/content'];
- // Single.
- this.executeTreeTest(
- '<mrow><mo>[</mo></mrow>',
- '<fence>[</fence>');
- // Single right.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>[</mo></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>[</punctuation>' +
- '</children>' +
- '</punctuated>');
- // Single middle.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>[</mo><mi>b</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>[</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>');
- // Single left.
- this.executeTreeTest(
- '<mrow><mo>[</mo><mi>b</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<punctuation>[</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>');
- // Multiple.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>[</mo><mi>b</mi><mi>c</mi><mo>(</mo><mi>d</mi>' +
- '<mo>{</mo><mi>e</mi><mo>&#x3008;</mo><mi>f</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>[</punctuation>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '<punctuation>(</punctuation>' +
- '<identifier>d</identifier>' +
- '<punctuation>{</punctuation>' +
- '<identifier>e</identifier>' +
- '<punctuation>\u3008</punctuation>' +
- '<identifier>f</identifier>' +
- '</children>' +
- '</punctuated>');
- // Multiple plus inner fenced.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>[</mo><mi>b</mi><mo>[</mo><mo>(</mo><mo>(</mo>' +
- '<mi>c</mi><mo>)</mo><mi>d</mi><mo>{</mo><mi>e</mi><mo>&#x3008;</mo>' +
- '<mi>f</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>[</punctuation>' +
- '<identifier>b</identifier>' +
- '<punctuation>[</punctuation>' +
- '<punctuation>(</punctuation>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</fenced>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</infixop>' +
- '<punctuation>{</punctuation>' +
- '<identifier>e</identifier>' +
- '<punctuation>\u3008</punctuation>' +
- '<identifier>f</identifier>' +
- '</children>' +
- '</punctuated>');
- this.xpathBlacklist = [];
-});
-
-
-/**
- * Pathological cases with only closing fences.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeClosingFencesOnly', function() {
- this.brief = true;
- this.xpathBlacklist = ['descendant::punctuated/content'];
- // Single.
- this.executeTreeTest(
- '<mrow><mo>]</mo></mrow>',
- '<fence>]</fence>');
- // Single right.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>]</mo></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>]</punctuation>' +
- '</children>' +
- '</punctuated>');
- // Single middle.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>]</mo><mi>b</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>]</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>');
- // Single left.
- this.executeTreeTest(
- '<mrow><mo>]</mo><mi>b</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<punctuation>]</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>');
- // Multiple.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>]</mo><mi>b</mi><mi>c</mi><mo>)</mo><mi>d</mi>' +
- '<mo>}</mo><mi>e</mi><mo>&#x3009;</mo><mi>f</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>]</punctuation>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</infixop>' +
- '<punctuation>)</punctuation>' +
- '<identifier>d</identifier>' +
- '<punctuation>}</punctuation>' +
- '<identifier>e</identifier>' +
- '<punctuation>\u3009</punctuation>' +
- '<identifier>f</identifier>' +
- '</children>' +
- '</punctuated>');
- // Multiple plus inner fenced.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>]</mo><mi>b</mi><mo>]</mo><mo>(</mo><mi>c</mi>' +
- '<mo>)</mo><mo>)</mo><mi>d</mi><mo>}</mo><mi>e</mi><mo>&#x3009;</mo>' +
- '<mi>f</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>]</punctuation>' +
- '<identifier>b</identifier>' +
- '<punctuation>]</punctuation>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>)</punctuation>' +
- '<identifier>d</identifier>' +
- '<punctuation>}</punctuation>' +
- '<identifier>e</identifier>' +
- '<punctuation>\u3009</punctuation>' +
- '<identifier>f</identifier>' +
- '</children>' +
- '</punctuated>');
- this.xpathBlacklist = [];
-});
-
-
-/**
- * Pathological cases with only neutral fences.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeNeutralFencesOnly', function() {
- this.brief = true;
- this.xpathBlacklist = ['descendant::punctuated/content'];
- // Single.
- this.executeTreeTest(
- '<mrow><mo>|</mo></mrow>',
- '<fence>|</fence>');
- // Single right.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>|</mo></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>|</punctuation>' +
- '</children>' +
- '</punctuated>');
- // Single middle.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>|</mo><mi>b</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>|</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>');
- // Single left.
- this.executeTreeTest(
- '<mrow><mo>|</mo><mi>b</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<punctuation>|</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>');
- // Two different bars.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>|</mo><mi>b</mi><mo>&#x00A6;</mo><mi>c</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>|</punctuation>' +
- '<identifier>b</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</punctuated>');
- // Three different bars.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>&#x2016;</mo><mi>b</mi><mo>|</mo><mi>c</mi>' +
- '<mo>&#x00A6;</mo><mi>d</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '<punctuation>|</punctuation>' +
- '<identifier>c</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</punctuated>');
- // Multiple plus inner fenced.
- this.executeTreeTest(
- '<mrow><mo>&#x2016;</mo><mo>[</mo><mi>a</mi><mo>&#x2016;</mo><mi>b</mi>' +
- '<mo>]</mo><mo>&#x2016;</mo><mo>|</mo><mi>x</mi><mo>&#x2016;</mo>' +
- '<mi>y</mi><mo>&#x00A6;</mo><mi>z</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>\u2016</fence>' +
- '<fence>\u2016</fence>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>|</punctuation>' +
- '<identifier>x</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>y</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>z</identifier>' +
- '</children>' +
- '</punctuated>');
- this.xpathBlacklist = [];
-});
-
-
-/**
- * Pathological cases with mixed fences.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeMixedUnmatchedFences', function() {
- this.brief = true;
- this.xpathBlacklist = ['descendant::punctuated/content'];
- // Close, neutral, open.
- this.executeTreeTest(
- '<mrow><mo>]</mo><mo>&#x2016;</mo><mi>b</mi><mo>|</mo><mi>c</mi>' +
- '<mo>(</mo></mrow>',
- '<punctuated>' +
- '<children>' +
- '<punctuation>]</punctuation>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '<punctuation>|</punctuation>' +
- '<identifier>c</identifier>' +
- '<punctuation>(</punctuation>' +
- '</children>' +
- '</punctuated>');
- // Neutrals and close.
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>&#x2016;</mo><mi>b</mi><mo>|</mo><mi>c</mi>' +
- '<mo>&#x00A6;</mo><mi>d</mi><mo>]</mo><mi>e</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '<punctuation>|</punctuation>' +
- '<identifier>c</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>d</identifier>' +
- '<punctuation>]</punctuation>' +
- '<identifier>e</identifier>' +
- '</children>' +
- '</punctuated>');
- // Neutrals and open.
- this.executeTreeTest(
- '<mrow><mo>[</mo><mi>a</mi><mo>&#x2016;</mo><mi>b</mi><mo>|</mo>' +
- '<mi>c</mi><mo>&#x00A6;</mo><mi>d</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<punctuation>[</punctuation>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '<punctuation>|</punctuation>' +
- '<identifier>c</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</punctuated>');
- // Multiple fences, fenced and operations
- this.executeTreeTest(
- '<mrow><mo>&#x2016;</mo><mo>[</mo><mi>a</mi><mo>&#x2016;</mo><mi>b</mi>' +
- '<mo>]</mo><mo>|</mo><mo>[</mo><mi>c</mi><mo>&#x2016;</mo>' +
- '<mo>&#x00A6;</mo><mi>d</mi><mo>]</mo><mo>&#x2016;</mo><mo>|</mo>' +
- '<mi>x</mi><mo>&#x2016;</mo><mi>y</mi><mo>&#x00A6;</mo><mi>z</mi>' +
- '<mo>]</mo></mrow>',
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>\u2016</fence>' +
- '<fence>\u2016</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>|</punctuation>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>c</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>d</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>|</punctuation>' +
- '<identifier>x</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>y</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>z</identifier>' +
- '<punctuation>]</punctuation>' +
- '</children>' +
- '</punctuated>');
- // Multiple fences, fenced and operations
- this.executeTreeTest(
- '<mrow><mo>&#x2016;</mo><mo>]</mo><mo>&#x00A6;</mo><mo>&#x2016;</mo>' +
- '<mo>[</mo><mo>|</mo><mo>[</mo><mi>a</mi><mo>&#x2016;</mo><mi>b</mi>' +
- '<mo>]</mo><mo>&#x2016;</mo><mo>|</mo><mi>[</mi><mo>&#x2016;</mo>' +
- '<mi>y</mi><mo>&#x00A6;</mo><mi>z</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>\u2016</fence>' +
- '<fence>\u2016</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<punctuation>]</punctuation>' +
- '<punctuation>\u00A6</punctuation>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>[</punctuation>' +
- '<fenced>' +
- '<content>' +
- '<fence>|</fence>' +
- '<fence>|</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>\u2016</punctuation>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '<punctuation>[</punctuation>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>y</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<identifier>z</identifier>' +
- '</children>' +
- '</punctuated>');
- // Multiple fences, fenced and operations
- this.executeTreeTest(
- '<mrow><mo>&#x2016;</mo><mo>[</mo><mi>a</mi><mo>&#x00A6;</mo>' +
- '<mo>&#x2016;</mo><mo>[</mo><mo>+</mo><mo>[</mo><mi>b</mi>' +
- '<mo>&#x2016;</mo><mi>c</mi><mo>]</mo><mo>+</mo><mo>&#x2016;</mo>' +
- '<mo>|</mo><mi>d</mi><mo>+</mo><mi>e</mi><mi>[</mi><mo>&#x2016;</mo>' +
- '<mi>y</mi><mo>&#x00A6;</mo><mo>+</mo><mi>z</mi></mrow>',
- '<punctuated>' +
- '<children>' +
- '<punctuation>\u2016</punctuation>' +
- '<punctuation>[</punctuation>' +
- '<identifier>a</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<punctuation>\u2016</punctuation>' +
- '<punctuation>[</punctuation>' +
- '<postfixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<prefixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<children>' +
- '<identifier>b</identifier>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>c</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</postfixop>' +
- '<punctuation>\u2016</punctuation>' +
- '<punctuation>|</punctuation>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>d</identifier>' +
- '<identifier>e</identifier>' +
- '</children>' +
- '</infixop>' +
- '<punctuation>[</punctuation>' +
- '<punctuation>\u2016</punctuation>' +
- '<identifier>y</identifier>' +
- '<punctuation>\u00A6</punctuation>' +
- '<prefixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>z</identifier>' +
- '</children>' +
- '</prefixop>' +
- '</children>' +
- '</punctuated>');
- this.xpathBlacklist = [];
-});
-
-
-/**
- * Simple function applications
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeSimpleFuncsSingle', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mi>f</mi></mrow>',
- '<identifier>f</identifier>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mi>y</mi><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>,</mo><mi>y</mi>' +
- '<mo>,</mo><mi>z</mi><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<punctuated>' +
- '<content>' +
- '<punctuation>,</punctuation>' +
- '<punctuation>,</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<punctuation>,</punctuation>' +
- '<identifier>y</identifier>' +
- '<punctuation>,</punctuation>' +
- '<identifier>z</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><msup><mi>x</mi><mn>2</mn></msup>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><msub><mi>x</mi><mn>2</mn></msub>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><msubsup><mi>x</mi><mn>2</mn>' +
- '<mn>1</mn></msubsup><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '<number>1</number>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mover><mi>x</mi><mn>2</mn></mover>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<overscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</overscore>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><munder><mi>x</mi><mn>2</mn></munder>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<underscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</underscore>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><munderover><mi>x</mi><mn>2</mn>' +
- '<mn>1</mn></munderover><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<overscore>' +
- '<children>' +
- '<underscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</underscore>' +
- '<number>1</number>' +
- '</children>' +
- '</overscore>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<fraction>' +
- '<children>' +
- '<number>1</number>' +
- '<number>2</number>' +
- '</children>' +
- '</fraction>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>+</mo><mi>y</mi>' +
- '<mo>)</mo></mrow>',
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>');
-});
-
-
-/**
- * Simple functions with surrounding operators.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeSimpleFuncsWithOps', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mn>1</mn><mo>+</mo><mi>f</mi><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<number>1</number>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo>' +
- '<mn>2</mn></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<number>2</number>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mn>1</mn><mo>+</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mo>+</mo><mn>2</mn></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<number>1</number>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<number>2</number>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>+</mo><mi>f</mi><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo>' +
- '<mo>b</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>+</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mo>+</mo><mo>b</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>=</mo><mi>f</mi><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo>' +
- '<mo>b</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>=</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mo>=</mo><mo>b</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Multiple simple functions.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeSimpleFuncsMulti', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo><mi>g</mi>' +
- '<mo>(</mo><mi>x</mi><mo>)</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>g</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo><mi>g</mi>' +
- '<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mi>h</mi><mo>(</mo>' +
- '<mi>x</mi><mo>)</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>g</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>h</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo><mi>g</mi>' +
- '<mo>(</mo><mi>y</mi><mo>)</mo><mo>=</mo><mi>h</mi><mo>(</mo>' +
- '<mi>x</mi><mi>y</mi><mo>)</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>g</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>h</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Nested simple functions.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeSimpleFuncsNested', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mi>g</mi><mo>(</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>g</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>h</mi><mo>(</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mi>g</mi><mo>(</mo><mi>y</mi><mo>)</mo><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>h</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>g</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>h</mi><mo>(</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mo>+</mo><mi>g</mi><mo>(</mo><mi>y</mi><mo>)</mo><mo>)</mo></mrow>',
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>h</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>g</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mi>P</mi><mo>[</mo><mi>x</mi><mo>=</mo><mn>2</mn><mo>]</mo>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>P</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>[</fence>' +
- '<fence>]</fence>' +
- '</content>' +
- '<children>' +
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-});
-
-
-/**
- * Simple functions with explicit function application.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeSimpleFuncsExplicitApp', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mi>f</mi><mo>\u2061</mo><mo>(</mo><mi>x</mi><mo>+</mo><mi>y</mi>' +
- '<mo>)</mo>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mi>f</mi><mo>\u2061</mo><mo>(</mo><mi>x</mi><mo>+</mo><mi>y</mi>' +
- '<mo>)</mo><mo>+</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>+</mo>' +
- '<mi>y</mi><mo>)</mo>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<msub><mi>f</mi><mn>1</mn></msub><mo>\u2061</mo><mo>(</mo><mi>x</mi>' +
- '<mo>+</mo><mi>y</mi><mo>)</mo>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<number>1</number>' +
- '</children>' +
- '</subscript>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<msup><msub><mi>f</mi><mn>n</mn></msub><mn>2</mn></msup>' +
- '<mo>\u2061</mo><mo>(</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo>)</mo>' +
- '<mo>+</mo><msup><msub><mi>f</mi><mn>m</mn></msub><mn>2</mn></msup>' +
- '<mo>(</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo>)</mo>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<identifier>n</identifier>' +
- '</children>' +
- '</subscript>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<identifier>f</identifier>' +
- '<identifier>m</identifier>' +
- '</children>' +
- '</subscript>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</infixop>');
-});
-
-
-/**
- * Prefix function applications
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsSingle', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mi>y</mi><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><msup><mi>x</mi><mn>2</mn></msup>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><msub><mi>x</mi><mn>2</mn></msub>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><msubsup><mi>x</mi><mn>2</mn>' +
- '<mn>1</mn></msubsup><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '<number>1</number>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mover><mi>x</mi><mn>2</mn></mover>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<overscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</overscore>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><munder><mi>x</mi><mn>2</mn></munder>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<underscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</underscore>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><munderover><mi>x</mi><mn>2</mn>' +
- '<mn>1</mn></munderover><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<overscore>' +
- '<children>' +
- '<underscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</underscore>' +
- '<number>1</number>' +
- '</children>' +
- '</overscore>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<fraction>' +
- '<children>' +
- '<number>1</number>' +
- '<number>2</number>' +
- '</children>' +
- '</fraction>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mo>+</mo><mi>y</mi>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-});
-
-
-/**
- * Prefix functions applications with surrounding operators.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsWithOps', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mn>1</mn><mo>+</mo><mi>sin</mi><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<number>1</number>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo>' +
- '<mn>2</mn></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<number>2</number>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mn>1</mn><mo>+</mo><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mo>+</mo><mn>2</mn></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<number>1</number>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<number>2</number>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>+</mo><mi>sin</mi><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo>' +
- '<mo>b</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>+</mo><mi>sin</mi><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo><mo>+</mo><mo>b</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>=</mo><mi>sin</mi><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo>' +
- '<mo>b</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>=</mo><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mo>=</mo><mo>b</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Multiple prefix function applications.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsMulti', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo><mi>cos</mi>' +
- '<mo>(</mo><mi>x</mi><mo>)</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>cos</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo><mi>cos</mi>' +
- '<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mi>tan</mi><mo>(</mo>' +
- '<mi>x</mi><mo>)</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>cos</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>tan</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo><mi>cos</mi>' +
- '<mo>(</mo><mi>y</mi><mo>)</mo><mo>=</mo><mi>tan</mi><mo>(</mo>' +
- '<mi>x</mi><mi>y</mi><mo>)</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>cos</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>tan</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Prefix function applications with sub- and superscripts.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsScripts', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><msup><mi>sin</mi><mn>2</mn></msup><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><msub><mi>sin</mi><mn>1</mn></msub><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>1</number>' +
- '</children>' +
- '</subscript>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><msubsup><mi>sin</mi><mn>2</mn><mn>1</mn></msubsup><mo>(</mo>' +
- '<mi>x</mi><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '<number>1</number>' +
- '</children>' +
- '</superscript>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><msup><mi>sin</mi><mn>2</mn></msup><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo><mo>+</mo><msup><mi>cos</mi><mn>2</mn></msup><mo>(</mo>' +
- '<mi>y</mi><mo>)</mo><mo>=</mo><mn>1</mn></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>cos</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<number>1</number>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Prefix function applications with unfenced arguments.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsUnfenced', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mi>x</mi></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mi>x</mi><mi>y</mi></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><msup><mi>x</mi><mn>2</mn></msup></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<superscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><msub><mi>x</mi><mn>2</mn></msub></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<subscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><msubsup><mi>x</mi><mn>2</mn><mn>1</mn>' +
- '</msubsup></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '<number>1</number>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mover><mi>x</mi><mn>2</mn></mover></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<overscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</overscore>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><munder><mi>x</mi><mn>2</mn></munder></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<underscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</underscore>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><munderover><mi>x</mi><mn>2</mn><mn>1</mn>' +
- '</munderover></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<overscore>' +
- '<children>' +
- '<underscore>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</underscore>' +
- '<number>1</number>' +
- '</children>' +
- '</overscore>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mfrac><mn>1</mn><mn>2</mn></mfrac></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fraction>' +
- '<children>' +
- '<number>1</number>' +
- '<number>2</number>' +
- '</children>' +
- '</fraction>' +
- '</children>' +
- '</appl>');
-});
-
-
-/**
- * Prefix function applications with unfenced arguments in an operator
- * expression.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsUnfencedOps', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mn>1</mn><mo>+</mo><mi>sin</mi><mi>x</mi></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<number>1</number>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mi>x</mi><mo>+</mo><mn>2</mn></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<number>2</number>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mn>1</mn><mo>+</mo><mi>sin</mi><mi>x</mi><mo>+</mo>' +
- '<mn>2</mn></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<number>1</number>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<number>2</number>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>+</mo><mi>sin</mi><mi>x</mi></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mi>x</mi><mo>+</mo><mo>b</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>+</mo><mi>sin</mi><mi>x</mi><mo>+</mo>' +
- '<mo>b</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>=</mo><mi>sin</mi><mi>x</mi></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mi>x</mi><mo>=</mo><mo>b</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mo>a</mo><mo>=</mo><mi>sin</mi><mi>x</mi><mo>=</mo>' +
- '<mo>b</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Multiple prefix function applications with unfenced arguments.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsMultiUnfenced', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mi>x</mi><mo>+</mo><mi>cos</mi><mi>x</mi></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>cos</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mi>x</mi><mo>+</mo><mi>cos</mi><mi>x</mi><mo>=</mo>' +
- '<mi>tan</mi><mi>x</mi></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>cos</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>tan</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mi>x</mi><mo>+</mo><mi>cos</mi><mi>y</mi><mo>=</mo>' +
- '<mi>tan</mi><mi>x</mi><mi>y</mi></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>cos</function>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>tan</function>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Prefix function applications with sub- and superscripts and unfenced
- * arguments.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsScriptUnfenced',
- function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><msup><mi>sin</mi><mn>2</mn></msup><mi>x</mi></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><msub><mi>sin</mi><mn>1</mn></msub><mi>x</mi></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>1</number>' +
- '</children>' +
- '</subscript>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><msubsup><mi>sin</mi><mn>2</mn><mn>1</mn></msubsup>' +
- '<mi>x</mi></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '<number>1</number>' +
- '</children>' +
- '</superscript>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><msup><mi>sin</mi><mn>2</mn></msup><mi>x</mi><mo>+</mo><msup>' +
- '<mi>cos</mi><mn>2</mn></msup><mi>y</mi><mo>=</mo><mn>1</mn></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>cos</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<number>1</number>' +
- '</children>' +
- '</relseq>');
- this.executeTreeTest(
- '<mrow><msubsup><msubsup><mi>sin</mi><mn>2</mn><mn>1</mn>' +
- '</msubsup><mi>n</mi><mi>m</mi></msubsup><mi>x</mi></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<subscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</subscript>' +
- '<number>1</number>' +
- '</children>' +
- '</superscript>' +
- '<identifier>n</identifier>' +
- '</children>' +
- '</subscript>' +
- '<identifier>m</identifier>' +
- '</children>' +
- '</superscript>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>');
-});
-
-
-/**
- * Prefix functions without arguments.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsNoArgs', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mi>sin</mi>',
- '<function>sin</function>');
-
- this.executeTreeTest(
- '<msup><mi>sin</mi><mn>2</mn></msup>',
- '<superscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>');
-
- this.executeTreeTest(
- '<msup><mi>sin</mi><mn>2</mn></msup><mo>+</mo><msup><mi>cos</mi>' +
- '<mn>2</mn></msup>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<empty/>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>cos</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<empty/>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><msup><mi>sin</mi><mn>2</mn></msup><mo>+</mo>' +
- '<msup><mi>cos</mi><mn>2</mn></msup><mo>=</mo><mn>1</mn></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>sin</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<empty/>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<superscript>' +
- '<children>' +
- '<function>cos</function>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '<empty/>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<number>1</number>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mi>sin</mi><mo>=</mo><mfrac><mn>1</mn>' +
- '<mi>csc</mi></mfrac></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<empty/>' +
- '</children>' +
- '</appl>' +
- '<fraction>' +
- '<children>' +
- '<number>1</number>' +
- '<function>csc</function>' +
- '</children>' +
- '</fraction>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Nested prefix function applications, both with and without fenced arguments.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreePrefixFuncsNested', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><mi>log</mi><mi>cos</mi><mi>x</mi></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>log</function>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>cos</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>ln</mi><mo>' +
- '(</mo><mi>sin</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>ln</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>log</mi><mi>cos</mi><mi>x</mi><mo>=' +
- '</mo><mi>ln</mi><mo>(</mo><mi>sin</mi><mo>' +
- '(</mo><mi>x</mi><mo>)</mo><mo>)</mo></mrow>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>log</function>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>cos</function>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>ln</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>sin</function>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Variations of tables representing matrices, vectors, case statements,
- * multiline equations and regular tables.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeTables', function() {
- this.brief = false;
- this.executeTreeTest(
- '<mrow class="MJX-TeXAtom-ORD"><mi mathvariant="bold">A</mi>' +
- '<mo>=</mo><mo>[</mo><mtable rowspacing="4pt" columnspacing="1em">' +
- '<mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr><mtr><mtd>' +
- '<mn>2</mn></mtd><mtd><mn>3</mn></mtd></mtr></mtable><mo>]</mo>' +
- '</mrow>',
- '<relseq role="equality" id="16">=' +
- '<content>' +
- '<relation role="equality" id="1">=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="bold" id="0">A</identifier>' +
- '<matrix role="unknown" id="13">' +
- '<content>' +
- '<fence role="open" id="2">[</fence>' +
- '<fence role="close" id="14">]</fence>' +
- '</content>' +
- '<children>' +
- '<row role="matrix" id="7">' +
- '<children>' +
- '<cell role="matrix" id="4">' +
- '<children>' +
- '<number role="integer" font="normal" id="3">0</number>' +
- '</children>' +
- '</cell>' +
- '<cell role="matrix" id="6">' +
- '<children>' +
- '<number role="integer" font="normal" id="5">1</number>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '<row role="matrix" id="12">' +
- '<children>' +
- '<cell role="matrix" id="9">' +
- '<children>' +
- '<number role="integer" font="normal" id="8">2</number>' +
- '</children>' +
- '</cell>' +
- '<cell role="matrix" id="11">' +
- '<children>' +
- '<number role="integer" font="normal" id="10">3</number>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '</children>' +
- '</matrix>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mo>[</mo><mtable rowspacing="4pt" columnspacing="1em"><mtr>' +
- '<mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr><mtr><mtd>' +
- '<mn>2</mn></mtd><mtd><mn>3</mn></mtd></mtr></mtable>' +
- '<mo>]</mo>',
- '<matrix role="unknown" id="11">' +
- '<content>' +
- '<fence role="open" id="0">[</fence>' +
- '<fence role="close" id="12">]</fence>' +
- '</content>' +
- '<children>' +
- '<row role="matrix" id="5">' +
- '<children>' +
- '<cell role="matrix" id="2">' +
- '<children>' +
- '<number role="integer" font="normal" id="1">0</number>' +
- '</children>' +
- '</cell>' +
- '<cell role="matrix" id="4">' +
- '<children>' +
- '<number role="integer" font="normal" id="3">1</number>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '<row role="matrix" id="10">' +
- '<children>' +
- '<cell role="matrix" id="7">' +
- '<children>' +
- '<number role="integer" font="normal" id="6">2</number>' +
- '</children>' +
- '</cell>' +
- '<cell role="matrix" id="9">' +
- '<children>' +
- '<number role="integer" font="normal" id="8">3</number>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '</children>' +
- '</matrix>');
-
- this.executeTreeTest(
- '<mrow class="MJX-TeXAtom-ORD"><mi mathvariant="bold">V</mi>' +
- '<mo>=</mo><mo>[</mo><mtable rowspacing="4pt" columnspacing="1em">' +
- '<mtr><mtd><mn>1</mn></mtd></mtr><mtr><mtd><mn>2</mn></mtd></mtr>' +
- '<mtr><mtd><mn>3</mn></mtd></mtr></mtable><mo>]</mo></mrow>',
- '<relseq role="equality" id="15">=' +
- '<content>' +
- '<relation role="equality" id="1">=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="bold" id="0">V</identifier>' +
- '<vector role="unknown" id="12">' +
- '<content>' +
- '<fence role="open" id="2">[</fence>' +
- '<fence role="close" id="13">]</fence>' +
- '</content>' +
- '<children>' +
- '<line role="vector" id="5">' +
- '<children>' +
- '<number role="integer" font="normal" id="3">1</number>' +
- '</children>' +
- '</line>' +
- '<line role="vector" id="8">' +
- '<children>' +
- '<number role="integer" font="normal" id="6">2</number>' +
- '</children>' +
- '</line>' +
- '<line role="vector" id="11">' +
- '<children>' +
- '<number role="integer" font="normal" id="9">3</number>' +
- '</children>' +
- '</line>' +
- '</children>' +
- '</vector>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mo>[</mo><mtable rowspacing="4pt" columnspacing="1em">' +
- '<mtr><mtd><mn>1</mn></mtd></mtr><mtr><mtd><mn>2</mn></mtd></mtr>' +
- '<mtr><mtd><mn>3</mn></mtd></mtr></mtable><mo>]</mo>',
- '<vector role="unknown" id="10">' +
- '<content>' +
- '<fence role="open" id="0">[</fence>' +
- '<fence role="close" id="11">]</fence>' +
- '</content>' +
- '<children>' +
- '<line role="vector" id="3">' +
- '<children>' +
- '<number role="integer" font="normal" id="1">1</number>' +
- '</children>' +
- '</line>' +
- '<line role="vector" id="6">' +
- '<children>' +
- '<number role="integer" font="normal" id="4">2</number>' +
- '</children>' +
- '</line>' +
- '<line role="vector" id="9">' +
- '<children>' +
- '<number role="integer" font="normal" id="7">3</number>' +
- '</children>' +
- '</line>' +
- '</children>' +
- '</vector>');
-
-
- this.executeTreeTest(
- '<mrow><mo>{</mo><mtable><mtr><mtd><mi>a</mi></mtd><mtd>' +
- '<mtext>often</mtext></mtd></mtr><mtr><mtd><mi>b</mi></mtd>' +
- '<mtd><mtext>sometimes</mtext></mtd></mtr></mtable></mrow>',
- '<cases role="unknown" id="11">' +
- '<content>' +
- '<punctuation role="openfence" id="0">{</punctuation>' +
- '</content>' +
- '<children>' +
- '<row role="cases" id="5">' +
- '<children>' +
- '<cell role="cases" id="2">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="1">a</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="cases" id="4">' +
- '<children>' +
- '<text role="unknown" id="3">often</text>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '<row role="cases" id="10">' +
- '<children>' +
- '<cell role="cases" id="7">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="6">b</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="cases" id="9">' +
- '<children>' +
- '<text role="unknown" id="8">sometimes</text>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '</children>' +
- '</cases>');
-
- this.executeTreeTest(
- '<mrow><mi mathvariant="bold">A</mi><mo>=</mo><mo>{</mo><mtable>' +
- '<mtr><mtd><mi>a</mi></mtd><mtd><mtext>often</mtext></mtd></mtr>' +
- '<mtr><mtd><mi>b</mi></mtd><mtd><mtext>sometimes</mtext></mtd></mtr>' +
- '</mtable></mrow>',
- '<relseq role="equality" id="14">=' +
- '<content>' +
- '<relation role="equality" id="1">=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="bold" id="0">A</identifier>' +
- '<cases role="unknown" id="13">' +
- '<content>' +
- '<punctuation role="openfence" id="2">{</punctuation>' +
- '</content>' +
- '<children>' +
- '<row role="cases" id="7">' +
- '<children>' +
- '<cell role="cases" id="4">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="3">a</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="cases" id="6">' +
- '<children>' +
- '<text role="unknown" id="5">often</text>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '<row role="cases" id="12">' +
- '<children>' +
- '<cell role="cases" id="9">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="8">b</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="cases" id="11">' +
- '<children>' +
- '<text role="unknown" id="10">sometimes</text>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '</children>' +
- '</cases>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mrow><mo>{</mo><mtable><mtr><mtd><mi>a</mi></mtd><mtd>' +
- '<mtext>often</mtext></mtd></mtr><mtr><mtd><mi>b</mi></mtd><mtd>' +
- '<mtext>sometimes</mtext></mtd></mtr></mtable><mo>.</mo></mrow>',
- '<punctuated role="endpunct" id="13">' +
- '<content>' +
- '<punctuation role="fullstop" id="12">.</punctuation>' +
- '</content>' +
- '<children>' +
- '<cases role="unknown" id="11">' +
- '<content>' +
- '<punctuation role="openfence" id="0">{</punctuation>' +
- '</content>' +
- '<children>' +
- '<row role="cases" id="5">' +
- '<children>' +
- '<cell role="cases" id="2">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="1">a</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="cases" id="4">' +
- '<children>' +
- '<text role="unknown" id="3">often</text>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '<row role="cases" id="10">' +
- '<children>' +
- '<cell role="cases" id="7">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="6">b</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="cases" id="9">' +
- '<children>' +
- '<text role="unknown" id="8">sometimes</text>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '</children>' +
- '</cases>' +
- '<punctuation role="fullstop" id="12">.</punctuation>' +
- '</children>' +
- '</punctuated>');
-
- this.executeTreeTest(
- '<mrow><mo>{</mo><mtable><mtr><mtd><mi>a</mi></mtd>' +
- '<mtd><mtext>often</mtext></mtd></mtr><mtr><mtd><mi>b</mi></mtd>' +
- '<mtd><mtext>sometimes</mtext></mtd></mtr></mtable>' +
- '<mo>,</mo><mi>b</mi><mo>,</mo><mi>c</mi><mo>.</mo></mrow>',
- '<punctuated role="sequence" id="17">' +
- '<content>' +
- '<punctuation role="unknown" id="12">,</punctuation>' +
- '<punctuation role="unknown" id="14">,</punctuation>' +
- '<punctuation role="fullstop" id="16">.</punctuation>' +
- '</content>' +
- '<children>' +
- '<cases role="unknown" id="11">' +
- '<content>' +
- '<punctuation role="openfence" id="0">{</punctuation>' +
- '</content>' +
- '<children>' +
- '<row role="cases" id="5">' +
- '<children>' +
- '<cell role="cases" id="2">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="1">a</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="cases" id="4">' +
- '<children>' +
- '<text role="unknown" id="3">often</text>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '<row role="cases" id="10">' +
- '<children>' +
- '<cell role="cases" id="7">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="6">b</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="cases" id="9">' +
- '<children>' +
- '<text role="unknown" id="8">sometimes</text>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '</children>' +
- '</cases>' +
- '<punctuation role="unknown" id="12">,</punctuation>' +
- '<identifier role="latinletter" font="normal" id="13">b</identifier>' +
- '<punctuation role="unknown" id="14">,</punctuation>' +
- '<identifier role="latinletter" font="normal" id="15">c</identifier>' +
- '<punctuation role="fullstop" id="16">.</punctuation>' +
- '</children>' +
- '</punctuated>');
-
- this.executeTreeTest(
- '<mrow><mo>{</mo><mtable><mtr><mtd><mi>a</mi><mo>,</mo>' +
- '<mtext>often</mtext></mtd></mtr><mtr><mtd><mi>b</mi><mo>,</mo>' +
- '<mtext>sometimes</mtext></mtd></mtr></mtable><mo>,</mo><mi>b</mi>' +
- '<mo>,</mo><mi>c</mi><mo>.</mo></mrow>',
- '<punctuated role="sequence" id="19">' +
- '<content>' +
- '<punctuation role="unknown" id="14">,</punctuation>' +
- '<punctuation role="unknown" id="16">,</punctuation>' +
- '<punctuation role="fullstop" id="18">.</punctuation>' +
- '</content>' +
- '<children>' +
- '<cases role="unknown" id="13">' +
- '<content>' +
- '<punctuation role="openfence" id="0">{</punctuation>' +
- '</content>' +
- '<children>' +
- '<line role="cases" id="6">' +
- '<children>' +
- '<punctuated role="sequence" id="4">' +
- '<content>' +
- '<punctuation role="unknown" id="2">,</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="1">a</identifier>' +
- '<punctuation role="unknown" id="2">,</punctuation>' +
- '<text role="unknown" id="3">often</text>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</line>' +
- '<line role="cases" id="12">' +
- '<children>' +
- '<punctuated role="sequence" id="10">' +
- '<content>' +
- '<punctuation role="unknown" id="8">,</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="7">b</identifier>' +
- '<punctuation role="unknown" id="8">,</punctuation>' +
- '<text role="unknown" id="9">sometimes</text>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</line>' +
- '</children>' +
- '</cases>' +
- '<punctuation role="unknown" id="14">,</punctuation>' +
- '<identifier role="latinletter" font="normal" id="15">b</identifier>' +
- '<punctuation role="unknown" id="16">,</punctuation>' +
- '<identifier role="latinletter" font="normal" id="17">c</identifier>' +
- '<punctuation role="fullstop" id="18">.</punctuation>' +
- '</children>' +
- '</punctuated>');
-
- this.executeTreeTest(
- '<mtable><mtr><mtd><mi>x</mi><maligngroup/><mo>=</mo><mn>4</mn>' +
- '</mtd></mtr><mtr><mtd><mi>y</mi><maligngroup/><mo>=</mo><mn>2</mn>' +
- '</mtd></mtr><mtr><mtd><mi>x</mi><mi>y</mi><maligngroup/><mo>=</mo>' +
- '<mn>6</mn></mtd></mtr></mtable>',
- '<multiline role="unknown" id="21">' +
- '<children>' +
- '<line role="multiline" id="5">' +
- '<children>' +
- '<relseq role="equality" id="3">=' +
- '<content>' +
- '<relation role="equality" id="1">=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="0">x</identifier>' +
- '<number role="integer" font="normal" id="2">4</number>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</line>' +
- '<line role="multiline" id="11">' +
- '<children>' +
- '<relseq role="equality" id="9">=' +
- '<content>' +
- '<relation role="equality" id="7">=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="6">y</identifier>' +
- '<number role="integer" font="normal" id="8">2</number>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</line>' +
- '<line role="multiline" id="20">' +
- '<children>' +
- '<relseq role="equality" id="18">=' +
- '<content>' +
- '<relation role="equality" id="14">=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop role="implicit" id="17">\u2062' +
- '<content>' +
- '<operator role="multiplication" id="16">\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="12">x</identifier>' +
- '<identifier role="latinletter" font="normal" id="13">y</identifier>' +
- '</children>' +
- '</infixop>' +
- '<number role="integer" font="normal" id="15">6</number>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</line>' +
- '</children>' +
- '</multiline>');
-
- this.executeTreeTest(
- '<mtable><mtr><mtd><mi>x</mi></mtd><mtd><mo>=</mo></mtd><mtd><mn>4</mn>' +
- '</mtd></mtr><mtr><mtd><mi>y</mi></mtd><mtd><mo>=</mo></mtd><mtd>' +
- '<mn>2</mn></mtd></mtr><mtr><mtd><mi>x</mi><mi>y</mi></mtd><mtd>' +
- '<mo>=</mo></mtd><mtd><mn>6</mn></mtd></mtr></mtable>',
- '<table role="unknown" id="24">' +
- '<children>' +
- '<row role="table" id="6">' +
- '<children>' +
- '<cell role="table" id="1">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="0">x</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="table" id="3">' +
- '<children>' +
- '<relation role="equality" id="2">=</relation>' +
- '</children>' +
- '</cell>' +
- '<cell role="table" id="5">' +
- '<children>' +
- '<number role="integer" font="normal" id="4">4</number>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '<row role="table" id="13">' +
- '<children>' +
- '<cell role="table" id="8">' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="7">y</identifier>' +
- '</children>' +
- '</cell>' +
- '<cell role="table" id="10">' +
- '<children>' +
- '<relation role="equality" id="9">=</relation>' +
- '</children>' +
- '</cell>' +
- '<cell role="table" id="12">' +
- '<children>' +
- '<number role="integer" font="normal" id="11">2</number>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '<row role="table" id="23">' +
- '<children>' +
- '<cell role="table" id="18">' +
- '<children>' +
- '<infixop role="implicit" id="17">\u2062' +
- '<content>' +
- '<operator role="multiplication" id="16">\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<identifier role="latinletter" font="normal" id="14">x</identifier>' +
- '<identifier role="latinletter" font="normal" id="15">y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</cell>' +
- '<cell role="table" id="20">' +
- '<children>' +
- '<relation role="equality" id="19">=</relation>' +
- '</children>' +
- '</cell>' +
- '<cell role="table" id="22">' +
- '<children>' +
- '<number role="integer" font="normal" id="21">6</number>' +
- '</children>' +
- '</cell>' +
- '</children>' +
- '</row>' +
- '</children>' +
- '</table>');
-});
-
-
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeLimitFunctions', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><munder><mi>lim</mi><mrow><mi>x</mi><mo>\u2192</mo>' +
- '<mi>\u221E</mi></mrow></munder><mo>(</mo><mi>x</mi><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<function>lim</function>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>+</mo><munder><mi>lim</mi><mrow><mi>x</mi>' +
- '<mo>\u2192</mo><mi>\u221E</mi></mrow></munder><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo><mo>+</mo><mi>b</mi></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<function>lim</function>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><msup><munder><mi>lim</mi><mrow><mi>x</mi><mo>\u2192</mo>' +
- '<mi>\u221E</mi></mrow></munder><mo>+</mo></msup><mo>(</mo><mi>x</mi>' +
- '<mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<limupper>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<function>lim</function>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>' +
- '<operator>+</operator>' +
- '</children>' +
- '</limupper>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><munderover><mi>lim</mi><mo>\u2015</mo><mrow><mi>x</mi>' +
- '<mo>\u2192</mo><mi>\u221E</mi></mrow></munderover><mo>(</mo>' +
- '<mi>x</mi><mo>)</mo></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<limboth>' +
- '<children>' +
- '<function>lim</function>' +
- '<punctuation>\u2015</punctuation>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limboth>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mrow><munder><mi>liminf</mi><mrow><mi>x</mi><mo>\u2192</mo>' +
- '<mi>\u221E</mi></mrow></munder><mo>(</mo><mi>x</mi><mo>)</mo>' +
- '<mo>+</mo><munder><mi>limsup</mi><mrow><mi>y</mi><mo>\u2192</mo>' +
- '<mi>\u221E</mi></mrow></munder><mo>(</mo><mi>y</mi><mo>)</mo></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<function>liminf</function>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<function>limsup</function>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>y</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>' +
- '<fenced>' +
- '<content>' +
- '<fence>(</fence>' +
- '<fence>)</fence>' +
- '</content>' +
- '<children>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</fenced>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><mi>a</mi><mo>+</mo><munder><mi>lim</mi><mrow><mi>x</mi>' +
- '<mo>\u2192</mo><mi>\u221E</mi></mrow></munder><mi>x</mi><mo>+</mo>' +
- '<mi>b</mi></mrow>',
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>a</identifier>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<function>lim</function>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</appl>' +
- '<identifier>b</identifier>' +
- '</children>' +
- '</infixop>');
-
- this.executeTreeTest(
- '<mrow><munder><mi>lim</mi><mrow><mi>x</mi><mo>\u2192</mo><mi>\u221E</mi>' +
- '</mrow></munder><mi>lim</mi><munder><mrow><mi>y</mi><mo>\u2192</mo>' +
- '<mi>\u221E</mi></mrow></munder><mi>x</mi><mi>y</mi></mrow>',
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<function>lim</function>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>lim</function>' +
- '<infixop>\u2062' +
- '<content>' +
- '<operator>\u2062</operator>' +
- '</content>' +
- '<children>' +
- '<underscore>' +
- '<children>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>y</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</underscore>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</appl>');
-
- this.executeTreeTest(
- '<mi>liminf</mi>',
- '<function>liminf</function>');
-
- this.executeTreeTest(
- '<munder><mi>lim</mi><mrow><mi>x</mi><mo>\u2192</mo><mi>\u221E</mi>' +
- '</mrow></munder>',
- '<limlower>' +
- '<children>' +
- '<function>lim</function>' +
- '<relseq>\u2192' +
- '<content>' +
- '<relation>\u2192</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>');
-
- this.executeTreeTest(
- '<mi>liminf</mi><mo>+</mo><mi>limsup</mi><mo>=</mo><mi>lim</mi>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>liminf</function>' +
- '<empty/>' +
- '</children>' +
- '</appl>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>limsup</function>' +
- '<empty/>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</infixop>' +
- '<appl>' +
- '<content>' +
- '<punctuation>\u2061</punctuation>' +
- '</content>' +
- '<children>' +
- '<function>lim</function>' +
- '<empty/>' +
- '</children>' +
- '</appl>' +
- '</children>' +
- '</relseq>');
-});
-
-
-/**
- * Variations of big operators.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeBigOps', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mrow><munderover><mi>\u2211</mi><mrow><mi>n</mi><mo>=</mo><mn>0</mn>' +
- '</mrow><mi>\u221E</mi></munderover><msup><mi>n</mi><mn>2</mn>' +
- '</msup></mrow>',
- '<bigop>' +
- '<children>' +
- '<limboth>' +
- '<children>' +
- '<largeop>\u2211</largeop>' +
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>n</identifier>' +
- '<number>0</number>' +
- '</children>' +
- '</relseq>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</limboth>' +
- '<superscript>' +
- '<children>' +
- '<identifier>n</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</bigop>');
-
- this.executeTreeTest(
- '<mrow><munderover><mi>\u2211</mi><mrow><mi>n</mi><mo>=</mo><mn>0</mn>' +
- '</mrow><mi>\u221E</mi></munderover><munderover><mi>\u2211</mi><mrow>' +
- '<mi>m</mi><mo>=</mo><mn>0</mn></mrow><mi>\u221E</mi></munderover><msup>' +
- '<mi>n</mi><mn>m</mn></msup></mrow>',
- '<bigop>' +
- '<children>' +
- '<limboth>' +
- '<children>' +
- '<largeop>\u2211</largeop>' +
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>n</identifier>' +
- '<number>0</number>' +
- '</children>' +
- '</relseq>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</limboth>' +
- '<bigop>' +
- '<children>' +
- '<limboth>' +
- '<children>' +
- '<largeop>\u2211</largeop>' +
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>m</identifier>' +
- '<number>0</number>' +
- '</children>' +
- '</relseq>' +
- '<identifier>\u221E</identifier>' +
- '</children>' +
- '</limboth>' +
- '<superscript>' +
- '<children>' +
- '<identifier>n</identifier>' +
- '<identifier>m</identifier>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</bigop>' +
- '</children>' +
- '</bigop>');
-
- this.executeTreeTest(
- '<mrow><munder><mi>\u2211</mi><mrow><mi>n</mi><mo>=</mo><mn>0</mn></mrow>' +
- '</munder><msup><mi>n</mi><mn>2</mn></msup></mrow>',
- '<bigop>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<largeop>\u2211</largeop>' +
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<identifier>n</identifier>' +
- '<number>0</number>' +
- '</children>' +
- '</relseq>' +
- '</children>' +
- '</limlower>' +
- '<superscript>' +
- '<children>' +
- '<identifier>n</identifier>' +
- '<number>2</number>' +
- '</children>' +
- '</superscript>' +
- '</children>' +
- '</bigop>');
-});
-
-
-
-/**
- * Variations of integrals.
- */
-TEST_F('CvoxSemanticTreeUnitTest', 'StreeIntegrals', function() {
- this.brief = true;
- this.executeTreeTest(
- '<mi>\u222B</mi>',
- '<largeop>\u222B</largeop>');
-
- this.executeTreeTest(
- '<mi>\u222B</mi><mi>dx</mi>',
- '<integral>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<empty/>' +
- '<identifier>dx</identifier>' +
- '</children>' +
- '</integral>');
-
- this.executeTreeTest(
- '<mrow><mi>\u222B</mi><mi>x</mi><mi>dx</mi></mrow>',
- '<integral>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<identifier>x</identifier>' +
- '<identifier>dx</identifier>' +
- '</children>' +
- '</integral>');
-
- this.executeTreeTest(
- '<mrow><mi>\u222B</mi><mi>x</mi><mi>d</mi><mi>x</mi></mrow>',
- '<integral>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<identifier>x</identifier>' +
- '<punctuated>' +
- '<content>' +
- '<punctuation>\u2063</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>d</identifier>' +
- '<punctuation>\u2063</punctuation>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</integral>');
-
- this.executeTreeTest(
- '<mrow><mi>\u222B</mi><mi>x</mi><mo>+' +
- '</mo><mi>y</mi><mi>d</mi><mi>x</mi></mrow>',
- '<integral>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<identifier>x</identifier>' +
- '<identifier>y</identifier>' +
- '</children>' +
- '</infixop>' +
- '<punctuated>' +
- '<content>' +
- '<punctuation>\u2063</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>d</identifier>' +
- '<punctuation>\u2063</punctuation>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</integral>');
-
- this.executeTreeTest(
- '<munderover><mi>\u222B</mi><mn>0</mn><mn>10</mn></munderover>',
- '<limboth>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<number>0</number>' +
- '<number>10</number>' +
- '</children>' +
- '</limboth>');
-
- this.executeTreeTest(
- '<munder><mi>\u222B</mi><mn>X</mn></munder>',
- '<limlower>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<identifier>X</identifier>' +
- '</children>' +
- '</limlower>');
-
- this.executeTreeTest(
- '<munderover><mi>\u222B</mi><mn>0</mn><mn>10</mn></munderover><mi>x</mi>' +
- '<mi>d</mi><mi>x</mi>',
- '<integral>' +
- '<children>' +
- '<limboth>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<number>0</number>' +
- '<number>10</number>' +
- '</children>' +
- '</limboth>' +
- '<identifier>x</identifier>' +
- '<punctuated>' +
- '<content>' +
- '<punctuation>\u2063</punctuation>' +
- '</content>' +
- '<children>' +
- '<identifier>d</identifier>' +
- '<punctuation>\u2063</punctuation>' +
- '<identifier>x</identifier>' +
- '</children>' +
- '</punctuated>' +
- '</children>' +
- '</integral>');
-
- this.executeTreeTest(
- '<munder><mi>\u222B</mi><mn>X</mn></munder><mi>x</mi><mi>dx</mi>',
- '<integral>' +
- '<children>' +
- '<limlower>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<identifier>X</identifier>' +
- '</children>' +
- '</limlower>' +
- '<identifier>x</identifier>' +
- '<identifier>dx</identifier>' +
- '</children>' +
- '</integral>');
-
- this.executeTreeTest(
- '<munderover><mi>\u222B</mi><mn>0</mn><mn>10</mn></munderover><mi>x</mi>' +
- '<mi>dx</mi><mo>+</mo><munderover><mi>\u222B</mi><mn>10</mn><mn>20</mn>' +
- '</munderover><mi>x</mi><mi>dx</mi><mo>=</mo><munderover><mi>\u222B</mi>' +
- '<mn>0</mn><mn>20</mn></munderover><mi>x</mi><mi>dx</mi>',
- '<relseq>=' +
- '<content>' +
- '<relation>=</relation>' +
- '</content>' +
- '<children>' +
- '<infixop>+' +
- '<content>' +
- '<operator>+</operator>' +
- '</content>' +
- '<children>' +
- '<integral>' +
- '<children>' +
- '<limboth>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<number>0</number>' +
- '<number>10</number>' +
- '</children>' +
- '</limboth>' +
- '<identifier>x</identifier>' +
- '<identifier>dx</identifier>' +
- '</children>' +
- '</integral>' +
- '<integral>' +
- '<children>' +
- '<limboth>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<number>10</number>' +
- '<number>20</number>' +
- '</children>' +
- '</limboth>' +
- '<identifier>x</identifier>' +
- '<identifier>dx</identifier>' +
- '</children>' +
- '</integral>' +
- '</children>' +
- '</infixop>' +
- '<integral>' +
- '<children>' +
- '<limboth>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<number>0</number>' +
- '<number>20</number>' +
- '</children>' +
- '</limboth>' +
- '<identifier>x</identifier>' +
- '<identifier>dx</identifier>' +
- '</children>' +
- '</integral>' +
- '</children>' +
- '</relseq>');
-
- this.executeTreeTest(
- '<mi>\u222B</mi><mi>\u222B</mi><mi>\u222B</mi>' +
- '<mi>dx</mi><mi>dy</mi><mi>dz</mi>',
- '<integral>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<integral>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<integral>' +
- '<children>' +
- '<largeop>\u222B</largeop>' +
- '<empty/>' +
- '<identifier>dx</identifier>' +
- '</children>' +
- '</integral>' +
- '<identifier>dy</identifier>' +
- '</children>' +
- '</integral>' +
- '<identifier>dz</identifier>' +
- '</children>' +
- '</integral>');
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_util.js
deleted file mode 100644
index 8d996874372..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_semantic_util.js
+++ /dev/null
@@ -1,135 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Utility functions for semantic tree computations.
- */
-
-goog.provide('cvox.SemanticUtil');
-
-
-/**
- * @constructor
- */
-cvox.SemanticUtil = function() { };
-
-
-/**
- * Merges keys of objects into an array.
- * @param {...Object<string>} objects Optional objects.
- * @return {Array<string>} Array of all keys of the objects.
- */
-cvox.SemanticUtil.objectsToKeys = function(objects) {
- objects = Array.prototype.slice.call(arguments, 0);
- var keys = [];
- return keys.concat.apply(keys, objects.map(Object.keys));
-};
-
-
-/**
- * Merges values of objects into an array.
- * @param {...Object<string>} objects Optional objects.
- * @return {Array<string>} Array of all values of the objects.
- */
-cvox.SemanticUtil.objectsToValues = function(objects) {
- objects = Array.prototype.slice.call(arguments, 0);
- var result = [];
- var collectValues = function(obj) {
- for (var key in obj) {
- result.push(obj[key]);
- }
- };
- objects.forEach(collectValues);
- return result;
-};
-
-
-/**
- * Transforms a unicode character into numeric representation. Returns null if
- * the input string is not a valid unicode character.
- * @param {string} unicode Character.
- * @return {?number} The decimal representation if it exists.
- */
-cvox.SemanticUtil.unicodeToNumber = function(unicode) {
- if (!unicode || unicode.length > 2) {
- return null;
- }
- // Treating surrogate pairs.
- if (unicode.length == 2) {
- var hi = unicode.charCodeAt(0);
- var low = unicode.charCodeAt(1);
- if (0xD800 <= hi && hi <= 0xDBFF && !isNaN(low)) {
- return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
- }
- return null;
- }
- return unicode.charCodeAt(0);
-};
-
-
-/**
- * Transforms a numberic representation of a unicode character into its
- * corresponding string.
- * @param {number} number Unicode point.
- * @return {string} The string representation.
- */
-cvox.SemanticUtil.numberToUnicode = function(number) {
- if (number >= 0x10000) {
- var hi = (number - 0x10000) / 0x0400 + 0xD800;
- var lo = (number - 0x10000) % 0x0400 + 0xDC00;
- return String.fromCharCode(hi, lo);
- }
- return String.fromCharCode(number);
-};
-
-
-/**
- * Returns the tagname of an element node in upper case.
- * @param {Element} node The node.
- * @return {string} The node's tagname.
- */
-cvox.SemanticUtil.tagName = function(node) {
- return node.tagName.toUpperCase();
-};
-
-
-/**
- * List of MathML Tags that are to be ignored.
- * @type {Array<string>}
- * @const
- */
-cvox.SemanticUtil.IGNORETAGS = [
- 'MERROR', 'MPHANTOM', 'MSPACE', 'MACTION', 'MALIGNGROUP', 'MALIGNMARK',
- 'MACTION'
-];
-
-
-/**
- * List of MathML Tags to be ignore if they have no children.
- * @type {Array<string>}
- * @const
- */
-cvox.SemanticUtil.EMPTYTAGS = ['MATH', 'MROW', 'MPADDED', 'MSTYLE'];
-
-
-/**
- * Removes elements from a list of MathML nodes that are either to be ignored or
- * ignored if they have empty children.
- * Observe that this is currently not recursive, i.e. will not take care of
- * pathological cases, where content is hidden in incorrectly used tags!
- * @param {Array<Element>} nodes The node list to be cleaned.
- * @return {Array<Element>} The cleansed list.
- */
-cvox.SemanticUtil.purgeNodes = function(nodes) {
- var nodeArray = [];
- for (var i = 0, node; node = nodes[i]; i++) {
- var tagName = cvox.SemanticUtil.tagName(node);
- if (cvox.SemanticUtil.IGNORETAGS.indexOf(tagName) != -1) continue;
- if (cvox.SemanticUtil.EMPTYTAGS.indexOf(tagName) != -1 &&
- node.childNodes.length == 0)
- continue;
- nodeArray.push(node);
- }
- return nodeArray;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/math_util.js
deleted file mode 100644
index 4de27ae3913..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/math_util.js
+++ /dev/null
@@ -1,263 +0,0 @@
-// 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.
-
-/**
- * @fileoverview DOM utility functions to aid in math expressions navigation.
- */
-
-goog.provide('cvox.MathUtil');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.XpathUtil');
-
-
-/**
- * Checks if a node is in a given class of MathML nodes.
- * @private
- * @param {!Node} node The node to test.
- * @param {Array<string>} tags List of tag names.
- * @return {boolean} True if node has a tag name included in tags.
- */
-cvox.MathUtil.isMathmlNodeOfClass_ = function(node, tags) {
- return tags.indexOf(node.tagName.toUpperCase()) != -1;
-};
-
-
-/**
- * Checks if a node is in a given class of MathJax nodes.
- * @private
- * @param {!Node} node The node to test.
- * @param {Array<string>} tags List of tag names.
- * @return {boolean} True if node has a tag name included in tags.
- */
-cvox.MathUtil.isMathjaxNodeOfClass_ = function(node, tags) {
- if (node.tagName == 'SPAN') {
- var classes = node.className.split(' ');
- return classes.some(function(x)
- {return tags.indexOf(x.toUpperCase()) != -1;});
- }
- return false;
-};
-
-
-/**
- * Checks if a node is an element node that belongs to a given class
- * of MathML or MathJax nodes.
- * @private
- * @param {!Node} node The node to test.
- * @param {Array<string>} tags List of tag names.
- * @return {boolean} True if node has a tag name included in tags.
- */
-cvox.MathUtil.isMathNodeOfClass_ = function(node, tags) {
- return (node.nodeType == Node.ELEMENT_NODE &&
- (cvox.MathUtil.isMathmlNodeOfClass_(node, tags) ||
- cvox.MathUtil.isMathjaxNodeOfClass_(node, tags)));
-};
-
-
-/**
- * Array of MathML Token Elements.
- * @type {!Array<string>}
- */
-cvox.MathUtil.TOKEN_LIST = ['MI', 'MN', 'MO', 'MTEXT', 'MSPACE', 'MS'];
-
-
-/**
- * Checks if an element of a math expression is a Token Element.
- * Token elements are the following:
- * <mi> identifier.
- * <mn> number.
- * <mo> operator, fence, or separator.
- * <mtext> text.
- * <mspace> space.
- * <ms> string literal.
- * @param {!Node} element The element of the math expression.
- * @return {boolean} True if element is a token.
- */
-cvox.MathUtil.isToken = function(element) {
- return cvox.MathUtil.isMathNodeOfClass_(element, cvox.MathUtil.TOKEN_LIST);
-};
-
-
-/**
- * Array of MathML Layout Schemata.
- * @type {!Array<string>}
- */
-cvox.MathUtil.LAYOUT_LIST = ['MROW', 'MFRAC', 'MSQRT', 'MROOT', 'MSTYLE',
- 'MERROR', 'MPADDED', 'MPHANTOM', 'MFENCED',
- 'MENCLOSE'];
-
-
-/**
- * Checks if an element of a math expression is a Layout Schema.
- * Layout elements are the following:
- * <mrow> group any number of sub-expressions horizontally
- * <mfrac> form a fraction from two sub-expressions
- * <msqrt> form a square root (radical without an index)
- * <mroot> form a radical with specified index
- * <mstyle> style change
- * <merror> enclose a syntax error message from a preprocessor
- * <mpadded> adjust space around content
- * <mphantom> make content invisible but preserve its size
- * <mfenced> surround content with a pair of fences
- * <menclose> enclose content with a stretching symbol such as a long
- * division sign.
- * @param {!Node} element The element of the math expression.
- * @return {boolean} True if element is a layout schema.
- */
-cvox.MathUtil.isLayout = function(element) {
- return cvox.MathUtil.isMathNodeOfClass_(element, cvox.MathUtil.LAYOUT_LIST);
-};
-
-
-/**
- * Array of MathML Script Schemata.
- * @type {!Array<string>}
- */
-cvox.MathUtil.SCRIPT_LIST = ['MSUB', 'MSUP', 'MSUBSUP', 'MUNDER', 'MOVER',
- 'MUNDEROVER', 'MMULTISCRIPTS', 'MPRESCRIPTS'];
-
-
-/**
- * Checks if an element of a math expression is a Script Schema.
- * Script elements are the following:
- * <msub> attach a subscript to a base.
- * <msup> attach a superscript to a base.
- * <msubsup> attach a subscript-superscript pair to a base.
- * <munder> attach an underscript to a base.
- * <mover> attach an overscript to a base.
- * <munderover> attach an underscript-overscript pair to a base.
- * <mmultiscripts> attach prescripts and tensor indices to a base.
- * Prescripts are optional.
- * <mprescripts> two elements prescripts of mmultiscripts. Only makes sense
- * in that environment (although not illegal outside)! Two
- * arguments mandatory (can be <none/>).
- * @param {!Node} element The element of the math expression.
- * @return {boolean} True if element is a script schema.
- */
-cvox.MathUtil.isScript = function(element) {
- return cvox.MathUtil.isMathNodeOfClass_(element, cvox.MathUtil.SCRIPT_LIST);
-};
-
-
-/**
- * Array of MathML Table and Matrix tokens.
- * @type {!Array<string>}
- */
-cvox.MathUtil.TABLES_LIST = ['MTABLE', 'MLABELEDTR', 'MTR', 'MTD',
- 'MALIGNGROUP', 'MALIGNMARK'];
-
-
-/**
- * Checks if an element of a math expression is a Tables Schema.
- * Tables elements are the following:
- * <mtable> table or matrix.
- * <mlabeledtr> row in a table or matrix with a label or equation number.
- * <mtr> row in a table or matrix.
- * <mtd> one entry in a table or matrix.
- * <maligngroup> and
- * <malignmark> alignment markers.
- * @param {!Node} element The element of the math expression.
- * @return {boolean} True if element is a tables schema.
- */
-cvox.MathUtil.isTables = function(element) {
- return cvox.MathUtil.isMathNodeOfClass_(element, cvox.MathUtil.TABLES_LIST);
-};
-
-
-/**
- * Array of MathML Elementary Layout Schemata.
- * @type {!Array<string>}
- */
-cvox.MathUtil.ELEMENTARY_LIST = ['MSTACK', 'MLONGDIV', 'MSGROUP', 'MSROW',
- 'MSCARRIES', 'MSCARRY', 'MSLINE'];
-
-
-/**
- * Checks if an element of a math expression is a Elementary Schema.
- * Elementary elements are the following:
- * <mstack> columns of aligned characters.
- * <mlongdiv> similar to msgroup, with the addition of a divisor and result.
- * <msgroup> a group of rows in an mstack that are shifted by similar amounts.
- * <msrow> a row in an mstack.
- * <mscarries> row in an mstack that whose contents represent carries
- * or borrows.
- * <mscarry> one entry in an mscarries.
- * <msline> horizontal line inside of mstack.
- * @param {!Node} element The element of the math expression.
- * @return {boolean} True if element is a elementary schema.
- */
-cvox.MathUtil.isElementary = function(element) {
- return cvox.MathUtil.isMathNodeOfClass_(element,
- cvox.MathUtil.ELEMENTARY_LIST);
-};
-
-
-/**
- * Array of all valid tags in a MathML expression.
- * This is a union of all other token lists.
- * @type {!Array<string>}
- */
-cvox.MathUtil.MATHML_TAG_LIST = [cvox.MathUtil.TOKEN_LIST,
- cvox.MathUtil.LAYOUT_LIST,
- cvox.MathUtil.SCRIPT_LIST,
- cvox.MathUtil.TABLES_LIST,
- cvox.MathUtil.ELEMENTARY_LIST].reduce(
- function(x, y) { return x.concat(y); });
-
-
-/**
- * Checks if a node is valid element of a MathML expression.
- * @param {!Node} element The element of the math expression.
- * @return {boolean} True if element has a valid MathML tag.
- */
-cvox.MathUtil.isMathmlTag = function(element) {
- return cvox.MathUtil.isMathNodeOfClass_(element,
- cvox.MathUtil.MATHML_TAG_LIST);
-};
-
-
-/**
- * Array of MathML Whitespace and Alignment tokens.
- * These are elements that can occur in the other token lists.
- * @type {!Array<string>}
- */
-cvox.MathUtil.WHITESPACE_LIST = ['MSROW', 'MROW', 'MSPACE',
- 'MPHANTOM', 'MPADDED'];
-
-
-/**
- * Checks if an element of a math expression is whitespace or an
- * alignment marker.
- * @param {!Node} element The element of the math expression.
- * @return {boolean} True if element is a whitespace node.
- */
-cvox.MathUtil.isWhitespace = function(element) {
- return cvox.MathUtil.isMathNodeOfClass_(element,
- cvox.MathUtil.WHITESPACE_LIST);
-};
-
-
-/**
- * Checks if an element of a math expression is a legal mathml markup element
- * but not a whitespace or an alignment marker.
- * @param {!Node} element The element of the math expression.
- * @return {boolean} True if element is a non-whitespace node.
- */
-cvox.MathUtil.isNotWhitespace = function(element) {
- return (cvox.MathUtil.isMathmlTag(element) &&
- !cvox.MathUtil.isWhitespace(element));
-};
-
-
-/**
- * Computes the union of two arrays (not in a strictly set theoretical sense
- * as all duplicate elements in either array still remain as duplicates!).
- * @param {Array} a An array.
- * @param {Array} b Another array.
- * @return {Array} Union of a and b.
- */
-cvox.MathUtil.union = function(a, b) {
- return a.concat(b.filter(function(x) {return a.indexOf(x) < 0;}));
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/media_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/media_widget.js
deleted file mode 100644
index 7b6dd05ed89..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/media_widget.js
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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.
-
-goog.provide('cvox.ChromeVoxHTMLMediaWidget');
-
-/**
- * @fileoverview Gives the user spoken feedback as they interact with the HTML5
- * media widgets (<video> and <audio>) + makes the widget keyboard accessible.
- *
- */
-
-/**
- * A class containing the information needed to speak
- * a media element to the user.
- *
- * @constructor
- * @param {Element} mediaElem The media widget element.
- * @param {cvox.TtsInterface} tts The TTS object from ChromeVox.
- */
-cvox.ChromeVoxHTMLMediaWidget = function(mediaElem, tts){
- var self = this;
- this.mediaElem_ = mediaElem;
- this.mediaTts_ = tts;
-
- this.keyListener_ = function(evt) {
- self.eventHandler_(evt);
- }
- this.blurListener_ = function(evt) {
- self.shutdown();
- }
-
- this.mediaElem_.addEventListener('keydown', this.keyListener_, false);
- this.mediaElem_.addEventListener('keyup', this.keyListener_, false);
- this.mediaElem_.addEventListener('blur', this.blurListener_, false);
-};
-
-/**
- * Removes the key listeners for the media widget.
- */
-cvox.ChromeVoxHTMLMediaWidget.prototype.shutdown = function() {
- this.mediaElem_.removeEventListener('blur', this.blurListener_, false);
- this.mediaElem_.removeEventListener('keydown', this.keyListener_, false);
- this.mediaElem_.removeEventListener('keyup', this.keyListener_, false);
-};
-
-cvox.ChromeVoxHTMLMediaWidget.prototype.jumpToTime_ = function(targetTime) {
- if (targetTime < 0) {
- targetTime = 0;
- }
- if (targetTime > this.mediaElem_.duration) {
- targetTime = this.mediaElem_.duration;
- }
- this.mediaElem_.currentTime = targetTime;
-};
-
-cvox.ChromeVoxHTMLMediaWidget.prototype.setVolume_ = function(targetVolume) {
- if (targetVolume < 0) {
- targetVolume = 0;
- }
- if (targetVolume > 1.0) {
- targetVolume = 1.0;
- }
- this.mediaElem_.volume = targetVolume;
-};
-
-/**
- * Adds basic keyboard handlers to the media widget.
- */
-cvox.ChromeVoxHTMLMediaWidget.prototype.eventHandler_ = function(evt) {
- if (evt.type == 'keydown') {
- // Space/Enter for play/pause toggle.
- if ((evt.keyCode == 13) || (evt.keyCode == 32)) {
- if (this.mediaElem_.paused){
- this.mediaElem_.play();
- } else {
- this.mediaElem_.pause();
- }
- } else if (evt.keyCode == 39) { // Right - FF
- this.jumpToTime_(
- this.mediaElem_.currentTime + (this.mediaElem_.duration/10));
- } else if (evt.keyCode == 37) { // Left - REW
- this.jumpToTime_(
- this.mediaElem_.currentTime - (this.mediaElem_.duration/10));
- } else if (evt.keyCode == 38) { // Up - Vol. Up
- this.setVolume_(this.mediaElem_.volume + .1);
- } else if (evt.keyCode == 40) { // Down - Vol. Down
- this.setVolume_(this.mediaElem_.volume - .1);
- }
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/memoize.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/memoize.js
deleted file mode 100644
index 0ac3f6386ac..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/memoize.js
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Provides a system for memoizing computations applied to
- * DOM nodes within the same call stack.
- *
- * To make a function memoizable - suppose you have a function
- * isAccessible that takes a node and returns a boolean:
- *
- * function isAccessible(node) {
- * return expensiveComputation(node);
- * }
- *
- * Make it memoizable like this:
- *
- * function isAccessible(node) {
- * return cvox.Memoize.memoize(computeIsAccessible_, 'isAccessible', node);
- * }
- *
- * function computeIsAccessible_(node) {
- * return expensiveComputation(node);
- * }
- *
- * To take advantage of memoization, you need to wrap a sequence of
- * computations in a call to memoize.scope() - memoization is only
- * enabled while in that scope, and all cached data is thrown away at
- * the end. You should use this only when you're sure the computation
- * being memoized will not change within the scope.
- *
- * cvox.Memoize.scope(function() {
- * console.log(isAccessible(document.body));
- * });
- *
- */
-
-
-goog.provide('cvox.Memoize');
-
-
-/**
- * Create the namespace.
- * @constructor
- */
-cvox.Memoize = function() {
-};
-
-/**
- * The cache: a map from string function name to a WeakMap from DOM node
- * to function result. This variable is null when we're out of scope, and it's
- * a map from string to WeakMap to result when we're in scope.
- *
- * @type {?Object<WeakMap<Node, *> >}
- * @private
- */
-cvox.Memoize.nodeMap_ = null;
-
-/**
- * Keeps track of how many nested times scope() has been called.
- * @type {number}
- * @private
- */
-cvox.Memoize.scopeCount_ = 0;
-
-
-/**
- * Enables memoization within the scope of the given function. You should
- * ensure that the DOM is not modified within this scope.
- *
- * It's safe to nest calls to scope. The nested calls have
- * no effect, only the outermost one.
- *
- * @param {Function} functionScope The function to call with memoization
- * enabled.
- * @return {*} The value returned by |functionScope|.
- */
-cvox.Memoize.scope = function(functionScope) {
- var result;
- try {
- cvox.Memoize.scopeCount_++;
- if (cvox.Memoize.scopeCount_ == 1) {
- cvox.Memoize.nodeMap_ = {};
- }
- result = functionScope();
- } finally {
- cvox.Memoize.scopeCount_--;
- if (cvox.Memoize.scopeCount_ == 0) {
- cvox.Memoize.nodeMap_ = null;
- }
- }
- return result;
-};
-
-/**
- * Memoizes the result of a function call, so if you call this again
- * with the same exact parameters and memoization is currently enabled
- * (via a call to scope()), the second time the cached result
- * will just be returned directly.
- *
- * @param {Function} functionClosure The function to call and cache the
- * result of.
- * @param {string} functionName The name of the function you're calling.
- * This string is used to store and retrieve the cached result, so
- * it should be unique. If the function to be memoized takes simple
- * arguments in addition to a DOM node, you can incorporate those
- * arguments into the function name.
- * @param {Node} node The DOM node that should be passed as the argument
- * to the function.
- * @return {*} The return value of |functionClosure|.
- */
-cvox.Memoize.memoize = function(functionClosure, functionName, node) {
- if (cvox.Memoize.nodeMap_ &&
- cvox.Memoize.nodeMap_[functionName] === undefined) {
- cvox.Memoize.nodeMap_[functionName] = new WeakMap();
- }
-
- // If we're not in scope, just call the function directly.
- if (!cvox.Memoize.nodeMap_) {
- return functionClosure(node);
- }
-
- var result = cvox.Memoize.nodeMap_[functionName].get(node);
- if (result === undefined) {
- result = functionClosure(node);
- if (result === undefined) {
- throw 'A memoized function cannot return undefined.';
- }
- cvox.Memoize.nodeMap_[functionName].set(node, result);
- }
-
- return result;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/msgs.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/msgs.js
deleted file mode 100644
index 8a9628e1d46..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/msgs.js
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Defines methods related to retrieving translated messages.
- */
-
-goog.provide('Msgs');
-
-/**
- * @constructor
- */
-Msgs = function() {};
-
-/**
- * The namespace for all Chromevox messages.
- * @type {string}
- * @const
- * @private
- */
-Msgs.NAMESPACE_ = 'chromevox_';
-
-/**
- * Dictionary of locale names.
- * @type {Object<string>}
- * @private
- */
-Msgs.localeNameDict_ = null;
-
-/**
- * Return the current locale.
- * @return {string} The locale.
- */
-Msgs.getLocale = function() {
- return chrome.i18n.getMessage('locale');
-};
-
-/**
- * Returns the message with the given message id from the ChromeVox namespace.
- *
- * If we can't find a message, throw an exception. This allows us to catch
- * typos early.
- *
- * @param {string} messageId The id.
- * @param {Array<string>=} opt_subs Substitution strings.
- * @return {string} The localized message.
- */
-Msgs.getMsg = function(messageId, opt_subs) {
- var message = Msgs.Untranslated[messageId.toUpperCase()];
- if (message !== undefined)
- return message;
- message = chrome.i18n.getMessage(
- Msgs.NAMESPACE_ + messageId, opt_subs);
- if (message == undefined || message == '') {
- throw new Error('Invalid ChromeVox message id: ' + messageId);
- }
- return message;
-};
-
-/**
- * Processes an HTML DOM, replacing text content with translated text messages
- * on elements marked up for translation. Elements whose class attributes
- * contain the 'i18n' class name are expected to also have an msgid
- * attribute. The value of the msgid attributes are looked up as message
- * IDs and the resulting text is used as the text content of the elements.
- *
- * @param {Node} root The root node where the translation should be performed.
- */
-Msgs.addTranslatedMessagesToDom = function(root) {
- var elts = root.querySelectorAll('.i18n');
- for (var i = 0; i < elts.length; i++) {
- var msgid = elts[i].getAttribute('msgid');
- if (!msgid) {
- throw new Error('Element has no msgid attribute: ' + elts[i]);
- }
- elts[i].textContent = this.getMsg(msgid);
- elts[i].classList.add('i18n-processed');
- }
-};
-
-/**
- * Retuns a number formatted correctly.
- *
- * @param {number} num The number.
- * @return {string} The number in the correct locale.
- */
-Msgs.getNumber = function(num) {
- return '' + num;
-};
-
-/**
- * Gets a localized display name for a locale.
- * NOTE: Only a subset of locale identifiers are supported. See the
- * |CHROMEVOX_LOCALE_DICT| message.
- * @param {string} locale On the form |ll| or |ll_CC|, where |ll| is
- * the language code and |CC| the country code.
- * @return {string} The display name.
- */
-Msgs.getLocaleDisplayName = function(locale) {
- if (!Msgs.localeNameDict_) {
- Msgs.localeNameDict_ = /** @type {!Object<string>} */(
- JSON.parse(this.getMsg('locale_dict')));
- }
- var name = Msgs.localeNameDict_[locale];
- if (!name) {
- throw Error('Unsupported locale identifier: ' + locale);
- }
- return name;
-};
-
-/**
- * Strings that are displayed in the user interface but don't need
- * be translated.
- * @type {Object<string>}
- */
-Msgs.Untranslated = {
- /** The unchecked state for a checkbox in braille. */
- CHECKBOX_UNCHECKED_STATE_BRL: '( )',
- /** The checked state for a checkbox in braille. */
- CHECKBOX_CHECKED_STATE_BRL: '(x)',
- /** The unselected state for a radio button in braille. */
- RADIO_UNSELECTED_STATE_BRL: '( )',
- /** The selected state for a radio button in braille. */
- RADIO_SELECTED_STATE_BRL: '(x)',
- /** Brailled after a menu if the menu has a submenu. */
- ARIA_HAS_SUBMENU_BRL: '->',
- /** Describes an element with the ARIA role option. */
- ROLE_OPTION: ' ',
- /** Braille of element with the ARIA role option. */
- ROLE_OPTION_BRL: ' ',
- /** Braille of element with the ARIA attribute aria-checked=true. */
- ARIA_CHECKED_TRUE_BRL: '(x)',
- /** Braille of element with the ARIA attribute aria-checked=false. */
- ARIA_CHECKED_FALSE_BRL: '( )',
- /** Braille of element with the ARIA attribute aria-checked=mixed. */
- ARIA_CHECKED_MIXED_BRL: '(-)',
- /** Braille of element with the ARIA attribute aria-disabled=true. */
- ARIA_DISABLED_TRUE_BRL: 'xx',
- /** Braille of element with the ARIA attribute aria-expanded=true. */
- ARIA_EXPANDED_TRUE_BRL: '-',
- /** Braille of element with the ARIA attribute aria-expanded=false. */
- ARIA_EXPANDED_FALSE_BRL: '+',
- /** Braille of element with the ARIA attribute aria-invalid=true. */
- ARIA_INVALID_TRUE_BRL: '!',
- /** Braille of element with the ARIA attribute aria-pressed=true. */
- ARIA_PRESSED_TRUE_BRL: '=',
- /** Braille of element with the ARIA attribute aria-pressed=false. */
- ARIA_PRESSED_FALSE_BRL: ' ',
- /** Braille of element with the ARIA attribute aria-pressed=mixed. */
- ARIA_PRESSED_MIXED_BRL: '-',
- /** Braille of element with the ARIA attribute aria-selected=true. */
- ARIA_SELECTED_TRUE_BRL: '(x)',
- /** Braille of element with the ARIA attribute aria-selected=false. */
- ARIA_SELECTED_FALSE_BRL: '( )',
- /** Brailled after a menu if it has a submenu. */
- HAS_SUBMENU_BRL: '->',
- /** Brailled to describe a &lt;time&gt; tag. */
- TAG_TIME_BRL: ' ',
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/nav_description.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/nav_description.js
deleted file mode 100644
index a158b5746c8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/nav_description.js
+++ /dev/null
@@ -1,163 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A simple container object for the description of a
- * navigation from one object to another.
- *
- */
-
-
-goog.provide('cvox.NavDescription');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.QueueMode');
-
-/**
- * A class representing the description of navigation from one object to
- * another.
- * @param {{context: (undefined|string),
- * text: (string),
- * userValue: (undefined|string),
- * annotation: (undefined|string),
- * earcons: (undefined|Array<cvox.Earcon>),
- * personality: (undefined|Object),
- * hint: (undefined|string),
- category: (undefined|string)}} kwargs The arguments for this
- * description.
- * context The context, for example descriptions of objects
- * that were crossed into, like "Toolbar" or "Menu Bar" or "List with
- * 5 items". This is all spoken with an annotation voice.
- * text The text of the object itself, including text from
- * titles, labels, etc.
- * userValue The text that the user has entered.
- * annotation The role and state of the object.
- * earcons A list of the earcon ids to play along
- * with the spoken description of this object.
- * personality Optional TTS personality to use for the text.
- * hint Optional Hint text (.e.g. aria-describedby).
- * category Optional category (for speech queueing behavior).
- * @constructor
- */
-cvox.NavDescription = function(kwargs) {
- this.context = kwargs.context ? kwargs.context : '';
- this.text = kwargs.text ? kwargs.text : '';
- this.userValue = kwargs.userValue ? kwargs.userValue : '';
- this.annotation = kwargs.annotation ? kwargs.annotation : '';
- this.earcons = kwargs.earcons ? kwargs.earcons : [];
- this.personality = kwargs.personality;
- this.hint = kwargs.hint ? kwargs.hint : '';
- this.category = kwargs.category ? kwargs.category : null;
-};
-
-
-/**
- * @return {boolean} true if this description is empty.
- */
-cvox.NavDescription.prototype.isEmpty = function() {
- return (this.context.length == 0 &&
- this.earcons.length == 0 &&
- this.text.length == 0 &&
- this.userValue.length == 0 &&
- this.annotation.length == 0);
-};
-
-
-/**
- * @return {string} A string representation of this object.
- */
-cvox.NavDescription.prototype.toString = function() {
- return 'NavDescription(context="' + this.context + '" ' +
- ' text="' + this.text + '" ' +
- ' userValue="' + this.userValue + '" ' +
- ' annotation="' + this.annotation +
- (this.category ? '" category="' + this.category + '")' : '') +
- '")';
-};
-
-
-/**
- * Modifies the earcon to play along with the spoken description of the object.
- * @param {cvox.Earcon} earconId An earcon id to be pushed on to the list of
- * earcon ids to play along with the spoken description of this object.
- */
-cvox.NavDescription.prototype.pushEarcon = function(earconId) {
- this.earcons.push(earconId);
-};
-
-
-/**
- * Speak this nav description with the given queue mode.
- * @param {cvox.QueueMode=} queueMode The queue mode.
- * @param {function()=} opt_startCallback Function called when this
- * starts speaking.
- * @param {function()=} opt_endCallback Function called when this ends speaking.
- */
-cvox.NavDescription.prototype.speak = function(
- queueMode, opt_startCallback, opt_endCallback) {
- /**
- * Return a deep copy of PERSONALITY_ANNOTATION for modifying.
- * @return {Object} The newly created properties object.
- */
- function makeAnnotationProps() {
- var properties = {};
- var src = cvox.AbstractTts.PERSONALITY_ANNOTATION;
- for (var key in src) {
- properties[key] = src[key];
- }
- return properties;
- }
-
- var speakArgs = new Array();
- if (this.context) {
- speakArgs.push([this.context, queueMode, makeAnnotationProps()]);
- queueMode = cvox.QueueMode.QUEUE;
- }
-
- speakArgs.push([this.text,
- queueMode,
- this.personality ? this.personality : {}]);
- queueMode = cvox.QueueMode.QUEUE;
-
- if (this.userValue) {
- speakArgs.push([this.userValue, queueMode, {}]);
- }
-
- if (this.annotation) {
- speakArgs.push([this.annotation, queueMode, makeAnnotationProps()]);
- }
-
- if (this.hint) {
- speakArgs.push([this.hint, queueMode, makeAnnotationProps()]);
- }
-
- var length = speakArgs.length;
- for (var i = 0; i < length; i++) {
- if (i == 0 && opt_startCallback) {
- speakArgs[i][2]['startCallback'] = opt_startCallback;
- }
- if (i == length - 1 && opt_endCallback) {
- speakArgs[i][2]['endCallback'] = opt_endCallback;
- }
- if (this.category) {
- speakArgs[i][2]['category'] = this.category;
- }
- cvox.ChromeVox.tts.speak.apply(cvox.ChromeVox.tts, speakArgs[i]);
- }
-};
-
-
-/**
- * Compares two NavDescriptions.
- * @param {cvox.NavDescription} that A NavDescription.
- * @return {boolean} True if equal.
- */
-cvox.NavDescription.prototype.equals = function(that) {
- return this.context == that.context &&
- this.text == that.text &&
- this.userValue == that.userValue &&
- this.annotation == that.annotation;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/nav_math_description.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/nav_math_description.js
deleted file mode 100644
index e76c6886804..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/nav_math_description.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A subclass of the navigation description container
- * specialising on math objects.
- *
- */
-
-
-goog.provide('cvox.NavMathDescription');
-
-goog.require('cvox.NavDescription');
-
-
-/**
- * Class specialising navigation descriptions for mathematics.
- * @param {{context: (undefined|string),
- * text: (string),
- * userValue: (undefined|string),
- * annotation: (undefined|string),
- * earcons: (undefined|Array<cvox.Earcon>),
- * personality: (undefined|Object),
- * hint: (undefined|string),
- * category: (undefined|string),
- * domain: (undefined|string),
- * style: (undefined|string)}} kwargs The arguments for
- * the specialised math navigationdescription. See arguments of nav
- * description plus the following:
- * domain Domain for translation.
- * style Style for translation.
- * @constructor
- * @extends {cvox.NavDescription}
- */
-cvox.NavMathDescription = function(kwargs) {
- goog.base(this, kwargs);
-
- var newPersonality = this.personality ? this.personality : {};
- var mathDescr = new Object();
-
- mathDescr['domain'] = kwargs.domain ? kwargs.domain : '';
- // TODO (sorge) Collate and document styles in an enum structure.
- mathDescr['style'] = kwargs.style ? kwargs.style : '';
- newPersonality['math'] = mathDescr;
- this.personality = newPersonality;
-};
-goog.inherits(cvox.NavMathDescription, cvox.NavDescription);
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/node_state.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/node_state.js
deleted file mode 100644
index d7f97fec382..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/node_state.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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.
-
-/**
- * @fileoverview The cvox.NodeState typedef.
- */
-
-goog.provide('cvox.NodeState');
-goog.provide('cvox.NodeStateUtil');
-
-goog.require('Msgs');
-
-/**
- * Holds the state of a node. It is an Array or Arrays of strings and numbers.
- * Each sub array is in the format:
- * [state, opt_arg, opt_arg, ...]. These sub arrays map directly to a
- * cvox.ChromeVox.getMsg() call. For example [list_position, 3, 5] maps to
- * getMsg('list_position', [3, 5]);
- *
- * @typedef {!Array<!Array<string|number>>}
- */
-cvox.NodeState;
-
-/**
- * Returns a localized, readable string with the NodeState.
- *
- * NOTE(deboer): Once AriaUtil and DomUtil are using NodeState exclusively, this
- * function can be moved into DescriptionUtil, removing the cvox.ChromeVox
- * dependency here.
- *
- * @param {cvox.NodeState} state The node state.
- * @return {string} The readable state string.
- */
-cvox.NodeStateUtil.expand = function(state) {
- try {
- return state.map(function(s) {
- if (s.length < 1) {
- throw new Error('cvox.NodeState must have at least one entry');
- }
- var args = s.slice(1).map(function(a) {
- if (typeof a == 'number') {
- return Msgs.getNumber(a);
- }
- return a;
- });
- return Msgs.getMsg(/** @type {string} */ (s[0]), args);
- }).join(' ');
- } catch (e) {
- throw new Error('error: ' + e + ' state: ' + state);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/page_selection.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/page_selection.js
deleted file mode 100644
index 7a46db20669..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/page_selection.js
+++ /dev/null
@@ -1,107 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class representing a DOM selection conveyed through
- * CursorSelection idioms.
- * A PageSelection is just a DOM selection. The class itself manages a single
- * CursorSelection that surrounds a fragment on the page. It also provides an
- * extend operation to either grow or shrink the selection given a
- * CursorSelection. The class handles correctly moving the internal
- * CursorSelection and providing immediate access to a full description of the
- * selection at any time.
- */
-
-goog.provide('cvox.PageSelection');
-
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.NavDescription');
-
-/**
- * @constructor
- * @param {!cvox.CursorSelection} sel The initial selection.
- */
-cvox.PageSelection = function(sel) {
- this.sel_ = sel.clone();
- this.sel_.select();
- this.wasBegin_ = true;
-};
-
-
-/**
- * Gets a description for the DOM selection during the course of navigation.
- * @param {cvox.AbstractShifter} navShifter Used to obtain walker-based
- * descriptions.
- * @param {!cvox.CursorSelection} prevSel Previous CursorSelection in
- * navigation.
- * @param {!cvox.CursorSelection} curSel Current CursorSelection in navigation.
- * @return {Array<cvox.NavDescription>} The new description.
- */
-cvox.PageSelection.prototype.getDescription =
- function(navShifter, prevSel, curSel) {
- var desc = [];
- if (this.sel_.isReversed() != curSel.isReversed()) {
- // A shrinking selection.
- desc = navShifter.getDescription(curSel, prevSel);
- desc[0].annotation = Msgs.getMsg('describe_unselected');
- desc[0].pushEarcon(cvox.Earcon.SELECTION_REVERSE);
- } else {
- // A growing selection.
- desc = navShifter.getDescription(prevSel, curSel);
- desc[0].annotation = Msgs.getMsg('describe_selected');
- desc[0].pushEarcon(cvox.Earcon.SELECTION);
- if (!this.wasBegin_ && this.sel_.absEquals(curSel.clone().normalize())) {
- // A selection has inverted across the start cursor. Describe it.
- var prevDesc = navShifter.getDescription(curSel, prevSel);
- prevDesc[0].annotation =
- Msgs.getMsg('describe_unselected');
- prevDesc[0].pushEarcon(cvox.Earcon.SELECTION_REVERSE);
- prevDesc[0].pushEarcon(cvox.Earcon.WRAP);
- desc = prevDesc.concat(desc);
- }
- }
- return desc;
-};
-
-
-/**
- * Gets a full description for the entire DOM selection.
- * Use this description when you want to describe the entire selection
- * represented by this instance.
- *
- * @return {Array<cvox.NavDescription>} The new description.
- */
-cvox.PageSelection.prototype.getFullDescription = function() {
- return [new cvox.NavDescription(
- {text: window.getSelection().toString(),
- context: Msgs.getMsg('selection_is')})];
-};
-
-
-/**
- * Extends this selection.
- * @param {!cvox.CursorSelection} sel Extend DOM selection to the selection.
- * @return {boolean} True if the extension occurred, false if the PageSelection
- * was reset to sel.
- */
-cvox.PageSelection.prototype.extend = function(sel) {
- if (!this.sel_.directedBefore(sel)) {
- // Do not allow for crossed selections. This restarts a page selection that
- // has been collapsed. This occurs when two CursorSelection's point away
- // from one another.
- this.sel_ = sel.clone();
- } else {
- // Otherwise, it is assumed that the CursorSelection's are in directed
- // document order. The CursorSelection's are either pointing in the same
- // direction or towards one another. In the first case, shrink/extend this
- // PageSelection to the end of "sel". In the second case, shrink/extend this
- // PageSelection to the start of "sel".
- this.sel_.end = this.sel_.isReversed() == sel.isReversed() ?
- sel.end.clone() : sel.start.clone();
- }
- this.sel_.select();
- this.wasBegin_ = false;
- return !this.sel_.absEquals(sel);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/page_selection_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/page_selection_test.unitjs
deleted file mode 100644
index 413b9292415..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/page_selection_test.unitjs
+++ /dev/null
@@ -1,143 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxPageSelectionUnitTest() {}
-
-CvoxPageSelectionUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.CursorSelection',
- 'cvox.PageSelection',
- ],
-
- /** @override */
- setUp: function() {
- this.loadDoc(function() {/*!
- <p id='p1'>The quick</p>
- <a id='a1' href='#'>brown fox</a>
- <h1 id='h1'>jumped over</h1>
- */});
- this.pSel = cvox.CursorSelection.fromNode($('p1'));
- this.pSel.start.index = 0;
- this.pSel.end.index = 1;
- this.aSel = cvox.CursorSelection.fromNode($('a1'));
- this.aSel.start.index = 0;
- this.aSel.end.index = 1;
- this.hSel = cvox.CursorSelection.fromNode($('h1'));
- this.hSel.start.index = 0;
- this.hSel.end.index = 1;
- },
-
- /**
- * Asserts a selection.
- * @param {string} str The expected contents of selection.
- * @private
- */
- assertSelection_: function(str) {
- assertEquals(str, window.getSelection().toString());
- }
-};
-
-TEST_F('CvoxPageSelectionUnitTest', 'BasicExtend', function() {
- var pageSel = new cvox.PageSelection(this.pSel);
- pageSel.extend(this.hSel);
- this.assertSelection_('The quick\n\nbrown fox\njumped over');
- this.hSel.end.node = this.hSel.end.node.firstChild;
- this.hSel.end.index = 6;
- pageSel.extend(this.hSel);
- this.assertSelection_('The quick\n\nbrown fox\njumped');
-});
-
-
-/** Tests a reverse extension. */
-TEST_F('CvoxPageSelectionUnitTest', 'ReverseExtend', function() {
- var pageSel = new cvox.PageSelection(this.pSel);
- this.assertSelection_('The quick');
- pageSel.extend(this.hSel);
- this.assertSelection_('The quick\n\nbrown fox\njumped over');
- pageSel.extend(this.aSel.setReversed(true));
- this.assertSelection_('The quick\n\nbrown fox');
- this.pSel.setReversed(true);
- pageSel.extend(this.pSel);
- this.assertSelection_('The quick');
- this.pSel.start.node = this.pSel.start.node.firstChild;
- this.pSel.start.index = 3;
- pageSel.extend(this.pSel);
- this.assertSelection_('The');
-});
-
-
-/** Tests all possible configurations of PageSelection's and extending
- * CursorSelection's.
- */
-TEST_F('CvoxPageSelectionUnitTest', 'ExtendDirections', function() {
- // A normal page selection, with a normal extension.
- var pageSel = new cvox.PageSelection(this.aSel);
- assertTrue(pageSel.extend(this.hSel));
-
- // A normal page selection, with a reversed extension.
- assertTrue(pageSel.extend(this.hSel.setReversed(true)));
-
- // A reversed page selection, with a normal cursor selection.
- var rPageSel = new cvox.PageSelection(this.aSel.setReversed(true));
- assertTrue(rPageSel.extend(this.pSel));
-
- // A reversed page selection, with a reversed extension.
- assertTrue(rPageSel.extend(this.pSel.setReversed(true)));
-});
-
-
-/** Tests degenerate extensions. */
-TEST_F('CvoxPageSelectionUnitTest', 'DegenerateExtensions', function() {
- var pageSel = new cvox.PageSelection(this.aSel);
-
- // A normal page selection, with a normal extension not in document order.
- assertFalse(pageSel.extend(this.pSel));
-
- // And, this causes a reset of page selection.
- assertTrue(pageSel.sel_.equals(this.pSel));
-
- // Reinitialize.
- pageSel = new cvox.PageSelection(this.aSel.setReversed(false));
-
- // A normal page selection, with a reversed extension not in document order.
- assertFalse(pageSel.extend(this.pSel.setReversed(true)));
-
- // And, again, it causes reset of page selection.
-assertTrue(pageSel.sel_.equals(this.pSel));
-
- // Reverse page selections.
- var rPageSel = new cvox.PageSelection(this.aSel.setReversed(true));
-
- // A reversed page selection, with a normal extension not in document order.
- assertFalse(rPageSel.extend(this.hSel));
- assertTrue(rPageSel.sel_.equals(this.hSel));
-
- // A reversed page selection, with a reversed extension not in document order.
- rPageSel = new cvox.PageSelection(this.aSel.setReversed(true));
- assertFalse(rPageSel.extend(this.hSel.setReversed(true)));
- assertTrue(rPageSel.sel_.equals(this.hSel));
-
- // And, finally, try extending to oneself in either direction.
- pageSel = new cvox.PageSelection(this.aSel.setReversed(false));
-
- // A normal page selection, with an extension to itself.
- assertFalse(pageSel.extend(this.aSel.setReversed(false)));
- assertFalse(pageSel.extend(this.aSel.setReversed(true)));
-
- // A reversed page selection, with an extension to itself.
- var rPageSel = new cvox.PageSelection(this.aSel.setReversed(true));
- assertFalse(rPageSel.extend(this.aSel.setReversed(true)));
- assertFalse(rPageSel.extend(this.aSel.setReversed(false)));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/platform_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/platform_util.js
deleted file mode 100644
index c1c67ed3807..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/platform_util.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Utilities for working with platforms.
- */
-
-
-goog.provide('cvox.PlatformFilter');
-goog.provide('cvox.PlatformUtil');
-
-goog.require('cvox.ChromeVox');
-
-/**
- * @enum
- */
-cvox.PlatformFilter = {
- NONE: 0,
- WINDOWS: 1,
- MAC: 2,
- LINUX: 4,
- WML: 7,
- CHROMEOS: 8,
- ANDROID: 16
-};
-
-
-/**
- *Checks whether the given filter matches the current platform. An undefined
- * filter always matches the current platform.
- * @param {undefined|cvox.PlatformFilter|number} filter The filter.
- * @return {boolean} Whether the filter matches the current platform.
- */
-cvox.PlatformUtil.matchesPlatform = function(filter) {
- var uA = navigator.userAgent;
- if (filter == undefined) {
- return true;
- } else if (uA.indexOf('Android') != -1) {
- return (filter & cvox.PlatformFilter.ANDROID) != 0;
- } else if (uA.indexOf('Win') != -1) {
- return (filter & cvox.PlatformFilter.WINDOWS) != 0;
- } else if (uA.indexOf('Mac') != -1) {
- return (filter & cvox.PlatformFilter.MAC) != 0;
- } else if (uA.indexOf('Linux') != -1) {
- return (filter & cvox.PlatformFilter.LINUX) != 0;
- } else if (uA.indexOf('CrOS') != -1) {
- return (filter & cvox.PlatformFilter.CHROMEOS) != 0;
- }
- return false;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/selection_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/selection_util.js
deleted file mode 100644
index 3057d2efc9b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/selection_util.js
+++ /dev/null
@@ -1,611 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A collection of JavaScript utilities used to improve selection
- * at different granularities.
- */
-
-
-goog.provide('cvox.SelectionUtil');
-
-goog.require('cvox.DomUtil');
-goog.require('cvox.XpathUtil');
-
-/**
- * Utilities for improving selection.
- * @constructor
- */
-cvox.SelectionUtil = function() {};
-
-/**
- * Cleans up a paragraph selection acquired by extending forward.
- * In this context, a paragraph selection is 'clean' when the focus
- * node (the end of the selection) is not on a text node.
- * @param {Selection} sel The paragraph-length selection.
- * @return {boolean} True if the selection has been cleaned.
- * False if the selection cannot be cleaned without invalid extension.
- */
-cvox.SelectionUtil.cleanUpParagraphForward = function(sel) {
- var expand = true;
-
- // nodeType:3 == TEXT_NODE
- while (sel.focusNode.nodeType == 3) {
- // Ending with a text node, which is incorrect. Keep extending forward.
- var fnode = sel.focusNode;
- var foffset = sel.focusOffset;
-
- sel.modify('extend', 'forward', 'sentence');
- if ((fnode == sel.focusNode) && (foffset == sel.focusOffset)) {
- // Nothing more to be done, cannot extend forward further.
- return false;
- }
- }
-
- return true;
-};
-
-/**
- * Cleans up a paragraph selection acquired by extending backward.
- * In this context, a paragraph selection is 'clean' when the focus
- * node (the end of the selection) is not on a text node.
- * @param {Selection} sel The paragraph-length selection.
- * @return {boolean} True if the selection has been cleaned.
- * False if the selection cannot be cleaned without invalid extension.
- */
-cvox.SelectionUtil.cleanUpParagraphBack = function(sel) {
- var expand = true;
-
- var fnode;
- var foffset;
-
- // nodeType:3 == TEXT_NODE
- while (sel.focusNode.nodeType == 3) {
- // Ending with a text node, which is incorrect. Keep extending backward.
- fnode = sel.focusNode;
- foffset = sel.focusOffset;
-
- sel.modify('extend', 'backward', 'sentence');
-
- if ((fnode == sel.focusNode) && (foffset == sel.focusOffset)) {
- // Nothing more to be done, cannot extend backward further.
- return true;
- }
- }
-
- return true;
-};
-
-/**
- * Cleans up a sentence selection by extending forward.
- * In this context, a sentence selection is 'clean' when the focus
- * node (the end of the selection) is either:
- * - not on a text node
- * - on a text node that ends with a period or a space
- * @param {Selection} sel The sentence-length selection.
- * @return {boolean} True if the selection has been cleaned.
- * False if the selection cannot be cleaned without invalid extension.
- */
-cvox.SelectionUtil.cleanUpSentence = function(sel) {
- var expand = true;
- var lastSelection;
- var lastSelectionOffset;
-
- while (expand) {
-
- // nodeType:3 == TEXT_NODE
- if (sel.focusNode.nodeType == 3) {
- // The focus node is of type text, check end for period
-
- var fnode = sel.focusNode;
- var foffset = sel.focusOffset;
-
- if (sel.rangeCount > 0 && sel.getRangeAt(0).endOffset > 0) {
- if (fnode.substringData(sel.getRangeAt(0).endOffset - 1, 1) == '.') {
- // Text node ends with period.
- return true;
- } else if (fnode.substringData(sel.getRangeAt(0).endOffset - 1, 1) ==
- ' ') {
- // Text node ends with space.
- return true;
- } else {
- // Text node does not end with period or space. Extend forward.
- sel.modify('extend', 'forward', 'sentence');
-
- if ((fnode == sel.focusNode) && (foffset == sel.focusOffset)) {
- // Nothing more to be done, cannot extend forward any further.
- return false;
- }
- }
- } else {
- return true;
- }
- } else {
- // Focus node is not text node, no further cleaning required.
- return true;
- }
- }
-
- return true;
-};
-
-/**
- * Finds the starting position (height from top and left width) of a
- * selection in a document.
- * @param {Selection} sel The selection.
- * @return {Array} The coordinates [top, left] of the selection.
- */
-cvox.SelectionUtil.findSelPosition = function(sel) {
- if (sel.rangeCount == 0) {
- return [0, 0];
- }
-
- var clientRect = sel.getRangeAt(0).getBoundingClientRect();
-
- if (!clientRect) {
- return [0, 0];
- }
-
- var top = window.pageYOffset + clientRect.top;
- var left = window.pageXOffset + clientRect.left;
- return [top, left];
-};
-
-/**
- * Calculates the horizontal and vertical position of a node
- * @param {Node} targetNode The node.
- * @return {Array} The coordinates [top, left] of the node.
- */
-cvox.SelectionUtil.findTopLeftPosition = function(targetNode) {
- var left = 0;
- var top = 0;
- var obj = targetNode;
-
- if (obj.offsetParent) {
- left = obj.offsetLeft;
- top = obj.offsetTop;
- obj = obj.offsetParent;
-
- while (obj !== null) {
- left += obj.offsetLeft;
- top += obj.offsetTop;
- obj = obj.offsetParent;
- }
- }
-
- return [top, left];
-};
-
-
-/**
- * Checks the contents of a selection for meaningful content.
- * @param {Selection} sel The selection.
- * @return {boolean} True if the selection is valid. False if the selection
- * contains only whitespace or is an empty string.
- */
-cvox.SelectionUtil.isSelectionValid = function(sel) {
- var regExpWhiteSpace = new RegExp(/^\s+$/);
- return (! ((regExpWhiteSpace.test(sel.toString())) ||
- (sel.toString() == '')));
-};
-
-/**
- * Checks the contents of a range for meaningful content.
- * @param {Range} range The range.
- * @return {boolean} True if the range is valid. False if the range
- * contains only whitespace or is an empty string.
- */
-cvox.SelectionUtil.isRangeValid = function(range) {
- var text = range.cloneContents().textContent;
- var regExpWhiteSpace = new RegExp(/^\s+$/);
- return (! ((regExpWhiteSpace.test(text)) ||
- (text == '')));
-};
-
-/**
- * Returns absolute top and left positions of an element.
- *
- * @param {!Node} node The element for which to compute the position.
- * @return {Array<number>} Index 0 is the left; index 1 is the top.
- * @private
- */
-cvox.SelectionUtil.findPos_ = function(node) {
- var curLeft = 0;
- var curTop = 0;
- if (node.offsetParent) {
- do {
- curLeft += node.offsetLeft;
- curTop += node.offsetTop;
- } while (node = node.offsetParent);
- }
- return [curLeft, curTop];
-};
-
-/**
- * Scrolls node in its parent node such the given node is visible.
- * @param {Node} focusNode The node.
- */
-cvox.SelectionUtil.scrollElementsToView = function(focusNode) {
- // First, walk up the DOM until we find a node with a bounding rectangle.
- while (focusNode && !focusNode.getBoundingClientRect) {
- focusNode = focusNode.parentElement;
- }
- if (!focusNode) {
- return;
- }
-
- // Walk up the DOM, ensuring each element is visible inside its parent.
- var node = focusNode;
- var parentNode = node.parentElement;
- while (node != document.body && parentNode) {
- node.scrollTop = node.offsetTop;
- node.scrollLeft = node.offsetLeft;
- node = parentNode;
- parentNode = node.parentElement;
- }
-
- // Center the active element on the page once we know it's visible.
- var pos = cvox.SelectionUtil.findPos_(focusNode);
- window.scrollTo(pos[0] - window.innerWidth / 2,
- pos[1] - window.innerHeight / 2);
-};
-
-/**
- * Scrolls the selection into view if it is out of view in the current window.
- * Inspired by workaround for already-on-screen elements @
- * http://
- * www.performantdesign.com/2009/08/26/scrollintoview-but-only-if-out-of-view/
- * @param {Selection} sel The selection to be scrolled into view.
- */
-cvox.SelectionUtil.scrollToSelection = function(sel) {
- if (sel.rangeCount == 0) {
- return;
- }
-
- // First, scroll all parent elements into view. Later, move the body
- // which works slightly differently.
-
- cvox.SelectionUtil.scrollElementsToView(sel.focusNode);
-
- var pos = cvox.SelectionUtil.findSelPosition(sel);
- var top = pos[0];
- var left = pos[1];
-
- var scrolledVertically = window.pageYOffset ||
- document.documentElement.scrollTop ||
- document.body.scrollTop;
- var pageHeight = window.innerHeight ||
- document.documentElement.clientHeight || document.body.clientHeight;
- var pageWidth = window.innerWidth ||
- document.documentElement.innerWidth || document.body.clientWidth;
-
- if (left < pageWidth) {
- left = 0;
- }
-
- // window.scroll puts specified pixel in upper left of window
- if ((scrolledVertically + pageHeight) < top) {
- // Align with bottom of page
- var diff = top - pageHeight;
- window.scroll(left, diff + 100);
- } else if (top < scrolledVertically) {
- // Align with top of page
- window.scroll(left, top - 100);
- }
-};
-
-/**
- * This is from https://developer.mozilla.org/en/Whitespace_in_the_DOM
- * Determine whether a node's text content is entirely whitespace.
- *
- * Throughout, whitespace is defined as one of the characters
- * "\t" TAB \u0009
- * "\n" LF \u000A
- * "\r" CR \u000D
- * " " SPC \u0020
- *
- * This does not use Javascript's "\s" because that includes non-breaking
- * spaces (and also some other characters).
- *
- * @param {Node} node A node implementing the |CharacterData| interface (i.e.,
- * a |Text|, |Comment|, or |CDATASection| node.
- * @return {boolean} True if all of the text content of |node| is whitespace,
- * otherwise false.
- */
-cvox.SelectionUtil.isAllWs = function(node) {
- // Use ECMA-262 Edition 3 String and RegExp features
- return !(/[^\t\n\r ]/.test(node.data));
-};
-
-
-/**
- * This is from https://developer.mozilla.org/en/Whitespace_in_the_DOM
- * Determine if a node should be ignored by the iterator functions.
- *
- * @param {Node} node An object implementing the DOM1 |Node| interface.
- * @return {boolean} True if the node is:
- * 1) A |Text| node that is all whitespace
- * 2) A |Comment| node
- * and otherwise false.
- */
-
-cvox.SelectionUtil.isIgnorable = function(node) {
- return (node.nodeType == 8) || // A comment node
- ((node.nodeType == 3) &&
- cvox.SelectionUtil.isAllWs(node)); // a text node, all ws
-};
-
-/**
- * This is from https://developer.mozilla.org/en/Whitespace_in_the_DOM
- * Version of |previousSibling| that skips nodes that are entirely
- * whitespace or comments. (Normally |previousSibling| is a property
- * of all DOM nodes that gives the sibling node, the node that is
- * a child of the same parent, that occurs immediately before the
- * reference node.)
- *
- * @param {Node} sib The reference node.
- * @return {Node} Either:
- * 1) The closest previous sibling to |sib| that is not
- * ignorable according to |isIgnorable|, or
- * 2) null if no such node exists.
- */
-cvox.SelectionUtil.nodeBefore = function(sib) {
- while ((sib = sib.previousSibling)) {
- if (!cvox.SelectionUtil.isIgnorable(sib)) {
- return sib;
- }
- }
- return null;
-};
-
-/**
- * This is from https://developer.mozilla.org/en/Whitespace_in_the_DOM
- * Version of |nextSibling| that skips nodes that are entirely
- * whitespace or comments.
- *
- * @param {Node} sib The reference node.
- * @return {Node} Either:
- * 1) The closest next sibling to |sib| that is not
- * ignorable according to |isIgnorable|, or
- * 2) null if no such node exists.
- */
-cvox.SelectionUtil.nodeAfter = function(sib) {
- while ((sib = sib.nextSibling)) {
- if (!cvox.SelectionUtil.isIgnorable(sib)) {
- return sib;
- }
- }
- return null;
-};
-
-/**
- * This is from https://developer.mozilla.org/en/Whitespace_in_the_DOM
- * Version of |lastChild| that skips nodes that are entirely
- * whitespace or comments. (Normally |lastChild| is a property
- * of all DOM nodes that gives the last of the nodes contained
- * directly in the reference node.)
- *
- * @param {Node} par The reference node.
- * @return {Node} Either:
- * 1) The last child of |sib| that is not
- * ignorable according to |isIgnorable|, or
- * 2) null if no such node exists.
- */
-cvox.SelectionUtil.lastChildNode = function(par) {
- var res = par.lastChild;
- while (res) {
- if (!cvox.SelectionUtil.isIgnorable(res)) {
- return res;
- }
- res = res.previousSibling;
- }
- return null;
-};
-
-/**
- * This is from https://developer.mozilla.org/en/Whitespace_in_the_DOM
- * Version of |firstChild| that skips nodes that are entirely
- * whitespace and comments.
- *
- * @param {Node} par The reference node.
- * @return {Node} Either:
- * 1) The first child of |sib| that is not
- * ignorable according to |isIgnorable|, or
- * 2) null if no such node exists.
- */
-cvox.SelectionUtil.firstChildNode = function(par) {
- var res = par.firstChild;
- while (res) {
- if (!cvox.SelectionUtil.isIgnorable(res)) {
- return res;
- }
- res = res.nextSibling;
- }
- return null;
-};
-
-/**
- * This is from https://developer.mozilla.org/en/Whitespace_in_the_DOM
- * Version of |data| that doesn't include whitespace at the beginning
- * and end and normalizes all whitespace to a single space. (Normally
- * |data| is a property of text nodes that gives the text of the node.)
- *
- * @param {Node} txt The text node whose data should be returned.
- * @return {string} A string giving the contents of the text node with
- * whitespace collapsed.
- */
-cvox.SelectionUtil.dataOf = function(txt) {
- var data = txt.data;
- // Use ECMA-262 Edition 3 String and RegExp features
- data = data.replace(/[\t\n\r ]+/g, ' ');
- if (data.charAt(0) == ' ') {
- data = data.substring(1, data.length);
- }
- if (data.charAt(data.length - 1) == ' ') {
- data = data.substring(0, data.length - 1);
- }
- return data;
-};
-
-/**
- * Returns true if the selection has content from at least one node
- * that has the specified tagName.
- *
- * @param {Selection} sel The selection.
- * @param {string} tagName Tagname that the selection should be checked for.
- * @return {boolean} True if the selection has content from at least one node
- * with the specified tagName.
- */
-cvox.SelectionUtil.hasContentWithTag = function(sel, tagName) {
- if (!sel || !sel.anchorNode || !sel.focusNode) {
- return false;
- }
- if (sel.anchorNode.tagName && (sel.anchorNode.tagName == tagName)) {
- return true;
- }
- if (sel.focusNode.tagName && (sel.focusNode.tagName == tagName)) {
- return true;
- }
- if (sel.anchorNode.parentNode.tagName &&
- (sel.anchorNode.parentNode.tagName == tagName)) {
- return true;
- }
- if (sel.focusNode.parentNode.tagName &&
- (sel.focusNode.parentNode.tagName == tagName)) {
- return true;
- }
- var docFrag = sel.getRangeAt(0).cloneContents();
- var span = document.createElement('span');
- span.appendChild(docFrag);
- return (span.getElementsByTagName(tagName).length > 0);
-};
-
-/**
- * Selects text within a text node.
- *
- * Note that the input node MUST be of type TEXT; otherwise, the offset
- * count would not mean # of characters - this is because of the way Range
- * works in JavaScript.
- *
- * @param {Node} textNode The text node to select text within.
- * @param {number} start The start of the selection.
- * @param {number} end The end of the selection.
- */
-cvox.SelectionUtil.selectText = function(textNode, start, end) {
- var newRange = document.createRange();
- newRange.setStart(textNode, start);
- newRange.setEnd(textNode, end);
- var sel = window.getSelection();
- sel.removeAllRanges();
- sel.addRange(newRange);
-};
-
-/**
- * Selects all the text in a given node.
- *
- * @param {Node} node The target node.
- */
-cvox.SelectionUtil.selectAllTextInNode = function(node) {
- var newRange = document.createRange();
- newRange.setStart(node, 0);
- newRange.setEndAfter(node);
- var sel = window.getSelection();
- sel.removeAllRanges();
- sel.addRange(newRange);
-};
-
-/**
- * Collapses the selection to the start. If nothing is selected,
- * selects the beginning of the given node.
- *
- * @param {Node} node The target node.
- */
-cvox.SelectionUtil.collapseToStart = function(node) {
- var sel = window.getSelection();
- var cursorNode = sel.anchorNode;
- var cursorOffset = sel.anchorOffset;
- if (cursorNode == null) {
- cursorNode = node;
- cursorOffset = 0;
- }
- var newRange = document.createRange();
- newRange.setStart(cursorNode, cursorOffset);
- newRange.setEnd(cursorNode, cursorOffset);
- sel.removeAllRanges();
- sel.addRange(newRange);
-};
-
-/**
- * Collapses the selection to the end. If nothing is selected,
- * selects the end of the given node.
- *
- * @param {Node} node The target node.
- */
-cvox.SelectionUtil.collapseToEnd = function(node) {
- var sel = window.getSelection();
- var cursorNode = sel.focusNode;
- var cursorOffset = sel.focusOffset;
- if (cursorNode == null) {
- cursorNode = node;
- cursorOffset = 0;
- }
- var newRange = document.createRange();
- newRange.setStart(cursorNode, cursorOffset);
- newRange.setEnd(cursorNode, cursorOffset);
- sel.removeAllRanges();
- sel.addRange(newRange);
-};
-
-/**
- * Retrieves all the text within a selection.
- *
- * Note that this can be different than simply using the string from
- * window.getSelection() as this will account for IMG nodes, etc.
- *
- * @return {string} The string of text contained in the current selection.
- */
-cvox.SelectionUtil.getText = function() {
- var sel = window.getSelection();
- if (cvox.SelectionUtil.hasContentWithTag(sel, 'IMG')) {
- var text = '';
- var docFrag = sel.getRangeAt(0).cloneContents();
- var span = document.createElement('span');
- span.appendChild(docFrag);
- var leafNodes = cvox.XpathUtil.getLeafNodes(span);
- for (var i = 0, node; node = leafNodes[i]; i++) {
- text = text + ' ' + cvox.DomUtil.getName(node);
- }
- return text;
- } else {
- return this.getSelectionText_();
- }
-};
-
-/**
- * Returns the selection as text instead of a selection object. Note that this
- * function must be used in place of getting text directly from the DOM
- * if you want i18n tests to pass.
- *
- * @return {string} The text.
- * @private
- */
-cvox.SelectionUtil.getSelectionText_ = function() {
- return '' + window.getSelection();
-};
-
-
-/**
- * Returns a range as text instead of a selection object. Note that this
- * function must be used in place of getting text directly from the DOM
- * if you want i18n tests to pass.
- *
- * @param {Range} range A range.
- * @return {string} The text.
- */
-cvox.SelectionUtil.getRangeText = function(range) {
- if (range)
- return range.cloneContents().textContent.replace(/\s+/g, ' ');
- else
- return '';
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/selection_util_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/selection_util_test.unitjs
deleted file mode 100644
index 7adbc57a8d3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/selection_util_test.unitjs
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxSelectionUtilUnitTest() {}
-
-CvoxSelectionUtilUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.SelectionUtil'
- ]
-};
-
-TEST_F('CvoxSelectionUtilUnitTest', 'SimpleFindPos', function() {
- this.loadDoc(function() {/*!
- <div id="foo" style="position:absolute;top:50px">
- </div>
- */});
- element = $('foo');
- assertEquals(cvox.SelectionUtil.findPos_(element)[1], 50);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/spannable.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/spannable.js
deleted file mode 100644
index be77ba04ae7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/spannable.js
+++ /dev/null
@@ -1,434 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Class which allows construction of annotated strings.
- */
-
-goog.provide('cvox.Spannable');
-
-goog.require('goog.object');
-
-/**
- * @constructor
- * @param {string|!cvox.Spannable=} opt_string Initial value of the spannable.
- * @param {*=} opt_annotation Initial annotation for the entire string.
- */
-cvox.Spannable = function(opt_string, opt_annotation) {
- /**
- * Underlying string.
- * @type {string}
- * @private
- */
- this.string_ = opt_string instanceof cvox.Spannable ? '' : opt_string || '';
-
- /**
- * Spans (annotations).
- * @type {!Array<!{ value: *, start: number, end: number }>}
- * @private
- */
- this.spans_ = [];
-
- // Append the initial spannable.
- if (opt_string instanceof cvox.Spannable)
- this.append(opt_string);
-
- // Optionally annotate the entire string.
- if (goog.isDef(opt_annotation)) {
- var len = this.string_.length;
- this.spans_.push({ value: opt_annotation, start: 0, end: len });
- }
-};
-
-
-/** @override */
-cvox.Spannable.prototype.toString = function() {
- return this.string_;
-};
-
-
-/**
- * Returns the length of the string.
- * @return {number} Length of the string.
- */
-cvox.Spannable.prototype.getLength = function() {
- return this.string_.length;
-};
-
-
-/**
- * Adds a span to some region of the string.
- * @param {*} value Annotation.
- * @param {number} start Starting index (inclusive).
- * @param {number} end Ending index (exclusive).
- */
-cvox.Spannable.prototype.setSpan = function(value, start, end) {
- this.removeSpan(value);
- if (0 <= start && start <= end && end <= this.string_.length) {
- // Zero-length spans are explicitly allowed, because it is possible to
- // query for position by annotation as well as the reverse.
- this.spans_.push({ value: value, start: start, end: end });
- this.spans_.sort(function(a, b) {
- var ret = a.start - b.start;
- if (ret == 0)
- ret = a.end - b.end;
- return ret;
- });
- } else {
- throw new RangeError('span out of range (start=' + start +
- ', end=' + end + ', len=' + this.string_.length + ')');
- }
-};
-
-
-/**
- * Removes a span.
- * @param {*} value Annotation.
- */
-cvox.Spannable.prototype.removeSpan = function(value) {
- for (var i = this.spans_.length - 1; i >= 0; i--) {
- if (this.spans_[i].value === value) {
- this.spans_.splice(i, 1);
- }
- }
-};
-
-
-/**
- * Appends another Spannable or string to this one.
- * @param {string|!cvox.Spannable} other String or spannable to concatenate.
- */
-cvox.Spannable.prototype.append = function(other) {
- if (other instanceof cvox.Spannable) {
- var otherSpannable = /** @type {!cvox.Spannable} */ (other);
- var originalLength = this.getLength();
- this.string_ += otherSpannable.string_;
- other.spans_.forEach(goog.bind(function(span) {
- this.setSpan(
- span.value,
- span.start + originalLength,
- span.end + originalLength);
- }, this));
- } else if (typeof other === 'string') {
- this.string_ += /** @type {string} */ (other);
- }
-};
-
-
-/**
- * Returns the first value matching a position.
- * @param {number} position Position to query.
- * @return {*} Value annotating that position, or undefined if none is found.
- */
-cvox.Spannable.prototype.getSpan = function(position) {
- for (var i = 0; i < this.spans_.length; i++) {
- var span = this.spans_[i];
- if (span.start <= position && position < span.end) {
- return span.value;
- }
- }
-};
-
-
-/**
- * Returns the first span value which is an instance of a given constructor.
- * @param {!Function} constructor Constructor.
- * @return {!Object|undefined} Object if found; undefined otherwise.
- */
-cvox.Spannable.prototype.getSpanInstanceOf = function(constructor) {
- for (var i = 0; i < this.spans_.length; i++) {
- var span = this.spans_[i];
- if (span.value instanceof constructor) {
- return span.value;
- }
- }
-};
-
-/**
- * Returns all span values which are an instance of a given constructor.
- * Spans are returned in the order of their starting index and ending index
- * for spans with equals tarting indices.
- * @param {!Function} constructor Constructor.
- * @return {!Array<Object>} Array of object.
- */
-cvox.Spannable.prototype.getSpansInstanceOf = function(constructor) {
- var ret = [];
- for (var i = 0; i < this.spans_.length; i++) {
- var span = this.spans_[i];
- if (span.value instanceof constructor) {
- ret.push(span.value);
- }
- }
- return ret;
-};
-
-
-/**
- * Returns all spans matching a position.
- * @param {number} position Position to query.
- * @return {!Array} Values annotating that position.
- */
-cvox.Spannable.prototype.getSpans = function(position) {
- var results = [];
- for (var i = 0; i < this.spans_.length; i++) {
- var span = this.spans_[i];
- if (span.start <= position && position < span.end) {
- results.push(span.value);
- }
- }
- return results;
-};
-
-
-/**
- * Returns the start of the requested span.
- * @param {*} value Annotation.
- * @return {number|undefined} Start of the span, or undefined if not attached.
- */
-cvox.Spannable.prototype.getSpanStart = function(value) {
- for (var i = 0; i < this.spans_.length; i++) {
- var span = this.spans_[i];
- if (span.value === value) {
- return span.start;
- }
- }
- return undefined;
-};
-
-
-/**
- * Returns the end of the requested span.
- * @param {*} value Annotation.
- * @return {number|undefined} End of the span, or undefined if not attached.
- */
-cvox.Spannable.prototype.getSpanEnd = function(value) {
- for (var i = 0; i < this.spans_.length; i++) {
- var span = this.spans_[i];
- if (span.value === value) {
- return span.end;
- }
- }
- return undefined;
-};
-
-
-/**
- * Returns a substring of this spannable.
- * Note that while similar to String#substring, this function is much less
- * permissive about its arguments. It does not accept arguments in the wrong
- * order or out of bounds.
- *
- * @param {number} start Start index, inclusive.
- * @param {number=} opt_end End index, exclusive.
- * If excluded, the length of the string is used instead.
- * @return {!cvox.Spannable} Substring requested.
- */
-cvox.Spannable.prototype.substring = function(start, opt_end) {
- var end = goog.isDef(opt_end) ? opt_end : this.string_.length;
-
- if (start < 0 || end > this.string_.length || start > end) {
- throw new RangeError('substring indices out of range');
- }
-
- var result = new cvox.Spannable(this.string_.substring(start, end));
- for (var i = 0; i < this.spans_.length; i++) {
- var span = this.spans_[i];
- if (span.start <= end && span.end >= start) {
- var newStart = Math.max(0, span.start - start);
- var newEnd = Math.min(end - start, span.end - start);
- result.spans_.push({ value: span.value, start: newStart, end: newEnd });
- }
- }
- return result;
-};
-
-
-/**
- * Trims whitespace from the beginning.
- * @return {!cvox.Spannable} String with whitespace removed.
- */
-cvox.Spannable.prototype.trimLeft = function() {
- return this.trim_(true, false);
-};
-
-
-/**
- * Trims whitespace from the end.
- * @return {!cvox.Spannable} String with whitespace removed.
- */
-cvox.Spannable.prototype.trimRight = function() {
- return this.trim_(false, true);
-};
-
-
-/**
- * Trims whitespace from the beginning and end.
- * @return {!cvox.Spannable} String with whitespace removed.
- */
-cvox.Spannable.prototype.trim = function() {
- return this.trim_(true, true);
-};
-
-
-/**
- * Trims whitespace from either the beginning and end or both.
- * @param {boolean} trimStart Trims whitespace from the start of a string.
- * @param {boolean} trimEnd Trims whitespace from the end of a string.
- * @return {!cvox.Spannable} String with whitespace removed.
- * @private
- */
-cvox.Spannable.prototype.trim_ = function(trimStart, trimEnd) {
- if (!trimStart && !trimEnd) {
- return this;
- }
-
- // Special-case whitespace-only strings, including the empty string.
- // As an arbitrary decision, we treat this as trimming the whitespace off the
- // end, rather than the beginning, of the string.
- // This choice affects which spans are kept.
- if (/^\s*$/.test(this.string_)) {
- return this.substring(0, 0);
- }
-
- // Otherwise, we have at least one non-whitespace character to use as an
- // anchor when trimming.
- var trimmedStart = trimStart ? this.string_.match(/^\s*/)[0].length : 0;
- var trimmedEnd = trimEnd ?
- this.string_.match(/\s*$/).index : this.string_.length;
- return this.substring(trimmedStart, trimmedEnd);
-};
-
-
-/**
- * Returns this spannable to a json serializable form, including the text and
- * span objects whose types have been registered with registerSerializableSpan
- * or registerStatelessSerializableSpan.
- * @return {!cvox.Spannable.SerializedSpannable_} the json serializable form.
- */
-cvox.Spannable.prototype.toJson = function() {
- var result = {};
- result.string = this.string_;
- result.spans = [];
- for (var i = 0; i < this.spans_.length; ++i) {
- var span = this.spans_[i];
- // Use linear search, since using functions as property keys
- // is not reliable.
- var serializeInfo = goog.object.findValue(
- cvox.Spannable.serializableSpansByName_,
- function(v) { return v.ctor === span.value.constructor; });
- if (serializeInfo) {
- var spanObj = {type: serializeInfo.name,
- start: span.start,
- end: span.end};
- if (serializeInfo.toJson) {
- spanObj.value = serializeInfo.toJson.apply(span.value);
- }
- result.spans.push(spanObj);
- }
- }
- return result;
-};
-
-
-/**
- * Creates a spannable from a json serializable representation.
- * @param {!cvox.Spannable.SerializedSpannable_} obj object containing the
- * serializable representation.
- * @return {!cvox.Spannable}
- */
-cvox.Spannable.fromJson = function(obj) {
- if (typeof obj.string !== 'string') {
- throw 'Invalid spannable json object: string field not a string';
- }
- if (!(obj.spans instanceof Array)) {
- throw 'Invalid spannable json object: no spans array';
- }
- var result = new cvox.Spannable(obj.string);
- for (var i = 0, span; span = obj.spans[i]; ++i) {
- if (typeof span.type !== 'string') {
- throw 'Invalid span in spannable json object: type not a string';
- }
- if (typeof span.start !== 'number' || typeof span.end !== 'number') {
- throw 'Invalid span in spannable json object: start or end not a number';
- }
- var serializeInfo = cvox.Spannable.serializableSpansByName_[span.type];
- var value = serializeInfo.fromJson(span.value);
- result.setSpan(value, span.start, span.end);
- }
- return result;
-};
-
-
-/**
- * Registers a type that can be converted to a json serializable format.
- * @param {!Function} constructor The type of object that can be converted.
- * @param {string} name String identifier used in the serializable format.
- * @param {function(!Object): !Object} fromJson A function that converts
- * the serializable object to an actual object of this type.
- * @param {function(!Object): !Object} toJson A function that converts
- * this object to a json serializable object. The function will
- * be called with this set to the object to convert.
- */
-cvox.Spannable.registerSerializableSpan = function(
- constructor, name, fromJson, toJson) {
- var obj = {name: name, ctor: constructor,
- fromJson: fromJson, toJson: toJson};
- cvox.Spannable.serializableSpansByName_[name] = obj;
-};
-
-
-/**
- * Registers an object type that can be converted to/from a json serializable
- * form. Objects of this type carry no state that will be preserved
- * when serialized.
- * @param {!Function} constructor The type of the object that can be converted.
- * This constructor will be called with no arguments to construct
- * new objects.
- * @param {string} name Name of the type used in the serializable object.
- */
-cvox.Spannable.registerStatelessSerializableSpan = function(
- constructor, name) {
- var obj = {name: name, ctor: constructor, toJson: undefined};
- /**
- * @param {!Object} obj
- * @return {!Object}
- */
- obj.fromJson = function(obj) {
- return new constructor();
- };
- cvox.Spannable.serializableSpansByName_[name] = obj;
-};
-
-
-/**
- * Describes how to convert a span type to/from serializable json.
- * @typedef {{ctor: !Function, name: string,
- * fromJson: function(!Object): !Object,
- * toJson: ((function(!Object): !Object)|undefined)}}
- * @private
- */
-cvox.Spannable.SerializeInfo_;
-
-
-/**
- * The serialized format of a spannable.
- * @typedef {{string: string, spans: Array<cvox.Spannable.SerializedSpan_>}}
- * @private
- */
-cvox.Spannable.SerializedSpannable_;
-
-
-/**
- * The format of a single annotation in a serialized spannable.
- * @typedef {{type: string, value: !Object, start: number, end: number}}
- * @private
- */
-cvox.Spannable.SerializedSpan_;
-
-/**
- * Maps type names to serialization info objects.
- * @type {Object<cvox.Spannable.SerializeInfo_>}
- * @private
- */
-cvox.Spannable.serializableSpansByName_ = {};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/spannable_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/spannable_test.unitjs
deleted file mode 100644
index 8a26cfeb5d3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/spannable_test.unitjs
+++ /dev/null
@@ -1,481 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-UnserializableSpan = function() {};
-
-StatelessSerializableSpan = function() {};
-
-NonStatelessSerializableSpan = function(value) {
- this.value = value;
-};
-
-/**
- * @param {!Object} obj object containing the
- * serializable representation.
- * @return {!Object} The Spannable.
- */
-NonStatelessSerializableSpan.fromJson = function(obj) {
- return new NonStatelessSerializableSpan(obj.value / 2);
-};
-
-/**
- * @return {Object} the json serializable form.
- */
-NonStatelessSerializableSpan.prototype.toJson = function() {
- return {value: this.value * 2};
-};
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxSpannableUnitTest() {}
-
-CvoxSpannableUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.Spannable',
- ],
-
- /** @override */
- setUp: function() {
- cvox.Spannable.registerStatelessSerializableSpan(
- StatelessSerializableSpan, 'StatelessSerializableSpan');
-
- cvox.Spannable.registerSerializableSpan(
- NonStatelessSerializableSpan, 'NonStatelessSerializableSpan',
- NonStatelessSerializableSpan.fromJson,
- NonStatelessSerializableSpan.prototype.toJson);
- }
-};
-
-TEST_F('CvoxSpannableUnitTest', 'ToStringUnannotated', function() {
- assertEquals('', new cvox.Spannable().toString());
- assertEquals('hello world', new cvox.Spannable('hello world').toString());
-});
-
-/** Tests that toString works correctly on annotated strings. */
-TEST_F('CvoxSpannableUnitTest', 'ToStringAnnotated', function() {
- var spannable = new cvox.Spannable('Hello Google');
- spannable.setSpan('http://www.google.com/', 6, 12);
- assertEquals('Hello Google', spannable.toString());
-});
-
-/** Tests the length calculation. */
-TEST_F('CvoxSpannableUnitTest', 'GetLength', function() {
- var spannable = new cvox.Spannable('Hello');
- spannable.setSpan({}, 0, 3);
- assertEquals(5, spannable.getLength());
- spannable.append(' world');
- assertEquals(11, spannable.getLength());
- spannable.append(new cvox.Spannable(' from cvox.Spannable'));
- assertEquals(31, spannable.getLength());
-});
-
-/** Tests that a span can be added and retrieved at the beginning. */
-TEST_F('CvoxSpannableUnitTest', 'SpanBeginning', function() {
- var annotation = {};
- var spannable = new cvox.Spannable('Hello world');
- spannable.setSpan(annotation, 0, 5);
- assertSame(annotation, spannable.getSpan(0));
- assertSame(annotation, spannable.getSpan(3));
- assertUndefined(spannable.getSpan(5));
- assertUndefined(spannable.getSpan(8));
-});
-
-/** Tests that a span can be added and retrieved at the beginning. */
-TEST_F('CvoxSpannableUnitTest', 'SpanEnd', function() {
- var annotation = {};
- var spannable = new cvox.Spannable('Hello world');
- spannable.setSpan(annotation, 6, 11);
- assertUndefined(spannable.getSpan(3));
- assertUndefined(spannable.getSpan(5));
- assertSame(annotation, spannable.getSpan(6));
- assertSame(annotation, spannable.getSpan(10));
-});
-
-/** Tests that a zero-length span is not retrieved. */
-TEST_F('CvoxSpannableUnitTest', 'SpanZeroLength', function() {
- var annotation = {};
- var spannable = new cvox.Spannable('Hello world');
- spannable.setSpan(annotation, 3, 3);
- assertUndefined(spannable.getSpan(2));
- assertUndefined(spannable.getSpan(3));
- assertUndefined(spannable.getSpan(4));
-});
-
-/** Tests that a removed span is not returned. */
-TEST_F('CvoxSpannableUnitTest', 'RemoveSpan', function() {
- var annotation = {};
- var spannable = new cvox.Spannable('Hello world');
- spannable.setSpan(annotation, 0, 3);
- assertSame(annotation, spannable.getSpan(1));
- spannable.removeSpan(annotation);
- assertUndefined(spannable.getSpan(1));
-});
-
-/** Tests that adding a span in one place removes it from another. */
-TEST_F('CvoxSpannableUnitTest', 'SetSpanMoves', function() {
- var annotation = {};
- var spannable = new cvox.Spannable('Hello world');
- spannable.setSpan(annotation, 0, 3);
- assertSame(annotation, spannable.getSpan(1));
- assertUndefined(spannable.getSpan(4));
- spannable.setSpan(annotation, 3, 6);
- assertUndefined(spannable.getSpan(1));
- assertSame(annotation, spannable.getSpan(4));
-});
-
-/** Tests that setSpan objects to out-of-range arguments. */
-TEST_F('CvoxSpannableUnitTest', 'SetSpanRangeError', function() {
- var spannable = new cvox.Spannable('Hello world');
-
- // Start index out of range.
- assertException('expected range error', function() {
- spannable.setSpan({}, -1, 0);
- }, 'RangeError');
-
- // End index out of range.
- assertException('expected range error', function() {
- spannable.setSpan({}, 0, 12);
- }, 'RangeError');
-
- // End before start.
- assertException('expected range error', function() {
- spannable.setSpan({}, 1, 0);
- }, 'RangeError');
-});
-
-/**
- * Tests that multiple spans can be retrieved at one point.
- * The first one added which applies should be returned by getSpan.
- */
-TEST_F('CvoxSpannableUnitTest', 'MultipleSpans', function() {
- var annotation1 = { number: 1 };
- var annotation2 = { number: 2 };
- assertNotSame(annotation1, annotation2);
- var spannable = new cvox.Spannable('Hello world');
- spannable.setSpan(annotation1, 1, 4);
- spannable.setSpan(annotation2, 2, 7);
- assertSame(annotation1, spannable.getSpan(1));
- assertThat([annotation1], eqJSON(spannable.getSpans(1)));
- assertSame(annotation1, spannable.getSpan(3));
- assertThat([annotation1, annotation2], eqJSON(spannable.getSpans(3)));
- assertSame(annotation2, spannable.getSpan(6));
- assertThat([annotation2], eqJSON(spannable.getSpans(6)));
-});
-
-/** Tests that appending appends the strings. */
-TEST_F('CvoxSpannableUnitTest', 'AppendToString', function() {
- var spannable = new cvox.Spannable('Google');
- assertEquals('Google', spannable.toString());
- spannable.append(' Chrome');
- assertEquals('Google Chrome', spannable.toString());
- spannable.append(new cvox.Spannable('Vox'));
- assertEquals('Google ChromeVox', spannable.toString());
-});
-
-/**
- * Tests that appending Spannables combines annotations.
- */
-TEST_F('CvoxSpannableUnitTest', 'AppendAnnotations', function() {
- var annotation1 = { number: 1 };
- var annotation2 = { number: 2 };
- assertNotSame(annotation1, annotation2);
- var left = new cvox.Spannable('hello');
- left.setSpan(annotation1, 0, 3);
- var right = new cvox.Spannable(' world');
- right.setSpan(annotation2, 0, 3);
- left.append(right);
- assertSame(annotation1, left.getSpan(1));
- assertSame(annotation2, left.getSpan(6));
-});
-
-/**
- * Tests that a span's bounds can be retrieved.
- */
-TEST_F('CvoxSpannableUnitTest', 'GetSpanStartAndEnd', function() {
- var annotation = {};
- var spannable = new cvox.Spannable('potato wedges');
- spannable.setSpan(annotation, 8, 12);
- assertEquals(8, spannable.getSpanStart(annotation));
- assertEquals(12, spannable.getSpanEnd(annotation));
-});
-
-/**
- * Tests that an absent span's bounds are reported correctly.
- */
-TEST_F('CvoxSpannableUnitTest', 'GetSpanStartAndEndAbsent', function() {
- var annotation = {};
- var spannable = new cvox.Spannable('potato wedges');
- assertUndefined(spannable.getSpanStart(annotation));
- assertUndefined(spannable.getSpanEnd(annotation));
-});
-
-/**
- * Test that a zero length span can still be found.
- */
-TEST_F('CvoxSpannableUnitTest', 'GetSpanStartAndEndZeroLength', function() {
- var annotation = {};
- var spannable = new cvox.Spannable('potato wedges');
- spannable.setSpan(annotation, 8, 8);
- assertEquals(8, spannable.getSpanStart(annotation));
- assertEquals(8, spannable.getSpanEnd(annotation));
-});
-
-/**
- * Tests that == (but not ===) objects are treated distinctly when getting
- * span bounds.
- */
-TEST_F('CvoxSpannableUnitTest', 'GetSpanStartAndEndEquality', function() {
- // Note that 0 == '' and '' == 0 in JavaScript.
- var spannable = new cvox.Spannable('wat');
- spannable.setSpan(0, 0, 0);
- spannable.setSpan('', 1, 3);
- assertEquals(0, spannable.getSpanStart(0));
- assertEquals(0, spannable.getSpanEnd(0));
- assertEquals(1, spannable.getSpanStart(''));
- assertEquals(3, spannable.getSpanEnd(''));
-});
-
-/**
- * Tests that substrings have the correct character sequence.
- */
-TEST_F('CvoxSpannableUnitTest', 'Substring', function() {
- var assertSubstringResult = function(expected, initial, start, opt_end) {
- var spannable = new cvox.Spannable(initial);
- var substring = spannable.substring(start, opt_end);
- assertEquals(expected, substring.toString());
- };
- assertSubstringResult('Page', 'Google PageRank', 7, 11);
- assertSubstringResult('Goog', 'Google PageRank', 0, 4);
- assertSubstringResult('Rank', 'Google PageRank', 11, 15);
- assertSubstringResult('Rank', 'Google PageRank', 11);
-});
-
-/**
- * Tests that substring arguments are validated properly.
- */
-TEST_F('CvoxSpannableUnitTest', 'SubstringRangeError', function() {
- var assertRangeError = function(initial, start, opt_end) {
- var spannable = new cvox.Spannable(initial);
- assertException('expected range error', function() {
- spannable.substring(start, opt_end);
- }, 'RangeError');
- };
- assertRangeError('Google PageRank', -1, 5);
- assertRangeError('Google PageRank', 0, 99);
- assertRangeError('Google PageRank', 5, 2);
-});
-
-/**
- * Tests that spans in the substring range are preserved.
- */
-TEST_F('CvoxSpannableUnitTest', 'SubstringSpansIncluded', function() {
- var assertSpanIncluded = function(expectedSpanStart, expectedSpanEnd,
- initial, initialSpanStart, initialSpanEnd, start, opt_end) {
- var annotation = {};
- var spannable = new cvox.Spannable(initial);
- spannable.setSpan(annotation, initialSpanStart, initialSpanEnd);
- var substring = spannable.substring(start, opt_end);
- assertEquals(expectedSpanStart, substring.getSpanStart(annotation));
- assertEquals(expectedSpanEnd, substring.getSpanEnd(annotation));
- };
- assertSpanIncluded(1, 5, 'potato wedges', 8, 12, 7);
- assertSpanIncluded(1, 5, 'potato wedges', 8, 12, 7, 13);
- assertSpanIncluded(1, 5, 'potato wedges', 8, 12, 7, 12);
- assertSpanIncluded(0, 4, 'potato wedges', 8, 12, 8, 12);
- assertSpanIncluded(0, 3, 'potato wedges', 0, 3, 0);
- assertSpanIncluded(0, 3, 'potato wedges', 0, 3, 0, 3);
- assertSpanIncluded(0, 3, 'potato wedges', 0, 3, 0, 6);
- assertSpanIncluded(0, 5, 'potato wedges', 8, 13, 8);
- assertSpanIncluded(0, 5, 'potato wedges', 8, 13, 8, 13);
- assertSpanIncluded(1, 6, 'potato wedges', 8, 13, 7, 13);
-
- // Note: we should keep zero-length spans, even at the edges of the range.
- assertSpanIncluded(0, 0, 'potato wedges', 0, 0, 0, 0);
- assertSpanIncluded(0, 0, 'potato wedges', 0, 0, 0, 6);
- assertSpanIncluded(1, 1, 'potato wedges', 8, 8, 7, 13);
- assertSpanIncluded(6, 6, 'potato wedges', 6, 6, 0, 6);
-});
-
-/**
- * Tests that spans outside the range are omitted.
- * It's fine to keep zero-length spans at the ends, though.
- */
-TEST_F('CvoxSpannableUnitTest', 'SubstringSpansExcluded', function() {
- var assertSpanExcluded = function(initial, spanStart, spanEnd,
- start, opt_end) {
- var annotation = {};
- var spannable = new cvox.Spannable(initial);
- spannable.setSpan(annotation, spanStart, spanEnd);
- var substring = spannable.substring(start, opt_end);
- assertUndefined(substring.getSpanStart(annotation));
- assertUndefined(substring.getSpanEnd(annotation));
- };
- assertSpanExcluded('potato wedges', 8, 12, 0, 6);
- assertSpanExcluded('potato wedges', 7, 12, 0, 6);
- assertSpanExcluded('potato wedges', 0, 6, 8);
- assertSpanExcluded('potato wedges', 6, 6, 8);
-});
-
-/**
- * Tests that spans which cross the boundary are clipped.
- */
-TEST_F('CvoxSpannableUnitTest', 'SubstringSpansClipped', function() {
- var assertSpanIncluded = function(expectedSpanStart, expectedSpanEnd,
- initial, initialSpanStart, initialSpanEnd, start, opt_end) {
- var annotation = {};
- var spannable = new cvox.Spannable(initial);
- spannable.setSpan(annotation, initialSpanStart, initialSpanEnd);
- var substring = spannable.substring(start, opt_end);
- assertEquals(expectedSpanStart, substring.getSpanStart(annotation));
- assertEquals(expectedSpanEnd, substring.getSpanEnd(annotation));
- };
- assertSpanIncluded(0, 4, 'potato wedges', 7, 13, 8, 12);
- assertSpanIncluded(0, 0, 'potato wedges', 0, 6, 0, 0);
- assertSpanIncluded(0, 0, 'potato wedges', 0, 6, 6, 6);
-
- // The first of the above should produce "edge".
- assertEquals('edge',
- new cvox.Spannable('potato wedges').substring(8, 12).toString());
-});
-
-/**
- * Tests that whitespace is trimmed.
- */
-TEST_F('CvoxSpannableUnitTest', 'Trim', function() {
- var assertTrimResult = function(expected, initial) {
- assertEquals(expected, new cvox.Spannable(initial).trim().toString());
- };
- assertTrimResult('John F. Kennedy', 'John F. Kennedy');
- assertTrimResult('John F. Kennedy', ' John F. Kennedy');
- assertTrimResult('John F. Kennedy', 'John F. Kennedy ');
- assertTrimResult('John F. Kennedy', ' \r\t \nJohn F. Kennedy\n\n \n');
- assertTrimResult('', '');
- assertTrimResult('', ' \t\t \n\r');
-});
-
-/**
- * Tests that trim keeps, drops and clips spans.
- */
-TEST_F('CvoxSpannableUnitTest', 'TrimSpans', function() {
- var spannable = new cvox.Spannable(' \t Kennedy\n');
- spannable.setSpan('tab', 1, 2);
- spannable.setSpan('jfk', 3, 10);
- spannable.setSpan('jfk-newline', 3, 11);
- var trimmed = spannable.trim();
- assertUndefined(trimmed.getSpanStart('tab'));
- assertUndefined(trimmed.getSpanEnd('tab'));
- assertEquals(0, trimmed.getSpanStart('jfk'));
- assertEquals(7, trimmed.getSpanEnd('jfk'));
- assertEquals(0, trimmed.getSpanStart('jfk-newline'));
- assertEquals(7, trimmed.getSpanEnd('jfk-newline'));
-});
-
-/**
- * Tests that when a string is all whitespace, we trim off the *end*.
- */
-TEST_F('CvoxSpannableUnitTest', 'TrimAllWhitespace', function() {
- var spannable = new cvox.Spannable(' ');
- spannable.setSpan('cursor 1', 0, 0);
- spannable.setSpan('cursor 2', 2, 2);
- var trimmed = spannable.trim();
- assertEquals(0, trimmed.getSpanStart('cursor 1'));
- assertEquals(0, trimmed.getSpanEnd('cursor 1'));
- assertUndefined(trimmed.getSpanStart('cursor 2'));
- assertUndefined(trimmed.getSpanEnd('cursor 2'));
-});
-
-/**
- * Tests finding a span which is an instance of a given class.
- */
-TEST_F('CvoxSpannableUnitTest', 'GetSpanInstanceOf', function() {
- function ExampleConstructorBase() {}
- function ExampleConstructor1() {}
- function ExampleConstructor2() {}
- function ExampleConstructor3() {}
- ExampleConstructor1.prototype = new ExampleConstructorBase();
- ExampleConstructor2.prototype = new ExampleConstructorBase();
- ExampleConstructor3.prototype = new ExampleConstructorBase();
- var ex1 = new ExampleConstructor1();
- var ex2 = new ExampleConstructor2();
- var spannable = new cvox.Spannable('Hello world');
- spannable.setSpan(ex1, 0, 0);
- spannable.setSpan(ex2, 1, 1);
- assertEquals(ex1, spannable.getSpanInstanceOf(ExampleConstructor1));
- assertEquals(ex2, spannable.getSpanInstanceOf(ExampleConstructor2));
- assertUndefined(spannable.getSpanInstanceOf(ExampleConstructor3));
- assertEquals(ex1, spannable.getSpanInstanceOf(ExampleConstructorBase));
-});
-
-/** Tests trimming only left or right. */
-TEST_F('CvoxSpannableUnitTest', 'TrimLeftOrRight', function() {
- var spannable = new cvox.Spannable(' ');
- spannable.setSpan('cursor 1', 0, 0);
- spannable.setSpan('cursor 2', 2, 2);
- var trimmed = spannable.trimLeft();
- assertEquals(0, trimmed.getSpanStart('cursor 1'));
- assertEquals(0, trimmed.getSpanEnd('cursor 1'));
- assertUndefined(trimmed.getSpanStart('cursor 2'));
- assertUndefined(trimmed.getSpanEnd('cursor 2'));
-
- var spannable2 = new cvox.Spannable('0 ');
- spannable2.setSpan('cursor 1', 0, 0);
- spannable2.setSpan('cursor 2', 2, 2);
- var trimmed2 = spannable2.trimLeft();
- assertEquals(0, trimmed2.getSpanStart('cursor 1'));
- assertEquals(0, trimmed2.getSpanEnd('cursor 1'));
- assertEquals(2, trimmed2.getSpanStart('cursor 2'));
- assertEquals(2, trimmed2.getSpanEnd('cursor 2'));
- trimmed2 = trimmed2.trimRight();
- assertEquals(0, trimmed2.getSpanStart('cursor 1'));
- assertEquals(0, trimmed2.getSpanEnd('cursor 1'));
- assertUndefined(trimmed2.getSpanStart('cursor 2'));
- assertUndefined(trimmed2.getSpanEnd('cursor 2'));
-
- var spannable3 = new cvox.Spannable(' 0');
- spannable3.setSpan('cursor 1', 0, 0);
- spannable3.setSpan('cursor 2', 2, 2);
- var trimmed3 = spannable3.trimRight();
- assertEquals(0, trimmed3.getSpanStart('cursor 1'));
- assertEquals(0, trimmed3.getSpanEnd('cursor 1'));
- assertEquals(2, trimmed3.getSpanStart('cursor 2'));
- assertEquals(2, trimmed3.getSpanEnd('cursor 2'));
- trimmed3 = trimmed3.trimLeft();
- assertUndefined(trimmed3.getSpanStart('cursor 1'));
- assertUndefined(trimmed3.getSpanEnd('cursor 1'));
- assertEquals(0, trimmed3.getSpanStart('cursor 2'));
- assertEquals(0, trimmed3.getSpanEnd('cursor 2'));
-});
-
-TEST_F('CvoxSpannableUnitTest', 'Serialize', function() {
- var fresh = new cvox.Spannable('text');
- var freshStatelessSerializable = new StatelessSerializableSpan();
- var freshNonStatelessSerializable = new NonStatelessSerializableSpan(14);
- fresh.setSpan(new UnserializableSpan(), 0, 1);
- fresh.setSpan(freshStatelessSerializable, 0, 2);
- fresh.setSpan(freshNonStatelessSerializable, 3, 4);
- var thawn = cvox.Spannable.fromJson(fresh.toJson());
- var thawnStatelessSerializable = thawn.getSpanInstanceOf(
- StatelessSerializableSpan);
- var thawnNonStatelessSerializable = thawn.getSpanInstanceOf(
- NonStatelessSerializableSpan);
- assertThat('text', eqJSON(thawn.toString()));
- assertUndefined(thawn.getSpanInstanceOf(UnserializableSpan));
- assertThat(
- fresh.getSpanStart(freshStatelessSerializable),
- eqJSON(thawn.getSpanStart(thawnStatelessSerializable)));
- assertThat(
- fresh.getSpanEnd(freshStatelessSerializable),
- eqJSON(thawn.getSpanEnd(thawnStatelessSerializable)));
- assertThat(freshNonStatelessSerializable,
- eqJSON(thawnNonStatelessSerializable));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/string_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/string_util.js
deleted file mode 100644
index 5b771c5a774..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/string_util.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Utilities for strings.
- */
-
-goog.provide('StringUtil');
-
-/**
- * @constructor
- */
-StringUtil = function() {};
-
-/**
- * Returns the length of the longest common prefix of two strings.
- * @param {string} first The first string.
- * @param {string} second The second string.
- * @return {number} The length of the longest common prefix, which may be 0
- * for an empty common prefix.
- */
-StringUtil.longestCommonPrefixLength = function(first, second) {
- var limit = Math.min(first.length, second.length);
- var i;
- for (i = 0; i < limit; ++i) {
- if (first.charAt(i) != second.charAt(i)) {
- break;
- }
- }
- return i;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/string_util_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/common/string_util_test.unitjs
deleted file mode 100644
index efd31a5afdb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/string_util_test.unitjs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Include test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function StringUtilUnitTest() {
- ChromeVoxUnitTestBase.call(this);
-}
-
-StringUtilUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'StringUtil',
- ],
-};
-
-TEST_F('StringUtilUnitTest', 'longestCommonPrefixLength', function() {
- var lcpl = StringUtil.longestCommonPrefixLength;
- assertEquals(0, lcpl('', ''));
- assertEquals(0, lcpl('', 'hello'));
- assertEquals(0, lcpl('hello', ''));
- assertEquals(1, lcpl('hi', 'hello'));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/table_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/table_util.js
deleted file mode 100644
index ec22512c1a5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/table_util.js
+++ /dev/null
@@ -1,179 +0,0 @@
-// 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.
-
-/**
- * @fileoverview DOM utility functions to aid in table navigation.
- */
-
-goog.provide('cvox.TableUtil');
-
-goog.require('cvox.XpathUtil');
-
-
-/**
- * Utility function to check if a particular table cell is a candidate
- * header cell.
- * @param {Node} cell The table cell.
- * @return {boolean} Whether or not the table cell is acting as a header cell.
- */
-cvox.TableUtil.checkIfHeader = function(cell) {
- /*
- * Headers are defined here as <TH> or <TD> elements. <TD> elements when
- * serving as header cells must have either:
- * - The scope attribute defined
- * - Their IDs referenced in the header content attribute of another <TD> or
- * <TH> element.
- * This function does not check whether this cell is referenced by another
- * <TD>. So this function by itself will not be able to gather all possible
- * header cells when applied across all table cells.
- *
- * Please Note:
- * The HTML5 spec specifies that only header <TH> elements can be headers
- * ( http://dev.w3.org/html5/spec/tabular-data.html#row-header ) but the
- * HTML4 spec says that <TD> elements can act as headers if they have a
- * scope attribute defined
- * ( http://www.w3.org/TR/html401/struct/tables.html#h-11.2.6 ). In the
- * interest of providing meaningful header information for all tables, here
- * we take the position that <TD> elements can act as headers.
- */
- return ((cell.tagName == 'TH') ||
- cell.hasAttribute('scope') || (cell.hasAttribute('role') &&
- ((cell.getAttribute('role') == 'rowheader') ||
- (cell.getAttribute('role') == 'columnheader'))));
-};
-
-
-/**
- * Utility function to determine colgroup structure. Builds an array that
- * associates a column number to a particular col group.
- * @param {Array} colGroups An array of all the colgroup elements in a
- * particular table.
- * @return {Array} An array that maps indexes representing table columns
- * to indexes into the colGroups array.
- */
-cvox.TableUtil.determineColGroups = function(colGroups) {
- var colToColGroup = [];
-
- if (colGroups.length == 0) {
- return colToColGroup;
- }
- // A colgroup has either a series of col element children or a span
- // attribute. If it has col children, ignore the span attribute
- for (var colGroupCtr = 0; colGroupCtr < colGroups.length;
- colGroupCtr++) {
-
- var currentColGroup = colGroups[colGroupCtr];
-
- var childCols = cvox.TableUtil.getColNodes(currentColGroup);
- if (childCols.length > 0) {
- for (var colNodeCtr = 0; colNodeCtr < childCols.length;
- colNodeCtr++) {
- var colElement = childCols[colNodeCtr];
-
- if (colElement.hasAttribute('span')) {
- var span = parseInt(colElement.getAttribute('span'), 10);
-
- for (var s = 0; s < span; s++) {
- colToColGroup.push(colGroupCtr);
- }
- } else {
- colToColGroup.push(colGroupCtr);
- }
- }
- } else {
- // No children of the current colgroup. Does it have a span attribute?
- if (currentColGroup.hasAttribute('span')) {
- var span = parseInt(currentColGroup.getAttribute('span'), 10);
-
- for (var s = 0; s < span; s++) {
- colToColGroup.push(colGroupCtr);
- }
- } else {
- // Default span value is 1
- colToColGroup.push(colGroupCtr);
- }
- }
- }
- return colToColGroup;
-
-};
-
-
-/**
- * Utility function to push an element into a given array only if that element
- * is not already contained in the array.
- * @param {Array} givenArray The given array.
- * @param {Node} givenElement The given element.
- */
-cvox.TableUtil.pushIfNotContained = function(givenArray, givenElement) {
- if (givenArray.indexOf(givenElement) == -1) {
- givenArray.push(givenElement);
- }
-};
-
-
-/**
- * Returns a JavaScript array of all the non-nested rows in the given table.
- *
- * @param {Node} table A table node.
- * @return {Array} An array of all the child rows of the active table.
- */
-cvox.TableUtil.getChildRows = function(table) {
- return cvox.XpathUtil.evalXPath('child::tbody/tr | child::thead/tr | ' +
- 'child::*[attribute::role="row"]', table);
-};
-
-
-/**
- * Returns a JavaScript array of all the child cell <TD> or <TH> or
- * role='gridcell' nodes of the given row.
- *
- * @param {Node} rowNode The specified row node.
- * @return {Array} An array of all the child cells of the given row node.
- */
-cvox.TableUtil.getChildCells = function(rowNode) {
- return cvox.XpathUtil.evalXPath('child::td | child::th | ' +
- 'child::*[attribute::role="gridcell"] |' +
- 'child::*[attribute::role="rowheader"] |' +
- 'child::*[attribute::role="columnheader"]', rowNode);
-};
-
-
-/**
- * Returns a JavaScript array containing the cell in the active table
- * with the given ID.
- *
- * @param {Node} table A table node.
- * @param {string} cellID The specified ID.
- * @return {Array} An array containing the cell with the specified ID.
- */
-cvox.TableUtil.getCellWithID = function(table, cellID) {
- return cvox.XpathUtil.evalXPath('id(\'' + cellID + '\')', table);
-};
-
-
-/**
- * Returns a Javascript array containing the colgroup elements in the
- * active table.
- *
- * @param {Node} table A table node.
- * @return {Array} An array of all the colgroup elements in the active table.
- */
-cvox.TableUtil.getColGroups = function(table) {
- return cvox.XpathUtil.evalXPath('child::colgroup', table);
-};
-
-
-/**
- * Returns a Javascript array containing the child col elements of the given
- * colgroup element.
- *
- * @param {Node} colGroupNode The specified <COLGROUP> element.
- * @return {Array} An array of all of the child col elements of the given
- * colgroup element.
- */
-cvox.TableUtil.getColNodes = function(colGroupNode) {
- return cvox.XpathUtil.evalXPath('child::col', colGroupNode);
-};
-
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/time_widget.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/time_widget.js
deleted file mode 100644
index 8691d63fb85..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/time_widget.js
+++ /dev/null
@@ -1,221 +0,0 @@
-// 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.
-
-goog.provide('cvox.ChromeVoxHTMLTimeWidget');
-
-/**
- * @fileoverview Gives the user spoken feedback as they interact with the time
- * widget (input type=time).
- *
- */
-
-/**
- * A class containing the information needed to speak
- * a text change event to the user.
- *
- * @constructor
- * @param {Element} timeElem The time widget element.
- * @param {cvox.TtsInterface} tts The TTS object from ChromeVox.
- */
-cvox.ChromeVoxHTMLTimeWidget = function(timeElem, tts) {
- var self = this;
- this.timeElem_ = timeElem;
- this.timeTts_ = tts;
- this.pHours_ = -1;
- this.pMinutes_ = -1;
- this.pSeconds_ = 0;
- this.pMilliseconds_ = 0;
- this.pAmpm_ = '';
- this.pos_ = 0;
- this.maxPos_ = 2;
- this.keyListener_ = function(evt) {
- self.eventHandler_(evt);
- };
- this.blurListener_ = function(evt) {
- self.shutdown();
- };
- if (this.timeElem_.hasAttribute('step')) {
- var step = this.timeElem_.getAttribute('step');
- if (step > 0) { // 0 or invalid values show hh:mm AM/PM
- if (step >= 1) {
- this.maxPos_ = 3; // Anything larger than 1 shows hh:mm:ss AM/PM
- } else {
- this.maxPos_ = 4; // Anything less than 1 shows hh:mm:ss.ms AM/PM
- }
- }
- }
-
- // Ensure we have a reasonable value to start with.
- if (this.timeElem_.value.length == 0) {
- this.forceInitTime_();
- }
-
- // Move the cursor to the first position so that we are guaranteed to start
- // off at the hours position.
- for (var i = 0; i < this.maxPos_; i++) {
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keydown', true, true, window, 'Left', 0, false, false, false, false);
- this.timeElem_.dispatchEvent(evt);
- evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent(
- 'keyup', true, true, window, 'Left', 0, false, false, false, false);
- this.timeElem_.dispatchEvent(evt);
- }
-
- this.timeElem_.addEventListener('keydown', this.keyListener_, false);
- this.timeElem_.addEventListener('keyup', this.keyListener_, false);
- this.timeElem_.addEventListener('blur', this.blurListener_, false);
- this.update_(true);
-};
-
-/**
- * Removes the key listeners for the time widget.
- *
- */
-cvox.ChromeVoxHTMLTimeWidget.prototype.shutdown = function() {
- this.timeElem_.removeEventListener('blur', this.blurListener_, false);
- this.timeElem_.removeEventListener('keydown', this.keyListener_, false);
- this.timeElem_.removeEventListener('keyup', this.keyListener_, false);
-};
-
-/**
- * Initialize to midnight.
- * @private
- */
-cvox.ChromeVoxHTMLTimeWidget.prototype.forceInitTime_ = function() {
- this.timeElem_.setAttribute('value', '12:00');
-};
-
-/**
- * Called when the position changes.
- * @private
- */
-cvox.ChromeVoxHTMLTimeWidget.prototype.handlePosChange_ = function() {
- if (this.pos_ < 0) {
- this.pos_ = 0;
- }
- if (this.pos_ > this.maxPos_) {
- this.pos_ = this.maxPos_;
- }
- // Reset the cached state of the new field so that the field will be spoken
- // in the update.
- if (this.pos_ == this.maxPos_) {
- this.pAmpm_ = '';
- return;
- }
- switch (this.pos_) {
- case 0:
- this.pHours_ = -1;
- break;
- case 1:
- this.pMinutes_ = -1;
- break;
- case 2:
- this.pSeconds_ = -1;
- break;
- case 3:
- this.pMilliseconds_ = -1;
- break;
- }
-};
-
-/**
- * @param {boolean} shouldSpeakLabel True if the label should be spoken.
- * @private
- */
-cvox.ChromeVoxHTMLTimeWidget.prototype.update_ = function(shouldSpeakLabel) {
- var splitTime = this.timeElem_.value.split(':');
- if (splitTime.length < 1) {
- this.forceInitTime_();
- return;
- }
-
- var hours = splitTime[0];
- var minutes = -1;
- var seconds = 0;
- var milliseconds = 0;
- var ampm = Msgs.getMsg('timewidget_am');
- if (splitTime.length > 1) {
- minutes = splitTime[1];
- }
- if (splitTime.length > 2) {
- var splitSecondsAndMilliseconds = splitTime[2].split('.');
- seconds = splitSecondsAndMilliseconds[0];
- if (splitSecondsAndMilliseconds.length > 1) {
- milliseconds = splitSecondsAndMilliseconds[1];
- }
- }
- if (hours > 12) {
- hours = hours - 12;
- ampm = Msgs.getMsg('timewidget_pm');
- }
- if (hours == 12) {
- ampm = Msgs.getMsg('timewidget_pm');
- }
- if (hours == 0) {
- hours = 12;
- ampm = Msgs.getMsg('timewidget_am');
- }
-
- var changeMessage = '';
-
- if (shouldSpeakLabel) {
- changeMessage = cvox.DomUtil.getName(this.timeElem_, true, true) + '\n';
- }
-
- if (hours != this.pHours_) {
- changeMessage = changeMessage + hours + ' ' +
- Msgs.getMsg('timewidget_hours') + '\n';
- this.pHours_ = hours;
- }
-
- if (minutes != this.pMinutes_) {
- changeMessage = changeMessage + minutes + ' ' +
- Msgs.getMsg('timewidget_minutes') + '\n';
- this.pMinutes_ = minutes;
- }
-
- if (seconds != this.pSeconds_) {
- changeMessage = changeMessage + seconds + ' ' +
- Msgs.getMsg('timewidget_seconds') + '\n';
- this.pSeconds_ = seconds;
- }
-
- if (milliseconds != this.pMilliseconds_) {
- changeMessage = changeMessage + milliseconds + ' ' +
- Msgs.getMsg('timewidget_milliseconds') + '\n';
- this.pMilliseconds_ = milliseconds;
- }
-
- if (ampm != this.pAmpm_) {
- changeMessage = changeMessage + ampm;
- this.pAmpm_ = ampm;
- }
-
- if (changeMessage.length > 0) {
- this.timeTts_.speak(changeMessage, cvox.QueueMode.FLUSH, null);
- }
-};
-
-/**
- * @param {Object} evt The event to handle.
- * @private
- */
-cvox.ChromeVoxHTMLTimeWidget.prototype.eventHandler_ = function(evt) {
- var shouldSpeakLabel = false;
- if (evt.type == 'keydown') {
- if (((evt.keyCode == 9) && !evt.shiftKey) || (evt.keyCode == 39)) {
- this.pos_++;
- this.handlePosChange_();
- shouldSpeakLabel = true;
- }
- if (((evt.keyCode == 9) && evt.shiftKey) || (evt.keyCode == 37)) {
- this.pos_--;
- this.handlePosChange_();
- shouldSpeakLabel = true;
- }
- }
- this.update_(shouldSpeakLabel);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_content.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_content.js
deleted file mode 100644
index 4ca1ec4183c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_content.js
+++ /dev/null
@@ -1,482 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview A DOM traversal interface for moving a selection around a
- * webpage. Provides multiple granularities:
- * 1. Move by paragraph.
- * 2. Move by sentence.
- * 3. Move by line.
- * 4. Move by word.
- * 5. Move by character.
- */
-
-goog.provide('cvox.TraverseContent');
-
-goog.require('cvox.CursorSelection');
-goog.require('cvox.DomUtil');
-goog.require('cvox.SelectionUtil');
-goog.require('cvox.TraverseUtil');
-
-/**
- * Moves a selection around a document or within a provided DOM object.
- *
- * @constructor
- * @param {Node=} domObj a DOM node (optional).
- */
-cvox.TraverseContent = function(domObj) {
- if (domObj != null) {
- this.currentDomObj = domObj;
- } else {
- this.currentDomObj = document.body;
- }
- var range = document.createRange();
- // TODO (dmazzoni): Switch this to avoid using range methods. Range methods
- // can cause exceptions (such as if the node is not attached to the DOM).
- try {
- range.selectNode(this.currentDomObj);
- this.startCursor_ = new cvox.Cursor(
- range.startContainer, range.startOffset,
- cvox.TraverseUtil.getNodeText(range.startContainer));
- this.endCursor_ = new cvox.Cursor(
- range.endContainer, range.endOffset,
- cvox.TraverseUtil.getNodeText(range.endContainer));
- } catch (e) {
- // Ignoring this error so that it will not break everything else.
- window.console.log('Error: Unselectable node:');
- window.console.log(domObj);
- }
-};
-goog.addSingletonGetter(cvox.TraverseContent);
-
-/**
- * Whether the last navigated selection only contained whitespace.
- * @type {boolean}
- */
-cvox.TraverseContent.prototype.lastSelectionWasWhitespace = false;
-
-/**
- * Whether we should skip whitespace when traversing individual characters.
- * @type {boolean}
- */
-cvox.TraverseContent.prototype.skipWhitespace = false;
-
-/**
- * If moveNext and movePrev should skip past an invalid selection,
- * so the user never gets stuck. Ideally the navigation code should never
- * return a range that's not a valid selection, but this keeps the user from
- * getting stuck if that code fails. This is set to false for unit testing.
- * @type {boolean}
- */
-cvox.TraverseContent.prototype.skipInvalidSelections = true;
-
-/**
- * If line and sentence navigation should break at <a> links.
- * @type {boolean}
- */
-cvox.TraverseContent.prototype.breakAtLinks = true;
-
-/**
- * The string constant for character granularity.
- * @type {string}
- * @const
- */
-cvox.TraverseContent.kCharacter = 'character';
-
-/**
- * The string constant for word granularity.
- * @type {string}
- * @const
- */
-cvox.TraverseContent.kWord = 'word';
-
-/**
- * The string constant for sentence granularity.
- * @type {string}
- * @const
- */
-cvox.TraverseContent.kSentence = 'sentence';
-
-/**
- * The string constant for line granularity.
- * @type {string}
- * @const
- */
-cvox.TraverseContent.kLine = 'line';
-
-/**
- * The string constant for paragraph granularity.
- * @type {string}
- * @const
- */
-cvox.TraverseContent.kParagraph = 'paragraph';
-
-/**
- * A constant array of all granularities.
- * @type {Array<string>}
- * @const
- */
-cvox.TraverseContent.kAllGrains =
- [cvox.TraverseContent.kParagraph,
- cvox.TraverseContent.kSentence,
- cvox.TraverseContent.kLine,
- cvox.TraverseContent.kWord,
- cvox.TraverseContent.kCharacter];
-
-/**
- * Set the current position to match the current WebKit selection.
- */
-cvox.TraverseContent.prototype.syncToSelection = function() {
- this.normalizeSelection();
-
- var selection = window.getSelection();
- if (!selection || !selection.anchorNode || !selection.focusNode) {
- return;
- }
- this.startCursor_ = new cvox.Cursor(
- selection.anchorNode, selection.anchorOffset,
- cvox.TraverseUtil.getNodeText(selection.anchorNode));
- this.endCursor_ = new cvox.Cursor(
- selection.focusNode, selection.focusOffset,
- cvox.TraverseUtil.getNodeText(selection.focusNode));
-};
-
-/**
- * Set the start and end cursors to the selection.
- * @param {cvox.CursorSelection} sel The selection.
- */
-cvox.TraverseContent.prototype.syncToCursorSelection = function(sel) {
- this.startCursor_ = sel.start.clone();
- this.endCursor_ = sel.end.clone();
-};
-
-/**
- * Get the cursor selection.
- * @return {cvox.CursorSelection} The selection.
- */
-cvox.TraverseContent.prototype.getCurrentCursorSelection = function() {
- return new cvox.CursorSelection(this.startCursor_, this.endCursor_);
-};
-
-/**
- * Set the WebKit selection based on the current position.
- */
-cvox.TraverseContent.prototype.updateSelection = function() {
- cvox.TraverseUtil.setSelection(this.startCursor_, this.endCursor_);
- cvox.SelectionUtil.scrollToSelection(window.getSelection());
-};
-
-/**
- * Get the current position as a range.
- * @return {Range} The current range.
- */
-cvox.TraverseContent.prototype.getCurrentRange = function() {
- var range = document.createRange();
- try {
- range.setStart(this.startCursor_.node, this.startCursor_.index);
- range.setEnd(this.endCursor_.node, this.endCursor_.index);
- } catch (e) {
- console.log('Invalid range ');
- }
- return range;
-};
-
-/**
- * Get the current text content as a string.
- * @return {string} The current spanned content.
- */
-cvox.TraverseContent.prototype.getCurrentText = function() {
- return cvox.SelectionUtil.getRangeText(this.getCurrentRange());
-};
-
-/**
- * Collapse to the end of the range.
- */
-cvox.TraverseContent.prototype.collapseToEnd = function() {
- this.startCursor_ = this.endCursor_.clone();
-};
-
-/**
- * Collapse to the start of the range.
- */
-cvox.TraverseContent.prototype.collapseToStart = function() {
- this.endCursor_ = this.startCursor_.clone();
-};
-
-/**
- * Moves selection forward.
- *
- * @param {string} grain specifies "sentence", "word", "character",
- * or "paragraph" granularity.
- * @return {?string} Either:
- * 1) The new selected text.
- * 2) null if the end of the domObj has been reached.
- */
-cvox.TraverseContent.prototype.moveNext = function(grain) {
- var breakTags = this.getBreakTags();
-
- // As a special case, if the current selection is empty or all
- // whitespace, ensure that the next returned selection will NOT be
- // only whitespace - otherwise you can get trapped.
- var skipWhitespace = this.skipWhitespace;
-
- var range = this.getCurrentRange();
- if (!cvox.SelectionUtil.isRangeValid(range)) {
- skipWhitespace = true;
- }
-
- var elementsEntered = [];
- var elementsLeft = [];
- var str;
- do {
- if (grain === cvox.TraverseContent.kSentence) {
- str = cvox.TraverseUtil.getNextSentence(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft,
- breakTags);
- } else if (grain === cvox.TraverseContent.kWord) {
- str = cvox.TraverseUtil.getNextWord(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft);
- } else if (grain === cvox.TraverseContent.kCharacter) {
- str = cvox.TraverseUtil.getNextChar(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft,
- skipWhitespace);
- } else if (grain === cvox.TraverseContent.kParagraph) {
- str = cvox.TraverseUtil.getNextParagraph(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft);
- } else if (grain === cvox.TraverseContent.kLine) {
- str = cvox.TraverseUtil.getNextLine(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft,
- breakTags);
- } else {
- // User has provided an invalid string.
- // Fall through to default: extend by sentence
- window.console.log('Invalid selection granularity: "' + grain + '"');
- grain = cvox.TraverseContent.kSentence;
- str = cvox.TraverseUtil.getNextSentence(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft,
- breakTags);
- }
-
- if (str == null) {
- // We reached the end of the document.
- return null;
- }
-
- range = this.getCurrentRange();
- var isInvalid = !range.getBoundingClientRect();
- } while (this.skipInvalidSelections && isInvalid);
-
- if (!cvox.SelectionUtil.isRangeValid(range)) {
- // It's OK if the selection navigation lands on whitespace once (in
- // character granularity), but if it hits whitespace more than once, then
- // skip forward until there is real content.
- if (!this.lastSelectionWasWhitespace &&
- grain == cvox.TraverseContent.kCharacter) {
- this.lastSelectionWasWhitespace = true;
- } else {
- while (!cvox.SelectionUtil.isRangeValid(this.getCurrentRange())) {
- if (this.moveNext(grain) == null) {
- break;
- }
- }
- }
- } else {
- this.lastSelectionWasWhitespace = false;
- }
-
- return this.getCurrentText();
-};
-
-
-/**
- * Moves selection backward.
- *
- * @param {string} grain specifies "sentence", "word", "character",
- * or "paragraph" granularity.
- * @return {?string} Either:
- * 1) The new selected text.
- * 2) null if the beginning of the domObj has been reached.
- */
-cvox.TraverseContent.prototype.movePrev = function(grain) {
- var breakTags = this.getBreakTags();
-
- // As a special case, if the current selection is empty or all
- // whitespace, ensure that the next returned selection will NOT be
- // only whitespace - otherwise you can get trapped.
- var skipWhitespace = this.skipWhitespace;
-
- var range = this.getCurrentRange();
- if (!cvox.SelectionUtil.isRangeValid(range)) {
- skipWhitespace = true;
- }
-
- var elementsEntered = [];
- var elementsLeft = [];
- var str;
- do {
- if (grain === cvox.TraverseContent.kSentence) {
- str = cvox.TraverseUtil.getPreviousSentence(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft,
- breakTags);
- } else if (grain === cvox.TraverseContent.kWord) {
- str = cvox.TraverseUtil.getPreviousWord(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft);
- } else if (grain === cvox.TraverseContent.kCharacter) {
- str = cvox.TraverseUtil.getPreviousChar(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft,
- skipWhitespace);
- } else if (grain === cvox.TraverseContent.kParagraph) {
- str = cvox.TraverseUtil.getPreviousParagraph(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft);
- } else if (grain === cvox.TraverseContent.kLine) {
- str = cvox.TraverseUtil.getPreviousLine(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft,
- breakTags);
- } else {
- // User has provided an invalid string.
- // Fall through to default: extend by sentence
- window.console.log('Invalid selection granularity: "' + grain + '"');
- grain = cvox.TraverseContent.kSentence;
- str = cvox.TraverseUtil.getPreviousSentence(
- this.startCursor_, this.endCursor_, elementsEntered, elementsLeft,
- breakTags);
- }
-
- if (str == null) {
- // We reached the end of the document.
- return null;
- }
-
- range = this.getCurrentRange();
- var isInvalid = !range.getBoundingClientRect();
- } while (this.skipInvalidSelections && isInvalid);
-
- if (!cvox.SelectionUtil.isRangeValid(range)) {
- // It's OK if the selection navigation lands on whitespace once (in
- // character granularity), but if it hits whitespace more than once, then
- // skip forward until there is real content.
- if (!this.lastSelectionWasWhitespace &&
- grain == cvox.TraverseContent.kCharacter) {
- this.lastSelectionWasWhitespace = true;
- } else {
- while (!cvox.SelectionUtil.isRangeValid(this.getCurrentRange())) {
- if (this.movePrev(grain) == null) {
- break;
- }
- }
- }
- } else {
- this.lastSelectionWasWhitespace = false;
- }
-
- return this.getCurrentText();
-};
-
-/**
- * Get the tag names that should break a sentence or line. Currently
- * just an anchor 'A' should break a sentence or line if the breakAtLinks
- * flag is true, but in the future we might have other rules for breaking.
- *
- * @return {Object} An associative array mapping a tag name to true if
- * it should break a sentence or line.
- */
-cvox.TraverseContent.prototype.getBreakTags = function() {
- return {
- 'A': this.breakAtLinks,
- 'BR': true,
- 'HR': true
- };
-};
-
-/**
- * Selects the next element of the document or within the provided DOM object.
- * Scrolls the window as appropriate.
- *
- * @param {string} grain specifies "sentence", "word", "character",
- * or "paragraph" granularity.
- * @param {Node=} domObj a DOM node (optional).
- * @return {?string} Either:
- * 1) The new selected text.
- * 2) null if the end of the domObj has been reached.
- */
-cvox.TraverseContent.prototype.nextElement = function(grain, domObj) {
- if (domObj != null) {
- this.currentDomObj = domObj;
- }
-
- var result = this.moveNext(grain);
- if (result != null &&
- (!cvox.DomUtil.isDescendantOfNode(
- this.startCursor_.node, this.currentDomObj) ||
- !cvox.DomUtil.isDescendantOfNode(
- this.endCursor_.node, this.currentDomObj))) {
- return null;
- }
-
- return result;
-};
-
-
-/**
- * Selects the previous element of the document or within the provided DOM
- * object. Scrolls the window as appropriate.
- *
- * @param {string} grain specifies "sentence", "word", "character",
- * or "paragraph" granularity.
- * @param {Node=} domObj a DOM node (optional).
- * @return {?string} Either:
- * 1) The new selected text.
- * 2) null if the beginning of the domObj has been reached.
- */
-cvox.TraverseContent.prototype.prevElement = function(grain, domObj) {
- if (domObj != null) {
- this.currentDomObj = domObj;
- }
-
- var result = this.movePrev(grain);
- if (result != null &&
- (!cvox.DomUtil.isDescendantOfNode(
- this.startCursor_.node, this.currentDomObj) ||
- !cvox.DomUtil.isDescendantOfNode(
- this.endCursor_.node, this.currentDomObj))) {
- return null;
- }
-
- return result;
-};
-
-/**
- * Make sure that exactly one item is selected. If there's no selection,
- * set the selection to the start of the document.
- */
-cvox.TraverseContent.prototype.normalizeSelection = function() {
- var selection = window.getSelection();
- if (selection.rangeCount < 1) {
- // Before the user has clicked a freshly-loaded page
-
- var range = document.createRange();
- range.setStart(this.currentDomObj, 0);
- range.setEnd(this.currentDomObj, 0);
-
- selection.removeAllRanges();
- selection.addRange(range);
-
- } else if (selection.rangeCount > 1) {
- // Multiple ranges exist - remove all ranges but the last one
- for (var i = 0; i < (selection.rangeCount - 1); i++) {
- selection.removeRange(selection.getRangeAt(i));
- }
- }
-};
-
-/**
- * Resets the selection.
- *
- * @param {Node=} domObj a DOM node. Optional.
- *
- */
-cvox.TraverseContent.prototype.reset = function(domObj) {
- window.getSelection().removeAllRanges();
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_math.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_math.js
deleted file mode 100644
index f14d8c29242..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_math.js
+++ /dev/null
@@ -1,446 +0,0 @@
-// 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.
-
-goog.provide('cvox.TraverseMath');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.DomUtil');
-goog.require('cvox.SemanticTree');
-
-
-/**
- * Initializes the traversal with the provided math node.
- *
- * @constructor
- */
-cvox.TraverseMath = function() {
- /**
- * The active math <MATH> node. In this context, "active" means that this is
- * the math expression the TraverseMath object is navigating.
- * @type {Node}
- */
- this.activeMath = null;
-
- /**
- * The node currently under inspection.
- * @type {Node}
- */
- this.activeNode = null;
-
- /**
- * Dictionary of all LaTeX elements in the page if there are any.
- * @type {!Object<!Node>}
- * @private
- */
- this.allTexs_ = {};
-
- /**
- * Dictionary of all MathJaxs elements in the page if there are any.
- * @type {!Object<!Node>}
- * @private
- */
- this.allMathjaxs_ = {};
-
- /**
- * Dictionary of all MathJaxs elements that have not yet been translated at
- * page load or during MathJax rendering.
- * @type {!Object<!Node>}
- * @private
- */
- this.todoMathjaxs_ = {};
-
- /**
- * When traversing a Mathjax node this will contain the internal
- * MathML representation of the node.
- * @type {Node}
- */
- this.activeMathmlHost = null;
-
- /**
- * Semantic representation of the current node.
- * @type {Node}
- */
- this.activeSemanticHost = null;
-
- /**
- * List of domain names.
- * @type {Array<string>}
- */
- this.allDomains = [];
-
- /**
- * List of style names.
- * @type {Array<string>}
- */
- this.allStyles = [];
-
- /**
- * Current domain.
- * @type {string}
- */
- this.domain = 'default';
-
- /**
- * Current style.
- * @type {string}
- */
- this.style = 'short';
-
- /**
- * Initialize special objects if necessary.
- */
- if (cvox.ChromeVox.mathJax) {
- this.initializeMathjaxs();
- this.initializeAltMaths();
- }
-};
-goog.addSingletonGetter(cvox.TraverseMath);
-
-
-/**
- * @type {boolean}
- * @private
- */
-cvox.TraverseMath.setSemantic_ = false;
-
-
-/**
- * Toggles the semantic setting.
- * @return {boolean} True if semantic interpretation is switched on. False
- * otherwise.
- */
-cvox.TraverseMath.toggleSemantic = function() {
- return cvox.TraverseMath.setSemantic_ = !cvox.TraverseMath.setSemantic_;
-};
-
-
-/**
- * Initializes a traversal of a math expression.
- * @param {Node} node A MathML node.
- */
-cvox.TraverseMath.prototype.initialize = function(node) {
- if (cvox.DomUtil.isMathImg(node)) {
- // If a node has a cvoxid attribute we know that it contains a LaTeX
- // expression that we have rewritten into its corresponding MathML
- // representation, which we can speak and walk.
- if (!node.hasAttribute('cvoxid')) {
- return;
- }
- var cvoxid = node.getAttribute('cvoxid');
- node = this.allTexs_[cvoxid];
- }
- if (cvox.DomUtil.isMathJax(node)) {
- this.activeMathmlHost = this.allMathjaxs_[node.getAttribute('id')];
- }
- this.activeMath = this.activeMathmlHost || node;
- this.activeNode = this.activeMathmlHost || node;
- if (this.activeNode && cvox.TraverseMath.setSemantic_ &&
- this.activeNode.nodeType == Node.ELEMENT_NODE) {
- this.activeNode =
- (new cvox.SemanticTree(/** @type {!Element} */ (this.activeNode))).xml();
- }
-};
-
-
-/**
- * Adds a mapping of a MathJax node to its MathML representation to the
- * dictionary of MathJax elements.
- * @param {!Node} mml The MathML node.
- * @param {string} id The MathJax node id.
- */
-cvox.TraverseMath.prototype.addMathjax = function(mml, id) {
- var spanId = cvox.DomUtil.getMathSpanId(id);
- if (spanId) {
- this.allMathjaxs_[spanId] = mml;
- } else {
- this.redoMathjaxs(mml, id);
- }
-};
-
-
-/**
- * Retries to compute MathML representations of MathJax elements, if
- * they have not been filled in during rendering.
- * @param {!Node} mml The MathML node.
- * @param {string} id The MathJax node id.
- */
-cvox.TraverseMath.prototype.redoMathjaxs = function(mml, id) {
- var fetch = goog.bind(function() {this.addMathjax(mml, id);}, this);
- setTimeout(fetch, 500);
-};
-
-
-/**
- * Initializes the MathJax to MathML mapping.
- * We first try to get all MathJax elements that are already being rendered.
- * Secondly, we register a signal to get updated on all elements that are
- * rendered or re-rendered later.
- */
-cvox.TraverseMath.prototype.initializeMathjaxs = function() {
- var callback =
- goog.bind(function(mml, id) {
- this.addMathjax(mml, id);
- }, this);
- cvox.ChromeVox.mathJax.isMathjaxActive(
- function(bool) {
- if (bool) {
- cvox.ChromeVox.mathJax.getAllJax(callback);
- cvox.ChromeVox.mathJax.registerSignal(callback, 'New Math');
- }
- });
-};
-
-
-/**
- * Initializes the elements in the page that we identify as potentially
- * containing tex or asciimath alt text.
- */
-cvox.TraverseMath.prototype.initializeAltMaths = function() {
- if (!document.querySelector(
- cvox.DomUtil.altMathQuerySelector('tex') + ', ' +
- cvox.DomUtil.altMathQuerySelector('asciimath'))) {
- return;
- }
- var callback = goog.bind(
- function(mml, id) {
- this.allTexs_[id] = mml;
- }, this);
- // Inject a minimalistic version of MathJax into the page.
- cvox.ChromeVox.mathJax.injectScripts();
- // Once MathJax is injected we harvest all Latex and AsciiMath in alt
- // attributes and translate them to MathML expression.
- cvox.ChromeVox.mathJax.isMathjaxActive(
- function(active) {
- if (active) {
- cvox.ChromeVox.mathJax.configMediaWiki();
- cvox.ChromeVox.mathJax.getAllTexs(callback);
- cvox.ChromeVox.mathJax.getAllAsciiMaths(callback);
- }
- });
-};
-
-
-/**
- * Moves to the next leaf node in the current Math expression if it exists.
- * @param {boolean} reverse True if reversed. False by default.
- * @param {function(!Node):boolean} pred Predicate deciding what a leaf is.
- * @return {Node} The next node.
- */
-cvox.TraverseMath.prototype.nextLeaf = function(reverse, pred) {
- if (this.activeNode && this.activeMath) {
- var next = pred(this.activeNode) ?
- cvox.DomUtil.directedFindNextNode(
- this.activeNode, this.activeMath, reverse, pred) :
- cvox.DomUtil.directedFindFirstNode(this.activeNode, reverse, pred);
- if (next) {
- this.activeNode = next;
- }
- }
- return this.activeNode;
-};
-
-
-// TODO (sorge) Refactor this logic into single walkers.
-/**
- * Returns a string with the content of the active node.
- * @return {string} The active content.
- */
-cvox.TraverseMath.prototype.activeContent = function() {
- return this.activeNode.textContent;
-};
-
-
-/**
- * Moves to the next subtree from a given node in a depth first fashion.
- * @param {boolean} reverse True if reversed. False by default.
- * @param {function(!Node):boolean} pred Predicate deciding what a subtree is.
- * @return {Node} The next subtree.
- */
-cvox.TraverseMath.prototype.nextSubtree = function(reverse, pred) {
- if (!this.activeNode || !this.activeMath) {
- return null;
- }
- if (!reverse) {
- var child = cvox.DomUtil.directedFindFirstNode(
- this.activeNode, reverse, pred);
- if (child) {
- this.activeNode = child;
- } else {
- var next = cvox.DomUtil.directedFindNextNode(
- this.activeNode, this.activeMath, reverse, pred);
- if (next) {
- this.activeNode = next;
- }
- }
- } else {
- if (this.activeNode == this.activeMath) {
- var child = cvox.DomUtil.directedFindDeepestNode(
- this.activeNode, reverse, pred);
- if (child != this.activeNode) {
- this.activeNode = child;
- return this.activeNode;
- }
- }
- var prev = cvox.DomUtil.directedFindNextNode(
- this.activeNode, this.activeMath, reverse, pred, true, true);
- if (prev) {
- this.activeNode = prev;
- }
- }
- return this.activeNode;
-};
-
-
-/**
- * left or right in the math expression.
- * Navigation is bounded by the presence of a sibling.
- * @param {boolean} r True to move left; false to move right.
- * @return {Node} The result.
- */
-cvox.TraverseMath.prototype.nextSibling = function(r) {
- if (!this.activeNode || !this.activeMath) {
- return null;
- }
- var node = this.activeNode;
- node = r ? node.previousSibling : node.nextSibling;
- if (!node) {
- return null;
- }
- this.activeNode = node;
- return this.activeNode;
-};
-
-
-/**
- * Moves up or down the math expression.
- * Navigation is bounded by the root math expression.
- * @param {boolean} r True to move up; false to move down.
- * @return {Node} The result.
- */
-cvox.TraverseMath.prototype.nextParentChild = function(r) {
- if (!this.activeNode || !this.activeMath) {
- return null;
- }
- if (this.activeNode == this.activeMath && r) {
- return null;
- }
- var node = this.activeNode;
- node = r ? node.parentNode : node.firstChild;
- if (!node) {
- return null;
- }
- this.activeNode = node;
- return this.activeNode;
-};
-
-
-/**
- * Adds a list of domains and styles to the existing one.
- * @param {Array<string>} domains List of domain names.
- * @param {Array<string>} styles List of style names.
- */
-cvox.TraverseMath.prototype.addDomainsAndStyles = function(domains, styles) {
- this.allDomains.push.apply(
- this.allDomains,
- domains.filter(
- goog.bind(function(x) {return this.allDomains.indexOf(x) < 0;},
- this)));
- this.allStyles.push.apply(
- this.allStyles,
- styles.filter(
- goog.bind(function(x) {return this.allStyles.indexOf(x) < 0;},
- this)));
-};
-
-
-/**
- * Gets a list of domains and styles from the symbol and function mappings.
- * Depending on the platform they either live in the background page or
- * in the android math map.
- */
-cvox.TraverseMath.prototype.initDomainsAndStyles = function() {
- if (cvox.ChromeVox.host['mathMap']) {
- this.addDomainsAndStyles(
- cvox.ChromeVox.host['mathMap'].allDomains,
- cvox.ChromeVox.host['mathMap'].allStyles);
- } else {
- cvox.ChromeVox.host.sendToBackgroundPage(
- {'target': 'Math',
- 'action': 'getDomains'});
- }
-};
-
-
-/**
- * Sets the domain for the TraverseMath object to the next one in the list
- * restarting from the first, if necessary.
- * @return {string} The name of the newly set domain.
- */
-cvox.TraverseMath.prototype.cycleDomain = function() {
- this.initDomainsAndStyles();
- var index = this.allDomains.indexOf(this.domain);
- if (index == -1) {
- return this.domain;
- }
- this.domain = this.allDomains[(++index) % this.allDomains.length];
- return this.domain;
-};
-
-
-/**
- * Sets the style for the TraverseMath object to the next one in the list
- * restarting from the first, if necessary.
- * @return {string} The name of the newly set style.
- */
-cvox.TraverseMath.prototype.cycleStyle = function() {
- this.initDomainsAndStyles();
- var index = this.allStyles.indexOf(this.style);
- if (index == -1) {
- return this.domain;
- }
- this.style = this.allStyles[(++index) % this.allStyles.length];
- return this.style;
-};
-
-
-/**
- * Sets the domain for the TraverseMath object.
- * @param {string} domain Name of the domain.
- * @private
- */
-cvox.TraverseMath.prototype.setDomain_ = function(domain) {
- if (this.allDomains.indexOf(domain) != -1) {
- this.domain = domain;
- } else {
- this.domain = 'default';
- }
-};
-
-
-/**
- * Sets the style for the TraverseMath object.
- * @param {string} style Name of the style.
- * @private
- */
-cvox.TraverseMath.prototype.setStyle_ = function(style) {
- if (this.allStyles.indexOf(style) != -1) {
- this.style = style;
- } else {
- this.style = 'default';
- }
-};
-
-
-/**
- * Gets the active node attached to the current document.
- * @return {Node} The active node, if it exists.
- */
-cvox.TraverseMath.prototype.getAttachedActiveNode = function() {
- var node = this.activeNode;
- if (!node || node.nodeType != Node.ELEMENT_NODE) {
- return null;
- }
- var id = node.getAttribute('spanID');
- return document.getElementById(id);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_table.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_table.js
deleted file mode 100644
index 8927c1d8846..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_table.js
+++ /dev/null
@@ -1,1309 +0,0 @@
-// 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.
-
-/**
- * TODO(stoarca): This class has become obsolete except for the shadow table.
- * Chop most of it away.
- * @fileoverview A DOM traversal interface for navigating data in tables.
- */
-
-goog.provide('cvox.TraverseTable');
-
-goog.require('cvox.DomPredicates');
-goog.require('cvox.DomUtil');
-goog.require('cvox.SelectionUtil');
-goog.require('cvox.TableUtil');
-goog.require('cvox.TraverseUtil');
-
-
-
-/**
- * An object that represents an active table cell inside the shadow table.
- * @constructor
- */
-function ShadowTableNode() {
- /**
- * The cells that are row headers of the corresponding active table cell
- * @type {!Array}
- */
- this.rowHeaderCells = [];
-
- /**
- * The cells that are column headers of the corresponding active table cell
- * @type {!Array}
- */
- this.colHeaderCells = [];
-}
-
-
-/**
- * Whether or not the active cell is spanned by a preceding cell.
- * @type {boolean}
- */
-ShadowTableNode.prototype.spanned;
-
-
-/**
- * Whether or not this cell is spanned by a rowSpan.
- * @type {?boolean}
- */
-ShadowTableNode.prototype.rowSpan;
-
-
-/**
- * Whether or not this cell is spanned by a colspan
- * @type {?boolean}
- */
-ShadowTableNode.prototype.colSpan;
-
-
-/**
- * The row index of the corresponding active table cell
- * @type {?number}
- */
-ShadowTableNode.prototype.i;
-
-
-/**
- * The column index of the corresponding active table cell
- * @type {?number}
- */
-ShadowTableNode.prototype.j;
-
-
-/**
- * The corresponding <TD> or <TH> node in the active table.
- * @type {?Node}
- */
-ShadowTableNode.prototype.activeCell;
-
-
-/**
- * Initializes the traversal with the provided table node.
- *
- * @constructor
- * @param {Node} tableNode The table to be traversed.
- */
-cvox.TraverseTable = function(tableNode) {
-
- /**
- * The active table <TABLE> node. In this context, "active" means that this is
- * the table the TraverseTable object is navigating.
- * @type {Node}
- * @private
- */
- this.activeTable_ = null;
-
- /**
- * A 2D array "shadow table" that contains pointers to nodes in the active
- * table. More specifically, each cell of the shadow table contains a special
- * object ShadowTableNode that has as one of its member variables the
- * corresponding cell in the active table.
- *
- * The shadow table will allow us efficient navigation of tables with
- * rowspans and colspans without needing to repeatedly scan the table. For
- * example, if someone requests a cell at (1,3), predecessor cells with
- * rowspans/colspans mean the cell you eventually return could actually be
- * one located at (0,2) that spans out to (1,3).
- *
- * This shadow table will contain a ShadowTableNode with the (0, 2) index at
- * the (1,3) position, eliminating the need to check for predecessor cells
- * with rowspan/colspan every time we traverse the table.
- *
- * @type {!Array<Array<ShadowTableNode>>}
- * @private
- */
- this.shadowTable_ = [];
-
- /**
- * An array of shadow table nodes that have been determined to contain header
- * cells or information about header cells. This array is collected at
- * initialization and then only recalculated if the table changes.
- * This array is used by findHeaderCells() to determine table row headers
- * and column headers.
- * @type {Array<ShadowTableNode>}
- * @private
- */
- this.candidateHeaders_ = [];
-
- /**
- * An array that associates cell IDs with their corresponding shadow nodes.
- * If there are two shadow nodes for the same cell (i.e. when a cell spans
- * other cells) then the first one will be associated with the ID. This means
- * that shadow nodes that have spanned set to true will not be included in
- * this array.
- * @type {Array<ShadowTableNode>}
- * @private
- */
- this.idToShadowNode_ = [];
-
- this.initialize(tableNode);
-};
-
-
-/**
- * The cell cursor, represented by an array that stores the row and
- * column location [i, j] of the active cell. These numbers are 0-based.
- * In this context, "active" means that this is the cell the user is
- * currently looking at.
- * @type {Array}
- */
-cvox.TraverseTable.prototype.currentCellCursor;
-
-
-/**
- * The number of columns in the active table. This is calculated at
- * initialization and then only recalculated if the table changes.
- *
- * Please Note: We have chosen to use the number of columns in the shadow
- * table as the canonical column count. This is important for tables that
- * have colspans - the number of columns in the active table will always be
- * less than the true number of columns.
- * @type {?number}
- */
-cvox.TraverseTable.prototype.colCount = null;
-
-
-/**
- * The number of rows in the active table. This is calculated at
- * initialization and then only recalculated if the table changes.
- * @type {?number}
- */
-cvox.TraverseTable.prototype.rowCount = null;
-
-
-/**
- * The row headers in the active table. This is calculated at
- * initialization and then only recalculated if the table changes.
- *
- * Please Note:
- * Row headers are defined here as <TH> or <TD> elements. <TD> elements when
- * serving as header cells must have either:
- * - The scope attribute defined
- * - Their IDs referenced in the header content attribute of another <TD> or
- * <TH> element.
- *
- * The HTML5 spec specifies that only header <TH> elements can be row headers
- * ( http://dev.w3.org/html5/spec/tabular-data.html#row-header ) but the
- * HTML4 spec says that <TD> elements can act as both
- * ( http://www.w3.org/TR/html401/struct/tables.html#h-11.2.6 ). In the
- * interest of providing meaningful header information for all tables, here
- * we take the position that <TD> elements can act as both.
- *
- * @type {Array}
- */
-cvox.TraverseTable.prototype.tableRowHeaders = null;
-
-
-/**
- * The column headers in the active table. This is calculated at
- * initialization and then only recalculated if the table changes.
- *
- * Please Note: see comment for tableRowHeaders.
- *
- * @type {Array}
- */
-cvox.TraverseTable.prototype.tableColHeaders = null;
-
-
-// TODO (stoarca): tighten up interface to {!Node}
-/**
- * Initializes the class member variables.
- * @param {Node} tableNode The table to be traversed.
- */
-cvox.TraverseTable.prototype.initialize = function(tableNode) {
- if (!tableNode) {
- return;
- }
- if (tableNode == this.activeTable_) {
- return;
- }
- this.activeTable_ = tableNode;
- this.currentCellCursor = null;
-
- this.tableRowHeaders = [];
- this.tableColHeaders = [];
-
- this.buildShadowTable_();
-
- this.colCount = this.shadowColCount_();
- this.rowCount = this.countRows_();
-
- this.findHeaderCells_();
-
- // Listen for changes to the active table. If the active table changes,
- // rebuild the shadow table.
- // TODO (stoarca): Is this safe? When this object goes away, doesn't the
- // eventListener stay on the node? Someone with better knowledge of js
- // please confirm. If so, this is a leak.
- this.activeTable_.addEventListener('DOMSubtreeModified',
- goog.bind(function() {
- this.buildShadowTable_();
- this.colCount = this.shadowColCount_();
- this.rowCount = this.countRows_();
-
- this.tableRowHeaders = [];
- this.tableColHeaders = [];
- this.findHeaderCells_();
-
- if (this.colCount == 0 && this.rowCount == 0) {
- return;
- }
-
- if (this.getCell() == null) {
- this.attachCursorToNearestCell_();
- }
- }, this), false);
-};
-
-
-/**
- * Finds the cell cursor containing the specified node within the table.
- * Returns null if there is no close cell.
- * @param {!Node} node The node for which to find the cursor.
- * @return {Array<number>} The table index for the node.
- */
-cvox.TraverseTable.prototype.findNearestCursor = function(node) {
- // TODO (stoarca): The current structure for representing the
- // shadow table is not optimal for this query, but it's not urgent
- // since this only gets executed at most once per user action.
-
- // In case node is in a table but above any individual cell, we go down as
- // deep as we can, being careful to avoid going into nested tables.
- var n = node;
-
- while (n.firstElementChild &&
- !(n.firstElementChild.tagName == 'TABLE' ||
- cvox.AriaUtil.isGrid(n.firstElementChild))) {
- n = n.firstElementChild;
- }
- while (!cvox.DomPredicates.cellPredicate(cvox.DomUtil.getAncestors(n))) {
- n = cvox.DomUtil.directedNextLeafNode(n);
- // TODO(stoarca): Ugly logic. Captions should be part of tables.
- // There have been a bunch of bugs as a result of
- // DomUtil.findTableNodeInList excluding captions from tables because
- // it makes them non-contiguous.
- if (!cvox.DomUtil.getContainingTable(n, {allowCaptions: true})) {
- return null;
- }
- }
- for (var i = 0; i < this.rowCount; ++i) {
- for (var j = 0; j < this.colCount; ++j) {
- if (this.shadowTable_[i][j]) {
- if (cvox.DomUtil.isDescendantOfNode(
- n, this.shadowTable_[i][j].activeCell)) {
- return [i, j];
- }
- }
- }
- }
- return null;
-};
-
-/**
- * Finds the valid cell nearest to the current cell cursor and moves the cell
- * cursor there. To be used when the table has changed and the current cell
- * cursor is now invalid (doesn't exist anymore).
- * @private
- */
-cvox.TraverseTable.prototype.attachCursorToNearestCell_ = function() {
- if (!this.currentCellCursor) {
- // We have no idea. Just go 'somewhere'. Other code paths in this
- // function go to the last cell, so let's do that!
- this.goToLastCell();
- return;
- }
-
- var currentCursor = this.currentCellCursor;
-
- // Does the current row still exist in the table?
- var currentRow = this.shadowTable_[currentCursor[0]];
- if (currentRow) {
- // Try last cell of current row
- this.currentCellCursor = [currentCursor[0], (currentRow.length - 1)];
- } else {
- // Current row does not exist anymore. Does current column still exist?
- // Try last cell of current column
- var numRows = this.shadowTable_.length;
- if (numRows == 0) {
- // Table has been deleted!
- this.currentCellCursor = null;
- return;
- }
- var aboveCell =
- this.shadowTable_[numRows - 1][currentCursor[1]];
- if (aboveCell) {
- this.currentCellCursor = [(numRows - 1), currentCursor[1]];
- } else {
- // Current column does not exist anymore either.
- // Move cursor to last cell in table.
- this.goToLastCell();
- }
- }
-};
-
-
-/**
- * Builds or rebuilds the shadow table by iterating through all of the cells
- * ( <TD> or <TH> or role='gridcell' nodes) of the active table.
- * @return {!Array} The shadow table.
- * @private
- */
-cvox.TraverseTable.prototype.buildShadowTable_ = function() {
- // Clear shadow table
- this.shadowTable_ = [];
-
- // Build shadow table structure. Initialize it as a 2D array.
- var allRows = cvox.TableUtil.getChildRows(this.activeTable_);
- var currentRowParent = null;
- var currentRowGroup = null;
-
- var colGroups = cvox.TableUtil.getColGroups(this.activeTable_);
- var colToColGroup = cvox.TableUtil.determineColGroups(colGroups);
-
- for (var ctr = 0; ctr < allRows.length; ctr++) {
- this.shadowTable_.push([]);
- }
-
- // Iterate through active table by row
- for (var i = 0; i < allRows.length; i++) {
- var childCells = cvox.TableUtil.getChildCells(allRows[i]);
-
- // Keep track of position in active table
- var activeTableCol = 0;
- // Keep track of position in shadow table
- var shadowTableCol = 0;
-
- while (activeTableCol < childCells.length) {
-
- // Check to make sure we haven't already filled this cell.
- if (this.shadowTable_[i][shadowTableCol] == null) {
-
- var activeTableCell = childCells[activeTableCol];
-
- // Default value for colspan and rowspan is 1
- var colsSpanned = 1;
- var rowsSpanned = 1;
-
- if (activeTableCell.hasAttribute('colspan')) {
-
- colsSpanned =
- parseInt(activeTableCell.getAttribute('colspan'), 10);
-
- if ((isNaN(colsSpanned)) || (colsSpanned <= 0)) {
- // The HTML5 spec defines colspan MUST be greater than 0:
- // http://dev.w3.org/html5/spec/Overview.html#attr-tdth-colspan
- //
- // This is a change from the HTML4 spec:
- // http://www.w3.org/TR/html401/struct/tables.html#adef-colspan
- //
- // We will degrade gracefully by treating a colspan=0 as
- // equivalent to a colspan=1.
- // Tested in method testColSpan0 in rowColSpanTable_test.js
- colsSpanned = 1;
- }
- }
- if (activeTableCell.hasAttribute('rowspan')) {
- rowsSpanned =
- parseInt(activeTableCell.getAttribute('rowspan'), 10);
-
- if ((isNaN(rowsSpanned)) || (rowsSpanned <= 0)) {
- // The HTML5 spec defines that rowspan can be any non-negative
- // integer, including 0:
- // http://dev.w3.org/html5/spec/Overview.html#attr-tdth-rowspan
- //
- // However, Chromium treats rowspan=0 as rowspan=1. This appears
- // to be a bug from WebKit:
- // https://bugs.webkit.org/show_bug.cgi?id=10300
- // Inherited from a bug (since fixed) in KDE:
- // http://bugs.kde.org/show_bug.cgi?id=41063
- //
- // We will follow Chromium and treat rowspan=0 as equivalent to
- // rowspan=1.
- //
- // Tested in method testRowSpan0 in rowColSpanTable_test.js
- //
- // Filed as a bug in Chromium: http://crbug.com/58223
- rowsSpanned = 1;
- }
- }
- for (var r = 0; r < rowsSpanned; r++) {
- for (var c = 0; c < colsSpanned; c++) {
- var shadowNode = new ShadowTableNode();
- if ((r == 0) && (c == 0)) {
- // This position is not spanned.
- shadowNode.spanned = false;
- shadowNode.rowSpan = false;
- shadowNode.colSpan = false;
- shadowNode.i = i;
- shadowNode.j = shadowTableCol;
- shadowNode.activeCell = activeTableCell;
- shadowNode.rowHeaderCells = [];
- shadowNode.colHeaderCells = [];
- shadowNode.isRowHeader = false;
- shadowNode.isColHeader = false;
- } else {
- // This position is spanned.
- shadowNode.spanned = true;
- shadowNode.rowSpan = (rowsSpanned > 1);
- shadowNode.colSpan = (colsSpanned > 1);
- shadowNode.i = i;
- shadowNode.j = shadowTableCol;
- shadowNode.activeCell = activeTableCell;
- shadowNode.rowHeaderCells = [];
- shadowNode.colHeaderCells = [];
- shadowNode.isRowHeader = false;
- shadowNode.isColHeader = false;
- }
- // Check this shadowNode to see if it is a candidate header cell
- if (cvox.TableUtil.checkIfHeader(shadowNode.activeCell)) {
- this.candidateHeaders_.push(shadowNode);
- } else if (shadowNode.activeCell.hasAttribute('headers')) {
- // This shadowNode has information about other header cells
- this.candidateHeaders_.push(shadowNode);
- }
-
- // Check and update row group status.
- if (currentRowParent == null) {
- // This is the first row
- currentRowParent = allRows[i].parentNode;
- currentRowGroup = 0;
- } else {
- if (allRows[i].parentNode != currentRowParent) {
- // We're in a different row group now
- currentRowParent = allRows[i].parentNode;
- currentRowGroup = currentRowGroup + 1;
- }
- }
- shadowNode.rowGroup = currentRowGroup;
-
- // Check and update col group status
- if (colToColGroup.length > 0) {
- shadowNode.colGroup = colToColGroup[shadowTableCol];
- } else {
- shadowNode.colGroup = 0;
- }
-
- if (! shadowNode.spanned) {
- if (activeTableCell.id != null) {
- this.idToShadowNode_[activeTableCell.id] = shadowNode;
- }
- }
-
- this.shadowTable_[i + r][shadowTableCol + c] = shadowNode;
- }
- }
- shadowTableCol += colsSpanned;
- activeTableCol++;
- } else {
- // This position has already been filled (by a previous cell that has
- // a colspan or a rowspan)
- shadowTableCol += 1;
- }
- }
- }
- return this.shadowTable_;
-};
-
-
-/**
- * Finds header cells from the list of candidate headers and classifies them
- * in two ways:
- * -- Identifies them for the entire table by adding them to
- * this.tableRowHeaders and this.tableColHeaders.
- * -- Identifies them for each shadow table node by adding them to the node's
- * rowHeaderCells or colHeaderCells arrays.
- *
- * @private
- */
-cvox.TraverseTable.prototype.findHeaderCells_ = function() {
- // Forming relationships between data cells and header cells:
- // http://dev.w3.org/html5/spec/tabular-data.html
- // #header-and-data-cell-semantics
-
- for (var i = 0; i < this.candidateHeaders_.length; i++) {
-
- var currentShadowNode = this.candidateHeaders_[i];
- var currentCell = currentShadowNode.activeCell;
-
- var assumedScope = null;
- var specifiedScope = null;
-
- if (currentShadowNode.spanned) {
- continue;
- }
-
- if ((currentCell.tagName == 'TH') &&
- !(currentCell.hasAttribute('scope'))) {
- // No scope specified - compute scope ourselves.
- // Go left/right - if there's a header node, then this is a column
- // header
- if (currentShadowNode.j > 0) {
- if (this.shadowTable_[currentShadowNode.i][currentShadowNode.j - 1].
- activeCell.tagName == 'TH') {
- assumedScope = 'col';
- }
- } else if (currentShadowNode.j < this.shadowTable_[currentShadowNode.i].
- length - 1) {
- if (this.shadowTable_[currentShadowNode.i][currentShadowNode.j + 1].
- activeCell.tagName == 'TH') {
- assumedScope = 'col';
- }
- } else {
- // This row has a width of 1 cell, just assume this is a colum header
- assumedScope = 'col';
- }
-
- if (assumedScope == null) {
- // Go up/down - if there's a header node, then this is a row header
- if (currentShadowNode.i > 0) {
- if (this.shadowTable_[currentShadowNode.i - 1][currentShadowNode.j].
- activeCell.tagName == 'TH') {
- assumedScope = 'row';
- }
- } else if (currentShadowNode.i < this.shadowTable_.length - 1) {
- if (this.shadowTable_[currentShadowNode.i + 1][currentShadowNode.j].
- activeCell.tagName == 'TH') {
- assumedScope = 'row';
- }
- } else {
- // This column has a height of 1 cell, just assume that this is
- // a row header
- assumedScope = 'row';
- }
- }
- } else if (currentCell.hasAttribute('scope')) {
- specifiedScope = currentCell.getAttribute('scope');
- } else if (currentCell.hasAttribute('role') &&
- (currentCell.getAttribute('role') == 'rowheader')) {
- specifiedScope = 'row';
- } else if (currentCell.hasAttribute('role') &&
- (currentCell.getAttribute('role') == 'columnheader')) {
- specifiedScope = 'col';
- }
-
- if ((specifiedScope == 'row') || (assumedScope == 'row')) {
- currentShadowNode.isRowHeader = true;
-
- // Go right until you hit the edge of the table or a data
- // cell after another header cell.
- // Add this cell to each shadowNode.rowHeaderCells attribute as you go.
- for (var rightCtr = currentShadowNode.j;
- rightCtr < this.shadowTable_[currentShadowNode.i].length;
- rightCtr++) {
-
- var rightShadowNode = this.shadowTable_[currentShadowNode.i][rightCtr];
- var rightCell = rightShadowNode.activeCell;
-
- if ((rightCell.tagName == 'TH') ||
- (rightCell.hasAttribute('scope'))) {
-
- if (rightCtr < this.shadowTable_[currentShadowNode.i].length - 1) {
- var checkDataCell =
- this.shadowTable_[currentShadowNode.i][rightCtr + 1];
- }
- }
- rightShadowNode.rowHeaderCells.push(currentCell);
- }
- this.tableRowHeaders.push(currentCell);
- } else if ((specifiedScope == 'col') || (assumedScope == 'col')) {
- currentShadowNode.isColHeader = true;
-
- // Go down until you hit the edge of the table or a data cell
- // after another header cell.
- // Add this cell to each shadowNode.colHeaders attribute as you go.
-
- for (var downCtr = currentShadowNode.i;
- downCtr < this.shadowTable_.length;
- downCtr++) {
-
- var downShadowNode = this.shadowTable_[downCtr][currentShadowNode.j];
- if (downShadowNode == null) {
- break;
- }
- var downCell = downShadowNode.activeCell;
-
- if ((downCell.tagName == 'TH') ||
- (downCell.hasAttribute('scope'))) {
-
- if (downCtr < this.shadowTable_.length - 1) {
- var checkDataCell =
- this.shadowTable_[downCtr + 1][currentShadowNode.j];
- }
- }
- downShadowNode.colHeaderCells.push(currentCell);
- }
- this.tableColHeaders.push(currentCell);
- } else if (specifiedScope == 'rowgroup') {
- currentShadowNode.isRowHeader = true;
-
- // This cell is a row header for the rest of the cells in this row group.
- var currentRowGroup = currentShadowNode.rowGroup;
-
- // Get the rest of the cells in this row first
- for (var cellsInRow = currentShadowNode.j + 1;
- cellsInRow < this.shadowTable_[currentShadowNode.i].length;
- cellsInRow++) {
- this.shadowTable_[currentShadowNode.i][cellsInRow].
- rowHeaderCells.push(currentCell);
- }
-
- // Now propagate to rest of row group
- for (var downCtr = currentShadowNode.i + 1;
- downCtr < this.shadowTable_.length;
- downCtr++) {
-
- if (this.shadowTable_[downCtr][0].rowGroup != currentRowGroup) {
- break;
- }
-
- for (var rightCtr = 0;
- rightCtr < this.shadowTable_[downCtr].length;
- rightCtr++) {
-
- this.shadowTable_[downCtr][rightCtr].
- rowHeaderCells.push(currentCell);
- }
- }
- this.tableRowHeaders.push(currentCell);
-
- } else if (specifiedScope == 'colgroup') {
- currentShadowNode.isColHeader = true;
-
- // This cell is a col header for the rest of the cells in this col group.
- var currentColGroup = currentShadowNode.colGroup;
-
- // Get the rest of the cells in this colgroup first
- for (var cellsInCol = currentShadowNode.j + 1;
- cellsInCol < this.shadowTable_[currentShadowNode.i].length;
- cellsInCol++) {
- if (this.shadowTable_[currentShadowNode.i][cellsInCol].colGroup ==
- currentColGroup) {
- this.shadowTable_[currentShadowNode.i][cellsInCol].
- colHeaderCells.push(currentCell);
- }
- }
-
- // Now propagate to rest of col group
- for (var downCtr = currentShadowNode.i + 1;
- downCtr < this.shadowTable_.length;
- downCtr++) {
-
- for (var rightCtr = 0;
- rightCtr < this.shadowTable_[downCtr].length;
- rightCtr++) {
-
- if (this.shadowTable_[downCtr][rightCtr].colGroup ==
- currentColGroup) {
- this.shadowTable_[downCtr][rightCtr].
- colHeaderCells.push(currentCell);
- }
- }
- }
- this.tableColHeaders.push(currentCell);
- }
- if (currentCell.hasAttribute('headers')) {
- this.findAttrbHeaders_(currentShadowNode);
- }
- if (currentCell.hasAttribute('aria-describedby')) {
- this.findAttrbDescribedBy_(currentShadowNode);
- }
- }
-};
-
-
-/**
- * Finds header cells from the 'headers' attribute of a given shadow node's
- * active cell and classifies them in two ways:
- * -- Identifies them for the entire table by adding them to
- * this.tableRowHeaders and this.tableColHeaders.
- * -- Identifies them for the shadow table node by adding them to the node's
- * rowHeaderCells or colHeaderCells arrays.
- * Please note that header cells found through the 'headers' attribute are
- * difficult to attribute to being either row or column headers because a
- * table cell can declare arbitrary cells as its headers. A guess is made here
- * based on which axis the header cell is closest to.
- *
- * @param {ShadowTableNode} currentShadowNode A shadow node with an active cell
- * that has a 'headers' attribute.
- *
- * @private
- */
-cvox.TraverseTable.prototype.findAttrbHeaders_ = function(currentShadowNode) {
- var activeTableCell = currentShadowNode.activeCell;
-
- var idList = activeTableCell.getAttribute('headers').split(' ');
- for (var idToken = 0; idToken < idList.length; idToken++) {
- // Find cell(s) with this ID, add to header list
- var idCellArray = cvox.TableUtil.getCellWithID(this.activeTable_,
- idList[idToken]);
-
- for (var idCtr = 0; idCtr < idCellArray.length; idCtr++) {
- if (idCellArray[idCtr].id == activeTableCell.id) {
- // Skip if the ID is the same as the current cell's ID
- break;
- }
- // Check if this list of candidate headers contains a
- // shadowNode with an active cell with this ID already
- var possibleHeaderNode =
- this.idToShadowNode_[idCellArray[idCtr].id];
- if (! cvox.TableUtil.checkIfHeader(possibleHeaderNode.activeCell)) {
- // This listed header cell will not be handled later.
- // Determine whether this is a row or col header for
- // the active table cell
-
- var iDiff = Math.abs(possibleHeaderNode.i - currentShadowNode.i);
- var jDiff = Math.abs(possibleHeaderNode.j - currentShadowNode.j);
- if ((iDiff == 0) || (iDiff < jDiff)) {
- cvox.TableUtil.pushIfNotContained(currentShadowNode.rowHeaderCells,
- possibleHeaderNode.activeCell);
- cvox.TableUtil.pushIfNotContained(this.tableRowHeaders,
- possibleHeaderNode.activeCell);
- } else {
- // This is a column header
- cvox.TableUtil.pushIfNotContained(currentShadowNode.colHeaderCells,
- possibleHeaderNode.activeCell);
- cvox.TableUtil.pushIfNotContained(this.tableColHeaders,
- possibleHeaderNode.activeCell);
- }
- }
- }
- }
-};
-
-
-/**
- * Finds header cells from the 'aria-describedby' attribute of a given shadow
- * node's active cell and classifies them in two ways:
- * -- Identifies them for the entire table by adding them to
- * this.tableRowHeaders and this.tableColHeaders.
- * -- Identifies them for the shadow table node by adding them to the node's
- * rowHeaderCells or colHeaderCells arrays.
- *
- * Please note that header cells found through the 'aria-describedby' attribute
- * must have the role='rowheader' or role='columnheader' attributes in order to
- * be considered header cells.
- *
- * @param {ShadowTableNode} currentShadowNode A shadow node with an active cell
- * that has an 'aria-describedby' attribute.
- *
- * @private
- */
-cvox.TraverseTable.prototype.findAttrbDescribedBy_ =
- function(currentShadowNode) {
- var activeTableCell = currentShadowNode.activeCell;
-
- var idList = activeTableCell.getAttribute('aria-describedby').split(' ');
- for (var idToken = 0; idToken < idList.length; idToken++) {
- // Find cell(s) with this ID, add to header list
- var idCellArray = cvox.TableUtil.getCellWithID(this.activeTable_,
- idList[idToken]);
-
- for (var idCtr = 0; idCtr < idCellArray.length; idCtr++) {
- if (idCellArray[idCtr].id == activeTableCell.id) {
- // Skip if the ID is the same as the current cell's ID
- break;
- }
- // Check if this list of candidate headers contains a
- // shadowNode with an active cell with this ID already
- var possibleHeaderNode =
- this.idToShadowNode_[idCellArray[idCtr].id];
- if (! cvox.TableUtil.checkIfHeader(possibleHeaderNode.activeCell)) {
- // This listed header cell will not be handled later.
- // Determine whether this is a row or col header for
- // the active table cell
-
- if (possibleHeaderNode.activeCell.hasAttribute('role') &&
- (possibleHeaderNode.activeCell.getAttribute('role') ==
- 'rowheader')) {
- cvox.TableUtil.pushIfNotContained(currentShadowNode.rowHeaderCells,
- possibleHeaderNode.activeCell);
- cvox.TableUtil.pushIfNotContained(this.tableRowHeaders,
- possibleHeaderNode.activeCell);
- } else if (possibleHeaderNode.activeCell.hasAttribute('role') &&
- (possibleHeaderNode.activeCell.getAttribute('role') ==
- 'columnheader')) {
- cvox.TableUtil.pushIfNotContained(currentShadowNode.colHeaderCells,
- possibleHeaderNode.activeCell);
- cvox.TableUtil.pushIfNotContained(this.tableColHeaders,
- possibleHeaderNode.activeCell);
- }
- }
- }
- }
-};
-
-
-/**
- * Gets the current cell or null if there is no current cell.
- * @return {?Node} The cell <TD> or <TH> or role='gridcell' node.
- */
-cvox.TraverseTable.prototype.getCell = function() {
- if (!this.currentCellCursor || !this.shadowTable_) {
- return null;
- }
-
- var shadowEntry =
- this.shadowTable_[this.currentCellCursor[0]][this.currentCellCursor[1]];
-
- return shadowEntry && shadowEntry.activeCell;
-};
-
-
-/**
- * Gets the cell at the specified location.
- * @param {Array<number>} index The index <i, j> of the required cell.
- * @return {?Node} The cell <TD> or <TH> or role='gridcell' node at the
- * specified location. Null if that cell does not exist.
- */
-cvox.TraverseTable.prototype.getCellAt = function(index) {
- if (((index[0] < this.rowCount) && (index[0] >= 0)) &&
- ((index[1] < this.colCount) && (index[1] >= 0))) {
- var shadowEntry = this.shadowTable_[index[0]][index[1]];
- if (shadowEntry != null) {
- return shadowEntry.activeCell;
- }
- }
- return null;
-};
-
-
-/**
- * Gets the cells that are row headers of the current cell.
- * @return {!Array} The cells that are row headers of the current cell. Empty if
- * the current cell does not have row headers.
- */
-cvox.TraverseTable.prototype.getCellRowHeaders = function() {
- var shadowEntry =
- this.shadowTable_[this.currentCellCursor[0]][this.currentCellCursor[1]];
-
- return shadowEntry.rowHeaderCells;
-};
-
-
-/**
- * Gets the cells that are col headers of the current cell.
- * @return {!Array} The cells that are col headers of the current cell. Empty if
- * the current cell does not have col headers.
- */
-cvox.TraverseTable.prototype.getCellColHeaders = function() {
- var shadowEntry =
- this.shadowTable_[this.currentCellCursor[0]][this.currentCellCursor[1]];
-
- return shadowEntry.colHeaderCells;
-};
-
-
-/**
- * Whether or not the current cell is spanned by another cell.
- * @return {boolean} Whether or not the current cell is spanned by another cell.
- */
-cvox.TraverseTable.prototype.isSpanned = function() {
- var shadowEntry =
- this.shadowTable_[this.currentCellCursor[0]][this.currentCellCursor[1]];
-
- return shadowEntry.spanned;
-};
-
-
-/**
- * Whether or not the current cell is a row header cell.
- * @return {boolean} Whether or not the current cell is a row header cell.
- */
-cvox.TraverseTable.prototype.isRowHeader = function() {
- var shadowEntry =
- this.shadowTable_[this.currentCellCursor[0]][this.currentCellCursor[1]];
-
- return shadowEntry.isRowHeader;
-};
-
-
-/**
- * Whether or not the current cell is a col header cell.
- * @return {boolean} Whether or not the current cell is a col header cell.
- */
-cvox.TraverseTable.prototype.isColHeader = function() {
- var shadowEntry =
- this.shadowTable_[this.currentCellCursor[0]][this.currentCellCursor[1]];
-
- return shadowEntry.isColHeader;
-};
-
-
-/**
- * Gets the active column, represented as an array of <TH> or <TD> nodes that
- * make up a column. In this context, "active" means that this is the column
- * that contains the cell the user is currently looking at.
- * @return {Array} An array of <TH> or <TD> or role='gridcell' nodes.
- */
-cvox.TraverseTable.prototype.getCol = function() {
- var colArray = [];
- for (var i = 0; i < this.shadowTable_.length; i++) {
-
- if (this.shadowTable_[i][this.currentCellCursor[1]]) {
- var shadowEntry = this.shadowTable_[i][this.currentCellCursor[1]];
-
- if (shadowEntry.colSpan && shadowEntry.rowSpan) {
- // Look at the last element in the column cell aray.
- var prev = colArray[colArray.length - 1];
- if (prev !=
- shadowEntry.activeCell) {
- // Watch out for positions spanned by a cell with rowspan and
- // colspan. We don't want the same cell showing up multiple times
- // in per-column cell lists.
- colArray.push(
- shadowEntry.activeCell);
- }
- } else if ((shadowEntry.colSpan) || (!shadowEntry.rowSpan)) {
- colArray.push(
- shadowEntry.activeCell);
- }
- }
- }
- return colArray;
-};
-
-
-/**
- * Gets the active row <TR> node. In this context, "active" means that this is
- * the row that contains the cell the user is currently looking at.
- * @return {Node} The active row node.
- */
-cvox.TraverseTable.prototype.getRow = function() {
- var childRows = cvox.TableUtil.getChildRows(this.activeTable_);
- return childRows[this.currentCellCursor[0]];
-};
-
-
-/**
- * Gets the table summary text.
- *
- * @return {?string} Either:
- * 1) The table summary text
- * 2) Null if the table does not contain a summary attribute.
- */
-cvox.TraverseTable.prototype.summaryText = function() {
- // see http://code.google.com/p/chromium/issues/detail?id=46567
- // for information why this is necessary
- if (!this.activeTable_.hasAttribute('summary')) {
- return null;
- }
- return this.activeTable_.getAttribute('summary');
-};
-
-
-/**
- * Gets the table caption text.
- *
- * @return {?string} Either:
- * 1) The table caption text
- * 2) Null if the table does not include a caption tag.
- */
-cvox.TraverseTable.prototype.captionText = function() {
- // If there's more than one outer <caption> element, choose the first one.
- var captionNodes = cvox.XpathUtil.evalXPath('caption\[1]',
- this.activeTable_);
- if (captionNodes.length > 0) {
- return captionNodes[0].innerHTML;
- } else {
- return null;
- }
-};
-
-
-/**
- * Calculates the number of columns in the shadow table.
- * @return {number} The number of columns in the shadow table.
- * @private
- */
-cvox.TraverseTable.prototype.shadowColCount_ = function() {
- // As the shadow table is a 2D array, the number of columns is the
- // max number of elements in the second-level arrays.
- var max = 0;
- for (var i = 0; i < this.shadowTable_.length; i++) {
- if (this.shadowTable_[i].length > max) {
- max = this.shadowTable_[i].length;
- }
- }
- return max;
-};
-
-
-/**
- * Calculates the number of rows in the table.
- * @return {number} The number of rows in the table.
- * @private
- */
-cvox.TraverseTable.prototype.countRows_ = function() {
- // Number of rows in a table is equal to the number of TR elements contained
- // by the (outer) TBODY elements.
- var rowCount = cvox.TableUtil.getChildRows(this.activeTable_);
- return rowCount.length;
-};
-
-
-/**
- * Calculates the number of columns in the table.
- * This uses the W3C recommended algorithm for calculating number of
- * columns, but it does not take rowspans or colspans into account. This means
- * that the number of columns calculated here might be lower than the actual
- * number of columns in the table if columns are indicated by colspans.
- * @return {number} The number of columns in the table.
- * @private
- */
-cvox.TraverseTable.prototype.getW3CColCount_ = function() {
- // See http://www.w3.org/TR/html401/struct/tables.html#h-11.2.4.3
-
- var colgroupNodes = cvox.XpathUtil.evalXPath('child::colgroup',
- this.activeTable_);
- var colNodes = cvox.XpathUtil.evalXPath('child::col', this.activeTable_);
-
- if ((colgroupNodes.length == 0) && (colNodes.length == 0)) {
- var maxcols = 0;
- var outerChildren = cvox.TableUtil.getChildRows(this.activeTable_);
- for (var i = 0; i < outerChildren.length; i++) {
- var childrenCount = cvox.TableUtil.getChildCells(outerChildren[i]);
- if (childrenCount.length > maxcols) {
- maxcols = childrenCount.length;
- }
- }
- return maxcols;
- } else {
- var sum = 0;
- for (var i = 0; i < colNodes.length; i++) {
- if (colNodes[i].hasAttribute('span')) {
- sum += colNodes[i].getAttribute('span');
- } else {
- sum += 1;
- }
- }
- for (i = 0; i < colgroupNodes.length; i++) {
- var colChildren = cvox.XpathUtil.evalXPath('child::col',
- colgroupNodes[i]);
- if (colChildren.length == 0) {
- if (colgroupNodes[i].hasAttribute('span')) {
- sum += colgroupNodes[i].getAttribute('span');
- } else {
- sum += 1;
- }
- }
- }
- }
- return sum;
-};
-
-
-/**
- * Moves to the next row in the table. Updates the cell cursor.
- *
- * @return {boolean} Either:
- * 1) True if the update has been made.
- * 2) False if the end of the table has been reached and the update has not
- * happened.
- */
-cvox.TraverseTable.prototype.nextRow = function() {
- if (!this.currentCellCursor) {
- // We have not started moving through the table yet
- return this.goToRow(0);
- } else {
- return this.goToRow(this.currentCellCursor[0] + 1);
- }
-
-};
-
-
-/**
- * Moves to the previous row in the table. Updates the cell cursor.
- *
- * @return {boolean} Either:
- * 1) True if the update has been made.
- * 2) False if the end of the table has been reached and the update has not
- * happened.
- */
-cvox.TraverseTable.prototype.prevRow = function() {
- if (!this.currentCellCursor) {
- // We have not started moving through the table yet
- return this.goToRow(this.rowCount - 1);
- } else {
- return this.goToRow(this.currentCellCursor[0] - 1);
- }
-};
-
-
-/**
- * Moves to the next column in the table. Updates the cell cursor.
- *
- * @return {boolean} Either:
- * 1) True if the update has been made.
- * 2) False if the end of the table has been reached and the update has not
- * happened.
- */
-cvox.TraverseTable.prototype.nextCol = function() {
- if (!this.currentCellCursor) {
- // We have not started moving through the table yet
- return this.goToCol(0);
- } else {
- return this.goToCol(this.currentCellCursor[1] + 1);
- }
-};
-
-
-/**
- * Moves to the previous column in the table. Updates the cell cursor.
- *
- * @return {boolean} Either:
- * 1) True if the update has been made.
- * 2) False if the end of the table has been reached and the update has not
- * happened.
- */
-cvox.TraverseTable.prototype.prevCol = function() {
- if (!this.currentCellCursor) {
- // We have not started moving through the table yet
- return this.goToCol(this.shadowColCount_() - 1);
- } else {
- return this.goToCol(this.currentCellCursor[1] - 1);
- }
-};
-
-
-/**
- * Moves to the row at the specified index in the table. Updates the cell
- * cursor.
- * @param {number} index The index of the required row.
- * @return {boolean} Either:
- * 1) True if the index is valid and the update has been made.
- * 2) False if the index is not valid (either less than 0 or greater than
- * the number of rows in the table).
- */
-cvox.TraverseTable.prototype.goToRow = function(index) {
- if (this.shadowTable_[index] != null) {
- if (this.currentCellCursor == null) {
- // We haven't started moving through the table yet
- this.currentCellCursor = [index, 0];
- } else {
- this.currentCellCursor = [index, this.currentCellCursor[1]];
- }
- return true;
- } else {
- return false;
- }
-};
-
-
-/**
- * Moves to the column at the specified index in the table. Updates the cell
- * cursor.
- * @param {number} index The index of the required column.
- * @return {boolean} Either:
- * 1) True if the index is valid and the update has been made.
- * 2) False if the index is not valid (either less than 0 or greater than
- * the number of rows in the table).
- */
-cvox.TraverseTable.prototype.goToCol = function(index) {
- if (index < 0 || index >= this.colCount) {
- return false;
- }
- if (this.currentCellCursor == null) {
- // We haven't started moving through the table yet
- this.currentCellCursor = [0, index];
- } else {
- this.currentCellCursor = [this.currentCellCursor[0], index];
- }
- return true;
-};
-
-
-/**
- * Moves to the cell at the specified index <i, j> in the table. Updates the
- * cell cursor.
- * @param {Array<number>} index The index <i, j> of the required cell.
- * @return {boolean} Either:
- * 1) True if the index is valid and the update has been made.
- * 2) False if the index is not valid (either less than 0, greater than
- * the number of rows or columns in the table, or there is no cell
- * at that location).
- */
-cvox.TraverseTable.prototype.goToCell = function(index) {
- if (((index[0] < this.rowCount) && (index[0] >= 0)) &&
- ((index[1] < this.colCount) && (index[1] >= 0))) {
- var cell = this.shadowTable_[index[0]][index[1]];
- if (cell != null) {
- this.currentCellCursor = index;
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Moves to the cell at the last index in the table. Updates the cell cursor.
- * @return {boolean} Either:
- * 1) True if the index is valid and the update has been made.
- * 2) False if the index is not valid (there is no cell at that location).
- */
-cvox.TraverseTable.prototype.goToLastCell = function() {
- var numRows = this.shadowTable_.length;
- if (numRows == 0) {
- return false;
- }
- var lastRow = this.shadowTable_[numRows - 1];
- var lastIndex = [(numRows - 1), (lastRow.length - 1)];
- var cell =
- this.shadowTable_[lastIndex[0]][lastIndex[1]];
- if (cell != null) {
- this.currentCellCursor = lastIndex;
- return true;
- }
- return false;
-};
-
-
-/**
- * Moves to the cell at the last index in the current row of the table. Update
- * the cell cursor.
- * @return {boolean} Either:
- * 1) True if the index is valid and the update has been made.
- * 2) False if the index is not valid (there is no cell at that location).
- */
-cvox.TraverseTable.prototype.goToRowLastCell = function() {
- var currentRow = this.currentCellCursor[0];
- var lastIndex = [currentRow, (this.shadowTable_[currentRow].length - 1)];
- var cell =
- this.shadowTable_[lastIndex[0]][lastIndex[1]];
- if (cell != null) {
- this.currentCellCursor = lastIndex;
- return true;
- }
- return false;
-};
-
-
-/**
- * Moves to the cell at the last index in the current column of the table.
- * Update the cell cursor.
- * @return {boolean} Either:
- * 1) True if the index is valid and the update has been made.
- * 2) False if the index is not valid (there is no cell at that location).
- */
-cvox.TraverseTable.prototype.goToColLastCell = function() {
- var currentCol = this.getCol();
- var lastIndex = [(currentCol.length - 1), this.currentCellCursor[1]];
- var cell =
- this.shadowTable_[lastIndex[0]][lastIndex[1]];
- if (cell != null) {
- this.currentCellCursor = lastIndex;
- return true;
- }
- return false;
-};
-
-
-/**
- * Resets the table cursors.
- *
- */
-cvox.TraverseTable.prototype.resetCursor = function() {
- this.currentCellCursor = null;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_util.js
deleted file mode 100644
index a77ac3eb284..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/traverse_util.js
+++ /dev/null
@@ -1,927 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Low-level DOM traversal utility functions to find the
- * next (or previous) character, word, sentence, line, or paragraph,
- * in a completely stateless manner without actually manipulating the
- * selection.
- */
-
-goog.provide('cvox.TraverseUtil');
-
-goog.require('cvox.Cursor');
-goog.require('cvox.DomPredicates');
-goog.require('cvox.DomUtil');
-
-/**
- * Utility functions for stateless DOM traversal.
- * @constructor
- */
-cvox.TraverseUtil = function() {};
-
-/**
- * Gets the text representation of a node. This allows us to substitute
- * alt text, names, or titles for html elements that provide them.
- * @param {Node} node A DOM node.
- * @return {string} A text string representation of the node.
- */
-cvox.TraverseUtil.getNodeText = function(node) {
- if (node.constructor == Text) {
- return node.data;
- } else {
- return '';
- }
-};
-
-/**
- * Return true if a node should be treated as a leaf node, because
- * its children are properties of the object that shouldn't be traversed.
- *
- * TODO(dmazzoni): replace this with a predicate that detects nodes with
- * ARIA roles and other objects that have their own description.
- * For now we just detect a couple of common cases.
- *
- * @param {Node} node A DOM node.
- * @return {boolean} True if the node should be treated as a leaf node.
- */
-cvox.TraverseUtil.treatAsLeafNode = function(node) {
- return node.childNodes.length == 0 ||
- node.nodeName == 'SELECT' ||
- node.getAttribute('role') == 'listbox' ||
- node.nodeName == 'OBJECT';
-};
-
-/**
- * Return true only if a single character is whitespace.
- * From https://developer.mozilla.org/en/Whitespace_in_the_DOM,
- * whitespace is defined as one of the characters
- * "\t" TAB \u0009
- * "\n" LF \u000A
- * "\r" CR \u000D
- * " " SPC \u0020.
- *
- * @param {string} c A string containing a single character.
- * @return {boolean} True if the character is whitespace, otherwise false.
- */
-cvox.TraverseUtil.isWhitespace = function(c) {
- return (c == ' ' || c == '\n' || c == '\r' || c == '\t');
-};
-
-/**
- * Set the selection to the range between the given start and end cursors.
- * @param {cvox.Cursor} start The desired start of the selection.
- * @param {cvox.Cursor} end The desired end of the selection.
- * @return {Selection} the selection object.
- */
-cvox.TraverseUtil.setSelection = function(start, end) {
- var sel = window.getSelection();
- sel.removeAllRanges();
- var range = document.createRange();
- range.setStart(start.node, start.index);
- range.setEnd(end.node, end.index);
- sel.addRange(range);
-
- return sel;
-};
-
-// TODO(dtseng): Combine with cvox.DomUtil.hasContent.
-/**
- * Check if this DOM node has the attribute aria-hidden='true', which should
- * hide it from screen readers.
- * @param {Node} node An HTML DOM node.
- * @return {boolean} Whether or not the html node should be traversed.
- */
-cvox.TraverseUtil.isHidden = function(node) {
- if (node instanceof HTMLElement &&
- node.getAttribute('aria-hidden') == 'true') {
- return true;
- }
- switch (node.tagName) {
- case 'SCRIPT':
- case 'NOSCRIPT':
- return true;
- }
- return false;
-};
-
-/**
- * Moves the cursor forwards until it has crossed exactly one character.
- * @param {cvox.Cursor} cursor The cursor location where the search should
- * start. On exit, the cursor will be immediately to the right of the
- * character returned.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @return {?string} The character found, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.forwardsChar = function(
- cursor, elementsEntered, elementsLeft) {
- while (true) {
- // Move down until we get to a leaf node.
- var childNode = null;
- if (!cvox.TraverseUtil.treatAsLeafNode(cursor.node)) {
- for (var i = cursor.index; i < cursor.node.childNodes.length; i++) {
- var node = cursor.node.childNodes[i];
- if (cvox.TraverseUtil.isHidden(node)) {
- if (node instanceof HTMLElement) {
- elementsEntered.push(node);
- }
- continue;
- }
- if (cvox.DomUtil.isVisible(node, {checkAncestors: false})) {
- childNode = node;
- break;
- }
- }
- }
- if (childNode) {
- cursor.node = childNode;
- cursor.index = 0;
- cursor.text = cvox.TraverseUtil.getNodeText(cursor.node);
- if (cursor.node instanceof HTMLElement) {
- elementsEntered.push(cursor.node);
- }
- continue;
- }
-
- // Return the next character from this leaf node.
- if (cursor.index < cursor.text.length)
- return cursor.text[cursor.index++];
-
- // Move to the next sibling, going up the tree as necessary.
- while (cursor.node != null) {
- // Try to move to the next sibling.
- var siblingNode = null;
- for (var node = cursor.node.nextSibling;
- node != null;
- node = node.nextSibling) {
- if (cvox.TraverseUtil.isHidden(node)) {
- if (node instanceof HTMLElement) {
- elementsEntered.push(node);
- }
- continue;
- }
- if (cvox.DomUtil.isVisible(node, {checkAncestors: false})) {
- siblingNode = node;
- break;
- }
- }
- if (siblingNode) {
- if (cursor.node instanceof HTMLElement) {
- elementsLeft.push(cursor.node);
- }
-
- cursor.node = siblingNode;
- cursor.text = cvox.TraverseUtil.getNodeText(siblingNode);
- cursor.index = 0;
-
- if (cursor.node instanceof HTMLElement) {
- elementsEntered.push(cursor.node);
- }
-
- break;
- }
-
- // Otherwise, move to the parent.
- if (cursor.node.parentNode &&
- cursor.node.parentNode.constructor != HTMLBodyElement) {
- if (cursor.node instanceof HTMLElement) {
- elementsLeft.push(cursor.node);
- }
- cursor.node = cursor.node.parentNode;
- cursor.text = null;
- cursor.index = 0;
- } else {
- return null;
- }
- }
- }
-};
-
-/**
- * Moves the cursor backwards until it has crossed exactly one character.
- * @param {cvox.Cursor} cursor The cursor location where the search should
- * start. On exit, the cursor will be immediately to the left of the
- * character returned.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @return {?string} The previous character, or null if the top of the
- * document has been reached.
- */
-cvox.TraverseUtil.backwardsChar = function(
- cursor, elementsEntered, elementsLeft) {
- while (true) {
- // Move down until we get to a leaf node.
- var childNode = null;
- if (!cvox.TraverseUtil.treatAsLeafNode(cursor.node)) {
- for (var i = cursor.index - 1; i >= 0; i--) {
- var node = cursor.node.childNodes[i];
- if (cvox.TraverseUtil.isHidden(node)) {
- if (node instanceof HTMLElement) {
- elementsEntered.push(node);
- }
- continue;
- }
- if (cvox.DomUtil.isVisible(node, {checkAncestors: false})) {
- childNode = node;
- break;
- }
- }
- }
- if (childNode) {
- cursor.node = childNode;
- cursor.text = cvox.TraverseUtil.getNodeText(cursor.node);
- if (cursor.text.length)
- cursor.index = cursor.text.length;
- else
- cursor.index = cursor.node.childNodes.length;
- if (cursor.node instanceof HTMLElement) {
- elementsEntered.push(cursor.node);
- }
- continue;
- }
-
- // Return the previous character from this leaf node.
- if (cursor.text.length > 0 && cursor.index > 0) {
- return cursor.text[--cursor.index];
- }
-
- // Move to the previous sibling, going up the tree as necessary.
- while (true) {
- // Try to move to the previous sibling.
- var siblingNode = null;
- for (var node = cursor.node.previousSibling;
- node != null;
- node = node.previousSibling) {
- if (cvox.TraverseUtil.isHidden(node)) {
- if (node instanceof HTMLElement) {
- elementsEntered.push(node);
- }
- continue;
- }
- if (cvox.DomUtil.isVisible(node, {checkAncestors: false})) {
- siblingNode = node;
- break;
- }
- }
- if (siblingNode) {
- if (cursor.node instanceof HTMLElement) {
- elementsLeft.push(cursor.node);
- }
-
- cursor.node = siblingNode;
- cursor.text = cvox.TraverseUtil.getNodeText(siblingNode);
- if (cursor.text.length)
- cursor.index = cursor.text.length;
- else
- cursor.index = cursor.node.childNodes.length;
-
- if (cursor.node instanceof HTMLElement) {
- elementsEntered.push(cursor.node);
- }
- break;
- }
-
- // Otherwise, move to the parent.
- if (cursor.node.parentNode &&
- cursor.node.parentNode.constructor != HTMLBodyElement) {
- if (cursor.node instanceof HTMLElement) {
- elementsLeft.push(cursor.node);
- }
- cursor.node = cursor.node.parentNode;
- cursor.text = null;
- cursor.index = 0;
- } else {
- return null;
- }
- }
- }
-};
-
-/**
- * Finds the next character, starting from endCursor. Upon exit, startCursor
- * and endCursor will surround the next character. If skipWhitespace is
- * true, will skip until a real character is found. Otherwise, it will
- * attempt to select all of the whitespace between the initial position
- * of endCursor and the next non-whitespace character.
- * @param {!cvox.Cursor} startCursor On exit, points to the position before
- * the char.
- * @param {!cvox.Cursor} endCursor The position to start searching for the next
- * char. On exit, will point to the position past the char.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * initial and final cursor position will be pushed onto this array.
- * @param {boolean} skipWhitespace If true, will keep scanning until a
- * non-whitespace character is found.
- * @return {?string} The next char, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getNextChar = function(
- startCursor, endCursor, elementsEntered, elementsLeft, skipWhitespace) {
-
- // Save the starting position and get the first character.
- startCursor.copyFrom(endCursor);
- var c = cvox.TraverseUtil.forwardsChar(
- endCursor, elementsEntered, elementsLeft);
- if (c == null)
- return null;
-
- // Keep track of whether the first character was whitespace.
- var initialWhitespace = cvox.TraverseUtil.isWhitespace(c);
-
- // Keep scanning until we find a non-whitespace or non-skipped character.
- while ((cvox.TraverseUtil.isWhitespace(c)) ||
- (cvox.TraverseUtil.isHidden(endCursor.node))) {
- c = cvox.TraverseUtil.forwardsChar(
- endCursor, elementsEntered, elementsLeft);
- if (c == null)
- return null;
- }
- if (skipWhitespace || !initialWhitespace) {
- // If skipWhitepace is true, or if the first character we encountered
- // was not whitespace, return that non-whitespace character.
- startCursor.copyFrom(endCursor);
- startCursor.index--;
- return c;
- }
- else {
- for (var i = 0; i < elementsEntered.length; i++) {
- if (cvox.TraverseUtil.isHidden(elementsEntered[i])) {
- // We need to make sure that startCursor and endCursor aren't
- // surrounding a skippable node.
- endCursor.index--;
- startCursor.copyFrom(endCursor);
- startCursor.index--;
- return ' ';
- }
- }
- // Otherwise, return all of the whitespace before that last character.
- endCursor.index--;
- return ' ';
- }
-};
-
-/**
- * Finds the previous character, starting from startCursor. Upon exit,
- * startCursor and endCursor will surround the previous character.
- * If skipWhitespace is true, will skip until a real character is found.
- * Otherwise, it will attempt to select all of the whitespace between
- * the initial position of endCursor and the next non-whitespace character.
- * @param {!cvox.Cursor} startCursor The position to start searching for the
- * char. On exit, will point to the position before the char.
- * @param {!cvox.Cursor} endCursor The position to start searching for the next
- * char. On exit, will point to the position past the char.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * initial and final cursor position will be pushed onto this array.
- * @param {boolean} skipWhitespace If true, will keep scanning until a
- * non-whitespace character is found.
- * @return {?string} The previous char, or null if the top of the
- * document has been reached.
- */
-cvox.TraverseUtil.getPreviousChar = function(
- startCursor, endCursor, elementsEntered, elementsLeft, skipWhitespace) {
-
- // Save the starting position and get the first character.
- endCursor.copyFrom(startCursor);
- var c = cvox.TraverseUtil.backwardsChar(
- startCursor, elementsEntered, elementsLeft);
- if (c == null)
- return null;
-
- // Keep track of whether the first character was whitespace.
- var initialWhitespace = cvox.TraverseUtil.isWhitespace(c);
-
- // Keep scanning until we find a non-whitespace or non-skipped character.
- while ((cvox.TraverseUtil.isWhitespace(c)) ||
- (cvox.TraverseUtil.isHidden(startCursor.node))) {
- c = cvox.TraverseUtil.backwardsChar(
- startCursor, elementsEntered, elementsLeft);
- if (c == null)
- return null;
- }
- if (skipWhitespace || !initialWhitespace) {
- // If skipWhitepace is true, or if the first character we encountered
- // was not whitespace, return that non-whitespace character.
- endCursor.copyFrom(startCursor);
- endCursor.index++;
- return c;
- } else {
- for (var i = 0; i < elementsEntered.length; i++) {
- if (cvox.TraverseUtil.isHidden(elementsEntered[i])) {
- startCursor.index++;
- endCursor.copyFrom(startCursor);
- endCursor.index++;
- return ' ';
- }
- }
- // Otherwise, return all of the whitespace before that last character.
- startCursor.index++;
- return ' ';
- }
-};
-
-/**
- * Finds the next word, starting from endCursor. Upon exit, startCursor
- * and endCursor will surround the next word. A word is defined to be
- * a string of 1 or more non-whitespace characters in the same DOM node.
- * @param {cvox.Cursor} startCursor On exit, will point to the beginning of the
- * word returned.
- * @param {cvox.Cursor} endCursor The position to start searching for the next
- * word. On exit, will point to the end of the word returned.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @return {?string} The next word, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getNextWord = function(startCursor, endCursor,
- elementsEntered, elementsLeft) {
-
- // Find the first non-whitespace or non-skipped character.
- var cursor = endCursor.clone();
- var c = cvox.TraverseUtil.forwardsChar(cursor, elementsEntered, elementsLeft);
- if (c == null)
- return null;
- while ((cvox.TraverseUtil.isWhitespace(c)) ||
- (cvox.TraverseUtil.isHidden(cursor.node))) {
- c = cvox.TraverseUtil.forwardsChar(cursor, elementsEntered, elementsLeft);
- if (c == null)
- return null;
- }
-
- // Set startCursor to the position immediately before the first
- // character in our word. It's safe to decrement |index| because
- // forwardsChar guarantees that the cursor will be immediately to the
- // right of the returned character on exit.
- startCursor.copyFrom(cursor);
- startCursor.index--;
-
- // Keep building up our word until we reach a whitespace character or
- // would cross a tag. Don't actually return any tags crossed, because this
- // word goes up until the tag boundary but not past it.
- endCursor.copyFrom(cursor);
- var word = c;
- var newEntered = [];
- var newLeft = [];
- c = cvox.TraverseUtil.forwardsChar(cursor, newEntered, newLeft);
- if (c == null) {
- return word;
- }
- while (!cvox.TraverseUtil.isWhitespace(c) &&
- newEntered.length == 0 &&
- newLeft == 0) {
- word += c;
- endCursor.copyFrom(cursor);
- c = cvox.TraverseUtil.forwardsChar(cursor, newEntered, newLeft);
- if (c == null) {
- return word;
- }
- }
-
- return word;
-};
-
-/**
- * Finds the previous word, starting from startCursor. Upon exit, startCursor
- * and endCursor will surround the previous word. A word is defined to be
- * a string of 1 or more non-whitespace characters in the same DOM node.
- * @param {cvox.Cursor} startCursor The position to start searching for the
- * previous word. On exit, will point to the beginning of the
- * word returned.
- * @param {cvox.Cursor} endCursor On exit, will point to the end of the
- * word returned.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @return {?string} The previous word, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getPreviousWord = function(startCursor, endCursor,
- elementsEntered, elementsLeft) {
- // Find the first non-whitespace or non-skipped character.
- var cursor = startCursor.clone();
- var c = cvox.TraverseUtil.backwardsChar(
- cursor, elementsEntered, elementsLeft);
- if (c == null)
- return null;
- while ((cvox.TraverseUtil.isWhitespace(c) ||
- (cvox.TraverseUtil.isHidden(cursor.node)))) {
- c = cvox.TraverseUtil.backwardsChar(cursor, elementsEntered, elementsLeft);
- if (c == null)
- return null;
- }
-
- // Set endCursor to the position immediately after the first
- // character we've found (the last character of the word, since we're
- // searching backwards).
- endCursor.copyFrom(cursor);
- endCursor.index++;
-
- // Keep building up our word until we reach a whitespace character or
- // would cross a tag. Don't actually return any tags crossed, because this
- // word goes up until the tag boundary but not past it.
- startCursor.copyFrom(cursor);
- var word = c;
- var newEntered = [];
- var newLeft = [];
- c = cvox.TraverseUtil.backwardsChar(cursor, newEntered, newLeft);
- if (c == null)
- return word;
- while (!cvox.TraverseUtil.isWhitespace(c) &&
- newEntered.length == 0 &&
- newLeft.length == 0) {
- word = c + word;
- startCursor.copyFrom(cursor);
-
- c = cvox.TraverseUtil.backwardsChar(cursor, newEntered, newLeft);
- if (c == null)
- return word;
- }
-
- return word;
-};
-
-
-/**
- * Given elements entered and left, and break tags, returns true if the
- * current word should break.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @param {Object<boolean>} breakTags Associative array of tags that should
- * break.
- * @return {boolean} True if elementsEntered or elementsLeft include an
- * element with one of these tags.
- */
-cvox.TraverseUtil.includesBreakTagOrSkippedNode = function(
- elementsEntered, elementsLeft, breakTags) {
- for (var i = 0; i < elementsEntered.length; i++) {
- if (cvox.TraverseUtil.isHidden(elementsEntered[i])) {
- return true;
- }
- var style = window.getComputedStyle(elementsEntered[i], null);
- if ((style && style.display != 'inline') ||
- breakTags[elementsEntered[i].tagName]) {
- return true;
- }
- }
- for (i = 0; i < elementsLeft.length; i++) {
- var style = window.getComputedStyle(elementsLeft[i], null);
- if ((style && style.display != 'inline') ||
- breakTags[elementsLeft[i].tagName]) {
- return true;
- }
- }
- return false;
-};
-
-
-/**
- * Finds the next sentence, starting from endCursor. Upon exit,
- * startCursor and endCursor will surround the next sentence.
- *
- * @param {cvox.Cursor} startCursor On exit, marks the beginning of the
- * sentence.
- * @param {cvox.Cursor} endCursor The position to start searching for the next
- * sentence. On exit, will point to the end of the returned string.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @param {Object<boolean>} breakTags Associative array of tags that should
- * break the sentence.
- * @return {?string} The next sentence, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getNextSentence = function(
- startCursor, endCursor, elementsEntered, elementsLeft, breakTags) {
- return cvox.TraverseUtil.getNextString(
- startCursor, endCursor, elementsEntered, elementsLeft,
- function(str, word, elementsEntered, elementsLeft) {
- if (str.substr(-1) == '.')
- return true;
- return cvox.TraverseUtil.includesBreakTagOrSkippedNode(
- elementsEntered, elementsLeft, breakTags);
- });
-};
-
-/**
- * Finds the previous sentence, starting from startCursor. Upon exit,
- * startCursor and endCursor will surround the previous sentence.
- *
- * @param {cvox.Cursor} startCursor The position to start searching for the next
- * sentence. On exit, will point to the start of the returned string.
- * @param {cvox.Cursor} endCursor On exit, the end of the returned string.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @param {Object<boolean>} breakTags Associative array of tags that should
- * break the sentence.
- * @return {?string} The previous sentence, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getPreviousSentence = function(
- startCursor, endCursor, elementsEntered, elementsLeft, breakTags) {
- return cvox.TraverseUtil.getPreviousString(
- startCursor, endCursor, elementsEntered, elementsLeft,
- function(str, word, elementsEntered, elementsLeft) {
- if (word.substr(-1) == '.')
- return true;
- return cvox.TraverseUtil.includesBreakTagOrSkippedNode(
- elementsEntered, elementsLeft, breakTags);
- });
-};
-
-/**
- * Finds the next line, starting from endCursor. Upon exit,
- * startCursor and endCursor will surround the next line.
- *
- * @param {cvox.Cursor} startCursor On exit, marks the beginning of the line.
- * @param {cvox.Cursor} endCursor The position to start searching for the next
- * line. On exit, will point to the end of the returned string.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @param {Object<boolean>} breakTags Associative array of tags that should
- * break the line.
- * @return {?string} The next line, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getNextLine = function(
- startCursor, endCursor, elementsEntered, elementsLeft, breakTags) {
- var range = document.createRange();
- var currentRect = null;
- var rightMostRect = null;
- var prevCursor = endCursor.clone();
- return cvox.TraverseUtil.getNextString(
- startCursor, endCursor, elementsEntered, elementsLeft,
- function(str, word, elementsEntered, elementsLeft) {
- range.setStart(startCursor.node, startCursor.index);
- range.setEnd(endCursor.node, endCursor.index);
- var currentRect = range.getBoundingClientRect();
- if (!rightMostRect) {
- rightMostRect = currentRect;
- }
-
- // Break at new lines except when within a link.
- if (currentRect.bottom != rightMostRect.bottom &&
- !cvox.DomPredicates.linkPredicate(cvox.DomUtil.getAncestors(
- endCursor.node))) {
- endCursor.copyFrom(prevCursor);
- return true;
- }
-
- rightMostRect = currentRect;
- prevCursor.copyFrom(endCursor);
-
- return cvox.TraverseUtil.includesBreakTagOrSkippedNode(
- elementsEntered, elementsLeft, breakTags);
- });
-};
-
-/**
- * Finds the previous line, starting from startCursor. Upon exit,
- * startCursor and endCursor will surround the previous line.
- *
- * @param {cvox.Cursor} startCursor The position to start searching for the next
- * line. On exit, will point to the start of the returned string.
- * @param {cvox.Cursor} endCursor On exit, the end of the returned string.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @param {Object<boolean>} breakTags Associative array of tags that should
- * break the line.
- * @return {?string} The previous line, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getPreviousLine = function(
- startCursor, endCursor, elementsEntered, elementsLeft, breakTags) {
- var range = document.createRange();
- var currentRect = null;
- var leftMostRect = null;
- var prevCursor = startCursor.clone();
- return cvox.TraverseUtil.getPreviousString(
- startCursor, endCursor, elementsEntered, elementsLeft,
- function(str, word, elementsEntered, elementsLeft) {
- range.setStart(startCursor.node, startCursor.index);
- range.setEnd(endCursor.node, endCursor.index);
- var currentRect = range.getBoundingClientRect();
- if (!leftMostRect) {
- leftMostRect = currentRect;
- }
-
- // Break at new lines except when within a link.
- if (currentRect.top != leftMostRect.top &&
- !cvox.DomPredicates.linkPredicate(cvox.DomUtil.getAncestors(
- startCursor.node))) {
- startCursor.copyFrom(prevCursor);
- return true;
- }
-
- leftMostRect = currentRect;
- prevCursor.copyFrom(startCursor);
-
- return cvox.TraverseUtil.includesBreakTagOrSkippedNode(
- elementsEntered, elementsLeft, breakTags);
- });
-};
-
-/**
- * Finds the next paragraph, starting from endCursor. Upon exit,
- * startCursor and endCursor will surround the next paragraph.
- *
- * @param {cvox.Cursor} startCursor On exit, marks the beginning of the
- * paragraph.
- * @param {cvox.Cursor} endCursor The position to start searching for the next
- * paragraph. On exit, will point to the end of the returned string.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @return {?string} The next paragraph, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getNextParagraph = function(startCursor, endCursor,
- elementsEntered, elementsLeft) {
- return cvox.TraverseUtil.getNextString(
- startCursor, endCursor, elementsEntered, elementsLeft,
- function(str, word, elementsEntered, elementsLeft) {
- for (var i = 0; i < elementsEntered.length; i++) {
- if (cvox.TraverseUtil.isHidden(elementsEntered[i])) {
- return true;
- }
- var style = window.getComputedStyle(elementsEntered[i], null);
- if (style && style.display != 'inline') {
- return true;
- }
- }
- for (i = 0; i < elementsLeft.length; i++) {
- var style = window.getComputedStyle(elementsLeft[i], null);
- if (style && style.display != 'inline') {
- return true;
- }
- }
- return false;
- });
-};
-
-/**
- * Finds the previous paragraph, starting from startCursor. Upon exit,
- * startCursor and endCursor will surround the previous paragraph.
- *
- * @param {cvox.Cursor} startCursor The position to start searching for the next
- * paragraph. On exit, will point to the start of the returned string.
- * @param {cvox.Cursor} endCursor On exit, the end of the returned string.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @return {?string} The previous paragraph, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getPreviousParagraph = function(
- startCursor, endCursor, elementsEntered, elementsLeft) {
- return cvox.TraverseUtil.getPreviousString(
- startCursor, endCursor, elementsEntered, elementsLeft,
- function(str, word, elementsEntered, elementsLeft) {
- for (var i = 0; i < elementsEntered.length; i++) {
- if (cvox.TraverseUtil.isHidden(elementsEntered[i])) {
- return true;
- }
- var style = window.getComputedStyle(elementsEntered[i], null);
- if (style && style.display != 'inline') {
- return true;
- }
- }
- for (i = 0; i < elementsLeft.length; i++) {
- var style = window.getComputedStyle(elementsLeft[i], null);
- if (style && style.display != 'inline') {
- return true;
- }
- }
- return false;
- });
-};
-
-/**
- * Customizable function to return the next string of words in the DOM, based
- * on provided functions to decide when to break one string and start
- * the next. This can be used to get the next sentence, line, paragraph,
- * or potentially other granularities.
- *
- * Finds the next contiguous string, starting from endCursor. Upon exit,
- * startCursor and endCursor will surround the next string.
- *
- * The breakBefore function takes four parameters, and
- * should return true if the string should be broken before the proposed
- * next word:
- * str The string so far.
- * word The next word to be added.
- * elementsEntered The elements entered in reaching this next word.
- * elementsLeft The elements left in reaching this next word.
- *
- * @param {cvox.Cursor} startCursor On exit, will point to the beginning of the
- * next string.
- * @param {cvox.Cursor} endCursor The position to start searching for the next
- * string. On exit, will point to the end of the returned string.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @param {function(string, string, Array<Element>, Array<Element>)}
- * breakBefore Function that takes the string so far, next word to be
- * added, and elements entered and left, and returns true if the string
- * should be ended before adding this word.
- * @return {?string} The next string, or null if the bottom of the
- * document has been reached.
- */
-cvox.TraverseUtil.getNextString = function(
- startCursor, endCursor, elementsEntered, elementsLeft, breakBefore) {
- // Get the first word and set the start cursor to the start of the
- // first word.
- var wordStartCursor = endCursor.clone();
- var wordEndCursor = endCursor.clone();
- var newEntered = [];
- var newLeft = [];
- var str = '';
- var word = cvox.TraverseUtil.getNextWord(
- wordStartCursor, wordEndCursor, newEntered, newLeft);
- if (word == null)
- return null;
- startCursor.copyFrom(wordStartCursor);
-
- // Always add the first word when the string is empty, and then keep
- // adding more words as long as breakBefore returns false
- while (!str || !breakBefore(str, word, newEntered, newLeft)) {
- // Append this word, set the end cursor to the end of this word, and
- // update the returned list of nodes crossed to include ones we crossed
- // in reaching this word.
- if (str)
- str += ' ';
- str += word;
- elementsEntered = elementsEntered.concat(newEntered);
- elementsLeft = elementsLeft.concat(newLeft);
- endCursor.copyFrom(wordEndCursor);
-
- // Get the next word and go back to the top of the loop.
- newEntered = [];
- newLeft = [];
- word = cvox.TraverseUtil.getNextWord(
- wordStartCursor, wordEndCursor, newEntered, newLeft);
- if (word == null)
- return str;
- }
-
- return str;
-};
-
-/**
- * Customizable function to return the previous string of words in the DOM,
- * based on provided functions to decide when to break one string and start
- * the next. See getNextString, above, for more details.
- *
- * Finds the previous contiguous string, starting from startCursor. Upon exit,
- * startCursor and endCursor will surround the next string.
- *
- * @param {cvox.Cursor} startCursor The position to start searching for the
- * previous string. On exit, will point to the beginning of the
- * string returned.
- * @param {cvox.Cursor} endCursor On exit, will point to the end of the
- * string returned.
- * @param {Array<Element>} elementsEntered Any HTML elements entered.
- * @param {Array<Element>} elementsLeft Any HTML elements left.
- * @param {function(string, string, Array<Element>, Array<Element>)}
- * breakBefore Function that takes the string so far, the word to be
- * added, and nodes crossed, and returns true if the string should be
- * ended before adding this word.
- * @return {?string} The next string, or null if the top of the
- * document has been reached.
- */
-cvox.TraverseUtil.getPreviousString = function(
- startCursor, endCursor, elementsEntered, elementsLeft, breakBefore) {
- // Get the first word and set the end cursor to the end of the
- // first word.
- var wordStartCursor = startCursor.clone();
- var wordEndCursor = startCursor.clone();
- var newEntered = [];
- var newLeft = [];
- var str = '';
- var word = cvox.TraverseUtil.getPreviousWord(
- wordStartCursor, wordEndCursor, newEntered, newLeft);
- if (word == null)
- return null;
- endCursor.copyFrom(wordEndCursor);
-
- // Always add the first word when the string is empty, and then keep
- // adding more words as long as breakBefore returns false
- while (!str || !breakBefore(str, word, newEntered, newLeft)) {
- // Prepend this word, set the start cursor to the start of this word, and
- // update the returned list of nodes crossed to include ones we crossed
- // in reaching this word.
- if (str)
- str = ' ' + str;
- str = word + str;
- elementsEntered = elementsEntered.concat(newEntered);
- elementsLeft = elementsLeft.concat(newLeft);
- startCursor.copyFrom(wordStartCursor);
-
- // Get the previous word and go back to the top of the loop.
- newEntered = [];
- newLeft = [];
- word = cvox.TraverseUtil.getPreviousWord(
- wordStartCursor, wordEndCursor, newEntered, newLeft);
- if (word == null)
- return str;
- }
-
- return str;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/xpath_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/xpath_util.js
deleted file mode 100644
index cad6346c016..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/xpath_util.js
+++ /dev/null
@@ -1,152 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A collection of JavaScript utilities used to simplify working
- * with xpaths.
- */
-
-
-goog.provide('cvox.XpathUtil');
-
-
-/**
- * Utilities for simplifying working with xpaths
- * @constructor
- */
-cvox.XpathUtil = function() {
- };
-
-
-/**
- * Mapping for some default namespaces.
- * @const
- * @private
- */
-cvox.XpathUtil.nameSpaces_ = {
- 'xhtml' : 'http://www.w3.org/1999/xhtml',
- 'mathml': 'http://www.w3.org/1998/Math/MathML'
-};
-
-
-/**
- * Resolve some default name spaces.
- * @param {string} prefix Namespace prefix.
- * @return {string} The corresponding namespace URI.
- */
-cvox.XpathUtil.resolveNameSpace = function(prefix) {
- return cvox.XpathUtil.nameSpaces_[prefix] || null;
-};
-
-
-/**
- * Given an XPath expression and rootNode, it returns an array of children nodes
- * that match. The code for this function was taken from Mihai Parparita's GMail
- * Macros Greasemonkey Script.
- * http://gmail-greasemonkey.googlecode.com/svn/trunk/scripts/gmail-new-macros.user.js
- * @param {string} expression The XPath expression to evaluate.
- * @param {Node} rootNode The HTML node to start evaluating the XPath from.
- * @return {Array} The array of children nodes that match.
- */
-cvox.XpathUtil.evalXPath = function(expression, rootNode) {
- try {
- var xpathIterator = rootNode.ownerDocument.evaluate(
- expression,
- rootNode,
- cvox.XpathUtil.resolveNameSpace,
- XPathResult.ORDERED_NODE_ITERATOR_TYPE,
- null); // no existing results
- } catch (err) {
- return [];
- }
- var results = [];
- // Convert result to JS array
- for (var xpathNode = xpathIterator.iterateNext();
- xpathNode;
- xpathNode = xpathIterator.iterateNext()) {
- results.push(xpathNode);
- }
- return results;
-};
-
-/**
- * Given a rootNode, it returns an array of all its leaf nodes.
- * @param {Node} rootNode The node to get the leaf nodes from.
- * @return {Array} The array of leaf nodes for the given rootNode.
- */
-cvox.XpathUtil.getLeafNodes = function(rootNode) {
- try {
- var xpathIterator = rootNode.ownerDocument.evaluate(
- './/*[count(*)=0]',
- rootNode,
- null, // no namespace resolver
- XPathResult.ORDERED_NODE_ITERATOR_TYPE,
- null); // no existing results
- } catch (err) {
- return [];
- }
- var results = [];
- // Convert result to JS array
- for (var xpathNode = xpathIterator.iterateNext();
- xpathNode;
- xpathNode = xpathIterator.iterateNext()) {
- results.push(xpathNode);
- }
- return results;
-};
-
-/**
- * Returns whether or not xpath is supported.
- * @return {boolean} True if xpath is supported.
- */
-cvox.XpathUtil.xpathSupported = function() {
- if (typeof(XPathResult) == 'undefined') {
- return false;
- }
- return true;
-};
-
-
-/**
- * Given an XPath expression and rootNode, it evaluates the XPath expression as
- * a boolean type and returns the result.
- * @param {string} expression The XPath expression to evaluate.
- * @param {Node} rootNode The HTML node to start evaluating the XPath from.
- * @return {boolean} The result of evaluating the xpath expression.
- */
-cvox.XpathUtil.evaluateBoolean = function(expression, rootNode) {
- try {
- var xpathResult = rootNode.ownerDocument.evaluate(
- expression,
- rootNode,
- cvox.XpathUtil.resolveNameSpace,
- XPathResult.BOOLEAN_TYPE,
- null); // no existing results
- } catch (err) {
- return false;
- }
- return xpathResult.booleanValue;
-};
-
-
-/**
- * Given an XPath expression and rootNode, it evaluates the XPath expression as
- * a string type and returns the result.
- * @param {string} expression The XPath expression to evaluate.
- * @param {Node} rootNode The HTML node to start evaluating the XPath from.
- * @return {string} The result of evaluating the Xpath expression.
- */
-cvox.XpathUtil.evaluateString = function(expression, rootNode) {
- try {
- var xpathResult = rootNode.ownerDocument.evaluate(
- expression,
- rootNode,
- cvox.XpathUtil.resolveNameSpace,
- XPathResult.STRING_TYPE,
- null); // no existing results
- } catch (err) {
- return '';
- }
- return xpathResult.stringValue;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
deleted file mode 100644
index f0ce021c40b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
+++ /dev/null
@@ -1,202 +0,0 @@
-// 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.
-
-/**
- * @fileoverview ChromeVox predicates for the automation extension API.
- */
-
-goog.provide('AutomationPredicate');
-goog.provide('AutomationPredicate.Binary');
-goog.provide('AutomationPredicate.Unary');
-
-goog.scope(function() {
-var RoleType = chrome.automation.RoleType;
-
-/**
- * @constructor
- */
-AutomationPredicate = function() {};
-
-/**
- * @typedef {function(chrome.automation.AutomationNode) : boolean}
- */
-AutomationPredicate.Unary;
-
-/**
- * @typedef {function(chrome.automation.AutomationNode,
- * chrome.automation.AutomationNode) : boolean}
- */
-AutomationPredicate.Binary;
-
-/**
- * Constructs a predicate given a role.
- * @param {RoleType} role
- * @return {AutomationPredicate.Unary}
- */
-AutomationPredicate.withRole = function(role) {
- return function(node) {
- return node.role == role;
- };
-};
-
-/** @type {AutomationPredicate.Unary} */
-AutomationPredicate.checkBox = AutomationPredicate.withRole(RoleType.checkBox);
-/** @type {AutomationPredicate.Unary} */
-AutomationPredicate.comboBox = AutomationPredicate.withRole(RoleType.comboBox);
-/** @type {AutomationPredicate.Unary} */
-AutomationPredicate.editText = AutomationPredicate.withRole(RoleType.textField);
-/** @type {AutomationPredicate.Unary} */
-AutomationPredicate.heading = AutomationPredicate.withRole(RoleType.heading);
-/** @type {AutomationPredicate.Unary} */
-AutomationPredicate.inlineTextBox =
- AutomationPredicate.withRole(RoleType.inlineTextBox);
-/** @type {AutomationPredicate.Unary} */
-AutomationPredicate.link = AutomationPredicate.withRole(RoleType.link);
-/** @type {AutomationPredicate.Unary} */
-AutomationPredicate.table = AutomationPredicate.withRole(RoleType.table);
-
-/**
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.button = function(node) {
- return /button/i.test(node.role);
-};
-
-/**
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.formField = function(node) {
- switch (node.role) {
- case 'button':
- case 'buttonDropDown':
- case 'checkBox':
- case 'comboBox':
- case 'date':
- case 'dateTime':
- case 'details':
- case 'disclosureTriangle':
- case 'form':
- case 'menuButton':
- case 'menuListPopup':
- case 'popUpButton':
- case 'radioButton':
- case 'searchBox':
- case 'slider':
- case 'spinButton':
- case 'switch':
- case 'tab':
- case 'textField':
- case 'time':
- case 'toggleButton':
- case 'tree':
- return true;
- }
- return false;
-};
-
-/**
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.landmark = function(node) {
- switch (node.role) {
- case 'application':
- case 'banner':
- case 'complementary':
- case 'contentInfo':
- case 'form':
- case 'main':
- case 'navigation':
- case 'search':
- return true;
- }
- return false;
-};
-
-/**
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.visitedLink = function(node) {
- return node.state.visited;
-};
-
-/**
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.focused = function(node) {
- return node.state.focused;
-};
-
-/**
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.leaf = function(node) {
- return !node.firstChild ||
- node.role == RoleType.button ||
- node.role == RoleType.buttonDropDown ||
- node.role == RoleType.popUpButton ||
- node.role == RoleType.slider ||
- node.role == RoleType.textField ||
- node.children.every(function(n) {
- return n.state.invisible;
- });
-};
-
-/**
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.leafWithText = function(node) {
- return AutomationPredicate.leaf(node) &&
- !!(node.name || node.value);
-};
-
-/**
- * Matches against non-inline textbox 'nodes' which have an equivalent in the
- * DOM.
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.leafDomNode = function(node) {
- return AutomationPredicate.leaf(node) ||
- node.role == RoleType.staticText;
-};
-
-/**
- * @param {chrome.automation.AutomationNode} first
- * @param {chrome.automation.AutomationNode} second
- * @return {boolean}
- */
-AutomationPredicate.linebreak = function(first, second) {
- // TODO(dtseng): Use next/previousOnLin once available.
- var fl = first.location;
- var sl = second.location;
- return fl.top != sl.top ||
- (fl.top + fl.height != sl.top + sl.height);
-};
-
-/**
- * Leaf nodes that should be ignored while traversing the automation tree. For
- * example, apply this predicate when moving to the next element.
- * @param {chrome.automation.AutomationNode} node
- * @return {boolean}
- */
-AutomationPredicate.shouldIgnoreLeaf = function(node) {
- if (node.name || node.value)
- return false;
-
- return AutomationPredicate.leaf(node) &&
- (node.role == RoleType.client ||
- node.role == RoleType.div ||
- node.role == RoleType.group ||
- node.role == RoleType.image ||
- node.role == RoleType.staticText);
-};
-
-}); // goog.scope
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js
deleted file mode 100644
index 17b52ffb4f6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js
+++ /dev/null
@@ -1,277 +0,0 @@
-// 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.
-
-/**
- * @fileoverview ChromeVox utilities for the automation extension API.
- */
-
-goog.provide('AutomationUtil');
-goog.provide('AutomationUtil.Dir');
-
-goog.require('AutomationPredicate');
-
-/**
- * @constructor
- */
-AutomationUtil = function() {};
-
-/**
- * Possible directions to perform tree traversals.
- * @enum {string}
- */
-AutomationUtil.Dir = {
- // Search from left to right.
- FORWARD: 'forward',
-
- // Search from right to left.
- BACKWARD: 'backward'
-};
-
-
-goog.scope(function() {
-var AutomationNode = chrome.automation.AutomationNode;
-var Dir = AutomationUtil.Dir;
-
-/**
- * Find a node in subtree of |cur| satisfying |pred| using pre-order traversal.
- * @param {AutomationNode} cur Node to begin the search from.
- * @param {Dir} dir
- * @param {AutomationPredicate.Unary} pred A predicate to apply
- * to a candidate node.
- * @return {AutomationNode}
- */
-AutomationUtil.findNodePre = function(cur, dir, pred) {
- if (pred(cur))
- return cur;
-
- var child = dir == Dir.BACKWARD ? cur.lastChild : cur.firstChild;
- while (child) {
- var ret = AutomationUtil.findNodePre(child, dir, pred);
- if (ret)
- return ret;
- child = dir == Dir.BACKWARD ?
- child.previousSibling : child.nextSibling;
- }
-};
-
-/**
- * Find a node in subtree of |cur| satisfying |pred| using post-order traversal.
- * @param {AutomationNode} cur Node to begin the search from.
- * @param {Dir} dir
- * @param {AutomationPredicate.Unary} pred A predicate to apply
- * to a candidate node.
- * @return {AutomationNode}
- */
-AutomationUtil.findNodePost = function(cur, dir, pred) {
- var child = dir == Dir.BACKWARD ? cur.lastChild : cur.firstChild;
- while (child) {
- var ret = AutomationUtil.findNodePost(child, dir, pred);
- if (ret)
- return ret;
- child = dir == Dir.BACKWARD ?
- child.previousSibling : child.nextSibling;
- }
-
- if (pred(cur))
- return cur;
-};
-
-/**
- * Find the next node in the given direction that is either an immediate sibling
- * or a sibling of an ancestor.
- * @param {AutomationNode} cur Node to start search from.
- * @param {Dir} dir
- * @return {AutomationNode}
- */
-AutomationUtil.findNextSubtree = function(cur, dir) {
- while (cur) {
- var next = dir == Dir.BACKWARD ?
- cur.previousSibling : cur.nextSibling;
- if (!AutomationUtil.isInSameTree(cur, next))
- return null;
- if (next)
- return next;
- if (!AutomationUtil.isInSameTree(cur, cur.parent))
- return null;
- cur = cur.parent;
- if (AutomationUtil.isTraversalRoot_(cur))
- return null;
- }
-};
-
-/**
- * Find the next node in the given direction in depth first order.
- * @param {AutomationNode} cur Node to begin the search from.
- * @param {Dir} dir
- * @param {AutomationPredicate.Unary} pred A predicate to apply
- * to a candidate node.
- * @return {AutomationNode}
- */
-AutomationUtil.findNextNode = function(cur, dir, pred) {
- var next = cur;
- do {
- if (!(next = AutomationUtil.findNextSubtree(cur, dir)))
- return null;
- cur = next;
- next = AutomationUtil.findNodePre(next, dir, pred);
- if (next && AutomationPredicate.shouldIgnoreLeaf(next)) {
- cur = next;
- next = null;
- }
- } while (!next);
- return next;
-};
-
-/**
- * Given nodes a_1, ..., a_n starting at |cur| in pre order traversal, apply
- * |pred| to a_i and a_(i - 1) until |pred| is satisfied. Returns a_(i - 1) or
- * a_i (depending on opt_options.before) or null if no match was found.
- * @param {AutomationNode} cur
- * @param {Dir} dir
- * @param {AutomationPredicate.Binary} pred
- * @param {{filter: (AutomationPredicate.Unary|undefined),
- * before: boolean?}=} opt_options
- * filter - Filters which candidate nodes to consider. Defaults to leaf
- * only.
- * before - True to return a_(i - 1); a_i otherwise. Defaults to false.
- * @return {AutomationNode}
- */
-AutomationUtil.findNodeUntil = function(cur, dir, pred, opt_options) {
- opt_options =
- opt_options || {filter: AutomationPredicate.leaf, before: false};
- if (!opt_options.filter)
- opt_options.filter = AutomationPredicate.leaf;
-
- var before = null;
- var after = null;
- var prev = cur;
- AutomationUtil.findNextNode(cur,
- dir,
- function(candidate) {
- if (!opt_options.filter(candidate))
- return false;
-
- var satisfied = pred(prev, candidate);
-
- prev = candidate;
- if (!satisfied)
- before = candidate;
- else
- after = candidate;
- return satisfied;
- });
- return opt_options.before ? before : after;
-};
-
-/**
- * Returns an array containing ancestors of node starting at root down to node.
- * @param {!AutomationNode} node
- * @return {!Array<AutomationNode>}
- */
-AutomationUtil.getAncestors = function(node) {
- var ret = [];
- var candidate = node;
- while (candidate) {
- ret.push(candidate);
-
- if (!AutomationUtil.isInSameTree(candidate, candidate.parent))
- break;
-
- candidate = candidate.parent;
- }
- return ret.reverse();
-};
-
-/**
- * Gets the first index where the two input arrays differ. Returns -1 if they
- * do not.
- * @param {!Array<AutomationNode>} ancestorsA
- * @param {!Array<AutomationNode>} ancestorsB
- * @return {number}
- */
-AutomationUtil.getDivergence = function(ancestorsA, ancestorsB) {
- for (var i = 0; i < ancestorsA.length; i++) {
- if (ancestorsA[i] !== ancestorsB[i])
- return i;
- }
- if (ancestorsA.length == ancestorsB.length)
- return -1;
- return ancestorsA.length;
-};
-
-/**
- * Returns ancestors of |node| that are not also ancestors of |prevNode|.
- * @param {!AutomationNode} prevNode
- * @param {!AutomationNode} node
- * @return {!Array<AutomationNode>}
- */
-AutomationUtil.getUniqueAncestors = function(prevNode, node) {
- var prevAncestors = AutomationUtil.getAncestors(prevNode);
- var ancestors = AutomationUtil.getAncestors(node);
- var divergence = AutomationUtil.getDivergence(prevAncestors, ancestors);
- return ancestors.slice(divergence);
-};
-
-/**
- * Given |nodeA| and |nodeB| in that order, determines their ordering in the
- * document.
- * @param {!AutomationNode} nodeA
- * @param {!AutomationNode} nodeB
- * @return {AutomationUtil.Dir}
- */
-AutomationUtil.getDirection = function(nodeA, nodeB) {
- var ancestorsA = AutomationUtil.getAncestors(nodeA);
- var ancestorsB = AutomationUtil.getAncestors(nodeB);
- var divergence = AutomationUtil.getDivergence(ancestorsA, ancestorsB);
-
- // Default to Dir.FORWARD.
- if (divergence == -1)
- return Dir.FORWARD;
-
- var divA = ancestorsA[divergence];
- var divB = ancestorsB[divergence];
-
- // One of the nodes is an ancestor of the other. Don't distinguish and just
- // consider it Dir.FORWARD.
- if (!divA || !divB || divA.parent === nodeB || divB.parent === nodeA)
- return Dir.FORWARD;
-
- return divA.indexInParent <= divB.indexInParent ? Dir.FORWARD : Dir.BACKWARD;
-};
-
-/**
- * Determines whether the two given nodes come from the same tree source.
- * @param {AutomationNode} a
- * @param {AutomationNode} b
- * @return {boolean}
- */
-AutomationUtil.isInSameTree = function(a, b) {
- if (!a || !b)
- return true;
-
- // Given two non-desktop roots, consider them in the "same" tree.
- return a.root === b.root ||
- (a.root.role == b.root.role && a.root.role == 'rootWebArea');
-};
-
-/**
- * Returns whether the given node should not be crossed when performing
- * traversals up the ancestry chain.
- * @param {AutomationNode} node
- * @return {boolean}
- * @private
- */
-AutomationUtil.isTraversalRoot_ = function(node) {
- switch (node.role) {
- case 'dialog':
- case 'window':
- return true;
- case 'toolbar':
- return node.root.role == 'desktop';
- default:
- return false;
- }
-};
-
-}); // goog.scope
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util_test.extjs b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util_test.extjs
deleted file mode 100644
index 2c75b9fc26b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util_test.extjs
+++ /dev/null
@@ -1,102 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js']);
-
-/**
- * Test fixture for automation_util.js.
- * @constructor
- * @extends {ChromeVoxE2ETestBase}
- */
-function AutomationUtilE2ETest() {
- ChromeVoxNextE2ETest.call(this);
-}
-
-AutomationUtilE2ETest.prototype = {
- __proto__: ChromeVoxNextE2ETest.prototype,
-
- /** @override */
- setUp: function() {
- window.Dir = AutomationUtil.Dir;
- },
-
- basicDoc: function() {/*!
- <p><a href='#'></a>hello</p>
- <h1><ul><li>a</ul><button></h1>
- */}
-};
-
-TEST_F('AutomationUtilE2ETest', 'GetAncestors', function() {
- this.runWithLoadedTree(this.basicDoc, function(root) {
- var expectedLength = 1;
- while (root) {
- var ancestors = AutomationUtil.getAncestors(root);
- assertEquals(expectedLength++, ancestors.length);
- root = root.firstChild;
- }
- });
-});
-
-TEST_F('AutomationUtilE2ETest', 'GetUniqueAncestors', function() {
- this.runWithLoadedTree(this.basicDoc, function(root) {
- var leftmost = root, rightmost = root;
- while (leftmost.firstChild)
- leftmost = leftmost.firstChild;
- while (rightmost.lastChild)
- rightmost = rightmost.lastChild;
-
- var leftAncestors = AutomationUtil.getAncestors(leftmost);
- var rightAncestors = AutomationUtil.getAncestors(rightmost);
- assertEquals(chrome.automation.RoleType.link, leftmost.role);
- assertEquals(chrome.automation.RoleType.button, rightmost.role);
- assertEquals(
- 1, AutomationUtil.getDivergence(leftAncestors, rightAncestors));
- assertEquals(
- -1, AutomationUtil.getDivergence(leftAncestors, leftAncestors));
-
- var uniqueAncestorsLeft =
- AutomationUtil.getUniqueAncestors(rightmost, leftmost);
- var uniqueAncestorsRight =
- AutomationUtil.getUniqueAncestors(leftmost, rightmost);
-
- assertEquals(2, uniqueAncestorsLeft.length);
- assertEquals(chrome.automation.RoleType.paragraph,
- uniqueAncestorsLeft[0].role);
- assertEquals(chrome.automation.RoleType.link,
- uniqueAncestorsLeft[1].role);
-
- assertEquals(3, uniqueAncestorsRight.length);
- assertEquals(chrome.automation.RoleType.heading,
- uniqueAncestorsRight[0].role);
- assertEquals(chrome.automation.RoleType.group,
- uniqueAncestorsRight[1].role);
- assertEquals(chrome.automation.RoleType.button,
- uniqueAncestorsRight[2].role);
-
- assertEquals(
- 1, AutomationUtil.getUniqueAncestors(leftmost, leftmost).length);
-
- });
-});
-
-TEST_F('AutomationUtilE2ETest', 'GetDirection', function() {
- this.runWithLoadedTree(this.basicDoc, function(root) {
- var left = root, right = root;
-
- // Same node.
- assertEquals(Dir.FORWARD, AutomationUtil.getDirection(left, right));
-
- // Ancestor.
- left = left.firstChild;
- assertEquals(Dir.FORWARD, AutomationUtil.getDirection(left, right));
- assertEquals(Dir.FORWARD, AutomationUtil.getDirection(right, left));
-
- // Ordered.
- right = right.lastChild;
- assertEquals(Dir.BACKWARD, AutomationUtil.getDirection(right, left));
- assertEquals(Dir.FORWARD, AutomationUtil.getDirection(left, right));
-
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.html b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.html
deleted file mode 100644
index 84d67865599..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!-- Components to load uncompressed ChromeVox -->
-<script src="../../closure/base.js"></script>
-<script src="../../deps.js"></script>
-
-<!-- ChromeVox Next -->
-<script src="loader.js"></script>
-<script src="../../chromeVox2ChromeBackgroundScript.js"></script>
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
deleted file mode 100644
index aaf20bdd961..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
+++ /dev/null
@@ -1,810 +0,0 @@
-// 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.
-
-/**
- * @fileoverview The entry point for all ChromeVox2 related code for the
- * background page.
- */
-
-goog.provide('Background');
-goog.provide('global');
-
-goog.require('AutomationPredicate');
-goog.require('AutomationUtil');
-goog.require('ClassicCompatibility');
-goog.require('Output');
-goog.require('Output.EventType');
-goog.require('cursors.Cursor');
-goog.require('cvox.BrailleKeyCommand');
-goog.require('cvox.ChromeVoxEditableTextBase');
-goog.require('cvox.ExtensionBridge');
-goog.require('cvox.NavBraille');
-
-goog.scope(function() {
-var AutomationNode = chrome.automation.AutomationNode;
-var Dir = AutomationUtil.Dir;
-var EventType = chrome.automation.EventType;
-var RoleType = chrome.automation.RoleType;
-
-/**
- * All possible modes ChromeVox can run.
- * @enum {string}
- */
-var ChromeVoxMode = {
- CLASSIC: 'classic',
- COMPAT: 'compat',
- NEXT: 'next',
- FORCE_NEXT: 'force_next'
-};
-
-/**
- * ChromeVox2 background page.
- * @constructor
- */
-Background = function() {
- /**
- * A list of site substring patterns to use with ChromeVox next. Keep these
- * strings relatively specific.
- * @type {!Array<string>}
- * @private
- */
- this.whitelist_ = ['chromevox_next_test'];
-
- /**
- * @type {cursors.Range}
- * @private
- */
- this.currentRange_ = null;
-
- /**
- * Which variant of ChromeVox is active.
- * @type {ChromeVoxMode}
- * @private
- */
- this.mode_ = ChromeVoxMode.COMPAT;
-
- /** @type {!ClassicCompatibility} @private */
- this.compat_ = new ClassicCompatibility();
-
- // Manually bind all functions to |this|.
- for (var func in this) {
- if (typeof(this[func]) == 'function')
- this[func] = this[func].bind(this);
- }
-
- /**
- * Maps an automation event to its listener.
- * @type {!Object<EventType, function(Object) : void>}
- */
- this.listeners_ = {
- alert: this.onAlert,
- focus: this.onFocus,
- hover: this.onEventDefault,
- loadComplete: this.onLoadComplete,
- menuStart: this.onEventDefault,
- menuEnd: this.onEventDefault,
- textChanged: this.onTextOrTextSelectionChanged,
- textSelectionChanged: this.onTextOrTextSelectionChanged,
- valueChanged: this.onValueChanged
- };
-
- /**
- * The object that speaks changes to an editable text field.
- * @type {?cvox.ChromeVoxEditableTextBase}
- */
- this.editableTextHandler_ = null;
-
- chrome.automation.getDesktop(this.onGotDesktop);
-
- // Handle messages directed to the Next background page.
- cvox.ExtensionBridge.addMessageListener(function(msg, port) {
- var target = msg['target'];
- var action = msg['action'];
-
- switch (target) {
- case 'next':
- if (action == 'getIsClassicEnabled') {
- var url = msg['url'];
- var isClassicEnabled = this.shouldEnableClassicForUrl_(url);
- port.postMessage({
- target: 'next',
- isClassicEnabled: isClassicEnabled
- });
- }
- break;
- }
- }.bind(this));
-};
-
-Background.prototype = {
- /** Forces ChromeVox Next to be active for all tabs. */
- forceChromeVoxNextActive: function() {
- this.setChromeVoxMode(ChromeVoxMode.FORCE_NEXT);
- },
-
- /**
- * Handles all setup once a new automation tree appears.
- * @param {chrome.automation.AutomationNode} desktop
- */
- onGotDesktop: function(desktop) {
- // Register all automation event listeners.
- for (var eventType in this.listeners_)
- desktop.addEventListener(eventType, this.listeners_[eventType], true);
-
- // Register a tree change observer.
- chrome.automation.addTreeChangeObserver(this.onTreeChange);
-
- // The focused state gets set on the containing webView node.
- var webView = desktop.find({role: RoleType.webView,
- state: {focused: true}});
- if (webView) {
- var root = webView.find({role: RoleType.rootWebArea});
- if (root) {
- this.onLoadComplete(
- {target: root,
- type: chrome.automation.EventType.loadComplete});
- }
- }
- },
-
- /**
- * Handles chrome.commands.onCommand.
- * @param {string} command
- * @param {boolean=} opt_skipCompat Whether to skip compatibility checks.
- */
- onGotCommand: function(command, opt_skipCompat) {
- if (!this.currentRange_)
- return;
-
- if (!opt_skipCompat && this.mode_ === ChromeVoxMode.COMPAT) {
- if (this.compat_.onGotCommand(command))
- return;
- }
-
- var current = this.currentRange_;
- var dir = Dir.FORWARD;
- var pred = null;
- var predErrorMsg = undefined;
- switch (command) {
- case 'nextCharacter':
- current = current.move(cursors.Unit.CHARACTER, Dir.FORWARD);
- break;
- case 'previousCharacter':
- current = current.move(cursors.Unit.CHARACTER, Dir.BACKWARD);
- break;
- case 'nextWord':
- current = current.move(cursors.Unit.WORD, Dir.FORWARD);
- break;
- case 'previousWord':
- current = current.move(cursors.Unit.WORD, Dir.BACKWARD);
- break;
- case 'nextLine':
- current = current.move(cursors.Unit.LINE, Dir.FORWARD);
- break;
- case 'previousLine':
- current = current.move(cursors.Unit.LINE, Dir.BACKWARD);
- break;
- case 'nextButton':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.button;
- predErrorMsg = 'no_next_button';
- break;
- case 'previousButton':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.button;
- predErrorMsg = 'no_previous_button';
- break;
- case 'nextCheckBox':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.checkBox;
- predErrorMsg = 'no_next_checkbox';
- break;
- case 'previousCheckBox':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.checkBox;
- predErrorMsg = 'no_previous_checkbox';
- break;
- case 'nextComboBox':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.comboBox;
- predErrorMsg = 'no_next_combo_box';
- break;
- case 'previousComboBox':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.comboBox;
- predErrorMsg = 'no_previous_combo_box';
- break;
- case 'nextEditText':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.editText;
- predErrorMsg = 'no_next_edit_text';
- break;
- case 'previousEditText':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.editText;
- predErrorMsg = 'no_previous_edit_text';
- break;
- case 'nextFormField':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.formField;
- predErrorMsg = 'no_next_form_field';
- break;
- case 'previousFormField':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.formField;
- predErrorMsg = 'no_previous_form_field';
- break;
- case 'nextHeading':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.heading;
- predErrorMsg = 'no_next_heading';
- break;
- case 'previousHeading':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.heading;
- predErrorMsg = 'no_previous_heading';
- break;
- case 'nextLink':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.link;
- predErrorMsg = 'no_next_link';
- break;
- case 'previousLink':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.link;
- predErrorMsg = 'no_previous_link';
- break;
- case 'nextTable':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.table;
- predErrorMsg = 'no_next_table';
- break;
- case 'previousTable':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.table;
- predErrorMsg = 'no_previous_table';
- break;
- case 'nextVisitedLink':
- dir = Dir.FORWARD;
- pred = AutomationPredicate.visitedLink;
- predErrorMsg = 'no_next_visited_link';
- break;
- case 'previousVisitedLink':
- dir = Dir.BACKWARD;
- pred = AutomationPredicate.visitedLink;
- predErrorMsg = 'no_previous_visited_link';
- break;
- case 'nextElement':
- current = current.move(cursors.Unit.DOM_NODE, Dir.FORWARD);
- break;
- case 'previousElement':
- current = current.move(cursors.Unit.DOM_NODE, Dir.BACKWARD);
- break;
- case 'goToBeginning':
- var node =
- AutomationUtil.findNodePost(current.start.node.root,
- Dir.FORWARD,
- AutomationPredicate.leaf);
- if (node)
- current = cursors.Range.fromNode(node);
- break;
- case 'goToEnd':
- var node =
- AutomationUtil.findNodePost(current.start.node.root,
- Dir.BACKWARD,
- AutomationPredicate.leaf);
- if (node)
- current = cursors.Range.fromNode(node);
- break;
- case 'doDefault':
- if (this.currentRange_) {
- var actionNode = this.currentRange_.start.node;
- if (actionNode.role == RoleType.inlineTextBox)
- actionNode = actionNode.parent;
- actionNode.doDefault();
- }
- // Skip all other processing; if focus changes, we should get an event
- // for that.
- return;
- case 'continuousRead':
- global.isReadingContinuously = true;
- var continueReading = function(prevRange) {
- if (!global.isReadingContinuously || !this.currentRange_)
- return;
-
- new Output().withSpeechAndBraille(
- this.currentRange_, prevRange, Output.EventType.NAVIGATE)
- .onSpeechEnd(function() { continueReading(prevRange); })
- .go();
- prevRange = this.currentRange_;
- this.currentRange_ =
- this.currentRange_.move(cursors.Unit.NODE, Dir.FORWARD);
-
- if (!this.currentRange_ || this.currentRange_.equals(prevRange))
- global.isReadingContinuously = false;
- }.bind(this);
-
- continueReading(null);
- return;
- case 'showContextMenu':
- if (this.currentRange_) {
- var actionNode = this.currentRange_.start.node;
- if (actionNode.role == RoleType.inlineTextBox)
- actionNode = actionNode.parent;
- actionNode.showContextMenu();
- return;
- }
- break;
- case 'showOptionsPage':
- var optionsPage = {url: 'chromevox/background/options.html'};
- chrome.tabs.create(optionsPage);
- break;
- }
-
- if (pred) {
- var node = AutomationUtil.findNextNode(
- current.getBound(dir).node, dir, pred);
-
- if (node) {
- current = cursors.Range.fromNode(node);
- } else {
- if (predErrorMsg) {
- cvox.ChromeVox.tts.speak(Msgs.getMsg(predErrorMsg),
- cvox.QueueMode.FLUSH);
- }
- return;
- }
- }
-
- if (current) {
- // TODO(dtseng): Figure out what it means to focus a range.
- var actionNode = current.start.node;
- if (actionNode.role == RoleType.inlineTextBox)
- actionNode = actionNode.parent;
- actionNode.focus();
-
- var prevRange = this.currentRange_;
- this.currentRange_ = current;
-
- new Output().withSpeechAndBraille(
- this.currentRange_, prevRange, Output.EventType.NAVIGATE)
- .go();
- }
- },
-
- /**
- * Handles a braille command.
- * @param {!cvox.BrailleKeyEvent} evt
- * @param {!cvox.NavBraille} content
- * @return {boolean} True if evt was processed.
- */
- onBrailleKeyEvent: function(evt, content) {
- if (this.mode_ === ChromeVoxMode.CLASSIC)
- return false;
-
- switch (evt.command) {
- case cvox.BrailleKeyCommand.PAN_LEFT:
- this.onGotCommand('previousElement', true);
- break;
- case cvox.BrailleKeyCommand.PAN_RIGHT:
- this.onGotCommand('nextElement', true);
- break;
- case cvox.BrailleKeyCommand.LINE_UP:
- this.onGotCommand('previousLine', true);
- break;
- case cvox.BrailleKeyCommand.LINE_DOWN:
- this.onGotCommand('nextLine', true);
- break;
- case cvox.BrailleKeyCommand.TOP:
- this.onGotCommand('goToBeginning', true);
- break;
- case cvox.BrailleKeyCommand.BOTTOM:
- this.onGotCommand('goToEnd', true);
- break;
- case cvox.BrailleKeyCommand.ROUTING:
- this.brailleRoutingCommand_(
- content.text,
- // Cast ok since displayPosition is always defined in this case.
- /** @type {number} */ (evt.displayPosition));
- break;
- default:
- return false;
- }
- return true;
- },
-
- /**
- * Provides all feedback once ChromeVox's focus changes.
- * @param {Object} evt
- */
- onEventDefault: function(evt) {
- var node = evt.target;
-
- if (!node)
- return;
-
- var prevRange = this.currentRange_;
-
- this.currentRange_ = cursors.Range.fromNode(node);
-
- // Check to see if we've crossed roots. Continue if we've crossed roots or
- // are not within web content.
- if (node.root.role == 'desktop' ||
- !prevRange ||
- prevRange.start.node.root != node.root)
- this.setupChromeVoxVariants_(node.root.docUrl || '');
-
- // Don't process nodes inside of web content if ChromeVox Next is inactive.
- if (node.root.role != RoleType.desktop &&
- this.mode_ === ChromeVoxMode.CLASSIC) {
- chrome.accessibilityPrivate.setFocusRing([]);
- return;
- }
-
- // Don't output if focused node hasn't changed.
- if (prevRange &&
- evt.type == 'focus' &&
- this.currentRange_.equals(prevRange))
- return;
-
- new Output().withSpeechAndBraille(
- this.currentRange_, prevRange, evt.type)
- .go();
- },
-
- /**
- * Makes an announcement without changing focus.
- * @param {Object} evt
- */
- onAlert: function(evt) {
- var node = evt.target;
- if (!node)
- return;
-
- // Don't process nodes inside of web content if ChromeVox Next is inactive.
- if (node.root.role != RoleType.desktop &&
- this.mode_ === ChromeVoxMode.CLASSIC) {
- return;
- }
-
- var range = cursors.Range.fromNode(node);
-
- new Output().withSpeechAndBraille(range, null, evt.type).go();
- },
-
- /**
- * Provides all feedback once a focus event fires.
- * @param {Object} evt
- */
- onFocus: function(evt) {
- // Invalidate any previous editable text handler state.
- this.editableTextHandler_ = null;
-
- var node = evt.target;
-
-
- // Discard focus events on embeddedObject nodes.
- if (node.role == RoleType.embeddedObject)
- return;
-
- // It almost never makes sense to place focus directly on a rootWebArea.
- if (node.role == RoleType.rootWebArea) {
- // Discard focus events for root web areas when focus was previously
- // placed on a descendant.
- if (this.currentRange_.start.node.root == node)
- return;
-
- // Discard focused root nodes without focused state set.
- if (!node.state.focused)
- return;
-
- // Try to find a focusable descendant.
- node = node.find({state: {focused: true}}) || node;
- }
-
- if (evt.target.role == RoleType.textField)
- this.createEditableTextHandlerIfNeeded_(evt.target);
-
- this.onEventDefault({target: node, type: 'focus'});
- },
-
- /**
- * Provides all feedback once a load complete event fires.
- * @param {Object} evt
- */
- onLoadComplete: function(evt) {
- this.setupChromeVoxVariants_(evt.target.docUrl);
-
- // Don't process nodes inside of web content if ChromeVox Next is inactive.
- if (evt.target.root.role != RoleType.desktop &&
- this.mode_ === ChromeVoxMode.CLASSIC)
- return;
-
- // If initial focus was already placed on this page (e.g. if a user starts
- // tabbing before load complete), then don't move ChromeVox's position on
- // the page.
- if (this.currentRange_ &&
- this.currentRange_.start.node.role != RoleType.rootWebArea &&
- this.currentRange_.start.node.root.docUrl == evt.target.docUrl)
- return;
-
- var root = evt.target;
- var webView = root;
- while (webView && webView.role != RoleType.webView)
- webView = webView.parent;
-
- if (!webView || !webView.state.focused)
- return;
-
- var node = AutomationUtil.findNodePost(root,
- Dir.FORWARD,
- AutomationPredicate.leaf);
-
- if (node)
- this.currentRange_ = cursors.Range.fromNode(node);
-
- if (this.currentRange_)
- new Output().withSpeechAndBraille(
- this.currentRange_, null, evt.type)
- .go();
- },
-
- /**
- * Provides all feedback once a text selection change event fires.
- * @param {Object} evt
- */
- onTextOrTextSelectionChanged: function(evt) {
- // Don't process nodes inside of web content if ChromeVox Next is inactive.
- if (evt.target.root.role != RoleType.desktop &&
- this.mode_ === ChromeVoxMode.CLASSIC)
- return;
-
- if (!evt.target.state.focused)
- return;
-
- if (evt.target.role != RoleType.textField)
- return;
-
- if (!this.currentRange_) {
- this.onEventDefault(evt);
- this.currentRange_ = cursors.Range.fromNode(evt.target);
- }
-
- this.createEditableTextHandlerIfNeeded_(evt.target);
- var textChangeEvent = new cvox.TextChangeEvent(
- evt.target.value,
- evt.target.textSelStart,
- evt.target.textSelEnd,
- true); // triggered by user
-
- this.editableTextHandler_.changed(textChangeEvent);
-
- new Output().withBraille(
- this.currentRange_, null, evt.type)
- .go();
- },
-
- /**
- * Provides all feedback once a value changed event fires.
- * @param {Object} evt
- */
- onValueChanged: function(evt) {
- // Don't process nodes inside of web content if ChromeVox Next is inactive.
- if (evt.target.root.role != RoleType.desktop &&
- this.mode_ === ChromeVoxMode.CLASSIC)
- return;
-
- if (!evt.target.state.focused)
- return;
-
- // Value change events fire on web text fields and text areas when pressing
- // enter; suppress them.
- if (!this.currentRange_ ||
- evt.target.role != RoleType.textField) {
- this.onEventDefault(evt);
- this.currentRange_ = cursors.Range.fromNode(evt.target);
- }
- },
-
- /**
- * Called when the automation tree is changed.
- * @param {chrome.automation.TreeChange} treeChange
- */
- onTreeChange: function(treeChange) {
- if (this.mode_ === ChromeVoxMode.CLASSIC)
- return;
-
- var node = treeChange.target;
- if (!node.containerLiveStatus)
- return;
-
- if (node.containerLiveRelevant.indexOf('additions') >= 0 &&
- treeChange.type == 'nodeCreated')
- this.outputLiveRegionChange_(node, null);
- if (node.containerLiveRelevant.indexOf('text') >= 0 &&
- treeChange.type == 'nodeChanged')
- this.outputLiveRegionChange_(node, null);
- if (node.containerLiveRelevant.indexOf('removals') >= 0 &&
- treeChange.type == 'nodeRemoved')
- this.outputLiveRegionChange_(node, '@live_regions_removed');
- },
-
- /**
- * Given a node that needs to be spoken as part of a live region
- * change and an additional optional format string, output the
- * live region description.
- * @param {!chrome.automation.AutomationNode} node The changed node.
- * @param {?string} opt_prependFormatStr If set, a format string for
- * cvox2.Output to prepend to the output.
- * @private
- */
- outputLiveRegionChange_: function(node, opt_prependFormatStr) {
- var range = cursors.Range.fromNode(node);
- var output = new Output();
- if (opt_prependFormatStr) {
- output.format(opt_prependFormatStr);
- }
- output.withSpeech(range, null, Output.EventType.NAVIGATE);
- output.go();
- },
-
- /**
- * Returns true if the url should have Classic running.
- * @return {boolean}
- * @private
- */
- shouldEnableClassicForUrl_: function(url) {
- return this.mode_ != ChromeVoxMode.FORCE_NEXT &&
- !this.isWhitelistedForCompat_(url) &&
- !this.isWhitelistedForNext_(url);
- },
-
- /**
- * @return {boolean}
- * @private
- */
- isWhitelistedForCompat_: function(url) {
- return url.indexOf('chrome://md-settings') != -1 ||
- url.indexOf('chrome://downloads') != -1 ||
- url.indexOf('chrome://oobe/login') != -1 ||
- url.indexOf(
- 'https://accounts.google.com/embedded/setup/chromeos') === 0 ||
- url === '';
- },
-
- /**
- * @private
- * @param {string} url
- * @return {boolean} Whether the given |url| is whitelisted.
- */
- isWhitelistedForNext_: function(url) {
- return this.whitelist_.some(function(item) {
- return url.indexOf(item) != -1;
- }.bind(this));
- },
-
- /**
- * Setup ChromeVox variants.
- * @param {string} url
- * @private
- */
- setupChromeVoxVariants_: function(url) {
- var mode = this.mode_;
- if (mode != ChromeVoxMode.FORCE_NEXT) {
- if (this.isWhitelistedForCompat_(url))
- mode = ChromeVoxMode.COMPAT;
- else if (this.isWhitelistedForNext_(url))
- mode = ChromeVoxMode.NEXT;
- else
- mode = ChromeVoxMode.CLASSIC;
- }
-
- this.setChromeVoxMode(mode);
- },
-
- /**
- * Disables classic ChromeVox in current web content.
- */
- disableClassicChromeVox_: function() {
- cvox.ExtensionBridge.send({
- message: 'SYSTEM_COMMAND',
- command: 'killChromeVox'
- });
- },
-
- /**
- * Sets the current ChromeVox mode.
- * @param {ChromeVoxMode} mode
- */
- setChromeVoxMode: function(mode) {
- if (mode === ChromeVoxMode.NEXT ||
- mode === ChromeVoxMode.COMPAT ||
- mode === ChromeVoxMode.FORCE_NEXT) {
- if (chrome.commands &&
- !chrome.commands.onCommand.hasListener(this.onGotCommand))
- chrome.commands.onCommand.addListener(this.onGotCommand);
- } else {
- if (chrome.commands &&
- chrome.commands.onCommand.hasListener(this.onGotCommand))
- chrome.commands.onCommand.removeListener(this.onGotCommand);
- }
-
- chrome.tabs.query({active: true}, function(tabs) {
- if (mode === ChromeVoxMode.CLASSIC) {
- // This case should do nothing because Classic gets injected by the
- // extension system via our manifest. Once ChromeVox Next is enabled
- // for tabs, re-enable.
- // cvox.ChromeVox.injectChromeVoxIntoTabs(tabs);
- } else {
- // When in compat mode, if the focus is within the desktop tree proper,
- // then do not disable content scripts.
- if (this.currentRange_.start.node.root.role == 'desktop')
- return;
-
- this.disableClassicChromeVox_();
- }
- }.bind(this));
-
- this.mode_ = mode;
- },
-
- /**
- * @param {!cvox.Spannable} text
- * @param {number} position
- * @private
- */
- brailleRoutingCommand_: function(text, position) {
- var actionNode = null;
- var selectionSpan = null;
- text.getSpans(position).forEach(function(span) {
- if (span instanceof Output.SelectionSpan) {
- selectionSpan = span;
- } else if (span instanceof Output.NodeSpan) {
- if (!actionNode ||
- (text.getSpanEnd(actionNode) - text.getSpanStart(actionNode) >
- text.getSpanEnd(span) - text.getSpanStart(span))) {
- actionNode = span.node;
- }
- }
- });
- if (!actionNode)
- return;
- if (actionNode.role === RoleType.inlineTextBox)
- actionNode = actionNode.parent;
- actionNode.doDefault();
- if (selectionSpan) {
- var start = text.getSpanStart(selectionSpan);
- actionNode.setSelection(position - start, position - start);
- }
- },
-
- /**
- * Create an editable text handler for the given node if needed.
- * @param {Object} node
- */
- createEditableTextHandlerIfNeeded_: function(node) {
- if (!this.editableTextHandler_ || node != this.currentRange_.start.node) {
- var start = node.textSelStart;
- var end = node.textSelEnd;
- if (start > end) {
- var tempOffset = end;
- end = start;
- start = tempOffset;
- }
-
- this.editableTextHandler_ =
- new cvox.ChromeVoxEditableTextBase(
- node.value,
- start,
- end,
- node.state.protected,
- cvox.ChromeVox.tts);
- }
- }
-};
-
-/** @type {Background} */
-global.backgroundObj = new Background();
-
-}); // goog.scope
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
deleted file mode 100644
index 82810f95a0d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
+++ /dev/null
@@ -1,370 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js',
- '../../testing/assert_additions.js']);
-
-GEN_INCLUDE(['../../testing/mock_feedback.js']);
-
-/**
- * Test fixture for Background.
- * @constructor
- * @extends {ChromeVoxNextE2ETest}
- */
-function BackgroundTest() {
- ChromeVoxNextE2ETest.call(this);
-}
-
-BackgroundTest.prototype = {
- __proto__: ChromeVoxNextE2ETest.prototype,
-
- /** @override */
- setUp: function() {
- global.backgroundObj.forceChromeVoxNextActive();
- },
-
- /**
- * @return {!MockFeedback}
- */
- createMockFeedback: function() {
- var mockFeedback = new MockFeedback(this.newCallback(),
- this.newCallback.bind(this));
- mockFeedback.install();
- return mockFeedback;
- },
-
- /**
- * Create a function which perform the command |cmd|.
- * @param {string} cmd
- * @return {function() : void}
- */
- doCmd: function(cmd) {
- return function() {
- global.backgroundObj.onGotCommand(cmd);
- };
- },
-
- linksAndHeadingsDoc: function() {/*!
- <p>start</p>
- <a href='#a'>alpha</a>
- <a href='#b'>beta</a>
- <p>
- <h1>charlie</h1>
- <a href='foo'>delta</a>
- </p>
- <a href='#bar'>echo</a>
- <h2>foxtraut</h2>
- <p>end<span>of test</span></p>
- */},
-
- formsDoc: function() {/*!
- <select id="fruitSelect">
- <option>apple</option>
- <option>grape</option>
- <option> banana</option>
- </select>
- */}
-};
-
-/** Tests that ChromeVox classic is in this context. */
-SYNC_TEST_F('BackgroundTest', 'ClassicNamespaces', function() {
- assertEquals('object', typeof(cvox));
- assertEquals('function', typeof(cvox.ChromeVoxBackground));
-});
-
-/** Tests that ChromeVox next is in this context. */
-SYNC_TEST_F('BackgroundTest', 'NextNamespaces', function() {
- assertEquals('function', typeof(Background));
-});
-
-/** Tests consistency of navigating forward and backward. */
-TEST_F('BackgroundTest', 'ForwardBackwardNavigation', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
- var doCmd = this.doCmd.bind(this);
-
- mockFeedback.expectSpeech('start').expectBraille('start');
-
- mockFeedback.call(doCmd('nextLink'))
- .expectSpeech('alpha', 'Link')
- .expectBraille('alpha lnk');
- mockFeedback.call(doCmd('nextLink'))
- .expectSpeech('beta', 'Link')
- .expectBraille('beta lnk');
- mockFeedback.call(doCmd('nextLink'))
- .expectSpeech('delta', 'Link')
- .expectBraille('delta lnk');
- mockFeedback.call(doCmd('previousLink'))
- .expectSpeech('beta', 'Link')
- .expectBraille('beta lnk');
- mockFeedback.call(doCmd('nextHeading'))
- .expectSpeech('Heading 1', 'charlie')
- .expectBraille('h1 charlie');
- mockFeedback.call(doCmd('nextHeading'))
- .expectSpeech('Heading 2', 'foxtraut')
- .expectBraille('h2 foxtraut');
- mockFeedback.call(doCmd('previousHeading'))
- .expectSpeech('Heading 1', 'charlie')
- .expectBraille('h1 charlie');
-
- mockFeedback.call(doCmd('nextElement'))
- .expectSpeech('delta', 'Link')
- .expectBraille('delta lnk');
- mockFeedback.call(doCmd('nextElement'))
- .expectSpeech('echo', 'Link')
- .expectBraille('echo lnk');
- mockFeedback.call(doCmd('nextElement'))
- .expectSpeech('Heading 2', 'foxtraut')
- .expectBraille('h2 foxtraut');
- mockFeedback.call(doCmd('nextElement'))
- .expectSpeech('end')
- .expectBraille('end');
- mockFeedback.call(doCmd('previousElement'))
- .expectSpeech('Heading 2', 'foxtraut')
- .expectBraille('h2 foxtraut');
- mockFeedback.call(doCmd('nextLine'))
- .expectSpeech('end', 'of test')
- .expectBraille('end of test');
-
- mockFeedback.call(doCmd('goToBeginning'))
- .expectSpeech('start')
- .expectBraille('start');
- mockFeedback.call(doCmd('goToEnd'))
- .expectSpeech('of test')
- .expectBraille('of test');
-
- mockFeedback.replay();
- });
-});
-
-TEST_F('BackgroundTest', 'CaretNavigation', function() {
- // TODO(plundblad): Add braille expectaions when crbug.com/523285 is fixed.
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
- var doCmd = this.doCmd.bind(this);
-
- mockFeedback.expectSpeech('start');
- mockFeedback.call(doCmd('nextCharacter'))
- .expectSpeech('t');
- mockFeedback.call(doCmd('nextCharacter'))
- .expectSpeech('a');
- mockFeedback.call(doCmd('nextWord'))
- .expectSpeech('Link', 'alpha');
- mockFeedback.call(doCmd('nextWord'))
- .expectSpeech('Link', 'beta');
- mockFeedback.call(doCmd('nextWord'))
- .expectSpeech('Heading 1', 'charlie');
- mockFeedback.call(doCmd('nextLine'))
- .expectSpeech('Link', 'delta');
- mockFeedback.call(doCmd('nextLine'))
- .expectSpeech('Link', 'echo');
- mockFeedback.call(doCmd('nextLine'))
- .expectSpeech('Heading 2', 'foxtraut');
- mockFeedback.call(doCmd('nextLine'))
- .expectSpeech('end', 'of test');
- mockFeedback.call(doCmd('nextCharacter'))
- .expectSpeech('n');
- mockFeedback.call(doCmd('previousCharacter'))
- .expectSpeech('e');
- mockFeedback.call(doCmd('previousCharacter'))
- .expectSpeech('Heading 2', 't');
- mockFeedback.call(doCmd('previousWord'))
- .expectSpeech('foxtraut');
- mockFeedback.call(doCmd('previousWord'))
- .expectSpeech('Link', 'echo');
- mockFeedback.call(doCmd('previousCharacter'))
- .expectSpeech('Link', 'a');
- mockFeedback.call(doCmd('previousCharacter'))
- .expectSpeech('t');
- mockFeedback.call(doCmd('nextWord'))
- .expectSpeech('Link', 'echo');
- mockFeedback.replay();
- });
-});
-
-TEST_F('BackgroundTest', 'SelectSingleBasic', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree(this.formsDoc, function() {
- var sendDownToSelect =
- this.sendKeyToElement.bind(this, undefined, 'Down', '#fruitSelect');
- mockFeedback.expectSpeech('apple', 'Menu item', /1 of 3/)
- .expectBraille('apple mnuitm 1/3')
- .call(sendDownToSelect)
- .expectSpeech('grape', /2 of 3/)
- .expectBraille('grape mnuitm 2/3')
- .call(sendDownToSelect)
- .expectSpeech('banana', /3 of 3/)
- .expectBraille('banana mnuitm 3/3');
- mockFeedback.replay();
- });
-});
-
-TEST_F('BackgroundTest', 'ContinuousRead', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
- mockFeedback.expectSpeech('start')
- .call(this.doCmd('continuousRead'))
- .expectSpeech(
- 'start',
- 'alpha', 'Link',
- 'beta', 'Link',
- 'Heading 1', 'charlie');
- mockFeedback.replay();
- });
-});
-
-TEST_F('BackgroundTest', 'LiveRegionAddElement', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree(
- function() {/*!
- <h1>Document with live region</h1>
- <p id="live" aria-live="polite"></p>
- <button id="go">Go</button>
- <script>
- document.getElementById('go').addEventListener('click', function() {
- document.getElementById('live').innerHTML = 'Hello, world';
- }, false);
- </script>
- */},
- function(rootNode) {
- var go = rootNode.find({ role: chrome.automation.RoleType.button });
- mockFeedback.call(go.doDefault.bind(go))
- .expectSpeech('Hello, world');
- mockFeedback.replay();
- });
-});
-
-TEST_F('BackgroundTest', 'LiveRegionRemoveElement', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree(
- function() {/*!
- <h1>Document with live region</h1>
- <p id="live" aria-live="polite" aria-relevant="removals">Hello, world</p>
- <button id="go">Go</button>
- <script>
- document.getElementById('go').addEventListener('click', function() {
- document.getElementById('live').innerHTML = '';
- }, false);
- </script>
- */},
- function(rootNode) {
- var go = rootNode.find({ role: chrome.automation.RoleType.button });
- go.doDefault();
- mockFeedback.expectSpeech('removed:')
- .expectSpeech('Hello, world');
- mockFeedback.replay();
- });
-});
-
-TEST_F('BackgroundTest', 'InitialFocus', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree('<a href="a">a</a>',
- function(rootNode) {
- mockFeedback.expectSpeech('a')
- .expectSpeech('Link');
- mockFeedback.replay();
- });
-});
-
-TEST_F('BackgroundTest', 'AriaLabel', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree('<a aria-label="foo" href="a">a</a>',
- function(rootNode) {
- rootNode.find({role: 'link'}).focus();
- mockFeedback.expectSpeech('foo')
- .expectSpeech('Link')
- .expectBraille('foo lnk');
- mockFeedback.replay();
- }
- );
-});
-
-TEST_F('BackgroundTest', 'ShowContextMenu', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree('<a href="a">a</a>',
- function(rootNode) {
- mockFeedback.expectSpeech(/menu opened/)
- .call(function() {
- // When shown, the context menu pushes a new message loop so test
- // messages sent to the browser do not get processed. Ensure we
- // exit the context menu here.
- go.showContextMenu();
- });
- mockFeedback.replay();
-
- var go = rootNode.find({ role: chrome.automation.RoleType.link });
- this.listenOnce(go, 'focus', function(e) {
- this.doCmd('showContextMenu')();
- }.bind(this), true);
- go.focus();
- }.bind(this));
-});
-
-TEST_F('BackgroundTest', 'BrailleRouting', function() {
- var mockFeedback = this.createMockFeedback();
- var route = function(position) {
- assertTrue(global.backgroundObj.onBrailleKeyEvent(
- {command: cvox.BrailleKeyCommand.ROUTING,
- displayPosition: position},
- mockFeedback.lastMatchedBraille));
- };
- this.runWithLoadedTree(
- function() {/*!
- <p>start</p>
- <button id="btn1">Click me</button>
- <p>Some text</p>
- <button id="btn2">Focus me</button>
- <p>Some more text</p>
- <input type="text" id ="text" value="Edit me">
- <script>
- document.getElementById('btn1').addEventListener('click', function() {
- document.getElementById('btn2').focus();
- }, false);
- </script>
- */},
- function(rootNode) {
- var button1 = rootNode.find({role: chrome.automation.RoleType.button,
- name: 'Click me'});
- var textField = rootNode.find(
- {role: chrome.automation.RoleType.textField});
- mockFeedback.expectBraille('start')
- .call(button1.focus.bind(button1))
- .expectBraille(/^Click me btn/)
- .call(route.bind(null, 5))
- .expectBraille(/Focus me btn/)
- .call(textField.focus.bind(textField))
- .expectBraille('Edit me ed', {startIndex: 0})
- .call(route.bind(null, 3))
- .expectBraille('Edit me ed', {startIndex: 3})
- .call(function() {
- assertEquals(3, textField.textSelStart);
- });
- mockFeedback.replay();
- });
-});
-
-TEST_F('BackgroundTest', 'FocusInputElement', function() {
- var mockFeedback = this.createMockFeedback();
- this.runWithLoadedTree(
- function() {/*!
- <input id="name" value="Lancelot">
- <input id="quest" value="Grail">
- <input id="color" value="Blue">
- */},
- function(rootNode) {
- var name = rootNode.find({ attributes: { value: 'Lancelot' } });
- var quest = rootNode.find({ attributes: { value: 'Grail' } });
- var color = rootNode.find({ attributes: { value: 'Blue' } });
-
- mockFeedback.call(quest.focus.bind(quest))
- .expectSpeech('Grail', 'Edit text')
- .call(color.focus.bind(color))
- .expectSpeech('Blue', 'Edit text')
- .call(name.focus.bind(name))
- .expectNextSpeechUtteranceIsNot('Blue')
- .expectSpeech('Lancelot', 'Edit text');
- mockFeedback.replay();
- }.bind(this));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js
deleted file mode 100644
index 35eb9ca3bad..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Provides a compatibility layer for ChromeVox Classic during the
- * transition to ChromeVox Next.
- */
-
-goog.provide('ClassicCompatibility');
-
-goog.require('cvox.ExtensionBridge');
-goog.require('cvox.KeyMap');
-goog.require('cvox.KeySequence');
-goog.require('cvox.KeyUtil');
-goog.require('cvox.SimpleKeyEvent');
-
-/**
- * @constructor
- */
-var ClassicCompatibility = function() {
- /**
- * @type {!Array<{description: string, name: string, shortcut: string}>}
- * @private
- */
- this.commands_ = [];
-
- // We grab the list of commands from the manifest because
- // chrome.commands.getAll is buggy.
- /** @type {!Object} */
- var commands = chrome.runtime.getManifest()['commands'];
- for (var key in commands) {
- /** @type {{suggested_key: {chromeos: string}}} */
- var command = commands[key];
- this.commands_.push({name: key, shortcut: command.suggested_key.chromeos});
- }
-};
-
-ClassicCompatibility.prototype = {
- /**
- * Processes a ChromeVox Next command.
- * @param {string} command
- * @return {boolean} Whether the command was successfully processed.
- */
- onGotCommand: function(command) {
- var evt = this.buildKeyEvent_(command);
- if (evt) {
- this.simulateKeyDownNext_(evt);
- return true;
- }
- cvox.KeyUtil.sequencing = false;
- },
-
- /**
- * Processes a ChromeVox Next command while in CLASSIC mode.
- * @param {string} command
- * @return {boolean} Whether the command was successfully processed.
- */
- onGotClassicCommand: function(command) {
- var evt = this.buildKeyEvent_(command);
- if (!evt)
- return false;
- this.simulateKeyDownClassic_(evt);
- return true;
- },
-
- /**
- * @param {string} command
- * @return {cvox.SimpleKeyEvent?}
- */
- buildKeyEvent_: function(command) {
- var commandInfo = this.commands_.filter(function(c) {
- return c.name == command;
- }.bind(this))[0];
- if (!commandInfo)
- return null;
- var shortcut = commandInfo.shortcut;
- return this.convertCommandShortcutToKeyEvent_(shortcut);
- },
-
- /**
- * @param {cvox.SimpleKeyEvent} evt
- * @private
- */
- simulateKeyDownNext_: function(evt) {
- var keySequence = cvox.KeyUtil.keyEventToKeySequence(evt);
- var classicCommand =
- cvox.KeyMap.fromCurrentKeyMap().commandForKey(keySequence);
- if (classicCommand) {
- var nextCommand = this.getNextCommand_(classicCommand);
- if (nextCommand)
- global.backgroundObj.onGotCommand(nextCommand, true);
- }
- },
-
- /**
- * @param {cvox.SimpleKeyEvent} evt
- * @private
- */
- simulateKeyDownClassic_: function(evt) {
- var keySequence = cvox.KeyUtil.keyEventToKeySequence(evt);
- var classicCommand =
- cvox.KeyMap.fromCurrentKeyMap().commandForKey(keySequence);
- if (classicCommand) {
- cvox.ExtensionBridge.send({
- 'message': 'USER_COMMAND',
- 'command': classicCommand
- });
- }
- },
-
- /**
- * @param {string} shortcut
- * @return {cvox.SimpleKeyEvent}
- * @private
- */
- convertCommandShortcutToKeyEvent_: function(shortcut) {
- var evt = {};
- shortcut.split('+').forEach(function(token) {
- // Known tokens.
- switch (token) {
- case 'Ctrl':
- evt.ctrlKey = true;
- break;
- case 'Shift':
- evt.shiftKey = true;
- break;
- case 'Alt':
- evt.altKey = true;
- break;
- case 'Search':
- evt.searchKeyHeld = true;
- break;
- case 'Space':
- evt.keyCode = 32;
- break;
- case 'Left':
- evt.keyCode = 37;
- break;
- case 'Up':
- evt.keyCode = 38;
- break;
- case 'Right':
- evt.keyCode = 39;
- break;
- case 'Down':
- evt.keyCode = 40;
- break;
- default:
- evt.keyCode = token.charCodeAt(0);
- }
- });
-
- return evt;
- },
-
- /**
- * Maps a Classic command to an approximate equivalent in Next.
- * @param {string} classicCommand
- * @return {string}
- * @private
- */
- getNextCommand_: function(classicCommand) {
- switch (classicCommand) {
- case 'right':
- return 'nextElement';
- case 'forward':
- return 'nextLine';
- case 'left':
- return 'previousElement';
- case 'backward':
- return 'previousLine';
- case 'forceClickOnCurrentItem':
- return 'doDefault';
- case 'readFromHere':
- return 'continuousRead';
- default:
- return classicCommand;
- }
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
deleted file mode 100644
index d92d55adcce..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
+++ /dev/null
@@ -1,397 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Classes related to cursors that point to and select parts of
- * the automation tree.
- */
-
-goog.provide('cursors.Cursor');
-goog.provide('cursors.Movement');
-goog.provide('cursors.Range');
-goog.provide('cursors.Unit');
-
-goog.require('AutomationUtil');
-
-/**
- * The special index that represents a cursor pointing to a node without
- * pointing to any part of its accessible text.
- */
-cursors.NODE_INDEX = -1;
-
-/**
- * Represents units of CursorMovement.
- * @enum {string}
- */
-cursors.Unit = {
- /** A single character within accessible name or value. */
- CHARACTER: 'character',
-
- /** A range of characters (given by attributes on automation nodes). */
- WORD: 'word',
-
- /** A leaf node. */
- NODE: 'node',
-
- /** A leaf DOM-node. */
- DOM_NODE: 'dom_node',
-
- /** Formed by a set of leaf nodes that are inline. */
- LINE: 'line'
-};
-
-/**
- * Represents the ways in which cursors can move given a cursor unit.
- * @enum {string}
- */
-cursors.Movement = {
- /** Move to the beginning or end of the current unit. */
- BOUND: 'bound',
-
- /** Move to the next unit in a particular direction. */
- DIRECTIONAL: 'directional'
-};
-
-goog.scope(function() {
-var AutomationNode = chrome.automation.AutomationNode;
-var Dir = AutomationUtil.Dir;
-var Movement = cursors.Movement;
-var Role = chrome.automation.RoleType;
-var Unit = cursors.Unit;
-
-/**
- * Represents a position within the automation tree.
- * @constructor
- * @param {!AutomationNode} node
- * @param {number} index A 0-based index into either this cursor's name or value
- * attribute. Relies on the fact that a node has either a name or a value but
- * not both. An index of |cursors.NODE_INDEX| means the node as a whole is
- * pointed to and covers the case where the accessible text is empty.
- */
-cursors.Cursor = function(node, index) {
- /** @type {!AutomationNode} @private */
- this.node_ = node;
- /** @type {number} @private */
- this.index_ = index;
-};
-
-/**
- * Convenience method to construct a Cursor from a node.
- * @param {!AutomationNode} node
- * @return {!cursors.Cursor}
- */
-cursors.Cursor.fromNode = function(node) {
- return new cursors.Cursor(node, cursors.NODE_INDEX);
-};
-
-cursors.Cursor.prototype = {
- /**
- * Returns true if |rhs| is equal to this cursor.
- * @param {!cursors.Cursor} rhs
- * @return {boolean}
- */
- equals: function(rhs) {
- return this.node_ === rhs.node &&
- this.index_ === rhs.getIndex();
- },
-
- /**
- * @return {!AutomationNode}
- */
- get node() {
- return this.node_;
- },
-
- /**
- * @return {number}
- */
- getIndex: function() {
- return this.index_;
- },
-
- /**
- * Gets the accessible text of the node associated with this cursor.
- *
- * Note that only one of |name| or |value| attribute is ever nonempty on an
- * automation node. If either contains whitespace, we still treat it as we do
- * for a nonempty string.
- * @param {!AutomationNode=} opt_node Use this node rather than this cursor's
- * node.
- * @return {string}
- */
- getText: function(opt_node) {
- var node = opt_node || this.node_;
- return node.name || node.value || '';
- },
-
- /**
- * Makes a Cursor which has been moved from this cursor by the unit in the
- * given direction using the given movement type.
- * @param {Unit} unit
- * @param {Movement} movement
- * @param {Dir} dir
- * @return {!cursors.Cursor} The moved cursor.
- */
- move: function(unit, movement, dir) {
- var newNode = this.node_;
- var newIndex = this.index_;
-
- if ((unit != Unit.NODE || unit != Unit.DOM_NODE) &&
- newIndex === cursors.NODE_INDEX)
- newIndex = 0;
-
- switch (unit) {
- case Unit.CHARACTER:
- // BOUND and DIRECTIONAL are the same for characters.
- newIndex = dir == Dir.FORWARD ? newIndex + 1 : newIndex - 1;
- if (newIndex < 0 || newIndex >= this.getText().length) {
- newNode = AutomationUtil.findNextNode(
- newNode, dir, AutomationPredicate.leafWithText);
- if (newNode) {
- newIndex =
- dir == Dir.FORWARD ? 0 : this.getText(newNode).length - 1;
- newIndex = newIndex == -1 ? 0 : newIndex;
- } else {
- newIndex = this.index_;
- }
- }
- break;
- case Unit.WORD:
- switch (movement) {
- case Movement.BOUND:
- if (newNode.role == Role.inlineTextBox) {
- var start, end;
- for (var i = 0; i < newNode.wordStarts.length; i++) {
- if (newIndex >= newNode.wordStarts[i] &&
- newIndex <= newNode.wordEnds[i]) {
- start = newNode.wordStarts[i];
- end = newNode.wordEnds[i];
- break;
- }
- }
- if (goog.isDef(start) && goog.isDef(end))
- newIndex = dir == Dir.FORWARD ? end : start;
- } else {
- // TODO(dtseng): Figure out what to do in this case.
- }
- break;
- case Movement.DIRECTIONAL:
- if (newNode.role == Role.inlineTextBox) {
- var start, end;
- for (var i = 0; i < newNode.wordStarts.length; i++) {
- if (newIndex >= newNode.wordStarts[i] &&
- newIndex <= newNode.wordEnds[i]) {
- var nextIndex = dir == Dir.FORWARD ? i + 1 : i - 1;
- start = newNode.wordStarts[nextIndex];
- end = newNode.wordEnds[nextIndex];
- break;
- }
- }
- if (goog.isDef(start)) {
- newIndex = start;
- } else {
- // The backward case is special at the beginning of nodes.
- if (dir == Dir.BACKWARD && newIndex != 0) {
- newIndex = 0;
- } else {
- newNode = AutomationUtil.findNextNode(newNode, dir,
- AutomationPredicate.leaf);
- if (newNode) {
- newIndex = 0;
- if (dir == Dir.BACKWARD &&
- newNode.role == Role.inlineTextBox) {
- var starts = newNode.wordStarts;
- newIndex = starts[starts.length - 1] || 0;
- } else {
- // TODO(dtseng): Figure out what to do for general nodes.
- }
- }
- }
- }
- } else {
- // TODO(dtseng): Figure out what to do in this case.
- }
- }
- break;
- case Unit.NODE:
- case Unit.DOM_NODE:
- switch (movement) {
- case Movement.BOUND:
- newIndex = dir == Dir.FORWARD ? this.getText().length - 1 : 0;
- break;
- case Movement.DIRECTIONAL:
- var pred = unit == Unit.NODE ?
- AutomationPredicate.leaf : AutomationPredicate.leafDomNode;
- newNode = AutomationUtil.findNextNode(
- newNode, dir, pred) || this.node_;
- newIndex = cursors.NODE_INDEX;
- break;
- }
- break;
- case Unit.LINE:
- newIndex = 0;
- switch (movement) {
- case Movement.BOUND:
- newNode = AutomationUtil.findNodeUntil(newNode, dir,
- AutomationPredicate.linebreak, {before: true});
- newNode = newNode || this.node_;
- newIndex =
- dir == Dir.FORWARD ? this.getText(newNode).length : 0;
- break;
- case Movement.DIRECTIONAL:
- newNode = AutomationUtil.findNodeUntil(
- newNode, dir, AutomationPredicate.linebreak);
- break;
- }
- break;
- default:
- throw 'Unrecognized unit: ' + unit;
- }
- newNode = newNode || this.node_;
- newIndex = goog.isDef(newIndex) ? newIndex : this.index_;
- return new cursors.Cursor(newNode, newIndex);
- }
-};
-
-/**
- * Represents a range in the automation tree. There is no visible selection on
- * the page caused by usage of this object.
- * It is assumed that the caller provides |start| and |end| in document order.
- * @param {!cursors.Cursor} start
- * @param {!cursors.Cursor} end
- * @constructor
- */
-cursors.Range = function(start, end) {
- /** @type {!cursors.Cursor} @private */
- this.start_ = start;
- /** @type {!cursors.Cursor} @private */
- this.end_ = end;
-};
-
-/**
- * Convenience method to construct a Range surrounding one node.
- * @param {!AutomationNode} node
- * @return {!cursors.Range}
- */
-cursors.Range.fromNode = function(node) {
- var cursor = cursors.Cursor.fromNode(node);
- return new cursors.Range(cursor, cursor);
-};
-
- /**
- * Given |rangeA| and |rangeB| in order, determine which |Dir|
- * relates them.
- * @param {!cursors.Range} rangeA
- * @param {!cursors.Range} rangeB
- * @return {Dir}
- */
-cursors.Range.getDirection = function(rangeA, rangeB) {
- if (!rangeA || !rangeB)
- return Dir.FORWARD;
-
- // They are the same range.
- if (rangeA.start.node === rangeB.start.node &&
- rangeB.end.node === rangeA.end.node)
- return Dir.FORWARD;
-
- var testDirA =
- AutomationUtil.getDirection(
- rangeA.start.node, rangeB.end.node);
- var testDirB =
- AutomationUtil.getDirection(
- rangeB.start.node, rangeA.end.node);
-
- // The two ranges are either partly overlapping or non overlapping.
- if (testDirA == Dir.FORWARD && testDirB == Dir.BACKWARD)
- return Dir.FORWARD;
- else if (testDirA == Dir.BACKWARD && testDirB == Dir.FORWARD)
- return Dir.BACKWARD;
- else
- return testDirA;
-};
-
-cursors.Range.prototype = {
- /**
- * Returns true if |rhs| is equal to this range.
- * @param {!cursors.Range} rhs
- * @return {boolean}
- */
- equals: function(rhs) {
- return this.start_.equals(rhs.start) &&
- this.end_.equals(rhs.end);
- },
-
- /**
- * Gets a cursor bounding this range.
- * @param {Dir} dir Which endpoint cursor to return; Dir.FORWARD for end,
- * Dir.BACKWARD for start.
- * @param {boolean=} opt_reverse Specify to have Dir.BACKWARD return end,
- * Dir.FORWARD return start.
- * @return {!cursors.Cursor}
- */
- getBound: function(dir, opt_reverse) {
- if (opt_reverse)
- return dir == Dir.BACKWARD ? this.end_ : this.start_;
- return dir == Dir.FORWARD ? this.end_ : this.start_;
- },
-
- /**
- * @return {!cursors.Cursor}
- */
- get start() {
- return this.start_;
- },
-
- /**
- * @return {!cursors.Cursor}
- */
- get end() {
- return this.end_;
- },
-
- /**
- * Returns true if this range covers less than a node.
- * @return {boolean}
- */
- isSubNode: function() {
- return this.start.node === this.end.node &&
- this.start.getIndex() > -1 &&
- this.end.getIndex() > -1;
- },
-
- /**
- * Makes a Range which has been moved from this range by the given unit and
- * direction.
- * @param {Unit} unit
- * @param {Dir} dir
- * @return {cursors.Range}
- */
- move: function(unit, dir) {
- var newStart = this.start_;
- var newEnd = newStart;
- switch (unit) {
- case Unit.CHARACTER:
- newStart = newStart.move(unit, Movement.BOUND, dir);
- newEnd = newStart.move(unit, Movement.BOUND, Dir.FORWARD);
- // Character crossed a node; collapses to the end of the node.
- if (newStart.node !== newEnd.node)
- newEnd = newStart;
- break;
- case Unit.WORD:
- case Unit.LINE:
- newStart = newStart.move(unit, Movement.DIRECTIONAL, dir);
- newStart = newStart.move(unit, Movement.BOUND, Dir.BACKWARD);
- newEnd = newStart.move(unit, Movement.BOUND, Dir.FORWARD);
- break;
- case Unit.NODE:
- case Unit.DOM_NODE:
- newStart = newStart.move(unit, Movement.DIRECTIONAL, dir);
- newEnd = newStart;
- break;
- }
- return new cursors.Range(newStart, newEnd);
- }
-};
-
-}); // goog.scope
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs
deleted file mode 100644
index 346001d4d1b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs
+++ /dev/null
@@ -1,294 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js']);
-
-/**
- * Test fixture for cvox2.cursors.
- * @constructor
- * @extends {ChromeVoxNextE2ETest}
- */
-function CursorsTest() {
- ChromeVoxNextE2ETest.call(this);
-}
-
-CursorsTest.prototype = {
- __proto__: ChromeVoxNextE2ETest.prototype,
-
- /** Test cursors.Cursor. @const {string} */
- CURSOR: 'cursor',
-
- /** Test cursors.Range. @const {string} */
- RANGE: 'range',
-
- /** @override */
- setUp: function() {
- // Various aliases.
- window.BACKWARD = AutomationUtil.Dir.BACKWARD;
- window.FORWARD = AutomationUtil.Dir.FORWARD;
- window.CHARACTER = cursors.Unit.CHARACTER;
- window.WORD = cursors.Unit.WORD;
- window.LINE = cursors.Unit.LINE;
- window.DOM_NODE = cursors.Unit.DOM_NODE;
- window.BOUND = cursors.Movement.BOUND;
- window.DIRECTIONAL = cursors.Movement.DIRECTIONAL;
- },
-
- /**
- * Performs a series of operations on a cursor and asserts the result.
- * @param {cursors.Cursor} cursor The starting cursor.
- * @param {!Array<Array<
- * cursors.Unit|
- * cursors.Movement|
- * automationUtil.Dir|
- * Object>>}
- * moves An array of arrays. Each inner array contains 4 items: unit,
- * movement, direction, and assertions object. See example below.
- */
- cursorMoveAndAssert: function(cursor, moves) {
- var move = null;
- while (move = moves.shift()) {
- cursor = cursor.move(move[0], move[1], move[2]);
- var expected = move[3];
- this.makeCursorAssertion(expected, cursor);
- }
- },
-
- /**
- * Performs a series of operations on a range and asserts the result.
- * @param {cursors.Range} range The starting range.
- * @param {!Array<Array<
- * cursors.Unit|
- * cursors.Movement|
- * automationUtil.Dir|
- * Object>>}
- * moves An array of arrays. Each inner array contains 4 items: unit,
- * direction, start and end assertions objects. See example below.
- */
- rangeMoveAndAssert: function(range, moves) {
- var move = null;
- while (move = moves.shift()) {
- range = range.move(move[0], move[1]);
- var expectedStart = move[2];
- var expectedEnd = move[3];
-
- this.makeCursorAssertion(expectedStart, range.start);
- this.makeCursorAssertion(expectedEnd, range.end);
- }
- },
-
- /**
- * Makes assertions about the given |cursor|.
- * @param {Object} expected
- * @param {Cursor} cursor
- */
- makeCursorAssertion: function(expected, cursor) {
- if (goog.isDef(expected.index))
- assertEquals(expected.index, cursor.getIndex());
- if (goog.isDef(expected.value))
- assertEquals(expected.value, cursor.node.value);
- },
-
- /**
- * Runs the specified moves on the |doc| and asserts expectations.
- * @param {function} doc
- * @param {string=} opt_testType Either CURSOR or RANGE.
- */
- runCursorMovesOnDocument: function(doc, moves, opt_testType) {
- this.runWithLoadedTree(doc,
- function(root) {
- var start = null;
-
- // This occurs as a result of a load complete.
- var start = AutomationUtil.findNodePost(root,
- FORWARD,
- AutomationPredicate.leaf);
-
- var cursor = new cursors.Cursor(start, 0);
- if (!opt_testType || opt_testType == this.CURSOR) {
- var cursor = new cursors.Cursor(start, 0);
- this.cursorMoveAndAssert(cursor, moves);
- } else if (opt_testType == this.RANGE) {
- var range = new cursors.Range(cursor, cursor);
- this.rangeMoveAndAssert(range, moves);
- }
- });
- },
-
-simpleDoc: function() {/*!
- <p>start <span>same line</span>
- <p>end
- */},
-
- multiInlineDoc: function() {/*!
- <p style='max-width: 5px'>start diff line</p>
- <p>end
- */}
-};
-
-TEST_F('CursorsTest', 'CharacterCursor', function() {
- this.runCursorMovesOnDocument(this.simpleDoc, [
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'start '}],
- [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
- [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
-
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'start '}],
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 2, value: 'start '}],
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 3, value: 'start '}],
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 4, value: 'start '}],
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 5, value: 'start '}],
-
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 0, value: 'same line'}],
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'same line'}],
- [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
-
- [CHARACTER, DIRECTIONAL, BACKWARD, {index: 5, value: 'start '}],]);
-});
-
-TEST_F('CursorsTest', 'WordCursor', function() {
- this.runCursorMovesOnDocument(this.simpleDoc, [
- // Word (BOUND).
- [WORD, BOUND, BACKWARD, {index: 0, value: 'start '}],
- [WORD, BOUND, BACKWARD, {index: 0, value: 'start '}],
- [WORD, BOUND, FORWARD, {index: 5, value: 'start '}],
- [WORD, BOUND, FORWARD, {index: 5, value: 'start '}],
-
- // Word (DIRECTIONAL).
- [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'same line'}],
- [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
-
- [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'end'}],
- [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'end'}],
-
- [WORD, DIRECTIONAL, BACKWARD, {index: 5, value: 'same line'}],
- [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
-
- [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
- [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}]]);
-});
-
-TEST_F('CursorsTest', 'CharacterWordCursor', function() {
- this.runCursorMovesOnDocument(this.simpleDoc, [
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'start '}],
-
- [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'same line'}],
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'same line'}],
- [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
- [CHARACTER, DIRECTIONAL, BACKWARD, {index: 4, value: 'same line'}],
- [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
- [CHARACTER, DIRECTIONAL, FORWARD, {index: 6, value: 'same line'}],
- [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
- [CHARACTER, DIRECTIONAL, BACKWARD, {index: 5, value: 'start '}],
- [CHARACTER, DIRECTIONAL, BACKWARD, {index: 4, value: 'start '}],
- [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}]]);
-});
-
-TEST_F('CursorsTest', 'LineCursor', function() {
- this.runCursorMovesOnDocument(this.simpleDoc, [
- // Line (BOUND).
- [LINE, BOUND, FORWARD, {value: 'same line'}],
- [LINE, BOUND, FORWARD, {value: 'same line'}],
- [LINE, BOUND, BACKWARD, {value: 'start '}],
- [LINE, BOUND, BACKWARD, {value: 'start '}],
-
- // Line (DIRECTIONAL).
- [LINE, DIRECTIONAL, FORWARD, {value: 'end'}],
- [LINE, DIRECTIONAL, FORWARD, {value: 'end'}],
- [LINE, DIRECTIONAL, BACKWARD, {value: 'same line'}],
- [LINE, DIRECTIONAL, BACKWARD, {value: 'same line'}],
- [LINE, BOUND, BACKWARD, {value: 'start '}],
- [LINE, DIRECTIONAL, FORWARD, {value: 'end'}]]);
-});
-
-TEST_F('CursorsTest', 'CharacterRange', function() {
- this.runCursorMovesOnDocument(this.simpleDoc, [
- [CHARACTER, FORWARD,
- {value: 'start ', index: 1}, {value: 'start ', index: 2}],
- [CHARACTER, FORWARD,
- {value: 'start ', index: 2}, {value: 'start ', index: 3}],
- [CHARACTER, FORWARD,
- {value: 'start ', index: 3}, {value: 'start ', index: 4}],
- [CHARACTER, FORWARD,
- {value: 'start ', index: 4}, {value: 'start ', index: 5}],
- [CHARACTER, FORWARD,
- {value: 'start ', index: 5}, {value: 'start ', index: 5}],
-
- [CHARACTER, FORWARD,
- {value: 'same line', index: 0}, {value: 'same line', index: 1}],
-
- [CHARACTER, BACKWARD,
- {value: 'start ', index: 5}, {value: 'start ', index: 5}],
- [CHARACTER, BACKWARD,
- {value: 'start ', index: 4}, {value: 'start ', index: 5}],
- [CHARACTER, BACKWARD,
- {value: 'start ', index: 3}, {value: 'start ', index: 4}],
- [CHARACTER, BACKWARD,
- {value: 'start ', index: 2}, {value: 'start ', index: 3}],
- [CHARACTER, BACKWARD,
- {value: 'start ', index: 1}, {value: 'start ', index: 2}],
- [CHARACTER, BACKWARD,
- {value: 'start ', index: 0}, {value: 'start ', index: 1}],
- [CHARACTER, BACKWARD,
- {value: 'start ', index: 0}, {value: 'start ', index: 1}],
- ], this.RANGE);
-});
-
-TEST_F('CursorsTest', 'WordRange', function() {
- this.runCursorMovesOnDocument(this.simpleDoc, [
- [WORD, FORWARD,
- {value: 'same line', index: 0}, {value: 'same line', index: 4}],
- [WORD, FORWARD,
- {value: 'same line', index: 5}, {value: 'same line', index: 9}],
-
- [WORD, FORWARD,
- {value: 'end', index: 0}, {value: 'end', index: 3}],
- [WORD, FORWARD,
- {value: 'end', index: 0}, {value: 'end', index: 3}],
-
- [WORD, BACKWARD,
- {value: 'same line', index: 5}, {value: 'same line', index: 9}],
- [WORD, BACKWARD,
- {value: 'same line', index: 0}, {value: 'same line', index: 4}],
-
- [WORD, BACKWARD,
- {value: 'start ', index: 0}, {value: 'start ', index: 5}],
- [WORD, BACKWARD,
- {value: 'start ', index: 0}, {value: 'start ', index: 5}],
- ], this.RANGE);
-});
-
-
-TEST_F('CursorsTest', 'LineRange', function() {
- this.runCursorMovesOnDocument(this.simpleDoc, [
- [LINE, FORWARD, {value: 'end', index: 0}, {value: 'end', index: 3}],
- [LINE, FORWARD, {value: 'end', index: 0}, {value: 'end', index: 3}],
-
- [LINE, BACKWARD,
- {value: 'start ', index: 0}, {value: 'same line', index: 9}],
-
- [LINE, BACKWARD,
- {value: 'start ', index: 0}, {value: 'same line', index: 9}],
- ], this.RANGE);
-});
-
-TEST_F('CursorsTest', 'DontSplitOnNodeNavigation', function() {
- this.runWithLoadedTree(this.multiInlineDoc, function(root) {
- var para = root.firstChild;
- assertEquals('paragraph', para.role);
- var cursor = new cursors.Cursor(para, 0);
- cursor = cursor.move(DOM_NODE, DIRECTIONAL, FORWARD);
- assertEquals('staticText', cursor.node.role);
- assertEquals('end', cursor.node.value);
-
- cursor = cursor.move(DOM_NODE, DIRECTIONAL, BACKWARD);
- assertEquals('staticText', cursor.node.role);
- assertEquals('start diff line', cursor.node.value);
-
- assertEquals('inlineTextBox', cursor.node.firstChild.role);
- assertEquals('start ', cursor.node.firstChild.value);
- assertEquals('diff ', cursor.node.firstChild.nextSibling.value);
- assertEquals('line', cursor.node.lastChild.value);
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcon_engine.js b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcon_engine.js
deleted file mode 100644
index fc428c54827..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcon_engine.js
+++ /dev/null
@@ -1,711 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview This is the low-level class that generates ChromeVox's
- * earcons. It's designed to be self-contained and not depend on the
- * rest of the code.
- */
-
-goog.provide('EarconEngine');
-
-/**
- * EarconEngine generates ChromeVox's earcons using the web audio API.
- * @constructor
- */
-EarconEngine = function() {
- // Public control parameters. All of these are meant to be adjustable.
-
- /** @type {number} The master volume, as an amplification factor. */
- this.masterVolume = 0.2;
-
- /** @type {number} The base relative pitch adjustment, in half-steps. */
- this.masterPitch = -4;
-
- /** @type {number} The click volume, as an amplification factor. */
- this.clickVolume = 0.4;
-
- /**
- * @type {number} The volume of the static sound, as an
- * amplification factor.
- */
- this.staticVolume = 0.2;
-
- /** @type {number} The base delay for repeated sounds, in seconds. */
- this.baseDelay = 0.045;
-
- /** @type {number} The master stereo panning, from -1 to 1. */
- this.masterPan = 0;
-
- /** @type {number} The master reverb level as an amplification factor. */
- this.masterReverb = 0.4;
-
- /**
- * @type {string} The choice of the reverb impulse response to use.
- * Must be one of the strings from EarconEngine.REVERBS.
- */
- this.reverbSound = 'small_room_2';
-
- /** @type {number} The base pitch for the 'wrap' sound in half-steps. */
- this.wrapPitch = 0;
-
- /** @type {number} The base pitch for the 'alert' sound in half-steps. */
- this.alertPitch = 0;
-
- /** @type {string} The choice of base sound for most controls. */
- this.controlSound = 'control';
-
- /**
- * @type {number} The delay between sounds in the on/off sweep effect,
- * in seconds.
- */
- this.sweepDelay = 0.045;
-
- /**
- * @type {number} The delay between echos in the on/off sweep, in seconds.
- */
- this.sweepEchoDelay = 0.15;
-
- /** @type {number} The number of echos in the on/off sweep. */
- this.sweepEchoCount = 3;
-
- /** @type {number} The pitch offset of the on/off sweep, in half-steps. */
- this.sweepPitch = -7;
-
- /**
- * @type {number} The final gain of the progress sound, as an
- * amplification factor.
- */
- this.progressFinalGain = 0.05;
-
- /** @type {number} The multiplicative decay rate of the progress ticks. */
- this.progressGain_Decay = 0.7;
-
- // Private variables.
-
- /** @type {AudioContext} @private The audio context. */
- this.context_ = new AudioContext();
-
- /** @type {?ConvolverNode} @private The reverb node, lazily initialized. */
- this.reverbConvolver_ = null;
-
- /**
- * @type {Object<string, AudioBuffer>} A map between the name of an
- * audio data file and its loaded AudioBuffer.
- * @private
- */
- this.buffers_ = {};
-
- /**
- * The source audio nodes for queued tick / tocks for progress.
- * Kept around so they can be canceled.
- *
- * @type {Array<AudioNode>}
- * @private
- */
- this.progressSources_ = [];
-
- /** @type {number} The current gain for progress sounds. @private */
- this.progressGain_ = 1.0;
-
- /** @type {?number} The current time for progress sounds. @private */
- this.progressTime_ = this.context_.currentTime;
-
- /**
- * @type {?number} The window.setInterval ID for progress sounds.
- * @private
- */
- this.progressIntervalID_ = null;
-
- // Initialization: load the base sound data files asynchronously.
- var allSoundFilesToLoad = EarconEngine.SOUNDS.concat(EarconEngine.REVERBS);
- allSoundFilesToLoad.forEach((function(sound) {
- var url = EarconEngine.BASE_URL + sound + '.wav';
- this.loadSound(sound, url);
- }).bind(this));
-};
-
-/**
- * @type {Array<string>} The list of sound data files to load.
- * @const
- */
-EarconEngine.SOUNDS = [
- 'control',
- 'selection',
- 'selection_reverse',
- 'skim',
- 'static'];
-
-/**
- * @type {Array<string>} The list of reverb data files to load.
- * @const
- */
-EarconEngine.REVERBS = [
- 'small_room_2'];
-
-/**
- * @type {number} The scale factor for one half-step.
- * @const
- */
-EarconEngine.HALF_STEP = Math.pow(2.0, 1.0 / 12.0);
-
-/**
- * @type {string} The base url for earcon sound resources.
- * @const
- */
-EarconEngine.BASE_URL = chrome.extension.getURL('cvox2/background/earcons/');
-
-/**
- * Fetches a sound asynchronously and loads its data into an AudioBuffer.
- *
- * @param {string} name The name of the sound to load.
- * @param {string} url The url where the sound should be fetched from.
- */
-EarconEngine.prototype.loadSound = function(name, url) {
- var request = new XMLHttpRequest();
- request.open('GET', url, true);
- request.responseType = 'arraybuffer';
-
- // Decode asynchronously.
- request.onload = (function() {
- this.context_.decodeAudioData(
- /** @type {ArrayBuffer} */ (request.response),
- (function(buffer) {
- this.buffers_[name] = buffer;
- }).bind(this));
- }).bind(this);
- request.send();
-};
-
-/**
- * Return an AudioNode containing the final processing that all
- * sounds go through: master volume / gain, panning, and reverb.
- * The chain is hooked up to the destination automatically, so you
- * just need to connect your source to the return value from this
- * method.
- *
- * @param {{gain: (number | undefined),
- * pan: (number | undefined),
- * reverb: (number | undefined)}} properties
- * An object where you can override the default
- * gain, pan, and reverb, otherwise these are taken from
- * masterVolume, masterPan, and masterReverb.
- * @return {AudioNode} The filters to be applied to all sounds, connected
- * to the destination node.
- */
-EarconEngine.prototype.createCommonFilters = function(properties) {
- var gain = this.masterVolume;
- if (properties.gain) {
- gain *= properties.gain;
- }
- var gainNode = this.context_.createGain();
- gainNode.gain.value = gain;
- var first = gainNode;
- var last = gainNode;
-
- var pan = this.masterPan;
- if (properties.pan !== undefined) {
- pan = properties.pan;
- }
- if (pan != 0) {
- var panNode = this.context_.createPanner();
- panNode.setPosition(pan, 0, -1);
- panNode.setOrientation(0, 0, 1);
- last.connect(panNode);
- last = panNode;
- }
-
- var reverb = this.masterReverb;
- if (properties.reverb !== undefined) {
- reverb = properties.reverb;
- }
- if (reverb) {
- if (!this.reverbConvolver_) {
- this.reverbConvolver_ = this.context_.createConvolver();
- this.reverbConvolver_.buffer = this.buffers_[this.reverbSound];
- this.reverbConvolver_.connect(this.context_.destination);
- }
-
- // Dry
- last.connect(this.context_.destination);
-
- // Wet
- var reverbGainNode = this.context_.createGain();
- reverbGainNode.gain.value = reverb;
- last.connect(reverbGainNode);
- reverbGainNode.connect(this.reverbConvolver_);
- } else {
- last.connect(this.context_.destination);
- }
-
- return first;
-};
-
-/**
- * High-level interface to play a sound from a buffer source by name,
- * with some simple adjustments like pitch change (in half-steps),
- * a start time (relative to the current time, in seconds),
- * gain, panning, and reverb.
- *
- * The only required parameter is the name of the sound. The time, pitch,
- * gain, panning, and reverb are all optional and are passed in an
- * object of optional properties.
- *
- * @param {string} sound The name of the sound to play. It must already
- * be loaded in a buffer.
- * @param {{pitch: (number | undefined),
- * time: (number | undefined),
- * gain: (number | undefined),
- * pan: (number | undefined),
- * reverb: (number | undefined)}=} opt_properties
- * An object where you can override the default pitch, gain, pan,
- * and reverb.
- * @return {AudioBufferSourceNode} The source node, so you can stop it
- * or set event handlers on it.
- */
-EarconEngine.prototype.play = function(sound, opt_properties) {
- var source = this.context_.createBufferSource();
- source.buffer = this.buffers_[sound];
-
- if (!opt_properties) {
- // This typecast looks silly, but the Closure compiler doesn't support
- // optional fields in record types very well so this is the shortest hack.
- opt_properties = /** @type {undefined} */({});
- }
-
- var pitch = this.masterPitch;
- if (opt_properties.pitch) {
- pitch += opt_properties.pitch;
- }
- if (pitch != 0) {
- source.playbackRate.value = Math.pow(EarconEngine.HALF_STEP, pitch);
- }
-
- var destination = this.createCommonFilters(opt_properties);
- source.connect(destination);
-
- if (opt_properties.time) {
- source.start(this.context_.currentTime + opt_properties.time);
- } else {
- source.start(this.context_.currentTime);
- }
-
- return source;
-};
-
-/**
- * Play the static sound.
- */
-EarconEngine.prototype.onStatic = function() {
- this.play('static', {gain: this.staticVolume});
-};
-
-/**
- * Play the link sound.
- */
-EarconEngine.prototype.onLink = function() {
- this.play('static', {gain: this.clickVolume});
- this.play(this.controlSound, {pitch: 12});
-};
-
-/**
- * Play the button sound.
- */
-EarconEngine.prototype.onButton = function() {
- this.play('static', {gain: this.clickVolume});
- this.play(this.controlSound);
-};
-
-/**
- * Play the text field sound.
- */
-EarconEngine.prototype.onTextField = function() {
- this.play('static', {gain: this.clickVolume});
- this.play('static', {time: this.baseDelay * 1.5,
- gain: this.clickVolume * 0.5});
- this.play(this.controlSound, {pitch: 4});
- this.play(this.controlSound,
- {pitch: 4,
- time: this.baseDelay * 1.5,
- gain: 0.5});
-};
-
-/**
- * Play the pop up button sound.
- */
-EarconEngine.prototype.onPopUpButton = function() {
- this.play('static', {gain: this.clickVolume});
-
- this.play(this.controlSound);
- this.play(this.controlSound,
- {time: this.baseDelay * 3,
- gain: 0.2,
- pitch: 12});
- this.play(this.controlSound,
- {time: this.baseDelay * 4.5,
- gain: 0.2,
- pitch: 12});
-};
-
-/**
- * Play the check on sound.
- */
-EarconEngine.prototype.onCheckOn = function() {
- this.play('static', {gain: this.clickVolume});
- this.play(this.controlSound, {pitch: -5});
- this.play(this.controlSound, {pitch: 7, time: this.baseDelay * 2});
-};
-
-/**
- * Play the check off sound.
- */
-EarconEngine.prototype.onCheckOff = function() {
- this.play('static', {gain: this.clickVolume});
- this.play(this.controlSound, {pitch: 7});
- this.play(this.controlSound, {pitch: -5, time: this.baseDelay * 2});
-};
-
-/**
- * Play the select control sound.
- */
-EarconEngine.prototype.onSelect = function() {
- this.play('static', {gain: this.clickVolume});
- this.play(this.controlSound);
- this.play(this.controlSound, {time: this.baseDelay});
- this.play(this.controlSound, {time: this.baseDelay * 2});
-};
-
-/**
- * Play the slider sound.
- */
-EarconEngine.prototype.onSlider = function() {
- this.play('static', {gain: this.clickVolume});
- this.play(this.controlSound);
- this.play(this.controlSound,
- {time: this.baseDelay,
- gain: 0.5,
- pitch: 2});
- this.play(this.controlSound,
- {time: this.baseDelay * 2,
- gain: 0.25,
- pitch: 4});
- this.play(this.controlSound,
- {time: this.baseDelay * 3,
- gain: 0.125,
- pitch: 6});
- this.play(this.controlSound,
- {time: this.baseDelay * 4,
- gain: 0.0625,
- pitch: 8});
-};
-
-/**
- * Play the skim sound.
- */
-EarconEngine.prototype.onSkim = function() {
- this.play('skim');
-};
-
-/**
- * Play the selection sound.
- */
-EarconEngine.prototype.onSelection = function() {
- this.play('selection');
-};
-
-/**
- * Play the selection reverse sound.
- */
-EarconEngine.prototype.onSelectionReverse = function() {
- this.play('selection_reverse');
-};
-
-/**
- * Generate a synthesized musical note based on a sum of sinusoidals shaped
- * by an envelope, controlled by a number of properties.
- *
- * The sound has a frequency of |freq|, or if |endFreq| is specified, does
- * an exponential ramp from |freq| to |endFreq|.
- *
- * If |overtones| is greater than 1, the sound will be mixed with additional
- * sinusoidals at multiples of |freq|, each one scaled by |overtoneFactor|.
- * This creates a rounder tone than a pure sine wave.
- *
- * The envelope is shaped by the duration |dur|, the attack time |attack|,
- * and the decay time |decay|, in seconds.
- *
- * As with other functions, |pan| and |reverb| can be used to override
- * masterPan and masterReverb.
- *
- * @param {{gain: number,
- * freq: number,
- * endFreq: (number | undefined),
- * time: (number | undefined),
- * overtones: (number | undefined),
- * overtoneFactor: (number | undefined),
- * dur: (number | undefined),
- * attack: (number | undefined),
- * decay: (number | undefined),
- * pan: (number | undefined),
- * reverb: (number | undefined)}} properties
- * An object containing the properties that can be used to
- * control the sound, as described above.
- */
-EarconEngine.prototype.generateSinusoidal = function(properties) {
- var envelopeNode = this.context_.createGain();
- envelopeNode.connect(this.context_.destination);
-
- var time = properties.time;
- if (time === undefined) {
- time = 0;
- }
-
- // Generate an oscillator for the frequency corresponding to the specified
- // frequency, and then additional overtones at multiples of that frequency
- // scaled by the overtoneFactor. Cue the oscillator to start and stop
- // based on the start time and specified duration.
- //
- // If an end frequency is specified, do an exponential ramp to that end
- // frequency.
- var gain = properties.gain;
- for (var i = 0; i < properties.overtones; i++) {
- var osc = this.context_.createOscillator();
- osc.frequency.value = properties.freq * (i + 1);
-
- if (properties.endFreq) {
- osc.frequency.setValueAtTime(
- properties.freq * (i + 1),
- this.context_.currentTime + time);
- osc.frequency.exponentialRampToValueAtTime(
- properties.endFreq * (i + 1),
- this.context_.currentTime + properties.dur);
- }
-
- osc.start(this.context_.currentTime + time);
- osc.stop(this.context_.currentTime + time + properties.dur);
-
- var gainNode = this.context_.createGain();
- gainNode.gain.value = gain;
- osc.connect(gainNode);
- gainNode.connect(envelopeNode);
-
- gain *= properties.overtoneFactor;
- }
-
- // Shape the overall sound by an envelope based on the attack and
- // decay times.
- envelopeNode.gain.setValueAtTime(0, this.context_.currentTime + time);
- envelopeNode.gain.linearRampToValueAtTime(
- 1, this.context_.currentTime + time + properties.attack);
- envelopeNode.gain.setValueAtTime(
- 1, this.context_.currentTime + time +
- properties.dur - properties.decay);
- envelopeNode.gain.linearRampToValueAtTime(
- 0, this.context_.currentTime + time + properties.dur);
-
- // Route everything through the common filters like reverb at the end.
- var destination = this.createCommonFilters({});
- envelopeNode.connect(destination);
-};
-
-/**
- * Play a sweep over a bunch of notes in a scale, with an echo,
- * for the ChromeVox on or off sounds.
- *
- * @param {boolean} reverse Whether to play in the reverse direction.
- */
-EarconEngine.prototype.onChromeVoxSweep = function(reverse) {
- var pitches = [-7, -5, 0, 5, 7, 12, 17, 19, 24];
-
- if (reverse) {
- pitches.reverse();
- }
-
- var attack = 0.015;
- var dur = pitches.length * this.sweepDelay;
-
- var destination = this.createCommonFilters({reverb: 2.0});
- for (var k = 0; k < this.sweepEchoCount; k++) {
- var envelopeNode = this.context_.createGain();
- var startTime = this.context_.currentTime + this.sweepEchoDelay * k;
- var sweepGain = Math.pow(0.3, k);
- var overtones = 2;
- var overtoneGain = sweepGain;
- for (var i = 0; i < overtones; i++) {
- var osc = this.context_.createOscillator();
- osc.start(startTime);
- osc.stop(startTime + dur);
-
- var gainNode = this.context_.createGain();
- osc.connect(gainNode);
- gainNode.connect(envelopeNode);
-
- for (var j = 0; j < pitches.length; j++) {
- var freqDecay;
- if (reverse) {
- freqDecay = Math.pow(0.75, pitches.length - j);
- } else {
- freqDecay = Math.pow(0.75, j);
- }
- var gain = overtoneGain * freqDecay;
- var freq = (i + 1) * 220 *
- Math.pow(EarconEngine.HALF_STEP, pitches[j] + this.sweepPitch);
- if (j == 0) {
- osc.frequency.setValueAtTime(freq, startTime);
- gainNode.gain.setValueAtTime(gain, startTime);
- } else {
- osc.frequency.exponentialRampToValueAtTime(
- freq, startTime + j * this.sweepDelay);
- gainNode.gain.linearRampToValueAtTime(
- gain, startTime + j * this.sweepDelay);
- }
- osc.frequency.setValueAtTime(
- freq, startTime + j * this.sweepDelay + this.sweepDelay - attack);
- }
-
- overtoneGain *= 0.1 + 0.2 * k;
- }
-
- envelopeNode.gain.setValueAtTime(0, startTime);
- envelopeNode.gain.linearRampToValueAtTime(1, startTime + this.sweepDelay);
- envelopeNode.gain.setValueAtTime(1, startTime + dur - attack * 2);
- envelopeNode.gain.linearRampToValueAtTime(0, startTime + dur);
- envelopeNode.connect(destination);
- }
-};
-
-/**
- * Play the "ChromeVox On" sound.
- */
-EarconEngine.prototype.onChromeVoxOn = function() {
- this.onChromeVoxSweep(false);
-};
-
-/**
- * Play the "ChromeVox Off" sound.
- */
-EarconEngine.prototype.onChromeVoxOff = function() {
- this.onChromeVoxSweep(true);
-};
-
-/**
- * Play an alert sound.
- */
-EarconEngine.prototype.onAlert = function() {
- var freq1 = 220 * Math.pow(EarconEngine.HALF_STEP, this.alertPitch - 2);
- var freq2 = 220 * Math.pow(EarconEngine.HALF_STEP, this.alertPitch - 3);
- this.generateSinusoidal({attack: 0.02,
- decay: 0.07,
- dur: 0.15,
- gain: 0.3,
- freq: freq1,
- overtones: 3,
- overtoneFactor: 0.1});
- this.generateSinusoidal({attack: 0.02,
- decay: 0.07,
- dur: 0.15,
- gain: 0.3,
- freq: freq2,
- overtones: 3,
- overtoneFactor: 0.1});
-};
-
-/**
- * Play a wrap sound.
- */
-EarconEngine.prototype.onWrap = function() {
- this.play('static', {gain: this.clickVolume * 0.3});
- var freq1 = 220 * Math.pow(EarconEngine.HALF_STEP, this.wrapPitch - 8);
- var freq2 = 220 * Math.pow(EarconEngine.HALF_STEP, this.wrapPitch + 8);
- this.generateSinusoidal({attack: 0.01,
- decay: 0.1,
- dur: 0.15,
- gain: 0.3,
- freq: freq1,
- endFreq: freq2,
- overtones: 1,
- overtoneFactor: 0.1});
-};
-
-/**
- * Queue up a few tick/tock sounds for a progress bar. This is called
- * repeatedly by setInterval to keep the sounds going continuously.
- * @private
- */
-EarconEngine.prototype.generateProgressTickTocks_ = function() {
- while (this.progressTime_ < this.context_.currentTime + 3.0) {
- var t = this.progressTime_ - this.context_.currentTime;
- this.progressSources_.push(
- [this.progressTime_,
- this.play('static',
- {gain: 0.5 * this.progressGain_,
- time: t})]);
- this.progressSources_.push(
- [this.progressTime_,
- this.play(this.controlSound,
- {pitch: 20,
- time: t,
- gain: this.progressGain_})]);
-
- if (this.progressGain_ > this.progressFinalGain) {
- this.progressGain_ *= this.progressGain_Decay;
- }
- t += 0.5;
-
- this.progressSources_.push(
- [this.progressTime_,
- this.play('static',
- {gain: 0.5 * this.progressGain_,
- time: t})]);
- this.progressSources_.push(
- [this.progressTime_,
- this.play(this.controlSound,
- {pitch: 8,
- time: t,
- gain: this.progressGain_})]);
-
- if (this.progressGain_ > this.progressFinalGain) {
- this.progressGain_ *= this.progressGain_Decay;
- }
-
- this.progressTime_ += 1.0;
- }
-
- var removeCount = 0;
- while (removeCount < this.progressSources_.length &&
- this.progressSources_[removeCount][0] < this.context_.currentTime - 0.2) {
- removeCount++;
- }
- this.progressSources_.splice(0, removeCount);
-};
-
-/**
- * Start playing tick / tock progress sounds continuously until
- * explicitly canceled.
- */
-EarconEngine.prototype.startProgress = function() {
- this.progressSources_ = [];
- this.progressGain_ = 0.5;
- this.progressTime_ = this.context_.currentTime;
- this.generateProgressTickTocks_();
- this.progressIntervalID_ = window.setInterval(
- this.generateProgressTickTocks_.bind(this), 1000);
-};
-
-/**
- * Stop playing any tick / tock progress sounds.
- */
-EarconEngine.prototype.cancelProgress = function() {
- if (!this.progressIntervalID_) {
- return;
- }
-
- for (var i = 0; i < this.progressSources_.length; i++) {
- this.progressSources_[i][1].stop();
- }
- this.progressSources_ = [];
-
- window.clearInterval(this.progressIntervalID_);
- this.progressIntervalID_ = null;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/control.wav b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/control.wav
deleted file mode 100644
index 4a37991111a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/control.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/selection.wav b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/selection.wav
deleted file mode 100644
index 7be8224dbd3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/selection.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/selection_reverse.wav b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/selection_reverse.wav
deleted file mode 100644
index a42b0d9afb3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/selection_reverse.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/skim.wav b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/skim.wav
deleted file mode 100644
index b74c196c18b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/skim.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/small_room_2.wav b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/small_room_2.wav
deleted file mode 100644
index 7ef10db6c87..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/small_room_2.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/static.wav b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/static.wav
deleted file mode 100644
index d43fae18449..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/earcons/static.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/loader.js b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/loader.js
deleted file mode 100644
index 7f2602dc9f3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/loader.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Loader for the background page.
- */
-
-goog.require('Background');
-goog.require('cvox.ChromeVoxBackground');
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
deleted file mode 100644
index 677030882ea..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
+++ /dev/null
@@ -1,1329 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Provides output services for ChromeVox.
- */
-
-goog.provide('Output');
-goog.provide('Output.EventType');
-
-goog.require('AutomationUtil.Dir');
-goog.require('EarconEngine');
-goog.require('cursors.Cursor');
-goog.require('cursors.Range');
-goog.require('cursors.Unit');
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.NavBraille');
-goog.require('cvox.Spannable');
-goog.require('cvox.ValueSelectionSpan');
-goog.require('cvox.ValueSpan');
-goog.require('goog.i18n.MessageFormat');
-
-goog.scope(function() {
-var Dir = AutomationUtil.Dir;
-
-/**
- * An Output object formats a cursors.Range into speech, braille, or both
- * representations. This is typically a cvox.Spannable.
- *
- * The translation from Range to these output representations rely upon format
- * rules which specify how to convert AutomationNode objects into annotated
- * strings.
- * The format of these rules is as follows.
- *
- * $ prefix: used to substitute either an attribute or a specialized value from
- * an AutomationNode. Specialized values include role and state.
- * For example, $value $role $enabled
- * @ prefix: used to substitute a message. Note the ability to specify params to
- * the message. For example, '@tag_html' '@selected_index($text_sel_start,
- * $text_sel_end').
- * @@ prefix: similar to @, used to substitute a message, but also pulls the
- * localized string through goog.i18n.MessageFormat to support locale
- * aware plural handling. The first argument should be a number which will
- * be passed as a COUNT named parameter to MessageFormat.
- * TODO(plundblad): Make subsequent arguments normal placeholder arguments
- * when needed.
- * = suffix: used to specify substitution only if not previously appended.
- * For example, $name= would insert the name attribute only if no name
- * attribute had been inserted previously.
- * @constructor
- */
-Output = function() {
- // TODO(dtseng): Include braille specific rules.
- /** @type {!Array<!cvox.Spannable>} */
- this.speechBuffer_ = [];
- /** @type {!Array<!cvox.Spannable>} */
- this.brailleBuffer_ = [];
- /** @type {!Array<!Object>} */
- this.locations_ = [];
- /** @type {function(?)} */
- this.speechEndCallback_;
-
- /**
- * Current global options.
- * @type {{speech: boolean, braille: boolean, location: boolean}}
- */
- this.formatOptions_ = {speech: true, braille: false, location: true};
-
- /**
- * Speech properties to apply to the entire output.
- * @type {!Object<*>}
- */
- this.speechProperties_ = {};
-};
-
-/**
- * Delimiter to use between output values.
- * @type {string}
- */
-Output.SPACE = ' ';
-
-/**
- * Metadata about supported automation roles.
- * @const {Object<{msgId: string,
- * earconId: (string|undefined),
- * inherits: (string|undefined)}>}
- * msgId: the message id of the role.
- * earconId: an optional earcon to play when encountering the role.
- * inherits: inherits rules from this role.
- * @private
- */
-Output.ROLE_INFO_ = {
- alert: {
- msgId: 'role_alert',
- earconId: 'ALERT_NONMODAL',
- },
- alertDialog: {
- msgId: 'role_alertdialog'
- },
- article: {
- msgId: 'role_article',
- inherits: 'abstractContainer'
- },
- application: {
- msgId: 'role_application',
- inherits: 'abstractContainer'
- },
- banner: {
- msgId: 'role_banner',
- inherits: 'abstractContainer'
- },
- button: {
- msgId: 'role_button',
- earconId: 'BUTTON'
- },
- buttonDropDown: {
- msgId: 'role_button',
- earconId: 'BUTTON'
- },
- cell: {
- msgId: 'role_gridcell'
- },
- checkBox: {
- msgId: 'role_checkbox'
- },
- columnHeader: {
- msgId: 'role_columnheader',
- inherits: 'abstractContainer'
- },
- comboBox: {
- msgId: 'role_combobox'
- },
- complementary: {
- msgId: 'role_complementary',
- inherits: 'abstractContainer'
- },
- contentInfo: {
- msgId: 'role_contentinfo',
- inherits: 'abstractContainer'
- },
- date: {
- msgId: 'input_type_date',
- inherits: 'abstractContainer'
- },
- definition: {
- msgId: 'role_definition',
- inherits: 'abstractContainer'
- },
- dialog: {
- msgId: 'role_dialog'
- },
- directory: {
- msgId: 'role_directory',
- inherits: 'abstractContainer'
- },
- document: {
- msgId: 'role_document',
- inherits: 'abstractContainer'
- },
- form: {
- msgId: 'role_form',
- inherits: 'abstractContainer'
- },
- grid: {
- msgId: 'role_grid'
- },
- group: {
- msgId: 'role_group'
- },
- heading: {
- msgId: 'role_heading',
- },
- image: {
- msgId: 'role_img',
- },
- inputTime: {
- msgId: 'input_type_time',
- inherits: 'abstractContainer'
- },
- link: {
- msgId: 'role_link',
- earconId: 'LINK'
- },
- listBox: {
- msgId: 'role_listbox',
- earconId: 'LISTBOX'
- },
- listBoxOption: {
- msgId: 'role_listitem',
- earconId: 'LIST_ITEM'
- },
- listItem: {
- msgId: 'role_listitem',
- earconId: 'LIST_ITEM'
- },
- log: {
- msgId: 'role_log',
- },
- main: {
- msgId: 'role_main',
- inherits: 'abstractContainer'
- },
- marquee: {
- msgId: 'role_marquee',
- },
- math: {
- msgId: 'role_math',
- inherits: 'abstractContainer'
- },
- menu: {
- msgId: 'role_menu'
- },
- menuBar: {
- msgId: 'role_menubar',
- },
- menuItem: {
- msgId: 'role_menuitem'
- },
- menuItemCheckBox: {
- msgId: 'role_menuitemcheckbox'
- },
- menuItemRadio: {
- msgId: 'role_menuitemradio'
- },
- menuListOption: {
- msgId: 'role_menuitem'
- },
- menuListPopup: {
- msgId: 'role_menu'
- },
- navigation: {
- msgId: 'role_navigation',
- inherits: 'abstractContainer'
- },
- note: {
- msgId: 'role_note',
- inherits: 'abstractContainer'
- },
- popUpButton: {
- msgId: 'role_button',
- earcon: 'LISTBOX'
- },
- radioButton: {
- msgId: 'role_radio'
- },
- radioGroup: {
- msgId: 'role_radiogroup',
- },
- region: {
- msgId: 'role_region',
- inherits: 'abstractContainer'
- },
- rowHeader: {
- msgId: 'role_rowheader',
- inherits: 'abstractContainer'
- },
- scrollBar: {
- msgId: 'role_scrollbar',
- },
- search: {
- msgId: 'role_search',
- inherits: 'abstractContainer'
- },
- separator: {
- msgId: 'role_separator',
- inherits: 'abstractContainer'
- },
- spinButton: {
- msgId: 'role_spinbutton',
- earconId: 'LISTBOX'
- },
- status: {
- msgId: 'role_status'
- },
- tab: {
- msgId: 'role_tab'
- },
- tabList: {
- msgId: 'role_tablist'
- },
- tabPanel: {
- msgId: 'role_tabpanel'
- },
- textBox: {
- msgId: 'input_type_text',
- earconId: 'EDITABLE_TEXT'
- },
- textField: {
- msgId: 'input_type_text',
- earconId: 'EDITABLE_TEXT'
- },
- time: {
- msgId: 'tag_time',
- inherits: 'abstractContainer'
- },
- timer: {
- msgId: 'role_timer'
- },
- toolbar: {
- msgId: 'role_toolbar'
- },
- tree: {
- msgId: 'role_tree'
- },
- treeItem: {
- msgId: 'role_treeitem'
- }
-};
-
-/**
- * Metadata about supported automation states.
- * @const {!Object<{on: {msgId: string, earconId: string},
- * off: {msgId: string, earconId: string},
- * omitted: {msgId: string, earconId: string}}>}
- * on: info used to describe a state that is set to true.
- * off: info used to describe a state that is set to false.
- * omitted: info used to describe a state that is undefined.
- * @private
- */
-Output.STATE_INFO_ = {
- checked: {
- on: {
- earconId: 'CHECK_ON',
- msgId: 'checkbox_checked_state'
- },
- off: {
- earconId: 'CHECK_OFF',
- msgId: 'checkbox_unchecked_state'
- },
- omitted: {
- earconId: 'CHECK_OFF',
- msgId: 'checkbox_unchecked_state'
- }
- },
- collapsed: {
- on: {
- msgId: 'aria_expanded_false'
- },
- off: {
- msgId: 'aria_expanded_true'
- }
- },
- expanded: {
- on: {
- msgId: 'aria_expanded_true'
- },
- off: {
- msgId: 'aria_expanded_false'
- }
- },
- visited: {
- on: {
- msgId: 'visited_state'
- }
- }
-};
-
-/**
- * Maps input types to message IDs.
- * @const {Object<string>}
- * @private
- */
-Output.INPUT_TYPE_MESSAGE_IDS_ = {
- 'email': 'input_type_email',
- 'number': 'input_type_number',
- 'password': 'input_type_password',
- 'search': 'input_type_search',
- 'tel': 'input_type_number',
- 'text': 'input_type_text',
- 'url': 'input_type_url',
-};
-
-/**
- * Rules specifying format of AutomationNodes for output.
- * @type {!Object<Object<Object<string>>>}
- */
-Output.RULES = {
- navigate: {
- 'default': {
- speak: '$name $value $help $role',
- braille: ''
- },
- abstractContainer: {
- enter: '$name $role',
- leave: '@exited_container($role)'
- },
- alert: {
- speak: '!doNotInterrupt $role $descendants'
- },
- alertDialog: {
- enter: '$name $role $descendants'
- },
- cell: {
- enter: '@column_granularity $tableCellColumnIndex'
- },
- checkBox: {
- speak: '$name $role $checked'
- },
- dialog: {
- enter: '$name $role'
- },
- div: {
- enter: '$name',
- speak: '$name'
- },
- grid: {
- enter: '$name $role'
- },
- heading: {
- enter: '@tag_h+$hierarchicalLevel',
- speak: '@tag_h+$hierarchicalLevel $nameOrDescendants='
- },
- inlineTextBox: {
- speak: '$value='
- },
- link: {
- enter: '$name $if($visited, @visited_link, $role)',
- stay: '$name= $if($visited, @visited_link, $role)',
- speak: '$name= $if($visited, @visited_link, $role)'
- },
- list: {
- enter: '$role @@list_with_items($countChildren(listItem))'
- },
- listBox: {
- enter: '$name $role @@list_with_items($countChildren(listBoxOption))'
- },
- listBoxOption: {
- speak: '$name $role @describe_index($indexInParent, $parentChildCount)'
- },
- listItem: {
- enter: '$role'
- },
- menu: {
- enter: '$name $role @@list_with_items($countChildren(menuItem))'
- },
- menuItem: {
- speak: '$name $role $if($haspopup, @has_submenu) ' +
- '@describe_index($indexInParent, $parentChildCount)'
- },
- menuListOption: {
- speak: '$name $value @role_menuitem ' +
- '@describe_index($indexInParent, $parentChildCount)'
- },
- paragraph: {
- speak: '$descendants'
- },
- popUpButton: {
- speak: '$value $name $role @aria_has_popup ' +
- '$if($collapsed, @aria_expanded_false, @aria_expanded_true)'
- },
- radioButton: {
- speak: '$if($checked, @describe_radio_selected($name), ' +
- '@describe_radio_unselected($name))'
- },
- radioGroup: {
- enter: '$name $role'
- },
- rootWebArea: {
- enter: '$name'
- },
- row: {
- enter: '@row_granularity $tableRowIndex'
- },
- slider: {
- speak: '@describe_slider($value, $name) $help'
- },
- staticText: {
- speak: '$value='
- },
- tab: {
- speak: '@describe_tab($name)'
- },
- textField: {
- speak: '$name $value $if(' +
- '$inputType, $inputType, $role)',
- braille: ''
- },
- toolbar: {
- enter: '$name $role'
- },
- tree: {
- enter: '$name $role @@list_with_items($countChildren(treeItem))'
- },
- treeItem: {
- enter: '$role $expanded $collapsed ' +
- '@describe_index($indexInParent, $parentChildCount) ' +
- '@describe_depth($hierarchicalLevel)'
- },
- window: {
- enter: '$name',
- speak: '@describe_window($name) $earcon(OBJECT_OPEN)'
- }
- },
- menuStart: {
- 'default': {
- speak: '@chrome_menu_opened($name) $earcon(OBJECT_OPEN)'
- }
- },
- menuEnd: {
- 'default': {
- speak: '@chrome_menu_closed $earcon(OBJECT_CLOSE)'
- }
- },
- menuListValueChanged: {
- 'default': {
- speak: '$value $name ' +
- '$find({"state": {"selected": true, "invisible": false}}, ' +
- '@describe_index($indexInParent, $parentChildCount)) '
- }
- },
- alert: {
- default: {
- speak: '!doNotInterrupt ' +
- '@role_alert $name $earcon(ALERT_NONMODAL) $descendants'
- }
- }
-};
-
-/**
- * Custom actions performed while rendering an output string.
- * @constructor
- */
-Output.Action = function() {
-};
-
-Output.Action.prototype = {
- run: function() {
- }
-};
-
-/**
- * Action to play an earcon.
- * @param {string} earconId
- * @constructor
- * @extends {Output.Action}
- */
-Output.EarconAction = function(earconId) {
- Output.Action.call(this);
- /** @type {string} */
- this.earconId = earconId;
-};
-
-Output.EarconAction.prototype = {
- __proto__: Output.Action.prototype,
-
- /** @override */
- run: function() {
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon[this.earconId]);
- }
-};
-
-/**
- * Annotation for selection.
- * @param {number} startIndex
- * @param {number} endIndex
- * @constructor
- */
-Output.SelectionSpan = function(startIndex, endIndex) {
- // TODO(dtseng): Direction lost below; should preserve for braille panning.
- this.startIndex = startIndex < endIndex ? startIndex : endIndex;
- this.endIndex = endIndex > startIndex ? endIndex : startIndex;
-};
-
-/**
- * Wrapper for automation nodes as annotations. Since the
- * {@code chrome.automation.AutomationNode} constructor isn't exposed in
- * the API, this class is used to allow isntanceof checks on these
- * annotations.
- @ @param {chrome.automation.AutomationNode} node
- * @constructor
- */
-Output.NodeSpan = function(node) {
- this.node = node;
-};
-
-/**
- * Possible events handled by ChromeVox internally.
- * @enum {string}
- */
-Output.EventType = {
- NAVIGATE: 'navigate'
-};
-
-Output.prototype = {
- /**
- * Gets the spoken output with separator '|'.
- * @return {!cvox.Spannable}
- */
- get speechOutputForTest() {
- return this.speechBuffer_.reduce(function(prev, cur) {
- if (prev === null)
- return cur;
- prev.append('|');
- prev.append(cur);
- return prev;
- }, null);
- },
-
- /**
- * Gets the output buffer for braille.
- * @return {!cvox.Spannable}
- */
- get brailleOutputForTest() {
- return this.createBrailleOutput_();
- },
-
- /**
- * Specify ranges for speech.
- * @param {!cursors.Range} range
- * @param {cursors.Range} prevRange
- * @param {chrome.automation.EventType|Output.EventType} type
- * @return {!Output}
- */
- withSpeech: function(range, prevRange, type) {
- this.formatOptions_ = {speech: true, braille: false, location: true};
- this.render_(range, prevRange, type, this.speechBuffer_);
- return this;
- },
-
- /**
- * Specify ranges for braille.
- * @param {!cursors.Range} range
- * @param {cursors.Range} prevRange
- * @param {chrome.automation.EventType|Output.EventType} type
- * @return {!Output}
- */
- withBraille: function(range, prevRange, type) {
- this.formatOptions_ = {speech: false, braille: true, location: false};
- this.render_(range, prevRange, type, this.brailleBuffer_);
- return this;
- },
-
- /**
- * Specify the same ranges for speech and braille.
- * @param {!cursors.Range} range
- * @param {cursors.Range} prevRange
- * @param {chrome.automation.EventType|Output.EventType} type
- * @return {!Output}
- */
- withSpeechAndBraille: function(range, prevRange, type) {
- this.withSpeech(range, prevRange, type);
- this.withBraille(range, prevRange, type);
- return this;
- },
-
- /**
- * Apply a format string directly to the output buffer. This lets you
- * output a message directly to the buffer using the format syntax.
- * @param {string} formatStr
- * @return {!Output}
- */
- format: function(formatStr) {
- this.formatOptions_ = {speech: true, braille: false, location: true};
- this.format_(null, formatStr, this.speechBuffer_);
-
- this.formatOptions_ = {speech: false, braille: true, location: false};
- this.format_(null, formatStr, this.brailleBuffer_);
-
- return this;
- },
-
- /**
- * Triggers callback for a speech event.
- * @param {function()} callback
- */
- onSpeechEnd: function(callback) {
- this.speechEndCallback_ = function(opt_cleanupOnly) {
- if (!opt_cleanupOnly)
- callback();
- }.bind(this);
- return this;
- },
-
- /**
- * Executes all specified output.
- */
- go: function() {
- // Speech.
- var queueMode = cvox.QueueMode.FLUSH;
- this.speechBuffer_.forEach(function(buff, i, a) {
- if (buff.toString()) {
- (function() {
- var scopedBuff = buff;
- this.speechProperties_['startCallback'] = function() {
- var actions = scopedBuff.getSpansInstanceOf(Output.Action);
- if (actions) {
- actions.forEach(function(a) {
- a.run();
- });
- }
- };
- }.bind(this)());
-
- if (this.speechEndCallback_ && i == a.length - 1)
- this.speechProperties_['endCallback'] = this.speechEndCallback_;
- else
- this.speechProperties_['endCallback'] = null;
- cvox.ChromeVox.tts.speak(
- buff.toString(), queueMode, this.speechProperties_);
- queueMode = cvox.QueueMode.QUEUE;
- }
- }.bind(this));
-
- // Braille.
- if (this.brailleBuffer_.length) {
- var buff = this.createBrailleOutput_();
- var selSpan =
- buff.getSpanInstanceOf(Output.SelectionSpan);
- var startIndex = -1, endIndex = -1;
- if (selSpan) {
- // Casts ok, since the span is known to be in the spannable.
- var valueStart =
- /** @type {number} */ (buff.getSpanStart(selSpan));
- var valueEnd =
- /** @type {number} */ (buff.getSpanEnd(selSpan));
- startIndex = valueStart + selSpan.startIndex;
- endIndex = valueStart + selSpan.endIndex;
- buff.setSpan(new cvox.ValueSpan(0), valueStart, valueEnd);
- buff.setSpan(new cvox.ValueSelectionSpan(), startIndex, endIndex);
- }
-
- var output = new cvox.NavBraille({
- text: buff,
- startIndex: startIndex,
- endIndex: endIndex
- });
-
- cvox.ChromeVox.braille.write(output);
- }
-
- // Display.
- chrome.accessibilityPrivate.setFocusRing(this.locations_);
- },
-
- /**
- * Renders the given range using optional context previous range and event
- * type.
- * @param {!cursors.Range} range
- * @param {cursors.Range} prevRange
- * @param {chrome.automation.EventType|string} type
- * @param {!Array<cvox.Spannable>} buff Buffer to receive rendered output.
- * @private
- */
- render_: function(range, prevRange, type, buff) {
- if (range.isSubNode())
- this.subNode_(range, prevRange, type, buff);
- else
- this.range_(range, prevRange, type, buff);
- },
-
- /**
- * Format the node given the format specifier.
- * @param {chrome.automation.AutomationNode} node
- * @param {string|!Object} format The output format either specified as an
- * output template string or a parsed output format tree.
- * @param {!Array<cvox.Spannable>} buff Buffer to receive rendered output.
- * @param {!Object=} opt_exclude A set of attributes to exclude.
- * @private
- */
- format_: function(node, format, buff, opt_exclude) {
- opt_exclude = opt_exclude || {};
- var tokens = [];
- var args = null;
-
- // Hacky way to support args.
- if (typeof(format) == 'string') {
- format = format.replace(/([,:])\W/g, '$1');
- tokens = format.split(' ');
- } else {
- tokens = [format];
- }
-
- tokens.forEach(function(token) {
- // Ignore empty tokens.
- if (!token)
- return;
-
- // Parse the token.
- var tree;
- if (typeof(token) == 'string')
- tree = this.createParseTree_(token);
- else
- tree = token;
-
- // Obtain the operator token.
- token = tree.value;
-
- // Set suffix options.
- var options = {};
- options.annotation = [];
- options.isUnique = token[token.length - 1] == '=';
- if (options.isUnique)
- token = token.substring(0, token.length - 1);
-
- // Annotate braille output with the corresponding automation nodes
- // to support acting on nodes based on location in the output.
- if (this.formatOptions_.braille)
- options.annotation.push(new Output.NodeSpan(node));
-
- // Process token based on prefix.
- var prefix = token[0];
- token = token.slice(1);
-
- if (opt_exclude[token])
- return;
-
- // All possible tokens based on prefix.
- if (prefix == '$') {
- if (token == 'value') {
- var text = node.value;
- if (text !== undefined) {
- if (node.textSelStart !== undefined) {
- options.annotation.push(new Output.SelectionSpan(
- node.textSelStart,
- node.textSelEnd));
- }
- }
- // Annotate this as a name so we don't duplicate names from ancestors.
- if (node.role == chrome.automation.RoleType.inlineTextBox ||
- node.role == chrome.automation.RoleType.staticText)
- token = 'name';
- options.annotation.push(token);
- this.append_(buff, text, options);
- } else if (token == 'name') {
- options.annotation.push(token);
- if (this.formatOptions_.speech) {
- var earconFinder = node;
- while (earconFinder) {
- var info = Output.ROLE_INFO_[earconFinder.role];
- if (info && info.earconId) {
- options.annotation.push(
- new Output.EarconAction(info.earconId));
- break;
- }
- earconFinder = earconFinder.parent;
- }
- }
-
- // Pending finalization of name calculation; we must use the
- // description property to access aria-label. See crbug.com/473220.
- var resolvedName = node.description || node.name;
- this.append_(buff, resolvedName, options);
- } else if (token == 'nameOrDescendants') {
- options.annotation.push(token);
- if (node.name)
- this.append_(buff, node.name, options);
- else
- this.format_(node, '$descendants', buff);
- } else if (token == 'indexInParent') {
- options.annotation.push(token);
- this.append_(buff, String(node.indexInParent + 1));
- } else if (token == 'parentChildCount') {
- options.annotation.push(token);
- if (node.parent)
- this.append_(buff, String(node.parent.children.length));
- } else if (token == 'state') {
- options.annotation.push(token);
- Object.getOwnPropertyNames(node.state).forEach(function(s) {
- this.append_(buff, s, options);
- }.bind(this));
- } else if (token == 'find') {
- // Find takes two arguments: JSON query string and format string.
- if (tree.firstChild) {
- var jsonQuery = tree.firstChild.value;
- node = node.find(
- /** @type {Object}*/(JSON.parse(jsonQuery)));
- var formatString = tree.firstChild.nextSibling;
- if (node)
- this.format_(node, formatString, buff);
- }
- } else if (token == 'descendants') {
- if (AutomationPredicate.leaf(node))
- return;
-
- // Construct a range to the leftmost and rightmost leaves.
- var leftmost = AutomationUtil.findNodePre(
- node, Dir.FORWARD, AutomationPredicate.leaf);
- var rightmost = AutomationUtil.findNodePre(
- node, Dir.BACKWARD, AutomationPredicate.leaf);
- if (!leftmost || !rightmost)
- return;
-
- var subrange = new cursors.Range(
- new cursors.Cursor(leftmost, 0),
- new cursors.Cursor(rightmost, 0));
- var prev = null;
- if (node)
- prev = cursors.Range.fromNode(node);
- this.range_(subrange, prev, 'navigate', buff);
- } else if (token == 'role') {
- options.annotation.push(token);
- var msg = node.role;
- var info = Output.ROLE_INFO_[node.role];
- if (info) {
- if (this.formatOptions_.braille)
- msg = Msgs.getMsg(info.msgId + '_brl');
- else
- msg = Msgs.getMsg(info.msgId);
- } else {
- console.error('Missing role info for ' + node.role);
- }
- this.append_(buff, msg, options);
- } else if (token == 'inputType') {
- if (!node.inputType)
- return;
- options.annotation.push(token);
- var msgId = Output.INPUT_TYPE_MESSAGE_IDS_[node.inputType] ||
- 'input_type_text';
- if (this.formatOptions_.braille)
- msgId = msgId + '_brl';
- this.append_(buff, Msgs.getMsg(msgId), options);
- } else if (token == 'tableRowIndex' ||
- token == 'tableCellColumnIndex') {
- var value = node[token];
- if (!value)
- return;
- value = String(value + 1);
- options.annotation.push(token);
- this.append_(buff, value, options);
- } else if (node[token] !== undefined) {
- options.annotation.push(token);
- var value = node[token];
- if (typeof value == 'number')
- value = String(value);
- this.append_(buff, value, options);
- } else if (Output.STATE_INFO_[token]) {
- options.annotation.push('state');
- var stateInfo = Output.STATE_INFO_[token];
- var resolvedInfo = {};
- if (node.state[token] === undefined)
- resolvedInfo = stateInfo.omitted;
- else
- resolvedInfo = node.state[token] ? stateInfo.on : stateInfo.off;
- if (!resolvedInfo)
- return;
- if (this.formatOptions_.speech && resolvedInfo.earconId) {
- options.annotation.push(
- new Output.EarconAction(resolvedInfo.earconId));
- }
- var msgId =
- this.formatOptions_.braille ? resolvedInfo.msgId + '_brl' :
- resolvedInfo.msgId;
- var msg = Msgs.getMsg(msgId);
- this.append_(buff, msg, options);
- } else if (tree.firstChild) {
- // Custom functions.
- if (token == 'if') {
- var cond = tree.firstChild;
- var attrib = cond.value.slice(1);
- if (node[attrib] || node.state[attrib])
- this.format_(node, cond.nextSibling, buff);
- else
- this.format_(node, cond.nextSibling.nextSibling, buff);
- } else if (token == 'earcon') {
- // Ignore unless we're generating speech output.
- if (!this.formatOptions_.speech)
- return;
- // Assumes there's existing output in our buffer.
- var lastBuff = buff[buff.length - 1];
- if (!lastBuff)
- return;
-
- lastBuff.setSpan(
- new Output.EarconAction(tree.firstChild.value), 0, 0);
- } else if (token == 'countChildren') {
- var role = tree.firstChild.value;
- var count = node.children.filter(function(e) {
- return e.role == role;
- }).length;
- this.append_(buff, String(count));
- }
- }
- } else if (prefix == '@') {
- var isPluralized = (token[0] == '@');
- if (isPluralized)
- token = token.slice(1);
- // Tokens can have substitutions.
- var pieces = token.split('+');
- token = pieces.reduce(function(prev, cur) {
- var lookup = cur;
- if (cur[0] == '$')
- lookup = node[cur.slice(1)];
- return prev + lookup;
- }.bind(this), '');
- var msgId = token;
- var msgArgs = [];
- if (!isPluralized) {
- var curArg = tree.firstChild;
- while (curArg) {
- if (curArg.value[0] != '$') {
- console.error('Unexpected value: ' + curArg.value);
- return;
- }
- var msgBuff = [];
- this.format_(node, curArg, msgBuff);
- msgArgs = msgArgs.concat(msgBuff);
- curArg = curArg.nextSibling;
- }
- }
- var msg = Msgs.getMsg(msgId, msgArgs);
- try {
- if (this.formatOptions_.braille)
- msg = Msgs.getMsg(msgId + '_brl', msgArgs) || msg;
- } catch(e) {}
-
- if (!msg) {
- console.error('Could not get message ' + msgId);
- return;
- }
-
- if (isPluralized) {
- var arg = tree.firstChild;
- if (!arg || arg.nextSibling) {
- console.error('Pluralized messages take exactly one argument');
- return;
- }
- if (arg.value[0] != '$') {
- console.error('Unexpected value: ' + arg.value);
- return;
- }
- var argBuff = [];
- this.format_(node, arg, argBuff);
- var namedArgs = {COUNT: Number(argBuff[0])};
- msg = new goog.i18n.MessageFormat(msg).format(namedArgs);
- }
-
- this.append_(buff, msg, options);
- } else if (prefix == '!') {
- this.speechProperties_[token] = true;
- }
- }.bind(this));
- },
-
- /**
- * @param {!cursors.Range} range
- * @param {cursors.Range} prevRange
- * @param {chrome.automation.EventType|string} type
- * @param {!Array<cvox.Spannable>} rangeBuff
- * @private
- */
- range_: function(range, prevRange, type, rangeBuff) {
- if (!prevRange)
- prevRange = cursors.Range.fromNode(range.start.node.root);
-
- var cursor = range.start;
- var prevNode = prevRange.start.node;
-
- var formatNodeAndAncestors = function(node, prevNode) {
- var buff = [];
- this.ancestry_(node, prevNode, type, buff);
- this.node_(node, prevNode, type, buff);
- if (this.formatOptions_.location)
- this.locations_.push(node.location);
- return buff;
- }.bind(this);
-
- while (cursor.node != range.end.node) {
- var node = cursor.node;
- rangeBuff.push.apply(rangeBuff, formatNodeAndAncestors(node, prevNode));
- prevNode = node;
- cursor = cursor.move(cursors.Unit.NODE,
- cursors.Movement.DIRECTIONAL,
- Dir.FORWARD);
-
- // Reached a boundary.
- if (cursor.node == prevNode)
- break;
- }
- var lastNode = range.end.node;
- rangeBuff.push.apply(rangeBuff, formatNodeAndAncestors(lastNode, prevNode));
- },
-
- /**
- * @param {!chrome.automation.AutomationNode} node
- * @param {!chrome.automation.AutomationNode} prevNode
- * @param {chrome.automation.EventType|string} type
- * @param {!Array<cvox.Spannable>} buff
- * @param {!Object=} opt_exclude A list of attributes to exclude from
- * processing.
- * @private
- */
- ancestry_: function(node, prevNode, type, buff, opt_exclude) {
- opt_exclude = opt_exclude || {};
- var prevUniqueAncestors =
- AutomationUtil.getUniqueAncestors(node, prevNode);
- var uniqueAncestors = AutomationUtil.getUniqueAncestors(prevNode, node);
-
- // First, look up the event type's format block.
- // Navigate is the default event.
- var eventBlock = Output.RULES[type] || Output.RULES['navigate'];
-
- var getMergedRoleBlock = function(role) {
- var parentRole = (Output.ROLE_INFO_[role] || {}).inherits;
- var roleBlock = eventBlock[role] || eventBlock['default'];
- var parentRoleBlock = parentRole ? eventBlock[parentRole] : {};
- var mergedRoleBlock = {};
- for (var key in parentRoleBlock)
- mergedRoleBlock[key] = parentRoleBlock[key];
- for (var key in roleBlock)
- mergedRoleBlock[key] = roleBlock[key];
- return mergedRoleBlock;
- };
-
- for (var i = 0, formatPrevNode;
- (formatPrevNode = prevUniqueAncestors[i]);
- i++) {
- var roleBlock = getMergedRoleBlock(formatPrevNode.role);
- if (roleBlock.leave)
- this.format_(formatPrevNode, roleBlock.leave, buff, opt_exclude);
- }
-
- var enterOutputs = [];
- var enterRole = {};
- for (var j = uniqueAncestors.length - 2, formatNode;
- (formatNode = uniqueAncestors[j]);
- j--) {
- var roleBlock = getMergedRoleBlock(formatNode.role);
- if (roleBlock.enter) {
- if (enterRole[formatNode.role])
- continue;
- enterRole[formatNode.role] = true;
- var tempBuff = [];
- this.format_(formatNode, roleBlock.enter, tempBuff, opt_exclude);
- enterOutputs.unshift(tempBuff);
- }
- if (formatNode.role == 'window')
- break;
- }
- enterOutputs.forEach(function(b) {
- buff.push.apply(buff, b);
- });
-
- if (!opt_exclude.stay) {
- var commonFormatNode = uniqueAncestors[0];
- while (commonFormatNode && commonFormatNode.parent) {
- commonFormatNode = commonFormatNode.parent;
- var roleBlock =
- eventBlock[commonFormatNode.role] || eventBlock['default'];
- if (roleBlock.stay)
- this.format_(commonFormatNode, roleBlock.stay, buff, opt_exclude);
- }
- }
- },
-
- /**
- * @param {!chrome.automation.AutomationNode} node
- * @param {!chrome.automation.AutomationNode} prevNode
- * @param {chrome.automation.EventType|string} type
- * @param {!Array<cvox.Spannable>} buff
- * @private
- */
- node_: function(node, prevNode, type, buff) {
- // Navigate is the default event.
- var eventBlock = Output.RULES[type] || Output.RULES['navigate'];
- var roleBlock = eventBlock[node.role] || eventBlock['default'];
- var speakFormat = roleBlock.speak || eventBlock['default'].speak;
- this.format_(node, speakFormat, buff);
- },
-
- /**
- * @param {!cursors.Range} range
- * @param {cursors.Range} prevRange
- * @param {chrome.automation.EventType|string} type
- * @param {!Array<cvox.Spannable>} buff
- * @private
- */
- subNode_: function(range, prevRange, type, buff) {
- if (!prevRange)
- prevRange = range;
- var dir = cursors.Range.getDirection(prevRange, range);
- var prevNode = prevRange.getBound(dir).node;
- this.ancestry_(
- range.start.node, prevNode, type, buff,
- {stay: true, name: true, value: true});
- var startIndex = range.start.getIndex();
- var endIndex = range.end.getIndex();
- if (startIndex === endIndex)
- endIndex++;
- this.append_(
- buff, range.start.getText().substring(startIndex, endIndex));
- },
-
- /**
- * Appends output to the |buff|.
- * @param {!Array<cvox.Spannable>} buff
- * @param {string|!cvox.Spannable} value
- * @param {{isUnique: (boolean|undefined),
- * annotation: !Array<*>}=} opt_options
- */
- append_: function(buff, value, opt_options) {
- opt_options = opt_options || {isUnique: false, annotation: []};
-
- // Reject empty values without annotations.
- if ((!value || value.length == 0) && opt_options.annotation.length == 0)
- return;
-
- var spannableToAdd = new cvox.Spannable(value);
- opt_options.annotation.forEach(function(a) {
- spannableToAdd.setSpan(a, 0, spannableToAdd.getLength());
- });
-
- // |isUnique| specifies an annotation that cannot be duplicated.
- if (opt_options.isUnique) {
- var annotationSansNodes = opt_options.annotation.filter(
- function(annotation) {
- return !(annotation instanceof Output.NodeSpan);
- });
- var alreadyAnnotated = buff.some(function(s) {
- return annotationSansNodes.some(function(annotation) {
- var start = s.getSpanStart(annotation);
- var end = s.getSpanEnd(annotation);
- if (start === undefined)
- return false;
- return s.substring(start, end).toString() == value.toString();
- });
- });
- if (alreadyAnnotated)
- return;
- }
-
- buff.push(spannableToAdd);
- },
-
- /**
- * Parses the token containing a custom function and returns a tree.
- * @param {string} inputStr
- * @return {Object}
- * @private
- */
- createParseTree_: function(inputStr) {
- var root = {value: ''};
- var currentNode = root;
- var index = 0;
- var braceNesting = 0;
- while (index < inputStr.length) {
- if (inputStr[index] == '(') {
- currentNode.firstChild = {value: ''};
- currentNode.firstChild.parent = currentNode;
- currentNode = currentNode.firstChild;
- } else if (inputStr[index] == ')') {
- currentNode = currentNode.parent;
- } else if (inputStr[index] == '{') {
- braceNesting++;
- currentNode.value += inputStr[index];
- } else if (inputStr[index] == '}') {
- braceNesting--;
- currentNode.value += inputStr[index];
- } else if (inputStr[index] == ',' && braceNesting === 0) {
- currentNode.nextSibling = {value: ''};
- currentNode.nextSibling.parent = currentNode.parent;
- currentNode = currentNode.nextSibling;
- } else {
- currentNode.value += inputStr[index];
- }
- index++;
- }
-
- if (currentNode != root)
- throw 'Unbalanced parenthesis.';
-
- return root;
- },
-
- /**
- * Converts the currently rendered braille buffers to a single spannable.
- * @return {!cvox.Spannable}
- * @private
- */
- createBrailleOutput_: function() {
- var result = new cvox.Spannable();
- var separator = ''; // Changes to space as appropriate.
- this.brailleBuffer_.forEach(function(cur) {
- // If this chunk is empty, don't add it since it won't result
- // in any output on the braille display, but node spans would
- // start before the separator in that case, which is not desired.
- // The exception is if this chunk contains a selectionm, in which
- // case it will result in a cursor which has to be preserved.
- // In this case, having separators, potentially both before and after
- // the empty string is correct.
- if (cur.getLength() == 0 && !cur.getSpanInstanceOf(Output.SelectionSpan))
- return;
- var spansToExtend = [];
- var spansToRemove = [];
- // Nodes that have node spans both on the character to the left
- // of the separator and to the right should also cover the separator.
- // We extend the left span to cover both the separator and what the
- // right span used to cover, removing the right span, mostly for
- // ease of writing tests and debug.
- // Note that getSpan(position) never returns zero length spans
- // (because they don't cover any position). Still, we want to include
- // these because they can be included (the selection span in an empty
- // text field is an example), which is why we write the below code
- // using getSpansInstanceOf and check the endpoints (isntead of doing
- // the opposite).
- result.getSpansInstanceOf(Output.NodeSpan).forEach(function(leftSpan) {
- if (result.getSpanEnd(leftSpan) < result.getLength())
- return;
- var newEnd = result.getLength();
- cur.getSpansInstanceOf(Output.NodeSpan).forEach(function(rightSpan) {
- if (cur.getSpanStart(rightSpan) == 0 &&
- leftSpan.node === rightSpan.node) {
- newEnd = Math.max(
- newEnd,
- result.getLength() + separator.length +
- cur.getSpanEnd(rightSpan));
- spansToRemove.push(rightSpan);
- }
- });
- if (newEnd > result.getLength())
- spansToExtend.push({span: leftSpan, end: newEnd});
- });
- result.append(separator);
- result.append(cur);
- spansToExtend.forEach(function(elem) {
- result.setSpan(
- elem.span,
- // Cast ok, since span is known to exist.
- /** @type {number} */ (result.getSpanStart(elem.span)),
- elem.end);
- });
- spansToRemove.forEach(result.removeSpan.bind(result));
- separator = Output.SPACE;
- });
- return result;
- }
-};
-
-}); // goog.scope
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs b/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs
deleted file mode 100644
index ad642ed0e50..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs
+++ /dev/null
@@ -1,545 +0,0 @@
-// 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.
-
-GEN_INCLUDE(['../../testing/assert_additions.js']);
-GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js']);
-
-/**
- * Gets the braille output and asserts that it matches expected values.
- * Annotations in the output that are primitive strings are ignored.
- */
-function checkBrailleOutput(expectedText, expectedSpans, output) {
- var actualOutput = output.brailleOutputForTest;
- // Remove string annotations. These are tested in the speech output and
- // there's no need to clutter the tests with the corresponding braille
- // annotations.
- var actualSpans = actualOutput.spans_.filter(function(span) {
- return (typeof span.value !== 'string');
- });
- assertEquals(expectedText, actualOutput.toString());
-
- function describeSpan(span) {
- var obj = {value: span.value, start: span.start, end: span.end};
- if (obj.value instanceof Output.NodeSpan) {
- obj.value.node = (obj.value.node.name || '') + ' ' +
- obj.value.node.toString();
- }
- return JSON.stringify(obj);
- }
-
- function describeActualSpans() {
- return '\nAll actual spans:\n' + actualSpans.map(describeSpan).join('\n');
- }
-
- for (var i = 0, max = Math.max(expectedSpans.length, actualSpans.length);
- i < max; ++i) {
- var expectedSpan = expectedSpans[i];
- var actualSpan = actualSpans[i];
- if (!expectedSpan)
- throw Error('Unexpected span in ' + expectedText + ': ' +
- describeSpan(actualSpan) + describeActualSpans());
- if (!actualSpan)
- throw Error('Missing expected span in ' + expectedText + ': ' +
- describeSpan(expectedSpan) + describeActualSpans());
- var equal = true;
- if (expectedSpan.start !== actualSpan.start ||
- expectedSpan.end !== actualSpan.end) {
- equal = false;
- } else if (expectedSpan.value instanceof Output.NodeSpan &&
- (!(actualSpan.value instanceof Output.NodeSpan) ||
- expectedSpan.value.node !== actualSpan.value.node)) {
- equal = false;
- } else {
- equal = (JSON.stringify(expectedSpan.value) ===
- JSON.stringify(actualSpan.value));
- }
- if (!equal) {
- throw Error('Spans differ in ' + expectedText + ':\n' +
- 'Expected: ' + describeSpan(expectedSpan) + '\n' +
- 'Got : ' + describeSpan(actualSpan) + describeActualSpans());
- }
- }
-}
-
-/**
- * Test fixture for output.js.
- * @constructor
- * @extends {ChromeVoxNextE2ETestBase}
- */
-function OutputE2ETest() {
- ChromeVoxNextE2ETest.call(this);
-}
-
-OutputE2ETest.prototype = {
- __proto__: ChromeVoxNextE2ETest.prototype,
-
- /** @override */
- setUp: function() {
- window.Dir = AutomationUtil.Dir;
- }
-};
-
-TEST_F('OutputE2ETest', 'Links', function() {
- this.runWithLoadedTree('<a href="#">Click here</a>',
- function(root) {
- var el = root.firstChild.firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_: 'Click here|Link', 'spans_': [
- // Attributes.
- {value: 'name', start: 0, end: 10},
-
- // Link earcon (based on the name).
- {value: {earconId: 'LINK'}, start: 0, end: 10},
-
- {value: 'role', start: 11, end: 15}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'Click here lnk',
- [{value: new Output.NodeSpan(el), start: 0, end: 14}],
- o);
- });
-});
-
-TEST_F('OutputE2ETest', 'Checkbox', function() {
- this.runWithLoadedTree('<input type="checkbox">',
- function(root) {
- var el = root.firstChild.firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_: '|Check box|not checked', 'spans_': [
- // Attributes.
- {value: 'name', start: 0, end: 0},
- {value: 'role', start: 1, end: 10},
- {value: 'state', start: 11, end: 22},
-
- // Checkbox earcon (based on the state).
- {value: {earconId: 'CHECK_OFF'}, start: 11, end: 22}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'chk ( )',
- [{value: new Output.NodeSpan(el), start: 0, end: 7}],
- o);
- });
-});
-
-TEST_F('OutputE2ETest', 'InLineTextBoxValueGetsIgnored', function() {
- this.runWithLoadedTree('<p>OK',
- function(root) {
- var el = root.firstChild.firstChild.firstChild;
- assertEquals('inlineTextBox', el.role);
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_: 'OK', 'spans_': [
- // Attributes.
- {value: 'name', start: 0, end: 2}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'OK',
- [{value: new Output.NodeSpan(el), start: 0, end: 2}],
- o);
-
- el = root.firstChild.firstChild;
- assertEquals('staticText', el.role);
- range = cursors.Range.fromNode(el);
- o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_: 'OK', 'spans_': [
- // Attributes.
- {value: 'name', start: 0, end: 2}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'OK',
- [{value: new Output.NodeSpan(el), start: 0, end: 2}],
- o);
- });
-});
-
-TEST_F('OutputE2ETest', 'Headings', function() {
- this.runWithLoadedTree(function() {/*!
- <h1>a</h1><h2>b</h2><h3>c</h3><h4>d</h4><h5>e</h5><h6>f</h6>
- <h1><a href="a.com">b</a></h1> */},
- function(root) {
- var el = root.firstChild;
- for (var i = 1; i <= 6; ++i) {
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- var letter = String.fromCharCode('a'.charCodeAt(0) + i -1);
- assertEqualsJSON({string_: 'Heading ' + i + '|' + letter, 'spans_': [
- // Attributes.
- {value: 'nameOrDescendants', start: 10, end: 11}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'h' + i + ' ' + letter,
- [{value: new Output.NodeSpan(el), start: 0, end: 4}],
- o);
- el = el.nextSibling;
- }
-
- range = cursors.Range.fromNode(el);
- o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_: 'Heading 1|b|Link', 'spans_': [
- // Link.
- {value: 'name', start: 10, end: 11},
- {value: {earconId: "LINK"}, start: 10, end: 11},
- {value: 'role', start: 12, end: 16}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'h1 b lnk',
- [{value: new Output.NodeSpan(el), start: 0, end: 2},
- {value: new Output.NodeSpan(el.firstChild), start: 3, end: 8}],
- o);
- });
-});
-
-TEST_F('OutputE2ETest', 'Audio', function() {
- this.runWithLoadedTree('<audio src="foo.mp3" controls></audio>',
- function(root) {
- var el = root.firstChild.firstChild.firstChild.firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON(
- {string_: 'audio|Tool bar|play||begin playback|Button',
- spans_:
- // Entered container toolbar.
-
- // Button.
- [{value: 'name', start: 15, end: 19},
-
- // Button earcon.
- {value: {earconId: "BUTTON"}, start: 15, end: 19},
-
- {value: 'value', start: 20, end: 20},
- {value: 'help', start: 21, end: 35},
- {value: 'role', start: 36, end: 42}]
- }, o.speechOutputForTest);
- checkBrailleOutput(
- 'audio tlbar play begin playback btn',
- [{value: new Output.NodeSpan(el.parent), start: 0, end: 11},
- {value: new Output.NodeSpan(el), start: 12, end: 35}],
- o);
-
- el = el.nextSibling;
- var prevRange = range;
- range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, prevRange, 'navigate');
- assertEqualsJSON({string_: '0, , slider|audio time scrubber',
- spans_:
- [{value: 'help', start: 12, end: 31}]
- }, o.speechOutputForTest);
- // TODO(plundblad): Investigate this.
- checkBrailleOutput(
- '0, , slider audio time scrubber',
- [{value: new Output.NodeSpan(el), start: 0, end: 31}],
- o);
- });
-});
-
-TEST_F('OutputE2ETest', 'Input', function() {
- this.runWithLoadedTree(
- '<input type="text"></input>' +
- '<input type="email"></input>' +
- '<input type="password"></input>' +
- '<input type="tel"></input>' +
- '<input type="number"></input>' +
- '<input type="time"></input>' +
- '<input type="date"></input>' +
- '<input type="file"</input>' +
- '<input type="search"</input>' +
- '<input type="invalidType"</input>',
- function(root) {
- var expected = {string_: '', 'spans_': [
- {value: 'name', start: 0, end: 0},
-
- // Earcon
- {value: {earconId: 'EDITABLE_TEXT'}, start: 0, end: 0},
-
- // Selection span.
- {value: {startIndex: 0, endIndex: 0}, start: 1, end: 1},
-
- {value: 'value', start: 1, end: 1},
- {value: 'inputType', start: 2}
- ]};
-
- var expectedSpeechValues = [
- '||Edit text',
- '||Edit text, email entry',
- '||Password edit text',
- '||Edit text numeric only',
- {string_: '||Spin button', spans_: [{value: 'name', start: 0, end: 0},
- {value: {earconId:'LISTBOX'}, start: 0, end: 0},
- {value: {startIndex: 0, endIndex: 0}, start: 1, end: 1},
- {value: 'value', start: 1, end: 1},
- {value: 'role', start: 2, end: 13}]},
- {string_: '||Time control', spans_: [{value: 'name', start: 0, end: 0},
- {value: 'value', start: 1, end: 1},
- {value: 'role', start: 2, end: 14}]},
- {string_: '||Date control', spans_: [{value: 'name', start: 0, end: 0},
- {value: 'value', start: 1, end: 1},
- {value: 'role', start: 2, end: 14}]},
- {string_: 'Choose File|No file chosen|Button',
- spans_: [{value: 'name', start: 0, end: 11},
- {value: {earconId: "BUTTON"}, start: 0, end: 11},
- {value: 'value', start: 12, end: 26},
- {value: 'role', start: 27, end: 33}]},
- '||Edit text, search entry',
- '||Edit text'
- ];
- // TODO(plundblad): Some of these are wrong, there should be an initial
- // space for the cursor in edit fields.
- var expectedBrailleValues = [
- ' ed',
- ' @ed',
- ' pwded',
- ' #ed',
- ' spnbtn',
- {string_: 'time'},
- {string_: 'date'},
- {string_: 'Choose File No file chosen btn'},
- ' srched',
- ' ed'
- ];
- assertEquals(expectedSpeechValues.length, expectedBrailleValues.length);
-
- var el = root.firstChild.firstChild;
- expectedSpeechValues.forEach(function(expectedValue) {
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- if (typeof expectedValue == 'object') {
- assertEqualsJSON(expectedValue, o.speechOutputForTest);
- } else {
- expected.string_ = expectedValue;
- expected.spans_[4].end = expectedValue.length;
- assertEqualsJSON(expected, o.speechOutputForTest);
- }
- el = el.nextSibling;
- });
-
- el = root.firstChild.firstChild;
- expectedBrailleValues.forEach(function(expectedValue) {
- var range = cursors.Range.fromNode(el);
- var o = new Output().withBraille(range, null, 'navigate');
- if (typeof expectedValue === 'string') {
- checkBrailleOutput(
- expectedValue,
- [{value: {startIndex: 0, endIndex: 0}, start: 0, end: 0},
- {value: new Output.NodeSpan(el), start: 0,
- end: expectedValue.length}],
- o);
- } else {
- checkBrailleOutput(
- expectedValue.string_,
- [{value: new Output.NodeSpan(el), start: 0,
- end: expectedValue.string_.length}],
- o);
- }
- el = el.nextSibling;
- });
- });
-});
-
-TEST_F('OutputE2ETest', 'List', function() {
- this.runWithLoadedTree(
- '<ul><li>a<li>b<li>c</ul>',
- function(root) {
- var el = root.firstChild.firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_: 'list|with 3 items|a||List item', spans_: [
- {value: 'name', start: 18, end: 19},
- {value: {earconId:'LIST_ITEM'}, start: 18, end: 19},
- {value: 'value', start:20, end: 20},
- {value: 'role', start: 21, end: 30}
- ]}, o.speechOutputForTest);
- // TODO(plundblad): This output is wrong. Add special handling for
- // braille here.
- checkBrailleOutput(
- 'list +3 a lstitm',
- [{value: new Output.NodeSpan(el.parent), start: 0, end: 7},
- {value: new Output.NodeSpan(el), start: 8, end: 16}],
- o);
- });
-});
-
-TEST_F('OutputE2ETest', 'Tree', function() {
- this.runWithLoadedTree(function() {/*!
- <ul role="tree">
- <li aria-expanded="true" role="treeitem">a
- <li role="treeitem">b
- <li aria-expanded="false" role="treeitem">c
- </ul>
- */},
- function(root) {
- var el = root.firstChild.children[0].firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON(
- {string_: '|Tree|with 3 items|Tree item|Expanded| 1 of 3 | level 1 |a',
- spans_: [
- // Enter rule.
-
- // TreeItem.
- {value: 'role','start': 19, end: 28},
- {value: 'state', start: 29, end: 37},
-
- // InLineTextBox.
- {value: 'name', start: 57, end: 58}
- ]}, o.speechOutputForTest);
- // TODO(plundblad): Braille output is wrong.
- checkBrailleOutput(
- 'tree +3 tritm - 1/3 level 1 a',
- [{value: new Output.NodeSpan(el.parent.parent), start: 0, end: 7},
- {value: new Output.NodeSpan(el.parent), start: 8, end: 29},
- {value: new Output.NodeSpan(el), start: 30, end: 31}],
- o);
-
- el = root.firstChild.children[1].firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON(
- {string_: '|Tree|with 3 items|Tree item| 2 of 3 | level 1 |b',
- spans_: [
- // Enter rule.
-
- // TreeItem.
- {value: 'role','start': 19, end: 28},
-
- // InLineTextBox.
- {value: 'name', start: 48, end: 49}
- ]}, o.speechOutputForTest);
- // TODO(plundblad): Braille output is wrong.
- checkBrailleOutput(
- 'tree +3 tritm 2/3 level 1 b',
- [{value: new Output.NodeSpan(el.parent.parent), start: 0, end: 7},
- {value: new Output.NodeSpan(el.parent), start: 8, end: 27},
- {value: new Output.NodeSpan(el), start: 28, end: 29}],
- o);
-
- el = root.firstChild.children[2].firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON(
- {string_: '|Tree|with 3 items|Tree item|Collapsed| 3 of 3 | level 1 |c',
- spans_: [
- // Enter rule.
-
- // TreeItem.
- {value: 'role','start': 19, end: 28},
- {value: 'state', start: 29, end: 38},
-
- // InLineTextBox.
- {value: 'name', start: 58, end: 59}
- ]}, o.speechOutputForTest);
- // TODO(plundblad): Braille output is wrong.
- checkBrailleOutput(
- 'tree +3 tritm + 3/3 level 1 c',
- [{value: new Output.NodeSpan(el.parent.parent), start: 0, end: 7},
- {value: new Output.NodeSpan(el.parent), start: 8, end: 29},
- {value: new Output.NodeSpan(el), start: 30, end: 31}],
- o);
- });
-});
-
-TEST_F('OutputE2ETest', 'Menu', function() {
- this.runWithLoadedTree(function() {/*!
- <div role="menu">
- <div role="menuitem">a</div>
- </div>
- */},
- function(root) {
- var el = root.firstChild.firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_:
- '|Menu|with 1 item|a|Menu item| 1 of 1 ', spans_: [
- {value: 'name', start: 18, end: 19},
- {value: 'role', start:20, end: 29}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'mnu +1 a mnuitm 1/1',
- [{value: new Output.NodeSpan(el.parent), start: 0, end: 6},
- {value: new Output.NodeSpan(el), start: 7, end: 19}],
- o);
- });
-});
-
-TEST_F('OutputE2ETest', 'ListBox', function() {
- this.runWithLoadedTree(function() {/*!
- <select multiple>
- <option>1</option>
- <option>2</option>
- </select>
- */},
- function(root) {
- var el = root.firstChild.firstChild.firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_: '|List box|with 2 items||List item| 1 of 2 ',
- spans_: [
- // ListBox.
- // Earcon.
- {value: {earconId:'LISTBOX'}, start: 0, end: 0},
-
- {value: 'name', start: 23, end: 23},
-
- // Earcon.
- {value: {earconId: 'LIST_ITEM'}, start: 23, end: 23},
-
- {value: 'role', start:24, end: 33}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'lstbx +2 lstitm 1/2',
- [{value: new Output.NodeSpan(el.parent), start: 0, end: 8},
- {value: new Output.NodeSpan(el), start: 9, end: 19}],
- o);
- });
-});
-
-SYNC_TEST_F('OutputE2ETest', 'MessageIdAndEarconValidity', function() {
- for (var key in Output.ROLE_INFO_) {
- var value = Output.ROLE_INFO_[key];
- Msgs.getMsg(value.msgId);
- Msgs.getMsg(value.msgId + '_brl');
- assertFalse(/[A-Z]+/.test(value.msgId));
- if (value.earconId)
- assertNotNullNorUndefined(cvox.Earcon[value.earconId]);
- }
- for (var key in Output.STATE_INFO_) {
- var value = Output.STATE_INFO_[key];
- for (innerKey in value) {
- var innerValue = value[innerKey];
- Msgs.getMsg(innerValue.msgId);
- Msgs.getMsg(innerValue.msgId + '_brl');
- assertFalse(/[A-Z]+/.test(innerValue.msgId));
- if (innerValue.earconId)
- assertNotNullNorUndefined(cvox.Earcon[innerValue.earconId]);
- }
- }
- for (var key in Output.INPUT_TYPE_MESSAGE_IDS_) {
- var msgId = Output.INPUT_TYPE_MESSAGE_IDS_[key];
- assertFalse(/[A-Z]+/.test(msgId));
- Msgs.getMsg(msgId);
- Msgs.getMsg(msgId + '_brl');
- }
-});
-
-TEST_F('OutputE2ETest', 'DivOmitsRole', function() {
- this.runWithLoadedTree(function() {/*!
- <div>that has content</div>
- <div></div>
- <div role='group'><div>nested content</div></div>
- */},
- function(root) {
- var el = root.firstChild.firstChild;
- var range = cursors.Range.fromNode(el);
- var o = new Output().withSpeechAndBraille(range, null, 'navigate');
- assertEqualsJSON({string_: '|that has content',
- spans_: [
- {value: 'name', start: 1, end: 17}
- ]}, o.speechOutputForTest);
- checkBrailleOutput(
- 'that has content',
- [{value: new Output.NodeSpan(el), start: 0, end: 16}],
- o);
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/abstract_result.js b/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/abstract_result.js
deleted file mode 100644
index 7bf16b3bc7d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/abstract_result.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Defines a result type interface.
- */
-
-goog.provide('cvox.AbstractResult');
-
-goog.require('cvox.SearchUtil');
-
-/**
- * @constructor
- */
-cvox.AbstractResult = function() { };
-
-/**
- * Checks the result if it is an unknown result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is an unknown result.
- */
-cvox.AbstractResult.prototype.isType = function(result) {
- return false;
-};
-
-/**
- * Speak a generic search result.
- * @param {Element} result Generic result to be spoken.
- * @return {boolean} Whether or not the result was spoken.
- */
-cvox.AbstractResult.prototype.speak = function(result) {
- return false;
-};
-
-/**
- * Extracts the wikipedia URL from knowledge panel.
- * @param {Element} result Result to extract from.
- * @return {?string} URL.
- */
-cvox.AbstractResult.prototype.getURL = cvox.SearchUtil.extractURL;
-
-/**
- * Returns the node to sync to.
- * @param {Element} result Result.
- * @return {?Node} Node to sync to.
- */
-cvox.AbstractResult.prototype.getSyncNode = function(result) {
- return result;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/constants.js b/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/constants.js
deleted file mode 100644
index 5fcdcc728f9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/constants.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Constants for Search.
- */
-
-goog.provide('cvox.SearchConstants');
-
-/**
- * @constructor
- */
-cvox.SearchConstants = function() {
-};
-
-/**
- * Keycodes.
- */
-cvox.SearchConstants.KeyCode = {
- UP: 38,
- DOWN: 40,
- PAGE_UP: 33,
- PAGE_DOWN: 34,
- LEFT: 37,
- RIGHT: 39,
- ENTER: 13,
- ESC: 27
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/context_menu.js b/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/context_menu.js
deleted file mode 100644
index 7f937b88af2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/context_menu.js
+++ /dev/null
@@ -1,141 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Context Menu for Search.
- */
-
-goog.provide('cvox.SearchContextMenu');
-
-goog.require('cvox.ChromeVoxKbHandler');
-goog.require('cvox.KeySequence');
-goog.require('cvox.Search');
-goog.require('cvox.SearchTool');
-
-/**
- * @constructor
- */
-cvox.SearchContextMenu = function() {
-};
-
-/* Globals */
-var Command = {
- TOOLS: 'tools',
- ADS: 'ads',
- MAIN: 'main'
-};
-
-/**
- * Current focus Search is in.
- */
-cvox.SearchContextMenu.currState = Command.MAIN;
-
-/**
- * Handles context menu events.
- * @param {Event} evt Event received.
- */
-cvox.SearchContextMenu.contextMenuHandler = function(evt) {
- var cmd = evt.detail['customCommand'];
- switch (cmd) {
- case Command.TOOLS:
- cvox.SearchContextMenu.focusTools();
- break;
-
- case Command.ADS:
- cvox.SearchContextMenu.focusAds();
- break;
-
- case Command.MAIN:
- cvox.SearchContextMenu.focusMain();
- break;
- }
-};
-
-/**
- * Handles key events.
- * @param {Event} evt Event received.
- * @return {boolean} True if key was handled, false otherwise.
- */
-cvox.SearchContextMenu.keyhandler = function(evt) {
- var ret = false;
- var keySeq = new cvox.KeySequence(evt);
- var command = cvox.ChromeVoxKbHandler.handlerKeyMap.commandForKey(keySeq);
- /* Handle if just default action. */
- if (!command || command === 'performDefaultAction') {
- switch (cvox.SearchContextMenu.currState) {
- case Command.TOOLS:
- ret = cvox.SearchTool.keyhandler(evt);
- break;
- case Command.ADS:
- case Command.MAIN:
- ret = cvox.Search.keyhandler(evt);
- break;
- }
- }
- return ret;
-};
-
-/**
- * Switch to main search results focus.
- */
-cvox.SearchContextMenu.focusMain = function() {
- if (cvox.SearchContextMenu.currState === Command.TOOLS) {
- cvox.SearchTool.toggleMenu();
- }
- cvox.Search.populateResults();
- cvox.Search.index = 0;
- cvox.Search.syncToIndex();
- cvox.SearchContextMenu.currState = Command.MAIN;
-};
-
-/**
- * Switch to ads focus.
- */
-cvox.SearchContextMenu.focusAds = function() {
- cvox.Search.populateAdResults();
- if (cvox.Search.results.length === 0) {
- cvox.SearchContextMenu.focusMain();
- return;
- }
- cvox.Search.index = 0;
- cvox.Search.syncToIndex();
-
- if (cvox.SearchContextMenu.currState === Command.TOOLS) {
- cvox.SearchTool.toggleMenu();
- }
-
- cvox.SearchContextMenu.currState = Command.ADS;
-};
-
-/**
- * Switch to tools focus.
- */
-cvox.SearchContextMenu.focusTools = function() {
- if (cvox.SearchContextMenu.currState !== Command.TOOLS) {
- cvox.SearchTool.activateTools();
- cvox.SearchContextMenu.currState = Command.TOOLS;
- }
-};
-
-/**
- * Initializes the context menu.
- */
-cvox.SearchContextMenu.init = function() {
- var ACTIONS = [
- { desc: 'Main Results', cmd: Command.MAIN },
- { desc: 'Search Tools', cmd: Command.TOOLS },
- { desc: 'Ads', cmd: Command.ADS }
- ];
- /* Attach ContextMenuActions. */
- var body = document.querySelector('body');
- body.setAttribute('contextMenuActions', JSON.stringify(ACTIONS));
-
- /* Listen for ContextMenu events. */
- body.addEventListener('ATCustomEvent',
- cvox.SearchContextMenu.contextMenuHandler, true);
-
- window.addEventListener('keydown', cvox.SearchContextMenu.keyhandler, true);
- cvox.Search.init();
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/loader.js b/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/loader.js
deleted file mode 100644
index 62c497b0815..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/loader.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-
-goog.provide('cvox.SearchLoader');
-goog.require('cvox.SearchContextMenu');
-
-/**
- * @fileoverview Inject the script into the page.
- */
-
-/**
- * @constructor
- */
-cvox.SearchLoader = function() {
-};
-
-/**
- * Called when document ready state changes.
- */
-cvox.SearchLoader.onReadyStateChange = function() {
- /* Make sure document is complete. Loading base.js when the document is
- * loading will destroy the DOM. */
- if (document.readyState !== 'complete') {
- return;
- }
- var GOOGLE_HOST = 'www.google.com';
- var SEARCH_PATH = '/search';
-
- if (window.location.host !== GOOGLE_HOST ||
- window.location.pathname !== SEARCH_PATH) {
- return;
- }
-
- cvox.SearchContextMenu.init();
-};
-
-/**
- * Inject Search into the page.
- */
-cvox.SearchLoader.init = function() {
- if (document.readyState !== 'complete') {
- document.onreadystatechange = cvox.SearchLoader.onReadyStateChange;
- } else {
- cvox.SearchLoader.onReadyStateChange();
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/results.js b/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/results.js
deleted file mode 100644
index db2799e90cf..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/results.js
+++ /dev/null
@@ -1,468 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Provides different rules for each type of result.
- */
-
-goog.provide('cvox.SearchResults');
-goog.provide('cvox.UnknownResult');
-
-goog.require('cvox.AbstractResult');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.SearchUtil');
-
-/**
- * @constructor
- */
-cvox.SearchResults = function() {
-};
-
-/**
- * Speaks a result based on given selectors.
- * @param {Element} result Search result to be spoken.
- * @param {Array} selectTexts Array of selectors or text to speak.
- */
-cvox.SearchResults.speakResultBySelectTexts = function(result, selectTexts) {
- for (var j = 0; j < selectTexts.length; j++) {
- var selectText = selectTexts[j];
- if (selectText.select) {
- var elems = result.querySelectorAll(selectText.select);
- for (var i = 0; i < elems.length; i++) {
- cvox.ChromeVox.speakNode(elems.item(i), cvox.QueueMode.QUEUE);
- }
- }
- if (selectText.text) {
- cvox.ChromeVox.tts.speak(selectText.text, cvox.QueueMode.QUEUE);
- }
- }
-};
-
-/**
- * Unknown Result Type. This is used if we don't know what to do.
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.UnknownResult = function() {
-};
-goog.inherits(cvox.UnknownResult, cvox.AbstractResult);
-
-/* Normal Result Type. */
-/**
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.NormalResult = function() {
-};
-goog.inherits(cvox.NormalResult, cvox.AbstractResult);
-
-/**
- * Checks the result if it is a normal result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is a normal result.
- * @override
- */
-cvox.NormalResult.prototype.isType = function(result) {
- var NORMAL_SELECT = '.rc';
- return result.querySelector(NORMAL_SELECT) !== null;
-};
-
-/**
- * Speak a normal search result.
- * @param {Element} result Normal result to be spoken.
- * @return {boolean} Whether or not the result was spoken.
- * @override
- */
-cvox.NormalResult.prototype.speak = function(result) {
- if (!result) {
- return false;
- }
- var NORMAL_TITLE_SELECT = '.rc .r';
- var NORMAL_URL_SELECT = '.kv';
- var NORMAL_DESC_SELECT = '.rc .st';
- var SITE_LINK_SELECT = '.osl';
- var MORE_RESULTS_SELECT = '.sld';
- var MORE_RESULTS_LINK_SELECT = '.mrf';
-
- var NORMAL_SELECTORS = [
- { select: NORMAL_TITLE_SELECT },
- { select: NORMAL_DESC_SELECT },
- { select: NORMAL_URL_SELECT },
- { select: SITE_LINK_SELECT },
- { select: MORE_RESULTS_SELECT },
- { select: MORE_RESULTS_LINK_SELECT }];
- cvox.SearchResults.speakResultBySelectTexts(result, NORMAL_SELECTORS);
-
- var DISCUSS_TITLE_SELECT = '.mas-1st-col div';
- var DISCUSS_DATE_SELECT = '.mas-col div';
- var discussTitles = result.querySelectorAll(DISCUSS_TITLE_SELECT);
- var discussDates = result.querySelectorAll(DISCUSS_DATE_SELECT);
- for (var i = 0; i < discussTitles.length; i++) {
- cvox.ChromeVox.speakNode(discussTitles.item(i), cvox.QueueMode.QUEUE);
- cvox.ChromeVox.speakNode(discussDates.item(i), cvox.QueueMode.QUEUE);
- }
- return true;
-};
-
-/* Weather Result */
-/**
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.WeatherResult = function() {
-};
-goog.inherits(cvox.WeatherResult, cvox.AbstractResult);
-
-/**
- * Checks the result if it is a weather result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is a weather result.
- * @override
- */
-cvox.WeatherResult.prototype.isType = function(result) {
- var WEATHER_SELECT = '#wob_wc';
- return result.querySelector(WEATHER_SELECT) !== null;
-};
-
-/**
- * Speak a weather forecast.
- * @param {Element} forecast Weather forecast to be spoken.
- */
-cvox.WeatherResult.speakForecast = function(forecast) {
- if (!forecast) {
- return;
- }
- var FORE_DAY_SELECT = '.vk_lgy';
- var FORE_COND_SELECT = 'img';
- var FORE_HIGH_SELECT = '.vk_gy';
- var FORE_LOW_SELECT = '.vk_lgy';
-
- var FORE_SELECTORS = [
- { select: FORE_DAY_SELECT },
- { select: FORE_COND_SELECT },
- { select: FORE_HIGH_SELECT },
- { select: FORE_LOW_SELECT }
- ];
- cvox.SearchResults.speakResultBySelectTexts(forecast, FORE_SELECTORS);
-};
-
-/**
- * Speak a weather search result.
- * @param {Element} result Weather result to be spoken.
- * @return {boolean} Whether or not the result was spoken.
- * @override
- */
-cvox.WeatherResult.prototype.speak = function(result) {
- if (!result) {
- return false;
- }
- /* TODO(peterxiao): Internationalization? */
- var WEATHER_INTRO = 'The weather forcast for';
- var WEATHER_TEMP_UNITS = 'degrees fahrenheit';
- var WEATHER_PREC_INTRO = 'precipitation is';
- var WEATHER_HUMID_INTRO = 'humidity is';
- var WEATHER_WIND_INTRO = 'wind is';
- var FORE_INTRO = 'Forecasts for this week';
- var WEATHER_LOC_SELECT = '.vk_h';
- var WEATHER_WHEN_SELECT = '#wob_dts';
- var WEATHER_COND_SELECT = '#wob_dc';
- var WEATHER_TEMP_SELECT = '#wob_tm';
- var WEATHER_PREC_SELECT = '#wob_pp';
- var WEATHER_HUMID_SELECT = '#wob_hm';
- var WEATHER_WIND_SELECT = '#wob_ws';
-
- var WEATHER_SELECT_TEXTS = [
- { text: WEATHER_INTRO },
- { select: WEATHER_LOC_SELECT },
- { select: WEATHER_WHEN_SELECT },
- { select: WEATHER_COND_SELECT },
- { select: WEATHER_TEMP_SELECT },
- { text: WEATHER_TEMP_UNITS },
- { text: WEATHER_PREC_INTRO },
- { select: WEATHER_PREC_SELECT },
- { text: WEATHER_HUMID_INTRO },
- { select: WEATHER_HUMID_SELECT },
- { text: WEATHER_WIND_INTRO },
- { select: WEATHER_WIND_SELECT }
- ];
- cvox.SearchResults.speakResultBySelectTexts(result, WEATHER_SELECT_TEXTS);
-
- var WEATHER_FORCAST_CLASS = 'wob_df';
- var forecasts = result.getElementsByClassName(WEATHER_FORCAST_CLASS);
- cvox.ChromeVox.tts.speak(FORE_INTRO, cvox.QueueMode.QUEUE);
- for (var i = 0; i < forecasts.length; i++) {
- var forecast = forecasts.item(i);
- cvox.WeatherResult.speakForecast(forecast);
- }
- return true;
-};
-
-/* Knowledge Panel Result */
-/**
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.KnowResult = function() {
-};
-goog.inherits(cvox.KnowResult, cvox.AbstractResult);
-
-/**
- * Checks the result if it is a know result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is a know result.
- * @override
- */
-cvox.KnowResult.prototype.isType = function(result) {
- var KNOP_SELECT = '.kno-ec';
- return result.querySelector(KNOP_SELECT) !== null;
-};
-
-/**
- * Speak a knowledge panel search result.
- * @param {Element} result Knowledge panel result to be spoken.
- * @return {boolean} Whether or not the result was spoken.
- * @override
- */
-cvox.KnowResult.prototype.speak = function(result) {
- cvox.ChromeVox.speakNode(result, cvox.QueueMode.QUEUE);
- return true;
-};
-
-/**
- * Extracts the wikipedia URL from knowledge panel.
- * @param {Element} result Result to extract from.
- * @return {?string} URL.
- * @override
- */
-cvox.KnowResult.prototype.getURL = function(result) {
- var LINK_SELECTOR = '.q';
- return cvox.SearchUtil.extractURL(result.querySelector(LINK_SELECTOR));
-};
-
-/**
- * Extracts the node to sync to in the knowledge panel.
- * @param {Element} result Result.
- * @return {?Node} Node to sync to.
- * @override
- */
-cvox.KnowResult.prototype.getSyncNode = function(result) {
- var HEADER_SELECTOR = '.kno-ecr-pt';
- return result.querySelector(HEADER_SELECTOR);
-};
-
-/* Calculator Type */
-/**
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.CalcResult = function() {
-};
-goog.inherits(cvox.CalcResult, cvox.AbstractResult);
-
-/**
- * Checks the result if it is a calculator result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is a calculator result.
- * @override
- */
-cvox.CalcResult.prototype.isType = function(result) {
- var CALC_SELECT = '#cwmcwd';
- return result.querySelector(CALC_SELECT) !== null;
-};
-
-/**
- * Speak a calculator search result.
- * @param {Element} result Calculator result to be spoken.
- * @return {boolean} Whether or not the result was spoken.
- * @override
- */
-cvox.CalcResult.prototype.speak = function(result) {
- if (!result) {
- return false;
- }
- var CALC_QUERY_SELECT = '#cwles';
- var CALC_RESULT_SELECT = '#cwos';
- var CALC_SELECTORS = [
- { select: CALC_QUERY_SELECT },
- { select: CALC_RESULT_SELECT }
- ];
- cvox.SearchResults.speakResultBySelectTexts(result, CALC_SELECTORS);
- return true;
-};
-
-/* Game Type */
-/**
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.GameResult = function() {
-};
-goog.inherits(cvox.GameResult, cvox.AbstractResult);
-
-/**
- * Checks the result if it is a game result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is a game result.
- * @override
- */
-cvox.GameResult.prototype.isType = function(result) {
- var GAME_SELECT = '.xpdbox';
- return result.querySelector(GAME_SELECT) !== null;
-};
-
-/* Image Type */
-/**
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.ImageResult = function() {
-};
-goog.inherits(cvox.ImageResult, cvox.AbstractResult);
-
-/**
- * Checks the result if it is a image result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is a image result.
- * @override
- */
-cvox.ImageResult.prototype.isType = function(result) {
- var IMAGE_CLASSES = 'rg_di';
- return result.className === IMAGE_CLASSES;
-};
-
-/**
- * Speak an image result.
- * @param {Element} result Image result to be spoken.
- * @return {boolean} Whether or not the result was spoken.
- * @override
- */
-cvox.ImageResult.prototype.speak = function(result) {
- if (!result) {
- return false;
- }
- /* Grab image result metadata. */
- var META_CLASS = 'rg_meta';
- var metaDiv = result.querySelector('.' + META_CLASS);
- var metaJSON = metaDiv.innerHTML;
- var metaData = JSON.parse(metaJSON);
-
- var imageSelectTexts = [];
-
- var filename = metaData['fn'];
- if (filename) {
- imageSelectTexts.push({ text: filename });
- }
-
- var rawDimensions = metaData['is'];
- if (rawDimensions) {
- /* Dimensions contain HTML codes, so we convert them. */
- var tmpDiv = document.createElement('div');
- tmpDiv.innerHTML = rawDimensions;
- var dimensions = tmpDiv.textContent || tmpDiv.innerText;
- imageSelectTexts.push({ text: dimensions });
- }
-
- var url = metaData['isu'];
- if (url) {
- imageSelectTexts.push({ text: url});
- }
- cvox.SearchResults.speakResultBySelectTexts(result, imageSelectTexts);
- return true;
-};
-
-/* Category Result */
-/**
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.CategoryResult = function() {
-};
-goog.inherits(cvox.CategoryResult, cvox.AbstractResult);
-
-/**
- * Checks the result if it is a category result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is a category result.
- * @override
- */
-cvox.CategoryResult.prototype.isType = function(result) {
- var CATEGORY_CLASSES = 'rg_fbl nj';
- return result.className === CATEGORY_CLASSES;
-};
-
-/**
- * Speak a category result.
- * @param {Element} result Category result to be spoken.
- * @return {boolean} Whether or not the result was spoken.
- * @override
- */
-cvox.CategoryResult.prototype.speak = function(result) {
- if (!result) {
- return false;
- }
- var LABEL_SELECT = '.rg_bb_label';
- var label = result.querySelector(LABEL_SELECT);
- cvox.ChromeVox.speakNode(label, cvox.QueueMode.QUEUE);
- return true;
-};
-
-/* Ad Result */
-/**
- * @constructor
- * @extends {cvox.AbstractResult}
- */
-cvox.AdResult = function() {
-};
-goog.inherits(cvox.AdResult, cvox.AbstractResult);
-
-/**
- * Checks the result if it is an ad result.
- * @param {Element} result Result to be checked.
- * @return {boolean} Whether or not the element is an ad result.
- * @override
- */
-cvox.AdResult.prototype.isType = function(result) {
- var ADS_CLASS = 'ads-ad';
- return result.className === ADS_CLASS;
-};
-
-/**
- * Speak an ad result.
- * @param {Element} result Ad result to be spoken.
- * @return {boolean} Whether or not the result was spoken.
- * @override
- */
-cvox.AdResult.prototype.speak = function(result) {
- if (!result) {
- return false;
- }
- var HEADER_SELECT = 'h3';
- var DESC_SELECT = '.ads-creative';
- var URL_SELECT = '.ads-visurl';
- var AD_SELECTS = [
- { select: HEADER_SELECT },
- { select: DESC_SELECT },
- { select: URL_SELECT }];
- cvox.SearchResults.speakResultBySelectTexts(result, AD_SELECTS);
- return true;
-};
-
-/**
- * To add new result types, create a new object with the following properties:
- * isType: Function to indicate if an element is the object's type.
- * speak: Function that takes in a result and speaks the type to the user.
- * getURL: Function that takes in a result and extracts the URL to follow.
- */
-cvox.SearchResults.RESULT_TYPES = [
- cvox.UnknownResult,
- cvox.NormalResult,
- cvox.KnowResult,
- cvox.WeatherResult,
- cvox.AdResult,
- cvox.CalcResult,
- cvox.GameResult,
- cvox.ImageResult,
- cvox.CategoryResult
-];
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/search.js b/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/search.js
deleted file mode 100644
index 9c8175a6627..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/search.js
+++ /dev/null
@@ -1,441 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Uses ChromeVox API to enhance the search experience.
- */
-
-goog.provide('cvox.Search');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.SearchConstants');
-goog.require('cvox.SearchResults');
-goog.require('cvox.SearchUtil');
-goog.require('cvox.UnknownResult');
-
-/**
- * @constructor
- */
-cvox.Search = function() {
-};
-
-/**
- * Selectors to match results.
- * @type {Object<string>}
- */
-cvox.Search.selectors = {};
-
-/**
- * Selectors for web results.
- */
-cvox.Search.webSelectors = {
- /* Topstuff typically contains important messages to be added first. */
- TOPSTUFF_SELECT: '#topstuff',
- SPELL_SUGG_SELECT: '.ssp',
- SPELL_CORRECTION_SELECT: '.sp_cnt',
- KNOW_PANEL_SELECT: '.knop',
- RESULT_SELECT: '.g',
- RELATED_SELECT: '#brs'
-};
-
-/**
- * Selectors for image results.
- */
-cvox.Search.imageSelectors = {
- IMAGE_CATEGORIES_SELECT: '#ifbc .rg_fbl',
- IMAGE_RESULT_SELECT: '#rg_s .rg_di'
-};
-
-/**
- * Index of the currently synced result.
- * @type {number}
- */
-cvox.Search.index;
-
-/**
- * Array of the search results.
- * @type {Array<Element>}
- */
-cvox.Search.results = [];
-
-/**
- * Array of the navigation panes.
- * @type {Array<Element>}
- */
-cvox.Search.panes = [];
-
-/**
- * Index of the currently synced pane.
- * @type {number}
- */
-cvox.Search.paneIndex;
-
-/**
- * If currently synced item is a pane.
- */
-cvox.Search.isPane = false;
-
-/**
- * Class of a selected pane.
- */
-cvox.Search.SELECTED_PANE_CLASS = 'hdtb_mitem hdtb_msel';
-
-
-/**
- * Speak and sync.
- * @private
- */
-cvox.Search.speakSync_ = function() {
- var result = cvox.Search.results[cvox.Search.index];
- var resultType = cvox.Search.getResultType(result);
- var isSpoken = resultType.speak(result);
- cvox.ChromeVox.syncToNode(resultType.getSyncNode(result), !isSpoken);
- cvox.Search.isPane = false;
-};
-
-/**
- * Sync the search result index to ChromeVox.
- */
-cvox.Search.syncToIndex = function() {
- cvox.ChromeVox.tts.stop();
- var prop = { endCallback: cvox.Search.speakSync_ };
- if (cvox.Search.index === 0) {
- cvox.ChromeVox.tts.speak('First result', cvox.QueueMode.QUEUE, prop);
- } else if (cvox.Search.index === cvox.Search.results.length - 1) {
- cvox.ChromeVox.tts.speak('Last result', cvox.QueueMode.QUEUE, prop);
- } else {
- cvox.Search.speakSync_();
- }
-};
-
-/**
- * Sync the current pane index to ChromeVox.
- */
-cvox.Search.syncPaneToIndex = function() {
- var pane = cvox.Search.panes[cvox.Search.paneIndex];
- var anchor = pane.querySelector('a');
- if (anchor) {
- cvox.ChromeVox.syncToNode(anchor, true);
- } else {
- cvox.ChromeVox.syncToNode(pane, true);
- }
- cvox.Search.isPane = true;
-};
-
-/**
- * Get the type of the result such as Knowledge Panel, Weather, etc.
- * @param {Element} result Result to be classified.
- * @return {cvox.AbstractResult} Type of the result.
- */
-cvox.Search.getResultType = function(result) {
- for (var i = 0; i < cvox.SearchResults.RESULT_TYPES.length; i++) {
- var resultType = new cvox.SearchResults.RESULT_TYPES[i]();
- if (resultType.isType(result)) {
- return resultType;
- }
- }
- return new cvox.UnknownResult();
-};
-
-/**
- * Get the page number associated with the url.
- * @param {string} url Url of search page.
- * @return {number} Page number.
- */
-cvox.Search.getPageNumber = function(url) {
- var PAGE_ANCHOR_SELECTOR = '#nav .fl';
- var pageAnchors = document.querySelectorAll(PAGE_ANCHOR_SELECTOR);
- for (var i = 0; i < pageAnchors.length; i++) {
- var pageAnchor = pageAnchors.item(i);
- if (pageAnchor.href === url) {
- return parseInt(pageAnchor.innerText, 10);
- }
- }
- return NaN;
-};
-
-/**
- * Navigate to the next / previous page.
- * @param {boolean} next True for the next page, false for the previous.
- */
-cvox.Search.navigatePage = function(next) {
- /* NavEnd contains previous / next page links. */
- var NAV_END_CLASS = 'navend';
- var navEnds = document.getElementsByClassName(NAV_END_CLASS);
- var navEnd = next ? navEnds[1] : navEnds[0];
- var url = cvox.SearchUtil.extractURL(navEnd);
- var navToUrl = function() {
- window.location = url;
- };
- var prop = { endCallback: navToUrl };
- if (url) {
- var pageNumber = cvox.Search.getPageNumber(url);
- if (!isNaN(pageNumber)) {
- cvox.ChromeVox.tts.speak('Page ' + pageNumber, cvox.QueueMode.FLUSH,
- prop);
- } else {
- cvox.ChromeVox.tts.speak('Unknown page.', cvox.QueueMode.FLUSH, prop);
- }
- }
-};
-
-/**
- * Navigates to the currently synced pane.
- */
-cvox.Search.goToPane = function() {
- var pane = cvox.Search.panes[cvox.Search.paneIndex];
- if (pane.className === cvox.Search.SELECTED_PANE_CLASS) {
- cvox.ChromeVox.tts.speak('You are already on that page.',
- cvox.QueueMode.QUEUE);
- return;
- }
- var anchor = pane.querySelector('a');
- cvox.ChromeVox.tts.speak(anchor.textContent, cvox.QueueMode.QUEUE);
- var url = cvox.SearchUtil.extractURL(pane);
- if (url) {
- window.location = url;
- }
-};
-
-/**
- * Follow the link to the current result.
- */
-cvox.Search.goToResult = function() {
- var result = cvox.Search.results[cvox.Search.index];
- var resultType = cvox.Search.getResultType(result);
- var url = resultType.getURL(result);
- if (url) {
- window.location = url;
- }
-};
-
-/**
- * Handle the keyboard.
- * @param {Event} evt Keydown event.
- * @return {boolean} True if key was handled, false otherwise.
- */
-cvox.Search.keyhandler = function(evt) {
- var SEARCH_INPUT_ID = 'gbqfq';
- var searchInput = document.getElementById(SEARCH_INPUT_ID);
- var result = cvox.Search.results[cvox.Search.index];
- var ret = false;
-
- /* TODO(peterxiao): Add cvox api call to determine cvox key. */
- if (evt.shiftKey || evt.altKey || evt.ctrlKey) {
- return false;
- }
-
- /* Do not handle if search input has focus, or if the search widget
- * has focus.
- */
- if (document.activeElement !== searchInput &&
- !cvox.SearchUtil.isSearchWidgetActive()) {
- switch (evt.keyCode) {
- case cvox.SearchConstants.KeyCode.UP:
- /* Add results.length because JS Modulo is silly. */
- cvox.Search.index = cvox.SearchUtil.subOneWrap(cvox.Search.index,
- cvox.Search.results.length);
- if (cvox.Search.index === cvox.Search.results.length - 1) {
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP);
- }
- cvox.Search.syncToIndex();
- break;
-
- case cvox.SearchConstants.KeyCode.DOWN:
- cvox.Search.index = cvox.SearchUtil.addOneWrap(cvox.Search.index,
- cvox.Search.results.length);
- if (cvox.Search.index === 0) {
- cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP);
- }
- cvox.Search.syncToIndex();
- break;
-
- case cvox.SearchConstants.KeyCode.PAGE_UP:
- cvox.Search.navigatePage(false);
- break;
-
- case cvox.SearchConstants.KeyCode.PAGE_DOWN:
- cvox.Search.navigatePage(true);
- break;
-
- case cvox.SearchConstants.KeyCode.LEFT:
- cvox.Search.paneIndex = cvox.SearchUtil.subOneWrap(cvox.Search.paneIndex,
- cvox.Search.panes.length);
- cvox.Search.syncPaneToIndex();
- break;
-
- case cvox.SearchConstants.KeyCode.RIGHT:
- cvox.Search.paneIndex = cvox.SearchUtil.addOneWrap(cvox.Search.paneIndex,
- cvox.Search.panes.length);
- cvox.Search.syncPaneToIndex();
- break;
-
- case cvox.SearchConstants.KeyCode.ENTER:
- if (cvox.Search.isPane) {
- cvox.Search.goToPane();
- } else {
- cvox.Search.goToResult();
- }
- break;
-
- default:
- return false;
- }
- evt.preventDefault();
- evt.stopPropagation();
- return true;
- }
- return false;
-};
-
-/**
- * Adds the elements that match the selector to results.
- * @param {string} selector Selector of element to add.
- */
-cvox.Search.addToResultsBySelector = function(selector) {
- var nodes = document.querySelectorAll(selector);
- for (var i = 0; i < nodes.length; i++) {
- var node = nodes.item(i);
- /* Do not add if empty. */
- if (node.innerHTML !== '') {
- cvox.Search.results.push(nodes.item(i));
- }
- }
-};
-
-/**
- * Populates the panes array.
- */
-cvox.Search.populatePanes = function() {
- cvox.Search.panes = [];
- var PANE_SELECT = '.hdtb_mitem';
- var paneElems = document.querySelectorAll(PANE_SELECT);
- for (var i = 0; i < paneElems.length; i++) {
- cvox.Search.panes.push(paneElems.item(i));
- }
-};
-
-/**
- * Populates the results with results.
- */
-cvox.Search.populateResults = function() {
- for (var prop in cvox.Search.selectors) {
- cvox.Search.addToResultsBySelector(cvox.Search.selectors[prop]);
- }
-};
-
-/**
- * Populates the results with ad results.
- */
-cvox.Search.populateAdResults = function() {
- cvox.Search.results = [];
- var ADS_SELECT = '.ads-ad';
- cvox.Search.addToResultsBySelector(ADS_SELECT);
-};
-
-/**
- * Observes mutations and updates results accordingly.
- */
-cvox.Search.observeMutation = function() {
- var SEARCH_AREA_SELECT = '#rg_s';
- var target = document.querySelector(SEARCH_AREA_SELECT);
-
- var observer = new MutationObserver(function(mutations) {
- cvox.Search.results = [];
- cvox.Search.populateResults();
- });
-
- var config =
- /** @type MutationObserverInit */
- ({ attributes: true, childList: true, characterData: true });
- observer.observe(target, config);
-};
-
-/**
- * Get the current selected pane's index.
- * @return {number} Index of selected pane.
- */
-cvox.Search.getSelectedPaneIndex = function() {
- var panes = cvox.Search.panes;
- for (var i = 0; i < panes.length; i++) {
- if (panes[i].className === cvox.Search.SELECTED_PANE_CLASS) {
- return i;
- }
- }
- return 0;
-};
-
-/**
- * Get the ancestor of node that is a result.
- * @param {Node} node Node.
- * @return {Node} Result ancestor.
- */
-cvox.Search.getAncestorResult = function(node) {
- var curr = node;
- while (curr) {
- for (var prop in cvox.Search.selectors) {
- var selector = cvox.Search.selectors[prop];
- if (curr.webkitMatchesSelector && curr.webkitMatchesSelector(selector)) {
- return curr;
- }
- }
- curr = curr.parentNode;
- }
- return null;
-};
-
-/**
- * Sync to the correct initial node.
- */
-cvox.Search.initialSync = function() {
- var currNode = cvox.ChromeVox.navigationManager.getCurrentNode();
- var result = cvox.Search.getAncestorResult(currNode);
- cvox.Search.index = cvox.Search.results.indexOf(result);
- if (cvox.Search.index === -1) {
- cvox.Search.index = 0;
- }
-
- if (cvox.Search.results.length > 0) {
- cvox.Search.syncToIndex();
- }
-};
-
-/**
- * Initialize Search.
- */
-cvox.Search.init = function() {
- cvox.Search.index = 0;
-
- /* Flush out anything that may have been speaking. */
- cvox.ChromeVox.tts.stop();
-
- /* Determine the type of search. */
- var SELECTED_CLASS = 'hdtb-msel';
- var selected = document.getElementsByClassName(SELECTED_CLASS)[0];
- if (!selected) {
- return;
- }
-
- var selectedHTML = selected.innerHTML;
- switch (selectedHTML) {
- case 'Web':
- case 'News':
- cvox.Search.selectors = cvox.Search.webSelectors;
- break;
- case 'Images':
- cvox.Search.selectors = cvox.Search.imageSelectors;
- cvox.Search.observeMutation();
- break;
- default:
- return;
- }
-
- cvox.Search.populateResults();
- cvox.Search.populatePanes();
- cvox.Search.paneIndex = cvox.Search.getSelectedPaneIndex();
-
- cvox.Search.initialSync();
-
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/search_tools.js b/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/search_tools.js
deleted file mode 100644
index 28b94a67272..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/search_tools.js
+++ /dev/null
@@ -1,208 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Uses ChromeVox API to access the search tools menu.
- */
-
-goog.provide('cvox.SearchTool');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.DomUtil');
-goog.require('cvox.Search');
-goog.require('cvox.SearchConstants');
-goog.require('cvox.SearchUtil');
-
-/**
- * @constructor
- */
-cvox.SearchTool = function() {
-};
-
-/**
- * Index of the current menu in focus.
- * @type {number}
- */
-cvox.SearchTool.menuIndex;
-
-/**
- * Array of menus.
- * @type {Array<Node>}
- */
-cvox.SearchTool.menus = [];
-
-/**
- * Index of the current menu item in focus.
- * @type {number}
- */
-cvox.SearchTool.menuItemIndex;
-
-/**
- * Array of menu items for the current menu.
- * @type {Array<Node>}
- */
-cvox.SearchTool.menuItems = [];
-
-/**
- * Id of the clear button.
- * @type {string}
- */
-cvox.SearchTool.CLEAR_ID = 'hdtb_rst';
-
-/**
- * Toggles a menu open / close by simulating a click.
- */
-cvox.SearchTool.toggleMenu = function() {
- var menu = cvox.SearchTool.menus[cvox.SearchTool.menuIndex];
- var menuDiv = menu.previousSibling;
- cvox.DomUtil.clickElem(menuDiv, false, false, false);
-};
-
-/**
- * Syncs the first item in the current menu to ChromeVox.
- */
-cvox.SearchTool.syncToMenu = function() {
- cvox.SearchTool.menuItemIndex = 0;
- cvox.SearchTool.toggleMenu();
- cvox.SearchTool.populateMenuItems();
- cvox.SearchTool.syncToMenuItem();
-};
-
-/**
- * Syncs the current menu item to ChromeVox.
- */
-cvox.SearchTool.syncToMenuItem = function() {
- var menuItem = cvox.SearchTool.menuItems[cvox.SearchTool.menuItemIndex];
- cvox.ChromeVox.syncToNode(menuItem, true);
-};
-
-/**
- * Fills in menuItems with the current menu's items.
- */
-cvox.SearchTool.populateMenuItems = function() {
- var menu = cvox.SearchTool.menus[cvox.SearchTool.menuIndex];
- cvox.SearchTool.menuItems = [];
- /* For now, we just special case on the clear button. */
- if (menu.id !== cvox.SearchTool.CLEAR_ID) {
- var MENU_ITEM_SELECTOR = '.hdtbItm';
- var menuItemNodeList = menu.querySelectorAll(MENU_ITEM_SELECTOR);
- for (var i = 0; i < menuItemNodeList.length; i++) {
- cvox.SearchTool.menuItems.push(menuItemNodeList.item(i));
- }
- } else {
- cvox.SearchTool.menuItems = [];
- cvox.SearchTool.menuItems.push(menu);
- }
-};
-
-/**
- * Fills in menus with the menus of the page.
- */
-cvox.SearchTool.populateMenus = function() {
- var MENU_SELECTOR = '.hdtbU';
- var menuDivs = document.querySelectorAll(MENU_SELECTOR);
- for (var i = 0; i < menuDivs.length; i++) {
- cvox.SearchTool.menus.push(menuDivs.item(i));
- }
-
- var clearDiv = document.getElementById(cvox.SearchTool.CLEAR_ID);
- if (clearDiv) {
- cvox.SearchTool.menus.push(clearDiv);
- }
-};
-
-/**
- * Switches focus to the tools interface, giving keyboard access.
- */
-cvox.SearchTool.activateTools = function() {
- var MENU_BAR_SELECTOR = '#hdtbMenus';
- var menuBar = document.querySelector(MENU_BAR_SELECTOR);
- var MENUS_OPEN_CLASS = 'hdtb-td-o';
- menuBar.className = MENUS_OPEN_CLASS;
-
- cvox.SearchTool.populateMenus();
- cvox.SearchTool.menuIndex = 0;
- cvox.SearchTool.syncToMenu();
-};
-
-/**
- * Goes to the link of the current menu item action.
- */
-cvox.SearchTool.gotoMenuItem = function() {
- var menuItem = cvox.SearchTool.menuItems[cvox.SearchTool.menuItemIndex];
- var LOCATION_INPUT_ID = '#lc-input';
- var input = menuItem.querySelector(LOCATION_INPUT_ID);
- /* Special case for setting location. */
- if (input) {
- input.focus();
- return;
- }
-
- /* Custom Date Range. */
- var CDR_ID = 'cdr_opt';
- switch (menuItem.id) {
- case cvox.SearchTool.CLEAR_ID:
- window.location = menuItem.dataset.url;
- break;
- case CDR_ID:
- var CDR_LINK_SELECTOR = '#cdrlnk';
- var cdrLink = menuItem.querySelector(CDR_LINK_SELECTOR);
- cvox.DomUtil.clickElem(cdrLink, false, false, false);
- cvox.SearchTool.toggleMenu();
- break;
- default:
- window.location = cvox.SearchUtil.extractURL(menuItem);
- break;
- }
-};
-
-/**
- * Handles key events for the tools interface.
- * @param {Event} evt Keydown event.
- * @return {boolean} True if key was handled, false otherwise.
- */
-cvox.SearchTool.keyhandler = function(evt) {
- if (cvox.SearchUtil.isSearchWidgetActive()) {
- return false;
- }
-
- switch (evt.keyCode) {
- case cvox.SearchConstants.KeyCode.UP:
- cvox.SearchTool.menuItemIndex = cvox.SearchUtil.subOneWrap(
- cvox.SearchTool.menuItemIndex, cvox.SearchTool.menuItems.length);
- cvox.SearchTool.syncToMenuItem();
- break;
-
- case cvox.SearchConstants.KeyCode.DOWN:
- cvox.SearchTool.menuItemIndex = cvox.SearchUtil.addOneWrap(
- cvox.SearchTool.menuItemIndex, cvox.SearchTool.menuItems.length);
- cvox.SearchTool.syncToMenuItem();
- break;
-
- case cvox.SearchConstants.KeyCode.LEFT:
- cvox.SearchTool.toggleMenu();
- cvox.SearchTool.menuIndex = cvox.SearchUtil.subOneWrap(
- cvox.SearchTool.menuIndex, cvox.SearchTool.menus.length);
- cvox.SearchTool.syncToMenu();
- break;
-
- case cvox.SearchConstants.KeyCode.RIGHT:
- cvox.SearchTool.toggleMenu();
- cvox.SearchTool.menuIndex = cvox.SearchUtil.addOneWrap(
- cvox.SearchTool.menuIndex, cvox.SearchTool.menus.length);
- cvox.SearchTool.syncToMenu();
- break;
-
- case cvox.SearchConstants.KeyCode.ENTER:
- cvox.SearchTool.gotoMenuItem();
- break;
-
- default:
- return false;
- }
- evt.preventDefault();
- evt.stopPropagation();
- return true;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/util.js b/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/util.js
deleted file mode 100644
index 1cccde971b4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/extensions/searchvox/util.js
+++ /dev/null
@@ -1,184 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Helper functions.
- */
-
-goog.provide('cvox.SearchUtil');
-
-/** Utility functions. */
-cvox.SearchUtil = function() {
-};
-
-/**
- * Extracts the first URL from an element.
- * @param {Node} node DOM element to extract from.
- * @return {?string} URL.
- */
-cvox.SearchUtil.extractURL = function(node) {
- if (node) {
- if (node.tagName === 'A') {
- return node.href;
- }
- var anchor = node.querySelector('a');
- if (anchor) {
- return anchor.href;
- }
- }
- return null;
-};
-
-/**
- * Indicates whether or not the search widget has been activated.
- * @return {boolean} Whether or not the search widget is active.
- */
-cvox.SearchUtil.isSearchWidgetActive = function() {
- var SEARCH_WIDGET_SELECT = '#cvox-search';
- return document.querySelector(SEARCH_WIDGET_SELECT) !== null;
-};
-
-/**
- * Adds one to and index with wrapping.
- * @param {number} index Index to add to.
- * @param {number} length Length to wrap at.
- * @return {number} The new index++, wrapped if exceeding length.
- */
-cvox.SearchUtil.addOneWrap = function(index, length) {
- return (index + 1) % length;
-};
-
-/**
- * Subtracts one to and index with wrapping.
- * @param {number} index Index to subtract from.
- * @param {number} length Length to wrap at.
- * @return {number} The new index--, wrapped if below 0.
- */
-cvox.SearchUtil.subOneWrap = function(index, length) {
- return (index - 1 + length) % length;
-};
-
-/**
- * Returns the id of a node's active descendant
- * @param {Node} targetNode The node.
- * @return {?string} The id of the active descendant.
- * @private
- */
-var getActiveDescendantId_ = function(targetNode) {
- if (!targetNode.getAttribute) {
- return null;
- }
-
- var activeId = targetNode.getAttribute('aria-activedescendant');
- if (!activeId) {
- return null;
- }
- return activeId;
-};
-
-/**
- * If the node is an object with an active descendant, returns the
- * descendant node.
- *
- * This function will fully resolve an active descendant chain. If a circular
- * chain is detected, it will return null.
- *
- * @param {Node} targetNode The node to get descendant information for.
- * @return {Node} The descendant node or null if no node exists.
- */
-var getActiveDescendant = function(targetNode) {
- var seenIds = {};
- var node = targetNode;
-
- while (node) {
- var activeId = getActiveDescendantId_(node);
- if (!activeId) {
- break;
- }
- if (activeId in seenIds) {
- // A circlar activeDescendant is an error, so return null.
- return null;
- }
- seenIds[activeId] = true;
- node = document.getElementById(activeId);
- }
-
- if (node == targetNode) {
- return null;
- }
- return node;
-};
-
-/**
- * Dispatches a left click event on the element that is the targetNode.
- * Clicks go in the sequence of mousedown, mouseup, and click.
- * @param {Node} targetNode The target node of this operation.
- * @param {boolean=} shiftKey Specifies if shift is held down.
- * @param {boolean=} callOnClickDirectly Specifies whether or not to directly
- * invoke the onclick method if there is one.
- * @param {boolean=} opt_double True to issue a double click.
- */
-cvox.SearchUtil.clickElem = function(
- targetNode, shiftKey, callOnClickDirectly, opt_double) {
- // If there is an activeDescendant of the targetNode, then that is where the
- // click should actually be targeted.
- var activeDescendant = getActiveDescendant(targetNode);
- if (activeDescendant) {
- targetNode = activeDescendant;
- }
- if (callOnClickDirectly) {
- var onClickFunction = null;
- if (targetNode.onclick) {
- onClickFunction = targetNode.onclick;
- }
- if (!onClickFunction && (targetNode.nodeType != 1) &&
- targetNode.parentNode && targetNode.parentNode.onclick) {
- onClickFunction = targetNode.parentNode.onclick;
- }
- var keepGoing = true;
- if (onClickFunction) {
- try {
- keepGoing = onClickFunction();
- } catch (exception) {
- // Something went very wrong with the onclick method; we'll ignore it
- // and just dispatch a click event normally.
- }
- }
- if (!keepGoing) {
- // The onclick method ran successfully and returned false, meaning the
- // event should not bubble up, so we will return here.
- return;
- }
- }
-
- // Send a mousedown (or simply a double click if requested).
- var evt = document.createEvent('MouseEvents');
- var evtType = opt_double ? 'dblclick' : 'mousedown';
- evt.initMouseEvent(evtType, true, true, document.defaultView,
- 1, 0, 0, 0, 0, false, false, shiftKey, false, 0, null);
- // Mark any events we generate so we don't try to process our own events.
- evt.fromCvox = true;
- try {
- targetNode.dispatchEvent(evt);
- } catch (e) {}
- //Send a mouse up
- evt = document.createEvent('MouseEvents');
- evt.initMouseEvent('mouseup', true, true, document.defaultView,
- 1, 0, 0, 0, 0, false, false, shiftKey, false, 0, null);
- // Mark any events we generate so we don't try to process our own events.
- evt.fromCvox = true;
- try {
- targetNode.dispatchEvent(evt);
- } catch (e) {}
- //Send a click
- evt = document.createEvent('MouseEvents');
- evt.initMouseEvent('click', true, true, document.defaultView,
- 1, 0, 0, 0, 0, false, false, shiftKey, false, 0, null);
- // Mark any events we generate so we don't try to process our own events.
- evt.fromCvox = true;
- try {
- targetNode.dispatchEvent(evt);
- } catch (e) {}
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/generate_manifest.gypi b/chromium/chrome/browser/resources/chromeos/chromevox/generate_manifest.gypi
index 758a73e77ef..7b9bdd198ad 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/generate_manifest.gypi
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/generate_manifest.gypi
@@ -14,14 +14,12 @@
#
# is_guest_manifest: 1 or 0; generates a manifest usable while in guest
# mode.
-# is_chromevox_classic: 1 or 0; generates a manifest for ChromeVox Classic.
# chromevox_compress_js: 1 or 0; whether the javascript is compressed.
{
'variables': {
'generate_manifest_script_path': 'tools/generate_manifest.py',
'is_guest_manifest%': 0,
- 'is_chromevox_classic%': 0,
},
'includes': [
'../../../../../build/util/version.gypi',
@@ -42,7 +40,6 @@
'<(generate_manifest_script_path)',
'--is_guest_manifest=<(is_guest_manifest)',
'--key=<(chromevox_extension_key)',
- '--is_chromevox_classic=<(is_chromevox_classic)',
'--is_js_compressed=<(chromevox_compress_js)',
'--set_version=<(version_full)',
'--output_manifest=<(output_manifest_path)',
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille.js
deleted file mode 100644
index 35a1d684cfa..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille.js
+++ /dev/null
@@ -1,110 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Bridge that sends Braille messages from content scripts or
- * other pages to the main background page.
- *
- */
-
-goog.provide('cvox.ChromeBraille');
-
-goog.require('cvox.BrailleInterface');
-goog.require('cvox.BrailleKeyEvent');
-goog.require('cvox.ChromeVoxUserCommands');
-goog.require('cvox.HostFactory');
-
-
-/**
- * @constructor
- * @implements {cvox.BrailleInterface}
- */
-cvox.ChromeBraille = function() {
- /**
- * @type {cvox.NavBraille}
- * @private
- */
- this.lastContent_ = null;
- /**
- * @type {string}
- * @private
- */
- this.lastContentId_ = '';
- /**
- * @type {number}
- * @private
- */
- this.nextLocalId_ = 1;
- cvox.ExtensionBridge.addMessageListener(goog.bind(function(msg, port) {
- // Since ChromeVox gets injected into multiple iframes on a page, check to
- // ensure that this is the "active" iframe via its focused state.
- // Furthermore, if the active element is itself an iframe, the focus is
- // within the iframe even though the containing document also has focus.
- // Don't process the event if this document isn't focused or focus lies in
- // a descendant.
- if (!cvox.ChromeVox.documentHasFocus()) {
- return;
- }
- if (msg['message'] == 'BRAILLE' && msg['args']) {
- var content = null;
- if (msg['contentId'] == this.lastContentId_) {
- content = this.lastContent_;
- }
- this.onKeyEvent_(msg['args'], content);
- }
- }, this));
-};
-
-
-/** @override */
-cvox.ChromeBraille.prototype.write = function(params) {
- this.lastContent_ = params;
- this.updateLastContentId_();
- var outParams = params.toJson();
-
- var message = {'target': 'BRAILLE',
- 'action': 'write',
- 'params': outParams,
- 'contentId' : this.lastContentId_};
-
- cvox.ExtensionBridge.send(message);
-};
-
-
-/** @private */
-cvox.ChromeBraille.prototype.updateLastContentId_ = function() {
- this.lastContentId_ = cvox.ExtensionBridge.uniqueId() + '.' +
- this.nextLocalId_++;
-};
-
-
-/**
- * Dispatches braille input commands.
- * @param {!cvox.BrailleKeyEvent} brailleEvt The braille key event.
- * @param {cvox.NavBraille} content display content when command was issued,
- * if available.
- * @private
- */
-cvox.ChromeBraille.prototype.onKeyEvent_ = function(brailleEvt,
- content) {
- var command = cvox.ChromeVoxUserCommands.commands[brailleEvt.command];
- if (command) {
- command({event: brailleEvt, content: content});
- } else {
- console.error('Unknown braille command: ' + JSON.stringify(brailleEvt));
- }
-};
-
-
-/**
- * Overrides the key event handler
- * @param {function(!cvox.BrailleKeyEvent, cvox.NavBraille):void} listener
- */
-cvox.ChromeBraille.prototype.setKeyEventHandlerForTest = function(listener) {
- this.onKeyEvent_ = listener;
-};
-
-
-/** Export platform constructor. */
-cvox.HostFactory.brailleConstructor = cvox.ChromeBraille;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js
deleted file mode 100644
index a1536ecbb18..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js
+++ /dev/null
@@ -1,145 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Sends Braille commands to the Braille API.
- */
-
-goog.provide('cvox.BrailleBackground');
-
-goog.require('cvox.BrailleDisplayManager');
-goog.require('cvox.BrailleInputHandler');
-goog.require('cvox.BrailleInterface');
-goog.require('cvox.BrailleKeyEvent');
-goog.require('cvox.BrailleTranslatorManager');
-goog.require('global');
-
-
-/**
- * @constructor
- * @param {cvox.BrailleDisplayManager=} opt_displayManagerForTest
- * Display manager (for mocking in tests).
- * @param {cvox.BrailleInputHandler=} opt_inputHandlerForTest Input handler
- * (for mocking in tests).
- * @param {cvox.BrailleTranslatorManager=} opt_translatorManagerForTest
- * Braille translator manager (for mocking in tests)
- * @implements {cvox.BrailleInterface}
- */
-cvox.BrailleBackground = function(opt_displayManagerForTest,
- opt_inputHandlerForTest,
- opt_translatorManagerForTest) {
- /**
- * @type {!cvox.BrailleTranslatorManager}
- * @private*/
- this.translatorManager_ = opt_translatorManagerForTest ||
- new cvox.BrailleTranslatorManager();
- /**
- * @type {cvox.BrailleDisplayManager}
- * @private
- */
- this.displayManager_ = opt_displayManagerForTest ||
- new cvox.BrailleDisplayManager(this.translatorManager_);
- this.displayManager_.setCommandListener(this.onBrailleKeyEvent_.bind(this));
- /**
- * @type {cvox.NavBraille}
- * @private
- */
- this.lastContent_ = null;
- /**
- * @type {?string}
- * @private
- */
- this.lastContentId_ = null;
- /**
- * @type {!cvox.BrailleInputHandler}
- * @private
- */
- this.inputHandler_ = opt_inputHandlerForTest ||
- new cvox.BrailleInputHandler(this.translatorManager_);
- this.inputHandler_.init();
-};
-
-
-/** @override */
-cvox.BrailleBackground.prototype.write = function(params) {
- this.setContent_(params, null);
-};
-
-
-/**
- * @return {cvox.BrailleTranslatorManager} The translator manager used by this
- * instance.
- */
-cvox.BrailleBackground.prototype.getTranslatorManager = function() {
- return this.translatorManager_;
-};
-
-
-/**
- * Called when a Braille message is received from a page content script.
- * @param {Object} msg The Braille message.
- */
-cvox.BrailleBackground.prototype.onBrailleMessage = function(msg) {
- if (msg['action'] == 'write') {
- this.setContent_(cvox.NavBraille.fromJson(msg['params']),
- msg['contentId']);
- }
-};
-
-
-/**
- * @param {!cvox.NavBraille} newContent
- * @param {?string} newContentId
- * @private
- */
-cvox.BrailleBackground.prototype.setContent_ = function(
- newContent, newContentId) {
- var updateContent = function() {
- this.lastContent_ = newContentId ? newContent : null;
- this.lastContentId_ = newContentId;
- this.displayManager_.setContent(
- newContent, this.inputHandler_.getExpansionType());
- }.bind(this);
- this.inputHandler_.onDisplayContentChanged(newContent.text, updateContent);
- updateContent();
-};
-
-
-/**
- * Handles braille key events by dispatching either to the input handler,
- * ChromeVox next's background object or ChromeVox classic's content script.
- * @param {!cvox.BrailleKeyEvent} brailleEvt The event.
- * @param {!cvox.NavBraille} content Content of display when event fired.
- * @private
- */
-cvox.BrailleBackground.prototype.onBrailleKeyEvent_ = function(
- brailleEvt, content) {
- if (this.inputHandler_.onBrailleKeyEvent(brailleEvt)) {
- return;
- }
- if (global.backgroundObj &&
- global.backgroundObj.onBrailleKeyEvent(brailleEvt, content)) {
- return;
- }
- this.sendCommand_(brailleEvt, content);
-};
-
-
-/**
- * Dispatches braille input commands to the content script.
- * @param {!cvox.BrailleKeyEvent} brailleEvt The event.
- * @param {cvox.NavBraille} content Content of display when event fired.
- * @private
- */
-cvox.BrailleBackground.prototype.sendCommand_ =
- function(brailleEvt, content) {
- var msg = {
- 'message': 'BRAILLE',
- 'args': brailleEvt
- };
- if (content === this.lastContent_) {
- msg.contentId = this.lastContentId_;
- }
- cvox.ExtensionBridge.send(msg);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_integration_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_integration_test.unitjs
deleted file mode 100644
index 6a9b7a44511..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_integration_test.unitjs
+++ /dev/null
@@ -1,253 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../../testing/chromevox_unittest_base.js',
- '../../testing/assert_additions.js']);
-
-// Tests the communication between content script and background page for
-// braille.
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxBrailleIntegrationUnitTest() {
- ChromeVoxUnitTestBase.call(this);
-}
-
-CvoxBrailleIntegrationUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.BrailleBackground',
- 'cvox.BrailleInputHandler',
- 'cvox.BrailleKeyCommand',
- 'cvox.ChromeBraille',
- 'cvox.ExpandingBrailleTranslator',
- 'cvox.ValueSelectionSpan',
- 'cvox.ValueSpan',
- ],
-
- /** @override */
- isAsync: true,
-
- /** @override */
- setUp: function() {
- this.displayManager = new FakeDisplayManager();
- this.inputHandler = new FakeInputHandler();
- this.translatorManager = new FakeTranslatorManager();
-
- this.brailleBackground = new cvox.BrailleBackground(
- this.displayManager, this.inputHandler, this.translatorManager);
-
- cvox.ExtensionBridge = new FakeExtensionBridge(this.brailleBackground);
-
- this.braille = new cvox.ChromeBraille();
- this.braille.setKeyEventHandlerForTest(function(command, content) {
- this.lastCommand = command;
- this.lastCommandContent = content;
- }.bind(this));
- this.lastCommand = null;
- this.lastCommandContent = null;
-
- // Create convenience objects used in all tests.
- this.command1 = {command: cvox.BrailleKeyCommand.PAN_LEFT};
- this.content1 = cvox.NavBraille.fromText('text 1');
- this.command2 = {command: cvox.BrailleKeyCommand.ROUTING};
- this.content2 = cvox.NavBraille.fromText('text 2');
- },
-
- /** @Override */
- tearDown: function() {
- cvox.ExtensionBridge = null;
- },
-
- sendCommand: function(command, content) {
- this.displayManager.commandListener(command, content);
- },
-
- /**
- * Waits for {@code document} to gain focus, arranging to call
- * {@code testDone} afterwards.
- * @param {Function()} callback Called when focus is gained
- */
- awaitDocumentFocused: function(callback) {
- callback = this.newCallback(callback);
- if (!document.hasFocus()) {
- var listener = this.newCallback(function() {
- assertTrue(document.hasFocus());
- window.removeEventListener('focus', listener);
- callback();
- });
- window.addEventListener('focus', listener);
- } else {
- callback();
- }
- }
-};
-
-function FakeExtensionBridge(brailleBackground) {
- /** @private {Function} */
- this.messageListener_ = null;
- /** @private {cvox.BrailleBackground} */
- this.brailleBackground_ = brailleBackground;
-}
-
-FakeExtensionBridge.prototype = {
- uniqueId: function() { return 1; },
-
- /** @param {Function} listener The listener. */
- addMessageListener: function(listener) {
- assertEquals(null, this.messageListener_);
- this.messageListener_ = listener;
- },
-
- send: function(msg) {
- if (msg['message'] == 'BRAILLE') {
- assertNotEquals(null, this.messageListener_);
- this.messageListener_(msg);
- } else {
- assertEquals('BRAILLE', msg['target']);
- this.brailleBackground_.onBrailleMessage(msg);
- }
- }
-};
-
-/** @extends {cvox.BrailleDisplaymanager} */
-function FakeDisplayManager() {
- /** @type {Function} */
- this.commandListener = null;
- /** @type {cvox.NavBraille} */
- this.content = null;
-}
-
-FakeDisplayManager.prototype = {
- /** @Override */
- setCommandListener: function(listener) {
- this.commandListener = listener;
- },
-
- /** @Override */
- setContent: function(content, expansionType) {
- assertEquals(cvox.ExpandingBrailleTranslator.ExpansionType.SELECTION,
- expansionType);
- this.content = content;
- }
-};
-
-/** @extends {cvox.BrailleInputHandler} */
-function FakeInputHandler() {
-}
-
-FakeInputHandler.prototype = {
- /** @Override */
- init: function() {},
-
- /** @Override */
- onBrailleKeyEvent: function() {
- return false;
- },
-
- /** @Override */
- onDisplayContentChanged: function() {},
-
- /** @Override */
- getExpansionType: function() {
- return cvox.ExpandingBrailleTranslator.ExpansionType.SELECTION;
- }
-};
-
-/** @extends {cvox.BrailleTranslatorManager} */
-function FakeTranslatorManager() {
-}
-
-SYNC_TEST_F('CvoxBrailleIntegrationUnitTest', 'Write', function() {
- this.braille.write(this.content1);
- assertEqualsJSON(this.content1, this.displayManager.content);
-});
-
-SYNC_TEST_F('CvoxBrailleIntegrationUnitTest', 'WriteWithSpans', function() {
- var selectionSpan = new cvox.ValueSelectionSpan();
- var valueSpan = new cvox.ValueSpan(20);
- var toSend = cvox.NavBraille.fromText(
- new cvox.Spannable('Hello', valueSpan));
- toSend.text.setSpan(selectionSpan, 0, 0);
- toSend.text.setSpan(document.body, 0, toSend.text.getLength());
- var expected = cvox.NavBraille.fromText(
- new cvox.Spannable(toSend.text.toString(), valueSpan));
- expected.text.setSpan(selectionSpan, 0, 0);
-
- this.braille.write(toSend);
- assertEqualsJSON(expected, this.displayManager.content);
-});
-
-TEST_F('CvoxBrailleIntegrationUnitTest', 'CommandNoContent', function() {
- // Commands are only delivered to the content script if the window has focus.
- this.awaitDocumentFocused(function() {
- this.sendCommand(this.command1, null);
- assertEqualsJSON(this.command1, this.lastCommand);
- assertEquals(null, this.lastCommandContent);
- });
-});
-
-TEST_F('CvoxBrailleIntegrationUnitTest',
- 'InterleavedWritesAndCommands',
- function() {
- this.awaitDocumentFocused(function() {
- this.braille.write(this.content1);
- this.sendCommand(this.command1, this.displayManager.content);
- assertEqualsJSON(this.command1, this.lastCommand);
- assertEqualsJSON(this.content1, this.lastCommandContent);
-
- var savedContent1 = this.displayManager.content;
- this.braille.write(this.content2);
- // Old content still on display.
- this.sendCommand(this.command1, savedContent1);
- assertEqualsJSON(this.command1, this.lastCommand);
- assertEquals(null, this.lastCommandContent);
- this.sendCommand(this.command2, this.displayManager.content);
- assertEqualsJSON(this.command2, this.lastCommand);
- assertEqualsJSON(this.content2, this.lastCommandContent);
- });
-});
-
-TEST_F('CvoxBrailleIntegrationUnitTest', 'CommandAfterBackgroundWrite',
- function() {
- this.awaitDocumentFocused(function() {
- this.braille.write(this.content1);
- this.sendCommand(this.command1, this.displayManager.content);
- assertEqualsJSON(this.command1, this.lastCommand);
- assertEqualsJSON(this.content1, this.lastCommandContent);
-
- this.brailleBackground.write(this.content2);
- assertEqualsJSON(this.content2, this.displayManager.content);
- this.sendCommand(this.command2, this.displayManager.content);
- assertEqualsJSON(this.command2, this.lastCommand);
- assertEquals(null, this.lastCommandContent);
- });
-});
-
-TEST_F('CvoxBrailleIntegrationUnitTest', 'CommandAfterOtherTabWrite',
- function() {
- this.awaitDocumentFocused(function() {
- // Ignore the listener of the braille from the second 'tab'.
- cvox.ExtensionBridge.addMessageListener = function() {}
- // Create another content script braille object, presumably from another
- // tab.
- var anotherBraille = new cvox.ChromeBraille();
- this.braille.write(this.content1);
- this.sendCommand(this.command1, this.displayManager.content);
- // Now, this other braille gets a different unique id.
- cvox.ExtensionBridge.uniqueId = function() { return 2; }
- anotherBraille.write(this.content2);
- this.sendCommand(this.command2, this.displayManager.content);
- // The first 'tab' still gets the command, but since the second 'tab's\
- // braille was on the display, it gets null content.
- assertEqualsJSON(this.command2, this.lastCommand);
- assertEquals(null, this.lastCommandContent);
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons.js
deleted file mode 100644
index c250e8c3967..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons.js
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Bridge that sends earcon messages from content scripts or
- * other pages to the main background page.
- *
- */
-
-
-goog.provide('cvox.ChromeEarcons');
-
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.ExtensionBridge');
-goog.require('cvox.HostFactory');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractEarcons}
- */
-cvox.ChromeEarcons = function() {
- goog.base(this);
-};
-goog.inherits(cvox.ChromeEarcons, cvox.AbstractEarcons);
-
-
-/**
- * @override
- */
-cvox.ChromeEarcons.prototype.playEarcon = function(earcon) {
- goog.base(this, 'playEarcon', earcon);
- if (!this.enabled) {
- return;
- }
-
- cvox.ExtensionBridge.send({
- 'target': 'EARCON',
- 'action': 'play',
- 'earcon': earcon});
-};
-
-
-/**
- * @override
- */
-cvox.ChromeEarcons.prototype.toggle = function() {
- goog.base(this, 'toggle');
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'earcons',
- 'value': this.enabled
- });
- if (!this.enabled) {
- cvox.ChromeVox.host.sendToBackgroundPage({
- 'target': 'Prefs',
- 'action': 'setPref',
- 'pref': 'useVerboseMode',
- 'value': true
- });
- }
- return this.enabled;
-};
-
-
-cvox.HostFactory.earconsConstructor = cvox.ChromeEarcons;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons_background.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons_background.js
deleted file mode 100644
index 500da1a1e48..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/earcons_background.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Earcons library that uses the HTML5 Audio element to play back
- * auditory cues.
- *
- */
-
-
-goog.provide('cvox.EarconsBackground');
-
-goog.require('cvox.AbstractEarcons');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractEarcons}
- */
-cvox.EarconsBackground = function() {
- goog.base(this);
-
- this.audioMap = new Object();
- if (localStorage['earcons'] === 'false') {
- this.enabled = false;
- }
-};
-goog.inherits(cvox.EarconsBackground, cvox.AbstractEarcons);
-
-
-/**
- * @return {string} The human-readable name of the earcon set.
- */
-cvox.EarconsBackground.prototype.getName = function() {
- return 'ChromeVox earcons';
-};
-
-
-/**
- * @return {string} The base URL for loading earcons.
- */
-cvox.EarconsBackground.prototype.getBaseUrl = function() {
- return cvox.EarconsBackground.BASE_URL;
-};
-
-
-/**
- * @override
- */
-cvox.EarconsBackground.prototype.playEarcon = function(earcon) {
- goog.base(this, 'playEarcon', earcon);
- if (!this.enabled) {
- return;
- }
- if (window['console']) {
- window['console']['log']('Earcon ' + earcon);
- }
-
- this.currentAudio = this.audioMap[earcon];
- if (!this.currentAudio) {
- this.currentAudio = new Audio(chrome.extension.getURL(this.getBaseUrl() +
- earcon + '.ogg'));
- this.audioMap[earcon] = this.currentAudio;
- }
- try {
- this.currentAudio.currentTime = 0;
- } catch (e) {
- }
- if (this.currentAudio.paused) {
- this.currentAudio.volume = 0.7;
- this.currentAudio.play();
- }
-};
-
-
-/**
- * The base URL for loading eracons.
- * @type {string}
- */
-cvox.EarconsBackground.BASE_URL = 'chromevox/background/earcons/';
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/extension_bridge.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/extension_bridge.js
deleted file mode 100644
index e2c8181a5dc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/extension_bridge.js
+++ /dev/null
@@ -1,342 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Bridge to aid in communication between a Chrome
- * background page and content script.
- *
- * It automatically figures out where it's being run and initializes itself
- * appropriately. Then just call send() to send a message from the background
- * to the page or vice versa, and addMessageListener() to provide a message
- * listener. Messages can be any object that can be serialized using JSON.
- *
- */
-
-goog.provide('cvox.ExtensionBridge');
-
-goog.require('cvox.ChromeVoxJSON');
-
-/**
- * @constructor
- */
-cvox.ExtensionBridge = function() {};
-
-/**
- * Initialize the extension bridge. Dynamically figure out whether we're in
- * the background page, content script, or in a page, and call the
- * corresponding function for more specific initialization.
- */
-cvox.ExtensionBridge.init = function() {
- var self = cvox.ExtensionBridge;
- self.messageListeners = [];
- self.disconnectListeners = [];
-
- if (/^chrome-extension:\/\/.*background\.html$/.test(window.location.href)) {
- // This depends on the fact that the background page has a specific url. We
- // should never be loaded into another extension's background page, so this
- // is a safe check.
- self.context = self.BACKGROUND;
- self.initBackground();
- return;
- }
-
- if (chrome && chrome.extension) {
- self.context = self.CONTENT_SCRIPT;
- self.initContentScript();
- }
-};
-
-/**
- * Constant indicating we're in a background page.
- * @type {number}
- * @const
- */
-cvox.ExtensionBridge.BACKGROUND = 0;
-
-/**
- * Constant indicating we're in a content script.
- * @type {number}
- * @const
- */
-cvox.ExtensionBridge.CONTENT_SCRIPT = 1;
-
-/**
- * The name of the port between the content script and background page.
- * @type {string}
- * @const
- */
-cvox.ExtensionBridge.PORT_NAME = 'cvox.ExtensionBridge.Port';
-
-/**
- * The name of the message between the content script and background to
- * see if they're connected.
- * @type {string}
- * @const
- */
-cvox.ExtensionBridge.PING_MSG = 'cvox.ExtensionBridge.Ping';
-
-/**
- * The name of the message between the background and content script to
- * confirm that they're connected.
- * @type {string}
- * @const
- */
-cvox.ExtensionBridge.PONG_MSG = 'cvox.ExtensionBridge.Pong';
-
-/**
- * Send a message. If the context is a page, sends a message to the
- * extension background page. If the context is a background page, sends
- * a message to the current active tab (not all tabs).
- *
- * @param {Object} message The message to be sent.
- */
-cvox.ExtensionBridge.send = function(message) {
- var self = cvox.ExtensionBridge;
- switch (self.context) {
- case self.BACKGROUND:
- self.sendBackgroundToContentScript(message);
- break;
- case self.CONTENT_SCRIPT:
- self.sendContentScriptToBackground(message);
- break;
- }
-};
-
-/**
- * Provide a function to listen to messages. In page context, this
- * listens to messages from the background. In background context,
- * this listens to messages from all pages.
- *
- * The function gets called with two parameters: the message, and a
- * port that can be used to send replies.
- *
- * @param {function(Object, Port)} listener The message listener.
- */
-cvox.ExtensionBridge.addMessageListener = function(listener) {
- cvox.ExtensionBridge.messageListeners.push(listener);
-};
-
-/**
- * Provide a function to be called when the connection is
- * disconnected.
- *
- * @param {function()} listener The listener.
- */
-cvox.ExtensionBridge.addDisconnectListener = function(listener) {
- cvox.ExtensionBridge.disconnectListeners.push(listener);
-};
-
-/**
- * Removes all message listeners from the extension bridge.
- */
-cvox.ExtensionBridge.removeMessageListeners = function() {
- cvox.ExtensionBridge.messageListeners.length = 0;
-};
-
-/**
- * Returns a unique id for this instance of the script.
- *
- * @return {number}
- */
-cvox.ExtensionBridge.uniqueId = function() {
- return cvox.ExtensionBridge.id_;
-};
-
-/**
- * Initialize the extension bridge in a background page context by registering
- * a listener for connections from the content script.
- */
-cvox.ExtensionBridge.initBackground = function() {
- var self = cvox.ExtensionBridge;
-
- /** @type {!Array<Port>} @private */
- self.portCache_ = [];
- /** @type {number} */
- self.nextPongId_ = 1;
- /** @type {number} */
- self.id_ = 0;
-
- var onConnectHandler = function(port) {
- if (port.name != self.PORT_NAME) {
- return;
- }
-
- self.portCache_.push(port);
-
- port.onMessage.addListener(function(message) {
- if (message[cvox.ExtensionBridge.PING_MSG]) {
- var pongMessage = {};
- pongMessage[cvox.ExtensionBridge.PONG_MSG] = self.nextPongId_++;
- port.postMessage(pongMessage);
- return;
- }
-
- for (var i = 0; i < self.messageListeners.length; i++) {
- self.messageListeners[i](message, port);
- }
- });
-
- port.onDisconnect.addListener(function(message) {
- for (var i = 0; i < self.portCache_.length; i++) {
- if (self.portCache_[i] == port) {
- self.portCache_.splice(i, 1);
- break;
- }
- }
- });
- };
-
- chrome.extension.onConnect.addListener(onConnectHandler);
-};
-
-/**
- * Initialize the extension bridge in a content script context, listening
- * for messages from the background page.
- */
-cvox.ExtensionBridge.initContentScript = function() {
- var self = cvox.ExtensionBridge;
- self.connected = false;
- self.pingAttempts = 0;
- self.queuedMessages = [];
- /** @type {number} */
- self.id_ = -1;
-
- var onMessageHandler = function(request, sender, sendResponse) {
- if (request && request['srcFile']) {
- // TODO (clchen, deboer): Investigate this further and come up with a
- // cleaner solution. The root issue is that this should never be run on
- // the background page, but it is in the Chrome OS case.
- return;
- }
- if (request[cvox.ExtensionBridge.PONG_MSG]) {
- self.gotPongFromBackgroundPage(request[cvox.ExtensionBridge.PONG_MSG]);
- } else {
- for (var i = 0; i < self.messageListeners.length; i++) {
- self.messageListeners[i](request, cvox.ExtensionBridge.backgroundPort);
- }
- }
- sendResponse({});
- };
-
- // Listen to requests from the background that don't come from
- // our connection port.
- chrome.extension.onMessage.addListener(onMessageHandler);
-
- self.setupBackgroundPort();
-
- self.tryToPingBackgroundPage();
-};
-
-/**
- * Set up the connection to the background page.
- */
-cvox.ExtensionBridge.setupBackgroundPort = function() {
- // Set up the connection to the background page.
- var self = cvox.ExtensionBridge;
- self.backgroundPort = chrome.extension.connect({name: self.PORT_NAME});
- self.backgroundPort.onMessage.addListener(function(message) {
- if (message[cvox.ExtensionBridge.PONG_MSG]) {
- self.gotPongFromBackgroundPage(
- message[cvox.ExtensionBridge.PONG_MSG]);
- } else {
- for (var i = 0; i < self.messageListeners.length; i++) {
- self.messageListeners[i](message, self.backgroundPort);
- }
- }
- });
- self.backgroundPort.onDisconnect.addListener(function(event) {
- // If we're not connected yet, don't give up - try again.
- if (!self.connected) {
- self.backgroundPort = null;
- return;
- }
-
- for (var i = 0; i < self.disconnectListeners.length; i++) {
- self.disconnectListeners[i]();
- }
- });
-};
-
-/**
- * Try to ping the background page.
- */
-cvox.ExtensionBridge.tryToPingBackgroundPage = function() {
- var self = cvox.ExtensionBridge;
-
- // If we already got a pong, great - we're done.
- if (self.connected) {
- return;
- }
-
- self.pingAttempts++;
- if (self.pingAttempts > 5) {
- // Could not connect after 5 ping attempts. Call the disconnect
- // handlers, which will disable ChromeVox.
- for (var i = 0; i < self.disconnectListeners.length; i++) {
- self.disconnectListeners[i]();
- }
- return;
- }
-
- // Send the ping.
- var msg = {};
- msg[cvox.ExtensionBridge.PING_MSG] = 1;
- if (!self.backgroundPort) {
- self.setupBackgroundPort();
- }
- self.backgroundPort.postMessage(msg);
-
- // Check again in 500 ms in case we get no response.
- window.setTimeout(cvox.ExtensionBridge.tryToPingBackgroundPage, 500);
-};
-
-/**
- * Got pong from the background page, now we know the connection was
- * successful.
- * @param {number} pongId unique id assigned to us by the background page
- */
-cvox.ExtensionBridge.gotPongFromBackgroundPage = function(pongId) {
- var self = cvox.ExtensionBridge;
- self.connected = true;
- self.id_ = pongId;
-
- while (self.queuedMessages.length > 0) {
- self.sendContentScriptToBackground(self.queuedMessages.shift());
- }
-};
-
-/**
- * Send a message from the content script to the background page.
- *
- * @param {Object} message The message to send.
- */
-cvox.ExtensionBridge.sendContentScriptToBackground = function(message) {
- var self = cvox.ExtensionBridge;
- if (!self.connected) {
- // We're not connected to the background page, so queue this message
- // until we're connected.
- self.queuedMessages.push(message);
- return;
- }
-
- if (cvox.ExtensionBridge.backgroundPort) {
- cvox.ExtensionBridge.backgroundPort.postMessage(message);
- } else {
- chrome.extension.sendMessage(message);
- }
-};
-
-/**
- * Send a message from the background page to the content script of the
- * current selected tab.
- *
- * @param {Object} message The message to send.
- */
-cvox.ExtensionBridge.sendBackgroundToContentScript = function(message) {
- cvox.ExtensionBridge.portCache_.forEach(function(port) {
- port.postMessage(message);
- });
-};
-
-cvox.ExtensionBridge.init();
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/externs.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/externs.js
deleted file mode 100644
index fbf813c3168..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/externs.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-/**
- * @type {Object}
- */
-chrome.brailleDisplayPrivate = {};
-
-/**
- * @param {function(!{available: boolean, textCellCount: (number|undefined)})}
- * callback
- */
-chrome.brailleDisplayPrivate.getDisplayState = function(callback) {};
-
-/**
- * @type {ChromeEvent}
- */
-chrome.brailleDisplayPrivate.onDisplayStateChanged;
-
-/**
- * @type {ChromeEvent}
- */
-chrome.brailleDisplayPrivate.onKeyEvent;
-
-/**
- * @param {ArrayBuffer} cells
- */
-chrome.brailleDisplayPrivate.writeDots = function(cells) {};
-
-/**
- * @const
- */
-chrome.virtualKeyboardPrivate = {};
-
-/**
- * @typedef {{type: string, charValue: number, keyCode: number,
- * keyName: string, modifiers: (number|undefined)}}
- */
-chrome.virtualKeyboardPrivate.VirtualKeyboardEvent;
-
-/**
- * @param {chrome.virtualKeyboardPrivate.VirtualKeyboardEvent} keyEvent
- * @param {Function=} opt_callback
- */
-chrome.virtualKeyboardPrivate.sendKeyEvent =
- function(keyEvent, opt_callback) {};
-/**
- * @type {Object}
- */
-window.speechSynthesis;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js
deleted file mode 100644
index b44711bf563..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js
+++ /dev/null
@@ -1,207 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Chrome-specific implementation of methods that differ
- * depending on the host platform.
- *
- */
-
-goog.provide('cvox.ChromeHost');
-
-goog.require('cvox.AbstractHost');
-goog.require('cvox.ApiImplementation');
-goog.require('cvox.BrailleOverlayWidget');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.ChromeVoxEventWatcher');
-goog.require('cvox.ChromeVoxKbHandler');
-goog.require('cvox.ExtensionBridge');
-goog.require('cvox.HostFactory');
-goog.require('cvox.InitialSpeech');
-goog.require('cvox.PdfProcessor');
-goog.require('cvox.SearchLoader');
-goog.require('cvox.TraverseMath');
-
-/**
- * @constructor
- * @extends {cvox.AbstractHost}
- */
-cvox.ChromeHost = function() {
- goog.base(this);
-
- /** @private {boolean} */
- this.gotPrefsAtLeastOnce_ = false;
-};
-goog.inherits(cvox.ChromeHost, cvox.AbstractHost);
-
-
-/** @override */
-cvox.ChromeHost.prototype.init = function() {
- // TODO(deboer): This pattern is relatively painful since it
- // must be duplicated in all host.js files. It also causes odd
- // dependencies.
- // TODO (stoarca): Not using goog.bind because for some reason it gets
- // compiled to native code and not possible to debug.
- var self = this;
- var listener = function(message) {
- if (message['history']) {
- cvox.ChromeVox.visitedUrls = message['history'];
- }
-
- if (message['keyBindings']) {
- cvox.ChromeVoxKbHandler.loadKeyToFunctionsTable(message['keyBindings']);
- }
- if (message['prefs']) {
- var prefs = message['prefs'];
- cvox.ChromeVoxEditableTextBase.useIBeamCursor =
- (prefs['useIBeamCursor'] == 'true');
- cvox.ChromeVoxEditableTextBase.eventTypingEcho = true;
- cvox.ChromeVoxEventWatcher.focusFollowsMouse =
- (prefs['focusFollowsMouse'] == 'true');
-
- cvox.ChromeVox.version = prefs['version'];
-
- cvox.ChromeVox.earcons.enabled =
- /** @type {boolean} */(JSON.parse(prefs['earcons']));
-
- cvox.ChromeVox.typingEcho =
- /** @type {number} */(JSON.parse(prefs['typingEcho']));
-
- if (prefs['position']) {
- cvox.ChromeVox.position =
- /** @type {Object<{x:number, y:number}>} */ (
- JSON.parse(prefs['position']));
- }
-
- if (prefs['granularity'] != 'undefined') {
- cvox.ChromeVox.navigationManager.setGranularity(
- /** @type {number} */ (JSON.parse(prefs['granularity'])));
- }
-
- self.activateOrDeactivateChromeVox(prefs['active'] == 'true');
- self.activateOrDeactivateStickyMode(prefs['sticky'] == 'true');
- if (!self.gotPrefsAtLeastOnce_) {
- cvox.InitialSpeech.speak();
- }
- self.gotPrefsAtLeastOnce_ = true;
-
- if (prefs['useVerboseMode'] == 'false') {
- cvox.ChromeVox.verbosity = cvox.VERBOSITY_BRIEF;
- } else {
- cvox.ChromeVox.verbosity = cvox.VERBOSITY_VERBOSE;
- }
- if (prefs['cvoxKey']) {
- cvox.ChromeVox.modKeyStr = prefs['cvoxKey'];
- }
-
- var apiPrefsChanged = (
- prefs['siteSpecificScriptLoader'] !=
- cvox.ApiImplementation.siteSpecificScriptLoader ||
- prefs['siteSpecificScriptBase'] !=
- cvox.ApiImplementation.siteSpecificScriptBase);
- cvox.ApiImplementation.siteSpecificScriptLoader =
- prefs['siteSpecificScriptLoader'];
- cvox.ApiImplementation.siteSpecificScriptBase =
- prefs['siteSpecificScriptBase'];
- if (apiPrefsChanged) {
- var searchInit = prefs['siteSpecificEnhancements'] === 'true' ?
- cvox.SearchLoader.init : undefined;
- cvox.ApiImplementation.init(searchInit);
- }
- cvox.BrailleOverlayWidget.getInstance().setActive(
- prefs['brailleCaptions'] == 'true');
- }
- };
- cvox.ExtensionBridge.addMessageListener(listener);
-
- cvox.ExtensionBridge.addMessageListener(function(msg, port) {
- if (msg['message'] == 'DOMAINS_STYLES') {
- cvox.TraverseMath.getInstance().addDomainsAndStyles(
- msg['domains'], msg['styles']);
- }});
-
- cvox.ExtensionBridge.addMessageListener(function(msg, port) {
- var message = msg['message'];
- var cmd = msg['command'];
- if (message == 'USER_COMMAND') {
- if (cmd != 'toggleChromeVox' && !cvox.ChromeVox.documentHasFocus()) {
- return;
- }
- cvox.ChromeVoxUserCommands.commands[cmd](msg);
- } else if (message == 'SYSTEM_COMMAND') {
- if (cmd == 'killChromeVox') {
- this.killChromeVox();
- }
- }
- }.bind(this));
-
- cvox.ExtensionBridge.send({
- 'target': 'Prefs',
- 'action': 'getPrefs'
- });
-
- cvox.ExtensionBridge.send({
- 'target': 'Data',
- 'action': 'getHistory'
- });
-};
-
-
-/** @override */
-cvox.ChromeHost.prototype.reinit = function() {
- cvox.ExtensionBridge.init();
-};
-
-
-/** @override */
-cvox.ChromeHost.prototype.onPageLoad = function() {
- cvox.PdfProcessor.processEmbeddedPdfs();
-
- cvox.ExtensionBridge.addDisconnectListener(goog.bind(function() {
- cvox.ChromeVox.isActive = false;
- cvox.ChromeVoxEventWatcher.cleanup(window);
- // TODO(stoarca): Huh?? Why are we resetting during disconnect?
- // This is not appropriate behavior!
- cvox.ChromeVox.navigationManager.reset();
- }, this));
-};
-
-
-/** @override */
-cvox.ChromeHost.prototype.sendToBackgroundPage = function(message) {
- cvox.ExtensionBridge.send(message);
-};
-
-
-/** @override */
-cvox.ChromeHost.prototype.getApiSrc = function() {
- return this.getFileSrc('chromevox/injected/api.js');
-};
-
-
-/** @override */
-cvox.ChromeHost.prototype.getFileSrc = function(file) {
- return window.chrome.extension.getURL(file);
-};
-
-
-/** @override */
-cvox.ChromeHost.prototype.killChromeVox = function() {
- goog.base(this, 'killChromeVox');
- cvox.ExtensionBridge.removeMessageListeners();
-};
-
-
-/**
- * Activates or deactivates Sticky Mode.
- * @param {boolean} sticky Whether sticky mode should be active.
- */
-cvox.ChromeHost.prototype.activateOrDeactivateStickyMode = function(sticky) {
- cvox.ChromeVox.isStickyPrefOn = sticky;
-};
-
-/**
- * The host constructor for Chrome.
- */
-cvox.HostFactory.hostConstructor = cvox.ChromeHost;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/mathjax.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/mathjax.js
deleted file mode 100644
index a9f41566cba..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/mathjax.js
+++ /dev/null
@@ -1,294 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Implementation of ChromeVox's bridge to MathJax.
- *
- */
-
-goog.provide('cvox.ChromeMathJax');
-
-goog.require('cvox.AbstractMathJax');
-goog.require('cvox.ApiImplementation');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.HostFactory');
-goog.require('cvox.ScriptInstaller');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractMathJax}
- */
-cvox.ChromeMathJax = function() {
- goog.base(this);
-
- /**
- * Set to when the bridge is initialized.
- * @type {boolean}
- * @private
- */
- this.initialized_ = false;
-
- /**
- * The port to communicate with the content script.
- * @type {Port}
- */
- this.port = null;
-
- /**
- * The next id to use for async callbacks.
- * @type {number}
- * @private
- */
- this.nextCallbackId_ = 1;
-
- /**
- * Map from callback ID to callback function.
- * @type {Object<number, Function>}
- * @private
- */
- this.callbackMap_ = {};
-
- /**
- * The ids for converted TeX nodes.
- * @type {number}
- * @private
- */
- this.texNodeId_ = 0;
-
- this.init();
-};
-goog.inherits(cvox.ChromeMathJax, cvox.AbstractMathJax);
-
-
-/**
- * Register a callback function in the mapping.
- * @param {Function} callback The callback function.
- * @return {number} id The new id.
- * @private
- */
-cvox.ChromeMathJax.prototype.registerCallback_ = function(callback) {
- var id = this.nextCallbackId_;
- this.nextCallbackId_++;
- this.callbackMap_[id] = callback;
- return id;
-};
-
-
-/**
- * Destructive Retrieval of a callback function from the mapping.
- * @param {string} idStr The id.
- * @return {Function} The callback function.
- * @private
- */
-cvox.ChromeMathJax.prototype.retrieveCallback_ = function(idStr) {
- var id = parseInt(idStr, 10);
- var callback = this.callbackMap_[id];
- if (callback) {
- return callback;
- }
- return null;
-};
-
-
-/**
- * Initialise communication with the content script.
- */
-cvox.ChromeMathJax.prototype.init = function() {
- window.addEventListener('message', goog.bind(this.portSetup, this), true);
- var scripts = new Array();
- scripts.push(cvox.ChromeVox.host.getFileSrc(
- 'chromevox/injected/mathjax_external_util.js'));
- scripts.push(cvox.ChromeVox.host.getFileSrc('chromevox/injected/mathjax.js'));
- scripts.push(cvox.ApiImplementation.siteSpecificScriptLoader);
- this.initialized_ = cvox.ScriptInstaller.installScript(
- scripts, 'mathjax', undefined,
- cvox.ApiImplementation.siteSpecificScriptBase);
-};
-
-
-/**
- * Destructive Retrieval of a callback function from the mapping.
- * @param {string} data The command to be sent to the content script.
- * @param {Function} callback A callback function.
- * @param {Object<*>=} args Object of arguments.
- */
-cvox.ChromeMathJax.prototype.postMsg = function(data, callback, args) {
- args = args || {};
- var id = this.registerCallback_(callback);
- var idStr = id.toString();
- this.port.postMessage({'cmd': data, 'id': idStr, 'args': args});
-};
-
-
-/**
- * This method is called when the content script receives a message from
- * the page.
- * @param {Event} event The DOM event with the message data.
- * @return {boolean} True if default event processing should continue.
- */
-cvox.ChromeMathJax.prototype.portSetup = function(event) {
- if (event.data == 'cvox.MathJaxPortSetup') {
- this.port = event.ports[0];
- this.port.onmessage =
- goog.bind(
- function(event) {this.dispatchMessage(event.data);},
- this);
- return false;
- }
- return true;
-};
-
-
-/**
- * Call the appropriate Cvox function dealing with MathJax return values.
- * @param {{cmd: string, id: string, args: Object<string>}} message A
- * message object.
- */
-cvox.ChromeMathJax.prototype.dispatchMessage = function(message) {
- var method;
- var argNames = [];
- switch (message['cmd']) {
- case 'NodeMml':
- method = this.convertMarkupToDom;
- argNames = ['mathml', 'elementId'];
- break;
- case 'Active':
- method = this.applyBoolean;
- argNames = ['status'];
- break;
- }
-
- if (!method) {
- throw 'Unknown MathJax call: ' + message['cmd'];
- }
- var callback = this.retrieveCallback_(message['id']);
- var args = message['args'];
- if (callback && method) {
- method.apply(this,
- [callback].concat(
- argNames.map(function(x) {return args[x];})));
- }
-};
-
-
-/**
- * Converts a Boolean string to boolean value and applies a callback function.
- * @param {function(boolean)} callback A function with one argument.
- * @param {boolean} bool A truth value.
- */
-cvox.ChromeMathJax.prototype.applyBoolean = function(
- callback, bool) {
- callback(bool);
-};
-
-
-/**
- * @override
- */
-cvox.ChromeMathJax.prototype.isMathjaxActive = function(callback) {
- if (!this.initialized_) {
- callback(false);
- return;
- }
-
- var retries = 0;
-
- var fetch = goog.bind(function() {
- retries++;
- try {this.postMsg('Active',
- function(result) {
- if (result) {
- callback(result);
- } else if (retries < 5) {
- setTimeout(fetch, 1000);
- }
- });
- } catch (x) { // Error usually means that the port is not ready yet.
- if (retries < 5) {
- setTimeout(fetch, 1000);
- } else {
- throw x;
- }}},
- this);
-
- fetch();
-};
-
-
-/**
- * @override
- */
-cvox.ChromeMathJax.prototype.getAllJax = function(callback) {
- this.postMsg('AllJax', callback);
-};
-
-
-/**
- * @override
- */
-cvox.ChromeMathJax.prototype.registerSignal = function(
- callback, signal) {
- this.postMsg('RegSig', callback, {sig: signal});
-};
-
-
-/**
- * @override
- */
-cvox.ChromeMathJax.prototype.injectScripts = function() {
- var retries = 0;
-
- var fetch = goog.bind(
- function() {
- retries++;
- if (this.port) {
- this.postMsg('InjectScripts', function() {});
- } else if (retries < 10) {
- setTimeout(fetch, 500);
- }
- },
- this);
-
- fetch();
-};
-
-
-/**
- * @override
- */
-cvox.ChromeMathJax.prototype.configMediaWiki = function() {
- this.postMsg('ConfWikipedia', function() { });
-};
-
-
-/**
- * @override
- */
-cvox.ChromeMathJax.prototype.getTex = function(callback, tex) {
- var altText = tex['alt'] || tex['title'];
- if (altText) {
- var newId = 'cvoxId-' + this.texNodeId_++;
- tex.setAttribute('cvoxId', newId);
- this.postMsg('TexToMml', callback, {alt: altText, id: newId});
- }
-};
-
-
-/**
- * @override
- */
-cvox.ChromeMathJax.prototype.getAsciiMath = function(callback, asciiMathNode) {
- var altText = asciiMathNode['alt'] || asciiMathNode['title'];
- if (altText) {
- var newId = 'cvoxId-' + this.texNodeId_++;
- asciiMathNode.setAttribute('cvoxId', newId);
- this.postMsg('AsciiMathToMml', callback, {alt: altText, id: newId});
- }
-};
-
-
-/** Export platform constructor. */
-cvox.HostFactory.mathJaxConstructor =
- cvox.ChromeMathJax;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts.js
deleted file mode 100644
index 77e257f6b97..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts.js
+++ /dev/null
@@ -1,139 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Bridge that sends TTS messages from content scripts or
- * other pages to the main background page.
- *
- */
-
-goog.provide('cvox.ChromeTts');
-
-goog.require('cvox.ChromeTtsBase');
-goog.require('cvox.HostFactory');
-
-/**
- * @constructor
- * @extends {cvox.ChromeTtsBase}
- */
-cvox.ChromeTts = function() {
- goog.base(this);
-
- this.addBridgeListener();
-};
-goog.inherits(cvox.ChromeTts, cvox.ChromeTtsBase);
-
-/**
- * Current call id, used for matching callback functions.
- * @type {number}
- */
-cvox.ChromeTts.callId = 1;
-
-/**
- * Maps call ids to callback functions.
- * @type {Object<number, Function>}
- */
-cvox.ChromeTts.functionMap = new Object();
-
-/** @override */
-cvox.ChromeTts.prototype.speak = function(textString, queueMode, properties) {
- if (!properties) {
- properties = {};
- }
-
- goog.base(this, 'speak', textString, queueMode, properties);
-
- cvox.ExtensionBridge.send(
- this.createMessageForProperties_(textString, queueMode, properties));
-};
-
-/** @override */
-cvox.ChromeTts.prototype.isSpeaking = function() {
- cvox.ChromeTts.superClass_.isSpeaking.call(this);
- return false;
-};
-
-/** @override */
-cvox.ChromeTts.prototype.stop = function() {
- cvox.ChromeTts.superClass_.stop.call(this);
- cvox.ExtensionBridge.send(
- {'target': 'TTS',
- 'action': 'stop'});
-};
-
-/** @override */
-cvox.ChromeTts.prototype.increaseOrDecreaseProperty =
- function(propertyName, increase) {
- cvox.ExtensionBridge.send(
- {'target': 'TTS',
- 'action': 'increaseOrDecrease',
- 'property': propertyName,
- 'increase': increase});
-};
-
-/**
- * Increases a TTS speech property.
- * @param {string} property_name The name of the property to increase.
- * @param {boolean} announce Whether to announce that the property is
- * changing.
- */
-cvox.ChromeTts.prototype.increaseProperty = function(property_name, announce) {
- goog.base(this, 'increaseProperty', property_name, announce);
- cvox.ExtensionBridge.send(
- {'target': 'TTS',
- 'action': 'increase' + property_name,
- 'announce': announce});
-};
-
-/**
- * Listens for TTS_COMPLETED message and executes the callback function.
- */
-cvox.ChromeTts.prototype.addBridgeListener = function() {
- cvox.ExtensionBridge.addMessageListener(
- function(msg, port) {
- var message = msg['message'];
- if (message == 'TTS_CALLBACK') {
- var id = msg['id'];
- var func = cvox.ChromeTts.functionMap[id];
- if (func != undefined) {
- if (!msg['cleanupOnly']) {
- func();
- }
- delete cvox.ChromeTts.functionMap[id];
- }
- }
- });
-};
-
-/**
- * Creates a message suitable for sending as a speak action to background tts.
- * @param {string} textString The string of text to be spoken.
- * @param {cvox.QueueMode} queueMode The queue mode.
- * @param {Object=} properties Speech properties to use for this utterance.
- * @return {Object} A message.
- * @private
- */
-cvox.ChromeTts.prototype.createMessageForProperties_ =
- function(textString, queueMode, properties) {
- var message = {'target': 'TTS',
- 'action': 'speak',
- 'text': textString,
- 'queueMode': queueMode,
- 'properties': properties};
-
- if (properties['startCallback'] != undefined) {
- cvox.ChromeTts.functionMap[cvox.ChromeTts.callId] =
- properties['startCallback'];
- message['startCallbackId'] = cvox.ChromeTts.callId++;
- }
- if (properties['endCallback'] != undefined) {
- cvox.ChromeTts.functionMap[cvox.ChromeTts.callId] =
- properties['endCallback'];
- message['endCallbackId'] = cvox.ChromeTts.callId++;
- }
- return message;
-};
-
-/** @override */
-cvox.HostFactory.ttsConstructor = cvox.ChromeTts;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_background.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_background.js
deleted file mode 100644
index d4f1676e00a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_background.js
+++ /dev/null
@@ -1,731 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Sends Text-To-Speech commands to Chrome's native TTS
- * extension API.
- *
- */
-
-goog.provide('cvox.TtsBackground');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.ChromeTtsBase');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.MathMap');
-goog.require('goog.i18n.MessageFormat');
-
-
-/**
- * @constructor
- * @param {string} textString The string of text to be spoken.
- * @param {Object} properties Speech properties to use for this utterance.
- */
-cvox.Utterance = function(textString, properties) {
- this.textString = textString;
- this.properties = properties;
- this.id = cvox.Utterance.nextUtteranceId_++;
-};
-
-/**
- * The next utterance id to use.
- * @type {number}
- * @private
- */
-cvox.Utterance.nextUtteranceId_ = 1;
-
-/**
- * @constructor
- * @param {boolean=} opt_enableMath Whether to process math. Used when running
- * on forge. Defaults to true.
- * @extends {cvox.ChromeTtsBase}
- */
-cvox.TtsBackground = function(opt_enableMath) {
- opt_enableMath = opt_enableMath == undefined ? true : opt_enableMath;
- goog.base(this);
-
- this.ttsProperties['rate'] = (parseFloat(localStorage['rate']) ||
- this.propertyDefault['rate']);
- this.ttsProperties['pitch'] = (parseFloat(localStorage['pitch']) ||
- this.propertyDefault['pitch']);
- this.ttsProperties['volume'] = (parseFloat(localStorage['volume']) ||
- this.propertyDefault['volume']);
-
- // Use the current locale as the speech language if not otherwise
- // specified.
- if (this.ttsProperties['lang'] == undefined) {
- this.ttsProperties['lang'] =
- chrome.i18n.getMessage('@@ui_locale').replace('_', '-');
- }
-
- this.lastEventType = 'end';
-
- /** @private {number} */
- this.currentPunctuationEcho_ =
- parseInt(localStorage[cvox.AbstractTts.PUNCTUATION_ECHO] || 1, 10);
-
- /**
- * @type {!Array<{name:(string),
- * msg:(string),
- * regexp:(RegExp),
- * clear:(boolean)}>}
- * @private
- */
- this.punctuationEchoes_ = [
- /**
- * Punctuation echoed for the 'none' option.
- */
- {
- name: 'none',
- msg: 'no_punctuation',
- regexp: /[-$#"()*;:<>\n\\\/+='~`@_]/g,
- clear: true
- },
-
- /**
- * Punctuation echoed for the 'some' option.
- */
- {
- name: 'some',
- msg: 'some_punctuation',
- regexp: /[$#"*<>\\\/\{\}+=~`%]/g,
- clear: false
- },
-
- /**
- * Punctuation echoed for the 'all' option.
- */
- {
- name: 'all',
- msg: 'all_punctuation',
- regexp: /[-$#"()*;:<>\n\\\/\{\}\[\]+='~`!@_.,?%]/g,
- clear: false
- }
- ];
-
- /**
- * A list of punctuation characters that should always be spliced into output
- * even with literal word substitutions.
- * This is important for tts prosity.
- * @type {!Array<string>}
- * @private
- */
- this.retainPunctuation_ =
- [';', '?', '!', '\''];
-
- /**
- * Mapping for math elements.
- * @type {cvox.MathMap}
- */
- this.mathmap = opt_enableMath ? new cvox.MathMap() : null;
-
- /**
- * The id of a callback returned from setTimeout.
- * @type {number|undefined}
- */
- this.timeoutId_;
-
- try {
- /**
- * @type {Object<string>}
- * @private
- * @const
- */
- this.PHONETIC_MAP_ = /** @type {Object<string>} */(
- JSON.parse(Msgs.getMsg('phonetic_map')));
- } catch (e) {
- console.log('Error; unable to parse phonetic map msg.');
- }
-
- /**
- * Capturing tts event listeners.
- * @type {Array<cvox.TtsCapturingEventListener>}
- * @private
- */
- this.capturingTtsEventListeners_ = [];
-
- /**
- * The current utterance.
- * @type {cvox.Utterance}
- * @private
- */
- this.currentUtterance_ = null;
-
- /**
- * The utterance queue.
- * @type {Array<cvox.Utterance>}
- * @private
- */
- this.utteranceQueue_ = [];
-
- // TODO(dtseng): Done while migrating away from using localStorage.
- if (localStorage['voiceName']) {
- chrome.storage.local.set({voiceName: localStorage['voiceName']});
- delete localStorage['voiceName'];
- }
-
- window.speechSynthesis.onvoiceschanged = function() {
- chrome.storage.local.get({voiceName: ''}, function(items) {
- this.updateVoice_(items.voiceName);
- }.bind(this));
- }.bind(this);
-
- chrome.storage.onChanged.addListener(function(changes, namespace) {
- if (changes.voiceName) {
- this.updateVoice_(changes.voiceName.newValue);
- }
- }.bind(this));
-};
-goog.inherits(cvox.TtsBackground, cvox.ChromeTtsBase);
-
-
-/**
- * The amount of time to wait before speaking a phonetic word for a
- * letter.
- * @type {number}
- * @private
- * @const
- */
-cvox.TtsBackground.PHONETIC_DELAY_MS_ = 1000;
-
-/**
- * The list of properties allowed to be passed to the chrome.tts.speak API.
- * Anything outside this list will be stripped.
- * @type {Array<string>}
- * @private
- * @const
- */
-cvox.TtsBackground.ALLOWED_PROPERTIES_ = [
- 'desiredEventTypes',
- 'enqueue',
- 'extensionId',
- 'gender',
- 'lang',
- 'onEvent',
- 'pitch',
- 'rate',
- 'requiredEventTypes',
- 'voiceName',
- 'volume'];
-
-
-/** @override */
-cvox.TtsBackground.prototype.speak = function(
- textString, queueMode, properties) {
- goog.base(this, 'speak', textString, queueMode, properties);
-
- if (!properties) {
- properties = {};
- }
-
- // Chunk to improve responsiveness. Use a replace/split pattern in order to
- // retain the original punctuation.
- var splitTextString = textString.replace(/([-\n\r.,!?;])(\s)/g, '$1$2|');
- splitTextString = splitTextString.split('|');
- // Since we are substituting the chunk delimiters back into the string, only
- // recurse when there are more than 2 split items. This should result in only
- // one recursive call.
- if (splitTextString.length > 2) {
- var startCallback = properties['startCallback'];
- var endCallback = properties['endCallback'];
- var onEvent = properties['onEvent'];
- for (var i = 0; i < splitTextString.length; i++) {
- var propertiesCopy = {};
- for (var p in properties) {
- propertiesCopy[p] = properties[p];
- }
- propertiesCopy['startCallback'] = i == 0 ? startCallback : null;
- propertiesCopy['endCallback'] =
- i == (splitTextString.length - 1) ? endCallback : null;
- propertiesCopy['onEvent'] =
- i == (splitTextString.length - 1) ? onEvent : null;
- this.speak(splitTextString[i], queueMode, propertiesCopy);
- queueMode = cvox.QueueMode.QUEUE;
- }
- return this;
- }
-
- textString = this.preprocess(textString, properties);
-
- // TODO(dtseng): Google TTS has bad performance when speaking numbers. This
- // pattern causes ChromeVox to read numbers as digits rather than words.
- textString = this.getNumberAsDigits_(textString);
-
- // TODO(dtseng): Google TTS flushes the queue when encountering strings of
- // this pattern which stops ChromeVox speech.
- if (!textString || !textString.match(/\w+/g)) {
- // We still want to callback for listeners in our content script.
- if (properties['startCallback']) {
- try {
- properties['startCallback']();
- } catch (e) {
- }
- }
- if (properties['endCallback']) {
- try {
- properties['endCallback']();
- } catch (e) {
- }
- }
- if (queueMode === cvox.QueueMode.FLUSH) {
- this.stop();
- }
- return this;
- }
-
- var mergedProperties = this.mergeProperties(properties);
-
- if (this.currentVoice) {
- mergedProperties['voiceName'] = this.currentVoice;
- }
-
- if (queueMode == cvox.QueueMode.CATEGORY_FLUSH &&
- !mergedProperties['category']) {
- queueMode = cvox.QueueMode.FLUSH;
- }
-
- var utterance = new cvox.Utterance(textString, mergedProperties);
- this.speakUsingQueue_(utterance, queueMode);
-};
-
-/**
- * Use the speech queue to handle the given speech request.
- * @param {cvox.Utterance} utterance The utterance to speak.
- * @param {cvox.QueueMode} queueMode The queue mode.
- * @private
- */
-cvox.TtsBackground.prototype.speakUsingQueue_ = function(utterance, queueMode) {
- // First, take care of removing the current utterance and flushing
- // anything from the queue we need to. If we remove the current utterance,
- // make a note that we're going to stop speech.
- if (queueMode == cvox.QueueMode.FLUSH ||
- queueMode == cvox.QueueMode.CATEGORY_FLUSH) {
- if (this.shouldCancel_(this.currentUtterance_, utterance, queueMode)) {
- this.cancelUtterance_(this.currentUtterance_);
- this.currentUtterance_ = null;
- }
- var i = 0;
- while (i < this.utteranceQueue_.length) {
- if (this.shouldCancel_(
- this.utteranceQueue_[i], utterance, queueMode)) {
- this.cancelUtterance_(this.utteranceQueue_[i]);
- this.utteranceQueue_.splice(i, 1);
- } else {
- i++;
- }
- }
- }
-
- // Next, add the new utterance to the queue.
- this.utteranceQueue_.push(utterance);
-
- // Now start speaking the next item in the queue.
- this.startSpeakingNextItemInQueue_();
-};
-
-/**
- * If nothing is speaking, pop the first item off the speech queue and
- * start speaking it. This is called when a speech request is made and
- * when the current utterance finishes speaking.
- * @private
- */
-cvox.TtsBackground.prototype.startSpeakingNextItemInQueue_ = function() {
- if (this.currentUtterance_) {
- return;
- }
-
- if (this.utteranceQueue_.length == 0) {
- return;
- }
-
- // There is no voice to speak with (e.g. the tts system has not fully
- // initialized).
- if (!this.currentVoice) {
- return;
- }
-
- this.currentUtterance_ = this.utteranceQueue_.shift();
- var utteranceId = this.currentUtterance_.id;
-
- this.currentUtterance_.properties['onEvent'] = goog.bind(function(event) {
- this.onTtsEvent_(event, utteranceId);
- },
- this);
-
- var validatedProperties = {};
- for (var i = 0; i < cvox.TtsBackground.ALLOWED_PROPERTIES_.length; i++) {
- var p = cvox.TtsBackground.ALLOWED_PROPERTIES_[i];
- if (this.currentUtterance_.properties[p]) {
- validatedProperties[p] = this.currentUtterance_.properties[p];
- }
- }
-
- chrome.tts.speak(this.currentUtterance_.textString,
- validatedProperties);
-};
-
-/**
- * Called when we get a speech event from Chrome. We ignore any event
- * that doesn't pertain to the current utterance, but when speech starts
- * or ends we optionally call callback functions, and start speaking the
- * next utterance if there's another one enqueued.
- * @param {Object} event The TTS event from chrome.
- * @param {number} utteranceId The id of the associated utterance.
- * @private
- */
-cvox.TtsBackground.prototype.onTtsEvent_ = function(event, utteranceId) {
- this.lastEventType = event['type'];
-
- // Ignore events sent on utterances other than the current one.
- if (!this.currentUtterance_ ||
- utteranceId != this.currentUtterance_.id) {
- return;
- }
-
- var utterance = this.currentUtterance_;
-
- switch (event.type) {
- case 'start':
- this.capturingTtsEventListeners_.forEach(function(listener) {
- listener.onTtsStart();
- });
- if (utterance.properties['startCallback']) {
- try {
- utterance.properties['startCallback']();
- } catch (e) {
- }
- }
- break;
- case 'end':
- // End callbacks could cause additional speech to queue up.
- this.currentUtterance_ = null;
- this.capturingTtsEventListeners_.forEach(function(listener) {
- listener.onTtsEnd();
- });
- if (utterance.properties['endCallback']) {
- try {
- utterance.properties['endCallback']();
- } catch (e) {
- }
- }
- this.startSpeakingNextItemInQueue_();
- break;
- case 'interrupted':
- this.cancelUtterance_(utterance);
- this.currentUtterance_ = null;
- for (var i = 0; i < this.utteranceQueue_.length; i++) {
- this.cancelUtterance_(this.utteranceQueue_[i]);
- }
- this.utteranceQueue_.length = 0;
- break;
- case 'error':
- this.onError_(event['errorMessage']);
- this.startSpeakingNextItemInQueue_();
- break;
- }
-};
-
-/**
- * Determines if |utteranceToCancel| should be canceled (interrupted if
- * currently speaking, or removed from the queue if not), given the new
- * utterance we want to speak and the queue mode. If the queue mode is
- * QUEUE or FLUSH, the logic is straightforward. If the queue mode is
- * CATEGORY_FLUSH, we only flush utterances with the same category.
- *
- * @param {cvox.Utterance} utteranceToCancel The utterance in question.
- * @param {cvox.Utterance} newUtterance The new utterance we're enqueueing.
- * @param {cvox.QueueMode} queueMode The queue mode.
- * @return {boolean} True if this utterance should be canceled.
- * @private
- */
-cvox.TtsBackground.prototype.shouldCancel_ =
- function(utteranceToCancel, newUtterance, queueMode) {
- if (!utteranceToCancel) {
- return false;
- }
- if (utteranceToCancel.properties['doNotInterrupt']) {
- return false;
- }
- switch (queueMode) {
- case cvox.QueueMode.QUEUE:
- return false;
- case cvox.QueueMode.FLUSH:
- return true;
- case cvox.QueueMode.CATEGORY_FLUSH:
- return (utteranceToCancel.properties['category'] ==
- newUtterance.properties['category']);
- }
-};
-
-/**
- * Do any cleanup necessary to cancel an utterance, like callings its
- * callback function if any.
- * @param {cvox.Utterance} utterance The utterance to cancel.
- * @private
- */
-cvox.TtsBackground.prototype.cancelUtterance_ = function(utterance) {
- if (utterance && utterance.properties['endCallback']) {
- try {
- utterance.properties['endCallback'](true);
- } catch (e) {
- }
- }
-};
-
-/** @override */
-cvox.TtsBackground.prototype.increaseOrDecreaseProperty =
- function(propertyName, increase) {
- goog.base(this, 'increaseOrDecreaseProperty', propertyName, increase);
- localStorage[propertyName] = this.ttsProperties[propertyName];
-};
-
-/** @override */
-cvox.TtsBackground.prototype.isSpeaking = function() {
- goog.base(this, 'isSpeaking');
- return this.lastEventType != 'end';
-};
-
-/** @override */
-cvox.TtsBackground.prototype.stop = function() {
- goog.base(this, 'stop');
-
- this.cancelUtterance_(this.currentUtterance_);
- this.currentUtterance_ = null;
-
- for (var i = 0; i < this.utteranceQueue_.length; i++) {
- this.cancelUtterance_(this.utteranceQueue_[i]);
- }
-
- this.utteranceQueue_.length = 0;
-
- chrome.tts.stop();
-};
-
-/** @override */
-cvox.TtsBackground.prototype.addCapturingEventListener = function(listener) {
- this.capturingTtsEventListeners_.push(listener);
-};
-
-/**
- * An error handler passed as a callback to chrome.tts.speak.
- * @param {string} errorMessage Describes the error (set by onEvent).
- * @private
- */
-cvox.TtsBackground.prototype.onError_ = function(errorMessage) {
- this.updateVoice_(this.currentVoice);
-};
-
-/**
- * Converts an engine property value to a percentage from 0.00 to 1.00.
- * @param {string} property The property to convert.
- * @return {?number} The percentage of the property.
- */
-cvox.TtsBackground.prototype.propertyToPercentage = function(property) {
- return (this.ttsProperties[property] - this.propertyMin[property]) /
- Math.abs(this.propertyMax[property] - this.propertyMin[property]);
-};
-
-
-/**
- * @override
- */
-cvox.TtsBackground.prototype.preprocess = function(text, properties) {
- properties = properties ? properties : {};
-
- // Perform specialized processing, such as mathematics.
- if (properties.math) {
- text = this.preprocessMath_(text, properties.math);
- }
-
- // Perform generic processing.
- text = goog.base(this, 'preprocess', text, properties);
-
- // Perform any remaining processing such as punctuation expansion.
- var pE = null;
- if (properties[cvox.AbstractTts.PUNCTUATION_ECHO]) {
- for (var i = 0; pE = this.punctuationEchoes_[i]; i++) {
- if (properties[cvox.AbstractTts.PUNCTUATION_ECHO] == pE.name) {
- break;
- }
- }
- } else {
- pE = this.punctuationEchoes_[this.currentPunctuationEcho_];
- }
- text =
- text.replace(pE.regexp, this.createPunctuationReplace_(pE.clear));
-
- // Try pronouncing phonetically for single characters. Cancel previous calls
- // to pronouncePhonetically_ if we fail to pronounce on this invokation or if
- // this text is math which should never be pronounced phonetically.
- if (properties.math ||
- !properties['phoneticCharacters'] ||
- !this.pronouncePhonetically_(text)) {
- this.clearTimeout_();
- }
-
- // Try looking up in our unicode tables for a short description.
- if (!properties.math && text.length == 1 && this.mathmap) {
- text = this.mathmap.store.lookupString(
- text.toLowerCase(),
- cvox.MathStore.createDynamicConstraint('default', 'short')) || text;
- }
-
- // Remove all whitespace from the beginning and end, and collapse all
- // inner strings of whitespace to a single space.
- text = text.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '');
-
- return text;
-};
-
-
-/**
- * Method that cycles among the available punctuation echo levels.
- * @return {string} The resulting punctuation level message id.
- */
-cvox.TtsBackground.prototype.cyclePunctuationEcho = function() {
- this.currentPunctuationEcho_ =
- (this.currentPunctuationEcho_ + 1) % this.punctuationEchoes_.length;
- localStorage[cvox.AbstractTts.PUNCTUATION_ECHO] =
- this.currentPunctuationEcho_;
- return this.punctuationEchoes_[this.currentPunctuationEcho_].msg;
-};
-
-
-/**
- * Process a math expression into a string suitable for a speech engine.
- * @param {string} text Text representing a math expression.
- * @param {Object= } math Parameter containing information how to
- * process the math expression.
- * @return {string} The string with a spoken version of the math expression.
- * @private
- */
-cvox.TtsBackground.prototype.preprocessMath_ = function(text, math) {
- if (!this.mathmap) {
- return text;
- }
- var result = '';
- var dynamicCstr = cvox.MathStore.createDynamicConstraint(
- math['domain'], math['style']);
- result = this.mathmap.store.lookupString(text, dynamicCstr);
- if (result) {
- return result;
- }
- return text;
-};
-
-
-/**
- * Converts a number into space-separated digits.
- * For numbers containing 4 or fewer digits, we return the original number.
- * This ensures that numbers like 123,456 or 2011 are not "digitized" while
- * 123456 is.
- * @param {string} text The text to process.
- * @return {string} A string with all numbers converted.
- * @private
- */
-cvox.TtsBackground.prototype.getNumberAsDigits_ = function(text) {
- return text.replace(/\d+/g, function(num) {
- if (num.length <= 4) {
- return num;
- }
- return num.split('').join(' ');
- });
-};
-
-
-/**
- * Constructs a function for string.replace that handles description of a
- * punctuation character.
- * @param {boolean} clear Whether we want to use whitespace in place of match.
- * @return {function(string): string} The replacement function.
- * @private
- */
-cvox.TtsBackground.prototype.createPunctuationReplace_ = function(clear) {
- return goog.bind(function(match) {
- var retain = this.retainPunctuation_.indexOf(match) != -1 ?
- match : ' ';
- return clear ? retain :
- ' ' + (new goog.i18n.MessageFormat(Msgs.getMsg(
- cvox.AbstractTts.CHARACTER_DICTIONARY[match])))
- .format({'COUNT': 1}) + retain + ' ';
- }, this);
-};
-
-
-/**
- * Pronounces single letters phonetically after some timeout.
- * @param {string} text The text.
- * @return {boolean} True if the text resulted in speech.
- * @private
- */
-cvox.TtsBackground.prototype.pronouncePhonetically_ = function(text) {
- if (!this.PHONETIC_MAP_) {
- return false;
- }
- text = text.toLowerCase();
- text = this.PHONETIC_MAP_[text];
- if (text) {
- this.clearTimeout_();
- var self = this;
- this.timeoutId_ = setTimeout(function() {
- self.speak(text, cvox.QueueMode.QUEUE);
- }, cvox.TtsBackground.PHONETIC_DELAY_MS_);
- return true;
- }
- return false;
-};
-
-
-/**
- * Clears the last timeout set via setTimeout.
- * @private
- */
-cvox.TtsBackground.prototype.clearTimeout_ = function() {
- if (goog.isDef(this.timeoutId_)) {
- clearTimeout(this.timeoutId_);
- this.timeoutId_ = undefined;
- }
-};
-
-
-/**
- * Update the current voice used to speak based upon values in storage. If that
- * does not succeed, fallback to use system locale when picking a voice.
- * @param {string} voiceName Voice name to set.
- * @private
- */
-cvox.TtsBackground.prototype.updateVoice_ = function(voiceName) {
- chrome.tts.getVoices(
- goog.bind(function(voices) {
- for (var i = 0, v; v = voices[i]; i++) {
- if (v['voiceName'] == voiceName) {
- this.currentVoice = v['voiceName'];
- this.startSpeakingNextItemInQueue_();
- return;
- }
- }
-
- var currentLocale =
- chrome.i18n.getMessage('@@ui_locale').replace('_', '-');
- voices.sort(function(v1, v2) {
- if (v1['remote'] && !v2['remote']) {
- return 1;
- }
- if (!v1['remote'] && v2['remote']) {
- return -1;
- }
- if (v1['lang'] == currentLocale && v2['lang'] != currentLocale) {
- return -1;
- }
- if (v1['lang'] != currentLocale && v2['lang'] == currentLocale) {
- return 1;
- }
- return 0;
- });
- if (voices[0]) {
- this.currentVoice = voices[0].voiceName;
- this.startSpeakingNextItemInQueue_();
- }
- }, this));
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_background_test.extjs b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_background_test.extjs
deleted file mode 100644
index 7c107b73d08..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_background_test.extjs
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../../testing/chromevox_e2e_test_base.js',
- '../../testing/assert_additions.js']);
-
-// E2E tests for TtsBackground.
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxE2ETest}
- */
-function CvoxTtsBackgroundTest() {
- ChromeVoxE2ETest.call(this);
-}
-
-CvoxTtsBackgroundTest.prototype = {
- __proto__: ChromeVoxE2ETest.prototype
-};
-
-SYNC_TEST_F('CvoxTtsBackgroundTest', 'Preprocess', function() {
- var tts = new cvox.TtsBackground(false);
- var preprocess = tts.preprocess.bind(tts);
-
- // Punctuation.
- assertEquals('dot', preprocess('.'));
- assertEquals('x.', preprocess('x.'));
- assertEquals('.x', preprocess('.x'));
- assertEquals('space', preprocess(' '));
- assertEquals('', preprocess(' '));
- assertEquals('A', preprocess('a'));
- assertEquals('A', preprocess('A'));
- assertEquals('a.', preprocess('a.'));
- assertEquals('.a', preprocess('.a'));
-
- assertEquals('10 equal signs', preprocess('=========='));
-
- assertEquals('new line', preprocess('\n'));
- assertEquals('return', preprocess('\r'));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_base.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_base.js
deleted file mode 100644
index 5a1074b9680..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/chrome/tts_base.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A base class for Tts living on Chrome platforms.
- *
- */
-
-goog.provide('cvox.ChromeTtsBase');
-
-goog.require('cvox.AbstractTts');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractTts}
- */
-cvox.ChromeTtsBase = function() {
- goog.base(this);
- this.propertyDefault['pitch'] = 1;
- this.propertyMin['pitch'] = 0.2;
- this.propertyMax['pitch'] = 2.0;
-
- this.propertyDefault['rate'] = 1;
- this.propertyMin['rate'] = 0.2;
- this.propertyMax['rate'] = 5.0;
-
- this.propertyDefault['volume'] = 1;
- this.propertyMin['volume'] = 0.2;
- this.propertyMax['volume'] = 1.0;
-};
-goog.inherits(cvox.ChromeTtsBase, cvox.AbstractTts);
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_earcons.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_earcons.js
deleted file mode 100644
index 1dabd1ad6d4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_earcons.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Base class for implementing earcons.
- *
- * When adding earcons, please add them to getEarconName and getEarconId.
- *
- */
-
-goog.provide('cvox.AbstractEarcons');
-goog.provide('cvox.Earcon');
-
-
-/**
- * Earcon names.
- * @enum {string}
- */
-cvox.Earcon = {
- ALERT_MODAL: 'alert_modal',
- ALERT_NONMODAL: 'alert_nonmodal',
- BUTTON: 'button',
- CHECK_OFF: 'check_off',
- CHECK_ON: 'check_on',
- EDITABLE_TEXT: 'editable_text',
- INVALID_KEYPRESS: 'invalid_keypress',
- LINK: 'link',
- LISTBOX: 'listbox',
- LIST_ITEM: 'list_item',
- LONG_DESC: 'long_desc',
- MATH: 'math',
- OBJECT_CLOSE: 'object_close',
- OBJECT_ENTER: 'object_enter',
- OBJECT_EXIT: 'object_exit',
- OBJECT_OPEN: 'object_open',
- OBJECT_SELECT: 'object_select',
- PAGE_FINISH_LOADING: 'page_finish_loading',
- PAGE_START_LOADING: 'page_start_loading',
- RECOVER_FOCUS: 'recover_focus',
- SELECTION: 'selection',
- SELECTION_REVERSE: 'selection_reverse',
- SKIP: 'skip',
- WRAP: 'wrap',
- WRAP_EDGE: 'wrap_edge',
-};
-
-
-/**
- * @constructor
- */
-cvox.AbstractEarcons = function() {
- /**
- * Public flag set to enable or disable earcons. Callers should prefer
- * toggle(); however, this member is public for initialization.
- * @type {boolean}
- */
- this.enabled = true;
-};
-
-
-/**
- * Plays the specified earcon sound.
- * @param {cvox.Earcon} earcon An earcon identifier.
- */
-cvox.AbstractEarcons.prototype.playEarcon = function(earcon) {
-};
-
-
-/**
- * Whether or not earcons are available.
- * @return {boolean} True if earcons are available.
- */
-cvox.AbstractEarcons.prototype.earconsAvailable = function() {
- return true;
-};
-
-
-/**
- * Toggles earcons on or off.
- * @return {boolean} True if earcons are now enabled; false otherwise.
- */
-cvox.AbstractEarcons.prototype.toggle = function() {
- this.enabled = !this.enabled;
- return this.enabled;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_host.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_host.js
deleted file mode 100644
index c4e1e2fcf1f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_host.js
+++ /dev/null
@@ -1,165 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Abstract interface to methods that differ depending on the
- * host platform.
- *
- */
-
-goog.provide('cvox.AbstractHost');
-
-
-/**
- * @constructor
- */
-cvox.AbstractHost = function() {
-};
-
-
-/**
- * @enum {number}
- */
-cvox.AbstractHost.State = {
- ACTIVE: 0,
- INACTIVE: 1,
- KILLED: 2
-};
-
-
-/**
- * Do all host-platform-specific initialization.
- */
-cvox.AbstractHost.prototype.init = function() {
-};
-
-
-/**
- * Used to reinitialize ChromeVox if initialization fails.
- */
-cvox.AbstractHost.prototype.reinit = function() {
-};
-
-
-/**
- * Executed on page load.
- */
-cvox.AbstractHost.prototype.onPageLoad = function() {
-};
-
-
-/**
- * Sends a message to the background page (if it exists) for this host.
- * @param {Object} message The message to pass to the background page.
- */
-cvox.AbstractHost.prototype.sendToBackgroundPage = function(message) {
-};
-
-
-/**
- * Returns the absolute URL to the API source.
- * @return {string} The URL.
- */
-cvox.AbstractHost.prototype.getApiSrc = function() {
- return '';
-};
-
-
-/**
- * Return the absolute URL to the given file.
- * @param {string} path The URL suffix.
- * @return {string} The full URL.
- */
-cvox.AbstractHost.prototype.getFileSrc = function(path) {
- return '';
-};
-
-
-/**
- * @return {boolean} True if the host has a Tts callback.
- */
-cvox.AbstractHost.prototype.hasTtsCallback = function() {
- return true;
-};
-
-
-/**
- * @return {boolean} True if the TTS has been loaded.
- */
-cvox.AbstractHost.prototype.ttsLoaded = function() {
- return true;
-};
-
-
-/**
- * @return {boolean} True if the ChromeVox is supposed to intercept and handle
- * mouse clicks for the platform, instead of just letting the clicks fall
- * through.
- *
- * Note: This behavior is only needed for Android because of the way touch
- * exploration and double-tap to click is implemented by the platform.
- */
-cvox.AbstractHost.prototype.mustRedispatchClickEvent = function() {
- return false;
-};
-
-/**
- * Activate or deactivate ChromeVox on this host.
- * @param {boolean} active The desired state; true for active, false for
- * inactive.
- */
-cvox.AbstractHost.prototype.activateOrDeactivateChromeVox = function(active) {
- this.onStateChanged_(active ? cvox.AbstractHost.State.ACTIVE :
- cvox.AbstractHost.State.INACTIVE);
-};
-
-
-/**
- * Kills ChromeVox on this host.
- */
-cvox.AbstractHost.prototype.killChromeVox = function() {
- this.onStateChanged_(cvox.AbstractHost.State.KILLED);
-};
-
-
-/**
- * Helper managing the three states of ChromeVox --
- * active: all event listeners registered
- * inactive: only key down listener registered
- * killed: no listeners registered
- * @param {cvox.AbstractHost.State} state The new state.
- * @private
- */
-cvox.AbstractHost.prototype.onStateChanged_ = function(state) {
- var active = state == cvox.AbstractHost.State.ACTIVE;
- if (active == cvox.ChromeVox.isActive) {
- return;
- }
- cvox.ChromeVoxEventWatcher.cleanup(window);
- switch (state) {
- case cvox.AbstractHost.State.ACTIVE:
- cvox.ChromeVox.isActive = true;
- cvox.ChromeVox.navigationManager.showOrHideIndicator(true);
- cvox.ChromeVoxEventWatcher.init(window);
- if (document.activeElement) {
- var speakNodeAlso = cvox.ChromeVox.documentHasFocus();
- cvox.ApiImplementation.syncToNode(
- document.activeElement, speakNodeAlso);
- } else {
- cvox.ChromeVox.navigationManager.updateIndicator();
- }
- break;
- case cvox.AbstractHost.State.INACTIVE:
- cvox.ChromeVox.isActive = false;
- cvox.ChromeVox.navigationManager.showOrHideIndicator(false);
- // If ChromeVox is inactive, the event watcher will only listen for key
- // down events.
- cvox.ChromeVoxEventWatcher.init(window);
- break;
- case cvox.AbstractHost.State.KILLED:
- cvox.ChromeVox.isActive = false;
- cvox.ChromeVox.navigationManager.showOrHideIndicator(false);
- break;
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_mathjax.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_mathjax.js
deleted file mode 100644
index ce19c05618d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_mathjax.js
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Implentation of ChromeVox's bridge to MathJax.
- *
- */
-
-goog.provide('cvox.AbstractMathJax');
-
-goog.require('cvox.MathJaxInterface');
-
-
-/**
- * Creates a new instance.
- * @constructor
- * @implements {cvox.MathJaxInterface}
- */
-cvox.AbstractMathJax = function() {
-};
-
-
-/**
- * @override
- */
-cvox.AbstractMathJax.prototype.isMathjaxActive = goog.abstractMethod;
-
-
-/**
- * @override
- */
-cvox.AbstractMathJax.prototype.getAllJax = goog.abstractMethod;
-
-
-/**
- * @override
- */
-cvox.AbstractMathJax.prototype.registerSignal = goog.abstractMethod;
-
-
-/**
- * @override
- */
-cvox.AbstractMathJax.prototype.getTex = goog.abstractMethod;
-
-
-/**
- * @override
- */
-cvox.AbstractMathJax.prototype.getAsciiMath = goog.abstractMethod;
-
-
-/**
- * @override
- */
-cvox.AbstractMathJax.prototype.injectScripts = goog.abstractMethod;
-
-
-/**
- * @override
- */
-cvox.AbstractMathJax.prototype.configMediaWiki = goog.abstractMethod;
-
-
-/**
- * Get MathML represententations for all images that have latex alt text.
- * @param {function(Node, string)} callback A function taking a MathML node and
- * an id string.
- */
-cvox.AbstractMathJax.prototype.getAllTexs = function(callback) {
- var allTexs = document.
- querySelectorAll(cvox.DomUtil.altMathQuerySelector('tex'));
- for (var i = 0, tex; tex = allTexs[i]; i++) {
- this.getTex(callback, tex);
- }
-};
-
-
-/**
- * Get MathML represententations for all images that have asciimath alt text.
- * @param {function(Node, string)} callback A function taking a MathML node and
- * an id string.
- */
-cvox.AbstractMathJax.prototype.getAllAsciiMaths = function(callback) {
- var allAsciiMaths = document.
- querySelectorAll(cvox.DomUtil.altMathQuerySelector('asciimath'));
- for (var i = 0, tex; tex = allAsciiMaths[i]; i++) {
- this.getAsciiMath(callback, tex);
- }
-};
-
-
-/**
- * Converts a XML markup string to a DOM node and applies a callback function.
- * The function is generally used in the context of retrieving a MathJax
- * element's MathML representation and converting it from a string. The callback
- * is therefore use by MathJax internally in case the requested MathML
- * representation is not ready yet.
- * @param {function(Node, string)} callback A function taking a node and an id
- * string.
- * @param {string} mml The MathML string.
- * @param {string} id The Mathjax node id.
- */
-cvox.AbstractMathJax.prototype.convertMarkupToDom = function(
- callback, mml, id) {
- if (mml) {
- var dp = new DOMParser;
- var cleanMml = mml.replace(/>\s+</g, '><');
- callback(dp.parseFromString(cleanMml, 'text/xml').firstChild, id);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_tts.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_tts.js
deleted file mode 100644
index 5e31345c5b6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/abstract_tts.js
+++ /dev/null
@@ -1,567 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Base class for Text-to-Speech engines that actually transform
- * text to speech.
- *
- */
-
-goog.provide('cvox.AbstractTts');
-
-goog.require('Msgs');
-goog.require('cvox.TtsInterface');
-goog.require('goog.i18n.MessageFormat');
-
-/**
- * Creates a new instance.
- * @constructor
- * @implements {cvox.TtsInterface}
- */
-cvox.AbstractTts = function() {
- this.ttsProperties = new Object();
-
- /**
- * Default value for TTS properties.
- * Note that these as well as the subsequent properties might be different
- * on different host platforms (like Chrome, Android, etc.).
- * @type {{pitch : number,
- * rate: number,
- * volume: number}}
- * @protected
- */
- this.propertyDefault = {
- 'rate': 0.5,
- 'pitch': 0.5,
- 'volume': 0.5
- };
-
- /**
- * Min value for TTS properties.
- * @type {{pitch : number,
- * rate: number,
- * volume: number}}
- * @protected
- */
- this.propertyMin = {
- 'rate': 0.0,
- 'pitch': 0.0,
- 'volume': 0.0
- };
-
- /**
- * Max value for TTS properties.
- * @type {{pitch : number,
- * rate: number,
- * volume: number}}
- * @protected
- */
- this.propertyMax = {
- 'rate': 1.0,
- 'pitch': 1.0,
- 'volume': 1.0
- };
-
- /**
- * Step value for TTS properties.
- * @type {{pitch : number,
- * rate: number,
- * volume: number}}
- * @protected
- */
- this.propertyStep = {
- 'rate': 0.1,
- 'pitch': 0.1,
- 'volume': 0.1
- };
-
-
- /** @private */
-
- if (cvox.AbstractTts.pronunciationDictionaryRegexp_ == undefined) {
- // Create an expression that matches all words in the pronunciation
- // dictionary on word boundaries, ignoring case.
- var words = [];
- for (var word in cvox.AbstractTts.PRONUNCIATION_DICTIONARY) {
- words.push(word);
- }
- var expr = '\\b(' + words.join('|') + ')\\b';
- cvox.AbstractTts.pronunciationDictionaryRegexp_ = new RegExp(expr, 'ig');
- }
-
- if (cvox.AbstractTts.substitutionDictionaryRegexp_ == undefined) {
- // Create an expression that matches all words in the substitution
- // dictionary.
- var symbols = [];
- for (var symbol in cvox.AbstractTts.SUBSTITUTION_DICTIONARY) {
- symbols.push(symbol);
- }
- var expr = '(' + symbols.join('|') + ')';
- cvox.AbstractTts.substitutionDictionaryRegexp_ = new RegExp(expr, 'ig');
- }
-};
-
-
-/**
- * Default TTS properties for this TTS engine.
- * @type {Object}
- * @protected
- */
-cvox.AbstractTts.prototype.ttsProperties;
-
-
-/** @override */
-cvox.AbstractTts.prototype.speak = function(textString, queueMode, properties) {
- return this;
-};
-
-
-/** @override */
-cvox.AbstractTts.prototype.isSpeaking = function() {
- return false;
-};
-
-
-/** @override */
-cvox.AbstractTts.prototype.stop = function() {
-};
-
-
-/** @override */
-cvox.AbstractTts.prototype.addCapturingEventListener = function(listener) { };
-
-
-/** @override */
-cvox.AbstractTts.prototype.increaseOrDecreaseProperty =
- function(propertyName, increase) {
- var min = this.propertyMin[propertyName];
- var max = this.propertyMax[propertyName];
- var step = this.propertyStep[propertyName];
- var current = this.ttsProperties[propertyName];
- current = increase ? current + step : current - step;
- this.ttsProperties[propertyName] = Math.max(Math.min(current, max), min);
- };
-
-
-/**
- * Merges the given properties with the default ones. Always returns a
- * new object, so that you can safely modify the result of mergeProperties
- * without worrying that you're modifying an object used elsewhere.
- * @param {Object=} properties The properties to merge with the current ones.
- * @return {Object} The merged properties.
- * @protected
- */
-cvox.AbstractTts.prototype.mergeProperties = function(properties) {
- var mergedProperties = new Object();
- var p;
- if (this.ttsProperties) {
- for (p in this.ttsProperties) {
- mergedProperties[p] = this.ttsProperties[p];
- }
- }
- if (properties) {
- var tts = cvox.AbstractTts;
- if (typeof(properties[tts.VOLUME]) == 'number') {
- mergedProperties[tts.VOLUME] = properties[tts.VOLUME];
- }
- if (typeof(properties[tts.PITCH]) == 'number') {
- mergedProperties[tts.PITCH] = properties[tts.PITCH];
- }
- if (typeof(properties[tts.RATE]) == 'number') {
- mergedProperties[tts.RATE] = properties[tts.RATE];
- }
- if (typeof(properties[tts.LANG]) == 'string') {
- mergedProperties[tts.LANG] = properties[tts.LANG];
- }
-
- var context = this;
- var mergeRelativeProperty = function(abs, rel) {
- if (typeof(properties[rel]) == 'number' &&
- typeof(mergedProperties[abs]) == 'number') {
- mergedProperties[abs] += properties[rel];
- var min = context.propertyMin[abs];
- var max = context.propertyMax[abs];
- if (mergedProperties[abs] > max) {
- mergedProperties[abs] = max;
- } else if (mergedProperties[abs] < min) {
- mergedProperties[abs] = min;
- }
- }
- };
-
- mergeRelativeProperty(tts.VOLUME, tts.RELATIVE_VOLUME);
- mergeRelativeProperty(tts.PITCH, tts.RELATIVE_PITCH);
- mergeRelativeProperty(tts.RATE, tts.RELATIVE_RATE);
- }
-
- for (p in properties) {
- if (!mergedProperties.hasOwnProperty(p)) {
- mergedProperties[p] = properties[p];
- }
- }
-
- return mergedProperties;
-};
-
-
-/**
- * Method to preprocess text to be spoken properly by a speech
- * engine.
- *
- * 1. Replace any single character with a description of that character.
- *
- * 2. Convert all-caps words to lowercase if they don't look like an
- * acronym / abbreviation.
- *
- * @param {string} text A text string to be spoken.
- * @param {Object= } properties Out parameter populated with how to speak the
- * string.
- * @return {string} The text formatted in a way that will sound better by
- * most speech engines.
- * @protected
- */
-cvox.AbstractTts.prototype.preprocess = function(text, properties) {
- if (text.length == 1 && text >= 'A' && text <= 'Z') {
- for (var prop in cvox.AbstractTts.PERSONALITY_CAPITAL)
- properties[prop] = cvox.AbstractTts.PERSONALITY_CAPITAL[prop];
- }
-
- // Substitute all symbols in the substitution dictionary. This is pretty
- // efficient because we use a single regexp that matches all symbols
- // simultaneously.
- text = text.replace(
- cvox.AbstractTts.substitutionDictionaryRegexp_,
- function(symbol) {
- return ' ' + cvox.AbstractTts.SUBSTITUTION_DICTIONARY[symbol] + ' ';
- });
-
- // Handle single characters that we want to make sure we pronounce.
- if (text.length == 1) {
- return cvox.AbstractTts.CHARACTER_DICTIONARY[text] ?
- (new goog.i18n.MessageFormat(Msgs.getMsg(
- cvox.AbstractTts.CHARACTER_DICTIONARY[text])))
- .format({'COUNT': 1}) :
- text.toUpperCase();
- }
-
- // Substitute all words in the pronunciation dictionary. This is pretty
- // efficient because we use a single regexp that matches all words
- // simultaneously, and it calls a function with each match, which we can
- // use to look up the replacement in our dictionary.
- text = text.replace(
- cvox.AbstractTts.pronunciationDictionaryRegexp_,
- function(word) {
- return cvox.AbstractTts.PRONUNCIATION_DICTIONARY[word.toLowerCase()];
- });
-
- // Expand all repeated characters.
- text = text.replace(
- cvox.AbstractTts.repetitionRegexp_, cvox.AbstractTts.repetitionReplace_);
-
- return text;
-};
-
-
-/** TTS rate property. @type {string} */
-cvox.AbstractTts.RATE = 'rate';
-/** TTS pitch property. @type {string} */
-cvox.AbstractTts.PITCH = 'pitch';
-/** TTS volume property. @type {string} */
-cvox.AbstractTts.VOLUME = 'volume';
-/** TTS language property. @type {string} */
-cvox.AbstractTts.LANG = 'lang';
-
-/** TTS relative rate property. @type {string} */
-cvox.AbstractTts.RELATIVE_RATE = 'relativeRate';
-/** TTS relative pitch property. @type {string} */
-cvox.AbstractTts.RELATIVE_PITCH = 'relativePitch';
-/** TTS relative volume property. @type {string} */
-cvox.AbstractTts.RELATIVE_VOLUME = 'relativeVolume';
-
-/** TTS color property (for the lens display). @type {string} */
-cvox.AbstractTts.COLOR = 'color';
-/** TTS CSS font-weight property (for the lens display). @type {string} */
-cvox.AbstractTts.FONT_WEIGHT = 'fontWeight';
-
-/** TTS punctuation-echo property. @type {string} */
-cvox.AbstractTts.PUNCTUATION_ECHO = 'punctuationEcho';
-
-/** TTS pause property. @type {string} */
-cvox.AbstractTts.PAUSE = 'pause';
-
-/**
- * TTS personality for annotations - text spoken by ChromeVox that
- * elaborates on a user interface element but isn't displayed on-screen.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_ANNOTATION = {
- 'relativePitch': -0.25,
- // TODO:(rshearer) Added this color change for I/O presentation.
- 'color': 'yellow',
- 'punctuationEcho': 'none'
-};
-
-
-/**
- * TTS personality for announcements - text spoken by ChromeVox that
- * isn't tied to any user interface elements.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT = {
- 'punctuationEcho': 'none'
-};
-
-/**
- * TTS personality for alerts from the system, such as battery level
- * warnings.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_SYSTEM_ALERT = {
- 'punctuationEcho': 'none',
- 'doNotInterrupt': true
-};
-
-/**
- * TTS personality for an aside - text in parentheses.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_ASIDE = {
- 'relativePitch': -0.1,
- 'color': '#669'
-};
-
-
-/**
- * TTS personality for capital letters.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_CAPITAL = {
- 'relativePitch': 0.6
-};
-
-
-/**
- * TTS personality for deleted text.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_DELETED = {
- 'punctuationEcho': 'none',
- 'relativePitch': -0.6
-};
-
-
-/**
- * TTS personality for quoted text.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_QUOTE = {
- 'relativePitch': 0.1,
- 'color': '#b6b',
- 'fontWeight': 'bold'
-};
-
-
-/**
- * TTS personality for strong or bold text.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_STRONG = {
- 'relativePitch': 0.1,
- 'color': '#b66',
- 'fontWeight': 'bold'
-};
-
-
-/**
- * TTS personality for emphasis or italicized text.
- * @type {Object}
- */
-cvox.AbstractTts.PERSONALITY_EMPHASIS = {
- 'relativeVolume': 0.1,
- 'relativeRate': -0.1,
- 'color': '#6bb',
- 'fontWeight': 'bold'
-};
-
-
-/**
- * Flag indicating if the TTS is being debugged.
- * @type {boolean}
- */
-cvox.AbstractTts.DEBUG = true;
-
-
-/**
- * Character dictionary. These symbols are replaced with their human readable
- * equivalents. This replacement only occurs for single character utterances.
- * @type {Object<string>}
- */
-cvox.AbstractTts.CHARACTER_DICTIONARY = {
- ' ': 'space',
- '`': 'backtick',
- '~': 'tilde',
- '!': 'exclamation',
- '@': 'at',
- '#': 'pound',
- '$': 'dollar',
- '%': 'percent',
- '^': 'caret',
- '&': 'ampersand',
- '*': 'asterisk',
- '(': 'open_paren',
- ')': 'close_paren',
- '-': 'dash',
- '_': 'underscore',
- '=': 'equals',
- '+': 'plus',
- '[': 'left_bracket',
- ']': 'right_bracket',
- '{': 'left_brace',
- '}': 'right_brace',
- '|': 'pipe',
- ';': 'semicolon',
- ':': 'colon',
- ',': 'comma',
- '.': 'dot',
- '<': 'less_than',
- '>': 'greater_than',
- '/': 'slash',
- '?': 'question_mark',
- '"': 'quote',
- '\'': 'apostrophe',
- '\t': 'tab',
- '\r': 'return',
- '\n': 'new_line',
- '\\': 'backslash'
-};
-
-
-/**
- * Pronunciation dictionary. Each key must be lowercase, its replacement
- * should be spelled out the way most TTS engines will pronounce it
- * correctly. This particular dictionary only handles letters and numbers,
- * no symbols.
- * @type {Object<string>}
- */
-cvox.AbstractTts.PRONUNCIATION_DICTIONARY = {
- 'admob': 'ad-mob',
- 'adsense': 'ad-sense',
- 'adwords': 'ad-words',
- 'angularjs': 'angular j s',
- 'bcc': 'B C C',
- 'cc': 'C C',
- 'chromevox': 'chrome vox',
- 'cr48': 'C R 48',
- 'ctrl': 'control',
- 'doubleclick': 'double-click',
- 'gmail': 'gee mail',
- 'gtalk': 'gee talk',
- 'http': 'H T T P',
- 'https' : 'H T T P S',
- 'igoogle': 'eye google',
- 'pagerank': 'page-rank',
- 'username': 'user-name',
- 'www': 'W W W',
- 'youtube': 'you tube'
-};
-
-
-/**
- * Pronunciation dictionary regexp.
- * @type {RegExp};
- * @private
- */
-cvox.AbstractTts.pronunciationDictionaryRegexp_;
-
-
-/**
- * Substitution dictionary. These symbols or patterns are ALWAYS substituted
- * whenever they occur, so this should be reserved only for unicode characters
- * and characters that never have any different meaning in context.
- *
- * For example, do not include '$' here because $2 should be read as
- * "two dollars".
- * @type {Object<string>}
- */
-cvox.AbstractTts.SUBSTITUTION_DICTIONARY = {
- '://': 'colon slash slash',
- '\u00bc': 'one fourth',
- '\u00bd': 'one half',
- '\u2190': 'left arrow',
- '\u2191': 'up arrow',
- '\u2192': 'right arrow',
- '\u2193': 'down arrow',
- '\u21d0': 'left double arrow',
- '\u21d1': 'up double arrow',
- '\u21d2': 'right double arrow',
- '\u21d3': 'down double arrow',
- '\u21e6': 'left arrow',
- '\u21e7': 'up arrow',
- '\u21e8': 'right arrow',
- '\u21e9': 'down arrow',
- '\u2303': 'control',
- '\u2318': 'command',
- '\u2325': 'option',
- '\u25b2': 'up triangle',
- '\u25b3': 'up triangle',
- '\u25b4': 'up triangle',
- '\u25b5': 'up triangle',
- '\u25b6': 'right triangle',
- '\u25b7': 'right triangle',
- '\u25b8': 'right triangle',
- '\u25b9': 'right triangle',
- '\u25ba': 'right pointer',
- '\u25bb': 'right pointer',
- '\u25bc': 'down triangle',
- '\u25bd': 'down triangle',
- '\u25be': 'down triangle',
- '\u25bf': 'down triangle',
- '\u25c0': 'left triangle',
- '\u25c1': 'left triangle',
- '\u25c2': 'left triangle',
- '\u25c3': 'left triangle',
- '\u25c4': 'left pointer',
- '\u25c5': 'left pointer',
- '\uf8ff': 'apple'
-};
-
-
-/**
- * Substitution dictionary regexp.
- * @type {RegExp};
- * @private
- */
-cvox.AbstractTts.substitutionDictionaryRegexp_;
-
-
-/**
- * repetition filter regexp.
- * @type {RegExp}
- * @private
- */
-cvox.AbstractTts.repetitionRegexp_ =
- /([-\/\\|!@#$%^&*\(\)=_+\[\]\{\}.?;'":<>])\1{2,}/g;
-
-
-/**
- * Constructs a description of a repeated character. Use as a param to
- * string.replace.
- * @param {string} match The matching string.
- * @return {string} The description.
- * @private
- */
-cvox.AbstractTts.repetitionReplace_ = function(match) {
- var count = match.length;
- return ' ' + (new goog.i18n.MessageFormat(Msgs.getMsg(
- cvox.AbstractTts.CHARACTER_DICTIONARY[match[0]])))
- .format({'COUNT': count}) + ' ';
-};
-
-
-/**
- * @override
- */
-cvox.AbstractTts.prototype.getDefaultProperty = function(property) {
- return this.propertyDefault[property];
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/braille_interface.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/braille_interface.js
deleted file mode 100644
index 9ecba7216a7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/braille_interface.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Defines a Braille interface.
- *
- * All Braille engines in ChromeVox conform to this interface.
- *
- */
-
-goog.provide('cvox.BrailleInterface');
-
-goog.require('cvox.BrailleKeyCommand');
-goog.require('cvox.BrailleKeyEvent');
-goog.require('cvox.NavBraille');
-
-/**
- * @interface
- */
-cvox.BrailleInterface = function() { };
-
-/**
- * Sends the given params to the Braille display for output.
- * @param {!cvox.NavBraille} params Parameters to send to the
- * platform braille service.
- */
-cvox.BrailleInterface.prototype.write =
- function(params) { };
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/host_factory.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/host_factory.js
deleted file mode 100644
index d1ce963d092..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/host_factory.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview A host factory. This factory allows us to decouple the
- * cvox.Host|Tts|... creatation from the main ChromeVox code.
- */
-
-goog.provide('cvox.HostFactory');
-
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.AbstractHost');
-goog.require('cvox.AbstractMathJax');
-goog.require('cvox.AbstractTts');
-
-
-/**
- * @constructor
- */
-cvox.HostFactory = function() {};
-
-/**
- * Returns the host.
- * @return {cvox.AbstractHost}
- */
-cvox.HostFactory.getHost = function() {
- return new cvox.HostFactory.hostConstructor;
-};
-
-/**
- * Returns the TTS interface.
- * @return {cvox.TtsInterface} The TTS engine.
- */
-cvox.HostFactory.getTts = function() {
- return new cvox.HostFactory.ttsConstructor;
-};
-
-/**
- * Returns the Braille interface.
- * @return {cvox.BrailleInterface} The Braille interface.
- */
-cvox.HostFactory.getBraille = function() {
- return new cvox.HostFactory.brailleConstructor;
-};
-
-/**
- * Returns the earcons interface.
- * @return {cvox.AbstractEarcons}
- */
-cvox.HostFactory.getEarcons = function() {
- return new cvox.HostFactory.earconsConstructor;
-};
-
-/**
- * Returns the MathJax interface.
- * @return {cvox.MathJaxInterface} The MathJax interface.
- */
-cvox.HostFactory.getMathJax = function() {
- return new cvox.HostFactory.mathJaxConstructor;
-};
-
-/**
- * @type {function (new:cvox.AbstractHost)}
- */
-cvox.HostFactory.hostConstructor;
-
-/**
- * @type {function (new:cvox.TtsInterface)}
- */
-cvox.HostFactory.ttsConstructor;
-
-/**
- * @type {function (new:cvox.BrailleInterface)}
- */
-cvox.HostFactory.brailleConstructor;
-
-/**
- * @type {function (new:cvox.AbstractEarcons)}
- */
-cvox.HostFactory.earconsConstructor;
-
-
-/**
- * @type {function (new:cvox.AbstractMathJax)}
- */
-cvox.HostFactory.mathJaxConstructor;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/mathjax_interface.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/mathjax_interface.js
deleted file mode 100644
index f15b2d79874..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/mathjax_interface.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Interface of ChromeVox's bridge to MathJax.
- *
- */
-
-goog.provide('cvox.MathJaxInterface');
-
-
-/**
- * @interface
- */
-cvox.MathJaxInterface = function() { };
-
-
-/**
- * True if MathJax is injected in a page.
- * @param {function(boolean)} callback A function with the active status as
- * argument.
- */
-cvox.MathJaxInterface.prototype.isMathjaxActive = function(callback) { };
-
-
-/**
- * Get MathML for all MathJax nodes that already exist by applying the callback
- * to every single MathJax node.
- * @param {function(Node, string)} callback A function taking a node and an id
- * string.
- */
-cvox.MathJaxInterface.prototype.getAllJax = function(callback) { };
-
-
-/**
- * Registers a persistent callback function to be executed by Mathjax on the
- * given signal.
- * @param {function(Node, string)} callback A function taking a node and an id
- * string.
- * @param {string} signal The Mathjax signal to fire the callback.
- */
-cvox.MathJaxInterface.prototype.registerSignal = function(callback, signal) { };
-
-
-/**
- * Injects some minimalistic MathJax script into the page to translate LaTeX
- * expressions.
- */
-cvox.MathJaxInterface.prototype.injectScripts = function() { };
-
-
-/**
- * Loads configurations for MediaWiki pages (e.g., Wikipedia).
- */
-cvox.MathJaxInterface.prototype.configMediaWiki = function() { };
-
-
-/**
- * Get MathML representation of images with tex or latex class if it has an
- * alt text or title.
- * @param {function(Node, string)} callback A function taking a MathML node and
- * an id string.
- * @param {Node} texNode Node with img tag and tex or latex class.
- */
-cvox.MathJaxInterface.prototype.getTex = function(callback, texNode) { };
-
-
-/**
- * Get MathML representation of images that have asciiMath in alt text.
- * @param {function(Node, string)} callback A function taking a MathML node and
- * an id string.
- * @param {Node} asciiMathNode Node with img tag and class of numberedequation,
- * inlineformula, or displayformula.
- */
-cvox.MathJaxInterface.prototype.getAsciiMath = function(
- callback, asciiMathNode) { };
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/tts_interface.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/tts_interface.js
deleted file mode 100644
index 9a1b63de5db..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/interface/tts_interface.js
+++ /dev/null
@@ -1,117 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Defines a Tts interface.
- *
- * All TTS engines in ChromeVox conform to the this interface.
- *
- */
-
-goog.provide('cvox.QueueMode');
-goog.provide('cvox.TtsCapturingEventListener');
-goog.provide('cvox.TtsCategory');
-goog.provide('cvox.TtsInterface');
-
-/**
- * Categories for a speech utterance. This can be used with the
- * CATEGORY_FLUSH queue mode, which flushes all utterances from a given
- * category but not other utterances.
- *
- * NAV: speech related to explicit navigation, or focus changing.
- * LIVE: speech coming from changes to live regions.
- *
- * @enum {string}
- */
-cvox.TtsCategory = {
- LIVE: 'live',
- NAV: 'nav'
-};
-
-/**
- * Queue modes for calls to {@code cvox.TtsInterface.speak}.
- * @enum
- */
-cvox.QueueMode = {
- /** Stop speech, clear everything, then speak this utterance. */
- FLUSH: 0,
-
- /** Append this utterance to the end of the queue. */
- QUEUE: 1,
-
- /**
- * Clear any utterances of the same category (as set by
- * properties['category']) from the queue, then enqueue this utterance.
- */
- CATEGORY_FLUSH: 2
-};
-
-/**
- * @interface
- * An interface for clients who want to get notified when an utterance
- * starts or ends from any source.
- */
-cvox.TtsCapturingEventListener = function() { };
-
-/**
- * Called when any utterance starts.
- */
-cvox.TtsCapturingEventListener.prototype.onTtsStart = function() { };
-
-/**
- * Called when any utterance ends.
- */
-cvox.TtsCapturingEventListener.prototype.onTtsEnd = function() { };
-
-
-/**
- * @interface
- */
-cvox.TtsInterface = function() { };
-
-/**
- * Speaks the given string using the specified queueMode and properties.
- * @param {string} textString The string of text to be spoken.
- * @param {cvox.QueueMode} queueMode The queue mode to use for speaking.
- * @param {Object=} properties Speech properties to use for this utterance.
- * @return {cvox.TtsInterface} A tts object useful for chaining speak calls.
- */
-cvox.TtsInterface.prototype.speak =
- function(textString, queueMode, properties) { };
-
-
-/**
- * Returns true if the TTS is currently speaking.
- * @return {boolean} True if the TTS is speaking.
- */
-cvox.TtsInterface.prototype.isSpeaking = function() { };
-
-
-/**
- * Stops speech.
- */
-cvox.TtsInterface.prototype.stop = function() { };
-
-/**
- * Adds a listener to get called whenever any utterance starts or ends.
- * @param {cvox.TtsCapturingEventListener} listener Listener to get called.
- */
-cvox.TtsInterface.prototype.addCapturingEventListener = function(listener) { };
-
-/**
- * Increases a TTS speech property.
- * @param {string} propertyName The name of the property to change.
- * @param {boolean} increase If true, increases the property value by one
- * step size, otherwise decreases.
- */
-cvox.TtsInterface.prototype.increaseOrDecreaseProperty =
- function(propertyName, increase) { };
-
-
-/**
- * Returns the default properties of the first tts that has default properties.
- * @param {string} property Name of property.
- * @return {?number} The default value.
- */
-cvox.TtsInterface.prototype.getDefaultProperty = function(property) { };
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/earcons.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/earcons.js
deleted file mode 100644
index c2a2658c3f6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/earcons.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Dummy earcons implementation for testing.
- *
- */
-
-goog.provide('cvox.TestEarcons');
-
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.HostFactory');
-
-/**
- * @constructor
- * @extends {cvox.AbstractEarcons}
- */
-cvox.TestEarcons = function() {
- cvox.Earcon.call(this);
-};
-goog.inherits(cvox.TestEarcons, cvox.AbstractEarcons);
-
-/** @override */
-cvox.HostFactory.earconsConstructor = cvox.TestEarcons;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/host.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/host.js
deleted file mode 100644
index 84ea9b1d597..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/host.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Dummy implementation of host.js for testing.
- *
- */
-
-goog.provide('cvox.TestHost');
-
-goog.require('cvox.AbstractHost');
-goog.require('cvox.HostFactory');
-
-/**
- * @constructor
- * @extends {cvox.AbstractHost}
- */
-cvox.TestHost = function() {
- cvox.AbstractHost.call(this);
-};
-goog.inherits(cvox.TestHost, cvox.AbstractHost);
-
-/** @override */
-cvox.HostFactory.hostConstructor = cvox.TestHost;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/mathjax.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/mathjax.js
deleted file mode 100644
index 2f9e329284e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/mathjax.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Testing stub for MathJax.
- *
- */
-
-goog.provide('cvox.TestMathJax');
-
-goog.require('cvox.AbstractMathJax');
-goog.require('cvox.HostFactory');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractMathJax}
- */
-cvox.TestMathJax = function() {
- goog.base(this);
-};
-goog.inherits(cvox.TestMathJax, cvox.AbstractMathJax);
-
-
-/**
- * @override
- */
-cvox.TestMathJax.prototype.isMathjaxActive = function(callback) { };
-
-
-/**
- * @override
- */
-cvox.TestMathJax.prototype.getAllJax = function(callback) { };
-
-
-/**
- * @override
- */
-cvox.TestMathJax.prototype.registerSignal = function(
- callback, signal) { };
-
-
-/**
- * @override
- */
-cvox.TestMathJax.prototype.injectScripts = function() { };
-
-
-/**
- * @override
- */
-cvox.TestMathJax.prototype.configMediaWiki = function() { };
-
-
-/**
- * @override
- */
-cvox.TestMathJax.prototype.getTex = function(callback, texNode) { };
-
-
-/**
- * @override
- */
-cvox.TestMathJax.prototype.getAsciiMath = function(callback, asciiMathNode) { };
-
-
-/** Export platform constructor. */
-cvox.HostFactory.mathJaxConstructor =
- cvox.TestMathJax;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/tts.js b/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/tts.js
deleted file mode 100644
index 168769bde6c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/host/testing/tts.js
+++ /dev/null
@@ -1,143 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Dummy implementation of TTS for testing.
- *
- */
-
-goog.provide('cvox.TestTts');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.DomUtil');
-goog.require('cvox.HostFactory');
-
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractTts}
- */
-cvox.TestTts = function() {
- cvox.AbstractTts.call(this);
- this.utterances_ = [];
-};
-goog.inherits(cvox.TestTts, cvox.AbstractTts);
-
-
-/**
- * @type {string}
- * @private
- */
-cvox.TestTts.prototype.sentinelText_ = '@@@STOP@@@';
-
-
-/**
- * @override
- */
-cvox.TestTts.prototype.speak = function(text, queueMode, opt_properties) {
- this.utterances_.push({text: text,
- queueMode: queueMode,
- properties: opt_properties});
- if (opt_properties && opt_properties['endCallback'] != undefined) {
- var len = this.utterances_.length;
- // 'After' is a sentinel value in the tests that tells TTS to stop and
- // ends callbacks being called.
- if (this.utterances_[len - 1].text !=
- this.sentinelText_) {
- opt_properties['endCallback']();
- }
- }
-};
-
-
-/**
- * Creates a sentinel element that indicates when TTS should stop and callbacks
- * should stop being called.
- * @return {Element} The sentinel element.
- */
-cvox.TestTts.prototype.createSentinel = function() {
- var sentinel = document.createElement('div');
- sentinel.textContent = this.sentinelText_;
- return sentinel;
-};
-
-
-/**
- * All calls to tts.speak are saved in an array of utterances.
- * Clear any utterances that were saved up to this point.
- */
-cvox.TestTts.prototype.clearUtterances = function() {
- this.utterances_.length = 0;
-};
-
-/**
- * Return a string of what was spoken by tts.speak().
- * @return {string} A single string containing all utterances spoken
- * since initialization or the last call to clearUtterances,
- * concatenated together with all whitespace collapsed to single
- * spaces.
- */
-cvox.TestTts.prototype.getUtterancesAsString = function() {
- return cvox.DomUtil.collapseWhitespace(this.getUtteranceList().join(' '));
-};
-
-/**
- * Processes the utterances spoken the same way the speech queue does,
- * as if they were all generated one after another, with no delay between
- * them, and returns a list of strings that would be output.
- *
- * For example, if two strings were spoken with a queue mode of FLUSH,
- * only the second string will be returned.
- * @return {Array<string>} A list of strings representing the speech output.
- */
-cvox.TestTts.prototype.getSpeechQueueOutput = function() {
- var queue = [];
- for (var i = 0; i < this.utterances_.length; i++) {
- var utterance = this.utterances_[i];
- switch (utterance.queueMode) {
- case cvox.AbstractTts.QUEUE_MODE_FLUSH:
- queue = [];
- break;
- case cvox.AbstractTts.QUEUE_MODE_QUEUE:
- break;
- case cvox.AbstractTts.QUEUE_MODE_CATEGORY_FLUSH:
- queue = queue.filter(function(u) {
- return (utterance.properties && utterance.properties.category) &&
- (!u.properties ||
- u.properties.category != utterance.properties.category);
- });
- break;
- }
- queue.push(utterance);
- }
-
- return queue.map(function(u) { return u.text; });
-};
-
-/**
- * Return a list of strings of what was spoken by tts.speak().
- * @return {Array<string>} A list of all utterances spoken since
- * initialization or the last call to clearUtterances.
- */
-cvox.TestTts.prototype.getUtteranceList = function() {
- var result = [];
- for (var i = 0; i < this.utterances_.length; i++) {
- result.push(this.utterances_[i].text);
- }
- return result;
-};
-
-/**
- * Return a list of strings of what was spoken by tts.speak().
- * @return {Array<{text: string, queueMode: cvox.QueueMode}>}
- * A list of info about all utterances spoken since
- * initialization or the last call to clearUtterances.
- */
-cvox.TestTts.prototype.getUtteranceInfoList = function() {
- return this.utterances_;
-};
-
-/** @override */
-cvox.HostFactory.ttsConstructor = cvox.TestTts;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/manifest.json.jinja2 b/chromium/chrome/browser/resources/chromeos/chromevox/manifest.json.jinja2
deleted file mode 100644
index d429e4318c7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/manifest.json.jinja2
+++ /dev/null
@@ -1,297 +0,0 @@
-{
-{%if key is defined %}
- "key": "{{key}}",
-{% endif %}
- "manifest_version": 2,
- "name": "__MSG_CHROMEVOX_NAME__",
- "version": "{{set_version}}",
- "description": "__MSG_CHROMEVOX_DESCRIPTION__",
-{% if is_guest_manifest == '1' %}
- "incognito": "split",
-{% endif %}
- "background": {
- "page": "cvox2/background/background.html"
- },
- "permissions": [
- "accessibilityPrivate",
- "bookmarks",
- "brailleDisplayPrivate",
- "commands.accessibility",
- "commandLinePrivate",
- "experimental",
- "history",
- "storage",
- "tabs",
- "tts",
- "virtualKeyboardPrivate",
- "<all_urls>"
- ],
- "content_scripts": [
- {
- "matches": [ "<all_urls>" ],
- "exclude_globs": [
- "chrome-extension://mndnfokpggljbaajbnioimlmbfngpief/cvox2/background/background.html"
- ],
- "all_frames": true,
- "js": [
-{% if is_js_compressed == '1' %}
- "chromeVoxChromePageScript.js"
-{% else %}
- "closure/closure_preinit.js",
- "closure/base.js",
- "deps.js",
- "chromevox/injected/loader.js"
-{% endif %}
- ]
- }
- ],
- "web_accessible_resources": [
- "chromevox/injected/api.js",
- "chromevox/injected/api_util.js",
- "chromevox/injected/mathjax.js",
- "chromevox/injected/mathjax_external_util.js"
- ],
- "automation": {
- "desktop": true
- },
- "commands": {
-{% if is_chromevox_classic == '0' %}
- "nextElement": {
- "description": "__MSG_CHROMEVOX_NEXT_OBJECT__",
- "suggested_key": {
- "chromeos": "Search+Right"
- }
- },
- "previousElement": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_OBJECT__",
- "suggested_key": {
- "chromeos": "Search+Left"
- }
- },
- "nextCharacter": {
- "description": "__MSG_CHROMEVOX_NEXT_CHARACTER__",
- "suggested_key": {
- "chromeos": "Search+Shift+Right"
- }
- },
- "previousCharacter": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_CHARACTER__",
- "suggested_key": {
- "chromeos": "Search+Shift+Left"
- }
- },
- "nextWord": {
- "description": "__MSG_CHROMEVOX_NEXT_WORD__",
- "suggested_key": {
- "chromeos": "Search+Ctrl+Shift+Right"
- }
- },
- "previousWord": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_WORD__",
- "suggested_key": {
- "chromeos": "Search+Ctrl+Shift+Left"
- }
- },
- "nextLine": {
- "description": "__MSG_CHROMEVOX_NEXT_LINE__",
- "suggested_key": {
- "chromeos": "Search+Down"
- }
- },
- "previousLine": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_LINE__",
- "suggested_key": {
- "chromeos": "Search+Up"
- }
- },
- "nextButton": {
- "description": "__MSG_CHROMEVOX_NEXT_BUTTON__",
- "suggested_key": {
- "chromeos": "Search+B"
- }
- },
- "previousButton": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_BUTTON__",
- "suggested_key": {
- "chromeos": "Search+Shift+B"
- }
- },
- "nextCheckBox": {
- "description": "__MSG_CHROMEVOX_NEXT_CHECKBOX__",
- "suggested_key": {
- "chromeos": "Search+X"
- }
- },
- "previousCheckBox": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_CHECKBOX__",
- "suggested_key": {
- "chromeos": "Search+Shift+X"
- }
- },
- "nextComboBox": {
- "description": "__MSG_CHROMEVOX_NEXT_COMBO_BOX__",
- "suggested_key": {
- "chromeos": "Search+C"
- }
- },
- "previousComboBox": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_COMBO_BOX__",
- "suggested_key": {
- "chromeos": "Search+Shift+C"
- }
- },
- "nextEditText": {
- "description": "__MSG_CHROMEVOX_NEXT_EDIT_TEXT__",
- "suggested_key": {
- "chromeos": "Search+E"
- }
- },
- "previousEditText": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_EDIT_TEXT__",
- "suggested_key": {
- "chromeos": "Search+Shift+E"
- }
- },
- "nextFormField": {
- "description": "__MSG_CHROMEVOX_NEXT_FORM_FIELD__",
- "suggested_key": {
- "chromeos": "Search+F"
- }
- },
- "previousFormField": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_FORM_FIELD__",
- "suggested_key": {
- "chromeos": "Search+Shift+F"
- }
- },
- "nextHeading": {
- "description": "__MSG_CHROMEVOX_NEXT_HEADING__",
- "suggested_key": {
- "chromeos": "Search+H"
- }
- },
- "previousHeading": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_HEADING__",
- "suggested_key": {
- "chromeos": "Search+Shift+H"
- }
- },
- "compatPreviousLine": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_HEADING__",
- "suggested_key": {
- "chromeos": "Search+Shift+Up"
- }
- },
- "compatNextLine": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_HEADING__",
- "suggested_key": {
- "chromeos": "Search+Shift+Down"
- }
- },
- "sequencePrefixPrevious": {
- "description": "Sequence prefix",
- "suggested_key": {
- "chromeos": "Search+Shift+P"
- }
- },
- "sequencePrefixNext": {
- "description": "Sequence prefix",
- "suggested_key": {
- "chromeos": "Search+Shift+N"
- }
- },
- "nextLink": {
- "description": "__MSG_CHROMEVOX_NEXT_LINK__",
- "suggested_key": {
- "chromeos": "Search+L"
- }
- },
- "previousLink": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_LINK__",
- "suggested_key": {
- "chromeos": "Search+Shift+L"
- }
- },
- "nextTable": {
- "description": "__MSG_CHROMEVOX_NEXT_TABLE__",
- "suggested_key": {
- "chromeos": "Search+T"
- }
- },
- "previousTable": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_TABLE__",
- "suggested_key": {
- "chromeos": "Search+Shift+T"
- }
- },
- "nextVisitedLink": {
- "description": "__MSG_CHROMEVOX_NEXT_VISITED_LINK__",
- "suggested_key": {
- "chromeos": "Search+V"
- }
- },
- "previousVisitedLink": {
- "description": "__MSG_CHROMEVOX_PREVIOUS_VISITED_LINK__",
- "suggested_key": {
- "chromeos": "Search+Shift+V"
- }
- },
- "goToBeginning": {
- "description": "__MSG_CHROMEVOX_JUMP_TO_TOP__",
- "suggested_key": {
- "chromeos": "Search+Ctrl+Left"
- }
- },
- "goToEnd": {
- "description": "__MSG_CHROMEVOX_JUMP_TO_BOTTOM__",
- "suggested_key": {
- "chromeos": "Search+Ctrl+Right"
- }
- },
- "doDefault": {
- "description": "__MSG_CHROMEVOX_PERFORM_DEFAULT_ACTION__",
- "suggested_key": {
- "chromeos": "Search+Space"
- }
- },
- "compatDoDefault": {
- "description": "__MSG_CHROMEVOX_PERFORM_DEFAULT_ACTION__",
- "suggested_key": {
- "chromeos": "Search+Shift+Space"
- }
- },
- "toggleChromeVoxVersion": {
- "description": "__MSG_CHROMEVOX_TOGGLE_CHROMEVOX__",
- "suggested_key": {
- "chromeos": "Search+Ctrl+Q"
- }
- },
- "continuousRead": {
- "description": "__MSG_CHROMEVOX_READ_FROM_HERE__",
- "suggested_key": {
- "chromeos": "Search+R"
- }
- },
- "compatContinuousRead": {
- "description": "__MSG_CHROMEVOX_READ_FROM_HERE__",
- "suggested_key": {
- "chromeos": "Search+Shift+R"
- }
- },
- "sequencePrefixOpen": {
- "description": "Sequence prefix",
- "suggested_key": {
- "chromeos": "Search+Shift+O"
- }
- },
- "showContextMenu": {
- "description": "__MSG_CHROMEVOX_SHOW_CONTEXT_MENU__",
- "suggested_key": {
- "chromeos": "Search+Ctrl+Space"
- }
- }
-{% endif %}
- },
- "options_page": "chromevox/background/options.html",
- "default_locale": "en"
-}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/base_rule_store.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/base_rule_store.js
deleted file mode 100644
index 079e4191ac2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/base_rule_store.js
+++ /dev/null
@@ -1,426 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Base class for all speech rule stores.
- *
- * The base rule store implements some basic functionality that is common to
- * most speech rule stores.
- */
-
-goog.provide('cvox.BaseRuleStore');
-
-goog.require('cvox.MathUtil');
-goog.require('cvox.SpeechRule');
-goog.require('cvox.SpeechRuleEvaluator');
-goog.require('cvox.SpeechRuleFunctions');
-goog.require('cvox.SpeechRuleStore');
-
-
-/**
- * @constructor
- * @implements {cvox.SpeechRuleEvaluator}
- * @implements {cvox.SpeechRuleStore}
- */
-cvox.BaseRuleStore = function() {
- /**
- * Set of custom query functions for the store.
- * @type {cvox.SpeechRuleFunctions.CustomQueries}
- */
- this.customQueries = new cvox.SpeechRuleFunctions.CustomQueries();
-
- /**
- * Set of custom strings for the store.
- * @type {cvox.SpeechRuleFunctions.CustomStrings}
- */
- this.customStrings = new cvox.SpeechRuleFunctions.CustomStrings();
-
- /**
- * Set of context functions for the store.
- * @type {cvox.SpeechRuleFunctions.ContextFunctions}
- */
- this.contextFunctions = new cvox.SpeechRuleFunctions.ContextFunctions();
-
- /**
- * Set of speech rules in the store.
- * @type {!Array<cvox.SpeechRule>}
- * @private
- */
- this.speechRules_ = [];
-
- /**
- * A priority list of dynamic constraint attributes.
- * @type {!Array<cvox.SpeechRule.DynamicCstrAttrib>}
- */
- this.dynamicCstrAttribs = [cvox.SpeechRule.DynamicCstrAttrib.STYLE];
-
- /**
- * List of TTS properties overridden by the store when it is active.
- * @type {!Array<string>}
- */
- this.defaultTtsProps = [];
-};
-
-
-/**
- * @override
- */
-cvox.BaseRuleStore.prototype.lookupRule = function(node, dynamic) {
- if (!node ||
- (node.nodeType != Node.ELEMENT_NODE && node.nodeType != Node.TEXT_NODE)) {
- return null;
- }
- var matchingRules = this.speechRules_.filter(
- goog.bind(
- function(rule) {
- return this.testDynamicConstraints(dynamic, rule) &&
- this.testPrecondition_(/** @type {!Node} */ (node), rule);},
- this));
- return (matchingRules.length > 0) ?
- this.pickMostConstraint_(dynamic, matchingRules) : null;
-};
-
-
-/**
- * @override
- */
-cvox.BaseRuleStore.prototype.defineRule = function(
- name, dynamic, action, prec, cstr) {
- try {
- var postc = cvox.SpeechRule.Action.fromString(action);
- var cstrList = Array.prototype.slice.call(arguments, 4);
- var fullPrec = new cvox.SpeechRule.Precondition(prec, cstrList);
- var dynamicCstr = {};
- dynamicCstr[cvox.SpeechRule.DynamicCstrAttrib.STYLE] = dynamic;
- var rule = new cvox.SpeechRule(name, dynamicCstr, fullPrec, postc);
- } catch (err) {
- if (err.name == 'RuleError') {
- console.log('Rule Error ', prec, '(' + dynamic + '):', err.message);
- return null;
- }
- else {
- throw err;
- }
- }
- this.addRule(rule);
- return rule;
-};
-
-
-/**
- * @override
- */
-cvox.BaseRuleStore.prototype.addRule = function(rule) {
- this.speechRules_.unshift(rule);
-};
-
-
-/**
- * @override
- */
-cvox.BaseRuleStore.prototype.deleteRule = function(rule) {
- var index = this.speechRules_.indexOf(rule);
- if (index != -1) {
- this.speechRules_.splice(index, 1);
- }
-};
-
-
-/**
- * @override
- */
-cvox.BaseRuleStore.prototype.findRule = function(pred) {
- for (var i = 0, rule; rule = this.speechRules_[i]; i++) {
- if (pred(rule)) {
- return rule;
- }
- }
- return null;
-};
-
-
-/**
- * @override
- */
-cvox.BaseRuleStore.prototype.findAllRules = function(pred) {
- return this.speechRules_.filter(pred);
-};
-
-
-/**
- * @override
- */
-cvox.BaseRuleStore.prototype.evaluateDefault = function(node) {
- return [new cvox.NavDescription({'text': node.textContent})];
-};
-
-
-/**
- * Test the applicability of a speech rule in debugging mode.
- * @param {string} name Rule to debug.
- * @param {!Node} node DOM node to test applicability of given rule.
- */
-cvox.BaseRuleStore.prototype.debugSpeechRule = goog.abstractMethod;
-
-
-/**
- * Function to initialize the store with speech rules. It is called by the
- * speech rule engine upon parametrization with this store. The function allows
- * us to define sets of rules in separate files while depending on functionality
- * that is defined in the rule store.
- * Essentially it is a way of getting around dependencies.
- */
-cvox.BaseRuleStore.prototype.initialize = goog.abstractMethod;
-
-
-/**
- * Removes duplicates of the given rule from the rule store. Thereby duplicates
- * are identified by having the same precondition and dynamic constraint.
- * @param {cvox.SpeechRule} rule The rule.
- */
-cvox.BaseRuleStore.prototype.removeDuplicates = function(rule) {
- for (var i = this.speechRules_.length - 1, oldRule;
- oldRule = this.speechRules_[i]; i--) {
- if (oldRule != rule &&
- cvox.BaseRuleStore.compareDynamicConstraints_(
- oldRule.dynamicCstr, rule.dynamicCstr) &&
- cvox.BaseRuleStore.comparePreconditions_(oldRule, rule)) {
- this.speechRules_.splice(i, 1);
- }
- }
-};
-
-
-// TODO (sorge) These should move into the speech rule functions.
-/**
- * Checks if we have a custom query and applies it. Otherwise returns null.
- * @param {!Node} node The initial node.
- * @param {string} funcName A function name.
- * @return {Array<Node>} The list of resulting nodes.
- */
-cvox.BaseRuleStore.prototype.applyCustomQuery = function(
- node, funcName) {
- var func = this.customQueries.lookup(funcName);
- return func ? func(node) : null;
-};
-
-
-/**
- * Applies either an Xpath selector or a custom query to the node
- * and returns the resulting node list.
- * @param {!Node} node The initial node.
- * @param {string} expr An Xpath expression string or a name of a custom
- * query.
- * @return {Array<Node>} The list of resulting nodes.
- */
-cvox.BaseRuleStore.prototype.applySelector = function(node, expr) {
- var result = this.applyCustomQuery(node, expr);
- return result || cvox.XpathUtil.evalXPath(expr, node);
-};
-
-
-/**
- * Applies either an Xpath selector or a custom query to the node
- * and returns the first result.
- * @param {!Node} node The initial node.
- * @param {string} expr An Xpath expression string or a name of a custom
- * query.
- * @return {Node} The resulting node.
- */
-cvox.BaseRuleStore.prototype.applyQuery = function(node, expr) {
- var results = this.applySelector(node, expr);
- if (results.length > 0) {
- return results[0];
- }
- return null;
-};
-
-
-/**
- * Applies either an Xpath selector or a custom query to the node and returns
- * true if the application yields a non-empty result.
- * @param {!Node} node The initial node.
- * @param {string} expr An Xpath expression string or a name of a custom
- * query.
- * @return {boolean} True if application was successful.
- */
-cvox.BaseRuleStore.prototype.applyConstraint = function(node, expr) {
- var result = this.applyQuery(node, expr);
- return !!result || cvox.XpathUtil.evaluateBoolean(expr, node);
-};
-
-
-/**
- * Tests whether a speech rule satisfies a set of dynamic constraints.
- * @param {!cvox.SpeechRule.DynamicCstr} dynamic Dynamic constraints.
- * @param {cvox.SpeechRule} rule The rule.
- * @return {boolean} True if the preconditions apply to the node.
- * @protected
- */
-cvox.BaseRuleStore.prototype.testDynamicConstraints = function(
- dynamic, rule) {
- // We allow a default value for each dynamic constraints attribute.
- // The idea is that when we can not find a speech rule matching the value for
- // a particular attribute in the dynamic constraintwe choose the one that has
- // the value 'default'.
- var allKeys = /** @type {Array<cvox.SpeechRule.DynamicCstrAttrib>} */ (
- Object.keys(dynamic));
- return allKeys.every(
- function(key) {
- return dynamic[key] == rule.dynamicCstr[key] ||
- rule.dynamicCstr[key] == 'default';
- });
-};
-
-
-/**
- * Get a set of all dynamic constraint values.
- * @return {!Object<cvox.SpeechRule.DynamicCstrAttrib, Array<string>>} The
- * object with all annotations.
- */
-cvox.BaseRuleStore.prototype.getDynamicConstraintValues = function() {
- var result = {};
- for (var i = 0, rule; rule = this.speechRules_[i]; i++) {
- for (var key in rule.dynamicCstr) {
- var newKey = [rule.dynamicCstr[key]];
- if (result[key]) {
- result[key] = cvox.MathUtil.union(result[key], newKey);
- } else {
- result[key] = newKey;
- }
- }
- }
- return result;
-};
-
-
-/**
- * Counts how many dynamic constraint values match exactly in the order
- * specified by the store.
- * @param {cvox.SpeechRule.DynamicCstr} dynamic Dynamic constraints.
- * @param {cvox.SpeechRule} rule The speech rule to match.
- * @return {number} The number of matching dynamic constraint values.
- * @private
- */
-cvox.BaseRuleStore.prototype.countMatchingDynamicConstraintValues_ = function(
- dynamic, rule) {
- var result = 0;
- for (var i = 0, key; key = this.dynamicCstrAttribs[i]; i++) {
- if (dynamic[key] == rule.dynamicCstr[key]) {
- result++;
- } else break;
- }
- return result;
-};
-
-
-/**
- * Picks the result of the most constraint rule by prefering those:
- * 1) that best match the dynamic constraints.
- * 2) with the most additional constraints.
- * @param {cvox.SpeechRule.DynamicCstr} dynamic Dynamic constraints.
- * @param {!Array<cvox.SpeechRule>} rules An array of rules.
- * @return {cvox.SpeechRule} The most constraint rule.
- * @private
- */
-cvox.BaseRuleStore.prototype.pickMostConstraint_ = function(dynamic, rules) {
- rules.sort(goog.bind(
- function(r1, r2) {
- var count1 = this.countMatchingDynamicConstraintValues_(dynamic, r1);
- var count2 = this.countMatchingDynamicConstraintValues_(dynamic, r2);
- // Rule one is a better match, don't swap.
- if (count1 > count2) {
- return -1;
- }
- // Rule two is a better match, swap.
- if (count2 > count1) {
- return 1;
- }
- // When same number of dynamic constraint attributes matches for
- // both rules, compare length of static constraints.
- return (r2.precondition.constraints.length -
- r1.precondition.constraints.length);},
- this));
- return rules[0];
-};
-
-
-/**
- * Test the precondition of a speech rule.
- * @param {!Node} node on which to test applicability of the rule.
- * @param {cvox.SpeechRule} rule The rule to be tested.
- * @return {boolean} True if the preconditions apply to the node.
- * @private
- */
-cvox.BaseRuleStore.prototype.testPrecondition_ = function(node, rule) {
- var prec = rule.precondition;
- return this.applyQuery(node, prec.query) === node &&
- prec.constraints.every(
- goog.bind(function(cstr) {
- return this.applyConstraint(node, cstr);},
- this));
-};
-
-
-// TODO (sorge) Define the following methods directly on the dynamic constraint
-// and precondition classes, respectively.
-/**
- * Compares two dynamic constraints and returns true if they are equal.
- * @param {cvox.SpeechRule.DynamicCstr} cstr1 First dynamic constraints.
- * @param {cvox.SpeechRule.DynamicCstr} cstr2 Second dynamic constraints.
- * @return {boolean} True if the dynamic constraints are equal.
- * @private
- */
-cvox.BaseRuleStore.compareDynamicConstraints_ = function(
- cstr1, cstr2) {
- if (Object.keys(cstr1).length != Object.keys(cstr2).length) {
- return false;
- }
- for (var key in cstr1) {
- if (!cstr2[key] || cstr1[key] !== cstr2[key]) {
- return false;
- }
- }
- return true;
-};
-
-
-/**
- * Compares two static constraints (i.e., lists of precondition constraints) and
- * returns true if they are equal.
- * @param {Array<string>} cstr1 First static constraints.
- * @param {Array<string>} cstr2 Second static constraints.
- * @return {boolean} True if the static constraints are equal.
- * @private
- */
-cvox.BaseRuleStore.compareStaticConstraints_ = function(
- cstr1, cstr2) {
- if (cstr1.length != cstr2.length) {
- return false;
- }
- for (var i = 0, cstr; cstr = cstr1[i]; i++) {
- if (cstr2.indexOf(cstr) == -1) {
- return false;
- }
- }
- return true;
-};
-
-
-/**
- * Compares the preconditions of two speech rules.
- * @param {cvox.SpeechRule} rule1 The first speech rule.
- * @param {cvox.SpeechRule} rule2 The second speech rule.
- * @return {boolean} True if the preconditions are equal.
- * @private
- */
-cvox.BaseRuleStore.comparePreconditions_ = function(rule1, rule2) {
- var prec1 = rule1.precondition;
- var prec2 = rule2.precondition;
- if (prec1.query != prec2.query) {
- return false;
- }
- return cvox.BaseRuleStore.compareStaticConstraints_(
- prec1.constraints, prec2.constraints);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/math_simple_store.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/math_simple_store.js
deleted file mode 100644
index dedc74b4719..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/math_simple_store.js
+++ /dev/null
@@ -1,181 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Rule stores for the basic components of math expressions:
- * Unicode symbols and functions.
- *
- * The idea of these stores is to provide a more efficient data structure to
- * look up rules in the background page than the usual flat array of rules
- * implemented by other stores.
- *
- */
-
-goog.provide('cvox.MathCompoundStore');
-goog.provide('cvox.MathSimpleStore');
-
-goog.require('cvox.MathStore');
-goog.require('cvox.SpeechRule');
-
-/**
- * A base store for simple Math objects.
- * @constructor
- * @extends {cvox.MathStore}
- */
-cvox.MathSimpleStore = function() {
- goog.base(this);
- };
-goog.inherits(cvox.MathSimpleStore, cvox.MathStore);
-
-
-/**
- * Turns a domain mapping from its JSON representation containing simple strings
- * only into a list of speech rules.
- * @param {string} name Name for the rules.
- * @param {string} str String for precondition and constraints.
- * @param {Object<Object<string>>} mapping Simple string
- * mapping.
- */
-cvox.MathSimpleStore.prototype.defineRulesFromMappings = function(
- name, str, mapping) {
- for (var domain in mapping) {
- for (var style in mapping[domain]) {
- var content = mapping[domain][style];
- var cstr = 'self::text() = "' + str + '"';
- var rule = this.defineRule(
- name, domain + '.' + style, '[t] "' + content + '"',
- 'self::text()', cstr);
- }
- }
-};
-
-
-/**
- * A compound store for simple Math objects.
- * @constructor
- */
-cvox.MathCompoundStore = function() {
- /**
- * A set of efficient substores.
- * @type {Object<cvox.MathStore>}
- * @private
- */
- this.subStores_ = {};
-};
-goog.addSingletonGetter(cvox.MathCompoundStore);
-
-
-/**
- * Function creates a rule store in the compound store for a particular string,
- * and populates it with a set of rules.
- * @param {string} name Name of the rule.
- * @param {string} str String used as key to refer to the rule store
- * precondition and constr
- * @param {Object} mappings JSON representation of mappings from styles and
- * domains to strings, from which the speech rules will be computed.
- */
-cvox.MathCompoundStore.prototype.defineRules = function(name, str, mappings) {
- var store = new cvox.MathSimpleStore();
- store.defineRulesFromMappings(name, str, mappings);
- this.subStores_[str] = store;
-};
-
-
-/**
- * Makes a speech rule for Unicode characters from its JSON representation.
- * @param {Object} json JSON object of the speech rules.
- */
-cvox.MathCompoundStore.prototype.addSymbolRules = function(json) {
- var key = cvox.MathSimpleStore.parseUnicode_(json['key']);
- this.defineRules(json['key'], key, json['mappings']);
-};
-
-
-/**
- * Makes a speech rule for Unicode characters from its JSON representation.
- * @param {Object} json JSON object of the speech rules.
- */
-cvox.MathCompoundStore.prototype.addFunctionRules = function(json) {
- var names = json['names'];
- var mappings = json['mappings'];
- for (var j = 0, name; name = names[j]; j++) {
- this.defineRules(name, name, mappings);
- }
-};
-
-
-/**
- * Retrieves a rule for the given node if one exists.
- * @param {Node} node A node.
- * @param {!cvox.SpeechRule.DynamicCstr} dynamic Additional dynamic
- * constraints. These are matched against properties of a rule.
- * @return {cvox.SpeechRule} The speech rule if it exists.
- */
-cvox.MathCompoundStore.prototype.lookupRule = function(node, dynamic) {
- var store = this.subStores_[node.textContent];
- if (store) {
- return store.lookupRule(node, dynamic);
- }
-};
-
-
-/**
- * Looks up a rule for a given string and executes its actions.
- * @param {string} text The text to be translated.
- * @param {!cvox.SpeechRule.DynamicCstr} dynamic Additional dynamic
- * constraints. These are matched against properties of a rule.
- * @return {!string} The string resulting from the action of speech rule.
- */
-cvox.MathCompoundStore.prototype.lookupString = function(text, dynamic) {
- var textNode = document.createTextNode(text);
- var rule = this.lookupRule(textNode, dynamic);
- if (!rule) {
- return '';
- }
- return rule.action.components
- .map(function(comp) {
- return comp.content.slice(1, -1);})
- .join(' ');
-};
-
-
-/**
- * Get a set of all dynamic constraint values.
- * @return {!Object<cvox.SpeechRule.DynamicCstrAttrib, Array<string>>} The
- * object with all annotations.
- */
-cvox.MathCompoundStore.prototype.getDynamicConstraintValues = function() {
- var newCstr = {};
- for (var store in this.subStores_) {
- var cstr = this.subStores_[store].getDynamicConstraintValues();
- for (var key in cstr) {
- var set = newCstr[key];
- if (set) {
- newCstr[key] = cvox.MathUtil.union(set, cstr[key]);
- } else {
- newCstr[key] = cstr[key];
- }
- }
- }
- return newCstr;
-};
-
-
-/**
- * Parses a string with a hex representatino of a unicode code point into the
- * corresponding unicode character.
- * @param {string} number The code point to be parsed.
- * @return {string} The unicode character.
- * @private
- */
-cvox.MathSimpleStore.parseUnicode_ = function(number) {
- var keyValue = parseInt(number, 16);
- if (keyValue < 0x10000) {
- return String.fromCharCode(keyValue);
- }
- keyValue -= 0x10000;
- var hiSurrogate = (keyValue >> 10) + 0xD800;
- var lowSurrogate = (keyValue & 0x3FF) + 0xDC00;
- return String.fromCharCode(hiSurrogate, lowSurrogate);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/math_store.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/math_store.js
deleted file mode 100644
index 4c33452b6b8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/math_store.js
+++ /dev/null
@@ -1,268 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Rule store for math syntax tree nodes.
- */
-
-goog.provide('cvox.MathStore');
-
-goog.require('cvox.AbstractTts');
-goog.require('cvox.BaseRuleStore');
-goog.require('cvox.ChromeVox');
-goog.require('cvox.NavMathDescription');
-goog.require('cvox.SpeechRule');
-goog.require('cvox.TraverseMath');
-
-
-/**
- * A store for Math rules.
- * @constructor
- * @extends {cvox.BaseRuleStore}
- */
-cvox.MathStore = function() {
- goog.base(this);
-
- /**
- * @override
- */
- this.dynamicCstrAttribs = [
- cvox.SpeechRule.DynamicCstrAttrib.DOMAIN,
- cvox.SpeechRule.DynamicCstrAttrib.STYLE
- ];
-
- /**
- * @override
- */
- this.defaultTtsProps = [cvox.AbstractTts.PITCH];
-};
-goog.inherits(cvox.MathStore, cvox.BaseRuleStore);
-
-/** This adds domain to dynamic constraint annotation. */
-cvox.SpeechRule.DynamicCstrAttrib.DOMAIN = 'domain';
-
-
-/**
- * @override
- */
-cvox.MathStore.prototype.defineRule = function(
- name, dynamic, action, query, cstr) {
- var dynamicCstr = this.parseDynamicConstraint(dynamic);
- var cstrList = Array.prototype.slice.call(arguments, 4);
- // We can not use goog.base due to variable number of constraint arguments.
- var rule = cvox.MathStore.superClass_.defineRule.apply(
- this, [name, dynamicCstr[cvox.SpeechRule.DynamicCstrAttrib.STYLE],
- action, query].concat(cstrList));
- // In the superclass the dynamic constraint only contains style annotations.
- // We now set the proper dynamic constraint that contains in addition a
- // a domain attribute/value pair.
- rule.dynamicCstr = dynamicCstr;
- this.removeDuplicates(rule);
- return rule;
-};
-
-
-/**
- * Parses the dynamic constraint for math rules, consisting of a domain and
- * style information, given as 'domain.style'.
- * @param {string} cstr A string representation of the dynamic constraint.
- * @return {!cvox.SpeechRule.DynamicCstr} The dynamic constraint.
- */
-cvox.MathStore.prototype.parseDynamicConstraint = function(cstr) {
- var domainStyle = cstr.split('.');
- if (!domainStyle[0] || !domainStyle[1]) {
- throw new cvox.SpeechRule.OutputError('Invalid domain assignment:' + cstr);
- }
- return cvox.MathStore.createDynamicConstraint(domainStyle[0], domainStyle[1]);
-};
-
-
-/**
- * Creates a dynamic constraint annotation for math rules from domain and style
- * values.
- * @param {string} domain Domain annotation.
- * @param {string} style Style annotation.
- * @return {!cvox.SpeechRule.DynamicCstr}
- */
-cvox.MathStore.createDynamicConstraint = function(domain, style) {
- var dynamicCstr = {};
- dynamicCstr[cvox.SpeechRule.DynamicCstrAttrib.DOMAIN] = domain;
- dynamicCstr[cvox.SpeechRule.DynamicCstrAttrib.STYLE] = style;
- return dynamicCstr;
-};
-
-
-/**
- * Adds an alias for an existing rule.
- * @param {string} name The name of the rule.
- * @param {string} dynamic A math domain and style assignment.
- * @param {string} query Precondition query of the rule.
- * @param {...string} cstr Additional static precondition constraints.
- */
-cvox.MathStore.prototype.defineUniqueRuleAlias = function(
- name, dynamic, query, cstr) {
- var dynamicCstr = this.parseDynamicConstraint(dynamic);
- var rule = this.findRule(
- goog.bind(
- function(rule) {
- return rule.name == name &&
- this.testDynamicConstraints(dynamicCstr, rule);},
- this));
- if (!rule) {
- throw new cvox.SpeechRule.OutputError(
- 'Rule named ' + name + ' with style ' + dynamic + ' does not exist.');
- }
- this.addAlias_(rule, query, Array.prototype.slice.call(arguments, 3));
-};
-
-
-/**
- * Adds an alias for an existing rule.
- * @param {string} name The name of the rule.
- * @param {string} query Precondition query of the rule.
- * @param {...string} cstr Additional static precondition constraints.
- */
-cvox.MathStore.prototype.defineRuleAlias = function(name, query, cstr) {
- var rule = this.findRule(function(rule) {
- return rule.name == name;});
- if (!rule) {
- throw new cvox.SpeechRule.OutputError(
- 'Rule with named ' + name + ' does not exist.');
- }
- this.addAlias_(rule, query, Array.prototype.slice.call(arguments, 2));
-};
-
-
-/**
- * Adds an alias for an existing rule.
- * @param {string} name The name of the rule.
- * @param {string} query Precondition query of the rule.
- * @param {...string} cstr Additional static precondition constraints.
- */
-cvox.MathStore.prototype.defineRulesAlias = function(name, query, cstr) {
- var rules = this.findAllRules(function(rule) {return rule.name == name;});
- if (rules.length == 0) {
- throw new cvox.SpeechRule.OutputError(
- 'Rule with name ' + name + ' does not exist.');
- }
- var cstrList = Array.prototype.slice.call(arguments, 2);
- rules.forEach(goog.bind(
- function(rule) {
- this.addAlias_(rule, query, cstrList);
- },
- this));
-};
-
-
-/**
- * Adds a new speech rule as alias of the given rule.
- * @param {cvox.SpeechRule} rule The existing rule.
- * @param {string} query Precondition query of the rule.
- * @param {Array<string>} cstrList List of additional constraints.
- * @private
- */
-cvox.MathStore.prototype.addAlias_ = function(rule, query, cstrList) {
- var prec = new cvox.SpeechRule.Precondition(query, cstrList);
- var newRule = new cvox.SpeechRule(
- rule.name, rule.dynamicCstr, prec, rule.action);
- newRule.name = rule.name;
- this.addRule(newRule);
-};
-
-
-// Evaluator
-/**
- * @override
- */
-cvox.MathStore.prototype.evaluateDefault = function(node) {
- return this.evaluateString_(node.textContent);
-};
-
-
-/**
- * Evaluates a single string of a math expressions. The method splits the given
- * string into components such as single characters, function names or words,
- * numbers, etc. and creates the appropriate navigation descriptions.
- * @param {string} str A string.
- * @return {!Array<cvox.NavDescription>} Messages for the math expression.
- * @private
- */
-cvox.MathStore.prototype.evaluateString_ = function(str) {
- var descs = new Array();
- if (str.match(/^\s+$/)) {
- // Nothing but whitespace: Ignore.
- return descs;
- }
- var split = cvox.MathStore.removeEmpty_(str.replace(/\s/g, ' ').split(' '));
- for (var i = 0, s; s = split[i]; i++) {
- if (s.length == 1) {
- descs.push(this.evaluate_(s));
- } else if (s.match(/^[a-zA-Z]+$/)) {
- descs.push(this.evaluate_(s));
- } else {
- // Break up string even further wrt. symbols vs alphanum substrings.
- var rest = s;
- var count = 0;
- while (rest) {
- var num = rest.match(/^\d+/);
- var alpha = rest.match(/^[a-zA-Z]+/);
- if (num) {
- descs.push(this.evaluate_(num[0]));
- rest = rest.substring(num[0].length);
- } else if (alpha) {
- descs.push(this.evaluate_(alpha[0]));
- rest = rest.substring(alpha[0].length);
- } else {
- // Dealing with surrogate pairs.
- var chr = rest[0];
- var code = chr.charCodeAt(0);
- if (0xD800 <= code && code <= 0xDBFF &&
- rest.length > 1 && !isNaN(rest.charCodeAt(1))) {
- descs.push(this.evaluate_(rest.slice(0, 2)));
- rest = rest.substring(2);
- } else {
- descs.push(this.evaluate_(rest[0]));
- rest = rest.substring(1);
- }
- }
- }
- }
- }
- return descs;
-};
-
-
-/**
- * Creates a new Navigation Description for a math expression that be used by
- * the background tts.
- * @param {string} text to be translated.
- * @return {cvox.NavDescription} Navigation description for the
- * math expression.
- * @private
- */
-cvox.MathStore.prototype.evaluate_ = function(text) {
- if (cvox.ChromeVox.host['mathMap']) {
- // VS: Change this for android!
- return cvox.ChromeVox.host['mathMap'].evaluate(
- text,
- cvox.TraverseMath.getInstance().domain,
- cvox.TraverseMath.getInstance().style);
- }
- return new cvox.NavMathDescription(
- {'text': text,
- 'domain': cvox.TraverseMath.getInstance().domain,
- 'style': cvox.TraverseMath.getInstance().style
- });
-};
-
-
-/**
- * Removes all empty strings from an array of strings.
- * @param {Array<string>} strs An array of strings.
- * @return {Array<string>} The cleaned array.
- * @private
- */
-cvox.MathStore.removeEmpty_ = function(strs) {
- return strs.filter(function(str) {return str;});
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store.js
deleted file mode 100644
index 62fa35e975e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Speech rule store for mathml and mathjax trees.
- */
-
-goog.provide('cvox.MathmlStore');
-
-goog.require('cvox.MathStore');
-
-
-/**
- * Rule initialization.
- * @constructor
- * @extends {cvox.MathStore}
- */
-cvox.MathmlStore = function() {
- goog.base(this);
-};
-goog.inherits(cvox.MathmlStore, cvox.MathStore);
-goog.addSingletonGetter(cvox.MathmlStore);
-
-
-/**
- * Adds a new MathML speech rule.
- * @param {string} name Rule name which corresponds to the MathML tag name.
- * @param {string} domain Domain annotation of the rule.
- * @param {string} rule String version of the speech rule.
- */
-cvox.MathmlStore.prototype.defineMathmlRule = function(name, domain, rule) {
- this.defineRule(name, domain, rule, 'self::mathml:' + name);
-};
-
-
-/**
- * Adds a new MathML speech rule for the default.default domain.
- * @param {string} name Rule name which corresponds to the MathML tag name.
- * @param {string} rule String version of the speech rule.
- */
-cvox.MathmlStore.prototype.defineDefaultMathmlRule = function(name, rule) {
- this.defineRule(name, 'default.default', rule, 'self::mathml:' + name);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store_rules.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store_rules.js
deleted file mode 100644
index ec16ce9a7c8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store_rules.js
+++ /dev/null
@@ -1,879 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Speech rules for mathml and mathjax nodes.
- */
-
-goog.provide('cvox.MathmlStoreRules');
-
-goog.require('cvox.MathStore');
-goog.require('cvox.MathmlStore');
-goog.require('cvox.MathmlStoreUtil');
-goog.require('cvox.StoreUtil');
-
-
-/**
- * Rule initialization.
- * @constructor
- */
-cvox.MathmlStoreRules = function() {
- // Custom functions used in the rules.
- cvox.MathmlStoreRules.initCustomFunctions_();
- cvox.MathmlStoreRules.initDefaultRules_(); // MathML rules.
- cvox.MathmlStoreRules.initMathjaxRules_(); // MathJax Rules
- cvox.MathmlStoreRules.initAliases_(); // MathJax Aliases for MathML rules.
- cvox.MathmlStoreRules.initSpecializationRules_(); // Square, cube, etc.
- cvox.MathmlStoreRules.initSemanticRules_();
-};
-goog.addSingletonGetter(cvox.MathmlStoreRules);
-
-
-/**
- * @type {cvox.MathStore}
- */
-cvox.MathmlStoreRules.mathStore = cvox.MathmlStore.getInstance();
-/**
- * @override
- */
-cvox.MathmlStoreRules.mathStore.initialize = cvox.MathmlStoreRules.getInstance;
-
-// These are used to work around Closure's rules for aliasing.
-/** @private */
-cvox.MathmlStoreRules.defineDefaultMathmlRule_ = goog.bind(
- cvox.MathmlStoreRules.mathStore.defineDefaultMathmlRule,
- cvox.MathmlStoreRules.mathStore);
-/** @private */
-cvox.MathmlStoreRules.defineRule_ = goog.bind(
- cvox.MathmlStoreRules.mathStore.defineRule,
- cvox.MathmlStoreRules.mathStore);
-/** @private */
-cvox.MathmlStoreRules.defineRuleAlias_ = goog.bind(
- cvox.MathmlStoreRules.mathStore.defineRuleAlias,
- cvox.MathmlStoreRules.mathStore);
-/** @private */
-cvox.MathmlStoreRules.addContextFunction_ = goog.bind(
- cvox.MathmlStoreRules.mathStore.contextFunctions.add,
- cvox.MathmlStoreRules.mathStore.contextFunctions);
-/** @private */
-cvox.MathmlStoreRules.addCustomQuery_ = goog.bind(
- cvox.MathmlStoreRules.mathStore.customQueries.add,
- cvox.MathmlStoreRules.mathStore.customQueries);
-
-goog.scope(function() {
-var defineDefaultMathmlRule = cvox.MathmlStoreRules.defineDefaultMathmlRule_;
-var defineRule = cvox.MathmlStoreRules.defineRule_;
-var defineRuleAlias = cvox.MathmlStoreRules.defineRuleAlias_;
-
-var addCTXF = cvox.MathmlStoreRules.addContextFunction_;
-var addCQF = cvox.MathmlStoreRules.addCustomQuery_;
-
-/**
- * Initialize the custom functions.
- * @private
- */
-cvox.MathmlStoreRules.initCustomFunctions_ = function() {
- addCTXF('CTXFnodeCounter', cvox.StoreUtil.nodeCounter);
- addCTXF('CTXFmfSeparators', cvox.MathmlStoreUtil.mfencedSeparators);
- addCTXF('CTXFcontentIterator', cvox.MathmlStoreUtil.contentIterator);
-
- addCQF('CQFextender', cvox.MathmlStoreUtil.retrieveMathjaxExtender);
- addCQF('CQFmathmlmunder', cvox.MathmlStoreUtil.checkMathjaxMunder);
- addCQF('CQFmathmlmover', cvox.MathmlStoreUtil.checkMathjaxMover);
- addCQF('CQFmathmlmsub', cvox.MathmlStoreUtil.checkMathjaxMsub);
- addCQF('CQFmathmlmsup', cvox.MathmlStoreUtil.checkMathjaxMsup);
- addCQF('CQFlookupleaf', cvox.MathmlStoreUtil.retrieveMathjaxLeaf);
-
-};
-
-
-/**
- * Initialize the default mathrules.
- * @private
- */
-cvox.MathmlStoreRules.initDefaultRules_ = function() {
- // Initial rule
- defineDefaultMathmlRule('math', '[m] ./*');
- defineDefaultMathmlRule('semantics', '[n] ./*[1]');
-
- // Space elements
- defineDefaultMathmlRule('mspace', '[p] (pause:250)');
- defineDefaultMathmlRule('mstyle', '[m] ./*');
- defineDefaultMathmlRule('mpadded', '[m] ./*');
- defineDefaultMathmlRule('merror', '[t] ""');
- defineDefaultMathmlRule('mphantom', '[t] ""');
-
- // Token elements.
- defineDefaultMathmlRule('mtext', '[t] text(); [p] (pause:200)');
- defineDefaultMathmlRule('mi', '[n] text()');
- defineDefaultMathmlRule('mo', '[n] text() (rate:-0.1)');
- defineDefaultMathmlRule('mn', '[n] text()');
-
- // Dealing with fonts.
- defineRule('mtext-variant', 'default.default',
- '[t] "begin"; [t] @mathvariant (pause:150);' +
- '[t] text() (pause:150); [t] "end"; ' +
- '[t] @mathvariant (pause:200)',
- 'self::mathml:mtext', '@mathvariant', '@mathvariant!="normal"');
-
- defineRule('mi-variant', 'default.default',
- '[t] @mathvariant; [n] text()',
- 'self::mathml:mi', '@mathvariant', '@mathvariant!="normal"');
-
- defineRuleAlias('mi-variant', 'self::mathml:mn', // mn
- '@mathvariant', '@mathvariant!="normal"');
-
- defineRule('mo-variant', 'default.default',
- '[t] @mathvariant; [n] text() (rate:-0.1)',
- 'self::mathml:mo', '@mathvariant', '@mathvariant!="normal"');
-
- defineDefaultMathmlRule(
- 'ms',
- '[t] "string" (pitch:0.5, rate:0.5); [t] text()');
-
- // Script elements.
- defineDefaultMathmlRule(
- 'msup', '[n] ./*[1]; [t] "super";' +
- '[n] ./*[2] (pitch:0.35); [p] (pause:300)');
- defineDefaultMathmlRule(
- 'msubsup',
- '[n] ./*[1]; [t] "sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);' +
- '[t] "super"; [n] ./*[3] (pitch:0.35); [p] (pause:300)'
- );
- defineDefaultMathmlRule(
- 'msub',
- '[n] ./*[1]; [t] "sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:300)');
- defineDefaultMathmlRule(
- 'mover', '[n] ./*[2] (pitch:0.35); [p] (pause:200);' +
- ' [t] "over"; [n] ./*[1]; [p] (pause:400)');
- defineDefaultMathmlRule(
- 'munder',
- '[n] ./*[2] (pitch:-0.35); [t] "under"; [n] ./*[1]; [p] (pause:400)');
- defineDefaultMathmlRule(
- 'munderover',
- '[n] ./*[2] (pitch:-0.35); [t] "under and"; [n] ./*[3] (pitch:0.35);' +
- ' [t] "over"; [n] ./*[1]; [p] (pause:400)');
-
- // Layout elements.
- defineDefaultMathmlRule('mrow', '[m] ./*');
- defineDefaultMathmlRule(
- 'msqrt', '[t] "Square root of"; [m] ./* (rate:0.2); [p] (pause:400)');
- defineDefaultMathmlRule(
- 'mroot', '[t] "root of order"; [n] ./*[2]; [t] "of";' +
- '[n] ./*[1] (rate:0.2); [p] (pause:400)');
- defineDefaultMathmlRule(
- 'mfrac', ' [p] (pause:400); [n] ./*[1] (pitch:0.3);' +
- ' [t] "divided by"; [n] ./*[2] (pitch:-0.3); [p] (pause:400)');
- defineRule(
- 'mfrac', 'default.short', '[p] (pause:200); [t] "start frac";' +
- '[n] ./*[1] (pitch:0.3); [t] "over"; ' +
- '[n] ./*[2] (pitch:-0.3); [p] (pause:400); [t] "end frac"',
- 'self::mathml:mfrac');
-
-
- defineRule(
- 'mfenced-single', 'default.default',
- '[t] concat(substring(@open, 0 div boolean(@open)), ' +
- 'substring("(", 0 div not(boolean(@open)))) (context:"opening"); ' +
- '[m] ./* (separator:@separators); ' +
- '[t] concat(substring(@close, 0 div boolean(@close)), ' +
- 'substring(")", 0 div not(boolean(@close)))) (context:"closing")',
- 'self::mathml:mfenced', 'string-length(string(@separators))=1');
-
- defineRule(
- 'mfenced-omit', 'default.default',
- '[t] concat(substring(@open, 0 div boolean(@open)), ' +
- 'substring("(", 0 div not(boolean(@open)))) (context:"opening"); ' +
- '[m] ./*; ' +
- '[t] concat(substring(@close, 0 div boolean(@close)), ' +
- 'substring(")", 0 div not(boolean(@close)))) (context:"closing")',
- 'self::mathml:mfenced', '@separators',
- 'string-length(string(@separators))=0', 'string(@separators)=""');
-
- defineRule(
- 'mfenced-empty', 'default.default',
- '[t] concat(substring(@open, 0 div boolean(@open)), ' +
- 'substring("(", 0 div not(boolean(@open)))) (context:"opening"); ' +
- '[m] ./*;' +
- '[t] concat(substring(@close, 0 div boolean(@close)), ' +
- 'substring(")", 0 div not(boolean(@close)))) (context:"closing")',
- 'self::mathml:mfenced', 'string-length(string(@separators))=1',
- 'string(@separators)=" "');
-
- defineRule(
- 'mfenced-comma', 'default.default',
- '[t] concat(substring(@open, 0 div boolean(@open)), ' +
- 'substring("(", 0 div not(boolean(@open)))) (context:"opening"); ' +
- '[m] ./* (separator:"comma");' +
- '[t] concat(substring(@close, 0 div boolean(@close)), ' +
- 'substring(")", 0 div not(boolean(@close)))) (context:"closing")',
- 'self::mathml:mfenced');
-
- defineRule(
- 'mfenced-multi', 'default.default',
- '[t] concat(substring(@open, 0 div boolean(@open)), ' +
- 'substring("(", 0 div not(boolean(@open)))) (context:"opening"); ' +
- '[m] ./* (sepFunc:CTXFmfSeparators, separator:@separators); ' +
- '[t] concat(substring(@close, 0 div boolean(@close)), ' +
- 'substring(")", 0 div not(boolean(@close)))) (context:"closing")',
- 'self::mathml:mfenced', 'string-length(string(@separators))>1');
-
- // Mtable rules.
- defineRule(
- 'mtable', 'default.default',
- '[t] "matrix"; [m] ./* (ctxtFunc:CTXFnodeCounter,' +
- 'context:"row",pause:100)',
- 'self::mathml:mtable');
-
- defineRule(
- 'mtr', 'default.default',
- '[m] ./* (ctxtFunc:CTXFnodeCounter,context:"column",pause:100)',
- 'self::mathml:mtr');
-
- defineRule(
- 'mtd', 'default.default',
- '[m] ./*', 'self::mathml:mtd');
-
- // Mtable superbrief rules.
- defineRule(
- 'mtable', 'default.superbrief',
- '[t] count(child::mathml:mtr); [t] "by";' +
- '[t] count(child::mathml:mtr[1]/mathml:mtd); [t] "matrix";',
- 'self::mathml:mtable');
-
- // Mtable short rules.
- defineRule(
- 'mtable', 'default.short',
- '[t] "matrix"; [m] ./*',
- 'self::mathml:mtable');
-
- defineRule(
- 'mtr', 'default.short',
- '[m] ./*', 'self::mathml:mtr');
-
- defineRule(
- 'mtd', 'default.short',
- '[t] "Element"; [t] count(./preceding-sibling::mathml:mtd)+1;' +
- '[t] count(./parent::mathml:mtr/preceding-sibling::mathml:mtr)+1;' +
- '[p] (pause:500); [m] ./*',
- 'self::mathml:mtd');
-
- // Mmultiscripts rules.
- defineRule(
- 'mmultiscripts-4', 'default.default',
- '[n] ./*[1]; [p] (pause:200);' +
- '[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);' +
- '[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:200);' +
- '[t] "right sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);' +
- '[t] "right super"; [n] ./*[3] (pitch:0.35); [p] (pause:300);',
- 'self::mathml:mmultiscripts');
- defineRule(
- 'mmultiscripts-3-1', 'default.default',
- '[n] ./*[1]; [p] (pause:200);' +
- '[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);' +
- '[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:200);' +
- '[t] "right super"; [n] ./*[3] (pitch:0.35); [p] (pause:300);',
- 'self::mathml:mmultiscripts', './mathml:none=./*[2]',
- './mathml:mprescripts=./*[4]');
- defineRule(
- 'mmultiscripts-3-2', 'default.default',
- '[n] ./*[1]; [p] (pause:200);' +
- '[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);' +
- '[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:200);' +
- '[t] "right sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);',
- 'self::mathml:mmultiscripts', './mathml:none=./*[3]',
- './mathml:mprescripts=./*[4]');
- defineRule(
- 'mmultiscripts-3-3', 'default.default',
- '[n] ./*[1]; [p] (pause:200);' +
- '[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:200);' +
- '[t] "right sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);' +
- '[t] "right super"; [n] ./*[3] (pitch:0.35); [p] (pause:300);',
- 'self::mathml:mmultiscripts', './mathml:none=./*[5]',
- './mathml:mprescripts=./*[4]');
- defineRule(
- 'mmultiscripts-3-4', 'default.default',
- '[n] ./*[1]; [p] (pause:200);' +
- '[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);' +
- '[t] "right sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);' +
- '[t] "right super"; [n] ./*[3] (pitch:0.35); [p] (pause:300);',
- 'self::mathml:mmultiscripts', './mathml:none=./*[6]',
- './mathml:mprescripts=./*[4]');
- defineRule(
- 'mmultiscripts-2-1', 'default.default',
- '[n] ./*[1]; [p] (pause:200);' +
- '[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);' +
- '[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:300);',
- 'self::mathml:mmultiscripts', './mathml:none=./*[2]',
- './mathml:none=./*[3]', './mathml:mprescripts=./*[4]');
- defineRule(
- 'mmultiscripts-1-1', 'default.default',
- '[n] ./*[1]; [p] (pause:200);' +
- '[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:300);',
- 'self::mathml:mmultiscripts', './mathml:none=./*[2]',
- './mathml:none=./*[3]', './mathml:mprescripts=./*[4]',
- './mathml:none=./*[5]');
- defineRule(
- 'mmultiscripts-1-2', 'default.default',
- '[n] ./*[1]; [p] (pause:200);' +
- '[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);',
- 'self::mathml:mmultiscripts', './mathml:none=./*[2]',
- './mathml:none=./*[3]', './mathml:mprescripts=./*[4]',
- './mathml:none=./*[6]');
-};
-
-
-/**
- * Initialize mathJax Rules
- * @private
- */
-cvox.MathmlStoreRules.initMathjaxRules_ = function() {
- // Initial rule
- defineRule('mj-math', 'default.default',
- '[n] ./*[1]/*[1]/*[1]', 'self::span[@class="math"]');
-
- // Token Elements
- defineRule(
- 'mj-leaf', 'default.default',
- '[n] CQFlookupleaf', 'self::span[@class="mi"]');
- defineRuleAlias('mj-leaf', 'self::span[@class="mo"]');
- defineRuleAlias('mj-leaf', 'self::span[@class="mn"]');
- defineRuleAlias('mj-leaf', 'self::span[@class="mtext"]');
- defineRule(
- 'mj-mo-ext', 'default.default',
- '[n] CQFextender', 'self::span[@class="mo"]',
- './*[1]/*[1]/text()', './*[1]/*[2]/text()');
- defineRule(
- 'mj-texatom', 'default.default',
- '[n] ./*[1]', 'self::span[@class="texatom"]');
-
- // Script elements.
- defineRule(
- 'mj-msubsup', 'default.default',
- '[n] ./*[1]/*[1]/*[1]; [t] "sub"; [n] ./*[1]/*[3]/*[1] (pitch:-0.35);' +
- '[p] (pause:200); [t] "super"; [n] ./*[1]/*[2]/*[1] (pitch:0.35);' +
- '[p] (pause:300)',
- 'self::span[@class="msubsup"]');
- defineRule(
- 'mj-msub', 'default.default',
- '[n] ./*[1]/*[1]/*[1]; [t] "sub";' +
- '[n] ./*[1]/*[2]/*[1] (pitch:-0.35); [p] (pause:300)',
- 'self::span[@class="msub"]');
- defineRule(
- 'mj-msup', 'default.default',
- '[n] ./*[1]/*[1]/*[1]; [t] "super";' +
- '[n] ./*[1]/*[2]/*[1] (pitch:0.35); [p] (pause:300)',
- 'self::span[@class="msup"]');
- defineRule(
- 'mj-munderover', 'default.default',
- '[n] ./*[1]/*[2]/*[1] (pitch:0.35); [t] "under and";' +
- '[n] ./*[1]/*[3]/*[1] (pitch:-0.35); [t] "over";' +
- '[n] ./*[1]/*[1]/*[1]; [p] (pause:400)',
- 'self::span[@class="munderover"]');
- defineRule(
- 'mj-munder', 'default.default',
- '[n] ./*[1]/*[2]/*[1] (pitch:0.35); [t] "under";' +
- '[n] ./*[1]/*[1]/*[1]; [p] (pause:400)',
- 'self::span[@class="munder"]');
- defineRule(
- 'mj-mover', 'default.default',
- '[n] ./*[1]/*[2]/*[1] (pitch:0.35); [t] "over";' +
- '[n] ./*[1]/*[1]/*[1]; [p] (pause:400)',
- 'self::span[@class="mover"]');
-
-
- // Layout elements.
- defineRule(
- 'mj-mfrac', 'default.default',
- '[p] (pause:250); [n] ./*[1]/*[1]/*[1] (pitch:0.3); [p] (pause:250);' +
- ' [t] "divided by"; [n] ./*[1]/*[2]/*[1] (pitch:-0.3);' +
- '[p] (pause:400)',
- 'self::span[@class="mfrac"]');
- defineRule(
- 'mj-msqrt', 'default.default',
- '[t] "Square root of";' +
- '[n] ./*[1]/*[1]/*[1] (rate:0.2); [p] (pause:400)',
- 'self::span[@class="msqrt"]');
- defineRule(
- 'mj-mroot', 'default.default',
- '[t] "root of order"; [n] ./*[1]/*[4]/*[1]; [t] "of";' +
- '[n] ./*[1]/*[1]/*[1] (rate:0.2); [p] (pause:400)',
- 'self::span[@class="mroot"]');
-
- defineRule(
- 'mj-mfenced', 'default.default',
- '[t] "opening"; [n] ./*[1]; ' +
- '[m] ./*[position()>1 and position()<last()];' +
- ' [t] "closing"; [n] ./*[last()]',
- 'self::span[@class="mfenced"]');
-
- // Mtable short rules.
- defineRuleAlias('mj-leaf', 'self::span[@class="mtable"]');
- // Mmultiscripts rules.
- defineRuleAlias('mj-leaf', 'self::span[@class="mmultiscripts"]');
-};
-
-
-/**
- * Initialize mathJax Aliases
- * @private
- */
-cvox.MathmlStoreRules.initAliases_ = function() {
- // Space elements
- defineRuleAlias('mspace', 'self::span[@class="mspace"]');
- defineRuleAlias('mstyle', 'self::span[@class="mstyle"]');
- defineRuleAlias('mpadded', 'self::span[@class="mpadded"]');
- defineRuleAlias('merror', 'self::span[@class="merror"]');
- defineRuleAlias('mphantom', 'self::span[@class="mphantom"]');
-
- // Token elements.
- defineRuleAlias('ms', 'self::span[@class="ms"]');
-
- // Layout elements.
- defineRuleAlias('mrow', 'self::span[@class="mrow"]');
-
- // The following rules fix bugs in MathJax's LaTeX translation.
- defineRuleAlias(
- 'mj-msub', 'self::span[@class="msubsup"]', 'CQFmathmlmsub');
-
- defineRuleAlias(
- 'mj-msup', 'self::span[@class="msubsup"]', 'CQFmathmlmsup');
-
- defineRuleAlias(
- 'mj-munder', 'self::span[@class="munderover"]', 'CQFmathmlmunder');
-
- defineRuleAlias(
- 'mj-mover', 'self::span[@class="munderover"]', 'CQFmathmlmover');
-};
-
-
-/**
- * Initialize specializations wrt. content of nodes.
- * @private
- */
-cvox.MathmlStoreRules.initSpecializationRules_ = function() {
- // Some special nodes for square and cube.
- // MathML
- defineRule(
- 'square', 'default.default',
- '[n] ./*[1]; [t] "square" (pitch:0.35); [p] (pause:300)',
- 'self::mathml:msup', './*[2][text()=2]');
- defineRuleAlias(
- 'square', 'self::mathml:msup',
- './mathml:mrow=./*[2]', 'count(./*[2]/*)=1', './*[2]/*[1][text()=2]');
-
- defineRule(
- 'cube', 'default.default',
- '[n] ./*[1]; [t] "cube" (pitch:0.35); [p] (pause:300)',
- 'self::mathml:msup', './*[2][text()=3]');
- defineRuleAlias(
- 'cube', 'self::mathml:msup',
- './mathml:mrow=./*[2]', 'count(./*[2]/*)=1', './*[2]/*[1][text()=3]');
-
- defineRule(
- 'square-sub', 'default.default',
- '[n] ./*[1]; [t] "sub"; [n] ./*[2] (pitch:-0.35);' +
- '[p] (pause:300); [t] "square" (pitch:0.35); [p] (pause:400)',
- 'self::mathml:msubsup', './*[3][text()=2]');
- defineRuleAlias(
- 'square-sub', 'self::mathml:msubsup',
- './mathml:mrow=./*[3]', 'count(./*[3]/*)=1', './*[3]/*[1][text()=2]');
-
- defineRule(
- 'cube-sub', 'default.default',
- '[n] ./*[1]; [t] "sub"; [n] ./*[2] (pitch:-0.35);' +
- '[p] (pause:300); [t] "cube" (pitch:0.35); [p] (pause:400)',
- 'self::mathml:msubsup', './*[3][text()=3]');
- defineRuleAlias(
- 'cube-sub', 'self::mathml:msubsup',
- './mathml:mrow=./*[3]', 'count(./*[3]/*)=1', './*[3]/*[1][text()=3]');
-
- // MathJax
- defineRule(
- 'mj-square', 'default.default',
- '[n] ./*[1]/*[1]/*[1]; [t] "square" (pitch:0.35); [p] (pause:300)',
- 'self::span[@class="msup"]', './*[1]/*[2]/*[1][text()=2]');
- defineRuleAlias(
- 'mj-square', 'self::span[@class="msup"]',
- './*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',
- 'count(./*[1]/*[2]/*[1]/*)=1', './*[1]/*[2]/*[1]/*[1][text()=2]');
- defineRuleAlias(
- 'mj-square', 'self::span[@class="msubsup"]', 'CQFmathmlmsup',
- './*[1]/*[2]/*[1][text()=2]');
- defineRuleAlias(
- 'mj-square', 'self::span[@class="msubsup"]', 'CQFmathmlmsup',
- './*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',
- 'count(./*[1]/*[2]/*[1]/*)=1', './*[1]/*[2]/*[1]/*[1][text()=2]');
-
- defineRule(
- 'mj-cube', 'default.default',
- '[n] ./*[1]/*[1]/*[1]; [t] "cube" (pitch:0.35); [p] (pause:300)',
- 'self::span[@class="msup"]', './*[1]/*[2]/*[1][text()=3]');
- defineRuleAlias(
- 'mj-cube', 'self::span[@class="msup"]',
- './*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',
- 'count(./*[1]/*[2]/*[1]/*)=1', './*[1]/*[2]/*[1]/*[1][text()=3]');
- defineRuleAlias(
- 'mj-cube', 'self::span[@class="msubsup"]', 'CQFmathmlmsup',
- './*[1]/*[2]/*[1][text()=3]');
- defineRuleAlias(
- 'mj-cube', 'self::span[@class="msubsup"]', 'CQFmathmlmsup',
- './*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',
- 'count(./*[1]/*[2]/*[1]/*)=1', './*[1]/*[2]/*[1]/*[1][text()=3]');
-
- defineRule(
- 'mj-square-sub', 'default.default',
- '[n] ./*[1]/*[1]/*[1]; [t] "sub"; [n] ./*[1]/*[3]/*[1] (pitch:-0.35); ' +
- '[p] (pause:300); [t] "square" (pitch:0.35); [p] (pause:400)',
- 'self::span[@class="msubsup"]', './*[1]/*[2]/*[1][text()=2]');
- defineRuleAlias(
- 'mj-square-sub', 'self::span[@class="msubsup"]',
- './*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',
- 'count(./*[1]/*[2]/*[1]/*)=1', './*[1]/*[2]/*[1]/*[1][text()=2]');
-
- defineRule(
- 'mj-cube-sub', 'default.default',
- '[n] ./*[1]/*[1]/*[1]; [t] "sub"; [n] ./*[1]/*[3]/*[1] (pitch:-0.35); ' +
- '[p] (pause:300); [t] "cube" (pitch:0.35); [p] (pause:400)',
- 'self::span[@class="msubsup"]', './*[1]/*[2]/*[1][text()=3]');
- defineRuleAlias(
- 'mj-cube-sub', 'self::span[@class="msubsup"]',
- './*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',
- 'count(./*[1]/*[2]/*[1]/*)=1', './*[1]/*[2]/*[1]/*[1][text()=3]');
-};
-
-
-/**
- * Initialize mathJax Aliases
- * @private
- */
-cvox.MathmlStoreRules.initSemanticRules_ = function() {
- // Initial rule
- defineRule(
- 'stree', 'default.default',
- '[n] ./*[1]', 'self::stree');
-
- defineRule(
- 'multrel', 'default.default',
- '[t] "multirelation"; [m] children/* (sepFunc:CTXFcontentIterator)',
- 'self::multirel');
-
- defineRule(
- 'variable-equality', 'default.default',
- '[t] "equation sequence"; [m] ./children/* ' +
- '(context:"part",ctxtFunc:CTXFnodeCounter,separator:./text())',
- 'self::relseq[@role="equality"]', 'count(./children/*)>2',
- './children/punct[@role="ellipsis"]');// Make that better!
-
- defineRule(
- 'multi-equality', 'default.default',
- '[t] "equation sequence"; [m] ./children/* ' +
- '(context:"part",ctxtFunc:CTXFnodeCounter,separator:./text())',
- 'self::relseq[@role="equality"]', 'count(./children/*)>2');
-
- defineRule(
- 'multi-equality', 'default.short',
- '[t] "equation sequence"; [m] ./children/* ' +
- '(separator:./text())',
- 'self::relseq[@role="equality"]', 'count(./children/*)>2');
-
- defineRule(
- 'equality', 'default.default',
- '[t] "equation"; [t] "left hand side"; [n] children/*[1];' +
- '[p] (pause:200); [n] text() (pause:200);' +
- '[t] "right hand side"; [n] children/*[2]',
- 'self::relseq[@role="equality"]', 'count(./children/*)=2');
-
- defineRule(
- 'simple-equality', 'default.default',
- '[n] children/*[1]; [p] (pause:200); [n] text() (pause:200);' +
- '[n] children/*[2]',
- 'self::relseq[@role="equality"]', 'count(./children/*)=2',
- './children/identifier or ./children/number');
-
- defineRule(
- 'simple-equality2', 'default.default',
- '[n] children/*[1]; [p] (pause:200); [n] text() (pause:200);' +
- '[n] children/*[2]',
- 'self::relseq[@role="equality"]', 'count(./children/*)=2',
- './children/function or ./children/appl');
-
- defineRule(
- 'multrel', 'default.default',
- '[m] children/* (separator:./text())',
- 'self::relseq');
-
- defineRule(
- 'binary-operation', 'default.default',
- '[m] children/* (separator:text());',
- 'self::infixop');
-
- defineRule(
- 'variable-addition', 'default.default',
- '[t] "sum with variable number of summands";' +
- '[p] (pause:400); [m] children/* (separator:./text())',
- 'self::infixop[@role="addition"]', 'count(children/*)>2',
- 'children/punct[@role="ellipsis"]');// Make that better!
-
- defineRule(
- 'multi-addition', 'default.default',
- '[t] "sum with,"; [t] count(./children/*); [t] ", summands";' +
- '[p] (pause:400); [m] ./children/* (separator:./text())',
- 'self::infixop[@role="addition"]', 'count(./children/*)>2');
-
- // Prefix Operator
- defineRule(
- 'prefix', 'default.default',
- '[t] "prefix"; [n] text(); [t] "of" (pause 150);' +
- '[n] children/*[1]',
- 'self::prefixop');
-
- defineRule(
- 'negative', 'default.default',
- '[t] "negative"; [n] children/*[1]',
- 'self::prefixop', 'self::prefixop[@role="negative"]');
-
- // Postfix Operator
- defineRule(
- 'postfix', 'default.default',
- '[n] children/*[1]; [t] "postfix"; [n] text() (pause 300)',
- 'self::postfixop');
-
- defineRule(
- 'identifier', 'default.default',
- '[n] text()', 'self::identifier');
-
- defineRule(
- 'number', 'default.default',
- '[n] text()', 'self::number');
-
- defineRule(
- 'fraction', 'default.default',
- '[p] (pause:250); [n] children/*[1] (pitch:0.3); [p] (pause:250);' +
- ' [t] "divided by"; [n] children/*[2] (pitch:-0.3); [p] (pause:400)',
- 'self::fraction');
-
- defineRule(
- 'superscript', 'default.default',
- '[n] children/*[1]; [t] "super"; [n] children/*[2] (pitch:0.35);' +
- '[p] (pause:300)',
- 'self::superscript');
- defineRule(
- 'subscript', 'default.default',
- '[n] children/*[1]; [t] "sub"; [n] children/*[2] (pitch:-0.35);' +
- '[p] (pause:300)',
- 'self::subscript');
-
- defineRule(
- 'ellipsis', 'default.default',
- '[p] (pause:200); [t] "dot dot dot"; [p] (pause:300)',
- 'self::punct', 'self::punct[@role="ellipsis"]');
-
- defineRule(
- 'fence-single', 'default.default',
- '[n] text()',
- 'self::punct', 'self::punct[@role="openfence"]');
- defineRuleAlias('fence-single', 'self::punct',
- 'self::punct[@role="closefence"]');
- defineRuleAlias('fence-single', 'self::punct',
- 'self::punct[@role="vbar"]');
- defineRuleAlias('fence-single', 'self::punct',
- 'self::punct[@role="application"]');
-
- // TODO (sorge) Refine punctuations further.
- defineRule(
- 'omit-punct', 'default.default',
- '[p] (pause:200);',
- 'self::punct');
-
- defineRule(
- 'omit-empty', 'default.default',
- '',
- 'self::empty');
-
- // Fences rules.
- defineRule(
- 'fences-open-close', 'default.default',
- '[p] (pause:100); [t] "open"; [n] children/*[1]; [p] (pause:200);' +
- '[t] "close"',
- 'self::fenced[@role="leftright"]');
-
- defineRule(
- 'fences-open-close-in-appl', 'default.default',
- '[p] (pause:100); [n] children/*[1]; [p] (pause:200);',
- 'self::fenced[@role="leftright"]', './parent::children/parent::appl');
-
- defineRule(
- 'fences-neutral', 'default.default',
- '[p] (pause:100); [t] "absolute value of"; [n] children/*[1];' +
- '[p] (pause:350);',
- 'self::fenced', 'self::fenced[@role="neutral"]');
-
- defineRule(
- 'omit-fences', 'default.default',
- '[p] (pause:500); [n] children/*[1]; [p] (pause:200);',
- 'self::fenced');
-
- // Matrix rules.
- defineRule(
- 'matrix', 'default.default',
- '[t] "matrix"; [m] children/* ' +
- '(ctxtFunc:CTXFnodeCounter,context:"row",pause:100)',
- 'self::matrix');
-
- defineRule(
- 'matrix-row', 'default.default',
- '[m] children/* (ctxtFunc:CTXFnodeCounter,context:"column",pause:100)',
- 'self::row[@role="matrix"]');
-
- defineRule(
- 'matrix-cell', 'default.default',
- '[n] children/*[1]', 'self::cell[@role="matrix"]');
-
- // Vector rules.
- defineRule(
- 'vector', 'default.default',
- '[t] "vector"; [m] children/* ' +
- '(ctxtFunc:CTXFnodeCounter,context:"element",pause:100)',
- 'self::vector');
-
- // Cases rules.
- defineRule(
- 'cases', 'default.default',
- '[t] "case statement"; [m] children/* ' +
- '(ctxtFunc:CTXFnodeCounter,context:"case",pause:100)',
- 'self::cases');
-
- defineRule(
- 'cases-row', 'default.default',
- '[m] children/*', 'self::row[@role="cases"]');
-
- defineRule(
- 'cases-cell', 'default.default',
- '[n] children/*[1]', 'self::cell[@role="cases"]');
-
- defineRule(
- 'row', 'default.default',
- '[m] ./* (ctxtFunc:CTXFnodeCounter,context:"column",pause:100)',
- 'self::row"');
-
- defineRule(
- 'cases-end', 'default.default',
- '[t] "case statement"; ' +
- '[m] children/* (ctxtFunc:CTXFnodeCounter,context:"case",pause:100);' +
- '[t] "end cases"',
- 'self::cases', 'following-sibling::*');
-
- // Multiline rules.
- defineRule(
- 'multiline', 'default.default',
- '[t] "multiline equation";' +
- '[m] children/* (ctxtFunc:CTXFnodeCounter,context:"line",pause:100)',
- 'self::multiline');
-
- defineRule(
- 'line', 'default.default',
- '[m] children/*', 'self::line');
-
- // Table rules.
- defineRule(
- 'table', 'default.default',
- '[t] "multiline equation";' +
- '[m] children/* (ctxtFunc:CTXFnodeCounter,context:"row",pause:200)',
- 'self::table');
-
- defineRule(
- 'table-row', 'default.default',
- '[m] children/* (pause:100)', 'self::row[@role="table"]');
-
- defineRuleAlias(
- 'cases-cell', 'self::cell[@role="table"]');
-
-
- // Rules for punctuated expressions.
- defineRule(
- 'end-punct', 'default.default',
- '[m] children/*; [p] (pause:300)',
- 'self::punctuated', '@role="endpunct"');
-
- defineRule(
- 'start-punct', 'default.default',
- '[n] content/*[1]; [p] (pause:200); [m] children/*',
- 'self::punctuated', '@role="startpunct"');
-
- defineRule(
- 'integral-punct', 'default.default',
- '[n] children/*[1] (rate:0.2); [n] children/*[3] (rate:0.2)',
- 'self::punctuated', '@role="integral"');
-
- defineRule(
- 'punctuated', 'default.default',
- '[m] children/* (pause:100)',
- 'self::punctuated');
-
- // Function rules
- defineRule(
- 'function', 'default.default',
- '[n] text()', 'self::function');
-
- defineRule(
- 'appl', 'default.default',
- '[n] children/*[1]; [n] content/*[1]; [n] children/*[2]', 'self::appl');
-
- // Limit operator rules
- defineRule(
- 'limboth', 'default.default',
- '[n] children/*[1]; [t] "from"; [n] children/*[2]; [t] "to";' +
- '[n] children/*[3]', 'self::limboth');
-
- defineRule(
- 'sum-only', 'default.default',
- '[n] children/*[1]; [p] (pause 100); [t] "over"; [n] children/*[2];' +
- '[p] (pause 250);',
- 'self::limboth', 'self::limboth[@role="sum"]');
-
- defineRule(
- 'limlower', 'default.default',
- '[n] children/*[1]; [t] "over"; [n] children/*[2];', 'self::limlower');
-
- defineRule(
- 'limupper', 'default.default',
- '[n] children/*[1]; [t] "under"; [n] children/*[2];', 'self::limupper');
-
- // Bigoperator rules
- defineRule(
- 'largeop', 'default.default',
- '[n] text()', 'self::largeop');
-
- defineRule(
- 'bigop', 'default.default',
- '[n] children/*[1]; [p] (pause 100); [t] "over"; [n] children/*[2];' +
- '[p] (pause 250);',
- 'self::bigop');
-
-
- // Integral rules
- defineRule(
- 'integral', 'default.default',
- '[n] children/*[1]; [p] (pause 100); [n] children/*[2]; [p] (pause 200);' +
- '[n] children/*[3] (rate:0.35);', 'self::integral');
-
-
- defineRule(
- 'sqrt', 'default.default',
- '[t] "Square root of"; [n] children/*[1] (rate:0.2); [p] (pause:400)',
- 'self::sqrt');
-
- defineRule(
- 'square', 'default.default',
- '[n] children/*[1]; [t] "square" (pitch:0.35); [p] (pause:300)',
- 'self::superscript', 'children/*[2][text()=2]');
-
- defineRule(
- 'text-no-mult', 'default.default',
- '[n] children/*[1]; [p] (pause:200); [n] children/*[2]',
- 'self::infixop', 'children/text');
-};
-
-}); // goog.scope
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store_util.js
deleted file mode 100644
index 7c1d4010d86..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/mathml_store_util.js
+++ /dev/null
@@ -1,177 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Utility functions for mathml and mathjax rule store.
- */
-
-goog.provide('cvox.MathmlStoreUtil');
-
-goog.require('cvox.MathUtil');
-goog.require('cvox.TraverseMath');
-
-
-/**
- * Retrieves MathML sub element with same id as MathJax node.
- * @param {!Node} inner A node internal to a MathJax node.
- * @return {Node} The internal MathML node corresponding to the MathJax node.
- */
-cvox.MathmlStoreUtil.matchMathjaxToMathml = function(inner) {
- var mml = cvox.TraverseMath.getInstance().activeMathmlHost;
- return mml.querySelector('#' + inner.id);
-};
-
-
-/**
- * Retrieve an extender symbol for a given node.
- * @param {!Node} jax The MathJax node.
- * @return {Array<Node>} The resulting node list.
- */
-cvox.MathmlStoreUtil.retrieveMathjaxExtender = function(jax) {
- var ext = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax);
- if (ext) {
- return [ext];
- }
- return [];
-};
-
-
-/**
- * Retrieve an extender symbol for a given node.
- * @param {!Node} jax The MathJax node.
- * @return {Array<Node>} The resulting node list.
- */
-cvox.MathmlStoreUtil.retrieveMathjaxLeaf = function(jax) {
- var leaf = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax);
- if (leaf) {
- return [leaf];
- }
- return [];
-};
-
-
-/**
- * For a given MathJax node it returns the equivalent MathML node,
- * if it is of the right tag.
- * @param {!Node} jax The Mathjax node.
- * @param {!string} tag The required tag.
- * @return {Array<Node>} The resulting node list.
- */
-cvox.MathmlStoreUtil.checkMathjaxTag = function(jax, tag) {
- var node = cvox.MathmlStoreUtil.matchMathjaxToMathml(jax);
- if (node && node.tagName.toUpperCase() == tag) {
- return [node];
- }
- return [];
-};
-
-
-/**
- * Returns MathML node if MathJax is munder.
- * @param {!Node} jax The Mathjax node.
- * @return {Array<Node>} The resulting node list.
- */
-cvox.MathmlStoreUtil.checkMathjaxMunder = function(jax) {
- return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MUNDER');
-};
-
-
-/**
- * Returns MathML node if MathJax is mover.
- * @param {!Node} jax The Mathjax node.
- * @return {Array<Node>} The resulting node list.
- */
-cvox.MathmlStoreUtil.checkMathjaxMover = function(jax) {
- return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MOVER');
-};
-
-
-/**
- * Returns MathML node if MathJax is msub.
- * @param {!Node} jax The Mathjax node.
- * @return {Array<Node>} The resulting node list.
- */
-cvox.MathmlStoreUtil.checkMathjaxMsub = function(jax) {
- return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MSUB');
-};
-
-
-/**
- * Returns MathML node if MathJax is msup.
- * @param {!Node} jax The Mathjax node.
- * @return {Array<Node>} The resulting node list.
- */
-cvox.MathmlStoreUtil.checkMathjaxMsup = function(jax) {
- return cvox.MathmlStoreUtil.checkMathjaxTag(jax, 'MSUP');
-};
-
-
-/**
- * Constructs a closure that returns separators for an MathML mfenced
- * expression.
- * Separators in MathML are represented by a list and used up one by one
- * until the final element is used as the default.
- * Example: a b c d e and separators [+,-,*]
- * would result in a + b - c * d * e.
- * @param {string} separators String representing a list of mfenced separators.
- * @return {function(): string|null} A closure that returns the next separator
- * for an mfenced expression starting with the first node in nodes.
- */
-cvox.MathmlStoreUtil.nextSeparatorFunction = function(separators) {
- if (separators) {
- // Mathjax does not expand empty separators.
- if (separators.match(/^\s+$/)) {
- return null;
- } else {
- var sepList = separators.replace(/\s/g, '')
- .split('')
- .filter(function(x) {return x;});
- }
- } else {
- // When no separator is given MathML uses comma as default.
- var sepList = [','];
- }
-
- return function() {
- if (sepList.length > 1) {
- return sepList.shift();
- }
- return sepList[0];
- };
-};
-
-
-/**
- * Computes the correct separators for each node.
- * @param {Array<Node>} nodes A node array.
- * @param {string} context A context string.
- * @return {function(): string} A closure that returns the next separator for an
- * mfenced expression starting with the first node in nodes.
- */
-cvox.MathmlStoreUtil.mfencedSeparators = function(nodes, context) {
- var nextSeparator = cvox.MathmlStoreUtil.nextSeparatorFunction(context);
- return function() {
- return nextSeparator ? nextSeparator() : '';
- };
-};
-
-
-/**
- * Iterates over the list of content nodes of the parent of the given nodes.
- * @param {Array<Node>} nodes A node array.
- * @param {string} context A context string.
- * @return {function(): string} A closure that returns the content of the next
- * content node. Returns only context string if list is exhausted.
- */
-cvox.MathmlStoreUtil.contentIterator = function(nodes, context) {
- if (nodes.length > 0) {
- var contentNodes = cvox.XpathUtil.evalXPath('../../content/*', nodes[0]);
- } else {
- var contentNodes = [];
- }
- return function() {
- var content = contentNodes.shift();
- return context + (content ? content.textContent : '');
- };
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule.js
deleted file mode 100644
index cf07c6bf502..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule.js
+++ /dev/null
@@ -1,379 +0,0 @@
-// 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.
-
-/**
- * @fileoverview An interface definition of a speech rule.
- *
- * A speech rule is a data structure along with supporting methods that
- * stipulates how to transform a tree structure such as XML, a browser DOM, or
- * HTML into a format (usually strings) suitable for rendering by a
- * text-to-speech engine.
- *
- * Speech rules consists of a variable number of speech rule components. Each
- * component describes how to construct a single utterance. Text-to-speech
- * renders the components in order.
- */
-
-goog.provide('cvox.SpeechRule');
-goog.provide('cvox.SpeechRule.Action');
-goog.provide('cvox.SpeechRule.Component');
-goog.provide('cvox.SpeechRule.DynamicCstr');
-goog.provide('cvox.SpeechRule.Precondition');
-goog.provide('cvox.SpeechRule.Type');
-
-
-/**
- * Creates a speech rule with precondition, actions and admin information.
- * @constructor
- * @param {string} name The name of the rule.
- * @param {cvox.SpeechRule.DynamicCstr} dynamic Dynamic constraint annotations
- * of the rule.
- * @param {cvox.SpeechRule.Precondition} prec Precondition of the rule.
- * @param {cvox.SpeechRule.Action} action Action of the speech rule.
- */
-cvox.SpeechRule = function(name, dynamic, prec, action) {
- /** @type {string} */
- this.name = name;
- /** @type {cvox.SpeechRule.DynamicCstr} */
- this.dynamicCstr = dynamic;
- /** @type {cvox.SpeechRule.Precondition} */
- this.precondition = prec;
- /** @type {cvox.SpeechRule.Action} */
- this.action = action;
-};
-
-
-/**
- *
- * @override
- */
-cvox.SpeechRule.prototype.toString = function() {
- var cstrStrings = [];
- for (var key in this.dynamicCstr) {
- cstrStrings.push(this.dynamicCstr[key]);
- }
- return this.name + ' | ' + cstrStrings.join('.') + ' | ' +
- this.precondition.toString() + ' ==> ' +
- this.action.toString();
-};
-
-
-/**
- * Mapping for types of speech rule components.
- * @enum {string}
- */
-cvox.SpeechRule.Type = {
- NODE: 'NODE',
- MULTI: 'MULTI',
- TEXT: 'TEXT',
- PERSONALITY: 'PERSONALITY'
-};
-
-
-/**
- * Maps a string to a valid speech rule type.
- * @param {string} str Input string.
- * @return {cvox.SpeechRule.Type}
- */
-cvox.SpeechRule.Type.fromString = function(str) {
- switch (str) {
- case '[n]': return cvox.SpeechRule.Type.NODE;
- case '[m]': return cvox.SpeechRule.Type.MULTI;
- case '[t]': return cvox.SpeechRule.Type.TEXT;
- case '[p]': return cvox.SpeechRule.Type.PERSONALITY;
- default: throw 'Parse error: ' + str;
- }
-};
-
-
-/**
- * Maps a speech rule type to a human-readable string.
- * @param {cvox.SpeechRule.Type} speechType
- * @return {string} Output string.
- */
-cvox.SpeechRule.Type.toString = function(speechType) {
- switch (speechType) {
- case cvox.SpeechRule.Type.NODE: return '[n]';
- case cvox.SpeechRule.Type.MULTI: return '[m]';
- case cvox.SpeechRule.Type.TEXT: return '[t]';
- case cvox.SpeechRule.Type.PERSONALITY: return '[p]';
- default: throw 'Unknown type error: ' + speechType;
- }
-};
-
-
-/**
- * Defines a component within a speech rule.
- * @param {{type: cvox.SpeechRule.Type, content: string}} kwargs The input
- * component in JSON format.
- * @constructor
- */
-cvox.SpeechRule.Component = function(kwargs) {
- /** @type {cvox.SpeechRule.Type} */
- this.type = kwargs.type;
-
- /** @type {string} */
- this.content = kwargs.content;
-};
-
-
-/**
- * Parses a valid string representation of a speech component into a Component
- * object.
- * @param {string} input The input string.
- * @return {cvox.SpeechRule.Component} The resulting component.
- */
-cvox.SpeechRule.Component.fromString = function(input) {
- // The output JSON.
- var output = {};
-
- // Parse the type.
- output.type = cvox.SpeechRule.Type.fromString(input.substring(0, 3));
-
- // Prep the rest of the parsing.
- var rest = input.slice(3).trimLeft();
- if (!rest) {
- throw new cvox.SpeechRule.OutputError('Missing content.');
- }
-
- switch (output.type) {
- case cvox.SpeechRule.Type.TEXT:
- if (rest[0] == '"') {
- var quotedString = cvox.SpeechRule.splitString_(rest, '\\(')[0].trim();
- if (quotedString.slice(-1) != '"') {
- throw new cvox.SpeechRule.OutputError('Invalid string syntax.');
- }
- output.content = quotedString;
- rest = rest.slice(quotedString.length).trim();
- if (rest.indexOf('(') == -1) {
- rest = '';
- }
- // This break is conditional. If the content is not an explicit string,
- // it can be treated like node and multi type.
- break;
- }
- case cvox.SpeechRule.Type.NODE:
- case cvox.SpeechRule.Type.MULTI:
- var bracket = rest.indexOf(' (');
- if (bracket == -1) {
- output.content = rest.trim();
- rest = '';
- break;
- }
- output.content = rest.substring(0, bracket).trim();
- rest = rest.slice(bracket).trimLeft();
- break;
- }
- output = new cvox.SpeechRule.Component(output);
- if (rest) {
- output.addAttributes(rest);
- }
- return output;
-};
-
-
-/**
- * @override
- */
-cvox.SpeechRule.Component.prototype.toString = function() {
- var strs = '';
- strs += cvox.SpeechRule.Type.toString(this.type);
- strs += this.content ? ' ' + this.content : '';
- var attribs = this.getAttributes();
- if (attribs.length > 0) {
- strs += ' (' + attribs.join(', ') + ')';
- }
- return strs;
-};
-
-
-/**
- * Adds a single attribute to the component.
- * @param {string} attr String representation of an attribute.
- */
-cvox.SpeechRule.Component.prototype.addAttribute = function(attr) {
- var colon = attr.indexOf(':');
- if (colon == -1) {
- this[attr.trim()] = 'true';
- } else {
- this[attr.substring(0, colon).trim()] = attr.slice(colon + 1).trim();
- }
-};
-
-
-/**
- * Adds a list of attributes to the component.
- * @param {string} attrs String representation of attribute list.
- */
-cvox.SpeechRule.Component.prototype.addAttributes = function(attrs) {
- if (attrs[0] != '(' || attrs.slice(-1) != ')') {
- throw new cvox.SpeechRule.OutputError(
- 'Invalid attribute expression: ' + attrs);
- }
- var attribs = cvox.SpeechRule.splitString_(attrs.slice(1, -1), ',');
- for (var i = 0; i < attribs.length; i++) {
- this.addAttribute(attribs[i]);
- }
-};
-
-
-/**
- * Transforms the attributes of an object into a list of strings.
- * @return {Array<string>} List of translated attribute:value strings.
- */
-cvox.SpeechRule.Component.prototype.getAttributes = function() {
- var attribs = [];
- for (var key in this) {
- if (key != 'content' && key != 'type' && typeof(this[key]) != 'function') {
- attribs.push(key + ':' + this[key]);
- }
- }
- return attribs;
-};
-
-
-/**
- * A speech rule is a collection of speech components.
- * @param {Array<cvox.SpeechRule.Component>} components The input rule.
- * @constructor
- */
-cvox.SpeechRule.Action = function(components) {
- /** @type {Array<cvox.SpeechRule.Component>} */
- this.components = components;
-};
-
-
-/**
- * Parses an input string into a speech rule class object.
- * @param {string} input The input string.
- * @return {cvox.SpeechRule.Action} The resulting object.
- */
-cvox.SpeechRule.Action.fromString = function(input) {
- var comps = cvox.SpeechRule.splitString_(input, ';')
- .filter(function(x) {return x.match(/\S/);})
- .map(function(x) {return x.trim();});
- var newComps = [];
- for (var i = 0; i < comps.length; i++) {
- var comp = cvox.SpeechRule.Component.fromString(comps[i]);
- if (comp) {
- newComps.push(comp);
- }
- }
-return new cvox.SpeechRule.Action(newComps);
-};
-
-
-/**
- * @override
- */
-cvox.SpeechRule.Action.prototype.toString = function() {
- var comps = this.components.map(function(c) { return c.toString(); });
- return comps.join('; ');
-};
-
-
-// TODO (sorge) Separatation of xpath expressions and custom functions.
-// Also test validity of xpath expressions.
-/**
- * Constructs a valid precondition for a speech rule.
- * @param {string} query A node selector function or xpath expression.
- * @param {Array<string>=} opt_constraints A list of constraint functions.
- * @constructor
- */
-cvox.SpeechRule.Precondition = function(query, opt_constraints) {
- /** @type {string} */
- this.query = query;
-
- /** @type {!Array<string>} */
- this.constraints = opt_constraints || [];
-};
-
-
-/**
- * @override
- */
-cvox.SpeechRule.Precondition.prototype.toString = function() {
- var constrs = this.constraints.join(', ');
- return this.query + ', ' + constrs;
-};
-
-
-/**
- * Split a string wrt. a given separator symbol while not splitting inside of a
- * double quoted string. For example, splitting
- * '[t] "matrix; 3 by 3"; [n] ./*[1]' with separators ';' would yield
- * ['[t] "matrix; 3 by 3"', ' [n] ./*[1]'].
- * @param {string} str String to be split.
- * @param {string} sep Separator symbol.
- * @return {Array<string>} A list of single component strings.
- * @private
- */
-cvox.SpeechRule.splitString_ = function(str, sep) {
- var strList = [];
- var prefix = '';
-
- while (str != '') {
- var sepPos = str.search(sep);
- if (sepPos == -1) {
- if ((str.match(/"/g) || []).length % 2 != 0) {
- throw new cvox.SpeechRule.OutputError(
- 'Invalid string in expression: ' + str);
- }
- strList.push(prefix + str);
- prefix = '';
- str = '';
- } else if (
- (str.substring(0, sepPos).match(/"/g) || []).length % 2 == 0) {
- strList.push(prefix + str.substring(0, sepPos));
- prefix = '';
- str = str.substring(sepPos + 1);
- } else {
- var nextQuot = str.substring(sepPos).search('"');
- if (nextQuot == -1) {
- throw new cvox.SpeechRule.OutputError(
- 'Invalid string in expression: ' + str);
- } else {
- prefix = prefix + str.substring(0, sepPos + nextQuot + 1);
- str = str.substring(sepPos + nextQuot + 1);
- }
- }
- }
- if (prefix) {
- strList.push(prefix);
- }
- return strList;
-};
-
-
-/**
- * Attributes for dynamic constraints.
- * We define one default attribute as style. Speech rule stores can add other
- * attributes later.
- * @enum {string}
- */
-cvox.SpeechRule.DynamicCstrAttrib =
-{
- STYLE: 'style'
-};
-
-
-/**
- * Dynamic constraints are a means to specialize rules that can be changed
- * dynamically by the user, for example by choosing different styles, etc.
- * @typedef {!Object<cvox.SpeechRule.DynamicCstrAttrib, string>}
- */
-cvox.SpeechRule.DynamicCstr;
-
-
-/**
- * Error object for signaling parsing errors.
- * @param {string} msg The error message.
- * @constructor
- * @extends {Error}
- */
-cvox.SpeechRule.OutputError = function(msg) {
- this.name = 'RuleError';
- this.message = msg || '';
-};
-goog.inherits(cvox.SpeechRule.OutputError, Error);
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_engine.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_engine.js
deleted file mode 100644
index d7be38210ec..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_engine.js
+++ /dev/null
@@ -1,371 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Implementation of the speech rule engine.
- *
- * The speech rule engine chooses and applies speech rules. Rules are chosen
- * from a set of rule stores wrt. their applicability to a node in a particular
- * markup type such as MathML or HTML. Rules are dispatched either by
- * recursively computing new nodes and applicable rules or, if no further rule
- * is applicable to a current node, by computing a speech object in the form of
- * an array of navigation descriptions.
- *
- * Consequently the rule engine is parameterisable wrt. rule stores and
- * evaluator function.
- */
-
-goog.provide('cvox.SpeechRuleEngine');
-
-goog.require('cvox.BaseRuleStore');
-goog.require('cvox.NavDescription');
-goog.require('cvox.NavMathDescription');
-goog.require('cvox.SpeechRule');
-
-
-/**
- * @constructor
- */
-cvox.SpeechRuleEngine = function() {
- /**
- * The currently active speech rule store.
- * @type {cvox.BaseRuleStore}
- * @private
- */
- this.activeStore_ = null;
-
- /**
- * Dynamic constraint annotation.
- * @type {!cvox.SpeechRule.DynamicCstr}
- */
- this.dynamicCstr = {};
- this.dynamicCstr[cvox.SpeechRule.DynamicCstrAttrib.STYLE] = 'short';
-};
-goog.addSingletonGetter(cvox.SpeechRuleEngine);
-
-
-/**
- * Parameterizes the speech rule engine.
- * @param {cvox.BaseRuleStore} store A speech rule store.
- */
-cvox.SpeechRuleEngine.prototype.parameterize = function(store) {
- try {
- store.initialize();
- } catch (err) {
- if (err.name == 'StoreError') {
- console.log('Store Error:', err.message);
- }
- else {
- throw err;
- }
- }
- this.activeStore_ = store;
-};
-
-
-/**
- * Parameterizes the dynamic constraint annotation for the speech rule
- * engine. This is a separate function as this can be done interactively, while
- * a particular speech rule store is active.
- * @param {cvox.SpeechRule.DynamicCstr} dynamic The new dynamic constraint.
- */
-cvox.SpeechRuleEngine.prototype.setDynamicConstraint = function(dynamic) {
- if (dynamic) {
- this.dynamicCstr = dynamic;
- }
-};
-
-
-/**
- * Constructs a string from the node and the given expression.
- * @param {!Node} node The initial node.
- * @param {string} expr An Xpath expression string, a name of a custom
- * function or a string.
- * @return {string} The result of applying expression to node.
- */
-cvox.SpeechRuleEngine.prototype.constructString = function(node, expr) {
- if (!expr) {
- return '';
- }
- if (expr.charAt(0) == '"') {
- return expr.slice(1, -1);
- }
- var func = this.activeStore_.customStrings.lookup(expr);
- if (func) {
- // We always return the result of the custom function, in case it
- // deliberately computes the empty string!
- return func(node);
- }
- // Finally we assume expr to be an xpath expression and calculate a string
- // value from the node.
- return cvox.XpathUtil.evaluateString(expr, node);
-};
-
-
-// Dispatch functionality.
-/**
- * Computes a speech object for a given node. Returns the empty list if
- * no node is given.
- * @param {Node} node The node to be evaluated.
- * @return {!Array<cvox.NavDescription>} A list of navigation descriptions for
- * that node.
- */
-cvox.SpeechRuleEngine.prototype.evaluateNode = function(node) {
- if (!node) {
- return [];
- }
- return this.evaluateTree_(node);
-};
-
-
-/**
- * Applies rules recursively to compute the final speech object.
- * @param {!Node} node Node to apply the speech rule to.
- * @return {!Array<cvox.NavDescription>} A list of Navigation descriptions.
- * @private
- */
-cvox.SpeechRuleEngine.prototype.evaluateTree_ = function(node) {
- var rule = this.activeStore_.lookupRule(node, this.dynamicCstr);
- if (!rule) {
- return this.activeStore_.evaluateDefault(node);
- }
- var components = rule.action.components;
- var result = [];
- for (var i = 0, component; component = components[i]; i++) {
- var navs = [];
- var content = component['content'] || '';
- switch (component.type) {
- case cvox.SpeechRule.Type.NODE:
- var selected = this.activeStore_.applyQuery(node, content);
- if (selected) {
- navs = this.evaluateTree_(selected);
- }
- break;
- case cvox.SpeechRule.Type.MULTI:
- selected = this.activeStore_.applySelector(node, content);
- if (selected.length > 0) {
- navs = this.evaluateNodeList_(
- selected,
- component['sepFunc'],
- this.constructString(node, component['separator']),
- component['ctxtFunc'],
- this.constructString(node, component['context']));
- }
- break;
- case cvox.SpeechRule.Type.TEXT:
- selected = this.constructString(node, content);
- if (selected) {
- navs = [new cvox.NavDescription({text: selected})];
- }
- break;
- case cvox.SpeechRule.Type.PERSONALITY:
- default:
- navs = [new cvox.NavDescription({text: content})];
- }
- // Adding overall context if it exists.
- if (navs[0] && component['context'] &&
- component.type != cvox.SpeechRule.Type.MULTI) {
- navs[0]['context'] =
- this.constructString(node, component['context']) +
- (navs[0]['context'] || '');
- }
- // Adding personality to the nav descriptions.
- result = result.concat(this.addPersonality_(navs, component));
- }
- return result;
-};
-
-
-/**
- * Evaluates a list of nodes into a list of navigation descriptions.
- * @param {!Array<Node>} nodes Array of nodes.
- * @param {string} sepFunc Name of a function used to compute a separator
- * between every element.
- * @param {string} separator A string that is used as argument to the sepFunc or
- * interspersed directly between each node if sepFunc is not supplied.
- * @param {string} ctxtFunc Name of a function applied to compute the context
- * for every element in the list.
- * @param {string} context Additional context string that is given to the
- * ctxtFunc function or used directly if ctxtFunc is not supplied.
- * @return {Array<cvox.NavDescription>} A list of Navigation descriptions.
- * @private
- */
-cvox.SpeechRuleEngine.prototype.evaluateNodeList_ = function(
- nodes, sepFunc, separator, ctxtFunc, context) {
- if (nodes == []) {
- return [];
- }
- var sep = separator || '';
- var cont = context || '';
- var cFunc = this.activeStore_.contextFunctions.lookup(ctxtFunc);
- var ctxtClosure = cFunc ? cFunc(nodes, cont) : function() {return cont;};
- var sFunc = this.activeStore_.contextFunctions.lookup(sepFunc);
- var sepClosure = sFunc ? sFunc(nodes, sep) : function() {return sep;};
- var result = [];
- for (var i = 0, node; node = nodes[i]; i++) {
- var navs = this.evaluateTree_(node);
- if (navs.length > 0) {
- navs[0]['context'] = ctxtClosure() + (navs[0]['context'] || '');
- result = result.concat(navs);
- if (i < nodes.length - 1) {
- var text = sepClosure();
- if (text) {
- result.push(new cvox.NavDescription({text: text}));
- }
- }
- }
- }
- return result;
-};
-
-
-/**
- * Maps properties in speech rules to personality properties.
- * @type {{pitch : string,
- * rate: string,
- * volume: string,
- * pause: string}}
- * @const
- */
-cvox.SpeechRuleEngine.propMap = {'pitch': cvox.AbstractTts.RELATIVE_PITCH,
- 'rate': cvox.AbstractTts.RELATIVE_RATE,
- 'volume': cvox.AbstractTts.RELATIVE_VOLUME,
- 'pause': cvox.AbstractTts.PAUSE
- };
-
-
-/**
- * Adds personality to every Navigation Descriptions in input list.
- * @param {Array<cvox.NavDescription>} navs A list of Navigation descriptions.
- * @param {Object} props Property dictionary.
- * TODO (sorge) Fully specify, when we have finalised the speech rule
- * format.
- * @return {Array<cvox.NavDescription>} The modified array.
- * @private
- */
-cvox.SpeechRuleEngine.prototype.addPersonality_ = function(navs, props) {
- var personality = {};
- for (var key in cvox.SpeechRuleEngine.propMap) {
- var value = parseFloat(props[key]);
- if (!isNaN(value)) {
- personality[cvox.SpeechRuleEngine.propMap[key]] = value;
- }
- }
- navs.forEach(goog.bind(function(nav) {
- this.addRelativePersonality_(nav, personality);
- this.resetPersonality_(nav);
- }, this));
- return navs;
-};
-
-
-/**
- * Adds relative personality entries to the personality of a Navigation
- * Description.
- * @param {cvox.NavDescription|cvox.NavMathDescription} nav Nav Description.
- * @param {!Object} personality Dictionary with relative personality entries.
- * @return {cvox.NavDescription|cvox.NavMathDescription} Updated description.
- * @private
- */
-cvox.SpeechRuleEngine.prototype.addRelativePersonality_ = function(
- nav, personality) {
- if (!nav['personality']) {
- nav['personality'] = personality;
- return nav;
- }
- var navPersonality = nav['personality'];
- for (var p in personality) {
- // Although values could exceed boundaries, they will be limited to the
- // correct interval via the call to
- // cvox.AbstractTts.prototype.mergeProperties in
- // cvox.TtsBackground.prototype.speak
- if (navPersonality[p] && typeof(navPersonality[p]) == 'number') {
- navPersonality[p] = navPersonality[p] + personality[p];
- } else {
- navPersonality[p] = personality[p];
- }
- }
- return nav;
-};
-
-
-/**
- * Resets personalities to default values if necessary.
- * @param {cvox.NavDescription|cvox.NavMathDescription} nav Nav Description.
- * @private
- */
-cvox.SpeechRuleEngine.prototype.resetPersonality_ = function(nav) {
- if (this.activeStore_.defaultTtsProps) {
- for (var i = 0, prop; prop = this.activeStore_.defaultTtsProps[i]; i++) {
- nav.personality[prop] = cvox.ChromeVox.tts.getDefaultProperty(prop);
- }
- }
-};
-
-
-/**
- * Flag for the debug mode of the speech rule engine.
- * @type {boolean}
- */
-cvox.SpeechRuleEngine.debugMode = false;
-
-
-/**
- * Give debug output.
- * @param {...*} output Rest elements of debug output.
- */
-cvox.SpeechRuleEngine.outputDebug = function(output) {
- if (cvox.SpeechRuleEngine.debugMode) {
- var outputList = Array.prototype.slice.call(arguments, 0);
- console.log.apply(console,
- ['Speech Rule Engine Debugger:'].concat(outputList));
- }
-};
-
-
-/**
- * Prints the list of all current rules in ChromeVox to the console.
- * @return {string} A textual representation of all rules in the speech rule
- * engine.
- */
-cvox.SpeechRuleEngine.prototype.toString = function() {
- var allRules = this.activeStore_.findAllRules(function(x) {return true;});
- return allRules.map(function(rule) {return rule.toString();}).
- join('\n');
-};
-
-
-/**
- * Test the precondition of a speech rule in debugging mode.
- * @param {cvox.SpeechRule} rule A speech rule.
- * @param {!Node} node DOM node to test applicability of the rule.
- */
-cvox.SpeechRuleEngine.debugSpeechRule = function(rule, node) {
- var store = cvox.SpeechRuleEngine.getInstance().activeStore_;
- if (store) {
- var prec = rule.precondition;
- cvox.SpeechRuleEngine.outputDebug(
- prec.query, store.applyQuery(node, prec.query));
- prec.constraints.forEach(
- function(cstr) {
- cvox.SpeechRuleEngine.outputDebug(
- cstr, store.applyConstraint(node, cstr));});
- }
-};
-
-
-/**
- * Test the precondition of a speech rule in debugging mode.
- * @param {string} name Rule to debug.
- * @param {!Node} node DOM node to test applicability of the rule.
- */
-cvox.SpeechRuleEngine.debugNamedSpeechRule = function(name, node) {
- var store = cvox.SpeechRuleEngine.getInstance().activeStore_;
- var allRules = store.findAllRules(
- function(rule) {return rule.name == name;});
- for (var i = 0, rule; rule = allRules[i]; i++) {
- cvox.SpeechRuleEngine.outputDebug('Rule', name, 'number', i);
- cvox.SpeechRuleEngine.debugSpeechRule(rule, node);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_evaluator.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_evaluator.js
deleted file mode 100644
index a355c81daf7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_evaluator.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Interface definition for a class which evaluates speech rules.
- *
- * A speech rule evaluator knows how to generate a description given a node and
- * a speech rule.
- */
-
-goog.provide('cvox.SpeechRuleEvaluator');
-
-goog.require('cvox.SpeechRule');
-
-
-/**
- * @interface
- */
-cvox.SpeechRuleEvaluator = goog.abstractMethod;
-
-
-/**
- * Default evaluation of a node if no speech rule is applicable.
- * @param {!Node} node The target node (or root of subtree).
- * @return {!Array<cvox.NavDescription>} The resulting description.
- */
-cvox.SpeechRuleEvaluator.prototype.evaluateDefault = goog.abstractMethod;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_functions.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_functions.js
deleted file mode 100644
index 83f5ed9001e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_functions.js
+++ /dev/null
@@ -1,137 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Classes for custom functions for the speech rule engine.
- *
- */
-
-goog.provide('cvox.SpeechRuleFunctions');
-goog.provide('cvox.SpeechRuleFunctions.ContextFunctions');
-goog.provide('cvox.SpeechRuleFunctions.CustomQueries');
-goog.provide('cvox.SpeechRuleFunctions.CustomStrings');
-
-
-
-/**
- * @constructor
- */
-cvox.SpeechRuleFunctions = function() { };
-
-
-/**
- * Private superclass of all the custom function stores.
- * @constructor
- * @param {string} prefix A prefix string for the function names.
- * @param {Object<Function>} store Storage object.
- * @private
- */
-cvox.SpeechRuleFunctions.Store_ = function(prefix, store) {
- /** @private */
- this.prefix_ = prefix;
- /** @private */
- this.store_ = store;
-};
-
-
-/**
- * Adds a new function for the function store.
- * @param {string} name A name.
- * @param {!Function} func A function.
- */
-cvox.SpeechRuleFunctions.Store_.prototype.add = function(name, func) {
- if (this.checkCustomFunctionSyntax_(name)) {
- this.store_[name] = func;
- }
-};
-
-
-/**
- * Retrieves a function with the given name if one exists.
- * @param {string} name A name.
- * @return {Function} The function if it exists.
- */
-cvox.SpeechRuleFunctions.Store_.prototype.lookup = function(name) {
- return this.store_[name];
-};
-
-
-/**
- * Context function for use in speech rules.
- * @typedef {function(!Node): Array<Node>}
- */
-cvox.SpeechRuleFunctions.CustomQuery;
-
-
-/**
- * @constructor
- * @extends {cvox.SpeechRuleFunctions.Store_}
- */
-cvox.SpeechRuleFunctions.CustomQueries = function() {
- var store =
- /** @type {Object<cvox.SpeechRuleFunctions.CustomQuery>} */ ({});
- goog.base(this, 'CQF', store);
-};
-goog.inherits(cvox.SpeechRuleFunctions.CustomQueries,
- cvox.SpeechRuleFunctions.Store_);
-
-
-/**
- * Context function for use in speech rules.
- * @typedef {function(!Node): string}
- */
-cvox.SpeechRuleFunctions.CustomString;
-
-
-/**
- * @constructor
- * @extends {cvox.SpeechRuleFunctions.Store_}
- */
-cvox.SpeechRuleFunctions.CustomStrings = function() {
- var store =
- /** @type {Object<cvox.SpeechRuleFunctions.CustomString>} */ ({});
- goog.base(this, 'CSF', store);
-};
-goog.inherits(cvox.SpeechRuleFunctions.CustomStrings,
- cvox.SpeechRuleFunctions.Store_);
-
-
-/**
- * Context function for use in speech rules.
- * @typedef {function(Array<Node>, ?string): (function(): string)}
- */
-cvox.SpeechRuleFunctions.ContextFunction;
-
-
-/**
- * @constructor
- * @extends {cvox.SpeechRuleFunctions.Store_}
- */
-cvox.SpeechRuleFunctions.ContextFunctions = function() {
- var store =
- /** @type {Object<cvox.SpeechRuleFunctions.ContextFunction>} */
- ({});
- goog.base(this, 'CTXF', store);
-};
-goog.inherits(cvox.SpeechRuleFunctions.ContextFunctions,
- cvox.SpeechRuleFunctions.Store_);
-
-
-/**
- * Checks validity for a custom function name.
- * @param {string} name The name of the custom function.
- * @return {!boolean} True if the name is valid.
- * @private
- */
-cvox.SpeechRuleFunctions.Store_.prototype.
- checkCustomFunctionSyntax_ = function(name) {
- var reg = new RegExp('^' + this.prefix_);
- if (!name.match(reg)) {
- console.log(
- 'FunctionError: Invalid function name. Expected prefix' +
- this.prefix_);
- return false;
- }
- return true;
- };
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_store.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_store.js
deleted file mode 100644
index 0ab964ac642..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/speech_rule_store.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Base interface for all speech rule stores.
- *
- * A speech rule store exposes the minimal set of methods a speech rule
- * author needs for a particular markup type such as MathML or HTML
- * (definition). A rule provider also acts as the permanent and authoritative
- * store for all rules for such markup (lookup).
- */
-
-goog.provide('cvox.SpeechRuleStore');
-
-/**
- * @interface
- */
-cvox.SpeechRuleStore = goog.abstractMethod;
-
-
-/**
- * Adds a new speech rule.
- * @param {cvox.SpeechRule} rule The speech rule to be added.
- */
-cvox.SpeechRuleStore.prototype.addRule = goog.abstractMethod;
-
-
-/**
- * Deletes a speech rule if it exists.
- * @param {cvox.SpeechRule} rule The speech rule to be deleted.
- */
-cvox.SpeechRuleStore.prototype.deleteRule = goog.abstractMethod;
-
-
-/**
- * Retrieves the first rule satisfying a given predicate.
- * @param {function(cvox.SpeechRule): boolean} pred A predicate on speech rules.
- * @return {cvox.SpeechRule} The first speech rule in the store satisfying pred.
- */
-cvox.SpeechRuleStore.prototype.findRule = goog.abstractMethod;
-
-
-/**
- * Retrieves all rules satisfying a given predicate.
- * @param {function(cvox.SpeechRule): boolean} pred A predicate on speech rules.
- * @return {Array<cvox.SpeechRule>} All speech rules in the store satisfying
- * pred.
- */
-cvox.SpeechRuleStore.prototype.findAllRules = goog.abstractMethod;
-
-
-/**
- * Retrieves a rule for the given node if one exists.
- * @param {Node} node A node.
- * @param {!cvox.SpeechRule.DynamicCstr} dynamic Additional dynamic
- * constraints. These are matched against properties of a rule.
- * @return {cvox.SpeechRule} The actions of the speech rule if it exists.
- */
-cvox.SpeechRuleStore.prototype.lookupRule = goog.abstractMethod;
-
-
-// TODO(sorge): Propagate this documentation *everywhere* once these
-// args/descriptions are hardened/cleared up.
-/**
- * Defines a new speech rule from given components.
- * @param {string} name Name of the rule. It does not have to be unique.
- * @param {string} dynamic Dynamic constraint annotation of the rule.
- * @param {string} action String version of the speech rule.
- * @param {string} prec Precondition of the rule.
- * @param {...string} constr Additional constraints.
- * @return {cvox.SpeechRule} The newly defined rule.
- */
-cvox.SpeechRuleStore.prototype.defineRule = goog.abstractMethod;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/store_util.js b/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/store_util.js
deleted file mode 100644
index f7d53356be0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/speech_rules/store_util.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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.
-
-/**
- * @fileoverview General utility functions for rule stores.
- */
-
-goog.provide('cvox.StoreUtil');
-
-
-/**
- * Count list of nodes and concatenate this with the context string.
- * Returns a closure with a local state.
- * @param {Array<Node>} nodes A node array.
- * @param {?string} context A context string.
- * @return {function(): string} A function returning a string.
- */
-cvox.StoreUtil.nodeCounter = function(nodes, context) {
- // Local state.
- var localLength = nodes.length;
- var localCounter = 0;
- var localContext = context;
- if (!context) {
- localContext = '';
- }
- return function() {
- if (localCounter < localLength) {
- localCounter += 1;
- }
- return localContext + ' ' + localCounter;
- };
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/BUILD.gn b/chromium/chrome/browser/resources/chromeos/chromevox/strings/BUILD.gn
deleted file mode 100644
index 9a7f8566756..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/BUILD.gn
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//tools/grit/grit_rule.gni")
-
-chromevox_out_dir = "$root_out_dir/resources/chromeos/chromevox"
-
-grit("chromevox_strings") {
- source = "chromevox_strings.grd"
- outputs = [
- "_locales/am/messages.json",
- "_locales/ar/messages.json",
- "_locales/bg/messages.json",
- "_locales/bn/messages.json",
- "_locales/ca/messages.json",
- "_locales/cs/messages.json",
- "_locales/da/messages.json",
- "_locales/de/messages.json",
- "_locales/el/messages.json",
- "_locales/en_GB/messages.json",
- "_locales/en/messages.json",
- "_locales/es/messages.json",
- "_locales/es_419/messages.json",
- "_locales/et/messages.json",
- "_locales/fa/messages.json",
- "_locales/fi/messages.json",
- "_locales/fil/messages.json",
- "_locales/fr/messages.json",
- "_locales/gu/messages.json",
- "_locales/he/messages.json",
- "_locales/hi/messages.json",
- "_locales/hr/messages.json",
- "_locales/hu/messages.json",
- "_locales/id/messages.json",
- "_locales/it/messages.json",
- "_locales/ja/messages.json",
- "_locales/kn/messages.json",
- "_locales/ko/messages.json",
- "_locales/lt/messages.json",
- "_locales/lv/messages.json",
- "_locales/ml/messages.json",
- "_locales/mr/messages.json",
- "_locales/ms/messages.json",
- "_locales/nl/messages.json",
- "_locales/nb/messages.json",
- "_locales/pl/messages.json",
- "_locales/pt_BR/messages.json",
- "_locales/pt_PT/messages.json",
- "_locales/ro/messages.json",
- "_locales/ru/messages.json",
- "_locales/sk/messages.json",
- "_locales/sl/messages.json",
- "_locales/sr/messages.json",
- "_locales/sv/messages.json",
- "_locales/sw/messages.json",
- "_locales/ta/messages.json",
- "_locales/te/messages.json",
- "_locales/th/messages.json",
- "_locales/tr/messages.json",
- "_locales/uk/messages.json",
- "_locales/vi/messages.json",
- "_locales/zh_CN/messages.json",
- "_locales/zh_TW/messages.json",
- ]
- output_dir = chromevox_out_dir
-
- # Don't polute the extension directory with stamp and .d files.
- depfile_dir = target_out_dir
- resource_ids = ""
-}
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 c198e539e66..878212fea90 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -944,18 +944,6 @@
<message desc='Brailled when describing an ARIA value maximum. For example "Distance, in meters: 6 min:2 max:10".' name="IDS_CHROMEVOX_ARIA_VALUE_MAX_BRL">
max:<ph name="x">$1</ph>
</message>
- <message desc='Spoken when describing an ARIA value. For example "Distance, in meters textbox 6, min 2, max 10".' name="IDS_CHROMEVOX_ARIA_VALUE_NOW">
- <ph name="x">$1</ph>
- </message>
- <message desc='Brailled when describing an ARIA value. For example "Distance, in meters: 6 min:2 max:10".' name="IDS_CHROMEVOX_ARIA_VALUE_NOW_BRL">
- <ph name="x">$1</ph>
- </message>
- <message desc='Spoken when describing an ARIA value text. For example "Distance, short distance set"' name="IDS_CHROMEVOX_ARIA_VALUE_TEXT">
- <ph name="x">$1</ph>
- </message>
- <message desc='Brailled when describing an ARIA value text. For example "Distance, short distance set"' name="IDS_CHROMEVOX_ARIA_VALUE_TEXT_BRL">
- <ph name="x">$1</ph>
- </message>
<message desc="Describes an element with the ARIA role alert." name="IDS_CHROMEVOX_ROLE_ALERT">
Alert
</message>
@@ -1826,6 +1814,9 @@
<message desc="Name of the classic key map." name="IDS_CHROMEVOX_KEYMAP_CLASSIC">
Classic keymap
</message>
+ <message desc="Name of the key map for release of ChromeVox named Next." name="IDS_CHROMEVOX_KEYMAP_NEXT">
+ Next keymap
+ </message>
<message desc="Name of the flat key map." name="IDS_CHROMEVOX_KEYMAP_FLAT">
Flat keymap
</message>
@@ -2362,6 +2353,52 @@
<message desc="Message spoken to user when switching to a mode where searching is case-sensitive." name="IDS_CHROMEVOX_CASE_SENSITIVE">
Case sensitive.
</message>
+
+ <!-- Keyboard Explorer -->
+ <message desc="Describes the back key in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_BACK_KEY">
+ back
+ </message>
+ <message desc="Describes the forward key in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_FORWARD_KEY">
+ forward
+ </message>
+ <message desc="Describes the refresh key in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_REFRESH_KEY">
+ refresh
+ </message>
+ <message desc="Describes the key to toggle full screen in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_TOGGLE_FULL_SCREEN_KEY">
+ toggle full screen
+ </message>
+ <message desc="Describes the key to toggle window overview in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_WINDOW_OVERVIEW_KEY">
+ window overview
+ </message>
+ <message desc="Describes the brightness down key in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_BRIGHTNESS_DOWN_KEY">
+ Brightness down
+ </message>
+ <message desc="Describes the brightness up key in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_BRIGHTNESS_UP_KEY">
+ Brightness up
+ </message>
+ <message desc="Describes the volume mute key in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_VOLUME_MUTE_KEY">
+ volume mute
+ </message>
+ <message desc="Describes the volume down key in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_VOLUME_DOWN_KEY">
+ volume down
+ </message>
+ <message desc="Describes the volume up key in the ChromeVox keyboard explorer." name="IDS_CHROMEVOX_VOLUME_UP_KEY">
+ volume up
+ </message>
+
+ <!-- Panel -->
+ <message desc="Title of the ChromeVox panel, a window that displays the text ChromeVox is speaking and contains controls to manipulate ChromeVox." name="IDS_CHROMEVOX_PANEL_TITLE">
+ ChromeVox Panel
+ </message>
+ <message desc="Title of the button that opens up the ChromeVox menu." name="IDS_CHROMEVOX_MENU_TITLE">
+ ChromeVox Menu
+ </message>
+ <message desc="Title of the button that opens up the ChromeVox menu." name="IDS_CHROMEVOX_OPTIONS">
+ ChromeVox Options
+ </message>
+ <message desc="Title of the button that disables ChromeVox." name="IDS_CHROMEVOX_DISABLE_CHROMEVOX">
+ Disable ChromeVox
+ </message>
</messages>
</release>
</grit>
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_am.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_am.xtb
deleted file mode 100644
index fa327a28475..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_am.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="am">
-<translation id="1012173283529841972">የዝርዝር ንጥል</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">ሰፍቷል።</translation>
-<translation id="1025074108959230262">አጣባቂ ሁነታ ተሰናክሏል</translation>
-<translation id="1031961866430398710">ከዚያ</translation>
-<translation id="1044777062731150180">ምንም ራስጌዎች የሉም</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">ልክ ያልሆነ ግቤት</translation>
-<translation id="1082209053475788238">ምንም ቀዳሚ የደረጃ 6 ርዕስ የለም።</translation>
-<translation id="1088219014394087294">ምንም ርዕሶች የሉም።</translation>
-<translation id="1106741348836243114">የድምጽ ግብረመልስ (ኢርኮኖች) ያብሩ ወይም ያጥፉ።</translation>
-<translation id="1120743664840974483">{"a": "አልፋ", "b": "ብራቮ", "c": "ቻርሊ", "d": "ዴልታ", "e": "ኤኮ", "f": "ፎክስትሮት", "g": "ጎልፍ", "h": "ሆቴል", "i": "ኢንዲያ", "j": "ጁሊዬት","k": "ኪሎ", "l": "ሊማ", "m": "ማይክ", "n": "ኖቬምበር", "o": "ኦስካር","p": "ፓፓ", "q": "ኴቤክ", "r": "ሮሚዮ", "s": "ሲዬራ", "t": "ታንጎ", "u": "ዩኒፎርም", "v": "ቪክቶር", "w": "ዊስኪ","x": "ኤክስሬይ", "y": "ያንኪ", "z": "ዙሉ"}</translation>
-<translation id="113582498867142724">የ<ph name="TAG" /> ስብስብ ከ<ph name="NUM" /> ንጥሎች ጋር</translation>
-<translation id="1155043339247954670">ምንም ቀጣይ የርዕስ ንጥል የለም።</translation>
-<translation id="1157782847298808853">የቁልፍ ሰሌዳ አጋዥ</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />፣ <ph name="NAME" />፣ ጥምድ ሳጥን</translation>
-<translation id="1167230103353892028"><ph name="NAME" />፣ የምናሌ ንጥል፣ ከንዑስ ምናሌ ጋር</translation>
-<translation id="1177863135347784049">ብጁ</translation>
-<translation id="1188858454923323853">ማሟያ</translation>
-<translation id="1206619573307042055">መልሶ መልስ</translation>
-<translation id="1213216066620407844">ChromeVox - ድምጽ ለChrome መስጠት</translation>
-<translation id="1229276918471378188">ቀዳሚ ዝላይ</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">ቀጣይ የደረጃ 6 ርዕስ</translation>
-<translation id="1275718070701477396">ተመርጧል</translation>
-<translation id="1319608975892113573">ምንም ቀዳሚ የጽሑፍ ጥቅስ የለም።</translation>
-<translation id="1321576897702511272">የChromeVox እገዛን ደብቅ</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> ከ<ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">የቁምፊ እና ቃል ማስተጋባት</translation>
-<translation id="1339428534620983148">ቀዳሚ የሠንጠረዥ አምድ</translation>
-<translation id="1342835525016946179">ጽሑፍ</translation>
-<translation id="1346748346194534595">ቀኝ</translation>
-<translation id="136718599399906424">ቀጣይ የሠንጠረዥ ረድፍ</translation>
-<translation id="1383876407941801731">ፍለጋ </translation>
-<translation id="1385214448885562192">ለመቀበል enter ወይም ይቅር ለማለት escape፣ ለቀጣዩ ታች እና ለቀዳሚው ላይን ይጫኑ።</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />፣ የይለፍ ቃል ጽሑፍ ሳጥን</translation>
-<translation id="1467432559032391204">ግራ</translation>
-<translation id="1474557363159888097">ምንም ቀዳሚ መልህቅ የለም።</translation>
-<translation id="1502086903961450562">ቀዳሚ ስዕላዊ</translation>
-<translation id="1506187449813838456">የድምጽ ቅጥነት ይጨምሩ</translation>
-<translation id="151784044608172266">ቀጣይ አረፍተ ነገር</translation>
-<translation id="1524531499102321782">የብሬይል ቀጣይ መስመር</translation>
-<translation id="1546370775711804143">ማሸብለያ አሞሌ</translation>
-<translation id="1559739829547075274">ወደኋላ ያስሱ</translation>
-<translation id="1571643229714746283">ChromeVox ዝግጁ ነው</translation>
-<translation id="158493514907962286">ዲሴምበር</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">ወደ ባለ6 ነጥብ ብሬይል ቀይር</translation>
-<translation id="1611168825862729585">የአምድ ራስጌ፦</translation>
-<translation id="1613476421962910979">ኢርኮኖች በርተዋል</translation>
-<translation id="1618597272655350600">የተሟላ የአሁኑ ቦታ ሙሉ ማብራሪያ ያስታውቃል</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{ይበልጣል}one{# የይበልጣል ምልክቶች}other{# የይበልጣል ምልክቶች}}</translation>
-<translation id="1653266918374749391">ቀዳሚ የደረጃ 3 ርዕስ</translation>
-<translation id="1659072772017912254">ምልክት አልተደረገበትም</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">የChromeVox አሰሳ</translation>
-<translation id="16777221443363124">የምናሌ አሞሌ</translation>
-<translation id="1692077714702418899">መዋቅራዊ መስመር</translation>
-<translation id="1700517974991662022">ተጎብኝቷል</translation>
-<translation id="1722567105086139392">አገናኝ</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">ቀጣይ ስዕላዊ</translation>
-<translation id="1781173782405573156">የማለፊያ ቁልፍ</translation>
-<translation id="1787176709638001873">የይለፍ ቃል አርትዖት ጽሑፍ</translation>
-<translation id="1810107444790159527">የዝርዝር ሳጥን</translation>
-<translation id="1828385960365606039">ሜይ</translation>
-<translation id="1834891354138622109">አምድ</translation>
-<translation id="1865601187525349519">የጽሑፉ መጨረሻ</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">የአሁኑን ሰዓት እና ቀን ተናገር።</translation>
-<translation id="1902396333223336119">ሕዋስ</translation>
-<translation id="1905379170753160525">የርዕሶች ዝርዝር አሳይ</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">የዓመቱ ሳምንት መቆጣጠሪያ</translation>
-<translation id="1964135212174907577">ቀጣይ ነገር</translation>
-<translation id="1969092762068865084">ጁላይ</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">የረድፍ ራስጌ፦</translation>
-<translation id="2002895034995108595">የአሁኑን የቁልፍ አደራደር ዳግም አስጀምር</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{የግራ ማዕዘን ቅንፍ}one{# የግራ ማዕዘን ቅንፎች}other{# የግራ ማዕዘን ቅንፎች}}</translation>
-<translation id="2045490512405922022">ምልክት አልተደረገበትም</translation>
-<translation id="20601713649439366">ምንም ቀዳሚ የሒሳብ ሐረግ የለም።</translation>
-<translation id="207477615537953741">ስነ ፍቺ ጠፍቷል</translation>
-<translation id="2086961585857038472">ቀጣይ ቃል</translation>
-<translation id="2089387485033699258">en</translation>
-<translation id="2091933974477985526">ቀዳሚ አርትዖት ሊደረግበት የሚችል የጽሑፍ አካባቢ</translation>
-<translation id="2100350898815792233">ሁሉም ስርዓተ ነጥብ</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">የመዳረሻ ቁልፍ፦<ph name="KEY" /></translation>
-<translation id="2155457205053847599">ከታች ካለው ዝርዝር አንድ አማራጭ በመምረጥ አሁን ያለውን ባለ6 ነጥብ ብሬይል ሰንጠረዡን ይለውጡ።</translation>
-<translation id="2169714232367507776">በአሁኑ ንጥል ላይ ጠቅ ያድርጉ</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{ዝግ ቅንፍ}one{# ዝግ ቅንፎች}other{# ዝግ ቅንፎች}}</translation>
-<translation id="2199994615414171367">ቀዳሚ ሒሳብ</translation>
-<translation id="2223693656926968778">በአሁኑ ንጥል ላይ እርምጃ ይውሰዱ</translation>
-<translation id="225732394367814946">የንግግር ፍጥነት ይጨምሩ</translation>
-<translation id="2267945578749931355">ቀጣዩ ቁምፊ</translation>
-<translation id="2281234842553884450">ቀዳሚ ተንሸራታች</translation>
-<translation id="2318372665160196757">ዋና</translation>
-<translation id="2329324941084714723">የትር ፓነል</translation>
-<translation id="2344193891939537199">የቀን ሰዓት መቆጣጠሪያ</translation>
-<translation id="2359897517538099099">በሰንጠረዥ ሁነታ ውስጥ</translation>
-<translation id="241124561063364910">ተከትሎም</translation>
-<translation id="2417569100218200841">የይዘት መረጃ</translation>
-<translation id="2422937916923936891">የምናሌ ንጥል አመልካች ሳጥን</translation>
-<translation id="2429669115401274487">ከሰዓት</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> አሁን አዲሱ የChromeVox መቀየሪያ ነው።</translation>
-<translation id="2450814015951372393">አመልካች ሳጥን</translation>
-<translation id="2462626033734746142">የሬዲዮ አዝራር ቡድን</translation>
-<translation id="2471138580042810658">ርዕስ 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{ኮከቢት}one{# ኮከቢቶች}other{# ኮከቢቶች}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> ዳግም እንዲጀምር ተደርጓል።</translation>
-<translation id="2553108862507765288">የስዋስው ስህተት</translation>
-<translation id="257674075312929031">ቡድን</translation>
-<translation id="2582407057977008361">ከጎን</translation>
-<translation id="2589102159832527089">ይህ ገጽ በራስ-ሰር ከፒ ዲ ኤፍ ፋይሉ &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; የወጣ ጽሑፍ አለው። &lt;a href="<ph name="URL" />"&gt;የመጀመሪያውን ለማግኘት እዚህ ጠቅ ያድርጉ።&lt;/a&gt;</translation>
-<translation id="2606210917827248971">ከ {COUNT,plural, =1{# ንጥል}one{# ንጥሎች}other{# ንጥሎች}}</translation>
-<translation id="2614981083756825552">የMath ML አቀማመጥ</translation>
-<translation id="2626530649491650971">ጠቅ ሊደረግ የሚችል</translation>
-<translation id="2628764385451019380">ምንም ቀዳሚ ጥምድ ሳጥን የለም።</translation>
-<translation id="2637227747952042642">ሒሳብ</translation>
-<translation id="2639750663247012216">የChromeVox መቀየሪያ</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">ከማዞሪያ ቁልፍ ስር ያለውን ንጥል ጠቅ ያድርጉ</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{ክፍት ቅንፍ}one{# ክፍት ቅንፎች}other{# ክፍት ቅንፎች}}</translation>
-<translation id="2705875883745373140">አልተጫነም</translation>
-<translation id="2706462751667573066">ላይ</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ድምጽ</translation>
-<translation id="2732718972699418926">ጥዋት</translation>
-<translation id="2749275490991666823">ምልክት ተደርጎበታል</translation>
-<translation id="27527859628328957">ሊተኮርበት ወደሚችል ቀጣዩ ንጥል ይዝለሉ</translation>
-<translation id="2770781857296573485">ወደ የቡድን አሰሳ ይግቡ</translation>
-<translation id="2777845298774924149">ወጥቷል</translation>
-<translation id="2800204403141299078">ምንም ተጨማሪ የተለዩ አካላት የሉም።</translation>
-<translation id="2800780099804980316">ምንም ቀዳሚ የደረጃ 1 ራስጌ የለም።</translation>
-<translation id="2811204574343810641">ረድፍ</translation>
-<translation id="2816654101880605877">ምንም ቀጣይ ተንሸራታች የለም።</translation>
-<translation id="2841013758207633010">ሰዓት</translation>
-<translation id="2843837985843789981">ቀዳሚ ቡድን</translation>
-<translation id="2844995807198708617">የአውድ ምናሌ</translation>
-<translation id="2849332794118375855">ምንም ቀጣይ አመልካች ሳጥን የለም።</translation>
-<translation id="2864481629947106776">ቀዳሚ አገናኝ</translation>
-<translation id="2873259058405069099">ወደ የሠንጠረዡ መጀመሪያ ይሂዱ</translation>
-<translation id="2894654529758326923">መረጃ</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{የግራ ሐረግ ቅንፍ}one{# የግራ ሐረግ ቅንፎች}other{# የግራ ሐረግ ቅንፎች}}</translation>
-<translation id="2911433807131383493">ChromeVox አጋዥ ስልጠናን ይክፈቱ</translation>
-<translation id="2932083475399492303">የመስመር አይነት በመዋቅራዊ እና አቀማመጥ መካከል ይቀያይሩ</translation>
-<translation id="2964026537669811554">የርዕስ ቡድን</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{ትር}one{# ትሮች}other{# ትሮች}}</translation>
-<translation id="2972078295414139404">ምንም ቀዳሚ የተጎበኘ አገናኝ የለም።</translation>
-<translation id="2972205263822847197">ጠቃሚ የመሣሪያ ምክር</translation>
-<translation id="2998131015536248178">ቀዳሚ ቁምፊ</translation>
-<translation id="2999559350546931576">የድምጽ ቅጥነት ይቀንሱ</translation>
-<translation id="2999945368667127852">ምንም ቀጣይ የሚዲያ ንዑስ ፕሮግራም የለም።</translation>
-<translation id="3012414509011670858">ምንም ቀዳሚ ክፍል የለም።</translation>
-<translation id="3030432017085518523">የምናሌ ንጥል ሬዲዮ አዝራር</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{ትእምርተ ጭረት}one{# ትእምርተ ጭረቶች}other{# ትእምርተ ጭረቶች}}</translation>
-<translation id="3046838483509668188">ChromeVox አማራጮች</translation>
-<translation id="3047143736589213134">የሙከራ ቁልፍ አደራደር</translation>
-<translation id="3060756054951570867">የ<ph name="TITLE" /> ምናሌ ተከፍቷል</translation>
-<translation id="3078345202707391975">ቀጣይ የደረጃ 2 ርዕስ</translation>
-<translation id="3078740164268491126">ሠንጠረዥ</translation>
-<translation id="3082557070674409251">ጠቅ ተደርጓል።</translation>
-<translation id="3084806535845658316">ምንም የትየባ ማስተጋባት የለም</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">ምንም ቀጣይ የሒሳብ ሐረግ የለም።</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">ቀጣይ የመሬት ምልክት</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">ተሰብስቧል</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">የመሬት ላይ ምልክቶች ዝርዝር አሳይ</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">ቀጣይ መስመር</translation>
-<translation id="3155083529632865074">ምንም ቀዳሚ አዝራር የለም።</translation>
-<translation id="3163593631834463955">ባዶ የአምድ ራስጌ</translation>
-<translation id="316542773973815724">አሰሳ</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{ክፍተት}one{# ክፍተቶች}other{# ክፍተቶች}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> አስገብተዋል</translation>
-<translation id="3223701887221307104"><ph name="NAME" />፣ ትር</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">የተጎበኘ አገናኝ</translation>
-<translation id="323731244387692321">የChromeVox ቁልፍ ሰሌዳ እገዛ</translation>
-<translation id="3241052487511142956">ቀዳሚ የተጎበኘ አገናኝ</translation>
-<translation id="3286390186030710347">ተንሸራታች</translation>
-<translation id="3299925995433437805">ምንም ቀጣይ የተጎበኘ አገናኝ የለም።</translation>
-<translation id="3303384412438961941">የማንኛውንም ቁልፍ ስም ለማወቅ ይጫኑት። Ctrl+W የቁልፍ ሰሌዳ አሳሹን ይዘጋዋል።</translation>
-<translation id="3307886118343381874">ወደ የሠንጠረዡ መጨረሻ ሂድ</translation>
-<translation id="3311969765485641742">ማንቂያዎችን ለመከለስ Alt+Shift+A ይጫኑ</translation>
-<translation id="3312997241656799641">ቀጣይ የተጎበኘ አገናኝ</translation>
-<translation id="3321460131042519426">የቃል ቅለሳን አንቃ</translation>
-<translation id="3322936298410871309">ቀዳሚ የደረጃ 1 ርዕስ</translation>
-<translation id="3323447499041942178">የፅሁፍ ሳጥን</translation>
-<translation id="3353420241558113817">{"ar": «አረብኛ»,
- "bg": «ቡልጋሪያን»,
- "ca": «ካታላን»,
- "cs": «ቼክ»,
- "da": «ዳኒሽ»,
- "de": «ጀርመንኛ»,
- "de_CH": «ጀርመንኛ (ስዊዘርላንድ)»,
- "de_DE": «ጀርመንኛ (ጀርመን)»,
- "el": «ግሪክኛ»,
- "en": «እንግሊዝኛ»,
- "en_CA": «እንግሊዝኛ (ካናዳ)»,
- "en_GB": «እንግሊዝኛ (ዩናይትድ ኪንግደም)»,
- "en_US": «እንግሊዝኛ (አሜሪካ)»,
- "es": «ስፓኒሽ»,
- "et": «ኢስቶኒያን»,
- "fr": «ፈረንሳይኛ»,
- "fr_CA": «ፈረንሳይኛ (ካናዳ)»,
- "fr_FR": «ፈረንሳይኛ (ፈረንሳይ)»,
- "fi": «ፊኒሽ»,
- "he": «ዕብራይስጥ»,
- "hi": «ሂንዲ»,
- "hr": «ክሮሺያኛ»,
- "hu": «ሃንጋሪያኛ»,
- "is": «አይስላንድኛ»,
- "it": «ጣልያንኛ»,
- "ko": «ኮሪያኛ»,
- "lt": «ሊቱዌኒያኛ»,
- "lv": «ላቲቪያኛ»,
- "nb": «ኖርዌጂያን ቦክማል»,
- "nl": «ደች»,
- "pl": «ፖላንድኛ»,
- "pt": «ፓርቱጋልኛ»,
- "ro": «ሮማኒያኛ»,
- "ru": «ራሽያን»,
- "sk": «ስሎቫክኛ»,
- "sl": «ስሎቬኒያኛ»,
- "sr": «ሰርቢያኛ»,
- "sv": «ስዊድንኛ»,
- "tr": «ቱርክኛ»,
- "vi": «ቬትናምኛ»,
- "zh": «ቻይንኛ»,
- "zh_TW": «ቻይንኛ (ተለምዷዊ ሃን)»}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{መደመር}one{# የመደመር ምልክቶች}other{# የመደመር ምልክቶች}}</translation>
-<translation id="338583716107319301">መለያ</translation>
-<translation id="3389259863310851658">ቀዳሚ የቅጽ መስክ</translation>
-<translation id="3390225400784126843">ቀጣይ የተለየ አካል።</translation>
-<translation id="3392045790598181549"><ph name="NAME" />፣ የምናሌ ንጥል</translation>
-<translation id="3406283310380167331">የቅጾች ዝርዝር አሳይ</translation>
-<translation id="3422338090358345848">የቁልፍ ሰሌዳ አሳሽን ይክፈቱ</translation>
-<translation id="3457000393508828486">በከፊል ተጭኗል</translation>
-<translation id="3462439746547587373"><ph name="NAME" />፣ አዝራር</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404">ከ<ph name="V1" /> እስከ <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{የቀኝ ማዕዘን ቅንፍ}one{# የቀኝ ማዕዘን ቅንፎች}other{# የቀኝ ማዕዘን ቅንፎች}}</translation>
-<translation id="3493915602752813531">ምንም ቀጣይ መልህቅ የለም።</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{የጥያቄ ምልክት}one{# የጥያቄ ምልክቶች}other{# የጥያቄ ምልክቶች}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{ድፋት}one{# ድፋቶች}other{# ድፋቶች}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />፣ አመልካች ሳጥኑ ላይ ምልክት አልተደረገም</translation>
-<translation id="3599054940393788245">ሒሳብ ውስጥ አይደለም</translation>
-<translation id="3616113530831147358">ድምጽ</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{የኋሊት ጥቅስ}one{# የኋሊት ጥቅሶች}other{# የኋሊት ጥቅሶች}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{ዶላር}one{# የዶላር ምልክቶች}other{# የዶላር ምልክቶች}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />፣ የዝርዝር ሳጥን</translation>
-<translation id="3687295507293856493">የአሁኑ ሕዋስ አምድ ራስጌ ገምት</translation>
-<translation id="3692274950075847560">ፍ፦<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">የመቆጣጠሪያ ንግግር</translation>
-<translation id="3716845769494773620">ብዙ መስመር</translation>
-<translation id="3731746171184829332">ምንም ቀዳሚ ርዕስ የለም።</translation>
-<translation id="3762198587642264450">ወደ የአሁኑ ረድፍ መጨረሻ ይሂዱ</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">ከመገናኛ ወጥተዋል።</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">የራስ-አጠናቅቅ ዝርዝር</translation>
-<translation id="3810838688059735925">ቪዲዮ</translation>
-<translation id="3816633764618089385">ቀጣይ ሚዲያ</translation>
-<translation id="3819376190738087562">ምንም ዝላዮች የሉም።</translation>
-<translation id="385383972552776628">የአማራጮች ገጹን ይክፈቱ</translation>
-<translation id="3856075812838139784">ተነባቢ ብቻ</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">ምናሌ</translation>
-<translation id="3909320334364316587">ቀዳሚ የደረጃ 6 ርዕስ</translation>
-<translation id="3914173277599553213">የሚያስፈልግ</translation>
-<translation id="3962990492275676168">ከአሁኑ አካባቢ ሆነው ማንበብ ይጀምሩ</translation>
-<translation id="4004802134384979325">ምልክት ተደርጎበታል</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">የወር ቁጥጥር</translation>
-<translation id="4039983576244166038">ባዶ የረድፍ ራስጌ</translation>
-<translation id="4042843249978639960">ምንም ቀጣይ የደረጃ 2 ርዕስ የለም።</translation>
-<translation id="4043348641337972076">ምንም ቀዳሚ የARIA ምልክት የለም።</translation>
-<translation id="4047216625641135770">ምልክት አድርግበት</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{ድፋትቅናት}one{# ድፋትቅናቶች}other{# ድፋትቅናቶች}}</translation>
-<translation id="409334809956508737">ቀዳሚ ነገር</translation>
-<translation id="4099274309791143834">ከንዑስ ምናሌ ጋር</translation>
-<translation id="4107807507418787238">ከታች ምንም ሕዋስ የለም።</translation>
-<translation id="4116415223832267137">ማንቂያ</translation>
-<translation id="4147126331795725888">ምንም ቀጣይ መቆጣጠሪያ የለም።</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{የቀኝ ሐረግ ቅንፍ}one{# የቀኝ ሐረግ ቅንፎች}other{# የቀኝ ሐረግ ቅንፎች}}</translation>
-<translation id="4158704014418536539">መልከፊደል-ትብ።</translation>
-<translation id="4161663686871496107">ChromeVox ተነጋሪ ግብረ መልስ ዝግጁ ነው</translation>
-<translation id="4173994908659439270">ምንም አርትዖት ሊደረግበት የሚችል የጽሑፍ መስክ የለም።</translation>
-<translation id="4176463684765177261">ተሰናክሏል</translation>
-<translation id="4188530942454211480">ቀዳሚ አረፍተ ነገር</translation>
-<translation id="4202186506458631436">ወደ ቀኝ ያንቀሳቅሱ</translation>
-<translation id="4206289001967551965">በሠንጠረዥ ውስጥ</translation>
-<translation id="4215733775853809057">ቀጣይ ተንሸራታች</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{ዳሽ}one{# ዳሾች}other{# ዳሾች}}</translation>
-<translation id="421884353938374759">color picker</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">በግራ ምንም ሕዋስ የለም።</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />፣ ደረጃ <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">ማስታወሻ</translation>
-<translation id="4254798249533888099">ዛፍ</translation>
-<translation id="4255943572433203166">ChromeVoxን ለማበጀት ከታች ያሉትን አማራጮች ይጠቀሙ። ለውጦች ወዲያውኑ ነው የሚተገበሩት።</translation>
-<translation id="4271220233568730077">ቀጣይ ሒሳብ</translation>
-<translation id="4271521365602459209">ምንም ተጨማሪ ውጤቶች የሉም።</translation>
-<translation id="4287520460805643128">ምንም ቀጣይ ጽሑፍ የለም።</translation>
-<translation id="4289540628985791613">ማጠቃለያ</translation>
-<translation id="4300318234632215983">ከአንድ አገናኝ ጀርባ ያለውን ዩአርኤል አስታውቅ</translation>
-<translation id="4301352596632316575">ንዑስ ምናሌ አለው</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{ነጥብ}=3{አስጨምሬ}one{# ነጥቦች}other{# ነጥቦች}}</translation>
-<translation id="4347461890115250064">ምንም ቀጣይ ርዕስ የለም።</translation>
-<translation id="4367650418938037324">የMath ML ቅጠል</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">የማቆሚያ ንግግር</translation>
-<translation id="4373197658375206385">ምንም አገናኝ ያልሆነ ቀዳሚ ንጥል የለም።</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">ዳግም አስጀምር</translation>
-<translation id="4471074325120394300">ምንም አገናኞች የሉም።</translation>
-<translation id="4476183483923481720">አዲስ መስመር</translation>
-<translation id="4482330759234983253">ቀዳሚ ሠንጠረዥ</translation>
-<translation id="4491109536499578614">ምስል</translation>
-<translation id="4529987814483543472">የሚታወቅ የቁልፍ አደራደር</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{እዝባር}one{# እዝባሮች}other{# እዝባሮች}}</translation>
-<translation id="4547556996012970016">ቀጣይ የደረጃ 5 ርዕስ</translation>
-<translation id="4562381607973973258">ራስጌ</translation>
-<translation id="4591507479202817876">፣ ተመርጧል</translation>
-<translation id="4597532268155981612">ቅጽ</translation>
-<translation id="4597896406374528575">ኤፕሪል</translation>
-<translation id="4615592953348396470">ቀጣይ ቁልፍ መጫንን ችላ ብሎ በመተው ላይ</translation>
-<translation id="461613135510474570">አረፍተ ነገር</translation>
-<translation id="4647836961514597010">ቀለም መምረጫ</translation>
-<translation id="4661075872484491155">ዛፍ</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">ቀዳሚ የመሬት ምልክት</translation>
-<translation id="4696413482802371445">ምንም ቀጣይ የደረጃ 5 ርዕስ የለም።</translation>
-<translation id="4729095194763193578">ቀዳሚ የሠንጠረዥ ረድፍ</translation>
-<translation id="4736221692378411923">ኦገስት</translation>
-<translation id="4740661827607246557">የእገዛ ትዕዛዞች</translation>
-<translation id="4759716709594980008">የChromeOS ቁልፍ ሰሌዳ አሳሽ</translation>
-<translation id="4763296182459741068">ወደ ታች ተጠቅልሏል</translation>
-<translation id="4763480195061959176">ቪዲዮ</translation>
-<translation id="479989351350248267">ፈልግ</translation>
-<translation id="481165870889056555">የአሁኑ ገጽ ርዕስ አስታውቅ</translation>
-<translation id="4826415162591436065">ወደፊት ያስሱ</translation>
-<translation id="4826604887384865800">ቀጣይ ዝላይ</translation>
-<translation id="4827410568042294688">አልተመረጠም</translation>
-<translation id="4842108708071771135">ምንም ቀጣይ የጽሑፍ ጥቅስ የለም።</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">ቀዳሚ ተመሳሳይ አባል።</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">የTTS ምዝግብ ማስታወሻ መያዝን ያንቁ</translation>
-<translation id="4877261390094455813">የፍለጋ መጠይቅ ያስገቡ።</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">ውስጣዊ አገናኝ</translation>
-<translation id="4953585991029886728">ጽሑፍ ያርትዑ</translation>
-<translation id="4954534434583049121">ቀዳሚ የጽሑፍ ጥቅስ</translation>
-<translation id="4973717656530883744">ዝቅተኛ <ph name="X" /></translation>
-<translation id="4973762002207131920">ወደ <ph name="KEY" /> ተቀይሯል።</translation>
-<translation id="4975416682604111799">ሚሊሰኮንዶች</translation>
-<translation id="49787999531187221">ChromeVox አሁን ቦዝኗል።</translation>
-<translation id="4979404613699303341">ቀዳሚ አዝራር</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />፣ <ph name="NAME" />፣ የዝርዝር ሳጥን</translation>
-<translation id="4983588134362688868">ወደ የገጹ ላይኛው ክፍል ይዝለሉ</translation>
-<translation id="4986606102545753256"><ph name="NAME" />፣ መስኮት</translation>
-<translation id="4993152509206108683">ፍጥነቱ <ph name="PERCENT" /> በመቶ</translation>
-<translation id="4996716799442435517">ምስላዊ</translation>
-<translation id="4997282455736854877"><ph name="NAME" />፣ የሬዲዮ አዝራር ተመርጧል</translation>
-<translation id="4997475792277222884">ምንም አገናኝ ያልሆነ ቀጣይ ንጥል የለም።</translation>
-<translation id="5000760171916499057">ምንም ቅጾች የሉም።</translation>
-<translation id="5005670136041063723">ምንም ተጨማሪ የተለዩ አባላት የሉም።</translation>
-<translation id="501473567976723023">ጃንዩዋሪ</translation>
-<translation id="5041394372352067729">የብሬይል ማሳያውን ወደ ገጹ አናት ያንቀሳቅሱ</translation>
-<translation id="5042770794184672516">የንግግር ድምጽ መጠን ይጨምሩ</translation>
-<translation id="5050015258024679800">ቀዳሚ የደረጃ 4 ርዕስ</translation>
-<translation id="5054047268577924192">ቀዳሚ የዝርዝር ንጥል</translation>
-<translation id="5078661581131202757">የፋይል ምርጫ</translation>
-<translation id="5080758118274074384">ሁለቴ ጠቅ ተደርጓል</translation>
-<translation id="5098541983634824365">ከፍርግርግ በመውጣት ላይ።</translation>
-<translation id="5102981729317424850">የመሣሪያ አሞሌ</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">ምንም ቀዳሚ የቅጽ መስክ የለም።</translation>
-<translation id="5111640677200759579">የአምድ ራስጌ</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">ምንም ቀዳሚ አገናኝ የለም።</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">፣ አልተመረጠም</translation>
-<translation id="5183440668879371625">ቀዳሚ መስመር</translation>
-<translation id="5184944171021383281">ምንም ቀጣይ የቅጽ መስክ የለም።</translation>
-<translation id="5189244881767082992">መስመር</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> አስቀድሞ ለአንድ ትዕዛዝ ተመድቧል።</translation>
-<translation id="5205493599117157272">የ<ph name="TYPE" /> ዝርዝር።</translation>
-<translation id="520883772648104506">ምንም ቀጣይ የሬዲዮ አዝራር የለም።</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">ጨርስ</translation>
-<translation id="5291783959063340370">ነገር</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />፣ ትር</translation>
-<translation id="5310788376443009632">የተወገዱ፦</translation>
-<translation id="5320727453979144100">አጣባቂ ሁነታ ነቅቷል</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{ኮማ}one{# ኮማዎች}other{# ኮማዎች}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />፣ የጽሑፍ ሳጥን</translation>
-<translation id="5330443287809544590"><ph name="NAME" />፣ አገናኝ</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">ቀጣይነት ባለው ንባብ ጊዜ ወደኋላ ይዝለሉ</translation>
-<translation id="5368000168321181111">ኢርኮኖች ጠፍተዋል</translation>
-<translation id="5374320867641260420">ምንም ቀጣይ አዝራር የለም።</translation>
-<translation id="5382299583965267720">ምንም ቀጣይ የደረጃ 1 ርዕስ የለም።</translation>
-<translation id="5402367795255837559">ብሬይል</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{ድርብ ሰረዝ}one{# ድርብ ሰረዞች}other{# ድርብ ሰረዞች}}</translation>
-<translation id="5411891038905756502">ምንም ቀዳሚ የመዝለያ ነጥብ የለም።</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{ያንሳል}one{# የያንሳል ምልክቶች}other{# የያንሳል ምልክቶች}}</translation>
-<translation id="5455441614648621694">ማሟያ</translation>
-<translation id="5485036206801896268">ምንም ቀዳሚ ስዕላዊ የለም።</translation>
-<translation id="5486947920110100234">ምንም ቀጣይ የመዝለያ ነጥብ የለም።</translation>
-<translation id="549602578321198708">ቃል</translation>
-<translation id="5500932716852106146">ምንም ቀዳሚ አርትዖት ሊደረግበት የሚችል የጽሑፍ መስክ የለም።</translation>
-<translation id="5502713021410870035">ሴፕቴምበር</translation>
-<translation id="5507663321906818013">ካስማ ያርሙ</translation>
-<translation id="5518443085409638729">ጽሑፍ ሲያርትዑ ጠቋሚውን በቁምፊዎች መካከል ያስቀምጡት (እንደ Mac ስርዓተ ክወና X)።</translation>
-<translation id="552195134157544755">የሬዲዮ አዝራር</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">ምንም ቀዳሚ የደረጃ 5 ርዕስ የለም።</translation>
-<translation id="556042886152191864">አዘራር</translation>
-<translation id="5561345396546889625">ቀጣይ ዝርዝር</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">ጽሑፍ፣ የኢሜይል ግቤት ያርትዑ</translation>
-<translation id="5597170376237141345">ቀጣይ አመልካች ሳጥን</translation>
-<translation id="5597933780944041114">ምንም ቀጣይ ርዕስ የለም።</translation>
-<translation id="5598905979683743333"><ph name="NAME" />፣ ሬዲዮ አዝራር አልተመረጠም</translation>
-<translation id="5601172225407283979">ነባሪ እርምጃ አከናውን</translation>
-<translation id="5608798115546226984">መስመር ውስጥ ራስ-አጠናቅቅ</translation>
-<translation id="561939826962581046">ሰዓት</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">ምዝግብ ማስታወሻ</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">ምንም ቀዳሚ ሠንጠረዥ የለም።</translation>
-<translation id="5655682562155942719">የዝላይ ትዕዛዞች</translation>
-<translation id="56637627897541303">የጽሑፍ ቦታ</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">የመሬት ምልክት</translation>
-<translation id="5683155931978483559">ቀዳሚ አመልካች ሳጥን</translation>
-<translation id="5684277895745049190">ዝርዝር</translation>
-<translation id="5700650669149824506">ምንም ቀዳሚ የደረጃ 4 ርዕስ የለም።</translation>
-<translation id="5709192780268610569">ምንም ረጅም ማብራሪያ የለም</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">ቀጣይ የሠንጠረዥ አምድ</translation>
-<translation id="571866080859340309">አሳሽ ቡድኖች</translation>
-<translation id="5728409797179002635">ምንም ሠንጠረዥ አልተገኘም።</translation>
-<translation id="5748623122140342504">ቀዳሚ የደረጃ 5 ርዕስ</translation>
-<translation id="5750633686117194034">ምንም መቀየሪያ አልተጫነም፤ እባክዎ አንድ ወይም ተጨማሪ መቀየሪያዎችን ተጭነው ይያዙ፤ ከጨረሱ በኋላ ጣቶችዎን ያንሱ እና ቁልፎቹ ተዘጋጅተው ያዳምጡዋቸዋል። ለመውጣት ትር።</translation>
-<translation id="5788275253279308023">ማንነት የማያሳውቅ መስኮት <ph name="TITLE" /> ትር</translation>
-<translation id="5806206155699461681">የተወሰኑ ጣቢያዎችን (እንደ Google ፍለጋ ያሉ) አሻሽል።</translation>
-<translation id="5819072574982403430">የዛፍ ንጥል</translation>
-<translation id="5826479389509458994">ረድፍ <ph name="ROW" /> አምድ <ph name="COL" /></translation>
-<translation id="5850707923114094062">ወደኋላ አንፏቅቅ</translation>
-<translation id="5851548754964597211">የትር ዝርዝር</translation>
-<translation id="5859752971144398932">ከገጽ ውስጥ አግኝ ወጥተዋል።</translation>
-<translation id="5866042630553435010">በከፊል ምልክት ተደርጎበታል</translation>
-<translation id="5869546221129391014">ፍርግርግ</translation>
-<translation id="5876817486144482042">የንግግር ድምጽ ይቀንሱ</translation>
-<translation id="5887397643266327462">የብሬይል መግለጫዎች ነቅተዋል።</translation>
-<translation id="5891934789323004067">ሠንጠረዥ</translation>
-<translation id="5919442531159595654">ገልብጥ።</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{እኩል}one{# የእኩል ምልክቶች}other{# የእኩል ምልክቶች}}</translation>
-<translation id="5939518447894949180">ዳግም አስጀምር</translation>
-<translation id="5948123859135882163">የሒሳብ አገላለጾች አተረጓገም በመዋቅራዊ እና ስነ ፍቺ መካከል ይቀያይሩ</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">መገናኛ</translation>
-<translation id="5963413905009737549">ክፍል</translation>
-<translation id="5968607524793740041">የአውድ ምናሌን አሳይ</translation>
-<translation id="5983179082906765664">የአሰሳ ጥራት ደረጃ ይጨምሩ</translation>
-<translation id="5999630716831179808">ድምጾች</translation>
-<translation id="6000417740266304866">ከታች ካለው ዝርዝር አንድ አማራጭ በመምረጥ አሁን ያለውን ባለ8 ነጥብ ብሬይል ሰንጠረዡን ይለውጡ።</translation>
-<translation id="6006050241733874051">ቅጽ</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{የኋላ እዝባር}one{# የኋላ እዝባሮች}other{# የኋላ እዝባሮች}}</translation>
-<translation id="6037602951055904232">ወደፊት አንፏቅቅ</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">የሕዋስ መጨረሻ።</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">ባዶ ቦታ</translation>
-<translation id="6142308968191113180">ርዕስ 4</translation>
-<translation id="6169420925157477918">ረጅም ማብራሪያ ያለው ምስል</translation>
-<translation id="6172087735260766220">ተደራሽ ጽሑፍ የቅጂ ጥበቃ ካለው ፒዲኤፍ መድረስ አልተቻለም።</translation>
-<translation id="6186305613600865047">ወደ የገጹ ታችኛው ክፍል ይዝለሉ</translation>
-<translation id="6193330012414963395">ጥዋት ከሰዓት</translation>
-<translation id="622484624075952240">ታች</translation>
-<translation id="6236061028292614533">ቀጣይ ርዕስ</translation>
-<translation id="6254901459154107917">ቀጣይ አርትዖት ሊደረግ የሚችል የጽሑፍ አካባቢ</translation>
-<translation id="6259464875943891919">ከ<ph name="TYPE" /> ወጥተዋል።</translation>
-<translation id="6281876499889881039">ቀጣይ ተመሳሳይ አካል።</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">ምንም ቀጣይ ጥምድ ሳጥን የለም።</translation>
-<translation id="6307969636681130414">ተጭኗል</translation>
-<translation id="6324551002951139333">የስዋስው ስህተት ተገኝቷል</translation>
-<translation id="6348657800373377022">ጥምር ሳጥን</translation>
-<translation id="6355910664415701303">ምንም ቀዳሚ የርዕስ ንጥል የለም።</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">ቀዳሚ ርዕስ</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">ምንም ቀዳሚ የሬዲዮ አዝራር የለም።</translation>
-<translation id="6414968628640960377">ቀዳሚ የተለየ አካል።</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{ሁለት ነጥብ}one{# ሁለት ነጥቦች}other{# ሁለት ነጥቦች}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />፣ ምናሌ</translation>
-<translation id="6444046323172968959">የማንቂያ መገናኛ</translation>
-<translation id="6459511626086141404">ልሙጥ የቁልፍ አደራደር</translation>
-<translation id="6468049171101508116">ቀጣይ አዝራር</translation>
-<translation id="6491972999578897419">ከታች ካለው ዝርዝር አንድ አማራጭ በመምረጥ የአሁኑን ድምጽ ይቀይሩት።</translation>
-<translation id="6508059270146105198">የብሬይል ማሳያውን ወደ ገጹ ግርጌ ያንቀሳቅሱ</translation>
-<translation id="6536864053412760904">የMath ML ማስመሰያ</translation>
-<translation id="6550720799683018100">ከታች ካለው ዝርዝር አንድ አማራጭ በመምረጥ የአሁኑ የቁልፍ አደራደር ይቀይሩት።</translation>
-<translation id="6561818612645211875">ወደ የአሁኑ ረድፍ መጀመሪያ ሂድ</translation>
-<translation id="6587021927234520429">ምንም ቀጣይ የደረጃ 4 ርዕስ የለም።</translation>
-<translation id="6601344353291556895">ብዙ ቃላት ያላቸው ማብራሪያዎችን አንቃ።</translation>
-<translation id="6615602925644411249">በዚህ ገጽ ውስጥ ያግኙ።</translation>
-<translation id="6633350132811819843">ምንም ቀጣይ ሠንጠረዥ የለም።</translation>
-<translation id="6637586476836377253">የምዝግብ ማስታወሻ</translation>
-<translation id="6657128831881431364">የሂደት አሞሌ</translation>
-<translation id="6659594942844771486">ትር</translation>
-<translation id="667999046851023355">ሰነድ</translation>
-<translation id="6697092096875747123">ቀዳሚ ጥምድ ሳጥን</translation>
-<translation id="6714813999819678458">ቀዳሚ የደረጃ 2 ርዕስ</translation>
-<translation id="6716505898850596801">መቀየሪያ ቁልፎች</translation>
-<translation id="671916444866103745">ምንም ቀጣይ የARIA ምልክት የለም።</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />፣ ጥምድ ሳጥን</translation>
-<translation id="6735257939857578167">ከ<ph name="NUM" /> ንጥሎች ጋር</translation>
-<translation id="6736510033526053669">ትር ተፈጥሯል</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">ጽሑፍ</translation>
-<translation id="6787839852456839824">የቁልፍ ሰሌዳ አቋራጮች</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">ግርጌ</translation>
-<translation id="6871161210040114857">የሆሄ አቢይ/ንዑስ ችላ በማለት ላይ።</translation>
-<translation id="6877435256196695200">ምንም ቀጣይ ስዕላዊ የለም።</translation>
-<translation id="6897341342232909480">ወደ ግራ ያንቀሳቅሱ</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">ተሰርዟል</translation>
-<translation id="6911965441508464308">ከላይ ምንም ሕዋስ የለም።</translation>
-<translation id="6919104639734799681">የሠንጠረዦች ዝርዝር አሳይ</translation>
-<translation id="6964088412282673743">ምንም ቀዳሚ መቆጣጠሪያ የለም።</translation>
-<translation id="6996566555547746822">ቀጣይ ጥምድ ሳጥን</translation>
-<translation id="7005146664810010831">ምንም ዩአርኤል አልተገኘም</translation>
-<translation id="7010712454773919705">የChromeVox መቀየሪያ ቁልፍ</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">ቀዳሚ ዝርዝር</translation>
-<translation id="7041173719775863268">ምርጫ ይጨርሱ</translation>
-<translation id="7095834689119144465">የጽሑፍ ቁጥር ብቻ ያርትዑ</translation>
-<translation id="7096001299300236431">ቀዳሚ ሚዲያ</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">የቃል ማስተጋባት</translation>
-<translation id="713824876195128146">ቀጣይ የጽሑፍ ጥቅስ</translation>
-<translation id="7161771961008409533">ብቅ-ባይ አዝራር</translation>
-<translation id="7167657087543110">የቁምፊ ማስተጋባት</translation>
-<translation id="7170733337935166589">ቀጣይነት ባለው ንባብ ጊዜ ወደፊት ይዝለሉ</translation>
-<translation id="7181697990050180700">የቁልፍ ሰሌዳ አቋራጮችን ተደጋጋሚ ለሆኑ ትዕዛዞች ለማበጀት ከታች ባሉት መስኮች ላይ ያስገቧቸው።</translation>
-<translation id="7203150201908454328">ተዘርግቷል</translation>
-<translation id="7210211103303402262">ደቂቃዎች</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">መስመር</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">ራስጌ</translation>
-<translation id="7241683698754534149">ረጅም ማብራሪያ በአዲስ ትር ይክፈቱ</translation>
-<translation id="7248671827512403053">መተግበሪያ</translation>
-<translation id="725969808843520477">ቀጣይ የሬዲዮ አዝራር</translation>
-<translation id="7269119382257320590">ምንም ስርዓተ ነጥብ የለም</translation>
-<translation id="7273174640290488576">ባዶ</translation>
-<translation id="7285387653379749618">ሠንጠረዦች</translation>
-<translation id="7289186959554153431">ርዕስ 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">የብሬይል መግለጫዎች ተሰናክለዋል።</translation>
-<translation id="7318872822751139669">ትኩረት ለመቀየር አይጤውን ይጠቀሙ።</translation>
-<translation id="7322388933135261569">ፌብሩዋሪ</translation>
-<translation id="7332592614823088566">ረድፍ <ph name="ROWINDEX" /> ከ<ph name="ROWTOTAL" />፣ አምድ <ph name="COLINDEX" /> ከ<ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">ብቅ-ባይ አለው</translation>
-<translation id="7356165926712028380">ወደ ባለ8 ነጥብ ብሬይል ቀይር</translation>
-<translation id="7362871137496673139">ምንም ቀዳሚ የደረጃ 2 ርዕስ የለም።</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{እና}one{# እናዎች}other{# እናዎች}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">ከሠንጠረዥ በመውጣት ላይ።</translation>
-<translation id="739763518212184081">ቀዳሚ መስመር</translation>
-<translation id="7400575256015741911">የፊደል አጻጻፍ ስህተት ተገኝቷል</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">መልስ</translation>
-<translation id="7434509671034404296">ገንቢ</translation>
-<translation id="7439060726180460871">ማውጫ</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">TAB</translation>
-<translation id="7492049978501397201">የገባ መገናኛ</translation>
-<translation id="7532613204005497612">ጁን</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />፣ <ph name="NAME" />፣ ተንሸራታች</translation>
-<translation id="7586163296341959563">ለጥፍ።</translation>
-<translation id="7596919493010894443">ምርጫ ጸድቷል</translation>
-<translation id="7604026522577407655">ወደ የአሁኑ አምድ መጀመሪያ ሂድ</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">የአሁኑ ገጽ ዩአርኤል አስታውቅ</translation>
-<translation id="7609363189280667021">የብሬይል መግለጫ ጽሑፎችን ይቀያይሩ</translation>
-<translation id="762020119231868829">ሁሉንም አሁን በመጫወት ላይ ያሉ የሚዲያ ንዑስ ፕሮግራሞችን ለአፍታ ያቆማቸዋል</translation>
-<translation id="7625690649919402823">ቀጣይ ሠንጠረዥ</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />)፣ ደረጃ <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">ምንም ቀዳሚ የደረጃ 3 ርዕስ የለም።</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />፣ <ph name="NAME" />፣ የጽሑፍ ሳጥን</translation>
-<translation id="7663318257180412551">ርዕስ 2</translation>
-<translation id="7674576868851035240">ቀጣይ አገናኝ</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">ጽሑፍ፣ የዩ አር ኤል ግቤት ያርትዑ</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">ቀዳሚ የሬዲዮ አዝራር</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />፣ <ph name="NAME" />፣ የይለፍ ቃል ጽሑፍ ሳጥን</translation>
-<translation id="7805247615045262757">ነባሪ አሰሳ</translation>
-<translation id="7805768142964895445">ሁኔታ</translation>
-<translation id="7810781339813764006">ቀጣይ ቡድን</translation>
-<translation id="7819187121850078213">የመስኮት <ph name="TITLE" /> ትር</translation>
-<translation id="7828956995407538686">ኦክቶበር</translation>
-<translation id="7839679365527550018">ቀዳሚው ቃል</translation>
-<translation id="7851816175263618915">የተወሰነ ስርዓተ ነጥብ</translation>
-<translation id="7870596830398826354">የMath ML ዛፍ</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox ንቡር ቀያይር።</translation>
-<translation id="7895896691902835279">ያልታወቀ አገናኝ</translation>
-<translation id="7927711904086083099">አልተመረጠም</translation>
-<translation id="7935627501098484003">የሰዓት መቆጣጠሪያ</translation>
-<translation id="7939428177581522200">ወደ ምርጫ ታክለዋል</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{በ}one{የ# የበ ምልክቶች}other{የ# የበ ምልክቶች}}</translation>
-<translation id="7965147473449754028">ምናሌ ተዘግቷል</translation>
-<translation id="7974390230414479278">የምናሌ ንጥል</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ቃለ አጋኖ}one{# ቃለ አጋኖዎች}other{# ቃለ አጋኖዎች}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{የጥቅስ ምልክት}one{# የጥቅስ ምልክቶች}other{# የጥቅስ ምልክቶች}}</translation>
-<translation id="8033827949643255796">ተመርጧል</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">ጽሑፍ፣ የፍለጋ ግቤት ያርትዑ</translation>
-<translation id="8049189770492311300">ሰዓት ቆጣሪ</translation>
-<translation id="8065607967589909823">ምርጫው</translation>
-<translation id="8066678206530322333">ሰንደቅ</translation>
-<translation id="8110647606445335195">ምንም የARIA ምልክቶች የሉም።</translation>
-<translation id="8153880621934657047">በሠንጠረዥ ውስጥ አይደሉም።</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{ሰረዘዘብጥ}one{# ሰረዘዘብጦች}other{# ሰረዘዘብጦች}}</translation>
-<translation id="8179976553408161302">አስገባ</translation>
-<translation id="81960742267269908">ቁረጥ።</translation>
-<translation id="8199231515320852133">የአሁኑ ሕዋስ ራስጌዎችን አስታውቅ</translation>
-<translation id="820417203470636242">ባዶ ሕዋስ።</translation>
-<translation id="8215202828671303819">ብዙ ምርጫ</translation>
-<translation id="8276439074553447000">ሊተኮርበት ወደሚችል ቀዳሚ ንጥል ይዝለሉ</translation>
-<translation id="8278417001922463147">ምንም ቀዳሚ ጽሑፍ የለም።</translation>
-<translation id="8283603667300770666">ቀጣይ የቅጽ መስክ</translation>
-<translation id="831207808878314375">ብየና</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">ሰዓቶች</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{መሰላል}one{# የመሰላል ምልክቶች}other{# የመሰላል ምልክቶች}}</translation>
-<translation id="8374154622594089836">month</translation>
-<translation id="8378855320830505539">ክልል</translation>
-<translation id="8382679411218029383">ራስ-አጠናቅቅ መስመር ውስጥ እና ዝርዝር</translation>
-<translation id="8428603554127842284">ደረጃ <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">ምንም ቀጣይ የደረጃ 3 ርዕስ የለም።</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">ምንም ቀዳሚ አመልካች ሳጥን የለም።</translation>
-<translation id="8455868257606149352">ከፍተኛ <ph name="X" /></translation>
-<translation id="84575901236241018">የመዳረሻ ቁልፍ <ph name="KEY" /> አለው</translation>
-<translation id="8503360654911991865">የአሰሳ ጥራት ደረጃ ይቀንሱ</translation>
-<translation id="8520472399088452386">ማሾሪያ አዝራር</translation>
-<translation id="8538744478902126321">የአሁኑ ሕዋስ ረድፍ ራስጌ ገምት</translation>
-<translation id="8540054775867439484">ወደ ላይ ተጠቅልሏል</translation>
-<translation id="8548973727659841685">ቁምፊ</translation>
-<translation id="8561322612995434619">ብቅ-ባይ አለው</translation>
-<translation id="8571096049907249734">በርካታ ምርጫ</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">የቀጣይ ዝርዝር ንጥል</translation>
-<translation id="860150890330522909"><ph name="NAME" /> አመልካች ሳጥን ላይ ምልክት ተደርጓል</translation>
-<translation id="8606621670302093223">የቀን መቆጣጠሪያ</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> ንጥሎች ተመርጠዋል</translation>
-<translation id="8638532244051952400">የአሁኑ የሕዋስ መገናኛ ነጥቦች አስታውቅ</translation>
-<translation id="8650576015643545550">ምንም ቀዳሚ ዝርዝር የለም።</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">የአገናኞች ዝርዝር አሳይ</translation>
-<translation id="8664519043722036194">ሴኮንድ</translation>
-<translation id="867187640362843212">ርዕስ 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{ቁም መስመር}one{# የቁም መስመሮች}other{# የቁም መስመሮች}}</translation>
-<translation id="8735450637152821465">ምርጫ ይጀምሩ</translation>
-<translation id="8743786158317878347">እንደ ሠንጠረዦች ያለ የተዋቀረ ይዘት ያስገቡ</translation>
-<translation id="8747966237988593539">በቅደም ተከተል የተቀመጠ ዝርዝር</translation>
-<translation id="8759334257841767240">ምንም ቀጣይ አገናኝ የለም።</translation>
-<translation id="8767968232364267681">ቀጣይ የደረጃ 4 ርዕስ</translation>
-<translation id="8770473310765924354">እንደ ሠንጠረዦች ካለ የተዋቀረ ይዘት ይውጡ</translation>
-<translation id="8791025954632646584">ስነ ፍቺ በርቷል</translation>
-<translation id="8796411681063377102">ቀጣይ የደረጃ 3 ርዕስ</translation>
-<translation id="8808582214901541005">ማርች</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">ትዕዛዞችን ለመከለስ ላይ ወይም ታች ይጫኑ፣ ለማግበር enterን ይጫኑ</translation>
-<translation id="8864099967139188018">ምንም ቀጣይ የደረጃ 6 ርዕስ የለም።</translation>
-<translation id="8882002077197914455">የረድፍ ራስጌ</translation>
-<translation id="8896347895970027998">ChromeVox እንዲገብር ወይም እንዲቦዝን ይቀያይሩ።</translation>
-<translation id="8898516272131543774">የስርዓተ ነጥብ ማስተጋባት ዑደት</translation>
-<translation id="8900148057318340779">የቅድመ-ቅጥያ ቁልፍ</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">ባዶ ርዕሶች</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">መቀየሪያ ቁልፎች</translation>
-<translation id="8943175951035496220">በቀኝ ምንም ሕዋስ የለም።</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">ምንም ሰንጠረዦች የሉም።</translation>
-<translation id="9040132695316389094">ርዕስ 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">የፍለጋ ንዑስ ፕሮግራም ይቀያይሩ</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">ከምርጫ ተወግዷል</translation>
-<translation id="9082874451376019682">ምንም ቀዳሚ ተንሸራታች የለም።</translation>
-<translation id="9089864840575085222">የትየባ ማስተጋባት ዑደት</translation>
-<translation id="9107530006868467849">ምንም ቀድማኢ የሚዲያ ንዑስ ፕሮግራም የለም።</translation>
-<translation id="9108370397979208512">ሒሳብ</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{መቶኛ}one{# የመቶኛ ምልክቶች}other{# የመቶኛ ምልክቶች}}</translation>
-<translation id="9115913704608474258">ኖቬምበር</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">የአሁኑን ቦታ አጭር ማብራሪያ ያስታውቃል</translation>
-<translation id="9153606228985488238">ቅጥነት <ph name="PERCENT" /> በመቶ</translation>
-<translation id="9160096769946561184">ወደ የአሁኑ አምድ መጨረሻ ሂድ</translation>
-<translation id="9173115498289768110">የድምጽ መጠን <ph name="PERCENT" /> በመቶ</translation>
-<translation id="9178973770513562274">ለማሰስ የላይ ወይም ታች ቀስት ቁልፎቹን ይጠቀሙ፣ ወይም ደግሞ ለመፈለግ ይተይቡ።</translation>
-<translation id="9192904702577636854">ቀልብ ሳቢ</translation>
-<translation id="9212322457209634662">ምንም ቀጣይ ክፍል የለም።</translation>
-<translation id="930275611743429116">ምርጫ ይጀምሩ ወይም ይጨርሱ።</translation>
-<translation id="948171205378458592">የንግግር ፍጥነት ይቀንሱ</translation>
-<translation id="962913030769097253">ቀጣይ የደረጃ 1 ርዕስ</translation>
-<translation id="973955474346881951">አጣባቂ ሁነታን አንቃ/አሰናክል</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ar.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ar.xtb
deleted file mode 100644
index 72cfd054cd8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ar.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ar">
-<translation id="1012173283529841972">عنصر قائمة</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">تم مد الخلية.</translation>
-<translation id="1025074108959230262">تم تعطيل الوضع الثابت</translation>
-<translation id="1031961866430398710">ثم</translation>
-<translation id="1044777062731150180">ليست هناك عناوين</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">إدخال غير صالح</translation>
-<translation id="1082209053475788238">ليس هناك عنوان سابق من المستوى السادس.</translation>
-<translation id="1088219014394087294">ليست هناك عناوين.</translation>
-<translation id="1106741348836243114">‏تشغيل التعليقات الصوتية (earcons) أو إيقافها.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">مجموعة من <ph name="TAG" /> تشتمل على <ph name="NUM" /> من العناصر</translation>
-<translation id="1155043339247954670">ليس هناك عنصر قائمة تالٍ.</translation>
-<translation id="1157782847298808853">مساعدة لوحة المفاتيح</translation>
-<translation id="1157843803349774103">مربع تحرير <ph name="NAME" />، بالقيمة <ph name="VALUE" /></translation>
-<translation id="1167230103353892028">عنصر القائمة <ph name="NAME" /> مع قائمة فرعية</translation>
-<translation id="1177863135347784049">مخصص</translation>
-<translation id="1188858454923323853">تكميلي</translation>
-<translation id="1206619573307042055">صورة بها نص متحرك</translation>
-<translation id="1213216066620407844">‏ChromeVox - تزويد Chrome بالصوت</translation>
-<translation id="1229276918471378188">الانتقال السابق</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">عنوان المستوى السادس التالي</translation>
-<translation id="1275718070701477396">محدد</translation>
-<translation id="1319608975892113573">ليست هناك علامة اقتباس فقرة سابقة.</translation>
-<translation id="1321576897702511272">‏إخفاء مساعدة ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> من <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">صدى الحرف والكلمة</translation>
-<translation id="1339428534620983148">عمود الجدول السابق</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">يمين</translation>
-<translation id="136718599399906424">صف الجدول التالي</translation>
-<translation id="1383876407941801731">البحث</translation>
-<translation id="1385214448885562192">‏اضغط على Enter للموافقة أو Esc للإلغاء، واضغط على السهم لأسفل للانتقال إلى النتيجة التالية وعلى السهم لأعلى للانتقال إلى النتيجة السابقة.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652">مربع نص كلمة المرور بالقيمة <ph name="VALUE" /></translation>
-<translation id="1467432559032391204">اليسار</translation>
-<translation id="1474557363159888097">ليس هناك إرساء سابق.</translation>
-<translation id="1502086903961450562">الرسم السابق</translation>
-<translation id="1506187449813838456">زيادة درجة الصوت</translation>
-<translation id="151784044608172266">الجملة التالية</translation>
-<translation id="1524531499102321782">السطر التالي بطريقة برايل</translation>
-<translation id="1546370775711804143">شريط التمرير</translation>
-<translation id="1559739829547075274">الانتقال للخلف</translation>
-<translation id="1571643229714746283">‏ChromeVox جاهز</translation>
-<translation id="158493514907962286">كانون الأول (ديسمبر)</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">التبديل إلى نمط برايل 6 نقاط</translation>
-<translation id="1611168825862729585">رأس العمود:</translation>
-<translation id="1613476421962910979">‏تم تشغيل Earcons</translation>
-<translation id="1618597272655350600">الإعلان عن وصف كامل للموضع الحالي</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{علامة أكبر من واحدة}zero{# greater than signs}two{علامتا أكبر من (#)}few{# علامات أكبر من}many{# علامة أكبر من}other{# من علامات أكبر من}}</translation>
-<translation id="1653266918374749391">عنوان المستوى الثالث السابق</translation>
-<translation id="1659072772017912254">غير محدد</translation>
-<translation id="1669290819662866522">أسبوع</translation>
-<translation id="1674262202423278359">‏التنقل في ChromeVox</translation>
-<translation id="16777221443363124">شريط قوائم</translation>
-<translation id="1692077714702418899">خط تنظيمي</translation>
-<translation id="1700517974991662022">تم الانتقال إليه</translation>
-<translation id="1722567105086139392">رابط</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">الرسم التالي</translation>
-<translation id="1781173782405573156">مفتاح التمرير</translation>
-<translation id="1787176709638001873">نص تعديل كلمة المرور</translation>
-<translation id="1810107444790159527">مربع قائمة</translation>
-<translation id="1828385960365606039">مايو (أيار)</translation>
-<translation id="1834891354138622109">عمود</translation>
-<translation id="1865601187525349519">نهاية النص</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">نطق الوقت والتاريخ الحاليين.</translation>
-<translation id="1902396333223336119">خلوي</translation>
-<translation id="1905379170753160525">عرض قائمة العناوين</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">التحكم في أسبوع من العام</translation>
-<translation id="1964135212174907577">الكائن التالي</translation>
-<translation id="1969092762068865084">تموز (يوليو)</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">عنوان الصف:</translation>
-<translation id="2002895034995108595">إعادة تعيين مخطط المفاتيح الحالي</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{قوس متوسط أيسر واحد}zero{# left brackets}two{قوسان متوسطان أيسران (#)}few{# أقواس متوسطة يسرى}many{# قوسًا متوسطًا أيسرًا}other{# من الأقواس اليسرى}}</translation>
-<translation id="2045490512405922022">غير محدد</translation>
-<translation id="20601713649439366">ليس هناك تعبير رياضي سابق.</translation>
-<translation id="207477615537953741">تم إيقاف الدلالات</translation>
-<translation id="2086961585857038472">الكلمة التالية</translation>
-<translation id="2089387485033699258">ar</translation>
-<translation id="2091933974477985526">منطقة النص السابق القابل للتعديل</translation>
-<translation id="2100350898815792233">جميع علامات الترقيم</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">مفتاح الدخول:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">يمكنك تغيير الجدول بنمط برايل 6 نقاط الحالي عبر تحديد خيار من القائمة أدناه.</translation>
-<translation id="2169714232367507776">النقر على العنصر الحالي</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{قوس مغلق واحد}zero{# close parens}two{قوسان مغلقان (#)}few{# أقواس مغلقة}many{# قوسًا مغلقًا}other{# من الأقواس المغلقة}}</translation>
-<translation id="2199994615414171367">التعبير الرياضي السابق</translation>
-<translation id="2223693656926968778">اتخاذ إجراء للعنصر الحالي</translation>
-<translation id="225732394367814946">زيادة تقييم النطق</translation>
-<translation id="2267945578749931355">الحرف التالي</translation>
-<translation id="2281234842553884450">شريط التمرير السابق</translation>
-<translation id="2318372665160196757">رئيسي</translation>
-<translation id="2329324941084714723">لوحة علامة التبويب</translation>
-<translation id="2344193891939537199">التحكم في الوقت والتاريخ</translation>
-<translation id="2359897517538099099">ليس في وضع الجدول.</translation>
-<translation id="241124561063364910">يليه</translation>
-<translation id="2417569100218200841">معلومات المحتوى</translation>
-<translation id="2422937916923936891">مربّع اختيار عنصر القائمة</translation>
-<translation id="2429669115401274487">مساءً</translation>
-<translation id="2435413342408885429">‏أصبح <ph name="KEY" /> مفتاح تعديل ChromeVox الجديد الآن.</translation>
-<translation id="2450814015951372393">مربع الاختيار</translation>
-<translation id="2462626033734746142">مجموعة أزرار الاختيار</translation>
-<translation id="2471138580042810658">العنوان السادس</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{علامة نجمة واحدة}zero{# asterisks}two{علامتا نجمة (#)}few{# علامات نجمة}many{# علامة نجمة}other{# من علامات النجمة}}</translation>
-<translation id="2549392850788122959">تمت إعادة تعيين <ph name="KEY" />.</translation>
-<translation id="2553108862507765288">خطأ نحوي</translation>
-<translation id="257674075312929031">مجموعة</translation>
-<translation id="2582407057977008361">جانبًا</translation>
-<translation id="2589102159832527089">‏تتضمن هذه الصفحة النص المستخرج تلقائيًا من ملف PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;انقر هنا للحصول على الملف الأصلي.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">مع {COUNT,plural, =1{عنصر واحد (#)}zero{# عنصر}two{عنصران (#)}few{# عناصر}many{# عنصرًا}other{# عنصر}}</translation>
-<translation id="2614981083756825552">تخطيط لغة التوصيف الرياضية</translation>
-<translation id="2626530649491650971">قابل للنقر</translation>
-<translation id="2628764385451019380">ليس هناك مربع تحرير وسرد سابق.</translation>
-<translation id="2637227747952042642">رياضيات</translation>
-<translation id="2639750663247012216">‏مفتاح تعديل ChromeVox</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">انقر فوق العنصر أسفل مفتاح التوجيه</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{قوس مفتوح واحد}zero{# open parens}two{قوسان مفتوحان (#)}few{# أقواس مفتوحة}many{# قوسًا مفتوحًا}other{# من الأقواس المفتوحة}}</translation>
-<translation id="2705875883745373140">غير مضغوط</translation>
-<translation id="2706462751667573066">أعلى</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">الصوت</translation>
-<translation id="2732718972699418926">صباحًا</translation>
-<translation id="2749275490991666823">محدد</translation>
-<translation id="27527859628328957">الانتقال إلى العنصر التالي القابل للتركيز</translation>
-<translation id="2770781857296573485">الدخول إلى استكشاف المجموعات</translation>
-<translation id="2777845298774924149">تم الإنهاء</translation>
-<translation id="2800204403141299078">ليس هناك المزيد من العناصر المختلفة.</translation>
-<translation id="2800780099804980316">ليس هناك عنوان سابق من المستوى الأول.</translation>
-<translation id="2811204574343810641">صف</translation>
-<translation id="2816654101880605877">ليس هناك شريط تمرير تالٍ.</translation>
-<translation id="2841013758207633010">الوقت</translation>
-<translation id="2843837985843789981">المجموعة السابقة</translation>
-<translation id="2844995807198708617">قائمة السياق</translation>
-<translation id="2849332794118375855">ليس هناك مربع اختيار تالٍ.</translation>
-<translation id="2864481629947106776">الرابط السابق</translation>
-<translation id="2873259058405069099">الانتقال إلى بداية الجدول</translation>
-<translation id="2894654529758326923">المعلومات</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{قوس كبير أيسر واحد}zero{# left braces}two{قوسان كبيران أيسران (#)}few{# أقواس كبيرة يسرى}many{# قوسًا كبيرًا أيسرًا}other{# من الأقواس الكبيرة اليسرى}}</translation>
-<translation id="2911433807131383493">‏فتح برنامج ChromeVox التعليمي</translation>
-<translation id="2932083475399492303">تبديل نوع الخط بين تنظيمي أو تخطيطي</translation>
-<translation id="2964026537669811554">مجموعة عناوين</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{علامة جدولة واحدة}zero{# tabs}two{علامتا جدولة}few{# علامات جدولة}many{# علامة جدولة}other{# من علامات الجدولة}}</translation>
-<translation id="2972078295414139404">ليس هناك رابط سابق تم الانتقال إليه.</translation>
-<translation id="2972205263822847197">تلميح</translation>
-<translation id="2998131015536248178">الحرف السابق</translation>
-<translation id="2999559350546931576">خفض درجة الصوت</translation>
-<translation id="2999945368667127852">ليس هناك أداة للوسائط التالية.</translation>
-<translation id="3012414509011670858">ليس هناك قسم سابق.</translation>
-<translation id="3030432017085518523">زر اختيار عنصر القائمة</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{فاصلة عليا واحدة}zero{# apostrophes}two{فاصلتان علويتان (}few{# فواصل علوية}many{# فاصلة علوية}other{# من الفواصل العلوية}}</translation>
-<translation id="3046838483509668188">‏خيارات ChromeVox</translation>
-<translation id="3047143736589213134">مخطط مفاتيح تجريبي</translation>
-<translation id="3060756054951570867">تم فتح القائمة <ph name="TITLE" /></translation>
-<translation id="3078345202707391975">عنوان المستوى الثاني التالي</translation>
-<translation id="3078740164268491126">جدول</translation>
-<translation id="3082557070674409251">تم النقر عليه</translation>
-<translation id="3084806535845658316">ليس هناك صدى للكتابة</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">ليس هناك تعبير رياضي تالٍ.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">المَعلم التالي</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">مصغّر</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">عرض قائمة المعالم</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">السطر التالي</translation>
-<translation id="3155083529632865074">ليس هناك زر سابق.</translation>
-<translation id="3163593631834463955">عنوان عمود فارغ</translation>
-<translation id="316542773973815724">تنقل</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{مسافة واحدة}zero{# spaces}two{مسافتان (#)}few{# مسافات}many{# مسافة}other{# من المسافات}}</translation>
-<translation id="320961988183078793">تم إدخال <ph name="TYPE" /></translation>
-<translation id="3223701887221307104">علامة تبويب <ph name="NAME" /></translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">الرابط الذي تم الانتقال إليه</translation>
-<translation id="323731244387692321">‏فتح مساعدة لوحة مفاتيح ChromeVox</translation>
-<translation id="3241052487511142956">الرابط السابق الذي تمّ الانتقال إليه</translation>
-<translation id="3286390186030710347">شريط تمرير</translation>
-<translation id="3299925995433437805">ليس هناك رابط تالٍ تم الانتقال إليه.</translation>
-<translation id="3303384412438961941">‏اضغط على أي مفتاح للتعرف على اسمه. يؤدي الضغط على Ctrl+W إلى إغلاق مستكشف لوحة المفاتيح.</translation>
-<translation id="3307886118343381874">الانتقال إلى نهاية الجدول</translation>
-<translation id="3311969765485641742">‏اضغط على Alt+Shift+A لمراجعة التنبيهات</translation>
-<translation id="3312997241656799641">الرابط التالي الذي تم الانتقال إليه</translation>
-<translation id="3321460131042519426">تمكين التفاف الكلمات</translation>
-<translation id="3322936298410871309">عنوان المستوى الأول السابق</translation>
-<translation id="3323447499041942178">مربع نص</translation>
-<translation id="3353420241558113817">‏{"ar": "العربية"،
- "bg": "البلغارية"،
- "ca": "الكتالانية"،
- "cs": "التشيكية"،
- "da": "الدنماركية"،
- "de": "الألمانية"،
- "de_CH": "الألمانية (سويسرا)"،
- "de_DE": "الألمانية (ألمانيا)"،
- "el": "اليونانية"،
- "en": "الإنجليزية"،
- "en_CA": "الإنجليزية (كندا)"،
- "en_GB": "الإنجليزية (المملكة المتحدة)"،
- "en_US": "الإنجليزية (الولايات المتحدة)"،
- "es": "الأسبانية"،
- "et": "الإستونية"،
- "fr": "الفرنسية"،
- "fr_CA": "الفرنسية (كندا)"،
- "fr_FR": "الفرنسية (فرنسا)"،
- "fi": "الفنلندية"،
- "he": "العبرية"،
- "hi": "الهندية"،
- "hr": "الكرواتية"،
- "hu": "المجرية"،
- "is": "الأيسلندية"،
- "it": "الإيطالية"،
- "ko": "الكورية"،
- "lt": "الليتوانية"،
- "lv": "اللاتفية"،
- "nb": "النرويجية (بوكمال)"،
- "nl": "الهولندية"،
- "pl": "البولندية"،
- "pt": "البرتغالية"،
- "ro": "الرومانية"،
- "ru": "الروسية"،
- "sk": "السلوفاكية"،
- "sl": "السلوفينية"،
- "sr": "الصربية"،
- "sv": "السويدية"،
- "tr": "التركية"،
- "vi": "الفيتنامية"،
- "zh": "الصينية"،
- "zh_TW": "الصينية (الهان التقليدية)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{علامة جمع واحدة}zero{# plus signs}two{علامتا جمع (#)}few{# علامات جمع}many{# علامة جمع}other{# من علامات الجمع}}</translation>
-<translation id="338583716107319301">فاصل</translation>
-<translation id="3389259863310851658">حقل النموذج السابق</translation>
-<translation id="3390225400784126843">العنصر المختلف التالي.</translation>
-<translation id="3392045790598181549">عنصر القائمة <ph name="NAME" /></translation>
-<translation id="3406283310380167331">عرض قائمة النماذج</translation>
-<translation id="3422338090358345848">فتح مستكشف لوحة المفاتيح</translation>
-<translation id="3457000393508828486">مضغوط جزئيًا</translation>
-<translation id="3462439746547587373">الزر <ph name="NAME" /></translation>
-<translation id="3473644018603298796">تم تحديد <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> إلى <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{قوس متوسط أيمن واحد}zero{# right brackets}two{قوسان متوسطان أيمنان (#)}few{# أقواس متوسطة يمنى}many{# قوسًا متوسطًا أيمنًا}other{# من الأقواس المتوسطة اليمنى}}</translation>
-<translation id="3493915602752813531">ليس هناك إرساء تالٍ.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{علامة استفهام واحدة}zero{# question marks}two{علامتا استفهام (#)}few{# علامات استفهام}many{# علامة استفهام}other{# من علامات الاستفهام}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{علامة إقحام واحدة}zero{# carets}two{علامتا إقحام (#)}few{# علامات إقحام}many{# علامة إقحام}other{# من علامات الإقحام}}</translation>
-<translation id="3568702578574425662">لم يتم تحديد مربع الاختيار <ph name="NAME" /></translation>
-<translation id="3599054940393788245">ليس داخل الرياضيات</translation>
-<translation id="3616113530831147358">الصوت</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{علامة تجزئة واحدة}zero{# backticks}two{علامتا تجزئة (#)}few{# علامات تجزئة}many{# علامة تجزئة}other{# من علامات التجزئة}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{علامة دولار واحدة}zero{# dollar signs}two{علامتا دولار (#)}few{# علامات دولار}many{# علامة دولار}other{# من علامات الدولار}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755">مربع القائمة <ph name="VALUE" /></translation>
-<translation id="3687295507293856493">إجراء تخمين في عنوان العمود للخلية الحالية</translation>
-<translation id="3692274950075847560">بحث:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">التحكم في النطق</translation>
-<translation id="3716845769494773620">متعدد الأسطر</translation>
-<translation id="3731746171184829332">ليس هناك عنوان سابق.</translation>
-<translation id="3762198587642264450">الانتقال إلى نهاية الصف الحالي</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">تم إنهاء مربع الحوار.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}zero{#}two{#}few{#}many{#}other{#}}</translation>
-<translation id="3801735343383419236">إكمال تلقائي على هيئة قائمة</translation>
-<translation id="3810838688059735925">فيديو</translation>
-<translation id="3816633764618089385">الوسائط التالية</translation>
-<translation id="3819376190738087562">ليست هناك نقاط انتقال.</translation>
-<translation id="385383972552776628">فتح صفحة الخيارات</translation>
-<translation id="3856075812838139784">للقراءة فقط</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">قائمة</translation>
-<translation id="3909320334364316587">عنوان المستوى السادس السابق</translation>
-<translation id="3914173277599553213">مطلوبة</translation>
-<translation id="3962990492275676168">بدء القراءة من الموقع الحالي</translation>
-<translation id="4004802134384979325">تم التحديد</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">التحكم في الشهر</translation>
-<translation id="4039983576244166038">عنوان صف فارغ</translation>
-<translation id="4042843249978639960">ليس هناك عنوان تالٍ من المستوى الثاني.</translation>
-<translation id="4043348641337972076">‏ليس هناك مَعلم ARIA سابق.</translation>
-<translation id="4047216625641135770">علامة</translation>
-<translation id="404803211695627272"><ph name="V1" />-‏<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{علامة تلدة واحدة}zero{# tildes}two{علامتا تلدة (#)}few{# علامات تلدة}many{# علامة تلدة}other{# من علامات تلدة}}</translation>
-<translation id="409334809956508737">الكائن السابق</translation>
-<translation id="4099274309791143834">بقائمة فرعية</translation>
-<translation id="4107807507418787238">ليست هناك خلية أدناه.</translation>
-<translation id="4116415223832267137">تنبيه</translation>
-<translation id="4147126331795725888">ليس هناك عنصر تحكم تالٍ.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{قوس كبير أيمن واحد}zero{# right braces}two{قوسان كبيران أيمنان (#)}few{# أقواس كبيرة يمنى}many{# قوسًا كبيرًا أيمنًا}other{# من الأقواس الكبيرة اليمنى}}</translation>
-<translation id="4158704014418536539">حساس لحالة الأحرف.</translation>
-<translation id="4161663686871496107">‏تعليقات ChromeVox المنطوقة جاهزة</translation>
-<translation id="4173994908659439270">ليس هناك حقل تالٍ قابل للتعديل.</translation>
-<translation id="4176463684765177261">معطل</translation>
-<translation id="4188530942454211480">الجملة السابقة</translation>
-<translation id="4202186506458631436">الانتقال يمينًا</translation>
-<translation id="4206289001967551965">داخل الجدول</translation>
-<translation id="4215733775853809057">شريط التمرير التالي</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{شرطة واحدة}zero{# dashes}two{شرطتان (#)}few{# شرطات}many{# شرطة}other{# من الشرطات}}</translation>
-<translation id="421884353938374759">علبة الألوان</translation>
-<translation id="4229646983878045487">تاريخ ووقت</translation>
-<translation id="423334822609210999">ليست هناك خلية في اليسار.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />، الدرجة <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">ملاحظة</translation>
-<translation id="4254798249533888099">متفرع</translation>
-<translation id="4255943572433203166">‏استخدم الخيارات أدناه لتخصيص ChromeVox. تسري التغييرات في الحال.</translation>
-<translation id="4271220233568730077">التعبير الرياضي التالي</translation>
-<translation id="4271521365602459209">لا تتوفر نتائج أخرى.</translation>
-<translation id="4287520460805643128">لا تتوفر مقالة تالية.</translation>
-<translation id="4289540628985791613">نظرة عامة</translation>
-<translation id="4300318234632215983">‏الإعلان عن عنوان URL وراء رابط</translation>
-<translation id="4301352596632316575">لها قائمة فرعية</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{نقطة واحدة}=3{علامة حذف}zero{# dots}two{نقطتان (#)}few{# نقاط}many{# نقطة}other{# من النقاط}}</translation>
-<translation id="4347461890115250064">ليست هناك قائمة تالية.</translation>
-<translation id="4367650418938037324">ورقة لغة التوصيف الرياضية</translation>
-<translation id="4372435075475052704">الحد الأدنى:<ph name="X" /></translation>
-<translation id="4372705107434148843">إيقاف النطق</translation>
-<translation id="4373197658375206385">ليس هناك عنصر سابق بخلاف الروابط.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">ليست هناك أية روابط.</translation>
-<translation id="4476183483923481720">سطر جديد</translation>
-<translation id="4482330759234983253">الجدول السابق</translation>
-<translation id="4491109536499578614">صورة</translation>
-<translation id="4529987814483543472">مخطط مفاتيح كلاسيكي</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{شرطة مائلة واحدة}zero{# slashes}two{شرطتان مائلتان (#)}few{# شرطات مائلة}many{# شرطة مائلة}other{# من الشرطات المائلة}}</translation>
-<translation id="4547556996012970016">عنوان المستوى الخامس التالي</translation>
-<translation id="4562381607973973258">رأس صفحة</translation>
-<translation id="4591507479202817876">، محدد</translation>
-<translation id="4597532268155981612">نموذج</translation>
-<translation id="4597896406374528575">نيسان (أبريل)</translation>
-<translation id="4615592953348396470">تجاهل الضغط على المفتاح التالي</translation>
-<translation id="461613135510474570">جملة</translation>
-<translation id="4647836961514597010">علبة الألوان</translation>
-<translation id="4661075872484491155">متفرع</translation>
-<translation id="4668929960204016307">،</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">المَعلم السابق</translation>
-<translation id="4696413482802371445">ليس هناك حقل تالٍ من المستوى الخامس.</translation>
-<translation id="4729095194763193578">صف الجدول السابق</translation>
-<translation id="4736221692378411923">آب (أغسطس)</translation>
-<translation id="4740661827607246557">أوامر المساعدة</translation>
-<translation id="4759716709594980008">‏مستكشف لوحة مفاتيح ChromeOS</translation>
-<translation id="4763296182459741068">التفاف إلى أسفل</translation>
-<translation id="4763480195061959176">فيديو</translation>
-<translation id="479989351350248267">بحث</translation>
-<translation id="481165870889056555">الإعلان عن عنوان الصفحة الحالية</translation>
-<translation id="4826415162591436065">التنقل للأمام</translation>
-<translation id="4826604887384865800">الانتقال التالي</translation>
-<translation id="4827410568042294688">تم إلغاء التحديد</translation>
-<translation id="4842108708071771135">ليست هناك علامة اقتباس فقرة تالية.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">العنصر المماثل السابق.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">‏تمكين تسجيل TTS</translation>
-<translation id="4877261390094455813">الدخول إلى طلب بحث.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">رابط داخلي</translation>
-<translation id="4953585991029886728">تعديل النص</translation>
-<translation id="4954534434583049121">الاقتباس الطويل السابق</translation>
-<translation id="4973717656530883744">الحد الأدنى <ph name="X" /></translation>
-<translation id="4973762002207131920">تم التبديل إلى <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">مللي ثانية</translation>
-<translation id="49787999531187221">‏الإضافة ChromeVox غير نشطة الآن.</translation>
-<translation id="4979404613699303341">الزر السابق</translation>
-<translation id="4982773647088557172">مربع القائمة <ph name="NAME" />، بالقيمة <ph name="VALUE" /></translation>
-<translation id="4983588134362688868">انتقال إلى أعلى الصفحة</translation>
-<translation id="4986606102545753256">النافذة <ph name="NAME" /></translation>
-<translation id="4993152509206108683">تقييم بنسبة <ph name="PERCENT" /> في المائة</translation>
-<translation id="4996716799442435517">مرئية</translation>
-<translation id="4997282455736854877">تم تحديد زر الاختيار <ph name="NAME" /></translation>
-<translation id="4997475792277222884">ليس هناك عنصر تالٍ بخلاف الروابط.</translation>
-<translation id="5000760171916499057">ليس هناك أي نماذج.</translation>
-<translation id="5005670136041063723">ليس هناك المزيد من العناصر المماثلة.</translation>
-<translation id="501473567976723023">كانون الثاني (يناير)</translation>
-<translation id="5041394372352067729">نقل عرض برايل إلى أعلى الصفحة</translation>
-<translation id="5042770794184672516">زيادة مستوى صوت النطق</translation>
-<translation id="5050015258024679800">عنوان المستوى الرابع السابق</translation>
-<translation id="5054047268577924192">عنصر القائمة السابق</translation>
-<translation id="5078661581131202757">تحديد الملف</translation>
-<translation id="5080758118274074384">تم النقر عليه نقرًا مزدوجًا</translation>
-<translation id="5098541983634824365">مغادرة الشبكة.</translation>
-<translation id="5102981729317424850">شريط الأدوات</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">ليس هناك حقل نموذج سابق.</translation>
-<translation id="5111640677200759579">عنوان العمود</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">ليس هناك رابط سابق.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">، تم إلغاء التحديد</translation>
-<translation id="5183440668879371625">السطر السابق بطريقة برايل</translation>
-<translation id="5184944171021383281">ليس هناك حقل نموذج تالٍ.</translation>
-<translation id="5189244881767082992">خط</translation>
-<translation id="5203930734796605961">تم تعيين <ph name="KEY" /> إلى أمر من قبل.</translation>
-<translation id="5205493599117157272">قائمة <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">ليس هناك زر اختيار تالٍ.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">‏مفتاح End</translation>
-<translation id="5291783959063340370">الهدف</translation>
-<translation id="5304943142864553931">علامة التبويب <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">تمت إزالة:</translation>
-<translation id="5320727453979144100">تم تمكين الوضع الثابت</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{فاصلة واحدة}zero{# commas}two{فاصلتان (#)}few{# فواصل}many{# فاصلة}other{# من الفواصل}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />، مربع النص</translation>
-<translation id="5330443287809544590">الرابط <ph name="NAME" /></translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">الرجوع إلى الخلف أثناء القراءة المتواصلة</translation>
-<translation id="5368000168321181111">‏تم إيقاف Earcons</translation>
-<translation id="5374320867641260420">ليس هناك زر تالٍ.</translation>
-<translation id="5382299583965267720">ليس هناك عنوان تالٍ من المستوى الأول.</translation>
-<translation id="5402367795255837559">لغة برايل</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{فاصلة منقوطة واحدة}zero{# semicolons}two{فاصلتان منقوطتان (#)}few{# فواصل منقوطة}many{# فاصلة منقوطة}other{# من الفواصل المنقوطة}}</translation>
-<translation id="5411891038905756502">ليست هناك نقطة انتقال سابقة.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{علامة أقل من واحدة}zero{# less than signs}two{علامتا أقل من (#)}few{# علامات أقل من}many{# علامة أقل من}other{# من علامات أقل من}}</translation>
-<translation id="5455441614648621694">تكميلي</translation>
-<translation id="5485036206801896268">ليس هناك رسم سابق.</translation>
-<translation id="5486947920110100234">ليست هناك نقطة انتقال تالية.</translation>
-<translation id="549602578321198708">كلمة</translation>
-<translation id="5500932716852106146">ليس هناك حقل نص سابق قابل للتعديل.</translation>
-<translation id="5502713021410870035">أيلول (سبتمبر)</translation>
-<translation id="5507663321906818013">معيار تصحيح الأخطاء</translation>
-<translation id="5518443085409638729">‏ضع المؤشر بين الحروف عند تعديل النص (مثل Mac OS X).</translation>
-<translation id="552195134157544755">زر الاختيار</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">ليس هناك عنوان سابق من المستوى الخامس.</translation>
-<translation id="556042886152191864">زر</translation>
-<translation id="5561345396546889625">القائمة التالية</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">تعديل النص، إدخال البريد الإلكتروني</translation>
-<translation id="5597170376237141345">مربع الاختيار التالي</translation>
-<translation id="5597933780944041114">ليس هناك عنوان تالٍ.</translation>
-<translation id="5598905979683743333">تم إلغاء تحديد زر الاختيار <ph name="NAME" /></translation>
-<translation id="5601172225407283979">تنفيذ إجراء افتراضي</translation>
-<translation id="5608798115546226984">إكمال تلقائي مضمن</translation>
-<translation id="561939826962581046">الوقت</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">السجل</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">ليس هناك جدول سابق.</translation>
-<translation id="5655682562155942719">أوامر الانتقال السريع</translation>
-<translation id="56637627897541303">منطقة النص</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">مَعلم</translation>
-<translation id="5683155931978483559">مربع الاختيار السابق</translation>
-<translation id="5684277895745049190">القائمة</translation>
-<translation id="5700650669149824506">ليس هناك عنوان سابق من المستوى الرابع.</translation>
-<translation id="5709192780268610569">ليس هناك وصف مطول</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">عمود الجدول التالي</translation>
-<translation id="571866080859340309">جارٍ استكشاف المجموعات</translation>
-<translation id="5728409797179002635">لم يتم العثور على جداول.</translation>
-<translation id="5748623122140342504">عنوان المستوى الخامس السابق</translation>
-<translation id="5750633686117194034">لم يتم الضغط على أي مفتاح تعديل؛ الرجاء الضغط مع الاستمرار على مفتاح تعديل أو أكثر؛ وارفع أصابعك بعد الانتهاء من الضغط وستسمع صوت تعيين المفاتيح. انقر للخروج.</translation>
-<translation id="5788275253279308023">نافذة تصفح متخفٍ بعلامة التبويب <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">‏تحسين مواقع محددة (مثل بحث Google).</translation>
-<translation id="5819072574982403430">عنصر متفرع</translation>
-<translation id="5826479389509458994">الصف <ph name="ROW" /> العمود <ph name="COL" /></translation>
-<translation id="5850707923114094062">لقطة استعراضية إلى الوراء</translation>
-<translation id="5851548754964597211">قائمة علامات التبويب</translation>
-<translation id="5859752971144398932">تم الخروج من "بحث في الصفحة".</translation>
-<translation id="5866042630553435010">محدد جزئيًا</translation>
-<translation id="5869546221129391014">شبكة</translation>
-<translation id="5876817486144482042">خفض مستوى صوت النطق</translation>
-<translation id="5887397643266327462">تم تمكين تسميات برايل التوضيحية.</translation>
-<translation id="5891934789323004067">جدول</translation>
-<translation id="5919442531159595654">نسخ.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{علامة تساوي واحدة}zero{# equal signs}two{علامتا تساوي (#)}few{# علامات تساوي}many{# علامة تساوي}other{# من علامات التساوي}}</translation>
-<translation id="5939518447894949180">إعادة</translation>
-<translation id="5948123859135882163">تبديل تفسير مصطلحات الرياضيات بين البنيوية والدلالية</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">مربع حوار</translation>
-<translation id="5963413905009737549">قسم</translation>
-<translation id="5968607524793740041">عرض قائمة السياقات</translation>
-<translation id="5983179082906765664">زيادة دقة التنقل</translation>
-<translation id="5999630716831179808">الأصوات</translation>
-<translation id="6000417740266304866">يمكنك تغيير الجدول بنمط برايل 8 نقاط الحالي عبر تحديد خيار من القائمة أدناه.</translation>
-<translation id="6006050241733874051">نموذج</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{شرطة واحدة مائلة للخلف}zero{# backslashes}two{شرطتان مائلتان للخلف (#)}few{# شرطات مائلة للخلف}many{# شرطة مائلة للخلف}other{# من الشرطات المائلة للخلف}}</translation>
-<translation id="6037602951055904232">تحريك للأمام</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">نهاية الخلية.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">مسافة</translation>
-<translation id="6142308968191113180">العنوان الرابع</translation>
-<translation id="6169420925157477918">الصورة بها وصف مطول</translation>
-<translation id="6172087735260766220">‏يتعذر الدخول إلى نص يمكن الوصول إليه من نسخة PDF محمية.</translation>
-<translation id="6186305613600865047">انتقال إلى أسفل الصفحة</translation>
-<translation id="6193330012414963395">صباحًا/مساءً</translation>
-<translation id="622484624075952240">Down</translation>
-<translation id="6236061028292614533">العنوان التالي</translation>
-<translation id="6254901459154107917">منطقة النص التالي القابل للتعديل</translation>
-<translation id="6259464875943891919">تم الخروج من <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">العنصر المماثل التالي.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">ليس هناك مربع تحرير وسرد تالٍ.</translation>
-<translation id="6307969636681130414">مضغوط</translation>
-<translation id="6324551002951139333">تم اكتشاف خطأ نحوي</translation>
-<translation id="6348657800373377022">مربع تحرير وسرد</translation>
-<translation id="6355910664415701303">ليس هناك عنصر قائمة سابق.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">العنوان السابق</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">ليس هناك زر اختيار سابق.</translation>
-<translation id="6414968628640960377">العنصر المختلف السابق.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{علامة نقطتين واحدة}zero{# colons}two{علامتا نقطتين (#)}few{# علامات نقطتين}many{# علامة نقطتين}other{# من علامات النقطتين}}</translation>
-<translation id="6438968337250688271">القائمة <ph name="NAME" /></translation>
-<translation id="6444046323172968959">مربع حوار للتنبيه</translation>
-<translation id="6459511626086141404">مخطط مفاتيح ثابت</translation>
-<translation id="6468049171101508116">الزر التالي</translation>
-<translation id="6491972999578897419">يمكنك تغيير الصوت الحالي عبر تحديد خيار من القائمة أدناه.</translation>
-<translation id="6508059270146105198">نقل عرض برايل إلى أسفل الصفحة</translation>
-<translation id="6536864053412760904">الرمز المميز للغة التوصيف الرياضية</translation>
-<translation id="6550720799683018100">يمكن تغيير مخطط المفاتيح الحالي عبر تحديد خيار من القائمة أدناه.</translation>
-<translation id="6561818612645211875">الانتقال إلى بداية الصف الحالي</translation>
-<translation id="6587021927234520429">ليس هناك عنوان تالٍ من المستوى الرابع.</translation>
-<translation id="6601344353291556895">تمكين الأوصاف المطوَّلة.</translation>
-<translation id="6615602925644411249">بحث في الصفحة.</translation>
-<translation id="6633350132811819843">ليس هناك جدول تالٍ.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">شريط التقدم</translation>
-<translation id="6659594942844771486">علامة تبويب</translation>
-<translation id="667999046851023355">مستند</translation>
-<translation id="6697092096875747123">مربع التحرير والسرد السابق</translation>
-<translation id="6714813999819678458">عنوان المستوى الثاني السابق</translation>
-<translation id="6716505898850596801">مفاتيح التعديل</translation>
-<translation id="671916444866103745">‏ليس هناك معلم ARIA تالٍ.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />، مربع التحرير والسرد</translation>
-<translation id="6735257939857578167">يشتمل على <ph name="NUM" /> من العناصر</translation>
-<translation id="6736510033526053669">تم إنشاء علامة تبويب</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">مقالة</translation>
-<translation id="6787839852456839824">اختصارات لوحة المفاتيح</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">تذييل</translation>
-<translation id="6871161210040114857">تجاهل حالة الأحرف.</translation>
-<translation id="6877435256196695200">ليس هناك رسم تالٍ.</translation>
-<translation id="6897341342232909480">الانتقال يسارًا</translation>
-<translation id="6901540140423170855">التاريخ</translation>
-<translation id="6910211073230771657">تم الحذف</translation>
-<translation id="6911965441508464308">ليست هناك خلية أعلاه.</translation>
-<translation id="6919104639734799681">عرض قائمة الجداول</translation>
-<translation id="6964088412282673743">ليس هناك عنصر تحكم سابق.</translation>
-<translation id="6996566555547746822">مربع تحرير وسرد التالي</translation>
-<translation id="7005146664810010831">‏لم يتم العثور على عنوان URL</translation>
-<translation id="7010712454773919705">‏مفتاح تعديل ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">القائمة السابقة</translation>
-<translation id="7041173719775863268">إنهاء التحديد</translation>
-<translation id="7095834689119144465">تعديل النص الرقمي فقط</translation>
-<translation id="7096001299300236431">الوسائط السابقة</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">صدى الكلمة</translation>
-<translation id="713824876195128146">الاقتباس الطويل التالي</translation>
-<translation id="7161771961008409533">زر بقائمة منبثقة</translation>
-<translation id="7167657087543110">صدى الحرف</translation>
-<translation id="7170733337935166589">التقدم للأمام أثناء القراءة المتواصلة</translation>
-<translation id="7181697990050180700">يمكنك تخصيص اختصارات لوحة مفاتيح للأوامر شائعة الاستخدام من خلال كتابتها في الحقول المقابلة أدناه.</translation>
-<translation id="7203150201908454328">موسع</translation>
-<translation id="7210211103303402262">دقيقة</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">خط</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">عنوان</translation>
-<translation id="7241683698754534149">فتح الوصف المطول في علامة تبويب جديدة</translation>
-<translation id="7248671827512403053">تطبيق</translation>
-<translation id="725969808843520477">زر الاختيار التالي</translation>
-<translation id="7269119382257320590">بدون علامات ترقيم</translation>
-<translation id="7273174640290488576">فارغ</translation>
-<translation id="7285387653379749618">الجداول</translation>
-<translation id="7289186959554153431">العنوان الثالث</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">تم تعطيل تسميات برايل التوضيحية.</translation>
-<translation id="7318872822751139669">استخدم الماوس لتغيير التركيز.</translation>
-<translation id="7322388933135261569">شباط (فبراير)</translation>
-<translation id="7332592614823088566">صف <ph name="ROWINDEX" /> من <ph name="ROWTOTAL" />، عمود <ph name="COLINDEX" /> من <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">له نافذة منبثقة</translation>
-<translation id="7356165926712028380">التبديل إلى نمط برايل 8 نقاط</translation>
-<translation id="7362871137496673139">ليس هناك عنوان سابق من المستوى الثاني.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{علامة عطف واحدة}zero{# ampersands}two{علامتا عطف (#)}few{# علامات عطف}many{# علامة عطف}other{# من علامات العطف}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">جارٍ مغادرة الجدول.</translation>
-<translation id="739763518212184081">السطر السابق</translation>
-<translation id="7400575256015741911">تم اكتشاف خطأ إملائي</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">رجوع</translation>
-<translation id="7434509671034404296">المطوِّر</translation>
-<translation id="7439060726180460871">الدليل</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">علامة تبويب</translation>
-<translation id="7492049978501397201">مربع حوار تم الدخول إليه</translation>
-<translation id="7532613204005497612">حزيران (يونيو)</translation>
-<translation id="7540083713905917247">شريط التمرير <ph name="NAME" />، بالقيمة <ph name="VALUE" /></translation>
-<translation id="7586163296341959563">لصق.</translation>
-<translation id="7596919493010894443">تم مسح التحديد</translation>
-<translation id="7604026522577407655">الانتقال إلى بداية العمود الحالي</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">‏الإعلان عن عنوان URL للصفحة الحالية</translation>
-<translation id="7609363189280667021">التبديل إلى تسميات برايل التوضيحية</translation>
-<translation id="762020119231868829">إيقاف كل أدوات الوسائط التي يتم تشغيلها حاليًا مؤقتًا</translation>
-<translation id="7625690649919402823">الجدول التالي</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />)، الدرجة <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">ليس هناك عنوان سابق من المستوى الثالث.</translation>
-<translation id="7659376057562985921">مربع نص <ph name="NAME" />، بالقيمة <ph name="VALUE" /></translation>
-<translation id="7663318257180412551">العنوان الثاني</translation>
-<translation id="7674576868851035240">الرابط التالي</translation>
-<translation id="7674768236845044097">علامة</translation>
-<translation id="7684431668231950609">‏تعديل النص، إدخال عنوان URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">زر الاختيار السابق</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748">مربع نص كلمة المرور <ph name="NAME" />، بالقيمة <ph name="VALUE" /></translation>
-<translation id="7805247615045262757">التنقل الافتراضي</translation>
-<translation id="7805768142964895445">الحالة</translation>
-<translation id="7810781339813764006">المجموعة التالية</translation>
-<translation id="7819187121850078213">نافذة علامة التبويب <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">تشرين الأول (أكتوبر)</translation>
-<translation id="7839679365527550018">الكلمة السابقة</translation>
-<translation id="7851816175263618915">بعض علامات الترقيم</translation>
-<translation id="7870596830398826354">شجرة لغة التوصيف الرياضية</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">‏تبديل ChromeVox الكلاسيكي.</translation>
-<translation id="7895896691902835279">رابط غير معروف</translation>
-<translation id="7927711904086083099">غير محدد</translation>
-<translation id="7935627501098484003">التحكم في الوقت</translation>
-<translation id="7939428177581522200">تمت الإضافة إلى التحديد</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{علامة على}zero{# at signs}two{علامتا على (#)}few{# علامات على}many{# علامة على}other{# من علامات على}}</translation>
-<translation id="7965147473449754028">تم غلق القائمة</translation>
-<translation id="7974390230414479278">عنصر القائمة</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{علامة تعجب واحدة}zero{# exclamation points}two{علامتا تعجب (#)}few{# علامات تعجب}many{# علامة تعجب}other{# من علامات التعجب}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{علامة اقتباس واحدة}zero{# quotes}two{علامتا اقتباس (#)}few{# علامات اقتباس}many{# علامة اقتباس}other{# من علامات الاقتباس}}</translation>
-<translation id="8033827949643255796">تم التحديد</translation>
-<translation id="8035962149453661158">الحد الأقصى:<ph name="X" /></translation>
-<translation id="8042761080832772327">تعديل النص، إدخال البحث</translation>
-<translation id="8049189770492311300">مؤقت</translation>
-<translation id="8065607967589909823">تم تحديد</translation>
-<translation id="8066678206530322333">بانر</translation>
-<translation id="8110647606445335195">‏ليست هناك معالم ARIA.</translation>
-<translation id="8153880621934657047">ليس بداخل الجدول.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{شرطة سفلية واحدة}zero{# underscores}two{شرطتان سفليتان (#)}few{# شرطات سفلية}many{# شرطة سفلية}other{# من الشرطات السفلية}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">قص.</translation>
-<translation id="8199231515320852133">الإعلان عن عناوين الخلية الحالية</translation>
-<translation id="820417203470636242">خلية فارغة.</translation>
-<translation id="8215202828671303819">تحديد متعدد</translation>
-<translation id="8276439074553447000">الانتقال إلى العنصر السابق القابل للتركيز</translation>
-<translation id="8278417001922463147">لا تتوفر مقالة سابقة.</translation>
-<translation id="8283603667300770666">حقل النموذج التالي</translation>
-<translation id="831207808878314375">تعريف</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">ساعة</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{علامة جنيه واحدة}zero{# pound signs}two{علامتا جنيه (#)}few{# علامات جنيه}many{# علامة جنيه}other{# من علامات الجنيه}}</translation>
-<translation id="8374154622594089836">شهر</translation>
-<translation id="8378855320830505539">منطقة</translation>
-<translation id="8382679411218029383">إكمال تلقائي على السطر وعلى هيئة قائمة</translation>
-<translation id="8428603554127842284">المستوى <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">ليس هناك عنوان تالٍ من المستوى الثالث.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">ليس هناك مربع اختيار سابق.</translation>
-<translation id="8455868257606149352">الحد الأقصى <ph name="X" /></translation>
-<translation id="84575901236241018">لديه مفتاح دخول، <ph name="KEY" /></translation>
-<translation id="8503360654911991865">خفض دقة التنقل</translation>
-<translation id="8520472399088452386">زر الدوران</translation>
-<translation id="8538744478902126321">إجراء تخمين في عنوان الصف للخلية الحالية</translation>
-<translation id="8540054775867439484">التفاف إلى أعلى</translation>
-<translation id="8548973727659841685">حرف</translation>
-<translation id="8561322612995434619">له نافذة منبثقة</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">عنصر القائمة التالي</translation>
-<translation id="860150890330522909">تم تحديد مربع الاختيار <ph name="NAME" /></translation>
-<translation id="8606621670302093223">التحكم في التاريخ</translation>
-<translation id="8631359288236106450">تم تحديد <ph name="COUNT" /> من العناصر</translation>
-<translation id="8638532244051952400">إعلان إحداثيات الخلية الحالية</translation>
-<translation id="8650576015643545550">ليست هناك قائمة سابقة.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">عرض قائمة الروابط</translation>
-<translation id="8664519043722036194">ثواني</translation>
-<translation id="867187640362843212">العنوان الخامس</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{شريط رأسي واحد}zero{# vertical pipes}two{شريطان رأسيان (#)}few{# أشرطة رأسية}many{# شريطًا رأسيًا}other{# من الأشرطة الرأسية}}</translation>
-<translation id="8735450637152821465">بدء التحديد</translation>
-<translation id="8743786158317878347">دخول إلى المحتوى المنظم، مثل الجداول</translation>
-<translation id="8747966237988593539">قائمة مرتبة</translation>
-<translation id="8759334257841767240">ليس هناك رابط تالٍ.</translation>
-<translation id="8767968232364267681">عنوان المستوى الرابع التالي</translation>
-<translation id="8770473310765924354">خروج من المحتوى المنظم، مثل الجداول</translation>
-<translation id="8791025954632646584">تم تشغيل الدلالات</translation>
-<translation id="8796411681063377102">عنوان المستوى الثالث التالي</translation>
-<translation id="8808582214901541005">آذار (مارس)</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">‏اضغط على السهم لأعلى أو لأسفل لمراجعة الأوامر، واضغط على enter للتنشيط</translation>
-<translation id="8864099967139188018">ليس هناك عنوان تالٍ من المستوى السادس.</translation>
-<translation id="8882002077197914455">عنوان الصف</translation>
-<translation id="8896347895970027998">‏تبديل ChromeVox بين الوضع نشط أو غير نشط.</translation>
-<translation id="8898516272131543774">دورة صدى علامات الترقيم</translation>
-<translation id="8900148057318340779">مفتاح بادئة</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">عناوين فارغة</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">مفاتيح التعديل</translation>
-<translation id="8943175951035496220">ليست هناك خلية في اليمين.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">ليست هناك أية جداول.</translation>
-<translation id="9040132695316389094">العنوان الأول</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">تبديل أداة البحث</translation>
-<translation id="9065283790526219006">+قائمة منبثقة</translation>
-<translation id="9077213568694924680">تمت الإزالة من التحديد</translation>
-<translation id="9082874451376019682">ليس هناك شريط تمرير سابق.</translation>
-<translation id="9089864840575085222">دورة صدى الكتابة</translation>
-<translation id="9107530006868467849">لا توجد أداة للوسائط السابقة.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{علامة نسبة مئوية واحدة}zero{# percent signs}two{علامتا نسبة مئوية (#)}few{# علامات نسبة مئوية}many{# علامة نسبة مئوية}other{# من علامات النسبة المئوية}}</translation>
-<translation id="9115913704608474258">تشرين الثاني (نوفمبر)</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">الإعلان عن وصف موجز للموضع الحالي</translation>
-<translation id="9153606228985488238">درجة صوت بنسبة <ph name="PERCENT" /> في المائة</translation>
-<translation id="9160096769946561184">الانتقال إلى نهاية العمود الحالي</translation>
-<translation id="9173115498289768110">مستوى الصوت بنسبة <ph name="PERCENT" /> في المائة</translation>
-<translation id="9178973770513562274">استخدم السهمين لأعلى أو لأسفل للتصفح أو اكتب للبحث.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">ليس هناك قسم تالٍ.</translation>
-<translation id="930275611743429116">بدء أو إنهاء التحديد.</translation>
-<translation id="948171205378458592">خفض تقييم النطق</translation>
-<translation id="962913030769097253">عنوان المستوى الأول التالي</translation>
-<translation id="973955474346881951">تمكين/تعطيل الوضع الثابت</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bg.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bg.xtb
deleted file mode 100644
index 327e485afd0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bg.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="bg">
-<translation id="1012173283529841972">Списъчен елемент</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Разпростряна.</translation>
-<translation id="1025074108959230262">Фиксираният режим е деактивиран</translation>
-<translation id="1031961866430398710">след това</translation>
-<translation id="1044777062731150180">Няма заглавки</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Невалидни въведени данни</translation>
-<translation id="1082209053475788238">Няма предишно заглавие от шесто ниво.</translation>
-<translation id="1088219014394087294">Няма заглавия.</translation>
-<translation id="1106741348836243114">Включване или изключване на обратната връзка със звук (звукови сигнали).</translation>
-<translation id="1120743664840974483">{"а": "антон", "б": "борис", "в": "васил", "г": "георги", "д": "димитър", "е": "елена", "ж": "живко", "з": "захари", "и": "иван", "й": "йордан", "к": "кирил", "л": "людмил", "м": "мария", "н": "николай", "о": "огнян", "п": "петър", "р": "румен", "с": "стефан", "т": "тодор", "у": "уляна", "ф": "филип", "х": "христо", "ц": "цветан", "ч": "чавдар", "ш": "шипка", "щ": "щерю", "ъ": "ер голям", "ь": "ер малък", "ю": "юлия", "я": "явор"}</translation>
-<translation id="113582498867142724">Колекция от <ph name="TAG" /> с/ъс <ph name="NUM" /> елемента</translation>
-<translation id="1155043339247954670">Няма следващ списъчен елемент.</translation>
-<translation id="1157782847298808853">Помощ за клавиатурата</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, „<ph name="NAME" />“, разгъващ се списък</translation>
-<translation id="1167230103353892028">„<ph name="NAME" />“, елемент от меню, с подменю</translation>
-<translation id="1177863135347784049">По избор</translation>
-<translation id="1188858454923323853">допълнение</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – Chrome получава глас</translation>
-<translation id="1229276918471378188">Предишният преход</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Следващото заглавие от шесто ниво</translation>
-<translation id="1275718070701477396">Избрано</translation>
-<translation id="1319608975892113573">Няма предишен блоков цитат.</translation>
-<translation id="1321576897702511272">Скриване на помощта за ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> от <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">ехо за знаците и думите</translation>
-<translation id="1339428534620983148">Предишната графа в таблицата</translation>
-<translation id="1342835525016946179">статия</translation>
-<translation id="1346748346194534595">Надясно</translation>
-<translation id="136718599399906424">Следващият ред в таблицата</translation>
-<translation id="1383876407941801731">Търсене</translation>
-<translation id="1385214448885562192">Натиснете „enter“, за да приемете, или „escape“, за да анулирате, стрелката за надолу – за напред, а тази за нагоре – за назад.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">област</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, текстово поле за парола</translation>
-<translation id="1467432559032391204">Наляво</translation>
-<translation id="1474557363159888097">Няма предишна котва.</translation>
-<translation id="1502086903961450562">Предишната графика</translation>
-<translation id="1506187449813838456">Увеличаване на височината на звука</translation>
-<translation id="151784044608172266">Следващото изречение</translation>
-<translation id="1524531499102321782">Следващият ред на брайловото писмо</translation>
-<translation id="1546370775711804143">Лента за превъртане</translation>
-<translation id="1559739829547075274">Навигация назад</translation>
-<translation id="1571643229714746283">ChromeVox е в готовност</translation>
-<translation id="158493514907962286">декември</translation>
-<translation id="1594072653727561613">меню</translation>
-<translation id="1610130962244179598">Превключване към 6-точково брайлово писмо</translation>
-<translation id="1611168825862729585">Заглавка на графа:</translation>
-<translation id="1613476421962910979">Звуковите сигнали са включени</translation>
-<translation id="1618597272655350600">Съобщава пълно описание на текущата позиция</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{знак за по-голямо}other{# знака за по-голямо}}</translation>
-<translation id="1653266918374749391">Предишното заглавие от трето ниво</translation>
-<translation id="1659072772017912254">Без отметка</translation>
-<translation id="1669290819662866522">седмица</translation>
-<translation id="1674262202423278359">Придвижване с ChromeVox</translation>
-<translation id="16777221443363124">Лента с менюта</translation>
-<translation id="1692077714702418899">структурен ред</translation>
-<translation id="1700517974991662022">Посетено</translation>
-<translation id="1722567105086139392">Връзка</translation>
-<translation id="1727806147743597030">долен колонтитул</translation>
-<translation id="174268867904053074">Следващата графика</translation>
-<translation id="1781173782405573156">Пропускане на клавиш</translation>
-<translation id="1787176709638001873">Поле за парола</translation>
-<translation id="1810107444790159527">Списъчно поле</translation>
-<translation id="1828385960365606039">май</translation>
-<translation id="1834891354138622109">Графа</translation>
-<translation id="1865601187525349519">Край на текста</translation>
-<translation id="1876229593313240038">документ</translation>
-<translation id="188130072164734898">Изговаряне на текущите дата и час.</translation>
-<translation id="1902396333223336119">Клетка</translation>
-<translation id="1905379170753160525">Показване на списъка със заглавия</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Контрола за седмицата от годината</translation>
-<translation id="1964135212174907577">Следващият обект</translation>
-<translation id="1969092762068865084">юли</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Заглавка на ред:</translation>
-<translation id="2002895034995108595">Връщане към първоначалната клавиатурна подредба</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{лява квадратна скоба}other{# леви квадратни скоби}}</translation>
-<translation id="2045490512405922022">без отметка</translation>
-<translation id="20601713649439366">Няма предишен математически израз.</translation>
-<translation id="207477615537953741">Семантиката е изключена</translation>
-<translation id="2086961585857038472">Следващата дума</translation>
-<translation id="2089387485033699258">bg</translation>
-<translation id="2091933974477985526">Предишната текстова област, която може да се редактира</translation>
-<translation id="2100350898815792233">Всички препинателни знаци</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">клавиш за достъп: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Променете текущата 6-точкова брайлова таблица, като изберете опция от списъка по-долу.</translation>
-<translation id="2169714232367507776">Кликване върху текущия елемент</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{затваряща скоба}other{# затварящи скоби}}</translation>
-<translation id="2199994615414171367">Предишният математически израз</translation>
-<translation id="2223693656926968778">Извършване на действие върху текущия елемент</translation>
-<translation id="225732394367814946">Увеличаване на скоростта на говора</translation>
-<translation id="2267945578749931355">Следващият знак</translation>
-<translation id="2281234842553884450">Предишният плъзгач</translation>
-<translation id="2318372665160196757">Основен елемент</translation>
-<translation id="2329324941084714723">Панел на раздел</translation>
-<translation id="2344193891939537199">Контрола за периода от време</translation>
-<translation id="2359897517538099099">Не сте в табличен режим.</translation>
-<translation id="241124561063364910">последвано от</translation>
-<translation id="2417569100218200841">Информация за съдържанието</translation>
-<translation id="2422937916923936891">Квадратче за отметка на елемент от меню</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">„<ph name="KEY" />“ вече е новият модифициращ клавиш за ChromeVox.</translation>
-<translation id="2450814015951372393">Квадратче за отметка</translation>
-<translation id="2462626033734746142">Група бутони за избор</translation>
-<translation id="2471138580042810658">Заглавие от шесто ниво</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{звездичка}other{# звездички}}</translation>
-<translation id="2549392850788122959">Върнахте се към първоначалната клавиатурна подредба „<ph name="KEY" />“.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Група</translation>
-<translation id="2582407057977008361">Странично съдържание</translation>
-<translation id="2589102159832527089">Тази страница съдържа текста, който е извлечен автоматично от PDF файла &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Кликнете тук за оригинала.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">с/ъс {COUNT,plural, =1{# елемент}other{# елемента}}</translation>
-<translation id="2614981083756825552">Оформление в Math ML</translation>
-<translation id="2626530649491650971">с възможност за кликване</translation>
-<translation id="2628764385451019380">Няма предишен разгъващ се списък.</translation>
-<translation id="2637227747952042642">Математически израз</translation>
-<translation id="2639750663247012216">Модифициращ клавиш за ChromeVox</translation>
-<translation id="2644542693584024604">правописна грешка</translation>
-<translation id="2667291555398229137">Кликнете върху елемента под ключа за пренасочване</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{отваряща скоба}other{# отварящи скоби}}</translation>
-<translation id="2705875883745373140">Не е натиснато</translation>
-<translation id="2706462751667573066">Клавиш за нагоре</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">звук</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">С отметка</translation>
-<translation id="27527859628328957">Преминаване към следващия елемент, който може да получи фокус</translation>
-<translation id="2770781857296573485">Влизане в режим за разглеждане на група</translation>
-<translation id="2777845298774924149">Излязохте</translation>
-<translation id="2800204403141299078">Няма повече различни елементи.</translation>
-<translation id="2800780099804980316">Няма предишно заглавие от първо ниво.</translation>
-<translation id="2811204574343810641">Ред</translation>
-<translation id="2816654101880605877">Няма следващ плъзгач.</translation>
-<translation id="2841013758207633010">Време</translation>
-<translation id="2843837985843789981">Предишната група</translation>
-<translation id="2844995807198708617">Контекстно меню</translation>
-<translation id="2849332794118375855">Няма следващо квадратче за отметка.</translation>
-<translation id="2864481629947106776">Предишната връзка</translation>
-<translation id="2873259058405069099">Към началото на таблицата</translation>
-<translation id="2894654529758326923">Информация</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{лява фигурна скоба}other{# леви фигурни скоби}}</translation>
-<translation id="2911433807131383493">Отваряне на урока за ChromeVox</translation>
-<translation id="2932083475399492303">Превключване между структурен или тип ред за оформление</translation>
-<translation id="2964026537669811554">Група заглавия</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{табулатор}other{# табулатора}}</translation>
-<translation id="2972078295414139404">Няма предишна посетена връзка.</translation>
-<translation id="2972205263822847197">Подсказка</translation>
-<translation id="2998131015536248178">Предишният знак</translation>
-<translation id="2999559350546931576">Намаляване на височината на звука</translation>
-<translation id="2999945368667127852">Няма следващо приспособление за мултимедия.</translation>
-<translation id="3012414509011670858">Няма предишна секция.</translation>
-<translation id="3030432017085518523">Бутон за избор на елемент от меню</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{апостроф}other{# апострофа}}</translation>
-<translation id="3046838483509668188">Опции за ChromeVox</translation>
-<translation id="3047143736589213134">Експериментална клавиатурна подредба</translation>
-<translation id="3060756054951570867">Отворихте менюто „<ph name="TITLE" />“</translation>
-<translation id="3078345202707391975">Следващото заглавие от второ ниво</translation>
-<translation id="3078740164268491126">таблица</translation>
-<translation id="3082557070674409251">Кликнахте</translation>
-<translation id="3084806535845658316">без ехо при въвеждане</translation>
-<translation id="3086746722712840547">забележка</translation>
-<translation id="308895241372589742">Няма следващ математически израз.</translation>
-<translation id="3090532668523289635">група</translation>
-<translation id="3093176084511590672">Следващият ориентир</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">диалогов прозорец за сигнал</translation>
-<translation id="3109724472072898302">Свито</translation>
-<translation id="3134461040845705080">само за четене</translation>
-<translation id="3138767756593758860">Показване на списъка с ориентири</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Следващият ред</translation>
-<translation id="3155083529632865074">Няма предишен бутон.</translation>
-<translation id="3163593631834463955">Празна заглавка на графа</translation>
-<translation id="316542773973815724">Навигация</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{интервал}other{# интервала}}</translation>
-<translation id="320961988183078793">влязохте в/ъв <ph name="TYPE" /></translation>
-<translation id="3223701887221307104">„<ph name="NAME" />“, раздел</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Посетена връзка</translation>
-<translation id="323731244387692321">Отваряне на помощта за клавиатурата за ChromeVox</translation>
-<translation id="3241052487511142956">Предишна посетена връзка</translation>
-<translation id="3286390186030710347">Плъзгач</translation>
-<translation id="3299925995433437805">Няма следваща посетена връзка.</translation>
-<translation id="3303384412438961941">Натиснете клавиш, за да научите името му. Ctrl+W затваря инструмента за изследване на клавиатурата.</translation>
-<translation id="3307886118343381874">Към края на таблицата</translation>
-<translation id="3311969765485641742">Натиснете „Alt+Shift+A“, за да прегледате сигналите</translation>
-<translation id="3312997241656799641">Следваща посетена връзка</translation>
-<translation id="3321460131042519426">Активиране на пренасянето на думи</translation>
-<translation id="3322936298410871309">Предишното заглавие от първо ниво</translation>
-<translation id="3323447499041942178">Текстово поле</translation>
-<translation id="3353420241558113817">{"en": "английски",
- "en_CA": "английски (Канада)",
- "en_GB": "английски (Обединено кралство)",
- "en_US": "английски (Съединени щати)",
- "ar": "арабски",
- "bg": "български",
- "vi": "виетнамски",
- "el": "гръцки",
- "da": "датски",
- "et": "естонски",
- "he": "иврит",
- "is": "исландски",
- "es": "испански",
- "it": "италиански",
- "ca": "каталонски",
- "zh": "китайски",
- "zh_TW": "китайски (традиционен хан)",
- "ko": "корейски",
- "lv": "латвийски",
- "lt": "литовски",
- "de": "немски",
- "de_DE": "немски (Германия)",
- "de_CH": "немски (Швейцария)",
- "nl": "нидерландски",
- "nb": "норвежки букмол",
- "pl": "полски",
- "pt": "португалски",
- "ro": "румънски",
- "ru": "руски",
- "sk": "словашки",
- "sl": "словенски",
- "sr": "сръбски",
- "tr": "турски",
- "hu": "унгарски",
- "fi": "финландски",
- "fr": "френски",
- "fr_CA": "френски (Канада)",
- "fr_FR": "френски (Франция)",
- "hi": "хинди",
- "hr": "хърватски",
- "cs": "чешки",
- "sv": "шведски"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{знак плюс}other{# знака плюс}}</translation>
-<translation id="338583716107319301">Разделител</translation>
-<translation id="3389259863310851658">Предишното поле във формуляра</translation>
-<translation id="3390225400784126843">Следващият различен елемент.</translation>
-<translation id="3392045790598181549">„<ph name="NAME" />“, елемент от меню</translation>
-<translation id="3406283310380167331">Показване на списъка с формуляри</translation>
-<translation id="3422338090358345848">Отваряне на инструмента за изследване на клавиатурата</translation>
-<translation id="3457000393508828486">Частично натиснато</translation>
-<translation id="3462439746547587373">„<ph name="NAME" />“, бутон</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> избрани</translation>
-<translation id="3486232535569802404"><ph name="V1" /> до <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{дясна квадратна скоба}other{# десни квадратни скоби}}</translation>
-<translation id="3493915602752813531">Няма следваща котва.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{въпросителен знак}other{# въпросителни знака}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{карета}other{# карети}}</translation>
-<translation id="3568702578574425662">„<ph name="NAME" />“, квадратче без отметка</translation>
-<translation id="3599054940393788245">Извън математическия израз</translation>
-<translation id="3616113530831147358">Аудио</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{обратен апостроф}other{# обратни апострофа}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{знак за долар}other{# знака за долар}}</translation>
-<translation id="3659787053479271466">сигнал</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, списъчно поле</translation>
-<translation id="3687295507293856493">Предположение за заглавката на графата за текущата клетка</translation>
-<translation id="3692274950075847560">Т: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Контролиране на говора</translation>
-<translation id="3716845769494773620">Няколко реда</translation>
-<translation id="3731746171184829332">Няма предишно заглавие.</translation>
-<translation id="3762198587642264450">Към края на текущия ред</translation>
-<translation id="3777255250339039212">заглавие от първо ниво</translation>
-<translation id="3793710123303304873">Излязохте от диалоговия прозорец.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Автоматично довършване в списък</translation>
-<translation id="3810838688059735925">Видео</translation>
-<translation id="3816633764618089385">Следващият мултимедиен елемент</translation>
-<translation id="3819376190738087562">Няма преминавания.</translation>
-<translation id="385383972552776628">Отваряне на страницата с опции</translation>
-<translation id="3856075812838139784">Само за четене</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Меню</translation>
-<translation id="3909320334364316587">Предишното заглавие от шесто ниво</translation>
-<translation id="3914173277599553213">Задължително</translation>
-<translation id="3962990492275676168">Стартиране на четенето от текущото местоположение</translation>
-<translation id="4004802134384979325">с отметка</translation>
-<translation id="4006140876663370126">изображение</translation>
-<translation id="4038349100599457191">Контрола за месеца</translation>
-<translation id="4039983576244166038">Празна заглавка на ред</translation>
-<translation id="4042843249978639960">Няма следващо заглавие от второ ниво.</translation>
-<translation id="4043348641337972076">Няма предишен отличителен белег на ARIA.</translation>
-<translation id="4047216625641135770">Маркиране</translation>
-<translation id="404803211695627272"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="4054936709456751127">състояние</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{ТИЛДА}other{# тилди}}</translation>
-<translation id="409334809956508737">Предишният обект</translation>
-<translation id="4099274309791143834">с подменю</translation>
-<translation id="4107807507418787238">Няма клетка отдолу.</translation>
-<translation id="4116415223832267137">Сигнал</translation>
-<translation id="4147126331795725888">Няма следваща контрола.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{дясна фигурна скоба}other{# десни фигурни скоби}}</translation>
-<translation id="4158704014418536539">Регистърът на буквите е от значение.</translation>
-<translation id="4161663686871496107">Обратната връзка с говор от ChromeVox е в готовност</translation>
-<translation id="4173994908659439270">Няма следващо текстово поле, което може да се редактира.</translation>
-<translation id="4176463684765177261">Деактивирано</translation>
-<translation id="4188530942454211480">Предишното изречение</translation>
-<translation id="4202186506458631436">Преместване надясно</translation>
-<translation id="4206289001967551965">В таблицата сте.</translation>
-<translation id="4215733775853809057">Следващият плъзгач</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{тире}other{# тирета}}</translation>
-<translation id="421884353938374759">инструмент за избор на цветове</translation>
-<translation id="4229646983878045487">дата и час</translation>
-<translation id="423334822609210999">Няма клетка отляво.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, клас <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Забележка</translation>
-<translation id="4254798249533888099">Дърво</translation>
-<translation id="4255943572433203166">Използвайте опциите по-долу, за да персонализирате ChromeVox. Промените влизат в сила незабавно.</translation>
-<translation id="4271220233568730077">Следващият математически израз</translation>
-<translation id="4271521365602459209">Няма повече резултати.</translation>
-<translation id="4287520460805643128">Няма следваща статия.</translation>
-<translation id="4289540628985791613">Общ преглед</translation>
-<translation id="4300318234632215983">Съобщаване на URL адреса зад връзката</translation>
-<translation id="4301352596632316575">има подменю</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{точка}=3{многоточие}other{# точки}}</translation>
-<translation id="4347461890115250064">Няма следващ списък.</translation>
-<translation id="4367650418938037324">Краен възел в Math ML</translation>
-<translation id="4372435075475052704">минимум: <ph name="X" /></translation>
-<translation id="4372705107434148843">Спиране на говора</translation>
-<translation id="4373197658375206385">Няма предишен елемент, който не е връзка.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">нулиране</translation>
-<translation id="4471074325120394300">Няма връзки.</translation>
-<translation id="4476183483923481720">нов ред</translation>
-<translation id="4482330759234983253">Предишната таблица</translation>
-<translation id="4491109536499578614">Изображение</translation>
-<translation id="4529987814483543472">Традиционна клавиатурна подредба</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{наклонена черта}other{# наклонени черти}}</translation>
-<translation id="4547556996012970016">Следващото заглавие от пето ниво</translation>
-<translation id="4562381607973973258">Горен колонтитул</translation>
-<translation id="4591507479202817876">, избрано</translation>
-<translation id="4597532268155981612">формуляр</translation>
-<translation id="4597896406374528575">април</translation>
-<translation id="4615592953348396470">Следващото натискане на клавиш се пренебрегва</translation>
-<translation id="461613135510474570">Изречение</translation>
-<translation id="4647836961514597010">Инструмент за избор на цветове</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">таблица</translation>
-<translation id="4693675773662933727">Предишният ориентир</translation>
-<translation id="4696413482802371445">Няма следващо заглавие от пето ниво.</translation>
-<translation id="4729095194763193578">Предишният ред в таблицата</translation>
-<translation id="4736221692378411923">август</translation>
-<translation id="4740661827607246557">Помощни команди</translation>
-<translation id="4759716709594980008">Инструмент за изследване на клавиатурата в ChromeOS</translation>
-<translation id="4763296182459741068">Пренасяне в края</translation>
-<translation id="4763480195061959176">видео</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Съобщаване на заглавието на текущата страница</translation>
-<translation id="4826415162591436065">Навигация напред</translation>
-<translation id="4826604887384865800">Следващият преход</translation>
-<translation id="4827410568042294688">отмяна на открояването</translation>
-<translation id="4842108708071771135">Няма следващ блоков цитат.</translation>
-<translation id="4848993367330139335">таймер</translation>
-<translation id="4850023505158945298">Предишният подобен елемент.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Активиране на регистрирането за синтезирания говор</translation>
-<translation id="4877261390094455813">Въведете заявка за търсене.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Вътрешна връзка</translation>
-<translation id="4953585991029886728">Текстово поле</translation>
-<translation id="4954534434583049121">Предишният блоков цитат</translation>
-<translation id="4973717656530883744">Минимум <ph name="X" /></translation>
-<translation id="4973762002207131920">Превключихте към „<ph name="KEY" />“.</translation>
-<translation id="4975416682604111799">милисекунди</translation>
-<translation id="49787999531187221">ChromeVox вече не е активен.</translation>
-<translation id="4979404613699303341">Предишният бутон</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, „<ph name="NAME" />“, списъчно поле</translation>
-<translation id="4983588134362688868">Преминаване към началото на страницата</translation>
-<translation id="4986606102545753256">„<ph name="NAME" />“, прозорец</translation>
-<translation id="4993152509206108683">Скорост: <ph name="PERCENT" /> процента</translation>
-<translation id="4996716799442435517">Видими области</translation>
-<translation id="4997282455736854877">„<ph name="NAME" />“, маркиран бутон за избор</translation>
-<translation id="4997475792277222884">Няма следващ елемент, който не е връзка.</translation>
-<translation id="5000760171916499057">Няма формуляри.</translation>
-<translation id="5005670136041063723">Няма повече подобни елементи.</translation>
-<translation id="501473567976723023">януари</translation>
-<translation id="5041394372352067729">Преместване на брайловия дисплей в горната част на страницата</translation>
-<translation id="5042770794184672516">Увеличаване на силата на звука на говора</translation>
-<translation id="5050015258024679800">Предишното заглавие от четвърто ниво</translation>
-<translation id="5054047268577924192">Предишният списъчен елемент</translation>
-<translation id="5078661581131202757">Избиране на файлове</translation>
-<translation id="5080758118274074384">кликнахте два пъти</translation>
-<translation id="5098541983634824365">Напускате таблицата.</translation>
-<translation id="5102981729317424850">Лента с инструменти</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Няма предишно поле във формуляра.</translation>
-<translation id="5111640677200759579">Заглавка на графа</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Няма предишна връзка.</translation>
-<translation id="513774504516943387">връзка</translation>
-<translation id="517143700877085897">, неизбрано</translation>
-<translation id="5183440668879371625">Предишен ред на брайловото писмо</translation>
-<translation id="5184944171021383281">Няма следващо поле във формуляра.</translation>
-<translation id="5189244881767082992">Ред</translation>
-<translation id="5203930734796605961">Клавишът „<ph name="KEY" />“ вече е зададен за команда.</translation>
-<translation id="5205493599117157272">Списък от тип „<ph name="TYPE" />“.</translation>
-<translation id="520883772648104506">Няма следващ бутон за избор.</translation>
-<translation id="5263344797180442561">заглавие от второ ниво</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Обект</translation>
-<translation id="5304943142864553931">„<ph name="TITLE" />“, раздел</translation>
-<translation id="5310788376443009632">премахнато:</translation>
-<translation id="5320727453979144100">Фиксираният режим е активиран</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{запетая}other{# запетаи}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, текстово поле</translation>
-<translation id="5330443287809544590">„<ph name="NAME" />“, връзка</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Превъртане назад при непрекъснато четене</translation>
-<translation id="5368000168321181111">Звуковите сигнали са изключени</translation>
-<translation id="5374320867641260420">Няма следващ бутон.</translation>
-<translation id="5382299583965267720">Няма следващо заглавие от първо ниво.</translation>
-<translation id="5402367795255837559">Брайлово писмо</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{точка и запетая}other{# точки и запетаи}}</translation>
-<translation id="5411891038905756502">Няма предишна точка за преминаване.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{знак за по-малко}other{# знака за по-малко}}</translation>
-<translation id="5455441614648621694">Допълнение</translation>
-<translation id="5485036206801896268">Няма предишна графика.</translation>
-<translation id="5486947920110100234">Няма следваща точка за преминаване.</translation>
-<translation id="549602578321198708">Дума</translation>
-<translation id="5500932716852106146">Няма предишно текстово поле, което може да се редактира.</translation>
-<translation id="5502713021410870035">септември</translation>
-<translation id="5507663321906818013">Тест за отстраняване на програмни дефекти</translation>
-<translation id="5518443085409638729">Поставяне на курсора между знаците при редактиране на текст (както при Mac OS X).</translation>
-<translation id="552195134157544755">Бутон за избор</translation>
-<translation id="5534303576632885660">заглавка</translation>
-<translation id="5546092960038624944">Няма предишно заглавие от пето ниво.</translation>
-<translation id="556042886152191864">Бутон</translation>
-<translation id="5561345396546889625">Следващият списък</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Поле за въвеждане на имейл адрес</translation>
-<translation id="5597170376237141345">Следващото квадратче за отметка</translation>
-<translation id="5597933780944041114">Няма следващо заглавие.</translation>
-<translation id="5598905979683743333">„<ph name="NAME" />“, немаркиран бутон за избор</translation>
-<translation id="5601172225407283979">Изпълняване на действие по подразбиране</translation>
-<translation id="5608798115546226984">Вградено автоматично довършване</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Регистрационен файл</translation>
-<translation id="5628125749885014029">заглавие от четвърто ниво</translation>
-<translation id="5637871198229500030">Няма предишна таблица.</translation>
-<translation id="5655682562155942719">Команди за преминаване</translation>
-<translation id="56637627897541303">Текстова област</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">определение</translation>
-<translation id="5682113568322255809">Ориентир</translation>
-<translation id="5683155931978483559">Предишното квадратче за отметка</translation>
-<translation id="5684277895745049190">Списък</translation>
-<translation id="5700650669149824506">Няма предишно заглавие от четвърто ниво.</translation>
-<translation id="5709192780268610569">Няма дълго описание</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Следващата графа в таблицата</translation>
-<translation id="571866080859340309">Разглеждане на групи</translation>
-<translation id="5728409797179002635">Няма намерена таблица.</translation>
-<translation id="5748623122140342504">Предишното заглавие от пето ниво</translation>
-<translation id="5750633686117194034">Не сте натиснали модифициращ клавиш. Моля, натиснете и задръжте един или повече. Щом сте готови, вдигнете пръстите си и ще чуете набора от клавиши. Използвайте „Tab“ за изход.</translation>
-<translation id="5788275253279308023">прозорец в режим „инкогнито“ с раздела „<ph name="TITLE" />“</translation>
-<translation id="5806206155699461681">Подобряване на конкретни сайтове (като Google Търсене).</translation>
-<translation id="5819072574982403430">Елемент от дърво</translation>
-<translation id="5826479389509458994">ред <ph name="ROW" />, графа <ph name="COL" /></translation>
-<translation id="5850707923114094062">Панорамно придвижване назад</translation>
-<translation id="5851548754964597211">Списък с раздели</translation>
-<translation id="5859752971144398932">Излязохте от търсенето в страницата.</translation>
-<translation id="5866042630553435010">Частично отметнато</translation>
-<translation id="5869546221129391014">Таблица</translation>
-<translation id="5876817486144482042">Намаляване на силата на звука на говора</translation>
-<translation id="5887397643266327462">Брайловите надписи са активирани.</translation>
-<translation id="5891934789323004067">Таблица</translation>
-<translation id="5919442531159595654">копиране.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{знак за равенство}other{# знака за равенство}}</translation>
-<translation id="5939518447894949180">Нулиране</translation>
-<translation id="5948123859135882163">Превключвайте между структурно и семантично интерпретиране на математическите изрази</translation>
-<translation id="5955304353782037793">приложение</translation>
-<translation id="5956928062748260866">Диалогов прозорец</translation>
-<translation id="5963413905009737549">Секция</translation>
-<translation id="5968607524793740041">Показване на контекстното меню</translation>
-<translation id="5983179082906765664">По-подробна навигация</translation>
-<translation id="5999630716831179808">Гласове</translation>
-<translation id="6000417740266304866">Променете текущата 8-точкова брайлова таблица, като изберете опция от списъка по-долу.</translation>
-<translation id="6006050241733874051">Формуляр</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{обратна наклонена черта}other{# обратни наклонени черти}}</translation>
-<translation id="6037602951055904232">Панорамно придвижване напред</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Край на клетката.</translation>
-<translation id="6122013438240733403">бутон</translation>
-<translation id="6129953537138746214">Интервал</translation>
-<translation id="6142308968191113180">Заглавие от четвърто ниво</translation>
-<translation id="6169420925157477918">Изображение с дълго описание</translation>
-<translation id="6172087735260766220">Няма достъп до текста от защитения срещу копиране PDF файл.</translation>
-<translation id="6186305613600865047">Преминаване към края на страницата</translation>
-<translation id="6193330012414963395">AM/PM</translation>
-<translation id="622484624075952240">Клавиш за надолу</translation>
-<translation id="6236061028292614533">Следващото заглавие</translation>
-<translation id="6254901459154107917">Следващата текстова област, която може да се редактира</translation>
-<translation id="6259464875943891919">Излязохте от <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Следващият подобен елемент.</translation>
-<translation id="6282062888058716985">навигация</translation>
-<translation id="6290434000785343030">Няма следващ разгъващ се списък.</translation>
-<translation id="6307969636681130414">Натиснато</translation>
-<translation id="6324551002951139333">Открита е граматична грешка</translation>
-<translation id="6348657800373377022">Разгъващ се списък</translation>
-<translation id="6355910664415701303">Няма предишен списъчен елемент.</translation>
-<translation id="6364795331201459219">заглавие от шесто ниво</translation>
-<translation id="6368143427468974988">Предишното заглавие</translation>
-<translation id="6387719785439924554">странично съдържание</translation>
-<translation id="6411426777058107714">Няма предишен бутон за избор.</translation>
-<translation id="6414968628640960377">Предишният различен елемент.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{двоеточие}other{# двоеточия}}</translation>
-<translation id="6438968337250688271">„<ph name="NAME" />“, меню</translation>
-<translation id="6444046323172968959">Диалогов прозорец със сигнал</translation>
-<translation id="6459511626086141404">Фиксирана клавиатурна подредба</translation>
-<translation id="6468049171101508116">Следващият бутон</translation>
-<translation id="6491972999578897419">Променете текущия глас, като изберете опция от списъка по-долу.</translation>
-<translation id="6508059270146105198">Преместване на брайловия дисплей в долната част на страницата</translation>
-<translation id="6536864053412760904">Означение в Math ML</translation>
-<translation id="6550720799683018100">Променете текущата клавиатурна подредба, като изберете опция от списъка по-долу.</translation>
-<translation id="6561818612645211875">Към началото на текущия ред</translation>
-<translation id="6587021927234520429">Няма следващо заглавие от четвърто ниво.</translation>
-<translation id="6601344353291556895">Активиране на подробните описания.</translation>
-<translation id="6615602925644411249">Търсене в страницата.</translation>
-<translation id="6633350132811819843">Няма следваща таблица.</translation>
-<translation id="6637586476836377253">регистрационен файл</translation>
-<translation id="6657128831881431364">Лента за хода</translation>
-<translation id="6659594942844771486">Раздел</translation>
-<translation id="667999046851023355">Документ</translation>
-<translation id="6697092096875747123">Предишният разгъващ се списък</translation>
-<translation id="6714813999819678458">Предишното заглавие от второ ниво</translation>
-<translation id="6716505898850596801">Модифициращи клавиши</translation>
-<translation id="671916444866103745">Няма следващ отличителен белег на ARIA.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, разгъващ се списък</translation>
-<translation id="6735257939857578167">с/ъс <ph name="NUM" /> елемента</translation>
-<translation id="6736510033526053669">разделът е създаден</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Статия</translation>
-<translation id="6787839852456839824">Клавишни комбинации</translation>
-<translation id="6793101435925451627">списъчно поле</translation>
-<translation id="6833103209700200188">Долен колонтитул</translation>
-<translation id="6871161210040114857">Регистърът на буквите се пренебрегва.</translation>
-<translation id="6877435256196695200">Няма следваща графика.</translation>
-<translation id="6897341342232909480">Преместване наляво</translation>
-<translation id="6901540140423170855">дата</translation>
-<translation id="6910211073230771657">Изтрито</translation>
-<translation id="6911965441508464308">Няма клетка отгоре.</translation>
-<translation id="6919104639734799681">Показване на списъка с таблици</translation>
-<translation id="6964088412282673743">Няма предишна контрола.</translation>
-<translation id="6996566555547746822">Следващият разгъващ се списък</translation>
-<translation id="7005146664810010831">Няма намерен URL адрес</translation>
-<translation id="7010712454773919705">Модифициращ клавиш за ChromeVox</translation>
-<translation id="7031651751836475482">списъчен елемент</translation>
-<translation id="7037042857287298941">Предишният списък</translation>
-<translation id="7041173719775863268">Край на открояването</translation>
-<translation id="7095834689119144465">Поле само за цифри</translation>
-<translation id="7096001299300236431">Предишният мултимедиен елемент</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">ехо за думите</translation>
-<translation id="713824876195128146">Следващият блоков цитат</translation>
-<translation id="7161771961008409533">Бутон с изскачащ прозорец</translation>
-<translation id="7167657087543110">ехо за знаците</translation>
-<translation id="7170733337935166589">Превъртане напред при непрекъснато четене</translation>
-<translation id="7181697990050180700">Персонализирайте клавишните комбинации за често използваните команди, като ги въведете в съответните полета по-долу.</translation>
-<translation id="7203150201908454328">Разгънато</translation>
-<translation id="7210211103303402262">минути</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">ред</translation>
-<translation id="7226216518520804442">списък</translation>
-<translation id="72393384879519786">Заглавие</translation>
-<translation id="7241683698754534149">Отваряне на дългото описание в нов раздел</translation>
-<translation id="7248671827512403053">Приложение</translation>
-<translation id="725969808843520477">Следващият бутон за избор</translation>
-<translation id="7269119382257320590">Без препинателни знаци</translation>
-<translation id="7273174640290488576">Празно</translation>
-<translation id="7285387653379749618">Таблици</translation>
-<translation id="7289186959554153431">Заглавие от трето ниво</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Брайловите надписи са деактивирани.</translation>
-<translation id="7318872822751139669">Използване на мишката за промяна на фокуса.</translation>
-<translation id="7322388933135261569">февруари</translation>
-<translation id="7332592614823088566">Ред <ph name="ROWINDEX" /> от <ph name="ROWTOTAL" />, графа <ph name="COLINDEX" /> от <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">има изскачащ прозорец</translation>
-<translation id="7356165926712028380">Превключване към 8-точково брайлово писмо</translation>
-<translation id="7362871137496673139">Няма предишно заглавие от второ ниво.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{амперсанд}other{# амперсанда}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Напускате таблицата.</translation>
-<translation id="739763518212184081">Предишният ред</translation>
-<translation id="7400575256015741911">Открита е правописна грешка</translation>
-<translation id="7408482676469142474">таблица</translation>
-<translation id="7425395583360211003">връщане в началото на реда</translation>
-<translation id="7434509671034404296">Програмист</translation>
-<translation id="7439060726180460871">Директория</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">раздел</translation>
-<translation id="7492049978501397201">Влязохте в диалогов прозорец</translation>
-<translation id="7532613204005497612">юни</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, „<ph name="NAME" />“, плъзгач</translation>
-<translation id="7586163296341959563">поставяне.</translation>
-<translation id="7596919493010894443">открояването е изчистено</translation>
-<translation id="7604026522577407655">Към началото на текущата графа</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Съобщаване на URL адреса на текущата страница</translation>
-<translation id="7609363189280667021">Превключване на брайловите надписи</translation>
-<translation id="762020119231868829">Поставя на пауза всички понастоящем пуснати приспособления за мултимедия</translation>
-<translation id="7625690649919402823">Следващата таблица</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), клас <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Няма предишно заглавие от трето ниво.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, „<ph name="NAME" />“, текстово поле</translation>
-<translation id="7663318257180412551">Заглавие от второ ниво</translation>
-<translation id="7674576868851035240">Следващата връзка</translation>
-<translation id="7674768236845044097">маркиране</translation>
-<translation id="7684431668231950609">Поле за въвеждане на URL адрес</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Предишният бутон за избор</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, „<ph name="NAME" />“, текстово поле за парола</translation>
-<translation id="7805247615045262757">навигиране по подразбиране</translation>
-<translation id="7805768142964895445">Състояние</translation>
-<translation id="7810781339813764006">Следващата група</translation>
-<translation id="7819187121850078213">прозорец с раздела „<ph name="TITLE" />“</translation>
-<translation id="7828956995407538686">октомври</translation>
-<translation id="7839679365527550018">Предишната дума</translation>
-<translation id="7851816175263618915">Някои препинателни знаци</translation>
-<translation id="7870596830398826354">Дърво в Math ML</translation>
-<translation id="78826985582142166">плъзгач</translation>
-<translation id="7894517696028036636">Превключване на класическия изглед на ChromeVox.</translation>
-<translation id="7895896691902835279">Неизвестна връзка</translation>
-<translation id="7927711904086083099">Не е избрано</translation>
-<translation id="7935627501098484003">Контрола за дата и час</translation>
-<translation id="7939428177581522200">добавени към открояването</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{знак @}other{# знака @}}</translation>
-<translation id="7965147473449754028">менюто е затворено</translation>
-<translation id="7974390230414479278">Елемент от меню</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{удивителен знак}other{# удивителни знака}}</translation>
-<translation id="8007540374018858731">заглавие от трето ниво</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{кавички}other{# кавички}}</translation>
-<translation id="8033827949643255796">откроени</translation>
-<translation id="8035962149453661158">максимум: <ph name="X" /></translation>
-<translation id="8042761080832772327">Поле за въвеждане на заявка за търсене</translation>
-<translation id="8049189770492311300">Таймер</translation>
-<translation id="8065607967589909823">Открояването е</translation>
-<translation id="8066678206530322333">Банер</translation>
-<translation id="8110647606445335195">Няма отличителни белези на ARIA.</translation>
-<translation id="8153880621934657047">Не сте в таблицата.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{долна черта}other{# долни черти}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">изрязване.</translation>
-<translation id="8199231515320852133">Съобщаване на заглавките за текущата клетка</translation>
-<translation id="820417203470636242">Празна клетка.</translation>
-<translation id="8215202828671303819">Избор на няколко елемента</translation>
-<translation id="8276439074553447000">Преминаване към предишния елемент, който може да получи фокус</translation>
-<translation id="8278417001922463147">Няма предишна статия.</translation>
-<translation id="8283603667300770666">Следващото поле във формуляра</translation>
-<translation id="831207808878314375">Определение</translation>
-<translation id="8313653172105209786">директория</translation>
-<translation id="8344569602005188545">часове</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{знак диез}other{# знака диез}}</translation>
-<translation id="8374154622594089836">месец</translation>
-<translation id="8378855320830505539">Област</translation>
-<translation id="8382679411218029383">Автоматично довършване – вградено и в списък</translation>
-<translation id="8428603554127842284">ниво <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Няма следващо заглавие от трето ниво.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Няма предишно квадратче за отметка.</translation>
-<translation id="8455868257606149352">Максимум <ph name="X" /></translation>
-<translation id="84575901236241018">има клавиш за достъп, „<ph name="KEY" />“</translation>
-<translation id="8503360654911991865">По-малко подробна навигация</translation>
-<translation id="8520472399088452386">Брояч</translation>
-<translation id="8538744478902126321">Предположение за заглавката на реда за текущата клетка</translation>
-<translation id="8540054775867439484">Пренасяне в началото</translation>
-<translation id="8548973727659841685">Символ</translation>
-<translation id="8561322612995434619">има изскачащ прозорец</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">заглавие от пето ниво</translation>
-<translation id="8587549812518406253">Следващият списъчен елемент</translation>
-<translation id="860150890330522909">квадратче „<ph name="NAME" />“ с отметка</translation>
-<translation id="8606621670302093223">Контрола за датата</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> избрани елемента</translation>
-<translation id="8638532244051952400">Съобщаване на координатите на текущата клетка</translation>
-<translation id="8650576015643545550">Няма предишен списък.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Показване на списъка с връзки</translation>
-<translation id="8664519043722036194">секунди</translation>
-<translation id="867187640362843212">Заглавие от пето ниво</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{вертикална черта}other{# вертикални черти}}</translation>
-<translation id="8735450637152821465">Начало на открояването</translation>
-<translation id="8743786158317878347">вход в структурирано съдържание, като например таблици</translation>
-<translation id="8747966237988593539">Подреден списък</translation>
-<translation id="8759334257841767240">Няма следваща връзка.</translation>
-<translation id="8767968232364267681">Следващото заглавие от четвърто ниво</translation>
-<translation id="8770473310765924354">изход от структурирано съдържание, като например таблици</translation>
-<translation id="8791025954632646584">Семантиката е включена</translation>
-<translation id="8796411681063377102">Следващото заглавие от трето ниво</translation>
-<translation id="8808582214901541005">март</translation>
-<translation id="8825828890761629845">банер</translation>
-<translation id="8851136666856101339">основен елемент</translation>
-<translation id="8856538297388979332">Натиснете стрелките за нагоре или надолу, за да прегледате командите, натиснете „enter“ за активиране</translation>
-<translation id="8864099967139188018">Няма следващо заглавие от шесто ниво.</translation>
-<translation id="8882002077197914455">Заглавка на ред</translation>
-<translation id="8896347895970027998">Превключване на ChromeVox между активно или неактивно състояние.</translation>
-<translation id="8898516272131543774">Цикъл на ехото за препинателни знаци</translation>
-<translation id="8900148057318340779">Клавиш за префикс</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Празни заглавки</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Модифициращи клавиши</translation>
-<translation id="8943175951035496220">Няма клетка отдясно.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">файл</translation>
-<translation id="9027462562263121875">Няма таблици.</translation>
-<translation id="9040132695316389094">Заглавие от първо ниво</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Превключване на приспособлението за търсене</translation>
-<translation id="9065283790526219006">+изскачащ прозорец</translation>
-<translation id="9077213568694924680">премахнати от открояването</translation>
-<translation id="9082874451376019682">Няма предишен плъзгач.</translation>
-<translation id="9089864840575085222">Цикъл на ехото при въвеждане</translation>
-<translation id="9107530006868467849">Няма предишно приспособление за мултимедия.</translation>
-<translation id="9108370397979208512">математически израз</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{знак за процент}other{# знака за процент}}</translation>
-<translation id="9115913704608474258">ноември</translation>
-<translation id="9128414153595658330">диалогов прозорец</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Съобщава кратко описание на текущата позиция</translation>
-<translation id="9153606228985488238">Височина: <ph name="PERCENT" /> процента</translation>
-<translation id="9160096769946561184">Към края на текущата графа</translation>
-<translation id="9173115498289768110">Сила на звука: <ph name="PERCENT" /> процента</translation>
-<translation id="9178973770513562274">Използвайте клавишите със стрелка за нагоре и надолу, за да сърфирате, или пишете, за да търсите.</translation>
-<translation id="9192904702577636854">Бягащ ред</translation>
-<translation id="9212322457209634662">Няма следваща секция.</translation>
-<translation id="930275611743429116">Начало или край на открояването.</translation>
-<translation id="948171205378458592">Намаляване на скоростта на говора</translation>
-<translation id="962913030769097253">Следващото заглавие от първо ниво</translation>
-<translation id="973955474346881951">Активиране/деактивиране на фиксирания режим</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bn.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bn.xtb
deleted file mode 100644
index ffef3920b82..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bn.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="bn">
-<translation id="1012173283529841972">তালিকা আইটেম</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">স্প্যান্ড</translation>
-<translation id="1025074108959230262">স্টিকি মোড অক্ষম</translation>
-<translation id="1031961866430398710">তারপর</translation>
-<translation id="1044777062731150180">কোনো শিরোলেখ নেই</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">অবৈধ ইনপুট</translation>
-<translation id="1082209053475788238">কোনো পূর্ববর্তী স্তর ৬ শিরোনাম নেই৷</translation>
-<translation id="1088219014394087294">কোনো শিরোলেখ নেই৷</translation>
-<translation id="1106741348836243114">শব্দ প্রতিক্রিয়া (earcons) চালু বা বন্ধ করুন৷</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="NUM" />টি আইটেমের সঙ্গে <ph name="TAG" /> সংগ্রহ</translation>
-<translation id="1155043339247954670">কোনো পরবর্তী তালিকা আইটেম নেই৷</translation>
-<translation id="1157782847298808853">কীবোর্ড সহায়তা</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, কম্বো বাক্স</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, মেনু আইটেম, উপমেনু সহ</translation>
-<translation id="1177863135347784049">কাস্টম</translation>
-<translation id="1188858454923323853">পরিপূরক</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome কে ভয়েস প্রদান</translation>
-<translation id="1229276918471378188">পূর্ববর্তী জাম্প</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">পরবর্তী স্তর ৬ শিরোনাম</translation>
-<translation id="1275718070701477396">নির্বাচিত</translation>
-<translation id="1319608975892113573">কোনো পূর্ববর্তী অবরুদ্ধ উর্দ্ধৃতি নেই৷</translation>
-<translation id="1321576897702511272">ChromeVox সহায়তা লুকান</translation>
-<translation id="1331702245475014624"><ph name="TOTAL" />-এর <ph name="INDEX" /></translation>
-<translation id="1334095593597963605">অক্ষর ও শব্দ ইকো</translation>
-<translation id="1339428534620983148">পরবর্তী সারণী কলাম</translation>
-<translation id="1342835525016946179">নিবন্ধ</translation>
-<translation id="1346748346194534595">ডান</translation>
-<translation id="136718599399906424">পরবর্তী সারণী সারি</translation>
-<translation id="1383876407941801731">অনুসন্ধান</translation>
-<translation id="1385214448885562192">স্বীকার করতে এন্টার বা বাতিল করতে এসকেপ, পরবর্তীর জন্য নীচে এবং পূর্ববর্তীর জন্য উপরে টিপুন৷</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, পাসওয়ার্ড পাঠ্য বাক্স</translation>
-<translation id="1467432559032391204">বাম</translation>
-<translation id="1474557363159888097">কোনো পূর্ববর্তী অ্যাঙ্কর নেই৷</translation>
-<translation id="1502086903961450562">পূর্ববর্তী গ্রাফিক</translation>
-<translation id="1506187449813838456">পিচ বাড়ান</translation>
-<translation id="151784044608172266">পরবর্তী বাক্য</translation>
-<translation id="1524531499102321782">ব্রেইল পরবর্তী লাইন</translation>
-<translation id="1546370775711804143">স্ক্রোল দণ্ড</translation>
-<translation id="1559739829547075274">পিছনের দিকে নেভিগেট করুন</translation>
-<translation id="1571643229714746283">ChromeVox প্রস্তুত</translation>
-<translation id="158493514907962286">ডিসেম্বর</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">৬ ডট ব্রেইল-এ স্যুইচ করুন</translation>
-<translation id="1611168825862729585">কলাম শিরোলেখ:</translation>
-<translation id="1613476421962910979">Earcons চালু আছে</translation>
-<translation id="1618597272655350600">বর্তমান অবস্থানটির একটি সম্পূর্ণ বিবরণ ঘোষণা করে</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{বৃহত্তম}one{#টি বৃহত্তম চিহ্ন}other{#টি বৃহত্তম চিহ্ন}}</translation>
-<translation id="1653266918374749391">পূর্ববর্তী স্তর ৩ শিরোনাম</translation>
-<translation id="1659072772017912254">চেক করা হয়নি</translation>
-<translation id="1669290819662866522">সপ্তাহ</translation>
-<translation id="1674262202423278359">ChromeVox নেভিগেশান</translation>
-<translation id="16777221443363124">মেনু দণ্ড</translation>
-<translation id="1692077714702418899">গঠনগত রেখা</translation>
-<translation id="1700517974991662022">ঘুরে দেখা হয়েছে</translation>
-<translation id="1722567105086139392">লিঙ্ক</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">পরবর্তী গ্রাফিক</translation>
-<translation id="1781173782405573156">পার হয়ে যাওয়ার কী</translation>
-<translation id="1787176709638001873">পাসওয়ার্ড সম্পাদনা পাঠ্য</translation>
-<translation id="1810107444790159527">তালিকা বাক্স</translation>
-<translation id="1828385960365606039">মে</translation>
-<translation id="1834891354138622109">কলাম</translation>
-<translation id="1865601187525349519">পাঠ্যের শেষে</translation>
-<translation id="1876229593313240038">দস্তাবেজ</translation>
-<translation id="188130072164734898">বর্তমান সময় ও তারিখ বলে৷</translation>
-<translation id="1902396333223336119">সেল</translation>
-<translation id="1905379170753160525">শিরোনাম তালিকা দেখান</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">বর্ষ নিয়ন্ত্রণের জন্য সপ্তাহ</translation>
-<translation id="1964135212174907577">পরবর্তী বস্তু</translation>
-<translation id="1969092762068865084">জুলাই</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">সারি শিরোলেখ:</translation>
-<translation id="2002895034995108595">বর্তমান কীম্যাপ পুনরায় সেট করুন</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{বাম বন্ধনী}one{#টি বাম বন্ধনী}other{#টি বাম বন্ধনী}}</translation>
-<translation id="2045490512405922022">চেক লাগানো হয়নি</translation>
-<translation id="20601713649439366">এর পূর্বে কোনো গাণিতিক অভিব্যক্তি নেই৷</translation>
-<translation id="207477615537953741">শব্দার্থিক বন্ধ আছে</translation>
-<translation id="2086961585857038472">পরবর্তী শব্দ</translation>
-<translation id="2089387485033699258">bn</translation>
-<translation id="2091933974477985526">পূর্ববর্তী সম্পাদনার যোগ্য পাঠ্য অঞ্চল</translation>
-<translation id="2100350898815792233">সমস্ত যতিচিহ্ন</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">অ্যাক্সেস কী:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">নীচের তালিকা থেকে একটি বিকল্প নির্বাচন করে বর্তমান ৬ ডট ব্রেইল সারণিটি পরিবর্তন করুন।</translation>
-<translation id="2169714232367507776">বর্তমান আইটেমে ক্লিক করুন</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{ডান বন্ধনী}one{#টি ডান বন্ধনী}other{#টি ডান বন্ধনী}}</translation>
-<translation id="2199994615414171367">পূর্ববর্তী গাণিতিক</translation>
-<translation id="2223693656926968778">বর্তমান আইটেমের উপর ব্যবস্থা গ্রহণ করুন</translation>
-<translation id="225732394367814946">কথনের হার বাড়ান</translation>
-<translation id="2267945578749931355">পরবর্তী অক্ষর</translation>
-<translation id="2281234842553884450">পূর্ববর্তী স্লাইডার</translation>
-<translation id="2318372665160196757">প্রধান</translation>
-<translation id="2329324941084714723">ট্যাব প্যানেল</translation>
-<translation id="2344193891939537199">তারিখ সময় নিয়ন্ত্রণ</translation>
-<translation id="2359897517538099099">টেবিল মোডে নয়।</translation>
-<translation id="241124561063364910">এর দ্বারা অনুসরণ করা হয়</translation>
-<translation id="2417569100218200841">সামগ্রীর তথ্য</translation>
-<translation id="2422937916923936891">মেনু আইটেম চেক বাক্স</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">এখন <ph name="KEY" /> হল নতুন ChromeVox সংশোধক৷</translation>
-<translation id="2450814015951372393">চেকবাক্স</translation>
-<translation id="2462626033734746142">রেডিও বোতাম গোষ্ঠী</translation>
-<translation id="2471138580042810658">শিরোনাম ৬</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{তারা}one{#টি তারা}other{#টি তারা}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> পুনরায় সেট হয়েছে৷</translation>
-<translation id="2553108862507765288">ব্যাকরণগত ভুল</translation>
-<translation id="257674075312929031">গোষ্ঠী</translation>
-<translation id="2582407057977008361">একপাশে</translation>
-<translation id="2589102159832527089">এই পৃষ্ঠাটিতে PDF ফাইল &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; থেকে স্বয়ংক্রিয়ভাবে নিষ্কাশিত হওয়া পাঠ্য রয়েছে৷ &lt;a href="<ph name="URL" />"&gt;আসলটির জন্য এখানে ক্লিক করুন৷&lt;/a&gt;</translation>
-<translation id="2606210917827248971">সাথে আছে {COUNT,plural, =1{#টি আইটেম}one{#টি আইটেম}other{#টি আইটেম}}</translation>
-<translation id="2614981083756825552">গাণিতিক ML লেআউট</translation>
-<translation id="2626530649491650971">ক্লিক যোগ্য</translation>
-<translation id="2628764385451019380">কোনো পূর্ববর্তী কম্বোবক্স ল্যান্ডমার্ক নেই৷</translation>
-<translation id="2637227747952042642">গণিত</translation>
-<translation id="2639750663247012216">ChromeVox সংশোধক</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">একটি রাউটিং কী এর অধীনে থাকা আইটেমে ক্লিক করুন</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{বাম বন্ধনী}one{#টি বাম বন্ধনী}other{# বাম বন্ধনী}}</translation>
-<translation id="2705875883745373140">টেপা হয়নি</translation>
-<translation id="2706462751667573066">উপরের</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">অডিও</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">চেক করা</translation>
-<translation id="27527859628328957">পরবর্তী ফোকাসযোগ্য আইটেমে জাম্প করুন</translation>
-<translation id="2770781857296573485">গোষ্ঠী অন্বেষণ প্রবেশ করে</translation>
-<translation id="2777845298774924149">বের করা হয়েছে</translation>
-<translation id="2800204403141299078">কোনো পৃথক উপাদান নেই৷</translation>
-<translation id="2800780099804980316">কোনো পূর্ববর্তী স্তর ১ শিরোনাম নেই৷</translation>
-<translation id="2811204574343810641">সারি</translation>
-<translation id="2816654101880605877">কোনো পরবর্তী স্লাইডার নেই৷</translation>
-<translation id="2841013758207633010">সময়</translation>
-<translation id="2843837985843789981">পূর্ববর্তী গোষ্ঠী</translation>
-<translation id="2844995807198708617">প্রসঙ্গ মেনু</translation>
-<translation id="2849332794118375855">কোনো পরবর্তী চেকবাক্স নেই৷</translation>
-<translation id="2864481629947106776">আগের লিঙ্ক</translation>
-<translation id="2873259058405069099">সারণীর শুরুতে যান</translation>
-<translation id="2894654529758326923">তথ্য</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{বাম দ্বিতীয় বন্ধনী}one{#টি বাম দ্বিতীয় বন্ধনী}other{#টি বাম দ্বিতীয় বন্ধনী}}</translation>
-<translation id="2911433807131383493">ChromeVox টিউটোরিয়াল খুলুন</translation>
-<translation id="2932083475399492303">গঠনগত বা লেআউট রেখার প্রকারের মধ্যে টগল করুন</translation>
-<translation id="2964026537669811554">শিরোনাম গোষ্ঠী</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{ট্যাব}one{#টি ট্যাব}other{#টি ট্যাব}}</translation>
-<translation id="2972078295414139404">কোনো পূর্ববর্তী ঘুরে দেখা লিঙ্ক নেই</translation>
-<translation id="2972205263822847197">টুল টিপ</translation>
-<translation id="2998131015536248178">পূর্ববর্তী অক্ষর</translation>
-<translation id="2999559350546931576">পিচ কমান</translation>
-<translation id="2999945368667127852">কোনো পরবর্তী মিডিয়া উইজেট নেই৷</translation>
-<translation id="3012414509011670858">এর পূর্বে কোনো বিভাগ নেই৷</translation>
-<translation id="3030432017085518523">মেনু আইটেম রেডিও বোতাম</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{ঊর্ধকমা}one{#টি ঊর্ধকমা}other{#টি ঊর্ধকমা}}</translation>
-<translation id="3046838483509668188">ChromeVox বিকল্প</translation>
-<translation id="3047143736589213134">পরীক্ষামূলক কীম্যাপ</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> মেনু খোলা আছে</translation>
-<translation id="3078345202707391975">পরবর্তী স্তর ২ শিরোনাম</translation>
-<translation id="3078740164268491126">সারণী</translation>
-<translation id="3082557070674409251">ক্লিক করা হয়েছে</translation>
-<translation id="3084806535845658316">কোনো টাইপিং ইকো নেই</translation>
-<translation id="3086746722712840547">দ্রষ্টব্য</translation>
-<translation id="308895241372589742">এরপরে কোনো গাণিতিক অভিব্যক্তি নেই৷</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">পরবর্তী ল্যান্ডমার্ক</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">সঙ্কুচিত</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">ল্যান্ডমার্ক তালিকা দেখান</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">পরবর্তী লাইন</translation>
-<translation id="3155083529632865074">কোনো পূর্ববর্তী বোতাম নেই৷</translation>
-<translation id="3163593631834463955">ফাঁকা কলাম শিরোলেখ</translation>
-<translation id="316542773973815724">নেভিগেশন</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{ব্যবধান}one{#টি ব্যবধান}other{#টি ব্যবধান}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> প্রবেশ করা হয়েছে</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, ট্যাব</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">ঘুরে দেখা লিঙ্ক</translation>
-<translation id="323731244387692321">ChromeVox সহায়তা খুলুন</translation>
-<translation id="3241052487511142956">পূর্ববর্তী ঘুরে দেখা লিঙ্ক</translation>
-<translation id="3286390186030710347">স্লাইডার</translation>
-<translation id="3299925995433437805">কোনো পরবর্তী ঘুরে দেখা লিঙ্ক নেই</translation>
-<translation id="3303384412438961941">এটির নাম জানতে যেকোনও কী টিপুন৷ Ctrl+W কীবোর্ড এক্সপ্লোরার বন্ধ করবে৷</translation>
-<translation id="3307886118343381874">সারণীর শেষে যান</translation>
-<translation id="3311969765485641742">এই সতর্কতা পর্যালোচনা করতে Alt+Shift+A টিপুন</translation>
-<translation id="3312997241656799641">পরবর্তী ঘুরে দেখা লিঙ্ক</translation>
-<translation id="3321460131042519426">শব্দ মোড়ানো সক্ষম করুন</translation>
-<translation id="3322936298410871309">পূর্ববর্তী স্তর ১ শিরোনাম</translation>
-<translation id="3323447499041942178">পাঠ্য বাক্স</translation>
-<translation id="3353420241558113817">{"ar": "আরবী",
- "bg": "বুলগেরিয়ান",
- "ca": "ক্যাটালান",
- "cs": "চেক",
- "da": "ড্যানিশ",
- "de": "জার্মান",
- "de_CH": "জার্মান (সুইজারল্যান্ড)",
- "de_DE": "জার্মান (জার্মানি)",
- "el": "গ্রীক",
- "en": "ইংরাজি",
- "en_CA": "ইংরাজি (কানাডা)",
- "en_GB": "ইংরাজি (যুক্তরাজ্য)",
- "en_US": "ইংরাজি (যুক্তরাষ্ট্র)",
- "es": "স্প্যানিশ",
- "et": "এস্তোনিয়ান",
- "fr": "ফরাসী",
- "fr_CA": "ফরাসী (কানাডা)",
- "fr_FR": "ফরাসী (ফ্রান্স)",
- "fi": "ফিনিশ",
- "he": "হিব্রু",
- "hi": "হিন্দী",
- "hr": "ক্রোয়েশিয়ান",
- "hu": "হাঙ্গেরিয়ান",
- "is": "আইসল্যান্ডিক",
- "it": "ইটালিয়ান",
- "ko": "কোরিয়ান",
- "lt": "লিথুয়ানিয়ান",
- "lv": "লাটভিয়ান",
- "nb": "নরওয়েজীয় বোকমাল",
- "nl": "ডাচ",
- "pl": "পোলিশ",
- "pt": "পর্তুগীজ",
- "ro": "রোমানিয়ান",
- "ru": "রাশিয়ান",
- "sk": "স্লোভাক",
- "sl": "স্লোভেনিয়ান",
- "sr": "সার্বিয়ান",
- "sv": "সুইডিশ",
- "tr": "তুর্কি",
- "vi": "ভিয়েতনামী",
- "zh": "চীনা",
- "zh_TW": "চীনা (ঐতিহ্যবাহি হান)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{যুক্ত}one{#টি যুক্ত চিহ্ন}other{#টি যুক্ত চিহ্ন}}</translation>
-<translation id="338583716107319301">পৃথককারী</translation>
-<translation id="3389259863310851658">পূর্ববর্তী ফর্ম ক্ষেত্র</translation>
-<translation id="3390225400784126843">পরবর্তী বিভিন্ন উপাদান৷</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, মেনু আইটেম</translation>
-<translation id="3406283310380167331">ফর্ম তালিকা দেখান</translation>
-<translation id="3422338090358345848">কীবোর্ড এক্সপ্লোরার খুলুন</translation>
-<translation id="3457000393508828486">আংশিক টেপা</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, বোতাম</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" />টি</translation>
-<translation id="3486232535569802404"><ph name="V1" /> থেকে <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{ডান বন্ধনী}one{#টি বাম বন্ধনী}other{#টি বাম বন্ধনী}}</translation>
-<translation id="3493915602752813531">কোনো পরবর্তী অ্যাঙ্কর নেই৷</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{প্রশ্নবোধক চিহ্ন}one{#টি প্রশ্নবোধক চিহ্ন}other{#টি প্রশ্নবোধক চিহ্ন}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{ক্যারেট}one{# ক্যারেট}other{# ক্যারেট}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, চেকবাক্স চেকযুক্ত করা হয়নি</translation>
-<translation id="3599054940393788245">গণিত বর্হিভূত</translation>
-<translation id="3616113530831147358">অডিও</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{ব্যাকটিক}one{#টি ব্যাকটিক}other{#টি ব্যাকটিক}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{ডলার}one{#টি ডলার চিহ্ন}other{#টি ডলার চিহ্ন}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, তালিকা বাক্স</translation>
-<translation id="3687295507293856493">বর্তমান ঘরের কলাম শিরোলেখে অনুমান করুন</translation>
-<translation id="3692274950075847560">অ:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">বক্তব্য নিয়ন্ত্রণ</translation>
-<translation id="3716845769494773620">একাধিক লাইন</translation>
-<translation id="3731746171184829332">কোনো পূর্ববর্তী শিরোলেখ নেই৷</translation>
-<translation id="3762198587642264450">বর্তমান সারির শেষে যান</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">কথোপকথন থেকে প্রস্থান করা হয়ছে৷</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">স্বতসম্পূর্ণ তালিকা</translation>
-<translation id="3810838688059735925">ভিডিও</translation>
-<translation id="3816633764618089385">পরবর্তী মিডিয়া</translation>
-<translation id="3819376190738087562">কোনো জাম্প নেই৷</translation>
-<translation id="385383972552776628">বিকল্প পৃষ্ঠা খুলুন</translation>
-<translation id="3856075812838139784">কেবল পঠনযোগ্য</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">মেনু</translation>
-<translation id="3909320334364316587">পূর্ববর্তী স্তর ৬ শিরোনাম</translation>
-<translation id="3914173277599553213">প্রয়োজন</translation>
-<translation id="3962990492275676168">বর্তমান অবস্থান থেকে পড়া শুরু করুন</translation>
-<translation id="4004802134384979325">চেক করা</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">মাস নির্বাচন</translation>
-<translation id="4039983576244166038">ফাঁকা সারি শিরোলেখ</translation>
-<translation id="4042843249978639960">কোনো পূর্ববর্তী স্তর ২ শিরোলেখ নেই৷</translation>
-<translation id="4043348641337972076">কোনো পূর্ববর্তী ARIA ল্যান্ডমার্ক নেই৷</translation>
-<translation id="4047216625641135770">চিহ্নিত</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{টিলড চিহ্ন}one{#টি টিলড চিহ্ন}other{#টি টিলড চিহ্ন}}</translation>
-<translation id="409334809956508737">পূর্ববর্তী বস্তু</translation>
-<translation id="4099274309791143834">উপমেনুর সাথে</translation>
-<translation id="4107807507418787238">নীচে কোনো কক্ষ নেই৷</translation>
-<translation id="4116415223832267137">সতর্কতা</translation>
-<translation id="4147126331795725888">এরপরে কোনো নিয়ন্ত্রণ নেই৷</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{ডান দ্বিতীয় বন্ধনী}one{#টি ডান দ্বিতীয় বন্ধনী}other{#টি ডান দ্বিতীয় বন্ধনী}}</translation>
-<translation id="4158704014418536539">কেস সংবেদনশীল।</translation>
-<translation id="4161663686871496107">ChromeVox কথ্য প্রতিক্রিয়া প্রস্তুত</translation>
-<translation id="4173994908659439270">কোনো পরবর্তী সম্পাদনযোগ্য পাঠ্য ক্ষেত্র নেই৷</translation>
-<translation id="4176463684765177261">অক্ষম</translation>
-<translation id="4188530942454211480">পূর্ববর্তী বাক্য</translation>
-<translation id="4202186506458631436">ডানদিকে সরান</translation>
-<translation id="4206289001967551965">সারণীর অভ্যন্তরে</translation>
-<translation id="4215733775853809057">পরবর্তী স্লাইডার</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{ড্যাশ}one{#টি ড্যাশ}other{#টি ড্যাশ}}</translation>
-<translation id="421884353938374759">রঙ চয়নকারী</translation>
-<translation id="4229646983878045487">তারিখ সময়</translation>
-<translation id="423334822609210999">বামদিকে কোনো কক্ষ নেই৷</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, গ্রেড <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">টিকা</translation>
-<translation id="4254798249533888099">ট্রী</translation>
-<translation id="4255943572433203166">ChromeVox কাস্টমাইজ করতে নীচের বিকল্পগুলি ব্যবহার করুন৷ পরিবর্তনগুলি তাত্ক্ষণিকভাবে প্রভাবিত হয়৷</translation>
-<translation id="4271220233568730077">পরবর্তী গাণিতিক</translation>
-<translation id="4271521365602459209">আর কোনো ফলাফল নেই৷</translation>
-<translation id="4287520460805643128">এরপরে কোনো নিবন্ধ নেই৷</translation>
-<translation id="4289540628985791613">ওভারভিউ</translation>
-<translation id="4300318234632215983">একটি লিঙ্কের পিছনের URL ঘোষণা করুন</translation>
-<translation id="4301352596632316575">উপমেনু রয়েছে</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{বিন্দু}=3{এলিপসিস}one{#টি বিন্দু}other{# বিন্দু}}</translation>
-<translation id="4347461890115250064">কোনো পরবর্তী তালিকা নেই৷</translation>
-<translation id="4367650418938037324">গাণিতিক ML লিফ</translation>
-<translation id="4372435075475052704">ন্যূনতম:<ph name="X" /></translation>
-<translation id="4372705107434148843">স্পিচ থামান</translation>
-<translation id="4373197658375206385">এমন কোনো পূর্ববর্তী আইটেম নেই যা লিঙ্ক নয়৷</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">পুনঃসেট করুন</translation>
-<translation id="4471074325120394300">কোনো লিঙ্ক নেই৷</translation>
-<translation id="4476183483923481720">নতুন লাইন</translation>
-<translation id="4482330759234983253">পূর্ববর্তী সারণী</translation>
-<translation id="4491109536499578614">চিত্র</translation>
-<translation id="4529987814483543472">ক্লাসিক কীম্যাপ</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{স্ল্যাশ}one{#টি স্ল্যাশ}other{#টি স্ল্যাশ}}</translation>
-<translation id="4547556996012970016">পরবর্তী স্তর ৫ শিরোনাম</translation>
-<translation id="4562381607973973258">শিরোনাম</translation>
-<translation id="4591507479202817876">, নির্বাচিত</translation>
-<translation id="4597532268155981612">ফর্ম</translation>
-<translation id="4597896406374528575">এপ্রিল</translation>
-<translation id="4615592953348396470">পরবর্তী কি টেপা উপেক্ষা করা হচ্ছে</translation>
-<translation id="461613135510474570">বাক্য</translation>
-<translation id="4647836961514597010">রঙ চয়নকারী</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">পূর্ববর্তী ল্যান্ডমার্ক</translation>
-<translation id="4696413482802371445">কোনো পূর্ববর্তী স্তর ৫ শিরোনাম নেই৷</translation>
-<translation id="4729095194763193578">পূর্ববর্তী সারণী সারি</translation>
-<translation id="4736221692378411923">আগস্ট</translation>
-<translation id="4740661827607246557">সহায়তা আদেশগুলি</translation>
-<translation id="4759716709594980008">ChromeOS কীবোর্ড এক্সপ্লোরার</translation>
-<translation id="4763296182459741068">নীচে সম্পৃক্ত রয়েছে</translation>
-<translation id="4763480195061959176">ভিডিও</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">বর্তমান পৃষ্ঠার শিরোনাম ঘোষণা করুন</translation>
-<translation id="4826415162591436065">অগ্রবর্তী নেভিগেট করুন</translation>
-<translation id="4826604887384865800">পরবর্তী জাম্প</translation>
-<translation id="4827410568042294688">অনির্বাচিত</translation>
-<translation id="4842108708071771135">কোনো পরবর্তী অবরুদ্ধ উর্দ্ধৃতি নেই৷</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">পূর্ববর্তী অনুরূপ উপাদান৷</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS লগ ইন সক্ষম করুন</translation>
-<translation id="4877261390094455813">একটি অনুসন্ধান ক্যোয়ারী লিখুন৷</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">অভ্যন্তরীণ লিঙ্ক</translation>
-<translation id="4953585991029886728">পাঠ্য সম্পাদনা করুন</translation>
-<translation id="4954534434583049121">পূর্ববর্তী অবরুদ্ধ উদ্ধৃতি</translation>
-<translation id="4973717656530883744">ন্যূনতম <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> এ স্যুইচ করেছে৷</translation>
-<translation id="4975416682604111799">মিলিসেকেন্ড</translation>
-<translation id="49787999531187221">ChromeVox বর্তমানে নিষ্ক্রিয় রয়েছে৷</translation>
-<translation id="4979404613699303341">পূর্ববর্তী বোতাম</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, তালিকা বাক্স</translation>
-<translation id="4983588134362688868">পৃষ্ঠাটির শীর্ষে ফিরে যান</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, উইন্ডো</translation>
-<translation id="4993152509206108683"><ph name="PERCENT" /> শতাংশ হার</translation>
-<translation id="4996716799442435517">ভিসুয়াল</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, রেডিও বোতাম নির্বাচিত</translation>
-<translation id="4997475792277222884">এমন কোনো পরবর্তী আইটেম নেই যা লিঙ্ক নয়৷</translation>
-<translation id="5000760171916499057">কোনো ফর্ম নেই৷</translation>
-<translation id="5005670136041063723">কোনো অনুরূপ উপাদান নেই৷</translation>
-<translation id="501473567976723023">জানুয়ারি</translation>
-<translation id="5041394372352067729">পৃষ্ঠার উপরের দিকে ব্রেইল প্রদর্শন সরান</translation>
-<translation id="5042770794184672516">কথন ভলিউম বাড়ান</translation>
-<translation id="5050015258024679800">পূর্ববর্তী স্তর ৫ শিরোনাম</translation>
-<translation id="5054047268577924192">পূর্ববর্তী তালিকা আইটেম</translation>
-<translation id="5078661581131202757">ফাইল নির্বাচন</translation>
-<translation id="5080758118274074384">দুবার ক্লিক করা হয়েছে</translation>
-<translation id="5098541983634824365">গ্রিড ত্যাগ করছে৷</translation>
-<translation id="5102981729317424850">সরঞ্জাম দণ্ড</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">কোনো পরবর্তী ফর্ম ক্ষেত্র নেই৷</translation>
-<translation id="5111640677200759579">কলাম শিরোলেখ</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">কোনো পূর্ববর্তী লিঙ্ক নেই৷</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, অনির্বাচিত</translation>
-<translation id="5183440668879371625">ব্রেইল পূর্ববর্তী লাইন</translation>
-<translation id="5184944171021383281">কোনো পূর্ববর্তী ফর্ম ক্ষেত্র নেই৷</translation>
-<translation id="5189244881767082992">লাইন</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> ইতিমধ্যেই একটি আদেশের জন্য অ্যাসাইন করা হয়েছে৷</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> তালিকা৷</translation>
-<translation id="520883772648104506">কোনো পরবর্তী রেডিও বোতাম নেই৷</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">অবজেক্ট</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, ট্যাব</translation>
-<translation id="5310788376443009632">সরানো হয়েছে:</translation>
-<translation id="5320727453979144100">স্টিকি মোড সক্ষম</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{কমা}one{# টি কমা}other{# টি কমা}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, পাঠ্য বাক্স</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, লিঙ্ক</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">একটানা পড়ার সময় ছেড়ে পিছনে যান</translation>
-<translation id="5368000168321181111">Earcons বন্ধ আছে</translation>
-<translation id="5374320867641260420">কোনো পরবর্তী বোতাম নেই৷</translation>
-<translation id="5382299583965267720">কোনো পূর্ববর্তী স্তর ১ শিরোলেখ নেই৷</translation>
-<translation id="5402367795255837559">ব্রেইল</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{সেমিকোলন}one{#টি সেমিকোলন}other{#টি সেমিকোলন}}</translation>
-<translation id="5411891038905756502">কোনো পূর্ববর্তী জাম্প বিন্দু নেই৷</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{ক্ষুদ্রতম}one{#টি ক্ষুদ্রতম চিহ্ন}other{#টি ক্ষুদ্রতম চিহ্ন}}</translation>
-<translation id="5455441614648621694">পরিপূরক</translation>
-<translation id="5485036206801896268">কোনো পূর্ববর্তী গ্রাফিক নেই৷</translation>
-<translation id="5486947920110100234">কোনো পরবর্তী জাম্প বিন্দু নেই৷</translation>
-<translation id="549602578321198708">শব্দ</translation>
-<translation id="5500932716852106146">কোনো পূর্ববর্তী সম্পাদনযোগ্য পাঠ্য ক্ষেত্র নেই৷</translation>
-<translation id="5502713021410870035">সেপ্টেম্বর</translation>
-<translation id="5507663321906818013">বেঞ্চমার্ক ডিভাগ করুন</translation>
-<translation id="5518443085409638729">পাঠ্য সম্পাদনা করার সময় কার্সার অক্ষরগুলির মধ্যে রাখুন (Mac OS X এর মত)৷</translation>
-<translation id="552195134157544755">রেডিও বোতাম</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">কোনো পূর্ববর্তী স্তর ৫ শিরোনাম নেই৷</translation>
-<translation id="556042886152191864">বোতাম</translation>
-<translation id="5561345396546889625">পরবর্তী তালিকা</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">ইমেল এন্ট্রি, পাঠ্য সম্পাদনা করুন</translation>
-<translation id="5597170376237141345">পরবর্তী চেকবাক্স</translation>
-<translation id="5597933780944041114">কোনো পরবর্তী শিরোনাম নেই৷</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, রেডিও বোতাম নির্বাচিত নেই</translation>
-<translation id="5601172225407283979">ডিফল্ট ক্রিয়াটি সম্পন্ন করুন</translation>
-<translation id="5608798115546226984">স্বতসম্পূর্ণ ইনলাইন</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">লগ</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">কোনো পূর্ববর্তী সারণী নেই৷</translation>
-<translation id="5655682562155942719">মন্তব্যগুলি ছেড়ে যান</translation>
-<translation id="56637627897541303">পাঠ্য ক্ষেত্র</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">ল্যান্ডমার্ক</translation>
-<translation id="5683155931978483559">পূর্ববর্তী চেকবাক্স</translation>
-<translation id="5684277895745049190">তালিকা</translation>
-<translation id="5700650669149824506">কোনো পূর্ববর্তী স্তর ৪ শিরোনাম নেই৷</translation>
-<translation id="5709192780268610569">কোনো দীর্ঘ বিবরণ নেই</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">পরবর্তী সারণী কলাম</translation>
-<translation id="571866080859340309">গোষ্ঠীগুলি অন্বেষণ করা হচ্ছে</translation>
-<translation id="5728409797179002635">কোনো সারণী খুঁজে পাওয়া যায় নি৷</translation>
-<translation id="5748623122140342504">পূর্ববর্তী স্তর ৫ শিরোনাম</translation>
-<translation id="5750633686117194034">কোন সংশোধক টেপা হয়নি; দয়া করে এক বা একাধিক সংশোধকে টিপুন এবং ধরে থাকুন; একবার হয়ে গেলে আপনার আঙুলগুলি তুলে নিন এবং কীগুলি সেট হয়েছে তা আপনি শুনতে পাবেন৷ বেরিয়ে যেতে ট্যাব টিপুন৷</translation>
-<translation id="5788275253279308023">ছদ্মবেশী উইন্ডো <ph name="TITLE" /> ট্যাব</translation>
-<translation id="5806206155699461681">নির্দিষ্ট সাইটগুলি (যেমন Google অনুসন্ধান) স্বতঃবৃদ্ধি করুন৷</translation>
-<translation id="5819072574982403430">ট্রি আইটেম</translation>
-<translation id="5826479389509458994">সারি <ph name="ROW" /> কলাম <ph name="COL" /></translation>
-<translation id="5850707923114094062">পিছনের দিকে প্যান করুন</translation>
-<translation id="5851548754964597211">ট্যাব তালিকা</translation>
-<translation id="5859752971144398932">পৃষ্ঠায় খোজা থেকে বেরিয়ে গিয়েছে হচ্ছে৷</translation>
-<translation id="5866042630553435010">আংশিক চেক করা হয়েছে</translation>
-<translation id="5869546221129391014">গ্রিড</translation>
-<translation id="5876817486144482042">স্পিচ ভলিউম কমান</translation>
-<translation id="5887397643266327462">ব্রেইল পরিচয়লিপিগুলি সক্ষম করা হয়েছে৷</translation>
-<translation id="5891934789323004067">সারণী</translation>
-<translation id="5919442531159595654">অনুলিপি করুন৷</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{সমান}one{#টি সমান চিহ্ন}other{#টি সমান চিহ্ন}}</translation>
-<translation id="5939518447894949180">রিসেট করুন</translation>
-<translation id="5948123859135882163">কাঠামোগত এবং শব্দার্থিক এর মধ্যে গাণিতিক এক্সপ্রেশনের ব্যাখ্যা টগল করে</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">কথোপকথন</translation>
-<translation id="5963413905009737549">বিভাগ</translation>
-<translation id="5968607524793740041">প্রসঙ্গ মেনু দেখান</translation>
-<translation id="5983179082906765664">নেভিগেশন গ্র্যানুলারিটি বাড়ান</translation>
-<translation id="5999630716831179808">ভয়েসগুলি</translation>
-<translation id="6000417740266304866">নীচের তালিকা থেকে একটি বিকল্প নির্বাচন করে বর্তমান ৮ ডট ব্রেইল সারণিটি পরিবর্তন করুন।</translation>
-<translation id="6006050241733874051">রূপ</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{ব্যাকস্ল্যাশ}one{#টি ব্যাকস্ল্যাশ}other{#টি ব্যাকস্ল্যাশ}}</translation>
-<translation id="6037602951055904232">প্যান ফরোয়ার্ড</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">কক্ষের সমাপ্তি৷</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">ব্যবধান</translation>
-<translation id="6142308968191113180">শিরোলেখ ৪</translation>
-<translation id="6169420925157477918">দীর্ঘ বিবরণ সহ চিত্র</translation>
-<translation id="6172087735260766220">অনুলিপি-সুরক্ষিত PDF থেকে অ্যাক্সেসযোগ্য পাঠ্য অ্যাক্সেস করতে অক্ষম।</translation>
-<translation id="6186305613600865047">পৃষ্ঠাটির একেবারে নীচে চলে যান</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">নিচের</translation>
-<translation id="6236061028292614533">পরবর্তী শিরোনাম</translation>
-<translation id="6254901459154107917">পরবর্তী সম্পাদনার যোগ্য পাঠ্য অঞ্চল</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> থেকে প্রস্থান করা৷</translation>
-<translation id="6281876499889881039">পরবর্তী অনুরূপ উপাদান৷</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">কোনো পরবর্তী কম্বোবক্স ল্যান্ডমার্ক নেই৷</translation>
-<translation id="6307969636681130414">টেপা হয়েছে</translation>
-<translation id="6324551002951139333">ব্যকরণগত ত্রুটি সনাক্ত হয়েছে</translation>
-<translation id="6348657800373377022">কম্বো বাক্স</translation>
-<translation id="6355910664415701303">কোনো পূর্ববর্তী তালিকা আইটেম নেই৷</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">পূর্ববর্তী শিরোনাম</translation>
-<translation id="6387719785439924554">একপাশে</translation>
-<translation id="6411426777058107714">কোনো পূর্ববর্তী রেডিও বোতাম নেই৷</translation>
-<translation id="6414968628640960377">পূর্ববর্তী পৃথক উপাদান৷</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{কোলন}one{#টি কোলন}other{#টি কোলন}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, মেনু</translation>
-<translation id="6444046323172968959">সতর্কতা কথোপকথন</translation>
-<translation id="6459511626086141404">ফ্ল্যাট কীম্যাপ</translation>
-<translation id="6468049171101508116">পরবর্তী বোতাম</translation>
-<translation id="6491972999578897419">নিচের তালিকা থেকে একটি বিকল্প নির্বাচনের মাধ্যমে বর্তমান ভয়েসটি পরিবর্তন করুন৷</translation>
-<translation id="6508059270146105198">পৃষ্ঠার নীচের দিকে ব্রেইল প্রদর্শন সরান</translation>
-<translation id="6536864053412760904">গাণিতিক ML টোকেন</translation>
-<translation id="6550720799683018100">নিচের তালিকা থেকে একটি বিকল্প নির্বাচনের মাধ্যমে বর্তমান কীম্যাপটি পরিবর্তন করুন৷</translation>
-<translation id="6561818612645211875">বর্তমান সারির শুরুতে যান</translation>
-<translation id="6587021927234520429">কোনো পূর্ববর্তী স্তর ৪ শিরোনাম নেই৷</translation>
-<translation id="6601344353291556895">ভার্বোস বিবরণগুলি সক্ষম করুন৷</translation>
-<translation id="6615602925644411249">পৃষ্ঠায় খুঁজুন৷</translation>
-<translation id="6633350132811819843">কোনো পরবর্তী সারণী নেই৷</translation>
-<translation id="6637586476836377253">লগ</translation>
-<translation id="6657128831881431364">প্রগতি দণ্ড</translation>
-<translation id="6659594942844771486">ট্যাব</translation>
-<translation id="667999046851023355">দস্তাবেজ</translation>
-<translation id="6697092096875747123">পূর্ববর্তী কম্বো বাক্স</translation>
-<translation id="6714813999819678458">পূর্ববর্তী স্তর ২ শিরোনাম</translation>
-<translation id="6716505898850596801">সংশোধক কীগুলি</translation>
-<translation id="671916444866103745">কোনো পরবর্তী ARIA ল্যান্ডমার্ক নেই৷</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, কম্বো বাক্স</translation>
-<translation id="6735257939857578167"><ph name="NUM" />টি আইটেম সহ</translation>
-<translation id="6736510033526053669">ট্যাব তৈরি করা হয়েছে</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">নিবন্ধ</translation>
-<translation id="6787839852456839824">কীবোর্ড শর্টকাটগুলি</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">পাদলেখ</translation>
-<translation id="6871161210040114857">কেস সংবেদনশীলতা উপেক্ষা করছে।</translation>
-<translation id="6877435256196695200">কোনো পরবর্তী গ্রাফিক নেই৷</translation>
-<translation id="6897341342232909480">বামদিকে সরান</translation>
-<translation id="6901540140423170855">তারিখ</translation>
-<translation id="6910211073230771657">মোছা হয়েছে</translation>
-<translation id="6911965441508464308">উপরে কোনো কক্ষ নেই৷</translation>
-<translation id="6919104639734799681">সারণী তালিকা দেখান</translation>
-<translation id="6964088412282673743">এর পূর্বে কোনো নিয়ন্ত্রণ নেই৷</translation>
-<translation id="6996566555547746822">পরবর্তী কম্বো বাক্স</translation>
-<translation id="7005146664810010831">কোনো URL খুঁজে পাওয়া যায় নি</translation>
-<translation id="7010712454773919705">ChromeVox সংশোধক কী</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">পূর্ববর্তী তালিকা</translation>
-<translation id="7041173719775863268">নির্বাচন সমাপ্ত করুন</translation>
-<translation id="7095834689119144465">কেবল পাঠ্য সংখ্যা সম্পাদনা করুন</translation>
-<translation id="7096001299300236431">পূর্ববর্তী মিডিয়া</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">শব্দ ইকো</translation>
-<translation id="713824876195128146">পরবর্তী অবরুদ্ধ উদ্ধৃতি</translation>
-<translation id="7161771961008409533">পপ-আপ বোতাম</translation>
-<translation id="7167657087543110">অক্ষর ইকো</translation>
-<translation id="7170733337935166589">একটানা পড়ার সময় ছেড়ে আগে যান</translation>
-<translation id="7181697990050180700">ঘন ঘন ব্যবহৃত কমান্ডগুলির জন্য নীচে যথাযঠ ফিল্ডগুলির মধ্যে সেগুলিকে টাইপ করার মাধ্যেমে কীবোর্ড শর্টকাটগুলি কাস্টমাইজ করুন৷</translation>
-<translation id="7203150201908454328">প্রসারিত</translation>
-<translation id="7210211103303402262">মিনিট</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">লাইন</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">শিরোনাম</translation>
-<translation id="7241683698754534149">একটি নতুন ট্যাবে দীর্ঘ বিবরণ খুলুন</translation>
-<translation id="7248671827512403053">অ্যাপ্লিকেশান</translation>
-<translation id="725969808843520477">পরবর্তী রেডিও বোতাম</translation>
-<translation id="7269119382257320590">কোনো যতিচিহ্ন নেই</translation>
-<translation id="7273174640290488576">খালি</translation>
-<translation id="7285387653379749618">সারণীগুলি</translation>
-<translation id="7289186959554153431">শিরোনাম ৩</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">ব্রেইল আখ্যানগুলি অক্ষম করা হয়েছে৷</translation>
-<translation id="7318872822751139669">ফোকাস পরিবর্তনের জন্য মাউস ব্যবহার করুন৷</translation>
-<translation id="7322388933135261569">ফেব্রুয়ারী</translation>
-<translation id="7332592614823088566"><ph name="ROWTOTAL" /> এর <ph name="ROWINDEX" /> সারি, <ph name="COLTOTAL" /> এর <ph name="COLINDEX" /> কলাম</translation>
-<translation id="7336596009609913925">পপআপ রয়েছে</translation>
-<translation id="7356165926712028380">৮ ডট ব্রেইল-এ স্যুইচ করুন</translation>
-<translation id="7362871137496673139">কোনো পূর্ববর্তী স্তর ২ শিরোনাম নেই৷</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{অ্যামপারসেন্ট}one{#টি অ্যামপারসেন্ট}other{#টি অ্যামপারসেন্ট}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">সারণী ত্যাগ করছে৷</translation>
-<translation id="739763518212184081">পূর্ববর্তী লাইন</translation>
-<translation id="7400575256015741911">বানান পরীক্ষাগত ত্রুটি সনাক্ত হয়েছে</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">ফিরে যান</translation>
-<translation id="7434509671034404296">বিকাশকারী</translation>
-<translation id="7439060726180460871">সংকলন</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">ট্যাব</translation>
-<translation id="7492049978501397201">প্রবেশ করানো ডায়লগ</translation>
-<translation id="7532613204005497612">জুন</translation>
-<translation id="7540083713905917247"><ph name="VALUE" /> , <ph name="NAME" /> , স্লাইডার</translation>
-<translation id="7586163296341959563">আটকান৷</translation>
-<translation id="7596919493010894443">নির্বাচন সাফ করা হয়েছে</translation>
-<translation id="7604026522577407655">বর্তমান কলামের শুরুতে যান</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">বর্তমান পৃষ্ঠার URL ঘোষণা করুন</translation>
-<translation id="7609363189280667021">ব্রেইল পরিচয়লিপি টগল করুন</translation>
-<translation id="762020119231868829">বর্তমানে চলছে এমন সমস্ত মিডিয়া উইজেটকে বিরাম দেয়</translation>
-<translation id="7625690649919402823">পরবর্তী সারণী</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), গ্রেড <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">কোনো পূর্ববর্তী স্তর ৩ শিরোনাম নেই৷</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, পাঠ্য বাক্স</translation>
-<translation id="7663318257180412551">শিরোনাম ২</translation>
-<translation id="7674576868851035240">পরবর্তী লিঙ্ক</translation>
-<translation id="7674768236845044097">চিহ্নিত</translation>
-<translation id="7684431668231950609">URL এন্ট্রি, পাঠ্য সম্পাদনা করুন</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">পূর্ববর্তী রেডিও বোতাম</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, পাসওয়ার্ড পাঠ্য বাক্স</translation>
-<translation id="7805247615045262757">ডিফল্ট নেভিগেশন</translation>
-<translation id="7805768142964895445">স্থিতি</translation>
-<translation id="7810781339813764006">পরবর্তী গোষ্ঠী</translation>
-<translation id="7819187121850078213">উইন্ডো <ph name="TITLE" /> ট্যাব</translation>
-<translation id="7828956995407538686">অক্টোবর</translation>
-<translation id="7839679365527550018">পূর্ববর্তী শব্দ</translation>
-<translation id="7851816175263618915">কিছু যতিচিহ্ন</translation>
-<translation id="7870596830398826354">গাণিতিক ML ট্রী</translation>
-<translation id="78826985582142166">স্লাইডার</translation>
-<translation id="7894517696028036636">ChromeVox ক্লাসিক টগল করুন।</translation>
-<translation id="7895896691902835279">অজানা লিঙ্ক</translation>
-<translation id="7927711904086083099">নির্বাচিত নেই</translation>
-<translation id="7935627501098484003">সময় নিয়ন্ত্রণ</translation>
-<translation id="7939428177581522200">নির্বাচনে জোড়া হয়েছে</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{অ্যাট}one{#টি অ্যাট চিহ্ন}other{#টি অ্যাট চিহ্ন}}</translation>
-<translation id="7965147473449754028">মেনু বন্ধ হয়েছে</translation>
-<translation id="7974390230414479278">মেনু আইটেম</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{বিস্মযসূচক চিহ্ন}one{# exclamation points}other{# বিস্মযসূচক চিহ্ন}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{উদ্ধৃতি}one{#টি উদ্ধৃতি}other{# উদ্ধৃতি}}</translation>
-<translation id="8033827949643255796">নির্বাচিত</translation>
-<translation id="8035962149453661158">সর্বোচ্চ:<ph name="X" /></translation>
-<translation id="8042761080832772327">অনুসন্ধান এন্ট্রি, পাঠ্য সম্পাদনা করুন</translation>
-<translation id="8049189770492311300">টাইমার</translation>
-<translation id="8065607967589909823">নির্বাচনটি</translation>
-<translation id="8066678206530322333">ব্যানার</translation>
-<translation id="8110647606445335195">কোনো ARIA ল্যান্ডমার্ক নেই৷</translation>
-<translation id="8153880621934657047">সারণীর ভিতরে নয়৷</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{আন্ডারস্কোর}one{#টি আন্ডারস্কোর}other{#টি আন্ডারস্কোর}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">ছেদন৷</translation>
-<translation id="8199231515320852133">বর্তমান কক্ষের শিরোলেখ ঘোষণা করুন</translation>
-<translation id="820417203470636242">ফাঁকা কক্ষ৷</translation>
-<translation id="8215202828671303819">একাধিক নির্বাচন</translation>
-<translation id="8276439074553447000">পূর্ববর্তী ফোকাসযোগ্য আইটেমে জাম্প করুন</translation>
-<translation id="8278417001922463147">এর পূর্বে কোনো নিবন্ধ নেই৷</translation>
-<translation id="8283603667300770666">পরবর্তী ফর্ম ক্ষেত্র</translation>
-<translation id="831207808878314375">সংজ্ঞা</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">ঘন্টা</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{পাউন্ড}one{#টি পাউন্ড চিহ্ন}other{#টি পাউন্ড চিহ্ন}}</translation>
-<translation id="8374154622594089836">মাস</translation>
-<translation id="8378855320830505539">অঞ্চল</translation>
-<translation id="8382679411218029383">স্বতসম্পূর্ণ ইনলাইন এবং তালিকা</translation>
-<translation id="8428603554127842284">স্তর <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">কোনো পূর্ববর্তী স্তর ২ শিরোনাম নেই৷</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">কোনো পূর্ববর্তী চেকবাক্স নেই৷</translation>
-<translation id="8455868257606149352">সর্বোচ্চ <ph name="X" /></translation>
-<translation id="84575901236241018">অ্যাক্সেস কী আছে, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">নেভিগেশন কণিকাভাবটি কমান</translation>
-<translation id="8520472399088452386">ঘূর্ণন বোতাম</translation>
-<translation id="8538744478902126321">বর্তমান কক্ষের সারি শিরোলেখে একটি অনুমান করে</translation>
-<translation id="8540054775867439484">শীর্ষে সম্পৃক্ত রয়েছে</translation>
-<translation id="8548973727659841685">চরিত্র</translation>
-<translation id="8561322612995434619">পপ আপ রয়েছে</translation>
-<translation id="8571096049907249734">বহুনির্বাচন</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">পরবর্তী তালিকা আইটেম</translation>
-<translation id="860150890330522909"><ph name="NAME" /> চেকবাক্সে চেক করা হয়েছে</translation>
-<translation id="8606621670302093223">তারিখ নিয়ন্ত্রণ</translation>
-<translation id="8631359288236106450">নির্বাচিত <ph name="COUNT" />টি আইটেম</translation>
-<translation id="8638532244051952400">বর্তমান কক্ষ স্থানাঙ্কগুলি ঘোষণা করে</translation>
-<translation id="8650576015643545550">কোনো পূর্ববর্তী তালিকা নেই৷</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">লিঙ্কের তালিকাগুলি দেখান</translation>
-<translation id="8664519043722036194">সেকেন্ড</translation>
-<translation id="867187640362843212">শিরোনাম ৫</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{পাইপ}one{#টি উলম্ব পাইপ}other{#টি উলম্ব পাইপ}}</translation>
-<translation id="8735450637152821465">নির্বাচন শুরু করুন</translation>
-<translation id="8743786158317878347">সংগঠিত সামগ্রী লিখুন, যেমন সারণীগুলি</translation>
-<translation id="8747966237988593539">ক্রমযুক্ত তালিকা</translation>
-<translation id="8759334257841767240">কোনো পরবর্তী লিঙ্ক নেই৷</translation>
-<translation id="8767968232364267681">পরবর্তী স্তর ৪ শিরোনাম</translation>
-<translation id="8770473310765924354">সংগঠিত সামগ্রী বের করুন, যেমন সারণী</translation>
-<translation id="8791025954632646584">শব্দার্থিক চালু আছে</translation>
-<translation id="8796411681063377102">পরবর্তী স্তর ৩ শিরোনাম</translation>
-<translation id="8808582214901541005">মার্চ</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">প্রধান</translation>
-<translation id="8856538297388979332">আদেশগুলি পর্যালোচনা করতে উপরের বা নীচের দিকে টিপুন, সক্রিয় করতে এন্টার টিপুন</translation>
-<translation id="8864099967139188018">কোনো পূর্ববর্তী স্তর ৬শিরোনাম নেই৷</translation>
-<translation id="8882002077197914455">সারি শিরোলেখ</translation>
-<translation id="8896347895970027998">ChromeVox সক্রিয় অথবা নিষ্ক্রিয় করতে টগল করুন৷</translation>
-<translation id="8898516272131543774">আবর্ত যতিচিহ্ন ইকো</translation>
-<translation id="8900148057318340779">উপসর্গ কী</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">ফাঁকা শিরোলেখ</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">সংশোধক কী</translation>
-<translation id="8943175951035496220">ডানদিকে কোনো কক্ষ নেই৷</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">ফাইল...</translation>
-<translation id="9027462562263121875">কোনো সারণী নেই৷</translation>
-<translation id="9040132695316389094">শিরোনাম ১</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">অনুসন্ধান উইজেট টগল করুন</translation>
-<translation id="9065283790526219006">+পপআপ</translation>
-<translation id="9077213568694924680">নির্বাচন থেকে সরিয়ে ফেলা হয়েছে</translation>
-<translation id="9082874451376019682">কোনো পূর্ববর্তী স্লাইডার নেই৷</translation>
-<translation id="9089864840575085222">আবর্ত টাইপিং ইকো</translation>
-<translation id="9107530006868467849">কোনো পূর্ববর্তী মিডিয়া উইজেট নেই৷</translation>
-<translation id="9108370397979208512">গণিত</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{শতাংশ}one{#টি শতাংশ চিহ্ন}other{#টি শতাংশ চিহ্ন}}</translation>
-<translation id="9115913704608474258">নভেম্বর</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">বর্তমান অবস্থানটির একটি সংক্ষিপ্ত বিবরণ ঘোষণা করে</translation>
-<translation id="9153606228985488238">পিচ <ph name="PERCENT" /> শতাংশ</translation>
-<translation id="9160096769946561184">বর্তমান কলামের শেষে যান</translation>
-<translation id="9173115498289768110"><ph name="PERCENT" /> শতাংশ ভলিউম</translation>
-<translation id="9178973770513562274">ব্রাউজ করতে উপরের বা নীচের তীর চিহ্ন কী ব্যবহার করুন, বা অনুসন্ধান করতে টাইপ করুন৷</translation>
-<translation id="9192904702577636854">মার্কি</translation>
-<translation id="9212322457209634662">এরপরে কোনো বিভাগ নেই৷</translation>
-<translation id="930275611743429116">নির্বাচন সূচনা বা সমাপ্ত করুন৷</translation>
-<translation id="948171205378458592">স্পিচের হার কমান</translation>
-<translation id="962913030769097253">পরবর্তী স্তর ১ শিরোনাম</translation>
-<translation id="973955474346881951">স্টিকি মোড সক্ষম/অক্ষম করুন</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ca.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ca.xtb
deleted file mode 100644
index 67ff4408c5a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ca.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ca">
-<translation id="1012173283529841972">Element de la llista</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Amb abast.</translation>
-<translation id="1025074108959230262">S'ha desactivat el mode atractiu.</translation>
-<translation id="1031961866430398710">i, a continuació,</translation>
-<translation id="1044777062731150180">No hi ha capçaleres.</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Entrada no vàlida</translation>
-<translation id="1082209053475788238">No hi ha cap capçalera anterior del nivell 6.</translation>
-<translation id="1088219014394087294">No hi ha cap capçalera.</translation>
-<translation id="1106741348836243114">Activa o desactiva els sons (earcons).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="TAG" /> col·lecció amb <ph name="NUM" /> elements</translation>
-<translation id="1155043339247954670">No hi ha cap element de llista més.</translation>
-<translation id="1157782847298808853">Ajuda del teclat</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, quadre combinat</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, element de menú, amb submenú</translation>
-<translation id="1177863135347784049">Personalitzat</translation>
-<translation id="1188858454923323853">complementari</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox: dóna veu a Chrome</translation>
-<translation id="1229276918471378188">Salt anterior</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Capçalera del nivell 6 següent</translation>
-<translation id="1275718070701477396">Seleccionat</translation>
-<translation id="1319608975892113573">No hi ha cap cita en bloc anterior.</translation>
-<translation id="1321576897702511272">Amaga l'ajuda de ChromeVox.</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> de <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">retorn de caràcters i de paraules</translation>
-<translation id="1339428534620983148">Columna anterior de la taula</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">A la dreta</translation>
-<translation id="136718599399906424">Fila següent de la taula</translation>
-<translation id="1383876407941801731">Cerca</translation>
-<translation id="1385214448885562192">Premeu Retorn per acceptar o Esc per cancel·lar; fletxa avall per passar al següent i fletxa amunt per tornar a l'anterior.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">regió</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, quadre de text de contrasenya</translation>
-<translation id="1467432559032391204">A l'esquerra</translation>
-<translation id="1474557363159888097">No hi ha cap ancoratge anterior.</translation>
-<translation id="1502086903961450562">Gràfic anterior</translation>
-<translation id="1506187449813838456">Augmenta la presentació</translation>
-<translation id="151784044608172266">Frase següent</translation>
-<translation id="1524531499102321782">Va a la línia següent de Braille.</translation>
-<translation id="1546370775711804143">Barra de desplaçament</translation>
-<translation id="1559739829547075274">Navega cap enrere</translation>
-<translation id="1571643229714746283">Ja podeu utilitzar ChromeVox.</translation>
-<translation id="158493514907962286">Desembre</translation>
-<translation id="1594072653727561613">menú</translation>
-<translation id="1610130962244179598">Canvia a braille de sis punts</translation>
-<translation id="1611168825862729585">Capçalera de la columna:</translation>
-<translation id="1613476421962910979">Earcons activats</translation>
-<translation id="1618597272655350600">Anuncia una descripció completa de la posició actual.</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{major que}other{# símbols major que}}</translation>
-<translation id="1653266918374749391">Capçalera del nivell 3 anterior</translation>
-<translation id="1659072772017912254">No s'ha comprovat.</translation>
-<translation id="1669290819662866522">setmana</translation>
-<translation id="1674262202423278359">Navegació de ChromeVox</translation>
-<translation id="16777221443363124">Barra de menús</translation>
-<translation id="1692077714702418899">línia estructural</translation>
-<translation id="1700517974991662022">Visitat</translation>
-<translation id="1722567105086139392">Enllaç</translation>
-<translation id="1727806147743597030">peu</translation>
-<translation id="174268867904053074">Gràfic següent</translation>
-<translation id="1781173782405573156">Tecla de traspàs</translation>
-<translation id="1787176709638001873">Text d'edició de la contrasenya</translation>
-<translation id="1810107444790159527">Quadre de llista</translation>
-<translation id="1828385960365606039">Maig</translation>
-<translation id="1834891354138622109">Columna</translation>
-<translation id="1865601187525349519">Fi del text</translation>
-<translation id="1876229593313240038">document</translation>
-<translation id="188130072164734898">Diu en veu alta la data i l'hora actuals.</translation>
-<translation id="1902396333223336119">Cel·la</translation>
-<translation id="1905379170753160525">Mostra la llista de capçaleres.</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Control de la setmana de l'any</translation>
-<translation id="1964135212174907577">Objecte següent</translation>
-<translation id="1969092762068865084">Juliol</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Capçalera de la fila:</translation>
-<translation id="2002895034995108595">Restableix el mapa de teclat actual</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{claudàtor d'obertura}other{# claudàtors d'obertura}}</translation>
-<translation id="2045490512405922022">sense marcar</translation>
-<translation id="20601713649439366">No hi ha cap expressió matemàtica anterior.</translation>
-<translation id="207477615537953741">Semàntica desactivada</translation>
-<translation id="2086961585857038472">Paraula següent</translation>
-<translation id="2089387485033699258">ca</translation>
-<translation id="2091933974477985526">Àrea de text editable anterior</translation>
-<translation id="2100350898815792233">Tots els signes de puntuació</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">clau d'accés: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Per canviar la taula actual de braille de sis punts, seleccioneu una de les opcions de la llista que hi ha a continuació.</translation>
-<translation id="2169714232367507776">Feu clic a l'element actual.</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{parèntesi de tancament}other{# parèntesis de tancament}}</translation>
-<translation id="2199994615414171367">Expressió matemàtica anterior</translation>
-<translation id="2223693656926968778">Emprèn una acció sobre l'element actual</translation>
-<translation id="225732394367814946">Augmenta la velocitat de la veu.</translation>
-<translation id="2267945578749931355">Caràcter següent</translation>
-<translation id="2281234842553884450">Control lliscant anterior</translation>
-<translation id="2318372665160196757">Principal</translation>
-<translation id="2329324941084714723">Tauler de pestanya</translation>
-<translation id="2344193891939537199">Control de data i hora</translation>
-<translation id="2359897517538099099">No teniu activat el mode de taula.</translation>
-<translation id="241124561063364910">i, tot seguit,</translation>
-<translation id="2417569100218200841">Informació sobre el contingut</translation>
-<translation id="2422937916923936891">Casella de selecció de l'element de menú</translation>
-<translation id="2429669115401274487">p.m.</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> és ara la nova tecla modificadora de ChromeVox.</translation>
-<translation id="2450814015951372393">Casella de selecció</translation>
-<translation id="2462626033734746142">Grup de botons d'opció</translation>
-<translation id="2471138580042810658">Capçalera 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisc}other{# asteriscos}}</translation>
-<translation id="2549392850788122959">S'ha restablert <ph name="KEY" />.</translation>
-<translation id="2553108862507765288">error gramatical</translation>
-<translation id="257674075312929031">Grup</translation>
-<translation id="2582407057977008361">A part</translation>
-<translation id="2589102159832527089">Aquesta pàgina conté el text extret automàticament del fitxer PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Feu clic aquí per veure l'original.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">amb {COUNT,plural, =1{# element}other{# elements}}</translation>
-<translation id="2614981083756825552">Disseny de MathML</translation>
-<translation id="2626530649491650971">s'hi pot fer clic</translation>
-<translation id="2628764385451019380">No hi ha cap quadre combinat anterior.</translation>
-<translation id="2637227747952042642">Matemàtic</translation>
-<translation id="2639750663247012216">Tecla modificadora de ChromeVox</translation>
-<translation id="2644542693584024604">amb errors ortogràfics</translation>
-<translation id="2667291555398229137">Fa clic a l'element que hi ha a sota d'una tecla d'encaminament.</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{parèntesi d'obertura}other{# parèntesis d'obertura}}</translation>
-<translation id="2705875883745373140">Sense prémer.</translation>
-<translation id="2706462751667573066">Amunt</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">àudio</translation>
-<translation id="2732718972699418926">a.m.</translation>
-<translation id="2749275490991666823">Comprovat</translation>
-<translation id="27527859628328957">Salta al punt enfocable següent</translation>
-<translation id="2770781857296573485">Entra a l'exploració de grups</translation>
-<translation id="2777845298774924149">S'ha sortit</translation>
-<translation id="2800204403141299078">No hi ha més elements diferents.</translation>
-<translation id="2800780099804980316">No hi ha cap capçalera anterior del nivell 1.</translation>
-<translation id="2811204574343810641">Fila</translation>
-<translation id="2816654101880605877">No hi ha cap control lliscant més.</translation>
-<translation id="2841013758207633010">Hora</translation>
-<translation id="2843837985843789981">Grup anterior</translation>
-<translation id="2844995807198708617">Menú contextual</translation>
-<translation id="2849332794118375855">No hi ha cap casella de selecció més.</translation>
-<translation id="2864481629947106776">Enllaç anterior</translation>
-<translation id="2873259058405069099">Vés al principi de la taula</translation>
-<translation id="2894654529758326923">Informació</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{clau d'obertura}other{# claus d'obertura}}</translation>
-<translation id="2911433807131383493">Obre el tutorial de ChromeVox</translation>
-<translation id="2932083475399492303">Commuta el tipus de línia entre estructural o disseny.</translation>
-<translation id="2964026537669811554">Grup de capçalera</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulació}other{# tabulacions}}</translation>
-<translation id="2972078295414139404">No hi ha cap enllaç visitat anterior.</translation>
-<translation id="2972205263822847197">Descripció emergent</translation>
-<translation id="2998131015536248178">Caràcter anterior</translation>
-<translation id="2999559350546931576">Disminueix la presentació.</translation>
-<translation id="2999945368667127852">No hi ha cap widget multimèdia a continuació.</translation>
-<translation id="3012414509011670858">No hi ha cap secció anterior.</translation>
-<translation id="3030432017085518523">Botó d'opció de l'element del menú</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apòstrof}other{# apòstrofs}}</translation>
-<translation id="3046838483509668188">Opcions de ChromeVox</translation>
-<translation id="3047143736589213134">Teclat experimental</translation>
-<translation id="3060756054951570867">S'ha obert el menú <ph name="TITLE" />.</translation>
-<translation id="3078345202707391975">Capçalera del nivell 2 següent</translation>
-<translation id="3078740164268491126">taula</translation>
-<translation id="3082557070674409251">S'hi ha fet clic.</translation>
-<translation id="3084806535845658316">sense retorn d'escriptura</translation>
-<translation id="3086746722712840547">nota</translation>
-<translation id="308895241372589742">No hi ha cap expressió matemàtica següent.</translation>
-<translation id="3090532668523289635">grup</translation>
-<translation id="3093176084511590672">Punt de referència següent</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">diàleg d'alerta</translation>
-<translation id="3109724472072898302">Reduït</translation>
-<translation id="3134461040845705080">només de lectura</translation>
-<translation id="3138767756593758860">Mostra la llista de punts de referència.</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Línia següent</translation>
-<translation id="3155083529632865074">No hi ha cap botó anterior.</translation>
-<translation id="3163593631834463955">La capçalera de la columna és buida.</translation>
-<translation id="316542773973815724">Navegació</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{espai}other{# espais}}</translation>
-<translation id="320961988183078793">s'ha introduït <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, pestanya</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Enllaç visitat</translation>
-<translation id="323731244387692321">Obre l'ajuda del teclat ChromeVox</translation>
-<translation id="3241052487511142956">Enllaç visitat anterior</translation>
-<translation id="3286390186030710347">Control lliscant</translation>
-<translation id="3299925995433437805">No hi ha cap enllaç visitat següent.</translation>
-<translation id="3303384412438961941">Premeu qualsevol tecla per saber-ne el nom. Ctrl + W tanca l'explorador del teclat.</translation>
-<translation id="3307886118343381874">Vés al final de la taula</translation>
-<translation id="3311969765485641742">Premeu Alt + Maj + A per revisar les alertes.</translation>
-<translation id="3312997241656799641">Enllaç visitat següent</translation>
-<translation id="3321460131042519426">Activa l'ajust de la paraula a la línia</translation>
-<translation id="3322936298410871309">Capçalera del nivell 1 anterior</translation>
-<translation id="3323447499041942178">Quadre de text</translation>
-<translation id="3353420241558113817">{"ar": "Àrab",
- "bg": "Búlgar",
- "ca": "Català",
- "cs": "Txec",
- "da": "Danès",
- "de": "Alemany",
- "de_CH": "Alemany (Suïssa)",
- "de_DE": "Alemany (Alemanya)",
- "el": "Grec",
- "en": "Anglès",
- "en_CA": "Anglès (Canadà)",
- "en_GB": "Anglès (Regne Unit)",
- "en_US": "Anglès (Estats Units)",
- "es": "Espanyol",
- "et": "Estonià",
- "fr": "Francès",
- "fr_CA": "Francès (Canadà)",
- "fr_FR": "Francès (França)",
- "fi": "Finès",
- "he": "Hebreu",
- "hi": "Hindi",
- "hr": "Croata",
- "hu": "Hongarès",
- "is": "Islandès",
- "it": "Italià",
- "ko": "Coreà",
- "lt": "Lituà",
- "lv": "Letó",
- "nb": "Noruec Bokmål",
- "nl": "Neerlandès",
- "pl": "Polonès",
- "pt": "Portuguès",
- "ro": "Romanès",
- "ru": "Rus",
- "sk": "Eslovac",
- "sl": "Eslovè",
- "sr": "Serbi",
- "sv": "Suec",
- "tr": "Turc",
- "vi": "Vietnamita",
- "zh": "Xinès",
- "zh_TW": "Xinès (han tradicional)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{més}other{# signes més}}</translation>
-<translation id="338583716107319301">Separador</translation>
-<translation id="3389259863310851658">Camp del formulari anterior</translation>
-<translation id="3390225400784126843">Element diferent següent</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, element de menú</translation>
-<translation id="3406283310380167331">Mostra la llista de formularis.</translation>
-<translation id="3422338090358345848">Obre l'explorador del teclat.</translation>
-<translation id="3457000393508828486">S'ha premut parcialment.</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, botó</translation>
-<translation id="3473644018603298796">control lliscant <ph name="COUNT" /></translation>
-<translation id="3486232535569802404">De <ph name="V1" /> a <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{claudàtor de tancament}other{# claudàtors de tancament}}</translation>
-<translation id="3493915602752813531">No hi ha cap ancoratge més.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{signe d'interrogació}other{# signes d'interrogació}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{accent circumflex}other{# accents circumflexos}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, casella de selecció no activada</translation>
-<translation id="3599054940393788245">No sou dins de math.</translation>
-<translation id="3616113530831147358">Àudio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{accent agut}other{# accents aguts}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dòlar}other{# símbols de dòlar}}</translation>
-<translation id="3659787053479271466">alerta</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, quadre de llista</translation>
-<translation id="3687295507293856493">Fa una suposició a la capçalera de la columna de la cel·la actual.</translation>
-<translation id="3692274950075847560">C: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Control de veu</translation>
-<translation id="3716845769494773620">Diverses línies</translation>
-<translation id="3731746171184829332">No hi ha cap capçalera anterior.</translation>
-<translation id="3762198587642264450">Va al final de la fila actual.</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">S'ha sortit del diàleg.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Llista de compleció automàtica</translation>
-<translation id="3810838688059735925">Vídeo</translation>
-<translation id="3816633764618089385">Fitxer multimèdia següent</translation>
-<translation id="3819376190738087562">No hi ha cap salt.</translation>
-<translation id="385383972552776628">Obre la pàgina d'opcions</translation>
-<translation id="3856075812838139784">Només de lectura</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menú</translation>
-<translation id="3909320334364316587">Capçalera del nivell 6 anterior</translation>
-<translation id="3914173277599553213">Obligatori</translation>
-<translation id="3962990492275676168">Inicia la lectura des de la ubicació actual.</translation>
-<translation id="4004802134384979325">marcada</translation>
-<translation id="4006140876663370126">imatge</translation>
-<translation id="4038349100599457191">Control de mes</translation>
-<translation id="4039983576244166038">La capçalera de la fila és buida.</translation>
-<translation id="4042843249978639960">No hi ha cap capçalera més del nivell 2.</translation>
-<translation id="4043348641337972076">No hi ha cap punt de referència ARIA anterior.</translation>
-<translation id="4047216625641135770">Marca</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">estat</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{accent}other{# accents}}</translation>
-<translation id="409334809956508737">Objecte anterior</translation>
-<translation id="4099274309791143834">amb submenú</translation>
-<translation id="4107807507418787238">No hi ha cap cel·la a sota.</translation>
-<translation id="4116415223832267137">Alerta</translation>
-<translation id="4147126331795725888">No hi ha cap control següent.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{clau de tancament}other{# claus de tancament}}</translation>
-<translation id="4158704014418536539">Es distingeix entre majúscules i minúscules.</translation>
-<translation id="4161663686871496107">Ja podeu utilitzar els comentaris de veu de ChromeVox.</translation>
-<translation id="4173994908659439270">No hi ha cap més camp de text que es pugui editar.</translation>
-<translation id="4176463684765177261">Desactivat</translation>
-<translation id="4188530942454211480">Frase anterior</translation>
-<translation id="4202186506458631436">Desplaça a la dreta.</translation>
-<translation id="4206289001967551965">Dins la taula</translation>
-<translation id="4215733775853809057">Control lliscant següent</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{guió}other{# guions}}</translation>
-<translation id="421884353938374759">selector de color</translation>
-<translation id="4229646983878045487">data i hora</translation>
-<translation id="423334822609210999">No hi ha cap cel·la a l'esquerra.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, grau <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Nota</translation>
-<translation id="4254798249533888099">Arbre</translation>
-<translation id="4255943572433203166">Utilitzeu les opcions següents per personalitzar ChromeVox. Els canvis tenen efecte immediatament.</translation>
-<translation id="4271220233568730077">Expressió matemàtica següent</translation>
-<translation id="4271521365602459209">No hi ha cap més resultat.</translation>
-<translation id="4287520460805643128">No hi ha cap article més.</translation>
-<translation id="4289540628985791613">Descripció general</translation>
-<translation id="4300318234632215983">Presenta l'URL darrere d'un enllaç.</translation>
-<translation id="4301352596632316575">té un submenú</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punt}=3{punts suspensius}other{# punts}}</translation>
-<translation id="4347461890115250064">No hi ha cap més llista.</translation>
-<translation id="4367650418938037324">Full de MathML</translation>
-<translation id="4372435075475052704">mín.: <ph name="X" /></translation>
-<translation id="4372705107434148843">Atura la veu</translation>
-<translation id="4373197658375206385">No hi ha cap element anterior que no sigui un enllaç.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">restableix</translation>
-<translation id="4471074325120394300">No hi ha cap enllaç.</translation>
-<translation id="4476183483923481720">línia nova</translation>
-<translation id="4482330759234983253">Taula anterior</translation>
-<translation id="4491109536499578614">Imatge</translation>
-<translation id="4529987814483543472">Mapa de teclat clàssic</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{barra inclinada}other{# barres inclinades}}</translation>
-<translation id="4547556996012970016">Capçalera del nivell 5 següent</translation>
-<translation id="4562381607973973258">Capçalera</translation>
-<translation id="4591507479202817876">, seleccionat</translation>
-<translation id="4597532268155981612">formulari</translation>
-<translation id="4597896406374528575">Abril</translation>
-<translation id="4615592953348396470">S'ignorarà la propera tecla que premeu.</translation>
-<translation id="461613135510474570">Frase</translation>
-<translation id="4647836961514597010">Selector de color</translation>
-<translation id="4661075872484491155">arbre</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">graella</translation>
-<translation id="4693675773662933727">Punt de referència anterior</translation>
-<translation id="4696413482802371445">No hi ha cap capçalera més del nivell 5.</translation>
-<translation id="4729095194763193578">Fila anterior de la taula</translation>
-<translation id="4736221692378411923">Agost</translation>
-<translation id="4740661827607246557">Ordres d'ajuda</translation>
-<translation id="4759716709594980008">Explorador del teclat de Chrome OS</translation>
-<translation id="4763296182459741068">Ajustat a la part inferior</translation>
-<translation id="4763480195061959176">vídeo</translation>
-<translation id="479989351350248267">cerca</translation>
-<translation id="481165870889056555">Presenta el títol de la pàgina actual</translation>
-<translation id="4826415162591436065">Navega cap endavant.</translation>
-<translation id="4826604887384865800">Salt següent</translation>
-<translation id="4827410568042294688">no seleccionat</translation>
-<translation id="4842108708071771135">No hi ha cap cita en bloc més.</translation>
-<translation id="4848993367330139335">cronòmetre</translation>
-<translation id="4850023505158945298">Element similar anterior.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Activa el registre TTS</translation>
-<translation id="4877261390094455813">Introduïu una consulta de cerca.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Enllaç intern</translation>
-<translation id="4953585991029886728">Edita el text</translation>
-<translation id="4954534434583049121">Cita de bloqueig anterior</translation>
-<translation id="4973717656530883744">Mín. <ph name="X" /></translation>
-<translation id="4973762002207131920">S'ha canviat a <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">mil·lisegons</translation>
-<translation id="49787999531187221">ChromeVox està inactiu.</translation>
-<translation id="4979404613699303341">Botó anterior</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, quadre de llista</translation>
-<translation id="4983588134362688868">Va a la part superior de la pàgina.</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, finestra</translation>
-<translation id="4993152509206108683">Taxa d'un <ph name="PERCENT" /> per cent</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, botó d'opció seleccionat</translation>
-<translation id="4997475792277222884">No hi ha cap element més que no sigui un enllaç.</translation>
-<translation id="5000760171916499057">No hi ha cap formulari.</translation>
-<translation id="5005670136041063723">No hi ha més elements similars.</translation>
-<translation id="501473567976723023">Gener</translation>
-<translation id="5041394372352067729">Mou la pantalla Braille a la part superior de la pàgina.</translation>
-<translation id="5042770794184672516">Augmenta el volum de la veu.</translation>
-<translation id="5050015258024679800">Capçalera del nivell 4 anterior</translation>
-<translation id="5054047268577924192">Element de la llista anterior</translation>
-<translation id="5078661581131202757">Selecció de fitxer</translation>
-<translation id="5080758118274074384">s'hi ha fet doble clic.</translation>
-<translation id="5098541983634824365">S'està sortint de la quadrícula.</translation>
-<translation id="5102981729317424850">Barra d'eines</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">No hi ha cap camp de formulari anterior.</translation>
-<translation id="5111640677200759579">Capçalera de la columna</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">No hi ha cap enllaç anterior.</translation>
-<translation id="513774504516943387">enllaç</translation>
-<translation id="517143700877085897">, no seleccionat</translation>
-<translation id="5183440668879371625">Va a la línia anterior de Braille.</translation>
-<translation id="5184944171021383281">No hi ha cap camp de formulari més.</translation>
-<translation id="5189244881767082992">Línia</translation>
-<translation id="5203930734796605961">La tecla <ph name="KEY" /> ja està assignada a una ordre.</translation>
-<translation id="5205493599117157272">Llista de: <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">No hi ha cap botó d'opció més.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Fi</translation>
-<translation id="5291783959063340370">Objecte</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, pestanya</translation>
-<translation id="5310788376443009632">s'ha suprimit:</translation>
-<translation id="5320727453979144100">S'ha activat el mode atractiu.</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{coma}other{# comes}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, quadre de text</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, enllaç</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Retrocedeix durant la lectura contínua</translation>
-<translation id="5368000168321181111">Earcons desactivats</translation>
-<translation id="5374320867641260420">No hi ha cap botó més.</translation>
-<translation id="5382299583965267720">No hi ha cap capçalera més del nivell 1.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{punt i coma}other{# punts i coma}}</translation>
-<translation id="5411891038905756502">No hi ha cap punt de salt anterior.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{menor que}other{# símbols menor que}}</translation>
-<translation id="5455441614648621694">Complementari</translation>
-<translation id="5485036206801896268">No hi ha cap gràfic anterior.</translation>
-<translation id="5486947920110100234">No hi ha cap punt de salt més.</translation>
-<translation id="549602578321198708">Paraula</translation>
-<translation id="5500932716852106146">No hi ha cap camp de text anterior que es pugui editar.</translation>
-<translation id="5502713021410870035">Setembre</translation>
-<translation id="5507663321906818013">Depura la referència.</translation>
-<translation id="5518443085409638729">Situa el cursor entre caràcters en editar un text (com a Mac OS X)</translation>
-<translation id="552195134157544755">Botó d'opció</translation>
-<translation id="5534303576632885660">capçalera</translation>
-<translation id="5546092960038624944">No hi ha cap capçalera anterior del nivell 5.</translation>
-<translation id="556042886152191864">Botó</translation>
-<translation id="5561345396546889625">Llista següent</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Retrocés</translation>
-<translation id="5585044216466955529">Edició de text, entrada de correu electrònic</translation>
-<translation id="5597170376237141345">Casella de selecció següent</translation>
-<translation id="5597933780944041114">No hi ha cap capçalera més.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, botó d'opció no seleccionat</translation>
-<translation id="5601172225407283979">Duu a terme l'acció predeterminada.</translation>
-<translation id="5608798115546226984">Compleció automàtica en línia</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Registre</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">No hi ha cap taula anterior.</translation>
-<translation id="5655682562155942719">Ordres de desplaçament</translation>
-<translation id="56637627897541303">Àrea de text</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">definició</translation>
-<translation id="5682113568322255809">Punt de referència</translation>
-<translation id="5683155931978483559">Casella de selecció anterior</translation>
-<translation id="5684277895745049190">Llista</translation>
-<translation id="5700650669149824506">No hi ha cap capçalera anterior del nivell 4.</translation>
-<translation id="5709192780268610569">No hi ha cap descripció llarga.</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Columna següent de la taula</translation>
-<translation id="571866080859340309">S'estan explorant els grups.</translation>
-<translation id="5728409797179002635">No s'ha trobat cap taula.</translation>
-<translation id="5748623122140342504">Capçalera del nivell 5 anterior</translation>
-<translation id="5750633686117194034">No s'ha premut cap tecla modificadora; manteniu premuda una o més tecles modificadores, deixeu anar quan hàgiu acabat i sentireu com es configuren les tecles. Premeu la tecla de tabulació per sortir.</translation>
-<translation id="5788275253279308023">pestanya <ph name="TITLE" /> de la finestra d'incògnit</translation>
-<translation id="5806206155699461681">Millora llocs determinats (com ara Cerca de Google)</translation>
-<translation id="5819072574982403430">Element d'arbre</translation>
-<translation id="5826479389509458994">fila <ph name="ROW" />, columna <ph name="COL" /></translation>
-<translation id="5850707923114094062">Es desplaça cap enrere.</translation>
-<translation id="5851548754964597211">Llista de pestanyes</translation>
-<translation id="5859752971144398932">S'ha sortit de la cerca a la pàgina.</translation>
-<translation id="5866042630553435010">Comprovat parcialment</translation>
-<translation id="5869546221129391014">Quadrícula</translation>
-<translation id="5876817486144482042">Redueix el volum de la veu.</translation>
-<translation id="5887397643266327462">Subtítols en braille activats.</translation>
-<translation id="5891934789323004067">Taula</translation>
-<translation id="5919442531159595654">copia.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{signe igual}other{# signes igual}}</translation>
-<translation id="5939518447894949180">Restableix</translation>
-<translation id="5948123859135882163">Canvia la interpretació de les expressions matemàtiques, entre estructural i semàntica.</translation>
-<translation id="5955304353782037793">aplicació</translation>
-<translation id="5956928062748260866">Diàleg</translation>
-<translation id="5963413905009737549">Secció</translation>
-<translation id="5968607524793740041">Mostra el menú contextual</translation>
-<translation id="5983179082906765664">Augmenta la granularitat de la navegació</translation>
-<translation id="5999630716831179808">Veus</translation>
-<translation id="6000417740266304866">Per canviar la taula actual de braille de vuit punts, seleccioneu una de les opcions de la llista que hi ha a continuació.</translation>
-<translation id="6006050241733874051">Formulari</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{barra invertida}other{# barres invertides}}</translation>
-<translation id="6037602951055904232">Desplaça cap endavant.</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Fi de la cel·la.</translation>
-<translation id="6122013438240733403">botó</translation>
-<translation id="6129953537138746214">Espai</translation>
-<translation id="6142308968191113180">Capçalera 4</translation>
-<translation id="6169420925157477918">Imatge amb descripció llarga</translation>
-<translation id="6172087735260766220">No es pot accedir a text accessible des d'un PDF protegit contra còpia.</translation>
-<translation id="6186305613600865047">Vés a la part inferior de la pàgina.</translation>
-<translation id="6193330012414963395">a. m./p. m.</translation>
-<translation id="622484624075952240">Avall</translation>
-<translation id="6236061028292614533">Capçalera següent</translation>
-<translation id="6254901459154107917">Àrea de text editable següent</translation>
-<translation id="6259464875943891919">S'ha sortit de <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Element similar següent</translation>
-<translation id="6282062888058716985">navegació</translation>
-<translation id="6290434000785343030">No hi ha cap quadre combinat més.</translation>
-<translation id="6307969636681130414">Premut</translation>
-<translation id="6324551002951139333">S'ha detectat un error gramatical.</translation>
-<translation id="6348657800373377022">Quadre de combinacions</translation>
-<translation id="6355910664415701303">No hi ha cap element de llista anterior.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Capçalera anterior</translation>
-<translation id="6387719785439924554">complement</translation>
-<translation id="6411426777058107714">No hi ha cap botó d'opció anterior.</translation>
-<translation id="6414968628640960377">Element diferent anterior.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dos punts}other{# dos punts}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menú</translation>
-<translation id="6444046323172968959">Diàleg d'alerta</translation>
-<translation id="6459511626086141404">Mapa de teclat pla</translation>
-<translation id="6468049171101508116">Botó següent</translation>
-<translation id="6491972999578897419">Podeu canviar la veu actual si seleccioneu una opció de la llista següent.</translation>
-<translation id="6508059270146105198">Mou la pantalla Braille a la part inferior de la pàgina.</translation>
-<translation id="6536864053412760904">Testimoni de MathML</translation>
-<translation id="6550720799683018100">Per canviar el mapa de teclat actual, seleccioneu una opció de la llista següent.</translation>
-<translation id="6561818612645211875">Vés al principi de la fila actual</translation>
-<translation id="6587021927234520429">No hi ha cap capçalera més del nivell 4.</translation>
-<translation id="6601344353291556895">Activa les descripcions detallades</translation>
-<translation id="6615602925644411249">Cerqueu a la pàgina.</translation>
-<translation id="6633350132811819843">No hi ha cap taula més.</translation>
-<translation id="6637586476836377253">registre</translation>
-<translation id="6657128831881431364">Barra de progrés</translation>
-<translation id="6659594942844771486">Pestanya</translation>
-<translation id="667999046851023355">Document</translation>
-<translation id="6697092096875747123">Quadre combinat anterior</translation>
-<translation id="6714813999819678458">Capçalera del nivell 2 anterior</translation>
-<translation id="6716505898850596801">Tecles de modificació</translation>
-<translation id="671916444866103745">No hi ha cap punt de referència ARIA més.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, quadre combinat</translation>
-<translation id="6735257939857578167">amb <ph name="NUM" /> elements</translation>
-<translation id="6736510033526053669">S'ha creat una pestanya.</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Article</translation>
-<translation id="6787839852456839824">Tecles de drecera</translation>
-<translation id="6793101435925451627">quadre de llista</translation>
-<translation id="6833103209700200188">Peu</translation>
-<translation id="6871161210040114857">No es distingeix entre majúscula i minúscula.</translation>
-<translation id="6877435256196695200">No hi ha cap gràfic més.</translation>
-<translation id="6897341342232909480">Desplaça a l'esquerra</translation>
-<translation id="6901540140423170855">data</translation>
-<translation id="6910211073230771657">Suprimit</translation>
-<translation id="6911965441508464308">No hi ha cap cel·la més amunt.</translation>
-<translation id="6919104639734799681">Mostra la llista de taules</translation>
-<translation id="6964088412282673743">No hi ha cap control anterior.</translation>
-<translation id="6996566555547746822">Quadre combinat següent</translation>
-<translation id="7005146664810010831">No s'ha trobat cap URL.</translation>
-<translation id="7010712454773919705">Tecla modificadora de ChromeVox</translation>
-<translation id="7031651751836475482">element llista</translation>
-<translation id="7037042857287298941">Llista anterior</translation>
-<translation id="7041173719775863268">Final de la selecció</translation>
-<translation id="7095834689119144465">Edita només text numèric</translation>
-<translation id="7096001299300236431">Fitxer multimèdia anterior</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">retorn de paraules</translation>
-<translation id="713824876195128146">Cita de bloc següent</translation>
-<translation id="7161771961008409533">Botó emergent</translation>
-<translation id="7167657087543110">retorn de caràcters</translation>
-<translation id="7170733337935166589">Avança durant la lectura contínua</translation>
-<translation id="7181697990050180700">Per personalitzar les tecles de drecera per a ordres utilitzades amb freqüència, escriviu-les als camps corresponents següents.</translation>
-<translation id="7203150201908454328">Ampliat</translation>
-<translation id="7210211103303402262">minuts</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">línia</translation>
-<translation id="7226216518520804442">llista</translation>
-<translation id="72393384879519786">Capçalera</translation>
-<translation id="7241683698754534149">Obre la descripció llarga en una pestanya nova.</translation>
-<translation id="7248671827512403053">Aplicació</translation>
-<translation id="725969808843520477">Botó d'opció següent</translation>
-<translation id="7269119382257320590">Sense cap signe de puntuació.</translation>
-<translation id="7273174640290488576">En blanc</translation>
-<translation id="7285387653379749618">Taules</translation>
-<translation id="7289186959554153431">Capçalera 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Subtítols en braille desactivats.</translation>
-<translation id="7318872822751139669">Utilitza el ratolí per canviar el focus.</translation>
-<translation id="7322388933135261569">Febrer</translation>
-<translation id="7332592614823088566">Fila <ph name="ROWINDEX" /> de <ph name="ROWTOTAL" />, columna <ph name="COLINDEX" /> de <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">té un element emergent</translation>
-<translation id="7356165926712028380">Canvia a braille de vuit punts.</translation>
-<translation id="7362871137496673139">No hi ha cap capçalera anterior del nivell 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{signe &amp;}other{# signes &amp;}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">S'està sortint de la taula.</translation>
-<translation id="739763518212184081">Línia anterior</translation>
-<translation id="7400575256015741911">S'ha detectat un error ortogràfic.</translation>
-<translation id="7408482676469142474">taula</translation>
-<translation id="7425395583360211003">retorn</translation>
-<translation id="7434509671034404296">Desenvolupador</translation>
-<translation id="7439060726180460871">Directori</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">pestanya</translation>
-<translation id="7492049978501397201">Diàleg introduït</translation>
-<translation id="7532613204005497612">Juny</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, control lliscant</translation>
-<translation id="7586163296341959563">enganxa.</translation>
-<translation id="7596919493010894443">S'ha esborrat la selecció.</translation>
-<translation id="7604026522577407655">Vés al principi de la columna actual</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Presenta l'URL de la pàgina actual.</translation>
-<translation id="7609363189280667021">Activa els subtítols en braille.</translation>
-<translation id="762020119231868829">Posa en pausa tots els widgets multimèdia que s'estiguin reproduint actualment.</translation>
-<translation id="7625690649919402823">Taula següent</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), de grau <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">No hi ha cap capçalera anterior del nivell 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, quadre de text</translation>
-<translation id="7663318257180412551">Capçalera 2</translation>
-<translation id="7674576868851035240">Enllaç següent</translation>
-<translation id="7674768236845044097">marca</translation>
-<translation id="7684431668231950609">Edició de text, entrada d'URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Botó d'opció anterior</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, quadre de text de la contrasenya</translation>
-<translation id="7805247615045262757">navegació predeterminada</translation>
-<translation id="7805768142964895445">Estat</translation>
-<translation id="7810781339813764006">Grup següent</translation>
-<translation id="7819187121850078213">pestanya <ph name="TITLE" /> de finestra</translation>
-<translation id="7828956995407538686">Octubre</translation>
-<translation id="7839679365527550018">Paraula anterior</translation>
-<translation id="7851816175263618915">Alguns signes de puntuació</translation>
-<translation id="7870596830398826354">Arbre de MathML</translation>
-<translation id="78826985582142166">control lliscant</translation>
-<translation id="7894517696028036636">Activa la versió clàssica de ChromeVox.</translation>
-<translation id="7895896691902835279">Enllaç desconegut</translation>
-<translation id="7927711904086083099">Sense seleccionar</translation>
-<translation id="7935627501098484003">Control de temps</translation>
-<translation id="7939428177581522200">s'ha afegit a la selecció</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{arrova}other{# símbols d'arrova}}</translation>
-<translation id="7965147473449754028">heu tancat el menú</translation>
-<translation id="7974390230414479278">Element del menú</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{signe d'admiració}other{# signes d'admiració}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{cometes}other{# cometes}}</translation>
-<translation id="8033827949643255796">seleccionats</translation>
-<translation id="8035962149453661158">màx.: <ph name="X" /></translation>
-<translation id="8042761080832772327">Edició de text, entrada de cerca</translation>
-<translation id="8049189770492311300">Temporitzador</translation>
-<translation id="8065607967589909823">La selecció és</translation>
-<translation id="8066678206530322333">Bàner</translation>
-<translation id="8110647606445335195">No hi ha cap punt de referència ARIA.</translation>
-<translation id="8153880621934657047">No sou dins la taula.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{ratlla baixa}other{# ratlles baixes}}</translation>
-<translation id="8179976553408161302">Retorn</translation>
-<translation id="81960742267269908">retalla</translation>
-<translation id="8199231515320852133">Presenta les capçaleres de la cel·la actual.</translation>
-<translation id="820417203470636242">Cel·la buida</translation>
-<translation id="8215202828671303819">Selecció múltiple</translation>
-<translation id="8276439074553447000">Vés a l'element enfocable anterior</translation>
-<translation id="8278417001922463147">No hi ha cap article anterior.</translation>
-<translation id="8283603667300770666">Camp de formulari següent</translation>
-<translation id="831207808878314375">Definició</translation>
-<translation id="8313653172105209786">directori</translation>
-<translation id="8344569602005188545">hores</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{lliura}other{# símbols de lliura}}</translation>
-<translation id="8374154622594089836">mes</translation>
-<translation id="8378855320830505539">Regió</translation>
-<translation id="8382679411218029383">Compleció automàtica en línia i llista</translation>
-<translation id="8428603554127842284">nivell <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">No hi ha cap capçalera més del nivell 3.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">No hi ha cap casella de selecció anterior.</translation>
-<translation id="8455868257606149352">Màx.: <ph name="X" /></translation>
-<translation id="84575901236241018">té una tecla d'accés, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Disminueix la granularitat de la navegació.</translation>
-<translation id="8520472399088452386">Botó de selecció de valors</translation>
-<translation id="8538744478902126321">Fes una suposició a la capçalera de la fila de la cel·la actual</translation>
-<translation id="8540054775867439484">Ajustat a la part superior</translation>
-<translation id="8548973727659841685">Caràcter</translation>
-<translation id="8561322612995434619">té una finestra emergent</translation>
-<translation id="8571096049907249734">selmult</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Element de llista següent</translation>
-<translation id="860150890330522909">S'ha marcat la casella de selecció <ph name="NAME" />.</translation>
-<translation id="8606621670302093223">Control de data</translation>
-<translation id="8631359288236106450">S'han seleccionat <ph name="COUNT" /> elements.</translation>
-<translation id="8638532244051952400">Anuncia les coordenades de la cel·la actual</translation>
-<translation id="8650576015643545550">No hi ha cap llista anterior.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Mostra la llista d'enllaços.</translation>
-<translation id="8664519043722036194">segons</translation>
-<translation id="867187640362843212">Capçalera 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{barra}other{# barres verticals}}</translation>
-<translation id="8735450637152821465">Inici de la selecció</translation>
-<translation id="8743786158317878347">entra al contingut estructurat, com ara les taules</translation>
-<translation id="8747966237988593539">Llista ordenada</translation>
-<translation id="8759334257841767240">No hi ha cap més enllaç.</translation>
-<translation id="8767968232364267681">Capçalera del nivell 4 següent</translation>
-<translation id="8770473310765924354">surt del contingut estructurat, com ara les taules</translation>
-<translation id="8791025954632646584">Semàntica activada</translation>
-<translation id="8796411681063377102">Capçalera del nivell 3 següent</translation>
-<translation id="8808582214901541005">Març</translation>
-<translation id="8825828890761629845">bàner</translation>
-<translation id="8851136666856101339">principal</translation>
-<translation id="8856538297388979332">Premeu la tecla cap amunt o cap avall per revisar les ordres o bé premeu retorn per activar.</translation>
-<translation id="8864099967139188018">No hi ha cap capçalera més del nivell 6.</translation>
-<translation id="8882002077197914455">Capçalera de fila</translation>
-<translation id="8896347895970027998">Activa o desactiva ChromeVox.</translation>
-<translation id="8898516272131543774">Retorn de la puntuació del cicle.</translation>
-<translation id="8900148057318340779">Tecla de prefix</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Capçaleres buides</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Tecles modificadores</translation>
-<translation id="8943175951035496220">No hi ha cap cel·la a la dreta.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">fitxer</translation>
-<translation id="9027462562263121875">No hi ha cap taula.</translation>
-<translation id="9040132695316389094">Capçalera 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Canvia el widget de la cerca.</translation>
-<translation id="9065283790526219006">+element emergent</translation>
-<translation id="9077213568694924680">s'ha suprimit de la selecció.</translation>
-<translation id="9082874451376019682">No hi ha cap control lliscant anterior.</translation>
-<translation id="9089864840575085222">Retorn de l'escriptura del cicle</translation>
-<translation id="9107530006868467849">No hi ha cap widget multimèdia anterior.</translation>
-<translation id="9108370397979208512">matemàtiques</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{percentatge}other{# símbols de percentatge}}</translation>
-<translation id="9115913704608474258">Novembre</translation>
-<translation id="9128414153595658330">diàleg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Anuncia una breu descripció de la posició actual.</translation>
-<translation id="9153606228985488238">Presenta un <ph name="PERCENT" /> per cent</translation>
-<translation id="9160096769946561184">Vés al final de la columna actual.</translation>
-<translation id="9173115498289768110">Volum del <ph name="PERCENT" /> per cent</translation>
-<translation id="9178973770513562274">Utilitzeu les tecles de fletxa amunt o avall per navegar, o bé escriviu per cercar.</translation>
-<translation id="9192904702577636854">Marquesina</translation>
-<translation id="9212322457209634662">No hi ha cap secció més.</translation>
-<translation id="930275611743429116">Inicia o finalitza la selecció.</translation>
-<translation id="948171205378458592">Disminueix la velocitat de la veu.</translation>
-<translation id="962913030769097253">Capçalera del nivell 1 següent</translation>
-<translation id="973955474346881951">Activa/desactiva el mode atractiu</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_cs.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_cs.xtb
deleted file mode 100644
index 479df9e9aab..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_cs.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="cs">
-<translation id="1012173283529841972">Položka seznamu</translation>
-<translation id="1013742170491673792">upr vyhl</translation>
-<translation id="1023866615269196768">Sloučeno.</translation>
-<translation id="1025074108959230262">Režim Jedním prstem je vypnut</translation>
-<translation id="1031961866430398710">a pak</translation>
-<translation id="1044777062731150180">Bez záhlaví</translation>
-<translation id="106222400312645156">záhl řádku</translation>
-<translation id="1065552602950927991">Neplatný vstup</translation>
-<translation id="1082209053475788238">Žádný předchozí nadpis 6. úrovně.</translation>
-<translation id="1088219014394087294">Žádné nadpisy.</translation>
-<translation id="1106741348836243114">Zapnout nebo vypnout zvukové signály.</translation>
-<translation id="1120743664840974483">{"a": "adam", "á": "dlouhé a", "b": "božena", "c": "cyril", "č": "čeněk", "d": "david", "ď": "ďáblice", "e": "emil", "ě": "e s háčkem", "é": "dlouhé e", "f": "františek", "g": "gustav", "h": "helena", "ch": "chrudim", "i": "ivan", "í": "dlouhé měkké i", "j": "josef", "k": "karel", "l": "ludvík", "m": "marie", "n": "neruda", "ň": "nina", "o": "otakar", "ó": "dlouhé o", "p": "petr", "q": "quido", "r": "rudolf", "ř": "řehoř", "s": "svatopluk", "š": "šimon", "t": "tomáš", "ť": "těšnov", "u": "urban", "ů": "u s kroužkem", "ú": "u s čárkou", "v": "václav", "w": "dvojité v", "x": "xaver", "y": "ypsilon", "ý": "dlouhé tvrdé y", "z": "zuzana", "ž": "žofie"}</translation>
-<translation id="113582498867142724">Sbírka <ph name="TAG" /> s <ph name="NUM" /> položkami</translation>
-<translation id="1155043339247954670">Žádná další položka seznamu.</translation>
-<translation id="1157782847298808853">Nápověda klávesnice</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, rozbalovací seznam</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, položka nabídky s podnabídkou</translation>
-<translation id="1177863135347784049">Vlastní</translation>
-<translation id="1188858454923323853">doplňkové</translation>
-<translation id="1206619573307042055">běžící text</translation>
-<translation id="1213216066620407844">ChromeVox – hlas Chromu</translation>
-<translation id="1229276918471378188">Předchozí skok</translation>
-<translation id="1237866625126425153">skup přep</translation>
-<translation id="1251750620252348585">Další nadpis 6. úrovně</translation>
-<translation id="1275718070701477396">Vybráno</translation>
-<translation id="1319608975892113573">Žádná předchozí bloková citace.</translation>
-<translation id="1321576897702511272">Skrýt nápovědu programu ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> z <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">vyslovovat znaky a slova</translation>
-<translation id="1339428534620983148">Předchozí sloupec tabulky</translation>
-<translation id="1342835525016946179">čl</translation>
-<translation id="1346748346194534595">Doprava</translation>
-<translation id="136718599399906424">Další řádek tabulky</translation>
-<translation id="1383876407941801731">Vyhledávání</translation>
-<translation id="1385214448885562192">Klávesou Enter položku přijmete, klávesou Esc zrušíte akci, šipkou dolů přejdete na další položku a šipkou nahoru na předchozí položku.</translation>
-<translation id="1396114365388024581">seznam karet</translation>
-<translation id="1439316808600711881">region</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, textové pole pro heslo</translation>
-<translation id="1467432559032391204">Doleva</translation>
-<translation id="1474557363159888097">Žádné předchozí ukotvení.</translation>
-<translation id="1502086903961450562">Předchozí obrázek</translation>
-<translation id="1506187449813838456">Zvýšit výšku hlasu</translation>
-<translation id="151784044608172266">Další věta</translation>
-<translation id="1524531499102321782">Braille – další řádek</translation>
-<translation id="1546370775711804143">Posuvník</translation>
-<translation id="1559739829547075274">Zpět</translation>
-<translation id="1571643229714746283">Služba ChromeVox je připravena</translation>
-<translation id="158493514907962286">Prosinec</translation>
-<translation id="1594072653727561613">nabíd</translation>
-<translation id="1610130962244179598">Přepnout na šestibodové Braillovo písmo</translation>
-<translation id="1611168825862729585">Záhlaví sloupce:</translation>
-<translation id="1613476421962910979">Zvukové signály zapnuty</translation>
-<translation id="1618597272655350600">Oznamuje úplný popis současné pozice</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{je větší než}few{# znaky je větší než}many{# greater than signs}other{# znaků je větší než}}</translation>
-<translation id="1653266918374749391">Předchozí nadpis 3. úrovně</translation>
-<translation id="1659072772017912254">Není zaškrtnuto</translation>
-<translation id="1669290819662866522">týden</translation>
-<translation id="1674262202423278359">Navigace ChromeVox</translation>
-<translation id="16777221443363124">Panel nabídek</translation>
-<translation id="1692077714702418899">řádek struktury</translation>
-<translation id="1700517974991662022">Navštíveno</translation>
-<translation id="1722567105086139392">Odkaz</translation>
-<translation id="1727806147743597030">zápatí</translation>
-<translation id="174268867904053074">Další obrázek</translation>
-<translation id="1781173782405573156">Klávesa průchodu</translation>
-<translation id="1787176709638001873">Úprava hesla – text</translation>
-<translation id="1810107444790159527">Seznam</translation>
-<translation id="1828385960365606039">Květen</translation>
-<translation id="1834891354138622109">Sloupec</translation>
-<translation id="1865601187525349519">Konec textu</translation>
-<translation id="1876229593313240038">dok</translation>
-<translation id="188130072164734898">Přečíst aktuální datum a čas</translation>
-<translation id="1902396333223336119">Buňka</translation>
-<translation id="1905379170753160525">Zobrazit seznam nadpisů</translation>
-<translation id="1912556590115083156">navšt odkaz</translation>
-<translation id="1913761808037590218">upr číslo</translation>
-<translation id="1954623340234317532">Ovládací prvek – týden v roce</translation>
-<translation id="1964135212174907577">Další objekt</translation>
-<translation id="1969092762068865084">Červenec</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Záhlaví řádku:</translation>
-<translation id="2002895034995108595">Resetovat aktuální mapu kláves</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{levá hranatá závorka}few{# levé hranaté závorky}many{# left brackets}other{# levých hranatých závorek}}</translation>
-<translation id="2045490512405922022">nezaškrtnuto</translation>
-<translation id="20601713649439366">Žádný předchozí matematický výraz není.</translation>
-<translation id="207477615537953741">Sémantika je vypnuta</translation>
-<translation id="2086961585857038472">Další slovo</translation>
-<translation id="2089387485033699258">cs</translation>
-<translation id="2091933974477985526">Předchozí upravitelná textová oblast</translation>
-<translation id="2100350898815792233">Veškerá interpunkce</translation>
-<translation id="2119965627982867824">číselník</translation>
-<translation id="2121067395472282800">přístupový klíč:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Změnit aktuální tabulku šestibodového Braillova písma na možnost ze seznamu níže.</translation>
-<translation id="2169714232367507776">Kliknout na aktuální položku</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{pravá závorka}few{# pravé závorky}many{# close parens}other{# pravých závorek}}</translation>
-<translation id="2199994615414171367">Předchozí matematický objekt</translation>
-<translation id="2223693656926968778">Provést akci s aktuální položkou</translation>
-<translation id="225732394367814946">Zvýšit rychlost řeči</translation>
-<translation id="2267945578749931355">Další znak</translation>
-<translation id="2281234842553884450">Předchozí posuvník</translation>
-<translation id="2318372665160196757">Hlavní</translation>
-<translation id="2329324941084714723">Panel karty</translation>
-<translation id="2344193891939537199">Ovládací prvek času a data</translation>
-<translation id="2359897517538099099">Nejste v režimu tabulky.</translation>
-<translation id="241124561063364910">a nakonec</translation>
-<translation id="2417569100218200841">Informace o obsahu</translation>
-<translation id="2422937916923936891">Položka nabídky – zaškrtávací políčko</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> je nyní nový modifikátor funkce ChromeVox.</translation>
-<translation id="2450814015951372393">Zaškrtávací políčko</translation>
-<translation id="2462626033734746142">Skupina přepínačů</translation>
-<translation id="2471138580042810658">Nadpis 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{hvězdička}few{# hvězdičky}many{# asterisks}other{# hvězdiček}}</translation>
-<translation id="2549392850788122959">Klávesa <ph name="KEY" /> byla resetována.</translation>
-<translation id="2553108862507765288">pravopisná chyba</translation>
-<translation id="257674075312929031">Skupina</translation>
-<translation id="2582407057977008361">Stranou</translation>
-<translation id="2589102159832527089">Tato stránka obsahuje text extrahovaný automaticky ze souboru PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Kliknutím sem zobrazíte původní soubor.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">s {COUNT,plural, =1{# položkou}few{# položkami}many{# položky}other{# položkami}}</translation>
-<translation id="2614981083756825552">Rozvržení MathML</translation>
-<translation id="2626530649491650971">klikatelné</translation>
-<translation id="2628764385451019380">Žádné předchozí pole se seznamem.</translation>
-<translation id="2637227747952042642">Math</translation>
-<translation id="2639750663247012216">Modifikační klávesa ChromeVox</translation>
-<translation id="2644542693584024604">překlep</translation>
-<translation id="2667291555398229137">Klikněte na položku pod navigační klávesou</translation>
-<translation id="2697408785920771974">auto přímo</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{levá závorka}few{# levé závorky}many{# open parens}other{# levých závorek}}</translation>
-<translation id="2705875883745373140">Nestisknuto</translation>
-<translation id="2706462751667573066">Nahoru</translation>
-<translation id="2717271541250958000">panel karet</translation>
-<translation id="2723001399770238859">zvuk</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Zaškrtnuto</translation>
-<translation id="27527859628328957">Přejít na další zaměřitelnou položku</translation>
-<translation id="2770781857296573485">Zahájit průzkum skupin</translation>
-<translation id="2777845298774924149">Ukončeno</translation>
-<translation id="2800204403141299078">Žádné další odlišné prvky.</translation>
-<translation id="2800780099804980316">Žádný předchozí nadpis 1. úrovně.</translation>
-<translation id="2811204574343810641">Řádek</translation>
-<translation id="2816654101880605877">Žádný další posuvník</translation>
-<translation id="2841013758207633010">Čas</translation>
-<translation id="2843837985843789981">Předchozí skupina</translation>
-<translation id="2844995807198708617">Kontextová nabídka</translation>
-<translation id="2849332794118375855">Žádné další zaškrtávací políčko.</translation>
-<translation id="2864481629947106776">Předchozí odkaz</translation>
-<translation id="2873259058405069099">Přejít na začátek tabulky</translation>
-<translation id="2894654529758326923">Informace</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{levá složená závorka}few{# levé složené závorky}many{# left braces}other{# levých složených závorek}}</translation>
-<translation id="2911433807131383493">Otevřít výukový program funkce ChromeVox</translation>
-<translation id="2932083475399492303">Přepnout typ řádku mezi strukturou a rozložením</translation>
-<translation id="2964026537669811554">Skupina nadpisů</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulátor}few{# tabulátory}many{# tabs}other{# tabulátorů}}</translation>
-<translation id="2972078295414139404">Žádný předchozí navštívený odkaz není.</translation>
-<translation id="2972205263822847197">Popisek</translation>
-<translation id="2998131015536248178">Předchozí znak</translation>
-<translation id="2999559350546931576">Snížit výšku hlasu</translation>
-<translation id="2999945368667127852">Žádný další mediální widget není k dispozici.</translation>
-<translation id="3012414509011670858">Žádná předchozí sekce není.</translation>
-<translation id="3030432017085518523">Položka nabídky – přepínač</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}few{# apostrofy}many{# apostrophes}other{# apostrofů}}</translation>
-<translation id="3046838483509668188">Možnosti programu ChromeVox</translation>
-<translation id="3047143736589213134">Experimentální mapa kláves</translation>
-<translation id="3060756054951570867">otevřena nabídka <ph name="TITLE" /></translation>
-<translation id="3078345202707391975">Další nadpis 2. úrovně</translation>
-<translation id="3078740164268491126">tabulka</translation>
-<translation id="3082557070674409251">Kliknuto</translation>
-<translation id="3084806535845658316">nevyslovovat psaný text</translation>
-<translation id="3086746722712840547">pozn</translation>
-<translation id="308895241372589742">Žádný další matematický výraz není.</translation>
-<translation id="3090532668523289635">skup</translation>
-<translation id="3093176084511590672">Další orientační bod</translation>
-<translation id="3096671415663099226">pole se sezn</translation>
-<translation id="3104705064753753826">dialog upoz</translation>
-<translation id="3109724472072898302">Sbaleno</translation>
-<translation id="3134461040845705080">pouze ke čtení</translation>
-<translation id="3138767756593758860">Zobrazit seznam orientačních bodů</translation>
-<translation id="3143851963874289911">buňka</translation>
-<translation id="3149472044574196936">Další řádek</translation>
-<translation id="3155083529632865074">Žádné předchozí tlačítko.</translation>
-<translation id="3163593631834463955">Prázdné záhlaví sloupce</translation>
-<translation id="316542773973815724">Navigace</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{mezera}few{# mezery}many{# spaces}other{# mezer}}</translation>
-<translation id="320961988183078793">zadá: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, karta</translation>
-<translation id="3226035351387556942">zaškrt pol</translation>
-<translation id="3229375994964697375">Navštívený odkaz</translation>
-<translation id="323731244387692321">Otevřít nápovědu klávesnice ChromeVox</translation>
-<translation id="3241052487511142956">Předchozí navštívený odkaz</translation>
-<translation id="3286390186030710347">Posuvník</translation>
-<translation id="3299925995433437805">Žádný další navštívený odkaz není.</translation>
-<translation id="3303384412438961941">Po stisknutí libovolné klávesy se dozvíte její název. Kombinací kláves Ctrl+W průzkumníka klávesnice ukončíte.</translation>
-<translation id="3307886118343381874">Přejít na konec tabulky</translation>
-<translation id="3311969765485641742">Chcete-li upozornění zkontrolovat, stiskněte klávesy Alt+Shift+A</translation>
-<translation id="3312997241656799641">Další navštívený odkaz</translation>
-<translation id="3321460131042519426">Povolit zalamování slov</translation>
-<translation id="3322936298410871309">Předchozí nadpis 1. úrovně</translation>
-<translation id="3323447499041942178">Textové pole</translation>
-<translation id="3353420241558113817">{"ar": "arabština",
-"bg": "bulharština",
-"ca": "katalánština",
-"cs": "čeština",
-"da": "dánština",
-"de": "němčina",
-"de_CH": "němčina (Švýcarsko)",
-"de_DE": "němčina (Německo)",
-"el": "řečtina",
-"en": "angličtina",
-"en_CA": "angličtina (Kanada)",
-"en_GB": "angličtina (Velká Británie)",
-"en_US": "angličtina (USA)",
-"es": "španělština",
-"et": "estonština",
-"fr": "francouzština",
-"fr_CA": "francouzština (Kanada)",
-"fr_FR": "francouzština (Francie)",
-"fi": "finština",
-"he": "hebrejština",
-"hi": "hindština",
-"hr": "chorvatština",
-"hu": "maďarština",
-"is": "islandština",
-"it": "italština",
-"ko": "korejština",
-"lt": "litevština",
-"lv": "lotyština",
-"nb": "norština (bokmål)",
-"nl": "nizozemština",
-"pl": "polština",
-"pt": "portugalština",
-"ro": "rumunština",
-"ru": "ruština",
-"sk": "slovenština",
-"sl": "slovinština",
-"sr": "srbština",
-"sv": "švédština",
-"tr": "turečtina",
-"vi": "vietnamština",
-"zh": "čínština",
-"zh_TW": "čínština (tradiční)"}</translation>
-<translation id="3359142382821736686">oddělovač</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plus}few{# znaky plus}many{# plus signs}other{# znaků plus}}</translation>
-<translation id="338583716107319301">Oddělovač</translation>
-<translation id="3389259863310851658">Předchozí pole formuláře</translation>
-<translation id="3390225400784126843">Další jiný prvek</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, položka nabídky</translation>
-<translation id="3406283310380167331">Zobrazit seznam formulářů</translation>
-<translation id="3422338090358345848">Otevřít průzkumníka klávesnice</translation>
-<translation id="3457000393508828486">Částečně stisknuto</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, tlačítko</translation>
-<translation id="3473644018603298796">vybr <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> až <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{pravá hranatá závorka}few{# pravé hranaté závorky}many{# right brackets}other{# pravých hranatých závorek}}</translation>
-<translation id="3493915602752813531">Žádné další ukotvení.</translation>
-<translation id="3494946239022273294">pol nabíd</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{otazník}few{# otazníky}many{# question marks}other{# otazníků}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{stříška}few{# stříšky}many{# carets}other{# stříšek}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, zaškrtávací políčko není zaškrtnuto</translation>
-<translation id="3599054940393788245">Nejedná se o matematiku</translation>
-<translation id="3616113530831147358">Zvuk</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{zpětná uvozovka}few{# zpětné uvozovky}many{# backticks}other{# zpětných uvozovek}}</translation>
-<translation id="3650317109285159359">zaškrt pol nabíd</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolar}few{# znaky dolar}many{# dollar signs}other{# znaků dolar}}</translation>
-<translation id="3659787053479271466">upoz</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, seznam</translation>
-<translation id="3687295507293856493">Odhadnout záhlaví sloupce aktuální buňky</translation>
-<translation id="3692274950075847560">V:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Ovládání řeči</translation>
-<translation id="3716845769494773620">Víceřádkový</translation>
-<translation id="3731746171184829332">Žádný předchozí nadpis.</translation>
-<translation id="3762198587642264450">Přejít na konec aktuálního řádku</translation>
-<translation id="3777255250339039212">nadp 1</translation>
-<translation id="3793710123303304873">Opustili jste dialog.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}few{#}many{#}other{#}}</translation>
-<translation id="3801735343383419236">Seznam automatického doplňování</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Další mediální objekt</translation>
-<translation id="3819376190738087562">Žádné skoky.</translation>
-<translation id="385383972552776628">Otevřít stránku možností</translation>
-<translation id="3856075812838139784">Pouze ke čtení</translation>
-<translation id="3887576927692165210">upr</translation>
-<translation id="3897092660631435901">Nabídka</translation>
-<translation id="3909320334364316587">Předchozí nadpis 6. úrovně</translation>
-<translation id="3914173277599553213">Vyžadováno</translation>
-<translation id="3962990492275676168">Začít číst z aktuálního místa</translation>
-<translation id="4004802134384979325">zaškrtnuto</translation>
-<translation id="4006140876663370126">obr</translation>
-<translation id="4038349100599457191">Ovládací prvek – měsíc</translation>
-<translation id="4039983576244166038">Prázdné záhlaví řádku</translation>
-<translation id="4042843249978639960">Žádný další nadpis 2. úrovně.</translation>
-<translation id="4043348641337972076">Žádný předchozí orientační bod ARIA.</translation>
-<translation id="4047216625641135770">Zvýraznění</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">stav</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDA}few{# tildy}many{# tildes}other{# tild}}</translation>
-<translation id="409334809956508737">Předchozí objekt</translation>
-<translation id="4099274309791143834">s podnabídkou</translation>
-<translation id="4107807507418787238">Dole není žádná buňka.</translation>
-<translation id="4116415223832267137">Upozornění</translation>
-<translation id="4147126331795725888">Žádný další ovládací prvek není.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{pravá složená závorka}few{# pravé složené závorky}many{# right braces}other{# pravých složených závorek}}</translation>
-<translation id="4158704014418536539">Rozlišují se velká a malá písmena.</translation>
-<translation id="4161663686871496107">Hlasová odezva ChromeVox je připravena</translation>
-<translation id="4173994908659439270">Žádné další upravitelné textové pole.</translation>
-<translation id="4176463684765177261">Deaktivováno</translation>
-<translation id="4188530942454211480">Předchozí věta</translation>
-<translation id="4202186506458631436">Posunout doprava</translation>
-<translation id="4206289001967551965">V tabulce</translation>
-<translation id="4215733775853809057">Další posuvník</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{spojovník}few{# spojovníky}many{# dashes}other{# spojovníků}}</translation>
-<translation id="421884353938374759">výběr barev</translation>
-<translation id="4229646983878045487">datum a čas</translation>
-<translation id="423334822609210999">Vlevo není žádná buňka.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, podoba: <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Poznámka</translation>
-<translation id="4254798249533888099">Strom</translation>
-<translation id="4255943572433203166">Pomocí možností níže si program ChromeVox můžete přizpůsobit. Změny se projeví okamžitě.</translation>
-<translation id="4271220233568730077">Další matematický objekt</translation>
-<translation id="4271521365602459209">Žádné další výsledky.</translation>
-<translation id="4287520460805643128">Žádný další článek.</translation>
-<translation id="4289540628985791613">Přehled</translation>
-<translation id="4300318234632215983">Oznámit adresu URL za odkazem</translation>
-<translation id="4301352596632316575">má podnabídku</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{tečka}=3{trojtečka}few{# tečky}many{# dots}other{# teček}}</translation>
-<translation id="4347461890115250064">Žádný další seznam.</translation>
-<translation id="4367650418938037324">List MathML</translation>
-<translation id="4372435075475052704">min: <ph name="X" /></translation>
-<translation id="4372705107434148843">Zastavit řeč</translation>
-<translation id="4373197658375206385">Žádná předchozí položka, která není odkaz.</translation>
-<translation id="4391478986194775161">info o obsahu</translation>
-<translation id="443163561286008705">resetovat</translation>
-<translation id="4471074325120394300">Žádné odkazy.</translation>
-<translation id="4476183483923481720">nový řádek</translation>
-<translation id="4482330759234983253">Předchozí tabulka</translation>
-<translation id="4491109536499578614">Obrázek</translation>
-<translation id="4529987814483543472">Klasická mapa kláves</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{lomítko}few{# lomítka}many{# slashes}other{# lomítek}}</translation>
-<translation id="4547556996012970016">Další nadpis 5. úrovně</translation>
-<translation id="4562381607973973258">Nadpis</translation>
-<translation id="4591507479202817876">, vybráno</translation>
-<translation id="4597532268155981612">formulář</translation>
-<translation id="4597896406374528575">Duben</translation>
-<translation id="4615592953348396470">Další stisknutí klávesy bude ignorováno</translation>
-<translation id="461613135510474570">Věta</translation>
-<translation id="4647836961514597010">Výběr barev</translation>
-<translation id="4661075872484491155">strom</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">mřížka</translation>
-<translation id="4693675773662933727">Předchozí orientační bod</translation>
-<translation id="4696413482802371445">Žádný další nadpis 5. úrovně.</translation>
-<translation id="4729095194763193578">Předchozí řádek tabulky</translation>
-<translation id="4736221692378411923">Srpen</translation>
-<translation id="4740661827607246557">Příkazy nápovědy</translation>
-<translation id="4759716709594980008">Průzkumník klávesnice systému ChromeOS</translation>
-<translation id="4763296182459741068">Skok na konec</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Oznámit název aktuální stránky</translation>
-<translation id="4826415162591436065">Přejít dopředu</translation>
-<translation id="4826604887384865800">Další skok</translation>
-<translation id="4827410568042294688">nevybráno</translation>
-<translation id="4842108708071771135">Žádná další bloková citace.</translation>
-<translation id="4848993367330139335">časovač</translation>
-<translation id="4850023505158945298">Předchozí podobný prvek.</translation>
-<translation id="4866956062845190338">přep pol nabíd</translation>
-<translation id="4867316986324544967">Povolit protokolování TTS</translation>
-<translation id="4877261390094455813">Zadejte vyhledávací dotaz.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Interní odkaz</translation>
-<translation id="4953585991029886728">Upravit text</translation>
-<translation id="4954534434583049121">Předchozí blok citace</translation>
-<translation id="4973717656530883744">Min <ph name="X" /></translation>
-<translation id="4973762002207131920">Přepnuto na klávesu <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">ms</translation>
-<translation id="49787999531187221">ChromeVox je nyní neaktivní.</translation>
-<translation id="4979404613699303341">Předchozí tlačítko</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, seznam</translation>
-<translation id="4983588134362688868">Přejít na začátek stránky</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, okno</translation>
-<translation id="4993152509206108683">Rychlost <ph name="PERCENT" /> procent</translation>
-<translation id="4996716799442435517">Vizuální oblast</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, přepínač je vybrán</translation>
-<translation id="4997475792277222884">Žádná další položka, která není odkaz.</translation>
-<translation id="5000760171916499057">Žádné formuláře.</translation>
-<translation id="5005670136041063723">Žádné další podobné prvky.</translation>
-<translation id="501473567976723023">Leden</translation>
-<translation id="5041394372352067729">Přesunout zobrazení Braillova písma na začátek stránky</translation>
-<translation id="5042770794184672516">Zvýšit hlasitost řeči</translation>
-<translation id="5050015258024679800">Předchozí nadpis 4. úrovně</translation>
-<translation id="5054047268577924192">Předchozí položka v seznamu</translation>
-<translation id="5078661581131202757">Výběr souboru</translation>
-<translation id="5080758118274074384">dvakrát kliknuto</translation>
-<translation id="5098541983634824365">Opouští se mřížka.</translation>
-<translation id="5102981729317424850">Panel nástrojů</translation>
-<translation id="5105050547967751155">požad</translation>
-<translation id="5110983769041734144">Žádné předchozí pole formuláře.</translation>
-<translation id="5111640677200759579">Záhlaví sloupce</translation>
-<translation id="5117636609870536415">upr email</translation>
-<translation id="5136967254288895616">Žádný předchozí odkaz.</translation>
-<translation id="513774504516943387">odk.</translation>
-<translation id="517143700877085897">, nevybráno</translation>
-<translation id="5183440668879371625">Braille – předchozí řádek</translation>
-<translation id="5184944171021383281">Žádné další pole formuláře.</translation>
-<translation id="5189244881767082992">Řádek</translation>
-<translation id="5203930734796605961">Klávesa <ph name="KEY" /> je již k příkazu přiřazena.</translation>
-<translation id="5205493599117157272">Seznam: <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Žádný další přepínač.</translation>
-<translation id="5263344797180442561">nadp 2</translation>
-<translation id="528468243742722775">Klávesa End</translation>
-<translation id="5291783959063340370">Objekt</translation>
-<translation id="5304943142864553931">karta <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">odebráno:</translation>
-<translation id="5320727453979144100">Režim Jedním prstem je zapnut</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{čárka}few{# čárky}many{# commas}other{# čárek}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, textové pole</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, odkaz</translation>
-<translation id="5336381510091010269">auto přímo+sezn</translation>
-<translation id="536031132345979795">Přejít zpět při nepřetržitém čtení</translation>
-<translation id="5368000168321181111">Zvukové signály vypnuty</translation>
-<translation id="5374320867641260420">Žádné další tlačítko.</translation>
-<translation id="5382299583965267720">Žádný další nadpis 1. úrovně.</translation>
-<translation id="5402367795255837559">Braillovo písmo</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{středník}few{# středníky}many{# semicolons}other{# středníků}}</translation>
-<translation id="5411891038905756502">Žádný předchozí bod skoku.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{je menší než}few{# znaky je menší než}many{# less than signs}other{# znaků je menší než}}</translation>
-<translation id="5455441614648621694">Doplňkové</translation>
-<translation id="5485036206801896268">Žádný předchozí obrázek.</translation>
-<translation id="5486947920110100234">Žádný další bod skoku.</translation>
-<translation id="549602578321198708">Slovo</translation>
-<translation id="5500932716852106146">Žádné předchozí upravitelné textové pole.</translation>
-<translation id="5502713021410870035">Září</translation>
-<translation id="5507663321906818013">Ukazatel ladění</translation>
-<translation id="5518443085409638729">Při úpravě textu kurzor umístit mezi znaky (jako v systému Mac OS X).</translation>
-<translation id="552195134157544755">Přepínač</translation>
-<translation id="5534303576632885660">nadpis</translation>
-<translation id="5546092960038624944">Žádný předchozí nadpis 5. úrovně.</translation>
-<translation id="556042886152191864">Tlačítko</translation>
-<translation id="5561345396546889625">Další seznam</translation>
-<translation id="5562645715554321347">skup nadp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Úprava textu, e-mail</translation>
-<translation id="5597170376237141345">Další zaškrtávací políčko</translation>
-<translation id="5597933780944041114">Žádný další nadpis.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, přepínač není vybrán</translation>
-<translation id="5601172225407283979">Provést výchozí akci</translation>
-<translation id="5608798115546226984">Přímé automatické doplňování</translation>
-<translation id="561939826962581046">čas</translation>
-<translation id="5623778242535476823">přep</translation>
-<translation id="5623842676595125836">Protokol</translation>
-<translation id="5628125749885014029">nadp 4</translation>
-<translation id="5637871198229500030">Žádná předchozí tabulka.</translation>
-<translation id="5655682562155942719">Přeskakovací příkazy</translation>
-<translation id="56637627897541303">Textová oblast</translation>
-<translation id="5678161956734658133">upr více řádků</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Orientační bod</translation>
-<translation id="5683155931978483559">Předchozí zaškrtávací políčko</translation>
-<translation id="5684277895745049190">Seznam</translation>
-<translation id="5700650669149824506">Žádný předchozí nadpis 4. úrovně.</translation>
-<translation id="5709192780268610569">Žádný dlouhý popis</translation>
-<translation id="5712244464475377681">vyskak tlač</translation>
-<translation id="5712338278108304766">Další sloupec tabulky</translation>
-<translation id="571866080859340309">Průzkum skupin</translation>
-<translation id="5728409797179002635">Nebyla nalezena žádná tabulka.</translation>
-<translation id="5748623122140342504">Předchozí nadpis 5. úrovně</translation>
-<translation id="5750633686117194034">Nestiskli jste žádný modifikátor. Stiskněte a podržte jeden nebo více modifikátorů. Po dokončení zvedněte prsty. Uslyšíte, které klávesy byly nastaveny. Klávesou Tabulátor tuto akci ukončíte.</translation>
-<translation id="5788275253279308023">anonymní okno, karta <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Vylepšení konkrétních webů (například Vyhledávání Google)</translation>
-<translation id="5819072574982403430">Položka stromu</translation>
-<translation id="5826479389509458994">řádek <ph name="ROW" /> sloupec <ph name="COL" /></translation>
-<translation id="5850707923114094062">Posunout zpět</translation>
-<translation id="5851548754964597211">Seznam karet</translation>
-<translation id="5859752971144398932">Vyhledávání na stránce ukončeno.</translation>
-<translation id="5866042630553435010">Částečně zaškrtnuto</translation>
-<translation id="5869546221129391014">Mřížka</translation>
-<translation id="5876817486144482042">Snížit hlasitost řeči</translation>
-<translation id="5887397643266327462">Titulky v Braillově písmu jsou zapnuty.</translation>
-<translation id="5891934789323004067">Tabulka</translation>
-<translation id="5919442531159595654">kopírovat.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{rovná se}few{# znaky rovná se}many{# equal signs}other{# znaků rovná se}}</translation>
-<translation id="5939518447894949180">Resetovat</translation>
-<translation id="5948123859135882163">Přepnout mezi strukturální a sémantickou interpretací matematických výrazů</translation>
-<translation id="5955304353782037793">aplik</translation>
-<translation id="5956928062748260866">Dialogové okno</translation>
-<translation id="5963413905009737549">Sekce</translation>
-<translation id="5968607524793740041">Zobrazit kontextovou nabídku</translation>
-<translation id="5983179082906765664">Zvýšit granularitu navigace</translation>
-<translation id="5999630716831179808">Hlasy</translation>
-<translation id="6000417740266304866">Změnit aktuální tabulku osmibodového Braillova písma na možnost ze seznamu níže.</translation>
-<translation id="6006050241733874051">Formulář</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{zpětné lomítko}few{# zpětná lomítka}many{# backslashes}other{# zpětných lomítek}}</translation>
-<translation id="6037602951055904232">Posunout dopředu</translation>
-<translation id="611827076493383239">navštív</translation>
-<translation id="6119955456199054975">Konec buňky.</translation>
-<translation id="6122013438240733403">tlčtko</translation>
-<translation id="6129953537138746214">Mezera</translation>
-<translation id="6142308968191113180">Nadpis 4</translation>
-<translation id="6169420925157477918">Obrázek s dlouhým popisem</translation>
-<translation id="6172087735260766220">Nelze získat přístup k přístupnému textu z dokumentu PDF s ochranou proti kopírování.</translation>
-<translation id="6186305613600865047">Přejít na konec stránky</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Dolů</translation>
-<translation id="6236061028292614533">Další nadpis</translation>
-<translation id="6254901459154107917">Další upravitelná textová oblast</translation>
-<translation id="6259464875943891919">Opustili jste prvek <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Další podobný prvek.</translation>
-<translation id="6282062888058716985">navig</translation>
-<translation id="6290434000785343030">Žádné další pole se seznamem.</translation>
-<translation id="6307969636681130414">Stisknuto</translation>
-<translation id="6324551002951139333">Zjištěna gramatická chyba</translation>
-<translation id="6348657800373377022">Pole se seznamem</translation>
-<translation id="6355910664415701303">Žádná předchozí položka seznamu.</translation>
-<translation id="6364795331201459219">nadp 6</translation>
-<translation id="6368143427468974988">Předchozí záhlaví</translation>
-<translation id="6387719785439924554">stranou</translation>
-<translation id="6411426777058107714">Žádný předchozí přepínač.</translation>
-<translation id="6414968628640960377">Předchozí jiný prvek.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dvojtečka}few{# dvojtečky}many{# colons}other{# dvojteček}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, nabídka</translation>
-<translation id="6444046323172968959">Dialog upozornění</translation>
-<translation id="6459511626086141404">Plochá mapa kláves</translation>
-<translation id="6468049171101508116">Další tlačítko</translation>
-<translation id="6491972999578897419">Aktuální hlas můžete změnit výběrem některé z položek v následujícím seznamu.</translation>
-<translation id="6508059270146105198">Přesunout zobrazení Brailleova písma na konec stránky</translation>
-<translation id="6536864053412760904">Token MathML</translation>
-<translation id="6550720799683018100">Aktuální mapu kláves můžete změnit výběrem některé z položek v následujícím seznamu.</translation>
-<translation id="6561818612645211875">Přejít na začátek aktuálního řádku</translation>
-<translation id="6587021927234520429">Žádný další nadpis 4. úrovně.</translation>
-<translation id="6601344353291556895">Aktivovat podrobné popisy.</translation>
-<translation id="6615602925644411249">Vyhledávání na stránce</translation>
-<translation id="6633350132811819843">Žádná další tabulka.</translation>
-<translation id="6637586476836377253">protokol</translation>
-<translation id="6657128831881431364">Indikátor průběhu</translation>
-<translation id="6659594942844771486">Karta</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Předchozí rozbalovací seznam</translation>
-<translation id="6714813999819678458">Předchozí nadpis 2. úrovně</translation>
-<translation id="6716505898850596801">Modifikační klávesy</translation>
-<translation id="671916444866103745">Žádný další orientační bod ARIA.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, rozbalovací seznam</translation>
-<translation id="6735257939857578167">s <ph name="NUM" /> položkami</translation>
-<translation id="6736510033526053669">karta vytvořena</translation>
-<translation id="675895815784134693">ukaz průběhu</translation>
-<translation id="6786800275320335305">Článek</translation>
-<translation id="6787839852456839824">Klávesové zkratky</translation>
-<translation id="6793101435925451627">nabíd</translation>
-<translation id="6833103209700200188">Zápatí</translation>
-<translation id="6871161210040114857">Velká a malá písmena jsou ignorována.</translation>
-<translation id="6877435256196695200">Žádný další obrázek.</translation>
-<translation id="6897341342232909480">Posunout doleva</translation>
-<translation id="6901540140423170855">datum</translation>
-<translation id="6910211073230771657">Smazáno</translation>
-<translation id="6911965441508464308">Nahoře není žádná buňka.</translation>
-<translation id="6919104639734799681">Zobrazit seznam tabulek</translation>
-<translation id="6964088412282673743">Žádný předchozí ovládací prvek není.</translation>
-<translation id="6996566555547746822">Další rozbalovací seznam</translation>
-<translation id="7005146664810010831">Nebyla nalezena žádná adresa URL</translation>
-<translation id="7010712454773919705">Modifikační klávesa ChromeVox</translation>
-<translation id="7031651751836475482">polož sezn</translation>
-<translation id="7037042857287298941">Předchozí seznam</translation>
-<translation id="7041173719775863268">Ukončit výběr</translation>
-<translation id="7095834689119144465">Úprava textu – pouze číslice</translation>
-<translation id="7096001299300236431">Předchozí mediální objekt</translation>
-<translation id="7116595520562830928">více řádků</translation>
-<translation id="712735679809149106">vyslovovat slova</translation>
-<translation id="713824876195128146">Další blok citace</translation>
-<translation id="7161771961008409533">Tlačítko s vyskakovacím oknem</translation>
-<translation id="7167657087543110">vyslovovat znaky</translation>
-<translation id="7170733337935166589">Přejít dopředu při nepřetržitém čtení</translation>
-<translation id="7181697990050180700">Klávesové zkratky často používaných příkazů můžete změnit pomocí příslušných polí níže.</translation>
-<translation id="7203150201908454328">Rozbaleno</translation>
-<translation id="7210211103303402262">minuty</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">řádek</translation>
-<translation id="7226216518520804442">sezn</translation>
-<translation id="72393384879519786">Nadpis</translation>
-<translation id="7241683698754534149">Otevřít dlouhý popis na nové kartě</translation>
-<translation id="7248671827512403053">Aplikace</translation>
-<translation id="725969808843520477">Další přepínač</translation>
-<translation id="7269119382257320590">Bez interpunkce</translation>
-<translation id="7273174640290488576">Prázdné</translation>
-<translation id="7285387653379749618">Tabulky</translation>
-<translation id="7289186959554153431">Nadpis 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">polož stromu</translation>
-<translation id="731576946540457939">Titulky v Braillově písmu jsou vypnuty.</translation>
-<translation id="7318872822751139669">Pomocí myši můžete změnit aktivní prvek na stránce.</translation>
-<translation id="7322388933135261569">Únor</translation>
-<translation id="7332592614823088566">Řádek <ph name="ROWINDEX" /> z <ph name="ROWTOTAL" />, sloupec <ph name="COLINDEX" /> z <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">má vyskak. okno</translation>
-<translation id="7356165926712028380">Přepnout na osmibodové Braillovo písmo</translation>
-<translation id="7362871137496673139">Žádný předchozí nadpis 2. úrovně.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersand}few{# ampersandy}many{# ampersands}other{# ampersandů}}</translation>
-<translation id="737396357417333429">klikatelné</translation>
-<translation id="7374104575779636480">Opouští se tabulka.</translation>
-<translation id="739763518212184081">Předchozí řádek</translation>
-<translation id="7400575256015741911">Zjištěna pravopisná chyba</translation>
-<translation id="7408482676469142474">tab</translation>
-<translation id="7425395583360211003">vrátit</translation>
-<translation id="7434509671034404296">Vývojář</translation>
-<translation id="7439060726180460871">Adresář</translation>
-<translation id="744163271241493234">upr heslo</translation>
-<translation id="7491962110804786152">karta</translation>
-<translation id="7492049978501397201">Aktivovaný dialog</translation>
-<translation id="7532613204005497612">Červen</translation>
-<translation id="7540083713905917247">posuvník <ph name="NAME" />, <ph name="VALUE" /></translation>
-<translation id="7586163296341959563">vložit</translation>
-<translation id="7596919493010894443">výběr byl vymazán</translation>
-<translation id="7604026522577407655">Přejít na začátek aktuálního sloupce</translation>
-<translation id="7604451927827590395">nadp</translation>
-<translation id="7609342235116740824">Oznámit adresu URL aktuální stránky</translation>
-<translation id="7609363189280667021">Přepnout braillské popisky</translation>
-<translation id="762020119231868829">Pozastaví všechny aktuálně hrající mediální widgety</translation>
-<translation id="7625690649919402823">Další tabulka</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), podoba: <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Žádný předchozí nadpis 3. úrovně.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, textové pole</translation>
-<translation id="7663318257180412551">Nadpis 2</translation>
-<translation id="7674576868851035240">Další odkaz</translation>
-<translation id="7674768236845044097">zvýraz</translation>
-<translation id="7684431668231950609">Úprava textu, webová adresa</translation>
-<translation id="7685589220304187312">lišta</translation>
-<translation id="7693840228159394336">Předchozí přepínač</translation>
-<translation id="7701196182766842984">auto sezn</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, textové pole pro heslo</translation>
-<translation id="7805247615045262757">výchozí navigace</translation>
-<translation id="7805768142964895445">Stav</translation>
-<translation id="7810781339813764006">Další skupina</translation>
-<translation id="7819187121850078213">okno, karta <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Říjen</translation>
-<translation id="7839679365527550018">Předchozí slovo</translation>
-<translation id="7851816175263618915">Část interpunkce</translation>
-<translation id="7870596830398826354">Strom MathML</translation>
-<translation id="78826985582142166">posuvník</translation>
-<translation id="7894517696028036636">Přepnout klasický režim ChromeVox.</translation>
-<translation id="7895896691902835279">Neznámý odkaz</translation>
-<translation id="7927711904086083099">Nevybráno</translation>
-<translation id="7935627501098484003">Ovládací prvek času</translation>
-<translation id="7939428177581522200">přidáno do výběru</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{zavináč}few{# zavináče}many{# at signs}other{# zavináčů}}</translation>
-<translation id="7965147473449754028">nabídka zavřena</translation>
-<translation id="7974390230414479278">Položka nabídky</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{vykřičník}few{# vykřičníky}many{# exclamation points}other{# vykřičníků}}</translation>
-<translation id="8007540374018858731">nadp 3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{uvozovka}few{# uvozovky}many{# quotes}other{# uvozovek}}</translation>
-<translation id="8033827949643255796">vybráno</translation>
-<translation id="8035962149453661158">max: <ph name="X" /></translation>
-<translation id="8042761080832772327">Úprava textu, vyhledávání</translation>
-<translation id="8049189770492311300">Časovač</translation>
-<translation id="8065607967589909823">Výběr je</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Žádné orientační body ARIA.</translation>
-<translation id="8153880621934657047">Mimo tabulku.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{podtržítko}few{# podtržítka}many{# underscores}other{# podtržítek}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">vyjmout.</translation>
-<translation id="8199231515320852133">Oznámit záhlaví aktuální buňky</translation>
-<translation id="820417203470636242">Prázdná buňka.</translation>
-<translation id="8215202828671303819">Vícenásobný výběr</translation>
-<translation id="8276439074553447000">Přejít na předchozí zaměřitelnou položku</translation>
-<translation id="8278417001922463147">Žádný předchozí článek.</translation>
-<translation id="8283603667300770666">Další pole formuláře</translation>
-<translation id="831207808878314375">Definice</translation>
-<translation id="8313653172105209786">adresář</translation>
-<translation id="8344569602005188545">h</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{křížek}few{# křížky}many{# pound signs}other{# křížků}}</translation>
-<translation id="8374154622594089836">měsíc</translation>
-<translation id="8378855320830505539">Region</translation>
-<translation id="8382679411218029383">Přímé automatické doplňování a seznam</translation>
-<translation id="8428603554127842284">úroveň <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Žádný další nadpis 3. úrovně.</translation>
-<translation id="8430049249787218991">panel nabíd</translation>
-<translation id="844681116543532394">Žádné předchozí zaškrtávací políčko.</translation>
-<translation id="8455868257606149352">Max <ph name="X" /></translation>
-<translation id="84575901236241018">má přístupový klíč <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Snížit rozlišovací schopnost navigace</translation>
-<translation id="8520472399088452386">Číselník</translation>
-<translation id="8538744478902126321">Odhadnout záhlaví řádku aktuální buňky</translation>
-<translation id="8540054775867439484">Skok na začátek</translation>
-<translation id="8548973727659841685">Znak</translation>
-<translation id="8561322612995434619">má vyskakovací okno</translation>
-<translation id="8571096049907249734">více možn</translation>
-<translation id="8584721346566392021">nadp 5</translation>
-<translation id="8587549812518406253">Další položka seznamu</translation>
-<translation id="860150890330522909">zaškrtnuto políčko <ph name="NAME" /></translation>
-<translation id="8606621670302093223">Ovládací prvek – datum</translation>
-<translation id="8631359288236106450">vybrané položky: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Oznamovat souřadnice aktuální buňky</translation>
-<translation id="8650576015643545550">Žádný předchozí seznam.</translation>
-<translation id="8653031188082306838">upr url</translation>
-<translation id="8653646212587894517">Zobrazit seznam odkazů</translation>
-<translation id="8664519043722036194">s</translation>
-<translation id="867187640362843212">Nadpis 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{svislá čára}few{# svislé čáry}many{# vertical pipes}other{# svislých čar}}</translation>
-<translation id="8735450637152821465">Zahájit výběr</translation>
-<translation id="8743786158317878347">vstoupit do strukturovaného obsahu, například tabulky</translation>
-<translation id="8747966237988593539">Seřazený seznam</translation>
-<translation id="8759334257841767240">Žádný další odkaz.</translation>
-<translation id="8767968232364267681">Další nadpis 4. úrovně</translation>
-<translation id="8770473310765924354">opustit strukturovaný obsah, například tabulky</translation>
-<translation id="8791025954632646584">Sémantika je zapnuta</translation>
-<translation id="8796411681063377102">Další nadpis 3. úrovně</translation>
-<translation id="8808582214901541005">Březen</translation>
-<translation id="8825828890761629845">banner</translation>
-<translation id="8851136666856101339">hlavní</translation>
-<translation id="8856538297388979332">Stisknutím šipky nahoru nebo dolů můžete procházet příkazy, stisknutím klávesy Enter provedete aktivaci.</translation>
-<translation id="8864099967139188018">Žádný další nadpis 6. úrovně.</translation>
-<translation id="8882002077197914455">Záhlaví řádku</translation>
-<translation id="8896347895970027998">Aktivace a deaktivace rozšíření ChromeVox.</translation>
-<translation id="8898516272131543774">Vyslovování interpunkce</translation>
-<translation id="8900148057318340779">Modifikační klávesa</translation>
-<translation id="8908714597367957477">záhl sloupce</translation>
-<translation id="8931936695772494138">Prázdná záhlaví</translation>
-<translation id="8937112856099038376">interní odk</translation>
-<translation id="8940925288729953902">Modifikační klávesy</translation>
-<translation id="8943175951035496220">Vpravo není žádná buňka.</translation>
-<translation id="8978496506222343566">popisek</translation>
-<translation id="900114243503212879">soubor</translation>
-<translation id="9027462562263121875">Žádné tabulky.</translation>
-<translation id="9040132695316389094">Nadpis 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Přepnout vyhledávací widget</translation>
-<translation id="9065283790526219006">+vyskakovací okno</translation>
-<translation id="9077213568694924680">odebráno z výběru</translation>
-<translation id="9082874451376019682">Žádný předchozí posuvník.</translation>
-<translation id="9089864840575085222">Vyslovování zadávaného textu</translation>
-<translation id="9107530006868467849">Žádný předchozí mediální widget není k dispozici.</translation>
-<translation id="9108370397979208512">matematika</translation>
-<translation id="9108589040018540527">posuvník</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{procento}few{# znaky procenta}many{# percent signs}other{# znaků procenta}}</translation>
-<translation id="9115913704608474258">Listopad</translation>
-<translation id="9128414153595658330">dial</translation>
-<translation id="9149560530563164529">oddíl</translation>
-<translation id="9151211641321628915">Oznamuje stručný popis současné pozice</translation>
-<translation id="9153606228985488238">Výška <ph name="PERCENT" /> procent</translation>
-<translation id="9160096769946561184">Přejít na konec aktuálního sloupce</translation>
-<translation id="9173115498289768110">Hlasitost <ph name="PERCENT" /> procent</translation>
-<translation id="9178973770513562274">Procházejte pomocí kláves Šipka nahoru a Šipka dolů nebo zadejte vyhledávací dotaz.</translation>
-<translation id="9192904702577636854">Běžící text</translation>
-<translation id="9212322457209634662">Žádná další sekce není.</translation>
-<translation id="930275611743429116">Zahájit nebo ukončit výběr.</translation>
-<translation id="948171205378458592">Snížit rychlost řeči</translation>
-<translation id="962913030769097253">Další nadpis 1. úrovně</translation>
-<translation id="973955474346881951">Aktivovat či deaktivovat režim Jedním prstem</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_da.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_da.xtb
deleted file mode 100644
index 3fad4eccf39..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_da.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="da">
-<translation id="1012173283529841972">Punkt på listen</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Overlappet.</translation>
-<translation id="1025074108959230262">Sticky-tilstand er deaktiveret</translation>
-<translation id="1031961866430398710">og derefter</translation>
-<translation id="1044777062731150180">Ingen overskrifter</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Ugyldigt input</translation>
-<translation id="1082209053475788238">Ingen tidligere niveau 6-overskrifter.</translation>
-<translation id="1088219014394087294">Ingen overskrifter.</translation>
-<translation id="1106741348836243114">Slå lydfeedback (earcons) til eller fra.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="TAG" />-samling med <ph name="NUM" /> elementer</translation>
-<translation id="1155043339247954670">Ikke flere elementer på listen.</translation>
-<translation id="1157782847298808853">Hjælp til tastatur</translation>
-<translation id="1157843803349774103">Kombifeltet <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="1167230103353892028">Menupunktet <ph name="NAME" /> med undermenu</translation>
-<translation id="1177863135347784049">Tilpasset</translation>
-<translation id="1188858454923323853">supplerende</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – talerør til Chrome</translation>
-<translation id="1229276918471378188">Forrige hop</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Næste niveau 6-overskrift</translation>
-<translation id="1275718070701477396">Valgt</translation>
-<translation id="1319608975892113573">Ingen tidligere blockquotes.</translation>
-<translation id="1321576897702511272">Skjul Hjælp til ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> af <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">tegn- og ordekko</translation>
-<translation id="1339428534620983148">Forrige tabelkolonne</translation>
-<translation id="1342835525016946179">artikel</translation>
-<translation id="1346748346194534595">Højre</translation>
-<translation id="136718599399906424">Næste tabelrække</translation>
-<translation id="1383876407941801731">Søg</translation>
-<translation id="1385214448885562192">Tryk på enter for at acceptere eller escape for at annullere. Tryk på ned for næste og op for forrige.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652">Adgangskodetekstfeltet <ph name="VALUE" /></translation>
-<translation id="1467432559032391204">Venstre</translation>
-<translation id="1474557363159888097">Ingen tidligere ankre.</translation>
-<translation id="1502086903961450562">Forrige grafik</translation>
-<translation id="1506187449813838456">Skru op for toneleje</translation>
-<translation id="151784044608172266">Næste sætning</translation>
-<translation id="1524531499102321782">Braille næste linje</translation>
-<translation id="1546370775711804143">Rullepanel</translation>
-<translation id="1559739829547075274">Naviger tilbage</translation>
-<translation id="1571643229714746283">ChromeVox er klar</translation>
-<translation id="158493514907962286">December</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Skift til 6-punkts braillealfabet</translation>
-<translation id="1611168825862729585">Kolonneoverskrift:</translation>
-<translation id="1613476421962910979">Earcons til</translation>
-<translation id="1618597272655350600">Angiver en komplet beskrivelse af den aktuelle position</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{større end}one{# større end-tegn}other{# større end-tegn}}</translation>
-<translation id="1653266918374749391">Forrige niveau 3-overskrift</translation>
-<translation id="1659072772017912254">Ikke kontrolleret</translation>
-<translation id="1669290819662866522">uge</translation>
-<translation id="1674262202423278359">Navigation i ChromeVox</translation>
-<translation id="16777221443363124">Menulinje</translation>
-<translation id="1692077714702418899">strukturel linje</translation>
-<translation id="1700517974991662022">Besøgt</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">si.fo</translation>
-<translation id="174268867904053074">Næste grafik</translation>
-<translation id="1781173782405573156">Ignorer-tast</translation>
-<translation id="1787176709638001873">Tekst om redigering af adgangskode</translation>
-<translation id="1810107444790159527">Listefelt</translation>
-<translation id="1828385960365606039">Maj</translation>
-<translation id="1834891354138622109">Kolonne</translation>
-<translation id="1865601187525349519">Slutning af ​​tekst</translation>
-<translation id="1876229593313240038">dok</translation>
-<translation id="188130072164734898">Sig det aktuelle klokkeslæt og den aktuelle dato.</translation>
-<translation id="1902396333223336119">Celle</translation>
-<translation id="1905379170753160525">Vis overskriftliste</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Kontrol for en uge om året</translation>
-<translation id="1964135212174907577">Næste objekt</translation>
-<translation id="1969092762068865084">Juli</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Rækkeoverskrift:</translation>
-<translation id="2002895034995108595">Nulstil aktuel tastaturoversigt</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{venstre kantet parentes}one{# venstre kantede parenteser}other{# venstre kantede parenteser}}</translation>
-<translation id="2045490512405922022">ikke markeret</translation>
-<translation id="20601713649439366">Der er ingen tidligere matematiske udtryk.</translation>
-<translation id="207477615537953741">Semantik fra</translation>
-<translation id="2086961585857038472">Næste ord</translation>
-<translation id="2089387485033699258">da</translation>
-<translation id="2091933974477985526">Forrige tekstområde, som kan redigeres</translation>
-<translation id="2100350898815792233">Al tegnsætning</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">hurtigtast:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Skift det aktuelle 6-punkts braillealfabet ved at vælge en indstilling på listen nedenfor.</translation>
-<translation id="2169714232367507776">Klik på aktuelt element</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{højre parentes}one{# højre parentes}other{# højre parenteser}}</translation>
-<translation id="2199994615414171367">Forrige matematiske udtryk</translation>
-<translation id="2223693656926968778">Foretag handling på aktuelt element</translation>
-<translation id="225732394367814946">Skru op for talehastigheden</translation>
-<translation id="2267945578749931355">Næste tegn</translation>
-<translation id="2281234842553884450">Forrige skyder</translation>
-<translation id="2318372665160196757">Hoved</translation>
-<translation id="2329324941084714723">Fanepanel</translation>
-<translation id="2344193891939537199">Kontrol af dato og tid</translation>
-<translation id="2359897517538099099">Tabeltilstand er ikke aktiveret.</translation>
-<translation id="241124561063364910">efterfulgt af</translation>
-<translation id="2417569100218200841">Indholdsoplysninger</translation>
-<translation id="2422937916923936891">Afkrydsningsfelt til menupunkt</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> er nu den nye ChromeVox-ændringstast.</translation>
-<translation id="2450814015951372393">Afkrydsningsfelt</translation>
-<translation id="2462626033734746142">Gruppe af alternativknapper</translation>
-<translation id="2471138580042810658">Overskrift 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{stjerne}one{# stjerner}other{# stjerner}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> er blevet nulstillet.</translation>
-<translation id="2553108862507765288">grammatisk fejl</translation>
-<translation id="257674075312929031">Gruppe</translation>
-<translation id="2582407057977008361">Uden for</translation>
-<translation id="2589102159832527089">Denne side indeholder tekst, der er trukket ud af PDF-filen &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; automatisk. &lt;a href="<ph name="URL" />"&gt;Klik her for at se originalen.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">med {COUNT,plural, =1{# element}one{# element}other{# elementer}}</translation>
-<translation id="2614981083756825552">Math ML-layout</translation>
-<translation id="2626530649491650971">klikbart</translation>
-<translation id="2628764385451019380">Ingen tidligere kombifelter.</translation>
-<translation id="2637227747952042642">Matematik</translation>
-<translation id="2639750663247012216">Ændringstast til ChromeVox</translation>
-<translation id="2644542693584024604">stavefejl</translation>
-<translation id="2667291555398229137">Klik på elementet under en routing-tast</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{venstre parentes}one{# venstre parentes}other{# venstre parenteser}}</translation>
-<translation id="2705875883745373140">Ikke trykket på</translation>
-<translation id="2706462751667573066">Op</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">lyd</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Kontrolleret</translation>
-<translation id="27527859628328957">Gå til næste element, der kan fokuseres på</translation>
-<translation id="2770781857296573485">Start udforskning af grupper</translation>
-<translation id="2777845298774924149">Lukket</translation>
-<translation id="2800204403141299078">Ikke flere anderledes elementer.</translation>
-<translation id="2800780099804980316">Ingen tidligere niveau 1-overskrifter.</translation>
-<translation id="2811204574343810641">Række</translation>
-<translation id="2816654101880605877">Ikke flere ​​skydere.</translation>
-<translation id="2841013758207633010">Tid</translation>
-<translation id="2843837985843789981">Forrige gruppe</translation>
-<translation id="2844995807198708617">Genvejsmenu</translation>
-<translation id="2849332794118375855">Ikke flere afkrydsningsfelter.</translation>
-<translation id="2864481629947106776">Forrige link</translation>
-<translation id="2873259058405069099">Gå til starten af ​​tabellen</translation>
-<translation id="2894654529758326923">Oplysninger</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{venstre klammeparentes}one{# venstre klammeparenteser}other{# venstre klammeparenteser}}</translation>
-<translation id="2911433807131383493">Åbn ChromeVox-selvstudie</translation>
-<translation id="2932083475399492303">Skift linjetype mellem strukturel eller layout</translation>
-<translation id="2964026537669811554">Overskriftsgruppe</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulator}one{# tabulatorer}other{# tabulatorer}}</translation>
-<translation id="2972078295414139404">Intet tidligere besøgt link.</translation>
-<translation id="2972205263822847197">Værktøjstip</translation>
-<translation id="2998131015536248178">Forrige tegn</translation>
-<translation id="2999559350546931576">Skru ned for toneleje</translation>
-<translation id="2999945368667127852">Der er ikke flere mediewidgets.</translation>
-<translation id="3012414509011670858">Der er ingen forrige afsnit.</translation>
-<translation id="3030432017085518523">Alternativknap til menupunkt</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}one{# apostroffer}other{# apostroffer}}</translation>
-<translation id="3046838483509668188">Indstillinger i ChromeVox</translation>
-<translation id="3047143736589213134">Eksperimentelt tastatur</translation>
-<translation id="3060756054951570867">Menuen <ph name="TITLE" /> åbnet</translation>
-<translation id="3078345202707391975">Næste niveau 2-overskrift</translation>
-<translation id="3078740164268491126">tabel</translation>
-<translation id="3082557070674409251">Klikket på</translation>
-<translation id="3084806535845658316">intet indtastningsekko</translation>
-<translation id="3086746722712840547">bmrk</translation>
-<translation id="308895241372589742">Der er ikke flere matematiske udtryk.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Næste orienteringspunkt</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">advar.dlg</translation>
-<translation id="3109724472072898302">Skjult</translation>
-<translation id="3134461040845705080">skrv.bsk</translation>
-<translation id="3138767756593758860">Vis liste med orienteringspunkter</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Næste linje</translation>
-<translation id="3155083529632865074">Ingen tidligere knapper.</translation>
-<translation id="3163593631834463955">Tom kolonneoverskrift</translation>
-<translation id="316542773973815724">Navigation</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{mellemrum}one{# mellemrum}other{# mellemrum}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> er indtastet</translation>
-<translation id="3223701887221307104">Fanen <ph name="NAME" /></translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Besøgt link</translation>
-<translation id="323731244387692321">Åbn Hjælp til ChromeVox-tastatur</translation>
-<translation id="3241052487511142956">Tidligere besøgt link</translation>
-<translation id="3286390186030710347">Skyder</translation>
-<translation id="3299925995433437805">Intet næste besøgte link.</translation>
-<translation id="3303384412438961941">Tryk på en tast for at få tastens navn at vide. Ctrl+W lukker tastaturudforsker.</translation>
-<translation id="3307886118343381874">Gå til slutningen af ​​tabellen</translation>
-<translation id="3311969765485641742">Tryk på Alt+Shift+A for at gennemse underretninger</translation>
-<translation id="3312997241656799641">Næste besøgte link</translation>
-<translation id="3321460131042519426">Aktivér tekstombrydning</translation>
-<translation id="3322936298410871309">Forrige niveau 1-overskrift</translation>
-<translation id="3323447499041942178">Tekstfelt</translation>
-<translation id="3353420241558113817">{"ar": "arabisk",
- "bg": "bulgarsk",
- "ca": "catalansk",
- "cs": "tjekkisk",
- "da": "dansk",
- "de": "tysk",
- "de_CH": "tysk (Schweiz)",
- "de_DE": "tysk (Tyskland)",
- "el": "græsk",
- "en": "engelsk",
- "en_CA": "engelsk (Canada)",
- "en_GB": "engelsk (Storbritannien)",
- "en_US": "engelsk (USA)",
- "es": "spansk",
- "et": "estisk",
- "fr": "fransk",
- "fr_CA": "fransk (Canada)",
- "fr_FR": "fransk (Frankrig)",
- "fi": "finsk",
- "he": "hebraisk",
- "hi": "hindi",
- "hr": "kroatisk",
- "hu": "ungarsk",
- "is": "islandsk",
- "it": "italiensk",
- "ko": "koreansk",
- "lt": "litauisk",
- "lv": "lettisk",
- "nb": "norsk bokmål",
- "nl": "hollandsk",
- "pl": "polsk",
- "pt": "portugisisk",
- "ro": "rumænsk",
- "ru": "russisk",
- "sk": "slovakisk",
- "sl": "slovensk",
- "sr": "serbisk",
- "sv": "svensk",
- "tr": "tyrkisk",
- "vi": "vietnamesisk",
- "zh": "kinesisk",
- "zh_TW": "kinesisk (traditionelt han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plus}one{# plustegn}other{# plustegn}}</translation>
-<translation id="338583716107319301">Separator</translation>
-<translation id="3389259863310851658">Forrige formularfelt</translation>
-<translation id="3390225400784126843">Næste anderledes element.</translation>
-<translation id="3392045790598181549">Menupunktet <ph name="NAME" /></translation>
-<translation id="3406283310380167331">Vis formularliste</translation>
-<translation id="3422338090358345848">Åbn tastaturudforsker</translation>
-<translation id="3457000393508828486">Delvist trykket ned</translation>
-<translation id="3462439746547587373">Knappen <ph name="NAME" /></translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> til <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{højre kantet parentes}one{# højre kantede parenteser}other{# højre kantede parenteser}}</translation>
-<translation id="3493915602752813531">Ikke flere ankre.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{spørgsmålstegn}one{# spørgsmålstegn}other{# spørgsmålstegn}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{cirkumfleks}one{ # cirkumflekser}other{# cirkumflekser}}</translation>
-<translation id="3568702578574425662">Afkrydsningsfeltet <ph name="NAME" /> er ikke markeret</translation>
-<translation id="3599054940393788245">Ikke inden i matematik</translation>
-<translation id="3616113530831147358">Lyd</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{accent grave}one{# accent graver}other{# accent graver}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollar}one{# dollartegn}other{# dollartegn}}</translation>
-<translation id="3659787053479271466">advar</translation>
-<translation id="3665563998540286755">Listefeltet <ph name="VALUE" /></translation>
-<translation id="3687295507293856493">Giv et bud på kolonneoverskriften af ​​den aktuelle celle</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Kontrollerer tale</translation>
-<translation id="3716845769494773620">Flere linjer</translation>
-<translation id="3731746171184829332">Ingen tidligere overskrifter.</translation>
-<translation id="3762198587642264450">Gå til slutningen af ​​den aktuelle række</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Dialogboks blev lukket.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">Autofuldførelsesliste</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Næste medie</translation>
-<translation id="3819376190738087562">Ingen hop.</translation>
-<translation id="385383972552776628">Åbn siden med indstillinger</translation>
-<translation id="3856075812838139784">Skrivebeskyttet</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Forrige niveau 6-overskrift</translation>
-<translation id="3914173277599553213">Påkrævet</translation>
-<translation id="3962990492275676168">Start læsning fra nuværende position</translation>
-<translation id="4004802134384979325">markeret</translation>
-<translation id="4006140876663370126">bidl</translation>
-<translation id="4038349100599457191">Månedlig kontrol</translation>
-<translation id="4039983576244166038">Tom rækkeoverskrift</translation>
-<translation id="4042843249978639960">Ikke flere niveau 2-overskrifter.</translation>
-<translation id="4043348641337972076">Ingen tidligere ARIA-orienteringspunkter.</translation>
-<translation id="4047216625641135770">Marker</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}one{# tilder}other{# tilder}}</translation>
-<translation id="409334809956508737">Forrige objekt</translation>
-<translation id="4099274309791143834">med undermenu</translation>
-<translation id="4107807507418787238">Ingen celle nedenfor.</translation>
-<translation id="4116415223832267137">Underretning</translation>
-<translation id="4147126331795725888">Der er ikke flere kontrolelementer.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{højre klammeparentes}one{# højre klammeparenteser}other{# højre klammeparenteser}}</translation>
-<translation id="4158704014418536539">Der er forskel på store og små bogstaver.</translation>
-<translation id="4161663686871496107">Talefeedback via ChromeVox er klar</translation>
-<translation id="4173994908659439270">Ikke flere redigerbare tekstfelter.</translation>
-<translation id="4176463684765177261">Deaktiveret</translation>
-<translation id="4188530942454211480">Forrige sætning</translation>
-<translation id="4202186506458631436">Flyt til højre</translation>
-<translation id="4206289001967551965">I tabel</translation>
-<translation id="4215733775853809057">Næste skyder</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{tankestreg}one{# tankestreger}other{# tankestreger}}</translation>
-<translation id="421884353938374759">farvevælger</translation>
-<translation id="4229646983878045487">dato og tid</translation>
-<translation id="423334822609210999">Ingen celle til venstre.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, grade <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Note</translation>
-<translation id="4254798249533888099">Træ</translation>
-<translation id="4255943572433203166">Brug indstillingerne nedenfor til at tilpasse ChromeVox. Ændringer træder i kraft med det samme.</translation>
-<translation id="4271220233568730077">Næste matematiske udtryk</translation>
-<translation id="4271521365602459209">Ikke flere resultater.</translation>
-<translation id="4287520460805643128">Ikke flere artikler.</translation>
-<translation id="4289540628985791613">Oversigt</translation>
-<translation id="4300318234632215983">Offentliggør webadressen bag et link</translation>
-<translation id="4301352596632316575">har undermenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punktum}=3{ellipse}one{# punktummer}other{# punktummer}}</translation>
-<translation id="4347461890115250064">Ikke flere lister.</translation>
-<translation id="4367650418938037324">Math ML-blad</translation>
-<translation id="4372435075475052704">min.:<ph name="X" /></translation>
-<translation id="4372705107434148843">Stop tale</translation>
-<translation id="4373197658375206385">Ingen tidligere elementer, der ikke er links.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">nulstil</translation>
-<translation id="4471074325120394300">Ingen links.</translation>
-<translation id="4476183483923481720">ny linje</translation>
-<translation id="4482330759234983253">Forrige tabel</translation>
-<translation id="4491109536499578614">Billede</translation>
-<translation id="4529987814483543472">Klassisk tastaturoversigt</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{skråstreg}one{# skråstreger}other{# skråstreger}}</translation>
-<translation id="4547556996012970016">Næste niveau 5-overskrift</translation>
-<translation id="4562381607973973258">Overskrift</translation>
-<translation id="4591507479202817876">, valgt</translation>
-<translation id="4597532268155981612">formular</translation>
-<translation id="4597896406374528575">April</translation>
-<translation id="4615592953348396470">Ignorerer næste tastetryk</translation>
-<translation id="461613135510474570">Sætning</translation>
-<translation id="4647836961514597010">Farvevælger</translation>
-<translation id="4661075872484491155">træ</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">git</translation>
-<translation id="4693675773662933727">Forrige orienteringspunkt</translation>
-<translation id="4696413482802371445">Ikke flere niveau 5-overskrifter.</translation>
-<translation id="4729095194763193578">Forrige tabelrække</translation>
-<translation id="4736221692378411923">August</translation>
-<translation id="4740661827607246557">Hjælpekommandoer</translation>
-<translation id="4759716709594980008">ChromeOS-tastaturudforsker</translation>
-<translation id="4763296182459741068">Ombrudt til bunden af siden</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">søg</translation>
-<translation id="481165870889056555">Offentliggør titlen på den aktuelle side</translation>
-<translation id="4826415162591436065">Naviger frem</translation>
-<translation id="4826604887384865800">Næste hop</translation>
-<translation id="4827410568042294688">fravalgt</translation>
-<translation id="4842108708071771135">Ikke flere blockquotes.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Forrige lignende element.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Aktivér TTS-logføring</translation>
-<translation id="4877261390094455813">Indtast en søgeforespørgsel.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Internt link</translation>
-<translation id="4953585991029886728">Rediger tekst</translation>
-<translation id="4954534434583049121">Forrige citatblok</translation>
-<translation id="4973717656530883744">Min. <ph name="X" /></translation>
-<translation id="4973762002207131920">Ændret til <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">millisekunder</translation>
-<translation id="49787999531187221">ChromeVox er nu deaktiveret.</translation>
-<translation id="4979404613699303341">Knappen Forrige</translation>
-<translation id="4982773647088557172">Listefeltet <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="4983588134362688868">Gå til toppen af siden</translation>
-<translation id="4986606102545753256">Vinduet <ph name="NAME" /></translation>
-<translation id="4993152509206108683">Tempo <ph name="PERCENT" /> procent</translation>
-<translation id="4996716799442435517">Visuel</translation>
-<translation id="4997282455736854877">Alternativknappen <ph name="NAME" /> er valgt</translation>
-<translation id="4997475792277222884">Ikke flere elementer, der ikke er links.</translation>
-<translation id="5000760171916499057">Ingen formularer.</translation>
-<translation id="5005670136041063723">Ikke flere lignende elementer.</translation>
-<translation id="501473567976723023">Januar</translation>
-<translation id="5041394372352067729">Flyt braille-visningen til toppen af siden</translation>
-<translation id="5042770794184672516">Skru op for talevolumen</translation>
-<translation id="5050015258024679800">Forrige niveau 4-overskrift</translation>
-<translation id="5054047268577924192">Forrige punkt på listen</translation>
-<translation id="5078661581131202757">Filvalg</translation>
-<translation id="5080758118274074384">dobbeltklikket på</translation>
-<translation id="5098541983634824365">Forlader gitter.</translation>
-<translation id="5102981729317424850">Værktøjslinje</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Ingen tidligere formularfelter.</translation>
-<translation id="5111640677200759579">Kolonneoverskrift</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Ingen tidligere links.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, ikke valgt</translation>
-<translation id="5183440668879371625">Braille forrige linje</translation>
-<translation id="5184944171021383281">Ikke flere formularfelter.</translation>
-<translation id="5189244881767082992">Linje</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> er allerede tilknyttet en kommando.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" />-liste.</translation>
-<translation id="520883772648104506">Ikke flere alternativknapper.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objekt</translation>
-<translation id="5304943142864553931">fanen <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">fjernet:</translation>
-<translation id="5320727453979144100">Sticky-tilstand er aktiveret</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{komma}one{# kommaer}other{# kommaer}}</translation>
-<translation id="532371086589123547">Tekstfeltet <ph name="VALUE" /></translation>
-<translation id="5330443287809544590">Linket <ph name="NAME" /></translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Spring tilbage under kontinuerlig læsning</translation>
-<translation id="5368000168321181111">Earcons fra</translation>
-<translation id="5374320867641260420">Ikke flere knapper.</translation>
-<translation id="5382299583965267720">Ikke flere niveau 1-overskrifter.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{semikolon}one{# semikoloner}other{# semikoloner}}</translation>
-<translation id="5411891038905756502">Ingen tidligere hoppunkter.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{mindre end}one{# mindre end-tegn}other{# mindre end-tegn}}</translation>
-<translation id="5455441614648621694">Supplerende</translation>
-<translation id="5485036206801896268">Ingen tidligere grafikker.</translation>
-<translation id="5486947920110100234">Ikke flere hoppunkter.</translation>
-<translation id="549602578321198708">Ord</translation>
-<translation id="5500932716852106146">Ingen tidligere redigerbare tekstfelter.</translation>
-<translation id="5502713021410870035">September</translation>
-<translation id="5507663321906818013">Udgangspunkt for fejlfinding</translation>
-<translation id="5518443085409638729">Placer markøren mellem tegn, når du redigerer tekst (ligesom Mac OS X).</translation>
-<translation id="552195134157544755">Alternativknap</translation>
-<translation id="5534303576632885660">si.ho</translation>
-<translation id="5546092960038624944">Ingen tidligere niveau 5-overskrifter.</translation>
-<translation id="556042886152191864">Knap</translation>
-<translation id="5561345396546889625">Næste liste</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Returtast</translation>
-<translation id="5585044216466955529">Rediger tekst, e-mailindtastning</translation>
-<translation id="5597170376237141345">Næste afkrydsningsfelt</translation>
-<translation id="5597933780944041114">Ikke flere overskrifter.</translation>
-<translation id="5598905979683743333">Alternativknappen <ph name="NAME" /> er ikke valgt</translation>
-<translation id="5601172225407283979">Udfør standardhandling</translation>
-<translation id="5608798115546226984">Autofuldførelse på linjen</translation>
-<translation id="561939826962581046">tidspunkt</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Log</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Ingen tidligere tabeller.</translation>
-<translation id="5655682562155942719">Hopkommandoer</translation>
-<translation id="56637627897541303">Tekstområde</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Orienteringspunkt</translation>
-<translation id="5683155931978483559">Forrige afkrydsningsfelt</translation>
-<translation id="5684277895745049190">Liste</translation>
-<translation id="5700650669149824506">Ingen tidligere niveau 4-overskrifter.</translation>
-<translation id="5709192780268610569">Ingen lang beskrivelse</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Næste tabelkolonne</translation>
-<translation id="571866080859340309">Udforsker grupper</translation>
-<translation id="5728409797179002635">Ingen tabel fundet.</translation>
-<translation id="5748623122140342504">Forrige niveau 5-overskrift</translation>
-<translation id="5750633686117194034">Der er ikke trykket på nogen ændringstast. Tryk på én eller flere ændringstaster, og hold dem nede. Når du er færdig, skal du løfte fingrene. Du vil nu høre, hvilke taster der er blevet indstillet. Tryk for at afslutte.</translation>
-<translation id="5788275253279308023">Incognito-vinduet <ph name="TITLE" />, fane</translation>
-<translation id="5806206155699461681">Optimer bestemte websites (f.eks. Google Søgning).</translation>
-<translation id="5819072574982403430">Træelement</translation>
-<translation id="5826479389509458994">række <ph name="ROW" /> kolonne <ph name="COL" /></translation>
-<translation id="5850707923114094062">Panorer tilbage</translation>
-<translation id="5851548754964597211">Faneliste</translation>
-<translation id="5859752971144398932">Søgefunktion på siden lukket.</translation>
-<translation id="5866042630553435010">Delvist kontrolleret</translation>
-<translation id="5869546221129391014">Gitter</translation>
-<translation id="5876817486144482042">Skru ned for talevolumen</translation>
-<translation id="5887397643266327462">Brailletekst er aktiveret.</translation>
-<translation id="5891934789323004067">Tabel</translation>
-<translation id="5919442531159595654">kopiér.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{lig med}one{# lig med-tegn}other{# lig med-tegn}}</translation>
-<translation id="5939518447894949180">Nulstil</translation>
-<translation id="5948123859135882163">Skift fortolkningen af matematiske udtryk mellem strukturel og semantisk</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialogboks</translation>
-<translation id="5963413905009737549">Afsnit</translation>
-<translation id="5968607524793740041">Vis genvejsmenu</translation>
-<translation id="5983179082906765664">Øg detaljegraden for navigation</translation>
-<translation id="5999630716831179808">Stemmer</translation>
-<translation id="6000417740266304866">Skift det aktuelle 8-punkts braillealfabet ved at vælge en indstilling på listen nedenfor.</translation>
-<translation id="6006050241733874051">Formular</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{omvendt skråstreg}one{ # omvendte skråstreger}other{# omvendte skråstreger}}</translation>
-<translation id="6037602951055904232">Panorer fremad</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Slut på celle.</translation>
-<translation id="6122013438240733403">knp</translation>
-<translation id="6129953537138746214">Mellemrum</translation>
-<translation id="6142308968191113180">Overskrift 4</translation>
-<translation id="6169420925157477918">Billede med lang beskrivelse</translation>
-<translation id="6172087735260766220">Der kunne ikke opnås adgang til tilgængelig tekst fra den kopibeskyttede PDF-fil.</translation>
-<translation id="6186305613600865047">Gå til bunden af siden</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Ned</translation>
-<translation id="6236061028292614533">Næste overskrift</translation>
-<translation id="6254901459154107917">Næste tekstområde, som kan redigeres</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> er afsluttet.</translation>
-<translation id="6281876499889881039">Næste lignende element.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Ikke flere kombifelter.</translation>
-<translation id="6307969636681130414">Trykket på</translation>
-<translation id="6324551002951139333">Der blev fundet en grammatisk fejl</translation>
-<translation id="6348657800373377022">Kombifelt</translation>
-<translation id="6355910664415701303">Ingen tidligere elementer på listen.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Forrige overskrift</translation>
-<translation id="6387719785439924554">tilsi</translation>
-<translation id="6411426777058107714">Ingen tidligere alternativknapper.</translation>
-<translation id="6414968628640960377">Forrige anderledes element.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{kolon}one{# koloner}other{# koloner}}</translation>
-<translation id="6438968337250688271">Menuen <ph name="NAME" /></translation>
-<translation id="6444046323172968959">Underretningsdialogboks</translation>
-<translation id="6459511626086141404">Flad tasteoversigt</translation>
-<translation id="6468049171101508116">Knappen Næste</translation>
-<translation id="6491972999578897419">Skift aktuel stemme ved at vælge en indstilling på listen nedenfor.</translation>
-<translation id="6508059270146105198">Flyt braille-visningen til bunden af siden</translation>
-<translation id="6536864053412760904">Math ML-token</translation>
-<translation id="6550720799683018100">Skift den nuværende tastaturoversigt ved at vælge en mulighed på listen nedenfor.</translation>
-<translation id="6561818612645211875">Gå til starten af ​​den aktuelle række</translation>
-<translation id="6587021927234520429">Ikke flere niveau 4-overskrifter.</translation>
-<translation id="6601344353291556895">Aktivér detaljerede beskrivelser.</translation>
-<translation id="6615602925644411249">Find på siden.</translation>
-<translation id="6633350132811819843">Ikke flere tabeller.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Statuslinje</translation>
-<translation id="6659594942844771486">Fane</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Forrige kombifelt</translation>
-<translation id="6714813999819678458">Forrige niveau 2-overskrift</translation>
-<translation id="6716505898850596801">Ændringstaster</translation>
-<translation id="671916444866103745">Ikke flere ARIA-orienteringspunkter.</translation>
-<translation id="6734854816611871228">Kombifeltet <ph name="VALUE" /></translation>
-<translation id="6735257939857578167">med <ph name="NUM" /> elementer</translation>
-<translation id="6736510033526053669">fanen blev oprettet</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artikel</translation>
-<translation id="6787839852456839824">Tastaturgenveje</translation>
-<translation id="6793101435925451627">lst</translation>
-<translation id="6833103209700200188">Sidefod</translation>
-<translation id="6871161210040114857">Der tages ikke højde for store og små bogstaver.</translation>
-<translation id="6877435256196695200">Ikke flere grafikker.</translation>
-<translation id="6897341342232909480">Flyt til venstre</translation>
-<translation id="6901540140423170855">dato</translation>
-<translation id="6910211073230771657">Slettet</translation>
-<translation id="6911965441508464308">Ingen celle ovenfor.</translation>
-<translation id="6919104639734799681">Vis tabelliste</translation>
-<translation id="6964088412282673743">Ingen tidligere kontrolelementer.</translation>
-<translation id="6996566555547746822">Næste kombifelt</translation>
-<translation id="7005146664810010831">Der blev ikke fundet nogen webadresse</translation>
-<translation id="7010712454773919705">Ændringstast til ChromeVox</translation>
-<translation id="7031651751836475482">ovs.elmt</translation>
-<translation id="7037042857287298941">Forrige liste</translation>
-<translation id="7041173719775863268">Det valgte afsluttes</translation>
-<translation id="7095834689119144465">Rediger kun tal i tekst</translation>
-<translation id="7096001299300236431">Forrige medie</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">ordekko</translation>
-<translation id="713824876195128146">Næste citatblok</translation>
-<translation id="7161771961008409533">Pop op-knap</translation>
-<translation id="7167657087543110">tegnekko</translation>
-<translation id="7170733337935166589">Spring frem under kontinuerlig læsning</translation>
-<translation id="7181697990050180700">Tilpas tastaturgenveje for kommandoer, der bruges ofte, ved at taste dem ind i de tilsvarende felter nedenfor.</translation>
-<translation id="7203150201908454328">Udvidet</translation>
-<translation id="7210211103303402262">minutter</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">linje</translation>
-<translation id="7226216518520804442">ovs</translation>
-<translation id="72393384879519786">Overskrift</translation>
-<translation id="7241683698754534149">Åbn lang beskrivelse i en ny fane</translation>
-<translation id="7248671827512403053">Applikation</translation>
-<translation id="725969808843520477">Næste alternativknap</translation>
-<translation id="7269119382257320590">Ingen tegnsætning</translation>
-<translation id="7273174640290488576">Tom</translation>
-<translation id="7285387653379749618">Tabeller</translation>
-<translation id="7289186959554153431">Overskrift 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Brailletekst er deaktiveret.</translation>
-<translation id="7318872822751139669">Brug musen til at skifte fokus.</translation>
-<translation id="7322388933135261569">Februar</translation>
-<translation id="7332592614823088566">Række <ph name="ROWINDEX" /> af <ph name="ROWTOTAL" />, kolonne <ph name="COLINDEX" /> af <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">har pop op-vindue</translation>
-<translation id="7356165926712028380">Skift til 8-punkts braillealfabet</translation>
-<translation id="7362871137496673139">Ingen tidligere niveau 2-overskrifter.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{og-tegn}one{# og-tegn}other{# og-tegn}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Forlader tabel.</translation>
-<translation id="739763518212184081">Forrige linje</translation>
-<translation id="7400575256015741911">Der blev fundet en stavefejl</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">retur</translation>
-<translation id="7434509671034404296">Udvikler</translation>
-<translation id="7439060726180460871">Mappe</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">fane</translation>
-<translation id="7492049978501397201">Indtastet dialog</translation>
-<translation id="7532613204005497612">Juni</translation>
-<translation id="7540083713905917247">Skyderen <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="7586163296341959563">sæt ind.</translation>
-<translation id="7596919493010894443">markering er ryddet</translation>
-<translation id="7604026522577407655">Gå til starten af ​​den aktuelle kolonne</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Offentliggør webadresse for den aktuelle side</translation>
-<translation id="7609363189280667021">Slå billedtekster med ledsagende brailletekst til eller fra</translation>
-<translation id="762020119231868829">Holder pause i alle aktive mediewidgets</translation>
-<translation id="7625690649919402823">Næste tabel</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), niveau <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Ingen tidligere niveau 3-overskrifter.</translation>
-<translation id="7659376057562985921">Tekstfeltet <ph name="NAME" />, <ph name="VALUE" /></translation>
-<translation id="7663318257180412551">Overskrift 2</translation>
-<translation id="7674576868851035240">Næste link</translation>
-<translation id="7674768236845044097">marker</translation>
-<translation id="7684431668231950609">Rediger tekst, webadresseindtastning</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Forrige alternativknap</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, adgangskodetekstfelt</translation>
-<translation id="7805247615045262757">standardnavigation</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Næste gruppe</translation>
-<translation id="7819187121850078213">vinduet <ph name="TITLE" />, fane</translation>
-<translation id="7828956995407538686">Oktober</translation>
-<translation id="7839679365527550018">Forrige ord</translation>
-<translation id="7851816175263618915">Nogen tegnsætning</translation>
-<translation id="7870596830398826354">Math ML-trævisning</translation>
-<translation id="78826985582142166">skdr</translation>
-<translation id="7894517696028036636">Slå ChromeVox Classic til eller fra.</translation>
-<translation id="7895896691902835279">Ukendt link</translation>
-<translation id="7927711904086083099">Ikke valgt</translation>
-<translation id="7935627501098484003">Tidsstyring</translation>
-<translation id="7939428177581522200">føjet til det valgte</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{snabel-a}one{# snabel-a'er}other{# snabel-a'er}}</translation>
-<translation id="7965147473449754028">menuen er lukket</translation>
-<translation id="7974390230414479278">Menupunkt</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{udråbstegn}one{# udråbstegn}other{# udråbstegn}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{anførelsestegn}one{# anførelsestegn}other{# anførelsestegn}}</translation>
-<translation id="8033827949643255796">valgt</translation>
-<translation id="8035962149453661158">maks.:<ph name="X" /></translation>
-<translation id="8042761080832772327">Rediger tekst, søgeindtastning</translation>
-<translation id="8049189770492311300">Timer</translation>
-<translation id="8065607967589909823">Det valgte er</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Ingen ARIA-orienteringspunkter.</translation>
-<translation id="8153880621934657047">Ikke i tabel.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{understregning}one{# understregninger}other{# understregninger}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">klip.</translation>
-<translation id="8199231515320852133">Offentliggør overskrifterne for den aktuelle celle</translation>
-<translation id="820417203470636242">Tom celle.</translation>
-<translation id="8215202828671303819">Valg af flere</translation>
-<translation id="8276439074553447000">Gå til forrige element, der kan fokuseres på</translation>
-<translation id="8278417001922463147">Ingen tidligere artikel.</translation>
-<translation id="8283603667300770666">Næste formularfelt</translation>
-<translation id="831207808878314375">Definition</translation>
-<translation id="8313653172105209786">map</translation>
-<translation id="8344569602005188545">timer</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{pund}one{# pund-tegn}other{# pund-tegn}}</translation>
-<translation id="8374154622594089836">måned</translation>
-<translation id="8378855320830505539">Område</translation>
-<translation id="8382679411218029383">Autofuldførelse på linje og på liste</translation>
-<translation id="8428603554127842284">niveau <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Ikke flere niveau 3-overskrifter.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Ingen tidligere afkrydsningsfelter.</translation>
-<translation id="8455868257606149352">Maksimum <ph name="X" /></translation>
-<translation id="84575901236241018">har hurtigtasten <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Mindsk detaljegraden for navigation</translation>
-<translation id="8520472399088452386">Skalafelt</translation>
-<translation id="8538744478902126321">Giv et bud på rækkeoverskriften for den aktuelle celle</translation>
-<translation id="8540054775867439484">Ombrudt til toppen</translation>
-<translation id="8548973727659841685">Tegn</translation>
-<translation id="8561322612995434619">har pop op-vindue</translation>
-<translation id="8571096049907249734">flr vlg</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Næste element på listen</translation>
-<translation id="860150890330522909">Afkrydsningsfeltet <ph name="NAME" /> er markeret</translation>
-<translation id="8606621670302093223">Datokontrol</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> elementer er valgt</translation>
-<translation id="8638532244051952400">Oplys aktuelle cellekoordinater</translation>
-<translation id="8650576015643545550">Ingen tidligere lister.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Vis liste over links</translation>
-<translation id="8664519043722036194">sekunder</translation>
-<translation id="867187640362843212">Overskrift 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{streg}one{# lodrette streger}other{# lodrette streger}}</translation>
-<translation id="8735450637152821465">Det valgte startes</translation>
-<translation id="8743786158317878347">indtast struktureret indhold, f.eks. tabeller</translation>
-<translation id="8747966237988593539">Sorteret liste</translation>
-<translation id="8759334257841767240">Ikke flere links.</translation>
-<translation id="8767968232364267681">Næste niveau 4-overskrift</translation>
-<translation id="8770473310765924354">luk struktureret indhold, som f.eks. tabeller</translation>
-<translation id="8791025954632646584">Semantik til</translation>
-<translation id="8796411681063377102">Næste niveau 3-overskrift</translation>
-<translation id="8808582214901541005">Marts</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">hovd</translation>
-<translation id="8856538297388979332">Tryk op eller ned for at gennemse kommandoer, og tryk på Enter for at aktivere</translation>
-<translation id="8864099967139188018">Ikke flere niveau 6-overskrifter.</translation>
-<translation id="8882002077197914455">Rækkeoverskrift</translation>
-<translation id="8896347895970027998">Aktivér eller deaktiver ChromeVox.</translation>
-<translation id="8898516272131543774">Cyklus for ekko ved tegnsætning</translation>
-<translation id="8900148057318340779">Præfikstast</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Tomme overskrifter</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Ændringstaster</translation>
-<translation id="8943175951035496220">Ingen celle til højre.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">fil</translation>
-<translation id="9027462562263121875">Ingen tabeller.</translation>
-<translation id="9040132695316389094">Overskrift 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Slå søgewidget til og fra</translation>
-<translation id="9065283790526219006">+pop op-vindue</translation>
-<translation id="9077213568694924680">fjernet fra det valgte</translation>
-<translation id="9082874451376019682">Ingen tidligere skydere.</translation>
-<translation id="9089864840575085222">Cyklus for ekko ved indtastning</translation>
-<translation id="9107530006868467849">Der er ikke nogen tidligere mediewidgets.</translation>
-<translation id="9108370397979208512">matematik</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{procent}one{# procenttegn}other{# procenttegn}}</translation>
-<translation id="9115913704608474258">November</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Angiver en kort beskrivelse af den aktuelle position</translation>
-<translation id="9153606228985488238">Toneleje <ph name="PERCENT" /> procent</translation>
-<translation id="9160096769946561184">Gå til slutningen af ​​den aktuelle kolonne</translation>
-<translation id="9173115498289768110">Lydstyrke <ph name="PERCENT" /> procent</translation>
-<translation id="9178973770513562274">Brug pil op og ned til at gennemse, eller indtast for at søge.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">Der er ikke flere afsnit.</translation>
-<translation id="930275611743429116">Start eller afslut det valgte.</translation>
-<translation id="948171205378458592">Skru ned for talehastighed</translation>
-<translation id="962913030769097253">Næste niveau 1-overskrift</translation>
-<translation id="973955474346881951">Aktivér/deaktiver sticky-tilstand</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_de.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_de.xtb
deleted file mode 100644
index 9e14f204ecd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_de.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="de">
-<translation id="1012173283529841972">Listenelement</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Übergreifend</translation>
-<translation id="1025074108959230262">Fixierter Modus deaktiviert</translation>
-<translation id="1031961866430398710">und</translation>
-<translation id="1044777062731150180">Keine Überschriften</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Ungültige Eingabe</translation>
-<translation id="1082209053475788238">Keine vorherige Überschrift der Ebene 6</translation>
-<translation id="1088219014394087294">Keine Überschriften</translation>
-<translation id="1106741348836243114">Akustisches Feedback (Earcons) aktivieren bzw. deaktivieren</translation>
-<translation id="1120743664840974483">{"a": "Anton", "b": "Berta", "c": "Cäsar", "d": "Dora", "e": "Emil", "f": "Friedrich", "g": "Gustav", "h": "Heinrich", "i": "Ida", "j": "Julius","k": "Kaufmann", "l": "Ludwig", "m": "Martha", "n": "Nordpol", "o": "Otto","p": "Paula", "q": "Quelle", "r": "Richard", "s": "Samuel", "t": "Theodor", "u": "Ulrich", "v": "Viktor", "w": "Wilhelm","x": "Xanthippe", "y": "Ypsilon", "z": "Zacharias"}</translation>
-<translation id="113582498867142724"><ph name="TAG" />-Sammlung mit <ph name="NUM" /> Elementen</translation>
-<translation id="1155043339247954670">Kein nächstes Listenelement</translation>
-<translation id="1157782847298808853">Tastaturhilfe</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, Kombinationsfeld "<ph name="NAME" />"</translation>
-<translation id="1167230103353892028">Menüpunkt "<ph name="NAME" />" mit Untermenü</translation>
-<translation id="1177863135347784049">Benutzerdefiniert</translation>
-<translation id="1188858454923323853">ergänzend</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – eine Stimme für Chrome</translation>
-<translation id="1229276918471378188">Vorheriger Sprung</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Nächste Überschrift der Ebene 6</translation>
-<translation id="1275718070701477396">Ausgewählt</translation>
-<translation id="1319608975892113573">Kein vorheriges blockquote-Element</translation>
-<translation id="1321576897702511272">ChromeVox-Hilfe ausblenden</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> von <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">Zeichen- und Wortecho</translation>
-<translation id="1339428534620983148">Vorherige Tabellenspalte</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Rechts</translation>
-<translation id="136718599399906424">Nächste Tabellenzeile</translation>
-<translation id="1383876407941801731">Suchen</translation>
-<translation id="1385214448885562192">Drücken Sie zum Bestätigen die Eingabetaste, zum Abbrechen die Esc-Taste, zum Aufrufen des nächsten Ergebnisses den Abwärtspfeil und des vorherigen Ergebnisses den Aufwärtspfeil.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, Passwort-Textfeld</translation>
-<translation id="1467432559032391204">Links</translation>
-<translation id="1474557363159888097">Kein vorheriges Ankerelement</translation>
-<translation id="1502086903961450562">Vorherige Grafik</translation>
-<translation id="1506187449813838456">Tonhöhe erhöhen</translation>
-<translation id="151784044608172266">Nächster Satz</translation>
-<translation id="1524531499102321782">Braille – nächste Zeile</translation>
-<translation id="1546370775711804143">Bildlaufleiste</translation>
-<translation id="1559739829547075274">Zurück navigieren</translation>
-<translation id="1571643229714746283">ChromeVox bereit</translation>
-<translation id="158493514907962286">Dezember</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Zu 6-Punkt-Braille wechseln</translation>
-<translation id="1611168825862729585">Spaltenüberschrift:</translation>
-<translation id="1613476421962910979">Earcons sind aktiviert.</translation>
-<translation id="1618597272655350600">Vollständige Beschreibung der aktuellen Position ansagen</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{Größer-als-Zeichen}other{# Größer-als-Zeichen}}</translation>
-<translation id="1653266918374749391">Vorherige Überschrift der Ebene 3</translation>
-<translation id="1659072772017912254">Nicht aktiviert</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">ChromeVox-Navigation</translation>
-<translation id="16777221443363124">Menüleiste</translation>
-<translation id="1692077714702418899">Strukturlinie</translation>
-<translation id="1700517974991662022">Besucht</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Nächste Grafik</translation>
-<translation id="1781173782405573156">Taste ignorieren</translation>
-<translation id="1787176709638001873">Text für Passwort bearbeiten</translation>
-<translation id="1810107444790159527">Listenfeld</translation>
-<translation id="1828385960365606039">Mai</translation>
-<translation id="1834891354138622109">Spalte</translation>
-<translation id="1865601187525349519">Ende des Texts</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Uhrzeit und Datum ansagen</translation>
-<translation id="1902396333223336119">Zelle</translation>
-<translation id="1905379170753160525">Überschriftenliste anzeigen</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Steuerung für Kalenderwoche</translation>
-<translation id="1964135212174907577">Nächstes Objekt</translation>
-<translation id="1969092762068865084">Juli</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Zeilenüberschrift:</translation>
-<translation id="2002895034995108595">Aktuelle Tastaturbelegung zurücksetzen</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{eckige Klammer links}other{# eckige Klammern links}}</translation>
-<translation id="2045490512405922022">nicht aktiviert</translation>
-<translation id="20601713649439366">Kein vorheriger mathematischer Ausdruck</translation>
-<translation id="207477615537953741">Semantische Interpretation aus</translation>
-<translation id="2086961585857038472">Nächstes Wort</translation>
-<translation id="2089387485033699258">de</translation>
-<translation id="2091933974477985526">Vorheriger bearbeitbarer Textbereich</translation>
-<translation id="2100350898815792233">Alle Satzzeichen</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">Zugriffsschlüssel: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Ändern Sie die aktuelle 6-Punkt-Brailletabelle durch Auswählen einer Option aus der unten stehenden Liste.</translation>
-<translation id="2169714232367507776">Auf aktuelles Element klicken</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{runde Klammer zu}other{# runde Klammern zu}}</translation>
-<translation id="2199994615414171367">Vorheriger mathematischer Ausdruck</translation>
-<translation id="2223693656926968778">Aktion für aktuelles Element durchführen</translation>
-<translation id="225732394367814946">Sprechgeschwindigkeit erhöhen</translation>
-<translation id="2267945578749931355">Nächstes Zeichen</translation>
-<translation id="2281234842553884450">Vorheriger Schieberegler</translation>
-<translation id="2318372665160196757">Hauptinhalt</translation>
-<translation id="2329324941084714723">Tabsteuerfeld</translation>
-<translation id="2344193891939537199">Steuerung für Uhrzeit/Datum</translation>
-<translation id="2359897517538099099">Tabellenmodus ist nicht aktiviert.</translation>
-<translation id="241124561063364910">gefolgt von</translation>
-<translation id="2417569100218200841">Inhaltsinfo</translation>
-<translation id="2422937916923936891">Kästchen für Menüpunkt</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> ist jetzt der neue Modifikator für ChromeVox.</translation>
-<translation id="2450814015951372393">Kästchen</translation>
-<translation id="2462626033734746142">Optionsfeldgruppe</translation>
-<translation id="2471138580042810658">Überschrift 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{Sternchen}other{# Sternchen}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> wurde zurückgesetzt.</translation>
-<translation id="2553108862507765288">Grammatikfehler</translation>
-<translation id="257674075312929031">Gruppe</translation>
-<translation id="2582407057977008361">Aside-Element</translation>
-<translation id="2589102159832527089">Diese Seite enthält automatisch aus der PDF-Datei &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; extrahierten Text. &lt;a href ="<ph name="URL" />"&gt;Klicken Sie hier, um das Original abzurufen.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">mit {COUNT,plural, =1{# Eintrag}other{# Einträgen}}</translation>
-<translation id="2614981083756825552">MathML-Layout</translation>
-<translation id="2626530649491650971">anklickbar</translation>
-<translation id="2628764385451019380">Kein vorheriges Kombinationsfeld</translation>
-<translation id="2637227747952042642">Mathematik</translation>
-<translation id="2639750663247012216">ChromeVox-Modifikator</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">Auf das Element unter einem Routing-Schlüssel klicken</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{runde Klammer auf}other{# runde Klammern auf}}</translation>
-<translation id="2705875883745373140">Nicht gedrückt</translation>
-<translation id="2706462751667573066">Aufwärts</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">Audio</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Aktiviert</translation>
-<translation id="27527859628328957">Zum nächsten fokussierbaren Element springen</translation>
-<translation id="2770781857296573485">Gruppenerkundung starten</translation>
-<translation id="2777845298774924149">Beendet</translation>
-<translation id="2800204403141299078">Keine weiteren anderen Elemente</translation>
-<translation id="2800780099804980316">Keine vorherige Überschrift der Ebene 1</translation>
-<translation id="2811204574343810641">Zeile</translation>
-<translation id="2816654101880605877">Kein nächster Schieberegler</translation>
-<translation id="2841013758207633010">Zeit</translation>
-<translation id="2843837985843789981">Vorherige Gruppe</translation>
-<translation id="2844995807198708617">Kontextmenü</translation>
-<translation id="2849332794118375855">Kein nächstes Kästchen</translation>
-<translation id="2864481629947106776">Vorheriger Link</translation>
-<translation id="2873259058405069099">Zum Anfang der Tabelle gehen</translation>
-<translation id="2894654529758326923">Informationen</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{geschweifte Klammer links}other{# geschweifte Klammern links}}</translation>
-<translation id="2911433807131383493">ChromeVox-Anleitung öffnen</translation>
-<translation id="2932083475399492303">Zwischen den Zeilenarten "Struktur" und "Layout" wechseln</translation>
-<translation id="2964026537669811554">Heading group-Element</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{Tabulatorzeichen}other{# Tabulatorzeichen}}</translation>
-<translation id="2972078295414139404">Kein vorheriger besuchter Link</translation>
-<translation id="2972205263822847197">Kurzinfo</translation>
-<translation id="2998131015536248178">Vorheriges Zeichen</translation>
-<translation id="2999559350546931576">Tonhöhe verringern</translation>
-<translation id="2999945368667127852">Kein weiteres Medien-Widget</translation>
-<translation id="3012414509011670858">Kein vorheriger Abschnitt</translation>
-<translation id="3030432017085518523">Optionsfeld für Menüpunkt</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{Apostroph}other{# Apostrophe}}</translation>
-<translation id="3046838483509668188">ChromeVox-Optionen</translation>
-<translation id="3047143736589213134">Experimentelle Tastaturbelegung</translation>
-<translation id="3060756054951570867">Menü "<ph name="TITLE" />" geöffnet</translation>
-<translation id="3078345202707391975">Nächste Überschrift der Ebene 2</translation>
-<translation id="3078740164268491126">Tabelle</translation>
-<translation id="3082557070674409251">Angeklickt</translation>
-<translation id="3084806535845658316">Kein Eingabeecho</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Kein weiterer mathematischer Ausdruck</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Nächste Markierung</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Minimiert</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Liste der Markierungen anzeigen</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Nächste Zeile</translation>
-<translation id="3155083529632865074">Keine vorherige Schaltfläche</translation>
-<translation id="3163593631834463955">Spaltenüberschrift leer</translation>
-<translation id="316542773973815724">Navigation</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{Leerzeichen}other{# Leerzeichen}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> eingegeben</translation>
-<translation id="3223701887221307104">Tab "<ph name="NAME" />"</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Besuchter Link</translation>
-<translation id="323731244387692321">ChromeVox-Tastaturhilfe öffnen</translation>
-<translation id="3241052487511142956">Vorheriger besuchter Link</translation>
-<translation id="3286390186030710347">Schieberegler</translation>
-<translation id="3299925995433437805">Kein nächster besuchter Link</translation>
-<translation id="3303384412438961941">Drücken Sie auf eine beliebige Taste, um den Namen zu erfahren. Mit Strg + W wird Keyboard Explorer geschlossen.</translation>
-<translation id="3307886118343381874">Zum Ende der Tabelle gehen</translation>
-<translation id="3311969765485641742">Drücken Sie Alt + Shift + A, um die Benachrichtigungen aufzurufen.</translation>
-<translation id="3312997241656799641">Nächster besuchter Link</translation>
-<translation id="3321460131042519426">Zeilenumbruch aktivieren</translation>
-<translation id="3322936298410871309">Vorherige Überschrift der Ebene 1</translation>
-<translation id="3323447499041942178">Textfeld</translation>
-<translation id="3353420241558113817">{"ar": "Arabisch",
- "bg": "Bulgarisch",
- "ca": "Katalanisch",
- "cs": "Tschechisch",
- "da": "Dänisch",
- "de": "Deutsch",
- "de_CH": "Deutsch (Schweiz)",
- "de_DE": "Deutsch (Deutschland)",
- "el": "Griechisch",
- "en": "Englisch",
- "en_CA": "Englisch (Kanada)",
- "en_GB": "Englisch (Vereinigtes Königreich)",
- "en_US": "Englisch (USA)",
- "es": "Spanisch",
- "et": "Estnisch",
- "fr": "Französisch",
- "fr_CA": "Französisch (Kanada)",
- "fr_FR": "Französisch (Frankreich)",
- "fi": "Finnisch",
- "he": "Hebräisch",
- "hi": "Hindi",
- "hr": "Kroatisch",
- "hu": "Ungarisch",
- "is": "Isländisch",
- "it": "Italienisch",
- "ko": "Koreanisch",
- "lt": "Litauisch",
- "lv": "Lettisch",
- "nb": "Norwegisch (Bokmål)",
- "nl": "Niederländisch",
- "pl": "Polnisch",
- "pt": "Portugiesisch",
- "ro": "Rumänisch",
- "ru": "Russisch",
- "sk": "Slowakisch",
- "sl": "Slowenisch",
- "sr": "Serbisch",
- "sv": "Schwedisch",
- "tr": "Türkisch",
- "vi": "Vietnamesisch",
- "zh": "Chinesisch",
- "zh_TW": ""Chinesisch (Traditionelles Han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{Pluszeichen}other{# Pluszeichen}}</translation>
-<translation id="338583716107319301">Trennzeichen</translation>
-<translation id="3389259863310851658">Vorheriges Formularfeld</translation>
-<translation id="3390225400784126843">Nächstes anderes Element</translation>
-<translation id="3392045790598181549">Menüeintrag "<ph name="NAME" />"</translation>
-<translation id="3406283310380167331">Formularliste anzeigen</translation>
-<translation id="3422338090358345848">Keyboard Explorer öffnen</translation>
-<translation id="3457000393508828486">Teilweise gedrückt</translation>
-<translation id="3462439746547587373">Schaltfläche "<ph name="NAME" />"</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> bis <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{eckige Klammer rechts}other{# eckige Klammern rechts}}</translation>
-<translation id="3493915602752813531">Kein nächstes Ankerelement</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{Fragezeichen}other{# Fragezeichen}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{Caret-Zeichen}other{# Caret-Zeichen}}</translation>
-<translation id="3568702578574425662">Kästchen "<ph name="NAME" />" ist nicht aktiviert.</translation>
-<translation id="3599054940393788245">Nicht in Mathematik</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{Backtick}other{# Backticks}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{Dollarzeichen}other{# Dollarzeichen}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, Listenfeld</translation>
-<translation id="3687295507293856493">Spaltenüberschrift der aktuellen Zelle vorschlagen</translation>
-<translation id="3692274950075847560">S: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Sprachausgabe steuern</translation>
-<translation id="3716845769494773620">Mehrzeilig</translation>
-<translation id="3731746171184829332">Keine vorherige Überschrift</translation>
-<translation id="3762198587642264450">Zum Ende der aktuellen Zeile gehen</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Dialogfeld geschlossen</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Liste der Autovervollständigungen</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Nächstes Medium</translation>
-<translation id="3819376190738087562">Keine Sprünge</translation>
-<translation id="385383972552776628">Seite "Optionen" öffnen</translation>
-<translation id="3856075812838139784">Schreibgeschützt</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menü</translation>
-<translation id="3909320334364316587">Vorherige Überschrift der Ebene 6</translation>
-<translation id="3914173277599553213">Erforderlich</translation>
-<translation id="3962990492275676168">Ab der aktuellen Position lesen</translation>
-<translation id="4004802134384979325">Aktiviert</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Steuerung für Monat</translation>
-<translation id="4039983576244166038">Zeilenüberschrift leer</translation>
-<translation id="4042843249978639960">Keine nächste Überschrift der Ebene 2</translation>
-<translation id="4043348641337972076">Keine vorherige ARIA-Markierung</translation>
-<translation id="4047216625641135770">Mark-Element</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{Tilde}other{# Tilden}}</translation>
-<translation id="409334809956508737">Vorheriges Objekt</translation>
-<translation id="4099274309791143834">mit Untermenü</translation>
-<translation id="4107807507418787238">Keine Zelle unterhalb</translation>
-<translation id="4116415223832267137">Benachrichtigung</translation>
-<translation id="4147126331795725888">Kein weiteres Steuerelement</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{geschweifte Klammer rechts}other{# geschweifte Klammern rechts}}</translation>
-<translation id="4158704014418536539">Groß- und Kleinschreibung wird beachtet.</translation>
-<translation id="4161663686871496107">Das gesprochene Feedback von ChromeVox ist bereit.</translation>
-<translation id="4173994908659439270">Kein nächstes bearbeitbares Textfeld</translation>
-<translation id="4176463684765177261">Deaktiviert</translation>
-<translation id="4188530942454211480">Vorheriger Satz</translation>
-<translation id="4202186506458631436">Nach rechts</translation>
-<translation id="4206289001967551965">In der Tabelle</translation>
-<translation id="4215733775853809057">Nächster Schieberegler</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{Gedankenstrich}other{# Gedankenstriche}}</translation>
-<translation id="421884353938374759">color picker</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">Keine Zelle links</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, Grad <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Notiz</translation>
-<translation id="4254798249533888099">Baumstruktur</translation>
-<translation id="4255943572433203166">Verwenden Sie die Optionen unten, um ChromeVox anzupassen. Änderungen werden sofort wirksam.</translation>
-<translation id="4271220233568730077">Nächster mathematischer Ausdruck</translation>
-<translation id="4271521365602459209">Keine weiteren Ergebnisse</translation>
-<translation id="4287520460805643128">Kein weiterer Artikel</translation>
-<translation id="4289540628985791613">Übersicht</translation>
-<translation id="4300318234632215983">URL hinter einem Link ansagen</translation>
-<translation id="4301352596632316575">enthält ein Untermenü</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{Punkt}=3{Auslassungspunkte}other{# Punkte}}</translation>
-<translation id="4347461890115250064">Keine nächste Liste</translation>
-<translation id="4367650418938037324">MathML-Blattknoten</translation>
-<translation id="4372435075475052704">Mind.: <ph name="X" /></translation>
-<translation id="4372705107434148843">Sprachausgabe anhalten</translation>
-<translation id="4373197658375206385">Kein vorheriges Element, das kein Link ist</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Keine Links</translation>
-<translation id="4476183483923481720">Neue Zeile</translation>
-<translation id="4482330759234983253">Vorherige Tabelle</translation>
-<translation id="4491109536499578614">Bild</translation>
-<translation id="4529987814483543472">Klassische Tastaturbelegung</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{Schrägstrich}other{# Schrägstriche}}</translation>
-<translation id="4547556996012970016">Nächste Überschrift der Ebene 5</translation>
-<translation id="4562381607973973258">Header-Element</translation>
-<translation id="4591507479202817876">, ausgewählt</translation>
-<translation id="4597532268155981612">Formular</translation>
-<translation id="4597896406374528575">April</translation>
-<translation id="4615592953348396470">Nächster Tastenanschlag wird ignoriert.</translation>
-<translation id="461613135510474570">Satz</translation>
-<translation id="4647836961514597010">Farbauswahl</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Vorherige Markierung</translation>
-<translation id="4696413482802371445">Keine nächste Überschrift der Ebene 5</translation>
-<translation id="4729095194763193578">Vorherige Tabellenzeile</translation>
-<translation id="4736221692378411923">August</translation>
-<translation id="4740661827607246557">Hilfebefehle</translation>
-<translation id="4759716709594980008">Chrome OS Keyboard Explorer</translation>
-<translation id="4763296182459741068">Umbruch am Seitenende</translation>
-<translation id="4763480195061959176">Video</translation>
-<translation id="479989351350248267">Suchen</translation>
-<translation id="481165870889056555">Titel der aktuellen Seite ansagen</translation>
-<translation id="4826415162591436065">Vorwärts navigieren</translation>
-<translation id="4826604887384865800">Nächster Sprung</translation>
-<translation id="4827410568042294688">nicht ausgewählt</translation>
-<translation id="4842108708071771135">Kein nächstes blockquote-Element</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Vorheriges ähnliches Element</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS-Protokollierung aktivieren</translation>
-<translation id="4877261390094455813">Suchanfrage eingeben</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Interner Link</translation>
-<translation id="4953585991029886728">Text bearbeiten</translation>
-<translation id="4954534434583049121">Vorheriges Blockzitat</translation>
-<translation id="4973717656530883744">Mind. <ph name="X" /></translation>
-<translation id="4973762002207131920">Zu <ph name="KEY" /> gewechselt</translation>
-<translation id="4975416682604111799">Millisekunden</translation>
-<translation id="49787999531187221">ChromeVox ist jetzt deaktiviert.</translation>
-<translation id="4979404613699303341">Vorherige Schaltfläche</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, Listenfeld "<ph name="NAME" />"</translation>
-<translation id="4983588134362688868">Zum Seitenanfang</translation>
-<translation id="4986606102545753256">Fenster "<ph name="NAME" />"</translation>
-<translation id="4993152509206108683">Geschwindigkeit: <ph name="PERCENT" /> %</translation>
-<translation id="4996716799442435517">Visuell</translation>
-<translation id="4997282455736854877">Optionsfeld "<ph name="NAME" />" ist ausgewählt.</translation>
-<translation id="4997475792277222884">Kein weiteres Element, das kein Link ist</translation>
-<translation id="5000760171916499057">Keine Formulare</translation>
-<translation id="5005670136041063723">Keine weiteren ähnlichen Elemente</translation>
-<translation id="501473567976723023">Januar</translation>
-<translation id="5041394372352067729">Braillezeile an den Seitenanfang verschieben</translation>
-<translation id="5042770794184672516">Sprachlautstärke erhöhen</translation>
-<translation id="5050015258024679800">Vorherige Überschrift der Ebene 4</translation>
-<translation id="5054047268577924192">Vorheriges Listenelement</translation>
-<translation id="5078661581131202757">Dateiauswahl</translation>
-<translation id="5080758118274074384">Doppelgeklickt</translation>
-<translation id="5098541983634824365">Raster wird verlassen.</translation>
-<translation id="5102981729317424850">Symbolleiste</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Kein vorheriges Formularfeld</translation>
-<translation id="5111640677200759579">Spaltenüberschrift</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Kein vorheriger Link</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, nicht ausgewählt</translation>
-<translation id="5183440668879371625">Braille – vorherige Zeile</translation>
-<translation id="5184944171021383281">Kein nächstes Formularfeld</translation>
-<translation id="5189244881767082992">Zeile</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> ist bereits einem Befehl zugewiesen.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" />-Liste</translation>
-<translation id="520883772648104506">Kein nächstes Optionsfeld</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Ende</translation>
-<translation id="5291783959063340370">Objekt</translation>
-<translation id="5304943142864553931">Tab "<ph name="TITLE" />"</translation>
-<translation id="5310788376443009632">Entfernt:</translation>
-<translation id="5320727453979144100">Fixierter Modus aktiviert</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{Komma}other{# Kommas}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, Textfeld</translation>
-<translation id="5330443287809544590">Link "<ph name="NAME" />"</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Im kontinuierlichen Lesemodus rückwärts springen</translation>
-<translation id="5368000168321181111">Earcons sind deaktiviert.</translation>
-<translation id="5374320867641260420">Keine nächste Schaltfläche</translation>
-<translation id="5382299583965267720">Keine nächste Überschrift der Ebene 1</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{Strichpunkt}other{# Strichpunkte}}</translation>
-<translation id="5411891038905756502">Kein vorheriger Ausgangspunkt</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{Kleiner-als-Zeichen}other{# Kleiner-als-Zeichen}}</translation>
-<translation id="5455441614648621694">Ergänzend</translation>
-<translation id="5485036206801896268">Keine vorherige Grafik</translation>
-<translation id="5486947920110100234">Kein nächster Ausgangspunkt</translation>
-<translation id="549602578321198708">Wort</translation>
-<translation id="5500932716852106146">Kein vorheriges bearbeitbares Textfeld</translation>
-<translation id="5502713021410870035">September</translation>
-<translation id="5507663321906818013">Debug-Benchmark</translation>
-<translation id="5518443085409638729">Cursor beim Bearbeiten von Text zwischen die Zeichen setzen (wie Mac OS X)</translation>
-<translation id="552195134157544755">Optionsfeld</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Keine vorherige Überschrift der Ebene 5</translation>
-<translation id="556042886152191864">Schaltfläche</translation>
-<translation id="5561345396546889625">Nächste Liste</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Rücktaste</translation>
-<translation id="5585044216466955529">Text bearbeiten, E-Mail-Eintrag</translation>
-<translation id="5597170376237141345">Nächstes Kästchen</translation>
-<translation id="5597933780944041114">Keine nächste Überschrift</translation>
-<translation id="5598905979683743333">Optionsfeld "<ph name="NAME" />" ist nicht aktiviert.</translation>
-<translation id="5601172225407283979">Standardaktion ausführen</translation>
-<translation id="5608798115546226984">Inline-Autovervollständigung</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Protokoll</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Keine vorherige Tabelle</translation>
-<translation id="5655682562155942719">Zwischen Befehlen wechseln</translation>
-<translation id="56637627897541303">Textbereich</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Markierung</translation>
-<translation id="5683155931978483559">Vorheriges Kästchen</translation>
-<translation id="5684277895745049190">Liste</translation>
-<translation id="5700650669149824506">Keine vorherige Überschrift der Ebene 4</translation>
-<translation id="5709192780268610569">Keine ausführliche Beschreibung</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Nächste Tabellenspalte</translation>
-<translation id="571866080859340309">Gruppen erkunden</translation>
-<translation id="5728409797179002635">Keine Tabelle gefunden</translation>
-<translation id="5748623122140342504">Vorherige Überschrift der Ebene 5</translation>
-<translation id="5750633686117194034">Sie haben keinen Modifikator gedrückt. Drücken und halten Sie mindestens einen Modifikator, heben Sie anschließend die Finger an und hören Sie, welche Tasten gewählt wurden. Beenden Sie mit der Tabulatortaste.</translation>
-<translation id="5788275253279308023">Inkognito-Fenster, Tab "<ph name="TITLE" />"</translation>
-<translation id="5806206155699461681">Bestimmte Websites optimieren, zum Beispiel die Google-Suche</translation>
-<translation id="5819072574982403430">Baumelement</translation>
-<translation id="5826479389509458994"><ph name="ROW" />. Zeile, <ph name="COL" />. Spalte</translation>
-<translation id="5850707923114094062">Nach hinten schwenken</translation>
-<translation id="5851548754964597211">Tab-Liste</translation>
-<translation id="5859752971144398932">Suche auf der Seite beendet</translation>
-<translation id="5866042630553435010">Teilweise aktiviert</translation>
-<translation id="5869546221129391014">Raster</translation>
-<translation id="5876817486144482042">Sprachlautstärke verringern</translation>
-<translation id="5887397643266327462">Braille-Untertitel aktiviert</translation>
-<translation id="5891934789323004067">Tabelle</translation>
-<translation id="5919442531159595654">kopieren</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{Gleichheitszeichen}other{# Gleichheitszeichen}}</translation>
-<translation id="5939518447894949180">Zurücksetzen</translation>
-<translation id="5948123859135882163">Interpretation mathematischer Ausdrücke zwischen strukturell und semantisch umschalten</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialogfeld</translation>
-<translation id="5963413905009737549">Section-Element</translation>
-<translation id="5968607524793740041">Kontextmenü anzeigen</translation>
-<translation id="5983179082906765664">Navigationsgenauigkeit erhöhen</translation>
-<translation id="5999630716831179808">Stimmen</translation>
-<translation id="6000417740266304866">Ändern Sie die aktuelle 8-Punkt-Brailletabelle durch Auswahl einer Option aus der unten stehenden Liste.</translation>
-<translation id="6006050241733874051">Formular</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{umgekehrter Schrägstrich}other{# umgekehrte Schrägstriche}}</translation>
-<translation id="6037602951055904232">Nach vorn verschieben</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Ende der Zelle</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Leerzeichen</translation>
-<translation id="6142308968191113180">Überschrift 4</translation>
-<translation id="6169420925157477918">Bild mit ausführlicher Beschreibung</translation>
-<translation id="6172087735260766220">Kein Zugriff auf Text für Bedienungshilfen im kopiergeschützten PDF.</translation>
-<translation id="6186305613600865047">Zum Seitenende</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Abwärts</translation>
-<translation id="6236061028292614533">Nächste Überschrift</translation>
-<translation id="6254901459154107917">Nächster bearbeitbarer Textbereich</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> beendet</translation>
-<translation id="6281876499889881039">Nächstes ähnliches Element</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Kein nächstes Kombinationsfeld</translation>
-<translation id="6307969636681130414">Gedrückt</translation>
-<translation id="6324551002951139333">Grammatikfehler gefunden</translation>
-<translation id="6348657800373377022">Kombinationsfeld</translation>
-<translation id="6355910664415701303">Kein vorheriges Listenelement</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Vorherige Überschrift</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Kein vorheriges Optionsfeld</translation>
-<translation id="6414968628640960377">Vorheriges anderes Element</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{Doppelpunkt}other{# Doppelpunkte}}</translation>
-<translation id="6438968337250688271">Menü "<ph name="NAME" />"</translation>
-<translation id="6444046323172968959">Benachrichtigungsdialogfeld</translation>
-<translation id="6459511626086141404">Flache Tastaturbelegung</translation>
-<translation id="6468049171101508116">Nächste Schaltfläche</translation>
-<translation id="6491972999578897419">Ändern Sie die aktuelle Stimme, indem Sie eine Option aus der Liste unten auswählen.</translation>
-<translation id="6508059270146105198">Braillezeile ans Seitenende verschieben</translation>
-<translation id="6536864053412760904">MathML-Token</translation>
-<translation id="6550720799683018100">Ändern Sie die aktuelle Tastaturbelegung, indem Sie eine Option aus der Liste unten auswählen.</translation>
-<translation id="6561818612645211875">Zum Anfang der aktuellen Zeile gehen</translation>
-<translation id="6587021927234520429">Keine nächste Überschrift der Ebene 4</translation>
-<translation id="6601344353291556895">Ausführliche Beschreibungen aktivieren</translation>
-<translation id="6615602925644411249">Auf Seite suchen</translation>
-<translation id="6633350132811819843">Keine nächste Tabelle</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Statusanzeige</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Vorheriges Kombinationsfeld</translation>
-<translation id="6714813999819678458">Vorherige Überschrift der Ebene 2</translation>
-<translation id="6716505898850596801">Modifikatortasten</translation>
-<translation id="671916444866103745">Keine nächste ARIA-Markierung</translation>
-<translation id="6734854816611871228">Kombinationsfeld <ph name="VALUE" /></translation>
-<translation id="6735257939857578167">mit <ph name="NUM" /> Elementen</translation>
-<translation id="6736510033526053669">Tab erstellt</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Article-Element</translation>
-<translation id="6787839852456839824">Tastenkombinationen</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Footer-Element</translation>
-<translation id="6871161210040114857">Groß- und Kleinschreibung wird nicht beachtet.</translation>
-<translation id="6877435256196695200">Keine nächste Grafik</translation>
-<translation id="6897341342232909480">Nach links</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Gelöscht</translation>
-<translation id="6911965441508464308">Keine Zelle oberhalb</translation>
-<translation id="6919104639734799681">Tabellenliste anzeigen</translation>
-<translation id="6964088412282673743">Kein vorheriges Steuerelement</translation>
-<translation id="6996566555547746822">Nächstes Kombinationsfeld</translation>
-<translation id="7005146664810010831">Keine URL gefunden</translation>
-<translation id="7010712454773919705">ChromeVox-Modifikatortaste</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Vorherige Liste</translation>
-<translation id="7041173719775863268">Auswahl beenden</translation>
-<translation id="7095834689119144465">Nur numerischen Text bearbeiten</translation>
-<translation id="7096001299300236431">Vorheriges Medium</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">Wortecho</translation>
-<translation id="713824876195128146">Nächstes Blockzitat</translation>
-<translation id="7161771961008409533">Pop-up-Schaltfläche</translation>
-<translation id="7167657087543110">Zeichenecho</translation>
-<translation id="7170733337935166589">Im kontinuierlichen Lesemodus vorwärts springen</translation>
-<translation id="7181697990050180700">Passen Sie die Tastenkombinationen für häufig verwendete Befehle an, indem Sie sie unten in die entsprechenden Felder eingeben.</translation>
-<translation id="7203150201908454328">Erweitert</translation>
-<translation id="7210211103303402262">Minuten</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">Zeile</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Überschrift</translation>
-<translation id="7241683698754534149">Ausführliche Beschreibung in neuem Tab öffnen</translation>
-<translation id="7248671827512403053">App</translation>
-<translation id="725969808843520477">Nächstes Optionsfeld</translation>
-<translation id="7269119382257320590">Keine Satzzeichen</translation>
-<translation id="7273174640290488576">Leer</translation>
-<translation id="7285387653379749618">Tabellen</translation>
-<translation id="7289186959554153431">Überschrift 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Braille-Untertitel deaktiviert</translation>
-<translation id="7318872822751139669">Fokus mithilfe der Maus verschieben</translation>
-<translation id="7322388933135261569">Februar</translation>
-<translation id="7332592614823088566">Zeile <ph name="ROWINDEX" /> von <ph name="ROWTOTAL" />, Spalte <ph name="COLINDEX" /> von <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">enthält ein Pop-up-Fenster</translation>
-<translation id="7356165926712028380">Zu 8-Punkt-Braille wechseln</translation>
-<translation id="7362871137496673139">Keine vorherige Überschrift der Ebene 2</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{Und-Zeichen}other{# Und-Zeichen}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Tabelle wird verlassen.</translation>
-<translation id="739763518212184081">Vorherige Zeile</translation>
-<translation id="7400575256015741911">Rechtschreibfehler gefunden</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">Wagenrücklauf</translation>
-<translation id="7434509671034404296">Entwickler</translation>
-<translation id="7439060726180460871">Verzeichnis</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Dialogfeldtext eingegeben</translation>
-<translation id="7532613204005497612">Juni</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, Schieberegler "<ph name="NAME" />"</translation>
-<translation id="7586163296341959563">einfügen</translation>
-<translation id="7596919493010894443">Auswahl gelöscht</translation>
-<translation id="7604026522577407655">Zum Anfang der aktuellen Spalte gehen</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">URL der aktuellen Seite ansagen</translation>
-<translation id="7609363189280667021">Braille-Untertitel aktivieren/deaktivieren</translation>
-<translation id="762020119231868829">Pausiert alle momentan aktiven Medien-Widgets</translation>
-<translation id="7625690649919402823">Nächste Tabelle</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Grad <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Keine vorherige Überschrift der Ebene 3</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, Textfeld "<ph name="NAME" />"</translation>
-<translation id="7663318257180412551">Überschrift 2</translation>
-<translation id="7674576868851035240">Nächster Link</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">Text bearbeiten, URL-Eintrag</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Vorheriges Optionsfeld</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, Passwort-Textfeld "<ph name="NAME" />"</translation>
-<translation id="7805247615045262757">Standardnavigation</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Nächste Gruppe</translation>
-<translation id="7819187121850078213">Fenster, Tab "<ph name="TITLE" />"</translation>
-<translation id="7828956995407538686">Oktober</translation>
-<translation id="7839679365527550018">Vorheriges Wort</translation>
-<translation id="7851816175263618915">Einige Satzzeichen</translation>
-<translation id="7870596830398826354">MathML-Baum</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Klassische ChromeVox-Ansicht umschalten.</translation>
-<translation id="7895896691902835279">Unbekannter Link</translation>
-<translation id="7927711904086083099">Nicht ausgewählt</translation>
-<translation id="7935627501098484003">Zeit-/Datumsangabe</translation>
-<translation id="7939428177581522200">zur Auswahl hinzugefügt</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{At-Zeichen}other{# At-Zeichen}}</translation>
-<translation id="7965147473449754028">Menü geschlossen</translation>
-<translation id="7974390230414479278">Menüpunkt</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{Ausrufezeichen}other{# Ausrufezeichen}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{Anführungszeichen}other{# Anführungszeichen}}</translation>
-<translation id="8033827949643255796">Ausgewählt</translation>
-<translation id="8035962149453661158">Max.: <ph name="X" /></translation>
-<translation id="8042761080832772327">Text bearbeiten, Sucheintrag</translation>
-<translation id="8049189770492311300">Timer</translation>
-<translation id="8065607967589909823">Ausgewählt ist</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Keine ARIA-Markierungen</translation>
-<translation id="8153880621934657047">Nicht in der Tabelle</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{Unterstrich}other{# Unterstriche}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">ausschneiden</translation>
-<translation id="8199231515320852133">Überschriften der aktuellen Zelle ansagen</translation>
-<translation id="820417203470636242">Leere Zelle</translation>
-<translation id="8215202828671303819">Mehrfachauswahl</translation>
-<translation id="8276439074553447000">Zum vorherigen fokussierbaren Element springen</translation>
-<translation id="8278417001922463147">Kein vorheriger Artikel</translation>
-<translation id="8283603667300770666">Nächstes Formularfeld</translation>
-<translation id="831207808878314375">Definition</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">Stunden</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{Doppelkreuz}other{# Doppelkreuze}}</translation>
-<translation id="8374154622594089836">month</translation>
-<translation id="8378855320830505539">Region</translation>
-<translation id="8382679411218029383">Inline-Autovervollständigung und Liste</translation>
-<translation id="8428603554127842284">Ebene <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Keine nächste Überschrift der Ebene 3</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Kein vorheriges Kästchen</translation>
-<translation id="8455868257606149352">Max.: <ph name="X" /></translation>
-<translation id="84575901236241018">verfügt über den Zugriffsschlüssel <ph name="KEY" />.</translation>
-<translation id="8503360654911991865">Navigationsgenauigkeit verringern</translation>
-<translation id="8520472399088452386">Drehfeld</translation>
-<translation id="8538744478902126321">Zeilenüberschrift für aktuelle Zelle vorschlagen</translation>
-<translation id="8540054775867439484">Umbruch am Seitenanfang</translation>
-<translation id="8548973727659841685">Zeichen</translation>
-<translation id="8561322612995434619">enthält ein Pop-up-Fenster</translation>
-<translation id="8571096049907249734">div</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Nächstes Listenelement</translation>
-<translation id="860150890330522909">Kästchen "<ph name="NAME" />" aktiviert</translation>
-<translation id="8606621670302093223">Steuerung für Datum</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> Elemente ausgewählt</translation>
-<translation id="8638532244051952400">Koordinaten der aktuellen Zelle ansagen</translation>
-<translation id="8650576015643545550">Keine vorherige Liste</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Linkliste anzeigen</translation>
-<translation id="8664519043722036194">Sekunden</translation>
-<translation id="867187640362843212">Überschrift 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{senkrechter Strich}other{# senkrechte Striche}}</translation>
-<translation id="8735450637152821465">Auswahl starten</translation>
-<translation id="8743786158317878347">Strukturierte Inhalte wie z. B. Tabellen eingeben</translation>
-<translation id="8747966237988593539">Geordnete Liste</translation>
-<translation id="8759334257841767240">Kein nächster Link</translation>
-<translation id="8767968232364267681">Nächste Überschrift der Ebene 4</translation>
-<translation id="8770473310765924354">Strukturierte Inhalte wie z. B. Tabellen beenden</translation>
-<translation id="8791025954632646584">Semantische Interpretation an</translation>
-<translation id="8796411681063377102">Nächste Überschrift der Ebene 3</translation>
-<translation id="8808582214901541005">März</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Drücken Sie die Nach-oben- oder Nach-unten-Taste, um die Befehle durchzusehen. Drücken Sie die Eingabetaste, um einen Befehl zu aktivieren.</translation>
-<translation id="8864099967139188018">Keine nächste Überschrift der Ebene 6</translation>
-<translation id="8882002077197914455">Zeilenüberschrift</translation>
-<translation id="8896347895970027998">ChromeVox aktivieren oder deaktivieren</translation>
-<translation id="8898516272131543774">Satzzeichenecho wiederholen</translation>
-<translation id="8900148057318340779">Präfix-Taste</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Überschriften leer</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Modifikatortasten</translation>
-<translation id="8943175951035496220">Keine Zelle rechts</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Keine Tabellen</translation>
-<translation id="9040132695316389094">Überschrift 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Such-Widget aktivieren/deaktivieren</translation>
-<translation id="9065283790526219006">+ Pop-up-Fenster</translation>
-<translation id="9077213568694924680">aus der Auswahl entfernt</translation>
-<translation id="9082874451376019682">Kein vorheriger Schieberegler</translation>
-<translation id="9089864840575085222">Eingabeecho wiederholen</translation>
-<translation id="9107530006868467849">Kein vorheriges Medien-Widget</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{Prozentzeichen}other{# Prozentzeichen}}</translation>
-<translation id="9115913704608474258">November</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Kurze Beschreibung der aktuellen Position ansagen</translation>
-<translation id="9153606228985488238">Tonhöhe: <ph name="PERCENT" /> %</translation>
-<translation id="9160096769946561184">Zum Ende der aktuellen Spalte gehen</translation>
-<translation id="9173115498289768110">Lautstärke: <ph name="PERCENT" /> %</translation>
-<translation id="9178973770513562274">Drücken Sie die Aufwärtspfeil- bzw. Abwärtspfeil-Taste, um den Inhalt zu durchsuchen, oder geben Sie eine Suchanfrage ein.</translation>
-<translation id="9192904702577636854">Laufschrift</translation>
-<translation id="9212322457209634662">Kein weiterer Abschnitt</translation>
-<translation id="930275611743429116">Auswahl starten oder beenden</translation>
-<translation id="948171205378458592">Sprechgeschwindigkeit verringern</translation>
-<translation id="962913030769097253">Nächste Überschrift der Ebene 1</translation>
-<translation id="973955474346881951">Fixierten Modus aktivieren/deaktivieren</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb
deleted file mode 100644
index f26c8602d59..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="el">
-<translation id="1012173283529841972">Στοιχείο λίστας</translation>
-<translation id="1013742170491673792">αναζήτηση ρόλου</translation>
-<translation id="1023866615269196768">Διευρυμένο.</translation>
-<translation id="1025074108959230262">Η λειτουργία διατήρησης ενδιαφέροντος (Sticky) απενεργοποιήθηκε</translation>
-<translation id="1031961866430398710">τότε</translation>
-<translation id="1044777062731150180">Χωρίς κεφαλίδες</translation>
-<translation id="106222400312645156">κεφαλίδα σειράς</translation>
-<translation id="1065552602950927991">Μη έγκυρη καταχώριση</translation>
-<translation id="1082209053475788238">Δεν υπάρχει προηγούμενη επικεφαλίδα επιπέδου 6.</translation>
-<translation id="1088219014394087294">Δεν υπάρχουν επικεφαλίδες.</translation>
-<translation id="1106741348836243114">Ενεργοποίηση ή απενεργοποίηση των ηχητικών σχολίων (ηχητικά μηνύματα).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Συλλογή <ph name="TAG" /> με <ph name="NUM" /> στοιχεία</translation>
-<translation id="1155043339247954670">Δεν υπάρχει επόμενο στοιχείο στη λίστα.</translation>
-<translation id="1157782847298808853">Βοήθεια πληκτρολογίου</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, σύνθετο πλαίσιο</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, στοιχείο μενού, με υπομενού</translation>
-<translation id="1177863135347784049">Προσαρμοσμένη</translation>
-<translation id="1188858454923323853">συμπληρωματικό</translation>
-<translation id="1206619573307042055">μαρκίζα</translation>
-<translation id="1213216066620407844">ChromeVox - Δίνει φωνή στο Chrome</translation>
-<translation id="1229276918471378188">Προηγούμενη μετάβαση</translation>
-<translation id="1237866625126425153">ομάδα κουμπιών επιλογής</translation>
-<translation id="1251750620252348585">Επικεφαλίδα επόμενου επιπέδου 6</translation>
-<translation id="1275718070701477396">Επιλεγμένο</translation>
-<translation id="1319608975892113573">Δεν υπάρχει προηγούμενη ενότητα σε παράθεση.</translation>
-<translation id="1321576897702511272">Απόκρυψη βοήθειας ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> από <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">εκφώνηση χαρακτήρων και λέξεων</translation>
-<translation id="1339428534620983148">Προηγούμενη στήλη πίνακα</translation>
-<translation id="1342835525016946179">άρθρο</translation>
-<translation id="1346748346194534595">Δεξιά</translation>
-<translation id="136718599399906424">Επόμενη σειρά πίνακα</translation>
-<translation id="1383876407941801731">Αναζήτηση</translation>
-<translation id="1385214448885562192">Πατήστε το πλήκτρο "enter" για αποδοχή ή "escape" για ακύρωση, "down" για το επόμενο και "up" για το προηγούμενο.</translation>
-<translation id="1396114365388024581">λίστα καρτελών</translation>
-<translation id="1439316808600711881">περιοχή</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, πλαίσιο κειμένου κωδικού πρόσβασης</translation>
-<translation id="1467432559032391204">Αριστερά</translation>
-<translation id="1474557363159888097">Δεν υπάρχει προηγούμενη αγκύρωση.</translation>
-<translation id="1502086903961450562">Προηγούμενο γραφικό</translation>
-<translation id="1506187449813838456">Αύξηση τόνου</translation>
-<translation id="151784044608172266">Επόμενη πρόταση</translation>
-<translation id="1524531499102321782">Επόμενη γραμμή μπράιγ</translation>
-<translation id="1546370775711804143">Γραμμή κύλισης</translation>
-<translation id="1559739829547075274">Μετάβαση προς τα πίσω</translation>
-<translation id="1571643229714746283">Το ChromeVox είναι έτοιμο</translation>
-<translation id="158493514907962286">Δεκέμβριος</translation>
-<translation id="1594072653727561613">μενού</translation>
-<translation id="1610130962244179598">Αλλαγή σε εξάστιγμο μπράιγ</translation>
-<translation id="1611168825862729585">Κεφαλίδα στήλης:</translation>
-<translation id="1613476421962910979">Ηχητικά μηνύματα ενεργά</translation>
-<translation id="1618597272655350600">Παρέχει μια πλήρη περιγραφή της τρέχουσας τοποθεσίας</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{σύμβολο "μεγαλύτερο από"}other{# σύμβολα "μεγαλύτερο από"}}</translation>
-<translation id="1653266918374749391">Επικεφαλίδα προηγούμενου επιπέδου 3</translation>
-<translation id="1659072772017912254">Μη επιλεγμένο</translation>
-<translation id="1669290819662866522">εβδομάδα</translation>
-<translation id="1674262202423278359">Πλοήγηση ChromeVox</translation>
-<translation id="16777221443363124">Γραμμή μενού</translation>
-<translation id="1692077714702418899">δομική γραμμή</translation>
-<translation id="1700517974991662022">Σύνδεσμος που έχετε επισκεφτεί</translation>
-<translation id="1722567105086139392">Σύνδεσμος</translation>
-<translation id="1727806147743597030">υποσέλιδο</translation>
-<translation id="174268867904053074">Επόμενο γραφικό</translation>
-<translation id="1781173782405573156">Κλειδί διαβίβασης</translation>
-<translation id="1787176709638001873">Επεξεργασία κειμένου κωδικού πρόσβασης</translation>
-<translation id="1810107444790159527">Πλαίσιο λίστας</translation>
-<translation id="1828385960365606039">Μάιος</translation>
-<translation id="1834891354138622109">Στήλη</translation>
-<translation id="1865601187525349519">Τέλος κειμένου</translation>
-<translation id="1876229593313240038">έγγραφο</translation>
-<translation id="188130072164734898">Εκφώνηση της τρέχουσας ώρας και ημερομηνίας.</translation>
-<translation id="1902396333223336119">Κελί</translation>
-<translation id="1905379170753160525">Εμφάνιση λίστας επικεφαλίδων</translation>
-<translation id="1912556590115083156">σύνδεσμος που επισκεφτήκατε</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Έλεγχος εβδομάδας του έτους</translation>
-<translation id="1964135212174907577">Επόμενο αντικείμενο</translation>
-<translation id="1969092762068865084">Ιούλιος</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Κεφαλίδα γραμμής:</translation>
-<translation id="2002895034995108595">Επαναφορά των τρεχουσών αντιστοιχίσεων πλήκτρων</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{αριστερή αγκύλη}other{# αριστερές αγκύλες}}</translation>
-<translation id="2045490512405922022">μη επιλεγμένο</translation>
-<translation id="20601713649439366">Δεν υπάρχει προηγούμενη μαθηματική έκφραση.</translation>
-<translation id="207477615537953741">Σημασιολογική ερμηνεία ανενεργή</translation>
-<translation id="2086961585857038472">Επόμενη λέξη</translation>
-<translation id="2089387485033699258">el</translation>
-<translation id="2091933974477985526">Προηγούμενη περιοχή κειμένου με δυνατότητα επεξεργασίας</translation>
-<translation id="2100350898815792233">Όλα τα σημεία στίξης</translation>
-<translation id="2119965627982867824">κουμπί αυξομείωσης</translation>
-<translation id="2121067395472282800">κλειδί πρόσβασης:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Αλλάξτε τον τρέχοντα πίνακα εξάστιγμου μπράιγ, ορίζοντας μια επιλογή από την παρακάτω λίστα.</translation>
-<translation id="2169714232367507776">Κλικ στο τρέχον στοιχείο</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{κλείσιμο παρένθεσης}other{# κλείσιμο παρενθέσεων}}</translation>
-<translation id="2199994615414171367">Προηγούμενη μαθηματική έκφραση</translation>
-<translation id="2223693656926968778">Εκτέλεση ενέργειας για το τρέχον αντικείμενο</translation>
-<translation id="225732394367814946">Αύξηση ταχύτητας ομιλίας</translation>
-<translation id="2267945578749931355">Επόμενος χαρακτήρας</translation>
-<translation id="2281234842553884450">Προηγούμενο ρυθμιστικό</translation>
-<translation id="2318372665160196757">Κύριο</translation>
-<translation id="2329324941084714723">Παράθυρο καρτέλας</translation>
-<translation id="2344193891939537199">Έλεγχος ημερομηνίας και ώρας</translation>
-<translation id="2359897517538099099">Όχι στη λειτουργία πίνακα.</translation>
-<translation id="241124561063364910">και στη συνέχεια</translation>
-<translation id="2417569100218200841">Πληροφορίες περιεχομένου</translation>
-<translation id="2422937916923936891">Πλαίσιο ελέγχου στοιχείου μενού</translation>
-<translation id="2429669115401274487">μ.μ.</translation>
-<translation id="2435413342408885429">Το πλήκτρο <ph name="KEY" /> είναι πλέον ο νέος τροποποιητής του ChromeVox.</translation>
-<translation id="2450814015951372393">Πλαίσιο ελέγχου</translation>
-<translation id="2462626033734746142">Ομάδα κουμπιών επιλογής</translation>
-<translation id="2471138580042810658">Επικεφαλίδα 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{αστερίσκος}other{# αστερίσκοι}}</translation>
-<translation id="2549392850788122959">Έγινε επαναφορά του πλήκτρου <ph name="KEY" />.</translation>
-<translation id="2553108862507765288">γραμματικό λάθος</translation>
-<translation id="257674075312929031">Ομάδα</translation>
-<translation id="2582407057977008361">Ετικέτα "εκτός" (aside)</translation>
-<translation id="2589102159832527089">Αυτή η σελίδα περιέχει το κείμενο που εξάγεται αυτομάτως από το αρχείο PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Κάντε κλικ εδώ για το πρωτότυπο.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">με {COUNT,plural, =1{# στοιχείο}other{# στοιχεία}}</translation>
-<translation id="2614981083756825552">Διάταξη Math ML</translation>
-<translation id="2626530649491650971">με δυνατότητα κλικ</translation>
-<translation id="2628764385451019380">Δεν υπάρχει προηγούμενο πλαίσιο συνδυασμού.</translation>
-<translation id="2637227747952042642">Μαθηματικά</translation>
-<translation id="2639750663247012216">Τροποποιητής ChromeVox</translation>
-<translation id="2644542693584024604">ορθογραφικό σφάλμα</translation>
-<translation id="2667291555398229137">Κάντε κλικ στο στοιχείο κάτω από το κλειδί δρομολόγησης</translation>
-<translation id="2697408785920771974">ενσωματωμένη αυτόματη συμπλήρωση</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{άνοιγμα παρένθεσης}other{# άνοιγμα παρενθέσεων}}</translation>
-<translation id="2705875883745373140">Δεν έχει πατηθεί</translation>
-<translation id="2706462751667573066">Πάνω</translation>
-<translation id="2717271541250958000">πίνακας καρτελών</translation>
-<translation id="2723001399770238859">ήχος</translation>
-<translation id="2732718972699418926">π.μ.</translation>
-<translation id="2749275490991666823">Επιλεγμένο</translation>
-<translation id="27527859628328957">Μετάβαση στο επόμενο αντικείμενο με δυνατότητα εστίασης</translation>
-<translation id="2770781857296573485">Εισαγωγή στην εξερεύνηση ομάδας</translation>
-<translation id="2777845298774924149">Έγινε έξοδος</translation>
-<translation id="2800204403141299078">Δεν υπάρχουν διαφορετικά στοιχεία.</translation>
-<translation id="2800780099804980316">Δεν υπάρχει προηγούμενη επικεφαλίδα επιπέδου 1.</translation>
-<translation id="2811204574343810641">Σειρά</translation>
-<translation id="2816654101880605877">Δεν υπάρχει επόμενο ρυθμιστικό.</translation>
-<translation id="2841013758207633010">Ώρα</translation>
-<translation id="2843837985843789981">Προηγούμενη ομάδα</translation>
-<translation id="2844995807198708617">Μενού περιβάλλοντος</translation>
-<translation id="2849332794118375855">Δεν υπάρχει επόμενο πλαίσιο ελέγχου.</translation>
-<translation id="2864481629947106776">Προηγούμενος σύνδεσμος</translation>
-<translation id="2873259058405069099">Μετάβαση στην αρχή του πίνακα</translation>
-<translation id="2894654529758326923">Πληροφορίες</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{αριστερό άγκιστρο}other{# αριστερά άγκιστρα}}</translation>
-<translation id="2911433807131383493">Άνοιγμα εκπαιδευτικού οδηγού ChromeVox</translation>
-<translation id="2932083475399492303">Εναλλαγή τύπου γραμμής μεταξύ δομικού ή διαρθρωτικού</translation>
-<translation id="2964026537669811554">Επικεφαλίδα ομάδας</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{χαρακτήρας "tab"}other{# χαρακτήρες "tab"}}</translation>
-<translation id="2972078295414139404">Δεν υπάρχει προηγούμενος σύνδεσμος που έχετε επισκεφτεί.</translation>
-<translation id="2972205263822847197">Επεξήγηση εργαλείου</translation>
-<translation id="2998131015536248178">Προηγούμενος χαρακτήρας</translation>
-<translation id="2999559350546931576">Μείωση προώθησης</translation>
-<translation id="2999945368667127852">Δεν υπάρχει γραφικό στοιχείο επόμενου μέσου.</translation>
-<translation id="3012414509011670858">Δεν υπάρχει προηγούμενη ενότητα.</translation>
-<translation id="3030432017085518523">Κουμπί επιλογής στοιχείου μενού</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{απόστροφος}other{# απόστροφοι}}</translation>
-<translation id="3046838483509668188">Επιλογές ChromeVox</translation>
-<translation id="3047143736589213134">Πειραματική αντιστοίχιση πλήκτρων</translation>
-<translation id="3060756054951570867">Το μενού <ph name="TITLE" /> άνοιξε</translation>
-<translation id="3078345202707391975">Επικεφαλίδα επόμενου επιπέδου 2</translation>
-<translation id="3078740164268491126">πίνακας</translation>
-<translation id="3082557070674409251">Έγινε κλικ</translation>
-<translation id="3084806535845658316">χωρίς εκφώνηση πληκτρολόγησης</translation>
-<translation id="3086746722712840547">σημείωση</translation>
-<translation id="308895241372589742">Δεν υπάρχει επόμενη μαθηματική έκφραση.</translation>
-<translation id="3090532668523289635">ομάδα</translation>
-<translation id="3093176084511590672">Επόμενο ορόσημο</translation>
-<translation id="3096671415663099226">σύνθετο πλαίσιο</translation>
-<translation id="3104705064753753826">παράθυρο διαλόγου ειδοποιήσεων</translation>
-<translation id="3109724472072898302">Συμπτυγμένο</translation>
-<translation id="3134461040845705080">μόνο για ανάγνωση</translation>
-<translation id="3138767756593758860">Εμφάνιση λίστας με ορόσημα</translation>
-<translation id="3143851963874289911">κελί</translation>
-<translation id="3149472044574196936">Επόμενη γραμμή</translation>
-<translation id="3155083529632865074">Δεν υπάρχει προηγούμενο κουμπί.</translation>
-<translation id="3163593631834463955">Κενή κεφαλίδα στήλης</translation>
-<translation id="316542773973815724">Πλοήγηση</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{διάστημα}other{# διαστήματα}}</translation>
-<translation id="320961988183078793">εισήχθη <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, καρτέλα</translation>
-<translation id="3226035351387556942">πλαίσιο επιλογής ρόλου</translation>
-<translation id="3229375994964697375">Σύνδεσμος που έχετε επισκεφτεί</translation>
-<translation id="323731244387692321">Άνοιγμα βοήθειας πληκτρολογίου του ChromeVox</translation>
-<translation id="3241052487511142956">Προηγούμενος σύνδεσμος που έχετε επισκεφτεί</translation>
-<translation id="3286390186030710347">Ρυθμιστικό</translation>
-<translation id="3299925995433437805">Δεν υπάρχει επόμενος σύνδεσμος που έχετε επισκεφτεί.</translation>
-<translation id="3303384412438961941">Πατήστε οποιοδήποτε πλήκτρο για να μάθετε το όνομά του. Με το συνδυασμό πλήκτρων Ctrl+W θα κλείσει η εξερεύνηση πληκτρολογίου.</translation>
-<translation id="3307886118343381874">Μετάβαση στο τέλος του πίνακα</translation>
-<translation id="3311969765485641742">Πατήστε τα πλήκτρα Alt+Shift+A για να ελέγξετε τις ειδοποιήσεις</translation>
-<translation id="3312997241656799641">Επόμενος σύνδεσμος που έχετε επισκεφτεί</translation>
-<translation id="3321460131042519426">Ενεργοποίηση αναδίπλωσης λέξης</translation>
-<translation id="3322936298410871309">Επικεφαλίδα προηγούμενου επιπέδου 1</translation>
-<translation id="3323447499041942178">Πλαίσιο κειμένου </translation>
-<translation id="3353420241558113817">{"ar": "Αραβικά",
- "bg": "Βουλγαρικά",
- "ca": "Καταλανικά",
- "cs": "Τσεχικά",
- "da": "Δανικά",
- "de": "Γερμανικά",
- "de_CH": "Γερμανικά (Ελβετίας)",
- "de_DE": "Γερμανικά (Γερμανίας)",
- "el": "Ελληνικά",
- "en": "Αγγλικά",
- "en_CA": "Αγγλικά (Καναδά)",
- "en_GB": "Αγγλικά (Ηνωμένου Βασιλείου)",
- "en_US": "Αγγλικά (Ηνωμένων Πολιτειών)",
- "es": "Ισπανικά",
- "et": "Εσθονικά",
- "fr": "Γαλλικά",
- "fr_CA": "Γαλλικά (Καναδά)",
- "fr_FR": "Γαλλικά (Γαλλίας)",
- "fi": "Φινλανδικά",
- "he": "Εβραϊκά",
- "hi": "Χίντι",
- "hr": "Κροατικά",
- "hu": "Ουγγρικά",
- "is": "Ισλανδικά",
- "it": "Ιταλικά",
- "ko": "Κορεατικά",
- "lt": "Λιθουανικά",
- "lv": "Λετονικά",
- "nb": "Νορβηγικά Bokmål",
- "nl": "Ολλανδικά",
- "pl": "Πολωνικά",
- "pt": "Πορτογαλικά",
- "ro": "Ρουμανικά",
- "ru": "Ρωσικά",
- "sk": "Σλοβακικά",
- "sl": "Σλοβενικά",
- "sr": "Σερβικά",
- "sv": "Σουηδικά",
- "tr": "Τουρκικά",
- "vi": "Βιετναμέζικα",
- "zh": "Κινεζικά",
- "zh_TW": "Κινεζικά (Παραδοσιακά Han)"}</translation>
-<translation id="3359142382821736686">διαχωριστικό ρόλων</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{σύμβολο "συν"}other{# σύμβολα "συν"}}</translation>
-<translation id="338583716107319301">Διαχωριστικό</translation>
-<translation id="3389259863310851658">Προηγούμενο πεδίο φόρμας</translation>
-<translation id="3390225400784126843">Επόμενο διαφορετικό στοιχείο.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, στοιχείο μενού</translation>
-<translation id="3406283310380167331">Εμφάνιση λίστας φορμών</translation>
-<translation id="3422338090358345848">Άνοιγμα της εξερεύνησης πληκτρολογίου</translation>
-<translation id="3457000393508828486">Έχει πατηθεί μερικώς</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, κουμπί</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> έως <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{δεξιά αγκύλη}other{# δεξιές αγκύλες}}</translation>
-<translation id="3493915602752813531">Δεν υπάρχει επόμενη αγκύρωση.</translation>
-<translation id="3494946239022273294">στοιχείο μενού</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{λατινικό ερωτηματικό}other{# λατινικά ερωτηματικά}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{σύμβολο προσθήκης}other{# σύμβολα προσθήκης}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, το πλαίσιο ελέγχου δεν είναι επιλεγμένο</translation>
-<translation id="3599054940393788245">Εκτός του math</translation>
-<translation id="3616113530831147358">Ήχος</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{βαρεία}other{# βαρείες}}</translation>
-<translation id="3650317109285159359">πλαίσιο επιλογής στοιχείου μενού</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{σύμβολο δολαρίου}other{# σύμβολα δολαρίου}}</translation>
-<translation id="3659787053479271466">ειδοποίηση</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, πλαίσιο λίστας</translation>
-<translation id="3687295507293856493">Κάντε μια εκτίμηση στην κεφαλίδα της στήλης του τρέχοντος κελιού</translation>
-<translation id="3692274950075847560">Α: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Έλεγχος ομιλίας</translation>
-<translation id="3716845769494773620">Πολλαπλών γραμμών</translation>
-<translation id="3731746171184829332">Δεν υπάρχει προηγούμενη επικεφαλίδα.</translation>
-<translation id="3762198587642264450">Μετάβαση στο τέλος της τρέχουσας σειράς</translation>
-<translation id="3777255250339039212">ετικέτα 1</translation>
-<translation id="3793710123303304873">Έξοδος από το παράθυρο διαλόγου.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Λίστα αυτόματης συμπλήρωσης</translation>
-<translation id="3810838688059735925">Βίντεο</translation>
-<translation id="3816633764618089385">Επόμενο μέσο</translation>
-<translation id="3819376190738087562">Δεν υπάρχουν μεταβάσεις.</translation>
-<translation id="385383972552776628">Άνοιγμα σελίδας επιλογών</translation>
-<translation id="3856075812838139784">Μόνο για ανάγνωση</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Μενού</translation>
-<translation id="3909320334364316587">Επικεφαλίδα προηγούμενου επιπέδου 6</translation>
-<translation id="3914173277599553213">Απαιτείται</translation>
-<translation id="3962990492275676168">Έναρξη ανάγνωσης από την τρέχουσα τοποθεσία</translation>
-<translation id="4004802134384979325">επιλεγμένο</translation>
-<translation id="4006140876663370126">εικόνα</translation>
-<translation id="4038349100599457191">Έλεγχος μήνα</translation>
-<translation id="4039983576244166038">Κενή κεφαλίδα γραμμής</translation>
-<translation id="4042843249978639960">Δεν υπάρχει επόμενη επικεφαλίδα επιπέδου 2.</translation>
-<translation id="4043348641337972076">Δεν υπάρχει προηγούμενο ορόσημο ARIA.</translation>
-<translation id="4047216625641135770">Επισήμανση</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">κατάσταση</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{ΠΕΡΙΣΠΩΜΕΝΗ}other{# περισπωμένες}}</translation>
-<translation id="409334809956508737">Προηγούμενο στοιχείο</translation>
-<translation id="4099274309791143834">με υπομενού</translation>
-<translation id="4107807507418787238">Δεν υπάρχει κελί παρακάτω.</translation>
-<translation id="4116415223832267137">Ειδοποίηση</translation>
-<translation id="4147126331795725888">Δεν υπάρχει επόμενο στοιχείο ελέγχου.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{δεξιό άγκιστρο}other{# δεξιά άγκιστρα}}</translation>
-<translation id="4158704014418536539">Διάκριση πεζών-κεφαλαίων.</translation>
-<translation id="4161663686871496107">Τα προφορικά σχόλια ChromeVox είναι έτοιμα</translation>
-<translation id="4173994908659439270">Δεν υπάρχει επόμενο πεδίο με δυνατότητα επεξεργασίας.</translation>
-<translation id="4176463684765177261">Απενεργοποιημένη</translation>
-<translation id="4188530942454211480">Προηγούμενη πρόταση</translation>
-<translation id="4202186506458631436">Μετακίνηση δεξιά</translation>
-<translation id="4206289001967551965">Μέσα στον πίνακα</translation>
-<translation id="4215733775853809057">Επόμενο ρυθμιστικό</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{παύλα}other{# παύλες}}</translation>
-<translation id="421884353938374759">επιλογέας χρώματος</translation>
-<translation id="4229646983878045487">ημερομηνία ώρα</translation>
-<translation id="423334822609210999">Δεν υπάρχει κελί αριστερά.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, Βαθμίδα <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Σημείωση</translation>
-<translation id="4254798249533888099">Δέντρο</translation>
-<translation id="4255943572433203166">Χρησιμοποιήστε τις παρακάτω επιλογές για να προσαρμόσετε το ChromeVox. Οι αλλαγές θα εφαρμοστούν αμέσως.</translation>
-<translation id="4271220233568730077">Επόμενη μαθηματική έκφραση</translation>
-<translation id="4271521365602459209">Δεν υπάρχουν άλλα αποτελέσματα.</translation>
-<translation id="4287520460805643128">Δεν υπάρχει επόμενο άρθρο.</translation>
-<translation id="4289540628985791613">Επισκόπηση</translation>
-<translation id="4300318234632215983">Ανακοίνωση της διεύθυνσης URL πίσω από ένα σύνδεσμο</translation>
-<translation id="4301352596632316575">διαθέτει υπομενού</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{κουκκίδα}=3{αποσιωπητικά}other{# κουκκίδες}}</translation>
-<translation id="4347461890115250064">Δεν υπάρχει επόμενη λίστα.</translation>
-<translation id="4367650418938037324">Math ML Leaf</translation>
-<translation id="4372435075475052704">ελάχ.:<ph name="X" /></translation>
-<translation id="4372705107434148843">Διακοπή ομιλίας</translation>
-<translation id="4373197658375206385">Δεν υπάρχει προηγούμενο στοιχείο που δεν αποτελεί σύνδεσμο.</translation>
-<translation id="4391478986194775161">πληροφορίες περιεχομένου</translation>
-<translation id="443163561286008705">επαναφορά</translation>
-<translation id="4471074325120394300">Δεν υπάρχουν σύνδεσμοι.</translation>
-<translation id="4476183483923481720">νέα γραμμή</translation>
-<translation id="4482330759234983253">Προηγούμενος πίνακας</translation>
-<translation id="4491109536499578614">Εικόνα</translation>
-<translation id="4529987814483543472">Κλασική αντιστοίχιση πλήκτρων</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{κάθετος}other{# κάθετοι}}</translation>
-<translation id="4547556996012970016">Επικεφαλίδα επόμενου επιπέδου 5</translation>
-<translation id="4562381607973973258">Κεφαλίδα</translation>
-<translation id="4591507479202817876">, επιλέχθηκε</translation>
-<translation id="4597532268155981612">φόρμα</translation>
-<translation id="4597896406374528575">Απρίλιος</translation>
-<translation id="4615592953348396470">Παράβλεψη του επόμενου πατήματος πλήκτρου</translation>
-<translation id="461613135510474570">Πρόταση</translation>
-<translation id="4647836961514597010">Επιλογέας χρώματος</translation>
-<translation id="4661075872484491155">δέντρο</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">πλέγμα</translation>
-<translation id="4693675773662933727">Προηγούμενο ορόσημο</translation>
-<translation id="4696413482802371445">Δεν υπάρχει επόμενη επικεφαλίδα επιπέδου 5.</translation>
-<translation id="4729095194763193578">Προηγούμενη σειρά πίνακα</translation>
-<translation id="4736221692378411923">Αύγουστος</translation>
-<translation id="4740661827607246557">Εντολές βοήθειας</translation>
-<translation id="4759716709594980008">Εξερεύνηση πληκτρολογίου ChromeOS</translation>
-<translation id="4763296182459741068">Ενσωμάτωση στο κάτω μέρος</translation>
-<translation id="4763480195061959176">βίντεο</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Ανακοίνωση του τίτλου της τρέχουσας σελίδας</translation>
-<translation id="4826415162591436065">Μετάβαση προς τα εμπρός</translation>
-<translation id="4826604887384865800">Επόμενη μετάβαση</translation>
-<translation id="4827410568042294688">μη επιλεγμένο</translation>
-<translation id="4842108708071771135">Δεν υπάρχει επόμενο blockquote.</translation>
-<translation id="4848993367330139335">χρονόμετρο</translation>
-<translation id="4850023505158945298">Προηγούμενο παρόμοιο στοιχείο.</translation>
-<translation id="4866956062845190338">κουμπί επιλογής στοιχείου μενού</translation>
-<translation id="4867316986324544967">Ενεργοποίηση καταγραφής TTS</translation>
-<translation id="4877261390094455813">Εισαγάγετε ένα ερώτημα αναζήτησης.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Ετικέτα "Εσωτερικός σύνδεσμος" (&lt;a&gt;)</translation>
-<translation id="4953585991029886728">Επεξεργασία κειμένου</translation>
-<translation id="4954534434583049121">Προηγούμενο block quote</translation>
-<translation id="4973717656530883744">Ελάχ. <ph name="X" /></translation>
-<translation id="4973762002207131920">Εναλλαγή σε <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">χιλιοστά του δευτερολέπτου</translation>
-<translation id="49787999531187221">Το ChromeVox είναι ανενεργό αυτήν τη στιγμή.</translation>
-<translation id="4979404613699303341">Προηγούμενο κουμπί</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, πλαίσιο λίστας</translation>
-<translation id="4983588134362688868">Μετάβαση στην κορυφή της σελίδας</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, παράθυρο</translation>
-<translation id="4993152509206108683">Ρυθμός <ph name="PERCENT" /> τοις εκατό</translation>
-<translation id="4996716799442435517">Οπτική λειτουργία</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, επιλεγμένο κουμπί επιλογής</translation>
-<translation id="4997475792277222884">Δεν υπάρχει επόμενο στοιχείο που δεν αποτελεί σύνδεσμο.</translation>
-<translation id="5000760171916499057">Δεν υπάρχουν φόρμες.</translation>
-<translation id="5005670136041063723">Δεν υπάρχουν παρόμοια στοιχεία.</translation>
-<translation id="501473567976723023">Ιανουάριος</translation>
-<translation id="5041394372352067729">Μετακίνηση της οθόνης μπράιγ στο επάνω μέρος της σελίδας</translation>
-<translation id="5042770794184672516">Αύξηση έντασης ομιλίας</translation>
-<translation id="5050015258024679800">Επικεφαλίδα προηγούμενου επιπέδου 4</translation>
-<translation id="5054047268577924192">Προηγούμενο στοιχείο λίστας</translation>
-<translation id="5078661581131202757">Επιλογή αρχείου</translation>
-<translation id="5080758118274074384">έγινε διπλό κλικ</translation>
-<translation id="5098541983634824365">Απομάκρυνση από το πλέγμα.</translation>
-<translation id="5102981729317424850">Γραμμή εργαλείων</translation>
-<translation id="5105050547967751155">απαιτείται</translation>
-<translation id="5110983769041734144">Δεν υπάρχει προηγούμενο πεδίο φόρμας.</translation>
-<translation id="5111640677200759579">Κεφαλίδα στήλης</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Δεν υπάρχει προηγούμενος σύνδεσμος.</translation>
-<translation id="513774504516943387">σύνδεσμος</translation>
-<translation id="517143700877085897">, μη επιλεγμένο</translation>
-<translation id="5183440668879371625">Προηγούμενη γραμμή μπράιγ</translation>
-<translation id="5184944171021383281">Δεν υπάρχει επόμενο πεδίο φόρμας.</translation>
-<translation id="5189244881767082992">Γραμμή</translation>
-<translation id="5203930734796605961">Το <ph name="KEY" /> έχει ήδη εκχωρηθεί σε μια εντολή.</translation>
-<translation id="5205493599117157272">Λίστα <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Δεν υπάρχει επόμενο κουμπί επιλογής.</translation>
-<translation id="5263344797180442561">κεφαλίδα 2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Στοιχείο</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, καρτέλα</translation>
-<translation id="5310788376443009632">καταργήθηκε:</translation>
-<translation id="5320727453979144100">Έχει ενεργοποιηθεί η λειτουργία διατήρησης ενδιαφέροντος (Sticky)</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{κόμμα}other{# κόμματα}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, πλαίσιο κειμένου</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, σύνδεσμος</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Μετάβαση προς τα πίσω κατά τη συνεχόμενη ανάγνωση</translation>
-<translation id="5368000168321181111">Ηχητικά μηνύματα ανενεργά</translation>
-<translation id="5374320867641260420">Δεν υπάρχει επόμενο κουμπί.</translation>
-<translation id="5382299583965267720">Δεν υπάρχει επόμενη επικεφαλίδα επιπέδου 1.</translation>
-<translation id="5402367795255837559">Μπράιγ</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{ερωτηματικό}other{# ερωτηματικά}}</translation>
-<translation id="5411891038905756502">Δεν υπάρχει προηγούμενο σημείο μετάβασης.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{σύμβολο "μικρότερο από"}other{# σύμβολα "μικρότερο από"}}</translation>
-<translation id="5455441614648621694">Συμπληρωματικό</translation>
-<translation id="5485036206801896268">Δεν υπάρχει προηγούμενο γραφικό.</translation>
-<translation id="5486947920110100234">Δεν υπάρχει επόμενο σημείο μετάβασης.</translation>
-<translation id="549602578321198708">Λέξη</translation>
-<translation id="5500932716852106146">Δεν υπάρχει προηγούμενο πεδίο με δυνατότητα επεξεργασίας.</translation>
-<translation id="5502713021410870035">Σεπτέμβριος</translation>
-<translation id="5507663321906818013">Συγκριτική αξιολόγηση εντοπισμού σφαλμάτων</translation>
-<translation id="5518443085409638729">Τοποθετήστε το δείκτη του ποντικιού μεταξύ των χαρακτήρων κατά την επεξεργασία κειμένου (όπως Mac OS X).</translation>
-<translation id="552195134157544755">Κουμπί επιλογής</translation>
-<translation id="5534303576632885660">κεφαλίδα</translation>
-<translation id="5546092960038624944">Δεν υπάρχει προηγούμενη επικεφαλίδα επιπέδου 5.</translation>
-<translation id="556042886152191864">Κουμπί</translation>
-<translation id="5561345396546889625">Επόμενη λίστα</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Πλήκτρο Backspace</translation>
-<translation id="5585044216466955529">Επεξεργασία κειμένου, καταχώριση διεύθυνσης ηλεκτρονικού ταχυδρομείου</translation>
-<translation id="5597170376237141345">Επόμενο πλαίσιο ελέγχου</translation>
-<translation id="5597933780944041114">Δεν υπάρχει επόμενη επικεφαλίδα.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, μη επιλεγμένο κουμπί επιλογής</translation>
-<translation id="5601172225407283979">Εκτέλεση προεπιλεγμένης ενέργειας</translation>
-<translation id="5608798115546226984">Ενσωματωμένη αυτόματη συμπλήρωση</translation>
-<translation id="561939826962581046">ώρα</translation>
-<translation id="5623778242535476823">κουμπί επιλογής ρόλου</translation>
-<translation id="5623842676595125836">Αρχείο καταγραφής</translation>
-<translation id="5628125749885014029">κεφαλίδα 4</translation>
-<translation id="5637871198229500030">Δεν υπάρχει προηγούμενος πίνακας.</translation>
-<translation id="5655682562155942719">Εντολές μετάβασης</translation>
-<translation id="56637627897541303">Ετικέτα "Περιοχή κειμένου"</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">ορισμός</translation>
-<translation id="5682113568322255809">Ορόσημο</translation>
-<translation id="5683155931978483559">Προηγούμενο πλαίσιο ελέγχου</translation>
-<translation id="5684277895745049190">Λίστα</translation>
-<translation id="5700650669149824506">Δεν υπάρχει προηγούμενη επικεφαλίδα επιπέδου 4.</translation>
-<translation id="5709192780268610569">Χωρίς εκτενή περιγραφή</translation>
-<translation id="5712244464475377681">κουμπί με αναδυόμενου μενού</translation>
-<translation id="5712338278108304766">Επόμενη στήλη πίνακα</translation>
-<translation id="571866080859340309">Εξερεύνηση ομάδων</translation>
-<translation id="5728409797179002635">Δεν βρέθηκε πίνακας.</translation>
-<translation id="5748623122140342504">Επικεφαλίδα προηγούμενου επιπέδου 5</translation>
-<translation id="5750633686117194034">Δεν πατήθηκε κανένας τροποποιητής. Πατήστε παρατεταμένα έναν ή περισσότερους τροποποιητές και όταν σηκώσετε τα δάχτυλά σας θα ακούσετε τον ήχο ορισμού ρύθμισης των πλήκτρων. Πατήστε "Tab" για έξοδο.</translation>
-<translation id="5788275253279308023">Καρτέλα <ph name="TITLE" /> παραθύρου ανώνυμης περιήγησης</translation>
-<translation id="5806206155699461681">Βελτίωση συγκεκριμένων σελίδων (όπως της Αναζήτησης Google).</translation>
-<translation id="5819072574982403430">Στοιχείο δέντρου</translation>
-<translation id="5826479389509458994">γραμμή <ph name="ROW" /> στήλη <ph name="COL" /></translation>
-<translation id="5850707923114094062">Μετακίνηση προς τα πίσω</translation>
-<translation id="5851548754964597211">Λίστα καρτελών</translation>
-<translation id="5859752971144398932">Έξοδος από την αναζήτηση στη σελίδα.</translation>
-<translation id="5866042630553435010">Μερικώς επιλεγμένο</translation>
-<translation id="5869546221129391014">Πλέγμα</translation>
-<translation id="5876817486144482042">Μείωση έντασης ομιλίας</translation>
-<translation id="5887397643266327462">Οι υπότιτλοι braille ενεργοποιήθηκαν.</translation>
-<translation id="5891934789323004067">Πίνακας</translation>
-<translation id="5919442531159595654">αντιγραφή.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{σύμβολο "ίσον"}other{# σύμβολα "ίσον"}}</translation>
-<translation id="5939518447894949180">Επαναφορά</translation>
-<translation id="5948123859135882163">Εναλλαγή ερμηνείας μαθηματικών εκφράσεων μεταξύ συντακτικής και σημασιολογικής</translation>
-<translation id="5955304353782037793">εφαρμογή</translation>
-<translation id="5956928062748260866">Διάλογος</translation>
-<translation id="5963413905009737549">Ενότητα</translation>
-<translation id="5968607524793740041">Εμφάνιση μενού περιβάλλοντος</translation>
-<translation id="5983179082906765664">Αύξηση ευαισθησίας περιήγησης</translation>
-<translation id="5999630716831179808">Φωνές</translation>
-<translation id="6000417740266304866">Αλλάξτε τον τρέχοντα πίνακα οκτάστιγμου μπράιγ, επιλέγοντας από την παρακάτω λίστα.</translation>
-<translation id="6006050241733874051">Φόρμα</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{ανάστροφη κάθετος}other{# ανάστροφες κάθετοι}}</translation>
-<translation id="6037602951055904232">Μετακίνηση προς τα εμπρός</translation>
-<translation id="611827076493383239">ιστότοπος που επισκεφτήκατε</translation>
-<translation id="6119955456199054975">Τέλος κελιού.</translation>
-<translation id="6122013438240733403">κουμπί</translation>
-<translation id="6129953537138746214">Κενό</translation>
-<translation id="6142308968191113180">Επικεφαλίδα 4</translation>
-<translation id="6169420925157477918">Εικόνα με εκτενή περιγραφή</translation>
-<translation id="6172087735260766220">Δεν είναι δυνατή η πρόσβαση στο προσβάσιμο κείμενο από PDF που προστατεύεται από αντιγραφή.</translation>
-<translation id="6186305613600865047">Μετάβαση στο κάτω μέρος της σελίδας</translation>
-<translation id="6193330012414963395">ΠΜ ΜΜ</translation>
-<translation id="622484624075952240">Κάτω</translation>
-<translation id="6236061028292614533">Επόμενη επικεφαλίδα</translation>
-<translation id="6254901459154107917">Επόμενη περιοχή κειμένου με δυνατότητα επεξεργασίας</translation>
-<translation id="6259464875943891919">Έγινε έξοδος από <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Επόμενο παρόμοιο στοιχείο.</translation>
-<translation id="6282062888058716985">πλοήγηση</translation>
-<translation id="6290434000785343030">Δεν υπάρχει επόμενο σύνθετο πλαίσιο.</translation>
-<translation id="6307969636681130414">Έχει πατηθεί</translation>
-<translation id="6324551002951139333">Έχει εντοπιστεί γραμματικό λάθος</translation>
-<translation id="6348657800373377022">Πλαίσιο συνδυασμών</translation>
-<translation id="6355910664415701303">Δεν υπάρχει προηγούμενο στοιχείο στη λίστα.</translation>
-<translation id="6364795331201459219">κεφαλίδα 6</translation>
-<translation id="6368143427468974988">Προηγούμενη επικεφαλίδα</translation>
-<translation id="6387719785439924554">εκτός</translation>
-<translation id="6411426777058107714">Δεν υπάρχει προηγούμενο κουμπί επιλογής.</translation>
-<translation id="6414968628640960377">Προηγούμενο διαφορετικό στοιχείο.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{άνω κάτω τελεία}other{# άνω κάτω τελείες}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, μενού</translation>
-<translation id="6444046323172968959">Παράθυρο διαλόγου ειδοποιήσεων</translation>
-<translation id="6459511626086141404">Σταθερή αντιστοίχιση πλήκτρων</translation>
-<translation id="6468049171101508116">Επόμενο κουμπί</translation>
-<translation id="6491972999578897419">Αλλάξτε την τρέχουσα φωνή ορίζοντας μια επιλογή από την παρακάτω λίστα.</translation>
-<translation id="6508059270146105198">Μετακίνηση οθόνης μπράιγ στο κάτω μέρος της σελίδας</translation>
-<translation id="6536864053412760904">Math ML Token</translation>
-<translation id="6550720799683018100">Αλλάξτε την τρέχουσα αντιστοίχιση πλήκτρων ορίζοντας μια επιλογή από την παρακάτω λίστα.</translation>
-<translation id="6561818612645211875">Μετάβαση στην αρχή της τρέχουσας σειράς</translation>
-<translation id="6587021927234520429">Δεν υπάρχει επόμενη επικεφαλίδα επιπέδου 4.</translation>
-<translation id="6601344353291556895">Ενεργοποίηση περιγραφών verbose.</translation>
-<translation id="6615602925644411249">Εύρεση στη σελίδα.</translation>
-<translation id="6633350132811819843">Δεν υπάρχει επόμενος πίνακας.</translation>
-<translation id="6637586476836377253">αρχείο καταγραφής</translation>
-<translation id="6657128831881431364">Γραμμή προόδου</translation>
-<translation id="6659594942844771486">Καρτέλα</translation>
-<translation id="667999046851023355">Έγγραφο</translation>
-<translation id="6697092096875747123">Προηγούμενο σύνθετο πλαίσιο</translation>
-<translation id="6714813999819678458">Επικεφαλίδα προηγούμενου επιπέδου 2</translation>
-<translation id="6716505898850596801">Πλήκτρα τροποποίησης</translation>
-<translation id="671916444866103745">Δεν υπάρχει επόμενο ορόσημο ARIA.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, πλαίσιο συνδυασμών</translation>
-<translation id="6735257939857578167">με <ph name="NUM" /> στοιχεία</translation>
-<translation id="6736510033526053669">δημιουργήθηκε καρτέλα</translation>
-<translation id="675895815784134693">γραμμή προόδου</translation>
-<translation id="6786800275320335305">Άρθρο</translation>
-<translation id="6787839852456839824">Συντομεύσεις πληκτρολογίου</translation>
-<translation id="6793101435925451627">πλαίσιο λίστας</translation>
-<translation id="6833103209700200188">Υποσέλιδο</translation>
-<translation id="6871161210040114857">Παράβλεψη διάκρισης πεζών-κεφαλαίων.</translation>
-<translation id="6877435256196695200">Δεν υπάρχει επόμενο γραφικό.</translation>
-<translation id="6897341342232909480">Μετακίνηση αριστερά</translation>
-<translation id="6901540140423170855">ημερομηνία</translation>
-<translation id="6910211073230771657">Διαγράφηκε</translation>
-<translation id="6911965441508464308">Δεν υπάρχει κελί επάνω.</translation>
-<translation id="6919104639734799681">Εμφάνιση λίστας πινάκων</translation>
-<translation id="6964088412282673743">Δεν υπάρχει προηγούμενο στοιχείο ελέγχου.</translation>
-<translation id="6996566555547746822">Επόμενο σύνθετο πλαίσιο</translation>
-<translation id="7005146664810010831">Δεν βρέθηκε διεύθυνση URL</translation>
-<translation id="7010712454773919705">Πλήκτρο τροποποίησης ChromeVox</translation>
-<translation id="7031651751836475482">στοιχείο λίστας</translation>
-<translation id="7037042857287298941">Προηγούμενη λίστα</translation>
-<translation id="7041173719775863268">Τερματισμός επιλογής</translation>
-<translation id="7095834689119144465">Επεξεργασία κειμένου μόνο για αριθμούς</translation>
-<translation id="7096001299300236431">Προηγούμενο μέσο</translation>
-<translation id="7116595520562830928">πολλές γραμμές</translation>
-<translation id="712735679809149106">εκφώνηση λέξεων</translation>
-<translation id="713824876195128146">Επόμενο block quote</translation>
-<translation id="7161771961008409533">Αναδυόμενο κουμπί</translation>
-<translation id="7167657087543110">εκφώνηση χαρακτήρων</translation>
-<translation id="7170733337935166589">Μετάβαση προς τα εμπρός κατά τη συνεχόμενη ανάγνωση</translation>
-<translation id="7181697990050180700">Προσαρμόστε τις συντομεύσεις πληκτρολογίου για τις εντολές που χρησιμοποιείτε συχνά πληκτρολογώντας τες στα αντίστοιχα πεδία παρακάτω.</translation>
-<translation id="7203150201908454328">Ανεπτυγμένο</translation>
-<translation id="7210211103303402262">λεπτά</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">γραμμή</translation>
-<translation id="7226216518520804442">λίστα</translation>
-<translation id="72393384879519786">Επικεφαλίδα</translation>
-<translation id="7241683698754534149">Άνοιγμα εκτενούς περιγραφής σε νέα καρτέλα</translation>
-<translation id="7248671827512403053">Εφαρμογή</translation>
-<translation id="725969808843520477">Επόμενο κουμπί επιλογής</translation>
-<translation id="7269119382257320590">Χωρίς σημεία στίξης</translation>
-<translation id="7273174640290488576">Κενό</translation>
-<translation id="7285387653379749618">Πίνακες</translation>
-<translation id="7289186959554153431">Επικεφαλίδα 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">στοιχείο δέντρου</translation>
-<translation id="731576946540457939">Οι υπότιτλοι μπράιγ απενεργοποιήθηκαν.</translation>
-<translation id="7318872822751139669">Χρησιμοποιήστε το ποντίκι για να αλλάξετε την εστίαση.</translation>
-<translation id="7322388933135261569">Φεβρουάριος</translation>
-<translation id="7332592614823088566">Σειρά <ph name="ROWINDEX" /> από <ph name="ROWTOTAL" />, στήλη <ph name="COLINDEX" /> από <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">με αναδυόμενο</translation>
-<translation id="7356165926712028380">Αλλαγή σε οκτάστιγμο μπράιγ</translation>
-<translation id="7362871137496673139">Δεν υπάρχει προηγούμενη επικεφαλίδα επιπέδου 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{συμπλεκτικό σύμβολο}other{# συμπλεκτικά σύμβολα}}</translation>
-<translation id="737396357417333429">στοιχείο με δυνατότητα κλικ</translation>
-<translation id="7374104575779636480">Απομάκρυνση από τον πίνακα.</translation>
-<translation id="739763518212184081">Προηγούμενη γραμμή</translation>
-<translation id="7400575256015741911">Έχει εντοπιστεί ορθογραφικό λάθος</translation>
-<translation id="7408482676469142474">πίνακας</translation>
-<translation id="7425395583360211003">επαναφορά</translation>
-<translation id="7434509671034404296">Για Προγραμματιστές</translation>
-<translation id="7439060726180460871">Κατάλογος</translation>
-<translation id="744163271241493234">κωδικός πρόσβασης</translation>
-<translation id="7491962110804786152">καρτέλα</translation>
-<translation id="7492049978501397201">Έγινε εισαγωγή διαλόγου</translation>
-<translation id="7532613204005497612">Ιούνιος</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, ρυθμιστικό</translation>
-<translation id="7586163296341959563">επικόλληση.</translation>
-<translation id="7596919493010894443">εκκαθάριση επιλογής</translation>
-<translation id="7604026522577407655">Μετάβαση στην αρχή της τρέχουσας στήλης</translation>
-<translation id="7604451927827590395">κεφαλίδα ρόλου</translation>
-<translation id="7609342235116740824">Ανακοίνωση της διεύθυνσης URL της τρέχουσας σελίδας</translation>
-<translation id="7609363189280667021">Εναλλαγή υποτίτλων μπράιγ</translation>
-<translation id="762020119231868829">Διακόπτει όλες τις τρέχουσες αναπαραγωγές γραφικών στοιχείων μέσων</translation>
-<translation id="7625690649919402823">Επόμενος πίνακας</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), βαθμός <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Δεν υπάρχει προηγούμενη επικεφαλίδα επιπέδου 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, πλαίσιο κειμένου</translation>
-<translation id="7663318257180412551">Επικεφαλίδα 2</translation>
-<translation id="7674576868851035240">Επόμενος σύνδεσμος</translation>
-<translation id="7674768236845044097">Ετικέτα mark</translation>
-<translation id="7684431668231950609">Επεξεργασία κειμένου, καταχώριση διεύθυνσης URL</translation>
-<translation id="7685589220304187312">γραμμή εργαλείων</translation>
-<translation id="7693840228159394336">Προηγούμενο κουμπί επιλογής</translation>
-<translation id="7701196182766842984">αυτόματη συμπλήρωση λίστας</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, πλαίσιο κειμένου κωδικού πρόσβασης</translation>
-<translation id="7805247615045262757">προεπιλεγμένη πλοήγηση</translation>
-<translation id="7805768142964895445">Κατάσταση</translation>
-<translation id="7810781339813764006">Επόμενη ομάδα</translation>
-<translation id="7819187121850078213">καρτέλα <ph name="TITLE" /> παραθύρου</translation>
-<translation id="7828956995407538686">Οκτώβριος</translation>
-<translation id="7839679365527550018">Προηγούμενη λέξη</translation>
-<translation id="7851816175263618915">Λίγα σημεία στίξης</translation>
-<translation id="7870596830398826354">Math ML Tree</translation>
-<translation id="78826985582142166">ρυθμιστικό</translation>
-<translation id="7894517696028036636">Εναλλαγή κλασικού ChromeVox.</translation>
-<translation id="7895896691902835279">Άγνωστος σύνδεσμος</translation>
-<translation id="7927711904086083099">Μη επιλεγμένο</translation>
-<translation id="7935627501098484003">Στοιχείο ελέγχου ώρας</translation>
-<translation id="7939428177581522200">έχει προστεθεί στην επιλογή</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{σύμβολο "at" (@)}other{# σύμβολα "at" (@)}}</translation>
-<translation id="7965147473449754028">κλειστό μενού</translation>
-<translation id="7974390230414479278">Στοιχείο μενού</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{θαυμαστικό}other{# θαυμαστικά}}</translation>
-<translation id="8007540374018858731">επικεφαλίδα 3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{εισαγωγικό}other{# εισαγωγικά}}</translation>
-<translation id="8033827949643255796">επιλεγμένο</translation>
-<translation id="8035962149453661158">μέγ.:<ph name="X" /></translation>
-<translation id="8042761080832772327">Επεξεργασία κειμένου, καταχώριση αναζήτησης</translation>
-<translation id="8049189770492311300">Χρονόμετρο</translation>
-<translation id="8065607967589909823">Η επιλογή είναι</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Δεν υπάρχουν ορόσημα ARIA.</translation>
-<translation id="8153880621934657047">Όχι μέσα στον πίνακα.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{σύμβολο υπογράμμισης}other{# σύμβολα υπογράμμισης}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">αποκοπή.</translation>
-<translation id="8199231515320852133">Ανακοίνωση των κεφαλίδων του τρέχοντος κελιού</translation>
-<translation id="820417203470636242">Κενό κελί.</translation>
-<translation id="8215202828671303819">Πολλαπλής επιλογής</translation>
-<translation id="8276439074553447000">Μετάβαση στο προηγούμενο αντικείμενο με δυνατότητα εστίασης</translation>
-<translation id="8278417001922463147">Δεν υπάρχει προηγούμενο αντικείμενο.</translation>
-<translation id="8283603667300770666">Επόμενο πεδίο φόρμας</translation>
-<translation id="831207808878314375">Ορισμός</translation>
-<translation id="8313653172105209786">κατάλογος</translation>
-<translation id="8344569602005188545">ώρες</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{σύμβολο λίρας}other{# σύμβολα λίρας}}</translation>
-<translation id="8374154622594089836">μήνας</translation>
-<translation id="8378855320830505539">Περιοχή</translation>
-<translation id="8382679411218029383">Ενσωματωμένη αυτόματη συμπλήρωση και λίστα</translation>
-<translation id="8428603554127842284">επίπεδο <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Δεν υπάρχει επόμενη επικεφαλίδα επιπέδου 3.</translation>
-<translation id="8430049249787218991">γραμμή μενού</translation>
-<translation id="844681116543532394">Δεν υπάρχει προηγούμενο πλαίσιο ελέγχου.</translation>
-<translation id="8455868257606149352">Μέγιστο <ph name="X" /></translation>
-<translation id="84575901236241018">διαθέτει το κλειδί πρόσβασης, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Μείωση ευαισθησίας πλοήγησης</translation>
-<translation id="8520472399088452386">Κουμπί περιστροφής</translation>
-<translation id="8538744478902126321">Κάντε μια εκτίμηση για την κεφαλίδα της σειράς του τρέχοντος κελιού</translation>
-<translation id="8540054775867439484">Ενσωμάτωση στο επάνω μέρος</translation>
-<translation id="8548973727659841685">Χαρακτήρας</translation>
-<translation id="8561322612995434619">διαθέτει αναδυόμενο</translation>
-<translation id="8571096049907249734">με δυνατότητα πολλαπλής επιλογής</translation>
-<translation id="8584721346566392021">κεφαλίδα 5</translation>
-<translation id="8587549812518406253">Επόμενο στοιχείο λίστας</translation>
-<translation id="860150890330522909">Το πλαίσιο ελέγχου <ph name="NAME" /> επιλέχθηκε</translation>
-<translation id="8606621670302093223">Έλεγχος δεδομένων</translation>
-<translation id="8631359288236106450">έχουν επιλεγεί <ph name="COUNT" /> στοιχεία</translation>
-<translation id="8638532244051952400">Ανακοίνωση συντεταγμένων τρέχοντος κελιού</translation>
-<translation id="8650576015643545550">Δεν υπάρχει προηγούμενη λίστα.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Εμφάνιση λίστας συνδέσμων</translation>
-<translation id="8664519043722036194">δευτερόλεπτα</translation>
-<translation id="867187640362843212">Επικεφαλίδα 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{κάθετη παύλα}other{# κάθετες παύλες}}</translation>
-<translation id="8735450637152821465">Έναρξη επιλογής</translation>
-<translation id="8743786158317878347">εισαγωγή σε δομημένο περιεχόμενο, όπως πίνακες</translation>
-<translation id="8747966237988593539">Ταξινομημένη λίστα</translation>
-<translation id="8759334257841767240">Δεν υπάρχει επόμενος σύνδεσμος.</translation>
-<translation id="8767968232364267681">Επικεφαλίδα επόμενου επιπέδου 4</translation>
-<translation id="8770473310765924354">έξοδος από δομημένο περιεχόμενο, όπως πίνακες</translation>
-<translation id="8791025954632646584">Σημασιολογική ερμηνεία ενεργή</translation>
-<translation id="8796411681063377102">Επικεφαλίδα επόμενου επιπέδου 3</translation>
-<translation id="8808582214901541005">Μάρτιος</translation>
-<translation id="8825828890761629845">banner</translation>
-<translation id="8851136666856101339">κύριο</translation>
-<translation id="8856538297388979332">Πατήστε τα πλήκτρα επάνω και κάτω για να δείτε τις εντολές, πατήστε "enter" για να τις ενεργοποιήσετε</translation>
-<translation id="8864099967139188018">Δεν υπάρχει επόμενη επικεφαλίδα επιπέδου 6.</translation>
-<translation id="8882002077197914455">Κεφαλίδα γραμμής</translation>
-<translation id="8896347895970027998">Εναλλαγή μεταξύ ενεργού ή ανενεργού ChromeVox.</translation>
-<translation id="8898516272131543774">Επανάληψη εκφώνησης σημείων στίξης</translation>
-<translation id="8900148057318340779">Κλειδί προθέματος</translation>
-<translation id="8908714597367957477">κεφαλίδα στήλης</translation>
-<translation id="8931936695772494138">Κενές κεφαλίδες</translation>
-<translation id="8937112856099038376">εσωτερικός σύνδεσμος</translation>
-<translation id="8940925288729953902">Κουμπιά τροποποιητή</translation>
-<translation id="8943175951035496220">Δεν υπάρχει κελί δεξιά.</translation>
-<translation id="8978496506222343566">επεξήγηση εργαλείου</translation>
-<translation id="900114243503212879">αρχείο</translation>
-<translation id="9027462562263121875">Δεν υπάρχουν πίνακες.</translation>
-<translation id="9040132695316389094">Επικεφαλίδα 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Εναλλαγή γραφικού στοιχείου αναζήτησης</translation>
-<translation id="9065283790526219006">+αναδυόμενα παράθυρα</translation>
-<translation id="9077213568694924680">καταργήθηκε από την επιλογή</translation>
-<translation id="9082874451376019682">Δεν υπάρχει προηγούμενο ρυθμιστικό.</translation>
-<translation id="9089864840575085222">Επανάληψη εκφώνησης πληκτρολόγησης</translation>
-<translation id="9107530006868467849">Δεν υπάρχει γραφικό στοιχείο προηγούμενου μέσου.</translation>
-<translation id="9108370397979208512">μαθηματικά</translation>
-<translation id="9108589040018540527">γραμμή κύλισης</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{σύμβολο "τοις εκατό"}other{# σύμβολα "τοις εκατό"}}</translation>
-<translation id="9115913704608474258">Νοέμβριος</translation>
-<translation id="9128414153595658330">διάλογος</translation>
-<translation id="9149560530563164529">ενότητα</translation>
-<translation id="9151211641321628915">Παρέχει μια σύντομη περιγραφή της τρέχουσας τοποθεσίας</translation>
-<translation id="9153606228985488238">Τόνος <ph name="PERCENT" /> τοις εκατό</translation>
-<translation id="9160096769946561184">Μετάβαση στο τέλος της τρέχουσας στήλης</translation>
-<translation id="9173115498289768110">Ένταση <ph name="PERCENT" /> τοις εκατό</translation>
-<translation id="9178973770513562274">Χρησιμοποιήστε τα πλήκτρα επάνω και κάτω για αναζήτηση ή πληκτρολογήστε για να κάνετε αναζήτηση.</translation>
-<translation id="9192904702577636854">Μαρκίζα</translation>
-<translation id="9212322457209634662">Δεν υπάρχει επόμενη ενότητα.</translation>
-<translation id="930275611743429116">Αρχή ή τέλος επιλογής.</translation>
-<translation id="948171205378458592">Μείωση ταχύτητας ομιλίας</translation>
-<translation id="962913030769097253">Επικεφαλίδα επόμενου επιπέδου 1</translation>
-<translation id="973955474346881951">Ενεργοποίηση/απενεργοποίηση λειτουργίας σταθεροποίησης</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb
deleted file mode 100644
index 5c36606676e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="en-GB">
-<translation id="1012173283529841972">List item</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Spanned.</translation>
-<translation id="1025074108959230262">Sticky mode disabled</translation>
-<translation id="1031961866430398710">then</translation>
-<translation id="1044777062731150180">No headers</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Invalid input</translation>
-<translation id="1082209053475788238">No previous level 6 heading.</translation>
-<translation id="1088219014394087294">No headings.</translation>
-<translation id="1106741348836243114">Turn sound feedback (earcons) on or off.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="TAG" /> collection with <ph name="NUM" /> items</translation>
-<translation id="1155043339247954670">No next list item.</translation>
-<translation id="1157782847298808853">Keyboard Help</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, combo box</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, menu item, with submenu</translation>
-<translation id="1177863135347784049">Customised</translation>
-<translation id="1188858454923323853">complementary</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – Giving Voice to Chrome</translation>
-<translation id="1229276918471378188">Previous jump</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Next level 6 heading</translation>
-<translation id="1275718070701477396">Selected</translation>
-<translation id="1319608975892113573">No previous block quote.</translation>
-<translation id="1321576897702511272">Hide ChromeVox help</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> of <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">character and word echo</translation>
-<translation id="1339428534620983148">Previous table column</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Right</translation>
-<translation id="136718599399906424">Next table row</translation>
-<translation id="1383876407941801731">Search</translation>
-<translation id="1385214448885562192">Press enter to accept or escape to cancel, down for next and up for previous.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, password text box</translation>
-<translation id="1467432559032391204">Left</translation>
-<translation id="1474557363159888097">No previous anchor.</translation>
-<translation id="1502086903961450562">Previous graphic</translation>
-<translation id="1506187449813838456">Increase pitch</translation>
-<translation id="151784044608172266">Next Sentence</translation>
-<translation id="1524531499102321782">Braille next Line</translation>
-<translation id="1546370775711804143">Scroll bar</translation>
-<translation id="1559739829547075274">Navigate backward</translation>
-<translation id="1571643229714746283">ChromeVox ready</translation>
-<translation id="158493514907962286">December</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Switch to 6 dot braille</translation>
-<translation id="1611168825862729585">Column header:</translation>
-<translation id="1613476421962910979">Earcons on</translation>
-<translation id="1618597272655350600">Announces a complete description of the current position</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{greater than}other{# greater than signs}}</translation>
-<translation id="1653266918374749391">Previous level 3 heading</translation>
-<translation id="1659072772017912254">Not ticked</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">ChromeVox Navigation</translation>
-<translation id="16777221443363124">Menu bar</translation>
-<translation id="1692077714702418899">structural line</translation>
-<translation id="1700517974991662022">Visited</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Next graphic</translation>
-<translation id="1781173782405573156">Pass through key</translation>
-<translation id="1787176709638001873">Password edit text</translation>
-<translation id="1810107444790159527">List box</translation>
-<translation id="1828385960365606039">May</translation>
-<translation id="1834891354138622109">Column</translation>
-<translation id="1865601187525349519">End of text</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Speak the current time and date.</translation>
-<translation id="1902396333223336119">Cell</translation>
-<translation id="1905379170753160525">Show headings list</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Week of the year control</translation>
-<translation id="1964135212174907577">Next Object</translation>
-<translation id="1969092762068865084">July</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Row header:</translation>
-<translation id="2002895034995108595">Reset current keymap</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{left bracket}other{# left brackets}}</translation>
-<translation id="2045490512405922022">not ticked</translation>
-<translation id="20601713649439366">No previous math expression.</translation>
-<translation id="207477615537953741">Semantics off</translation>
-<translation id="2086961585857038472">Next Word</translation>
-<translation id="2089387485033699258">en</translation>
-<translation id="2091933974477985526">Previous editable text area</translation>
-<translation id="2100350898815792233">All punctuation</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">access key:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Change the current 6 dot braille table by selecting an option from the list below.</translation>
-<translation id="2169714232367507776">Click on current item</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{close paren}other{# close parens}}</translation>
-<translation id="2199994615414171367">Previous math</translation>
-<translation id="2223693656926968778">Take action on current item</translation>
-<translation id="225732394367814946">Increase rate of speech</translation>
-<translation id="2267945578749931355">Next Character</translation>
-<translation id="2281234842553884450">Previous slider</translation>
-<translation id="2318372665160196757">Main</translation>
-<translation id="2329324941084714723">Tab panel</translation>
-<translation id="2344193891939537199">Date time control</translation>
-<translation id="2359897517538099099">Not in table mode.</translation>
-<translation id="241124561063364910">followed by</translation>
-<translation id="2417569100218200841">Content info</translation>
-<translation id="2422937916923936891">Menu item tick box</translation>
-<translation id="2429669115401274487">p.m.</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> is now the new ChromeVox modifier.</translation>
-<translation id="2450814015951372393">Tick box</translation>
-<translation id="2462626033734746142">Radio button group</translation>
-<translation id="2471138580042810658">Heading 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisk}other{# asterisks}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> has been reset.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Group</translation>
-<translation id="2582407057977008361">Aside</translation>
-<translation id="2589102159832527089">This page contains the text automatically extracted from the PDF file &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Click here for the original.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">with {COUNT,plural, =1{# item}other{# items}}</translation>
-<translation id="2614981083756825552">Math ML Layout</translation>
-<translation id="2626530649491650971">clickable</translation>
-<translation id="2628764385451019380">No previous combo box.</translation>
-<translation id="2637227747952042642">Math</translation>
-<translation id="2639750663247012216">ChromeVox modifier</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">Click the item under a routing key</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{open paren}other{# open parens}}</translation>
-<translation id="2705875883745373140">Not pressed</translation>
-<translation id="2706462751667573066">Up</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">a.m.</translation>
-<translation id="2749275490991666823">Ticked</translation>
-<translation id="27527859628328957">Jump to next focusable item</translation>
-<translation id="2770781857296573485">Enter group exploration</translation>
-<translation id="2777845298774924149">Exited</translation>
-<translation id="2800204403141299078">No more different elements.</translation>
-<translation id="2800780099804980316">No previous level 1 heading.</translation>
-<translation id="2811204574343810641">Row</translation>
-<translation id="2816654101880605877">No next slider.</translation>
-<translation id="2841013758207633010">Time</translation>
-<translation id="2843837985843789981">Previous Group</translation>
-<translation id="2844995807198708617">Context Menu</translation>
-<translation id="2849332794118375855">No next tick box.</translation>
-<translation id="2864481629947106776">Previous link</translation>
-<translation id="2873259058405069099">Go to beginning of table</translation>
-<translation id="2894654529758326923">Information</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{left brace}other{# left braces}}</translation>
-<translation id="2911433807131383493">Open ChromeVox tutorial</translation>
-<translation id="2932083475399492303">Toggle line type between structural or layout</translation>
-<translation id="2964026537669811554">Heading group</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tab}other{# tabs}}</translation>
-<translation id="2972078295414139404">No previous visited link.</translation>
-<translation id="2972205263822847197">Tool tip</translation>
-<translation id="2998131015536248178">Previous Character</translation>
-<translation id="2999559350546931576">Decrease pitch</translation>
-<translation id="2999945368667127852">No next media widget.</translation>
-<translation id="3012414509011670858">No previous section.</translation>
-<translation id="3030432017085518523">Menu item radio button</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrophe}other{# apostrophes}}</translation>
-<translation id="3046838483509668188">ChromeVox Options</translation>
-<translation id="3047143736589213134">Experimental keymap</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> menu opened</translation>
-<translation id="3078345202707391975">Next level 2 heading</translation>
-<translation id="3078740164268491126">table</translation>
-<translation id="3082557070674409251">Clicked</translation>
-<translation id="3084806535845658316">no typing echo</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">No next math expression.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Next landmark</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Collapsed</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Show landmarks list</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Next Line</translation>
-<translation id="3155083529632865074">No previous button.</translation>
-<translation id="3163593631834463955">Empty column header</translation>
-<translation id="316542773973815724">Navigation</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{space}other{# spaces}}</translation>
-<translation id="320961988183078793">entered <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, tab</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Visited link</translation>
-<translation id="323731244387692321">Open ChromeVox keyboard help</translation>
-<translation id="3241052487511142956">Previous visited link</translation>
-<translation id="3286390186030710347">Slider</translation>
-<translation id="3299925995433437805">No next visited link.</translation>
-<translation id="3303384412438961941">Press any key to learn its name. Ctrl+W will close the keyboard explorer.</translation>
-<translation id="3307886118343381874">Go to end of table</translation>
-<translation id="3311969765485641742">Press Alt+Shift+A to review alerts</translation>
-<translation id="3312997241656799641">Next visited link</translation>
-<translation id="3321460131042519426">Enable word wrap</translation>
-<translation id="3322936298410871309">Previous level 1 heading</translation>
-<translation id="3323447499041942178">Text box</translation>
-<translation id="3353420241558113817">{"ar": "Arabic",
- "bg": "Bulgarian",
- "ca": "Catalan",
- "cs": "Czech",
- "da": "Danish",
- "de": "German",
- "de_CH": "German (Switzerland)",
- "de_DE": "German (Germany)",
- "el": "Greek",
- "en": "English",
- "en_CA": "English (Canada)",
- "en_GB": "English (United Kingdom)",
- "en_US": "English (United States)",
- "es": "Spanish",
- "et": "Estonian",
- "fr": "French",
- "fr_CA": "French (Canada)",
- "fr_FR": "French (France)",
- "fi": "Finnish",
- "he": "Hebrew",
- "hi": "Hindi",
- "hr": "Croatian",
- "hu": "Hungarian",
- "is": "Icelandic",
- "it": "Italian",
- "ko": "Korean",
- "lt": "Lithuanian",
- "lv": "Latvian",
- "nb": "Norwegian Bokmål",
- "nl": "Dutch",
- "pl": "Polish",
- "pt": "Portuguese",
- "ro": "Romanian",
- "ru": "Russian",
- "sk": "Slovak",
- "sl": "Slovenian",
- "sr": "Serbian",
- "sv": "Swedish",
- "tr": "Turkish",
- "vi": "Vietnamese",
- "zh": "Chinese",
- "zh_TW": "Chinese (Traditional Han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plus}other{# plus signs}}</translation>
-<translation id="338583716107319301">Separator</translation>
-<translation id="3389259863310851658">Previous form field</translation>
-<translation id="3390225400784126843">Next different element.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, menu item</translation>
-<translation id="3406283310380167331">Show forms list</translation>
-<translation id="3422338090358345848">Open keyboard explorer</translation>
-<translation id="3457000393508828486">Partially pressed</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, button</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> to <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{right bracket}other{# right brackets}}</translation>
-<translation id="3493915602752813531">No next anchor.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{question mark}other{# question marks}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{caret}other{# carets}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, tick box not ticked</translation>
-<translation id="3599054940393788245">Not inside math</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{backtick}other{# backticks}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollar}other{# dollar signs}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, list box</translation>
-<translation id="3687295507293856493">Make a guess at the column header of the current cell</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Controlling Speech</translation>
-<translation id="3716845769494773620">Multi line</translation>
-<translation id="3731746171184829332">No previous heading.</translation>
-<translation id="3762198587642264450">Go to end of the current row</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Exited dialogue.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Auto-completion list</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Next media</translation>
-<translation id="3819376190738087562">No jumps.</translation>
-<translation id="385383972552776628">Open options page</translation>
-<translation id="3856075812838139784">Read only</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Previous level 6 heading</translation>
-<translation id="3914173277599553213">Required</translation>
-<translation id="3962990492275676168">Start reading from current location</translation>
-<translation id="4004802134384979325">ticked</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Month control</translation>
-<translation id="4039983576244166038">Empty row header</translation>
-<translation id="4042843249978639960">No next level 2 heading.</translation>
-<translation id="4043348641337972076">No previous ARIA landmark.</translation>
-<translation id="4047216625641135770">Mark</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}other{# tildes}}</translation>
-<translation id="409334809956508737">Previous Object</translation>
-<translation id="4099274309791143834">with submenu</translation>
-<translation id="4107807507418787238">No cell below.</translation>
-<translation id="4116415223832267137">Alert</translation>
-<translation id="4147126331795725888">No next control.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{right brace}other{# right braces}}</translation>
-<translation id="4158704014418536539">Case sensitive.</translation>
-<translation id="4161663686871496107">ChromeVox spoken feedback is ready</translation>
-<translation id="4173994908659439270">No next editable text field.</translation>
-<translation id="4176463684765177261">Disabled</translation>
-<translation id="4188530942454211480">Previous Sentence</translation>
-<translation id="4202186506458631436">Move right</translation>
-<translation id="4206289001967551965">Inside table</translation>
-<translation id="4215733775853809057">Next slider</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{dash}other{# dashes}}</translation>
-<translation id="421884353938374759">colour picker</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">No cell left.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, Grade <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Note</translation>
-<translation id="4254798249533888099">Tree</translation>
-<translation id="4255943572433203166">Use the options below to customise ChromeVox. Changes take effect immediately.</translation>
-<translation id="4271220233568730077">Next math</translation>
-<translation id="4271521365602459209">No more results.</translation>
-<translation id="4287520460805643128">No next article.</translation>
-<translation id="4289540628985791613">Overview</translation>
-<translation id="4300318234632215983">Announce the URL behind a link</translation>
-<translation id="4301352596632316575">has submenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{dot}=3{ellipsis}other{# dots}}</translation>
-<translation id="4347461890115250064">No next list.</translation>
-<translation id="4367650418938037324">Math ML Leaf</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Stop speech</translation>
-<translation id="4373197658375206385">No previous item that isn't a link.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">No links.</translation>
-<translation id="4476183483923481720">new line</translation>
-<translation id="4482330759234983253">Previous table</translation>
-<translation id="4491109536499578614">Image</translation>
-<translation id="4529987814483543472">Classic keymap</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{slash}other{# slashes}}</translation>
-<translation id="4547556996012970016">Next level 5 heading</translation>
-<translation id="4562381607973973258">Header</translation>
-<translation id="4591507479202817876">, selected</translation>
-<translation id="4597532268155981612">form</translation>
-<translation id="4597896406374528575">April</translation>
-<translation id="4615592953348396470">Ignoring next key press</translation>
-<translation id="461613135510474570">Sentence</translation>
-<translation id="4647836961514597010">Colour picker</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Previous landmark</translation>
-<translation id="4696413482802371445">No next level 5 heading.</translation>
-<translation id="4729095194763193578">Previous table row</translation>
-<translation id="4736221692378411923">August</translation>
-<translation id="4740661827607246557">Help Commands</translation>
-<translation id="4759716709594980008">ChromeOS Keyboard Explorer</translation>
-<translation id="4763296182459741068">Wrapped to bottom</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Announce the title of the current page</translation>
-<translation id="4826415162591436065">Navigate forward</translation>
-<translation id="4826604887384865800">Next jump</translation>
-<translation id="4827410568042294688">unselected</translation>
-<translation id="4842108708071771135">No next block quote.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Previous similar element.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Enable TTS logging</translation>
-<translation id="4877261390094455813">Enter a search query.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Internal link</translation>
-<translation id="4953585991029886728">Edit text</translation>
-<translation id="4954534434583049121">Previous block quote</translation>
-<translation id="4973717656530883744">Min <ph name="X" /></translation>
-<translation id="4973762002207131920">Switched to <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milliseconds</translation>
-<translation id="49787999531187221">ChromeVox is now inactive.</translation>
-<translation id="4979404613699303341">Previous button</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, list box</translation>
-<translation id="4983588134362688868">Jump to the top of the page</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, window</translation>
-<translation id="4993152509206108683">Rate <ph name="PERCENT" /> percent</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, radio button selected</translation>
-<translation id="4997475792277222884">No next item that isn't a link.</translation>
-<translation id="5000760171916499057">No forms.</translation>
-<translation id="5005670136041063723">No more similar elements.</translation>
-<translation id="501473567976723023">January</translation>
-<translation id="5041394372352067729">Move braille display to top of page</translation>
-<translation id="5042770794184672516">Increase speech volume</translation>
-<translation id="5050015258024679800">Previous level 4 heading</translation>
-<translation id="5054047268577924192">Previous list item</translation>
-<translation id="5078661581131202757">File selection</translation>
-<translation id="5080758118274074384">double clicked</translation>
-<translation id="5098541983634824365">Leaving grid.</translation>
-<translation id="5102981729317424850">Tool bar</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">No previous form field.</translation>
-<translation id="5111640677200759579">Column header</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">No previous link.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, unselected</translation>
-<translation id="5183440668879371625">Braille previous Line</translation>
-<translation id="5184944171021383281">No next form field.</translation>
-<translation id="5189244881767082992">Line</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> is already assigned to a command.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> list.</translation>
-<translation id="520883772648104506">No next radio button.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Object</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, tab</translation>
-<translation id="5310788376443009632">removed:</translation>
-<translation id="5320727453979144100">Sticky mode enabled</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{comma}other{# commas}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, text box</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Skip backward during continuous reading</translation>
-<translation id="5368000168321181111">Earcons off</translation>
-<translation id="5374320867641260420">No next button.</translation>
-<translation id="5382299583965267720">No next level 1 heading.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{semicolon}other{# semicolons}}</translation>
-<translation id="5411891038905756502">No previous jump point.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{less than}other{# less than signs}}</translation>
-<translation id="5455441614648621694">Complementary</translation>
-<translation id="5485036206801896268">No previous graphic.</translation>
-<translation id="5486947920110100234">No next jump point.</translation>
-<translation id="549602578321198708">Word</translation>
-<translation id="5500932716852106146">No previous editable text field.</translation>
-<translation id="5502713021410870035">September</translation>
-<translation id="5507663321906818013">Debug benchmark</translation>
-<translation id="5518443085409638729">Place cursor between characters when editing text (like Mac OS X).</translation>
-<translation id="552195134157544755">Radio button</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">No previous level 5 heading.</translation>
-<translation id="556042886152191864">Button</translation>
-<translation id="5561345396546889625">Next list</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Edit text, email entry</translation>
-<translation id="5597170376237141345">Next tick box</translation>
-<translation id="5597933780944041114">No next heading.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, radio button unselected</translation>
-<translation id="5601172225407283979">Perform default action</translation>
-<translation id="5608798115546226984">Auto-completion inline</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Log</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">No previous table.</translation>
-<translation id="5655682562155942719">Jump Commands</translation>
-<translation id="56637627897541303">Text area</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Landmark</translation>
-<translation id="5683155931978483559">Previous tick box</translation>
-<translation id="5684277895745049190">List</translation>
-<translation id="5700650669149824506">No previous level 4 heading.</translation>
-<translation id="5709192780268610569">No long description</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Next table column</translation>
-<translation id="571866080859340309">Exploring groups</translation>
-<translation id="5728409797179002635">No table found.</translation>
-<translation id="5748623122140342504">Previous level 5 heading</translation>
-<translation id="5750633686117194034">No modifier pressed; please press and hold one or more modifiers; lift your fingers once done and you will hear the keys set. Tab to exit.</translation>
-<translation id="5788275253279308023">incognito window <ph name="TITLE" /> tab</translation>
-<translation id="5806206155699461681">Enhance specific sites (like Google Search).</translation>
-<translation id="5819072574982403430">Tree item</translation>
-<translation id="5826479389509458994">row <ph name="ROW" /> column <ph name="COL" /></translation>
-<translation id="5850707923114094062">Pan backward</translation>
-<translation id="5851548754964597211">Tab list</translation>
-<translation id="5859752971144398932">Exited find in page.</translation>
-<translation id="5866042630553435010">Partially checked</translation>
-<translation id="5869546221129391014">Grid</translation>
-<translation id="5876817486144482042">Decrease speech volume</translation>
-<translation id="5887397643266327462">Braille captions enabled.</translation>
-<translation id="5891934789323004067">Table</translation>
-<translation id="5919442531159595654">copy.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{equal}other{# equal signs}}</translation>
-<translation id="5939518447894949180">Reset</translation>
-<translation id="5948123859135882163">Toggle interpretation of math expressions between structural and semantic</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialogue</translation>
-<translation id="5963413905009737549">Section</translation>
-<translation id="5968607524793740041">Show context menu</translation>
-<translation id="5983179082906765664">Increase navigation granularity</translation>
-<translation id="5999630716831179808">Voices</translation>
-<translation id="6000417740266304866">Change the current 8 dot braille table by selecting an option from the list below.</translation>
-<translation id="6006050241733874051">Form</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{backslash}other{# backslashes}}</translation>
-<translation id="6037602951055904232">Pan forward</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">End of cell.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Space</translation>
-<translation id="6142308968191113180">Heading 4</translation>
-<translation id="6169420925157477918">Image with long description</translation>
-<translation id="6172087735260766220">Unable to access accessible text from copy-protected PDF.</translation>
-<translation id="6186305613600865047">Jump to the bottom of the page</translation>
-<translation id="6193330012414963395">a.m. p.m.</translation>
-<translation id="622484624075952240">Down</translation>
-<translation id="6236061028292614533">Next heading</translation>
-<translation id="6254901459154107917">Next editable text area</translation>
-<translation id="6259464875943891919">Exited <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Next similar element.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">No next combo box.</translation>
-<translation id="6307969636681130414">Pressed</translation>
-<translation id="6324551002951139333">Grammatical mistake detected</translation>
-<translation id="6348657800373377022">Combo box</translation>
-<translation id="6355910664415701303">No previous list item.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Previous heading</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">No previous radio button.</translation>
-<translation id="6414968628640960377">Previous different element.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{colon}other{# colons}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Alert dialogue</translation>
-<translation id="6459511626086141404">Flat keymap</translation>
-<translation id="6468049171101508116">Next button</translation>
-<translation id="6491972999578897419">Change the current voice by selecting an option from the list below.</translation>
-<translation id="6508059270146105198">Move braille display to bottom of page</translation>
-<translation id="6536864053412760904">Math ML Token</translation>
-<translation id="6550720799683018100">Change the current keymap by selecting an option from the list below.</translation>
-<translation id="6561818612645211875">Go to beginning of the current row</translation>
-<translation id="6587021927234520429">No next level 4 heading.</translation>
-<translation id="6601344353291556895">Enable verbose descriptions.</translation>
-<translation id="6615602925644411249">Find in page.</translation>
-<translation id="6633350132811819843">No next table.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Progress bar</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Document</translation>
-<translation id="6697092096875747123">Previous combo box</translation>
-<translation id="6714813999819678458">Previous level 2 heading</translation>
-<translation id="6716505898850596801">Modifier keys</translation>
-<translation id="671916444866103745">No next ARIA landmark.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, combo box</translation>
-<translation id="6735257939857578167">with <ph name="NUM" /> items</translation>
-<translation id="6736510033526053669">tab created</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Article</translation>
-<translation id="6787839852456839824">Keyboard shortcuts</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Footer</translation>
-<translation id="6871161210040114857">Ignoring case.</translation>
-<translation id="6877435256196695200">No next graphic.</translation>
-<translation id="6897341342232909480">Move left</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Deleted</translation>
-<translation id="6911965441508464308">No cell above.</translation>
-<translation id="6919104639734799681">Show tables list</translation>
-<translation id="6964088412282673743">No previous control.</translation>
-<translation id="6996566555547746822">Next combo box</translation>
-<translation id="7005146664810010831">No URL found</translation>
-<translation id="7010712454773919705">ChromeVox modifier key</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Previous list</translation>
-<translation id="7041173719775863268">End selection</translation>
-<translation id="7095834689119144465">Edit text numeric only</translation>
-<translation id="7096001299300236431">Previous media</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">word echo</translation>
-<translation id="713824876195128146">Next block quote</translation>
-<translation id="7161771961008409533">Pop-up button</translation>
-<translation id="7167657087543110">character echo</translation>
-<translation id="7170733337935166589">Skip forward during continuous reading</translation>
-<translation id="7181697990050180700">Customise keyboard shortcuts for frequently used commands by typing them into the corresponding fields below.</translation>
-<translation id="7203150201908454328">Expanded</translation>
-<translation id="7210211103303402262">minutes</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">line</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Heading</translation>
-<translation id="7241683698754534149">Open long description in a new tab</translation>
-<translation id="7248671827512403053">Application</translation>
-<translation id="725969808843520477">Next radio button</translation>
-<translation id="7269119382257320590">No punctuation</translation>
-<translation id="7273174640290488576">Blank</translation>
-<translation id="7285387653379749618">Tables</translation>
-<translation id="7289186959554153431">Heading 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Braille captions disabled.</translation>
-<translation id="7318872822751139669">Use the mouse to change focus.</translation>
-<translation id="7322388933135261569">February</translation>
-<translation id="7332592614823088566">Row <ph name="ROWINDEX" /> of <ph name="ROWTOTAL" />, Column <ph name="COLINDEX" /> of <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">has pop-up</translation>
-<translation id="7356165926712028380">Switch to 8 dot braille</translation>
-<translation id="7362871137496673139">No previous level 2 heading.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersand}other{# ampersands}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Leaving table.</translation>
-<translation id="739763518212184081">Previous Line</translation>
-<translation id="7400575256015741911">Spelling mistake detected</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">return</translation>
-<translation id="7434509671034404296">Developer</translation>
-<translation id="7439060726180460871">Directory</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Entered dialogue</translation>
-<translation id="7532613204005497612">June</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, slider</translation>
-<translation id="7586163296341959563">paste.</translation>
-<translation id="7596919493010894443">cleared selection</translation>
-<translation id="7604026522577407655">Go to beginning of the current column</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Announce the URL of the current page</translation>
-<translation id="7609363189280667021">Toggle braille captions</translation>
-<translation id="762020119231868829">Pauses all currently playing media widgets</translation>
-<translation id="7625690649919402823">Next table</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Grade <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">No previous level 3 heading.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, text box</translation>
-<translation id="7663318257180412551">Heading 2</translation>
-<translation id="7674576868851035240">Next link</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">Edit text, URL entry</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Previous radio button</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, password text box</translation>
-<translation id="7805247615045262757">default navigation</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Next Group</translation>
-<translation id="7819187121850078213">window <ph name="TITLE" /> tab</translation>
-<translation id="7828956995407538686">October</translation>
-<translation id="7839679365527550018">Previous Word</translation>
-<translation id="7851816175263618915">Some punctuation</translation>
-<translation id="7870596830398826354">Math ML Tree</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Toggle ChromeVox classic.</translation>
-<translation id="7895896691902835279">Unknown link</translation>
-<translation id="7927711904086083099">Not selected</translation>
-<translation id="7935627501098484003">Time control</translation>
-<translation id="7939428177581522200">added to selection</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{at}other{# at signs}}</translation>
-<translation id="7965147473449754028">menu closed</translation>
-<translation id="7974390230414479278">Menu item</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{exclamation point}other{# exclamation points}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{quote}other{# quotes}}</translation>
-<translation id="8033827949643255796">selected</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">Edit text, search entry</translation>
-<translation id="8049189770492311300">Timer</translation>
-<translation id="8065607967589909823">Selection is</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">No ARIA landmarks.</translation>
-<translation id="8153880621934657047">Not inside table.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{underscore}other{# underscores}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">cut.</translation>
-<translation id="8199231515320852133">Announce the headers of the current cell</translation>
-<translation id="820417203470636242">Empty cell.</translation>
-<translation id="8215202828671303819">Multi select</translation>
-<translation id="8276439074553447000">Jump to previous focusable item</translation>
-<translation id="8278417001922463147">No previous article.</translation>
-<translation id="8283603667300770666">Next form field</translation>
-<translation id="831207808878314375">Definition</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">hours</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{pound}other{# pound signs}}</translation>
-<translation id="8374154622594089836">month</translation>
-<translation id="8378855320830505539">Region</translation>
-<translation id="8382679411218029383">Auto-completion inline and list</translation>
-<translation id="8428603554127842284">level <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">No next level 3 heading.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">No previous tick box.</translation>
-<translation id="8455868257606149352">Max <ph name="X" /></translation>
-<translation id="84575901236241018">has access key, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Decrease navigation granularity</translation>
-<translation id="8520472399088452386">Spin button</translation>
-<translation id="8538744478902126321">Make a guess at the row header of the current cell</translation>
-<translation id="8540054775867439484">Wrapped to top</translation>
-<translation id="8548973727659841685">Character</translation>
-<translation id="8561322612995434619">has pop up</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Next list item</translation>
-<translation id="860150890330522909"><ph name="NAME" /> tick box ticked</translation>
-<translation id="8606621670302093223">Date control</translation>
-<translation id="8631359288236106450">selected <ph name="COUNT" /> items</translation>
-<translation id="8638532244051952400">Announce current cell co-ordinates</translation>
-<translation id="8650576015643545550">No previous list.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Show links list</translation>
-<translation id="8664519043722036194">seconds</translation>
-<translation id="867187640362843212">Heading 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{pipe}other{# vertical pipes}}</translation>
-<translation id="8735450637152821465">Start selection</translation>
-<translation id="8743786158317878347">enter structured content, such as tables</translation>
-<translation id="8747966237988593539">Ordered List</translation>
-<translation id="8759334257841767240">No next link.</translation>
-<translation id="8767968232364267681">Next level 4 heading</translation>
-<translation id="8770473310765924354">exit structured content, such as tables</translation>
-<translation id="8791025954632646584">Semantics on</translation>
-<translation id="8796411681063377102">Next level 3 heading</translation>
-<translation id="8808582214901541005">March</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Press up or down to review commands, press enter to activate</translation>
-<translation id="8864099967139188018">No next level 6 heading.</translation>
-<translation id="8882002077197914455">Row header</translation>
-<translation id="8896347895970027998">Toggle ChromeVox active or inactive.</translation>
-<translation id="8898516272131543774">Cycle punctuation echo</translation>
-<translation id="8900148057318340779">Prefix key</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Empty headers</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Modifier Keys</translation>
-<translation id="8943175951035496220">No cell right.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">No tables.</translation>
-<translation id="9040132695316389094">Heading 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Toggle search widget</translation>
-<translation id="9065283790526219006">+pop-up</translation>
-<translation id="9077213568694924680">removed from selection</translation>
-<translation id="9082874451376019682">No previous slider.</translation>
-<translation id="9089864840575085222">Cycle typing echo</translation>
-<translation id="9107530006868467849">No previous media widget.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{percent}other{# percent signs}}</translation>
-<translation id="9115913704608474258">November</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Announces a brief description of the current position</translation>
-<translation id="9153606228985488238">Pitch <ph name="PERCENT" /> percent</translation>
-<translation id="9160096769946561184">Go to end of the current column</translation>
-<translation id="9173115498289768110">Volume <ph name="PERCENT" /> percent</translation>
-<translation id="9178973770513562274">Use up and down arrow keys to browse, or type to search.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">No next section.</translation>
-<translation id="930275611743429116">Start or end selection.</translation>
-<translation id="948171205378458592">Decrease rate of speech</translation>
-<translation id="962913030769097253">Next level 1 heading</translation>
-<translation id="973955474346881951">Enable / Disable sticky mode</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es-419.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es-419.xtb
deleted file mode 100644
index 19adfd96391..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es-419.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="es-419">
-<translation id="1012173283529841972">Elemento de lista</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Ampliada</translation>
-<translation id="1025074108959230262">Modo permanente inhabilitado</translation>
-<translation id="1031961866430398710">luego</translation>
-<translation id="1044777062731150180">Sin encabezados</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Entrada no válida</translation>
-<translation id="1082209053475788238">No hay ningún encabezado de nivel 6 anterior.</translation>
-<translation id="1088219014394087294">No hay encabezados.</translation>
-<translation id="1106741348836243114">Permite activar o desactivar el sonido.</translation>
-<translation id="1120743664840974483">{"a": "alfa", "b": "bravo", "c": "chocolate", "d": "delta", "e": "eco", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "julieta","k": "kilo", "l": "lima", "m": "maría", "n": "noviembre", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniforme", "v": "víctor", "w": "whisky","x": "xilófono", "y": "yanqui", "z": "zulú"}</translation>
-<translation id="113582498867142724">Colección de <ph name="TAG" /> con <ph name="NUM" /> elementos</translation>
-<translation id="1155043339247954670">No hay ningún elemento de la lista posterior.</translation>
-<translation id="1157782847298808853">Ayuda del teclado</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, cuadro combinado</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, elemento del menú, con submenú</translation>
-<translation id="1177863135347784049">Personalizado</translation>
-<translation id="1188858454923323853">complementario</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox, la voz de Chrome</translation>
-<translation id="1229276918471378188">Salto anterior</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Siguiente encabezado de nivel 6</translation>
-<translation id="1275718070701477396">Seleccionado</translation>
-<translation id="1319608975892113573">No hay ninguna etiqueta "blockquote" anterior.</translation>
-<translation id="1321576897702511272">Ocultar ayuda de ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> de <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">reproducción oral de caracteres y palabras</translation>
-<translation id="1339428534620983148">Columna anterior de la tabla</translation>
-<translation id="1342835525016946179">artículo</translation>
-<translation id="1346748346194534595">Derecha</translation>
-<translation id="136718599399906424">Siguiente fila de la tabla</translation>
-<translation id="1383876407941801731">Buscar</translation>
-<translation id="1385214448885562192">Presiona Enter para aceptar, Escape para cancelar, la tecla de flecha hacia abajo para ver el siguiente resultado y la tecla de flecha hacia arriba para ver el resultado anterior.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, cuadro de texto de la contraseña</translation>
-<translation id="1467432559032391204">Izquierda</translation>
-<translation id="1474557363159888097">No hay ningún anclaje anterior.</translation>
-<translation id="1502086903961450562">Gráfico anterior</translation>
-<translation id="1506187449813838456">Aumentar el tono</translation>
-<translation id="151784044608172266">Frase siguiente</translation>
-<translation id="1524531499102321782">Línea de braille siguiente</translation>
-<translation id="1546370775711804143">Barra de desplazamiento</translation>
-<translation id="1559739829547075274">Retroceder</translation>
-<translation id="1571643229714746283">ChromeVox está listo.</translation>
-<translation id="158493514907962286">Diciembre</translation>
-<translation id="1594072653727561613">mnú</translation>
-<translation id="1610130962244179598">Cambiar a braille de seis puntos</translation>
-<translation id="1611168825862729585">Encabezado de columna:</translation>
-<translation id="1613476421962910979">Sonido activado</translation>
-<translation id="1618597272655350600">Muestra una descripción completa de la posición actual.</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{mayor que}other{# signos mayor que}}</translation>
-<translation id="1653266918374749391">Encabezado anterior de nivel 3</translation>
-<translation id="1659072772017912254">Sin marcar</translation>
-<translation id="1669290819662866522">semana</translation>
-<translation id="1674262202423278359">Navegación de ChromeVox</translation>
-<translation id="16777221443363124">Barra de menús</translation>
-<translation id="1692077714702418899">línea estructural</translation>
-<translation id="1700517974991662022">Visitado</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">pie</translation>
-<translation id="174268867904053074">Siguiente gráfico</translation>
-<translation id="1781173782405573156">Tecla de acceso rápido</translation>
-<translation id="1787176709638001873">Texto de edición de contraseña</translation>
-<translation id="1810107444790159527">Cuadro de lista</translation>
-<translation id="1828385960365606039">Mayo</translation>
-<translation id="1834891354138622109">Columna</translation>
-<translation id="1865601187525349519">Fin del texto</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Di la fecha y la hora actuales.</translation>
-<translation id="1902396333223336119">Celda</translation>
-<translation id="1905379170753160525">Mostrar lista de encabezados</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Control de semana del año</translation>
-<translation id="1964135212174907577">Objeto siguiente</translation>
-<translation id="1969092762068865084">Julio</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Encabezado de fila:</translation>
-<translation id="2002895034995108595">Restablecer el mapa de teclas actual</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{corchete de apertura}other{# corchetes de apertura}}</translation>
-<translation id="2045490512405922022">sin marcar</translation>
-<translation id="20601713649439366">No hay expresiones matemáticas anteriores.</translation>
-<translation id="207477615537953741">Semántica desactivada</translation>
-<translation id="2086961585857038472">Palabra siguiente</translation>
-<translation id="2089387485033699258">es-419</translation>
-<translation id="2091933974477985526">Área de texto editable anterior</translation>
-<translation id="2100350898815792233">Todos los signos de puntuación</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">tecla de acceso: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Para cambiar la tabla actual de braille de seis puntos, selecciona una opción de la siguiente lista.</translation>
-<translation id="2169714232367507776">Hacer clic en el elemento actual</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{paréntesis de cierre}other{# paréntesis de cierre}}</translation>
-<translation id="2199994615414171367">Expresión matemática anterior</translation>
-<translation id="2223693656926968778">Tomar medidas sobre el elemento actual</translation>
-<translation id="225732394367814946">Hablar más rápido</translation>
-<translation id="2267945578749931355">Carácter siguiente</translation>
-<translation id="2281234842553884450">Control deslizante anterior</translation>
-<translation id="2318372665160196757">Principales</translation>
-<translation id="2329324941084714723">Panel de pestañas</translation>
-<translation id="2344193891939537199">Control de hora y fecha</translation>
-<translation id="2359897517538099099">No está en el modo de tabla.</translation>
-<translation id="241124561063364910">seguido de</translation>
-<translation id="2417569100218200841">Información del contenido</translation>
-<translation id="2422937916923936891">Casilla de verificación del elemento de menú</translation>
-<translation id="2429669115401274487">p. m.</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> ahora es la nueva tecla modificadora de ChromeVox.</translation>
-<translation id="2450814015951372393">Casilla de verificación</translation>
-<translation id="2462626033734746142">Grupo de botones de selección</translation>
-<translation id="2471138580042810658">Encabezado 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisco}other{# asteriscos}}</translation>
-<translation id="2549392850788122959">Se restableció <ph name="KEY" />.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Grupo</translation>
-<translation id="2582407057977008361">Lateral</translation>
-<translation id="2589102159832527089">Esta página incluye el texto que se extrajo automáticamente del archivo PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Haz clic aquí para acceder al original&lt;/a&gt;.</translation>
-<translation id="2606210917827248971">con {COUNT,plural, =1{# elemento}other{# elementos}}</translation>
-<translation id="2614981083756825552">Diseño de MathML</translation>
-<translation id="2626530649491650971">elemento en el que se puede hacer clic</translation>
-<translation id="2628764385451019380">No hay ningún cuadro combinado anterior.</translation>
-<translation id="2637227747952042642">Math</translation>
-<translation id="2639750663247012216">Tecla modificadora de ChromeVox</translation>
-<translation id="2644542693584024604">error ortográfico</translation>
-<translation id="2667291555398229137">Hacer clic en el elemento que aparece debajo de una clave de enrutamiento</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{paréntesis de apertura}other{# paréntesis de apertura}}</translation>
-<translation id="2705875883745373140">Sin presionar</translation>
-<translation id="2706462751667573066">Arriba</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">a. m.</translation>
-<translation id="2749275490991666823">Seleccionado</translation>
-<translation id="27527859628328957">Saltar al siguiente elemento enfocable</translation>
-<translation id="2770781857296573485">Ingresar exploración de grupos</translation>
-<translation id="2777845298774924149">Salió.</translation>
-<translation id="2800204403141299078">No hay más elementos diferentes.</translation>
-<translation id="2800780099804980316">No hay ningún encabezado de nivel 1 anterior.</translation>
-<translation id="2811204574343810641">Fila</translation>
-<translation id="2816654101880605877">No hay ningún control deslizante posterior.</translation>
-<translation id="2841013758207633010">Hora</translation>
-<translation id="2843837985843789981">Grupo anterior</translation>
-<translation id="2844995807198708617">Menú contextual</translation>
-<translation id="2849332794118375855">No hay ninguna casilla de verificación posterior.</translation>
-<translation id="2864481629947106776">Vínculo anterior</translation>
-<translation id="2873259058405069099">Ir al principio de la tabla</translation>
-<translation id="2894654529758326923">Información</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{llave de apertura}other{# llaves de apertura}}</translation>
-<translation id="2911433807131383493">Abrir tutorial de ChromeVox</translation>
-<translation id="2932083475399492303">Alternar entre líneas estructurales y líneas de diseño</translation>
-<translation id="2964026537669811554">Grupo de encabezados</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulación}other{# tabulaciones}}</translation>
-<translation id="2972078295414139404">No hay ningún vínculo anterior visitado.</translation>
-<translation id="2972205263822847197">Información de la herramienta</translation>
-<translation id="2998131015536248178">Carácter anterior</translation>
-<translation id="2999559350546931576">Disminuir el tono</translation>
-<translation id="2999945368667127852">No hay ningún widget multimedia posterior.</translation>
-<translation id="3012414509011670858">No hay ninguna sección anterior.</translation>
-<translation id="3030432017085518523">Botón de selección del elemento de menú</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apóstrofo}other{# apóstrofos}}</translation>
-<translation id="3046838483509668188">Opciones de ChromeVox</translation>
-<translation id="3047143736589213134">Mapa de teclado experimental</translation>
-<translation id="3060756054951570867">menú <ph name="TITLE" /> abierto</translation>
-<translation id="3078345202707391975">Siguiente encabezado de nivel 2</translation>
-<translation id="3078740164268491126">tabla</translation>
-<translation id="3082557070674409251">Se hizo clic.</translation>
-<translation id="3084806535845658316">sin reproducción oral de escritura</translation>
-<translation id="3086746722712840547">nota</translation>
-<translation id="308895241372589742">No hay ninguna expresión matemática posterior.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Siguiente punto de referencia</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">cdr dlg alrt</translation>
-<translation id="3109724472072898302">Contraído</translation>
-<translation id="3134461040845705080">sololctr</translation>
-<translation id="3138767756593758860">Mostrar lista de puntos de referencia</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Línea siguiente</translation>
-<translation id="3155083529632865074">No hay ningún botón anterior.</translation>
-<translation id="3163593631834463955">Encabezado de columna vacío</translation>
-<translation id="316542773973815724">Navegación</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{espacio}other{# espacios}}</translation>
-<translation id="320961988183078793">Se ingresó <ph name="TYPE" />.</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, pestaña</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Vínculo visitado</translation>
-<translation id="323731244387692321">Abrir ayuda de teclado de ChromeVox</translation>
-<translation id="3241052487511142956">Vínculo visitado anterior</translation>
-<translation id="3286390186030710347">Control deslizante</translation>
-<translation id="3299925995433437805">No hay ningún vínculo visitado posterior.</translation>
-<translation id="3303384412438961941">Presiona cualquier tecla para conocer su nombre. Con Ctrl + W, se cierra el explorador del teclado.</translation>
-<translation id="3307886118343381874">Ir al final de la tabla</translation>
-<translation id="3311969765485641742">Presiona Alt+Mayúscula+A para revisar las alertas.</translation>
-<translation id="3312997241656799641">Siguiente vínculo visitado</translation>
-<translation id="3321460131042519426">Habilitar ajuste de línea</translation>
-<translation id="3322936298410871309">Encabezado anterior de nivel 1</translation>
-<translation id="3323447499041942178">Cuadro de texto</translation>
-<translation id="3353420241558113817">{"ar": "árabe",
- "bg": "búlgaro",
- "ca": "catalán",
- "cs": "checo",
- "da": "danés",
- "de": "alemán",
- "de_CH": "alemán (Suiza)",
- "de_DE": "alemán (Alemania)",
- "el": "griego",
- "en": "inglés",
- "en_CA": "inglés (Canadá)",
- "en_GB": "inglés (Reino Unido)",
- "en_US": "inglés (Estados Unidos)",
- "es": "español",
- "et": "estonio",
- "fr": "francés",
- "fr_CA": "francés (Canadá)",
- "fr_FR": "francés (Francia)",
- "fi": "finlandés",
- "he": "hebreo",
- "hi": "hindi",
- "hr": "croata",
- "hu": "húngaro",
- "is": "islandés",
- "it": "italiano",
- "ko": "coreano",
- "lt": "lituano",
- "lv": "letón",
- "nb": "bokmål noruego",
- "nl": "holandés",
- "pl": "polaco",
- "pt": "portugués",
- "ro": "rumano",
- "ru": "ruso",
- "sk": "eslovaco",
- "sl": "esloveno",
- "sr": "serbio",
- "sv": "sueco",
- "tr": "turco",
- "vi": "vietnamita",
- "zh": "chino",
- "zh_TW": "chino (tradicional)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{más}other{# signos más}}</translation>
-<translation id="338583716107319301">Separador</translation>
-<translation id="3389259863310851658">Campo de formulario anterior</translation>
-<translation id="3390225400784126843">Siguiente elemento distinto</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, elemento del menú</translation>
-<translation id="3406283310380167331">Mostrar lista de formularios</translation>
-<translation id="3422338090358345848">Abre el explorador del teclado.</translation>
-<translation id="3457000393508828486">Presionado parcialmente</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, botón</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> sld</translation>
-<translation id="3486232535569802404"><ph name="V1" /> a <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{corchete de cierre}other{# corchetes de cierre}}</translation>
-<translation id="3493915602752813531">No hay ningún anclaje posterior.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{signo de interrogación}other{# signos de interrogación}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{signo de intercalación}other{# signos de intercalación}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, casilla de verificación no marcada</translation>
-<translation id="3599054940393788245">No incluido en el objeto matemático</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{comilla simple}other{# comillas simples}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dólar}other{# signos de dólar}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, cuadro de lista</translation>
-<translation id="3687295507293856493">Realizar una estimación sobre el encabezado de la columna de la celda actual</translation>
-<translation id="3692274950075847560">B:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Control de voz</translation>
-<translation id="3716845769494773620">Multilínea</translation>
-<translation id="3731746171184829332">No hay ningún encabezado anterior.</translation>
-<translation id="3762198587642264450">Ir al final de la fila actual</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Saliste del cuadro de diálogo.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Lista de autocompletados</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Archivo multimedia siguiente</translation>
-<translation id="3819376190738087562">No hay saltos.</translation>
-<translation id="385383972552776628">Abrir página de opciones</translation>
-<translation id="3856075812838139784">Solo lectura</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menú</translation>
-<translation id="3909320334364316587">Encabezado anterior de nivel 6</translation>
-<translation id="3914173277599553213">Permisos requeridos</translation>
-<translation id="3962990492275676168">Comenzar a leer desde la ubicación actual</translation>
-<translation id="4004802134384979325">seleccionada</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Control de mes</translation>
-<translation id="4039983576244166038">Encabezado de fila vacío</translation>
-<translation id="4042843249978639960">No hay ningún encabezado de nivel 2 posterior.</translation>
-<translation id="4043348641337972076">No hay ningún punto de referencia de ARIA anterior.</translation>
-<translation id="4047216625641135770">Marca</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">std</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{tilde}other{# tildes}}</translation>
-<translation id="409334809956508737">Objeto anterior</translation>
-<translation id="4099274309791143834">con submenú</translation>
-<translation id="4107807507418787238">No hay ninguna celda debajo.</translation>
-<translation id="4116415223832267137">Alerta</translation>
-<translation id="4147126331795725888">No hay ningún control posterior.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{llave de cierre}other{# llaves de cierre}}</translation>
-<translation id="4158704014418536539">Distingue mayúsculas de minúsculas.</translation>
-<translation id="4161663686871496107">Los comentarios por voz de ChromeVox están listos.</translation>
-<translation id="4173994908659439270">No hay ningún campo de texto editable posterior.</translation>
-<translation id="4176463684765177261">Deshabilitado</translation>
-<translation id="4188530942454211480">Frase anterior</translation>
-<translation id="4202186506458631436">Mover hacia la derecha</translation>
-<translation id="4206289001967551965">Dentro de la tabla</translation>
-<translation id="4215733775853809057">Siguiente control deslizante</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{guion}other{# guiones}}</translation>
-<translation id="421884353938374759">selector de color</translation>
-<translation id="4229646983878045487">fecha y hora</translation>
-<translation id="423334822609210999">No hay ninguna celda a la izquierda.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, grado <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Nota</translation>
-<translation id="4254798249533888099">Árbol</translation>
-<translation id="4255943572433203166">Usa las siguientes opciones para personalizar ChromeVox. Los cambios se aplican inmediatamente.</translation>
-<translation id="4271220233568730077">Expresión matemática siguiente</translation>
-<translation id="4271521365602459209">No hay más resultados.</translation>
-<translation id="4287520460805643128">No hay ningún artículo posterior.</translation>
-<translation id="4289540628985791613">Descripción general</translation>
-<translation id="4300318234632215983">Indicar URL de un enlace</translation>
-<translation id="4301352596632316575">tiene un submenú.</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punto}=3{puntos suspensivos}other{# puntos}}</translation>
-<translation id="4347461890115250064">No hay ninguna lista posterior.</translation>
-<translation id="4367650418938037324">Hoja de MathML</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Detener voz</translation>
-<translation id="4373197658375206385">No hay ningún elemento anterior que no sea un vínculo.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">restablecer</translation>
-<translation id="4471074325120394300">No hay vínculos.</translation>
-<translation id="4476183483923481720">Nueva línea</translation>
-<translation id="4482330759234983253">Tabla anterior</translation>
-<translation id="4491109536499578614">Imagen</translation>
-<translation id="4529987814483543472">Mapa de teclado clásico</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{barra}other{# barras}}</translation>
-<translation id="4547556996012970016">Siguiente encabezado de nivel 5</translation>
-<translation id="4562381607973973258">Encabezado</translation>
-<translation id="4591507479202817876">, seleccionado</translation>
-<translation id="4597532268155981612">formulario</translation>
-<translation id="4597896406374528575">Abril</translation>
-<translation id="4615592953348396470">Se ignorará la siguiente pulsación de tecla.</translation>
-<translation id="461613135510474570">Frase</translation>
-<translation id="4647836961514597010">Selector de color</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">cdrcl</translation>
-<translation id="4693675773662933727">Punto de referencia anterior</translation>
-<translation id="4696413482802371445">No hay ningún encabezado de nivel 5 posterior.</translation>
-<translation id="4729095194763193578">Fila anterior de la tabla</translation>
-<translation id="4736221692378411923">Agosto</translation>
-<translation id="4740661827607246557">Comandos de ayuda</translation>
-<translation id="4759716709594980008">Explorador de teclado del Sistema operativo Chrome</translation>
-<translation id="4763296182459741068">Ajustar a la parte inferior</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Indicar el título de la página actual</translation>
-<translation id="4826415162591436065">Avanzar</translation>
-<translation id="4826604887384865800">Siguiente salto</translation>
-<translation id="4827410568042294688">sin seleccionar</translation>
-<translation id="4842108708071771135">No hay ningún bloque entrecomillado posterior.</translation>
-<translation id="4848993367330139335">tmprz</translation>
-<translation id="4850023505158945298">Elemento anterior similar</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Habilitar registro de texto a voz</translation>
-<translation id="4877261390094455813">Ingresa una consulta de búsqueda.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Vínculo interno</translation>
-<translation id="4953585991029886728">Editar texto</translation>
-<translation id="4954534434583049121">Cita de bloque anterior</translation>
-<translation id="4973717656530883744">Mínimo <ph name="X" /></translation>
-<translation id="4973762002207131920">Se cambió a <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisegundos</translation>
-<translation id="49787999531187221">ChromeVox está inactivo.</translation>
-<translation id="4979404613699303341">Botón anterior</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, cuadro de lista</translation>
-<translation id="4983588134362688868">Ir al principio de la página</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, ventana</translation>
-<translation id="4993152509206108683">Velocidad: <ph name="PERCENT" /> %</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, botón de selección seleccionado</translation>
-<translation id="4997475792277222884">No hay ningún elemento posterior que no sea un vínculo.</translation>
-<translation id="5000760171916499057">No hay formularios.</translation>
-<translation id="5005670136041063723">No hay más elementos similares.</translation>
-<translation id="501473567976723023">Enero</translation>
-<translation id="5041394372352067729">Mover la pantalla de braille a la parte superior de la página</translation>
-<translation id="5042770794184672516">Aumentar el volumen de voz</translation>
-<translation id="5050015258024679800">Encabezado anterior de nivel 4</translation>
-<translation id="5054047268577924192">Elemento anterior de la lista</translation>
-<translation id="5078661581131202757">Selección de archivos</translation>
-<translation id="5080758118274074384">Se hizo doble clic.</translation>
-<translation id="5098541983634824365">Saliendo de la cuadrícula</translation>
-<translation id="5102981729317424850">Barra de herramientas</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">No hay ningún campo de formulario anterior.</translation>
-<translation id="5111640677200759579">Encabezado de columna</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">No hay ningún vínculo anterior.</translation>
-<translation id="513774504516943387">vncl</translation>
-<translation id="517143700877085897">, sin seleccionar</translation>
-<translation id="5183440668879371625">Línea de braille anterior</translation>
-<translation id="5184944171021383281">No hay ningún campo de formulario posterior.</translation>
-<translation id="5189244881767082992">Línea</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> ya se asignó a un comando.</translation>
-<translation id="5205493599117157272">Lista <ph name="TYPE" /></translation>
-<translation id="520883772648104506">No hay ningún botón de selección posterior.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Fin</translation>
-<translation id="5291783959063340370">Objeto</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, pestaña</translation>
-<translation id="5310788376443009632">eliminado:</translation>
-<translation id="5320727453979144100">Modo permanente habilitado</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{coma}other{# comas}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, cuadro de texto</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, vínculo</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Saltar atrás durante la lectura continua</translation>
-<translation id="5368000168321181111">Sonido desactivado</translation>
-<translation id="5374320867641260420">No hay ningún botón posterior.</translation>
-<translation id="5382299583965267720">No hay ningún encabezado de nivel 1 posterior.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{punto y coma}other{# punto y coma}}</translation>
-<translation id="5411891038905756502">No hay ningún punto de salto anterior.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{menor que}other{# signos menor que}}</translation>
-<translation id="5455441614648621694">Complementario</translation>
-<translation id="5485036206801896268">No hay ningún gráfico anterior.</translation>
-<translation id="5486947920110100234">No hay ningún punto de salto posterior.</translation>
-<translation id="549602578321198708">Palabra</translation>
-<translation id="5500932716852106146">No hay ningún campo de texto editable anterior.</translation>
-<translation id="5502713021410870035">Septiembre</translation>
-<translation id="5507663321906818013">Referencia de depuración</translation>
-<translation id="5518443085409638729">Colocar el cursor entre los caracteres al editar texto (como en Mac OS X)</translation>
-<translation id="552195134157544755">Botón de selección</translation>
-<translation id="5534303576632885660">encbz</translation>
-<translation id="5546092960038624944">No hay ningún encabezado de nivel 5 anterior.</translation>
-<translation id="556042886152191864">Botón</translation>
-<translation id="5561345396546889625">Siguiente lista</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Tecla de retroceso</translation>
-<translation id="5585044216466955529">Editar texto, entrada de correo electrónico</translation>
-<translation id="5597170376237141345">Siguiente casilla de verificación</translation>
-<translation id="5597933780944041114">No hay ningún encabezado posterior.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, botón de selección no seleccionado</translation>
-<translation id="5601172225407283979">Realizar acción predeterminada</translation>
-<translation id="5608798115546226984">Integración de autocompletados</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Registro</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">No hay ninguna tabla anterior.</translation>
-<translation id="5655682562155942719">Comandos de salto</translation>
-<translation id="56637627897541303">Área de texto</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Punto de referencia</translation>
-<translation id="5683155931978483559">Casilla de verificación anterior</translation>
-<translation id="5684277895745049190">Lista</translation>
-<translation id="5700650669149824506">No hay ningún encabezado de nivel 4 anterior.</translation>
-<translation id="5709192780268610569">No hay descripción larga.</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Siguiente columna de la tabla</translation>
-<translation id="571866080859340309">Explorando grupos</translation>
-<translation id="5728409797179002635">No se encontró la tabla.</translation>
-<translation id="5748623122140342504">Encabezado anterior de nivel 5</translation>
-<translation id="5750633686117194034">No se presionó ninguna tecla modificadora; mantén presionada una o más teclas modificadoras y luego suéltalas para escuchar el conjunto de teclas. Presiona el tabulador para salir.</translation>
-<translation id="5788275253279308023">pestaña <ph name="TITLE" /> de la ventana de incógnito</translation>
-<translation id="5806206155699461681">Mejorar sitios específicos (como la Búsqueda de Google)</translation>
-<translation id="5819072574982403430">Elemento de árbol</translation>
-<translation id="5826479389509458994">Fila <ph name="ROW" />, columna <ph name="COL" /></translation>
-<translation id="5850707923114094062">Desplazar hacia atrás</translation>
-<translation id="5851548754964597211">Lista de pestañas</translation>
-<translation id="5859752971144398932">Buscar en la página se cerró.</translation>
-<translation id="5866042630553435010">Seleccionado parcialmente</translation>
-<translation id="5869546221129391014">Cuadrícula</translation>
-<translation id="5876817486144482042">Disminuir el volumen de voz</translation>
-<translation id="5887397643266327462">Subtítulos en braille habilitados</translation>
-<translation id="5891934789323004067">Tabla</translation>
-<translation id="5919442531159595654">Copiar</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{igual}other{# signos igual}}</translation>
-<translation id="5939518447894949180">Restablecer</translation>
-<translation id="5948123859135882163">Alternar interpretación de expresiones matemáticas entre estructural y semántica</translation>
-<translation id="5955304353782037793">apl</translation>
-<translation id="5956928062748260866">Cuadro de diálogo</translation>
-<translation id="5963413905009737549">Sección</translation>
-<translation id="5968607524793740041">Mostrar el menú contextual</translation>
-<translation id="5983179082906765664">Aumentar nivel de detalle de navegación</translation>
-<translation id="5999630716831179808">Voces</translation>
-<translation id="6000417740266304866">Para cambiar la tabla actual de braille de ocho puntos, selecciona una opción de la siguiente lista.</translation>
-<translation id="6006050241733874051">Formulario</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{barra diagonal inversa}other{# barras diagonales inversas}}</translation>
-<translation id="6037602951055904232">Desplazar hacia delante</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Fin de celda</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Google Space</translation>
-<translation id="6142308968191113180">Encabezado 4</translation>
-<translation id="6169420925157477918">Imagen con descripción larga</translation>
-<translation id="6172087735260766220">No se puede acceder al texto del PDF protegido contra copia.</translation>
-<translation id="6186305613600865047">Ir al final de la página</translation>
-<translation id="6193330012414963395">a. m./p. m.</translation>
-<translation id="622484624075952240">Abajo</translation>
-<translation id="6236061028292614533">Siguiente encabezado</translation>
-<translation id="6254901459154107917">Área de texto editable siguiente</translation>
-<translation id="6259464875943891919">Saliste de <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Siguiente elemento similar</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">No hay ningún cuadro combinado posterior.</translation>
-<translation id="6307969636681130414">Presionado</translation>
-<translation id="6324551002951139333">Error gramatical detectado</translation>
-<translation id="6348657800373377022">Cuadro combinado</translation>
-<translation id="6355910664415701303">No hay ningún elemento de la lista anterior.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Encabezado anterior</translation>
-<translation id="6387719785439924554">lateral</translation>
-<translation id="6411426777058107714">No hay ningún botón de selección anterior.</translation>
-<translation id="6414968628640960377">Elemento anterior distinto</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dos puntos}other{# dos puntos}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menú</translation>
-<translation id="6444046323172968959">Cuadro de diálogo de alerta</translation>
-<translation id="6459511626086141404">Mapa de teclado plano</translation>
-<translation id="6468049171101508116">Botón Siguiente</translation>
-<translation id="6491972999578897419">Para cambiar la voz actual, selecciona una de las opciones de la lista que aparece a continuación.</translation>
-<translation id="6508059270146105198">Mover la pantalla de braille a la parte inferior de la página</translation>
-<translation id="6536864053412760904">Token de MathML</translation>
-<translation id="6550720799683018100">Para cambiar el mapa de teclado, selecciona una de las opciones de la lista que aparece a continuación.</translation>
-<translation id="6561818612645211875">Ir al principio de la fila actual</translation>
-<translation id="6587021927234520429">No hay ningún encabezado de nivel 4 posterior.</translation>
-<translation id="6601344353291556895">Habilitar descripciones más detalladas</translation>
-<translation id="6615602925644411249">Buscar en la página</translation>
-<translation id="6633350132811819843">No hay ninguna tabla posterior.</translation>
-<translation id="6637586476836377253">rgstr</translation>
-<translation id="6657128831881431364">Barra de progreso</translation>
-<translation id="6659594942844771486">Pestaña</translation>
-<translation id="667999046851023355">Documento</translation>
-<translation id="6697092096875747123">Cuadro combinado anterior</translation>
-<translation id="6714813999819678458">Encabezado anterior de nivel 2</translation>
-<translation id="6716505898850596801">Teclas modificadoras</translation>
-<translation id="671916444866103745">No hay ningún punto de referencia de ARIA posterior.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, cuadro combinado</translation>
-<translation id="6735257939857578167">con <ph name="NUM" /> elementos</translation>
-<translation id="6736510033526053669">pestaña creada</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artículo</translation>
-<translation id="6787839852456839824">Combinaciones de teclas para acceso directo</translation>
-<translation id="6793101435925451627">cdr lst</translation>
-<translation id="6833103209700200188">Pie de página</translation>
-<translation id="6871161210040114857">No distingue mayúscula de minúscula.</translation>
-<translation id="6877435256196695200">No hay ningún gráfico posterior.</translation>
-<translation id="6897341342232909480">Mover hacia la izquierda</translation>
-<translation id="6901540140423170855">fecha</translation>
-<translation id="6910211073230771657">Eliminado</translation>
-<translation id="6911965441508464308">No hay ninguna celda arriba.</translation>
-<translation id="6919104639734799681">Mostrar lista de tablas</translation>
-<translation id="6964088412282673743">No hay controles anteriores.</translation>
-<translation id="6996566555547746822">Siguiente cuadro combinado</translation>
-<translation id="7005146664810010831">No se encontró ninguna URL.</translation>
-<translation id="7010712454773919705">Tecla modificadora de ChromeVox</translation>
-<translation id="7031651751836475482">elmnt lst</translation>
-<translation id="7037042857287298941">Lista anterior</translation>
-<translation id="7041173719775863268">Finalizar selección</translation>
-<translation id="7095834689119144465">Modificar solo texto numérico</translation>
-<translation id="7096001299300236431">Archivo multimedia anterior</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">reproducción oral de palabras</translation>
-<translation id="713824876195128146">Siguiente cita de bloque</translation>
-<translation id="7161771961008409533">Botón con ventana emergente</translation>
-<translation id="7167657087543110">reproducción oral de caracteres</translation>
-<translation id="7170733337935166589">Saltar adelante durante la lectura continua</translation>
-<translation id="7181697990050180700">Para personalizar la combinación de teclas para acceso directo a los comandos que usas con frecuencia, ingresa las combinaciones deseadas en los siguientes campos.</translation>
-<translation id="7203150201908454328">Expandido</translation>
-<translation id="7210211103303402262">minutos</translation>
-<translation id="7217912842225915592">Más de <ph name="NUM" /></translation>
-<translation id="7221740160534240920">línea</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Encabezado</translation>
-<translation id="7241683698754534149">Abrir la descripción larga en una pestaña nueva</translation>
-<translation id="7248671827512403053">Aplicación</translation>
-<translation id="725969808843520477">Siguiente botón de selección</translation>
-<translation id="7269119382257320590">Sin puntuación</translation>
-<translation id="7273174640290488576">En blanco</translation>
-<translation id="7285387653379749618">Tablas</translation>
-<translation id="7289186959554153431">Encabezado 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Subtítulos en braille inhabilitados</translation>
-<translation id="7318872822751139669">Usar el mouse para cambiar el elemento seleccionado</translation>
-<translation id="7322388933135261569">Febrero</translation>
-<translation id="7332592614823088566">Fila <ph name="ROWINDEX" /> de <ph name="ROWTOTAL" />, columna <ph name="COLINDEX" /> de <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">con componente emergente</translation>
-<translation id="7356165926712028380">Cambiar a braille de ocho puntos</translation>
-<translation id="7362871137496673139">No hay ningún encabezado de nivel 2 anterior.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{et}other{# signos et}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Saliendo de la tabla…</translation>
-<translation id="739763518212184081">Línea anterior</translation>
-<translation id="7400575256015741911">Error de ortografía detectado</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">retorno de carro</translation>
-<translation id="7434509671034404296">Opciones para desarrolladores</translation>
-<translation id="7439060726180460871">Directorio</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Se ingresó un cuadro de diálogo.</translation>
-<translation id="7532613204005497612">Junio</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, control deslizante</translation>
-<translation id="7586163296341959563">pegar</translation>
-<translation id="7596919493010894443">selección borrada</translation>
-<translation id="7604026522577407655">Ir al principio de la columna actual</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Indicar URL de la página actual</translation>
-<translation id="7609363189280667021">Activar subtítulos en braille</translation>
-<translation id="762020119231868829">Detiene todos los widgets de medios que se estén reproduciendo.</translation>
-<translation id="7625690649919402823">Siguiente tabla</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Grado <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">No hay ningún encabezado de nivel 3 anterior.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, cuadro de texto</translation>
-<translation id="7663318257180412551">Encabezado 2</translation>
-<translation id="7674576868851035240">Siguiente vínculo</translation>
-<translation id="7674768236845044097">marca</translation>
-<translation id="7684431668231950609">Editar texto, entrada de URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Botón de selección anterior</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, cuadro de texto de la contraseña</translation>
-<translation id="7805247615045262757">navegación predeterminada</translation>
-<translation id="7805768142964895445">Estado</translation>
-<translation id="7810781339813764006">Grupo siguiente</translation>
-<translation id="7819187121850078213">pestaña <ph name="TITLE" /> de la ventana</translation>
-<translation id="7828956995407538686">Octubre</translation>
-<translation id="7839679365527550018">Palabra anterior</translation>
-<translation id="7851816175263618915">Algunos signos de puntuación</translation>
-<translation id="7870596830398826354">Árbol de MathML</translation>
-<translation id="78826985582142166">ctrl desl</translation>
-<translation id="7894517696028036636">Activa o desactiva la versión clásica de ChromeVox.</translation>
-<translation id="7895896691902835279">Vínculo desconocido</translation>
-<translation id="7927711904086083099">Sin seleccionar</translation>
-<translation id="7935627501098484003">Control de fecha y hora</translation>
-<translation id="7939428177581522200">Se agregó a la selección.</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{arroba}other{# arrobas}}</translation>
-<translation id="7965147473449754028">menú cerrado</translation>
-<translation id="7974390230414479278">Elemento del menú</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{signo de exclamación}other{# signos de exclamación}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{comilla}other{# comillas}}</translation>
-<translation id="8033827949643255796">seleccionados</translation>
-<translation id="8035962149453661158">máx:<ph name="X" /></translation>
-<translation id="8042761080832772327">Editar texto, entrada de búsqueda</translation>
-<translation id="8049189770492311300">Temporizador</translation>
-<translation id="8065607967589909823">La selección es</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">No hay puntos de referencia de ARIA.</translation>
-<translation id="8153880621934657047">No está dentro de la tabla.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{guion bajo}other{# guiones bajos}}</translation>
-<translation id="8179976553408161302">Intro</translation>
-<translation id="81960742267269908">Cortar</translation>
-<translation id="8199231515320852133">Indicar los encabezados de la celda actual</translation>
-<translation id="820417203470636242">Celda vacía</translation>
-<translation id="8215202828671303819">Selección múltiple</translation>
-<translation id="8276439074553447000">Saltar al elemento enfocable anterior</translation>
-<translation id="8278417001922463147">No hay artículos anteriores.</translation>
-<translation id="8283603667300770666">Siguiente campo de formulario</translation>
-<translation id="831207808878314375">Definición</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">horas</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{signo numeral}other{# signos numerales}}</translation>
-<translation id="8374154622594089836">mes</translation>
-<translation id="8378855320830505539">Región</translation>
-<translation id="8382679411218029383">Autocompletados integrados y lista de autocompletados</translation>
-<translation id="8428603554127842284">Nivel <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">No hay ningún encabezado de nivel 3 posterior.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">No hay ninguna casilla de verificación anterior.</translation>
-<translation id="8455868257606149352">Máximo <ph name="X" /></translation>
-<translation id="84575901236241018">tiene tecla de acceso, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Disminuir nivel de detalle de navegación</translation>
-<translation id="8520472399088452386">Botón de número</translation>
-<translation id="8538744478902126321">Realizar una estimación sobre el encabezado de la fila de la celda actual</translation>
-<translation id="8540054775867439484">Ajustar a la parte superior</translation>
-<translation id="8548973727659841685">Carácter</translation>
-<translation id="8561322612995434619">con componente emergente</translation>
-<translation id="8571096049907249734">mult sel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Siguiente elemento de la lista</translation>
-<translation id="860150890330522909">casilla de verificación <ph name="NAME" /> seleccionada</translation>
-<translation id="8606621670302093223">Control de fecha</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> elementos seleccionados</translation>
-<translation id="8638532244051952400">Anunciar coordenadas de celda actuales</translation>
-<translation id="8650576015643545550">No hay ninguna lista anterior.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Mostrar la lista de vínculos</translation>
-<translation id="8664519043722036194">segundos</translation>
-<translation id="867187640362843212">Encabezado 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{barra vertical}other{# barras verticales}}</translation>
-<translation id="8735450637152821465">Iniciar selección</translation>
-<translation id="8743786158317878347">ingresar al contenido estructurado, como tablas</translation>
-<translation id="8747966237988593539">Lista ordenada</translation>
-<translation id="8759334257841767240">No hay ningún vínculo posterior.</translation>
-<translation id="8767968232364267681">Siguiente encabezado de nivel 4</translation>
-<translation id="8770473310765924354">salir del contenido estructurado, como tablas</translation>
-<translation id="8791025954632646584">Semántica activada</translation>
-<translation id="8796411681063377102">Siguiente encabezado de nivel 3</translation>
-<translation id="8808582214901541005">Marzo</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">ppal</translation>
-<translation id="8856538297388979332">Presiona las flechas hacia arriba y hacia abajo para revisar los comandos y presiona Enter para activarlos.</translation>
-<translation id="8864099967139188018">No hay ningún encabezado de nivel 6 posterior.</translation>
-<translation id="8882002077197914455">Encabezado de fila</translation>
-<translation id="8896347895970027998">Activar o desactivar ChromeVox</translation>
-<translation id="8898516272131543774">Reproducción oral del ciclo de puntuación</translation>
-<translation id="8900148057318340779">Tecla de prefijo</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Encabezados vacíos</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Teclas modificadoras</translation>
-<translation id="8943175951035496220">No hay ninguna celda a la derecha.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">archivo</translation>
-<translation id="9027462562263121875">No hay tablas.</translation>
-<translation id="9040132695316389094">Encabezado 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Alternar widget de búsqueda</translation>
-<translation id="9065283790526219006">+emergente</translation>
-<translation id="9077213568694924680">eliminado de la selección</translation>
-<translation id="9082874451376019682">No hay ningún control deslizante anterior.</translation>
-<translation id="9089864840575085222">Reproducción oral del ciclo de escritura</translation>
-<translation id="9107530006868467849">No hay widgets multimedia anteriores.</translation>
-<translation id="9108370397979208512">expr mtmtc</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{porcentaje}other{# signos de porcentaje}}</translation>
-<translation id="9115913704608474258">Noviembre</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Muestra una breve descripción de la posición actual.</translation>
-<translation id="9153606228985488238">Tono: <ph name="PERCENT" /> %</translation>
-<translation id="9160096769946561184">Ir al final de la columna actual</translation>
-<translation id="9173115498289768110">Volumen: <ph name="PERCENT" /> %</translation>
-<translation id="9178973770513562274">Usa las teclas de flecha hacia arriba y hacia abajo para navegar o escribe un término para realizar una búsqueda.</translation>
-<translation id="9192904702577636854">Recuadro</translation>
-<translation id="9212322457209634662">No hay ninguna sección posterior.</translation>
-<translation id="930275611743429116">Iniciar o finalizar selección</translation>
-<translation id="948171205378458592">Hablar más lento</translation>
-<translation id="962913030769097253">Encabezado siguiente de nivel 1</translation>
-<translation id="973955474346881951">Habilitar/inhabilitar modo permanente</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es.xtb
deleted file mode 100644
index b0243ba8a5a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="es">
-<translation id="1012173283529841972">Elemento de lista</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Ampliada.</translation>
-<translation id="1025074108959230262">Modo permanente inhabilitado</translation>
-<translation id="1031961866430398710">y</translation>
-<translation id="1044777062731150180">No hay encabezados</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Entrada no válida</translation>
-<translation id="1082209053475788238">No hay ningún título de nivel 6 anterior.</translation>
-<translation id="1088219014394087294">No hay títulos.</translation>
-<translation id="1106741348836243114">Activa o desactiva el sonido.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Colección de <ph name="TAG" /> con <ph name="NUM" /> elementos</translation>
-<translation id="1155043339247954670">No hay ningún elemento de la lista posterior.</translation>
-<translation id="1157782847298808853">Ayuda del teclado</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, cuadro combinado</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, elemento de menú, con submenú</translation>
-<translation id="1177863135347784049">Personalizado</translation>
-<translation id="1188858454923323853">complementario</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox, la voz de Chrome</translation>
-<translation id="1229276918471378188">Salto anterior</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Siguiente encabezado de nivel 6</translation>
-<translation id="1275718070701477396">Seleccionado</translation>
-<translation id="1319608975892113573">No hay ninguna etiqueta "blockquote" anterior.</translation>
-<translation id="1321576897702511272">Oculta la ayuda de ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> de <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">decir palabras y caracteres</translation>
-<translation id="1339428534620983148">Columna anterior de la tabla</translation>
-<translation id="1342835525016946179">artículo</translation>
-<translation id="1346748346194534595">Derecha</translation>
-<translation id="136718599399906424">Siguiente fila de la tabla</translation>
-<translation id="1383876407941801731">Buscar</translation>
-<translation id="1385214448885562192">Pulsa Intro para aceptar, Esc para cancelar, la tecla de flecha hacia abajo para ver el siguiente resultado y la tecla de flecha hacia arriba para ver el resultado anterior.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, cuadro de texto de contraseña</translation>
-<translation id="1467432559032391204">Izquierda</translation>
-<translation id="1474557363159888097">No hay ningún anclaje anterior.</translation>
-<translation id="1502086903961450562">Gráfico anterior</translation>
-<translation id="1506187449813838456">Sube el tono</translation>
-<translation id="151784044608172266">Frase siguiente</translation>
-<translation id="1524531499102321782">Línea braille posterior</translation>
-<translation id="1546370775711804143">Barra de desplazamiento</translation>
-<translation id="1559739829547075274">Retrocede</translation>
-<translation id="1571643229714746283">Ya puedes usar ChromeVox</translation>
-<translation id="158493514907962286">Diciembre</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Cambiar a Braille de seis puntos</translation>
-<translation id="1611168825862729585">Encabezado de columna:</translation>
-<translation id="1613476421962910979">Sonido activado</translation>
-<translation id="1618597272655350600">Muestra una descripción completa de la posición actual.</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{mayor que}other{# signos mayor que}}</translation>
-<translation id="1653266918374749391">Encabezado anterior de nivel 3</translation>
-<translation id="1659072772017912254">Sin marcar</translation>
-<translation id="1669290819662866522">semana</translation>
-<translation id="1674262202423278359">Navegación de ChromeVox</translation>
-<translation id="16777221443363124">Barra de menú</translation>
-<translation id="1692077714702418899">línea estructural</translation>
-<translation id="1700517974991662022">Visitado</translation>
-<translation id="1722567105086139392">Enlace</translation>
-<translation id="1727806147743597030">pie</translation>
-<translation id="174268867904053074">Siguiente gráfico</translation>
-<translation id="1781173782405573156">Tecla de acceso directo</translation>
-<translation id="1787176709638001873">Texto de edición de contraseña</translation>
-<translation id="1810107444790159527">Cuadro de lista</translation>
-<translation id="1828385960365606039">Mayo</translation>
-<translation id="1834891354138622109">Columna</translation>
-<translation id="1865601187525349519">Fin del texto</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Di la fecha y la hora actuales.</translation>
-<translation id="1902396333223336119">Celda</translation>
-<translation id="1905379170753160525">Muestra la lista de encabezados</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Control de semana del año</translation>
-<translation id="1964135212174907577">Objeto siguiente</translation>
-<translation id="1969092762068865084">Julio</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Encabezado de fila:</translation>
-<translation id="2002895034995108595">Restablecer mapa de teclado actual</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{corchete de apertura}other{# corchetes de apertura}}</translation>
-<translation id="2045490512405922022">sin seleccionar</translation>
-<translation id="20601713649439366">No hay expresiones matemáticas anteriores.</translation>
-<translation id="207477615537953741">Semántica desactivada</translation>
-<translation id="2086961585857038472">Palabra siguiente</translation>
-<translation id="2089387485033699258">es</translation>
-<translation id="2091933974477985526">Área de texto editable anterior</translation>
-<translation id="2100350898815792233">Todos los signos de puntuación</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">clave de acceso: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Para cambiar la tabla de Braille de seis puntos actual, selecciona una opción de la lista que aparece a continuación.</translation>
-<translation id="2169714232367507776">Clic en el elemento actual</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{paréntesis de cierre}other{# paréntesis de cierre}}</translation>
-<translation id="2199994615414171367">Anterior expresión matemática</translation>
-<translation id="2223693656926968778">Realiza la acción con el elemento actual</translation>
-<translation id="225732394367814946">Habla más rápido</translation>
-<translation id="2267945578749931355">Carácter siguiente</translation>
-<translation id="2281234842553884450">Control deslizante anterior</translation>
-<translation id="2318372665160196757">Principal</translation>
-<translation id="2329324941084714723">Panel de pestaña</translation>
-<translation id="2344193891939537199">Control de fecha y hora</translation>
-<translation id="2359897517538099099">No en modo tabla.</translation>
-<translation id="241124561063364910">seguido de</translation>
-<translation id="2417569100218200841">Información del contenido</translation>
-<translation id="2422937916923936891">Casilla de verificación de elemento de menú</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> es ahora el nuevo modificador de ChromeVox.</translation>
-<translation id="2450814015951372393">Casilla de verificación</translation>
-<translation id="2462626033734746142">Grupo de botones de opción</translation>
-<translation id="2471138580042810658">Título 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisco}other{# asteriscos}}</translation>
-<translation id="2549392850788122959">Se ha restablecido <ph name="KEY" />.</translation>
-<translation id="2553108862507765288">error gramatical</translation>
-<translation id="257674075312929031">Grupo</translation>
-<translation id="2582407057977008361">Etiqueta de contenido tangencial</translation>
-<translation id="2589102159832527089">Esta página incluye el texto extraído automáticamente del archivo PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Haz clic aquí para acceder al archivo original&lt;/a&gt;.</translation>
-<translation id="2606210917827248971">con {COUNT,plural, =1{# elemento}other{# elementos}}</translation>
-<translation id="2614981083756825552">Diseño de MathML</translation>
-<translation id="2626530649491650971">elemento en el que se puede hacer clic</translation>
-<translation id="2628764385451019380">No hay ningún cuadro combinado anterior.</translation>
-<translation id="2637227747952042642">Objeto matemático</translation>
-<translation id="2639750663247012216">Modificador de ChromeVox</translation>
-<translation id="2644542693584024604">error ortográfico</translation>
-<translation id="2667291555398229137">Haz clic en el elemento que aparece debajo de una tecla de enrutamiento</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{paréntesis de apertura}other{# paréntesis de apertura}}</translation>
-<translation id="2705875883745373140">Sin pulsar</translation>
-<translation id="2706462751667573066">Flecha hacia arriba</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Marcado</translation>
-<translation id="27527859628328957">Salta al siguiente elemento enfocable</translation>
-<translation id="2770781857296573485">Introduce exploración de grupos</translation>
-<translation id="2777845298774924149">Cerrado</translation>
-<translation id="2800204403141299078">No hay más elementos diferentes.</translation>
-<translation id="2800780099804980316">No hay ningún título de nivel 1 anterior.</translation>
-<translation id="2811204574343810641">Fila</translation>
-<translation id="2816654101880605877">No hay ningún control deslizante posterior.</translation>
-<translation id="2841013758207633010">Hora</translation>
-<translation id="2843837985843789981">Grupo anterior</translation>
-<translation id="2844995807198708617">Menú contextual</translation>
-<translation id="2849332794118375855">No hay ninguna casilla de verificación posterior.</translation>
-<translation id="2864481629947106776">Enlace anterior</translation>
-<translation id="2873259058405069099">Accede al principio de la tabla</translation>
-<translation id="2894654529758326923">Información</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{llave de apertura}other{# llaves de apertura}}</translation>
-<translation id="2911433807131383493">Abrir el tutorial de ChromeVox</translation>
-<translation id="2932083475399492303">Alterna tipo de línea entre estructural o de diseño</translation>
-<translation id="2964026537669811554">Etiqueta de grupo de encabezados</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulación}other{# tabulaciones}}</translation>
-<translation id="2972078295414139404">No hay ningún enlace anterior visitado.</translation>
-<translation id="2972205263822847197">Sugerencia</translation>
-<translation id="2998131015536248178">Carácter anterior</translation>
-<translation id="2999559350546931576">Baja el tono</translation>
-<translation id="2999945368667127852">No hay más widgets multimedia.</translation>
-<translation id="3012414509011670858">No hay secciones anteriores.</translation>
-<translation id="3030432017085518523">Botón de opción de elemento de menú</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apóstrofe}other{# apóstrofes}}</translation>
-<translation id="3046838483509668188">Opciones de ChromeVox</translation>
-<translation id="3047143736589213134">Mapa de teclado experimental</translation>
-<translation id="3060756054951570867"><ph name="TITLE" />, menú abierto</translation>
-<translation id="3078345202707391975">Siguiente encabezado de nivel 2</translation>
-<translation id="3078740164268491126">tabla</translation>
-<translation id="3082557070674409251">Se ha hecho clic</translation>
-<translation id="3084806535845658316">no hablar al escribir</translation>
-<translation id="3086746722712840547">nota</translation>
-<translation id="308895241372589742">No hay más expresiones matemáticas.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Siguiente punto de referencia</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Contraído</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Muestra la lista de puntos de referencia</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Línea siguiente</translation>
-<translation id="3155083529632865074">No hay ningún botón anterior.</translation>
-<translation id="3163593631834463955">Encabezado de columna vacío</translation>
-<translation id="316542773973815724">Navegación</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{espacio}other{# espacios}}</translation>
-<translation id="320961988183078793">se ha introducido <ph name="TYPE" />.</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, pestaña</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Vínculo visitado</translation>
-<translation id="323731244387692321">Abre la ayuda del teclado de ChromeVox</translation>
-<translation id="3241052487511142956">Anterior enlace visitado</translation>
-<translation id="3286390186030710347">Control deslizante</translation>
-<translation id="3299925995433437805">No hay ningún enlace siguiente visitado.</translation>
-<translation id="3303384412438961941">Pulsa cualquier tecla para saber su nombre. Al pulsar Ctrl+W, se cierra el explorador del teclado.</translation>
-<translation id="3307886118343381874">Accede al final de la tabla</translation>
-<translation id="3311969765485641742">Pulsa Alt+Mayús+A para revisar las alertas</translation>
-<translation id="3312997241656799641">Siguiente enlace visitado</translation>
-<translation id="3321460131042519426">Habilitar ajuste de palabras</translation>
-<translation id="3322936298410871309">Encabezado anterior de nivel 1</translation>
-<translation id="3323447499041942178">Cuadro de texto</translation>
-<translation id="3353420241558113817">{"ar": "Árabe",
- "bg": "Búlgaro",
- "ca": "Catalán",
- "cs": "Checo",
- "da": "Danés",
- "de": "Alemán",
- "de_CH": "Alemán (Suiza)",
- "de_DE": "Alemán (Alemania)",
- "el": "Griego",
- "en": "Inglés",
- "en_CA": "Inglés (Canadá)",
- "en_GB": "Inglés (Reino Unido)",
- "en_US": "Inglés (Estados Unidos)",
- "es": "Español",
- "et": "Estonio",
- "fr": "Francés",
- "fr_CA": "Francés (Canadá)",
- "fr_FR": "Francés (Francia)",
- "fi": "Finés",
- "he": "Hebreo",
- "hi": "Hindú",
- "hr": "Croata",
- "hu": "Húngaro",
- "is": "Islandés",
- "it": "Italiano",
- "ko": "Coreano",
- "lt": "Lituano",
- "lv": "Letón",
- "nb": "Noruego (Bokmål)",
- "nl": "Neerlandés",
- "pl": "Polaco",
- "pt": "Portugués",
- "ro": "Rumano",
- "ru": "Ruso",
- "sk": "Eslovaco",
- "sl": "Esloveno",
- "sr": "Serbio",
- "sv": "Sueco",
- "tr": "Turco",
- "vi": "Vietnamita",
- "zh": "Chino",
- "zh_TW": "Chino (Han tradicional)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{más}other{# signos más}}</translation>
-<translation id="338583716107319301">Separador</translation>
-<translation id="3389259863310851658">Campo de formulario anterior</translation>
-<translation id="3390225400784126843">Siguiente elemento distinto.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, elemento de menú</translation>
-<translation id="3406283310380167331">Muestra la lista de formularios</translation>
-<translation id="3422338090358345848">Abre el explorador del teclado</translation>
-<translation id="3457000393508828486">Pulsado parcialmente</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, botón</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> slcd</translation>
-<translation id="3486232535569802404"><ph name="V1" /> a <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{corchete de cierre}other{# corchetes de cierre}}</translation>
-<translation id="3493915602752813531">No hay ningún anclaje posterior.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{signo de interrogación}other{# signos de interrogación}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{símbolo de intercalación}other{# símbolos de intercalación}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, casilla de verificación no seleccionada</translation>
-<translation id="3599054940393788245">No incluido en la expresión matemática</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{comilla simple}other{# comillas simples}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dólar}other{# símbolos de dólar}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, cuadro de lista</translation>
-<translation id="3687295507293856493">Intenta detectar el encabezado de la columna de la celda actual</translation>
-<translation id="3692274950075847560">B:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Control de voz</translation>
-<translation id="3716845769494773620">Multilínea</translation>
-<translation id="3731746171184829332">No hay ningún título anterior.</translation>
-<translation id="3762198587642264450">Accede al final de la fila actual</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Has salido del cuadro de diálogo.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Lista de autocompletados</translation>
-<translation id="3810838688059735925">Vídeo</translation>
-<translation id="3816633764618089385">Siguiente archivo multimedia</translation>
-<translation id="3819376190738087562">No hay saltos.</translation>
-<translation id="385383972552776628">Abre página de opciones</translation>
-<translation id="3856075812838139784">Solo lectura</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menú</translation>
-<translation id="3909320334364316587">Encabezado anterior de nivel 6</translation>
-<translation id="3914173277599553213">Obligatorios</translation>
-<translation id="3962990492275676168">Empieza a leer desde la ubicación actual</translation>
-<translation id="4004802134384979325">marcada</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Control de mes</translation>
-<translation id="4039983576244166038">Encabezado de fila vacío</translation>
-<translation id="4042843249978639960">No hay ningún título de nivel 2 posterior.</translation>
-<translation id="4043348641337972076">No hay ningún punto de referencia de ARIA anterior.</translation>
-<translation id="4047216625641135770">Etiqueta de marcado</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">std</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{VIRGULILLA}other{# virgulillas}}</translation>
-<translation id="409334809956508737">Objeto anterior</translation>
-<translation id="4099274309791143834">con submenú</translation>
-<translation id="4107807507418787238">No hay ninguna celda debajo.</translation>
-<translation id="4116415223832267137">Alerta</translation>
-<translation id="4147126331795725888">No hay controles posteriores.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{llave de cierre}other{# llaves de cierre}}</translation>
-<translation id="4158704014418536539">Se distingue entre mayúsculas y minúsculas.</translation>
-<translation id="4161663686871496107">Ya puedes usar la síntesis de voz de ChromeVox</translation>
-<translation id="4173994908659439270">No hay ningún campo de texto editable posterior.</translation>
-<translation id="4176463684765177261">Inhabilitado</translation>
-<translation id="4188530942454211480">Frase anterior</translation>
-<translation id="4202186506458631436">Se desplaza a la derecha</translation>
-<translation id="4206289001967551965">Dentro de la tabla</translation>
-<translation id="4215733775853809057">Siguiente control deslizante</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{guión}other{# guiones}}</translation>
-<translation id="421884353938374759">selector de color</translation>
-<translation id="4229646983878045487">fecha y hora</translation>
-<translation id="423334822609210999">No hay ninguna celda a la izquierda.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, grado <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Nota</translation>
-<translation id="4254798249533888099">Árbol</translation>
-<translation id="4255943572433203166">Puedes personalizar ChromeVox con las opciones que aparecen a continuación. Los cambios se aplican inmediatamente.</translation>
-<translation id="4271220233568730077">Siguiente expresión matemática</translation>
-<translation id="4271521365602459209">No hay más resultados.</translation>
-<translation id="4287520460805643128">No hay más artículos.</translation>
-<translation id="4289540628985791613">Descripción general</translation>
-<translation id="4300318234632215983">Indica la URL de un enlace</translation>
-<translation id="4301352596632316575">tiene un submenú</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punto}=3{puntos suspensivos}other{# puntos}}</translation>
-<translation id="4347461890115250064">No hay ninguna lista posterior.</translation>
-<translation id="4367650418938037324">Hoja de MathML</translation>
-<translation id="4372435075475052704">mín:<ph name="X" /></translation>
-<translation id="4372705107434148843">Detiene la voz</translation>
-<translation id="4373197658375206385">No hay ningún elemento anterior que no sea un enlace.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">restablecer</translation>
-<translation id="4471074325120394300">No hay enlaces.</translation>
-<translation id="4476183483923481720">nueva línea</translation>
-<translation id="4482330759234983253">Tabla anterior</translation>
-<translation id="4491109536499578614">Imagen</translation>
-<translation id="4529987814483543472">Mapa de teclado clásico</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{barra}other{# barras}}</translation>
-<translation id="4547556996012970016">Siguiente encabezado de nivel 5</translation>
-<translation id="4562381607973973258">Etiqueta de encabezado</translation>
-<translation id="4591507479202817876">, seleccionado</translation>
-<translation id="4597532268155981612">formulario</translation>
-<translation id="4597896406374528575">Abril</translation>
-<translation id="4615592953348396470">Ignorando siguiente pulsación de tecla</translation>
-<translation id="461613135510474570">Oración</translation>
-<translation id="4647836961514597010">Selector de color</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Punto de referencia anterior</translation>
-<translation id="4696413482802371445">No hay ningún título de nivel 5 posterior.</translation>
-<translation id="4729095194763193578">Fila anterior de la tabla</translation>
-<translation id="4736221692378411923">Agosto</translation>
-<translation id="4740661827607246557">Comandos de ayuda</translation>
-<translation id="4759716709594980008">Explorador de teclado de Chrome OS</translation>
-<translation id="4763296182459741068">Continuar a la parte inferior</translation>
-<translation id="4763480195061959176">vídeo</translation>
-<translation id="479989351350248267">buscar</translation>
-<translation id="481165870889056555">Indica el título de la página actual</translation>
-<translation id="4826415162591436065">Avanza</translation>
-<translation id="4826604887384865800">Siguiente salto</translation>
-<translation id="4827410568042294688">no seleccionado</translation>
-<translation id="4842108708071771135">No hay ninguna etiqueta "blockquote" posterior.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Elemento anterior similar.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Habilita registro de síntesis de voz</translation>
-<translation id="4877261390094455813">Introduce una consulta de búsqueda.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Enlace interno</translation>
-<translation id="4953585991029886728">Edita texto</translation>
-<translation id="4954534434583049121">Cita de bloque anterior</translation>
-<translation id="4973717656530883744">Mínimo <ph name="X" /></translation>
-<translation id="4973762002207131920">Se ha cambiado a <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisegundos</translation>
-<translation id="49787999531187221">ChromeVox está ahora desactivado.</translation>
-<translation id="4979404613699303341">Botón anterior</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, cuadro de lista</translation>
-<translation id="4983588134362688868">Accede al principio de la página</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, ventana</translation>
-<translation id="4993152509206108683">Velocidad: <ph name="PERCENT" />%</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, botón de opción seleccionado</translation>
-<translation id="4997475792277222884">No hay ningún elemento posterior que no sea un enlace.</translation>
-<translation id="5000760171916499057">No hay formularios.</translation>
-<translation id="5005670136041063723">No hay más elementos similares.</translation>
-<translation id="501473567976723023">Enero</translation>
-<translation id="5041394372352067729">Mueve la pantalla braille a la parte superior de la página</translation>
-<translation id="5042770794184672516">Aumenta el volumen de voz</translation>
-<translation id="5050015258024679800">Encabezado anterior de nivel 4</translation>
-<translation id="5054047268577924192">Elemento anterior de la lista</translation>
-<translation id="5078661581131202757">Selección de archivos</translation>
-<translation id="5080758118274074384">se ha hecho doble clic</translation>
-<translation id="5098541983634824365">Saliendo de la cuadrícula</translation>
-<translation id="5102981729317424850">Barra de herramientas</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">No hay ningún campo de formulario anterior.</translation>
-<translation id="5111640677200759579">Encabezado de columna</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">No hay ningún enlace anterior.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, sin seleccionar</translation>
-<translation id="5183440668879371625">Línea braille anterior</translation>
-<translation id="5184944171021383281">No hay ningún campo de formulario posterior.</translation>
-<translation id="5189244881767082992">Línea</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> ya se ha asignado a un comando.</translation>
-<translation id="5205493599117157272">Lista <ph name="TYPE" /></translation>
-<translation id="520883772648104506">No hay ningún botón de opción posterior.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Fin</translation>
-<translation id="5291783959063340370">Objeto</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, pestaña</translation>
-<translation id="5310788376443009632">eliminada:</translation>
-<translation id="5320727453979144100">Modo permanente habilitado</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{coma}other{# comas}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, cuadro de texto</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, enlace</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Retrocede durante una lectura continua</translation>
-<translation id="5368000168321181111">Sonido desactivado</translation>
-<translation id="5374320867641260420">No hay ningún botón posterior.</translation>
-<translation id="5382299583965267720">No hay ningún título de nivel 1 posterior.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{punto y coma}other{# puntos y comas}}</translation>
-<translation id="5411891038905756502">No hay ningún punto de salto anterior.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{menor que}other{# signos menor que}}</translation>
-<translation id="5455441614648621694">Complementario</translation>
-<translation id="5485036206801896268">No hay ningún gráfico anterior.</translation>
-<translation id="5486947920110100234">No hay ningún punto de salto posterior.</translation>
-<translation id="549602578321198708">Palabra</translation>
-<translation id="5500932716852106146">No hay ningún campo de texto editable anterior.</translation>
-<translation id="5502713021410870035">Septiembre</translation>
-<translation id="5507663321906818013">Punto de referencia de depuración</translation>
-<translation id="5518443085409638729">Colocar el cursor entre los caracteres al editar texto (como en Mac OS X)</translation>
-<translation id="552195134157544755">Botón de opción</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">No hay ningún título de nivel 5 anterior.</translation>
-<translation id="556042886152191864">Botón</translation>
-<translation id="5561345396546889625">Siguiente lista</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Tecla de retroceso</translation>
-<translation id="5585044216466955529">Edita texto, entrada de correo electrónico</translation>
-<translation id="5597170376237141345">Siguiente casilla de verificación</translation>
-<translation id="5597933780944041114">No hay ningún título posterior.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, botón de opción no seleccionado</translation>
-<translation id="5601172225407283979">Realiza una acción predeterminada</translation>
-<translation id="5608798115546226984">Autocompletados insertados</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Registro</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">No hay ninguna tabla anterior.</translation>
-<translation id="5655682562155942719">Comandos de salto</translation>
-<translation id="56637627897541303">Área de texto</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Punto de referencia</translation>
-<translation id="5683155931978483559">Casilla de verificación anterior</translation>
-<translation id="5684277895745049190">Lista</translation>
-<translation id="5700650669149824506">No hay ningún título de nivel 4 anterior.</translation>
-<translation id="5709192780268610569">No hay descripción larga.</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Siguiente columna de la tabla</translation>
-<translation id="571866080859340309">Explorando grupos</translation>
-<translation id="5728409797179002635">No se ha encontrado la tabla.</translation>
-<translation id="5748623122140342504">Encabezado anterior de nivel 5</translation>
-<translation id="5750633686117194034">No se ha pulsado ningún modificador; mantén pulsado uno o varios modificadores; levanta los dedos cuando lo hayas hecho y escucharás el conjunto de teclas. Pulsa el tabulador para salir.</translation>
-<translation id="5788275253279308023">ventana de incógnito, <ph name="TITLE" />, pestaña</translation>
-<translation id="5806206155699461681">Mejorar sitios específicos (como la Búsqueda de Google).</translation>
-<translation id="5819072574982403430">Elemento de árbol</translation>
-<translation id="5826479389509458994">fila <ph name="ROW" /> columna <ph name="COL" /></translation>
-<translation id="5850707923114094062">Se desplaza hacia atrás</translation>
-<translation id="5851548754964597211">Lista de pestañas</translation>
-<translation id="5859752971144398932">Se ha cerrado Buscar en la página.</translation>
-<translation id="5866042630553435010">Seleccionado parcialmente</translation>
-<translation id="5869546221129391014">Cuadrícula</translation>
-<translation id="5876817486144482042">Disminuye el volumen de voz</translation>
-<translation id="5887397643266327462">Subtítulos Braille habilitados.</translation>
-<translation id="5891934789323004067">Tabla</translation>
-<translation id="5919442531159595654">copiar.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{igual}other{# signos igual}}</translation>
-<translation id="5939518447894949180">Restablecer</translation>
-<translation id="5948123859135882163">Alterna interpretación de expresiones matemáticas entre estructural y semántica</translation>
-<translation id="5955304353782037793">aplic</translation>
-<translation id="5956928062748260866">Diálogo</translation>
-<translation id="5963413905009737549">Etiqueta de sección</translation>
-<translation id="5968607524793740041">Mostrar menú contextual</translation>
-<translation id="5983179082906765664">Aumenta la granularidad de navegación</translation>
-<translation id="5999630716831179808">Voces</translation>
-<translation id="6000417740266304866">Para cambiar la tabla de Braille de ocho puntos actual, selecciona una opción de la lista que aparece a continuación.</translation>
-<translation id="6006050241733874051">Formulario</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{barra inversa}other{# barras inversas}}</translation>
-<translation id="6037602951055904232">Se desplaza hacia delante</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Fin de celda.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Espacio</translation>
-<translation id="6142308968191113180">Título 4</translation>
-<translation id="6169420925157477918">Imagen con descripción larga</translation>
-<translation id="6172087735260766220">No se puede acceder a texto accesible desde un PDF protegido contra copias.</translation>
-<translation id="6186305613600865047">Accede al final de la página</translation>
-<translation id="6193330012414963395">a.m. p.m.</translation>
-<translation id="622484624075952240">Flecha hacia abajo</translation>
-<translation id="6236061028292614533">Siguiente encabezado</translation>
-<translation id="6254901459154107917">Siguiente área de texto editable</translation>
-<translation id="6259464875943891919">Has salido de <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Siguiente elemento similar</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">No hay ningún cuadro combinado posterior.</translation>
-<translation id="6307969636681130414">Pulsado</translation>
-<translation id="6324551002951139333">Error gramatical detectado</translation>
-<translation id="6348657800373377022">Cuadro combinado</translation>
-<translation id="6355910664415701303">No hay ningún elemento de la lista anterior.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Encabezado anterior</translation>
-<translation id="6387719785439924554">etiqueta de contenido tangencial</translation>
-<translation id="6411426777058107714">No hay ningún botón de opción anterior.</translation>
-<translation id="6414968628640960377">Elemento anterior distinto</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dos puntos}other{# signos dos puntos}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menú</translation>
-<translation id="6444046323172968959">Cuadro de diálogo de alerta</translation>
-<translation id="6459511626086141404">Mapa de teclado plano</translation>
-<translation id="6468049171101508116">Botón siguiente</translation>
-<translation id="6491972999578897419">Cambia la voz actual seleccionando una de las opciones de la lista que aparece a continuación.</translation>
-<translation id="6508059270146105198">Mueve la pantalla braille a la parte inferior de la página</translation>
-<translation id="6536864053412760904">Token de MathML</translation>
-<translation id="6550720799683018100">Cambia el mapa de teclado actual seleccionando una de las opciones de la lista que aparece a continuación.</translation>
-<translation id="6561818612645211875">Accede al principio de la fila actual</translation>
-<translation id="6587021927234520429">No hay ningún título de nivel 4 posterior.</translation>
-<translation id="6601344353291556895">Habilitar descripciones detalladas.</translation>
-<translation id="6615602925644411249">Buscar en la página</translation>
-<translation id="6633350132811819843">No hay ninguna tabla posterior.</translation>
-<translation id="6637586476836377253">registro</translation>
-<translation id="6657128831881431364">Barra de progreso</translation>
-<translation id="6659594942844771486">Pestaña</translation>
-<translation id="667999046851023355">Documento</translation>
-<translation id="6697092096875747123">Cuadro combinado anterior</translation>
-<translation id="6714813999819678458">Encabezado anterior de nivel 2</translation>
-<translation id="6716505898850596801">Teclas modificadoras</translation>
-<translation id="671916444866103745">No hay ningún punto de referencia de ARIA posterior.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, cuadro combinado</translation>
-<translation id="6735257939857578167">con <ph name="NUM" /> elementos</translation>
-<translation id="6736510033526053669">pestaña creada</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Etiqueta de artículo</translation>
-<translation id="6787839852456839824">Combinaciones de teclas</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Etiqueta de pie de página</translation>
-<translation id="6871161210040114857">No se distingue entre mayúsculas y minúsculas.</translation>
-<translation id="6877435256196695200">No hay ningún gráfico posterior.</translation>
-<translation id="6897341342232909480">Se desplaza a la izquierda</translation>
-<translation id="6901540140423170855">fecha</translation>
-<translation id="6910211073230771657">Eliminado</translation>
-<translation id="6911965441508464308">No hay ninguna celda arriba.</translation>
-<translation id="6919104639734799681">Muestra la lista de tablas</translation>
-<translation id="6964088412282673743">No hay controles anteriores.</translation>
-<translation id="6996566555547746822">Siguiente cuadro combinado</translation>
-<translation id="7005146664810010831">No se ha encontrado la URL.</translation>
-<translation id="7010712454773919705">Tecla de modificación ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Lista anterior</translation>
-<translation id="7041173719775863268">Finalizar selección</translation>
-<translation id="7095834689119144465">Edita solo texto numérico</translation>
-<translation id="7096001299300236431">Anterior archivo multimedia</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">decir palabras</translation>
-<translation id="713824876195128146">Siguiente cita de bloque</translation>
-<translation id="7161771961008409533">Botón con componente emergente</translation>
-<translation id="7167657087543110">decir caracteres</translation>
-<translation id="7170733337935166589">Avanza durante una lectura continua</translation>
-<translation id="7181697990050180700">Personaliza las combinaciones de teclas de los comandos utilizados con frecuencia incluyéndolas en los campos correspondientes.</translation>
-<translation id="7203150201908454328">Ampliado</translation>
-<translation id="7210211103303402262">minutos</translation>
-<translation id="7217912842225915592">Más de <ph name="NUM" /></translation>
-<translation id="7221740160534240920">línea</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Título</translation>
-<translation id="7241683698754534149">Abre descripción larga en una pestaña nueva</translation>
-<translation id="7248671827512403053">Aplicación</translation>
-<translation id="725969808843520477">Siguiente botón de opción</translation>
-<translation id="7269119382257320590">Ningún signo de puntuación</translation>
-<translation id="7273174640290488576">Línea vacía</translation>
-<translation id="7285387653379749618">Tablas</translation>
-<translation id="7289186959554153431">Título 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Subtítulos Braille inhabilitados.</translation>
-<translation id="7318872822751139669">Utilizar el ratón para cambiar los elementos seleccionados.</translation>
-<translation id="7322388933135261569">Febrero</translation>
-<translation id="7332592614823088566">Fila <ph name="ROWINDEX" /> de <ph name="ROWTOTAL" />, columna <ph name="COLINDEX" /> de <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">tiene un componente emergente</translation>
-<translation id="7356165926712028380">Cambiar a Braille de ocho puntos</translation>
-<translation id="7362871137496673139">No hay ningún título de nivel 2 anterior.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{et}other{# símbolos et}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Saliendo de la tabla.</translation>
-<translation id="739763518212184081">Línea anterior</translation>
-<translation id="7400575256015741911">Error de ortografía detectado</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">retorno</translation>
-<translation id="7434509671034404296">Opciones para desarrolladores</translation>
-<translation id="7439060726180460871">Directorio</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tabulador</translation>
-<translation id="7492049978501397201">Diálogo introducido</translation>
-<translation id="7532613204005497612">Junio</translation>
-<translation id="7540083713905917247">Control deslizante <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="7586163296341959563">pegar.</translation>
-<translation id="7596919493010894443">selección borrada</translation>
-<translation id="7604026522577407655">Accede al principio de la columna actual</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Indica la URL de la página actual</translation>
-<translation id="7609363189280667021">Activa los subtítulos braille</translation>
-<translation id="762020119231868829">Pausa todos los widgets multimedia en reproducción</translation>
-<translation id="7625690649919402823">Siguiente tabla</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), grado <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">No hay ningún título de nivel 3 anterior.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, cuadro de texto</translation>
-<translation id="7663318257180412551">Título 2</translation>
-<translation id="7674576868851035240">Siguiente enlace</translation>
-<translation id="7674768236845044097">etiqueta de marcado</translation>
-<translation id="7684431668231950609">Edita texto, entrada de URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Botón de opción anterior</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, cuadro de texto de contraseña</translation>
-<translation id="7805247615045262757">navegación predeterminada</translation>
-<translation id="7805768142964895445">Estado</translation>
-<translation id="7810781339813764006">Grupo siguiente</translation>
-<translation id="7819187121850078213">ventana, <ph name="TITLE" />, pestaña</translation>
-<translation id="7828956995407538686">Octubre</translation>
-<translation id="7839679365527550018">Palabra anterior</translation>
-<translation id="7851816175263618915">Algunos signos de puntuación</translation>
-<translation id="7870596830398826354">Árbol de MathML</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Habilitar o inhabilitar ChromeVox clásico</translation>
-<translation id="7895896691902835279">Enlace desconocido</translation>
-<translation id="7927711904086083099">No esta seleccionado</translation>
-<translation id="7935627501098484003">Control de hora</translation>
-<translation id="7939428177581522200">eliminado de la selección</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{arroba}other{# arrobas}}</translation>
-<translation id="7965147473449754028">menú cerrado</translation>
-<translation id="7974390230414479278">Elemento de menú</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{signo de exclamación}other{# signos de exclamación}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{comilla}other{# comillas}}</translation>
-<translation id="8033827949643255796">seleccionados</translation>
-<translation id="8035962149453661158">máx:<ph name="X" /></translation>
-<translation id="8042761080832772327">Edita texto, entrada de búsqueda</translation>
-<translation id="8049189770492311300">Temporizador</translation>
-<translation id="8065607967589909823">Has seleccionado</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">No hay puntos de referencia de ARIA.</translation>
-<translation id="8153880621934657047">No está dentro de la tabla.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{guión bajo}other{# guiones bajos}}</translation>
-<translation id="8179976553408161302">Intro</translation>
-<translation id="81960742267269908">cortar.</translation>
-<translation id="8199231515320852133">Indica los encabezados de la celda actual</translation>
-<translation id="820417203470636242">Celda vacía.</translation>
-<translation id="8215202828671303819">Selección múltiple</translation>
-<translation id="8276439074553447000">Salta al elemento enfocable anterior</translation>
-<translation id="8278417001922463147">No hay artículos anteriores.</translation>
-<translation id="8283603667300770666">Siguiente campo de formulario</translation>
-<translation id="831207808878314375">Definición</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">horas</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{almohadilla}other{# almohadillas}}</translation>
-<translation id="8374154622594089836">mes</translation>
-<translation id="8378855320830505539">Región</translation>
-<translation id="8382679411218029383">Autocompletados insertados y lista de autocompletados</translation>
-<translation id="8428603554127842284">nivel <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">No hay ningún título de nivel 3 posterior.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">No hay ninguna casilla de verificación anterior.</translation>
-<translation id="8455868257606149352">Máximo <ph name="X" /></translation>
-<translation id="84575901236241018">tiene clave de acceso, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Disminuye granularidad de navegación</translation>
-<translation id="8520472399088452386">Botón de control numérico</translation>
-<translation id="8538744478902126321">Intenta detectar el encabezado de la fila de la celda actual</translation>
-<translation id="8540054775867439484">Continuar al principio</translation>
-<translation id="8548973727659841685">Carácter</translation>
-<translation id="8561322612995434619">tiene un componente emergente</translation>
-<translation id="8571096049907249734">selmult</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Siguiente elemento de la lista</translation>
-<translation id="860150890330522909"><ph name="NAME" />, casilla de verificación activada</translation>
-<translation id="8606621670302093223">Control de fecha</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> elementos seleccionados</translation>
-<translation id="8638532244051952400">Indica las coordenadas actuales de la celda</translation>
-<translation id="8650576015643545550">No hay ninguna lista anterior.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Muestra la lista de enlaces</translation>
-<translation id="8664519043722036194">segundos</translation>
-<translation id="867187640362843212">Título 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{barra vertical}other{# barras verticales}}</translation>
-<translation id="8735450637152821465">Inicia selección</translation>
-<translation id="8743786158317878347">introduce contenido estructurado (por ejemplo, tablas)</translation>
-<translation id="8747966237988593539">Lista ordenada</translation>
-<translation id="8759334257841767240">No hay ningún enlace posterior.</translation>
-<translation id="8767968232364267681">Siguiente encabezado de nivel 4</translation>
-<translation id="8770473310765924354">sale del contenido estructurado (por ejemplo, tablas)</translation>
-<translation id="8791025954632646584">Semántica activada</translation>
-<translation id="8796411681063377102">Siguiente encabezado de nivel 3</translation>
-<translation id="8808582214901541005">Marzo</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">principal</translation>
-<translation id="8856538297388979332">Pulsa las flechas hacia arriba o hacia abajo para revisar comandos. Pulsa la tecla Intro para activarlos.</translation>
-<translation id="8864099967139188018">No hay ningún título de nivel 6 posterior.</translation>
-<translation id="8882002077197914455">Encabezado de fila</translation>
-<translation id="8896347895970027998">Activar o desactivar ChromeVox.</translation>
-<translation id="8898516272131543774">Di ciclo de puntuación</translation>
-<translation id="8900148057318340779">Tecla de prefijo</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Encabezados vacíos</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Teclas modificadoras</translation>
-<translation id="8943175951035496220">No hay ninguna celda a la derecha.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">No hay tablas.</translation>
-<translation id="9040132695316389094">Título 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Activa o desactiva widget de búsqueda</translation>
-<translation id="9065283790526219006">más componente emergente</translation>
-<translation id="9077213568694924680">eliminado de la selección</translation>
-<translation id="9082874451376019682">No hay ningún control deslizante anterior.</translation>
-<translation id="9089864840575085222">Di ciclo de escritura</translation>
-<translation id="9107530006868467849">No hay widgets multimedia anteriores.</translation>
-<translation id="9108370397979208512">expresión matemática</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{porcentaje}other{# porcentajes}}</translation>
-<translation id="9115913704608474258">Noviembre</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Muestra una breve descripción de la posición actual.</translation>
-<translation id="9153606228985488238">Tono: <ph name="PERCENT" />%</translation>
-<translation id="9160096769946561184">Accede al final de la columna actual</translation>
-<translation id="9173115498289768110">Volumen: <ph name="PERCENT" />%</translation>
-<translation id="9178973770513562274">Utiliza las flechas hacia arriba y hacia abajo para explorar contenido o escribe tu consulta.</translation>
-<translation id="9192904702577636854">Desplazamiento</translation>
-<translation id="9212322457209634662">No hay más secciones.</translation>
-<translation id="930275611743429116">Inicia o termina la selección.</translation>
-<translation id="948171205378458592">Habla más lento</translation>
-<translation id="962913030769097253">Siguiente encabezado de nivel 1</translation>
-<translation id="973955474346881951">Habilita o inhabilita el modo de recarga automática</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_et.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_et.xtb
deleted file mode 100644
index 3705d47418c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_et.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="et">
-<translation id="1012173283529841972">Loendiüksus</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Ulatusega.</translation>
-<translation id="1025074108959230262">Nakkerežiim on keelatud</translation>
-<translation id="1031961866430398710">siis</translation>
-<translation id="1044777062731150180">Päiseid ei ole</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Kehtetu sisend</translation>
-<translation id="1082209053475788238">Eelmist 6. taseme pealkirja ei ole.</translation>
-<translation id="1088219014394087294">Pealkirju ei ole.</translation>
-<translation id="1106741348836243114">Lülitage helitagasiside (helisignaalid) sisse või välja.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Kollektsioon <ph name="TAG" />, mis hõlmab <ph name="NUM" /> üksust</translation>
-<translation id="1155043339247954670">Järgmist loendiüksust ei ole.</translation>
-<translation id="1157782847298808853">Klaviatuuri abi</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, liitboks</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, menüü-üksus, alammenüüga</translation>
-<translation id="1177863135347784049">Kohandatud</translation>
-<translation id="1188858454923323853">täiendav</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – annab Chrome'ile hääle</translation>
-<translation id="1229276918471378188">Eelmine hüpe</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Järgmine 6. taseme pealkiri</translation>
-<translation id="1275718070701477396">Valitud</translation>
-<translation id="1319608975892113573">Eelmist plokktsitaati ei ole.</translation>
-<translation id="1321576897702511272">Peida ChromeVoxi abi</translation>
-<translation id="1331702245475014624"><ph name="INDEX" />/<ph name="TOTAL" />-st</translation>
-<translation id="1334095593597963605">tähemärkide ja sõnade kaja</translation>
-<translation id="1339428534620983148">Tabeli eelmine veerg</translation>
-<translation id="1342835525016946179">artikkel</translation>
-<translation id="1346748346194534595">Paremale</translation>
-<translation id="136718599399906424">Järgmine tabeli rida</translation>
-<translation id="1383876407941801731">Otsi</translation>
-<translation id="1385214448885562192">Nõustumiseks vajutage sisestusklahvi Enter, tühistamiseks paoklahvi Escape, järgmise juurde liikumiseks vajutage alla ja eelmise juurde liikumiseks üles.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, parooli tekstikast</translation>
-<translation id="1467432559032391204">Vasakule</translation>
-<translation id="1474557363159888097">Eelmist ankrut ei ole.</translation>
-<translation id="1502086903961450562">Eelmine graafik</translation>
-<translation id="1506187449813838456">Suurendab helikõrgust</translation>
-<translation id="151784044608172266">Järgmine lause</translation>
-<translation id="1524531499102321782">Braille' järgmine rida</translation>
-<translation id="1546370775711804143">Kerimisriba</translation>
-<translation id="1559739829547075274">Liigu tagasi</translation>
-<translation id="1571643229714746283">ChromeVox on valmis</translation>
-<translation id="158493514907962286">Detsember</translation>
-<translation id="1594072653727561613">mnü</translation>
-<translation id="1610130962244179598">Lülitu 6-punktisele punktkirjale</translation>
-<translation id="1611168825862729585">Veeru päis:</translation>
-<translation id="1613476421962910979">Helisignaalid on sees</translation>
-<translation id="1618597272655350600">Esitab praeguse asukoha täpse kirjelduse</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{suurem kui}other{# märki „suurem kui”}}</translation>
-<translation id="1653266918374749391">Eelmine 3. taseme pealkiri</translation>
-<translation id="1659072772017912254">Märkimata</translation>
-<translation id="1669290819662866522">nädal</translation>
-<translation id="1674262202423278359">ChromeVoxi navigeerimine</translation>
-<translation id="16777221443363124">Menüüriba</translation>
-<translation id="1692077714702418899">struktuurne joon</translation>
-<translation id="1700517974991662022">Külastatud</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Järgmine graafik</translation>
-<translation id="1781173782405573156">Läbimisklahv</translation>
-<translation id="1787176709638001873">Parooli muutmise tekst</translation>
-<translation id="1810107444790159527">Loendiboks</translation>
-<translation id="1828385960365606039">Mai</translation>
-<translation id="1834891354138622109">Veerg</translation>
-<translation id="1865601187525349519">Teksti lõpp</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Esitage praegune kellaaeg ja kuupäev.</translation>
-<translation id="1902396333223336119">Lahter</translation>
-<translation id="1905379170753160525">Kuva pealkirjade loend</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Aasta nädala valimine</translation>
-<translation id="1964135212174907577">Järgmine objekt</translation>
-<translation id="1969092762068865084">Juuli</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Rea päis:</translation>
-<translation id="2002895034995108595">Lähtesta praegune klahvitabel</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{vasak nurksulg}other{# vasakut nurksulgu}}</translation>
-<translation id="2045490512405922022">märkimata</translation>
-<translation id="20601713649439366">Eelmist matemaatilist avaldist ei ole.</translation>
-<translation id="207477615537953741">Semantiline on välja lülitatud</translation>
-<translation id="2086961585857038472">Järgmine sõna</translation>
-<translation id="2089387485033699258">et</translation>
-<translation id="2091933974477985526">Eelmine muudetav tekstiala</translation>
-<translation id="2100350898815792233">Kõik kirjavahemärgid</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">pääsuklahv:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Vahetage praegust 6-punktise punktkirja tabelit, tehes valiku allolevast loendist.</translation>
-<translation id="2169714232367507776">Klõpsa aktiivsel elemendil</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{parem ümarsulg}other{# paremat ümarsulgu}}</translation>
-<translation id="2199994615414171367">Eelmine valem</translation>
-<translation id="2223693656926968778">Toiming praeguse üksusega</translation>
-<translation id="225732394367814946">Suurenda kõne kiirust</translation>
-<translation id="2267945578749931355">Järgmine tärk</translation>
-<translation id="2281234842553884450">Eelmine liugur</translation>
-<translation id="2318372665160196757">Peamine</translation>
-<translation id="2329324941084714723">Vahelehepaneel</translation>
-<translation id="2344193891939537199">Kuupäeva ja kellaaja valimine</translation>
-<translation id="2359897517538099099">Pole tabelirežiimis.</translation>
-<translation id="241124561063364910">millele järgneb</translation>
-<translation id="2417569100218200841">Sisu teave</translation>
-<translation id="2422937916923936891">Menüü-üksuse märkeruut</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> on nüüd uus ChromeVoxi muuteklahv.</translation>
-<translation id="2450814015951372393">Märkeruut</translation>
-<translation id="2462626033734746142">Raadionuppude rühm</translation>
-<translation id="2471138580042810658">6. pealkiri</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{tärn}other{# tärni}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> on lähtestatud.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Rühm</translation>
-<translation id="2582407057977008361">Kõrvale</translation>
-<translation id="2589102159832527089">Leht sisaldab automaatselt PDF-failist &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; ekstraktitud teksti. &lt;a href="<ph name="URL" />"&gt;Originaali jaoks klõpsake siin.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">koos {COUNT,plural, =1{# üksusega}other{# üksusega}}</translation>
-<translation id="2614981083756825552">Math ML-i paigutus</translation>
-<translation id="2626530649491650971">klõpsatav</translation>
-<translation id="2628764385451019380">Eelmist liitboksi ei ole.</translation>
-<translation id="2637227747952042642">Matemaatika</translation>
-<translation id="2639750663247012216">ChromeVoxi muuteklahv</translation>
-<translation id="2644542693584024604">kirjaviga</translation>
-<translation id="2667291555398229137">Klõpsake marsruutimisvõtme all oleval üksusel</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{vasak ümarsulg}other{# vasakut ümarsulgu}}</translation>
-<translation id="2705875883745373140">Pole vajutatud</translation>
-<translation id="2706462751667573066">Üles</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">heli</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Märgitud</translation>
-<translation id="27527859628328957">Liigu järgmise fookustatud üksuse juurde</translation>
-<translation id="2770781857296573485">Rühma uuringu sisestamine</translation>
-<translation id="2777845298774924149">Väljus</translation>
-<translation id="2800204403141299078">Pole rohkem erinevaid elemente.</translation>
-<translation id="2800780099804980316">Eelmist 1. taseme pealkirja ei ole.</translation>
-<translation id="2811204574343810641">Rida</translation>
-<translation id="2816654101880605877">Järgmist liugurit ei ole.</translation>
-<translation id="2841013758207633010">Aeg</translation>
-<translation id="2843837985843789981">Eelmine rühm</translation>
-<translation id="2844995807198708617">Kontekstimenüü</translation>
-<translation id="2849332794118375855">Järgmist märkeruutu ei ole.</translation>
-<translation id="2864481629947106776">Eelmine link</translation>
-<translation id="2873259058405069099">Mine tabeli algusesse</translation>
-<translation id="2894654529758326923">Teave</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{vasak loogeline sulg}other{# vasakut loogelist sulgu}}</translation>
-<translation id="2911433807131383493">ChromeVoxi õpetuse avamine</translation>
-<translation id="2932083475399492303">Vahetab struktuurse ja paigutuse joone vahel</translation>
-<translation id="2964026537669811554">Pealkirja rühm</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulaator}other{# tabulaatorit}}</translation>
-<translation id="2972078295414139404">Pole eelmist külastatud linki.</translation>
-<translation id="2972205263822847197">Tööriista nõuanne</translation>
-<translation id="2998131015536248178">Eelmine tärk</translation>
-<translation id="2999559350546931576">Vähenda helikõrgust</translation>
-<translation id="2999945368667127852">Järgmist meediavidinat pole.</translation>
-<translation id="3012414509011670858">Eelmist jaotist ei ole.</translation>
-<translation id="3030432017085518523">Menüü-üksuse raadionupp</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{ülakoma}other{# ülakoma}}</translation>
-<translation id="3046838483509668188">ChromeVoxi valikud</translation>
-<translation id="3047143736589213134">Katseline klahvitabel</translation>
-<translation id="3060756054951570867">Menüü <ph name="TITLE" /> on avatud</translation>
-<translation id="3078345202707391975">Järgmine 2. taseme pealkiri</translation>
-<translation id="3078740164268491126">tabel</translation>
-<translation id="3082557070674409251">Klõpsatud</translation>
-<translation id="3084806535845658316">teksti sisestamise kaja on välja lülitatud</translation>
-<translation id="3086746722712840547">märge</translation>
-<translation id="308895241372589742">Järgmist matemaatilist avaldist ei ole.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Järgmine maamärk</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alm dlg</translation>
-<translation id="3109724472072898302">Ahendatud</translation>
-<translation id="3134461040845705080">kirjutuskaitstud</translation>
-<translation id="3138767756593758860">Kuva maamärkide loend</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Järgmine rida</translation>
-<translation id="3155083529632865074">Eelmist nuppu ei ole.</translation>
-<translation id="3163593631834463955">Veeru päis on tühi</translation>
-<translation id="316542773973815724">Navigeerimine</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{tühik}other{# tühikut}}</translation>
-<translation id="320961988183078793">sisestatud <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, vaheleht</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Külastatud link</translation>
-<translation id="323731244387692321">ChromeVoxi klaviatuuri abi avamine</translation>
-<translation id="3241052487511142956">Eelmine külastatud link</translation>
-<translation id="3286390186030710347">Liugur</translation>
-<translation id="3299925995433437805">Järgmist külastatud linki pole.</translation>
-<translation id="3303384412438961941">Vajutage mis tahes klahvi, et selle nime teada saada. Klahvikombinatsioon Ctrl + W suleb Keyboard Exploreri.</translation>
-<translation id="3307886118343381874">Mine tabeli lõppu</translation>
-<translation id="3311969765485641742">Märguannete ülevaatamiseks vajutage klahve Alt + Tõstuklahv + A</translation>
-<translation id="3312997241656799641">Järgmine külastatud link</translation>
-<translation id="3321460131042519426">Luba sõna murdmine</translation>
-<translation id="3322936298410871309">Eelmine 1. taseme pealkiri</translation>
-<translation id="3323447499041942178">Tekstiväli</translation>
-<translation id="3353420241558113817">{"ar": "araabia",
- "bg": "bulgaaria",
- "ca": "katalaani",
- "cs": "tšehhi",
- "da": "taani",
- "de": "saksa",
- "de_CH": "saksa (Šveits)",
- "de_DE": "saksa (Saksamaa)",
- "el": "kreeka",
- "en": "inglise",
- "en_CA": "inglise (Kanada)",
- "en_GB": "inglise (Ühendkuningriik)",
- "en_US": "inglise (Ameerika Ühendriigid)",
- "es": "hispaania",
- "et": "eesti",
- "fr": "prantsuse",
- "fr_CA": "prantsuse (Kanada)",
- "fr_FR": "prantsuse (Prantsusmaa)",
- "fi": "soome",
- "he": "heebrea",
- "hi": "hindi",
- "hr": "horvaadi",
- "hu": "ungari",
- "is": "islandi",
- "it": "itaalia",
- "ko": "korea",
- "lt": "leedu",
- "lv": "läti",
- "nb": "norra bokmål",
- "nl": "hollandi",
- "pl": "poola",
- "pt": "portugali",
- "ro": "rumeenia",
- "ru": "vene",
- "sk": "slovaki",
- "sl": "sloveeni",
- "sr": "serbia",
- "sv": "rootsi",
- "tr": "türgi",
- "vi": "vietnami",
- "zh": "hiina",
- "zh_TW": "hiina (traditsiooniline han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{pluss}other{# plussmärki}}</translation>
-<translation id="338583716107319301">Eraldaja</translation>
-<translation id="3389259863310851658">Vormi eelmine väli</translation>
-<translation id="3390225400784126843">Järgmine erinev element.</translation>
-<translation id="3392045790598181549">Menüü-üksus <ph name="NAME" /></translation>
-<translation id="3406283310380167331">Kuva vormide loend</translation>
-<translation id="3422338090358345848">Ava Keyboard Explorer</translation>
-<translation id="3457000393508828486">Osaliselt vajutatud</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, nupp</translation>
-<translation id="3473644018603298796">valitud <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> &gt; <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{parem nurksulg}other{# paremat nurksulgu}}</translation>
-<translation id="3493915602752813531">Järgmist ankrut ei ole.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{küsimärk}other{# küsimärki}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{sisestusmärk}other{# sisetusmärki}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, ruut ei ole märgitud</translation>
-<translation id="3599054940393788245">Ei kuulu valemisse</translation>
-<translation id="3616113530831147358">Heli</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{graavis}other{# graavist}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollar}other{# dollarimärki}}</translation>
-<translation id="3659787053479271466">alarm</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, loendiboks</translation>
-<translation id="3687295507293856493">Tee praeguse lahtri veerupäise kohta oletus</translation>
-<translation id="3692274950075847560">S: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Kõne juhtimine</translation>
-<translation id="3716845769494773620">Mitu rida</translation>
-<translation id="3731746171184829332">Eelmist pealkirja ei ole.</translation>
-<translation id="3762198587642264450">Mine praeguse rea lõppu</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Väljus dialoogist.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Loendi automaatne täitmine</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Järgmine meediaüksus</translation>
-<translation id="3819376190738087562">Siirdeid ei ole.</translation>
-<translation id="385383972552776628">Ava valikute leht</translation>
-<translation id="3856075812838139784">Kirjutuskaitstud</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menüü</translation>
-<translation id="3909320334364316587">Eelmine 6. taseme pealkiri</translation>
-<translation id="3914173277599553213">Kohustuslik</translation>
-<translation id="3962990492275676168">Alusta lugemist praegusest asukohast</translation>
-<translation id="4004802134384979325">märgitud</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Kuu kontroll</translation>
-<translation id="4039983576244166038">Rea päis on tühi</translation>
-<translation id="4042843249978639960">Järgmist 2. taseme pealkirja ei ole.</translation>
-<translation id="4043348641337972076">Eelmist ARIA maamärki ei ole.</translation>
-<translation id="4047216625641135770">Märk</translation>
-<translation id="404803211695627272"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="4054936709456751127">olek</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}other{# tildet}}</translation>
-<translation id="409334809956508737">Eelmine objekt</translation>
-<translation id="4099274309791143834">koos alammenüüga</translation>
-<translation id="4107807507418787238">All ei ole ühtki lahtrit.</translation>
-<translation id="4116415223832267137">Hoiatus</translation>
-<translation id="4147126331795725888">Järgmist juhtelementi ei ole.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{parem loogeline sulg}other{# paremat loogelist sulgu}}</translation>
-<translation id="4158704014418536539">Tõstutundlik.</translation>
-<translation id="4161663686871496107">ChromeVoxi kõnena esitatav tagasiside on valmis</translation>
-<translation id="4173994908659439270">Järgmist muudetavat tekstivälja ei ole.</translation>
-<translation id="4176463684765177261">Keelatud</translation>
-<translation id="4188530942454211480">Eelmine lause</translation>
-<translation id="4202186506458631436">Teisalda paremale</translation>
-<translation id="4206289001967551965">Tabelis</translation>
-<translation id="4215733775853809057">Järgmine liugur</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{kriips}other{# kriipsu}}</translation>
-<translation id="421884353938374759">värvivalija</translation>
-<translation id="4229646983878045487">kuupäev, kellaaeg</translation>
-<translation id="423334822609210999">Vasakul ei ole ühtki lahtrit.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" />. tase</translation>
-<translation id="4253168017788158739">Märkus</translation>
-<translation id="4254798249533888099">Puu</translation>
-<translation id="4255943572433203166">Kohandage ChromeVoxi allolevate valikute abil. Muudatused jõustuvad kohe.</translation>
-<translation id="4271220233568730077">Järgmine valem</translation>
-<translation id="4271521365602459209">Rohkem tulemusi pole.</translation>
-<translation id="4287520460805643128">Järgmist artiklit pole.</translation>
-<translation id="4289540628985791613">Ülevaade</translation>
-<translation id="4300318234632215983">Esita liURL</translation>
-<translation id="4301352596632316575">koos alammenüüga</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punkt}=3{ellips}other{# punkti}}</translation>
-<translation id="4347461890115250064">Järgmist loendit ei ole.</translation>
-<translation id="4367650418938037324">Math ML-i leht</translation>
-<translation id="4372435075475052704">min: <ph name="X" /></translation>
-<translation id="4372705107434148843">Kõne lõpetam</translation>
-<translation id="4373197658375206385">Kõik eelmised üksused on lingid.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">lähtesta</translation>
-<translation id="4471074325120394300">Linke ei ole.</translation>
-<translation id="4476183483923481720">uus rida</translation>
-<translation id="4482330759234983253">Eelmine tabel</translation>
-<translation id="4491109536499578614">Image</translation>
-<translation id="4529987814483543472">Klassikaline klahvitabel</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{kaldkriips}other{# kaldkriipsu}}</translation>
-<translation id="4547556996012970016">Järgmine 5. taseme pealkiri</translation>
-<translation id="4562381607973973258">Päis</translation>
-<translation id="4591507479202817876">, valitud</translation>
-<translation id="4597532268155981612">vorm</translation>
-<translation id="4597896406374528575">Aprill</translation>
-<translation id="4615592953348396470">Järgmist klahvivajutust ignoreeritakse</translation>
-<translation id="461613135510474570">Lause</translation>
-<translation id="4647836961514597010">Värvivalija</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">võrg</translation>
-<translation id="4693675773662933727">Eelmine maamärk</translation>
-<translation id="4696413482802371445">Järgmist 5. taseme pealkirja ei ole.</translation>
-<translation id="4729095194763193578">Eelmine tabeli rida</translation>
-<translation id="4736221692378411923">August</translation>
-<translation id="4740661827607246557">Abikäsud</translation>
-<translation id="4759716709594980008">ChromeOS-i Keyboard Explorer</translation>
-<translation id="4763296182459741068">Pakitud lehe alaossa</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">otsing</translation>
-<translation id="481165870889056555">Esitab praeguse lehe pealkirja</translation>
-<translation id="4826415162591436065">Liigu edasi</translation>
-<translation id="4826604887384865800">Järgmine hüpe</translation>
-<translation id="4827410568042294688">valimata</translation>
-<translation id="4842108708071771135">Järgmist plokktsitaati ei ole.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Eelmine sarnane element.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Luba TTS-i logimine</translation>
-<translation id="4877261390094455813">Otsingupäringu sisestamine.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Siselink</translation>
-<translation id="4953585991029886728">Teksti muutmine</translation>
-<translation id="4954534434583049121">Eelmine tsitaat</translation>
-<translation id="4973717656530883744">Min <ph name="X" /></translation>
-<translation id="4973762002207131920">Lülituti klahvitabelile <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">millisekundid</translation>
-<translation id="49787999531187221">ChromeVox ei ole enam aktiivne.</translation>
-<translation id="4979404613699303341">Eelmine nupp</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, loendiboks</translation>
-<translation id="4983588134362688868">Saate liikuda lehe algusesse</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, aken</translation>
-<translation id="4993152509206108683">Kiirus: <ph name="PERCENT" /> protsenti</translation>
-<translation id="4996716799442435517">Visuaal</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, raadionupp on valitud</translation>
-<translation id="4997475792277222884">Kõik järgmised üksused on lingid.</translation>
-<translation id="5000760171916499057">Vorme ei ole.</translation>
-<translation id="5005670136041063723">Pole rohkem sarnaseid elemente.</translation>
-<translation id="501473567976723023">Jaanuar</translation>
-<translation id="5041394372352067729">Braille' kuva lehe ülaserva liigutamine</translation>
-<translation id="5042770794184672516">Suurenda kõne helitugevust</translation>
-<translation id="5050015258024679800">Eelmine 4. taseme pealkiri</translation>
-<translation id="5054047268577924192">Eelmine loendiüksus</translation>
-<translation id="5078661581131202757">Faili valimine</translation>
-<translation id="5080758118274074384">topeltklõpsatud</translation>
-<translation id="5098541983634824365">Ruudustikust väljumine.</translation>
-<translation id="5102981729317424850">Tööriistariba</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Eelmist vormivälja ei ole.</translation>
-<translation id="5111640677200759579">Veeru päis</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Eelmist linki ei ole.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, valimata</translation>
-<translation id="5183440668879371625">Braille' eelmine rida</translation>
-<translation id="5184944171021383281">Järgmist vormivälja ei ole.</translation>
-<translation id="5189244881767082992">Rida</translation>
-<translation id="5203930734796605961">Klahvile <ph name="KEY" /> on käsk juba määratud.</translation>
-<translation id="5205493599117157272">Loend <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Järgmist raadionuppu ei ole.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objekt</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, vaheleht</translation>
-<translation id="5310788376443009632">eemaldatud:</translation>
-<translation id="5320727453979144100">Nakkerežiim on lubatud</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{koma}other{# koma}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, tekstikast</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Liigub pideva lugemise ajal tagasi</translation>
-<translation id="5368000168321181111">Helisignaalid on väljas</translation>
-<translation id="5374320867641260420">Järgmist nuppu ei ole.</translation>
-<translation id="5382299583965267720">Järgmist 1. taseme pealkirja ei ole.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{semikoolon}other{# semikoolonit}}</translation>
-<translation id="5411891038905756502">Eelmist siirdepunkti ei ole.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{vähem kui}other{# märki „vähem kui”}}</translation>
-<translation id="5455441614648621694">Täiendav</translation>
-<translation id="5485036206801896268">Eelmist graafikat ei ole.</translation>
-<translation id="5486947920110100234">Järgmist siirdepunkti ei ole.</translation>
-<translation id="549602578321198708">Sõna</translation>
-<translation id="5500932716852106146">Eelmist muudetavat tekstivälja ei ole.</translation>
-<translation id="5502713021410870035">September</translation>
-<translation id="5507663321906818013">Silumise etalon</translation>
-<translation id="5518443085409638729">Kursori tähemärkide vahele paigutamine teksti muutmisel (nagu Mac OS X-is).</translation>
-<translation id="552195134157544755">Raadionupp</translation>
-<translation id="5534303576632885660">päi</translation>
-<translation id="5546092960038624944">Eelmist 5. taseme pealkirja ei ole.</translation>
-<translation id="556042886152191864">Nupp</translation>
-<translation id="5561345396546889625">Järgmine loend</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Tagasilükkeklahv</translation>
-<translation id="5585044216466955529">Meilisõnumi teksti muutmine</translation>
-<translation id="5597170376237141345">Järgmine märkeruut</translation>
-<translation id="5597933780944041114">Järgmist pealkirja ei ole.</translation>
-<translation id="5598905979683743333">Raadionupp <ph name="NAME" /> ei ole valitud</translation>
-<translation id="5601172225407283979">Vaiketoimingu tegemine</translation>
-<translation id="5608798115546226984">Rea automaatne täitmine</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Logi</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Eelmist tabelit ei ole.</translation>
-<translation id="5655682562155942719">Siirdekäsud</translation>
-<translation id="56637627897541303">Tekstiala</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Maamärk</translation>
-<translation id="5683155931978483559">Eelmine märkeruut</translation>
-<translation id="5684277895745049190">Loend</translation>
-<translation id="5700650669149824506">Eelmist 4. taseme pealkirja ei ole.</translation>
-<translation id="5709192780268610569">Pikk kirjeldus puudub</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Järgmine tabeli veerg</translation>
-<translation id="571866080859340309">Rühma uuring</translation>
-<translation id="5728409797179002635">Tabelit ei leitud.</translation>
-<translation id="5748623122140342504">Eelmine 5. taseme pealkiri</translation>
-<translation id="5750633686117194034">Ei vajutatud ühtegi muuteklahvi. Vajutage ja hoidke all vähemalt ühte muuteklahvi. Kui olete lõpetanud, tõstke sõrmed ja kuulete klahvide fikseerimist. Väljumiseks puudutage.</translation>
-<translation id="5788275253279308023">inkognitoakna vaheleht <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Konkreetsete saitide (nagu Google'i otsing) täiustamine.</translation>
-<translation id="5819072574982403430">Puuüksus</translation>
-<translation id="5826479389509458994">rida <ph name="ROW" /> veerg <ph name="COL" /></translation>
-<translation id="5850707923114094062">Tagasi paanimine</translation>
-<translation id="5851548754964597211">Vahelehtede loend</translation>
-<translation id="5859752971144398932">Väljus lehelt otsimisest.</translation>
-<translation id="5866042630553435010">Osaliselt märgitud</translation>
-<translation id="5869546221129391014">Ruudustik</translation>
-<translation id="5876817486144482042">Vähenda kõne helitugevust</translation>
-<translation id="5887397643266327462">Punktkirjas tiitrid on lubatud.</translation>
-<translation id="5891934789323004067">Tabel</translation>
-<translation id="5919442531159595654">kopeeri.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{võrdusmärk}other{# võrdusmärki}}</translation>
-<translation id="5939518447894949180">Lähtesta</translation>
-<translation id="5948123859135882163">Matemaatiliste avaldiste struktuurse ja semantilise kujutamise vahetamine</translation>
-<translation id="5955304353782037793">rak</translation>
-<translation id="5956928062748260866">Dialoog</translation>
-<translation id="5963413905009737549">Jaotis</translation>
-<translation id="5968607524793740041">Kontekstimenüü kuvamine</translation>
-<translation id="5983179082906765664">Suurenda navigatsiooni detailsust</translation>
-<translation id="5999630716831179808">Hääled</translation>
-<translation id="6000417740266304866">Vahetage praegust 8-punktise punktkirja tabelit, tehes valiku allolevast loendist.</translation>
-<translation id="6006050241733874051">Vorm</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{kurakriips}other{# kurakaldkriipsu}}</translation>
-<translation id="6037602951055904232">Edasi navigeerimine</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Lahtri lõpp.</translation>
-<translation id="6122013438240733403">nupp</translation>
-<translation id="6129953537138746214">Tühik</translation>
-<translation id="6142308968191113180">4. pealkiri</translation>
-<translation id="6169420925157477918">Pika kirjeldusega kujutis</translation>
-<translation id="6172087735260766220">Kopeerimiskaitsega PDF-is ei pääse juurdepääsetavale tekstile juurde.</translation>
-<translation id="6186305613600865047">Saate liikuda lehe lõppu</translation>
-<translation id="6193330012414963395">AM/PM</translation>
-<translation id="622484624075952240">Alla</translation>
-<translation id="6236061028292614533">Järgmine pealkiri</translation>
-<translation id="6254901459154107917">Järgmine muudetav tekstiala</translation>
-<translation id="6259464875943891919">Väljusite ümbrisest <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Järgmine sarnane element.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Järgmist liitboksi ei ole.</translation>
-<translation id="6307969636681130414">Vajutatud</translation>
-<translation id="6324551002951139333">Tuvastati grammatiline viga</translation>
-<translation id="6348657800373377022">Liitboks</translation>
-<translation id="6355910664415701303">Eelmist loendiüksust ei ole.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Eelmine pealkiri</translation>
-<translation id="6387719785439924554">kõrvale</translation>
-<translation id="6411426777058107714">Eelmist raadionuppu ei ole.</translation>
-<translation id="6414968628640960377">Eelmine erinev element.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{koolon}other{# koolonit}}</translation>
-<translation id="6438968337250688271">Menüü <ph name="NAME" /></translation>
-<translation id="6444046323172968959">Hoiatusdialoog</translation>
-<translation id="6459511626086141404">Lame klahvitabel</translation>
-<translation id="6468049171101508116">Järgmine nupp</translation>
-<translation id="6491972999578897419">Muutke praegust häält, tehes valiku allolevas loendis.</translation>
-<translation id="6508059270146105198">Braille' kuva lehe alaserva liigutamine</translation>
-<translation id="6536864053412760904">Math ML-i märk</translation>
-<translation id="6550720799683018100">Muutke praegust klahvitabelit, tehes valiku allolevas loendis.</translation>
-<translation id="6561818612645211875">Mine praeguse rea algusesse</translation>
-<translation id="6587021927234520429">Järgmist 4. taseme pealkirja ei ole.</translation>
-<translation id="6601344353291556895">Paljusõnaliste kirjelduste lubamine.</translation>
-<translation id="6615602925644411249">Lehelt otsimine.</translation>
-<translation id="6633350132811819843">Järgmist tabelit ei ole.</translation>
-<translation id="6637586476836377253">logi</translation>
-<translation id="6657128831881431364">Edenemisriba</translation>
-<translation id="6659594942844771486">Vaheleht</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Eelmine liitboks</translation>
-<translation id="6714813999819678458">Eelmine 2. taseme pealkiri</translation>
-<translation id="6716505898850596801">Muuteklahvid</translation>
-<translation id="671916444866103745">Järgmist ARIA maamärki ei ole.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, liitboks</translation>
-<translation id="6735257939857578167">hõlmab <ph name="NUM" /> üksust</translation>
-<translation id="6736510033526053669">vaheleht on loodud</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artikkel</translation>
-<translation id="6787839852456839824">Klaviatuuri otseteed</translation>
-<translation id="6793101435925451627">lndkast</translation>
-<translation id="6833103209700200188">Jalus</translation>
-<translation id="6871161210040114857">Tähe suurust eiratakse.</translation>
-<translation id="6877435256196695200">Järgmist graafikat ei ole.</translation>
-<translation id="6897341342232909480">Teisalda vasakule</translation>
-<translation id="6901540140423170855">kuupäev</translation>
-<translation id="6910211073230771657">Kustutatud</translation>
-<translation id="6911965441508464308">Ülal ei ole ühtki lahtrit.</translation>
-<translation id="6919104639734799681">Kuva tabelite loend</translation>
-<translation id="6964088412282673743">Eelmist juhtelementi ei ole.</translation>
-<translation id="6996566555547746822">Järgmine liitboks</translation>
-<translation id="7005146664810010831">URL-i ei leitud</translation>
-<translation id="7010712454773919705">ChromeVoxi muuteklahv</translation>
-<translation id="7031651751836475482">lnd üksus</translation>
-<translation id="7037042857287298941">Eelmine loend</translation>
-<translation id="7041173719775863268">Valiku lõpp</translation>
-<translation id="7095834689119144465">Tekstis olevate numbrite muutmine</translation>
-<translation id="7096001299300236431">Eelmine meediaüksus</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">sõnade kaja</translation>
-<translation id="713824876195128146">Järgmine tsitaat</translation>
-<translation id="7161771961008409533">Hüpikunupp</translation>
-<translation id="7167657087543110">tähemärkide kaja</translation>
-<translation id="7170733337935166589">Liigub pideva lugemise ajal edasi</translation>
-<translation id="7181697990050180700">Kohandage sagedasti kasutavate käskude klaviatuuri otseteid, sisestades need vastavatele allolevatele väljadele.</translation>
-<translation id="7203150201908454328">Laiendatud</translation>
-<translation id="7210211103303402262">minutit</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">rida</translation>
-<translation id="7226216518520804442">lnd</translation>
-<translation id="72393384879519786">Pealkiri</translation>
-<translation id="7241683698754534149">Avab pika kirjelduse uuel vahelehel</translation>
-<translation id="7248671827512403053">Rakendus</translation>
-<translation id="725969808843520477">Järgmine raadionupp</translation>
-<translation id="7269119382257320590">Kirjavahemärkideta</translation>
-<translation id="7273174640290488576">Tühi</translation>
-<translation id="7285387653379749618">Tabelid</translation>
-<translation id="7289186959554153431">3. pealkiri</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Punktkirjas tiitrid on keelatud.</translation>
-<translation id="7318872822751139669">Hiire abil fookuse muut.</translation>
-<translation id="7322388933135261569">Veebruar</translation>
-<translation id="7332592614823088566">Rida <ph name="ROWINDEX" />/<ph name="ROWTOTAL" />, veerg <ph name="COLINDEX" />/<ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">koos hüpikuga</translation>
-<translation id="7356165926712028380">Lülitu 8-punktisele punktkirjale</translation>
-<translation id="7362871137496673139">Eelmist 2. taseme pealkirja ei ole.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersand}other{# ampersandi}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Tabelist lahkumine.</translation>
-<translation id="739763518212184081">Eelmine rida</translation>
-<translation id="7400575256015741911">Tuvastati õigekirjaviga</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">tagasi</translation>
-<translation id="7434509671034404296">Arendaja</translation>
-<translation id="7439060726180460871">Kataloog</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">Tabulaator</translation>
-<translation id="7492049978501397201">Sisestatud dialoog</translation>
-<translation id="7532613204005497612">Juuni</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, liugur</translation>
-<translation id="7586163296341959563">kleebi.</translation>
-<translation id="7596919493010894443">valik on tühjendatud</translation>
-<translation id="7604026522577407655">Mine praeguse veeru algusesse</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Esita praeguse lehe URL</translation>
-<translation id="7609363189280667021">Punktkirjas tiitrite sisse- ja väljalülitamine</translation>
-<translation id="762020119231868829">Peatab kõik praegu esitatavad meediavidinad</translation>
-<translation id="7625690649919402823">Järgmine tabel</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), klass <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Eelmist 3. taseme pealkirja ei ole.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, tekstikast</translation>
-<translation id="7663318257180412551">2. pealkiri</translation>
-<translation id="7674576868851035240">Järgmine link</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">URL-i muutmine</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Eelmine raadionupp</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, parooli tekstikast</translation>
-<translation id="7805247615045262757">vaikimisi navigeerimine</translation>
-<translation id="7805768142964895445">Olek</translation>
-<translation id="7810781339813764006">Järgmine rühm</translation>
-<translation id="7819187121850078213">akna vaheleht <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Oktoober</translation>
-<translation id="7839679365527550018">Eelmine sõna</translation>
-<translation id="7851816175263618915">Mõned kirjavahemärgid</translation>
-<translation id="7870596830398826354">Math ML-i puu</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVoxi klassikalisele režiimile lülitamine.</translation>
-<translation id="7895896691902835279">Tundmatu link</translation>
-<translation id="7927711904086083099">Valimata</translation>
-<translation id="7935627501098484003">Aja juhtimine</translation>
-<translation id="7939428177581522200">lisatud valikusse</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{ät-märk (@)}other{# ät-märki (@)}}</translation>
-<translation id="7965147473449754028">menüü suleti</translation>
-<translation id="7974390230414479278">Menüü-üksus</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{hüüumärk}other{# hüüumärki}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{jutumärk}other{# jutumärki}}</translation>
-<translation id="8033827949643255796">valitud</translation>
-<translation id="8035962149453661158">max: <ph name="X" /></translation>
-<translation id="8042761080832772327">Otsingu teksti muutmine</translation>
-<translation id="8049189770492311300">Taimer</translation>
-<translation id="8065607967589909823">Valik on</translation>
-<translation id="8066678206530322333">Bänner</translation>
-<translation id="8110647606445335195">ARIA maamärke ei ole.</translation>
-<translation id="8153880621934657047">Ei ole tabelis.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{alljoon}other{# alljoont}}</translation>
-<translation id="8179976553408161302">Sisestusklahv</translation>
-<translation id="81960742267269908">lõika.</translation>
-<translation id="8199231515320852133">Esita praeguse lahtri päised</translation>
-<translation id="820417203470636242">Tühi lahter.</translation>
-<translation id="8215202828671303819">Mitmikvalimine</translation>
-<translation id="8276439074553447000">Liigu eelmise fookustatava üksuse juurde</translation>
-<translation id="8278417001922463147">Eelmist artiklit pole.</translation>
-<translation id="8283603667300770666">Vormi järgmine väli</translation>
-<translation id="831207808878314375">Definitsioon</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">tunnid</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{nael}other{# naelamärki}}</translation>
-<translation id="8374154622594089836">kuu</translation>
-<translation id="8378855320830505539">Piirkond</translation>
-<translation id="8382679411218029383">Rea ja loendi automaatne täitmine</translation>
-<translation id="8428603554127842284"><ph name="DEPTH" />. tase</translation>
-<translation id="842922884199979200">Järgmist 3. taseme pealkirja ei ole.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Eelmist märkeruutu ei ole.</translation>
-<translation id="8455868257606149352">Max <ph name="X" /></translation>
-<translation id="84575901236241018">on pääsuklahv, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Vähenda navigatsiooni detailsust</translation>
-<translation id="8520472399088452386">Pöördnupp</translation>
-<translation id="8538744478902126321">Tee praeguse lahtri rea päise kohta oletus</translation>
-<translation id="8540054775867439484">Pakitud lehe ülaossa</translation>
-<translation id="8548973727659841685">Tähemärk</translation>
-<translation id="8561322612995434619">koos hüpikuga</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Järgmine loendiüksus</translation>
-<translation id="860150890330522909">Ruut <ph name="NAME" /> on märgitud</translation>
-<translation id="8606621670302093223">Kuupäeva valimine</translation>
-<translation id="8631359288236106450">valitud on <ph name="COUNT" /> üksust</translation>
-<translation id="8638532244051952400">Praeguse lahtri koordinaatide ütlemine</translation>
-<translation id="8650576015643545550">Eelmist loendit ei ole.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Kuva linkide loend</translation>
-<translation id="8664519043722036194">sekundid</translation>
-<translation id="867187640362843212">5. pealkiri</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{püstkriips}other{# püstkriipsu}}</translation>
-<translation id="8735450637152821465">Valiku algus</translation>
-<translation id="8743786158317878347">siseneb struktuursesse sisusse, näiteks tabelitesse</translation>
-<translation id="8747966237988593539">Korrastatud loend</translation>
-<translation id="8759334257841767240">Järgmist linki ei ole.</translation>
-<translation id="8767968232364267681">Järgmine 4. taseme pealkiri</translation>
-<translation id="8770473310765924354">väljub struktuursest sisust, näiteks tabelitest</translation>
-<translation id="8791025954632646584">Semantiline on sisse lülitatud</translation>
-<translation id="8796411681063377102">Järgmine 3. taseme pealkiri</translation>
-<translation id="8808582214901541005">Märts</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">pea</translation>
-<translation id="8856538297388979332">Käskude vaatamiseks vajutage üles või alla, aktiveerimiseks vajutage sisestusklahvi</translation>
-<translation id="8864099967139188018">Järgmist 6. taseme pealkirja ei ole.</translation>
-<translation id="8882002077197914455">Rea päis</translation>
-<translation id="8896347895970027998">ChromeVoxi sisse- või väljalülitamine.</translation>
-<translation id="8898516272131543774">Kirjavahemärkide kaja tsükkel</translation>
-<translation id="8900148057318340779">Prefiksklahv</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Päised on tühjad</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Muuteklahvid</translation>
-<translation id="8943175951035496220">Paremal ei ole ühtki lahtrit.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">fail</translation>
-<translation id="9027462562263121875">Tabeleid ei ole.</translation>
-<translation id="9040132695316389094">1. pealkiri</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Otsinguvidin sisse/välja</translation>
-<translation id="9065283790526219006">+hüpik</translation>
-<translation id="9077213568694924680">eemaldatakse valikust</translation>
-<translation id="9082874451376019682">Eelmist liugurit ei ole.</translation>
-<translation id="9089864840575085222">Teksti sisestamise kaja tsükkel</translation>
-<translation id="9107530006868467849">Eelmist meediavidinat pole.</translation>
-<translation id="9108370397979208512">matemaatika</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{protsent}other{# protsendimärki}}</translation>
-<translation id="9115913704608474258">November</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Esitab praeguse asukoha lühikirjelduse</translation>
-<translation id="9153606228985488238">Helikõrgus: <ph name="PERCENT" /> protsenti</translation>
-<translation id="9160096769946561184">Mine praeguse veeru lõppu</translation>
-<translation id="9173115498289768110">Helitugevus: <ph name="PERCENT" /> protsenti</translation>
-<translation id="9178973770513562274">Kasutage sirvimiseks üles ja alla nooleklahve või sisestage otsimiseks.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">Järgmist jaotist ei ole.</translation>
-<translation id="930275611743429116">Valimise alustamine või lõpetamine.</translation>
-<translation id="948171205378458592">Vähenda kõne kiirust</translation>
-<translation id="962913030769097253">Järgmine 1. taseme pealkiri</translation>
-<translation id="973955474346881951">Luba/keela püsiv režiim</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb
deleted file mode 100644
index df5aa9a5f54..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="fa">
-<translation id="1012173283529841972">مورد لیست</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">گسترش یافت.</translation>
-<translation id="1025074108959230262">حالت چسبان غیرفعال شد</translation>
-<translation id="1031961866430398710">سپس</translation>
-<translation id="1044777062731150180">بدون عنوان</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">ورودی نامعتبر</translation>
-<translation id="1082209053475788238">عنوان سطح ۶ قبلی وجود ندارد.</translation>
-<translation id="1088219014394087294">عنوانی وجود ندارد.</translation>
-<translation id="1106741348836243114">بازخورد صوتی (نمادهای شنیداری) را روشن یا خاموش کنید.</translation>
-<translation id="1120743664840974483">{«ا»: «اسب»، «ب»: «بازی»، «پ»: «پروین»، «ت»: «ترانه»، «ث»: «ثریا»، «ج»: «جوجه»، «چ»: «چرخ»، «ح»: «حریم»، « خ»:«خصوصی »، « د»: «دفترچه»، «ذ»: «ذلیل»، «ر»: «روز»، «ز»: «زمان»، «ژ»: «ژولیت»، «س»: «سیاست»، «ش»: «شنبه»، «ص»: «صفحه»، «ض»: «ضروری»، «ط»: «طراوت»، «ظ»: «ظهر»، «ع»: «عصر»، « غ»: «غروب»، «ف»: «فروش»، «ق»: «قلب»، «ک»: «کودکان»، «گ»: «گوشی»، «ل»: «لوله»، «م»: «مرز»، «ن»: «نامناسب»، «و»: «ویلا»، «ه»: «هیاهو»، «ی»: «یادآور»}</translation>
-<translation id="113582498867142724">مجموعه <ph name="TAG" /> با <ph name="NUM" /> مورد</translation>
-<translation id="1155043339247954670">مورد لیست بعدی وجود ندارد.</translation>
-<translation id="1157782847298808853">راهنمای صفحه‌کلید</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />، <ph name="NAME" />، کادر ترکیبی</translation>
-<translation id="1167230103353892028"><ph name="NAME" />، مورد منو، با منوی فرعی</translation>
-<translation id="1177863135347784049">سفارشی</translation>
-<translation id="1188858454923323853">تکمیلی</translation>
-<translation id="1206619573307042055">نوشتار متحرک روی صفحه</translation>
-<translation id="1213216066620407844">‏ChromeVox - ارائه صدا به Chrome</translation>
-<translation id="1229276918471378188">پرش قبلی</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">عنوان بعدی سطح ۶</translation>
-<translation id="1275718070701477396">انتخاب شد</translation>
-<translation id="1319608975892113573">نقل قول قبلی موجود نیست.</translation>
-<translation id="1321576897702511272">‏پنهان کردن راهنمای ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> از <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">بازگویی نویسه و کلمه</translation>
-<translation id="1339428534620983148">ستون قبلی جدول</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">راست</translation>
-<translation id="136718599399906424">ردیف بعدی جدول</translation>
-<translation id="1383876407941801731">جستجو</translation>
-<translation id="1385214448885562192">‏enter را برای پذیرش یا escape را برای لغو، پیکان پایین را برای بعدی یا پیکان بالا را برای قبلی فشار دهید.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />، کادر نوشتاری گذرواژه</translation>
-<translation id="1467432559032391204">چپ</translation>
-<translation id="1474557363159888097">کد لنگر قبلی موجود نیست.</translation>
-<translation id="1502086903961450562">گرافیک قبلی</translation>
-<translation id="1506187449813838456">افزایش گام</translation>
-<translation id="151784044608172266">جمله بعدی</translation>
-<translation id="1524531499102321782">خط بعدی بریل</translation>
-<translation id="1546370775711804143">نوار پیمایش</translation>
-<translation id="1559739829547075274">پیمایش به عقب</translation>
-<translation id="1571643229714746283">‏ChromeVox آماده است</translation>
-<translation id="158493514907962286">دسامبر</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">تغییر به بریل ۶ نقطه</translation>
-<translation id="1611168825862729585">عنوان ستون:</translation>
-<translation id="1613476421962910979">نمادهای شنیداری روشن است</translation>
-<translation id="1618597272655350600">شرح کاملی از موقعیت کنونی را اعلام می‌کند</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{علامت بزرگ‌تر}one{# علامت بزرگ‌تر}other{# علامت بزرگ‌تر}}</translation>
-<translation id="1653266918374749391">عنوان قبلی سطح ۳</translation>
-<translation id="1659072772017912254">بررسی نشده</translation>
-<translation id="1669290819662866522">هفته</translation>
-<translation id="1674262202423278359">‏پیمایش ChromeVox</translation>
-<translation id="16777221443363124">نوار منو</translation>
-<translation id="1692077714702418899">خط ساختاری</translation>
-<translation id="1700517974991662022">بازدیدشده</translation>
-<translation id="1722567105086139392">پیوند</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">گرافیک بعدی</translation>
-<translation id="1781173782405573156">کلید عبور</translation>
-<translation id="1787176709638001873">نوشتار ویرایش گذرواژه</translation>
-<translation id="1810107444790159527">کادر لیست</translation>
-<translation id="1828385960365606039">مه</translation>
-<translation id="1834891354138622109">ستون</translation>
-<translation id="1865601187525349519">پایان نوشتار</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">تاریخ و زمان کنونی را بگویید.</translation>
-<translation id="1902396333223336119">سلول</translation>
-<translation id="1905379170753160525">نمایش لیست عناوین</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">‎#ed</translation>
-<translation id="1954623340234317532">کنترل هفته از سال</translation>
-<translation id="1964135212174907577">شیء بعدی</translation>
-<translation id="1969092762068865084">ژوئیه</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">عنوان ردیف:</translation>
-<translation id="2002895034995108595">بازنشانی نقشه کلید کنونی</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{کروشه چپ}one{# کروشه چپ}other{# کروشه چپ}}</translation>
-<translation id="2045490512405922022">بدون علامت</translation>
-<translation id="20601713649439366">هیچ رابطه ریاضی قبلی وجود ندارد.</translation>
-<translation id="207477615537953741">تفسیر معنایی خاموش است</translation>
-<translation id="2086961585857038472">کلمه بعدی</translation>
-<translation id="2089387485033699258">fa</translation>
-<translation id="2091933974477985526">قسمت نوشتاری قابل ویرایش قبلی</translation>
-<translation id="2100350898815792233">همه علائم نگارشی</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">کلید دسترسی: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">با انتخاب گزینه‌ای از لیست زیر، جدول بریل ۶ نقطه‌ای فعلی را تغییر دهید.</translation>
-<translation id="2169714232367507776">کلیک روی مورد کنونی</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{پرانتز بسته}one{# پرانتز بسته}other{# پرانتز بسته}}</translation>
-<translation id="2199994615414171367">عبارت ریاضی قبلی</translation>
-<translation id="2223693656926968778">در خصوص مورد کنونی اقدامی انجام دهید</translation>
-<translation id="225732394367814946">افزایش سرعت گفتار</translation>
-<translation id="2267945578749931355">نویسه بعدی</translation>
-<translation id="2281234842553884450">اسلایدر قبلی</translation>
-<translation id="2318372665160196757">اصلی</translation>
-<translation id="2329324941084714723">پانل برگه</translation>
-<translation id="2344193891939537199">کنترل تاریخ زمان</translation>
-<translation id="2359897517538099099">از حالت جدول استفاده نمی‌کنید.</translation>
-<translation id="241124561063364910">و پس از آن</translation>
-<translation id="2417569100218200841">اطلاعات محتوا</translation>
-<translation id="2422937916923936891">کادر بررسی مورد منو</translation>
-<translation id="2429669115401274487">ب.ظ</translation>
-<translation id="2435413342408885429">‏کلید <ph name="KEY" /> اکنون کلید تغییردهنده جدید ChromeVox است.</translation>
-<translation id="2450814015951372393">کادر انتخاب</translation>
-<translation id="2462626033734746142">گروه دکمه رادیویی</translation>
-<translation id="2471138580042810658">عنوان ۶</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{ستاره}one{# ستاره}other{# ستاره}}</translation>
-<translation id="2549392850788122959">کلید <ph name="KEY" /> بازنشانی شد.</translation>
-<translation id="2553108862507765288">اشتباه دستوری</translation>
-<translation id="257674075312929031">گروه</translation>
-<translation id="2582407057977008361">جدا</translation>
-<translation id="2589102159832527089">‏این صفحه حاوی نوشتاری است که به صورت خودکار از فایل PDF استخراج شده است. &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;برای نسخه اصلی اینجا را کلیک کنید.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">با {COUNT,plural, =1{# مورد}one{# مورد}other{# مورد}}</translation>
-<translation id="2614981083756825552">‏چیدمان ML ریاضی</translation>
-<translation id="2626530649491650971">قابل کلیک</translation>
-<translation id="2628764385451019380">کادر ترکیبی قبلی وجود ندارد.</translation>
-<translation id="2637227747952042642">ریاضی</translation>
-<translation id="2639750663247012216">‏تغییردهنده Chrome Vox</translation>
-<translation id="2644542693584024604">املای اشتباه</translation>
-<translation id="2667291555398229137">روی مورد زیر کلید مسیریابی کلیک کنید</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{پرانتز باز}one{# پرانتز باز}other{# پرانتز باز}}</translation>
-<translation id="2705875883745373140">فشرده نشده</translation>
-<translation id="2706462751667573066">پیکان بالا</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">صدا</translation>
-<translation id="2732718972699418926">ق.ظ</translation>
-<translation id="2749275490991666823">دارای علامت</translation>
-<translation id="27527859628328957">پرش به مورد قابل فوکوس بعدی</translation>
-<translation id="2770781857296573485">به کاوش گروه وارد شوید</translation>
-<translation id="2777845298774924149">خارج شد</translation>
-<translation id="2800204403141299078">هیچ عنصر متفاوت دیگری نیست.</translation>
-<translation id="2800780099804980316">عنوان سطح ۱ قبلی وجود ندارد.</translation>
-<translation id="2811204574343810641">ردیف</translation>
-<translation id="2816654101880605877">اسلایدر بعدی موجود نیست.</translation>
-<translation id="2841013758207633010">زمان</translation>
-<translation id="2843837985843789981">گروه قبلی</translation>
-<translation id="2844995807198708617">منوی زمینه</translation>
-<translation id="2849332794118375855">کادر انتخاب بعدی وجود ندارد.</translation>
-<translation id="2864481629947106776">پیوند قبلی</translation>
-<translation id="2873259058405069099">رفتن به ابتدای جدول</translation>
-<translation id="2894654529758326923">اطلاعات</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{آکولاد چپ}one{# آکولاد چپ}other{# آکولاد چپ}}</translation>
-<translation id="2911433807131383493">‏باز کردن برنامه آموزشی ChromeVox</translation>
-<translation id="2932083475399492303">تعویض نوع خط بین حالت چیدمان یا ساختاری</translation>
-<translation id="2964026537669811554">سرگروه</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{علامت جهش}one{# علامت جهش}other{# علامت جهش}}</translation>
-<translation id="2972078295414139404">پیوند بازدید شده قبلی وجود ندارد.</translation>
-<translation id="2972205263822847197">راهنمای ابزار</translation>
-<translation id="2998131015536248178">نویسه قبلی</translation>
-<translation id="2999559350546931576">کاهش گام</translation>
-<translation id="2999945368667127852">ابزارک رسانه‌ای بعدی دیگری وجود ندارد</translation>
-<translation id="3012414509011670858">بخش قبلی وجود ندارد.</translation>
-<translation id="3030432017085518523">دکمه رادیویی مورد منو</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{آپاستروف}one{# آپاستروف}other{# آپاستروف}}</translation>
-<translation id="3046838483509668188">‏گزینه‌های ChromeVox</translation>
-<translation id="3047143736589213134">نقشه کلید آزمایشی</translation>
-<translation id="3060756054951570867">منوی <ph name="TITLE" /> باز شد</translation>
-<translation id="3078345202707391975">عنوان بعدی سطح ۲</translation>
-<translation id="3078740164268491126">جدول</translation>
-<translation id="3082557070674409251">کلیک شد</translation>
-<translation id="3084806535845658316">فاقد بازگویی تایپ</translation>
-<translation id="3086746722712840547">نت</translation>
-<translation id="308895241372589742">هیچ رابطه ریاضی بعدی وجود ندارد.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">علامت مشخصه بعدی</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">جمع شده</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">نمایش لیست علامت مشخصه‌ها</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">خط بعدی</translation>
-<translation id="3155083529632865074">دکمه قبلی موجود نیست.</translation>
-<translation id="3163593631834463955">عنوان ستون خالی</translation>
-<translation id="316542773973815724">پیمایش</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{فاصله}one{# فاصله}other{# فاصله}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> قرار داده شد</translation>
-<translation id="3223701887221307104"><ph name="NAME" />، برگه</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">پیوند بازدیدشده</translation>
-<translation id="323731244387692321">‏باز کردن راهنمای صفحه‌کلید ChromeVox</translation>
-<translation id="3241052487511142956">پیوند بازدید شده قبلی</translation>
-<translation id="3286390186030710347">اسلایدر</translation>
-<translation id="3299925995433437805">پیوند بازدید شده بعدی وجود ندارد.</translation>
-<translation id="3303384412438961941">‏هر کلیدی را که می‌خواهید برای اطلاع از نام آن فشار دهید. Ctrl+W کاوشگر صفحه‌کلید را می‌بندد.</translation>
-<translation id="3307886118343381874">رفتن به انتهای جدول</translation>
-<translation id="3311969765485641742">‏برای بررسی هشدارها Alt+Shift+A را فشار دهید</translation>
-<translation id="3312997241656799641">پیوند بازدید شده بعدی</translation>
-<translation id="3321460131042519426">فعال کردن «قرارگیری متن در کادر»</translation>
-<translation id="3322936298410871309">عنوان قبلی سطح ۱</translation>
-<translation id="3323447499041942178">کادر متنی</translation>
-<translation id="3353420241558113817">‏{"ar": "عربی",
- "bg": "بلغاری",
- "ca": "کاتالان",
- "cs": "چکی",
- "da": "دانمارکی",
- "de": "آلمانی",
- "de_CH": "آلمان (سوئیس)",
- "de_DE": "آلمانی (آلمان)",
- "el": "یونانی",
- "en": "انگلیسی",
- "en_CA": "انگلیسی (کانادا)",
- "en_GB": "انگلیسی (بریتانیا)",
- "en_US": "انگلیسی (ایالات متحده)",
- "es": "اسپانیایی",
- "et": "استونیایی",
- "fr": "فرانسوی",
- "fr_CA": "فرانسوی (کانادا)",
- "fr_FR": "فرانسوی (فرانسه)",
- "fi": "فنلاندی",
- "he": "عبری",
- "hi": "هندی",
- "hr": "کرواتی",
- "hu": "مجارستانی",
- "is": "ایسلندی",
- "it": "ایتالیایی",
- "ko": "کره‌ای",
- "lt": "لیتوانیایی",
- "lv": "لاتویایی",
- "nb": "بوکمل نروژی",
- "nl": "هلندی",
- "pl": "لهستانی",
- "pt": "پرتغالی",
- "ro": "رومانیایی",
- "ru": "روسی",
- "sk": "اسلواکی",
- "sl": "اسلوونیایی",
- "sr": "صربی",
- "sv": "سوئدی",
- "tr": "ترکی",
- "vi": "ویتنامی",
- "zh": "چینی",
- "zh_TW": "چینی (هان سنتی)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{علامت به اضافه}one{# علامت به اضافه}other{# علامت به اضافه}}</translation>
-<translation id="338583716107319301">جداساز</translation>
-<translation id="3389259863310851658">فیلد قبلی فرم</translation>
-<translation id="3390225400784126843">عنصر متفاوت بعدی.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />، مورد منو</translation>
-<translation id="3406283310380167331">نمایش لیست فرم‌ها</translation>
-<translation id="3422338090358345848">باز کردن کاوشگر صفحه‌کلید</translation>
-<translation id="3457000393508828486">فشردن مختصر</translation>
-<translation id="3462439746547587373"><ph name="NAME" />، دکمه</translation>
-<translation id="3473644018603298796">‏<ph name="COUNT" /> مورد انتخابی</translation>
-<translation id="3486232535569802404"><ph name="V1" /> تا <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{کروشه راست}one{# کروشه راست}other{# کروشه راست}}</translation>
-<translation id="3493915602752813531">مرجع بعدی موجود نیست.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{علامت سؤال}one{# علامت سؤال}other{# علامت سؤال}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{علامت هشتک}one{# علامت هشتک}other{# علامت هشتک}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />، کادر انتخاب انتخاب نشده است</translation>
-<translation id="3599054940393788245">بدون ریاضی داخلی</translation>
-<translation id="3616113530831147358">صوتی</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{نقل قول وارونه}one{# نقل قول وارونه}other{# نقل قول وارونه}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{علامت دلار}one{# علامت دلار}other{# علامت دلار}}</translation>
-<translation id="3659787053479271466">هشدار</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />، کادر لیست</translation>
-<translation id="3687295507293856493">حدس در مورد عنوان ستون سلول کنونی</translation>
-<translation id="3692274950075847560">ج: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">کنترل گفتگو</translation>
-<translation id="3716845769494773620">چند خطی</translation>
-<translation id="3731746171184829332">عنوان قبلی وجود ندارد.</translation>
-<translation id="3762198587642264450">رفتن به انتهای ردیف کنونی</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">از گفتگو خارج شد.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">لیست تکمیل خودکار</translation>
-<translation id="3810838688059735925">فیلم</translation>
-<translation id="3816633764618089385">رسانه بعدی</translation>
-<translation id="3819376190738087562">پرشی وجود ندارد.</translation>
-<translation id="385383972552776628">باز کردن صفحه گزینه‌ها</translation>
-<translation id="3856075812838139784">فقط خوانده شده</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">منو</translation>
-<translation id="3909320334364316587">عنوان قبلی سطح ۶</translation>
-<translation id="3914173277599553213">ضروری</translation>
-<translation id="3962990492275676168">شروع به خواندن از محل کنونی</translation>
-<translation id="4004802134384979325">علامت‌دار</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">کنترل ماه</translation>
-<translation id="4039983576244166038">عنوان ردیف خالی است</translation>
-<translation id="4042843249978639960">عنوان سطح ۲ بعدی وجود ندارد.</translation>
-<translation id="4043348641337972076">‏علامت مشخصه ARIA قبلی وجود ندارد.</translation>
-<translation id="4047216625641135770">علامت</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{علامت مد}one{# علامت مد}other{# علامت مد}}</translation>
-<translation id="409334809956508737">شیء قبلی</translation>
-<translation id="4099274309791143834">دارای منوی فرعی</translation>
-<translation id="4107807507418787238">سلولی در زیر وجود ندارد.</translation>
-<translation id="4116415223832267137">هشدار</translation>
-<translation id="4147126331795725888">کنترل بعدی وجود ندارد.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{آکولاد راست}one{# پرانتز راست}other{# آکولاد راست}}</translation>
-<translation id="4158704014418536539">حساس به حروف کوچک و بزرگ.</translation>
-<translation id="4161663686871496107">‏بازخورد گفتاری ChromeVox آماده است</translation>
-<translation id="4173994908659439270">فیلد نوشتاری قابل ویرایش بعدی وجود ندارد.</translation>
-<translation id="4176463684765177261">غیرفعال شد</translation>
-<translation id="4188530942454211480">جمله قبلی</translation>
-<translation id="4202186506458631436">حرکت به راست</translation>
-<translation id="4206289001967551965">داخل جدول</translation>
-<translation id="4215733775853809057">اسلایدر بعدی</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{خط تیره}one{# خط تیره}other{# خط تیره}}</translation>
-<translation id="421884353938374759">انتخابگر رنگ</translation>
-<translation id="4229646983878045487">زمان تاریخ</translation>
-<translation id="423334822609210999">سلولی در سمت چپ وجود ندارد.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />، درجه <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">یادداشت</translation>
-<translation id="4254798249533888099">درخت</translation>
-<translation id="4255943572433203166">‏از گزینه‌های زیر برای سفارشی کردن ChromeVox استفاده کنید. تغییرات بلافاصله اعمال می‌شوند.</translation>
-<translation id="4271220233568730077">عبارت ریاضی بعدی</translation>
-<translation id="4271521365602459209">نتیجه دیگری موجود نیست.</translation>
-<translation id="4287520460805643128">مقاله بعدی وجود ندارد.</translation>
-<translation id="4289540628985791613">مرور کلی</translation>
-<translation id="4300318234632215983">اعلان نشانی وب پشت یک پیوند</translation>
-<translation id="4301352596632316575">منوی فرعی دارد</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{نقطه}=3{سه نقطه}one{# نقطه}other{# نقطه}}</translation>
-<translation id="4347461890115250064">لیست بعدی موجود نیست.</translation>
-<translation id="4367650418938037324">‏برگ ML ریاضی</translation>
-<translation id="4372435075475052704">حداقل: <ph name="X" /></translation>
-<translation id="4372705107434148843">توقف گفتار</translation>
-<translation id="4373197658375206385">مورد قبلی که پیوند نباشد وجود ندارد.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">بازنشانی</translation>
-<translation id="4471074325120394300">پیوندی موجود نیست.</translation>
-<translation id="4476183483923481720">خط جدید</translation>
-<translation id="4482330759234983253">جدول قبلی</translation>
-<translation id="4491109536499578614">تصویر</translation>
-<translation id="4529987814483543472">نقشه کلید کلاسیک</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{ممیز}one{# ممیز}other{# ممیز}}</translation>
-<translation id="4547556996012970016">عنوان بعدی سطح ۵</translation>
-<translation id="4562381607973973258">Header</translation>
-<translation id="4591507479202817876">، انتخاب شد</translation>
-<translation id="4597532268155981612">فرم</translation>
-<translation id="4597896406374528575">آوریل</translation>
-<translation id="4615592953348396470">نادیده گرفتن فشار دکمه بعدی</translation>
-<translation id="461613135510474570">جمله</translation>
-<translation id="4647836961514597010">انتخابگر رنگ</translation>
-<translation id="4661075872484491155">درخت</translation>
-<translation id="4668929960204016307">،</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">علامت مشخصه قبلی</translation>
-<translation id="4696413482802371445">عنوان سطح ۵ بعدی وجود ندارد.</translation>
-<translation id="4729095194763193578">ردیف جدول قبلی</translation>
-<translation id="4736221692378411923">اوت</translation>
-<translation id="4740661827607246557">فرمان‌های راهنما</translation>
-<translation id="4759716709594980008">‏کاوشگر صفحه‌کلید ChromeOS</translation>
-<translation id="4763296182459741068">جمع کردن به پایین</translation>
-<translation id="4763480195061959176">ویدیو</translation>
-<translation id="479989351350248267">جستجو</translation>
-<translation id="481165870889056555">اعلام عنوان صفحه کنونی</translation>
-<translation id="4826415162591436065">پیمایش به جلو</translation>
-<translation id="4826604887384865800">پرش بعدی</translation>
-<translation id="4827410568042294688">انتخاب لغو شد</translation>
-<translation id="4842108708071771135">نقل قول بعدی موجود نیست.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">عنصر مشابه قبلی.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">‏فعال کردن گزارش‌گیری TTS</translation>
-<translation id="4877261390094455813">یک عبارت جستجو را وارد کنید.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">پیوند داخلی</translation>
-<translation id="4953585991029886728">ویرایش نوشتار</translation>
-<translation id="4954534434583049121">نقل قول طولانی قبلی</translation>
-<translation id="4973717656530883744">حداقل <ph name="X" /></translation>
-<translation id="4973762002207131920">به کلید <ph name="KEY" /> تغییر داده شد.</translation>
-<translation id="4975416682604111799">میلی‌ثانیه</translation>
-<translation id="49787999531187221">‏ChromeVox اکنون غیرفعال است.</translation>
-<translation id="4979404613699303341">دکمه قبلی</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />، <ph name="NAME" />، کادر لیست</translation>
-<translation id="4983588134362688868">رفتن به بالای صفحه</translation>
-<translation id="4986606102545753256"><ph name="NAME" />، پنجره</translation>
-<translation id="4993152509206108683">نرخ <ph name="PERCENT" /> درصد</translation>
-<translation id="4996716799442435517">دیداری</translation>
-<translation id="4997282455736854877"><ph name="NAME" />، دکمه رادیویی انتخاب شد</translation>
-<translation id="4997475792277222884">مورد بعدی که پیوند نباشد وجود ندارد.</translation>
-<translation id="5000760171916499057">فرمی موجود نیست.</translation>
-<translation id="5005670136041063723">هیچ عنصر مشابه دیگری نیست.</translation>
-<translation id="501473567976723023">ژانویه</translation>
-<translation id="5041394372352067729">انتقال صفحه‌نمایش بریل به بالای صفحه</translation>
-<translation id="5042770794184672516">افزایش میزان صدای گفتار</translation>
-<translation id="5050015258024679800">عنوان قبلی سطح ۴</translation>
-<translation id="5054047268577924192">مورد قبلی لیست</translation>
-<translation id="5078661581131202757">انتخاب فایل</translation>
-<translation id="5080758118274074384">دوبار کلیک شد</translation>
-<translation id="5098541983634824365">خروج از حالت جدولی.</translation>
-<translation id="5102981729317424850">نوار ابزار</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">فیلد فرم قبلی وجود ندارد.</translation>
-<translation id="5111640677200759579">عنوان ستون</translation>
-<translation id="5117636609870536415">‎@ed</translation>
-<translation id="5136967254288895616">پیوند قبلی موجود نیست.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">، از حالت انتخاب خارج شد</translation>
-<translation id="5183440668879371625">خط قبلی بریل</translation>
-<translation id="5184944171021383281">فیلد بعدی فرم وجود ندارد.</translation>
-<translation id="5189244881767082992">خط</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> قبلاً به یک دستور اختصاص داده شده است.</translation>
-<translation id="5205493599117157272">لیست <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">دکمه رادیویی بعدی موجود نیست.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">پایان</translation>
-<translation id="5291783959063340370">شیء</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />، برگه</translation>
-<translation id="5310788376443009632">حذف شد:</translation>
-<translation id="5320727453979144100">حالت چسبان فعال شد</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{کاما}one{# کاما}other{# کاما}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />، کادر نوشتاری</translation>
-<translation id="5330443287809544590"><ph name="NAME" />، پیوند</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">در حین مطالعه متوالی، به عقب بروید</translation>
-<translation id="5368000168321181111">نمادهای شنیداری خاموش است</translation>
-<translation id="5374320867641260420">دکمه بعدی موجود نیست.</translation>
-<translation id="5382299583965267720">عنوان سطح 1 بعدی وجود ندارد.</translation>
-<translation id="5402367795255837559">بریل</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{نقطه ویرگول}one{# نقطه ویرگول}other{# نقطه ویرگول}}</translation>
-<translation id="5411891038905756502">هیچ نقطه پرش قبلی وجود ندارد.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{علامت کوچک‌تر}one{# علامت کوچک‌تر}other{# علامت کوچک‌تر}}</translation>
-<translation id="5455441614648621694">مکمل</translation>
-<translation id="5485036206801896268">گرافیک قبلی وجود ندارد.</translation>
-<translation id="5486947920110100234">نقطه پرش بعدی وجود ندارد.</translation>
-<translation id="549602578321198708">کلمه</translation>
-<translation id="5500932716852106146">فیلد نوشتاری قابل ویرایش قبلی موجود نیست.</translation>
-<translation id="5502713021410870035">سپتامبر</translation>
-<translation id="5507663321906818013">معیار اشکال‌زدایی</translation>
-<translation id="5518443085409638729">‏هنگام ویرایش نوشتار، مکان‌نما را بین نویسه‌ها قرار دهید (مانند Mac OS X).</translation>
-<translation id="552195134157544755">دکمه رادیویی</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">عنوان سطح ۵ قبلی وجود ندارد.</translation>
-<translation id="556042886152191864">دکمه</translation>
-<translation id="5561345396546889625">لیست بعدی</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">ویرایش نوشتار، ورودی ایمیل</translation>
-<translation id="5597170376237141345">کادر انتخاب بعدی</translation>
-<translation id="5597933780944041114">عنوان نوشتار موجود نیست.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />، دکمه رادیویی انتخاب نشد</translation>
-<translation id="5601172225407283979">انجام عملکرد پیش‌فرض</translation>
-<translation id="5608798115546226984">تکمیل خودکار درون برنامه</translation>
-<translation id="561939826962581046">زمان</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">گزارش</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">جدول قبلی موجود نیست.</translation>
-<translation id="5655682562155942719">پرش از فرمان‌ها</translation>
-<translation id="56637627897541303">قسمت نوشتاری</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">علامت مشخصه</translation>
-<translation id="5683155931978483559">کادر انتخاب قبلی</translation>
-<translation id="5684277895745049190">لیست</translation>
-<translation id="5700650669149824506">عنوان سطح ۴ قبلی وجود ندارد.</translation>
-<translation id="5709192780268610569">بدون شرح طولانی</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">ستون بعدی جدول</translation>
-<translation id="571866080859340309">کاوش در گروه‌ها</translation>
-<translation id="5728409797179002635">جدولی یافت نشد.</translation>
-<translation id="5748623122140342504">عنوان قبلی سطح ۵</translation>
-<translation id="5750633686117194034">‏کلید تغییردهنده‌ای فشار داده نشده است؛ لطفاً یک یا چند کلید تغییردهنده را فشار دهید و نگهدارید؛ پس از انجام این کار انگشتان خود را بردارید تا صدای تنظیم کلیدها را بشنوید. برای خروج روی Tab بزنید.</translation>
-<translation id="5788275253279308023">برگه پنجره ناشناس <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">‏بهبود تجربه سایت‌هایی خاص (مانند جستجوی Google).</translation>
-<translation id="5819072574982403430">مورد درختی</translation>
-<translation id="5826479389509458994">ردیف <ph name="ROW" /> ستون <ph name="COL" /></translation>
-<translation id="5850707923114094062">حرکت به عقب</translation>
-<translation id="5851548754964597211">لیست برگه</translation>
-<translation id="5859752971144398932">از «یافتن در صفحه» خارج شد.</translation>
-<translation id="5866042630553435010">علامت‌گذاری نیمه</translation>
-<translation id="5869546221129391014">جدولی</translation>
-<translation id="5876817486144482042">کاهش میزان صدای گفتار</translation>
-<translation id="5887397643266327462">زیرنویس بریل فعال شد.</translation>
-<translation id="5891934789323004067">جدول</translation>
-<translation id="5919442531159595654">کپی.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{علامت مساوی}one{# علامت مساوی}other{# علامت مساوی}}</translation>
-<translation id="5939518447894949180">بازنشانی</translation>
-<translation id="5948123859135882163">جابه‌جایی بین تفسیر ساختاری و معنایی عبارات ریاضی</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">گفتگو</translation>
-<translation id="5963413905009737549">بخش</translation>
-<translation id="5968607524793740041">نمایش منوی بافت</translation>
-<translation id="5983179082906765664">افزایش جزئیات پیمایش</translation>
-<translation id="5999630716831179808">صداها</translation>
-<translation id="6000417740266304866">با انتخاب گزینه‌ای از لیست زیر، جدول بریل ۸ نقطه‌ای فعلی را تغییر دهید.</translation>
-<translation id="6006050241733874051">فرم</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{اریب وارو}one{# اریب وارو}other{# اریب وارو}}</translation>
-<translation id="6037602951055904232">حرکت به جلو</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">پایان سلول.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">فضا</translation>
-<translation id="6142308968191113180">عنوان ۴</translation>
-<translation id="6169420925157477918">تصویر با شرح طولانی</translation>
-<translation id="6172087735260766220">‏دسترسی به نوشتار قابل‌دسترسی از PDF محافظت‌شده در برابر کپی امکان‌پذیر نیست.</translation>
-<translation id="6186305613600865047">رفتن به پایین صفحه</translation>
-<translation id="6193330012414963395">ق.ظ/ب.ظ</translation>
-<translation id="622484624075952240">پیکان پایین</translation>
-<translation id="6236061028292614533">عنوان بعدی</translation>
-<translation id="6254901459154107917">فیلد نوشتاری قابل ویرایش بعدی</translation>
-<translation id="6259464875943891919">از <ph name="TYPE" /> خارج شدید.</translation>
-<translation id="6281876499889881039">عنصر مشابه بعدی.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">کادر ترکیبی بعدی وجود ندارد.</translation>
-<translation id="6307969636681130414">فشرده شده</translation>
-<translation id="6324551002951139333">اشتباه دستوری شناسایی شد</translation>
-<translation id="6348657800373377022">کادر ترکیبی</translation>
-<translation id="6355910664415701303">مورد قبلی لیست وجود ندارد.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">عنوان قبلی</translation>
-<translation id="6387719785439924554">جدا</translation>
-<translation id="6411426777058107714">دکمه رادیویی قبلی وجود ندارد.</translation>
-<translation id="6414968628640960377">عنصر متفاوت قبلی.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{دونقطه}one{# دونقطه}other{# دونقطه}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />، منو</translation>
-<translation id="6444046323172968959">گفتگوی هشدار</translation>
-<translation id="6459511626086141404">نقشه کلید مسطح</translation>
-<translation id="6468049171101508116">دکمه بعدی</translation>
-<translation id="6491972999578897419">صدای کنونی را با انتخاب یک گزینه از لیست زیر تغییر دهید.</translation>
-<translation id="6508059270146105198">انتقال صفحه‌نمایش بریل به پایین صفحه</translation>
-<translation id="6536864053412760904">‏کد ML ریاضی</translation>
-<translation id="6550720799683018100">نقشه کلید کنونی را با انتخاب یک گزینه از لیست زیر تغییر دهید.</translation>
-<translation id="6561818612645211875">رفتن به شروع ردیف کنونی</translation>
-<translation id="6587021927234520429">عنوان سطح ۴ بعدی وجود ندارد.</translation>
-<translation id="6601344353291556895">توضیحات طولانی را فعال کنید.</translation>
-<translation id="6615602925644411249">یافتن در صفحه.</translation>
-<translation id="6633350132811819843">جدول بعدی موجود نیست.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">نوار پیشرفت</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">سند</translation>
-<translation id="6697092096875747123">کادر ترکیبی قبلی</translation>
-<translation id="6714813999819678458">عنوان قبلی سطح ۲</translation>
-<translation id="6716505898850596801">کلیدهای تغییردهنده</translation>
-<translation id="671916444866103745">‏علامت مشخصه ARIA بعدی وجود ندارد.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />، کادر ترکیبی</translation>
-<translation id="6735257939857578167">با <ph name="NUM" /> مورد</translation>
-<translation id="6736510033526053669">برگه ایجاد شد</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">مقاله</translation>
-<translation id="6787839852456839824">میان‌برهای صفحه‌کلید</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">پاورقی</translation>
-<translation id="6871161210040114857">بزرگی و کوچکی حروف نادیده گرفته شود.</translation>
-<translation id="6877435256196695200">گرافیک بعدی موجود نیست.</translation>
-<translation id="6897341342232909480">حرکت به چپ</translation>
-<translation id="6901540140423170855">تاریخ</translation>
-<translation id="6910211073230771657">حذف شد</translation>
-<translation id="6911965441508464308">سلولی در بالا وجود ندارد.</translation>
-<translation id="6919104639734799681">نمایش لیست جدول‌ها</translation>
-<translation id="6964088412282673743">کنترل قبلی وجود ندارد.</translation>
-<translation id="6996566555547746822">کادر ترکیبی بعدی</translation>
-<translation id="7005146664810010831">نشانی وب پیدا نشد</translation>
-<translation id="7010712454773919705">‏کلید تغییردهنده ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">لیست قبلی</translation>
-<translation id="7041173719775863268">پایان انتخاب</translation>
-<translation id="7095834689119144465">فقط ویرایش عددی نوشتار</translation>
-<translation id="7096001299300236431">رسانه قبلی</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">بازگویی کلمه</translation>
-<translation id="713824876195128146">نقل قول طولانی بعدی</translation>
-<translation id="7161771961008409533">دکمه بازشو</translation>
-<translation id="7167657087543110">بازگویی نویسه</translation>
-<translation id="7170733337935166589">در حین مطالعه متوالی، به جلو بروید</translation>
-<translation id="7181697990050180700">میان‌برهای صفحه‌کلید را برای فرمان‌هایی که اغلب استفاده می‌شوند با تایپ کردن آنها در قسمت‌های مربوطه در زیر سفارشی کنید.</translation>
-<translation id="7203150201908454328">باز شده</translation>
-<translation id="7210211103303402262">دقیقه</translation>
-<translation id="7217912842225915592">‎+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">خط</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">عنوان</translation>
-<translation id="7241683698754534149">باز کردن شرح طولانی در یک برگه جدید</translation>
-<translation id="7248671827512403053">برنامه کاربردی</translation>
-<translation id="725969808843520477">دکمه رادیویی بعدی</translation>
-<translation id="7269119382257320590">فاقد علائم نگارشی</translation>
-<translation id="7273174640290488576">خالی</translation>
-<translation id="7285387653379749618">جدول‌ها</translation>
-<translation id="7289186959554153431">عنوان ۳</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">زیرنویس بریل غیرفعال شد.</translation>
-<translation id="7318872822751139669">برای تغییر فوکوس، از موشواره استفاده کنید.</translation>
-<translation id="7322388933135261569">فوریه</translation>
-<translation id="7332592614823088566">ردیف <ph name="ROWINDEX" /> از <ph name="ROWTOTAL" />، ستون<ph name="COLINDEX" /> از <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">پنجره بازشو دارد</translation>
-<translation id="7356165926712028380">تغییر به بریل ۸ نقطه‌ای</translation>
-<translation id="7362871137496673139">عنوان سطح ۲ قبلی وجود ندارد.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{امپرسند}one{# امپرسند}other{# امپرسند}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">در حال خروج از جدول.</translation>
-<translation id="739763518212184081">خط قبلی</translation>
-<translation id="7400575256015741911">غلط املایی شناسایی شد</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">بازگشت</translation>
-<translation id="7434509671034404296">برنامه‌نویس</translation>
-<translation id="7439060726180460871">فهرست راهنما</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">برگه</translation>
-<translation id="7492049978501397201">گفتگو وارد شد</translation>
-<translation id="7532613204005497612">ژوئن</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />، <ph name="NAME" />، اسلایدر</translation>
-<translation id="7586163296341959563">جای‌گذاری.</translation>
-<translation id="7596919493010894443">موارد انتخابی پاک شد</translation>
-<translation id="7604026522577407655">رفتن به ابتدای ستون کنونی</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">‏اعلام URL صفحه کنونی</translation>
-<translation id="7609363189280667021">تغییر توصیف‌های بریل</translation>
-<translation id="762020119231868829">همه ابزارک‌های رسانه ىر حال پخش را موقتاً متوقف می‌کند</translation>
-<translation id="7625690649919402823">جدول بعدی</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />)، درجه <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">عنوان سطح ۳ قبلی وجود ندارد.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />، <ph name="NAME" />، کادر نوشتار</translation>
-<translation id="7663318257180412551">عنوان ۲</translation>
-<translation id="7674576868851035240">پیوند بعدی</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">ویرایش نوشتار، ورودی نشانی وب</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">دکمه رادیویی قبلی</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />، <ph name="NAME" />، کادر نوشتار گذرواژه</translation>
-<translation id="7805247615045262757">پیمایش پیش‌فرض</translation>
-<translation id="7805768142964895445">وضعیت</translation>
-<translation id="7810781339813764006">گروه بعدی</translation>
-<translation id="7819187121850078213">برگه <ph name="TITLE" /> پنجره</translation>
-<translation id="7828956995407538686">اکتبر</translation>
-<translation id="7839679365527550018">کلمه قبلی</translation>
-<translation id="7851816175263618915">برخی از علائم نگارشی</translation>
-<translation id="7870596830398826354">‏درخت ML ریاضی</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">‏روشن و خاموش کردن ChromeVox کلاسیک.</translation>
-<translation id="7895896691902835279">پیوند ناشناخته</translation>
-<translation id="7927711904086083099">انتخاب نشده</translation>
-<translation id="7935627501098484003">کنترل زمان</translation>
-<translation id="7939428177581522200">به موارد انتخابی اضافه شد</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{علامت @}one{# علامت @}other{# علامت @}}</translation>
-<translation id="7965147473449754028">منو بسته شد</translation>
-<translation id="7974390230414479278">مورد منو</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{علامت تعجب}one{# علامت تعجب}other{# علامت تعجب}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{نقل قول}one{# نقل قول}other{# نقل قول}}</translation>
-<translation id="8033827949643255796">انتخاب شد</translation>
-<translation id="8035962149453661158">حداکثر:<ph name="X" /></translation>
-<translation id="8042761080832772327">ویرایش نوشتار، ورودی جستجو</translation>
-<translation id="8049189770492311300">تایمر</translation>
-<translation id="8065607967589909823">مورد انتخابی عبارتست از</translation>
-<translation id="8066678206530322333">بنر</translation>
-<translation id="8110647606445335195">‏علامت مشخصه ARIA موجود نیست.</translation>
-<translation id="8153880621934657047">خارج از جدول</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{زیرخط}one{# زیرخط}other{# زیرخط}}</translation>
-<translation id="8179976553408161302">ورود</translation>
-<translation id="81960742267269908">برش.</translation>
-<translation id="8199231515320852133">اعلان عناوین سلول کنونی</translation>
-<translation id="820417203470636242">سلول خالی است.</translation>
-<translation id="8215202828671303819">چند انتخاب</translation>
-<translation id="8276439074553447000">پرش به مورد قابل فوکوس قبلی</translation>
-<translation id="8278417001922463147">مقاله قبلی وجود ندارد.</translation>
-<translation id="8283603667300770666">فیلد بعدی فرم</translation>
-<translation id="831207808878314375">تعریف</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">ساعت</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{پوند}one{# علامت پوند}other{# علامت پوند}}</translation>
-<translation id="8374154622594089836">ماه</translation>
-<translation id="8378855320830505539">منطقه</translation>
-<translation id="8382679411218029383">تکمیل خودکار درون خطی و لیست</translation>
-<translation id="8428603554127842284">سطح <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">عنوان سطح ۳ بعدی وجود ندارد.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">کادر انتخاب قبلی وجود ندارد.</translation>
-<translation id="8455868257606149352">حداکثر <ph name="X" /></translation>
-<translation id="84575901236241018">کلید دسترسی دارد، <ph name="KEY" /></translation>
-<translation id="8503360654911991865">کاهش جزئیات پیمایش</translation>
-<translation id="8520472399088452386">دکمه چرخش</translation>
-<translation id="8538744478902126321">حدس در مورد عنوان ردیف سلول کنونی</translation>
-<translation id="8540054775867439484">جمع کردن به بالا</translation>
-<translation id="8548973727659841685">نویسه</translation>
-<translation id="8561322612995434619">پنجره بازشو دارد</translation>
-<translation id="8571096049907249734">چندانتخاب</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">مورد لیست بعدی</translation>
-<translation id="860150890330522909">کادر تأیید <ph name="NAME" /> علامت‌گذاری شد</translation>
-<translation id="8606621670302093223">کنترل تاریخ</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> مورد انتخاب شده</translation>
-<translation id="8638532244051952400">اعلام مختصات سلول کنونی</translation>
-<translation id="8650576015643545550">لیست قبلی موجود نیست.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">نمایش لیست پیوندها</translation>
-<translation id="8664519043722036194">ثانیه</translation>
-<translation id="867187640362843212">عنوان ۵</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{میله}one{# میله عمودی}other{# میله عمودی}}</translation>
-<translation id="8735450637152821465">شروع انتخاب</translation>
-<translation id="8743786158317878347">ورود به محتوای سازمان یافته، مانند جداول</translation>
-<translation id="8747966237988593539">لیست سفارش داده شده</translation>
-<translation id="8759334257841767240">پیوند بعدی موجود نیست.</translation>
-<translation id="8767968232364267681">عنوان بعدی سطح ۴</translation>
-<translation id="8770473310765924354">خروج از محتوای سازمان یافته، مانند جداول</translation>
-<translation id="8791025954632646584">تفسیر معنایی روشن است</translation>
-<translation id="8796411681063377102">عنوان بعدی سطح ۳</translation>
-<translation id="8808582214901541005">مارس</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">اصلی</translation>
-<translation id="8856538297388979332">‏برای بررسی نظرات، کلیدهای بالا یا پایین را فشار دهید یا برای فعال کردن enter را فشار دهید</translation>
-<translation id="8864099967139188018">عنوان سطح ۶ بعدی وجود ندارد.</translation>
-<translation id="8882002077197914455">عنوان ردیف</translation>
-<translation id="8896347895970027998">‏ChromeVox را فعال یا غیرفعال کنید.</translation>
-<translation id="8898516272131543774">بازگویی علائم نگارشی حلقه</translation>
-<translation id="8900148057318340779">کلید پیشوند</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">عنوان‌های خالی</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">کلیدهای تغییردهنده</translation>
-<translation id="8943175951035496220">سلولی در راست موجود نیست.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">فایل</translation>
-<translation id="9027462562263121875">جدولی وجود ندارد.</translation>
-<translation id="9040132695316389094">عنوان ۱</translation>
-<translation id="9043969572162476692"><ph name="NUM" />٪</translation>
-<translation id="9061915073547935367">جابجایی ابزارک جستجو</translation>
-<translation id="9065283790526219006">+پنجره بازشو</translation>
-<translation id="9077213568694924680">از قسمت انتخابی حذف شد</translation>
-<translation id="9082874451376019682">اسلایدر قبلی موجود نیست.</translation>
-<translation id="9089864840575085222">بازگویی تایپ حلقه</translation>
-<translation id="9107530006868467849">ابزارک رسانه‌ای قبلی دیگری وجود ندارد.</translation>
-<translation id="9108370397979208512">حساب</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{علامت درصد}one{# علامت درصد}other{# علامت درصد}}</translation>
-<translation id="9115913704608474258">نوامبر</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">شرح مختصری از موقعیت کنونی را اعلام می‌کند</translation>
-<translation id="9153606228985488238">گام <ph name="PERCENT" /> درصد</translation>
-<translation id="9160096769946561184">رفتن به انتهای ستون کنونی</translation>
-<translation id="9173115498289768110">میزان صدا <ph name="PERCENT" /> درصد</translation>
-<translation id="9178973770513562274">از کلیدهای پیکان بالا و پایین برای مرور استفاده کنید یا برای جستجو تایپ کنید.</translation>
-<translation id="9192904702577636854">نوشتار متحرک روی صفحه</translation>
-<translation id="9212322457209634662">بخش بعدی وجود ندارد.</translation>
-<translation id="930275611743429116">شروع یا پایان انتخاب.</translation>
-<translation id="948171205378458592">کاهش سرعت گفتار</translation>
-<translation id="962913030769097253">عنوان بعدی سطح ۱</translation>
-<translation id="973955474346881951">فعال/غیرفعال کردن حالت چسبنده</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fi.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fi.xtb
deleted file mode 100644
index 381e29c7635..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fi.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="fi">
-<translation id="1012173283529841972">Luettelokohde</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Kohdistettu.</translation>
-<translation id="1025074108959230262">Kiinnitetty tila pois käytöstä</translation>
-<translation id="1031961866430398710">sitten</translation>
-<translation id="1044777062731150180">Ei otsikoita</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Virheellinen syöte</translation>
-<translation id="1082209053475788238">Ei edellisiä tason 6 otsikoita.</translation>
-<translation id="1088219014394087294">Ei otsikoita.</translation>
-<translation id="1106741348836243114">Ota äänipalaute (earcon-äänimerkit) käyttöön tai poista se käytöstä.</translation>
-<translation id="1120743664840974483">{"a": "aarne", "b": "bertta", "c": "celcius", "d": "daavid", "e": "eemeli", "f": "faarao", "g": "gideon", "h": "heikki", "i": "iivari", "j": "jussi","k": "kalle", "l": "lauri", "m": "matti", "n": "niilo", "o": "otto","p": "paavo", "q": "kuu", "r": "risto", "s": "sakari", "t": "tyyne", "u": "urho", "v": "vihtori", "w": "wiski","x": "äksä", "y": "yrjö", "z": "tseta", "å": "åke", "ä": "äiti", "ö": "öljy"}</translation>
-<translation id="113582498867142724"><ph name="TAG" />-kokoelma, jossa <ph name="NUM" /> kohdetta</translation>
-<translation id="1155043339247954670">Ei seuraavia luettelokohteita.</translation>
-<translation id="1157782847298808853">Näppäimistöohje</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, yhdistelmäruutu</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, valikkokohde, jossa alivalikko</translation>
-<translation id="1177863135347784049">Muokattu</translation>
-<translation id="1188858454923323853">täydentävä</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – Chromen ääni</translation>
-<translation id="1229276918471378188">Edellinen siirtyminen</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Seuraava tason 6 otsikko</translation>
-<translation id="1275718070701477396">Valittu</translation>
-<translation id="1319608975892113573">Ei edellisiä lainauksia.</translation>
-<translation id="1321576897702511272">Piilota ChromeVox-ohje</translation>
-<translation id="1331702245475014624"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">merkkien ja sanojen puhuminen</translation>
-<translation id="1339428534620983148">Taulukon edellinen sarake</translation>
-<translation id="1342835525016946179">artikkeli</translation>
-<translation id="1346748346194534595">Oikealle</translation>
-<translation id="136718599399906424">Taulukon seuraava rivi</translation>
-<translation id="1383876407941801731">Haku</translation>
-<translation id="1385214448885562192">Hyväksy painamalla enter-painiketta tai peruuta esc-painikkeella, siirry seuraavaan alanuolella ja edelliseen ylänuolella.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">alue</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, salasanan tekstikenttä</translation>
-<translation id="1467432559032391204">Vasemmalle</translation>
-<translation id="1474557363159888097">Ei edellisiä ankkureita.</translation>
-<translation id="1502086903961450562">Edellinen grafiikka</translation>
-<translation id="1506187449813838456">Lisää äänenkorkeutta</translation>
-<translation id="151784044608172266">Seuraava lause</translation>
-<translation id="1524531499102321782">Pistekirjoituksen seuraava rivi</translation>
-<translation id="1546370775711804143">Vierityspalkki</translation>
-<translation id="1559739829547075274">Siirry taaksepäin</translation>
-<translation id="1571643229714746283">ChromeVox on valmis</translation>
-<translation id="158493514907962286">joulukuu</translation>
-<translation id="1594072653727561613">val.</translation>
-<translation id="1610130962244179598">Vaihda 6 pisteen pistekirjoitukseen</translation>
-<translation id="1611168825862729585">Sarakkeen otsikko:</translation>
-<translation id="1613476421962910979">Earcon-äänimerkit käytössä</translation>
-<translation id="1618597272655350600">Ilmoittaa nykyisen aseman täydellisen kuvauksen.</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{suuremmuus}other{# suuremmuusmerkkiä}}</translation>
-<translation id="1653266918374749391">Edellinen tason 3 otsikko</translation>
-<translation id="1659072772017912254">Ei valittu</translation>
-<translation id="1669290819662866522">viikko</translation>
-<translation id="1674262202423278359">ChromeVox-navigointi</translation>
-<translation id="16777221443363124">Valikkopalkki</translation>
-<translation id="1692077714702418899">rakenteellinen linja</translation>
-<translation id="1700517974991662022">Käyty</translation>
-<translation id="1722567105086139392">Linkki</translation>
-<translation id="1727806147743597030">footer</translation>
-<translation id="174268867904053074">Seuraava grafiikka</translation>
-<translation id="1781173782405573156">Ohitusnäppäin</translation>
-<translation id="1787176709638001873">Salasanan muokkausteksti</translation>
-<translation id="1810107444790159527">Luetteloruutu</translation>
-<translation id="1828385960365606039">touko</translation>
-<translation id="1834891354138622109">Sarake</translation>
-<translation id="1865601187525349519">Tekstin loppu</translation>
-<translation id="1876229593313240038">dok.</translation>
-<translation id="188130072164734898">Sano tämänhetkinen aika ja päivämäärä.</translation>
-<translation id="1902396333223336119">Matkapuhelin</translation>
-<translation id="1905379170753160525">Näytä otsikoiden luettelo</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Vuoden viikon hallinta</translation>
-<translation id="1964135212174907577">Seuraava objekti</translation>
-<translation id="1969092762068865084">heinäkuu</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Rivin otsikko:</translation>
-<translation id="2002895034995108595">Nollaa nykyinen näppäinkartta</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{vasen hakasulje}other{# vasenta hakasuljetta}}</translation>
-<translation id="2045490512405922022">ei tarkistettu</translation>
-<translation id="20601713649439366">Ei edeltävää matemaattista lauseketta.</translation>
-<translation id="207477615537953741">Semanttinen on pois käytöstä</translation>
-<translation id="2086961585857038472">Seuraava sana</translation>
-<translation id="2089387485033699258">fi</translation>
-<translation id="2091933974477985526">Edellinen muokattava tekstialue</translation>
-<translation id="2100350898815792233">Kaikki välimerkit</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">pääsyavain: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Muuta nykyistä kuuden pisteen pistekirjoitustaulukkoa valitsemalla vaihtoehto alla olevasta luettelosta.</translation>
-<translation id="2169714232367507776">Klikkaa nykyistä kohdetta</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{oikea kaarisulje}other{# oikeaa kaarisuljetta}}</translation>
-<translation id="2199994615414171367">Edellinen matemaattinen lauseke</translation>
-<translation id="2223693656926968778">Käsittele nykyistä kohdetta</translation>
-<translation id="225732394367814946">Lisää puhenopeutta</translation>
-<translation id="2267945578749931355">Seuraava merkki</translation>
-<translation id="2281234842553884450">Edellinen liukusäädin</translation>
-<translation id="2318372665160196757">Ensisijainen</translation>
-<translation id="2329324941084714723">Välilehtipaneeli</translation>
-<translation id="2344193891939537199">Päivämäärän ja ajan valinta</translation>
-<translation id="2359897517538099099">Ei taulukkotilassa.</translation>
-<translation id="241124561063364910">ja sitten</translation>
-<translation id="2417569100218200841">Sisällön tiedot</translation>
-<translation id="2422937916923936891">Valikkokohteen valintaruutu</translation>
-<translation id="2429669115401274487">ip</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> on nyt uusi ChromeVoxin muokkausnäppäin.</translation>
-<translation id="2450814015951372393">Valintaruutu</translation>
-<translation id="2462626033734746142">Valintanappiryhmä</translation>
-<translation id="2471138580042810658">Otsikko 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asteriski}other{# asteriskia}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> on nollattu.</translation>
-<translation id="2553108862507765288">kielioppivirhe</translation>
-<translation id="257674075312929031">Ryhmä</translation>
-<translation id="2582407057977008361">Aside-tunniste</translation>
-<translation id="2589102159832527089">Tämä sivu sisältää PDF-tiedostosta &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; automaattisesti noudettua tekstiä. &lt;a href="<ph name="URL" />"&gt;Lue alkuperäinen asiakirja klikkaamalla tätä.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">jossa on {COUNT,plural, =1{# kohde}other{# kohdetta}}</translation>
-<translation id="2614981083756825552">Math ML -asettelu</translation>
-<translation id="2626530649491650971">klikattava</translation>
-<translation id="2628764385451019380">Ei edellisiä yhdistelmäruutuja.</translation>
-<translation id="2637227747952042642">Matematiikka</translation>
-<translation id="2639750663247012216">ChromeVox-muokkaaja</translation>
-<translation id="2644542693584024604">väärin kirjoitettu</translation>
-<translation id="2667291555398229137">Klikkaa reititysavaimen alla olevaa kohdetta</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{vasen kaarisulje}other{# vasenta kaarisuljetta}}</translation>
-<translation id="2705875883745373140">Ei painettu</translation>
-<translation id="2706462751667573066">Ylös</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ääni</translation>
-<translation id="2732718972699418926">ap</translation>
-<translation id="2749275490991666823">Valittu</translation>
-<translation id="27527859628328957">Siirry seuraavaan aktivoitavaan kohteeseen</translation>
-<translation id="2770781857296573485">Käytä ryhmätutkintaa</translation>
-<translation id="2777845298774924149">Suljettiin</translation>
-<translation id="2800204403141299078">Ei muita erilaisia elementtejä.</translation>
-<translation id="2800780099804980316">Ei edellisiä tason 1 otsikoita.</translation>
-<translation id="2811204574343810641">Rivi</translation>
-<translation id="2816654101880605877">Ei seuraavia liukusäätimiä.</translation>
-<translation id="2841013758207633010">Aika</translation>
-<translation id="2843837985843789981">Edellinen ryhmä</translation>
-<translation id="2844995807198708617">Kontekstivalikko</translation>
-<translation id="2849332794118375855">Ei seuraavia valintaruutuja.</translation>
-<translation id="2864481629947106776">Edellinen linkki</translation>
-<translation id="2873259058405069099">Siirry taulukon alkuun</translation>
-<translation id="2894654529758326923">Tiedot</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{vasen aaltosulje}other{# vasenta aaltosuljetta}}</translation>
-<translation id="2911433807131383493">Avaa ChromeVox-opetusohjelma</translation>
-<translation id="2932083475399492303">Vaihda linjatyyppiä rakenteellisen ja asettelun välillä</translation>
-<translation id="2964026537669811554">Otsikkoryhmä</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{sarkain}other{# sarkainta}}</translation>
-<translation id="2972078295414139404">Ei edellisiä käytyjä linkkejä.</translation>
-<translation id="2972205263822847197">Työkaluvinkki</translation>
-<translation id="2998131015536248178">Edellinen merkki</translation>
-<translation id="2999559350546931576">Vähennä äänenkorkeutta</translation>
-<translation id="2999945368667127852">Ei seuraavaa mediawidgetiä.</translation>
-<translation id="3012414509011670858">Ei edeltävää osiota.</translation>
-<translation id="3030432017085518523">Valikkokohde radiopainike</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{heittomerkki}other{# heittomerkkiä}}</translation>
-<translation id="3046838483509668188">ChromeVox-asetukset</translation>
-<translation id="3047143736589213134">Kokeellinen näppäinkartta</translation>
-<translation id="3060756054951570867"><ph name="TITLE" />-valikko avattu</translation>
-<translation id="3078345202707391975">Seuraava tason 2 otsikko</translation>
-<translation id="3078740164268491126">taulukko</translation>
-<translation id="3082557070674409251">Klikattiin</translation>
-<translation id="3084806535845658316">ei kirjoituksen puhumista</translation>
-<translation id="3086746722712840547">huom.</translation>
-<translation id="308895241372589742">Ei seuraavaa matemaattista lauseketta.</translation>
-<translation id="3090532668523289635">ryhmä</translation>
-<translation id="3093176084511590672">Seuraava maamerkki</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">ilm.ikk.</translation>
-<translation id="3109724472072898302">Tiivistetty</translation>
-<translation id="3134461040845705080">vain luku</translation>
-<translation id="3138767756593758860">Näytä maamerkkiluettelo</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Seuraava rivi</translation>
-<translation id="3155083529632865074">Ei edellisiä painikkeita.</translation>
-<translation id="3163593631834463955">Tyhjä sarakkeen otsikko</translation>
-<translation id="316542773973815724">Liikkuminen</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{välilyönti}other{# välilyöntiä}}</translation>
-<translation id="320961988183078793">lisäsit seuraavaa sisältöä: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, välilehti</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Käyty linkki</translation>
-<translation id="323731244387692321">Avaa ChromeVox-näppäimistöohje</translation>
-<translation id="3241052487511142956">Edellinen käyty linkki</translation>
-<translation id="3286390186030710347">Liukusäädin</translation>
-<translation id="3299925995433437805">Ei seuraavia käytyjä linkkejä.</translation>
-<translation id="3303384412438961941">Opi nimi painamalla mitä tahansa näppäintä. Ctrl + W sulkee näppäinselaimen.</translation>
-<translation id="3307886118343381874">Siirry taulukon loppuun</translation>
-<translation id="3311969765485641742">Tarkista ilmoitukset painamalla Alt+Shift+A</translation>
-<translation id="3312997241656799641">Seuraava käyty linkki</translation>
-<translation id="3321460131042519426">Ota sanojen rivitys käyttöön</translation>
-<translation id="3322936298410871309">Edellinen tason 1 otsikko</translation>
-<translation id="3323447499041942178">Tekstiruutu</translation>
-<translation id="3353420241558113817">{"ar": "arabia",
- "bg": "bulgaria",
- "ca": "katalaani",
- "cs": "tšekki",
- "da": "tanska",
- "de": "saksa",
- "de_CH": "saksa (Sveitsi)",
- "de_DE": "saksa (Saksa)",
- "el": "kreikka",
- "en": "englanti",
- "en_CA": "englanti (Kanada)",
- "en_GB": "englanti (Iso-Britannia)",
- "en_US": "englanti (Yhdysvallat)",
- "es": "espanja",
- "et": "viro",
- "fr": "ranska",
- "fr_CA": "ranska (Kanada)",
- "fr_FR": "ranska (Ranska)",
- "fi": "suomi",
- "he": "heprea",
- "hi": "hindi",
- "hr": "kroatia",
- "hu": "unkari",
- "is": "islanti",
- "it": "italia",
- "ko": "korea",
- "lt": "liettua",
- "lv": "latvia",
- "nb": "norja (bokmål)",
- "nl": "hollanti",
- "pl": "puola",
- "pt": "portugali",
- "ro": "romania",
- "ru": "venäjä",
- "sk": "slovakki",
- "sl": "sloveeni",
- "sr": "serbia",
- "sv": "ruotsi",
- "tr": "turkki",
- "vi": "vietnam",
- "zh": "kiina",
- "zh_TW": "kiina (perinteinen han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plus}other{# plusmerkkiä}}</translation>
-<translation id="338583716107319301">Erotin</translation>
-<translation id="3389259863310851658">Edellinen lomakekenttä</translation>
-<translation id="3390225400784126843">Seuraava erilainen elementti.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, valikkokohde</translation>
-<translation id="3406283310380167331">Näytä muotojen luettelo</translation>
-<translation id="3422338090358345848">Avaa näppäimistöselain</translation>
-<translation id="3457000393508828486">Painettu osittain</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, painike</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{oikea hakasulje}other{# oikeaa hakasuljetta}}</translation>
-<translation id="3493915602752813531">Ei seuraavia ankkureita.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{kysymysmerkki}other{# kysymysmerkkiä}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{poisjääntimerkki}other{# poisjääntimerkkiä}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, valintaruutua ei ole valittu</translation>
-<translation id="3599054940393788245">Ei sovi math-rooliin</translation>
-<translation id="3616113530831147358">Ääni</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{aksenttimerkki}other{# aksenttimerkkiä}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollari}other{# dollarimerkkiä}}</translation>
-<translation id="3659787053479271466">ilm.</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, luetteloruutu</translation>
-<translation id="3687295507293856493">Arvioi nykyisen solun sarakkeen otsikossa</translation>
-<translation id="3692274950075847560">H:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Puheen hallinta</translation>
-<translation id="3716845769494773620">Monirivinen</translation>
-<translation id="3731746171184829332">Ei edellisiä otsikoita.</translation>
-<translation id="3762198587642264450">Siirry nykyisen rivin loppuun</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Valintaikkuna suljettiin.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Ennakoivan tekstinsyötön luettelo</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Seuraava mediakohde</translation>
-<translation id="3819376190738087562">Ei siirtymiä.</translation>
-<translation id="385383972552776628">Avaa asetussivu</translation>
-<translation id="3856075812838139784">Vain luku</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Valikko</translation>
-<translation id="3909320334364316587">Edellinen tason 6 otsikko</translation>
-<translation id="3914173277599553213">Pakollinen</translation>
-<translation id="3962990492275676168">Aloita lukeminen nykyisestä sijainnista</translation>
-<translation id="4004802134384979325">valittu</translation>
-<translation id="4006140876663370126">kuva</translation>
-<translation id="4038349100599457191">Kuukauden hallinta</translation>
-<translation id="4039983576244166038">Tyhjä rivin otsikko</translation>
-<translation id="4042843249978639960">Ei seuraavia tason 2 otsikoita.</translation>
-<translation id="4043348641337972076">Ei edellisiä ARIA-maamerkkejä.</translation>
-<translation id="4047216625641135770">Merkintä</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">tila</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{tilde}other{# tildeä}}</translation>
-<translation id="409334809956508737">Edellinen objekti</translation>
-<translation id="4099274309791143834">alavalikolla</translation>
-<translation id="4107807507418787238">Ei alla olevia soluja.</translation>
-<translation id="4116415223832267137">Ilmoitus</translation>
-<translation id="4147126331795725888">Ei seuraavaa ohjausobjektia.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{oikea aaltosulje}other{# oikeaa aaltosuljetta}}</translation>
-<translation id="4158704014418536539">Kirjainkoolla on väliä.</translation>
-<translation id="4161663686871496107">ChromeVox-puhepalaute on valmis</translation>
-<translation id="4173994908659439270">Ei seuraavia muokattavia tekstikenttiä.</translation>
-<translation id="4176463684765177261">Pois käytöstä</translation>
-<translation id="4188530942454211480">Edellinen lause</translation>
-<translation id="4202186506458631436">Siirrä oikealle</translation>
-<translation id="4206289001967551965">Taulukossa</translation>
-<translation id="4215733775853809057">Seuraava liukusäädin</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{ajatusviiva}other{# ajatusviivaa}}</translation>
-<translation id="421884353938374759">värinvalitsin</translation>
-<translation id="4229646983878045487">päiväys/aika</translation>
-<translation id="423334822609210999">Ei vasemmalla olevia soluja.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, tyyppi <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Huomautus</translation>
-<translation id="4254798249533888099">Puu</translation>
-<translation id="4255943572433203166">Muokkaa ChromeVoxia alla olevien asetusten avulla. Muutokset tulevat voimaan välittömästi.</translation>
-<translation id="4271220233568730077">Seuraava matemaattinen lauseke</translation>
-<translation id="4271521365602459209">Ei enempää tuloksia.</translation>
-<translation id="4287520460805643128">Tämä on viimeinen artikkeli.</translation>
-<translation id="4289540628985791613">Yleiskatsaus</translation>
-<translation id="4300318234632215983">Ilmoita linkin takana oleva URL-osoite</translation>
-<translation id="4301352596632316575">sisältää alivalikon</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{piste}=3{ellipsi}other{# pistettä}}</translation>
-<translation id="4347461890115250064">Ei seuraavia luetteloita.</translation>
-<translation id="4367650418938037324">Math ML -lehti</translation>
-<translation id="4372435075475052704">vähintään <ph name="X" /></translation>
-<translation id="4372705107434148843">Lopeta puhe</translation>
-<translation id="4373197658375206385">Ei edellisiä kohteita, jotka eivät ole linkkejä.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">palauta</translation>
-<translation id="4471074325120394300">Ei linkkejä.</translation>
-<translation id="4476183483923481720">uusi rivi</translation>
-<translation id="4482330759234983253">Edellinen taulukko</translation>
-<translation id="4491109536499578614">Kuva</translation>
-<translation id="4529987814483543472">Perinteinen näppäinasettelu</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{kauttaviiva}other{# kauttaviivaa}}</translation>
-<translation id="4547556996012970016">Seuraava tason 5 otsikko</translation>
-<translation id="4562381607973973258">Otsikko</translation>
-<translation id="4591507479202817876">, valittu</translation>
-<translation id="4597532268155981612">lomake</translation>
-<translation id="4597896406374528575">huhtikuu</translation>
-<translation id="4615592953348396470">Seuraava näppäimen painallus ohitetaan</translation>
-<translation id="461613135510474570">Virke</translation>
-<translation id="4647836961514597010">Värinvalitsin</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">ruud.</translation>
-<translation id="4693675773662933727">Edellinen maamerkki</translation>
-<translation id="4696413482802371445">Ei seuraavia tason 5 otsikoita.</translation>
-<translation id="4729095194763193578">Edellinen taulukkorivi</translation>
-<translation id="4736221692378411923">elokuu</translation>
-<translation id="4740661827607246557">Apukomennot</translation>
-<translation id="4759716709594980008">ChromeOS Keyboard Explorer</translation>
-<translation id="4763296182459741068">Sijoitettu alareunaan</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">haku</translation>
-<translation id="481165870889056555">Ilmoita nykyisen sivun otsikko</translation>
-<translation id="4826415162591436065">Siirry eteenpäin</translation>
-<translation id="4826604887384865800">Seuraava siirtyminen</translation>
-<translation id="4827410568042294688">ei valittu</translation>
-<translation id="4842108708071771135">Ei seuraavia lainauksia.</translation>
-<translation id="4848993367330139335">ajast.</translation>
-<translation id="4850023505158945298">Edellinen samankaltainen elementti.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Ota TTS-kirjaaminen käyttöön</translation>
-<translation id="4877261390094455813">Anna hakutermi.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Sisäinen linkki</translation>
-<translation id="4953585991029886728">Muokkaa tekstiä</translation>
-<translation id="4954534434583049121">Edellinen estoviittaus</translation>
-<translation id="4973717656530883744">Vähintään <ph name="X" /></translation>
-<translation id="4973762002207131920">Vaihdettu näppäimeen <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">millisekuntia</translation>
-<translation id="49787999531187221">ChromeVox ei ole käytössä.</translation>
-<translation id="4979404613699303341">Edellinen-painike</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, luetteloruutu</translation>
-<translation id="4983588134362688868">Siirry sivun yläosaan</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, ikkuna</translation>
-<translation id="4993152509206108683">Nopeus <ph name="PERCENT" /> prosenttia.</translation>
-<translation id="4996716799442435517">Visuaalinen</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, radiopainike valittu</translation>
-<translation id="4997475792277222884">Ei seuraavia kohteita, jotka eivät ole linkkejä.</translation>
-<translation id="5000760171916499057">Ei lomakkeita.</translation>
-<translation id="5005670136041063723">Ei muita samanlaisia ​​elementtejä.</translation>
-<translation id="501473567976723023">tammikuu</translation>
-<translation id="5041394372352067729">Siirrä pistekirjoitusnäyttö sivun yläreunaan</translation>
-<translation id="5042770794184672516">Lisää puheen äänenvoimakkuutta</translation>
-<translation id="5050015258024679800">Edellinen tason 4 otsikko</translation>
-<translation id="5054047268577924192">Edellinen luettelokohde</translation>
-<translation id="5078661581131202757">Tiedoston valinta</translation>
-<translation id="5080758118274074384">kaksoisklikattiin</translation>
-<translation id="5098541983634824365">Poistutaan ruudukosta.</translation>
-<translation id="5102981729317424850">Työkalupalkki</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Ei edellisiä lomakkeen kenttiä.</translation>
-<translation id="5111640677200759579">Sarakkeen otsikko</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Ei edellisiä linkkejä.</translation>
-<translation id="513774504516943387">linkki</translation>
-<translation id="517143700877085897">, ei valittu</translation>
-<translation id="5183440668879371625">Pistekirjoituksen edellinen rivi</translation>
-<translation id="5184944171021383281">Ei seuraavia lomakkeen kenttiä.</translation>
-<translation id="5189244881767082992">Rivi</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> on jo määritetty komennolle.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" />luettelo.</translation>
-<translation id="520883772648104506">Ei seuraavia valintanappeja.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Kohde</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, välilehti</translation>
-<translation id="5310788376443009632">poistettu:</translation>
-<translation id="5320727453979144100">Kiinnitetty tila käytössä</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{pilkku}other{# pilkkua}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, tekstikenttä</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, linkki</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Siirry taaksepäin jatkuvan lukemisen aikana</translation>
-<translation id="5368000168321181111">Earcon-äänimerkit pois käytöstä</translation>
-<translation id="5374320867641260420">Ei seuraavia painikkeita.</translation>
-<translation id="5382299583965267720">Ei seuraavia tason 1 otsikoita.</translation>
-<translation id="5402367795255837559">Pistekirjoitus</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{puolipiste}other{# puolipistettä}}</translation>
-<translation id="5411891038905756502">Ei edellisiä siirtymäkohtia.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{pienemmyys}other{# pienemmyysmerkkiä}}</translation>
-<translation id="5455441614648621694">Täydentävä</translation>
-<translation id="5485036206801896268">Ei edellisiä kuvia.</translation>
-<translation id="5486947920110100234">Ei seuraavia siirtymäkohtia.</translation>
-<translation id="549602578321198708">Sana</translation>
-<translation id="5500932716852106146">Ei edellisiä muokattavia tekstikenttiä.</translation>
-<translation id="5502713021410870035">syyskuu</translation>
-<translation id="5507663321906818013">Viankorjauksen kynnysarvo</translation>
-<translation id="5518443085409638729">Aseta osoitin merkkien väliin muokatessasi tekstiä (kuten Mac OS X).</translation>
-<translation id="552195134157544755">Valintanappi</translation>
-<translation id="5534303576632885660">header</translation>
-<translation id="5546092960038624944">Ei edellisiä tason 5 otsikoita.</translation>
-<translation id="556042886152191864">Painike</translation>
-<translation id="5561345396546889625">Seuraava luettelo</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Askelpalautin</translation>
-<translation id="5585044216466955529">Muokkaa tekstiä, sähköposti</translation>
-<translation id="5597170376237141345">Seuraava valintaruutu</translation>
-<translation id="5597933780944041114">Ei seuraavia otsikoita.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, valintanappia ei valittu</translation>
-<translation id="5601172225407283979">Suorita oletustoiminto</translation>
-<translation id="5608798115546226984">Ennakoiva tekstin syöttö upotettuna</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Loki</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Ei edellisiä taulukoita.</translation>
-<translation id="5655682562155942719">Siirtymiskomennot</translation>
-<translation id="56637627897541303">Tekstialue</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">kuv.</translation>
-<translation id="5682113568322255809">Maamerkki</translation>
-<translation id="5683155931978483559">Edellinen valintaruutu</translation>
-<translation id="5684277895745049190">Luettelo</translation>
-<translation id="5700650669149824506">Ei edellisiä tason 4 otsikoita.</translation>
-<translation id="5709192780268610569">Ei pitkää kuvausta</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Taulukon seuraava sarake</translation>
-<translation id="571866080859340309">Tutkitaan ryhmiä</translation>
-<translation id="5728409797179002635">Taulukoita ei löytynyt.</translation>
-<translation id="5748623122140342504">Edellinen tason 5 otsikko</translation>
-<translation id="5750633686117194034">Muokkausnäppäintä ei ole painettu. Paina yhtä tai useampaa näppäintä samanaikaisesti. Lopeta, kun olet valmis, niin kuulet asetetut näppäimet. Poistu sarkainnäppäimellä.</translation>
-<translation id="5788275253279308023">incognito-ikkuna <ph name="TITLE" /> välilehti</translation>
-<translation id="5806206155699461681">Paranna tiettyjä sivustoja (kuten Google-haku).</translation>
-<translation id="5819072574982403430">Puukohde</translation>
-<translation id="5826479389509458994">rivi <ph name="ROW" /> sarake <ph name="COL" /></translation>
-<translation id="5850707923114094062">Panoroi taaksepäin</translation>
-<translation id="5851548754964597211">Välilehtiluettelo</translation>
-<translation id="5859752971144398932">Haku sivulta suljettiin.</translation>
-<translation id="5866042630553435010">Tarkistettu osittain</translation>
-<translation id="5869546221129391014">Ruudukko</translation>
-<translation id="5876817486144482042">Pienennä puheen äänenvoimakkuutta</translation>
-<translation id="5887397643266327462">Pistekirjoituskuvatekstit ovat käytössä.</translation>
-<translation id="5891934789323004067">Taulukko</translation>
-<translation id="5919442531159595654">kopioi.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{yhtäläisyys}other{# yhtäläisyysmerkkiä}}</translation>
-<translation id="5939518447894949180">Tyhjennä</translation>
-<translation id="5948123859135882163">Vaihda matemaattisten lausekkeiden tulkintatapaa rakenteellisen ja semanttisen välillä</translation>
-<translation id="5955304353782037793">sov.</translation>
-<translation id="5956928062748260866">Dialogi</translation>
-<translation id="5963413905009737549">Osio</translation>
-<translation id="5968607524793740041">Näytä kontekstivalikko</translation>
-<translation id="5983179082906765664">Lisää siirtymisen tarkkuutta</translation>
-<translation id="5999630716831179808">Äänet</translation>
-<translation id="6000417740266304866">Muuta nykyistä kahdeksan pisteen pistekirjoitustaulukkoa valitsemalla vaihtoehto alla olevasta luettelosta.</translation>
-<translation id="6006050241733874051">Lomake</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{kenoviiva}other{# kenoviivaa}}</translation>
-<translation id="6037602951055904232">Panoroi eteenpäin</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Solu päättyi.</translation>
-<translation id="6122013438240733403">pain.</translation>
-<translation id="6129953537138746214">Välilyönti</translation>
-<translation id="6142308968191113180">Otsikko 4</translation>
-<translation id="6169420925157477918">Kuva, jolla on pitkä kuvaus</translation>
-<translation id="6172087735260766220">Helppokäyttötekstiä ei voi käyttää kopiosuojatusta PDF:stä.</translation>
-<translation id="6186305613600865047">Siirry sivun alaosaan</translation>
-<translation id="6193330012414963395">ap/ip</translation>
-<translation id="622484624075952240">Alas</translation>
-<translation id="6236061028292614533">Seuraava otsikko</translation>
-<translation id="6254901459154107917">Seuraava muokattava tekstialue</translation>
-<translation id="6259464875943891919">Poistuttu kohteesta <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Seuraava samankaltainen elementti.</translation>
-<translation id="6282062888058716985">nav.</translation>
-<translation id="6290434000785343030">Ei seuraavia yhdistelmäruutuja.</translation>
-<translation id="6307969636681130414">Painettu</translation>
-<translation id="6324551002951139333">Kielioppivirhe havaittu</translation>
-<translation id="6348657800373377022">Yhdistelmäruutu</translation>
-<translation id="6355910664415701303">Ei edellisiä luettelokohteita.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Edellinen otsikko</translation>
-<translation id="6387719785439924554">sivuun</translation>
-<translation id="6411426777058107714">Ei edellisiä valintanappeja.</translation>
-<translation id="6414968628640960377">Edellinen erilainen elementti.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{kaksoispiste}other{# kaksoispistettä}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, valikko</translation>
-<translation id="6444046323172968959">Ilmoitusvalintaikkuna</translation>
-<translation id="6459511626086141404">Flat-näppäinkartta</translation>
-<translation id="6468049171101508116">Seuraava-painike</translation>
-<translation id="6491972999578897419">Vaihda ääntä valitsemalla vaihtoehto alla olevasta luettelosta.</translation>
-<translation id="6508059270146105198">Siirrä pistenäyttö sivun alareunaan</translation>
-<translation id="6536864053412760904">Math ML -tunnus</translation>
-<translation id="6550720799683018100">Vaihda näppäinasettelua valitsemalla vaihtoehto alla olevasta luettelosta.</translation>
-<translation id="6561818612645211875">Siirry nykyisen rivin alkuun</translation>
-<translation id="6587021927234520429">Ei seuraavia tason 4 otsikoita.</translation>
-<translation id="6601344353291556895">Ota puhekuvaukset käyttöön.</translation>
-<translation id="6615602925644411249">Haku sivulta.</translation>
-<translation id="6633350132811819843">Ei seuraavia taulukoita.</translation>
-<translation id="6637586476836377253">loki</translation>
-<translation id="6657128831881431364">Etenemispalkki</translation>
-<translation id="6659594942844771486">Välilehti</translation>
-<translation id="667999046851023355">Dokumentti</translation>
-<translation id="6697092096875747123">Edellinen yhdistelmäruutu</translation>
-<translation id="6714813999819678458">Edellinen tason 2 otsikko</translation>
-<translation id="6716505898850596801">Muokkausnäppäimet</translation>
-<translation id="671916444866103745">Ei seuraavia ARIA-maamerkkejä.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, yhdistelmäruutu</translation>
-<translation id="6735257939857578167">jossa <ph name="NUM" /> kohdetta</translation>
-<translation id="6736510033526053669">välilehti luotu</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artikkeli</translation>
-<translation id="6787839852456839824">Pikanäppäimet</translation>
-<translation id="6793101435925451627">luett.kenttä</translation>
-<translation id="6833103209700200188">Alaviite</translation>
-<translation id="6871161210040114857">Ohitetaan kirjainkoko.</translation>
-<translation id="6877435256196695200">Ei seuraavia kuvia.</translation>
-<translation id="6897341342232909480">Siirrä vasemmalle</translation>
-<translation id="6901540140423170855">pvm</translation>
-<translation id="6910211073230771657">Poistettu</translation>
-<translation id="6911965441508464308">Ei yläpuolella olevia soluja.</translation>
-<translation id="6919104639734799681">Näytä taulukoiden luettelo</translation>
-<translation id="6964088412282673743">Ei edeltävää ohjausobjektia.</translation>
-<translation id="6996566555547746822">Seuraava yhdistelmäruutu</translation>
-<translation id="7005146664810010831">URL-osoitteita ei löydetty.</translation>
-<translation id="7010712454773919705">ChromeVox-muokkausnäppäin</translation>
-<translation id="7031651751836475482">luett.kohd.</translation>
-<translation id="7037042857287298941">Edellinen luettelo</translation>
-<translation id="7041173719775863268">Lopeta valinta</translation>
-<translation id="7095834689119144465">Muokkaa tekstiä vain numeraaleja</translation>
-<translation id="7096001299300236431">Edellinen mediakohde</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">sanojen puhuminen</translation>
-<translation id="713824876195128146">Seuraava estoviittaus</translation>
-<translation id="7161771961008409533">Ponnahduspainike</translation>
-<translation id="7167657087543110">merkkien puhuminen</translation>
-<translation id="7170733337935166589">Siirry eteenpäin jatkuvan lukemisen aikana</translation>
-<translation id="7181697990050180700">Muokkaa usein käytettyjen komentojen pikanäppäimiä kirjoittamalla ne haluamiisi alla oleviin kenttiin.</translation>
-<translation id="7203150201908454328">Laajennettu</translation>
-<translation id="7210211103303402262">minuuttia</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">rivi</translation>
-<translation id="7226216518520804442">luett.</translation>
-<translation id="72393384879519786">Otsikko</translation>
-<translation id="7241683698754534149">Avaa pitkä kuvaus uudessa välilehdessä</translation>
-<translation id="7248671827512403053">Sovellus</translation>
-<translation id="725969808843520477">Seuraava valintanappi</translation>
-<translation id="7269119382257320590">Ei välimerkkejä</translation>
-<translation id="7273174640290488576">Tyhjä</translation>
-<translation id="7285387653379749618">Taulukot</translation>
-<translation id="7289186959554153431">Otsikko 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Pistekirjoitustekstitys pois käytöstä.</translation>
-<translation id="7318872822751139669">Vaihda aktiivista kohtaa hiiren avulla.</translation>
-<translation id="7322388933135261569">helmikuu</translation>
-<translation id="7332592614823088566">Rivi <ph name="ROWINDEX" />/<ph name="ROWTOTAL" />, sarake <ph name="COLINDEX" />/<ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">sisältää ponnahdusikkunan</translation>
-<translation id="7356165926712028380">Vaihda 8 pisteen pistekirjoitukseen</translation>
-<translation id="7362871137496673139">Ei edellisiä tason 2 otsikoita.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{et-merkki}other{# et-merkkiä}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Poistutaan taulukosta.</translation>
-<translation id="739763518212184081">Edellinen rivi</translation>
-<translation id="7400575256015741911">Oikeinkirjoitusvirhe havaittu</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">takaisin</translation>
-<translation id="7434509671034404296">Kehittäjille</translation>
-<translation id="7439060726180460871">Hakemisto</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">sarkain</translation>
-<translation id="7492049978501397201">Lisätty valintaikkuna</translation>
-<translation id="7532613204005497612">kesäkuu</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, liukusäädin</translation>
-<translation id="7586163296341959563">liitä.</translation>
-<translation id="7596919493010894443">valinta poistettu</translation>
-<translation id="7604026522577407655">Siirry nykyisen sarakkeen alkuun</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Ilmoita nykyisen sivun URL-osoite</translation>
-<translation id="7609363189280667021">Ota pistekirjoitustekstitys käyttöön tai poista se käytöstä</translation>
-<translation id="762020119231868829">Keskeyttää toiston kaikissa mediawidgeteissä</translation>
-<translation id="7625690649919402823">Seuraava taulukko</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), tyyppi <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Ei edellisiä tason 3 otsikoita.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, tekstikenttä</translation>
-<translation id="7663318257180412551">Otsikko 2</translation>
-<translation id="7674576868851035240">Seuraava linkki</translation>
-<translation id="7674768236845044097">merkintä</translation>
-<translation id="7684431668231950609">Muokkaa tekstiä, URL-osoite</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Edellinen valintanappi</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, salasanan tekstikenttä</translation>
-<translation id="7805247615045262757">oletusnavigointi</translation>
-<translation id="7805768142964895445">Tila</translation>
-<translation id="7810781339813764006">Seuraava ryhmä</translation>
-<translation id="7819187121850078213">ikkuna <ph name="TITLE" /> välilehti</translation>
-<translation id="7828956995407538686">lokakuu</translation>
-<translation id="7839679365527550018">Edellinen sana</translation>
-<translation id="7851816175263618915">Osa välimerkeistä</translation>
-<translation id="7870596830398826354">Math ML -puu</translation>
-<translation id="78826985582142166">liukusäädin</translation>
-<translation id="7894517696028036636">Ota ChromeVox classic käyttöön tai poista se käytöstä.</translation>
-<translation id="7895896691902835279">Tuntematon linkki</translation>
-<translation id="7927711904086083099">Ei valittu</translation>
-<translation id="7935627501098484003">Ajanhallinta</translation>
-<translation id="7939428177581522200">lisätty valintaan</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{ät-merkki}other{# ät-merkkiä}}</translation>
-<translation id="7965147473449754028">valikko suljettu</translation>
-<translation id="7974390230414479278">Valikkokohde</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{huutomerkki}other{# huutomerkkiä}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{lainausmerkki}other{# lainausmerkkiä}}</translation>
-<translation id="8033827949643255796">valittu</translation>
-<translation id="8035962149453661158">enintään <ph name="X" /></translation>
-<translation id="8042761080832772327">Muokkaa tekstiä, haku</translation>
-<translation id="8049189770492311300">Ajastin</translation>
-<translation id="8065607967589909823">Valinta on</translation>
-<translation id="8066678206530322333">Banneri</translation>
-<translation id="8110647606445335195">Ei ARIA-maamerkkejä.</translation>
-<translation id="8153880621934657047">Et ole taulukossa.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{alaviiva}other{# alaviivaa}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">leikkaa.</translation>
-<translation id="8199231515320852133">Ilmoita nykyisen solun otsikot</translation>
-<translation id="820417203470636242">Tyhjä solu.</translation>
-<translation id="8215202828671303819">Monivalinta</translation>
-<translation id="8276439074553447000">Siirry edelliseen aktivoitavaan kohteeseen</translation>
-<translation id="8278417001922463147">Ei aiempaa artikkelia.</translation>
-<translation id="8283603667300770666">Seuraava lomakekenttä</translation>
-<translation id="831207808878314375">Määritelmä</translation>
-<translation id="8313653172105209786">hakem.</translation>
-<translation id="8344569602005188545">tuntia</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{ristikko}other{# ristikkomerkkiä}}</translation>
-<translation id="8374154622594089836">kk</translation>
-<translation id="8378855320830505539">Alue</translation>
-<translation id="8382679411218029383">Ennakoiva tekstin syöttö upotettuna ja luettelona</translation>
-<translation id="8428603554127842284">taso <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Ei seuraavia tason 3 otsikoita.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Ei edellisiä valintaruutuja.</translation>
-<translation id="8455868257606149352">Enintään <ph name="X" /></translation>
-<translation id="84575901236241018">omistaa pääsyavaimen, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Vähennä siirtymisen rakeisuutta</translation>
-<translation id="8520472399088452386">Pyörityspainike</translation>
-<translation id="8538744478902126321">Arvioi nykyisen solun rivin otsikossa</translation>
-<translation id="8540054775867439484">Sijoitettu yläreunaan</translation>
-<translation id="8548973727659841685">Merkki</translation>
-<translation id="8561322612995434619">sisältää ponnahdusikkunan</translation>
-<translation id="8571096049907249734">monival.</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Seuraava luettelokohde</translation>
-<translation id="860150890330522909"><ph name="NAME" />-valintaruutu valittu</translation>
-<translation id="8606621670302093223">Päivämäärän hallinta</translation>
-<translation id="8631359288236106450">valittu <ph name="COUNT" /> kohdetta</translation>
-<translation id="8638532244051952400">Kerro nykyiset solukoordinaatit</translation>
-<translation id="8650576015643545550">Ei edellisiä luetteloita.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Näytä linkkiluettelo</translation>
-<translation id="8664519043722036194">sekuntia</translation>
-<translation id="867187640362843212">Otsikko 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{pystyviiva}other{# pystyviivaa}}</translation>
-<translation id="8735450637152821465">Aloita valinta</translation>
-<translation id="8743786158317878347">siirry rakenteelliseen sisältöön, kuten taulukkoon</translation>
-<translation id="8747966237988593539">Järjestetty luettelo</translation>
-<translation id="8759334257841767240">Ei seuraavia linkkejä.</translation>
-<translation id="8767968232364267681">Seuraava tason 4 otsikko</translation>
-<translation id="8770473310765924354">poistu rakenteellisesta sisällöstä, kuten taulukosta</translation>
-<translation id="8791025954632646584">Semanttinen on käytössä</translation>
-<translation id="8796411681063377102">Seuraava tason 3 otsikko</translation>
-<translation id="8808582214901541005">maaliskuu</translation>
-<translation id="8825828890761629845">bann.</translation>
-<translation id="8851136666856101339">pää</translation>
-<translation id="8856538297388979332">Selaa komentoja painamalla ylös tai alas, valitse painamalla enteriä</translation>
-<translation id="8864099967139188018">Ei seuraavia tason 6 otsikoita.</translation>
-<translation id="8882002077197914455">Rivin otsikko</translation>
-<translation id="8896347895970027998">Ota ChromeVox käyttöön tai poista se käytöstä.</translation>
-<translation id="8898516272131543774">Ota välimerkkien puhuminen käyttöön tai pois käytöstä</translation>
-<translation id="8900148057318340779">Etuliitenäppäin</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Tyhjät otsikot</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Muokkausavaimet</translation>
-<translation id="8943175951035496220">Ei oikealla olevia soluja.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">tiedosto</translation>
-<translation id="9027462562263121875">Ei taulukoita.</translation>
-<translation id="9040132695316389094">Otsikko 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Ota hakuwidget käyttöön tai poista se käytöstä</translation>
-<translation id="9065283790526219006">+ponnahdus</translation>
-<translation id="9077213568694924680">poistettu valinnasta</translation>
-<translation id="9082874451376019682">Ei edellisiä liukusäätimiä.</translation>
-<translation id="9089864840575085222">Ota kirjoituksen puhuminen käyttöön tai pois käytöstä</translation>
-<translation id="9107530006868467849">Ei edellistä mediawidgetiä.</translation>
-<translation id="9108370397979208512">matematiikka</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{prosentti}other{# prosenttimerkkiä}}</translation>
-<translation id="9115913704608474258">marraskuu</translation>
-<translation id="9128414153595658330">ikk.</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Ilmoittaa nykyisen aseman lyhyen kuvauksen</translation>
-<translation id="9153606228985488238">Äänenkorkeus <ph name="PERCENT" /> prosenttia</translation>
-<translation id="9160096769946561184">Siirry nykyisen sarakkeen loppuun</translation>
-<translation id="9173115498289768110">Äänenvoimakkuus <ph name="PERCENT" /> prosenttia.</translation>
-<translation id="9178973770513562274">Selaa ylös- ja alasnäppäimillä tai tee haku kirjoittamalla.</translation>
-<translation id="9192904702577636854">Vierivä kuva</translation>
-<translation id="9212322457209634662">Ei seuraavaa osiota.</translation>
-<translation id="930275611743429116">Aloita tai lopeta valinta.</translation>
-<translation id="948171205378458592">Vähennä puhenopeutta</translation>
-<translation id="962913030769097253">Seuraava tason 1 otsikko</translation>
-<translation id="973955474346881951">Kiinnitystilan ottaminen käyttöön / poistaminen käytöstä</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fil.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fil.xtb
deleted file mode 100644
index a158e05b119..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fil.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="fil">
-<translation id="1012173283529841972">Item sa listahan</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Na-span.</translation>
-<translation id="1025074108959230262">Na-disable ang sticky mode</translation>
-<translation id="1031961866430398710">pagkatapos</translation>
-<translation id="1044777062731150180">Walang mga header</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Hindi wastong input</translation>
-<translation id="1082209053475788238">Walang nakaraang heading sa antas 6.</translation>
-<translation id="1088219014394087294">Walang mga heading.</translation>
-<translation id="1106741348836243114">I-on o i-off ang feedback ng tunog (mga earcon).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Koleksyon ng <ph name="TAG" /> na may <ph name="NUM" /> (na) item</translation>
-<translation id="1155043339247954670">Walang susunod na item sa listahan.</translation>
-<translation id="1157782847298808853">Tulong sa Keyboard</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, combo box</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, item sa menu, na may submenu</translation>
-<translation id="1177863135347784049">Custom</translation>
-<translation id="1188858454923323853">complementary</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Nagbibigay ng Boses sa Chrome</translation>
-<translation id="1229276918471378188">Nakaraang paglaktaw</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Susunod na heading sa antas 6</translation>
-<translation id="1275718070701477396">Pinili</translation>
-<translation id="1319608975892113573">Walang nakaraang blockquote.</translation>
-<translation id="1321576897702511272">Itago ang tulong sa ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> ng <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">echo ng character at salita</translation>
-<translation id="1339428534620983148">Nakaraang column ng talahanayan</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Kanan</translation>
-<translation id="136718599399906424">Susunod na row ng talahanayan</translation>
-<translation id="1383876407941801731">Hanapin</translation>
-<translation id="1385214448885562192">Pindutin ang enter upang tanggapin o escape upang kanselahin, down para sa susunod at up para sa nakaraan.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, text box ng password</translation>
-<translation id="1467432559032391204">Kaliwa</translation>
-<translation id="1474557363159888097">Walang nakaraang anchor.</translation>
-<translation id="1502086903961450562">Nakaraang graphic</translation>
-<translation id="1506187449813838456">Taasan ang pitch</translation>
-<translation id="151784044608172266">Susunod na Pangungusap</translation>
-<translation id="1524531499102321782">Susunod na Linya ng Braille</translation>
-<translation id="1546370775711804143">Scroll bar</translation>
-<translation id="1559739829547075274">Mag-navigate pabalik</translation>
-<translation id="1571643229714746283">Handa na ang ChromeVox</translation>
-<translation id="158493514907962286">Disyembre</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Lumipat sa 6 dot braille</translation>
-<translation id="1611168825862729585">Header ng column:</translation>
-<translation id="1613476421962910979">Naka-on ang mga earcon</translation>
-<translation id="1618597272655350600">Nagpapahayag ng kumpletong paglalarawan sa kasalukuyang posisyon</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{greater than}one{# greater than sign}other{# na greater than sign}}</translation>
-<translation id="1653266918374749391">Nakaraang heading sa antas 3</translation>
-<translation id="1659072772017912254">Hindi nilagyan ng check</translation>
-<translation id="1669290819662866522">linggo</translation>
-<translation id="1674262202423278359">Nabigasyon sa ChromeVox</translation>
-<translation id="16777221443363124">Menu bar</translation>
-<translation id="1692077714702418899">structural na linya</translation>
-<translation id="1700517974991662022">Nabisita na</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Susunod na graphic</translation>
-<translation id="1781173782405573156">Ipasa ang susunod na key</translation>
-<translation id="1787176709638001873">Text sa pag-edit ng password</translation>
-<translation id="1810107444790159527">Kahon ng listahan</translation>
-<translation id="1828385960365606039">Mayo</translation>
-<translation id="1834891354138622109">Column</translation>
-<translation id="1865601187525349519">Dulo ng text</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Sabihin ang kasalukuyang oras at petsa.</translation>
-<translation id="1902396333223336119">Cell</translation>
-<translation id="1905379170753160525">Ipakita ang listahan ng mga heading</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Kontrol sa linggo ng taon</translation>
-<translation id="1964135212174907577">Susunod na Bagay</translation>
-<translation id="1969092762068865084">Hulyo</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Header ng row:</translation>
-<translation id="2002895034995108595">I-reset ang kasalukuyang keymap</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{kaliwang bracket}one{# kaliwang bracket}other{# na kaliwang bracket}}</translation>
-<translation id="2045490512405922022">hindi nilagyan ng check</translation>
-<translation id="20601713649439366">Walang nakaraang math expression.</translation>
-<translation id="207477615537953741">Naka-off ang semantics</translation>
-<translation id="2086961585857038472">Susunod na Salita</translation>
-<translation id="2089387485033699258">fil</translation>
-<translation id="2091933974477985526">Nakaraang na-e-edit na lugar ng text</translation>
-<translation id="2100350898815792233">Lahat ng bantas</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">access key:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Palitan ang kasalukuyang talahanayan ng 6 dot braille sa pamamagitan ng pagpili ng opsyon sa listahan sa ibaba.</translation>
-<translation id="2169714232367507776">Mag-click sa kasalukuyang item</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{close paren}one{# close paren}other{# na close paren}}</translation>
-<translation id="2199994615414171367">Nakaraang math</translation>
-<translation id="2223693656926968778">Magsagawa ng pagkilos sa kasalukuyang item</translation>
-<translation id="225732394367814946">Dagdagan ang rate ng speech</translation>
-<translation id="2267945578749931355">Susunod na Character</translation>
-<translation id="2281234842553884450">Nakaraang slider</translation>
-<translation id="2318372665160196757">Pangunahin</translation>
-<translation id="2329324941084714723">Panel ng tab</translation>
-<translation id="2344193891939537199">Kontrol sa petsa at oras</translation>
-<translation id="2359897517538099099">Wala sa table mode.</translation>
-<translation id="241124561063364910">sinusundan ng</translation>
-<translation id="2417569100218200841">Impormasyon ng nilalaman</translation>
-<translation id="2422937916923936891">Check box ng item sa menu</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">Ang <ph name="KEY" /> ay ang bago na ngayong modifier ng ChromeVox.</translation>
-<translation id="2450814015951372393">Check box</translation>
-<translation id="2462626033734746142">Pangkat ng radio button</translation>
-<translation id="2471138580042810658">Heading 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisk}one{# asterisk}other{# na asterisk}}</translation>
-<translation id="2549392850788122959">Na-reset ang <ph name="KEY" />.</translation>
-<translation id="2553108862507765288">pagkakamali sa grammar</translation>
-<translation id="257674075312929031">Pangkat</translation>
-<translation id="2582407057977008361">Kaugnay</translation>
-<translation id="2589102159832527089">Nilalaman ng page na ito ang text na awtomatikong na-extract mula sa PDF file na &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Mag-click dito para sa orihinal.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">may {COUNT,plural, =1{# item}one{# item}other{# na item}}</translation>
-<translation id="2614981083756825552">Math ML Layout</translation>
-<translation id="2626530649491650971">naki-click</translation>
-<translation id="2628764385451019380">Walang nakaraang combo box.</translation>
-<translation id="2637227747952042642">Math</translation>
-<translation id="2639750663247012216">Modifier ng ChromeVox</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">I-click ang item sa ilalim ng isang routing key</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{open paren}one{# open paren}other{# na open paren}}</translation>
-<translation id="2705875883745373140">Hindi pinindot</translation>
-<translation id="2706462751667573066">Up</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Nilagyan ng check</translation>
-<translation id="27527859628328957">Lumaktaw sa susunod na napo-focus na item</translation>
-<translation id="2770781857296573485">Pumasok sa pag-explore ng pangkat</translation>
-<translation id="2777845298774924149">Lumabas</translation>
-<translation id="2800204403141299078">Wala nang mga naiibang elemento.</translation>
-<translation id="2800780099804980316">Walang nakaraang heading sa antas 1.</translation>
-<translation id="2811204574343810641">Row</translation>
-<translation id="2816654101880605877">Walang susunod na slider.</translation>
-<translation id="2841013758207633010">Oras</translation>
-<translation id="2843837985843789981">Nakaraang Pangkat</translation>
-<translation id="2844995807198708617">Menu ng Konteksto</translation>
-<translation id="2849332794118375855">Walang susunod na checkbox.</translation>
-<translation id="2864481629947106776">Nakaraang link</translation>
-<translation id="2873259058405069099">Pumunta sa umpisa ng talahanayan</translation>
-<translation id="2894654529758326923">Impormasyon</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{kaliwang brace}one{# kaliwang brace}other{# na kaliwang brace}}</translation>
-<translation id="2911433807131383493">Buksan ang tutorial ng ChromeVox</translation>
-<translation id="2932083475399492303">I-toggle ang uri ng linya sa pagitan ng structural o layout</translation>
-<translation id="2964026537669811554">Pangkat ng heading</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tab}one{# tab}other{# na tab}}</translation>
-<translation id="2972078295414139404">Walang nakaraang binisitang link.</translation>
-<translation id="2972205263822847197">Tool tip</translation>
-<translation id="2998131015536248178">Nakaraang Character</translation>
-<translation id="2999559350546931576">Babaan ang pitch</translation>
-<translation id="2999945368667127852">Walang susunod na widget ng media.</translation>
-<translation id="3012414509011670858">Walang nakaraang seksyon.</translation>
-<translation id="3030432017085518523">Radio button ng item sa menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{kudlit}one{# kudlit}other{# na kudlit}}</translation>
-<translation id="3046838483509668188">Mga Opsyon sa ChromeVox</translation>
-<translation id="3047143736589213134">Pang-eksperimentong keymap</translation>
-<translation id="3060756054951570867">binuksan ang menu ng <ph name="TITLE" /></translation>
-<translation id="3078345202707391975">Susunod na heading sa antas 2</translation>
-<translation id="3078740164268491126">talahanayan</translation>
-<translation id="3082557070674409251">Na-click</translation>
-<translation id="3084806535845658316">walang echo ng pagta-type</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Walang susunod na math expression.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Susunod na landmark</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Naka-collapse</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Ipakita ang listahan ng mga landmark</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Susunod na Linya</translation>
-<translation id="3155083529632865074">Walang nakaraang button.</translation>
-<translation id="3163593631834463955">Walang laman na header ng column</translation>
-<translation id="316542773973815724">Nabigasyon</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{espasyo}one{# espasyo}other{# na espasyo}}</translation>
-<translation id="320961988183078793">naglagay ng <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, tab</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Nabisita nang link</translation>
-<translation id="323731244387692321">Buksan ang tulong sa keyboard ng ChromeVox</translation>
-<translation id="3241052487511142956">Nakaraang binisitang link</translation>
-<translation id="3286390186030710347">Slider</translation>
-<translation id="3299925995433437805">Walang sunod na binisitang link.</translation>
-<translation id="3303384412438961941">Pumindot ng anumang key upang malaman ang pangalan nito. Isasara ng Ctrl+W ang keyboard explorer.</translation>
-<translation id="3307886118343381874">Pumunta sa dulo ng talahanayan</translation>
-<translation id="3311969765485641742">Pindutin ang Alt+Shift+A upang suriin ang mga alerto</translation>
-<translation id="3312997241656799641">Sunod na binisitang link</translation>
-<translation id="3321460131042519426">I-enable ang word wrap</translation>
-<translation id="3322936298410871309">Nakaraang heading sa antas 1</translation>
-<translation id="3323447499041942178">Text box</translation>
-<translation id="3353420241558113817">{"ar": "Arabic",
- "bg": "Bulgarian",
- "ca": "Catalan",
- "cs": "Czech",
- "da": "Danish",
- "de": "German",
- "de_CH": "German (Switzerland)",
- "de_DE": "German (Germany)",
- "el": "Greek",
- "en": "English",
- "en_CA": "English (Canada)",
- "en_GB": "English (United Kingdom)",
- "en_US": "English (United States)",
- "es": "Spanish",
- "et": "Estonian",
- "fr": "French",
- "fr_CA": "French (Canada)",
- "fr_FR": "French (France)",
- "fi": "Finnish",
- "he": "Hebrew",
- "hi": "Hindi",
- "hr": "Croatian",
- "hu": "Hungarian",
- "is": "Icelandic",
- "it": "Italian",
- "ko": "Korean",
- "lt": "Lithuanian",
- "lv": "Latvian",
- "nb": "Norwegian Bokmål",
- "nl": "Dutch",
- "pl": "Polish",
- "pt": "Portuguese",
- "ro": "Romanian",
- "ru": "Russian",
- "sk": "Slovak",
- "sl": "Slovenian",
- "sr": "Serbian",
- "sv": "Swedish",
- "tr": "Turkish",
- "vi": "Vietnamese",
- "zh": "Chinese",
- "zh_TW": "Chinese (Traditional Han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plus}one{# plus sign}other{# na plus sign}}</translation>
-<translation id="338583716107319301">Separator</translation>
-<translation id="3389259863310851658">Nakaraang field ng form</translation>
-<translation id="3390225400784126843">Susunod na naiibang elemento.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, item sa menu</translation>
-<translation id="3406283310380167331">Ipakita ang listahan ng mga form</translation>
-<translation id="3422338090358345848">Buksan ang keyboard explorer</translation>
-<translation id="3457000393508828486">Bahagyang napindot</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, button</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> hanggang <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{kanang bracket}one{# kanang bracket}other{# na kanang bracket}}</translation>
-<translation id="3493915602752813531">Walang susunod na anchor.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{tandang pananong}one{# tandang pananong}other{# na tandang pananong}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{caret}one{# caret}other{# na caret}}</translation>
-<translation id="3568702578574425662">Hindi nilagyan ng check ang <ph name="NAME" />, checkbox</translation>
-<translation id="3599054940393788245">Hindi sa loob ng math</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{backtick}one{# backtick}other{# na backtick}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollar}one{# dollar sign}other{# na dollar sign}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, kahon ng listahan</translation>
-<translation id="3687295507293856493">Maglagay ng hula sa header ng column ng kasalukuyang cell</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Pagkontrol sa Speech</translation>
-<translation id="3716845769494773620">Maramihang linya</translation>
-<translation id="3731746171184829332">Walang nakaraang heading.</translation>
-<translation id="3762198587642264450">Pumunta sa dulo ng kasalukuyang row</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Lumabas sa dialog.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">Listahan ng autocompletion</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Susunod na media</translation>
-<translation id="3819376190738087562">Walang mga jump.</translation>
-<translation id="385383972552776628">Buksan ang page ng mga opsyon</translation>
-<translation id="3856075812838139784">Read only</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Nakaraang heading sa antas 6</translation>
-<translation id="3914173277599553213">Kinakailangan</translation>
-<translation id="3962990492275676168">Magsimulang magbasa mula sa kasalukuyang lokasyon</translation>
-<translation id="4004802134384979325">nilagyan ng check</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Kontrol sa buwan</translation>
-<translation id="4039983576244166038">Walang laman na header ng row</translation>
-<translation id="4042843249978639960">Walang susunod na heading sa antas 2.</translation>
-<translation id="4043348641337972076">Walang nakaraang landmark ng ARIA.</translation>
-<translation id="4047216625641135770">Markahan</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}one{# tilde}other{# na tilde}}</translation>
-<translation id="409334809956508737">Nakaraang Bagay</translation>
-<translation id="4099274309791143834">na may submenu</translation>
-<translation id="4107807507418787238">Walang cell sa ibaba.</translation>
-<translation id="4116415223832267137">Alerto</translation>
-<translation id="4147126331795725888">Walang susunod na kontrol.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{kanang brace}one{# kanang brace}other{# na kanang brace}}</translation>
-<translation id="4158704014418536539">Case sensitive.</translation>
-<translation id="4161663686871496107">Handa na ang sinasalitang feedback ng ChromeVox</translation>
-<translation id="4173994908659439270">Walang susunod na na-e-edit na field ng text.</translation>
-<translation id="4176463684765177261">Hindi Pinagana</translation>
-<translation id="4188530942454211480">Nakaraang Pangungusap</translation>
-<translation id="4202186506458631436">Ilipat pakanan</translation>
-<translation id="4206289001967551965">Nasa loob ng talahanayan</translation>
-<translation id="4215733775853809057">Susunod na slider</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{gitling}one{# gitling}other{# na gitling}}</translation>
-<translation id="421884353938374759">tagapili ng kulay</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">Walang cell sa kaliwa.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, Baitang <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Tala</translation>
-<translation id="4254798249533888099">Tree</translation>
-<translation id="4255943572433203166">Gamitin ang mga opsyon sa ibaba upang i-customize ang ChromeVox. Agad na magkakabisa ang mga pagbabago.</translation>
-<translation id="4271220233568730077">Susunod na math</translation>
-<translation id="4271521365602459209">Wala nang mga resulta.</translation>
-<translation id="4287520460805643128">Walang susunod na artikulo.</translation>
-<translation id="4289540628985791613">Pangkalahatang-ideya</translation>
-<translation id="4300318234632215983">Ianunsyo ang URL sa likod ng isang link</translation>
-<translation id="4301352596632316575">may submenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{tuldok}=3{ellipsis}one{# tuldok}other{# na tuldok}}</translation>
-<translation id="4347461890115250064">Walang susunod na listahan.</translation>
-<translation id="4367650418938037324">Math ML Leaf</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Ihinto ang speech</translation>
-<translation id="4373197658375206385">Walang nakaraang item na hindi isang link.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Walang mga link.</translation>
-<translation id="4476183483923481720">bagong linya</translation>
-<translation id="4482330759234983253">Nakaraang talahanayan</translation>
-<translation id="4491109536499578614">Larawan</translation>
-<translation id="4529987814483543472">Classic na keymap</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{slash}one{# slash}other{# na slash}}</translation>
-<translation id="4547556996012970016">Susunod na heading sa antas 5</translation>
-<translation id="4562381607973973258">Header</translation>
-<translation id="4591507479202817876">, pinili</translation>
-<translation id="4597532268155981612">form</translation>
-<translation id="4597896406374528575">Abril</translation>
-<translation id="4615592953348396470">Babalewalain ang susunod na pagpindot ng key</translation>
-<translation id="461613135510474570">Pangungusap</translation>
-<translation id="4647836961514597010">Tagapili ng kulay</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Nakaraang landmark</translation>
-<translation id="4696413482802371445">Walang susunod na heading sa antas 5.</translation>
-<translation id="4729095194763193578">Nakaraang row ng talahanayan</translation>
-<translation id="4736221692378411923">Agosto</translation>
-<translation id="4740661827607246557">Mga Command ng Tulong</translation>
-<translation id="4759716709594980008">ChromeOS Keyboard Explorer</translation>
-<translation id="4763296182459741068">Naka-wrap sa ibaba</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Ianunsyo ang pamagat ng kasalukuyang page</translation>
-<translation id="4826415162591436065">Mag-navigate pasulong</translation>
-<translation id="4826604887384865800">Susunod na paglaktaw</translation>
-<translation id="4827410568042294688">hindi napili</translation>
-<translation id="4842108708071771135">Walang susunod na blockquote.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Nakaraang katulad na elemento.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">I-enable ang pagtatalang TTS</translation>
-<translation id="4877261390094455813">Maglagay ng query sa paghahanap.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Internal na link</translation>
-<translation id="4953585991029886728">I-edit ang text</translation>
-<translation id="4954534434583049121">Nakaraang block quote</translation>
-<translation id="4973717656530883744">Min <ph name="X" /></translation>
-<translation id="4973762002207131920">Lumipat sa <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">mga millisecond</translation>
-<translation id="49787999531187221">Hindi na aktibo ngayon ang ChromeVox.</translation>
-<translation id="4979404613699303341">Nakaraang button</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, kahon ng listahan</translation>
-<translation id="4983588134362688868">Pumunta sa itaas ng page</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, window</translation>
-<translation id="4993152509206108683"><ph name="PERCENT" /> (na) porsyento ang rate</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877">Pinili ang <ph name="NAME" />, radio button</translation>
-<translation id="4997475792277222884">Walang susunod na item na hindi isang link.</translation>
-<translation id="5000760171916499057">Walang mga form.</translation>
-<translation id="5005670136041063723">Wala nang mga katulad na elemento.</translation>
-<translation id="501473567976723023">Enero</translation>
-<translation id="5041394372352067729">Ilipat ang display ng braille sa itaas ng page</translation>
-<translation id="5042770794184672516">Lakasan ang volume ng speech</translation>
-<translation id="5050015258024679800">Nakaraang heading sa antas 4</translation>
-<translation id="5054047268577924192">Nakaraang item sa listahan</translation>
-<translation id="5078661581131202757">Pagpili ng file</translation>
-<translation id="5080758118274074384">na-double click</translation>
-<translation id="5098541983634824365">Umaalis sa grid.</translation>
-<translation id="5102981729317424850">Tool bar</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Walang nakaraang field ng form.</translation>
-<translation id="5111640677200759579">Header ng column</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Walang nakaraang link.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, hindi napili</translation>
-<translation id="5183440668879371625">Nakaraang Linya ng Braille</translation>
-<translation id="5184944171021383281">Walang susunod na field ng form.</translation>
-<translation id="5189244881767082992">Linya</translation>
-<translation id="5203930734796605961">Ang <ph name="KEY" /> ay nakatakda na sa isang command.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> na listahan.</translation>
-<translation id="520883772648104506">Walang susunod na radio button.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Wakas na</translation>
-<translation id="5291783959063340370">Bagay</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, tab</translation>
-<translation id="5310788376443009632">inalis:</translation>
-<translation id="5320727453979144100">Na-enable ang sticky mode</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{kuwit}one{# kuwit}other{# na kuwit}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, text box</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Lumaktaw pabalik habang patuloy na nagbabasa</translation>
-<translation id="5368000168321181111">Naka-off ang mga earcon</translation>
-<translation id="5374320867641260420">Walang susunod na button.</translation>
-<translation id="5382299583965267720">Walang susunod na heading sa antas 1.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{semicolon}one{# semicolon}other{# na semicolon}}</translation>
-<translation id="5411891038905756502">Walang nakaraang jump point.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{less than}one{# less than sign}other{# na less than sign}}</translation>
-<translation id="5455441614648621694">Complementary</translation>
-<translation id="5485036206801896268">Walang nakaraang graphic.</translation>
-<translation id="5486947920110100234">Walang susunod na jump point.</translation>
-<translation id="549602578321198708">Salita</translation>
-<translation id="5500932716852106146">Walang nakaraang na-e-edit na field ng text.</translation>
-<translation id="5502713021410870035">Setyembre</translation>
-<translation id="5507663321906818013">I-debug ang benchmark</translation>
-<translation id="5518443085409638729">Ilagay ang cursor sa pagitan ng mga character kapag nag-e-edit ng text (tulad ng Mac OS X).</translation>
-<translation id="552195134157544755">Radio button</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Walang nakaraang heading sa antas 5.</translation>
-<translation id="556042886152191864">Pindutan</translation>
-<translation id="5561345396546889625">Susunod na listahan</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">I-edit ang text, entry ng email</translation>
-<translation id="5597170376237141345">Susunod na checkbox</translation>
-<translation id="5597933780944041114">Walang susunod na heading.</translation>
-<translation id="5598905979683743333">Inalis sa pagkakapili ang <ph name="NAME" />, radio button</translation>
-<translation id="5601172225407283979">Magsagawa ng default na pagkilos</translation>
-<translation id="5608798115546226984">Inline ng autocompletion</translation>
-<translation id="561939826962581046">oras</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Log</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Walang nakaraang talahanayan.</translation>
-<translation id="5655682562155942719">Mga Command sa Paglaktaw</translation>
-<translation id="56637627897541303">Lugar ng text</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Landmark</translation>
-<translation id="5683155931978483559">Nakaraang checkbox</translation>
-<translation id="5684277895745049190">Listahan</translation>
-<translation id="5700650669149824506">Walang nakaraang heading sa antas 4.</translation>
-<translation id="5709192780268610569">Walang mahabang paglalarawan</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Susunod na column ng talahanayan</translation>
-<translation id="571866080859340309">Nag-e-explore ng mga pangkat</translation>
-<translation id="5728409797179002635">Walang nakitang talahanayan.</translation>
-<translation id="5748623122140342504">Nakaraang heading sa antas 5</translation>
-<translation id="5750633686117194034">Walang pinindot na modifier; mangyaring pindutin nang matagal ang isa o higit pang mga modifier; iangat ang iyong mga daliri kapag tapos na at maririnig mo ang pagtakda sa mga key. Mag-tap upang lumabas.</translation>
-<translation id="5788275253279308023">tab na <ph name="TITLE" /> ng incognito window</translation>
-<translation id="5806206155699461681">Magpahusay ng mga partikular na site (tulad ng Google Search).</translation>
-<translation id="5819072574982403430">Tree item</translation>
-<translation id="5826479389509458994">row <ph name="ROW" /> column <ph name="COL" /></translation>
-<translation id="5850707923114094062">Mag-pan nang pabalik</translation>
-<translation id="5851548754964597211">Listahan ng tab</translation>
-<translation id="5859752971144398932">Lumabas sa hanapin sa page.</translation>
-<translation id="5866042630553435010">Bahagyang nilagyan ng check</translation>
-<translation id="5869546221129391014">Grid</translation>
-<translation id="5876817486144482042">Hinaan ang volume ng speech</translation>
-<translation id="5887397643266327462">Na-enable ang mga caption ng braille.</translation>
-<translation id="5891934789323004067">Talahanayan</translation>
-<translation id="5919442531159595654">kopyahin.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{equal}one{# equal sign}other{# na equal sign}}</translation>
-<translation id="5939518447894949180">I-reset</translation>
-<translation id="5948123859135882163">I-toggle ang pag-interpret sa mga math expression sa pagitan ng structural at semantic</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialog</translation>
-<translation id="5963413905009737549">Seksyon</translation>
-<translation id="5968607524793740041">Ipakita ang menu ng konteksto</translation>
-<translation id="5983179082906765664">Paramihin ang granularity ng nabigasyon</translation>
-<translation id="5999630716831179808">Mga Boses</translation>
-<translation id="6000417740266304866">Palitan ang kasalukuyang talahanayan ng 8 dot braille sa pamamagitan ng pagpili ng opsyon sa listahan sa ibaba.</translation>
-<translation id="6006050241733874051">Form</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{backslash}one{# backslash}other{# na backslash}}</translation>
-<translation id="6037602951055904232">I-pan paharap</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Dulo ng cell.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Puwang</translation>
-<translation id="6142308968191113180">Heading 4</translation>
-<translation id="6169420925157477918">Larawang may mahabang paglalarawan</translation>
-<translation id="6172087735260766220">Hindi ma-access ang naa-access na text mula sa PDF na naka-copy protect.</translation>
-<translation id="6186305613600865047">Pumunta sa ibaba ng page</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Down</translation>
-<translation id="6236061028292614533">Susunod na heading</translation>
-<translation id="6254901459154107917">Susunod na na-e-edit na lugar ng text</translation>
-<translation id="6259464875943891919">Lumabas sa <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Susunod na katulad na elemento.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Walang susunod na combo box.</translation>
-<translation id="6307969636681130414">Pinindot</translation>
-<translation id="6324551002951139333">Nakakita ng pagkakamali sa grammar</translation>
-<translation id="6348657800373377022">Combo box</translation>
-<translation id="6355910664415701303">Walang nakaraang item sa listahan.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Nakaraang heading</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Walang nakaraang radio button.</translation>
-<translation id="6414968628640960377">Nakaraang naiibang elemento.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{tutuldok}one{# tutuldok}other{# na tutuldok}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Dialog ng alerto</translation>
-<translation id="6459511626086141404">Flat na keymap</translation>
-<translation id="6468049171101508116">Susunod na button</translation>
-<translation id="6491972999578897419">Palitan ang kasalukuyang boses sa pamamagitan ng pagpili ng opsyon sa listahan sa ibaba.</translation>
-<translation id="6508059270146105198">Ilipat ang display ng braille sa ibaba ng page</translation>
-<translation id="6536864053412760904">Math ML Token</translation>
-<translation id="6550720799683018100">Palitan ang kasalukuyang keymap sa pamamagitan ng pagpili ng opsyon sa listahan sa ibaba.</translation>
-<translation id="6561818612645211875">Pumunta sa umpisa ng kasalukuyang row</translation>
-<translation id="6587021927234520429">Walang susunod na heading sa antas 4.</translation>
-<translation id="6601344353291556895">I-enable ang mga masalitang paglalarawan.</translation>
-<translation id="6615602925644411249">Hanapin sa page.</translation>
-<translation id="6633350132811819843">Walang susunod na talahanayan.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Progress bar</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Dokumento</translation>
-<translation id="6697092096875747123">Nakaraang combo box</translation>
-<translation id="6714813999819678458">Nakaraang heading sa antas 2</translation>
-<translation id="6716505898850596801">Mga modifier key</translation>
-<translation id="671916444866103745">Walang susunod na landmark ng ARIA.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, combo box</translation>
-<translation id="6735257939857578167">may <ph name="NUM" /> (na) item</translation>
-<translation id="6736510033526053669">nagawa ang tab</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artikulo</translation>
-<translation id="6787839852456839824">Mga keyboard shortcut</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Footer</translation>
-<translation id="6871161210040114857">Binabalewala ang case.</translation>
-<translation id="6877435256196695200">Walang susunod na graphic.</translation>
-<translation id="6897341342232909480">Ilipat pakaliwa</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Na-delete</translation>
-<translation id="6911965441508464308">Walang cell sa itaas.</translation>
-<translation id="6919104639734799681">Ipakita ang listahan ng mga talahanayan</translation>
-<translation id="6964088412282673743">Walang nakaraang kontrol.</translation>
-<translation id="6996566555547746822">Susunod na combo box</translation>
-<translation id="7005146664810010831">Walang nakitang URL</translation>
-<translation id="7010712454773919705">Modifier key ng ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Nakaraang listahan</translation>
-<translation id="7041173719775863268">Tapusin ang pagpili</translation>
-<translation id="7095834689119144465">I-edit lang ang text numeric</translation>
-<translation id="7096001299300236431">Nakaraang media</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">echo ng salita</translation>
-<translation id="713824876195128146">Susunod na block quote</translation>
-<translation id="7161771961008409533">Pop-up na button</translation>
-<translation id="7167657087543110">echo ng character</translation>
-<translation id="7170733337935166589">Lumaktaw pasulong habang patuloy na nagbabasa</translation>
-<translation id="7181697990050180700">Mag-customize ng mga keyboard shortcut para sa mga madalas na ginagamit na command sa pamamagitan ng pagta-type sa mga ito sa mga kaukulang field sa ibaba.</translation>
-<translation id="7203150201908454328">Pinalawak</translation>
-<translation id="7210211103303402262">mga minuto</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">linya</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Heading</translation>
-<translation id="7241683698754534149">Magbukas ng mahabang paglalarawan sa isang bagong tab</translation>
-<translation id="7248671827512403053">Application</translation>
-<translation id="725969808843520477">Susunod na radio button</translation>
-<translation id="7269119382257320590">Walang bantas</translation>
-<translation id="7273174640290488576">Blangko</translation>
-<translation id="7285387653379749618">Mga Talahanayan</translation>
-<translation id="7289186959554153431">Heading 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Na-disable ang mga caption ng braille.</translation>
-<translation id="7318872822751139669">Gamitin ang mouse upang palitan ang focus.</translation>
-<translation id="7322388933135261569">Pebrero</translation>
-<translation id="7332592614823088566">Row <ph name="ROWINDEX" /> ng <ph name="ROWTOTAL" />, Column <ph name="COLINDEX" /> ng <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">may popup</translation>
-<translation id="7356165926712028380">Lumipat sa 8 dot braille</translation>
-<translation id="7362871137496673139">Walang nakaraang heading sa antas 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersand}one{# ampersand}other{# na ampersand}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Umaalis sa talahanayan.</translation>
-<translation id="739763518212184081">Nakaraang Linya</translation>
-<translation id="7400575256015741911">Nakakita ng pagkakamali sa spelling</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">return</translation>
-<translation id="7434509671034404296">Bumubuo</translation>
-<translation id="7439060726180460871">Direktoryo</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Naglagay ng dialog</translation>
-<translation id="7532613204005497612">Hunyo</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, slider</translation>
-<translation id="7586163296341959563">i-paste.</translation>
-<translation id="7596919493010894443">na-clear ang pagpili</translation>
-<translation id="7604026522577407655">Pumunta sa umpisa ng kasalukuyang column</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Ianunsyo ang URL ng kasalukuyang page</translation>
-<translation id="7609363189280667021">I-toggle ang mga caption na braille</translation>
-<translation id="762020119231868829">Pino-pause ang lahat ng kasalukuyang nagpe-play na widget ng media</translation>
-<translation id="7625690649919402823">Susunod na talahanayan</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Antas <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Walang nakaraang heading sa antas 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, text box</translation>
-<translation id="7663318257180412551">Heading 2</translation>
-<translation id="7674576868851035240">Susunod na link</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">I-edit ang text, entry ng URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Nakaraang radio button</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, text box ng password</translation>
-<translation id="7805247615045262757">default na pag-navigate</translation>
-<translation id="7805768142964895445">Katayuan</translation>
-<translation id="7810781339813764006">Susunod na Pangkat</translation>
-<translation id="7819187121850078213">tab na <ph name="TITLE" /> ng window</translation>
-<translation id="7828956995407538686">Oktubre</translation>
-<translation id="7839679365527550018">Nakaraang Salita</translation>
-<translation id="7851816175263618915">Ilang bantas</translation>
-<translation id="7870596830398826354">Math ML Tree</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">I-toggle ang classic na ChromeVox.</translation>
-<translation id="7895896691902835279">Hindi alam na link</translation>
-<translation id="7927711904086083099">Hindi napili</translation>
-<translation id="7935627501098484003">Kontrol sa oras</translation>
-<translation id="7939428177581522200">idinagdag sa pagpili</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{at}one{# at sign}other{# na at sign}}</translation>
-<translation id="7965147473449754028">isinara ang menu</translation>
-<translation id="7974390230414479278">Item sa menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{tandang padamdam}one{# tandang padamdam}other{# na tandang padamdam}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{panipi}one{# panipi}other{# na panipi}}</translation>
-<translation id="8033827949643255796">pinili</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">I-edit ang text, entry ng paghahanap</translation>
-<translation id="8049189770492311300">Timer</translation>
-<translation id="8065607967589909823">Ang pagpipilian ay</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Walang mga landmark ng ARIA.</translation>
-<translation id="8153880621934657047">Wala sa loob ng talahanayan.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{underscore}one{# underscore}other{# na underscore}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">i-cut.</translation>
-<translation id="8199231515320852133">Ianunsyo ang mga header ng kasalukuyang cell</translation>
-<translation id="820417203470636242">Walang lamang cell.</translation>
-<translation id="8215202828671303819">Maramihang pagpili</translation>
-<translation id="8276439074553447000">Lumaktaw sa nakaraang napo-focus na item</translation>
-<translation id="8278417001922463147">Walang nakaraang artikulo.</translation>
-<translation id="8283603667300770666">Susunod na field ng form</translation>
-<translation id="831207808878314375">Kahulugan</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">mga oras</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{pound}one{# pound sign}other{# na pound sign}}</translation>
-<translation id="8374154622594089836">buwan</translation>
-<translation id="8378855320830505539">Rehiyon</translation>
-<translation id="8382679411218029383">Inline at listahan ng autocompletion</translation>
-<translation id="8428603554127842284">antas <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Walang susunod na heading sa antas 3.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Walang nakaraang checkbox.</translation>
-<translation id="8455868257606149352">Max <ph name="X" /></translation>
-<translation id="84575901236241018">may access key, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Bawasan ang granularity ng nabigasyon</translation>
-<translation id="8520472399088452386">Spin button</translation>
-<translation id="8538744478902126321">Maglagay ng hula sa header ng row ng kasalukuyang cell</translation>
-<translation id="8540054775867439484">Naka-wrap sa itaas</translation>
-<translation id="8548973727659841685">Character</translation>
-<translation id="8561322612995434619">may pop up</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Susunod na item sa listahan</translation>
-<translation id="860150890330522909">Nilagyan ng check ang checkbox na <ph name="NAME" /></translation>
-<translation id="8606621670302093223">Kontrol sa petsa</translation>
-<translation id="8631359288236106450">napili ang <ph name="COUNT" /> (na) item</translation>
-<translation id="8638532244051952400">Ianunsyo ang mga kasalukuyang cell coordinate</translation>
-<translation id="8650576015643545550">Walang nakaraang listahan.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Ipakita ang listahan ng mga link</translation>
-<translation id="8664519043722036194">mga segundo</translation>
-<translation id="867187640362843212">Heading 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{pipe}one{# vertical pipe}other{# na vertical pipe}}</translation>
-<translation id="8735450637152821465">Simulan ang pagpili</translation>
-<translation id="8743786158317878347">maglagay ng nakabalangkas na nilalaman, gaya ng mga talahanayan</translation>
-<translation id="8747966237988593539">Nakaayos na Listahan</translation>
-<translation id="8759334257841767240">Walang susunod na link.</translation>
-<translation id="8767968232364267681">Susunod na heading sa antas 4</translation>
-<translation id="8770473310765924354">lumabas sa nakabalangkas na nilalaman, gaya ng mga talahanayan</translation>
-<translation id="8791025954632646584">Naka-on ang semantics</translation>
-<translation id="8796411681063377102">Susunod na heading sa antas 3</translation>
-<translation id="8808582214901541005">Marso</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Pindutin ang up o down upang suriin ang mga command, pindutin ang enter upang i-activate</translation>
-<translation id="8864099967139188018">Walang susunod na heading sa antas 6.</translation>
-<translation id="8882002077197914455">Header ng row</translation>
-<translation id="8896347895970027998">I-toggle sa aktibo o hindi aktibo ang ChromeVox.</translation>
-<translation id="8898516272131543774">Echo ng cycle punctuation</translation>
-<translation id="8900148057318340779">Prefix key</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Mga walang lamang header</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Mga Modifier Key</translation>
-<translation id="8943175951035496220">Walang cell sa kanan.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Walang mga talahanayan.</translation>
-<translation id="9040132695316389094">Heading 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">I-toggle ang widget ng paghahanap</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">inalis sa pagpili</translation>
-<translation id="9082874451376019682">Walang nakaraang slider.</translation>
-<translation id="9089864840575085222">Echo ng cycle typing</translation>
-<translation id="9107530006868467849">Walang nakaraang widget ng media.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{percent}one{# percent sign}other{# na percent sign}}</translation>
-<translation id="9115913704608474258">Nobyembre</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Nag-aanunsyo ng maikling paglalarawan sa kasalukuyang posisyon</translation>
-<translation id="9153606228985488238"><ph name="PERCENT" /> (na) porsyento ang pitch</translation>
-<translation id="9160096769946561184">Pumunta sa dulo ng kasalukuyang column</translation>
-<translation id="9173115498289768110"><ph name="PERCENT" /> (na) porsyento ang volume</translation>
-<translation id="9178973770513562274">Gamitin ang mga up at down arrow key upang mag-browse, o mag-type upang maghanap.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">Walang susunod na seksyon.</translation>
-<translation id="930275611743429116">Simulan o tapusin ang pagpili.</translation>
-<translation id="948171205378458592">Bawasan ang rate ng speech</translation>
-<translation id="962913030769097253">Susunod na heading sa antas 1</translation>
-<translation id="973955474346881951">I-enable/I-disable ang sticky mode</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fr.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fr.xtb
deleted file mode 100644
index cdeb4bc71cb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fr.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="fr">
-<translation id="1012173283529841972">Élément de liste</translation>
-<translation id="1013742170491673792">recherche</translation>
-<translation id="1023866615269196768">Cellule fractionnée</translation>
-<translation id="1025074108959230262">Mode permanent désactivé</translation>
-<translation id="1031961866430398710">puis</translation>
-<translation id="1044777062731150180">Aucun en-tête</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Données incorrectes</translation>
-<translation id="1082209053475788238">Aucun titre de niveau 6 précédent</translation>
-<translation id="1088219014394087294">Aucun titre</translation>
-<translation id="1106741348836243114">Activer ou désactiver les commentaires audio (icônes audio)</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Collection de <ph name="TAG" /> avec <ph name="NUM" /> éléments</translation>
-<translation id="1155043339247954670">Aucun élément de liste suivant</translation>
-<translation id="1157782847298808853">Aide du clavier</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, liste déroulante</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, élément de menu comportant un sous-menu</translation>
-<translation id="1177863135347784049">Personnalisé</translation>
-<translation id="1188858454923323853">complémentaire</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox donne la parole à Google Chrome.</translation>
-<translation id="1229276918471378188">Renvoi précédent</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">En-tête suivant de niveau 6</translation>
-<translation id="1275718070701477396">Sélectionnée</translation>
-<translation id="1319608975892113573">Aucune balise blockquote précédente</translation>
-<translation id="1321576897702511272">Masquer l'aide ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> sur <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">écho des caractères et des mots</translation>
-<translation id="1339428534620983148">Colonne précédente du tableau</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Vers la droite</translation>
-<translation id="136718599399906424">Ligne suivante du tableau</translation>
-<translation id="1383876407941801731">Rechercher</translation>
-<translation id="1385214448885562192">Appuyez sur Entrée pour accepter ou Échap pour annuler. Passez au résultat suivant à l'aide de la flèche vers le bas et revenez au résultat précédent à l'aide de la flèche vers le haut.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">région</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, zone de texte du mot de passe</translation>
-<translation id="1467432559032391204">Vers la gauche</translation>
-<translation id="1474557363159888097">Aucun ancrage précédent</translation>
-<translation id="1502086903961450562">Élément graphique précédent</translation>
-<translation id="1506187449813838456">Augmenter le timbre de la voix</translation>
-<translation id="151784044608172266">Phrase suivante</translation>
-<translation id="1524531499102321782">Ligne suivante (braille)</translation>
-<translation id="1546370775711804143">Barre de défilement</translation>
-<translation id="1559739829547075274">Navigation vers le haut</translation>
-<translation id="1571643229714746283">ChromeVox est prêt.</translation>
-<translation id="158493514907962286">Décembre</translation>
-<translation id="1594072653727561613">menu</translation>
-<translation id="1610130962244179598">Passer au braille à six points</translation>
-<translation id="1611168825862729585">En-tête de colonne :</translation>
-<translation id="1613476421962910979">Icônes audio activées</translation>
-<translation id="1618597272655350600">Énonce la description complète de la position actuelle.</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{signe supérieur à}one{# signe supérieur à}other{# signes supérieur à}}</translation>
-<translation id="1653266918374749391">En-tête précédent de niveau 3</translation>
-<translation id="1659072772017912254">Non cochée</translation>
-<translation id="1669290819662866522">semaine</translation>
-<translation id="1674262202423278359">Navigation ChromeVox</translation>
-<translation id="16777221443363124">Barre des menus</translation>
-<translation id="1692077714702418899">ligne de structure</translation>
-<translation id="1700517974991662022">Consulté</translation>
-<translation id="1722567105086139392">Lien</translation>
-<translation id="1727806147743597030">conclusion</translation>
-<translation id="174268867904053074">Élément graphique suivant</translation>
-<translation id="1781173782405573156">Ignorer la touche</translation>
-<translation id="1787176709638001873">Modifier le texte du mot de passe</translation>
-<translation id="1810107444790159527">Zone de liste</translation>
-<translation id="1828385960365606039">Mai</translation>
-<translation id="1834891354138622109">Colonne</translation>
-<translation id="1865601187525349519">Fin du texte</translation>
-<translation id="1876229593313240038">doc.</translation>
-<translation id="188130072164734898">Énoncer la date et l'heure actuelles</translation>
-<translation id="1902396333223336119">Cellule</translation>
-<translation id="1905379170753160525">Afficher la liste des en-têtes</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Commande relative à la semaine de l'année</translation>
-<translation id="1964135212174907577">Objet suivant</translation>
-<translation id="1969092762068865084">Juillet</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">En-tête de ligne :</translation>
-<translation id="2002895034995108595">Réinitialiser le mappage du clavier actuel</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{crochet gauche}one{# crochet gauche}other{# crochets gauches}}</translation>
-<translation id="2045490512405922022">non cochée</translation>
-<translation id="20601713649439366">Aucune expression mathématique précédente</translation>
-<translation id="207477615537953741">Interprétation sémantique désactivée</translation>
-<translation id="2086961585857038472">Mot suivant</translation>
-<translation id="2089387485033699258">fr</translation>
-<translation id="2091933974477985526">Zone de texte modifiable précédente</translation>
-<translation id="2100350898815792233">Tous les signes de ponctuation</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">touche d'accès : <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Modifiez la table braille actuelle à six points en sélectionnant une option dans la liste ci-dessous.</translation>
-<translation id="2169714232367507776">Cliquer sur l'élément actuel</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{parenthèse fermée}one{# parenthèse fermée}other{# parenthèses fermées}}</translation>
-<translation id="2199994615414171367">Objet Math précédent</translation>
-<translation id="2223693656926968778">Effectuer une action sur l'élément actuel</translation>
-<translation id="225732394367814946">Accélérer la cadence de la voix</translation>
-<translation id="2267945578749931355">Caractère suivant</translation>
-<translation id="2281234842553884450">Curseur précédent</translation>
-<translation id="2318372665160196757">Principal</translation>
-<translation id="2329324941084714723">Panneau tab</translation>
-<translation id="2344193891939537199">Commande relative à la date et à l'heure</translation>
-<translation id="2359897517538099099">Vous n'utilisez pas le mode Tableau.</translation>
-<translation id="241124561063364910">suivi de</translation>
-<translation id="2417569100218200841">Infos sur le contenu</translation>
-<translation id="2422937916923936891">Case à cocher d'élément de menu</translation>
-<translation id="2429669115401274487">p.m.</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> est la nouvelle touche de modification ChromeVox.</translation>
-<translation id="2450814015951372393">Case à cocher</translation>
-<translation id="2462626033734746142">Groupe de cases d'option</translation>
-<translation id="2471138580042810658">Titre 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{astérisque}one{# astérisque}other{# astérisques}}</translation>
-<translation id="2549392850788122959">Le mappage du clavier <ph name="KEY" /> a été réinitialisé.</translation>
-<translation id="2553108862507765288">erreur grammaticale</translation>
-<translation id="257674075312929031">Groupe</translation>
-<translation id="2582407057977008361">Contenu relatif</translation>
-<translation id="2589102159832527089">Cette page contient du texte extrait automatiquement du fichier PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Cliquez ici pour consulter l'original&lt;/a&gt;.</translation>
-<translation id="2606210917827248971">avec {COUNT,plural, =1{1 élément}one{# élément}other{# éléments}}</translation>
-<translation id="2614981083756825552">Mise en page MathML</translation>
-<translation id="2626530649491650971">cliquable</translation>
-<translation id="2628764385451019380">Aucune liste déroulante précédente</translation>
-<translation id="2637227747952042642">Objet Math</translation>
-<translation id="2639750663247012216">Touche de modification ChromeVox</translation>
-<translation id="2644542693584024604">faute d'orthographe</translation>
-<translation id="2667291555398229137">Cliquez sur l'élément sous une clé de routage.</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{parenthèse ouverte}one{# parenthèse ouverte}other{# parenthèses ouvertes}}</translation>
-<translation id="2705875883745373140">Non appuyé</translation>
-<translation id="2706462751667573066">Haut</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">a.m.</translation>
-<translation id="2749275490991666823">Cochée</translation>
-<translation id="27527859628328957">Renvoyer à l'élément suivant pouvant être agrandi</translation>
-<translation id="2770781857296573485">Passer en mode d'exploration par groupe</translation>
-<translation id="2777845298774924149">Fermé</translation>
-<translation id="2800204403141299078">Aucun autre élément différent</translation>
-<translation id="2800780099804980316">Aucun titre de niveau 1 précédent</translation>
-<translation id="2811204574343810641">Ligne</translation>
-<translation id="2816654101880605877">Aucun curseur suivant</translation>
-<translation id="2841013758207633010">Heure</translation>
-<translation id="2843837985843789981">Groupe précédent</translation>
-<translation id="2844995807198708617">Menu contextuel</translation>
-<translation id="2849332794118375855">Aucune case à cocher suivante</translation>
-<translation id="2864481629947106776">Lien précédent</translation>
-<translation id="2873259058405069099">Accéder au début du tableau</translation>
-<translation id="2894654529758326923">Informations</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{accolade gauche}one{# accolade gauche}other{# accolades gauches}}</translation>
-<translation id="2911433807131383493">Ouvrir le didacticiel ChromeVox</translation>
-<translation id="2932083475399492303">Changer de type de ligne (ligne de structure et ligne de mise en page)</translation>
-<translation id="2964026537669811554">Titre de groupe</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulation}one{# tabulation}other{# tabulations}}</translation>
-<translation id="2972078295414139404">Aucun lien consulté précédent</translation>
-<translation id="2972205263822847197">Info-bulle</translation>
-<translation id="2998131015536248178">Caractère précédent</translation>
-<translation id="2999559350546931576">Diminuer le timbre de la voix</translation>
-<translation id="2999945368667127852">Aucun widget de contenu multimédia suivant</translation>
-<translation id="3012414509011670858">Aucune section précédente</translation>
-<translation id="3030432017085518523">Case d'option d'élément de menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrophe}one{# apostrophe}other{# apostrophes}}</translation>
-<translation id="3046838483509668188">Options ChromeVox</translation>
-<translation id="3047143736589213134">Mappage expérimental du clavier</translation>
-<translation id="3060756054951570867">menu <ph name="TITLE" /> ouvert</translation>
-<translation id="3078345202707391975">En-tête suivant de niveau 2</translation>
-<translation id="3078740164268491126">tableau</translation>
-<translation id="3082557070674409251">Élément sur lequel vous avez cliqué</translation>
-<translation id="3084806535845658316">aucun écho de saisie</translation>
-<translation id="3086746722712840547">remarque</translation>
-<translation id="308895241372589742">Aucune expression mathématique suivante.</translation>
-<translation id="3090532668523289635">groupe</translation>
-<translation id="3093176084511590672">Repère suivant</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">boîte dialogue alerte</translation>
-<translation id="3109724472072898302">Réduit</translation>
-<translation id="3134461040845705080">lecture seule</translation>
-<translation id="3138767756593758860">Afficher la liste des repères</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Ligne suivante</translation>
-<translation id="3155083529632865074">Aucun bouton précédent</translation>
-<translation id="3163593631834463955">En-tête de colonne vide</translation>
-<translation id="316542773973815724">Navigation</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{espace}one{# espace}other{# espaces}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> saisi</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, onglet</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Lien consulté</translation>
-<translation id="323731244387692321">Ouvrir l'aide du clavier ChromeVox</translation>
-<translation id="3241052487511142956">Lien consulté précédent</translation>
-<translation id="3286390186030710347">Curseur</translation>
-<translation id="3299925995433437805">Aucun lien consulté suivant.</translation>
-<translation id="3303384412438961941">Appuyez sur n'importe quelle touche pour connaître son nom. Ctrl + W permet de fermer l'explorateur du clavier.</translation>
-<translation id="3307886118343381874">Accéder à la fin du tableau</translation>
-<translation id="3311969765485641742">Appuyez sur Alt + Maj + A pour examiner les alertes.</translation>
-<translation id="3312997241656799641">Lien consulté suivant</translation>
-<translation id="3321460131042519426">Enable word wrap</translation>
-<translation id="3322936298410871309">En-tête précédent de niveau 1</translation>
-<translation id="3323447499041942178">Zone de saisie</translation>
-<translation id="3353420241558113817">{"ar": "Arabe",
- "bg": "Bulgare",
- "ca": "Catalan",
- "cs": "Tchèque",
- "da": "Danois",
- "de": "Allemand",
- "de_CH": "Allemand (Suisse)",
- "de_DE": "Allemand (Allemagne)",
- "el": "Grec",
- "en": "Anglais",
- "en_CA": "Anglais (Canada)",
- "en_GB": "Anglais (Royaume-Uni)",
- "en_US": "Anglais (États-Unis)",
- "es": "Espagnol",
- "et": "Estonien",
- "fr": "Français",
- "fr_CA": "Français (Canada)",
- "fr_FR": "Français (France)",
- "fi": "Finnois",
- "he": "Hébreu",
- "hi": "Hindi",
- "hr": "Croate",
- "hu": "Hongrois",
- "is": "Islandais",
- "it": "Italien",
- "ko": "Coréen",
- "lt": "Lituanien",
- "lv": "Letton",
- "nb": "Norvégien bokmål",
- "nl": "Néerlandais",
- "pl": "Polonais",
- "pt": "Portuguais",
- "ro": "Roumain",
- "ru": "Russe",
- "sk": "Slovaque",
- "sl": "Slovène",
- "sr": "Serbe",
- "sv": "Suédois",
- "tr": "Turc",
- "vi": "Vietnamien",
- "zh": "Chinois",
- "zh_TW": "Chinois (traditionnel han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{signe plus}one{# signe plus}other{# signes plus}}</translation>
-<translation id="338583716107319301">Séparateur</translation>
-<translation id="3389259863310851658">Champ de formulaire précédent</translation>
-<translation id="3390225400784126843">Élément différent suivant</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, élément de menu</translation>
-<translation id="3406283310380167331">Afficher la liste des formulaires</translation>
-<translation id="3422338090358345848">Ouvrir l'explorateur du clavier</translation>
-<translation id="3457000393508828486">Partiellement sélectionné</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, bouton</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> slct</translation>
-<translation id="3486232535569802404"><ph name="V1" /> à <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{crochet droit}one{# crochet droit}other{# crochets droits}}</translation>
-<translation id="3493915602752813531">Aucun ancrage suivant</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{point d'interrogation}one{# point d'interrogation}other{# points d'interrogation}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{caret}one{# caret}other{# carets}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, case non cochée</translation>
-<translation id="3599054940393788245">En dehors de l'expression mathématique</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{apostrophe inversée}one{# apostrophe inversée}other{# apostrophes inversées}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollar}one{# dollar}other{# dollars}}</translation>
-<translation id="3659787053479271466">alerte</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, zone de liste.</translation>
-<translation id="3687295507293856493">Faire une proposition au niveau de l'en-tête de colonne de la cellule actuelle</translation>
-<translation id="3692274950075847560">R : <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Contrôle de la voix</translation>
-<translation id="3716845769494773620">Multiligne</translation>
-<translation id="3731746171184829332">Aucun titre précédent</translation>
-<translation id="3762198587642264450">Aller à la fin de la ligne actuelle</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Vous avez quitté la boîte de dialogue.</translation>
-<translation id="3795836767122514678">et{COUNT,plural, =1{# autre}one{# autre}other{# autres}}</translation>
-<translation id="3801735343383419236">Saisie semi-automatique sous forme de liste</translation>
-<translation id="3810838688059735925">Vidéo</translation>
-<translation id="3816633764618089385">Contenu multimédia suivant</translation>
-<translation id="3819376190738087562">Aucun renvoi</translation>
-<translation id="385383972552776628">Ouvrir la page d'options</translation>
-<translation id="3856075812838139784">Lecture seule</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">En-tête précédent de niveau 6</translation>
-<translation id="3914173277599553213">Obligatoire</translation>
-<translation id="3962990492275676168">Démarrer la description audio à partir de l'emplacement actuel</translation>
-<translation id="4004802134384979325">cochée</translation>
-<translation id="4006140876663370126">image</translation>
-<translation id="4038349100599457191">Commande relative au mois</translation>
-<translation id="4039983576244166038">En-tête de ligne vide</translation>
-<translation id="4042843249978639960">Aucun titre de niveau 2 suivant</translation>
-<translation id="4043348641337972076">Aucun repère ARIA précédent</translation>
-<translation id="4047216625641135770">Surlignage</translation>
-<translation id="404803211695627272"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="4054936709456751127">statut</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}one{# tilde}other{# tildes}}</translation>
-<translation id="409334809956508737">Objet précédent</translation>
-<translation id="4099274309791143834">avec sous-menu</translation>
-<translation id="4107807507418787238">Aucune cellule au-dessous</translation>
-<translation id="4116415223832267137">Alerte</translation>
-<translation id="4147126331795725888">Aucune commande suivante.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{accolade droite}one{# accolade droite}other{# accolades droites}}</translation>
-<translation id="4158704014418536539">Sensible à la casse</translation>
-<translation id="4161663686871496107">La fonctionnalité de commentaires audio ChromeVox est prête.</translation>
-<translation id="4173994908659439270">Aucun champ de texte modifiable suivant</translation>
-<translation id="4176463684765177261">Désactivé</translation>
-<translation id="4188530942454211480">Phrase précédente</translation>
-<translation id="4202186506458631436">Déplacer vers la droite</translation>
-<translation id="4206289001967551965">Dans le tableau</translation>
-<translation id="4215733775853809057">Curseur suivant</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{tiret}one{# tiret}other{# tirets}}</translation>
-<translation id="421884353938374759">palette couleurs</translation>
-<translation id="4229646983878045487">date heure</translation>
-<translation id="423334822609210999">Aucune cellule à gauche</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, catégorie <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Remarque</translation>
-<translation id="4254798249533888099">Arborescence</translation>
-<translation id="4255943572433203166">Utilisez les options ci-dessous pour personnaliser ChromeVox. Les modifications prendront effet immédiatement.</translation>
-<translation id="4271220233568730077">Objet Math suivant</translation>
-<translation id="4271521365602459209">Aucun autre résultat</translation>
-<translation id="4287520460805643128">Aucun article suivant</translation>
-<translation id="4289540628985791613">Présentation</translation>
-<translation id="4300318234632215983">Énoncer l'URL du lien</translation>
-<translation id="4301352596632316575">avec sous-menu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{point}=3{points de suspension}one{# point}other{# points}}</translation>
-<translation id="4347461890115250064">Aucune liste suivante</translation>
-<translation id="4367650418938037324">Feuille MathML</translation>
-<translation id="4372435075475052704">min. : <ph name="X" /></translation>
-<translation id="4372705107434148843">Arrêter la diffusion vocale</translation>
-<translation id="4373197658375206385">Aucun élément précédent autre qu'un lien</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">réinitialiser</translation>
-<translation id="4471074325120394300">Aucun lien</translation>
-<translation id="4476183483923481720">Nouvelle ligne</translation>
-<translation id="4482330759234983253">Tableau précédent</translation>
-<translation id="4491109536499578614">Image</translation>
-<translation id="4529987814483543472">Mappage classique du clavier</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{barre oblique}one{# barre oblique}other{# barres obliques}}</translation>
-<translation id="4547556996012970016">En-tête suivant de niveau 5</translation>
-<translation id="4562381607973973258">En-tête</translation>
-<translation id="4591507479202817876">, sélectionné</translation>
-<translation id="4597532268155981612">formulaire</translation>
-<translation id="4597896406374528575">Avril</translation>
-<translation id="4615592953348396470">La prochaine touche actionnée sera ignorée.</translation>
-<translation id="461613135510474570">Navigation par phrase</translation>
-<translation id="4647836961514597010">Palette couleurs</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grille</translation>
-<translation id="4693675773662933727">Repère précédent</translation>
-<translation id="4696413482802371445">Aucun titre de niveau 5 suivant</translation>
-<translation id="4729095194763193578">Ligne précédente du tableau</translation>
-<translation id="4736221692378411923">Août</translation>
-<translation id="4740661827607246557">Commandes relatives à l'aide</translation>
-<translation id="4759716709594980008">Explorateur de clavier Chrome OS</translation>
-<translation id="4763296182459741068">Accéder au bas</translation>
-<translation id="4763480195061959176">vidéo</translation>
-<translation id="479989351350248267">rechercher</translation>
-<translation id="481165870889056555">Énoncer le titre de la page actuelle</translation>
-<translation id="4826415162591436065">Navigation vers le bas</translation>
-<translation id="4826604887384865800">Renvoi suivant</translation>
-<translation id="4827410568042294688">désélectionné</translation>
-<translation id="4842108708071771135">Aucun bloc de citation suivant</translation>
-<translation id="4848993367330139335">horloge</translation>
-<translation id="4850023505158945298">Élément similaire précédent</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Activer l'enregistrement de la synthèse vocale dans le journal</translation>
-<translation id="4877261390094455813">Saisissez une requête de recherche.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" /> sur <ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Lien interne</translation>
-<translation id="4953585991029886728">Modifier le texte</translation>
-<translation id="4954534434583049121">Bloc de citation précédent</translation>
-<translation id="4973717656530883744">Minimum <ph name="X" /></translation>
-<translation id="4973762002207131920">Passage au mappage du clavier <ph name="KEY" /> effectué</translation>
-<translation id="4975416682604111799">millisecondes</translation>
-<translation id="49787999531187221">ChromeVox est désormais inactif.</translation>
-<translation id="4979404613699303341">Bouton précédent</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, zone de liste</translation>
-<translation id="4983588134362688868">Revenir en haut de la page</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, fenêtre</translation>
-<translation id="4993152509206108683">Vitesse : <ph name="PERCENT" /> %</translation>
-<translation id="4996716799442435517">Navigation par zone visuelle</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, case d'option sélectionnée</translation>
-<translation id="4997475792277222884">Aucun élément suivant autre qu'un lien</translation>
-<translation id="5000760171916499057">Aucun formulaire</translation>
-<translation id="5005670136041063723">Aucun autre élément similaire</translation>
-<translation id="501473567976723023">Janvier</translation>
-<translation id="5041394372352067729">Déplacer l'écran de braille vers le haut de la page</translation>
-<translation id="5042770794184672516">Augmenter le volume de la voix</translation>
-<translation id="5050015258024679800">En-tête précédent de niveau 4</translation>
-<translation id="5054047268577924192">Élément de liste précédent</translation>
-<translation id="5078661581131202757">Sélection de fichier</translation>
-<translation id="5080758118274074384">Élément sur lequel vous avez double-cliqué</translation>
-<translation id="5098541983634824365">Fermeture de la grille</translation>
-<translation id="5102981729317424850">Barre d'outils</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Aucun champ de formulaire précédent</translation>
-<translation id="5111640677200759579">En-tête de colonne</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Aucun lien précédent</translation>
-<translation id="513774504516943387">lien</translation>
-<translation id="517143700877085897">, désélectionné</translation>
-<translation id="5183440668879371625">Ligne précédente (braille)</translation>
-<translation id="5184944171021383281">Aucun champ de formulaire suivant</translation>
-<translation id="5189244881767082992">Ligne</translation>
-<translation id="5203930734796605961">La touche <ph name="KEY" /> est déjà associée à une commande</translation>
-<translation id="5205493599117157272">Liste <ph name="TYPE" /></translation>
-<translation id="520883772648104506">Aucune case d'option suivante</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Fin</translation>
-<translation id="5291783959063340370">Navigation par objet</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, onglet</translation>
-<translation id="5310788376443009632">Éléments supprimés :</translation>
-<translation id="5320727453979144100">Mode permanent activé</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{virgule}one{# virgule}other{# virgules}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, zone de texte</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, lien</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Retour en arrière en lecture en continu</translation>
-<translation id="5368000168321181111">Icônes audio désactivées</translation>
-<translation id="5374320867641260420">Aucun bouton suivant</translation>
-<translation id="5382299583965267720">Aucun titre de niveau 1 suivant</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{point-virgule}one{# point-virgule}other{# points-virgules}}</translation>
-<translation id="5411891038905756502">Aucun renvoi précédent</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{signe inférieur à}one{# signe inférieur à}other{# signes inférieur à}}</translation>
-<translation id="5455441614648621694">Complémentaire</translation>
-<translation id="5485036206801896268">Aucune image précédente</translation>
-<translation id="5486947920110100234">Aucun renvoi suivant</translation>
-<translation id="549602578321198708">Navigation par mot</translation>
-<translation id="5500932716852106146">Aucun champ de texte modifiable précédent</translation>
-<translation id="5502713021410870035">Septembre</translation>
-<translation id="5507663321906818013">Analyse comparative pour le débogage</translation>
-<translation id="5518443085409638729">Placer le curseur entre les caractères pour modifier le texte (comme dans Mac OS X)</translation>
-<translation id="552195134157544755">Case d'option</translation>
-<translation id="5534303576632885660">titre</translation>
-<translation id="5546092960038624944">Aucun titre de niveau 5 précédent</translation>
-<translation id="556042886152191864">Bouton</translation>
-<translation id="5561345396546889625">Liste suivante</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Retour</translation>
-<translation id="5585044216466955529">Modifier le texte de l'adresse e-mail</translation>
-<translation id="5597170376237141345">Case à cocher suivante</translation>
-<translation id="5597933780944041114">Aucun titre suivant</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, case d'option non sélectionnée</translation>
-<translation id="5601172225407283979">Exécuter l'action par défaut</translation>
-<translation id="5608798115546226984">Saisie semi-automatique intégrée</translation>
-<translation id="561939826962581046">horodatage</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Journal</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Aucun tableau précédent</translation>
-<translation id="5655682562155942719">Commandes d'accès direct</translation>
-<translation id="56637627897541303">Zone de texte</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">déf.</translation>
-<translation id="5682113568322255809">Rep</translation>
-<translation id="5683155931978483559">Case à cocher précédente</translation>
-<translation id="5684277895745049190">Liste</translation>
-<translation id="5700650669149824506">Aucun titre de niveau 4 précédent</translation>
-<translation id="5709192780268610569">Aucune description longue</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Colonne suivante du tableau</translation>
-<translation id="571866080859340309">Exploration par groupe</translation>
-<translation id="5728409797179002635">Aucun tableau trouvé</translation>
-<translation id="5748623122140342504">En-tête précédent de niveau 5</translation>
-<translation id="5750633686117194034">Vous n'avez appuyé sur aucune touche de modification. Veuillez appuyer sur une ou plusieurs d'entre elles, puis relever les doigts. Les touches définies sont alors énoncées. Appuyez sur la touche de tabulation pour quitter.</translation>
-<translation id="5788275253279308023">fenêtre de navigation privée onglet <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Améliorez certains sites (tels que la recherche Google).</translation>
-<translation id="5819072574982403430">Élément d'arborescence</translation>
-<translation id="5826479389509458994">ligne <ph name="ROW" />, colonne <ph name="COL" /></translation>
-<translation id="5850707923114094062">Panoramique arrière</translation>
-<translation id="5851548754964597211">Liste d'onglets</translation>
-<translation id="5859752971144398932">Vous avez quitté la recherche.</translation>
-<translation id="5866042630553435010">Partiellement cochée</translation>
-<translation id="5869546221129391014">Grille</translation>
-<translation id="5876817486144482042">Diminuer le volume de la voix</translation>
-<translation id="5887397643266327462">Sous-titres braille activés</translation>
-<translation id="5891934789323004067">Tableau</translation>
-<translation id="5919442531159595654">copier</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{signe égal}one{# signe égal}other{# signes égal}}</translation>
-<translation id="5939518447894949180">Réinitialiser</translation>
-<translation id="5948123859135882163">Passer de l'interprétation structurelle à l'interprétation sémantique des expressions mathématiques et vice versa</translation>
-<translation id="5955304353782037793">application</translation>
-<translation id="5956928062748260866">Boîte de dialogue</translation>
-<translation id="5963413905009737549">Section</translation>
-<translation id="5968607524793740041">Afficher le menu contextuel</translation>
-<translation id="5983179082906765664">Augmenter la granularité de la navigation</translation>
-<translation id="5999630716831179808">Voix</translation>
-<translation id="6000417740266304866">Modifiez la table braille actuelle à huit points en sélectionnant une option dans la liste ci-dessous.</translation>
-<translation id="6006050241733874051">Formulaire</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{barre oblique inverse}one{# barre oblique inverse}other{# barres obliques inverses}}</translation>
-<translation id="6037602951055904232">Panoramique avant</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Fin de la cellule</translation>
-<translation id="6122013438240733403">bouton</translation>
-<translation id="6129953537138746214">Espace</translation>
-<translation id="6142308968191113180">Titre 4</translation>
-<translation id="6169420925157477918">Image avec une description longue</translation>
-<translation id="6172087735260766220">Impossible d'accéder au texte accessible du fichier PDF protégé contre la copie.</translation>
-<translation id="6186305613600865047">Aller au bas de la page</translation>
-<translation id="6193330012414963395">matin soir</translation>
-<translation id="622484624075952240">Bas</translation>
-<translation id="6236061028292614533">En-tête suivant</translation>
-<translation id="6254901459154107917">Zone de texte modifiable suivante</translation>
-<translation id="6259464875943891919">Vous avez quitté <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Élément similaire suivant</translation>
-<translation id="6282062888058716985">nav.</translation>
-<translation id="6290434000785343030">Aucune liste déroulante suivante</translation>
-<translation id="6307969636681130414">Élément sur lequel vous avez appuyé</translation>
-<translation id="6324551002951139333">erreur grammaticale détectée</translation>
-<translation id="6348657800373377022">Liste déroulante</translation>
-<translation id="6355910664415701303">Aucun élément de liste précédent</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">En-tête précédent</translation>
-<translation id="6387719785439924554">contenu relatif</translation>
-<translation id="6411426777058107714">Aucune case d'option précédente</translation>
-<translation id="6414968628640960377">Élément différent précédent</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{deux-points}one{# deux-points}other{# deux-points}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Boîte de dialogue d'alerte</translation>
-<translation id="6459511626086141404">Mappage plat du clavier</translation>
-<translation id="6468049171101508116">Bouton suivant</translation>
-<translation id="6491972999578897419">Modifiez la voix actuelle en sélectionnant une option dans la liste ci-dessous.</translation>
-<translation id="6508059270146105198">Déplacer l'écran de braille vers le bas de la page</translation>
-<translation id="6536864053412760904">Jeton MathML</translation>
-<translation id="6550720799683018100">Modifiez le mappage actuel du clavier en sélectionnant une option dans la liste ci-dessous.</translation>
-<translation id="6561818612645211875">Accéder au début de la ligne actuelle</translation>
-<translation id="6587021927234520429">Aucun titre de niveau 4 suivant</translation>
-<translation id="6601344353291556895">Activer les descriptions détaillées</translation>
-<translation id="6615602925644411249">Rechercher sur la page</translation>
-<translation id="6633350132811819843">Aucun tableau suivant</translation>
-<translation id="6637586476836377253">journal</translation>
-<translation id="6657128831881431364">Barre de progression</translation>
-<translation id="6659594942844771486">Onglet</translation>
-<translation id="667999046851023355">Document</translation>
-<translation id="6697092096875747123">Liste déroulante précédente</translation>
-<translation id="6714813999819678458">En-tête précédent de niveau 2</translation>
-<translation id="6716505898850596801">Touches de modification</translation>
-<translation id="671916444866103745">Aucun repère ARIA suivant</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, liste déroulante</translation>
-<translation id="6735257939857578167">avec <ph name="NUM" /> éléments</translation>
-<translation id="6736510033526053669">onglet créé</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Article</translation>
-<translation id="6787839852456839824">Raccourcis clavier</translation>
-<translation id="6793101435925451627">zone liste</translation>
-<translation id="6833103209700200188">Pied de page</translation>
-<translation id="6871161210040114857">Insensible à la casse</translation>
-<translation id="6877435256196695200">Aucune image suivante</translation>
-<translation id="6897341342232909480">Déplacer vers la gauche</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Supprimé</translation>
-<translation id="6911965441508464308">Aucune cellule au-dessus</translation>
-<translation id="6919104639734799681">Afficher la liste des tableaux</translation>
-<translation id="6964088412282673743">Aucune commande précédente.</translation>
-<translation id="6996566555547746822">Liste déroulante suivante</translation>
-<translation id="7005146664810010831">Aucune URL trouvée</translation>
-<translation id="7010712454773919705">Touche de modification ChromeVox</translation>
-<translation id="7031651751836475482">élément liste</translation>
-<translation id="7037042857287298941">Liste précédente</translation>
-<translation id="7041173719775863268">Fin de la sélection</translation>
-<translation id="7095834689119144465">Texte de modification (chiffres uniquement)</translation>
-<translation id="7096001299300236431">Contenu multimédia précédent</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">écho des mots</translation>
-<translation id="713824876195128146">Bloc de citation suivant</translation>
-<translation id="7161771961008409533">Bouton pop-up</translation>
-<translation id="7167657087543110">écho des caractères</translation>
-<translation id="7170733337935166589">Avance rapide en lecture en continu</translation>
-<translation id="7181697990050180700">Personnalisez les raccourcis clavier pour les commandes fréquemment utilisées en les saisissant dans les champs correspondants ci-dessous.</translation>
-<translation id="7203150201908454328">Développé</translation>
-<translation id="7210211103303402262">minutes</translation>
-<translation id="7217912842225915592">+ <ph name="NUM" /></translation>
-<translation id="7221740160534240920">ligne</translation>
-<translation id="7226216518520804442">liste</translation>
-<translation id="72393384879519786">Titre</translation>
-<translation id="7241683698754534149">Ouvrir les descriptions longues dans un nouvel onglet</translation>
-<translation id="7248671827512403053">Application</translation>
-<translation id="725969808843520477">Case d'option suivante</translation>
-<translation id="7269119382257320590">Aucun signe de ponctuation</translation>
-<translation id="7273174640290488576">Vide</translation>
-<translation id="7285387653379749618">Tableaux</translation>
-<translation id="7289186959554153431">Titre 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Sous-titres braille désactivés</translation>
-<translation id="7318872822751139669">Utiliser la souris pour sélectionner un autre élément</translation>
-<translation id="7322388933135261569">Février</translation>
-<translation id="7332592614823088566">Ligne <ph name="ROWINDEX" /> sur <ph name="ROWTOTAL" />, colonne <ph name="COLINDEX" /> sur <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">avec fenêtre pop-up</translation>
-<translation id="7356165926712028380">Passer au braille à huit points</translation>
-<translation id="7362871137496673139">Aucun titre de niveau 2 précédent</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{esperluette}one{# esperluette}other{# esperluettes}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Fermeture du tableau</translation>
-<translation id="739763518212184081">Ligne précédente</translation>
-<translation id="7400575256015741911">Faute d'orthographe détectée</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">Retour</translation>
-<translation id="7434509671034404296">Options pour les développeurs</translation>
-<translation id="7439060726180460871">Répertoire</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tabulation</translation>
-<translation id="7492049978501397201">Boîte de dialogue ouverte</translation>
-<translation id="7532613204005497612">Juin</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, curseur</translation>
-<translation id="7586163296341959563">coller</translation>
-<translation id="7596919493010894443">sélection effacée</translation>
-<translation id="7604026522577407655">Accéder au début de la colonne actuelle</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Énoncer l'URL de la page actuelle</translation>
-<translation id="7609363189280667021">Activer/Désactiver les sous-titres en braille</translation>
-<translation id="762020119231868829">Met en veille tous les widgets multimédias en cours d'utilisation</translation>
-<translation id="7625690649919402823">Tableau suivant</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), niveau <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Aucun titre de niveau 3 précédent</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, zone de texte</translation>
-<translation id="7663318257180412551">Titre 2</translation>
-<translation id="7674576868851035240">Lien suivant</translation>
-<translation id="7674768236845044097">surlignage</translation>
-<translation id="7684431668231950609">Modifier le texte de l'URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Case d'option précédente</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, zone de texte du mot de passe</translation>
-<translation id="7805247615045262757">navigation par défaut</translation>
-<translation id="7805768142964895445">État</translation>
-<translation id="7810781339813764006">Groupe suivant</translation>
-<translation id="7819187121850078213">fenêtre onglet <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Octobre</translation>
-<translation id="7839679365527550018">Mot précédent</translation>
-<translation id="7851816175263618915">Certains signes de ponctuation</translation>
-<translation id="7870596830398826354">Arbre MathML</translation>
-<translation id="78826985582142166">crsr</translation>
-<translation id="7894517696028036636">Activer/Désactiver la version classique de ChromeVox</translation>
-<translation id="7895896691902835279">Lien inconnu</translation>
-<translation id="7927711904086083099">Non sélectionné</translation>
-<translation id="7935627501098484003">Contrôle de l'heure</translation>
-<translation id="7939428177581522200">ajouté à la sélection</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{arobase}one{# arobase}other{# arobases}}</translation>
-<translation id="7965147473449754028">menu fermé</translation>
-<translation id="7974390230414479278">Élément de menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{point d'exclamation}one{# point d'exclamation}other{# points d'exclamation}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{guillemet}one{# guillemet}other{# guillemets}}</translation>
-<translation id="8033827949643255796">sélectionné</translation>
-<translation id="8035962149453661158">max. : <ph name="X" /></translation>
-<translation id="8042761080832772327">Modifier le texte de la requête de recherche</translation>
-<translation id="8049189770492311300">Horloge</translation>
-<translation id="8065607967589909823">La sélection est la suivante :</translation>
-<translation id="8066678206530322333">Bannière</translation>
-<translation id="8110647606445335195">Aucun repère ARIA</translation>
-<translation id="8153880621934657047">Hors du tableau</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{trait de soulignement}one{# trait de soulignement}other{# traits de soulignement}}</translation>
-<translation id="8179976553408161302">Entrée</translation>
-<translation id="81960742267269908">couper</translation>
-<translation id="8199231515320852133">Énoncer les en-têtes de la cellule actuelle</translation>
-<translation id="820417203470636242">Cellule vide</translation>
-<translation id="8215202828671303819">Sélection multiple</translation>
-<translation id="8276439074553447000">Renvoyer à l'élément précédent pouvant être agrandi</translation>
-<translation id="8278417001922463147">Aucun article précédent</translation>
-<translation id="8283603667300770666">Champ de formulaire suivant</translation>
-<translation id="831207808878314375">Définition</translation>
-<translation id="8313653172105209786">répertoire</translation>
-<translation id="8344569602005188545">heures</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{dièse}one{# dièse}other{# dièses}}</translation>
-<translation id="8374154622594089836">mois</translation>
-<translation id="8378855320830505539">Section</translation>
-<translation id="8382679411218029383">Saisie semi-automatique intégrée ou sous forme de liste</translation>
-<translation id="8428603554127842284">niveau <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Aucun titre de niveau 3 suivant</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Aucune case à cocher précédente</translation>
-<translation id="8455868257606149352">max. <ph name="X" /></translation>
-<translation id="84575901236241018">dispose d'une clé d'accès, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Diminuer la granularité de la navigation</translation>
-<translation id="8520472399088452386">Bouton Toupie</translation>
-<translation id="8538744478902126321">Tenter de détecter l'en-tête de ligne de la cellule actuelle</translation>
-<translation id="8540054775867439484">Revenir au début</translation>
-<translation id="8548973727659841685">Caractère</translation>
-<translation id="8561322612995434619">avec fenêtre pop-up</translation>
-<translation id="8571096049907249734">sél_multiple</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Élément de liste suivant</translation>
-<translation id="860150890330522909">case <ph name="NAME" /> cochée</translation>
-<translation id="8606621670302093223">Commande relative à la date</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> éléments sélectionnés</translation>
-<translation id="8638532244051952400">Annoncer les coordonnées de la cellule active</translation>
-<translation id="8650576015643545550">Aucune liste précédente</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Afficher la liste des liens</translation>
-<translation id="8664519043722036194">secondes</translation>
-<translation id="867187640362843212">Titre 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{barre verticale}one{# barre verticale}other{# barres verticales}}</translation>
-<translation id="8735450637152821465">Début de la sélection</translation>
-<translation id="8743786158317878347">saisir du contenu structuré, tel que des tableaux</translation>
-<translation id="8747966237988593539">Liste numérotée</translation>
-<translation id="8759334257841767240">Aucun lien suivant</translation>
-<translation id="8767968232364267681">En-tête suivant de niveau 4</translation>
-<translation id="8770473310765924354">quitter le contenu structuré, tel que les tableaux</translation>
-<translation id="8791025954632646584">Interprétation sémantique activée</translation>
-<translation id="8796411681063377102">En-tête suivant de niveau 3</translation>
-<translation id="8808582214901541005">Mars</translation>
-<translation id="8825828890761629845">bannière</translation>
-<translation id="8851136666856101339">principal</translation>
-<translation id="8856538297388979332">Appuyez sur la flèche vers le haut ou vers le bas pour examiner les commandes, et appuyez sur la touche Entrée pour les activer.</translation>
-<translation id="8864099967139188018">Aucun titre de niveau 6 suivant</translation>
-<translation id="8882002077197914455">En-tête de ligne</translation>
-<translation id="8896347895970027998">Activer/Désactiver ChromeVox</translation>
-<translation id="8898516272131543774">Écho de la ponctuation par cycle</translation>
-<translation id="8900148057318340779">Touche Préfixe</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">En-têtes vides</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Touches de modification</translation>
-<translation id="8943175951035496220">Aucune cellule à droite</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">fichier</translation>
-<translation id="9027462562263121875">Aucun tableau</translation>
-<translation id="9040132695316389094">Titre 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Utiliser un autre widget de recherche</translation>
-<translation id="9065283790526219006">+pop-up</translation>
-<translation id="9077213568694924680">supprimé de la sélection</translation>
-<translation id="9082874451376019682">Aucun curseur précédent</translation>
-<translation id="9089864840575085222">Écho de la saisie par cycle</translation>
-<translation id="9107530006868467849">Aucun widget de contenu multimédia précédent</translation>
-<translation id="9108370397979208512">math.</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{pourcentage}one{# pourcentage}other{# pourcentages}}</translation>
-<translation id="9115913704608474258">Novembre</translation>
-<translation id="9128414153595658330">boîte dialogue</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Énonce une brève description de la position actuelle.</translation>
-<translation id="9153606228985488238">Timbre de voix : <ph name="PERCENT" /> %</translation>
-<translation id="9160096769946561184">Accéder à la fin de la colonne actuelle</translation>
-<translation id="9173115498289768110">Volume : <ph name="PERCENT" /> %</translation>
-<translation id="9178973770513562274">Utilisez les flèches vers le haut et vers le bas pour naviguer, ou saisissez votre recherche.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">Aucune section suivante</translation>
-<translation id="930275611743429116">Début ou fin de sélection</translation>
-<translation id="948171205378458592">Ralentir la cadence de la voix</translation>
-<translation id="962913030769097253">En-tête suivant de niveau 1</translation>
-<translation id="973955474346881951">Activer/Désactiver le mode autocollant</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_gu.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_gu.xtb
deleted file mode 100644
index 5bfdad38b89..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_gu.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="gu">
-<translation id="1012173283529841972">સૂચિ આઇટમ</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">સ્પેન કર્યું.</translation>
-<translation id="1025074108959230262">સ્ટીકી મોડ અક્ષમ કર્યો</translation>
-<translation id="1031961866430398710">પછી</translation>
-<translation id="1044777062731150180">હેડર્સ નથી</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">અમાન્ય ઇનપુટ</translation>
-<translation id="1082209053475788238">પહેલાંનુ સ્તર 6 મથાળું નથી.</translation>
-<translation id="1088219014394087294">કોઇ મથાળું નથી.</translation>
-<translation id="1106741348836243114">સાઉન્ડ પ્રતિસાદ (ઇઅરકોન્સ) ચાલુ અથવા બંધ કરો.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="NUM" /> આઇટમ્સ સાથેનો <ph name="TAG" /> સંગ્રહ</translation>
-<translation id="1155043339247954670">આગલી સૂચિ આઇટમ નથી.</translation>
-<translation id="1157782847298808853">કીબોર્ડ સહાય</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, કોમ્બો બૉક્સ</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, મેનૂ આઇટમ, પેટામેનૂ સાથે</translation>
-<translation id="1177863135347784049">કસ્ટમ</translation>
-<translation id="1188858454923323853">પૂરક</translation>
-<translation id="1206619573307042055">માર્કી</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome ને વૉઇસ આપવો</translation>
-<translation id="1229276918471378188">પહેલાનું જમ્પ</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">આગલા સ્તર 6 નું મથાળું</translation>
-<translation id="1275718070701477396">પસંદ કરેલું</translation>
-<translation id="1319608975892113573">પહેલાનું બ્લૉકક્વોટ નથી.</translation>
-<translation id="1321576897702511272">ChromeVox સહાય છુપાવો</translation>
-<translation id="1331702245475014624"><ph name="TOTAL" /> માંથી <ph name="INDEX" /></translation>
-<translation id="1334095593597963605">અક્ષર અને શબ્દ પડઘો</translation>
-<translation id="1339428534620983148">પહેલાનું કોષ્ટક કૉલમ</translation>
-<translation id="1342835525016946179">લેખ</translation>
-<translation id="1346748346194534595">જમણે</translation>
-<translation id="136718599399906424">આગલી કોષ્ટક પંક્તિ</translation>
-<translation id="1383876407941801731">શોધો</translation>
-<translation id="1385214448885562192">સ્વીકારવા માટે enter અથવા રદ કરવા માટે escape, આગલું માટે નીચે અને પહેલાનું માટે ઉપર દબાવો.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, પાસવર્ડ ટેક્સ્ટ બૉક્સ</translation>
-<translation id="1467432559032391204">ડાબું</translation>
-<translation id="1474557363159888097">પહેલાનું એન્કર નથી</translation>
-<translation id="1502086903961450562">પહેલાનું ગ્રાફિક</translation>
-<translation id="1506187449813838456">પિચ વધારો</translation>
-<translation id="151784044608172266">આગલું વાક્ય</translation>
-<translation id="1524531499102321782">બ્રેઇલ આગલી રેખા</translation>
-<translation id="1546370775711804143">સ્ક્રોલ બાર</translation>
-<translation id="1559739829547075274">પાછળ નેવિગેટ કરો</translation>
-<translation id="1571643229714746283">ChromeVox તૈયાર</translation>
-<translation id="158493514907962286">ડિસેમ્બર</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6 ડોટ બ્રેઇલ પર સ્વિચ કરો</translation>
-<translation id="1611168825862729585">કૉલમ હેડર:</translation>
-<translation id="1613476421962910979">ઇઅરકોન્સ ચાલુ છે</translation>
-<translation id="1618597272655350600">વર્તમાન સ્થિતિનું સંપૂર્ણ વર્ણન જાહેર કરે છે</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{આના કરતાં મોટું}one{# આના કરતાં મોટાની નિશાની}other{# આના કરતાં મોટાની નિશાની}}</translation>
-<translation id="1653266918374749391">પહેલાનાં સ્તર 3 નું મથાળું</translation>
-<translation id="1659072772017912254">તપાસેલું નથી</translation>
-<translation id="1669290819662866522">અઠવાડિયું</translation>
-<translation id="1674262202423278359">ChromeVox નેવિગેશન્</translation>
-<translation id="16777221443363124">મેનૂ બાર</translation>
-<translation id="1692077714702418899">માળખાકીય રેખા</translation>
-<translation id="1700517974991662022">મુલાકાત લીધેલ</translation>
-<translation id="1722567105086139392">લિંક</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">આગલું ગ્રાફિક</translation>
-<translation id="1781173782405573156">પાસ થ્રુ કી</translation>
-<translation id="1787176709638001873">પાસવર્ડ સંપાદન ટેક્સ્ટ</translation>
-<translation id="1810107444790159527">સૂચિ બૉક્સ</translation>
-<translation id="1828385960365606039">મે</translation>
-<translation id="1834891354138622109">કૉલમ</translation>
-<translation id="1865601187525349519">ટેક્સ્ટના અંતે</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">વર્તમાન સમય અને તારીખ બોલો.</translation>
-<translation id="1902396333223336119">કોષ</translation>
-<translation id="1905379170753160525">મથાળાની સૂચિ બતાવો</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">વર્ષના સપ્તાહનું નિયંત્રણ</translation>
-<translation id="1964135212174907577">આગલો ઑબ્જેક્ટ</translation>
-<translation id="1969092762068865084">જુલાઈ</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">પંક્તિ હેડર:</translation>
-<translation id="2002895034995108595">વર્તમાન કીમેપને ફરીથી સેટ કરો</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{ડાબો મોટો કૌંસ}one{# ડાબા મોટા કૌંસ}other{# ડાબા મોટા કૌંસ}}</translation>
-<translation id="2045490512405922022">ચૅક કરેલું નથી</translation>
-<translation id="20601713649439366">કોઈ પહેલાંની ગણિત પદાવલિ નથી.</translation>
-<translation id="207477615537953741">સિમેન્ટિક્સ બંધ</translation>
-<translation id="2086961585857038472">આગલો શબ્દ</translation>
-<translation id="2089387485033699258">gu</translation>
-<translation id="2091933974477985526">પહેલાનું સંપાદનયોગ્ય ટેક્સ્ટ ક્ષેત્ર</translation>
-<translation id="2100350898815792233">તમામ વિરામચિહ્ન</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">ઍક્સેસ કી:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">નીચેની સૂચિમાંથી એક વિકલ્પ પસંદ કરીને વર્તમાન 6 ડોટ બ્રેઇલ કોષ્ટક બદલો.</translation>
-<translation id="2169714232367507776">ચાલુ આઇટમ પર ક્લિક કરો</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{બંધ થતો કૌંસ}one{# બંધ થતાં કૌંસ}other{# બંધ થતાં કૌંસ}}</translation>
-<translation id="2199994615414171367">પહેલાનું ગણિત</translation>
-<translation id="2223693656926968778">ચાલુ આઇટમ પર પગલા લો</translation>
-<translation id="225732394367814946">ભાષણનો રેટ વધારો</translation>
-<translation id="2267945578749931355">આગલો અક્ષર</translation>
-<translation id="2281234842553884450">પહેલાનું સ્લાઇડર</translation>
-<translation id="2318372665160196757">મુખ્ય</translation>
-<translation id="2329324941084714723">ટેબ પેનલ</translation>
-<translation id="2344193891939537199">તારીખ સમયનું નિયંત્રણ</translation>
-<translation id="2359897517538099099">કોષ્ટક મોડમાં નથી.</translation>
-<translation id="241124561063364910">આના દ્વારા અનુસરાયેલ</translation>
-<translation id="2417569100218200841">સામગ્રી માહિતી</translation>
-<translation id="2422937916923936891">મેનૂ આઇટમ ચેક બૉક્સ</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> હવે નવું ChromeVox સંશોધક છે.</translation>
-<translation id="2450814015951372393">ચેક બૉક્સ</translation>
-<translation id="2462626033734746142">રેડિઓ બટન જૂથ</translation>
-<translation id="2471138580042810658">મથાળું 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{તારક ચિહ્ન}one{# તારક ચિહ્ન}other{# તારક ચિહ્ન}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> ને ફરીથી સેટ કરવામાં આવી છે.</translation>
-<translation id="2553108862507765288">વ્યાકરણની ભૂલ</translation>
-<translation id="257674075312929031">જૂથ</translation>
-<translation id="2582407057977008361">એક તરફ</translation>
-<translation id="2589102159832527089">આ પૃષ્ઠમાં PDF ફાઇલ &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; થી આપમેળે બહાર કાઢેલ ટેક્સ્ટ શામેલ છે. &lt;a href="<ph name="URL" />"&gt;મૂળ માટે અહીં ક્લિક કરો.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">આ સાથેની {COUNT,plural, =1{# આઇટમ}one{# આઇટમ}other{# આઇટમ}}</translation>
-<translation id="2614981083756825552">ગણિત ML લેઆઉટ</translation>
-<translation id="2626530649491650971">ક્લિક કરી શકાય તેવા</translation>
-<translation id="2628764385451019380">પહેલાનું કોમ્બો બૉક્સ નથી.</translation>
-<translation id="2637227747952042642">ગણિત</translation>
-<translation id="2639750663247012216">ChromeVox સંશોધક</translation>
-<translation id="2644542693584024604">ખોટીજોડણીવાળું</translation>
-<translation id="2667291555398229137">રૂટિંગ કી હેઠળની આઇટમને ક્લિક કરો</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{ખુલતો કૌંસ}one{# ખુલતાં કૌંસ}other{# ખુલતાં કૌંસ}}</translation>
-<translation id="2705875883745373140">દબાયેલું નહીં</translation>
-<translation id="2706462751667573066">Up</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ઑડિઓ</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">તપાસેલું</translation>
-<translation id="27527859628328957">આગલી ફોકસ કરવા યોગ્ય આઇટમ પર જમ્પ કરો</translation>
-<translation id="2770781857296573485">સમૂહ અન્વેષણ દાખલ કરો</translation>
-<translation id="2777845298774924149">બહાર</translation>
-<translation id="2800204403141299078">કોઈ વધુ અલગ ઘટકો નથી.</translation>
-<translation id="2800780099804980316">પહેલાંનુ સ્તર 2 મથાળું નથી.</translation>
-<translation id="2811204574343810641">પંક્તિ</translation>
-<translation id="2816654101880605877">આગલું સ્લાઇડર નથી.</translation>
-<translation id="2841013758207633010">સમય</translation>
-<translation id="2843837985843789981">પહેલાંનું જૂથ</translation>
-<translation id="2844995807198708617">સંદર્ભ મેનૂ</translation>
-<translation id="2849332794118375855">આગલું ચેકબૉક્સ નથી.</translation>
-<translation id="2864481629947106776">પહેલાની લિંક</translation>
-<translation id="2873259058405069099">કોષ્ટકની શરૂઆત પર જાઓ</translation>
-<translation id="2894654529758326923">માહિતી</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{ડાબો છગડિયો કૌંસ}one{# ડાબા છગડિયા કૌંસ}other{# ડાબા છગડિયા કૌંસ}}</translation>
-<translation id="2911433807131383493">ChromeVox ટ્યૂટોરિયલ ખોલો</translation>
-<translation id="2932083475399492303">માળખાકીય અથવા લેઆઉટ વચ્ચે રેખા પ્રકાર ટોગલ કરો</translation>
-<translation id="2964026537669811554">મથાળા જૂથ</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{ટેબ}one{# ટેબ્સ}other{# ટેબ્સ}}</translation>
-<translation id="2972078295414139404">કોઈ પહેલાંની મુલાકાત લીધેલી લિંક નથી.</translation>
-<translation id="2972205263822847197">સાધન ટિપ</translation>
-<translation id="2998131015536248178">પહેલાનો અક્ષર</translation>
-<translation id="2999559350546931576">પિચ ઘટાડો</translation>
-<translation id="2999945368667127852">કોઈ આગલું મીડિયા વિજેટ નથી.</translation>
-<translation id="3012414509011670858">કોઈ પહેલાંનો વિભાગ નથી.</translation>
-<translation id="3030432017085518523">મેનૂ આઇટમ રેડિયો બટન</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{અપૉસ્ટ્રફી}one{# અપૉસ્ટ્રોફી}other{# અપૉસ્ટ્રોફી}}</translation>
-<translation id="3046838483509668188">ChromeVox વિકલ્પો</translation>
-<translation id="3047143736589213134">પ્રાયોગિક કિમેપ</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> મેનૂ ખોલ્યું</translation>
-<translation id="3078345202707391975">આગલા સ્તર 2 નું મથાળું</translation>
-<translation id="3078740164268491126">કોષ્ટક</translation>
-<translation id="3082557070674409251">ક્લિક કર્યું</translation>
-<translation id="3084806535845658316">કોઈ લખાણ પડઘો નથી</translation>
-<translation id="3086746722712840547">નોંધ</translation>
-<translation id="308895241372589742">કોઈ આગલી ગણિત પદાવલિ નથી.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">આગલી સ્થળનિશાની</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">સંકુચિત</translation>
-<translation id="3134461040845705080">ફક્ત વાંચવા માટે</translation>
-<translation id="3138767756593758860">સ્થળનિશાનીઓની સૂચિ બતાવો</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">આગલી રેખા</translation>
-<translation id="3155083529632865074">પહેલાંનું બટન નથી.</translation>
-<translation id="3163593631834463955">કૉલમ હેડર ખાલી છે</translation>
-<translation id="316542773973815724">નેવિગેશન</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{જગ્યા}one{# જગ્યા}other{# જગ્યા}}</translation>
-<translation id="320961988183078793">દાખલ કરેલ <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, ટૅબ</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">મુલાકાત લીધેલી લિંક</translation>
-<translation id="323731244387692321">ChromeVox કીબોર્ડ સહાય ખોલો</translation>
-<translation id="3241052487511142956">પહેલાંની મુલાકાત લીધેલી લિંક</translation>
-<translation id="3286390186030710347">સ્લાઇડર</translation>
-<translation id="3299925995433437805">કોઈ આગલી મુલાકાત લીધેલી લિંક નથી.</translation>
-<translation id="3303384412438961941">કોઈપણ કીનું નામ જાણવા માટે તેને દબાવો. Ctrl+W કીબોર્ડ અન્વેષકને બંધ કરશે.</translation>
-<translation id="3307886118343381874">કોષ્ટકની સમાપ્તિ પર જાઓ</translation>
-<translation id="3311969765485641742">ચેતવણીઓની સમીક્ષા કરવા માટે Alt+Shift+A દબાવો</translation>
-<translation id="3312997241656799641">આગલી મુલાકાત લીધેલી લિંક</translation>
-<translation id="3321460131042519426">શબ્દ વીંટો સક્ષમ કરો</translation>
-<translation id="3322936298410871309">આગલા સ્તર 1 નું મથાળું</translation>
-<translation id="3323447499041942178">ટેક્સ્ટ બૉક્સ</translation>
-<translation id="3353420241558113817">{"ar": "અરબી",
- "bg": "બલ્ગેરિયન",
- "ca": "કતલાન",
- "cs": "ચેક",
- "da": "ડેનિશ",
- "de": "જર્મન",
- "de_CH": "જર્મન (સ્વિટ્ઝર્લેન્ડ)",
- "de_DE": "જર્મન (જર્મની)",
- "el": "ગ્રીક",
- "en": "અંગ્રેજી",
- "en_CA": "અંગ્રેજી (કેનેડા)",
- "en_GB": "અંગ્રેજી (યુનાઇટેડ કિંગડમ)",
- "en_US": "અંગ્રેજી (યુનાઇટેડ સ્ટેટ્સ)",
- "es": "સ્પેનિશ",
- "et": "એસ્ટોનિયન",
- "fr": "ફ્રેંચ",
- "fr_CA": "ફ્રેંચ (કેનેડા)",
- "fr_FR": "ફ્રેંચ (ફ્રાંસ)",
- "fi": "ફિનિશ",
- "he": "હીબ્રુ",
- "hi": "હિન્દી",
- "hr": "ક્રોએશિયન",
- "hu": "હંગેરિયન",
- "is": "આઇસલેન્ડિક",
- "it": "ઇટાલિયન",
- "ko": "કોરિયન",
- "lt": "લિથુઆનિયન",
- "lv": "લાતવિયન",
- "nb": "નોર્વેજિયન બોકમાલ",
- "nl": "ડચ",
- "pl": "પોલિશ",
- "pt": "પોર્ટુગીઝ",
- "ro": "રોમાનિયન",
- "ru": "રશિયન",
- "sk": "સ્લોવાક",
- "sl": "સ્લોવેનિયન",
- "sr": "સર્બિયન",
- "sv": "સ્વીડિશ",
- "tr": "ટર્કિશ",
- "vi": "વિયેતનામીઝ",
- "zh": "ચાઇનીઝ",
- "zh_TW": "ચાઇનીઝ (પરંપરાગત હાન)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{વત્તા}one{# વત્તાની નિશાની}other{# વત્તાની નિશાની}}</translation>
-<translation id="338583716107319301">વિભાજક</translation>
-<translation id="3389259863310851658">પહેલાનું ફોર્મ ફીલ્ડ</translation>
-<translation id="3390225400784126843">આગલા ભિન્ન ઘટક.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, મેનૂ આઇટમ</translation>
-<translation id="3406283310380167331">ફોર્મ્સની સૂચિ બતાવો</translation>
-<translation id="3422338090358345848">કીબોર્ડ અન્વેષક ખોલો</translation>
-<translation id="3457000393508828486">આંશિક રૂપે દબાયેલું</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, બટન</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> થી <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{જમણો મોટો કૌંસ}one{# જમણા મોટાં કૌંસ}other{# જમણા મોટાં કૌંસ}}</translation>
-<translation id="3493915602752813531">આગલું એન્કર નથી.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{પ્રશ્નાર્થ ચિહ્ન}one{# પ્રશ્નાર્થ ચિહ્ન}other{# પ્રશ્નાર્થ ચિહ્ન}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{કૅરેટ}one{# કૅરેટ}other{# કૅરેટ}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, ચેકબૉક્સ ચેક કરેલો નથી</translation>
-<translation id="3599054940393788245">ગણિતમાં નહીં</translation>
-<translation id="3616113530831147358">ઑડિઓ</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{બેકટિક}one{# બેકટિક}other{# બેકટિક}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{ડૉલર}one{# ડૉલરની નિશાની}other{# ડૉલરની નિશાની}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, સૂચિ બૉક્સ</translation>
-<translation id="3687295507293856493">ચાલુ કોષના કૉલમ મથાળા પર એક અનુમાન કરો</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">ભાષણને નિયંત્રિત કરી રહ્યું છે</translation>
-<translation id="3716845769494773620">બહુ રેખા</translation>
-<translation id="3731746171184829332">પહેલાંનું મથાળું નથી.</translation>
-<translation id="3762198587642264450">ચાલુ પંક્તિની સમાપ્તિ પર જાઓ</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">સંવાદમાંથી બહાર થયા.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">સ્વતઃપૂર્ણ સૂચિ</translation>
-<translation id="3810838688059735925">વિડિઓ</translation>
-<translation id="3816633764618089385">આગલું મીડિયા</translation>
-<translation id="3819376190738087562">જમ્પ્સ નથી</translation>
-<translation id="385383972552776628">વિકલ્પોનું પૃષ્ઠ ખોલો</translation>
-<translation id="3856075812838139784">ફક્ત વાંચવા માટે</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">મેનૂ</translation>
-<translation id="3909320334364316587">પહેલાનું સ્તર 6 નું મથાળું</translation>
-<translation id="3914173277599553213">આવશ્યક</translation>
-<translation id="3962990492275676168">ચાલુ સ્થાનથી વાંચવાનું શરૂ કરો</translation>
-<translation id="4004802134384979325">તપાસેલું</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">મહિનાનું નિયંત્રણ</translation>
-<translation id="4039983576244166038">પંક્તિ હેડર ખાલી છે</translation>
-<translation id="4042843249978639960">આગલું સ્તર 2 મથાળું નથી.</translation>
-<translation id="4043348641337972076">પહેલાની ARIA સ્થળ નિશાનીઓ નથી.</translation>
-<translation id="4047216625641135770">માર્ક કરો</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{ટિલ્ડ}one{# ટિલ્ડ}other{# ટિલ્ડ}}</translation>
-<translation id="409334809956508737">પહેલાનો ઑબ્જેક્ટ</translation>
-<translation id="4099274309791143834">સબમેનૂ સા</translation>
-<translation id="4107807507418787238">નીચે કોષ નથી.</translation>
-<translation id="4116415223832267137">ચેતવણી</translation>
-<translation id="4147126331795725888">કોઈ આગલું નિયંત્રણ નથી.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{જમણો છગડિયો કૌંસ}one{# જમણા છગડિયા કૌંસ}other{# જમણા છગડિયા કૌંસ}}</translation>
-<translation id="4158704014418536539">કેસ સંવેદી.</translation>
-<translation id="4161663686871496107">ChromeVox બોલાયેલ પ્રતિસાદ તૈયાર છે</translation>
-<translation id="4173994908659439270">આગલી સંપાદનયોગ્ય ટેક્સ્ટ ફીલ્ડ નથી</translation>
-<translation id="4176463684765177261">અક્ષમ કરેલું</translation>
-<translation id="4188530942454211480">પહેલાનું વાક્ય</translation>
-<translation id="4202186506458631436">જમણી બાજુએ ખસેડો</translation>
-<translation id="4206289001967551965">કોષ્ટકની અંદર</translation>
-<translation id="4215733775853809057">આગલું સ્લાઇડર</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{ડેશ}one{# ડેશ}other{# ડેશ}}</translation>
-<translation id="421884353938374759">રંગ ચૂંટનાર</translation>
-<translation id="4229646983878045487">તારીખ સમય</translation>
-<translation id="423334822609210999">ડાબી બાજુએ કોષ નથી.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, ગ્રેડ <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">નોંધ</translation>
-<translation id="4254798249533888099">ટ્રી</translation>
-<translation id="4255943572433203166">ChromeVox ને કસ્ટમાઇઝ કરવા માટે નીચેના વિકલ્પોનો ઉપયોગ કરો. ફેરફારો તરતજ પ્રભાવી થાય છે.</translation>
-<translation id="4271220233568730077">આગલું ગણિત</translation>
-<translation id="4271521365602459209">વધુ પરિણામો નથી.</translation>
-<translation id="4287520460805643128">કોઈ આગલો લેખ નથી.</translation>
-<translation id="4289540628985791613">વિહંગાવલોકન</translation>
-<translation id="4300318234632215983">લિંકની પાછળનાં URL ની ઘોષણા કરો</translation>
-<translation id="4301352596632316575">તેમાં સબમેનૂ છે</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{ટપકું }=3{પદલોપ}one{# ટપકાં}other{# ટપકાં}}</translation>
-<translation id="4347461890115250064">આગલી સૂચિ નથી.</translation>
-<translation id="4367650418938037324">ગણિત ML લીફ</translation>
-<translation id="4372435075475052704">ન્યૂનતમ: <ph name="X" /></translation>
-<translation id="4372705107434148843">ભાષણ રોકો</translation>
-<translation id="4373197658375206385">પહેલાની આઇટમ નથી તે કોઈ લિંક નથી.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">ફરીથી સેટ કરો</translation>
-<translation id="4471074325120394300">લિંક્સ નથી.</translation>
-<translation id="4476183483923481720">નવી લાઇન</translation>
-<translation id="4482330759234983253">અગાઉનું કોષ્ટક</translation>
-<translation id="4491109536499578614">છબી</translation>
-<translation id="4529987814483543472">ક્લાસિક કીમૅપ</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{સ્લેશ}one{# સ્લેશ}other{# સ્લેશ}}</translation>
-<translation id="4547556996012970016">આગલા સ્તર 5 નું મથાળું</translation>
-<translation id="4562381607973973258">હેડર</translation>
-<translation id="4591507479202817876">, પસંદ કરેલું</translation>
-<translation id="4597532268155981612">ફોર્મ</translation>
-<translation id="4597896406374528575">એપ્રિલ</translation>
-<translation id="4615592953348396470">આગલા કી દબાણને અવગણે છે</translation>
-<translation id="461613135510474570">વાક્ય</translation>
-<translation id="4647836961514597010">રંગ ચૂંટનાર</translation>
-<translation id="4661075872484491155">ટ્રી</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">પહેલાની સ્થળનિશાની</translation>
-<translation id="4696413482802371445">આગલું સ્તર 5 મથાળું નથી.</translation>
-<translation id="4729095194763193578">પહેલાંની કોષ્ટક પંક્તિ</translation>
-<translation id="4736221692378411923">ઑગસ્ટ</translation>
-<translation id="4740661827607246557">સહાય આદેશો</translation>
-<translation id="4759716709594980008">ChromeOS કીબોર્ડ અન્વેષક</translation>
-<translation id="4763296182459741068">નીચે રૅપ કર્યું</translation>
-<translation id="4763480195061959176">વિડિઓ</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">ચાલુ પૃષ્ઠના શીર્ષકની ઘોષણા કરો</translation>
-<translation id="4826415162591436065">આગળ નેવિગેટ કરો</translation>
-<translation id="4826604887384865800">આગલો જમ્પ</translation>
-<translation id="4827410568042294688">પસંદ ન કરેલ</translation>
-<translation id="4842108708071771135">આગલું બ્લૉકક્વૉટ નથી.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">પાછલા સમાન ઘટક.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS લોગિંગને સક્ષમ કરો</translation>
-<translation id="4877261390094455813">શોધ ક્વેરી દાખલ કરો.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">આંતરિક લિંક</translation>
-<translation id="4953585991029886728">ટેક્સ્ટ સંપાદિત કરો</translation>
-<translation id="4954534434583049121">પહેલાનું બ્લોક ક્વોટ</translation>
-<translation id="4973717656530883744">ન્યૂનતમ <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> પર સ્વિચ કર્યુ.</translation>
-<translation id="4975416682604111799">મીલીસેકન્ડ</translation>
-<translation id="49787999531187221">ChromeVox હવે નિષ્ક્રિય છે.</translation>
-<translation id="4979404613699303341">પહેલાનું બટન</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, સૂચિ બૉક્સ</translation>
-<translation id="4983588134362688868">પૃષ્ઠની ટોચ પર જાઓ</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, વિંડો</translation>
-<translation id="4993152509206108683">દર <ph name="PERCENT" /> ટકા</translation>
-<translation id="4996716799442435517">વિઝ્યૂલ</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, રેડિયો બટન પસંદ કર્યું</translation>
-<translation id="4997475792277222884">આગલી આઇટમ નથી તે કોઈ લિંક નથી.</translation>
-<translation id="5000760171916499057">કોઇ ફોર્મ્સ નથી.</translation>
-<translation id="5005670136041063723">કોઈ વધુ સમાન ઘટકો નથી.</translation>
-<translation id="501473567976723023">જાન્યુઆરી</translation>
-<translation id="5041394372352067729">બ્રેઇલ પ્રદર્શનને પૃષ્ઠની શીર્ષ પર ખસેડો</translation>
-<translation id="5042770794184672516">ભાષણનો અવાજ વધારો</translation>
-<translation id="5050015258024679800">પહેલાનાં સ્તર 4 નું મથાળું</translation>
-<translation id="5054047268577924192">પહેલાની સૂચિ આઇટમ</translation>
-<translation id="5078661581131202757">ફાઇલ પસંદગી</translation>
-<translation id="5080758118274074384">ડબલ ક્લિક કર્યું</translation>
-<translation id="5098541983634824365">ગ્રીડ છોડવી.</translation>
-<translation id="5102981729317424850">ટુલ બાર</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">પહેલાની ફોર્મ ફીલ્ડ નથી.</translation>
-<translation id="5111640677200759579">કૉલમ હેડર</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">પહેલાની લિંક નથી.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, પસંદ ન કરેલું</translation>
-<translation id="5183440668879371625">બ્રેઇલ પાછલી રેખા</translation>
-<translation id="5184944171021383281">આગલી ફોર્મ ફીલ્ડ નથી.</translation>
-<translation id="5189244881767082992">લાઇન</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> પહેલેથી જ એક કમાન્ડને સોંપેલી છે.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> સૂચિ.</translation>
-<translation id="520883772648104506">ટેક્સ્ટ ઓડિઓ બટન નથી.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">સમાપ્ત</translation>
-<translation id="5291783959063340370">ઑબ્જેક્ટ</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, ટેબ</translation>
-<translation id="5310788376443009632">દૂર કર્યું:</translation>
-<translation id="5320727453979144100">સ્ટીકી મોડ સક્ષમ કર્યો</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{અલ્પવિરામ}one{# અલ્પવિરામ}other{# અલ્પવિરામ}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, ટેક્સ્ટ બોક્સ</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, લિંક</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">સતત વાંચન દરમિયાન પાછળ જાઓ</translation>
-<translation id="5368000168321181111">ઇઅરકોન્સ બંધ છે</translation>
-<translation id="5374320867641260420">આગલું બટન નથી.</translation>
-<translation id="5382299583965267720">આગલું સ્તર 1 મથાળું નથી.</translation>
-<translation id="5402367795255837559">બ્રેઇલ</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{અર્ધવિરામ}one{# અર્ધવિરામ}other{# અર્ધવિરામ}}</translation>
-<translation id="5411891038905756502">પહેલાનું જમ્પ બિંદુ નથી.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{આના કરતાં ઓછું}one{# આના કરતાં ઓછાની નિશાની}other{# આના કરતાં ઓછાની નિશાની}}</translation>
-<translation id="5455441614648621694">પૂરક</translation>
-<translation id="5485036206801896268">પહેલાનું ગ્રાફિક નથી.</translation>
-<translation id="5486947920110100234">આગલું જમ્પ બિંદુ નથી.</translation>
-<translation id="549602578321198708">શબ્દ</translation>
-<translation id="5500932716852106146">પહેલાની સંપાદનયોગ્ય ટેક્સ્ટ ફીલ્ડ નથી</translation>
-<translation id="5502713021410870035">સપ્ટેમ્બર</translation>
-<translation id="5507663321906818013">બેન્ચમાર્ક ડીબગ કરો</translation>
-<translation id="5518443085409638729">ટેક્સ્ટ સંપાદિત કરતી વખતે કર્સરને અક્ષરોની વચ્ચે રાખો (જેમ કે Mac OS X).</translation>
-<translation id="552195134157544755">રેડિઓ બટન</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">પહેલાંનુ સ્તર 5 મથાળું નથી.</translation>
-<translation id="556042886152191864">બટન</translation>
-<translation id="5561345396546889625">આગલી સૂચિ</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">ટેક્સ્ટ, ઇમેઇલ એન્ટ્રી સંપાદિત કરો</translation>
-<translation id="5597170376237141345">આગલો ચેકબૉક્સ</translation>
-<translation id="5597933780944041114">આગલું મથાળું નથી</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, રેડિયો બટન પસંદ કરેલું</translation>
-<translation id="5601172225407283979">ડિફોલ્ટ ક્રિયા ભજવો</translation>
-<translation id="5608798115546226984">સ્વતઃપૂર્ણ ઇનલાઇન</translation>
-<translation id="561939826962581046">સમય</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">લૉગ</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">પહેલાનું કોષ્ટક નથી.</translation>
-<translation id="5655682562155942719">જંપ આદેશો</translation>
-<translation id="56637627897541303">ટેક્સ્ટ ક્ષેત્ર</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">સ્થળનિશાની</translation>
-<translation id="5683155931978483559">પહેલાનું ચેકબૉક્સ</translation>
-<translation id="5684277895745049190">સૂચિ</translation>
-<translation id="5700650669149824506">પહેલાંનુ સ્તર 4 મથાળું નથી.</translation>
-<translation id="5709192780268610569">કોઈ લાંબું વર્ણન નથી</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">આગલું કોષ્ટક કૉલમ</translation>
-<translation id="571866080859340309">જૂથોનું અન્વેષણ થઇ રહ્યું છે</translation>
-<translation id="5728409797179002635">કોષ્ટક મળ્યું નથી.</translation>
-<translation id="5748623122140342504">પહેલાનાં સ્તર 5 નું મથાળું</translation>
-<translation id="5750633686117194034">કોઈ સંશોધક દબાવાયું નથી; કૃપા કરીને દબાવો અને એક અથવા વધુ સંશોધકોને હોલ્ડ કરો; એકવાર પૂર્ણ થઈ જાય પછી તમારી આંગળીઓને લઈ લો અને તમને કીઝ સેટ સંભળાશે. બહાર નીકળવા માટે ટેબ કરો.</translation>
-<translation id="5788275253279308023">છુપી વિંડો <ph name="TITLE" /> ટેબ</translation>
-<translation id="5806206155699461681">વિશિષ્ટ સાઇટ્સ (જેમ કે Google શોધ)ને વિસ્તૃત કરો.</translation>
-<translation id="5819072574982403430">ટ્રી આઇટમ</translation>
-<translation id="5826479389509458994">પંક્તિ <ph name="ROW" /> કૉલમ <ph name="COL" /></translation>
-<translation id="5850707923114094062">પાછળની તરફ પેન કરો</translation>
-<translation id="5851548754964597211">ટેબ સૂચિ</translation>
-<translation id="5859752971144398932">પૃષ્ઠમાં શોધથી બહાર કાઢ્યાં</translation>
-<translation id="5866042630553435010">આંશિક રૂપે તપાસેલું</translation>
-<translation id="5869546221129391014">ગ્રિડ</translation>
-<translation id="5876817486144482042">ભાષણનો અવાજ ધીમો કરો</translation>
-<translation id="5887397643266327462">બ્રેઇલ કૅપ્શન્સ સક્ષમ કર્યા.</translation>
-<translation id="5891934789323004067">ટેબલ</translation>
-<translation id="5919442531159595654">કૉપિ કરો.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{બરાબર}one{# બરાબરની નિશાની}other{# બરાબરની નિશાની}}</translation>
-<translation id="5939518447894949180">રીસેટ કરો</translation>
-<translation id="5948123859135882163">સંરચનાગત અને સિમેન્ટિક વચ્ચે ગણિત પદાવલિઓની સમજૂતિને ટોગલ કરો</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">સંવાદ</translation>
-<translation id="5963413905009737549">સેક્શન</translation>
-<translation id="5968607524793740041">સંદર્ભ મેનૂ બતાવો</translation>
-<translation id="5983179082906765664">નેવિગેશન ગ્રેન્યુલેરિટી વધારો</translation>
-<translation id="5999630716831179808">અવાજો</translation>
-<translation id="6000417740266304866">નીચેની સૂચિમાંથી એક વિકલ્પ પસંદ કરીને વર્તમાન 8 ડોટ બ્રેઇલ કોષ્ટક બદલો.</translation>
-<translation id="6006050241733874051">ફોર્મ</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{બેકસ્લેશ}one{# બેકસ્લેશ}other{# બેકસ્લેશ}}</translation>
-<translation id="6037602951055904232">આગળની તરફ પેન કરો</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">કોષની સમાપ્તિ.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">જગ્યા</translation>
-<translation id="6142308968191113180">મથાળું 4</translation>
-<translation id="6169420925157477918">લાંબા વર્ણન સાથેની છબી</translation>
-<translation id="6172087735260766220">કૉપિ-રક્ષિત PDF માંથી ઍક્સેસિબલ ટેક્સ્ટ ઍક્સેસ કરવામાં અસમર્થ.</translation>
-<translation id="6186305613600865047">પૃચ્ઠમાં નીચે જાઓ</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Down</translation>
-<translation id="6236061028292614533">આગલું મથાળું</translation>
-<translation id="6254901459154107917">આગલું સંપાદનયોગ્ય ટેક્સ્ટ ક્ષેત્ર</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> થી બહાર નીકળ્યાં છે.</translation>
-<translation id="6281876499889881039">આગલા સમાન ઘટક.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">આગલું કોમ્બો બૉક્સ નથી.</translation>
-<translation id="6307969636681130414">દબાયેલું</translation>
-<translation id="6324551002951139333">વ્યાકરણની ભૂલ મળી</translation>
-<translation id="6348657800373377022">કૉમ્બો બૉક્સ</translation>
-<translation id="6355910664415701303">પહેલાની સૂચિ આઇટમ નથી.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">પહેલાનું મથાળું</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">પહેલાંનું રેડિયો બટન નથી.</translation>
-<translation id="6414968628640960377">પાછલા ભિન્ન ઘટક.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{મહાવિરામ}one{# મહાવિરામ}other{# મહાવિરામ}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, મેનૂ</translation>
-<translation id="6444046323172968959">ચેતવણી સંવાદ</translation>
-<translation id="6459511626086141404">સપાટ કિમેપ</translation>
-<translation id="6468049171101508116">આગલું બટન</translation>
-<translation id="6491972999578897419">નીચેની સૂચિમાંથી એક વિકલ્પ પસંદ કરીને વર્તમાન અવાજ બદલો.</translation>
-<translation id="6508059270146105198">બ્રેઇલ પ્રદર્શનને પૃષ્ઠની નીચે ખસેડો</translation>
-<translation id="6536864053412760904">ગણિત ML ટોકન</translation>
-<translation id="6550720799683018100">નીચેની સૂચિમાંથી એક વિકલ્પ પસંદ કરીને વર્તમાન કીમૅપ બદલો.</translation>
-<translation id="6561818612645211875">ચાલુ પંક્તિની શરૂઆત પર જાઓ</translation>
-<translation id="6587021927234520429">આગલું સ્તર 4 મથાળું નથી.</translation>
-<translation id="6601344353291556895">વર્બોઝ વર્ણનો સક્ષમ કરો.</translation>
-<translation id="6615602925644411249">પૃષ્ઠમાં શોધો.</translation>
-<translation id="6633350132811819843">આગલું કોષ્ટક નથી.</translation>
-<translation id="6637586476836377253">લૉગ</translation>
-<translation id="6657128831881431364">પ્રોગ્રેસ બાર</translation>
-<translation id="6659594942844771486">ટૅબ</translation>
-<translation id="667999046851023355">દસ્તાવેજ</translation>
-<translation id="6697092096875747123">પહેલાનું કોમ્બો બૉક્સ</translation>
-<translation id="6714813999819678458">આગલા સ્તર 2 નું મથાળું</translation>
-<translation id="6716505898850596801">સંશોધક કીઝ</translation>
-<translation id="671916444866103745">આગલી ARIA સ્થળ નિશાનીઓ નથી.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, કૉમ્બો બૉક્સ</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> આઇટમ સાથે</translation>
-<translation id="6736510033526053669">ટેબ બનાવ્યું</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">લેખ</translation>
-<translation id="6787839852456839824">કીબોર્ડ શોર્ટકટ્સ</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">ફૂટર</translation>
-<translation id="6871161210040114857">કેસ અવગણી રહ્યાં છે.</translation>
-<translation id="6877435256196695200">આગલું ગ્રાફિક નથી.</translation>
-<translation id="6897341342232909480">ડાબે ખસેડો</translation>
-<translation id="6901540140423170855">તારીખ</translation>
-<translation id="6910211073230771657">કાઢી નાખ્યું</translation>
-<translation id="6911965441508464308">ઉપર કોષ નથી.</translation>
-<translation id="6919104639734799681">કોષ્ટકોની સૂચિ બતાવો</translation>
-<translation id="6964088412282673743">કોઈ પહેલાંનું નિયંત્રણ નથી.</translation>
-<translation id="6996566555547746822">આગલું કૉંબો બૉક્સ</translation>
-<translation id="7005146664810010831">URL મળ્યું નથી</translation>
-<translation id="7010712454773919705">ChromeVox સંશોધક કી</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">પહેલાની સૂચિ</translation>
-<translation id="7041173719775863268">પસંદગી સમાપ્ત કરો</translation>
-<translation id="7095834689119144465">ફક્ત આંકડાકીય ટેક્સ્ટને જ સંપાદિત કરો</translation>
-<translation id="7096001299300236431">પહેલાનું મીડિયા</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">શબ્દ પડઘો</translation>
-<translation id="713824876195128146">આગલું બ્લોક ક્વોટ</translation>
-<translation id="7161771961008409533">પોપ-અપ બટન</translation>
-<translation id="7167657087543110">અક્ષર પડઘો</translation>
-<translation id="7170733337935166589">સતત વાંચન દરમિયાન આગળ જાઓ</translation>
-<translation id="7181697990050180700">વારંવાર ઉપયોગ થતાં કમાન્ડ્સ માટેનાં કીબોર્ડ શૉર્ટકટ્સને નીચેની અનુરૂપ ફીલ્ડ્સમાં લખીને તેમને કસ્ટમાઇઝ કરો.</translation>
-<translation id="7203150201908454328">વિસ્તૃત કરેલ</translation>
-<translation id="7210211103303402262">મિનિટ</translation>
-<translation id="7217912842225915592"><ph name="NUM" />%</translation>
-<translation id="7221740160534240920">લાઇન</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">મથાળું</translation>
-<translation id="7241683698754534149">નવા ટેબમાં લાંબું વર્ણન ખોલો</translation>
-<translation id="7248671827512403053">એપ્લિકેશન</translation>
-<translation id="725969808843520477">આગલું રેડિયો બટન</translation>
-<translation id="7269119382257320590">કોઈ વિરામચિહ્ન નથી</translation>
-<translation id="7273174640290488576">ખાલી</translation>
-<translation id="7285387653379749618">કોષ્ટકો</translation>
-<translation id="7289186959554153431">મથાળું 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">બ્રેઇલ કૅપ્શન્સ અક્ષમ કર્યા.</translation>
-<translation id="7318872822751139669">ફૉકસ બદલવા માટે માઉસનો ઉપયોગ કરો.</translation>
-<translation id="7322388933135261569">ફેબ્રુઆરી</translation>
-<translation id="7332592614823088566"><ph name="ROWTOTAL" /> માંથી <ph name="ROWINDEX" /> પંક્તિ, <ph name="COLTOTAL" /> માંથી <ph name="COLINDEX" /> કૉલમ</translation>
-<translation id="7336596009609913925">તેમાં પૉપઅપ છે</translation>
-<translation id="7356165926712028380">8 ડોટ બ્રેઇલ પર સ્વિચ કરો</translation>
-<translation id="7362871137496673139">પહેલાંનુ સ્તર 2 મથાળું નથી.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{એમ્પરસેંડ}one{# એમ્પરસેંડ્સ}other{# એમ્પરસેંડ્સ}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">કોષ્ટક છોડી રહ્યાં છે.</translation>
-<translation id="739763518212184081">પહેલાની રેખા પસંદ કરો</translation>
-<translation id="7400575256015741911">જોડણીની ભૂલ મળી</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">રીટર્ન</translation>
-<translation id="7434509671034404296">વિકાસકર્તા</translation>
-<translation id="7439060726180460871">નિર્દેશિકા</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">ટેબ</translation>
-<translation id="7492049978501397201">દાખલ કરેલો સંવાદ</translation>
-<translation id="7532613204005497612">જૂન</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, સ્લાઇડર</translation>
-<translation id="7586163296341959563">પેસ્ટ કરો.</translation>
-<translation id="7596919493010894443">પસંદગી સાફ કરી</translation>
-<translation id="7604026522577407655">ચાલુ કૉલમની શરૂઆત પર જાઓ</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">ચાલુ પૃષ્ઠના URL ની ઘોષણા કરો</translation>
-<translation id="7609363189280667021">બ્રેઇલ કૅપ્શન્સને ટોગલ કરો</translation>
-<translation id="762020119231868829">વર્તમાનમાં ચાલી રહેલા બધા મીડિયા વિજેટ્સને થોભાવે છે</translation>
-<translation id="7625690649919402823">આગલું કોષ્ટક</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), ગ્રેડ <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">પહેલાંનુ સ્તર 3 મથાળું નથી.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, ટેક્સ્ટ બૉક્સ</translation>
-<translation id="7663318257180412551">મથાળું 2</translation>
-<translation id="7674576868851035240">આગલી લિંક</translation>
-<translation id="7674768236845044097">માર્ક</translation>
-<translation id="7684431668231950609">ટેક્સ્ટ, URL એન્ટ્રી સંપાદિત કરો</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">પહેલાનું રેડિઓ બટન</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, પાસવર્ડ ટેક્સ્ટ બૉક્સ</translation>
-<translation id="7805247615045262757">ડિફોલ્ટ નેવિગેશન</translation>
-<translation id="7805768142964895445">સ્થિતિ</translation>
-<translation id="7810781339813764006">આગલું જૂથ</translation>
-<translation id="7819187121850078213">વિંડો <ph name="TITLE" /> ટેબ</translation>
-<translation id="7828956995407538686">ઓક્ટોબર</translation>
-<translation id="7839679365527550018">પહેલાનો શબ્દ</translation>
-<translation id="7851816175263618915">કેટલાક વિરામચિહ્ન</translation>
-<translation id="7870596830398826354">ગણિત ML ટ્રી</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox ક્લાસિક ટોગલ કરો.</translation>
-<translation id="7895896691902835279">અજ્ઞાત લિંક</translation>
-<translation id="7927711904086083099">પસંદ કરેલું નથી</translation>
-<translation id="7935627501098484003">સમય નિયંત્રણ</translation>
-<translation id="7939428177581522200">પસંદગીમાં ઉમેરાયું</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{એટ}one{# એટની નિશાની}other{# એટની નિશાની}}</translation>
-<translation id="7965147473449754028">મેનૂ બંધ કર્યું</translation>
-<translation id="7974390230414479278">મેનૂ આઇટમ</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ઉદ્ગારવાચક બિંદુ}one{# ઉદ્ગારવાચક બિંદુઓ}other{# ઉદ્ગારવાચક બિંદુઓ}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{અવતરણ ચિહ્ન}one{# અવતરણ ચિહ્નો}other{# અવતરણ ચિહ્નો}}</translation>
-<translation id="8033827949643255796">પસંદ કરેલ</translation>
-<translation id="8035962149453661158">મહત્તમ: <ph name="X" /></translation>
-<translation id="8042761080832772327">ટેક્સ્ટ, શોધ એન્ટ્રી સંપાદિત કરો</translation>
-<translation id="8049189770492311300">ટાઇમર</translation>
-<translation id="8065607967589909823">પસંદગી આ છે</translation>
-<translation id="8066678206530322333">બેનર</translation>
-<translation id="8110647606445335195">ARIA સ્થળ નિશાનીઓ નથી.</translation>
-<translation id="8153880621934657047">કોષ્ટકની અંદર નથી</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{અંડરસ્કોર}one{# અંડરસ્કોર}other{# અંડરસ્કોર}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">કાપો.</translation>
-<translation id="8199231515320852133">ચાલુ કોષના મથાળાની ઘોષણા કરો</translation>
-<translation id="820417203470636242">ખાલી કોષ.</translation>
-<translation id="8215202828671303819">બહુ પસંદ</translation>
-<translation id="8276439074553447000">પહેલાંની ફોકસ કરવા યોગ્ય આઇટમ પર જમ્પ કરો</translation>
-<translation id="8278417001922463147">કોઈ પહેલાંનો લેખ નથી.</translation>
-<translation id="8283603667300770666">આગલું ફોર્મ ફીલ્ડ</translation>
-<translation id="831207808878314375">વ્યાખ્યા</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">કલાક</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{પાઉન્ડ}one{# પાઉન્ડની નિશાની}other{# પાઉન્ડની નિશાની}}</translation>
-<translation id="8374154622594089836">મહિનો</translation>
-<translation id="8378855320830505539">પ્રદેશ</translation>
-<translation id="8382679411218029383">સ્વતઃપૂર્ણ ઇનલાઇન અને સૂચિ</translation>
-<translation id="8428603554127842284">સ્તર <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">આગલું સ્તર 3 મથાળું નથી.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">પહેલાંનું ચેકબૉક્સ નથી.</translation>
-<translation id="8455868257606149352">મહત્તમ <ph name="X" /></translation>
-<translation id="84575901236241018">ઍક્સેસ કી ધરાવે છે, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">નેવિગેશન ગ્રેન્યુલેરિટી ઘટાડો</translation>
-<translation id="8520472399088452386">સ્પિન બટન</translation>
-<translation id="8538744478902126321">ચાલુ કોષના પંક્તિ મથાળા પર એક અનુમાન કરો</translation>
-<translation id="8540054775867439484">ટોચ પર રૅપ કર્યું</translation>
-<translation id="8548973727659841685">અક્ષર</translation>
-<translation id="8561322612995434619">તેમાં પૉપ અપ છે</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">આગલી સૂચિ આઇટમ</translation>
-<translation id="860150890330522909"><ph name="NAME" /> ચેકબોક્સ ચેક કર્યો છે</translation>
-<translation id="8606621670302093223">તારીખનું નિયંત્રણ</translation>
-<translation id="8631359288236106450">પસંદ કરેલી <ph name="COUNT" /> આઇટમ્સ</translation>
-<translation id="8638532244051952400">વર્તમાન કોષના સહગુણાંકોની ઘોષણા કરો</translation>
-<translation id="8650576015643545550">પહેલાની સૂચિ નથી.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">લિંક્સની સૂચિ બતાવો</translation>
-<translation id="8664519043722036194">સેકંડ</translation>
-<translation id="867187640362843212">મથાળું 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{પાઇપ}one{# વર્ટિકલ પાઇપ}other{# વર્ટિકલ પાઇપ}}</translation>
-<translation id="8735450637152821465">પસંદગી પ્રારંભ કરો</translation>
-<translation id="8743786158317878347">માળખાકીય સામગ્રી દાખલ કરો, જેમ કે કોષ્ટકો</translation>
-<translation id="8747966237988593539">ક્રમાંકિત સૂચિ</translation>
-<translation id="8759334257841767240">આગલી લિંક નથી.</translation>
-<translation id="8767968232364267681">આગલા સ્તર 4 નું મથાળું</translation>
-<translation id="8770473310765924354">માળખાકીય સામગ્રીથી બહાર નીકળો, જેમ કે કોષ્ટકો</translation>
-<translation id="8791025954632646584">સિમેન્ટિક્સ ચાલુ</translation>
-<translation id="8796411681063377102">આગલા સ્તર 3 નું મથાળું</translation>
-<translation id="8808582214901541005">માર્ચ</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">મુખ્ય</translation>
-<translation id="8856538297388979332">આદેશોની સમીક્ષા કરવા માટે ઉપર અથવા નીચે દબાવો, સક્રિય કરવા માટે enter દબાવો</translation>
-<translation id="8864099967139188018">આગલું સ્તર 6 મથાળું નથી.</translation>
-<translation id="8882002077197914455">પંક્તિ હેડર</translation>
-<translation id="8896347895970027998">ChromeVox ને સક્રિય અથવા નિષ્ક્રિય પર ટૉગલ કરો.</translation>
-<translation id="8898516272131543774">વિરામચિહ્ન પડઘાનું આવર્તન</translation>
-<translation id="8900148057318340779">પ્રીફિક્સ કી</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">હેડર્સ ખાલી છે</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">સંશોધક કીઝ</translation>
-<translation id="8943175951035496220">જમણી બાજુએ કોષ નથી.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">ફાઇલ</translation>
-<translation id="9027462562263121875">કોઈ કોષ્ટકો નથી.</translation>
-<translation id="9040132695316389094">મથાળું 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">શોધ વિજેટને ટૉગલ કરો</translation>
-<translation id="9065283790526219006">+પૉપઅપ</translation>
-<translation id="9077213568694924680">પસંદગીમાંથી દૂર કર્યું</translation>
-<translation id="9082874451376019682">પહેલાનું સ્લાઇડર નથી.</translation>
-<translation id="9089864840575085222">લખાણ પડઘાનું આવર્તન</translation>
-<translation id="9107530006868467849">કોઈ પહેલાનું મીડિયા વિજેટ નથી.</translation>
-<translation id="9108370397979208512">ગણિત</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{ટકાવારી}one{# ટકાવારીની નિશાની}other{# ટકાવારીની નિશાની}}</translation>
-<translation id="9115913704608474258">નવેમ્બર</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">વર્તમાન સ્થિતિનું સંક્ષિપ્ત વર્ણન જાહેર કરે છે</translation>
-<translation id="9153606228985488238">પીચ <ph name="PERCENT" /> ટકા</translation>
-<translation id="9160096769946561184">ચાલુ કૉલમની સમાપ્તિ પર જાઓ</translation>
-<translation id="9173115498289768110">વૉલ્યુમ <ph name="PERCENT" /> ટકા</translation>
-<translation id="9178973770513562274">બ્રાઉઝ કરવા માટે, અથવા શોધને લખવા માટે ઉપર અને નીચે એરો કીઝનો ઉપયોગ કરો.</translation>
-<translation id="9192904702577636854">માર્કી</translation>
-<translation id="9212322457209634662">કોઈ આગલો વિભાગ નથી.</translation>
-<translation id="930275611743429116">પસંદગી પ્રારંભ કરો અથવા સમાપ્ત કરો.</translation>
-<translation id="948171205378458592">ભાષણનો રેટ ઘટાડો</translation>
-<translation id="962913030769097253">આગલા સ્તર 1 નું મથાળું</translation>
-<translation id="973955474346881951">સ્ટીકી મોડ સક્ષમ/અક્ષમ કરો</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hi.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hi.xtb
deleted file mode 100644
index acf6c561eeb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hi.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="hi">
-<translation id="1012173283529841972">सूची आइटम</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">स्पैन किया हुआ.</translation>
-<translation id="1025074108959230262">रोचक मोड अक्षम</translation>
-<translation id="1031961866430398710">फिर</translation>
-<translation id="1044777062731150180">कोई शीर्षलेख नहीं</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">अमान्य इनपुट</translation>
-<translation id="1082209053475788238">कोई पिछला स्‍तर 6 शीर्षक नहीं.</translation>
-<translation id="1088219014394087294">कोई शीर्षक नहीं.</translation>
-<translation id="1106741348836243114">ध्वनि फ़ीडबैक (ईयरकॉन) चालू या बंद करें.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="NUM" /> आइटम के साथ <ph name="TAG" /> संकलन</translation>
-<translation id="1155043339247954670">कोई अगला सूची आइटम नहीं.</translation>
-<translation id="1157782847298808853">कीबोर्ड सहायता</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, कॉम्‍बो बॉक्‍स</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, मेनू आइटम, सबमेनू सहित</translation>
-<translation id="1177863135347784049">कस्टम</translation>
-<translation id="1188858454923323853">पूरक</translation>
-<translation id="1206619573307042055">मार्की</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome को ध्‍वनि देना</translation>
-<translation id="1229276918471378188">पिछला जंप</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">अगले स्‍तर 6 का शीर्षक</translation>
-<translation id="1275718070701477396">चयनित</translation>
-<translation id="1319608975892113573">कोई पिछला ब्‍लॉककोट नहीं.</translation>
-<translation id="1321576897702511272">ChromeVox सहायता छिपाएं</translation>
-<translation id="1331702245475014624"><ph name="TOTAL" /> में से <ph name="INDEX" /></translation>
-<translation id="1334095593597963605">वर्ण तथा शब्द इको</translation>
-<translation id="1339428534620983148">पिछला तालिका स्तंभ</translation>
-<translation id="1342835525016946179">लेख</translation>
-<translation id="1346748346194534595">दाएं</translation>
-<translation id="136718599399906424">अगली तालिका पंक्ति</translation>
-<translation id="1383876407941801731">खोज</translation>
-<translation id="1385214448885562192">स्वीकार करने के लिए enter या रद्द करने के लिए escape, अगले के लिए down और पिछले के लिए up दबाएं.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, पासवर्ड लेख बॉक्‍स</translation>
-<translation id="1467432559032391204">बाएं</translation>
-<translation id="1474557363159888097">कोई पिछला एंकर नहीं.</translation>
-<translation id="1502086903961450562">पिछला ग्राफ़‍िक</translation>
-<translation id="1506187449813838456">पिच बढ़ाएं</translation>
-<translation id="151784044608172266">अगला वाक्य</translation>
-<translation id="1524531499102321782">अगली पंक्ति को ब्रेल में लिखें</translation>
-<translation id="1546370775711804143">स्क्रॉल बार</translation>
-<translation id="1559739829547075274">पीछे की ओर नेविगेट करें</translation>
-<translation id="1571643229714746283">ChromeVox तैयार है</translation>
-<translation id="158493514907962286">दिसंबर</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6 बिंदु ब्रेल पर स्विच करें</translation>
-<translation id="1611168825862729585">स्तंभ शीर्षलेख:</translation>
-<translation id="1613476421962910979">ईयरकॉन चालू हैं</translation>
-<translation id="1618597272655350600">वर्तमान स्थिति का संपूर्ण विवरण दर्शाता है</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{इससे बड़ा}one{# इससे बड़ा चिह्न}other{# इससे बड़ा चिह्न}}</translation>
-<translation id="1653266918374749391">पिछले स्‍तर 3 का शीर्षक</translation>
-<translation id="1659072772017912254">चेक नहीं किया गया</translation>
-<translation id="1669290819662866522">सप्ताह</translation>
-<translation id="1674262202423278359">ChromeVox मार्गदर्शक</translation>
-<translation id="16777221443363124">मेनू बार</translation>
-<translation id="1692077714702418899">संरचनात्मक रेखा</translation>
-<translation id="1700517974991662022">देखा गया</translation>
-<translation id="1722567105086139392">लिंक</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">अगला ग्राफ़िक</translation>
-<translation id="1781173782405573156">Pass through कुंजी</translation>
-<translation id="1787176709638001873">पासवर्ड संपादन लेख</translation>
-<translation id="1810107444790159527">सूची बॉक्स</translation>
-<translation id="1828385960365606039">मई</translation>
-<translation id="1834891354138622109">स्तंभ</translation>
-<translation id="1865601187525349519">लेख का अंत</translation>
-<translation id="1876229593313240038">दस्तावेज़</translation>
-<translation id="188130072164734898">वर्तमान समय और दिनांक बोलें.</translation>
-<translation id="1902396333223336119">सेल</translation>
-<translation id="1905379170753160525">शीर्षकों की सूची दिखाएं</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">वर्ष का सप्ताह नियंत्रण</translation>
-<translation id="1964135212174907577">अगला ऑब्जेक्ट</translation>
-<translation id="1969092762068865084">जुलाई</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">पंक्ति शीर्षलेख:</translation>
-<translation id="2002895034995108595">वर्तमान कुंजीमैप को रीसेट करें</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{बायां कोष्ठक}one{# बाएं कोष्ठक}other{# बाएं कोष्ठक}}</translation>
-<translation id="2045490512405922022">चेक नहीं किया गया</translation>
-<translation id="20601713649439366">कोई पिछला गणित का व्यंजक नहीं.</translation>
-<translation id="207477615537953741">शब्दार्थ विज्ञान बंद</translation>
-<translation id="2086961585857038472">अगला शब्‍द</translation>
-<translation id="2089387485033699258">hi</translation>
-<translation id="2091933974477985526">पिछला संपादन-योग्‍य लेख क्षेत्र</translation>
-<translation id="2100350898815792233">सभी विराम चिह्न</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">एक्सेस कुंजी:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">नीचे दी गई सूची से कोई विकल्प चुनकर वर्तमान 6 बिंदु ब्रेल तालिका को बदलें.</translation>
-<translation id="2169714232367507776">वर्तमान आइटम पर क्लिक करें</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{बंद कोष्ठक}one{# बंद कोष्ठक}other{# बंद कोष्ठक}}</translation>
-<translation id="2199994615414171367">पिछला गणित</translation>
-<translation id="2223693656926968778">वर्तमान आइटम पर कार्रवाई करें</translation>
-<translation id="225732394367814946">बोली की दर बढ़ाएं</translation>
-<translation id="2267945578749931355">अगला वर्ण</translation>
-<translation id="2281234842553884450">पिछला स्लाइडर</translation>
-<translation id="2318372665160196757">मुख्य</translation>
-<translation id="2329324941084714723">टैब फलक</translation>
-<translation id="2344193891939537199">दिनांक समय नियंत्रण</translation>
-<translation id="2359897517538099099">तालिका मोड में नहीं है.</translation>
-<translation id="241124561063364910">इसके बाद</translation>
-<translation id="2417569100218200841">सामग्री की जानकारी</translation>
-<translation id="2422937916923936891">मेनू आइटम चेक बॉक्स</translation>
-<translation id="2429669115401274487">अपराह्न</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> अब नया ChromeVox संशोधक है.</translation>
-<translation id="2450814015951372393">चेक बॉक्स</translation>
-<translation id="2462626033734746142">रेडियो बटन समूह</translation>
-<translation id="2471138580042810658">शीर्षक 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{तारा चिह्न}one{# तारा चिह्न}other{# तारा चिह्न}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> को रीसेट कर दिया गया है.</translation>
-<translation id="2553108862507765288">व्याकरण की गलती</translation>
-<translation id="257674075312929031">समूह</translation>
-<translation id="2582407057977008361">अलग</translation>
-<translation id="2589102159832527089">इस पृष्ठ में PDF फ़ाइल &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; से अपने आप निकला हुआ लेख शामिल है. &lt;a href="<ph name="URL" />"&gt;मूल के लिए यहां क्लिक करें.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">इनके साथ {COUNT,plural, =1{# आइटम}one{# आइटम}other{# आइटम}}</translation>
-<translation id="2614981083756825552">गणित ML लेआउट</translation>
-<translation id="2626530649491650971">क्‍लिक करने योग्‍य</translation>
-<translation id="2628764385451019380">कोई पिछला कॉम्बो बॉक्स नहीं.</translation>
-<translation id="2637227747952042642">गणित</translation>
-<translation id="2639750663247012216">ChromeVox संशोधक</translation>
-<translation id="2644542693584024604">गलत वर्तनी</translation>
-<translation id="2667291555398229137">रूटिंग कुंजी के अंतर्गत आइटम क्लिक करें</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{खुला कोष्ठक}one{# खुले कोष्ठक}other{# खुले कोष्ठक}}</translation>
-<translation id="2705875883745373140">दबाया नहीं गया</translation>
-<translation id="2706462751667573066">ऊपर</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ऑडियो</translation>
-<translation id="2732718972699418926">पूर्वाह्न</translation>
-<translation id="2749275490991666823">चेक किया गया</translation>
-<translation id="27527859628328957">अगले फ़ोकस करने योग्‍य आइटम पर जंप करें</translation>
-<translation id="2770781857296573485">समूह अन्‍वेषण डालें</translation>
-<translation id="2777845298774924149">बाहर हो गया</translation>
-<translation id="2800204403141299078">कोई और भिन्‍न तत्‍व नहीं.</translation>
-<translation id="2800780099804980316">कोई पिछला स्‍तर 1 शीर्षक नहीं.</translation>
-<translation id="2811204574343810641">पंक्ति</translation>
-<translation id="2816654101880605877">कोई अगला स्लाइडर नहीं.</translation>
-<translation id="2841013758207633010">समय</translation>
-<translation id="2843837985843789981">पिछला समूह</translation>
-<translation id="2844995807198708617">प्रसंग मेनू</translation>
-<translation id="2849332794118375855">कोई अगला चेकबॉक्स नहीं.</translation>
-<translation id="2864481629947106776">पिछला लिंक</translation>
-<translation id="2873259058405069099">तालिका के प्रारंभ पर जाएं</translation>
-<translation id="2894654529758326923">जानकारी</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{बायां कोष्ठक}one{# बाएं कोष्ठक}other{# बाएं कोष्ठक}}</translation>
-<translation id="2911433807131383493">ChromeVox निर्देश खोलें</translation>
-<translation id="2932083475399492303">संरचनात्मक या लेआउट के बीच रेखा प्रकार टॉगल करें</translation>
-<translation id="2964026537669811554">शीर्षक समूह</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{टैब}one{# टैब}other{# टैब}}</translation>
-<translation id="2972078295414139404">पहले देखा गया कोई लिंक नहीं.</translation>
-<translation id="2972205263822847197">टूल टिप</translation>
-<translation id="2998131015536248178">पिछला वर्ण</translation>
-<translation id="2999559350546931576">पिच घटाएं</translation>
-<translation id="2999945368667127852">कोई अगला मीडिया विजेट नहीं.</translation>
-<translation id="3012414509011670858">कोई पिछला अनुभाग नहीं.</translation>
-<translation id="3030432017085518523">मेनू आइटम रेडियो बटन</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{संबंध कारक चिह्न}one{# संबंध कारक चिह्न}other{# संबंध कारक चिह्न}}</translation>
-<translation id="3046838483509668188">ChromeVox विकल्प</translation>
-<translation id="3047143736589213134">प्रयोगात्‍मक कीमैप</translation>
-<translation id="3060756054951570867"><ph name="TITLE" />, मेनू खुल गया</translation>
-<translation id="3078345202707391975">अगले स्तर 2 का शीर्षक</translation>
-<translation id="3078740164268491126">तालिका</translation>
-<translation id="3082557070674409251">क्लिक किया गया</translation>
-<translation id="3084806535845658316">कोई टाइपिंग इको नहीं</translation>
-<translation id="3086746722712840547">नोट</translation>
-<translation id="308895241372589742">कोई अगला गणित का व्यंजक नहीं.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">अगला स्थानचिह्न</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">संक्षिप्त</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">स्थानचिह्न की सूची दिखाएं</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">अगली पंक्ति</translation>
-<translation id="3155083529632865074">कोई पिछला बटन नहीं.</translation>
-<translation id="3163593631834463955">खाली स्तंभ शीर्षलेख</translation>
-<translation id="316542773973815724">मार्गदर्शक</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{रिक्ति}one{# रिक्तियां}other{# रिक्तियां}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> डाला/डाली</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, टैब</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">देखा गया लिंक</translation>
-<translation id="323731244387692321">ChromeVox कीबोर्ड सहायता खोलें</translation>
-<translation id="3241052487511142956">पहले देखा गया लिंक</translation>
-<translation id="3286390186030710347">स्लाइडर</translation>
-<translation id="3299925995433437805">बाद में देखा गया कोई लिंक नहीं.</translation>
-<translation id="3303384412438961941">किसी भी कुंजी का नाम जानने के लिए उसे दबाएं. Ctrl+W से कीबोर्ड एक्‍सप्‍लोरर बंद हो जाएगा.</translation>
-<translation id="3307886118343381874">तालिका के अंत में जाएं</translation>
-<translation id="3311969765485641742">नोटिफिकेशन की समीक्षा करने के लिए Alt+Shift+A दबाएं</translation>
-<translation id="3312997241656799641">बाद में देखा गया लिंक</translation>
-<translation id="3321460131042519426">शब्द लपेटना सक्षम करें</translation>
-<translation id="3322936298410871309">पिछले स्‍तर 1 का शीर्षक</translation>
-<translation id="3323447499041942178">टेक्स्ट बॉक्‍स</translation>
-<translation id="3353420241558113817">{"ar": "अरबी",
- "bg": "बुल्गारियाई",
- "ca": "कातलान",
- "cs": "चेक",
- "da": "डैनिश",
- "de": "जर्मन",
- "de_CH": "जर्मन (स्विट्‍ज़रलैंड)",
- "de_DE": "जर्मन (जर्मनी)",
- "el": "यूनानी",
- "en": "अंग्रेज़ी",
- "en_CA": "अंग्रेज़ी (कनाडा)",
- "en_GB": "अंग्रेज़ी (युनाइटेड किंगडम)",
- "en_US": "अंग्रेज़ी (युनाइटेड स्टेट्स)",
- "es": "स्पैनिश",
- "et": "एस्टोनियाई",
- "fr": "फ़्रेंच",
- "fr_CA": "फ़्रेंच (कनाडा)",
- "fr_FR": "फ़्रेंच (फ़्रांस)",
- "fi": "फ़िनिश",
- "he": "हिब्रू",
- "hi": "हिन्दी",
- "hr": "क्रोएशियाई",
- "hu": "हंगेरियाई",
- "is": "आइसलैंडिक",
- "it": "इतालवी",
- "ko": "कोरियाई",
- "lt": "लिथुआनियाई",
- "lv": "लातवियाई",
- "nb": "नॉर्वेजियाई बोकमाल",
- "nl": "डच",
- "pl": "पोलिश",
- "pt": "पुर्तगाली",
- "ro": "रोमानियाई",
- "ru": "रूसी",
- "sk": "स्लोवाक",
- "sl": "स्लोवेनियाई",
- "sr": "सर्बियाई",
- "sv": "स्वीडिश",
- "tr": "तुर्की",
- "vi": "वियतनामी",
- "zh": "चीनी",
- "zh_TW": "चीनी (पारंपरिक हान)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{धन}one{# धन चिह्न}other{# धन चिह्न}}</translation>
-<translation id="338583716107319301">विभाजक</translation>
-<translation id="3389259863310851658">पिछला फ़ॉर्म फ़ील्‍ड</translation>
-<translation id="3390225400784126843">अगला भिन्न तत्व.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, मेनू आइटम</translation>
-<translation id="3406283310380167331">फ़ॉर्म सूची दिखाएं</translation>
-<translation id="3422338090358345848">कीबोर्ड एक्‍सप्‍लोरर खोलें</translation>
-<translation id="3457000393508828486">आंशिक रूप से दबाया गया</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, बटन</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> से <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{दायां कोष्ठक}one{# दाएं कोष्ठक}other{# दाएं कोष्ठक}}</translation>
-<translation id="3493915602752813531">कोई अगला एंकर नहीं.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{प्रश्न चिह्न}one{# प्रश्न चिह्न}other{# प्रश्न चिह्न}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{कैरेट}one{# कैरेट}other{# कैरेट}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, चेकबॉक्‍स चेक न‍हीं किया गया</translation>
-<translation id="3599054940393788245">गणना में नहीं</translation>
-<translation id="3616113530831147358">ऑडियो</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{बैकटिक}one{# बैकटिक}other{# बैकटिक}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{डॉलर}one{# डॉलर चिह्न}other{# डॉलर चिह्न}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, सूची बॉक्‍स</translation>
-<translation id="3687295507293856493">वर्तमान सेल के स्‍तंभ शीर्ष लेख पर कोई अनुमान लगाएं</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">बोली नियंत्रित करना</translation>
-<translation id="3716845769494773620">एकाधिक पंक्ति</translation>
-<translation id="3731746171184829332">कोई पिछला शीर्षक नहीं.</translation>
-<translation id="3762198587642264450">वर्तमान पंक्ति के अंत में जाएं</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">डॉयलॉग से बाहर हो गए हैं.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">स्वत: पूर्णता सूची</translation>
-<translation id="3810838688059735925">वीडियो</translation>
-<translation id="3816633764618089385">अगला मीडिया</translation>
-<translation id="3819376190738087562">कोई जंप नहीं.</translation>
-<translation id="385383972552776628">विकल्प पृष्ठ खोलें</translation>
-<translation id="3856075812838139784">केवल पढ़ने के लिए</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">मेनू</translation>
-<translation id="3909320334364316587">पिछले स्‍तर 6 का शीर्षक</translation>
-<translation id="3914173277599553213">आवश्यक</translation>
-<translation id="3962990492275676168">वर्तमान स्‍थान से पढ़ना प्रारंभ करें</translation>
-<translation id="4004802134384979325">चेक किया गया</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">माह नियंत्रण</translation>
-<translation id="4039983576244166038">खाली पंक्ति शीर्षलेख</translation>
-<translation id="4042843249978639960">कोई अगला स्तर 2 शीर्षक नहीं.</translation>
-<translation id="4043348641337972076">कोई पिछला ARIA स्थानचिह्न नहीं.</translation>
-<translation id="4047216625641135770">मार्क</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{टिल्ड}one{# टिल्ड}other{# टिल्ड}}</translation>
-<translation id="409334809956508737">पिछला ऑब्जेक्ट</translation>
-<translation id="4099274309791143834">सबमेनू के साथ</translation>
-<translation id="4107807507418787238">नीचे कोई सेल नहीं.</translation>
-<translation id="4116415223832267137">सूचना</translation>
-<translation id="4147126331795725888">कोई अगला नियंत्रण नहीं.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{दायां कोष्ठक}one{# दाएं कोष्ठक}other{# दाएं कोष्ठक}}</translation>
-<translation id="4158704014418536539">केस संवेदी</translation>
-<translation id="4161663686871496107">ChromeVox बोले जाने वाला फ़ीडैबक तैयार है</translation>
-<translation id="4173994908659439270">कोई अगला संपादन-योग्य लेख फ़ील्ड नहीं.</translation>
-<translation id="4176463684765177261">अक्षम</translation>
-<translation id="4188530942454211480">पिछला वाक्य</translation>
-<translation id="4202186506458631436">दाएं ले जाएं</translation>
-<translation id="4206289001967551965">तालिका के अंदर</translation>
-<translation id="4215733775853809057">अगला स्लाइडर</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{डैश}one{# डैश}other{# डैश}}</translation>
-<translation id="421884353938374759">रंग पिकर</translation>
-<translation id="4229646983878045487">दिनांक समय</translation>
-<translation id="423334822609210999">कोई बायां सेल नहीं.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, ग्रेड <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">नोट</translation>
-<translation id="4254798249533888099">ट्री</translation>
-<translation id="4255943572433203166">ChromeVox को कस्टमाइज़ करने के लिए नीचे दिए गए विकल्‍पों का उपयोग करें. बदलाव तुरंत लागू हो जाते हैं.</translation>
-<translation id="4271220233568730077">अगला गणित</translation>
-<translation id="4271521365602459209">और अधिक परिणाम नहीं.</translation>
-<translation id="4287520460805643128">कोई अगला लेख नहीं.</translation>
-<translation id="4289540628985791613">संक्षिप्त विवरण</translation>
-<translation id="4300318234632215983">किसी लिंक के पीछे का URL प्रदर्शित करें</translation>
-<translation id="4301352596632316575">सबमेनू है</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{बिंदु}=3{पदलोप चिह्न}one{# बिंदु}other{# बिंदु}}</translation>
-<translation id="4347461890115250064">कोई अगली सूची नहीं.</translation>
-<translation id="4367650418938037324">गणित ML लीफ़</translation>
-<translation id="4372435075475052704">न्यूनतम:<ph name="X" /></translation>
-<translation id="4372705107434148843">बोली रोकें</translation>
-<translation id="4373197658375206385">कोई पिछला आइटम नहीं जो लिंक नहीं है.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">रीसेट करें</translation>
-<translation id="4471074325120394300">कोई लिंक नहीं.</translation>
-<translation id="4476183483923481720">नई पंक्ति</translation>
-<translation id="4482330759234983253">पिछली तालिका</translation>
-<translation id="4491109536499578614">चित्र</translation>
-<translation id="4529987814483543472">क्लासिक कीमैप</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{स्लैश}one{# स्लैश}other{# स्लैश}}</translation>
-<translation id="4547556996012970016">अगले स्तर 5 का शीर्षक</translation>
-<translation id="4562381607973973258">शीर्षलेख</translation>
-<translation id="4591507479202817876">, चयनित</translation>
-<translation id="4597532268155981612">फ़ॉर्म</translation>
-<translation id="4597896406374528575">अप्रैल</translation>
-<translation id="4615592953348396470">अगली कुंजी दबाने पर ध्यान न देना</translation>
-<translation id="461613135510474570">वाक्य</translation>
-<translation id="4647836961514597010">रंग पिकर</translation>
-<translation id="4661075872484491155">ट्री</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">पिछला थानचिह्न</translation>
-<translation id="4696413482802371445">कोई अगला स्‍तर 5 शीर्षक नहीं.</translation>
-<translation id="4729095194763193578">पिछली तालिका पंक्ति</translation>
-<translation id="4736221692378411923">अगस्त</translation>
-<translation id="4740661827607246557">सहायता आदेश</translation>
-<translation id="4759716709594980008">ChromeOS कीबोर्ड एक्‍सप्‍लोरर</translation>
-<translation id="4763296182459741068">नीचे तक लपेटा गया</translation>
-<translation id="4763480195061959176">वीडियो</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">वर्तमान पृष्ठ का शीर्षक प्रदर्शित करें</translation>
-<translation id="4826415162591436065">आगे की ओर नेविगेट करें</translation>
-<translation id="4826604887384865800">अगला जंप</translation>
-<translation id="4827410568042294688">अचयनित</translation>
-<translation id="4842108708071771135">कोई अगला ब्लॉककोट नहीं.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">पिछला समान तत्व.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS लॉगिंग सक्षम करें</translation>
-<translation id="4877261390094455813">खोज क्वेरी डालें.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">आंतरिक लिंक</translation>
-<translation id="4953585991029886728">लेख संपादित करें</translation>
-<translation id="4954534434583049121">पिछला ब्‍लॉक कोट</translation>
-<translation id="4973717656530883744">न्‍यूनतम <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> पर स्विच किया गया.</translation>
-<translation id="4975416682604111799">मिलीसेकंड</translation>
-<translation id="49787999531187221">ChromeVox अब निष्क्रिय हो गया है.</translation>
-<translation id="4979404613699303341">पिछला बटन</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, सूची बॉक्‍स</translation>
-<translation id="4983588134362688868">पृष्ठ के शीर्ष पर जाएं</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, विंडो</translation>
-<translation id="4993152509206108683">दर <ph name="PERCENT" /> प्रतिशत</translation>
-<translation id="4996716799442435517">विज़ुअल</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, रेडियो बटन चयनित</translation>
-<translation id="4997475792277222884">कोई अगला आइटम नहीं जो लिंक नहीं है.</translation>
-<translation id="5000760171916499057">कोई फ़ॉर्म नहीं.</translation>
-<translation id="5005670136041063723">कोई और समान तत्‍व नहीं.</translation>
-<translation id="501473567976723023">जनवरी</translation>
-<translation id="5041394372352067729">ब्रेल प्रदर्शन को पृष्ठ के शीर्ष पर ले जाएं</translation>
-<translation id="5042770794184672516">बोली वॉल्‍यूम बढ़ाएं</translation>
-<translation id="5050015258024679800">पिछले स्‍तर 4 का शीर्षक</translation>
-<translation id="5054047268577924192">पिछला सूची आइटम</translation>
-<translation id="5078661581131202757">फ़ाइल चयन</translation>
-<translation id="5080758118274074384">डबल क्लिक किया गया</translation>
-<translation id="5098541983634824365">ग्रिड छोड़ रहे हैं.</translation>
-<translation id="5102981729317424850">टूल बार</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">कोई पिछला फ़ॉर्म फ़ील्ड नहीं.</translation>
-<translation id="5111640677200759579">स्‍तंभ शीर्षलेख</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">कोई पिछला लिंक नहीं.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, अचयनित</translation>
-<translation id="5183440668879371625">पिछली पंक्ति को ब्रेल में लिखें</translation>
-<translation id="5184944171021383281">कोई अगला फ़ॉर्म फ़ील्‍ड नहीं.</translation>
-<translation id="5189244881767082992">पंक्ति</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> पहले से किसी आदेश को असाइन की हुई है.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> सूची.</translation>
-<translation id="520883772648104506">कोई अगला रेडियो बटन नहीं.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">समाप्त</translation>
-<translation id="5291783959063340370">ऑब्जेक्ट</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, टैब</translation>
-<translation id="5310788376443009632">निकाले गए:</translation>
-<translation id="5320727453979144100">रोचक मोड सक्षम</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{अल्पविराम}one{# अल्पविराम}other{# अल्पविराम}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, लेख बॉक्‍स</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, लिंक</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">निरंतर पढ़ने के दौरान पीछे जाएं छोड़ें</translation>
-<translation id="5368000168321181111">ईयरकॉन बंद हैं</translation>
-<translation id="5374320867641260420">कोई अगला बटन नहीं.</translation>
-<translation id="5382299583965267720">कोई अगला स्तर 1 शीर्षक नहीं.</translation>
-<translation id="5402367795255837559">ब्रेल</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{अर्धविराम}one{# अर्धविराम}other{# अर्धविराम}}</translation>
-<translation id="5411891038905756502">कोई पिछला जंप बिंदु नहीं.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{इससे कम}one{# इससे कम चिह्न}other{# इससे कम चिह्न}}</translation>
-<translation id="5455441614648621694">पूरक</translation>
-<translation id="5485036206801896268">कोई पिछला ग्राफ़िक नहीं.</translation>
-<translation id="5486947920110100234">कोई अगला जंप बिंदु नहीं.</translation>
-<translation id="549602578321198708">शब्‍द</translation>
-<translation id="5500932716852106146">कोई पिछला संपादन-योग्य लेख फ़ील्ड नहीं.</translation>
-<translation id="5502713021410870035">सितंबर</translation>
-<translation id="5507663321906818013">बेंचमार्क को डीबग करें</translation>
-<translation id="5518443085409638729">लेख (जैसे Mac OS X) को संपादित करते समय कर्सर को वर्णों के बीच रखें.</translation>
-<translation id="552195134157544755">रेडियो बटन</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">कोई पिछला स्तर 5 शीर्षक नहीं.</translation>
-<translation id="556042886152191864">बटन</translation>
-<translation id="5561345396546889625">अगली सूची</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">लेख, ईमेल प्रविष्टि संपादित करें</translation>
-<translation id="5597170376237141345">अगला चेकबॉक्‍स</translation>
-<translation id="5597933780944041114">कोई अगला शीर्षक नहीं.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, रेडियो बटन अचयनित</translation>
-<translation id="5601172225407283979">डिफ़ॉल्ट सेटिंग चलाएं</translation>
-<translation id="5608798115546226984">स्वतः पूर्णता इनलाइन</translation>
-<translation id="561939826962581046">समय</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">लॉग</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">कोई पिछली तालिका नहीं.</translation>
-<translation id="5655682562155942719">आदेशों पर जाएं</translation>
-<translation id="56637627897541303">लेख क्षेत्र</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">स्थानचिह्न</translation>
-<translation id="5683155931978483559">पिछला चेकबॉक्स</translation>
-<translation id="5684277895745049190">सूची</translation>
-<translation id="5700650669149824506">कोई पिछला स्तर 4 शीर्षक नहीं.</translation>
-<translation id="5709192780268610569">कोई बड़ा विवरण नहीं</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">अगला तालिका स्‍तंभ</translation>
-<translation id="571866080859340309">समूहों को एक्सप्लोर कर रहा है</translation>
-<translation id="5728409797179002635">कोई तालिका नहीं मिली.</translation>
-<translation id="5748623122140342504">पिछले स्‍तर 5 का शीर्षक</translation>
-<translation id="5750633686117194034">कोई संशोधक नहीं दबाया गया; कृपया एक या अधिक संशोधक दबाकर रखें; पूर्ण हो जाने पर अपनी अंगुलियां उठा लें और आपको सुनाई देगा कि कुंजियां सेट हो गई हैं. बाहर निकलने के लिए टैब दबाएं.</translation>
-<translation id="5788275253279308023">गुप्‍त विंडो, <ph name="TITLE" />, टैब</translation>
-<translation id="5806206155699461681">विशिष्ट साइटें (जैसे Google खोज) एन्‍हांस करें.</translation>
-<translation id="5819072574982403430">ट्री आइटम</translation>
-<translation id="5826479389509458994">पंक्ति <ph name="ROW" /> स्तंभ <ph name="COL" /></translation>
-<translation id="5850707923114094062">पीछे पैन करें</translation>
-<translation id="5851548754964597211">टैब सूची</translation>
-<translation id="5859752971144398932">ढूंढें पृष्ठ से बाहर हो गया.</translation>
-<translation id="5866042630553435010">आंशिक रूप से चेक किया गया</translation>
-<translation id="5869546221129391014">ग्रिड</translation>
-<translation id="5876817486144482042">बोली वॉल्‍यूम घटाएं</translation>
-<translation id="5887397643266327462">ब्रेल कैप्शन सक्षम किए गए.</translation>
-<translation id="5891934789323004067">तालिका</translation>
-<translation id="5919442531159595654">प्रतिलिपि बनाएं.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{बराबर}one{# बराबर चिह्न}other{# बराबर चिह्न}}</translation>
-<translation id="5939518447894949180">रीसेट करें</translation>
-<translation id="5948123859135882163">गणितीय व्यंजकों की व्याख्या को संरचनात्मक और शब्दार्थ विज्ञान के बीच टॉगल करें</translation>
-<translation id="5955304353782037793">ऐप्स</translation>
-<translation id="5956928062748260866">डॉयलॉग</translation>
-<translation id="5963413905009737549">अनुभाग</translation>
-<translation id="5968607524793740041">प्रसंग मेनू दिखाएं</translation>
-<translation id="5983179082906765664">मार्गदर्शक विवरण का स्‍तर बढ़ाएं</translation>
-<translation id="5999630716831179808">ध्वनियां</translation>
-<translation id="6000417740266304866">नीचे दी गई सूची से कोई विकल्प चुनकर वर्तमान 8 बिंदु ब्रेल तालिका को बदलें.</translation>
-<translation id="6006050241733874051">फ़ॉर्म</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{बैकस्लैश}one{# बैकस्लैश}other{# बैकस्लैश}}</translation>
-<translation id="6037602951055904232">आगे की ओर पैन करें</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">सेल के अंत में.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Space</translation>
-<translation id="6142308968191113180">शीर्षक 4</translation>
-<translation id="6169420925157477918">बड़े विवरण वाला चित्र</translation>
-<translation id="6172087735260766220">कॉपी-संरक्षित PDF से ऐक्सेस योग्य लेख की ऐक्सेस करने में असमर्थ.</translation>
-<translation id="6186305613600865047">पृष्ठ में नीचे जाएं</translation>
-<translation id="6193330012414963395">पूर्वाह्न अपराह्न</translation>
-<translation id="622484624075952240">नीचे</translation>
-<translation id="6236061028292614533">अगला शीर्षक</translation>
-<translation id="6254901459154107917">अगला संपादन-योग्‍य लेख क्षेत्र</translation>
-<translation id="6259464875943891919">बाहर निकल गए <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">अगला समान तत्व.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">कोई अगला कॉम्‍बो बॉक्‍स नहीं.</translation>
-<translation id="6307969636681130414">दबाया गया</translation>
-<translation id="6324551002951139333">व्याकरण की गलती का पता चला</translation>
-<translation id="6348657800373377022">कॉम्बो बॉक्स</translation>
-<translation id="6355910664415701303">कोई पिछला सूची आइटम नहीं.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">पिछला शीर्षक</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">कोई पिछला रेडियो बटन नहीं.</translation>
-<translation id="6414968628640960377">पिछला भिन्न तत्व.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{विरामचिह्न}one{# विरामचिह्न}other{# विरामचिह्न}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, मेनू</translation>
-<translation id="6444046323172968959">सूचना डॉयलॉग</translation>
-<translation id="6459511626086141404">फ़्लैट कीमैप</translation>
-<translation id="6468049171101508116">अगला बटन</translation>
-<translation id="6491972999578897419">नीचे दी गई सूची से विकल्प चुनकर वर्तमान ध्वनि बदलें.</translation>
-<translation id="6508059270146105198">ब्रेल प्रदर्शन को पृष्ठ के नीचे ले जाएं</translation>
-<translation id="6536864053412760904">गणित ML टोकन</translation>
-<translation id="6550720799683018100">नीचे दी गई सूची से विकल्प चुनकर वर्तमान कीमैप बदलें.</translation>
-<translation id="6561818612645211875">वर्तमान पंक्ति के प्रारंभ पर जाएं</translation>
-<translation id="6587021927234520429">कोई अगला स्तर 4 शीर्षक नहीं.</translation>
-<translation id="6601344353291556895">शब्‍दाडंबरपूर्ण वर्णन सक्षम करें.</translation>
-<translation id="6615602925644411249">पृष्ठ में ढूंढें.</translation>
-<translation id="6633350132811819843">कोई अगली तालिका नहीं.</translation>
-<translation id="6637586476836377253">लॉग</translation>
-<translation id="6657128831881431364">प्रगति बार</translation>
-<translation id="6659594942844771486">टैब</translation>
-<translation id="667999046851023355">दस्तावेज़</translation>
-<translation id="6697092096875747123">पिछला कॉम्बो बॉक्स</translation>
-<translation id="6714813999819678458">पिछले स्‍तर 2 का शीर्षक</translation>
-<translation id="6716505898850596801">संशोधक कुंजियां</translation>
-<translation id="671916444866103745">कोई अगला ARIA स्थानचिह्न नहीं है.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, कॉम्‍बो बॉक्‍स</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> आइटम के साथ</translation>
-<translation id="6736510033526053669">टैब बनाया गया</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">लेख</translation>
-<translation id="6787839852456839824">कीबोर्ड शॉर्टकट</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">पादलेख</translation>
-<translation id="6871161210040114857">केस को अनदेखा करना.</translation>
-<translation id="6877435256196695200">कोई अगला ग्राफ़िक नहीं.</translation>
-<translation id="6897341342232909480">बाएं ले जाएं</translation>
-<translation id="6901540140423170855">दिनांक</translation>
-<translation id="6910211073230771657">हटाया गया</translation>
-<translation id="6911965441508464308">ऊपर कोई सेल नहीं.</translation>
-<translation id="6919104639734799681">तालिकाओं की सूची दिखाएं</translation>
-<translation id="6964088412282673743">कोई पिछला नियंत्रण नहीं.</translation>
-<translation id="6996566555547746822">अगला कॉम्बो बॉक्स</translation>
-<translation id="7005146664810010831">कोई URL नहीं मिला</translation>
-<translation id="7010712454773919705">ChromeVox संशोधक कुंजी</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">पिछली सूची</translation>
-<translation id="7041173719775863268">चयन समाप्त करें</translation>
-<translation id="7095834689119144465">केवल संख्यात्मक लेख संपादित करें</translation>
-<translation id="7096001299300236431">पिछला मीडिया</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">शब्द इको</translation>
-<translation id="713824876195128146">अगला ब्‍लॉक कोट</translation>
-<translation id="7161771961008409533">पॉप-अप बटन</translation>
-<translation id="7167657087543110">वर्ण इको</translation>
-<translation id="7170733337935166589">निरंतर पढ़ने के दौरान आगे जाएं छोड़ें</translation>
-<translation id="7181697990050180700">अक्‍सर उपयोग किए जाने वाले आदेशों को नीचे दी गई संबंधित फ़ील्‍ड में लिखकर उनके लिए कीबोर्ड शॉर्टकट कस्‍टमाइज़ करें.</translation>
-<translation id="7203150201908454328">विस्तृत</translation>
-<translation id="7210211103303402262">मिनट</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">रेखा</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">शीर्षक</translation>
-<translation id="7241683698754534149">बड़ा विवरण नए टैब में खोलें</translation>
-<translation id="7248671827512403053">ऐप्स </translation>
-<translation id="725969808843520477">अगला रेडियो बटन</translation>
-<translation id="7269119382257320590">कोई विराम चिह्न नहीं</translation>
-<translation id="7273174640290488576">खाली</translation>
-<translation id="7285387653379749618">तालिकाएं</translation>
-<translation id="7289186959554153431">शीर्षक 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">ब्रेल कैप्शन अक्षम किए गए.</translation>
-<translation id="7318872822751139669">फ़ोकस बदलने के लिए माउस का उपयोग करें.</translation>
-<translation id="7322388933135261569">फरवरी</translation>
-<translation id="7332592614823088566"><ph name="ROWTOTAL" /> में से <ph name="ROWINDEX" /> पंक्ति, <ph name="COLTOTAL" /> में से <ph name="COLINDEX" /> स्‍तंभ</translation>
-<translation id="7336596009609913925">पॉपअप है</translation>
-<translation id="7356165926712028380">8 बिंदु ब्रेल पर स्विच करें</translation>
-<translation id="7362871137496673139">कोई पिछला स्तर 2 शीर्षक नहीं.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ऐम्परसेंड}one{# ऐम्परसेंड}other{# ऐम्परसेंड}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">तालिका छोड़ रहे हैं.</translation>
-<translation id="739763518212184081">पिछली पंक्ति</translation>
-<translation id="7400575256015741911">वर्तनी की गलती का पता चला</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">वापस लौटें</translation>
-<translation id="7434509671034404296">डेवलपर</translation>
-<translation id="7439060726180460871">निर्देशिका</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">टैब</translation>
-<translation id="7492049978501397201">डाला गया डॉयलॉग</translation>
-<translation id="7532613204005497612">जून</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, स्‍लाइडर</translation>
-<translation id="7586163296341959563">चिपकाएं.</translation>
-<translation id="7596919493010894443">साफ़ किया गया अनुभाग</translation>
-<translation id="7604026522577407655">वर्तमान स्‍तंभ के प्रारंभ पर जाएं</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">वर्तमान पृष्ठ का URL प्रदर्शित करें</translation>
-<translation id="7609363189280667021">ब्रेल कैप्शन टॉगल करें</translation>
-<translation id="762020119231868829">वर्तमान में चल रहे सभी मीडिया विजेट को रोकता है</translation>
-<translation id="7625690649919402823">अगली तालिका</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), ग्रेड <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">कोई पिछला स्तर 3 शीर्षक नहीं.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, लेख बॉक्‍स</translation>
-<translation id="7663318257180412551">शीर्षक 2</translation>
-<translation id="7674576868851035240">अगला लिंक</translation>
-<translation id="7674768236845044097">चिह्नित करें</translation>
-<translation id="7684431668231950609">लेख, URL प्रविष्टि संपादित करें</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">पिछला रेडियो बटन</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, पासवर्ड लेख बॉक्‍स</translation>
-<translation id="7805247615045262757">डिफ़ॉल्ट मार्गदर्शक</translation>
-<translation id="7805768142964895445">स्थिति</translation>
-<translation id="7810781339813764006">अगला समूह</translation>
-<translation id="7819187121850078213">विंडो <ph name="TITLE" /> टैब</translation>
-<translation id="7828956995407538686">अक्टूबर</translation>
-<translation id="7839679365527550018">पिछला शब्‍द</translation>
-<translation id="7851816175263618915">कुछ विराम चिह्न</translation>
-<translation id="7870596830398826354">गणित ML ट्री</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox क्लासिक को टॉगल करें.</translation>
-<translation id="7895896691902835279">अज्ञात लिंक</translation>
-<translation id="7927711904086083099">चयनित नहीं</translation>
-<translation id="7935627501098484003">समय नियंत्रण</translation>
-<translation id="7939428177581522200">चयन में जोड़े गए</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{ऐट}one{# ऐट चिह्न}other{# ऐट चिह्न}}</translation>
-<translation id="7965147473449754028">मेनू बंद किया</translation>
-<translation id="7974390230414479278">मेनू आइटम</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{विस्मयादिबोधक चिह्न}one{# विस्मयादिबोधक चिह्न}other{# विस्मयादिबोधक चिह्न}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{उद्धरण}one{# उद्धरण}other{# उद्धरण}}</translation>
-<translation id="8033827949643255796">चयनित</translation>
-<translation id="8035962149453661158">अधि:<ph name="X" /></translation>
-<translation id="8042761080832772327">लेख, खोज प्रविष्टि संपादित करें</translation>
-<translation id="8049189770492311300">टाइमर</translation>
-<translation id="8065607967589909823">यह चयनित है:</translation>
-<translation id="8066678206530322333">बैनर</translation>
-<translation id="8110647606445335195">कोई ARIA स्थानचिह्न नहीं.</translation>
-<translation id="8153880621934657047">तालिका में नहीं है.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{अंडरस्कोर}one{# अंडरस्कोर}other{# अंडरस्कोर}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">काटें.</translation>
-<translation id="8199231515320852133">वर्तमान सेल के शीर्षलेखों को प्रदर्शित करें</translation>
-<translation id="820417203470636242">खाली सेल.</translation>
-<translation id="8215202828671303819">एकाधिक चयन</translation>
-<translation id="8276439074553447000">पिछले फ़ोकस करने योग्‍य आइटम पर जंप करें</translation>
-<translation id="8278417001922463147">कोई पिछला लेख नहीं.</translation>
-<translation id="8283603667300770666">अगला फ़ॉर्म फ़ील्‍ड</translation>
-<translation id="831207808878314375">परिभाषा</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">घंटे</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{पाउंड}one{# पाउंड चिह्न}other{# पाउंड चिह्न}}</translation>
-<translation id="8374154622594089836">माह</translation>
-<translation id="8378855320830505539">क्षेत्र</translation>
-<translation id="8382679411218029383">स्वत: पूर्णता इनलाइन और सूची</translation>
-<translation id="8428603554127842284">स्तर <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">कोई अगला स्‍तर 3 शीर्षक नहीं.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">कोई पिछला चेकबॉक्स नहीं.</translation>
-<translation id="8455868257606149352">अधिकतम <ph name="X" /></translation>
-<translation id="84575901236241018">एक्सेस कुंजी है, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">मार्गदर्शक विवरण का स्तर घटाएं</translation>
-<translation id="8520472399088452386">स्पिन बटन</translation>
-<translation id="8538744478902126321">वर्तमान सेल के पंक्ति शीर्षलेख पर कोई अनुमान लगाएं</translation>
-<translation id="8540054775867439484">शीर्ष पर लपेटा गया</translation>
-<translation id="8548973727659841685">अक्षर</translation>
-<translation id="8561322612995434619">पॉप अप है</translation>
-<translation id="8571096049907249734">एकाधिक चयन</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">अगला सूची आइटम</translation>
-<translation id="860150890330522909"><ph name="NAME" />, चेकबॉक्‍स चेक किया गया</translation>
-<translation id="8606621670302093223">दिनांक नियंत्रण</translation>
-<translation id="8631359288236106450">चयनित <ph name="COUNT" /> आइटम</translation>
-<translation id="8638532244051952400">वर्तमान सेल निर्देशांक बताएं</translation>
-<translation id="8650576015643545550">कोई पिछली सूची नहीं.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">लिंक सूची दिखाएं</translation>
-<translation id="8664519043722036194">सेकंड</translation>
-<translation id="867187640362843212">शीर्षक 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{पाइप}one{# लम्बवत पाइप}other{# लम्बवत पाइप}}</translation>
-<translation id="8735450637152821465">चयन प्रारंभ करें</translation>
-<translation id="8743786158317878347">संरचित सामग्री, जैसे तालिकाएं डालें</translation>
-<translation id="8747966237988593539">क्रमित सूची</translation>
-<translation id="8759334257841767240">कोई अगला लिंक नहीं.</translation>
-<translation id="8767968232364267681">अगले स्‍तर 4 का शीर्षक</translation>
-<translation id="8770473310765924354">संरचित सामग्री, जैसे तालिकाओं से बाहर निकलें</translation>
-<translation id="8791025954632646584">शब्दार्थ विज्ञान चालू</translation>
-<translation id="8796411681063377102">अगले स्तर 3 का शीर्षक</translation>
-<translation id="8808582214901541005">मार्च</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">मुख्य</translation>
-<translation id="8856538297388979332">आदेशों की समीक्षा करने के लिए ऊपर या नीचे कुंजी दबाएं, सक्रिय करने के लिए enter दबाएं</translation>
-<translation id="8864099967139188018">कोई अगला स्‍तर 6 शीर्षक नहीं.</translation>
-<translation id="8882002077197914455">पंक्ति शीर्षलेख</translation>
-<translation id="8896347895970027998">ChromeVox सक्रिय या निष्क्रिय को टॉगल करें.</translation>
-<translation id="8898516272131543774">विराम चिह्न इको को चक्रित करें</translation>
-<translation id="8900148057318340779">आगे वाली कुंजी</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">खाली शीर्षलेख</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">संशोधक कुंजियां</translation>
-<translation id="8943175951035496220">कोई दायां सेल नहीं.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">फ़ाइल</translation>
-<translation id="9027462562263121875">कोई तालिका नहीं.</translation>
-<translation id="9040132695316389094">शीर्षक 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">खोज विजेट टॉगल करें</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">चयन से निकाले गए</translation>
-<translation id="9082874451376019682">कोई पिछला स्लाइडर नहीं.</translation>
-<translation id="9089864840575085222">टाइपिंग इको को चक्रित करें</translation>
-<translation id="9107530006868467849">कोई पिछला मीडिया विजेट नहीं.</translation>
-<translation id="9108370397979208512">गणित</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{प्रतिशत}one{# प्रतिशत चिह्न}other{# प्रतिशत चिह्न}}</translation>
-<translation id="9115913704608474258">नवंबर</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">वर्तमान स्थिति का संक्षिप्त विवरण प्रदर्शित करता है</translation>
-<translation id="9153606228985488238">पिच <ph name="PERCENT" /> प्रतिशत</translation>
-<translation id="9160096769946561184">वर्तमान स्‍तंभ के अंत में जाएं</translation>
-<translation id="9173115498289768110">वॉल्यूम <ph name="PERCENT" /> प्रतिशत</translation>
-<translation id="9178973770513562274">ब्राउज़ करने के लिए ऊपर या नीचे तीर कुंजियों का उपयोग करें, या खोजने के लिए लिखें.</translation>
-<translation id="9192904702577636854">मार्की</translation>
-<translation id="9212322457209634662">कोई अगला अनुभाग नहीं.</translation>
-<translation id="930275611743429116">चयन प्रारंभ या समाप्त करें.</translation>
-<translation id="948171205378458592">बोली की दर घटाएं</translation>
-<translation id="962913030769097253">अगले स्तर 1 का शीर्षक</translation>
-<translation id="973955474346881951">रोचक मोड सक्षम/अक्षम करें</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hr.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hr.xtb
deleted file mode 100644
index 9661f41ffcc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hr.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="hr">
-<translation id="1012173283529841972">Stavka popisa</translation>
-<translation id="1013742170491673792">prtrž</translation>
-<translation id="1023866615269196768">Rastegnuto.</translation>
-<translation id="1025074108959230262">Ljepljiv način onemogućen</translation>
-<translation id="1031961866430398710">pa</translation>
-<translation id="1044777062731150180">Nema zaglavlja</translation>
-<translation id="106222400312645156">zglvljrtk</translation>
-<translation id="1065552602950927991">Unos nije važeći</translation>
-<translation id="1082209053475788238">Nema prethodnog naslova razine 6.</translation>
-<translation id="1088219014394087294">Nema naslova.</translation>
-<translation id="1106741348836243114">Uključuje ili isključuje zvučne povratne informacije (zvučne ikone).</translation>
-<translation id="1120743664840974483">{"a": "Alan", "b": "Biokovo", "c": "Cavtat", "č": "Čakovec", "ć": "Ćilipi", "d": "Dubrovnik", "dž": "Džamija", "đ": "Đakovo", "e": "Europa", "f": "Fažana", "g": "Gospić", "h": "Hrvatska", "i": "Istra", "j": "Jadran", "k": "Karlovac", "l": "Lika", "lj": "Ljuta", "m": "Makarska", "n": "Novska", "nj": "Njivice", "o": "Osijek", "p": "Pula", "r": "Rijeka", "s": "Sisak", "š": "Šibenik", "t": "Trogir", "u": "Učka", "v": "Vukovar", "z": "Zagreb", "ž": Žabno"}</translation>
-<translation id="113582498867142724"><ph name="TAG" /> zbirka sa sljedećim brojem stavki: <ph name="NUM" /></translation>
-<translation id="1155043339247954670">Nema sljedeće stavke popisa.</translation>
-<translation id="1157782847298808853">Tipkovna pomoć</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, kombinirani okvir</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, stavka izbornika, s podizbornikom</translation>
-<translation id="1177863135347784049">Prilagođeno</translation>
-<translation id="1188858454923323853">dopunski</translation>
-<translation id="1206619573307042055">pomični tekst</translation>
-<translation id="1213216066620407844">ChromeVox – daje Chromeu glas</translation>
-<translation id="1229276918471378188">Prethodni skok</translation>
-<translation id="1237866625126425153">gmbgr</translation>
-<translation id="1251750620252348585">Sljedeći naslov razine 6</translation>
-<translation id="1275718070701477396">Odabrano</translation>
-<translation id="1319608975892113573">Nema prethodnog navoda bloka.</translation>
-<translation id="1321576897702511272">Sakrij pomoć za ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> od <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">odjek znakova i riječi</translation>
-<translation id="1339428534620983148">Prethodni stupac tablice</translation>
-<translation id="1342835525016946179">članak</translation>
-<translation id="1346748346194534595">Udesno</translation>
-<translation id="136718599399906424">Sljedeći redak tablice</translation>
-<translation id="1383876407941801731">Traži</translation>
-<translation id="1385214448885562192">Pritisnite tipku "enter" za prihvaćanje ili tipku "escape" za otkazivanje, strelicu prema dolje za sljedeće i strelicu prema gore za prethodno.</translation>
-<translation id="1396114365388024581">popkart</translation>
-<translation id="1439316808600711881">podrč</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, tekstualni okvir zaporke</translation>
-<translation id="1467432559032391204">Ulijevo</translation>
-<translation id="1474557363159888097">Nema prethodnog sidra.</translation>
-<translation id="1502086903961450562">Prethodna slika</translation>
-<translation id="1506187449813838456">Povećanje visine tona</translation>
-<translation id="151784044608172266">Sljedeća rečenica</translation>
-<translation id="1524531499102321782">Sljedeći redak brajice</translation>
-<translation id="1546370775711804143">Kliznik</translation>
-<translation id="1559739829547075274">Kretanje unatrag</translation>
-<translation id="1571643229714746283">ChromeVox je spreman</translation>
-<translation id="158493514907962286">prosinac</translation>
-<translation id="1594072653727561613">izb</translation>
-<translation id="1610130962244179598">Prijeđi na 6-točkastu brajicu</translation>
-<translation id="1611168825862729585">Zaglavlje stupca:</translation>
-<translation id="1613476421962910979">Zvučne su ikone uključene</translation>
-<translation id="1618597272655350600">Najavljuje potpun opis trenutačnog položaja</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{znak "veće od"}one{# znak "veće od"}few{# znaka "veće od"}other{# znakova "veće od"}}</translation>
-<translation id="1653266918374749391">Prethodni naslov razine 3</translation>
-<translation id="1659072772017912254">Nije označen</translation>
-<translation id="1669290819662866522">tjedan</translation>
-<translation id="1674262202423278359">Navigacija ChromeVoxa</translation>
-<translation id="16777221443363124">Traka izbornika</translation>
-<translation id="1692077714702418899">strukturna crta</translation>
-<translation id="1700517974991662022">Posjećeno</translation>
-<translation id="1722567105086139392">Veza</translation>
-<translation id="1727806147743597030">podnžj</translation>
-<translation id="174268867904053074">Sljedeća slika</translation>
-<translation id="1781173782405573156">Tipka za izravni pristup</translation>
-<translation id="1787176709638001873">Tekst uređivanja zaporke</translation>
-<translation id="1810107444790159527">Okvir s popisom</translation>
-<translation id="1828385960365606039">svibanj</translation>
-<translation id="1834891354138622109">Stupac</translation>
-<translation id="1865601187525349519">Završetak teksta</translation>
-<translation id="1876229593313240038">dokm</translation>
-<translation id="188130072164734898">Izgovara trenutačno vrijeme i datum.</translation>
-<translation id="1902396333223336119">Ćelija</translation>
-<translation id="1905379170753160525">Prikaz popisa naslova</translation>
-<translation id="1912556590115083156">psjćvz</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Upravljanje tjednom u godini</translation>
-<translation id="1964135212174907577">Sljedeći objekt</translation>
-<translation id="1969092762068865084">srpanj</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Zaglavlje retka:</translation>
-<translation id="2002895034995108595">Poništi trenutačnu kartu tipkovnice</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{lijeva zagrada}one{# lijeva zagrada}few{# lijeve zgrade}other{# lijevih zagrada}}</translation>
-<translation id="2045490512405922022">nije označeno</translation>
-<translation id="20601713649439366">Nema prethodnog matematičkog izraza.</translation>
-<translation id="207477615537953741">Semantička je interpretacija isključena</translation>
-<translation id="2086961585857038472">Sljedeća riječ</translation>
-<translation id="2089387485033699258">hr</translation>
-<translation id="2091933974477985526">Prethodno područje s mogućnošću uređivanja</translation>
-<translation id="2100350898815792233">Sva interpunkcija</translation>
-<translation id="2119965627982867824">okgmb</translation>
-<translation id="2121067395472282800">pristupna tipka: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Kako biste promijenili trenutačnu tablicu 6-točkaste brajice, odaberite opciju s popisa u nastavku.</translation>
-<translation id="2169714232367507776">Klik na trenutačnu stavku</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{zatvoreni navodnik}one{# zatvoreni navodnik}few{# zatvorena navodnika}other{# zatvorenih navodnika}}</translation>
-<translation id="2199994615414171367">Prethodni matematički izraz</translation>
-<translation id="2223693656926968778">Radnja na trenutačnoj stavci</translation>
-<translation id="225732394367814946">Povećanje brzine govora</translation>
-<translation id="2267945578749931355">Sljedeći znak</translation>
-<translation id="2281234842553884450">Prethodni klizač</translation>
-<translation id="2318372665160196757">Glavno</translation>
-<translation id="2329324941084714723">Ploča kartice</translation>
-<translation id="2344193891939537199">Upravljanje datumom i vremenom</translation>
-<translation id="2359897517538099099">Niste u tabličnom načinu.</translation>
-<translation id="241124561063364910">a zatim</translation>
-<translation id="2417569100218200841">Informacije o sadržaju</translation>
-<translation id="2422937916923936891">Potvrdni okvir stavke izbornika</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">Tipka <ph name="KEY" /> postala je novi modifikator ChromeVoxa.</translation>
-<translation id="2450814015951372393">Potvrdni okvir</translation>
-<translation id="2462626033734746142">Grupa izbornog gumba</translation>
-<translation id="2471138580042810658">Naslov 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{zvjezdica}one{# zvjezdica}few{# zvjezdice}other{# zvjezdica}}</translation>
-<translation id="2549392850788122959">Tipka <ph name="KEY" /> poništena je.</translation>
-<translation id="2553108862507765288">gramatička pogreška</translation>
-<translation id="257674075312929031">Grupa</translation>
-<translation id="2582407057977008361">Pored</translation>
-<translation id="2589102159832527089">Ova stranica sadrži tekst automatski izlučen iz PDF datoteke &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Kliknite ovdje za prikaz originala.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">s {COUNT,plural, =1{# stavkom}one{# stavkom}few{# stavke}other{# stavki}}</translation>
-<translation id="2614981083756825552">Math ML raspored</translation>
-<translation id="2626530649491650971">može se kliknuti</translation>
-<translation id="2628764385451019380">Nema prethodnog kombiniranog okvira.</translation>
-<translation id="2637227747952042642">Matematički</translation>
-<translation id="2639750663247012216">Modifikator ChromeVoxa</translation>
-<translation id="2644542693584024604">pravopisna pogreška</translation>
-<translation id="2667291555398229137">Kliknite stavku ispod tipke za usmjeravanje</translation>
-<translation id="2697408785920771974">autougr</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{otvoreni navodnik}one{# otvoreni navodnik}few{# otvorena navodnika}other{# otvorenih navodnika}}</translation>
-<translation id="2705875883745373140">Nije pritisnut</translation>
-<translation id="2706462751667573066">Gore</translation>
-<translation id="2717271541250958000">plkart</translation>
-<translation id="2723001399770238859">zvuk</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Označen</translation>
-<translation id="27527859628328957">Skok na sljedeću stavku s mogućnošću fokusiranja</translation>
-<translation id="2770781857296573485">Unesite grupno istraživanje</translation>
-<translation id="2777845298774924149">Izašli ste</translation>
-<translation id="2800204403141299078">Nema više različitih elemenata.</translation>
-<translation id="2800780099804980316">Nema prethodnog naslova razine 1.</translation>
-<translation id="2811204574343810641">Redak</translation>
-<translation id="2816654101880605877">Nema sljedećeg klizača.</translation>
-<translation id="2841013758207633010">Vrijeme</translation>
-<translation id="2843837985843789981">Prethodna grupa</translation>
-<translation id="2844995807198708617">Kontekstni izbornik</translation>
-<translation id="2849332794118375855">Nema sljedećeg potvrdnog okvira.</translation>
-<translation id="2864481629947106776">Prethodna veza</translation>
-<translation id="2873259058405069099">Prelazak na početak tablice</translation>
-<translation id="2894654529758326923">Informacije</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{lijeva vitičasta zagrada}one{# lijeva vitičasta zagrada}few{# lijeve vitičaste zagrade}other{# lijevih vitičasta zagrada}}</translation>
-<translation id="2911433807131383493">Otvaranje vodiča za ChromeVox</translation>
-<translation id="2932083475399492303">Izmjenjivanje strukturne crte i crte rasporeda</translation>
-<translation id="2964026537669811554">Skupina naslova</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulator}one{# tabulator}few{# tabulatora}other{# tabulatora}}</translation>
-<translation id="2972078295414139404">Nema prethodne posjećene veze.</translation>
-<translation id="2972205263822847197">Opis</translation>
-<translation id="2998131015536248178">Prethodni znak</translation>
-<translation id="2999559350546931576">Snižavanje visine tona</translation>
-<translation id="2999945368667127852">Nema sljedećeg widgeta medija.</translation>
-<translation id="3012414509011670858">Nema prethodnog odjeljka.</translation>
-<translation id="3030432017085518523">Izborni gumb stavke izbornika</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{izostavnik}one{# izostavnik}few{# izostavnika}other{# izostavnika}}</translation>
-<translation id="3046838483509668188">Opcije ChromeVoxa</translation>
-<translation id="3047143736589213134">Eksperimentalna karta tipkovnice</translation>
-<translation id="3060756054951570867">otvoren je izbornik <ph name="TITLE" /></translation>
-<translation id="3078345202707391975">Sljedeći naslov razine 2</translation>
-<translation id="3078740164268491126">tablica</translation>
-<translation id="3082557070674409251">Kliknuto</translation>
-<translation id="3084806535845658316">nema odjeka tipkanja</translation>
-<translation id="3086746722712840547">napom</translation>
-<translation id="308895241372589742">Nema sljedećeg matematičkog izraza.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Sljedeći orijentir</translation>
-<translation id="3096671415663099226">kmbokv</translation>
-<translation id="3104705064753753826">dij upoz</translation>
-<translation id="3109724472072898302">Sažeto</translation>
-<translation id="3134461040845705080">samozačitanje</translation>
-<translation id="3138767756593758860">Prikaži popis orijentira</translation>
-<translation id="3143851963874289911">ćl</translation>
-<translation id="3149472044574196936">Sljedeći redak</translation>
-<translation id="3155083529632865074">Nema prethodnog gumba.</translation>
-<translation id="3163593631834463955">Prazno zaglavlje stupca</translation>
-<translation id="316542773973815724">Navigacija</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{razmak}one{# razmak}few{# razmaka}other{# razmaka}}</translation>
-<translation id="320961988183078793">unesen je sadržaj: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, kartica</translation>
-<translation id="3226035351387556942">ptvrd</translation>
-<translation id="3229375994964697375">Posjećena veza</translation>
-<translation id="323731244387692321">Otvori tipkovničku pomoć za ChromeVox</translation>
-<translation id="3241052487511142956">Prethodna posjećena veza</translation>
-<translation id="3286390186030710347">Klizač</translation>
-<translation id="3299925995433437805">Nema sljedeće posjećene veze.</translation>
-<translation id="3303384412438961941">Pritisnite bilo koju tipku da biste joj saznali naziv. Ctrl + W zatvorit će istraživač tipkovnice.</translation>
-<translation id="3307886118343381874">Prelazak na kraj tablice</translation>
-<translation id="3311969765485641742">Pritisnite Alt + Shift + A da biste pregledali upozorenja</translation>
-<translation id="3312997241656799641">Sljedeća posjećena veza</translation>
-<translation id="3321460131042519426">Omogući prelazak riječi u drugi redak</translation>
-<translation id="3322936298410871309">Prethodni naslov razine 1</translation>
-<translation id="3323447499041942178">Tekstni okvir</translation>
-<translation id="3353420241558113817">{"ar": "arapski",
- "bg": "bugarski",
- "ca": "katalonski",
- "cs": "češki",
- "da": "danski",
- "de": "njemački",
- "de_CH": "njemački (Švicarska)",
- "de_DE": "njemački (Njemačka)",
- "el": "grčki",
- "en": "engleski",
- "en_CA": "engleski (Kanada)",
- "en_GB": "engleski (Ujedinjeno Kraljevstvo)",
- "en_US": "engleski (Sjedinjene Američke Države)",
- "es": "španjolski",
- "et": "estonski",
- "fr": "francuski",
- "fr_CA": "francuski (Kanada)",
- "fr_FR": "francuski (Francuska)",
- "fi": "finski",
- "he": "hebrejski",
- "hi": "hindski",
- "hr": "hrvatski",
- "hu": "mađarski",
- "is": "islandski",
- "it": "talijanski",
- "ko": "korejski",
- "lt": "litavski",
- "lv": "latvijski",
- "nb": "norveški bokmål",
- "nl": "nizozemski",
- "pl": "poljski",
- "pt": "portugalski",
- "ro": "rumunjski",
- "ru": "ruski",
- "sk": "slovački",
- "sl": "slovenski",
- "sr": "srpski",
- "sv": "švedski",
- "tr": "turski",
- "vi": "vijetnamski",
- "zh": "kineski",
- "zh_TW": "kineski (tradicionalni hanski)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plus}one{# plus}few{# plusa}other{# plusova}}</translation>
-<translation id="338583716107319301">Separator</translation>
-<translation id="3389259863310851658">Prethodno polje obrasca</translation>
-<translation id="3390225400784126843">Sljedeći različiti element.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, stavka izbornika</translation>
-<translation id="3406283310380167331">Prikaz popisa obrazaca</translation>
-<translation id="3422338090358345848">Otvori istraživač tipkovnice</translation>
-<translation id="3457000393508828486">Djelomično pritisnut</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, gumb</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404">Od <ph name="V1" /> do <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{desna zagrada}one{# desna zagrada}few{# desne zagrade}other{# desnih zagrada}}</translation>
-<translation id="3493915602752813531">Nema sljedećeg sidra.</translation>
-<translation id="3494946239022273294">stizb</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{upitnik}one{# upitnik}few{# upitnika}other{# upitnika}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{znak za umetanje}one{# znak za umetanje}few{# znaka za umetanje}other{# znakova za umetanje}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, potvrdni okvir nije označen</translation>
-<translation id="3599054940393788245">Nije u matematičkoj oznaci</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{zatvoreni jednostruki navodnik}one{# zatvoreni jednostruki navodnik}few{# zatvorena jednostruka navodnika}other{# zatvorenih jednostrukih navodnika}}</translation>
-<translation id="3650317109285159359">ptvrdstizb</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{znak dolara}one{# znak dolara}few{# znaka dolara}other{# znakova dolara}}</translation>
-<translation id="3659787053479271466">upoz</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, okvir s popisom</translation>
-<translation id="3687295507293856493">Pokušaj utvrđivanja zaglavlja stupca trenutačne ćelije</translation>
-<translation id="3692274950075847560">P:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Kontroliranje govora</translation>
-<translation id="3716845769494773620">Više redaka</translation>
-<translation id="3731746171184829332">Nema prethodnog naslova.</translation>
-<translation id="3762198587642264450">Prelazak na kraj trenutačnog retka</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Napustili ste dijaloški okvir.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}few{#}other{#}}</translation>
-<translation id="3801735343383419236">Popis automatskog dovršavanja</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Sljedeći medij</translation>
-<translation id="3819376190738087562">Nema skokova.</translation>
-<translation id="385383972552776628">Otvaranje stranice s opcijama</translation>
-<translation id="3856075812838139784">Samo za čitanje</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Izbornik</translation>
-<translation id="3909320334364316587">Prethodni naslov razine 6</translation>
-<translation id="3914173277599553213">Obavezno</translation>
-<translation id="3962990492275676168">Počni čitati od trenutačne lokacije</translation>
-<translation id="4004802134384979325">označen</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Upravljanje mjesecima</translation>
-<translation id="4039983576244166038">Prazan redak zaglavlja</translation>
-<translation id="4042843249978639960">Nema sljedećeg naslova razine 2.</translation>
-<translation id="4043348641337972076">Nema prethodnog ARIA orijentira.</translation>
-<translation id="4047216625641135770">Oznaka</translation>
-<translation id="404803211695627272"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="4054936709456751127">stat</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDA}one{# tilda}few{# tilde}other{# tildi}}</translation>
-<translation id="409334809956508737">Prethodni objekt</translation>
-<translation id="4099274309791143834">s podizbornikom</translation>
-<translation id="4107807507418787238">U nastavku nema ćelije.</translation>
-<translation id="4116415223832267137">Upozorenje</translation>
-<translation id="4147126331795725888">Nema sljedeće kontrole.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{desna vitičasta zagrada}one{# desna vitičasta zagrada}few{# desne vitičaste zagrade}other{# desnih vitičastih zagrada}}</translation>
-<translation id="4158704014418536539">Osjetljivost na velika/mala slova.</translation>
-<translation id="4161663686871496107">Spremne su govorne povratne informacije ChromeVox</translation>
-<translation id="4173994908659439270">Nema sljedećeg tekstualnog polja koje je moguće urediti.</translation>
-<translation id="4176463684765177261">Onemogućeno</translation>
-<translation id="4188530942454211480">Prethodna rečenica</translation>
-<translation id="4202186506458631436">Pomakni desno</translation>
-<translation id="4206289001967551965">Unutar tablice</translation>
-<translation id="4215733775853809057">Sljedeći klizač</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{crtica}one{# crtica}few{# crtice}other{# crtica}}</translation>
-<translation id="421884353938374759">odabir boja</translation>
-<translation id="4229646983878045487">datum vrijeme</translation>
-<translation id="423334822609210999">S lijeve strane nema ćelije.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, stupanj <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Napomena</translation>
-<translation id="4254798249533888099">Stablo</translation>
-<translation id="4255943572433203166">Za prilagodbu ChromeVoxa upotrijebite opcije u nastavku. Promjene odmah stupaju na snagu.</translation>
-<translation id="4271220233568730077">Sljedeći matematički izraz</translation>
-<translation id="4271521365602459209">Nema više rezultata.</translation>
-<translation id="4287520460805643128">Nema sljedećeg članka.</translation>
-<translation id="4289540628985791613">Pregled</translation>
-<translation id="4300318234632215983">Izgovaranje URL-a veze</translation>
-<translation id="4301352596632316575">ima podizbornik</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{točka}=3{trotočka}one{# točka}few{# točke}other{# točaka}}</translation>
-<translation id="4347461890115250064">Nema sljedećeg popisa.</translation>
-<translation id="4367650418938037324">Math ML list</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Zaustavljanje govora</translation>
-<translation id="4373197658375206385">Nema prethodne stavke koja nije veza.</translation>
-<translation id="4391478986194775161">sdržjinfo</translation>
-<translation id="443163561286008705">poništi</translation>
-<translation id="4471074325120394300">Nema veza.</translation>
-<translation id="4476183483923481720">novi redak</translation>
-<translation id="4482330759234983253">Prethodna tablica</translation>
-<translation id="4491109536499578614">Slika</translation>
-<translation id="4529987814483543472">Klasična karta tipkovnice</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{kosa crta}one{# kosa crta}few{# kose crte}other{# kosih crta}}</translation>
-<translation id="4547556996012970016">Sljedeći naslov razine 5</translation>
-<translation id="4562381607973973258">Zaglavlje</translation>
-<translation id="4591507479202817876">, odabran</translation>
-<translation id="4597532268155981612">obrazac</translation>
-<translation id="4597896406374528575">travanj</translation>
-<translation id="4615592953348396470">Zanemarivanje pritiska na sljedeću tipku</translation>
-<translation id="461613135510474570">Rečenica</translation>
-<translation id="4647836961514597010">Odabir boja</translation>
-<translation id="4661075872484491155">stablo</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">rštk</translation>
-<translation id="4693675773662933727">Prethodni orijentir</translation>
-<translation id="4696413482802371445">Nema sljedećeg naslova razine 5.</translation>
-<translation id="4729095194763193578">Prethodni redak tablice</translation>
-<translation id="4736221692378411923">kolovoz</translation>
-<translation id="4740661827607246557">Naredbe pomoći</translation>
-<translation id="4759716709594980008">Istraživač tipkovnice uređaja ChromeOS-a</translation>
-<translation id="4763296182459741068">Prelomljeno na dno</translation>
-<translation id="4763480195061959176">videozapis</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Izgovaranje naslova trenutačne stranice</translation>
-<translation id="4826415162591436065">Kretanje naprijed</translation>
-<translation id="4826604887384865800">Sljedeći skok</translation>
-<translation id="4827410568042294688">neodabran</translation>
-<translation id="4842108708071771135">Nema sljedećeg navoda bloka.</translation>
-<translation id="4848993367330139335">mjerač</translation>
-<translation id="4850023505158945298">Prethodni sličan element.</translation>
-<translation id="4866956062845190338">rdstizb</translation>
-<translation id="4867316986324544967">Omogući TTS prijave</translation>
-<translation id="4877261390094455813">Unesite upit za pretraživanje.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Interna veza</translation>
-<translation id="4953585991029886728">Uređivanje teksta</translation>
-<translation id="4954534434583049121">Prethodni blok citata</translation>
-<translation id="4973717656530883744">Minimalno <ph name="X" /></translation>
-<translation id="4973762002207131920">Prijelaz na tipku <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisekunde</translation>
-<translation id="49787999531187221">ChromeVox je postao neaktivan.</translation>
-<translation id="4979404613699303341">Prethodni gumb</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, okvir s popisom</translation>
-<translation id="4983588134362688868">Skok na vrh stranice</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, prozor</translation>
-<translation id="4993152509206108683">Stopa <ph name="PERCENT" /> posto</translation>
-<translation id="4996716799442435517">Vizualno</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, izborni gumb odabran</translation>
-<translation id="4997475792277222884">Nema sljedeće stavke koja nije veza.</translation>
-<translation id="5000760171916499057">Nema obrazaca.</translation>
-<translation id="5005670136041063723">Nema više sličnih elemenata.</translation>
-<translation id="501473567976723023">siječanj</translation>
-<translation id="5041394372352067729">Premještanje brajičnog prikaza na vrh stranice</translation>
-<translation id="5042770794184672516">Pojačanje glasnoće govora</translation>
-<translation id="5050015258024679800">Prethodni naslov razine 4</translation>
-<translation id="5054047268577924192">Prethodna stavka popisa</translation>
-<translation id="5078661581131202757">Odabir datoteke</translation>
-<translation id="5080758118274074384">dvaput kliknuto</translation>
-<translation id="5098541983634824365">Napuštanje rešetke.</translation>
-<translation id="5102981729317424850">Alatna traka</translation>
-<translation id="5105050547967751155">obvz</translation>
-<translation id="5110983769041734144">Nema prethodnog polja obrasca.</translation>
-<translation id="5111640677200759579">Zaglavlje stupca</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Nema prethodne veze.</translation>
-<translation id="513774504516943387">veza</translation>
-<translation id="517143700877085897">, neodabrano</translation>
-<translation id="5183440668879371625">Prethodni redak brajice</translation>
-<translation id="5184944171021383281">Nema sljedećeg polja obrasca.</translation>
-<translation id="5189244881767082992">Redak</translation>
-<translation id="5203930734796605961">Tipka <ph name="KEY" /> već je dodijeljena naredbi.</translation>
-<translation id="5205493599117157272">Popis <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Nema sljedećeg izbornog gumba.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objekt</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, kartica</translation>
-<translation id="5310788376443009632">uklonjeno:</translation>
-<translation id="5320727453979144100">Ljepljiv način omogućen</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{zarez}one{# zarez}few{# zareza}other{# zareza}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, tekstualni okvir</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, veza</translation>
-<translation id="5336381510091010269">autougr+pop</translation>
-<translation id="536031132345979795">Preskoči natrag tijekom kontinuiranog čitanja</translation>
-<translation id="5368000168321181111">Zvučne su ikone isključene</translation>
-<translation id="5374320867641260420">Nema sljedećeg gumba.</translation>
-<translation id="5382299583965267720">Nema sljedećeg naslova razine 1.</translation>
-<translation id="5402367795255837559">Brajica</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{točka sa zarezom}one{# točka sa zarezom}few{# točke sa zarezom}other{# točaka sa zarezom}}</translation>
-<translation id="5411891038905756502">Nema prethodne točke skoka.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{znak "manje od"}one{# znak "manje od"}few{# znaka "manje od"}other{# znakova "manje od"}}</translation>
-<translation id="5455441614648621694">Dopunski</translation>
-<translation id="5485036206801896268">Nema prethodne slike.</translation>
-<translation id="5486947920110100234">Nema sljedeće točke skoka.</translation>
-<translation id="549602578321198708">Riječ</translation>
-<translation id="5500932716852106146">Nema prethodnog tekstualnog polja koje je moguće urediti.</translation>
-<translation id="5502713021410870035">rujan</translation>
-<translation id="5507663321906818013">Usporedna analiza za uklanjanje pogrešaka</translation>
-<translation id="5518443085409638729">Postavi pokazivač između znakova prilikom uređivanja teksta (kao u sustavu Mac OS X).</translation>
-<translation id="552195134157544755">Izborni gumb</translation>
-<translation id="5534303576632885660">zglvlj</translation>
-<translation id="5546092960038624944">Nema prethodnog naslova razine 5.</translation>
-<translation id="556042886152191864">Gumb</translation>
-<translation id="5561345396546889625">Sljedeći popis</translation>
-<translation id="5562645715554321347">zglvljgrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Uređivanje teksta, unos e-pošte</translation>
-<translation id="5597170376237141345">Sljedeći potvrdni okvir</translation>
-<translation id="5597933780944041114">Nema sljedećeg naslova.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, izborni gumb nije odabran</translation>
-<translation id="5601172225407283979">Izvršavanje zadane radnje</translation>
-<translation id="5608798115546226984">Automatsko dovršavanje retka</translation>
-<translation id="561939826962581046">vrijeme</translation>
-<translation id="5623778242535476823">rgmb</translation>
-<translation id="5623842676595125836">Zapisnik</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Nema prethodne tablice.</translation>
-<translation id="5655682562155942719">Naredbe za skok</translation>
-<translation id="56637627897541303">Područje teksta</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Orijentir</translation>
-<translation id="5683155931978483559">Prethodni potvrdni okvir</translation>
-<translation id="5684277895745049190">Popis</translation>
-<translation id="5700650669149824506">Nema prethodnog naslova razine 4.</translation>
-<translation id="5709192780268610569">Nema dugačkih opisa</translation>
-<translation id="5712244464475377681">skčgmb</translation>
-<translation id="5712338278108304766">Sljedeći stupac tablice</translation>
-<translation id="571866080859340309">Istraživanje grupa</translation>
-<translation id="5728409797179002635">Nije pronađena nijedna tablica.</translation>
-<translation id="5748623122140342504">Prethodni naslov razine 5</translation>
-<translation id="5750633686117194034">Nije pritisnut nijedan modifikator. Pritisnite i zadržite jedan ili više modifikatora, pustite ih kada završite i čut ćete postavljene tipke. Pritisnite tabulator za izlazak.</translation>
-<translation id="5788275253279308023">kartica anonimnog prozora <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Poboljšajte određene web-lokacije (primjerice, Google pretraživanje).</translation>
-<translation id="5819072574982403430">Stavka stabla</translation>
-<translation id="5826479389509458994"><ph name="ROW" />. redak <ph name="COL" />. stupac</translation>
-<translation id="5850707923114094062">Pomiči prema natrag</translation>
-<translation id="5851548754964597211">Popis kartica</translation>
-<translation id="5859752971144398932">Izašli ste iz traženja na stranici.</translation>
-<translation id="5866042630553435010">Djelomično označeno</translation>
-<translation id="5869546221129391014">Rešetka</translation>
-<translation id="5876817486144482042">Stišavanje glasnoće govora</translation>
-<translation id="5887397643266327462">Omogućeni su opisi na brajici.</translation>
-<translation id="5891934789323004067">Tablica</translation>
-<translation id="5919442531159595654">kopiranje.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{znak jednakosti}one{# znak jednakosti}few{# znaka jednakosti}other{# znakova jednakosti}}</translation>
-<translation id="5939518447894949180">Ponovno postavi</translation>
-<translation id="5948123859135882163">Uključuje/isključuje strukturnu ili semantičku interpretaciju matematičkih izraza</translation>
-<translation id="5955304353782037793">apl</translation>
-<translation id="5956928062748260866">Dijaloški okvir</translation>
-<translation id="5963413905009737549">Odjeljak</translation>
-<translation id="5968607524793740041">Prikaz kontekstnog izbornika</translation>
-<translation id="5983179082906765664">Povećanje razine pojedinosti navigacije</translation>
-<translation id="5999630716831179808">Glasovi</translation>
-<translation id="6000417740266304866">Kako biste promijenili trenutačnu tablicu 8-točkaste brajice, odaberite opciju s popisu u nastavku.</translation>
-<translation id="6006050241733874051">Obrazac</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{kosa crta ulijevo}one{# kosa crta ulijevo}few{# kose crte ulijevo}other{# kosih crta ulijevo}}</translation>
-<translation id="6037602951055904232">Pomiči se prema naprijed</translation>
-<translation id="611827076493383239">psjćn</translation>
-<translation id="6119955456199054975">Kraj ćelije.</translation>
-<translation id="6122013438240733403">gmb</translation>
-<translation id="6129953537138746214">Razmak</translation>
-<translation id="6142308968191113180">Naslov 4</translation>
-<translation id="6169420925157477918">Slika s dugačkim opisom</translation>
-<translation id="6172087735260766220">Ne može se pristupiti dostupnom tekstu PDF-a zaštićenog od kopiranja.</translation>
-<translation id="6186305613600865047">Skok na dno stranice</translation>
-<translation id="6193330012414963395">prijepodne popodne</translation>
-<translation id="622484624075952240">Dolje</translation>
-<translation id="6236061028292614533">Sljedeći naslov</translation>
-<translation id="6254901459154107917">Sljedeće tekstualno područje s mogućnošću uređivanja</translation>
-<translation id="6259464875943891919">Napustili ste <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Sljedeći sličan element.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Nema sljedećeg kombiniranog okvira.</translation>
-<translation id="6307969636681130414">Pritisnut</translation>
-<translation id="6324551002951139333">Otkrivena je gramatička pogreška</translation>
-<translation id="6348657800373377022">Kombinirani okvir</translation>
-<translation id="6355910664415701303">Nema prethodne stavke popisa.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Prethodni naslov</translation>
-<translation id="6387719785439924554">pored</translation>
-<translation id="6411426777058107714">Nema prethodnog izbornog gumba.</translation>
-<translation id="6414968628640960377">Prethodni drugačiji element.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dvotočka}one{# dvotočka}few{# dvotočke}other{# dvotočaka}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, izbornik</translation>
-<translation id="6444046323172968959">Dijaloški okvir upozorenja</translation>
-<translation id="6459511626086141404">Plošna karta tipkovnice</translation>
-<translation id="6468049171101508116">Sljedeći gumb</translation>
-<translation id="6491972999578897419">Promijenite trenutačni glas odabirom opcije na popisu u nastavku.</translation>
-<translation id="6508059270146105198">Premještanje brajičnog prikaza na dno stranice</translation>
-<translation id="6536864053412760904">Math ML oznaka</translation>
-<translation id="6550720799683018100">Promijenite trenutačnu kartu tipkovnice odabirom opcije na donjem popisu.</translation>
-<translation id="6561818612645211875">Prelazak na početak trenutačnog retka</translation>
-<translation id="6587021927234520429">Nema sljedećeg naslova razine 4.</translation>
-<translation id="6601344353291556895">Omogući opširne opise.</translation>
-<translation id="6615602925644411249">Traženje na stranici.</translation>
-<translation id="6633350132811819843">Nema sljedeće tablice.</translation>
-<translation id="6637586476836377253">zap</translation>
-<translation id="6657128831881431364">Traka napretka</translation>
-<translation id="6659594942844771486">Kartica</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Prethodni kombinirani okvir</translation>
-<translation id="6714813999819678458">Prethodni naslov razine 2</translation>
-<translation id="6716505898850596801">Modifikatorske tipke</translation>
-<translation id="671916444866103745">Nema sljedećeg ARIA orijentira.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, kombinirani okvir</translation>
-<translation id="6735257939857578167">s ukupnim brojem stavki: <ph name="NUM" /></translation>
-<translation id="6736510033526053669">stvorena je kartica</translation>
-<translation id="675895815784134693">trknprtk</translation>
-<translation id="6786800275320335305">Članak</translation>
-<translation id="6787839852456839824">Tipkovnički prečaci</translation>
-<translation id="6793101435925451627">okv pops</translation>
-<translation id="6833103209700200188">Podnožje</translation>
-<translation id="6871161210040114857">Zanemarivanje velikih i malih slova.</translation>
-<translation id="6877435256196695200">Nema sljedeće slike.</translation>
-<translation id="6897341342232909480">Pomakni lijevo</translation>
-<translation id="6901540140423170855">datum</translation>
-<translation id="6910211073230771657">Izbrisano</translation>
-<translation id="6911965441508464308">Iznad nema ćelije.</translation>
-<translation id="6919104639734799681">Prikaz popisa tablica</translation>
-<translation id="6964088412282673743">Nema prethodne kontrole.</translation>
-<translation id="6996566555547746822">Sljedeći kombinirani okvir</translation>
-<translation id="7005146664810010831">Nije pronađen nijedan URL</translation>
-<translation id="7010712454773919705">Modifikatorska tipka ChromeVox</translation>
-<translation id="7031651751836475482">stvk pops</translation>
-<translation id="7037042857287298941">Prethodni popis</translation>
-<translation id="7041173719775863268">Kraj odabira</translation>
-<translation id="7095834689119144465">Samo numeričko uređivanje teksta</translation>
-<translation id="7096001299300236431">Prethodni medij</translation>
-<translation id="7116595520562830928">višeredk</translation>
-<translation id="712735679809149106">odjek riječi</translation>
-<translation id="713824876195128146">Sljedeći blok citata</translation>
-<translation id="7161771961008409533">Gumb skočnog prozora</translation>
-<translation id="7167657087543110">odjek znakova</translation>
-<translation id="7170733337935166589">Preskakanje unaprijed tijekom kontinuiranog čitanja</translation>
-<translation id="7181697990050180700">Prilagodite tipkovne prečace za često upotrebljavane naredbe tako da ih upišete u odgovarajuća polja u nastavku.</translation>
-<translation id="7203150201908454328">Proširen</translation>
-<translation id="7210211103303402262">minute</translation>
-<translation id="7217912842225915592">+ <ph name="NUM" /></translation>
-<translation id="7221740160534240920">redak</translation>
-<translation id="7226216518520804442">pops</translation>
-<translation id="72393384879519786">Naslov</translation>
-<translation id="7241683698754534149">Otvaranje dugačkih opisa u novoj kartici</translation>
-<translation id="7248671827512403053">Aplikacija</translation>
-<translation id="725969808843520477">Sljedeći izborni gumb</translation>
-<translation id="7269119382257320590">Bez interpunkcije</translation>
-<translation id="7273174640290488576">Prazno</translation>
-<translation id="7285387653379749618">Tablice</translation>
-<translation id="7289186959554153431">Naslov 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">stvkstab</translation>
-<translation id="731576946540457939">Onemogućeni su opisi na brajici.</translation>
-<translation id="7318872822751139669">Upotrijebi miš za promjenu fokusa.</translation>
-<translation id="7322388933135261569">veljača</translation>
-<translation id="7332592614823088566"><ph name="ROWINDEX" />. redak od <ph name="ROWTOTAL" />, <ph name="COLINDEX" />. stupac od <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">ima skočni prozor</translation>
-<translation id="7356165926712028380">Prijeđi na 8-točkastu brajicu</translation>
-<translation id="7362871137496673139">Nema prethodnog naslova razine 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{znak &amp;}one{# znak &amp;}few{# znaka &amp;}other{# znakova &amp;}}</translation>
-<translation id="737396357417333429">klk</translation>
-<translation id="7374104575779636480">Napuštanje tablice.</translation>
-<translation id="739763518212184081">Prethodni redak</translation>
-<translation id="7400575256015741911">Otkrivena pravopisna pogreška</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">natrag</translation>
-<translation id="7434509671034404296">Razvojni programer</translation>
-<translation id="7439060726180460871">Direktorij</translation>
-<translation id="744163271241493234">zprk</translation>
-<translation id="7491962110804786152">kart</translation>
-<translation id="7492049978501397201">Otvorili ste dijaloški okvir</translation>
-<translation id="7532613204005497612">lipanj</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, klizač</translation>
-<translation id="7586163296341959563">lijepljenje.</translation>
-<translation id="7596919493010894443">odabir je izbrisan</translation>
-<translation id="7604026522577407655">Prelazak na početak trenutačnog stupca</translation>
-<translation id="7604451927827590395">zglvlj</translation>
-<translation id="7609342235116740824">Izgovaranje URL-a trenutačne stranice</translation>
-<translation id="7609363189280667021">Uključivanje ili isključivanje brajičnih opisa</translation>
-<translation id="762020119231868829">Pauzira sve widgete medija koji se trenutačno reproduciraju</translation>
-<translation id="7625690649919402823">Sljedeća tablica</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), stupanj <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Nema prethodnog naslova razine 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, tekstualni okvir</translation>
-<translation id="7663318257180412551">Naslov 2</translation>
-<translation id="7674576868851035240">Sljedeća veza</translation>
-<translation id="7674768236845044097">oznaka</translation>
-<translation id="7684431668231950609">Uređivanje teksta, unos URL-a</translation>
-<translation id="7685589220304187312">alttrk</translation>
-<translation id="7693840228159394336">Prethodni izborni gumb</translation>
-<translation id="7701196182766842984">autopop</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, tekstualni okvir zaporke</translation>
-<translation id="7805247615045262757">zadana navigacija</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Sljedeća grupa</translation>
-<translation id="7819187121850078213">kartica prozora <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">listopad</translation>
-<translation id="7839679365527550018">Prethodna riječ</translation>
-<translation id="7851816175263618915">Neki interpunkcijski znakovi</translation>
-<translation id="7870596830398826354">Math ML stablo</translation>
-<translation id="78826985582142166">klz</translation>
-<translation id="7894517696028036636">Omogućivanje/onemogućivanje klasičnog ChromeVoxa.</translation>
-<translation id="7895896691902835279">Nepoznata veza</translation>
-<translation id="7927711904086083099">Nije odabran</translation>
-<translation id="7935627501098484003">Kontrola vremena</translation>
-<translation id="7939428177581522200">dodano u odabir</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{znak @}one{# znak @}few{# znaka @}other{# znakova @}}</translation>
-<translation id="7965147473449754028">izbornik zatvoren</translation>
-<translation id="7974390230414479278">Stavka izbornika</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{uskličnik}one{# uskličnik}few{# uskličnika}other{# uskličnika}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{navodnik}one{# navodnik}few{# navodnika}other{# navodnika}}</translation>
-<translation id="8033827949643255796">odabrano</translation>
-<translation id="8035962149453661158">maks:<ph name="X" /></translation>
-<translation id="8042761080832772327">Uređivanje teksta, unos pretraživanja</translation>
-<translation id="8049189770492311300">Brojač vremena</translation>
-<translation id="8065607967589909823">Odabir je</translation>
-<translation id="8066678206530322333">Natpis</translation>
-<translation id="8110647606445335195">Nema ARIA orijentira.</translation>
-<translation id="8153880621934657047">Niste unutar tablice.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{donja crta}one{# donja crta}few{# donje crte}other{# donjih crta}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">izrezivanje.</translation>
-<translation id="8199231515320852133">Izgovaranje zaglavlja trenutačne ćelije</translation>
-<translation id="820417203470636242">Prazna ćelija.</translation>
-<translation id="8215202828671303819">Višestruki odabir</translation>
-<translation id="8276439074553447000">Skok na prethodnu stavku s mogućnošću fokusiranja</translation>
-<translation id="8278417001922463147">Nema prethodnog članka.</translation>
-<translation id="8283603667300770666">Sljedeće polje obrasca</translation>
-<translation id="831207808878314375">Definicija</translation>
-<translation id="8313653172105209786">dirkt</translation>
-<translation id="8344569602005188545">sati</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{znak funte}one{# znak funte}few{# znaka funte}other{# znakova funte}}</translation>
-<translation id="8374154622594089836">mjesec</translation>
-<translation id="8378855320830505539">Regija</translation>
-<translation id="8382679411218029383">Automatsko dovršavanje retka i popisa</translation>
-<translation id="8428603554127842284">razina <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Nema sljedećeg naslova razine 3.</translation>
-<translation id="8430049249787218991">trizb</translation>
-<translation id="844681116543532394">Nema prethodnog potvrdnog okvira.</translation>
-<translation id="8455868257606149352">Maksimalno <ph name="X" /></translation>
-<translation id="84575901236241018">ima pristupni ključ, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Smanji razinu pojedinosti navigacije</translation>
-<translation id="8520472399088452386">Okretni gumb</translation>
-<translation id="8538744478902126321">Pokušaj utvrđivanja zaglavlja retka trenutačne ćelije</translation>
-<translation id="8540054775867439484">Prelomljeno na vrh</translation>
-<translation id="8548973727659841685">Znak</translation>
-<translation id="8561322612995434619">ima skočni prozor</translation>
-<translation id="8571096049907249734">všstrk odbr</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Sljedeća stavka popisa</translation>
-<translation id="860150890330522909">označen je potvrdni okvir <ph name="NAME" /></translation>
-<translation id="8606621670302093223">Upravljanje datumom</translation>
-<translation id="8631359288236106450">broj odabranih stavki: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Izgovaranje koordinata trenutačnog polja</translation>
-<translation id="8650576015643545550">Nema prethodnog popisa.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Prikaz popisa veza</translation>
-<translation id="8664519043722036194">sekunde</translation>
-<translation id="867187640362843212">Naslov 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{okomita crta}one{# okomita crta}few{# okomite crte}other{# okomitih crta}}</translation>
-<translation id="8735450637152821465">Početak odabira</translation>
-<translation id="8743786158317878347">unos strukturiranog sadržaja, na primjer, tablica</translation>
-<translation id="8747966237988593539">Uređeni popis</translation>
-<translation id="8759334257841767240">Nema sljedeće veze.</translation>
-<translation id="8767968232364267681">Sljedeći naslov razine 4</translation>
-<translation id="8770473310765924354">napuštanje strukturiranog sadržaja, na primjer, tablica</translation>
-<translation id="8791025954632646584">Semantička je interpretacija uključena</translation>
-<translation id="8796411681063377102">Sljedeći naslov razine 3</translation>
-<translation id="8808582214901541005">ožujak</translation>
-<translation id="8825828890761629845">natp</translation>
-<translation id="8851136666856101339">glav</translation>
-<translation id="8856538297388979332">Pritisnite gore ili dolje za pregled naredbi, pritisnite Enter za aktivaciju</translation>
-<translation id="8864099967139188018">Nema sljedećeg naslova razine 6.</translation>
-<translation id="8882002077197914455">Zaglavlje retka</translation>
-<translation id="8896347895970027998">Aktiviranje ili deaktiviranje ChromeVoxa.</translation>
-<translation id="8898516272131543774">Kružna izmjena odjeka interpunkcije</translation>
-<translation id="8900148057318340779">Tipka prefiksa</translation>
-<translation id="8908714597367957477">zglvljstpc</translation>
-<translation id="8931936695772494138">Prazna zaglavlja</translation>
-<translation id="8937112856099038376">intveza</translation>
-<translation id="8940925288729953902">Modifikatorske tipke</translation>
-<translation id="8943175951035496220">S desne strane nema ćelije.</translation>
-<translation id="8978496506222343566">opis</translation>
-<translation id="900114243503212879">dat</translation>
-<translation id="9027462562263121875">Nema tablica.</translation>
-<translation id="9040132695316389094">Naslov 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Prikazivanje/sakrivanje widgeta za pretraživanje</translation>
-<translation id="9065283790526219006">+ skočni prozor</translation>
-<translation id="9077213568694924680">uklonjeno iz odabira</translation>
-<translation id="9082874451376019682">Nema prethodnog klizača.</translation>
-<translation id="9089864840575085222">Kružna izmjena odjeka tipkanja</translation>
-<translation id="9107530006868467849">Nema widgeta za prethodni medij.</translation>
-<translation id="9108370397979208512">mat</translation>
-<translation id="9108589040018540527">klzč</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{znak postotka}one{# znak postotka}few{# znaka postotka}other{# znakova postotka}}</translation>
-<translation id="9115913704608474258">studeni</translation>
-<translation id="9128414153595658330">dij</translation>
-<translation id="9149560530563164529">odjljk</translation>
-<translation id="9151211641321628915">Najavljuje kratak opis trenutačnog položaja</translation>
-<translation id="9153606228985488238">Visina glasa: <ph name="PERCENT" /> posto</translation>
-<translation id="9160096769946561184">Prelazak na kraj trenutačnog stupca</translation>
-<translation id="9173115498289768110">Glasnoća <ph name="PERCENT" /> posto</translation>
-<translation id="9178973770513562274">Za pregledavanje upotrijebite tipke sa strelicama prema gore ili dolje ili tipkajte da biste pretražili.</translation>
-<translation id="9192904702577636854">Pomični tekst</translation>
-<translation id="9212322457209634662">Nema sljedećeg odjeljka.</translation>
-<translation id="930275611743429116">Početak ili kraj odabira.</translation>
-<translation id="948171205378458592">Smanjenje brzine govora</translation>
-<translation id="962913030769097253">Sljedeći naslov razine 1</translation>
-<translation id="973955474346881951">Omogućivanje/onemogućivanje ljepljivog načina</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hu.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hu.xtb
deleted file mode 100644
index 10dba6dc069..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hu.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="hu">
-<translation id="1012173283529841972">Listaelem</translation>
-<translation id="1013742170491673792">keresés</translation>
-<translation id="1023866615269196768">Egyesítve.</translation>
-<translation id="1025074108959230262">Beragadó mód kikapcsolva</translation>
-<translation id="1031961866430398710">majd</translation>
-<translation id="1044777062731150180">Nincsenek fejlécek</translation>
-<translation id="106222400312645156">sorfejléc</translation>
-<translation id="1065552602950927991">Érvénytelen adat</translation>
-<translation id="1082209053475788238">Nincs előző 6-os szintű címsor.</translation>
-<translation id="1088219014394087294">Nincsenek címsorok.</translation>
-<translation id="1106741348836243114">Hangjelzések be- és kikapcsolása.</translation>
-<translation id="1120743664840974483">{"a": "aladár", "á": "ákos" "b": "béla", "c": "cecil", "cs": "csaba", "d": "dénes", "dz": "edzés", "dzs": "dzsungel", "e": "elemér", "é": "éva", "f": "ferenc", "g": "géza", "gy": "györgy", "h": "hugó", "i": "ilona", "í": "írás", "j": "józsef","k": "katalin", "l": "lászló", "ly": "lyuk", "m": "márton", "n": "nándor", "ny": "nyár", "o": "ottó", "ó": "óriás", "ö": "ödön", "ő": "őrség", "p": "péter", "q": "quebec", "r": "róbert", "s": "sándor", "sz": "szilárd", "t": "tibor", "ty": "tyúk", "u": "ubul", "ú": "újság", "ü": "ünnep", "ű": "űrhajó", "v": "viktor", "w": "waterloo","x": "xilofon", "y": "youtube", "z": "zoltán", "zs": "zsuzsanna",}</translation>
-<translation id="113582498867142724"><ph name="TAG" /> gyűjtemény <ph name="NUM" /> elemmel</translation>
-<translation id="1155043339247954670">Nincs következő listaelem.</translation>
-<translation id="1157782847298808853">Billentyűzet Súgó</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, legördülő lista</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, menüelem almenüvel</translation>
-<translation id="1177863135347784049">Egyéni</translation>
-<translation id="1188858454923323853">kiegészítő</translation>
-<translation id="1206619573307042055">fényújság</translation>
-<translation id="1213216066620407844">ChromeVox – A Chrome megszólaltatása</translation>
-<translation id="1229276918471378188">Előző ugrás</translation>
-<translation id="1237866625126425153">rádiógombcsoport</translation>
-<translation id="1251750620252348585">Következő 6. szintű fejléc</translation>
-<translation id="1275718070701477396">Kijelölt</translation>
-<translation id="1319608975892113573">Nincs előző bekezdésszintű idézet.</translation>
-<translation id="1321576897702511272">ChromeVox súgójának elrejtése</translation>
-<translation id="1331702245475014624"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">karakterek és szavak visszaolvasása</translation>
-<translation id="1339428534620983148">Előző táblázatoszlop</translation>
-<translation id="1342835525016946179">cikk</translation>
-<translation id="1346748346194534595">Jobbra</translation>
-<translation id="136718599399906424">Következő táblázatsor</translation>
-<translation id="1383876407941801731">Keresés</translation>
-<translation id="1385214448885562192">Nyomja le az entert az elfogadáshoz vagy az escape-et a visszavonáshoz, a le gombot a következőhöz, a fel gombot az előzőhöz.</translation>
-<translation id="1396114365388024581">füllista</translation>
-<translation id="1439316808600711881">régió</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, jelszómező</translation>
-<translation id="1467432559032391204">Balra</translation>
-<translation id="1474557363159888097">Nincs előző horgony.</translation>
-<translation id="1502086903961450562">Előző grafika</translation>
-<translation id="1506187449813838456">Hangszín növelése</translation>
-<translation id="151784044608172266">Következő mondat</translation>
-<translation id="1524531499102321782">Következő sor Braille-írása</translation>
-<translation id="1546370775711804143">Görgetősáv</translation>
-<translation id="1559739829547075274">Navigálás visszafelé</translation>
-<translation id="1571643229714746283">A ChromeVox készen áll</translation>
-<translation id="158493514907962286">december</translation>
-<translation id="1594072653727561613">mnü</translation>
-<translation id="1610130962244179598">Váltás 6 pontos braille-táblázatra</translation>
-<translation id="1611168825862729585">Oszlopfejléc:</translation>
-<translation id="1613476421962910979">beállítási oldal</translation>
-<translation id="1618597272655350600">Pontosan elmondja, hogy mi az aktuális pozíció</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{nagyobb jel}other{# nagyobb jel}}</translation>
-<translation id="1653266918374749391">Előző 3. szintű fejléc</translation>
-<translation id="1659072772017912254">Nincs bejelölve</translation>
-<translation id="1669290819662866522">hét</translation>
-<translation id="1674262202423278359">Navigáció a ChromeVoxban</translation>
-<translation id="16777221443363124">Menüsor</translation>
-<translation id="1692077714702418899">strukturális vonal</translation>
-<translation id="1700517974991662022">Felkeresett</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">lábl</translation>
-<translation id="174268867904053074">Következő grafika</translation>
-<translation id="1781173782405573156">Átugrás gomb</translation>
-<translation id="1787176709638001873">Jelszó – szövegszerkesztés</translation>
-<translation id="1810107444790159527">Lista mező</translation>
-<translation id="1828385960365606039">május</translation>
-<translation id="1834891354138622109">Oszlop</translation>
-<translation id="1865601187525349519">Szöveg vége</translation>
-<translation id="1876229593313240038">dok</translation>
-<translation id="188130072164734898">A pontos idő és dátum kimondása.</translation>
-<translation id="1902396333223336119">Mobil</translation>
-<translation id="1905379170753160525">Fejléclista megjelenítése</translation>
-<translation id="1912556590115083156">felkeresett link</translation>
-<translation id="1913761808037590218">#beviteli mező</translation>
-<translation id="1954623340234317532">Az év hetének beállítása</translation>
-<translation id="1964135212174907577">Következő objektum</translation>
-<translation id="1969092762068865084">július</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Sorfejléc:</translation>
-<translation id="2002895034995108595">Jelenlegi billentyűzetkiosztás visszaállítása</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{szögletes nyitó zárójel}other{# szögletes nyitó zárójel}}</translation>
-<translation id="2045490512405922022">nincs bejelölve</translation>
-<translation id="20601713649439366">Nincs előző matematikai kifejezés.</translation>
-<translation id="207477615537953741">Szemantikai értelmezés kikapcsolva</translation>
-<translation id="2086961585857038472">Következő szó</translation>
-<translation id="2089387485033699258">hu</translation>
-<translation id="2091933974477985526">Előző szerkeszthető szövegterület</translation>
-<translation id="2100350898815792233">Minden írásjellel</translation>
-<translation id="2119965627982867824">léptetőgomb</translation>
-<translation id="2121067395472282800">hozzáférési kulcs: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">A jelenlegi 6 pontos braille-táblázatot az alábbi lehetőségek egyikének kiválasztásával módosíthatja.</translation>
-<translation id="2169714232367507776">Kattintás az aktuális elemre</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{berekesztő zárójel}other{# berekesztő zárójel}}</translation>
-<translation id="2199994615414171367">Előző művelet</translation>
-<translation id="2223693656926968778">Művelet végrehajtása az aktuális elemen</translation>
-<translation id="225732394367814946">Beszédsebesség növelése</translation>
-<translation id="2267945578749931355">Következő karakter</translation>
-<translation id="2281234842553884450">Előző dia</translation>
-<translation id="2318372665160196757">Fő</translation>
-<translation id="2329324941084714723">Lappanel</translation>
-<translation id="2344193891939537199">Dátum és idő beállítása</translation>
-<translation id="2359897517538099099">Nem táblázat módban van.</translation>
-<translation id="241124561063364910">azután</translation>
-<translation id="2417569100218200841">Tartalominformáció</translation>
-<translation id="2422937916923936891">Menüelem – jelölőnégyzet</translation>
-<translation id="2429669115401274487">du.</translation>
-<translation id="2435413342408885429">A ChromeVox módosítóbillentyűje mostantól a következő: <ph name="KEY" />.</translation>
-<translation id="2450814015951372393">Jelölőnégyzet</translation>
-<translation id="2462626033734746142">Választógombcsoport</translation>
-<translation id="2471138580042810658">6-os címsor</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{csillag}other{# csillag}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> visszaállítva.</translation>
-<translation id="2553108862507765288">nyelvtani hiba</translation>
-<translation id="257674075312929031">Csoport</translation>
-<translation id="2582407057977008361">Oldaltartalom</translation>
-<translation id="2589102159832527089">Ez az oldal a(z) &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; PDF-fájlból automatikusan kinyert szöveget tartalmazza. &lt;a href="<ph name="URL" />"&gt;Kattintson ide az eredeti dokumentumért.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">{COUNT,plural, =1{# elemmel}other{# elemmel}}</translation>
-<translation id="2614981083756825552">Matematikai „ML” elrendezés</translation>
-<translation id="2626530649491650971">rákattintható</translation>
-<translation id="2628764385451019380">Nincs előző legördülő lista.</translation>
-<translation id="2637227747952042642">Matematika</translation>
-<translation id="2639750663247012216">ChromeVox módosítógomb</translation>
-<translation id="2644542693584024604">elgépelés</translation>
-<translation id="2667291555398229137">Kattintson az átirányítási kulcs alatti elemre</translation>
-<translation id="2697408785920771974">szövegközi automatikus kiegészítés</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{nyitó zárójel}other{# nyitó zárójel}}</translation>
-<translation id="2705875883745373140">Nincs megnyomva</translation>
-<translation id="2706462751667573066">Fel</translation>
-<translation id="2717271541250958000">fülpanel</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">de.</translation>
-<translation id="2749275490991666823">Bejelölve</translation>
-<translation id="27527859628328957">Ugrás a következő fókuszálható elemre</translation>
-<translation id="2770781857296573485">Csoportfelfedezés megadása</translation>
-<translation id="2777845298774924149">Kilépett</translation>
-<translation id="2800204403141299078">Nincs több eltérő elem.</translation>
-<translation id="2800780099804980316">Nincs előző 1-es szintű címsor.</translation>
-<translation id="2811204574343810641">Sor</translation>
-<translation id="2816654101880605877">Nincs következő dia.</translation>
-<translation id="2841013758207633010">Idő</translation>
-<translation id="2843837985843789981">Előző csoport</translation>
-<translation id="2844995807198708617">Helyi menü</translation>
-<translation id="2849332794118375855">Nincs következő jelölőnégyzet.</translation>
-<translation id="2864481629947106776">Előző link</translation>
-<translation id="2873259058405069099">Ugrás a táblázat elejére</translation>
-<translation id="2894654529758326923">Információ</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{kapcsos nyitó zárójel}other{# kapcsos nyitó zárójel}}</translation>
-<translation id="2911433807131383493">A ChromeVox útmutatójának megnyitása</translation>
-<translation id="2932083475399492303">Váltás a strukturális és elrendezési vonalak között</translation>
-<translation id="2964026537669811554">Címsorcsoport</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulátor}other{# tabulátor}}</translation>
-<translation id="2972078295414139404">Nincs előző felkeresett link.</translation>
-<translation id="2972205263822847197">Elemleírás</translation>
-<translation id="2998131015536248178">Előző karakter</translation>
-<translation id="2999559350546931576">Hangszín csökkentése</translation>
-<translation id="2999945368667127852">Nincs következő médiamodul.</translation>
-<translation id="3012414509011670858">Nincs előző panel.</translation>
-<translation id="3030432017085518523">Menüelem választógomb</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{aposztróf}other{# aposztróf}}</translation>
-<translation id="3046838483509668188">ChromeVox-opciók</translation>
-<translation id="3047143736589213134">Kísérleti billentyűzetkiosztás</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> menü megnyitva</translation>
-<translation id="3078345202707391975">Következő 2. szintű fejléc</translation>
-<translation id="3078740164268491126">táblázat</translation>
-<translation id="3082557070674409251">Rákattintott</translation>
-<translation id="3084806535845658316">nincs gépelési visszaolvasás</translation>
-<translation id="3086746722712840547">jegyzet</translation>
-<translation id="308895241372589742">Nincs következő matematikai kifejezés.</translation>
-<translation id="3090532668523289635">csop</translation>
-<translation id="3093176084511590672">Következő határjel</translation>
-<translation id="3096671415663099226">kombinált szövegbeviteli mező</translation>
-<translation id="3104705064753753826">riaszt pnl</translation>
-<translation id="3109724472072898302">Összecsukott</translation>
-<translation id="3134461040845705080">csak olv</translation>
-<translation id="3138767756593758860">Határjelek listájának megjelenítése</translation>
-<translation id="3143851963874289911">cella</translation>
-<translation id="3149472044574196936">Következő sor</translation>
-<translation id="3155083529632865074">Nincs előző gomb.</translation>
-<translation id="3163593631834463955">Üres oszlopfejléc</translation>
-<translation id="316542773973815724">Navigálás</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{szóköz}other{# szóköz}}</translation>
-<translation id="320961988183078793">bevitte ezt: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, lap</translation>
-<translation id="3226035351387556942">jelölőnégyzet</translation>
-<translation id="3229375994964697375">Felkeresett link</translation>
-<translation id="323731244387692321">A ChromeVox billentyűzettel kapcsolatos súgójának megnyitása</translation>
-<translation id="3241052487511142956">Előző felkeresett link</translation>
-<translation id="3286390186030710347">Csúszka</translation>
-<translation id="3299925995433437805">Nincs következő felkeresett link.</translation>
-<translation id="3303384412438961941">A név megismeréséhez kattintson egy billentyűre. A Ctrl+W billentyűkombináció bezárja a Keyboard Explorert.</translation>
-<translation id="3307886118343381874">Ugrás a táblázat végére</translation>
-<translation id="3311969765485641742">Az értesítések megtekintéséhez nyomja meg az Alt+Shift+A kombinációt</translation>
-<translation id="3312997241656799641">A következő felkeresett link</translation>
-<translation id="3321460131042519426">Szavak egyben tartásának engedélyezése</translation>
-<translation id="3322936298410871309">Előző 1. szintű fejléc</translation>
-<translation id="3323447499041942178">Szövegmező</translation>
-<translation id="3353420241558113817">{"ar": "arab",
- "bg": "bolgár",
- "ca": "katalán",
- "cs": "cseh",
- "da": "dán",
- "de": "német",
- "de_CH": "német (Svájc)",
- "de_DE": "német (Németország)",
- "el": "görög",
- "en": "angol",
- "en_CA": "angol (Kanada)",
- "en_GB": "angol (Egyesült Királyság)",
- "en_US": "angol (Amerikai Egyesült Államok)",
- "es": "spanyol",
- "et": "észt",
- "fr": "francia",
- "fr_CA": "francia (Kanada)",
- "fr_FR": "francia (Franciaország)",
- "fi": "finn",
- "he": "héber",
- "hi": "hindi",
- "hr": "horvát",
- "hu": "magyar",
- "is": "izlandi",
- "it": "olasz",
- "ko": "koreai",
- "lt": "litván",
- "lv": "lett",
- "nb": "norvég bokmål",
- "nl": "holland",
- "pl": "lengyel",
- "pt": "portugál",
- "ro": "román",
- "ru": "orosz",
- "sk": "szlovák",
- "sl": "szlovén",
- "sr": "szerb",
- "sv": "svéd",
- "tr": "török",
- "vi": "vietnami",
- "zh": "kínai",
- "zh_TW": "kínai (hagyományos han)"}</translation>
-<translation id="3359142382821736686">elválasztó</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{pluszjel}other{# pluszjel}}</translation>
-<translation id="338583716107319301">Elválasztó</translation>
-<translation id="3389259863310851658">Előző űrlap mező</translation>
-<translation id="3390225400784126843">Következő eltérő elem.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, menüelem</translation>
-<translation id="3406283310380167331">Űrlaplista megjelenítése</translation>
-<translation id="3422338090358345848">Keyboard Explorer megnyitása</translation>
-<translation id="3457000393508828486">Részben megnyomva</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, gomb</translation>
-<translation id="3473644018603298796"><ph name="COUNT" />. dia</translation>
-<translation id="3486232535569802404"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{szögletes berekesztő zárójel}other{# szögletes berekesztő zárójel}}</translation>
-<translation id="3493915602752813531">Nincs következő horgony.</translation>
-<translation id="3494946239022273294">menüelem</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{kérdőjel}other{# kérdőjel}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{csúcsos ékezet}other{# csúcsos ékezet}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, jelölőnégyzet nincs bejelölve</translation>
-<translation id="3599054940393788245">Nincs math elemben</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{egyszeres nyitó idézőjel}other{# egyszeres nyitó idézőjel}}</translation>
-<translation id="3650317109285159359">jelölőnégyzet menüelem</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollárjel}other{# dollárjel}}</translation>
-<translation id="3659787053479271466">riaszt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, lista</translation>
-<translation id="3687295507293856493">Aktuális cella oszlopfejlécének tippelése</translation>
-<translation id="3692274950075847560">K:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Beszéd vezérlése</translation>
-<translation id="3716845769494773620">Többsoros</translation>
-<translation id="3731746171184829332">Nincs előző címsor.</translation>
-<translation id="3762198587642264450">Ugrás az aktuális sor végére</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Kilépett a párbeszédpanelből.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Automatikus kiegészítés listaként</translation>
-<translation id="3810838688059735925">Videó</translation>
-<translation id="3816633764618089385">Következő médiaelem</translation>
-<translation id="3819376190738087562">Nincs ugrás.</translation>
-<translation id="385383972552776628">A beállítások oldalának megnyitása</translation>
-<translation id="3856075812838139784">Csak olvasható</translation>
-<translation id="3887576927692165210">szövegmező</translation>
-<translation id="3897092660631435901">Menü</translation>
-<translation id="3909320334364316587">Előző 6. szintű fejléc</translation>
-<translation id="3914173277599553213">Kötelező</translation>
-<translation id="3962990492275676168">Olvasás megkezdése az aktuális helyről</translation>
-<translation id="4004802134384979325">bejelölve</translation>
-<translation id="4006140876663370126">kép</translation>
-<translation id="4038349100599457191">Hónap beállítása</translation>
-<translation id="4039983576244166038">Üres sorfejléc</translation>
-<translation id="4042843249978639960">Nincs következő 2-es szintű címsor.</translation>
-<translation id="4043348641337972076">Nincs előző ARIA határjel.</translation>
-<translation id="4047216625641135770">Kiemelés</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">állpt</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{HULLÁMVONAL}other{# hullámvonal}}</translation>
-<translation id="409334809956508737">Előző objektum</translation>
-<translation id="4099274309791143834">almenüvel</translation>
-<translation id="4107807507418787238">Nincs több cella lefelé.</translation>
-<translation id="4116415223832267137">Értesítés</translation>
-<translation id="4147126331795725888">Nincs következő vezérlő.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{kapcsos berekesztő zárójel}other{# kapcsos berekesztő zárójel}}</translation>
-<translation id="4158704014418536539">A kis- és nagybetű különböző.</translation>
-<translation id="4161663686871496107">A ChromeVox hangos visszajelzés készen áll</translation>
-<translation id="4173994908659439270">Nincs következő szerkeszthető szövegmező.</translation>
-<translation id="4176463684765177261">Kikapcsolva</translation>
-<translation id="4188530942454211480">Előző mondat</translation>
-<translation id="4202186506458631436">Mozgatás jobbra</translation>
-<translation id="4206289001967551965">Belső táblázat</translation>
-<translation id="4215733775853809057">Következő dia</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{kötőjel}other{# kötőjel}}</translation>
-<translation id="421884353938374759">színválasztó</translation>
-<translation id="4229646983878045487">dátum idő</translation>
-<translation id="423334822609210999">Nincs több cella balra.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" />. osztály</translation>
-<translation id="4253168017788158739">Jegyzet</translation>
-<translation id="4254798249533888099">Fa</translation>
-<translation id="4255943572433203166">Használja az alábbi lehetőségeket a ChromeVox személyre szabásához. A változások azonnal életbe lépnek.</translation>
-<translation id="4271220233568730077">Következő művelet</translation>
-<translation id="4271521365602459209">Nincsenek további találatok.</translation>
-<translation id="4287520460805643128">Nincs következő cikk.</translation>
-<translation id="4289540628985791613">Áttekintés</translation>
-<translation id="4300318234632215983">Link URL-jének felolvasása</translation>
-<translation id="4301352596632316575">almenüvel rendelkezik</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{pont}=3{három pont}other{# pont}}</translation>
-<translation id="4347461890115250064">Nincs következő lista.</translation>
-<translation id="4367650418938037324">Matematikai „ML Leaf”</translation>
-<translation id="4372435075475052704">min.: <ph name="X" /></translation>
-<translation id="4372705107434148843">Beszéd leállítása</translation>
-<translation id="4373197658375206385">Nincs előző elem, amely ne lenne link.</translation>
-<translation id="4391478986194775161">tartalominformáció</translation>
-<translation id="443163561286008705">visszaáll</translation>
-<translation id="4471074325120394300">Nincsenek linkek.</translation>
-<translation id="4476183483923481720">új sor</translation>
-<translation id="4482330759234983253">Előző táblázat</translation>
-<translation id="4491109536499578614">Kép</translation>
-<translation id="4529987814483543472">Hagyományos billentyűzetkiosztás</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{törtvonal}other{# törtvonal}}</translation>
-<translation id="4547556996012970016">Következő 5. szintű fejléc</translation>
-<translation id="4562381607973973258">Fejléc</translation>
-<translation id="4591507479202817876">, kiválasztva</translation>
-<translation id="4597532268155981612">űrlap</translation>
-<translation id="4597896406374528575">április</translation>
-<translation id="4615592953348396470">A következő gombnyomás figyelmen kívül hagyása</translation>
-<translation id="461613135510474570">Mondat</translation>
-<translation id="4647836961514597010">Színválasztó</translation>
-<translation id="4661075872484491155">fa</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">rács</translation>
-<translation id="4693675773662933727">Előző határjel</translation>
-<translation id="4696413482802371445">Nincs következő 5-ös szintű címsor.</translation>
-<translation id="4729095194763193578">Előző táblázatsor</translation>
-<translation id="4736221692378411923">augusztus</translation>
-<translation id="4740661827607246557">Súgóparancsok</translation>
-<translation id="4759716709594980008">ChromeOS Keyboard Explorer</translation>
-<translation id="4763296182459741068">Az aljára kerül</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Aktuális oldal címének felolvasása</translation>
-<translation id="4826415162591436065">Navigálás előre</translation>
-<translation id="4826604887384865800">Következő ugrás</translation>
-<translation id="4827410568042294688">nincs kijelölve</translation>
-<translation id="4842108708071771135">Nincs következő bekezdésszintű idézet.</translation>
-<translation id="4848993367330139335">időz</translation>
-<translation id="4850023505158945298">Előző hasonló elem.</translation>
-<translation id="4866956062845190338">rádiógomb menüelem</translation>
-<translation id="4867316986324544967">TTS naplózásának engedélyezése</translation>
-<translation id="4877261390094455813">Adjon meg egy keresési lekérdezést.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Belső link</translation>
-<translation id="4953585991029886728">Szöveg szerkesztése</translation>
-<translation id="4954534434583049121">Előző idézetblokk</translation>
-<translation id="4973717656530883744">Maximum <ph name="X" /></translation>
-<translation id="4973762002207131920">A rendszer átvált a következőre: <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">ezredmásodperc</translation>
-<translation id="49787999531187221">A ChromeVox most inaktív.</translation>
-<translation id="4979404613699303341">Előző gomb</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, listamező</translation>
-<translation id="4983588134362688868">Ugrás az oldal tetejére</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, ablak</translation>
-<translation id="4993152509206108683">Sebesség: <ph name="PERCENT" /> százalék</translation>
-<translation id="4996716799442435517">Vizuális</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, kiválasztott választógomb</translation>
-<translation id="4997475792277222884">Nincs következő elem, amely ne lenne link.</translation>
-<translation id="5000760171916499057">Nincsenek űrlapok.</translation>
-<translation id="5005670136041063723">Nincs több hasonló elem.</translation>
-<translation id="501473567976723023">január</translation>
-<translation id="5041394372352067729">A Braille-kijelző áthelyezése az oldal tetejére</translation>
-<translation id="5042770794184672516">Beszéd hangerejének növelése</translation>
-<translation id="5050015258024679800">Előző 4. szintű fejléc</translation>
-<translation id="5054047268577924192">Előző listaelem</translation>
-<translation id="5078661581131202757">Fájl kiválasztása</translation>
-<translation id="5080758118274074384">duplán kattintva</translation>
-<translation id="5098541983634824365">Rács elhagyása.</translation>
-<translation id="5102981729317424850">Eszköztár</translation>
-<translation id="5105050547967751155">kötelező</translation>
-<translation id="5110983769041734144">Nincs előző űrlap mező.</translation>
-<translation id="5111640677200759579">Oszlopfejléc</translation>
-<translation id="5117636609870536415">e-mail mező</translation>
-<translation id="5136967254288895616">Nincs előző link.</translation>
-<translation id="513774504516943387">link</translation>
-<translation id="517143700877085897">, nincs kiválasztva</translation>
-<translation id="5183440668879371625">Előző sor Braille-írása</translation>
-<translation id="5184944171021383281">Nincs következő űrlap mező.</translation>
-<translation id="5189244881767082992">Sor</translation>
-<translation id="5203930734796605961">A(z) <ph name="KEY" /> billentyű már hozzá van rendelve egy parancshoz.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> lista.</translation>
-<translation id="520883772648104506">Nincs következő választógomb.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Befejezés</translation>
-<translation id="5291783959063340370">Objektum</translation>
-<translation id="5304943142864553931"><ph name="TITLE" /> lap</translation>
-<translation id="5310788376443009632">eltávolítva:</translation>
-<translation id="5320727453979144100">Beragadó mód bekapcsolva</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{vessző}other{# vessző}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, szövegmező</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">automatikus kiegészítés (szövegközi és lista)</translation>
-<translation id="536031132345979795">Ugrás vissza folyamatos olvasáskor</translation>
-<translation id="5368000168321181111">Hangjelzések kikapcsolva</translation>
-<translation id="5374320867641260420">Nincs következő gomb.</translation>
-<translation id="5382299583965267720">Nincs következő 1-es szintű címsor.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{pontosvessző}other{# pontosvessző}}</translation>
-<translation id="5411891038905756502">Nincs előző ugrópont.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{kisebb jel}other{# kisebb jel}}</translation>
-<translation id="5455441614648621694">Kiegészítő</translation>
-<translation id="5485036206801896268">Nincs előző ábra.</translation>
-<translation id="5486947920110100234">Nincs következő ugrópont.</translation>
-<translation id="549602578321198708">Szó</translation>
-<translation id="5500932716852106146">Nincs előző szerkeszthető szövegmező.</translation>
-<translation id="5502713021410870035">szeptember</translation>
-<translation id="5507663321906818013">Összehasonlítás hibajavítása</translation>
-<translation id="5518443085409638729">A szöveg szerkesztéséhez vigye a kurzort a karakterek közé (mint a Mac OS X-nél).</translation>
-<translation id="552195134157544755">Választógomb</translation>
-<translation id="5534303576632885660">fejl</translation>
-<translation id="5546092960038624944">Nincs előző 5-ös szintű címsor.</translation>
-<translation id="556042886152191864">Gomb</translation>
-<translation id="5561345396546889625">Következő lista</translation>
-<translation id="5562645715554321347">címsorcsoport</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Szövegszerkesztés, e-mail bevitel</translation>
-<translation id="5597170376237141345">Következő jelölőnégyzet</translation>
-<translation id="5597933780944041114">Nincs következő címsor.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, nem kiválasztott választógomb</translation>
-<translation id="5601172225407283979">Alapértelmezett művelet végrehajtása</translation>
-<translation id="5608798115546226984">Automatikus kiegészítés soron belül</translation>
-<translation id="561939826962581046">idő</translation>
-<translation id="5623778242535476823">rádiógomb</translation>
-<translation id="5623842676595125836">Napló</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Nincs előző táblázat.</translation>
-<translation id="5655682562155942719">Ugrás parancsai</translation>
-<translation id="56637627897541303">Szövegterület</translation>
-<translation id="5678161956734658133">szövegterület</translation>
-<translation id="5681643281275621376">megh</translation>
-<translation id="5682113568322255809">Határjel</translation>
-<translation id="5683155931978483559">Előző jelölőnégyzet</translation>
-<translation id="5684277895745049190">Lista</translation>
-<translation id="5700650669149824506">Nincs előző 4-es szintű címsor.</translation>
-<translation id="5709192780268610569">Nincs hosszú leírás</translation>
-<translation id="5712244464475377681">előugró ablak gombja</translation>
-<translation id="5712338278108304766">Következő táblázatoszlop</translation>
-<translation id="571866080859340309">Csoportok felfedezése</translation>
-<translation id="5728409797179002635">Nem található táblázat.</translation>
-<translation id="5748623122140342504">Előző 5. szintű fejléc</translation>
-<translation id="5750633686117194034">Nincs lenyomva módosítóbillentyű. Kérjük, nyomjon le egy vagy több módosítóbillentyűt, majd engedje fel, ha kész. Hallani fogja, hogy a billentyűk be lettek állítva. A Tab segítségével léphet ki.</translation>
-<translation id="5788275253279308023">inkognitóablak, <ph name="TITLE" /> lap</translation>
-<translation id="5806206155699461681">Bizonyos oldalak javítása (például Google Keresés)</translation>
-<translation id="5819072574982403430">Faelem</translation>
-<translation id="5826479389509458994"><ph name="ROW" />. sor, <ph name="COL" />. oszlop</translation>
-<translation id="5850707923114094062">Pásztázás hátrafelé</translation>
-<translation id="5851548754964597211">Laplista</translation>
-<translation id="5859752971144398932">Kilépett az oldalon történő keresésből.</translation>
-<translation id="5866042630553435010">Részben bejelölve</translation>
-<translation id="5869546221129391014">Rács</translation>
-<translation id="5876817486144482042">Beszéd hangerejének csökkentése</translation>
-<translation id="5887397643266327462">Braille-feliratok engedélyezve.</translation>
-<translation id="5891934789323004067">Táblázat</translation>
-<translation id="5919442531159595654">másolás.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{egyenlőségjel}other{# egyenlőségjel}}</translation>
-<translation id="5939518447894949180">Visszaállítás</translation>
-<translation id="5948123859135882163">Váltás a matematikai kifejezések strukturális és szemantikai értelmezése között</translation>
-<translation id="5955304353782037793">alk</translation>
-<translation id="5956928062748260866">Párbeszédpanel</translation>
-<translation id="5963413905009737549">Szakasz</translation>
-<translation id="5968607524793740041">Helyi menü megjelenítése</translation>
-<translation id="5983179082906765664">Navigáció részletezettségének növelése</translation>
-<translation id="5999630716831179808">Hangok</translation>
-<translation id="6000417740266304866">A jelenlegi 8 pontos braille-táblázatot az alábbi lehetőségek egyikének kiválasztásával módosíthatja.</translation>
-<translation id="6006050241733874051">Űrlap</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{fordított törtvonal}other{# fordított törtvonal}}</translation>
-<translation id="6037602951055904232">Pászt előre</translation>
-<translation id="611827076493383239">felkeresett</translation>
-<translation id="6119955456199054975">Cella vége.</translation>
-<translation id="6122013438240733403">gmb</translation>
-<translation id="6129953537138746214">Szóköz</translation>
-<translation id="6142308968191113180">4-es címsor</translation>
-<translation id="6169420925157477918">Kép hosszú leírással</translation>
-<translation id="6172087735260766220">A jelszóval védett PDF-ből származó szöveghez való hozzáférés sikertelen.</translation>
-<translation id="6186305613600865047">Ugrás az oldal aljára</translation>
-<translation id="6193330012414963395">DE DU</translation>
-<translation id="622484624075952240">Le</translation>
-<translation id="6236061028292614533">Következő fejléc</translation>
-<translation id="6254901459154107917">Következő szerkeszthető szövegterület</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> bezárva.</translation>
-<translation id="6281876499889881039">Következő hasonló elem.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Nincs következő legördülő lista.</translation>
-<translation id="6307969636681130414">Megnyomva</translation>
-<translation id="6324551002951139333">Észlelt nyelvtani hiba</translation>
-<translation id="6348657800373377022">Legördülő lista</translation>
-<translation id="6355910664415701303">Nincs előző listaelem.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Előző fejléc</translation>
-<translation id="6387719785439924554">oldaltartalom</translation>
-<translation id="6411426777058107714">Nincs előző választógomb.</translation>
-<translation id="6414968628640960377">Előző eltérő elem.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{kettőspont}other{# kettőspont}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menü</translation>
-<translation id="6444046323172968959">Értesítő párbeszédpanel</translation>
-<translation id="6459511626086141404">Sima billentyűzetkiosztás</translation>
-<translation id="6468049171101508116">Tovább gomb</translation>
-<translation id="6491972999578897419">A jelenlegi hangot az alábbi listáról választva változtathatja meg.</translation>
-<translation id="6508059270146105198">A Braille-kijelző áthelyezése az oldal aljára</translation>
-<translation id="6536864053412760904">Matematikai „ML” token</translation>
-<translation id="6550720799683018100">A jelenlegi billentyűzetkiosztást az alábbi listáról választva változtathatja meg.</translation>
-<translation id="6561818612645211875">Ugrás az aktuális sor elejére</translation>
-<translation id="6587021927234520429">Nincs következő 4-es szintű címsor.</translation>
-<translation id="6601344353291556895">Terjedelmesebb leírások engedélyezése.</translation>
-<translation id="6615602925644411249">Keresés az oldalon.</translation>
-<translation id="6633350132811819843">Nincs következő táblázat.</translation>
-<translation id="6637586476836377253">napló</translation>
-<translation id="6657128831881431364">Folyamatjelző</translation>
-<translation id="6659594942844771486">Lap</translation>
-<translation id="667999046851023355">Dokumentum</translation>
-<translation id="6697092096875747123">Előző legördülő lista</translation>
-<translation id="6714813999819678458">Előző 2. szintű fejléc</translation>
-<translation id="6716505898850596801">Módosítóbillentyűk</translation>
-<translation id="671916444866103745">Nincs következő ARIA határjel.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, kombinált mező</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> elemmel</translation>
-<translation id="6736510033526053669">lap létrehozva</translation>
-<translation id="675895815784134693">folyamatjelző sáv</translation>
-<translation id="6786800275320335305">Cikk</translation>
-<translation id="6787839852456839824">Billentyűkódok</translation>
-<translation id="6793101435925451627">lstmez</translation>
-<translation id="6833103209700200188">Lábléc</translation>
-<translation id="6871161210040114857">A kis- és nagybetűk nem különbözők.</translation>
-<translation id="6877435256196695200">Nincs következő ábra.</translation>
-<translation id="6897341342232909480">Mozgatás balra</translation>
-<translation id="6901540140423170855">dátum</translation>
-<translation id="6910211073230771657">Törölve</translation>
-<translation id="6911965441508464308">Nincs több cella felfelé.</translation>
-<translation id="6919104639734799681">Táblázatlista megjelenítése</translation>
-<translation id="6964088412282673743">Nincs előző vezérlő.</translation>
-<translation id="6996566555547746822">Következő legördülő lista</translation>
-<translation id="7005146664810010831">Nem található URL</translation>
-<translation id="7010712454773919705">ChromeVox-módosítóbillentyű</translation>
-<translation id="7031651751836475482">lstelem</translation>
-<translation id="7037042857287298941">Előző lista</translation>
-<translation id="7041173719775863268">Kijelölés vége</translation>
-<translation id="7095834689119144465">Szövegszerkesztés – csak numerikus</translation>
-<translation id="7096001299300236431">Előző médiaelem</translation>
-<translation id="7116595520562830928">többsoros</translation>
-<translation id="712735679809149106">szavak visszaolvasása</translation>
-<translation id="713824876195128146">Következő idézetblokk</translation>
-<translation id="7161771961008409533">Előugró gomb</translation>
-<translation id="7167657087543110">karakterek visszaolvasása</translation>
-<translation id="7170733337935166589">Ugrás előre folyamatos olvasáskor</translation>
-<translation id="7181697990050180700">Gépelje be a megfelelő mezőbe a billentyűparancsokat a gyakran használt parancsok személyre szabásához.</translation>
-<translation id="7203150201908454328">Kibontott</translation>
-<translation id="7210211103303402262">perc</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">sor</translation>
-<translation id="7226216518520804442">list</translation>
-<translation id="72393384879519786">Címsor</translation>
-<translation id="7241683698754534149">Hosszú leírás megnyitása új lapon</translation>
-<translation id="7248671827512403053">Alkalmazás</translation>
-<translation id="725969808843520477">Következő választógomb</translation>
-<translation id="7269119382257320590">Írásjelek mellőzése</translation>
-<translation id="7273174640290488576">Üres</translation>
-<translation id="7285387653379749618">Táblázatok</translation>
-<translation id="7289186959554153431">3-as címsor</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">faelem</translation>
-<translation id="731576946540457939">Braille-feliratok letiltva.</translation>
-<translation id="7318872822751139669">A fókusz megváltoztatásához használja az egeret.</translation>
-<translation id="7322388933135261569">február</translation>
-<translation id="7332592614823088566"><ph name="ROWINDEX" />/<ph name="ROWTOTAL" />. sor, <ph name="COLINDEX" />/<ph name="COLTOTAL" />. oszlop</translation>
-<translation id="7336596009609913925">előugróval rendelkezik</translation>
-<translation id="7356165926712028380">Váltás 8 pontos braille-táblázatra</translation>
-<translation id="7362871137496673139">Nincs előző 2-es szintű címsor.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ÉS jel}other{# ÉS jel}}</translation>
-<translation id="737396357417333429">kattintható</translation>
-<translation id="7374104575779636480">Táblázat elhagyása.</translation>
-<translation id="739763518212184081">Előző sor</translation>
-<translation id="7400575256015741911">Észlelt helyesírási hiba</translation>
-<translation id="7408482676469142474">tábl</translation>
-<translation id="7425395583360211003">ugrás a sor elejére</translation>
-<translation id="7434509671034404296">Fejlesztőknek</translation>
-<translation id="7439060726180460871">Címtár</translation>
-<translation id="744163271241493234">jelszóbevitel</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Belépett a párbeszédbe</translation>
-<translation id="7532613204005497612">június</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, csúszka</translation>
-<translation id="7586163296341959563">beillesztés.</translation>
-<translation id="7596919493010894443">kijelölés törölve</translation>
-<translation id="7604026522577407655">Ugrás az aktuális oszlop elejére</translation>
-<translation id="7604451927827590395">címsor</translation>
-<translation id="7609342235116740824">Aktuális oldal URL-jének felolvasása</translation>
-<translation id="7609363189280667021">Braille-feliratok bekapcsolása</translation>
-<translation id="762020119231868829">A jelenleg működő összes médiamodul szüneteltetése</translation>
-<translation id="7625690649919402823">Következő táblázat</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Grade <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Nincs előző 3-as szintű címsor.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, szövegmező</translation>
-<translation id="7663318257180412551">2-es címsor</translation>
-<translation id="7674576868851035240">Következő link</translation>
-<translation id="7674768236845044097">kiemelés</translation>
-<translation id="7684431668231950609">Szövegszerkesztés, URL-bevitel</translation>
-<translation id="7685589220304187312">eszközsor</translation>
-<translation id="7693840228159394336">Előző választógomb</translation>
-<translation id="7701196182766842984">automatikus kiegészítés lista</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, jelszómező</translation>
-<translation id="7805247615045262757">alapértelmezett navigáció</translation>
-<translation id="7805768142964895445">Állapot</translation>
-<translation id="7810781339813764006">Következő csoport</translation>
-<translation id="7819187121850078213">ablak, <ph name="TITLE" /> lap</translation>
-<translation id="7828956995407538686">október</translation>
-<translation id="7839679365527550018">Előző szó</translation>
-<translation id="7851816175263618915">Bizonyos írásjelek</translation>
-<translation id="7870596830398826354">Matematikai „ML Tree”</translation>
-<translation id="78826985582142166">csúsz</translation>
-<translation id="7894517696028036636">Váltás a klasszikus ChromeVox aktív és inaktív állapota között</translation>
-<translation id="7895896691902835279">Ismeretlen link</translation>
-<translation id="7927711904086083099">Nincs kiválasztva</translation>
-<translation id="7935627501098484003">Idő szabályozása</translation>
-<translation id="7939428177581522200">hozzáadás a kijelöléshez</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{kukac}other{# kukac}}</translation>
-<translation id="7965147473449754028">menü bezárva</translation>
-<translation id="7974390230414479278">Menüelem</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{felkiáltójel}other{# felkiáltójel}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{idézőjel}other{# idézőjel}}</translation>
-<translation id="8033827949643255796">kijelölve</translation>
-<translation id="8035962149453661158">max.: <ph name="X" /></translation>
-<translation id="8042761080832772327">Szövegszerkesztés, keresési bevitel</translation>
-<translation id="8049189770492311300">Időzítő</translation>
-<translation id="8065607967589909823">A kijelölés:</translation>
-<translation id="8066678206530322333">Szalaghirdetés</translation>
-<translation id="8110647606445335195">Nincsenek ARIA határjelek.</translation>
-<translation id="8153880621934657047">Nem táblázatban van.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{alulvonás}other{# alulvonás}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">kivágás.</translation>
-<translation id="8199231515320852133">Aktuális cella fejléceinek felolvasása</translation>
-<translation id="820417203470636242">Üres cella.</translation>
-<translation id="8215202828671303819">Többszörös kiválasztás</translation>
-<translation id="8276439074553447000">Ugrás következő fókuszálható elemre</translation>
-<translation id="8278417001922463147">Nincs előző cikk.</translation>
-<translation id="8283603667300770666">Következő űrlapmező</translation>
-<translation id="831207808878314375">Definíció</translation>
-<translation id="8313653172105209786">könyvt</translation>
-<translation id="8344569602005188545">óra</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{kettős kereszt}other{# kettős kereszt jel}}</translation>
-<translation id="8374154622594089836">hónap</translation>
-<translation id="8378855320830505539">Terület</translation>
-<translation id="8382679411218029383">Automatikus kiegészítés soron belül és listaként</translation>
-<translation id="8428603554127842284"><ph name="DEPTH" />. szint</translation>
-<translation id="842922884199979200">Nincs következő 3-as szintű címsor.</translation>
-<translation id="8430049249787218991">menüsor</translation>
-<translation id="844681116543532394">Nincs előző jelölőnégyzet.</translation>
-<translation id="8455868257606149352">Max <ph name="X" /></translation>
-<translation id="84575901236241018">hozzáférési kulccsal rendelkezik: <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Navigáció részletezettségének csökkentése</translation>
-<translation id="8520472399088452386">Léptetőnyíl</translation>
-<translation id="8538744478902126321">Aktuális cella sorfejlécének tippelése</translation>
-<translation id="8540054775867439484">A tetejére kerül</translation>
-<translation id="8548973727659841685">Karakter</translation>
-<translation id="8561322612995434619">pop-uppal rendelkezik</translation>
-<translation id="8571096049907249734">többkijel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Következő listaelem</translation>
-<translation id="860150890330522909"><ph name="NAME" /> négyzet bejelölve</translation>
-<translation id="8606621670302093223">Dátum beállítása</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> elem kiválasztva</translation>
-<translation id="8638532244051952400">Aktuális cella koordinátáinak kimondása</translation>
-<translation id="8650576015643545550">Nincs előző lista.</translation>
-<translation id="8653031188082306838">url szerkesztése</translation>
-<translation id="8653646212587894517">Linklista megjelenítése</translation>
-<translation id="8664519043722036194">másodperc</translation>
-<translation id="867187640362843212">5-ös címsor</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{függőleges vonal}other{# függőleges vonal karakter}}</translation>
-<translation id="8735450637152821465">Kijelölés eleje</translation>
-<translation id="8743786158317878347">belépés a strukturált tartalmakba, például táblázatokba</translation>
-<translation id="8747966237988593539">Rendezett lista</translation>
-<translation id="8759334257841767240">Nincs következő link.</translation>
-<translation id="8767968232364267681">Következő 4. szintű fejléc</translation>
-<translation id="8770473310765924354">kilépés a strukturált tartalmakból, például táblázatokból</translation>
-<translation id="8791025954632646584">Szemantikai értelmezés bekapcsolva</translation>
-<translation id="8796411681063377102">Következő 3. szintű fejléc</translation>
-<translation id="8808582214901541005">március</translation>
-<translation id="8825828890761629845">szlghird</translation>
-<translation id="8851136666856101339">fő</translation>
-<translation id="8856538297388979332">Nyomja meg felfelé vagy lefelé a parancsok megtekintéséhez, majd az Entert az aktiválásukhoz</translation>
-<translation id="8864099967139188018">Nincs következő 6-os szintű címsor.</translation>
-<translation id="8882002077197914455">Sorfejléc</translation>
-<translation id="8896347895970027998">Váltás a ChromeVox aktív és inaktív állapota között.</translation>
-<translation id="8898516272131543774">Központozás visszaolvasásának be- vagy kikapcsolása</translation>
-<translation id="8900148057318340779">Előtagkulcs</translation>
-<translation id="8908714597367957477">oszlopfejléc</translation>
-<translation id="8931936695772494138">Üres fejlécek</translation>
-<translation id="8937112856099038376">belső link</translation>
-<translation id="8940925288729953902">Módosítóbillentyűk</translation>
-<translation id="8943175951035496220">Nincs több cella jobbra.</translation>
-<translation id="8978496506222343566">helyi súgó</translation>
-<translation id="900114243503212879">fájl</translation>
-<translation id="9027462562263121875">Nincsenek táblázatok.</translation>
-<translation id="9040132695316389094">1-es címsor</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Keresési modul ki- és bekapcsolása</translation>
-<translation id="9065283790526219006">+előugr</translation>
-<translation id="9077213568694924680">eltávolítva a kiválasztottak közül</translation>
-<translation id="9082874451376019682">Nincs előző dia.</translation>
-<translation id="9089864840575085222">Ciklikus gépelési visszaolvasás</translation>
-<translation id="9107530006868467849">Nincs előző médiamodul.</translation>
-<translation id="9108370397979208512">matematika</translation>
-<translation id="9108589040018540527">görgetősáv</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{százalékjel}other{# százalékjel}}</translation>
-<translation id="9115913704608474258">november</translation>
-<translation id="9128414153595658330">pnl</translation>
-<translation id="9149560530563164529">szakasz</translation>
-<translation id="9151211641321628915">Röviden elmondja, hogy mi az aktuális pozíció</translation>
-<translation id="9153606228985488238">Hangmagasság: <ph name="PERCENT" /> százalék</translation>
-<translation id="9160096769946561184">Ugrás az aktuális oszlop végére</translation>
-<translation id="9173115498289768110">Hangerő: <ph name="PERCENT" /> százalék</translation>
-<translation id="9178973770513562274">A fel és le nyílbillentyűkkel böngészhet, vagy kezdjen el gépelni a kereséshez.</translation>
-<translation id="9192904702577636854">Futószöveg</translation>
-<translation id="9212322457209634662">Nincs következő panel.</translation>
-<translation id="930275611743429116">Kijelölés vagy kijelölés vége.</translation>
-<translation id="948171205378458592">Beszédsebesség csökkentése</translation>
-<translation id="962913030769097253">Következő 1. szintű fejléc</translation>
-<translation id="973955474346881951">Rögzített mód engedélyezése/tiltása</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_id.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_id.xtb
deleted file mode 100644
index 625f0e5445d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_id.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="id">
-<translation id="1012173283529841972">Item daftar</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Diregangkan.</translation>
-<translation id="1025074108959230262">Mode lekat dinonaktifkan</translation>
-<translation id="1031961866430398710">kemudian</translation>
-<translation id="1044777062731150180">Tanpa judul</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Input tidak valid</translation>
-<translation id="1082209053475788238">Tidak ada judul tingkat 6 sebelumnya.</translation>
-<translation id="1088219014394087294">Tanpa judul.</translation>
-<translation id="1106741348836243114">Mengaktifkan atau menonaktifkan masukan suara (earcons).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Koleksi <ph name="TAG" /> dengan <ph name="NUM" /> item</translation>
-<translation id="1155043339247954670">Tidak ada item daftar berikutnya.</translation>
-<translation id="1157782847298808853">Bantuan Keyboard</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, kotak kombo</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, item menu, dengan submenu</translation>
-<translation id="1177863135347784049">Sesuaikan</translation>
-<translation id="1188858454923323853">komplementer</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Memberikan Suara untuk Chrome</translation>
-<translation id="1229276918471378188">Lompatan sebelumnya</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Judul tingkat 6 berikutnya</translation>
-<translation id="1275718070701477396">Dipilih</translation>
-<translation id="1319608975892113573">Tidak ada blockquote sebelumnya.</translation>
-<translation id="1321576897702511272">Menyembunyikan bantuan ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> dari <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">pengulangan karakter dan kata</translation>
-<translation id="1339428534620983148">Kolom tabel sebelumnya</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Kanan</translation>
-<translation id="136718599399906424">Baris tabel berikutnya</translation>
-<translation id="1383876407941801731">Telusuri</translation>
-<translation id="1385214448885562192">Tekan enter untuk menerima atau escape untuk membatalkan, panah ke bawah untuk selanjutnya dan panah ke atas untuk sebelumnya.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, kotak teks sandi</translation>
-<translation id="1467432559032391204">Kiri</translation>
-<translation id="1474557363159888097">Tidak ada jangkar sebelumnya.</translation>
-<translation id="1502086903961450562">Grafik sebelumnya</translation>
-<translation id="1506187449813838456">Meningkatkan tinggi nada</translation>
-<translation id="151784044608172266">Kalimat Berikutnya</translation>
-<translation id="1524531499102321782">Baris Braille selanjutnya</translation>
-<translation id="1546370775711804143">Bilah gulir</translation>
-<translation id="1559739829547075274">Menavigasi mundur</translation>
-<translation id="1571643229714746283">ChromeVox siap</translation>
-<translation id="158493514907962286">Desember</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Beralih ke braille 6 titik</translation>
-<translation id="1611168825862729585">Judul kolom:</translation>
-<translation id="1613476421962910979">Earcons aktif</translation>
-<translation id="1618597272655350600">Mengumumkan deskripsi lengkap dari posisi saat ini</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{lebih dari}other{# tanda lebih dari}}</translation>
-<translation id="1653266918374749391">Judul tingkat 3 sebelumnya</translation>
-<translation id="1659072772017912254">Tidak dicentang</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">Navigasi ChromeVox</translation>
-<translation id="16777221443363124">Bilah menu</translation>
-<translation id="1692077714702418899">baris struktural</translation>
-<translation id="1700517974991662022">Dikunjungi</translation>
-<translation id="1722567105086139392">Tautan</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Grafik berikutnya</translation>
-<translation id="1781173782405573156">Tombol pengabaian</translation>
-<translation id="1787176709638001873">Sandi edit teks</translation>
-<translation id="1810107444790159527">Kotak daftar</translation>
-<translation id="1828385960365606039">Mei</translation>
-<translation id="1834891354138622109">Kolom</translation>
-<translation id="1865601187525349519">Akhir teks</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Mengucapkan waktu dan tanggal saat ini.</translation>
-<translation id="1902396333223336119">Sel</translation>
-<translation id="1905379170753160525">Tampilkan daftar judul</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Kontrol pekan dalam tahun</translation>
-<translation id="1964135212174907577">Objek Berikutnya</translation>
-<translation id="1969092762068865084">Juli</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Judul baris:</translation>
-<translation id="2002895034995108595">Setel ulang peta tombol saat ini</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{kurung siku buka}other{# kurung siku buka}}</translation>
-<translation id="2045490512405922022">tidak dicentang</translation>
-<translation id="20601713649439366">Tidak ada persamaan matematika sebelumnya.</translation>
-<translation id="207477615537953741">Semantik tidak aktif</translation>
-<translation id="2086961585857038472">Kata Berikutnya</translation>
-<translation id="2089387485033699258">id</translation>
-<translation id="2091933974477985526">Area teks yang dapat diedit sebelumnya</translation>
-<translation id="2100350898815792233">Semua tanda baca</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">access key:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Mengubah tabel braille 6 titik saat ini dengan memilih opsi dari daftar berikut.</translation>
-<translation id="2169714232367507776">Klik pada item ini</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{kurung tutup}other{# kurung tutup}}</translation>
-<translation id="2199994615414171367">Matematika sebelumnya</translation>
-<translation id="2223693656926968778">Mengambil tindakan pada item ini</translation>
-<translation id="225732394367814946">Meningkatkan laju ucapan</translation>
-<translation id="2267945578749931355">Karakter Berikutnya</translation>
-<translation id="2281234842553884450">Penggeser sebelumnya</translation>
-<translation id="2318372665160196757">Utama</translation>
-<translation id="2329324941084714723">Panel tab</translation>
-<translation id="2344193891939537199">Kontrol tanggal dan waktu</translation>
-<translation id="2359897517538099099">Tidak dalam mode tabel.</translation>
-<translation id="241124561063364910">diikuti dengan</translation>
-<translation id="2417569100218200841">Info konten</translation>
-<translation id="2422937916923936891">Kotak centang item menu</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> sekarang adalah pengubah ChromeVox yang baru.</translation>
-<translation id="2450814015951372393">Kotak centang</translation>
-<translation id="2462626033734746142">Grup tombol radio</translation>
-<translation id="2471138580042810658">Judul 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{tanda bintang}other{# tanda bintang}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> telah disetel ulang.</translation>
-<translation id="2553108862507765288">kesalahan tata bahasa</translation>
-<translation id="257674075312929031">Grup</translation>
-<translation id="2582407057977008361">Pinggir</translation>
-<translation id="2589102159832527089">Laman ini berisi teks yang diekstrak secara otomatis dari file PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Klik di sini untuk aslinya.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">dengan {COUNT,plural, =1{# item}other{# item}}</translation>
-<translation id="2614981083756825552">Tata Letak Math ML</translation>
-<translation id="2626530649491650971">dapat diklik</translation>
-<translation id="2628764385451019380">Tidak ada kotak kombo sebelumnya.</translation>
-<translation id="2637227747952042642">Matematika</translation>
-<translation id="2639750663247012216">Pengubah ChromeVox</translation>
-<translation id="2644542693584024604">salah eja</translation>
-<translation id="2667291555398229137">Klik item di bawah tombol perutean</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{kurung buka}other{# kurung buka}}</translation>
-<translation id="2705875883745373140">Tidak ditekan</translation>
-<translation id="2706462751667573066">Atas</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Dicentang</translation>
-<translation id="27527859628328957">Melompat ke item yang dapat difokuskan berikutnya</translation>
-<translation id="2770781857296573485">Masukkan penjelajahan grup</translation>
-<translation id="2777845298774924149">Keluar</translation>
-<translation id="2800204403141299078">Tidak ada elemen berbeda lainnya.</translation>
-<translation id="2800780099804980316">Tidak ada judul tingkat 1 sebelumnya.</translation>
-<translation id="2811204574343810641">Baris</translation>
-<translation id="2816654101880605877">Tidak ada penggeser berikutnya.</translation>
-<translation id="2841013758207633010">Waktu</translation>
-<translation id="2843837985843789981">Grup Sebelumnya</translation>
-<translation id="2844995807198708617">Menu Konteks</translation>
-<translation id="2849332794118375855">Tidak ada kotak centang berikutnya.</translation>
-<translation id="2864481629947106776">Tautan sebelumnya</translation>
-<translation id="2873259058405069099">Berpindah ke awal tabel</translation>
-<translation id="2894654529758326923">Informasi</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{kurung kurawal buka}other{# kurung kurawal buka}}</translation>
-<translation id="2911433807131383493">Membuka tutorial ChromeVox</translation>
-<translation id="2932083475399492303">Jenis baris pengalih antara struktural atau tata letak</translation>
-<translation id="2964026537669811554">Grup judul</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tab}other{# tab}}</translation>
-<translation id="2972078295414139404">Tidak ada tautan yang dikunjungi sebelumnya.</translation>
-<translation id="2972205263822847197">Kiat alat</translation>
-<translation id="2998131015536248178">Karakter Sebelumnya</translation>
-<translation id="2999559350546931576">Menurunkan tinggi nada</translation>
-<translation id="2999945368667127852">Tidak ada widget media berikutnya.</translation>
-<translation id="3012414509011670858">Tidak ada bagian sebelumnya.</translation>
-<translation id="3030432017085518523">Tombol radio item menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}other{# apostrof}}</translation>
-<translation id="3046838483509668188">Opsi ChromeVox</translation>
-<translation id="3047143736589213134">Peta tombol eksperimental</translation>
-<translation id="3060756054951570867">menu <ph name="TITLE" /> dibuka</translation>
-<translation id="3078345202707391975">Judul tingkat 2 berikutnya</translation>
-<translation id="3078740164268491126">tabel</translation>
-<translation id="3082557070674409251">Diklik</translation>
-<translation id="3084806535845658316">tanpa pengulangan pengetikan</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Tidak ada persamaan matematika berikutnya.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Bangunan terkenal berikutnya</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Diciutkan</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Menampilkan daftar bangunan terkenal</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Baris Berikutnya</translation>
-<translation id="3155083529632865074">Tidak ada tombol sebelumnya.</translation>
-<translation id="3163593631834463955">Judul kolom kosong</translation>
-<translation id="316542773973815724">Navigasi</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{spasi}other{# spasi}}</translation>
-<translation id="320961988183078793">memasukkan <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, tab</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Tautan yang dikunjungi</translation>
-<translation id="323731244387692321">Membuka bantuan keyboard ChromeVox</translation>
-<translation id="3241052487511142956">Tautan yang dikunjungi sebelumnya</translation>
-<translation id="3286390186030710347">Penggeser</translation>
-<translation id="3299925995433437805">Tidak ada tautan yang dikunjungi selanjutnya.</translation>
-<translation id="3303384412438961941">Tekan tombol apa saja untuk mengetahui namanya. Ctrl+W akan menutup penjelajah keyboard.</translation>
-<translation id="3307886118343381874">Berpindah ke akhir tabel</translation>
-<translation id="3311969765485641742">Tekan Alt+Shift+A untuk memeriksa lansiran</translation>
-<translation id="3312997241656799641">Tautan yang dikunjungi selanjutnya</translation>
-<translation id="3321460131042519426">Aktifkan pelipatan kata</translation>
-<translation id="3322936298410871309">Judul tingkat 1 sebelumnya</translation>
-<translation id="3323447499041942178">Kotak teks</translation>
-<translation id="3353420241558113817">{"ar": "Arab",
- "bg": "Bulgaria",
- "ca": "Katala",
- "cs": "Cheska",
- "da": "Dansk",
- "de": "Jerman",
- "de_CH": "Jerman (Swiss)",
- "de_DE": "Jerman (Jerman)",
- "el": "Yunani",
- "en": "Inggris",
- "en_CA": "Inggris (Kanada)",
- "en_GB": "Inggris (Inggris Raya)",
- "en_US": "Inggris (Amerika Serikat)",
- "es": "Spanyol",
- "et": "Esti",
- "fr": "Prancis",
- "fr_CA": "Prancis (Kanada)",
- "fr_FR": "Prancis (Prancis)",
- "fi": "Suomi",
- "he": "Ibrani",
- "hi": "Hindi",
- "hr": "Kroat",
- "hu": "Magyar",
- "is": "Islan",
- "it": "Italia",
- "ko": "Korea",
- "lt": "Lituavi",
- "lv": "Latvi",
- "nb": "Norsk",
- "nl": "Belanda",
- "pl": "Polski",
- "pt": "Portugis",
- "ro": "Rumania",
- "ru": "Rusia",
- "sk": "Slovak",
- "sl": "Sloven",
- "sr": "Serb",
- "sv": "Swensk",
- "tr": "Turki",
- "vi": "Vietnam",
- "zh": "China",
- "zh_TW": "China (Han Tradisional)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{tambah}other{# tanda tambah}}</translation>
-<translation id="338583716107319301">Pemisah</translation>
-<translation id="3389259863310851658">Bidang formulir sebelumnya</translation>
-<translation id="3390225400784126843">Elemen berbeda berikutnya.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, item menu</translation>
-<translation id="3406283310380167331">Menampilkan daftar formulir</translation>
-<translation id="3422338090358345848">Membuka penjelajah keyboard</translation>
-<translation id="3457000393508828486">Ditekan sebagian</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, tombol</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> hingga <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{kurung siku tutup}other{# kurung siku tutup}}</translation>
-<translation id="3493915602752813531">Tidak ada jangkar berikutnya.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{tanda tanya}other{# tanda tanya}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{tanda caret}other{# tanda caret}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, kotak centang tidak dicentang</translation>
-<translation id="3599054940393788245">Tidak di dalam matematika</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{petik satu}other{# petik satu}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolar}other{# tanda dolar}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, kotak daftar</translation>
-<translation id="3687295507293856493">Menerka di judul kolom sel saat ini</translation>
-<translation id="3692274950075847560">P:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Ucapan Pengontrol</translation>
-<translation id="3716845769494773620">Multi-baris</translation>
-<translation id="3731746171184829332">Tidak ada judul sebelumnya.</translation>
-<translation id="3762198587642264450">Berpindah ke akhir baris saat ini</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Keluar dari dialog.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Pelengkapan otomatis daftar</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Media berikutnya</translation>
-<translation id="3819376190738087562">Tidak ada lompatan.</translation>
-<translation id="385383972552776628">Membuka laman opsi</translation>
-<translation id="3856075812838139784">Hanya baca</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Judul tingkat 6 sebelumnya</translation>
-<translation id="3914173277599553213">Diperlukan</translation>
-<translation id="3962990492275676168">Mulai membaca dari lokasi saat ini</translation>
-<translation id="4004802134384979325">dicentang</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Kontrol bulan</translation>
-<translation id="4039983576244166038">Judul baris kosong</translation>
-<translation id="4042843249978639960">Tidak ada judul tingkat 2 berikutnya.</translation>
-<translation id="4043348641337972076">Tidak ada bangunan terkenal ARIA sebelumnya.</translation>
-<translation id="4047216625641135770">Tanda</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}other{# tanda tilde}}</translation>
-<translation id="409334809956508737">Objek Sebelumnya</translation>
-<translation id="4099274309791143834">dengan submenu</translation>
-<translation id="4107807507418787238">Tidak ada sel di bawah.</translation>
-<translation id="4116415223832267137">Lansiran</translation>
-<translation id="4147126331795725888">Tidak ada kontrol berikutnya.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{kurung kurawal tutup}other{# kurung kurawal tutup}}</translation>
-<translation id="4158704014418536539">Peka huruf besar/kecil.</translation>
-<translation id="4161663686871496107">Masukan lisan ChromeVox siap</translation>
-<translation id="4173994908659439270">Tidak ada bidang teks yang dapat diedit berikutnya.</translation>
-<translation id="4176463684765177261">Dinonaktifkan</translation>
-<translation id="4188530942454211480">Kalimat Sebelumnya</translation>
-<translation id="4202186506458631436">Pindah ke kanan</translation>
-<translation id="4206289001967551965">Di dalam tabel</translation>
-<translation id="4215733775853809057">Penggeser berikutnya</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{tanda hubung}other{# tanda hubung}}</translation>
-<translation id="421884353938374759">pemilih warna</translation>
-<translation id="4229646983878045487">tanggal dan waktu</translation>
-<translation id="423334822609210999">Tidak ada sel di kiri.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, Tingkat <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Catatan</translation>
-<translation id="4254798249533888099">Tree</translation>
-<translation id="4255943572433203166">Gunakan opsi di bawah untuk menyesuaikan ChromeVox. Perubahan segera diterapkan.</translation>
-<translation id="4271220233568730077">Matematika berikutnya</translation>
-<translation id="4271521365602459209">Tidak ada hasil lainnya.</translation>
-<translation id="4287520460805643128">Tidak ada artikel berikutnya.</translation>
-<translation id="4289540628985791613">Ikhtisar</translation>
-<translation id="4300318234632215983">Mengumumkan URL di belakang tautan</translation>
-<translation id="4301352596632316575">memiliki submenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{titik}=3{tiga titik}other{# titik}}</translation>
-<translation id="4347461890115250064">Tidak ada daftar berikutnya.</translation>
-<translation id="4367650418938037324">Daun Math ML</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Hentikan ucapan</translation>
-<translation id="4373197658375206385">Tidak ada item sebelumnya yang bukan tautan.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">setel ulang</translation>
-<translation id="4471074325120394300">Tidak ada tautan.</translation>
-<translation id="4476183483923481720">baris baru</translation>
-<translation id="4482330759234983253">Tabel sebelumnya</translation>
-<translation id="4491109536499578614">Gambar</translation>
-<translation id="4529987814483543472">Peta tombol klasik</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{garis miring}other{# garis miring}}</translation>
-<translation id="4547556996012970016">Judul tingkat 5 berikutnya</translation>
-<translation id="4562381607973973258">Header</translation>
-<translation id="4591507479202817876">, dipilih</translation>
-<translation id="4597532268155981612">formulir</translation>
-<translation id="4597896406374528575">April</translation>
-<translation id="4615592953348396470">Mengabaikan penekanan tombol berikutnya</translation>
-<translation id="461613135510474570">Kalimat</translation>
-<translation id="4647836961514597010">Pemilih warna</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Bangunan terkenal sebelumnya</translation>
-<translation id="4696413482802371445">Tidak ada judul tingkat 5 berikutnya.</translation>
-<translation id="4729095194763193578">Baris tabel sebelumnya</translation>
-<translation id="4736221692378411923">Agustus</translation>
-<translation id="4740661827607246557">Perintah Bantuan</translation>
-<translation id="4759716709594980008">Penjelajah Keyboard ChromeOS</translation>
-<translation id="4763296182459741068">Terbungkus ke bawah</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Mengumumkan judul dari laman saat ini</translation>
-<translation id="4826415162591436065">Navigasi ke depan</translation>
-<translation id="4826604887384865800">Lompatan berikutnya</translation>
-<translation id="4827410568042294688">tidak dipilih</translation>
-<translation id="4842108708071771135">Tidak ada blockquote berikutnya.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Elemen sama sebelumnya.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Aktifkan penyimpanan log TTS</translation>
-<translation id="4877261390094455813">Masukkan kueri penelusuran.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Tautan internal</translation>
-<translation id="4953585991029886728">Edit teks</translation>
-<translation id="4954534434583049121">Blockquote sebelumnya</translation>
-<translation id="4973717656530883744">Min <ph name="X" /></translation>
-<translation id="4973762002207131920">Dialihkan ke <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milidetik</translation>
-<translation id="49787999531187221">ChromeVox tidak aktif.</translation>
-<translation id="4979404613699303341">Tombol sebelumnya</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, kotak daftar</translation>
-<translation id="4983588134362688868">Menuju ke bagian atas laman</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, jendela</translation>
-<translation id="4993152509206108683">Tingkat kecepatan <ph name="PERCENT" /> persen</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, tombol radio dipilih</translation>
-<translation id="4997475792277222884">Tidak ada item berikutnya yang bukan tautan.</translation>
-<translation id="5000760171916499057">Tidak ada formulir.</translation>
-<translation id="5005670136041063723">Tidak ada elemen serupa lainnya.</translation>
-<translation id="501473567976723023">Januari</translation>
-<translation id="5041394372352067729">Pindahkan layar braille ke bagian atas laman</translation>
-<translation id="5042770794184672516">Meningkatkan volume ucapan</translation>
-<translation id="5050015258024679800">Judul tingkat 4 sebelumnya</translation>
-<translation id="5054047268577924192">Item daftar sebelumnya</translation>
-<translation id="5078661581131202757">Pilihan file</translation>
-<translation id="5080758118274074384">diklik dua kali</translation>
-<translation id="5098541983634824365">Meninggalkan kisi.</translation>
-<translation id="5102981729317424850">Bilah alat</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Tidak ada bidang formulir sebelumnya.</translation>
-<translation id="5111640677200759579">Judul kolom</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Tidak ada tautan sebelumnya.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, tidak dipilih</translation>
-<translation id="5183440668879371625">Baris Braille sebelumnya</translation>
-<translation id="5184944171021383281">Tidak ada bidang formulir berikutnya.</translation>
-<translation id="5189244881767082992">Baris</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> telah ditetapkan untuk suatu perintah.</translation>
-<translation id="5205493599117157272">Daftar <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Tidak ada tombol radio berikutnya.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Berakhir</translation>
-<translation id="5291783959063340370">Objek</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, tab</translation>
-<translation id="5310788376443009632">dihapus:</translation>
-<translation id="5320727453979144100">Mode lekat diaktifkan</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{koma}other{# koma}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, kotak teks</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, tautan</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Lompat ke belakang selama proses membaca berlangsung</translation>
-<translation id="5368000168321181111">Earcons tidak aktif</translation>
-<translation id="5374320867641260420">Tidak ada tombol berikutnya.</translation>
-<translation id="5382299583965267720">Tidak ada judul tingkat 1 berikutnya.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{titik koma}other{# titik koma}}</translation>
-<translation id="5411891038905756502">Tidak ada titik lompatan sebelumnya.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{kurang dari}other{# tanda kurang dari}}</translation>
-<translation id="5455441614648621694">Komplementer</translation>
-<translation id="5485036206801896268">Tidak ada grafik sebelumnya.</translation>
-<translation id="5486947920110100234">Tidak ada titik lompatan berikutnya.</translation>
-<translation id="549602578321198708">Kata</translation>
-<translation id="5500932716852106146">Tidak ada bidang teks yang dapat diedit sebelumnya.</translation>
-<translation id="5502713021410870035">September</translation>
-<translation id="5507663321906818013">Melakukan debug pada tolok ukur</translation>
-<translation id="5518443085409638729">Tempatkan kursor di antara karakter saat mengedit teks (seperti Mac OS X).</translation>
-<translation id="552195134157544755">Tombol radio</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Tidak ada judul tingkat 5 sebelumnya.</translation>
-<translation id="556042886152191864">Tombol</translation>
-<translation id="5561345396546889625">Daftar berikutnya</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Mengedit teks, entri email</translation>
-<translation id="5597170376237141345">Kotak centang berikutnya</translation>
-<translation id="5597933780944041114">Tidak ada judul berikutnya.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, tombol radio tidak dipilih</translation>
-<translation id="5601172225407283979">Melakukan tindakan default</translation>
-<translation id="5608798115546226984">Pelengkapan otomatis sebaris</translation>
-<translation id="561939826962581046">waktu</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Log</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Tidak ada tabel sebelumnya.</translation>
-<translation id="5655682562155942719">Perintah Lompat</translation>
-<translation id="56637627897541303">Area teks</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Bangunan terkenal</translation>
-<translation id="5683155931978483559">Kotak centang sebelumnya</translation>
-<translation id="5684277895745049190">Daftar</translation>
-<translation id="5700650669149824506">Tidak ada judul tingkat 4 sebelumnya.</translation>
-<translation id="5709192780268610569">Tidak ada deskripsi panjang</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Kolom tabel berikutnya</translation>
-<translation id="571866080859340309">Menjelajahi grup</translation>
-<translation id="5728409797179002635">Tidak ditemukan tabel.</translation>
-<translation id="5748623122140342504">Judul tingkat 5 sebelumnya</translation>
-<translation id="5750633686117194034">Tidak ada pengubah yang ditekan; tekan dan tahan satu atau beberapa pengubah; angkat jari Anda setelah selesai dan akan terdengar tombol disetel. Ketuk untuk keluar.</translation>
-<translation id="5788275253279308023">jendela penyamaran tab <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Tingkatkan situs tertentu (misalnya Google Penelusuran).</translation>
-<translation id="5819072574982403430">Item pohon</translation>
-<translation id="5826479389509458994">baris <ph name="ROW" /> kolom <ph name="COL" /></translation>
-<translation id="5850707923114094062">Geser ke belakang</translation>
-<translation id="5851548754964597211">Daftar tab</translation>
-<translation id="5859752971144398932">Keluar dari cari di laman.</translation>
-<translation id="5866042630553435010">Dicentang sebagian</translation>
-<translation id="5869546221129391014">Kisi</translation>
-<translation id="5876817486144482042">Mengurangi volume ucapan</translation>
-<translation id="5887397643266327462">Teks braille diaktifkan.</translation>
-<translation id="5891934789323004067">Tabel</translation>
-<translation id="5919442531159595654">salin.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{sama dengan}other{# tanda sama dengan}}</translation>
-<translation id="5939518447894949180">Setel ulang</translation>
-<translation id="5948123859135882163">Beralih interpretasi persamaan matematika antara struktur dan semantik</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialog</translation>
-<translation id="5963413905009737549">Bagian</translation>
-<translation id="5968607524793740041">Tampilkan menu konteks</translation>
-<translation id="5983179082906765664">Meningkatkan granularitas navigasi</translation>
-<translation id="5999630716831179808">Suara</translation>
-<translation id="6000417740266304866">Mengubah tabel braille 8 titik saat ini dengan memilih opsi dari daftar berikut.</translation>
-<translation id="6006050241733874051">Formulir</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{garis miring terbalik}other{# garis miring terbalik}}</translation>
-<translation id="6037602951055904232">Geser ke depan</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Akhir dari sel.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Spasi</translation>
-<translation id="6142308968191113180">Judul 4</translation>
-<translation id="6169420925157477918">Gambar dengan deskripsi panjang</translation>
-<translation id="6172087735260766220">Tidak dapat mengakses teks yang dapat diakses, dari PDF yang tidak dapat disalin.</translation>
-<translation id="6186305613600865047">Melompat ke bagian bawah laman</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Bawah</translation>
-<translation id="6236061028292614533">Judul berikutnya</translation>
-<translation id="6254901459154107917">Area teks yang dapat diedit berikutnya</translation>
-<translation id="6259464875943891919">Keluar <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Elemen sama berikutnya.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Tidak ada kotak kombo berikutnya.</translation>
-<translation id="6307969636681130414">Ditekan</translation>
-<translation id="6324551002951139333">Kesalahan tata bahasa terdeteksi</translation>
-<translation id="6348657800373377022">Kotak kombo</translation>
-<translation id="6355910664415701303">Tidak ada item daftar sebelumnya.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Judul sebelumnya</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Tidak ada tombol radio sebelumnya.</translation>
-<translation id="6414968628640960377">Elemen berbeda sebelumnya.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{titik dua}other{# titik dua}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Dialog lansiran</translation>
-<translation id="6459511626086141404">Peta tombol datar</translation>
-<translation id="6468049171101508116">Tombol berikutnya</translation>
-<translation id="6491972999578897419">Ubah suara yang sekarang dengan memilih opsi dari daftar di bawah.</translation>
-<translation id="6508059270146105198">Pindahkan layar braille ke bagian bawah laman</translation>
-<translation id="6536864053412760904">Token Math ML</translation>
-<translation id="6550720799683018100">Ubah peta tombol saat ini dengan memilih opsi dari daftar di bawah.</translation>
-<translation id="6561818612645211875">Berpindah ke awal baris saat ini</translation>
-<translation id="6587021927234520429">Tidak ada judul tingkat 4 berikutnya.</translation>
-<translation id="6601344353291556895">Aktifkan deskripsi panjang.</translation>
-<translation id="6615602925644411249">Cari di laman.</translation>
-<translation id="6633350132811819843">Tidak ada tabel berikutnya.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Bilah kemajuan</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Dokumen</translation>
-<translation id="6697092096875747123">Kotak kombo sebelumnya</translation>
-<translation id="6714813999819678458">Judul tingkat 2 sebelumnya</translation>
-<translation id="6716505898850596801">Tombol pengubah</translation>
-<translation id="671916444866103745">Tidak ada bangunan terkenal ARIA berikutnya.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, kotak kombo</translation>
-<translation id="6735257939857578167">dengan <ph name="NUM" /> item</translation>
-<translation id="6736510033526053669">tab dibuat</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artikel</translation>
-<translation id="6787839852456839824">Pintasan keyboard</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Footer</translation>
-<translation id="6871161210040114857">Mengabaikan huruf besar/kecil.</translation>
-<translation id="6877435256196695200">Tidak ada grafik berikutnya.</translation>
-<translation id="6897341342232909480">Pindah ke kiri</translation>
-<translation id="6901540140423170855">tanggal</translation>
-<translation id="6910211073230771657">Dihapus</translation>
-<translation id="6911965441508464308">Tidak ada sel di atas.</translation>
-<translation id="6919104639734799681">Menampilkan daftar tabel</translation>
-<translation id="6964088412282673743">Tidak ada kontrol sebelumnya.</translation>
-<translation id="6996566555547746822">Kotak kombo berikutnya</translation>
-<translation id="7005146664810010831">Tidak ditemukan URL</translation>
-<translation id="7010712454773919705">Tombol pengubah ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Daftar sebelumnya</translation>
-<translation id="7041173719775863268">Akhiri pilihan</translation>
-<translation id="7095834689119144465">Edit teks numerik saja</translation>
-<translation id="7096001299300236431">Media sebelumnya</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">pengulangan kata</translation>
-<translation id="713824876195128146">Blockquote berikutnya</translation>
-<translation id="7161771961008409533">Tombol munculan</translation>
-<translation id="7167657087543110">pengulangan karakter</translation>
-<translation id="7170733337935166589">Lompat ke depan selama proses membaca berlangsung</translation>
-<translation id="7181697990050180700">Sesuaikan pintasan keyboard untuk perintah yang sering digunakan dengan mengetikkannya ke dalam bidang yang sesuai di bawah.</translation>
-<translation id="7203150201908454328">Diperluas</translation>
-<translation id="7210211103303402262">menit</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">baris</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Judul</translation>
-<translation id="7241683698754534149">Membuka deskripsi panjang di tab baru</translation>
-<translation id="7248671827512403053">Aplikasi</translation>
-<translation id="725969808843520477">Tombol radio berikutnya</translation>
-<translation id="7269119382257320590">Tanpa tanda baca</translation>
-<translation id="7273174640290488576">Kosong</translation>
-<translation id="7285387653379749618">Tabel</translation>
-<translation id="7289186959554153431">Judul 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Teks braille dinonaktifkan.</translation>
-<translation id="7318872822751139669">Gunakan mouse untuk mengubah fokus.</translation>
-<translation id="7322388933135261569">Februari</translation>
-<translation id="7332592614823088566">Baris <ph name="ROWINDEX" /> dari <ph name="ROWTOTAL" />, Kolom <ph name="COLINDEX" /> dari <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">memiliki munculan</translation>
-<translation id="7356165926712028380">Beralih ke braille 8 titik</translation>
-<translation id="7362871137496673139">Tidak ada judul tingkat 2 sebelumnya.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{tanda dan}other{# tanda dan}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Meninggalkan tabel.</translation>
-<translation id="739763518212184081">Baris Sebelumnya</translation>
-<translation id="7400575256015741911">Kesalahan ejaan terdeteksi</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">kembali</translation>
-<translation id="7434509671034404296">Pengembang</translation>
-<translation id="7439060726180460871">Direktori</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Telah memasukkan dialog</translation>
-<translation id="7532613204005497612">Juni</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, penggeser</translation>
-<translation id="7586163296341959563">tempel.</translation>
-<translation id="7596919493010894443">pilihan yang dihapus</translation>
-<translation id="7604026522577407655">Berpindah ke awal kolom saat ini</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Mengumumkan URL laman saat ini</translation>
-<translation id="7609363189280667021">Beralih teks braille</translation>
-<translation id="762020119231868829">Menjeda semua widget media yang sedang diputar</translation>
-<translation id="7625690649919402823">Tabel berikutnya</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Kelas <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Tidak ada judul tingkat 3 sebelumnya.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, kotak teks</translation>
-<translation id="7663318257180412551">Judul 2</translation>
-<translation id="7674576868851035240">Tautan berikutnya</translation>
-<translation id="7674768236845044097">tanda</translation>
-<translation id="7684431668231950609">Mengedit teks, entri URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Tombol radio sebelumnya</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, kotak teks sandi</translation>
-<translation id="7805247615045262757">navigasi default</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Grup Berikutnya</translation>
-<translation id="7819187121850078213">jendela tab <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Oktober</translation>
-<translation id="7839679365527550018">Kata Sebelumnya</translation>
-<translation id="7851816175263618915">Beberapa tanda baca</translation>
-<translation id="7870596830398826354">Pohon Math ML</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Beralih ke ChromeVox klasik.</translation>
-<translation id="7895896691902835279">Tautan tidak dikenal</translation>
-<translation id="7927711904086083099">Tidak dipilih</translation>
-<translation id="7935627501098484003">Kontrol waktu</translation>
-<translation id="7939428177581522200">ditambahkan ke pilihan</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{et}other{# tanda et}}</translation>
-<translation id="7965147473449754028">menu ditutup</translation>
-<translation id="7974390230414479278">Item menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{tanda seru}other{# tanda seru}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{tanda kutip}other{# tanda kutip}}</translation>
-<translation id="8033827949643255796">dipilih</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">Mengedit teks, entri penelusuran</translation>
-<translation id="8049189770492311300">Pewaktu</translation>
-<translation id="8065607967589909823">Pemilihannya adalah</translation>
-<translation id="8066678206530322333">Spanduk</translation>
-<translation id="8110647606445335195">Tidak ada bangunan terkenal ARIA.</translation>
-<translation id="8153880621934657047">Tidak ada di dalam tabel.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{garis bawah}other{# garis bawah}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">potong.</translation>
-<translation id="8199231515320852133">Mengumumkan judul sel saat ini</translation>
-<translation id="820417203470636242">Sel kosong.</translation>
-<translation id="8215202828671303819">Multi-pilihan</translation>
-<translation id="8276439074553447000">Melompat ke item yang dapat difokuskan sebelumnya</translation>
-<translation id="8278417001922463147">Tidak ada artikel sebelumnya.</translation>
-<translation id="8283603667300770666">Bidang formulir berikutnya</translation>
-<translation id="831207808878314375">Definisi</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">jam</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{tanda pagar}other{# tanda pagar}}</translation>
-<translation id="8374154622594089836">bulan</translation>
-<translation id="8378855320830505539">Kawasan</translation>
-<translation id="8382679411218029383">Pelengkapan otomatis sebaris dan daftar</translation>
-<translation id="8428603554127842284">tingkat <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Tidak ada judul tingkat 3 berikutnya.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Tidak ada kotak centang sebelumnya.</translation>
-<translation id="8455868257606149352">Maks <ph name="X" /></translation>
-<translation id="84575901236241018">memiliki tombol akses, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Menurunkan granularitas navigasi</translation>
-<translation id="8520472399088452386">Tombol putar</translation>
-<translation id="8538744478902126321">Menerka di judul baris sel saat ini</translation>
-<translation id="8540054775867439484">Terbungkus ke atas</translation>
-<translation id="8548973727659841685">Karakter</translation>
-<translation id="8561322612995434619">memiliki munculan</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Item daftar berikutnya</translation>
-<translation id="860150890330522909">kotak centang <ph name="NAME" /> dicentang</translation>
-<translation id="8606621670302093223">Kontrol tanggal</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> item yang dipilih</translation>
-<translation id="8638532244051952400">Mengumumkan koordinat sel saat ini</translation>
-<translation id="8650576015643545550">Tidak ada daftar sebelumnya.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Menampilkan daftar tautan</translation>
-<translation id="8664519043722036194">detik</translation>
-<translation id="867187640362843212">Judul 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{pipa}other{# pipa vertikal}}</translation>
-<translation id="8735450637152821465">Mulai pilihan</translation>
-<translation id="8743786158317878347">memasuki konten terstruktur, misalnya tabel</translation>
-<translation id="8747966237988593539">Daftar Berurutan</translation>
-<translation id="8759334257841767240">Tidak ada tautan berikutnya.</translation>
-<translation id="8767968232364267681">Judul tingkat 4 berikutnya</translation>
-<translation id="8770473310765924354">keluar dari konten terstruktur, misalnya tabel</translation>
-<translation id="8791025954632646584">Semantik aktif</translation>
-<translation id="8796411681063377102">Judul tingkat 3 berikutnya</translation>
-<translation id="8808582214901541005">Maret</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Tekan ke atas atau ke bawah untuk meninjau perintah, tekan enter untuk mengaktifkan</translation>
-<translation id="8864099967139188018">Tidak ada judul tingkat 6 berikutnya.</translation>
-<translation id="8882002077197914455">Judul baris</translation>
-<translation id="8896347895970027998">Beralih ke ChromeVox aktif atau tidak aktif.</translation>
-<translation id="8898516272131543774">Siklus pengulangan tanda baca</translation>
-<translation id="8900148057318340779">Tombol awalan</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Judul kosong</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Tombol Pengubah</translation>
-<translation id="8943175951035496220">Tidak ada sel di kanan.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Tidak ada tabel.</translation>
-<translation id="9040132695316389094">Judul 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Beralih ke widget penelusuran</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">dihapus dari pilihan</translation>
-<translation id="9082874451376019682">Tidak ada penggeser sebelumnya.</translation>
-<translation id="9089864840575085222">Siklus pengulangan pengetikan</translation>
-<translation id="9107530006868467849">Tidak ada widget media sebelumnya.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{persen}other{# tanda persen}}</translation>
-<translation id="9115913704608474258">November</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Mengumumkan deskripsi singkat dari posisi saat ini</translation>
-<translation id="9153606228985488238">Tinggi nada <ph name="PERCENT" /> persen</translation>
-<translation id="9160096769946561184">Berpindah ke akhir kolom saat ini</translation>
-<translation id="9173115498289768110">Volume <ph name="PERCENT" /> persen</translation>
-<translation id="9178973770513562274">Gunakan tombol panah atas dan bawah untuk menjelajahi, atau ketik untuk menelusuri.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">Tidak ada bagian berikutnya.</translation>
-<translation id="930275611743429116">Mulai atau akhiri pemilihan.</translation>
-<translation id="948171205378458592">Mengurangi laju ucapan</translation>
-<translation id="962913030769097253">Judul tingkat 1 berikutnya</translation>
-<translation id="973955474346881951">Mengaktifkan/Menonaktifkan mode lekat</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_it.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_it.xtb
deleted file mode 100644
index 0aa02de2fa6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_it.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="it">
-<translation id="1012173283529841972">Voce elenco</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Con spanning.</translation>
-<translation id="1025074108959230262">Modalità persistente disattivata</translation>
-<translation id="1031961866430398710">poi</translation>
-<translation id="1044777062731150180">Nessuna intestazione</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Dati non validi</translation>
-<translation id="1082209053475788238">Nessuna intestazione livello 6 precedente.</translation>
-<translation id="1088219014394087294">Nessuna intestazione.</translation>
-<translation id="1106741348836243114">Attiva o disattiva feedback audio (icone audio).</translation>
-<translation id="1120743664840974483">{"a": "alfa", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "x-ray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Raccolta <ph name="TAG" /> con <ph name="NUM" /> elementi</translation>
-<translation id="1155043339247954670">Nessuna voce elenco successiva.</translation>
-<translation id="1157782847298808853">Guida tastiera</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, casella combinata</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, voce di menu, con sottomenu</translation>
-<translation id="1177863135347784049">Personalizzati</translation>
-<translation id="1188858454923323853">elementi complementari</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - dare voce a Chrome</translation>
-<translation id="1229276918471378188">Collegamento precedente</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Intestazione livello 6 successiva</translation>
-<translation id="1275718070701477396">Selezionato</translation>
-<translation id="1319608975892113573">Nessuna citazione lunga precedente.</translation>
-<translation id="1321576897702511272">Nascondi guida di ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> di <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">eco caratteri e parole</translation>
-<translation id="1339428534620983148">Colonna tabella precedente</translation>
-<translation id="1342835525016946179">articolo</translation>
-<translation id="1346748346194534595">Destra</translation>
-<translation id="136718599399906424">Riga tabella successiva</translation>
-<translation id="1383876407941801731">Cerca</translation>
-<translation id="1385214448885562192">Premi Invio per accettare o Esc per annullare, freccia Giù per passare al prossimo e freccia Su per passare al precedente.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, casella di testo della password</translation>
-<translation id="1467432559032391204">Sinistra</translation>
-<translation id="1474557363159888097">Nessun ancoraggio precedente.</translation>
-<translation id="1502086903961450562">Immagine precedente</translation>
-<translation id="1506187449813838456">Aumenta tono</translation>
-<translation id="151784044608172266">Frase successiva</translation>
-<translation id="1524531499102321782">Braille riga successiva</translation>
-<translation id="1546370775711804143">Barra di scorrimento</translation>
-<translation id="1559739829547075274">Spostati indietro</translation>
-<translation id="1571643229714746283">ChromeVox pronto</translation>
-<translation id="158493514907962286">Dicembre</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Passa a braille a sei punti</translation>
-<translation id="1611168825862729585">Intestazione di colonna:</translation>
-<translation id="1613476421962910979">Icone audio attivate</translation>
-<translation id="1618597272655350600">Fornisce una descrizione completa della posizione corrente</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{simbolo di maggiore}other{# simboli di maggiore}}</translation>
-<translation id="1653266918374749391">Intestazione livello 3 precedente</translation>
-<translation id="1659072772017912254">Non selezionato</translation>
-<translation id="1669290819662866522">settimana</translation>
-<translation id="1674262202423278359">Navigazione in ChromeVox</translation>
-<translation id="16777221443363124">Barra dei menu</translation>
-<translation id="1692077714702418899">linea strutturale</translation>
-<translation id="1700517974991662022">Visitato</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Immagine successiva</translation>
-<translation id="1781173782405573156">Tasto pass through</translation>
-<translation id="1787176709638001873">Testo di modifica della password</translation>
-<translation id="1810107444790159527">Casella di riepilogo</translation>
-<translation id="1828385960365606039">Maggio</translation>
-<translation id="1834891354138622109">Colonna</translation>
-<translation id="1865601187525349519">Fine del testo</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Leggi data e ora correnti.</translation>
-<translation id="1902396333223336119">Cella</translation>
-<translation id="1905379170753160525">Mostra elenco intestazioni</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Controllo settimana dell'anno</translation>
-<translation id="1964135212174907577">Oggetto successivo</translation>
-<translation id="1969092762068865084">Luglio</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Intestazione di riga:</translation>
-<translation id="2002895034995108595">Reimposta mappa di chiavi corrente</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{parentesi quadra di apertura}other{# parentesi quadre di apertura}}</translation>
-<translation id="2045490512405922022">non selezionata</translation>
-<translation id="20601713649439366">Nessuna espressione matematica precedente.</translation>
-<translation id="207477615537953741">Semantica disattivata</translation>
-<translation id="2086961585857038472">Parola successiva</translation>
-<translation id="2089387485033699258">it</translation>
-<translation id="2091933974477985526">Area di testo modificabile precedente</translation>
-<translation id="2100350898815792233">Tutta la punteggiatura</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">tasto di accesso:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Cambia la tavoletta braille a sei punti corrente selezionando un'opzione dall'elenco sotto.</translation>
-<translation id="2169714232367507776">Clic sulla voce corrente</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{parentesi tonda di chiusura}other{# parentesi tonde di chiusura}}</translation>
-<translation id="2199994615414171367">Espressione matematica precedente</translation>
-<translation id="2223693656926968778">Agisci su voce corrente</translation>
-<translation id="225732394367814946">Aumenta velocità comandi vocali</translation>
-<translation id="2267945578749931355">Carattere successivo</translation>
-<translation id="2281234842553884450">Dispositivo di scorrimento precedente</translation>
-<translation id="2318372665160196757">Principale</translation>
-<translation id="2329324941084714723">Riquadro a schede</translation>
-<translation id="2344193891939537199">Controllo data/ora</translation>
-<translation id="2359897517538099099">La modalità tabella non è attiva.</translation>
-<translation id="241124561063364910">seguito da</translation>
-<translation id="2417569100218200841">Informazioni sui contenuti</translation>
-<translation id="2422937916923936891">Casella di controllo voce di menu</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">Il tasto <ph name="KEY" /> è ora il nuovo tasto di modifica di ChromeVox.</translation>
-<translation id="2450814015951372393">Casella di controllo</translation>
-<translation id="2462626033734746142">Gruppo pulsanti di opzione</translation>
-<translation id="2471138580042810658">Intestazione 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisco}other{# asterischi}}</translation>
-<translation id="2549392850788122959">Il tasto <ph name="KEY" /> è stato reimpostato.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Gruppo</translation>
-<translation id="2582407057977008361">Di lato</translation>
-<translation id="2589102159832527089">Questa pagina contiene il testo estratto automaticamente dal file PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Fai clic qui per visualizzare l'originale.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">con {COUNT,plural, =1{# voce}other{# voci}}</translation>
-<translation id="2614981083756825552">Layout MathML</translation>
-<translation id="2626530649491650971">selezionabile</translation>
-<translation id="2628764385451019380">Nessuna casella combinata precedente.</translation>
-<translation id="2637227747952042642">Elemento matematico</translation>
-<translation id="2639750663247012216">Tasto di modifica di ChromeVox</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">Fai clic sull'elemento sotto una chiave di routing</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{parentesi tonda di apertura}other{# parentesi tonde di apertura}}</translation>
-<translation id="2705875883745373140">Non premuto</translation>
-<translation id="2706462751667573066">Su</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Selezionato</translation>
-<translation id="27527859628328957">Passa a elemento attivabile successivo</translation>
-<translation id="2770781857296573485">Attiva l'esplorazione dei gruppi</translation>
-<translation id="2777845298774924149">Uscita</translation>
-<translation id="2800204403141299078">Nessun altro elemento diverso.</translation>
-<translation id="2800780099804980316">Nessuna intestazione livello 1 precedente.</translation>
-<translation id="2811204574343810641">Riga</translation>
-<translation id="2816654101880605877">Nessun dispositivo di scorrimento successivo.</translation>
-<translation id="2841013758207633010">Ora</translation>
-<translation id="2843837985843789981">Gruppo precedente</translation>
-<translation id="2844995807198708617">Menu contestuale</translation>
-<translation id="2849332794118375855">Nessun casella di controllo successiva.</translation>
-<translation id="2864481629947106776">Link precedente</translation>
-<translation id="2873259058405069099">Vai all'inizio della tabella</translation>
-<translation id="2894654529758326923">Informazioni</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{parentesi graffa di apertura}other{# parentesi graffe di apertura}}</translation>
-<translation id="2911433807131383493">Apri il tutorial di ChromeVox</translation>
-<translation id="2932083475399492303">Alterna tipo di linea strutturale o di layout</translation>
-<translation id="2964026537669811554">Gruppo di intestazioni</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{carattere di tabulazione}other{# caratteri di tabulazione}}</translation>
-<translation id="2972078295414139404">Nessun link visitato precedente.</translation>
-<translation id="2972205263822847197">Descrizione comando</translation>
-<translation id="2998131015536248178">Carattere precedente</translation>
-<translation id="2999559350546931576">Abbassa tono</translation>
-<translation id="2999945368667127852">Nessun widget multimediale successivo.</translation>
-<translation id="3012414509011670858">Nessuna sezione precedente.</translation>
-<translation id="3030432017085518523">Pulsante di opzione voce di menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrofo}other{# apostrofi}}</translation>
-<translation id="3046838483509668188">Opzioni ChromeVox</translation>
-<translation id="3047143736589213134">Mappa di chiavi sperimentale</translation>
-<translation id="3060756054951570867">Menu <ph name="TITLE" /> aperto</translation>
-<translation id="3078345202707391975">Intestazione livello 2 successiva</translation>
-<translation id="3078740164268491126">tabella</translation>
-<translation id="3082557070674409251">Selezionato</translation>
-<translation id="3084806535845658316">eco digitazione non impostata</translation>
-<translation id="3086746722712840547">nota</translation>
-<translation id="308895241372589742">Nessuna espressione matematica successiva.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Punto di riferimento successivo</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Compresso</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Mostra elenco punti di riferimento</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Riga successiva</translation>
-<translation id="3155083529632865074">Nessun pulsante precedente.</translation>
-<translation id="3163593631834463955">Intestazione di colonna vuota</translation>
-<translation id="316542773973815724">Navigazione</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{spazio}other{# spazi}}</translation>
-<translation id="320961988183078793">Elemento <ph name="TYPE" /> inserito</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, scheda</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Link visitato</translation>
-<translation id="323731244387692321">Apri la guida della tastiera di ChromeVox</translation>
-<translation id="3241052487511142956">Link visitato precedente</translation>
-<translation id="3286390186030710347">Dispositivo di scorrimento</translation>
-<translation id="3299925995433437805">Nessun link visitato successivo.</translation>
-<translation id="3303384412438961941">Premi un tasto qualsiasi per conoscerne il nome. Premi Ctrl+W per chiudere esplorazione tastiera.</translation>
-<translation id="3307886118343381874">Vai alla fine della tabella</translation>
-<translation id="3311969765485641742">Premi Alt+Maiusc+A per esaminare gli avvisi</translation>
-<translation id="3312997241656799641">Link visitato successivo</translation>
-<translation id="3321460131042519426">Attiva ritorno a capo automatico</translation>
-<translation id="3322936298410871309">Intestazione livello 1 precedente</translation>
-<translation id="3323447499041942178">Casella di testo</translation>
-<translation id="3353420241558113817">{"ar": "Arabo",
- "bg": "Bulgaro",
- "ca": "Catalano",
- "cs": "Ceco",
- "da": "Danese",
- "de": "Tedesco",
- "de_CH": "Tedesco (Svizzera)",
- "de_DE": "Tedesco (Germania)",
- "el": "Greco",
- "en": "Inglese",
- "en_CA": "Inglese (Canada)",
- "en_GB": "Inglese (Regno Unito)",
- "en_US": "Inglese (Stati Uniti)",
- "es": "Spagnolo",
- "et": "Estone",
- "fr": "Francese",
- "fr_CA": "Francese (Canada)",
- "fr_FR": "Francese (Francia)",
- "fi": "Finlandese",
- "he": "Ebraico",
- "hi": "Hindi",
- "hr": "Croato",
- "hu": "Ungherese",
- "is": "Islandese",
- "it": "Italiano",
- "ko": "Coreano",
- "lt": "Lituano",
- "lv": "Lettone",
- "nb": "Norvegese Bokmål",
- "nl": "Olandese",
- "pl": "Polacco",
- "pt": "Portoghese",
- "ro": "Rumeno",
- "ru": "Russo",
- "sk": "Slovacco",
- "sl": "Sloveno",
- "sr": "Serbo",
- "sv": "Svedese",
- "tr": "Turco",
- "vi": "Vietnamita",
- "zh": "Cinese",
- "zh_TW": "Cinese (Han tradizionale)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{più}other{# segni più}}</translation>
-<translation id="338583716107319301">Separatore</translation>
-<translation id="3389259863310851658">Campo modulo precedente</translation>
-<translation id="3390225400784126843">Elemento diverso successivo.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, voce di menu</translation>
-<translation id="3406283310380167331">Mostra elenco moduli</translation>
-<translation id="3422338090358345848">Apri esplorazione tastiera</translation>
-<translation id="3457000393508828486">Parzialmente premuto</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, pulsante</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> sel</translation>
-<translation id="3486232535569802404">Da <ph name="V1" /> a <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{parentesi quadra di chiusura}other{# parentesi quadre di chiusura}}</translation>
-<translation id="3493915602752813531">Nessun ancoraggio successivo.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{punto interrogativo}other{# punti interrogativi}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{accento circonflesso}other{# accenti circonflessi}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, casella di controllo non selezionata</translation>
-<translation id="3599054940393788245">Non incluso nella categoria "matematica"</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{apice inverso}other{# apici inversi}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollaro}other{# simboli dollaro}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, casella di riepilogo</translation>
-<translation id="3687295507293856493">Fai un'ipotesi per l'intestazione di colonna della cella corrente</translation>
-<translation id="3692274950075847560">R:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Controllo vocale</translation>
-<translation id="3716845769494773620">Multiriga</translation>
-<translation id="3731746171184829332">Nessuna intestazione precedente.</translation>
-<translation id="3762198587642264450">Vai alla fine della riga corrente</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Finestra di dialogo chiusa.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Elenco di completamento automatico</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Elemento multimediale successivo</translation>
-<translation id="3819376190738087562">Nessun passaggio.</translation>
-<translation id="385383972552776628">Apri pagina di opzioni</translation>
-<translation id="3856075812838139784">Sola lettura</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Intestazione livello 6 precedente</translation>
-<translation id="3914173277599553213">Obbligatorie</translation>
-<translation id="3962990492275676168">Inizia a leggere dalla posizione corrente</translation>
-<translation id="4004802134384979325">selezionata</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Controllo mese</translation>
-<translation id="4039983576244166038">Intestazione di riga vuota</translation>
-<translation id="4042843249978639960">Nessuna intestazione livello 2 successiva.</translation>
-<translation id="4043348641337972076">Nessun landmark ARIA precedente.</translation>
-<translation id="4047216625641135770">Contrassegno</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}other{# caratteri tilde}}</translation>
-<translation id="409334809956508737">Oggetto precedente</translation>
-<translation id="4099274309791143834">con sottomenu</translation>
-<translation id="4107807507418787238">Nessuna cella sotto.</translation>
-<translation id="4116415223832267137">Avviso</translation>
-<translation id="4147126331795725888">Nessun controllo successivo.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{parentesi graffa di chiusura}other{# parentesi graffe di chiusura}}</translation>
-<translation id="4158704014418536539">Distinzione tra maiuscole e minuscole.</translation>
-<translation id="4161663686871496107">La lettura vocale di ChromeVox è pronta</translation>
-<translation id="4173994908659439270">Nessun campo di testo modificabile successivo.</translation>
-<translation id="4176463684765177261">Disabilitato</translation>
-<translation id="4188530942454211480">Frase precedente</translation>
-<translation id="4202186506458631436">Sposta a destra</translation>
-<translation id="4206289001967551965">Sei all'interno della tabella</translation>
-<translation id="4215733775853809057">Dispositivo di scorrimento successivo</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{trattino}other{# trattini}}</translation>
-<translation id="421884353938374759">selettore colori</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">Nessuna cella a sinistra.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, grado <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Nota</translation>
-<translation id="4254798249533888099">Albero</translation>
-<translation id="4255943572433203166">Utilizza le opzioni sotto per personalizzare ChromeVox. Le modifiche hanno effetto immediato.</translation>
-<translation id="4271220233568730077">Espressione matematica successiva</translation>
-<translation id="4271521365602459209">Nessun altro risultato.</translation>
-<translation id="4287520460805643128">Nessun articolo successivo.</translation>
-<translation id="4289540628985791613">Panoramica</translation>
-<translation id="4300318234632215983">Pronuncia l'URL di un link</translation>
-<translation id="4301352596632316575">con un sottomenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punto}=3{puntini di sospensione}other{# punti}}</translation>
-<translation id="4347461890115250064">Nessun elenco successivo.</translation>
-<translation id="4367650418938037324">Foglia MathML</translation>
-<translation id="4372435075475052704">minimo: <ph name="X" /></translation>
-<translation id="4372705107434148843">Interrompi i comandi vocali</translation>
-<translation id="4373197658375206385">Nessun elemento precedente che non sia un link.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Nessun link.</translation>
-<translation id="4476183483923481720">nuova riga</translation>
-<translation id="4482330759234983253">Tabella precedente</translation>
-<translation id="4491109536499578614">Immagine</translation>
-<translation id="4529987814483543472">Mappa di chiavi classica</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{barra}other{# barre}}</translation>
-<translation id="4547556996012970016">Intestazione livello 5 successiva</translation>
-<translation id="4562381607973973258">Intestazione</translation>
-<translation id="4591507479202817876">, selezionato</translation>
-<translation id="4597532268155981612">modulo</translation>
-<translation id="4597896406374528575">Aprile</translation>
-<translation id="4615592953348396470">La prossima pressione di tasti verrà ignorata</translation>
-<translation id="461613135510474570">Frase</translation>
-<translation id="4647836961514597010">Selettore colori</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Punto di riferimento precedente</translation>
-<translation id="4696413482802371445">Nessuna intestazione livello 5 successiva.</translation>
-<translation id="4729095194763193578">Riga tabella precedente</translation>
-<translation id="4736221692378411923">Agosto</translation>
-<translation id="4740661827607246557">Comandi della Guida</translation>
-<translation id="4759716709594980008">Esplorazione tastiera Chrome OS</translation>
-<translation id="4763296182459741068">Ricomincia dalla fine</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">ricerca</translation>
-<translation id="481165870889056555">Pronuncia il titolo della pagina corrente</translation>
-<translation id="4826415162591436065">Spostati avanti</translation>
-<translation id="4826604887384865800">Collegamento successivo</translation>
-<translation id="4827410568042294688">non selezionato</translation>
-<translation id="4842108708071771135">Nessuna citazione lunga successiva.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Elemento simile precedente.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Attiva la registrazione TTS</translation>
-<translation id="4877261390094455813">Inserisci una query di ricerca.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Link interno</translation>
-<translation id="4953585991029886728">Modifica testo</translation>
-<translation id="4954534434583049121">Citazione lunga precedente</translation>
-<translation id="4973717656530883744">Minimo <ph name="X" /></translation>
-<translation id="4973762002207131920">Sei passato a <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">millisecondi</translation>
-<translation id="49787999531187221">ChromeVox non è attivo.</translation>
-<translation id="4979404613699303341">Pulsante precedente</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, casella di riepilogo</translation>
-<translation id="4983588134362688868">Vai all'inizio della pagina</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, finestra</translation>
-<translation id="4993152509206108683">Velocità: <ph name="PERCENT" />%</translation>
-<translation id="4996716799442435517">Visivo</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, pulsante di opzione selezionato</translation>
-<translation id="4997475792277222884">Nessun elemento successivo che non sia un link.</translation>
-<translation id="5000760171916499057">Nessun modulo.</translation>
-<translation id="5005670136041063723">Nessun altro elemento simile.</translation>
-<translation id="501473567976723023">Gennaio</translation>
-<translation id="5041394372352067729">Sposta display braille a inizio pagina</translation>
-<translation id="5042770794184672516">Aumenta volume comandi vocali</translation>
-<translation id="5050015258024679800">Intestazione livello 4 precedente</translation>
-<translation id="5054047268577924192">Voce elenco precedente</translation>
-<translation id="5078661581131202757">Selezione file</translation>
-<translation id="5080758118274074384">Selezionato con doppio clic</translation>
-<translation id="5098541983634824365">Stai uscendo dalla griglia.</translation>
-<translation id="5102981729317424850">Barra degli strumenti</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Nessun campo modulo precedente.</translation>
-<translation id="5111640677200759579">Intestazione di colonna</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Nessun link precedente.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, non selezionato</translation>
-<translation id="5183440668879371625">Braille riga precedente</translation>
-<translation id="5184944171021383281">Nessun campo modulo successivo.</translation>
-<translation id="5189244881767082992">Riga</translation>
-<translation id="5203930734796605961">Il tasto <ph name="KEY" /> è già assegnato a un comando.</translation>
-<translation id="5205493599117157272">Elenco <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Nessun pulsante di opzione successivo.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Fine</translation>
-<translation id="5291783959063340370">Oggetto</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, scheda</translation>
-<translation id="5310788376443009632">rimossa:</translation>
-<translation id="5320727453979144100">Modalità persistente attiva</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{virgola}other{# virgole}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, casella di testo</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Vai indietro durante la lettura continua</translation>
-<translation id="5368000168321181111">Icone audio disattivate</translation>
-<translation id="5374320867641260420">Nessun pulsante successivo.</translation>
-<translation id="5382299583965267720">Nessuna intestazione livello 1 successiva.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{punto e virgola}other{# punti e virgola}}</translation>
-<translation id="5411891038905756502">Nessun passaggio precedente.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{simbolo di minore}other{# simboli di minore}}</translation>
-<translation id="5455441614648621694">Complementare</translation>
-<translation id="5485036206801896268">Nessuna immagine precedente.</translation>
-<translation id="5486947920110100234">Nessun passaggio successivo.</translation>
-<translation id="549602578321198708">Parola</translation>
-<translation id="5500932716852106146">Nessun campo di testo modificabile precedente.</translation>
-<translation id="5502713021410870035">Settembre</translation>
-<translation id="5507663321906818013">Debug benchmark</translation>
-<translation id="5518443085409638729">Posiziona il cursore tra i caratteri durante la modifica di testo (come in Mac OS X).</translation>
-<translation id="552195134157544755">Pulsante di opzione</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Nessuna intestazione livello 5 precedente.</translation>
-<translation id="556042886152191864">Pulsante</translation>
-<translation id="5561345396546889625">Elenco successivo</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Modifica testo, email</translation>
-<translation id="5597170376237141345">Casella di controllo successiva</translation>
-<translation id="5597933780944041114">Nessuna intestazione successiva.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, pulsante di opzione non selezionato</translation>
-<translation id="5601172225407283979">Esegui azione predefinita</translation>
-<translation id="5608798115546226984">Completamento automatico incorporato</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Log</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Nessuna tabella precedente.</translation>
-<translation id="5655682562155942719">Comandi di spostamento</translation>
-<translation id="56637627897541303">Area di testo</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Punto di riferimento</translation>
-<translation id="5683155931978483559">Casella di controllo precedente</translation>
-<translation id="5684277895745049190">Elenco</translation>
-<translation id="5700650669149824506">Nessuna intestazione livello 4 precedente.</translation>
-<translation id="5709192780268610569">Nessuna descrizione lunga</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Colonna tabella successiva</translation>
-<translation id="571866080859340309">Esplorazione gruppi</translation>
-<translation id="5728409797179002635">Nessuna tabella trovata.</translation>
-<translation id="5748623122140342504">Intestazione livello 5 precedente</translation>
-<translation id="5750633686117194034">Nessun tasto di modifica premuto; premi e tieni premuti uno o più tasti di modifica; solleva le dita una volta terminata l'operazione e verranno pronunciati i tasti impostati. Premi Tab per uscire.</translation>
-<translation id="5788275253279308023">scheda <ph name="TITLE" /> della finestra di navigazione in incognito</translation>
-<translation id="5806206155699461681">Ottimizza siti specifici (ad esempio Ricerca Google).</translation>
-<translation id="5819072574982403430">Elemento albero</translation>
-<translation id="5826479389509458994">riga <ph name="ROW" /> colonna <ph name="COL" /></translation>
-<translation id="5850707923114094062">Panoramica in avanti</translation>
-<translation id="5851548754964597211">Elenco schede</translation>
-<translation id="5859752971144398932">Uscito da Trova nella pagina.</translation>
-<translation id="5866042630553435010">Parzialmente selezionato</translation>
-<translation id="5869546221129391014">Griglia</translation>
-<translation id="5876817486144482042">Abbassa volume comandi vocali</translation>
-<translation id="5887397643266327462">Sottotitoli braille attivati.</translation>
-<translation id="5891934789323004067">Tabella</translation>
-<translation id="5919442531159595654">copia.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{uguale}other{# segni di uguale}}</translation>
-<translation id="5939518447894949180">Ripristina</translation>
-<translation id="5948123859135882163">Passa dall'interpretazione strutturale a quella semantica delle espressioni matematiche</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Finestra di dialogo</translation>
-<translation id="5963413905009737549">Sezione</translation>
-<translation id="5968607524793740041">Mostra il menu contestuale</translation>
-<translation id="5983179082906765664">Aumenta livello di dettaglio navigazione</translation>
-<translation id="5999630716831179808">Voci</translation>
-<translation id="6000417740266304866">Cambia la tavoletta braille a otto punti corrente selezionando un'opzione dall'elenco sotto.</translation>
-<translation id="6006050241733874051">Modulo</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{barra rovesciata}other{# barre rovesciate}}</translation>
-<translation id="6037602951055904232">Panoramica avanti</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Fine della cella.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Spazio</translation>
-<translation id="6142308968191113180">Intestazione 4</translation>
-<translation id="6169420925157477918">Immagine con descrizione lunga</translation>
-<translation id="6172087735260766220">Impossibile visualizzare il testo accessibile del PDF protetto dalla copia.</translation>
-<translation id="6186305613600865047">Vai alla fine della pagina</translation>
-<translation id="6193330012414963395">AM/PM</translation>
-<translation id="622484624075952240">Giù</translation>
-<translation id="6236061028292614533">Intestazione successiva</translation>
-<translation id="6254901459154107917">Area di testo modificabile successiva</translation>
-<translation id="6259464875943891919">Uscito da <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Elemento simile successivo.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Nessuna casella combinata successiva.</translation>
-<translation id="6307969636681130414">Premuto</translation>
-<translation id="6324551002951139333">Errore grammaticale rilevato</translation>
-<translation id="6348657800373377022">Casella combinata</translation>
-<translation id="6355910664415701303">Nessuna voce elenco precedente.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Intestazione precedente</translation>
-<translation id="6387719785439924554">di lato</translation>
-<translation id="6411426777058107714">Nessun pulsante di opzione precedente.</translation>
-<translation id="6414968628640960377">Elemento diverso precedente.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{due punti}other{# segni di due punti}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Finestra di avviso</translation>
-<translation id="6459511626086141404">Mappa di chiavi di tipo "flat"</translation>
-<translation id="6468049171101508116">Pulsante Avanti</translation>
-<translation id="6491972999578897419">Modifica la voce corrente scegliendo una delle opzioni riportate di seguito.</translation>
-<translation id="6508059270146105198">Sposta display braille in fondo alla pagina</translation>
-<translation id="6536864053412760904">Token MathML</translation>
-<translation id="6550720799683018100">Modifica la voce mappa di chiavi corrente scegliendo una delle opzioni riportate di seguito.</translation>
-<translation id="6561818612645211875">Vai all'inizio della riga corrente</translation>
-<translation id="6587021927234520429">Nessuna intestazione livello 4 successiva.</translation>
-<translation id="6601344353291556895">Attiva descrizioni dettagliate.</translation>
-<translation id="6615602925644411249">Trova nella pagina.</translation>
-<translation id="6633350132811819843">Nessuna tabella successiva.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Barra di avanzamento</translation>
-<translation id="6659594942844771486">TAB</translation>
-<translation id="667999046851023355">Documento</translation>
-<translation id="6697092096875747123">Casella combinata precedente</translation>
-<translation id="6714813999819678458">Intestazione livello 2 precedente</translation>
-<translation id="6716505898850596801">Tasti di modifica</translation>
-<translation id="671916444866103745">Nessun landmark ARIA successivo.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, casella combinata</translation>
-<translation id="6735257939857578167">con <ph name="NUM" /> voci</translation>
-<translation id="6736510033526053669">scheda creata</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Articolo</translation>
-<translation id="6787839852456839824">Scorciatoie da tastiera</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Piè di pagina</translation>
-<translation id="6871161210040114857">Le maiuscole/minuscole vengono ignorate.</translation>
-<translation id="6877435256196695200">Nessuna immagine successiva.</translation>
-<translation id="6897341342232909480">Sposta a sinistra</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Eliminato</translation>
-<translation id="6911965441508464308">Nessuna cella sopra.</translation>
-<translation id="6919104639734799681">Mostra elenco tabelle</translation>
-<translation id="6964088412282673743">Nessun controllo precedente.</translation>
-<translation id="6996566555547746822">Casella combinata successiva</translation>
-<translation id="7005146664810010831">Nessun URL trovato</translation>
-<translation id="7010712454773919705">Tasto di modifica di ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Elenco precedente</translation>
-<translation id="7041173719775863268">Termina selezione</translation>
-<translation id="7095834689119144465">Modifica solo caratteri numerici e di testo</translation>
-<translation id="7096001299300236431">Elemento multimediale precedente</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">eco parole</translation>
-<translation id="713824876195128146">Citazione lunga successiva</translation>
-<translation id="7161771961008409533">Pulsante popup</translation>
-<translation id="7167657087543110">eco caratteri</translation>
-<translation id="7170733337935166589">Vai avanti durante la lettura continua</translation>
-<translation id="7181697990050180700">Personalizza le scorciatoie da tastiera per i comandi che utilizzi spesso digitandole nei campi corrispondenti riportati di seguito.</translation>
-<translation id="7203150201908454328">Espanso</translation>
-<translation id="7210211103303402262">minuti</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">riga</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Intestazione</translation>
-<translation id="7241683698754534149">Apri descrizione lunga in una nuova scheda</translation>
-<translation id="7248671827512403053">Applicazione</translation>
-<translation id="725969808843520477">Pulsante di opzione successivo</translation>
-<translation id="7269119382257320590">Nessuna punteggiatura</translation>
-<translation id="7273174640290488576">Vuota</translation>
-<translation id="7285387653379749618">Tabelle</translation>
-<translation id="7289186959554153431">Intestazione 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Sottotitoli braille disattivati.</translation>
-<translation id="7318872822751139669">Utilizza il mouse per cambiare l'elemento attivo.</translation>
-<translation id="7322388933135261569">Febbraio</translation>
-<translation id="7332592614823088566">Riga <ph name="ROWINDEX" /> di <ph name="ROWTOTAL" />, colonna <ph name="COLINDEX" /> di <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">con popup</translation>
-<translation id="7356165926712028380">Passa a braille a otto punti</translation>
-<translation id="7362871137496673139">Nessuna intestazione livello 2 precedente.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{e commerciale}other{# simboli di e commerciale}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Stai uscendo dalla tabella.</translation>
-<translation id="739763518212184081">Riga precedente</translation>
-<translation id="7400575256015741911">Errore di ortografia rilevato</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">ritorno a capo</translation>
-<translation id="7434509671034404296">Opzioni per sviluppatori</translation>
-<translation id="7439060726180460871">Directory</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">Tab</translation>
-<translation id="7492049978501397201">Finestra di dialogo compilata</translation>
-<translation id="7532613204005497612">Giugno</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, dispositivo di scorrimento</translation>
-<translation id="7586163296341959563">incolla.</translation>
-<translation id="7596919493010894443">selezione cancellata</translation>
-<translation id="7604026522577407655">Vai all'inizio della colonna corrente</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Pronuncia l'URL della pagina corrente</translation>
-<translation id="7609363189280667021">Attiva/disattiva sottotitoli braille</translation>
-<translation id="762020119231868829">Mette in pausa tutti i widget multimediali che sono in riproduzione</translation>
-<translation id="7625690649919402823">Tabella successiva</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), grado <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Nessuna intestazione livello 3 precedente.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, casella di testo</translation>
-<translation id="7663318257180412551">Intestazione 2</translation>
-<translation id="7674576868851035240">Link successivo</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">Modifica testo, URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Pulsante di opzione precedente</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, casella di testo della password</translation>
-<translation id="7805247615045262757">navigazione predefinita</translation>
-<translation id="7805768142964895445">Stato</translation>
-<translation id="7810781339813764006">Gruppo successivo</translation>
-<translation id="7819187121850078213">scheda <ph name="TITLE" /> finestra</translation>
-<translation id="7828956995407538686">Ottobre</translation>
-<translation id="7839679365527550018">Parola precedente</translation>
-<translation id="7851816175263618915">Alcuni caratteri di punteggiatura</translation>
-<translation id="7870596830398826354">Albero MathML</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Attiva/disattiva la modalità classica di ChromeVox.</translation>
-<translation id="7895896691902835279">Link sconosciuto</translation>
-<translation id="7927711904086083099">Non selezionato</translation>
-<translation id="7935627501098484003">Controllo di data/ora</translation>
-<translation id="7939428177581522200">aggiunti alla selezione</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{chiocciola}other{# simboli chiocciola}}</translation>
-<translation id="7965147473449754028">menu chiuso</translation>
-<translation id="7974390230414479278">Voce di menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{punto esclamativo}other{# punti esclamativi}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{virgolette}other{# segni di virgolette}}</translation>
-<translation id="8033827949643255796">selezionati</translation>
-<translation id="8035962149453661158">massimo: <ph name="X" /></translation>
-<translation id="8042761080832772327">Modifica testo, ricerca</translation>
-<translation id="8049189770492311300">Timer</translation>
-<translation id="8065607967589909823">La selezione è</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Nessun landmark ARIA.</translation>
-<translation id="8153880621934657047">Non sei all'interno della tabella.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{carattere di sottolineatura}other{# caratteri di sottolineatura}}</translation>
-<translation id="8179976553408161302">Invio</translation>
-<translation id="81960742267269908">taglia.</translation>
-<translation id="8199231515320852133">Pronuncia le intestazioni della cella corrente</translation>
-<translation id="820417203470636242">Cella vuota.</translation>
-<translation id="8215202828671303819">Selezione multipla</translation>
-<translation id="8276439074553447000">Passa a elemento attivabile precedente</translation>
-<translation id="8278417001922463147">Nessun articolo precedente.</translation>
-<translation id="8283603667300770666">Campo modulo successivo</translation>
-<translation id="831207808878314375">Definizione</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">ore</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{cancelletto}other{# simboli cancelletto}}</translation>
-<translation id="8374154622594089836">mese</translation>
-<translation id="8378855320830505539">Regione</translation>
-<translation id="8382679411218029383">Completamento automatico incorporato ed elenco</translation>
-<translation id="8428603554127842284">livello <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Nessuna intestazione livello 3 successiva.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Nessuna casella di controllo precedente.</translation>
-<translation id="8455868257606149352">Massimo: <ph name="X" /></translation>
-<translation id="84575901236241018">dispone di tasto di accesso, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Riduci livello di dettaglio navigazione</translation>
-<translation id="8520472399088452386">Pulsante di selezione</translation>
-<translation id="8538744478902126321">Fai un'ipotesi per l'intestazione di riga della cella corrente</translation>
-<translation id="8540054775867439484">Ricomincia dall'inizio</translation>
-<translation id="8548973727659841685">Carattere</translation>
-<translation id="8561322612995434619">con popup</translation>
-<translation id="8571096049907249734">sel mult</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Voce elenco successiva</translation>
-<translation id="860150890330522909">Casella di controllo <ph name="NAME" /> selezionata</translation>
-<translation id="8606621670302093223">Controllo data</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> elementi selezionati</translation>
-<translation id="8638532244051952400">Vengono comunicate le coordinate della cella corrente</translation>
-<translation id="8650576015643545550">Nessun elenco precedente.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Mostra elenco link</translation>
-<translation id="8664519043722036194">secondi</translation>
-<translation id="867187640362843212">Intestazione 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{barra verticale}other{# barre verticali}}</translation>
-<translation id="8735450637152821465">Inizia selezione</translation>
-<translation id="8743786158317878347">entra in contenuti strutturati, come tabelle</translation>
-<translation id="8747966237988593539">Elenco ordinato</translation>
-<translation id="8759334257841767240">Nessun link successivo.</translation>
-<translation id="8767968232364267681">Intestazione livello 4 successiva</translation>
-<translation id="8770473310765924354">esci da contenuti strutturati, come tabelle</translation>
-<translation id="8791025954632646584">Semantica attivata</translation>
-<translation id="8796411681063377102">Intestazione livello 3 successiva</translation>
-<translation id="8808582214901541005">Marzo</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Premi su o giù per rivedere i comandi; premi Invio per attivarli</translation>
-<translation id="8864099967139188018">Nessuna intestazione livello 6 successiva.</translation>
-<translation id="8882002077197914455">Intestazione riga</translation>
-<translation id="8896347895970027998">Attiva/disattiva ChromeVox.</translation>
-<translation id="8898516272131543774">Imposta eco punteggiatura a rotazione</translation>
-<translation id="8900148057318340779">Tasto prefisso</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Intestazioni vuote</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Tasti di modifica</translation>
-<translation id="8943175951035496220">Nessuna cella a destra.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Nessuna tabella.</translation>
-<translation id="9040132695316389094">Intestazione 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Attiva/disattiva widget di ricerca</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">rimossi dalla selezione</translation>
-<translation id="9082874451376019682">Nessun dispositivo di scorrimento precedente.</translation>
-<translation id="9089864840575085222">Imposta eco digitazione a rotazione</translation>
-<translation id="9107530006868467849">Nessun widget multimediale precedente.</translation>
-<translation id="9108370397979208512">elemento matematico</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{percentuale}other{# simboli percentuale}}</translation>
-<translation id="9115913704608474258">Novembre</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Fornisce una breve descrizione della posizione corrente</translation>
-<translation id="9153606228985488238">Tono: <ph name="PERCENT" />%</translation>
-<translation id="9160096769946561184">Vai alla fine della colonna corrente</translation>
-<translation id="9173115498289768110">Volume: <ph name="PERCENT" />%</translation>
-<translation id="9178973770513562274">Utilizza i tasti freccia su e giù per sfogliare, oppure digita per cercare.</translation>
-<translation id="9192904702577636854">Testo scorrevole</translation>
-<translation id="9212322457209634662">Nessuna sezione successiva.</translation>
-<translation id="930275611743429116">Inizia o termina la selezione.</translation>
-<translation id="948171205378458592">Diminuisci velocità comandi vocali</translation>
-<translation id="962913030769097253">Intestazione livello 1 successiva</translation>
-<translation id="973955474346881951">Attiva/disattiva modalità persistente</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb
deleted file mode 100644
index ce6aea63363..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="iw">
-<translation id="1012173283529841972">פריט רשימה</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">מורחב.</translation>
-<translation id="1025074108959230262">מצב אתר דביק מושבת</translation>
-<translation id="1031961866430398710">לאחר מכן</translation>
-<translation id="1044777062731150180">ללא כותרות</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">קלט לא חוקי</translation>
-<translation id="1082209053475788238">אין כותרת קודמת של רמה 6.</translation>
-<translation id="1088219014394087294">אין כותרות.</translation>
-<translation id="1106741348836243114">‏הפעל או השבת משוב צלילים (Earcons).</translation>
-<translation id="1120743664840974483">{"א": "אלף", "ב": "בועז", "ג": "גימל", "ד": "דוד", "ה": "הגר", "ו": "וו", "ז": "זאב", "ח": "חוה", "ט": "טיח", "י": "יונה","כ": "כרמל", "ל": "לאה", "מ": "משה", "נ": "נשר", "ס": "סמך","ע": "עין", "פ": "פסל", "צ": "ציפור", "ק": "קורח", "ר": "רות", "ש": "שמיר", "ת": "תלם"}</translation>
-<translation id="113582498867142724">אוסף <ph name="TAG" /> עם <ph name="NUM" /> פריטים</translation>
-<translation id="1155043339247954670">אין עוד פריט ברשימה.</translation>
-<translation id="1157782847298808853">עזרה למקלדת</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, תיבה משולבת</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, פריט תפריט, עם תפריט משנה</translation>
-<translation id="1177863135347784049">מותאם אישית</translation>
-<translation id="1188858454923323853">משלים</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">‏ChromeVox - מתן קול ל-Chrome</translation>
-<translation id="1229276918471378188">הדילוג הקודם</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">הכותרת הבאה של רמה 6</translation>
-<translation id="1275718070701477396">נבחר</translation>
-<translation id="1319608975892113573">‏אין blockquote קודם.</translation>
-<translation id="1321576897702511272">‏הסתר עזרה של ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> מתוך <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">הד תו ומילה</translation>
-<translation id="1339428534620983148">העמודה הקודמת בטבלה</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">ימינה</translation>
-<translation id="136718599399906424">השורה הבאה בטבלה</translation>
-<translation id="1383876407941801731">חפש</translation>
-<translation id="1385214448885562192">‏הקש על Enter כדי לאשר או על Escape כדי לבטל, למטה כדי לעבור לתוצאה הבאה ולמעלה כדי לעבור לתוצאה הקודמת.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, תיבת טקסט של סיסמה</translation>
-<translation id="1467432559032391204">שמאלה</translation>
-<translation id="1474557363159888097">אין עוגן קודם.</translation>
-<translation id="1502086903961450562">הגרפיקה הקודמת</translation>
-<translation id="1506187449813838456">הגבר את גובה הצליל</translation>
-<translation id="151784044608172266">המשפט הבא</translation>
-<translation id="1524531499102321782">השורה הבאה בברייל</translation>
-<translation id="1546370775711804143">סרגל גלילה</translation>
-<translation id="1559739829547075274">נווט לאחור</translation>
-<translation id="1571643229714746283">ChromeVox ready</translation>
-<translation id="158493514907962286">דצמבר</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">עבור לברייל 6 נקודות</translation>
-<translation id="1611168825862729585">כותרת עמודה:</translation>
-<translation id="1613476421962910979">‏Earcons מופעלים</translation>
-<translation id="1618597272655350600">הכרזה על תיאור מלא של המיקום הנוכחי</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{סימן ‘גדול מ’}two{# סימני ’גדול מ’}many{# סימני ’גדול מ’}other{# סימני ’גדול מ’}}</translation>
-<translation id="1653266918374749391">הכותרת הקודמת של רמה 3</translation>
-<translation id="1659072772017912254">לא מסומן</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">‏ניווט ב-ChromeVox</translation>
-<translation id="16777221443363124">סרגל תפריטים</translation>
-<translation id="1692077714702418899">שורה מבנית</translation>
-<translation id="1700517974991662022">הופעל</translation>
-<translation id="1722567105086139392">קישור</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">פריט הגרפיקה הבא</translation>
-<translation id="1781173782405573156">מקש דילוג</translation>
-<translation id="1787176709638001873">טקסט לעריכת סיסמה</translation>
-<translation id="1810107444790159527">תיבת רשימה</translation>
-<translation id="1828385960365606039">מאי</translation>
-<translation id="1834891354138622109">עמודה</translation>
-<translation id="1865601187525349519">סוף הטקסט</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">אמור את התאריך והשעה הנוכחיים.</translation>
-<translation id="1902396333223336119">תא</translation>
-<translation id="1905379170753160525">הצג את רשימת הכותרות</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">בקרת שבוע בשנה</translation>
-<translation id="1964135212174907577">האובייקט הבא</translation>
-<translation id="1969092762068865084">יולי</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">כותרת שורה:</translation>
-<translation id="2002895034995108595">אפס את מפת המפתחות הנוכחית</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{סוגר מרובע שמאלי}two{# סימני סוגר מרובע שמאלי}many{# סימני סוגר מרובע שמאלי}other{# סימני סוגר מרובע שמאלי}}</translation>
-<translation id="2045490512405922022">לא מסומן</translation>
-<translation id="20601713649439366">אין ביטוי מתמטי קודם.</translation>
-<translation id="207477615537953741">סמנטי כבוי</translation>
-<translation id="2086961585857038472">המילה הבאה</translation>
-<translation id="2089387485033699258">en</translation>
-<translation id="2091933974477985526">אזור טקסט קודם הניתן לעריכה</translation>
-<translation id="2100350898815792233">כל סימני הפיסוק</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">מקש גישה:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">שנה את הטבלה הנוכחית בברייל 6 נקודות על ידי בחירה באפשרות מתוך הרשימה בהמשך.</translation>
-<translation id="2169714232367507776">לחץ על הפריט הנוכחי</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{סגור סוגריים}two{# סימני סגור סוגריים}many{# סימני סגור סוגריים}other{# סימני סגור סוגריים}}</translation>
-<translation id="2199994615414171367">הביטוי המתמטי הקודם</translation>
-<translation id="2223693656926968778">נקוט פעולה לגבי הפריט הנוכחי</translation>
-<translation id="225732394367814946">הגבר את קצב הדיבור</translation>
-<translation id="2267945578749931355">התו הבא</translation>
-<translation id="2281234842553884450">המחוון הקודם</translation>
-<translation id="2318372665160196757">ראשי</translation>
-<translation id="2329324941084714723">חלונית כרטיסיות</translation>
-<translation id="2344193891939537199">בקרת תאריך ושעה</translation>
-<translation id="2359897517538099099">לא במצב טבלה.</translation>
-<translation id="241124561063364910">לאחר מכן</translation>
-<translation id="2417569100218200841">פרטי תוכן</translation>
-<translation id="2422937916923936891">תיבת סימון של פריט תפריט</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">‏<ph name="KEY" /> הוא כעת מקש הצירוף החדש של ChromeVox.</translation>
-<translation id="2450814015951372393">תיבת סימון</translation>
-<translation id="2462626033734746142">קבוצת לחצני בחירה</translation>
-<translation id="2471138580042810658">כותרת 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{כוכבית}two{# סימני כוכבית}many{# סימני כוכבית}other{# סימני כוכבית}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> אופס.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">קבוצה</translation>
-<translation id="2582407057977008361">בצד</translation>
-<translation id="2589102159832527089">‏דף זה מכיל את הטקסט שחולץ באופן אוטומטי מקובץ ה-‏PDF‏ &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;לחץ כאן להצגת המקור.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">עם {COUNT,plural, =1{פריט אחד}two{שני פריטים}many{# פריטים}other{# פריטים}}</translation>
-<translation id="2614981083756825552">‏פריסת Math ML</translation>
-<translation id="2626530649491650971">clickable</translation>
-<translation id="2628764385451019380">אין תיבה משולבת קודמת.</translation>
-<translation id="2637227747952042642">Math</translation>
-<translation id="2639750663247012216">‏מקש צירוף של ChromeVox</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">לחץ על הפריט שמתחת למקש ניתוב</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{פתח סוגריים}two{# סימני פתח סוגריים}many{# סימני פתח סוגריים}other{# סימני פתח סוגריים}}</translation>
-<translation id="2705875883745373140">לא לחוץ</translation>
-<translation id="2706462751667573066">למעלה</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">אודיו</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">מסומן</translation>
-<translation id="27527859628328957">דלג לפריט הבא הניתן למיקוד</translation>
-<translation id="2770781857296573485">הזן סקירת קבוצה</translation>
-<translation id="2777845298774924149">יצאת</translation>
-<translation id="2800204403141299078">אין עוד אלמנטים שונים.</translation>
-<translation id="2800780099804980316">אין כותרת קודמת של רמה 1.</translation>
-<translation id="2811204574343810641">שורה</translation>
-<translation id="2816654101880605877">אין מחוון הבא.</translation>
-<translation id="2841013758207633010">שעה</translation>
-<translation id="2843837985843789981">הקבוצה הקודמת</translation>
-<translation id="2844995807198708617">תפריט הקשר</translation>
-<translation id="2849332794118375855">אין עוד תיבת סימון.</translation>
-<translation id="2864481629947106776">הקישור הקודם</translation>
-<translation id="2873259058405069099">עבור לתחילת הטבלה</translation>
-<translation id="2894654529758326923">מידע</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{סוגר מסולסל שמאלי}two{# סימני סוגר מסולסל שמאלי}many{# סימני סוגר מסולסל שמאלי}other{# סימני סוגר מסולסל שמאלי}}</translation>
-<translation id="2911433807131383493">‏פתח את המדריך של ChromeVox</translation>
-<translation id="2932083475399492303">החלף סוג שורה בין מבנית או פריסה</translation>
-<translation id="2964026537669811554">קבוצת כותרות</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{טאב}two{# סימני טאב}many{# סימני טאב}other{# סימני טאב}}</translation>
-<translation id="2972078295414139404">אין קישורים קודמים שבהם ביקרת.</translation>
-<translation id="2972205263822847197">הסבר קצר</translation>
-<translation id="2998131015536248178">התו הקודם</translation>
-<translation id="2999559350546931576">הורד את גובה הצליל</translation>
-<translation id="2999945368667127852">אין עוד ווידג'ט של מדיה.</translation>
-<translation id="3012414509011670858">אין קטע קודם.</translation>
-<translation id="3030432017085518523">לחצן בחירה של פריט בתפריט</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{גרש}two{# סימני גרש}many{# סימני גרש}other{# סימני גרש}}</translation>
-<translation id="3046838483509668188">‏אפשרויות של ChromeVox</translation>
-<translation id="3047143736589213134">מפת מפתחות ניסיונית</translation>
-<translation id="3060756054951570867">תפריט <ph name="TITLE" /> נפתח</translation>
-<translation id="3078345202707391975">הכותרת הבאה של רמה 2</translation>
-<translation id="3078740164268491126">טבלה</translation>
-<translation id="3082557070674409251">בוצעה לחיצה</translation>
-<translation id="3084806535845658316">ללא הד הקלדה</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">אין עוד ביטוי מתמטי.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">ציון הדרך הבא</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">מכווץ</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">הצג רשימת ציוני דרך</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">השורה הבאה</translation>
-<translation id="3155083529632865074">אין לחצן הקודם.</translation>
-<translation id="3163593631834463955">כותרת עמודה ריקה</translation>
-<translation id="316542773973815724">ניווט</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{רווח}two{# רווחים}many{# רווחים}other{# רווחים}}</translation>
-<translation id="320961988183078793">הוזן <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, כרטיסייה</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">קישור שהפעלת</translation>
-<translation id="323731244387692321">‏פתח את העזרה של מקלדת ChromeVox</translation>
-<translation id="3241052487511142956">הקישור הקודם שבו ביקרת</translation>
-<translation id="3286390186030710347">מחוון</translation>
-<translation id="3299925995433437805">אין עוד קישורים שבהם ביקרת.</translation>
-<translation id="3303384412438961941">‏הקש על מקש כלשהו כדי לגלות את שמו. לחיצה על Ctrl+W תסגור את סייר המקלדת.</translation>
-<translation id="3307886118343381874">עבור לסוף הטבלה</translation>
-<translation id="3311969765485641742">‏הקש על Alt+Shift+A כדי לעיין בהתראות</translation>
-<translation id="3312997241656799641">הקישור הבא שבו ביקרת</translation>
-<translation id="3321460131042519426">הפעל גלישת שורות</translation>
-<translation id="3322936298410871309">הכותרת הקודמת של רמה 1</translation>
-<translation id="3323447499041942178">תיבת טקסט</translation>
-<translation id="3353420241558113817">‏{"ar": "ערבית",
- "bg": "בולגרית",
- "ca": "קטלאנית",
- "cs": "צ'כית",
- "da": "דנית",
- "de": "גרמנית",
- "de_CH": "גרמנית (שווייץ)",
- "de_DE": "גרמנית (גרמניה)",
- "el": "יוונית",
- "en": "אנגלית",
- "en_CA": "אנגלית (קנדה)",
- "en_GB": "אנגלית (בריטניה)",
- "en_US": "אנגלית (ארצות הברית)",
- "es": "ספרדית",
- "et": "אסטונית",
- "fr": "צרפתית",
- "fr_CA": "צרפתית (קנדה)",
- "fr_FR": "צרפתית (צרפת)",
- "fi": "פינית",
- "he": "עברית",
- "hi": "הינדית",
- "hr": "קרואטית",
- "hu": "הונגרית",
- "is": "איסלנדית",
- "it": "איטלקית",
- "ko": "קוריאנית",
- "lt": "ליטאית",
- "lv": "לטבית",
- "nb": "נורווגיה Bokmål",
- "nl": "הולנדית",
- "pl": "פולנית",
- "pt": "פורטוגזית",
- "ro": "רומנית",
- "ru": "רוסית",
- "sk": "סלובקית",
- "sl": "סלובנית",
- "sr": "סרבית",
- "sv": "שוודית",
- "tr": "טורקית",
- "vi": "וייטנאמית",
- "zh": "סינית",
- "zh_TW": "סינית (האן מסורתית)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{סימן חיבור}two{# סימני חיבור}many{# סימני חיבור}other{# סימני חיבור}}</translation>
-<translation id="338583716107319301">מפריד</translation>
-<translation id="3389259863310851658">שדה קודם בטופס</translation>
-<translation id="3390225400784126843">הרכיב השונה הבא.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, פריט תפריט</translation>
-<translation id="3406283310380167331">הצג את רשימת הטפסים</translation>
-<translation id="3422338090358345848">פתח את סייר המקלדת</translation>
-<translation id="3457000393508828486">לחוץ חלקית</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, לחצן</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> עד <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{סוגר מרובע ימני}two{# סימני סוגר מרובע ימני}many{# סימני סוגר מרובע ימני}other{# סימני סוגר מרובע ימני}}</translation>
-<translation id="3493915602752813531">אין עוד עוגן.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{סימן שאלה}two{# סימני שאלה}many{# סימני שאלה}other{# סימני שאלה}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{סימן קארה (^)}two{# סימני קארה (^)}many{# סימני קארה (^)}other{# סימני קארה (^)}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, תיבת הסימון לא מסומנת</translation>
-<translation id="3599054940393788245">לא בתוך ביטוי מתמטי</translation>
-<translation id="3616113530831147358">אודיו</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{סימן הטעמה משני (`)}two{# סימני הטעמה משניים (`)}many{# סימני הטעמה משניים (`)}other{# סימני הטעמה משניים (`)}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{דולר}two{# סימני דולר}many{# סימני דולר}other{# סימני דולר}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, תיבת רשימה</translation>
-<translation id="3687295507293856493">נחש מהי כותרת העמודה של התא הנוכחי</translation>
-<translation id="3692274950075847560">ח:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">בקרת דיבור</translation>
-<translation id="3716845769494773620">שורות מרובות</translation>
-<translation id="3731746171184829332">אין כותרת קודמת.</translation>
-<translation id="3762198587642264450">עבור לסוף השורה הנוכחית</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">יצאת מתיבת דו-שיח.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}two{#}many{#}other{#}}</translation>
-<translation id="3801735343383419236">רשימת השלמה אוטומטית</translation>
-<translation id="3810838688059735925">וידאו</translation>
-<translation id="3816633764618089385">המדיה הבאה</translation>
-<translation id="3819376190738087562">אין דילוגים.</translation>
-<translation id="385383972552776628">פתח את דף האפשרויות</translation>
-<translation id="3856075812838139784">קריאה בלבד</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">תפריט</translation>
-<translation id="3909320334364316587">הכותרת הקודמת של רמה 6</translation>
-<translation id="3914173277599553213">נדרש</translation>
-<translation id="3962990492275676168">התחל לקרוא מהמיקום הנוכחי</translation>
-<translation id="4004802134384979325">מסומנת</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">בקרת חודשים</translation>
-<translation id="4039983576244166038">כותרת שורה ריקה</translation>
-<translation id="4042843249978639960">אין כותרת הבאה של רמה 2.</translation>
-<translation id="4043348641337972076">‏אין ציון דרך קודם מסוג ARIA.</translation>
-<translation id="4047216625641135770">סימון</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{טילדה (~)}two{# סימני טילדה (~)}many{# סימני טילדה (~)}other{# סימני טילדה (~)}}</translation>
-<translation id="409334809956508737">האובייקט הקודם</translation>
-<translation id="4099274309791143834">כולל תפריט משנה</translation>
-<translation id="4107807507418787238">אין תא למטה.</translation>
-<translation id="4116415223832267137">התראה</translation>
-<translation id="4147126331795725888">אין עוד פקד.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{סוגר מסולסל ימני}two{# סימני סוגר מסולסל ימני}many{# סימני סוגר מסולסל ימני}other{# סימני סוגר מסולסל ימני}}</translation>
-<translation id="4158704014418536539">תלוי רישיות.</translation>
-<translation id="4161663686871496107">‏המשוב בדיבור של ChromeVox מוכן</translation>
-<translation id="4173994908659439270">אין עוד שדה טקסט הניתן לעריכה.</translation>
-<translation id="4176463684765177261">מושבת</translation>
-<translation id="4188530942454211480">המשפט הקודם</translation>
-<translation id="4202186506458631436">העבר ימינה</translation>
-<translation id="4206289001967551965">בתוך טבלה</translation>
-<translation id="4215733775853809057">המחוון הבא</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{מקף}two{# סימני מקף}many{# סימני מקף}other{# סימני מקף}}</translation>
-<translation id="421884353938374759">color picker</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">אין תא משמאל.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, רמה <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">הערה</translation>
-<translation id="4254798249533888099">עץ</translation>
-<translation id="4255943572433203166">‏השתמש באפשרויות הבאות כדי להתאים אישית את ChromeVox. השינויים ייכנסו לתוקף באופן מיידי.</translation>
-<translation id="4271220233568730077">הביטוי המתמטי הבא</translation>
-<translation id="4271521365602459209">אין תוצאות נוספות.</translation>
-<translation id="4287520460805643128">אין עוד סעיף.</translation>
-<translation id="4289540628985791613">סקירה כללית</translation>
-<translation id="4300318234632215983">הכרזה על כתובת האתר של קישור</translation>
-<translation id="4301352596632316575">כולל תפריט משנה</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{נקודה}=3{שלוש נקודות}two{# נקודות}many{# נקודות}other{# נקודות}}</translation>
-<translation id="4347461890115250064">אין עוד רשימה.</translation>
-<translation id="4367650418938037324">‏רובד Math ML</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">הפסק דיבור</translation>
-<translation id="4373197658375206385">אין פריט קודם שאינו קישור.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">אין קישורים.</translation>
-<translation id="4476183483923481720">שורה חדשה</translation>
-<translation id="4482330759234983253">הטבלה הקודמת</translation>
-<translation id="4491109536499578614">תמונה</translation>
-<translation id="4529987814483543472">מפת מקשים קלאסית</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{קו נטוי}two{# סימני קו נטוי}many{# סימני קו נטוי}other{# סימני קו נטוי}}</translation>
-<translation id="4547556996012970016">הכותרת הבאה של רמה 5</translation>
-<translation id="4562381607973973258">כותרת עליונה</translation>
-<translation id="4591507479202817876">, מסומן</translation>
-<translation id="4597532268155981612">טופס</translation>
-<translation id="4597896406374528575">אפריל</translation>
-<translation id="4615592953348396470">מתעלם מלחיצת המקש הבאה</translation>
-<translation id="461613135510474570">משפט</translation>
-<translation id="4647836961514597010">בוחר צבעים</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">ציון הדרך הקודם</translation>
-<translation id="4696413482802371445">אין עוד כותרת ברמה 5.</translation>
-<translation id="4729095194763193578">השורה הקודמת בטבלה</translation>
-<translation id="4736221692378411923">אוגוסט</translation>
-<translation id="4740661827607246557">פקודות עזרה</translation>
-<translation id="4759716709594980008">‏סייר המקלדת של ChromeOS</translation>
-<translation id="4763296182459741068">גלישה לחלק התחתון</translation>
-<translation id="4763480195061959176">סרטוני וידאו</translation>
-<translation id="479989351350248267">Search</translation>
-<translation id="481165870889056555">הכרזה על הכותרת של הדף הנוכחי</translation>
-<translation id="4826415162591436065">נווט קדימה</translation>
-<translation id="4826604887384865800">הדילוג הבא</translation>
-<translation id="4827410568042294688">בחירה בוטלה</translation>
-<translation id="4842108708071771135">‏אין blockquote הבא.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">הרכיב הדומה הקודם.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">‏אפשר רישום TTS</translation>
-<translation id="4877261390094455813">הזן שאילתת חיפוש.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">קישור פנימי</translation>
-<translation id="4953585991029886728">ערוך טקסט</translation>
-<translation id="4954534434583049121">‏Blockquote הקודם</translation>
-<translation id="4973717656530883744">מינימום <ph name="X" /></translation>
-<translation id="4973762002207131920">עברת ל-<ph name="KEY" />.</translation>
-<translation id="4975416682604111799">אלפיות שנייה</translation>
-<translation id="49787999531187221">‏ChromeVox לא פעיל כעת.</translation>
-<translation id="4979404613699303341">לחצן 'הקודם'</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, תיבת רשימה</translation>
-<translation id="4983588134362688868">דלג לחלק העליון של הדף</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, חלון</translation>
-<translation id="4993152509206108683"><ph name="PERCENT" /> אחוזים מקצב הדיבור</translation>
-<translation id="4996716799442435517">ויזואלי</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, לחצן בחירה מסומן</translation>
-<translation id="4997475792277222884">אין פריט הבא שאינו קישור.</translation>
-<translation id="5000760171916499057">אין טפסים.</translation>
-<translation id="5005670136041063723">אין עוד רכיבים דומים.</translation>
-<translation id="501473567976723023">ינואר</translation>
-<translation id="5041394372352067729">העבר תצוגת ברייל לחלק העליון של הדף</translation>
-<translation id="5042770794184672516">הגבר את עוצמת הדיבור</translation>
-<translation id="5050015258024679800">הכותרת הקודמת של רמה 4</translation>
-<translation id="5054047268577924192">פריט קודם ברשימה</translation>
-<translation id="5078661581131202757">בחירת קובץ</translation>
-<translation id="5080758118274074384">בוצעה לחיצה כפולה</translation>
-<translation id="5098541983634824365">יציאה מהרשת.</translation>
-<translation id="5102981729317424850">סרגל כלים</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">אין שדה קודם בטופס.</translation>
-<translation id="5111640677200759579">כותרת עמודה</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">אין קישור קודם.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, לא מסומן</translation>
-<translation id="5183440668879371625">השורה הקודמת בברייל</translation>
-<translation id="5184944171021383281">אין עוד שדה בטופס.</translation>
-<translation id="5189244881767082992">שורה</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> כבר הוקצה לפקודה.</translation>
-<translation id="5205493599117157272">רשימת <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">אין עוד לחצן בחירה.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">אובייקט</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, כרטיסייה</translation>
-<translation id="5310788376443009632">הוסר:</translation>
-<translation id="5320727453979144100">מצב דביק מופעל</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{פסיק}two{# פסיקים}many{# פסיקים}other{# פסיקים}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, תיבת טקסט</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, קישור</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">דלג אחורה בזמן קריאה רציפה</translation>
-<translation id="5368000168321181111">‏Earcons כבוי</translation>
-<translation id="5374320867641260420">אין עוד לחצן.</translation>
-<translation id="5382299583965267720">אין עוד כותרת ברמה 1.</translation>
-<translation id="5402367795255837559">ברייל</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{נקודה ופסיק}two{# סימני נקודה ופסיק}many{# סימני נקודה ופסיק}other{# סימני נקודה ופסיק}}</translation>
-<translation id="5411891038905756502">אין נקודת דילוג קודמת.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{סימן ‘קטן מ‘}two{# סימני ‘קטן מ‘}many{# סימני ‘קטן מ‘}other{# סימני ‘קטן מ‘}}</translation>
-<translation id="5455441614648621694">משלים</translation>
-<translation id="5485036206801896268">אין פריט גרפיקה קודם.</translation>
-<translation id="5486947920110100234">אין עוד נקודת דילוג.</translation>
-<translation id="549602578321198708">מילה</translation>
-<translation id="5500932716852106146">אין שדה טקסט קודם הניתן לעריכה.</translation>
-<translation id="5502713021410870035">ספטמבר</translation>
-<translation id="5507663321906818013">בחינת ביצועים של ניפוי באגים</translation>
-<translation id="5518443085409638729">‏הצב את הסמן בין תווים בזמן עריכת טקסט (בדומה ל-Mac OS X).</translation>
-<translation id="552195134157544755">לחצן בחירה</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">אין כותרת קודמת של רמה 5.</translation>
-<translation id="556042886152191864">לחצן</translation>
-<translation id="5561345396546889625">הרשימה הבאה</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">ערוך טקסט, רשומת אימייל</translation>
-<translation id="5597170376237141345">תיבת הסימון הבאה</translation>
-<translation id="5597933780944041114">אין כותרת הבאה.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, לחצן הבחירה לא נבחר</translation>
-<translation id="5601172225407283979">בצע את פעולת ברירת המחדל</translation>
-<translation id="5608798115546226984">השלמה אוטומטית מוטבעת</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">יומן</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">אין טבלה קודמת.</translation>
-<translation id="5655682562155942719">פקודות דילוג</translation>
-<translation id="56637627897541303">אזור טקסט</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">ציון דרך</translation>
-<translation id="5683155931978483559">תיבת הסימון הקודמת</translation>
-<translation id="5684277895745049190">רשימה</translation>
-<translation id="5700650669149824506">אין כותרת קודמת של רמה 4.</translation>
-<translation id="5709192780268610569">אין תיאור ארוך</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">העמודה הבאה בטבלה</translation>
-<translation id="571866080859340309">סקירת קבוצות</translation>
-<translation id="5728409797179002635">לא נמצאה טבלה.</translation>
-<translation id="5748623122140342504">הכותרת הקודמת של רמה 5</translation>
-<translation id="5750633686117194034">‏לא הוקש מקש צירוף. הקש ממושכות על מקש צירוף אחד או יותר. הרם את האצבע לאחר שתסיים ותשמע את המקשים שהוגדרו. הקש על Tab כדי לצאת.</translation>
-<translation id="5788275253279308023">כרטיסייה <ph name="TITLE" /> בחלון גלישה בסתר</translation>
-<translation id="5806206155699461681">‏שיפור אתרים ספציפיים (כדוגמת חיפוש Google).</translation>
-<translation id="5819072574982403430">פריט עץ</translation>
-<translation id="5826479389509458994">שורה <ph name="ROW" /> עמודה <ph name="COL" /></translation>
-<translation id="5850707923114094062">הזז לאחור</translation>
-<translation id="5851548754964597211">רשימת כרטיסיות</translation>
-<translation id="5859752971144398932">יצאת מחיפוש בדף.</translation>
-<translation id="5866042630553435010">מסומן חלקית</translation>
-<translation id="5869546221129391014">רשת</translation>
-<translation id="5876817486144482042">החלש עוצמת דיבור</translation>
-<translation id="5887397643266327462">כיתובי ברייל הופעלו.</translation>
-<translation id="5891934789323004067">טבלה</translation>
-<translation id="5919442531159595654">העתק.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{סימן שווה}two{# סימני שווה}many{# סימני שווה}other{# סימני שווה}}</translation>
-<translation id="5939518447894949180">אפס</translation>
-<translation id="5948123859135882163">עבור בין פירוש מבני וסמנטי של ביטויים מתמטיים</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">דו-שיח</translation>
-<translation id="5963413905009737549">קטע</translation>
-<translation id="5968607524793740041">הצג תפריט הקשר</translation>
-<translation id="5983179082906765664">העמק את רמת הפירוט של הניווט</translation>
-<translation id="5999630716831179808">קולות</translation>
-<translation id="6000417740266304866">שנה את הטבלה הנוכחית בברייל 8 נקודות על ידי בחירה באפשרות מתוך הרשימה בהמשך.</translation>
-<translation id="6006050241733874051">טופס</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{קו נטוי שמאלי}two{# סימני קו נטוי שמאלי}many{# סימני קו נטוי שמאלי}other{# סימני קו נטוי שמאלי}}</translation>
-<translation id="6037602951055904232">הזז קדימה</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">סוף התא.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">רווח</translation>
-<translation id="6142308968191113180">כותרת 4</translation>
-<translation id="6169420925157477918">תמונה עם תיאור ארוך</translation>
-<translation id="6172087735260766220">‏אין אפשרות לגשת לטקסט נגיש בקובץ PDF המוגן מפני עריכה.</translation>
-<translation id="6186305613600865047">דלג לתחתית הדף</translation>
-<translation id="6193330012414963395">לפנה"צ אחה"צ</translation>
-<translation id="622484624075952240">למטה</translation>
-<translation id="6236061028292614533">הכותרת הבאה</translation>
-<translation id="6254901459154107917">האזור הבא בטקסט הניתן לעריכה</translation>
-<translation id="6259464875943891919">יצאת מ-<ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">הרכיב הדומה הבא.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">אין עוד תיבה משולבת.</translation>
-<translation id="6307969636681130414">לחוץ</translation>
-<translation id="6324551002951139333">Grammatical mistake detected</translation>
-<translation id="6348657800373377022">תיבה משולבת</translation>
-<translation id="6355910664415701303">אין פריט קודם ברשימה.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">הכותרת הקודמת</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">אין לחצן בחירה קודם.</translation>
-<translation id="6414968628640960377">הרכיב השונה הקודם.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{נקודתיים}two{# סימני נקודתיים}many{# סימני נקודתיים}other{# סימני נקודתיים}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, תפריט</translation>
-<translation id="6444046323172968959">תיבת דו-שיח של התראה</translation>
-<translation id="6459511626086141404">מפת מפתחות שטוחה</translation>
-<translation id="6468049171101508116">הלחצן הבא</translation>
-<translation id="6491972999578897419">שנה את הקול הנוכחי על ידי בחירה באפשרות מתוך הרשימה הבאה.</translation>
-<translation id="6508059270146105198">העבר תצוגת ברייל לתחתית הדף</translation>
-<translation id="6536864053412760904">‏אסימון Math ML</translation>
-<translation id="6550720799683018100">שנה את מפת המקשים הנוכחית על ידי בחירה באפשרות מתוך הרשימה בהמשך.</translation>
-<translation id="6561818612645211875">עבור לתחילת השורה הנוכחית</translation>
-<translation id="6587021927234520429">אין עוד כותרת ברמה 4.</translation>
-<translation id="6601344353291556895">הפעל תיאורים מרובי-מלל.</translation>
-<translation id="6615602925644411249">חפש בדף.</translation>
-<translation id="6633350132811819843">אין עוד טבלה.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">סרגל התקדמות</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">מסמך</translation>
-<translation id="6697092096875747123">התיבה המשולבת הקודמת</translation>
-<translation id="6714813999819678458">הכותרת הקודמת של רמה 2</translation>
-<translation id="6716505898850596801">מקשי צירוף</translation>
-<translation id="671916444866103745">‏אין ציון דרך הבא מסוג ARIA.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, תיבה משולבת</translation>
-<translation id="6735257939857578167">כולל <ph name="NUM" /> פריטים</translation>
-<translation id="6736510033526053669">הכרטיסייה נוצרה</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">סעיף</translation>
-<translation id="6787839852456839824">מקשי קיצור</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">כותרת תחתונה</translation>
-<translation id="6871161210040114857">ללא תלות ברישיות.</translation>
-<translation id="6877435256196695200">אין עוד פריט גרפיקה.</translation>
-<translation id="6897341342232909480">העבר שמאלה</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">נמחק</translation>
-<translation id="6911965441508464308">אין תא מעל.</translation>
-<translation id="6919104639734799681">הצג את רשימת הטבלאות</translation>
-<translation id="6964088412282673743">אין פקד קודם.</translation>
-<translation id="6996566555547746822">התיבה המשולבת הבאה</translation>
-<translation id="7005146664810010831">לא נמצאה כתובת אתר</translation>
-<translation id="7010712454773919705">‏מקש צירוף של ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">הרשימה הקודמת</translation>
-<translation id="7041173719775863268">סיום בחירה</translation>
-<translation id="7095834689119144465">ערוך טקסט מספרי בלבד</translation>
-<translation id="7096001299300236431">המדיה הקודמת</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">הד מילה</translation>
-<translation id="713824876195128146">‏blockquote הבא</translation>
-<translation id="7161771961008409533">לחצן קופץ</translation>
-<translation id="7167657087543110">הד תו</translation>
-<translation id="7170733337935166589">דלג קדימה בזמן קריאה רציפה</translation>
-<translation id="7181697990050180700">התאם אישית את מקשי הקיצור עבור פקודות נפוצות על ידי הקלדה שלהם בשדות המתאימים למטה.</translation>
-<translation id="7203150201908454328">מורחב</translation>
-<translation id="7210211103303402262">דקות</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">שורה</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">כותרת</translation>
-<translation id="7241683698754534149">פתח תיאור ארוך בכרטיסייה חדשה</translation>
-<translation id="7248671827512403053">יישום</translation>
-<translation id="725969808843520477">לחצן הבחירה הבא</translation>
-<translation id="7269119382257320590">אין סימני פיסוק</translation>
-<translation id="7273174640290488576">ריקה</translation>
-<translation id="7285387653379749618">טבלאות</translation>
-<translation id="7289186959554153431">כותרת 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">כיתובי ברייל מושבתים.</translation>
-<translation id="7318872822751139669">השתמש בעכבר כדי לשנות את המיקוד.</translation>
-<translation id="7322388933135261569">פברואר</translation>
-<translation id="7332592614823088566">שורה <ph name="ROWINDEX" /> מתוך <ph name="ROWTOTAL" />, עמודה <ph name="COLINDEX" /> מתוך <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">has popup</translation>
-<translation id="7356165926712028380">עבור לברייל 8 נקודות</translation>
-<translation id="7362871137496673139">אין כותרת קודמת של רמה 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{אמפרסנד (&amp;)}two{# סימני אמפרסנד (&amp;)}many{# סימני אמפרסנד (&amp;)}other{# סימני אמפרסנד (&amp;)}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">יציאה מהטבלה.</translation>
-<translation id="739763518212184081">השורה הקודמת</translation>
-<translation id="7400575256015741911">זוהתה טעות באיות</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">חזרה</translation>
-<translation id="7434509671034404296">למפתחים</translation>
-<translation id="7439060726180460871">ספריה</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">נכנסת לתיבת דו-שיח</translation>
-<translation id="7532613204005497612">יוני</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, מחוון</translation>
-<translation id="7586163296341959563">הדבק.</translation>
-<translation id="7596919493010894443">הבחירה נוקתה</translation>
-<translation id="7604026522577407655">עבור לתחילת העמודה הנוכחית</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">הכרזה על כתובת האתר של הדף הנוכחי</translation>
-<translation id="7609363189280667021">החלף כיתובי ברייל</translation>
-<translation id="762020119231868829">השהה את כל הווידאג'טים של מדיה הפועלים כעת</translation>
-<translation id="7625690649919402823">הטבלה הבאה</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), רמה <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">אין כותרת קודמת של רמה 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, תיבת טקסט</translation>
-<translation id="7663318257180412551">כותרת 2</translation>
-<translation id="7674576868851035240">הקישור הבא</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">ערוך טקסט, רשומת כתובת אתר</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">לחצן הבחירה הקודם</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, תיבת טקסט של סיסמה</translation>
-<translation id="7805247615045262757">ניווט ברירת מחדל</translation>
-<translation id="7805768142964895445">סטטוס</translation>
-<translation id="7810781339813764006">הקבוצה הבאה</translation>
-<translation id="7819187121850078213">חלון <ph name="TITLE" /> בכרטיסייה</translation>
-<translation id="7828956995407538686">אוקטובר</translation>
-<translation id="7839679365527550018">המילה הקודמת</translation>
-<translation id="7851816175263618915">חלק מסימני הפיסוק</translation>
-<translation id="7870596830398826354">‏עץ Math ML</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">‏החלף מצב של ChromeVox קלאסי.</translation>
-<translation id="7895896691902835279">קישור לא ידוע</translation>
-<translation id="7927711904086083099">לא נבחר</translation>
-<translation id="7935627501098484003">פקד זמן</translation>
-<translation id="7939428177581522200">נוסף לבחירה</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{סימן @}two{# סימני @}many{# סימני @}other{# סימני @}}</translation>
-<translation id="7965147473449754028">התפריט נסגר</translation>
-<translation id="7974390230414479278">פריט תפריט</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{סימן קריאה}two{# סימני קריאה}many{# סימני קריאה}other{# סימני קריאה}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{מרכאה}two{# סימני מרכאות}many{# סימני מרכאות}other{# סימני מרכאות}}</translation>
-<translation id="8033827949643255796">מסומן</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">ערוך טקסט, רשומת חיפוש</translation>
-<translation id="8049189770492311300">טיימר</translation>
-<translation id="8065607967589909823">הבחירה היא</translation>
-<translation id="8066678206530322333">מודעת באנר</translation>
-<translation id="8110647606445335195">‏אין ציוני דרך מסוג ARIA.</translation>
-<translation id="8153880621934657047">לא בתוך טבלה.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{קו תחתון}two{# סימני קו תחתון}many{# סימני קו תחתון}other{# סימני קו תחתון}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">גזור.</translation>
-<translation id="8199231515320852133">הכרזה על הכותרות של התא הנוכחי</translation>
-<translation id="820417203470636242">תא ריק.</translation>
-<translation id="8215202828671303819">בחירה מרובה</translation>
-<translation id="8276439074553447000">דלג לפריט הקודם הניתן למיקוד</translation>
-<translation id="8278417001922463147">אין סעיף קודם.</translation>
-<translation id="8283603667300770666">השדה הבא בטופס</translation>
-<translation id="831207808878314375">הגדרה</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">שעות</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{סולמית}two{# סימני סולמית}many{# סימני סולמית}other{# סימני סולמית}}</translation>
-<translation id="8374154622594089836">month</translation>
-<translation id="8378855320830505539">אזור</translation>
-<translation id="8382679411218029383">השלמה אוטומטית מוטבעת ורשימה</translation>
-<translation id="8428603554127842284">רמה <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">אין כותרת הבאה של רמה 3.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">אין תיבת סימון קודמת.</translation>
-<translation id="8455868257606149352">מקסימום <ph name="X" /></translation>
-<translation id="84575901236241018">כולל מקש גישה, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">הקטן רמת פירוט של ניווט</translation>
-<translation id="8520472399088452386">לחצן סיבוב</translation>
-<translation id="8538744478902126321">נחש מהי כותרת השורה של התא הנוכחי</translation>
-<translation id="8540054775867439484">גלישה לחלק העליון</translation>
-<translation id="8548973727659841685">תו</translation>
-<translation id="8561322612995434619">כולל חלון קופץ</translation>
-<translation id="8571096049907249734">בחירה מרובה</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">הפריט הבא ברשימה</translation>
-<translation id="860150890330522909">תיבת הסימון <ph name="NAME" /> סומנה</translation>
-<translation id="8606621670302093223">בקרת תאריך</translation>
-<translation id="8631359288236106450">נבחרו <ph name="COUNT" /> פריטים</translation>
-<translation id="8638532244051952400">הקרא את הקואורדינטות של התא הנוכחי</translation>
-<translation id="8650576015643545550">אין רשימה קודמת.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">הצג את רשימת הקישורים</translation>
-<translation id="8664519043722036194">שניות</translation>
-<translation id="867187640362843212">כותרת 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{קו ניצב}two{# סימני קו ניצב}many{# סימני קו ניצב}other{# סימני קו ניצב}}</translation>
-<translation id="8735450637152821465">התחל בחירה</translation>
-<translation id="8743786158317878347">היכנס לתוכן מובנה, כמו טבלאות</translation>
-<translation id="8747966237988593539">רשימה לפי סדר</translation>
-<translation id="8759334257841767240">אין קישור הבא.</translation>
-<translation id="8767968232364267681">הכותרת הבאה של רמה 4</translation>
-<translation id="8770473310765924354">צא מתוכן מובנה, כמו טבלאות</translation>
-<translation id="8791025954632646584">סמנטיקה מופעלת</translation>
-<translation id="8796411681063377102">הכותרת הבאה של רמה 3</translation>
-<translation id="8808582214901541005">מרץ</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">‏הקש למעלה או למטה לסקירת הפקודות, הקש Enter להפעלה</translation>
-<translation id="8864099967139188018">אין עוד כותרת ברמה 6.</translation>
-<translation id="8882002077197914455">כותרת שורה</translation>
-<translation id="8896347895970027998">‏הפעל או כבה את ChromeVox.</translation>
-<translation id="8898516272131543774">הד סימני ניקוד מחזוריים</translation>
-<translation id="8900148057318340779">מקש קידומת</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">כותרות ריקות</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">מקשי צירוף</translation>
-<translation id="8943175951035496220">אין תא מימין.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">אין טבלאות.</translation>
-<translation id="9040132695316389094">כותרת 1</translation>
-<translation id="9043969572162476692">%<ph name="NUM" /></translation>
-<translation id="9061915073547935367">החלף ווידג'ט חיפוש</translation>
-<translation id="9065283790526219006">‎+popup‎</translation>
-<translation id="9077213568694924680">הוסר מהבחירה</translation>
-<translation id="9082874451376019682">אין מחוון קודם.</translation>
-<translation id="9089864840575085222">הד הקלדה מחזורית</translation>
-<translation id="9107530006868467849">אין ווידג'ט למדיה הקודמת.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{אחוז}two{# סימני אחוז}many{# סימני אחוז}other{# סימני אחוז}}</translation>
-<translation id="9115913704608474258">נובמבר</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">הכרזה על תיאור קצר של המיקום הנוכחי</translation>
-<translation id="9153606228985488238"><ph name="PERCENT" /> אחוזים מגובה הצליל</translation>
-<translation id="9160096769946561184">עבור לסוף העמודה הנוכחית</translation>
-<translation id="9173115498289768110"><ph name="PERCENT" /> אחוזים מעוצמת השמע</translation>
-<translation id="9178973770513562274">השתמש במקשי החצים למעלה ולמטה כדי לדפדף, או הקלד לחיפוש.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">אין עוד קטע.</translation>
-<translation id="930275611743429116">התחל או סיים בחירה.</translation>
-<translation id="948171205378458592">האט את קצב הדיבור</translation>
-<translation id="962913030769097253">הכותרת הבאה של רמה 1</translation>
-<translation id="973955474346881951">הפעל/השבת מצב דביק</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ja.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ja.xtb
deleted file mode 100644
index 9b5ce8bb022..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ja.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ja">
-<translation id="1012173283529841972">リスト項目</translation>
-<translation id="1013742170491673792">検索用語を編集</translation>
-<translation id="1023866615269196768">拡張されました。</translation>
-<translation id="1025074108959230262">スティッキー モードは無効</translation>
-<translation id="1031961866430398710">この場合</translation>
-<translation id="1044777062731150180">見出しなし</translation>
-<translation id="106222400312645156">行見出し</translation>
-<translation id="1065552602950927991">無効な入力値</translation>
-<translation id="1082209053475788238">前のレベル 6 見出しはありません。</translation>
-<translation id="1088219014394087294">見出しがありません。</translation>
-<translation id="1106741348836243114">音声フィードバック(イアコン)をオンまたはオフにします。</translation>
-<translation id="1120743664840974483">{"a": "アルファ", "b": "ブラボー", "c": "チャーリー", "d": "デルタ", "e": "エコー", "f": "フォックストロット", "g": "ゴルフ", "h": "ホテル", "i": "インディア", "j": "ジュリエット","k": "キロ", "l": "リマ", "m": "マイク", "n": "ノベンバー", "o": "オスカー","p": "パパ", "q": "ケベック", "r": "ロメオ", "s": "シエラ", "t": "タンゴ", "u": "ユニフォーム", "v": "ビクター", "w": "ウイスキー","x": "エックスレイ", "y": "ヤンキー", "z": "ズールー"}</translation>
-<translation id="113582498867142724"><ph name="TAG" /> コレクション(<ph name="NUM" /> 個の項目)</translation>
-<translation id="1155043339247954670">次のリスト項目はありません。</translation>
-<translation id="1157782847298808853">キーボード ヘルプ</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />、<ph name="NAME" />、コンボ ボックス</translation>
-<translation id="1167230103353892028"><ph name="NAME" />、メニュー項目、サブメニューあり</translation>
-<translation id="1177863135347784049">カスタム</translation>
-<translation id="1188858454923323853">捕捉</translation>
-<translation id="1206619573307042055">マーキー</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome を音声で読み上げ</translation>
-<translation id="1229276918471378188">前のジャンプ</translation>
-<translation id="1237866625126425153">ラジオグループ</translation>
-<translation id="1251750620252348585">次のレベル 6 見出し</translation>
-<translation id="1275718070701477396">選択されています</translation>
-<translation id="1319608975892113573">前の引用箇所はありません。</translation>
-<translation id="1321576897702511272">ChromeVox ヘルプを表示しない</translation>
-<translation id="1331702245475014624"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">文字と単語の読み上げ</translation>
-<translation id="1339428534620983148">表の前の列</translation>
-<translation id="1342835525016946179">記事</translation>
-<translation id="1346748346194534595">右</translation>
-<translation id="136718599399906424">表の次の行</translation>
-<translation id="1383876407941801731">検索</translation>
-<translation id="1385214448885562192">確定するには Enter キー、キャンセルするには Esc キー、次へ進むには下矢印キー、前へ戻るには上矢印キーを押してください。</translation>
-<translation id="1396114365388024581">タブリスト</translation>
-<translation id="1439316808600711881">領域</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />、パスワード テキスト ボックス</translation>
-<translation id="1467432559032391204">左</translation>
-<translation id="1474557363159888097">前のアンカーはありません。</translation>
-<translation id="1502086903961450562">前の図</translation>
-<translation id="1506187449813838456">ピッチを上げる</translation>
-<translation id="151784044608172266">次の文</translation>
-<translation id="1524531499102321782">ブライユ点字の次の行</translation>
-<translation id="1546370775711804143">スクロールバー</translation>
-<translation id="1559739829547075274">逆方向にナビゲート</translation>
-<translation id="1571643229714746283">ChromeVox 対応</translation>
-<translation id="158493514907962286">12 月</translation>
-<translation id="1594072653727561613">メニュー</translation>
-<translation id="1610130962244179598">6 点点字に切り替え</translation>
-<translation id="1611168825862729585">列見出し:</translation>
-<translation id="1613476421962910979">イアコン オン</translation>
-<translation id="1618597272655350600">現在位置の詳細な説明を読み上げます</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{大なり}other{# 個の大なり記号}}</translation>
-<translation id="1653266918374749391">前のレベル 3 見出し</translation>
-<translation id="1659072772017912254">オフ</translation>
-<translation id="1669290819662866522">週間</translation>
-<translation id="1674262202423278359">ChromeVox ナビゲーション</translation>
-<translation id="16777221443363124">メニューバー</translation>
-<translation id="1692077714702418899">構造化された行</translation>
-<translation id="1700517974991662022">アクセス済み</translation>
-<translation id="1722567105086139392">リンク</translation>
-<translation id="1727806147743597030">フッター</translation>
-<translation id="174268867904053074">次の図</translation>
-<translation id="1781173782405573156">パススルー キー</translation>
-<translation id="1787176709638001873">パスワード テキスト編集</translation>
-<translation id="1810107444790159527">リスト ボックス</translation>
-<translation id="1828385960365606039">5 月</translation>
-<translation id="1834891354138622109">列</translation>
-<translation id="1865601187525349519">テキスト終了</translation>
-<translation id="1876229593313240038">ドキュメント</translation>
-<translation id="188130072164734898">現在の日付と時刻を音声で読み上げます。</translation>
-<translation id="1902396333223336119">セル</translation>
-<translation id="1905379170753160525">見出しリストを表示</translation>
-<translation id="1912556590115083156">アクセス済みのリンク</translation>
-<translation id="1913761808037590218">数字を編集</translation>
-<translation id="1954623340234317532">週の設定(年間通し番号)</translation>
-<translation id="1964135212174907577">次のオブジェクト</translation>
-<translation id="1969092762068865084">7 月</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">行見出し:</translation>
-<translation id="2002895034995108595">現在のキーマップをリセット</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{左角かっこ}other{# 個の左角かっこ}}</translation>
-<translation id="2045490512405922022">オフ</translation>
-<translation id="20601713649439366">前の数式はありません。</translation>
-<translation id="207477615537953741">セマンティクス オフ</translation>
-<translation id="2086961585857038472">次の単語</translation>
-<translation id="2089387485033699258">ja</translation>
-<translation id="2091933974477985526">前の編集可能テキスト領域</translation>
-<translation id="2100350898815792233">すべての句読点を読み上げます</translation>
-<translation id="2119965627982867824">スピンボタン</translation>
-<translation id="2121067395472282800">アクセス キー: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">現在の 6 点点字表を変更するには、下のリストからオプションを選択します。</translation>
-<translation id="2169714232367507776">現在の項目をクリック</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{右丸かっこ}other{# 個の右丸かっこ}}</translation>
-<translation id="2199994615414171367">前の数式</translation>
-<translation id="2223693656926968778">現在の項目に対して操作を実行</translation>
-<translation id="225732394367814946">読み上げの速度を上げる</translation>
-<translation id="2267945578749931355">次の文字</translation>
-<translation id="2281234842553884450">前のスライダ</translation>
-<translation id="2318372665160196757">本文</translation>
-<translation id="2329324941084714723">タブ パネル</translation>
-<translation id="2344193891939537199">日時の設定</translation>
-<translation id="2359897517538099099">表モードではありません。</translation>
-<translation id="241124561063364910">を押して、次のキーを押します:</translation>
-<translation id="2417569100218200841">コンテンツ情報</translation>
-<translation id="2422937916923936891">メニュー項目のチェックボックス</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> が新しい ChromeVox 修飾キーになりました。</translation>
-<translation id="2450814015951372393">チェックボックス</translation>
-<translation id="2462626033734746142">ラジオボタン グループ</translation>
-<translation id="2471138580042810658">見出し 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{アスタリスク}other{# 個のアスタリスク}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> がリセットされました。</translation>
-<translation id="2553108862507765288">文法上の誤り</translation>
-<translation id="257674075312929031">グループ</translation>
-<translation id="2582407057977008361">補足</translation>
-<translation id="2589102159832527089">このページには、PDF ファイル &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; から自動的に抽出したテキストが表示されています。元のファイルは&lt;a href="<ph name="URL" />"&gt;こちら&lt;/a&gt;をクリックしてください。</translation>
-<translation id="2606210917827248971">に {COUNT,plural, =1{# 件の項目}other{# 件の項目}}</translation>
-<translation id="2614981083756825552">MathML レイアウト</translation>
-<translation id="2626530649491650971">クリック可能</translation>
-<translation id="2628764385451019380">前のコンボ ボックスはありません。</translation>
-<translation id="2637227747952042642">数式</translation>
-<translation id="2639750663247012216">ChromeVox 修飾キー</translation>
-<translation id="2644542693584024604">スペルミス</translation>
-<translation id="2667291555398229137">ルーティング キーの下の項目をクリックします</translation>
-<translation id="2697408785920771974">インライン オートコンプリート</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{左丸かっこ}other{# 個の左丸かっこ}}</translation>
-<translation id="2705875883745373140">オフ</translation>
-<translation id="2706462751667573066">上矢印キー</translation>
-<translation id="2717271541250958000">タブパネル</translation>
-<translation id="2723001399770238859">音声</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">オン</translation>
-<translation id="27527859628328957">次のフォーカス可能項目にジャンプ</translation>
-<translation id="2770781857296573485">グループ検索を入力</translation>
-<translation id="2777845298774924149">終了しました</translation>
-<translation id="2800204403141299078">この他に異なる要素はありません。</translation>
-<translation id="2800780099804980316">前のレベル 1 見出しはありません。</translation>
-<translation id="2811204574343810641">行</translation>
-<translation id="2816654101880605877">次のスライダはありません。</translation>
-<translation id="2841013758207633010">時間</translation>
-<translation id="2843837985843789981">前のグループ</translation>
-<translation id="2844995807198708617">コンテキスト メニュー</translation>
-<translation id="2849332794118375855">次のチェックボックスはありません。</translation>
-<translation id="2864481629947106776">前のリンク</translation>
-<translation id="2873259058405069099">表の先頭に移動</translation>
-<translation id="2894654529758326923">情報</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{左中かっこ}other{# 個の左中かっこ}}</translation>
-<translation id="2911433807131383493">ChromeVox チュートリアルを開く</translation>
-<translation id="2932083475399492303">構造化された行とレイアウト行の切り替え</translation>
-<translation id="2964026537669811554">見出しグループ</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{タブ}other{# 個のタブ}}</translation>
-<translation id="2972078295414139404">前にアクセスしたリンクはありません。</translation>
-<translation id="2972205263822847197">ツールチップ</translation>
-<translation id="2998131015536248178">前の文字</translation>
-<translation id="2999559350546931576">ピッチを下げる</translation>
-<translation id="2999945368667127852">次のメディア ウィジェットはありません。</translation>
-<translation id="3012414509011670858">前のセクションはありません。</translation>
-<translation id="3030432017085518523">メニュー項目のラジオボタン</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{アポストロフィ}other{# 個のアポストロフィ}}</translation>
-<translation id="3046838483509668188">ChromeVox のオプション</translation>
-<translation id="3047143736589213134">テスト用キーマップ</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> メニューを開きました</translation>
-<translation id="3078345202707391975">次のレベル 2 見出し</translation>
-<translation id="3078740164268491126">表</translation>
-<translation id="3082557070674409251">クリックしました</translation>
-<translation id="3084806535845658316">入力読み上げなし</translation>
-<translation id="3086746722712840547">注記</translation>
-<translation id="308895241372589742">次の数式はありません。</translation>
-<translation id="3090532668523289635">グループ</translation>
-<translation id="3093176084511590672">次のランドマーク</translation>
-<translation id="3096671415663099226">コンボボックス</translation>
-<translation id="3104705064753753826">アラート ダイアログ</translation>
-<translation id="3109724472072898302">折りたたみ表示中</translation>
-<translation id="3134461040845705080">読み取り専用</translation>
-<translation id="3138767756593758860">ランドマーク リストを表示</translation>
-<translation id="3143851963874289911">セル</translation>
-<translation id="3149472044574196936">次の行</translation>
-<translation id="3155083529632865074">前のボタンはありません。</translation>
-<translation id="3163593631834463955">列見出しが空です</translation>
-<translation id="316542773973815724">ナビゲーション</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{スペース}other{# 個のスペース}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" />を入力しました</translation>
-<translation id="3223701887221307104"><ph name="NAME" />、タブ</translation>
-<translation id="3226035351387556942">チェックボックス</translation>
-<translation id="3229375994964697375">アクセス済みのリンク</translation>
-<translation id="323731244387692321">ChromeVox キーボード ヘルプを開く</translation>
-<translation id="3241052487511142956">前にアクセスしたリンク</translation>
-<translation id="3286390186030710347">スライダ</translation>
-<translation id="3299925995433437805">次にアクセスしたリンクはありません。</translation>
-<translation id="3303384412438961941">キーを押すとその名前が読み上げられます。Ctrl キーと W キーを同時に押すとキーボード エクスプローラが終了します。</translation>
-<translation id="3307886118343381874">表の末尾に移動</translation>
-<translation id="3311969765485641742">アラートを確認するには Alt+Shift+A を押してください</translation>
-<translation id="3312997241656799641">次にアクセスしたリンク</translation>
-<translation id="3321460131042519426">ワードラップを有効にする</translation>
-<translation id="3322936298410871309">前のレベル 1 見出し</translation>
-<translation id="3323447499041942178">テキスト ボックス</translation>
-<translation id="3353420241558113817">{"ar": "アラビア語",
- "bg": "ブルガリア語",
- "ca": "カタロニア語",
- "cs": "チェコ語",
- "da": "デンマーク語",
- "de": "ドイツ語",
- "de_CH": "ドイツ語(スイス)",
- "de_DE": "ドイツ語(ドイツ)",
- "el": "ギリシャ語",
- "en": "英語",
- "en_CA": "英語(カナダ)",
- "en_GB": "英語(イギリス)",
- "en_US": "英語(アメリカ)",
- "es": "スペイン語",
- "et": "エストニア語",
- "fr": "フランス語",
- "fr_CA": "フランス語(カナダ)",
- "fr_FR": "フランス語(フランス)",
- "fi": "フィンランド語",
- "he": "ヘブライ語",
- "hi": "ヒンディー語",
- "hr": "クロアチア語",
- "hu": "ハンガリー語",
- "is": "アイスランド語",
- "it": "イタリア語",
- "ko": "韓国語",
- "lt": "リトアニア語",
- "lv": "ラトビア語",
- "nb": "ノルウェー語(ブークモール)",
- "nl": "オランダ語",
- "pl": "ポーランド語",
- "pt": "ポルトガル語",
- "ro": "ルーマニア語",
- "ru": "ロシア語",
- "sk": "スロバキア語",
- "sl": "スロベニア語",
- "sr": "セルビア語",
- "sv": "スウェーデン語",
- "tr": "トルコ語",
- "vi": "ベトナム語",
- "zh": "中国語",
- "zh_TW": "中国語(繁体字)"}</translation>
-<translation id="3359142382821736686">区切り文字</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{プラス}other{# 個のプラス記号}}</translation>
-<translation id="338583716107319301">セパレータ</translation>
-<translation id="3389259863310851658">前のフォーム フィールド</translation>
-<translation id="3390225400784126843">次の異なる要素。</translation>
-<translation id="3392045790598181549"><ph name="NAME" />、メニュー項目</translation>
-<translation id="3406283310380167331">フォーム リストを表示</translation>
-<translation id="3422338090358345848">キーボード エクスプローラを開く</translation>
-<translation id="3457000393508828486">一部オン</translation>
-<translation id="3462439746547587373"><ph name="NAME" />、ボタン</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> 件選択</translation>
-<translation id="3486232535569802404"><ph name="V1" />~<ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{右角かっこ}other{# 個の右角かっこ}}</translation>
-<translation id="3493915602752813531">次のアンカーはありません。</translation>
-<translation id="3494946239022273294">メニュー項目</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{疑問符}other{# 個の疑問符}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{キャレット}other{# 個のキャレット}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />、オフのチェックボックス</translation>
-<translation id="3599054940393788245">数式の外部</translation>
-<translation id="3616113530831147358">音声</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{バッククォート}other{# 個のバッククォート}}</translation>
-<translation id="3650317109285159359">メニュー項目のチェックボックス</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{ドル}other{# 個のドル記号}}</translation>
-<translation id="3659787053479271466">アラート</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />、リスト ボックス</translation>
-<translation id="3687295507293856493">現在のセルの列見出しを推測</translation>
-<translation id="3692274950075847560">け: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">読み上げのコントロール</translation>
-<translation id="3716845769494773620">複数行可</translation>
-<translation id="3731746171184829332">前の見出しはありません。</translation>
-<translation id="3762198587642264450">現在の行の末尾に移動</translation>
-<translation id="3777255250339039212">見出し 1</translation>
-<translation id="3793710123303304873">ダイアログを終了しました。</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">オートコンプリートはリスト形式</translation>
-<translation id="3810838688059735925">動画</translation>
-<translation id="3816633764618089385">次のメディア</translation>
-<translation id="3819376190738087562">ジャンプはありません。</translation>
-<translation id="385383972552776628">オプション ページを開く</translation>
-<translation id="3856075812838139784">読み取り専用</translation>
-<translation id="3887576927692165210">編集</translation>
-<translation id="3897092660631435901">メニュー</translation>
-<translation id="3909320334364316587">前のレベル 6 見出し</translation>
-<translation id="3914173277599553213">必須</translation>
-<translation id="3962990492275676168">現在の場所から読み上げを開始</translation>
-<translation id="4004802134384979325">オン</translation>
-<translation id="4006140876663370126">画像</translation>
-<translation id="4038349100599457191">月の設定</translation>
-<translation id="4039983576244166038">行見出しが空です</translation>
-<translation id="4042843249978639960">次のレベル 2 見出しはありません。</translation>
-<translation id="4043348641337972076">前の ARIA ランドマークはありません。</translation>
-<translation id="4047216625641135770">マーク</translation>
-<translation id="404803211695627272"><ph name="V1" />~<ph name="V2" /></translation>
-<translation id="4054936709456751127">ステータス</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{チルダ}other{# 個のチルダ}}</translation>
-<translation id="409334809956508737">前のオブジェクト</translation>
-<translation id="4099274309791143834">サブメニューあり</translation>
-<translation id="4107807507418787238">下にセルはありません。</translation>
-<translation id="4116415223832267137">アラート</translation>
-<translation id="4147126331795725888">次のコントロールはありません。</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{右中かっこ}other{# 個の右中かっこ}}</translation>
-<translation id="4158704014418536539">大文字と小文字を区別します。</translation>
-<translation id="4161663686871496107">ChromeVox 音声フィードバックをご利用いただけます</translation>
-<translation id="4173994908659439270">次の編集可能テキスト フィールドはありません。</translation>
-<translation id="4176463684765177261">無効</translation>
-<translation id="4188530942454211480">前の文</translation>
-<translation id="4202186506458631436">右へ移動</translation>
-<translation id="4206289001967551965">表の中です</translation>
-<translation id="4215733775853809057">次のスライダ</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{ダッシュ}other{# 個のダッシュ}}</translation>
-<translation id="421884353938374759">色の選択</translation>
-<translation id="4229646983878045487">日時</translation>
-<translation id="423334822609210999">左にセルはありません。</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />、グレード <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">メモ</translation>
-<translation id="4254798249533888099">ツリー</translation>
-<translation id="4255943572433203166">以下のオプションを使用して ChromeVox をカスタマイズします。変更は直ちに有効になります。</translation>
-<translation id="4271220233568730077">次の数式</translation>
-<translation id="4271521365602459209">他に検索結果はありません。</translation>
-<translation id="4287520460805643128">次の記事はありません。</translation>
-<translation id="4289540628985791613">概要</translation>
-<translation id="4300318234632215983">リンクの URL を読み上げる</translation>
-<translation id="4301352596632316575">サブメニューあり</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{ドット}=3{三点リーダー}other{# 個のドット}}</translation>
-<translation id="4347461890115250064">次のリストはありません。</translation>
-<translation id="4367650418938037324">MathML リーフ</translation>
-<translation id="4372435075475052704">最小: <ph name="X" /></translation>
-<translation id="4372705107434148843">読み上げの停止</translation>
-<translation id="4373197658375206385">リンクでない前の項目はありません。</translation>
-<translation id="4391478986194775161">コンテンツ情報</translation>
-<translation id="443163561286008705">リセット</translation>
-<translation id="4471074325120394300">リンクがありません。</translation>
-<translation id="4476183483923481720">新しい行</translation>
-<translation id="4482330759234983253">前の表</translation>
-<translation id="4491109536499578614">画像</translation>
-<translation id="4529987814483543472">クラシック キーマップ</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{スラッシュ}other{# 個のスラッシュ}}</translation>
-<translation id="4547556996012970016">次のレベル 5 見出し</translation>
-<translation id="4562381607973973258">見出し</translation>
-<translation id="4591507479202817876">、選択済み</translation>
-<translation id="4597532268155981612">フォーム</translation>
-<translation id="4597896406374528575">4 月</translation>
-<translation id="4615592953348396470">次に押すキーを無視します</translation>
-<translation id="461613135510474570">文</translation>
-<translation id="4647836961514597010">色の選択</translation>
-<translation id="4661075872484491155">ツリー</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">グリッド</translation>
-<translation id="4693675773662933727">前のランドマーク</translation>
-<translation id="4696413482802371445">次のレベル 5 見出しはありません。</translation>
-<translation id="4729095194763193578">表の前の行</translation>
-<translation id="4736221692378411923">8 月</translation>
-<translation id="4740661827607246557">ヘルプ コマンド</translation>
-<translation id="4759716709594980008">ChromeOS キーボード エクスプローラ</translation>
-<translation id="4763296182459741068">最後に戻ります</translation>
-<translation id="4763480195061959176">動画</translation>
-<translation id="479989351350248267">検索</translation>
-<translation id="481165870889056555">現在のページのタイトルを読み上げる</translation>
-<translation id="4826415162591436065">順方向にナビゲート</translation>
-<translation id="4826604887384865800">次のジャンプ</translation>
-<translation id="4827410568042294688">選択していません</translation>
-<translation id="4842108708071771135">次の引用箇所はありません。</translation>
-<translation id="4848993367330139335">タイマー</translation>
-<translation id="4850023505158945298">前の類似の要素。</translation>
-<translation id="4866956062845190338">メニュー項目のラジオボタン</translation>
-<translation id="4867316986324544967">TTS ログを有効にする</translation>
-<translation id="4877261390094455813">検索キーワードを入力してください。</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">内部リンク</translation>
-<translation id="4953585991029886728">テキスト編集</translation>
-<translation id="4954534434583049121">前の引用文</translation>
-<translation id="4973717656530883744">最小 <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> に切り替えました。</translation>
-<translation id="4975416682604111799">ミリ秒</translation>
-<translation id="49787999531187221">ChromeVox は現在無効です。</translation>
-<translation id="4979404613699303341">前のボタン</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />、<ph name="NAME" />、リスト ボックス</translation>
-<translation id="4983588134362688868">ページの先頭に移動します</translation>
-<translation id="4986606102545753256"><ph name="NAME" />、ウィンドウ</translation>
-<translation id="4993152509206108683">速度 <ph name="PERCENT" /> パーセント</translation>
-<translation id="4996716799442435517">ビジュアル</translation>
-<translation id="4997282455736854877"><ph name="NAME" />、選択されたラジオボタン</translation>
-<translation id="4997475792277222884">リンクでない次の項目はありません。</translation>
-<translation id="5000760171916499057">フォームがありません。</translation>
-<translation id="5005670136041063723">この他に類似の要素はありません。</translation>
-<translation id="501473567976723023">1 月</translation>
-<translation id="5041394372352067729">ブライユ点字表示をページ上部に移動</translation>
-<translation id="5042770794184672516">読み上げの音量を上げる</translation>
-<translation id="5050015258024679800">前のレベル 4 見出し</translation>
-<translation id="5054047268577924192">前のリスト項目</translation>
-<translation id="5078661581131202757">ファイル選択</translation>
-<translation id="5080758118274074384">ダブルクリックしました</translation>
-<translation id="5098541983634824365">グリッドから離れます。</translation>
-<translation id="5102981729317424850">ツールバー</translation>
-<translation id="5105050547967751155">必須</translation>
-<translation id="5110983769041734144">前のフォーム フィールドはありません。</translation>
-<translation id="5111640677200759579">列見出し</translation>
-<translation id="5117636609870536415">メールアドレスを編集</translation>
-<translation id="5136967254288895616">前のリンクはありません。</translation>
-<translation id="513774504516943387">リンク</translation>
-<translation id="517143700877085897">、選択されていません</translation>
-<translation id="5183440668879371625">ブライユ点字の前の行</translation>
-<translation id="5184944171021383281">次のフォーム フィールドはありません。</translation>
-<translation id="5189244881767082992">行</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> は既にコマンドに割り当てられています。</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> リスト。</translation>
-<translation id="520883772648104506">次のラジオボタンはありません。</translation>
-<translation id="5263344797180442561">見出し 2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">オブジェクト</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />、タブ</translation>
-<translation id="5310788376443009632">次の内容を削除しました:</translation>
-<translation id="5320727453979144100">スティッキー モードは有効</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{カンマ}other{# 個のカンマ}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />、テキスト ボックス</translation>
-<translation id="5330443287809544590"><ph name="NAME" />、リンク</translation>
-<translation id="5336381510091010269">リストのインライン オートコンプリート</translation>
-<translation id="536031132345979795">連続読み上げ時に後方へスキップします</translation>
-<translation id="5368000168321181111">イアコン オフ</translation>
-<translation id="5374320867641260420">次のボタンはありません。</translation>
-<translation id="5382299583965267720">次のレベル 1 見出しはありません。</translation>
-<translation id="5402367795255837559">点字</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{セミコロン}other{# 個のセミコロン}}</translation>
-<translation id="5411891038905756502">前のジャンプ ポイントはありません。</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{小なり}other{# 個の小なり記号}}</translation>
-<translation id="5455441614648621694">補足的情報</translation>
-<translation id="5485036206801896268">前の図はありません。</translation>
-<translation id="5486947920110100234">次のジャンプ ポイントはありません。</translation>
-<translation id="549602578321198708">単語</translation>
-<translation id="5500932716852106146">前の編集可能テキスト フィールドはありません。</translation>
-<translation id="5502713021410870035">9 月</translation>
-<translation id="5507663321906818013">デバッグ ベンチマーク</translation>
-<translation id="5518443085409638729">テキスト編集時のカーソルは文字の間に置く(Mac OS X と同様)。</translation>
-<translation id="552195134157544755">ラジオボタン</translation>
-<translation id="5534303576632885660">ヘッダー</translation>
-<translation id="5546092960038624944">前のレベル 5 見出しはありません。</translation>
-<translation id="556042886152191864">ボタン</translation>
-<translation id="5561345396546889625">次のリスト</translation>
-<translation id="5562645715554321347">見出しグループ</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">テキスト編集、メール エントリ</translation>
-<translation id="5597170376237141345">次のチェックボックス</translation>
-<translation id="5597933780944041114">次の見出しはありません。</translation>
-<translation id="5598905979683743333"><ph name="NAME" />、選択されていないラジオボタン</translation>
-<translation id="5601172225407283979">デフォルトの操作を実行します</translation>
-<translation id="5608798115546226984">オートコンプリートはインライン表示</translation>
-<translation id="561939826962581046">日時</translation>
-<translation id="5623778242535476823">ラジオボタン</translation>
-<translation id="5623842676595125836">ログ</translation>
-<translation id="5628125749885014029">見出し 4</translation>
-<translation id="5637871198229500030">前の表はありません。</translation>
-<translation id="5655682562155942719">ジャンプ コマンド</translation>
-<translation id="56637627897541303">テキスト領域</translation>
-<translation id="5678161956734658133">メールを編集</translation>
-<translation id="5681643281275621376">定義</translation>
-<translation id="5682113568322255809">ランドマーク</translation>
-<translation id="5683155931978483559">前のチェックボックス</translation>
-<translation id="5684277895745049190">リスト</translation>
-<translation id="5700650669149824506">前のレベル 4 見出しはありません。</translation>
-<translation id="5709192780268610569">長い説明はありません</translation>
-<translation id="5712244464475377681">ポップアップ ボタン</translation>
-<translation id="5712338278108304766">表の次の列</translation>
-<translation id="571866080859340309">グループを検索しています</translation>
-<translation id="5728409797179002635">表が見つかりません。</translation>
-<translation id="5748623122140342504">前のレベル 5 見出し</translation>
-<translation id="5750633686117194034">修飾キーが押されていません。設定する修飾キーを押してください。2 つ以上の場合は同時に押します。指を離すとキーの設定が音声で通知されます。終了するには Tab キーを押します。</translation>
-<translation id="5788275253279308023">シークレット ウィンドウ <ph name="TITLE" /> タブ</translation>
-<translation id="5806206155699461681">特定のサイト(Google 検索など)の利便性を高めます。</translation>
-<translation id="5819072574982403430">ツリー項目</translation>
-<translation id="5826479389509458994">行 <ph name="ROW" /> 列 <ph name="COL" /></translation>
-<translation id="5850707923114094062">後方にパンします</translation>
-<translation id="5851548754964597211">タブ リスト</translation>
-<translation id="5859752971144398932">ページ内検索を終了しました。</translation>
-<translation id="5866042630553435010">一部オン</translation>
-<translation id="5869546221129391014">グリッド</translation>
-<translation id="5876817486144482042">読み上げの音量を下げる</translation>
-<translation id="5887397643266327462">ブライユ点字の表示が有効になっています。</translation>
-<translation id="5891934789323004067">表</translation>
-<translation id="5919442531159595654">コピーします。</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{等号}other{# 個の等号}}</translation>
-<translation id="5939518447894949180">リセット</translation>
-<translation id="5948123859135882163">数式の解釈を、構文と意味の間で切り替えます</translation>
-<translation id="5955304353782037793">アプリ</translation>
-<translation id="5956928062748260866">ダイアログ</translation>
-<translation id="5963413905009737549">セクション</translation>
-<translation id="5968607524793740041">コンテキスト メニューを表示</translation>
-<translation id="5983179082906765664">一度に移動する単位を小さくする</translation>
-<translation id="5999630716831179808">音声</translation>
-<translation id="6000417740266304866">現在の 8 点点字表を変更するには、下のリストからオプションを選択します。</translation>
-<translation id="6006050241733874051">フォーム</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{バックスラッシュ}other{# 個のバックスラッシュ}}</translation>
-<translation id="6037602951055904232">前方にパンします</translation>
-<translation id="611827076493383239">アクセス済み</translation>
-<translation id="6119955456199054975">ここでセルは終わりです。</translation>
-<translation id="6122013438240733403">ボタン</translation>
-<translation id="6129953537138746214">スペース</translation>
-<translation id="6142308968191113180">見出し 4</translation>
-<translation id="6169420925157477918">長い説明付きの画像です</translation>
-<translation id="6172087735260766220">コピー プロテクトのかかった PDF 上のアクセス可能なテキストにアクセスできません。</translation>
-<translation id="6186305613600865047">ページの最後に移動します</translation>
-<translation id="6193330012414963395">AM/PM</translation>
-<translation id="622484624075952240">下矢印キー</translation>
-<translation id="6236061028292614533">次の見出し</translation>
-<translation id="6254901459154107917">次の編集可能テキスト領域</translation>
-<translation id="6259464875943891919"><ph name="TYPE" />の外に出ました。</translation>
-<translation id="6281876499889881039">次の類似の要素。</translation>
-<translation id="6282062888058716985">ナビ</translation>
-<translation id="6290434000785343030">次のコンボ ボックスはありません。</translation>
-<translation id="6307969636681130414">オン</translation>
-<translation id="6324551002951139333">文法の誤りが見つかりました</translation>
-<translation id="6348657800373377022">コンボ ボックス</translation>
-<translation id="6355910664415701303">前のリスト項目はありません。</translation>
-<translation id="6364795331201459219">見出し 6</translation>
-<translation id="6368143427468974988">前の見出し</translation>
-<translation id="6387719785439924554">別記</translation>
-<translation id="6411426777058107714">前のラジオボタンはありません。</translation>
-<translation id="6414968628640960377">前の異なる要素。</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{コロン}other{# 個のコロン}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />、メニュー</translation>
-<translation id="6444046323172968959">アラート ダイアログ</translation>
-<translation id="6459511626086141404">フラット キーマップ</translation>
-<translation id="6468049171101508116">次のボタン</translation>
-<translation id="6491972999578897419">下のリストからオプションを選択して、現在の音声を変更できます。</translation>
-<translation id="6508059270146105198">ブライユ点字表示をページ下部に移動</translation>
-<translation id="6536864053412760904">MathML トークン</translation>
-<translation id="6550720799683018100">下のリストからオプションを選択して、現在のキーマップを変更できます。</translation>
-<translation id="6561818612645211875">現在の行の先頭に移動</translation>
-<translation id="6587021927234520429">次のレベル 4 見出しはありません。</translation>
-<translation id="6601344353291556895">詳細な説明を有効にする。</translation>
-<translation id="6615602925644411249">ページ内検索です。</translation>
-<translation id="6633350132811819843">次の表はありません。</translation>
-<translation id="6637586476836377253">ログ</translation>
-<translation id="6657128831881431364">プログレスバー</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">ドキュメント</translation>
-<translation id="6697092096875747123">前のコンボ ボックス</translation>
-<translation id="6714813999819678458">前のレベル 2 見出し</translation>
-<translation id="6716505898850596801">修飾キー</translation>
-<translation id="671916444866103745">次の ARIA ランドマークはありません。</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />、コンボ ボックス</translation>
-<translation id="6735257939857578167">(<ph name="NUM" /> 個の項目)</translation>
-<translation id="6736510033526053669">タブが作成されました</translation>
-<translation id="675895815784134693">進行状況バー</translation>
-<translation id="6786800275320335305">記事</translation>
-<translation id="6787839852456839824">キーボード ショートカット</translation>
-<translation id="6793101435925451627">リスト ボックス</translation>
-<translation id="6833103209700200188">フッター</translation>
-<translation id="6871161210040114857">大文字と小文字を区別しません。</translation>
-<translation id="6877435256196695200">次の図はありません。</translation>
-<translation id="6897341342232909480">左へ移動</translation>
-<translation id="6901540140423170855">日付</translation>
-<translation id="6910211073230771657">削除済み</translation>
-<translation id="6911965441508464308">上にセルはありません。</translation>
-<translation id="6919104639734799681">表リストを表示</translation>
-<translation id="6964088412282673743">前のコントロールはありません。</translation>
-<translation id="6996566555547746822">次のコンボ ボックス</translation>
-<translation id="7005146664810010831">URL が見つかりません</translation>
-<translation id="7010712454773919705">ChromeVox 修飾キー</translation>
-<translation id="7031651751836475482">リスト項目</translation>
-<translation id="7037042857287298941">前のリスト</translation>
-<translation id="7041173719775863268">選択を終了</translation>
-<translation id="7095834689119144465">数字のみのテキスト編集</translation>
-<translation id="7096001299300236431">前のメディア</translation>
-<translation id="7116595520562830928">複数行</translation>
-<translation id="712735679809149106">単語読み上げ</translation>
-<translation id="713824876195128146">次の引用文</translation>
-<translation id="7161771961008409533">ポップアップ ボタン</translation>
-<translation id="7167657087543110">文字読み上げ</translation>
-<translation id="7170733337935166589">連続読み上げ時に前方へスキップします</translation>
-<translation id="7181697990050180700">下の対応するフィールドに入力して、頻繁に使用するコマンドのキーボード ショートカットをカスタマイズできます。</translation>
-<translation id="7203150201908454328">展開表示中</translation>
-<translation id="7210211103303402262">分</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">行</translation>
-<translation id="7226216518520804442">リスト</translation>
-<translation id="72393384879519786">見出し</translation>
-<translation id="7241683698754534149">長い説明を新しいタブで開きます</translation>
-<translation id="7248671827512403053">アプリケーション</translation>
-<translation id="725969808843520477">次のラジオボタン</translation>
-<translation id="7269119382257320590">句読点を読み上げません</translation>
-<translation id="7273174640290488576">空白</translation>
-<translation id="7285387653379749618">表</translation>
-<translation id="7289186959554153431">見出し 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" />(<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">ツリー項目</translation>
-<translation id="731576946540457939">ブライユ点字の表示が無効になっています。</translation>
-<translation id="7318872822751139669">マウスを使用してフォーカスを変更する。</translation>
-<translation id="7322388933135261569">2 月</translation>
-<translation id="7332592614823088566">行 <ph name="ROWINDEX" />/<ph name="ROWTOTAL" />、列 <ph name="COLINDEX" />/<ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">ポップアップあり</translation>
-<translation id="7356165926712028380">8 点点字に切り替え</translation>
-<translation id="7362871137496673139">前のレベル 2 見出しはありません。</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{アンパサンド}other{# 個のアンパサンド}}</translation>
-<translation id="737396357417333429">クリック可能</translation>
-<translation id="7374104575779636480">表から移動します。</translation>
-<translation id="739763518212184081">前の行</translation>
-<translation id="7400575256015741911">スペルミスが見つかりました</translation>
-<translation id="7408482676469142474">表</translation>
-<translation id="7425395583360211003">改行</translation>
-<translation id="7434509671034404296">開発/管理</translation>
-<translation id="7439060726180460871">ディレクトリ</translation>
-<translation id="744163271241493234">パスワードを編集</translation>
-<translation id="7491962110804786152">タブ</translation>
-<translation id="7492049978501397201">ダイアログを入力しました</translation>
-<translation id="7532613204005497612">6 月</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />、<ph name="NAME" />、スライダ</translation>
-<translation id="7586163296341959563">貼り付けます。</translation>
-<translation id="7596919493010894443">選択をクリアしました</translation>
-<translation id="7604026522577407655">現在の列の先頭に移動</translation>
-<translation id="7604451927827590395">見出し</translation>
-<translation id="7609342235116740824">現在のページの URL を読み上げる</translation>
-<translation id="7609363189280667021">ブライユ点字キャプションを切り替える</translation>
-<translation id="762020119231868829">現在再生中のメディア ウィジェットをすべて一時停止します</translation>
-<translation id="7625690649919402823">次の表</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" />(<ph name="VARIANT" />)、グレード <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">前のレベル 3 見出しはありません。</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />、<ph name="NAME" />、テキスト ボックス</translation>
-<translation id="7663318257180412551">見出し 2</translation>
-<translation id="7674576868851035240">次のリンク</translation>
-<translation id="7674768236845044097">マーク</translation>
-<translation id="7684431668231950609">テキスト編集、URL エントリ</translation>
-<translation id="7685589220304187312">ツールバー</translation>
-<translation id="7693840228159394336">前のラジオボタン</translation>
-<translation id="7701196182766842984">リストのオートコンプリート</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />、<ph name="NAME" />、パスワード テキスト ボックス</translation>
-<translation id="7805247615045262757">デフォルトのナビゲーション</translation>
-<translation id="7805768142964895445">ステータス</translation>
-<translation id="7810781339813764006">次のグループ</translation>
-<translation id="7819187121850078213">ウィンドウ <ph name="TITLE" /> タブ</translation>
-<translation id="7828956995407538686">10 月</translation>
-<translation id="7839679365527550018">前の単語</translation>
-<translation id="7851816175263618915">一部の句読点を読み上げます</translation>
-<translation id="7870596830398826354">MathML ツリー</translation>
-<translation id="78826985582142166">スライダ</translation>
-<translation id="7894517696028036636">ChromeVox クラシックを切り替えます。</translation>
-<translation id="7895896691902835279">不明なリンク</translation>
-<translation id="7927711904086083099">選択されていません</translation>
-<translation id="7935627501098484003">日時コントロール</translation>
-<translation id="7939428177581522200">選択範囲に追加しました</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{アットマーク}other{# 個のアットマーク}}</translation>
-<translation id="7965147473449754028">メニューを閉じました</translation>
-<translation id="7974390230414479278">メニュー項目</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{感嘆符}other{# 個の感嘆符}}</translation>
-<translation id="8007540374018858731">見出し 3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{引用符}other{# 個の引用符}}</translation>
-<translation id="8033827949643255796">選択しました</translation>
-<translation id="8035962149453661158">最大: <ph name="X" /></translation>
-<translation id="8042761080832772327">テキスト編集、検索エントリ</translation>
-<translation id="8049189770492311300">タイマー</translation>
-<translation id="8065607967589909823">現在選択しているのは、</translation>
-<translation id="8066678206530322333">バナー</translation>
-<translation id="8110647606445335195">ARIA ランドマークはありません。</translation>
-<translation id="8153880621934657047">表の中ではありません。</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{アンダースコア}other{# 個のアンダースコア}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">切り取ります。</translation>
-<translation id="8199231515320852133">現在のセルの見出しを読み上げる</translation>
-<translation id="820417203470636242">セルは空欄です。</translation>
-<translation id="8215202828671303819">複数選択可</translation>
-<translation id="8276439074553447000">前のフォーカス可能項目にジャンプ</translation>
-<translation id="8278417001922463147">前の記事はありません。</translation>
-<translation id="8283603667300770666">次のフォーム フィールド</translation>
-<translation id="831207808878314375">定義</translation>
-<translation id="8313653172105209786">ディレクトリ</translation>
-<translation id="8344569602005188545">時間</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{ポンド}other{# 個のポンド記号}}</translation>
-<translation id="8374154622594089836">月</translation>
-<translation id="8378855320830505539">地域</translation>
-<translation id="8382679411218029383">オートコンプリートはインライン表示とリスト形式の両方</translation>
-<translation id="8428603554127842284"><ph name="DEPTH" /> 階層</translation>
-<translation id="842922884199979200">次のレベル 3 見出しはありません。</translation>
-<translation id="8430049249787218991">メニューバー</translation>
-<translation id="844681116543532394">前のチェックボックスはありません。</translation>
-<translation id="8455868257606149352">最大値 <ph name="X" /></translation>
-<translation id="84575901236241018">アクセス キー <ph name="KEY" /> があります</translation>
-<translation id="8503360654911991865">一度に移動する単位を大きくする</translation>
-<translation id="8520472399088452386">スピンボタン</translation>
-<translation id="8538744478902126321">現在のセルの行見出しを推測</translation>
-<translation id="8540054775867439484">先頭に戻ります</translation>
-<translation id="8548973727659841685">文字</translation>
-<translation id="8561322612995434619">ポップアップあり</translation>
-<translation id="8571096049907249734">複数選択</translation>
-<translation id="8584721346566392021">見出し 5</translation>
-<translation id="8587549812518406253">次のリスト項目</translation>
-<translation id="860150890330522909"><ph name="NAME" /> チェックボックスがオンです</translation>
-<translation id="8606621670302093223">日付の設定</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> 件の項目を選択しました</translation>
-<translation id="8638532244051952400">現在のセルの座標を読み上げる</translation>
-<translation id="8650576015643545550">前のリストはありません。</translation>
-<translation id="8653031188082306838">URL を編集</translation>
-<translation id="8653646212587894517">リンク リストを表示</translation>
-<translation id="8664519043722036194">秒</translation>
-<translation id="867187640362843212">見出し 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{パイプ}other{# 個のパイプ}}</translation>
-<translation id="8735450637152821465">選択を開始</translation>
-<translation id="8743786158317878347">表などの構造化コンテンツに入ります</translation>
-<translation id="8747966237988593539">番号付きリスト</translation>
-<translation id="8759334257841767240">次のリンクはありません。</translation>
-<translation id="8767968232364267681">次のレベル 4 見出し</translation>
-<translation id="8770473310765924354">表などの構造化コンテンツの外に出ます</translation>
-<translation id="8791025954632646584">セマンティクス オン</translation>
-<translation id="8796411681063377102">次のレベル 3 見出し</translation>
-<translation id="8808582214901541005">3 月</translation>
-<translation id="8825828890761629845">バナー</translation>
-<translation id="8851136666856101339">本文</translation>
-<translation id="8856538297388979332">上下の矢印キーでコマンドを確認し、Enter キーを押して有効にしてください</translation>
-<translation id="8864099967139188018">次のレベル 6 見出しはありません。</translation>
-<translation id="8882002077197914455">行見出し</translation>
-<translation id="8896347895970027998">ChromeVox の有効/無効を切り替えます。</translation>
-<translation id="8898516272131543774">句読点読み上げを切り替えます</translation>
-<translation id="8900148057318340779">プレフィックス キー</translation>
-<translation id="8908714597367957477">列見出し</translation>
-<translation id="8931936695772494138">見出しが空です</translation>
-<translation id="8937112856099038376">内部リンク</translation>
-<translation id="8940925288729953902">修飾キー</translation>
-<translation id="8943175951035496220">右にセルはありません。</translation>
-<translation id="8978496506222343566">ツールチップ</translation>
-<translation id="900114243503212879">ファイル</translation>
-<translation id="9027462562263121875">表がありません。</translation>
-<translation id="9040132695316389094">見出し 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">検索ウィジェットを切り替える</translation>
-<translation id="9065283790526219006">ポップアップあり</translation>
-<translation id="9077213568694924680">選択範囲から削除されています</translation>
-<translation id="9082874451376019682">前のスライダはありません。</translation>
-<translation id="9089864840575085222">入力読み上げを切り替えます</translation>
-<translation id="9107530006868467849">前のメディア ウィジェットはありません。</translation>
-<translation id="9108370397979208512">数式</translation>
-<translation id="9108589040018540527">スクロールバー</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{パーセント}other{# 個のパーセント記号}}</translation>
-<translation id="9115913704608474258">11 月</translation>
-<translation id="9128414153595658330">ダイアログ</translation>
-<translation id="9149560530563164529">セクション</translation>
-<translation id="9151211641321628915">現在位置の簡単な説明を読み上げます</translation>
-<translation id="9153606228985488238">ピッチ <ph name="PERCENT" /> パーセント</translation>
-<translation id="9160096769946561184">現在の列の末尾に移動</translation>
-<translation id="9173115498289768110">音量 <ph name="PERCENT" /> パーセント</translation>
-<translation id="9178973770513562274">上下の矢印キーでブラウジングするか、キーワードを入力して検索してください。</translation>
-<translation id="9192904702577636854">マーキー</translation>
-<translation id="9212322457209634662">次のセクションはありません。</translation>
-<translation id="930275611743429116">選択を開始または終了します。</translation>
-<translation id="948171205378458592">読み上げの速度を下げる</translation>
-<translation id="962913030769097253">次のレベル 1 見出し</translation>
-<translation id="973955474346881951">スティッキー モードを有効または無効にする</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_kn.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_kn.xtb
deleted file mode 100644
index a531dd8e8b6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_kn.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="kn">
-<translation id="1012173283529841972">ಪಟ್ಟಿಯ ಐಟಂ</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">ಸ್ಪ್ಯಾನ್ ಮಾಡಲಾಗಿದೆ.</translation>
-<translation id="1025074108959230262">ಸ್ಟಿಕಿ ಮೋಡ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation>
-<translation id="1031961866430398710">ನಂತರ</translation>
-<translation id="1044777062731150180">ಯಾವುದೇ ಶಿರೋನಾಮೆಗಳಿಲ್ಲ</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">ಅಮಾನ್ಯ ಇನ್‌ಪುಟ್</translation>
-<translation id="1082209053475788238">ಹಿಂದಿನ ಹಂತದ 6 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="1088219014394087294">ಯಾವುದೇ ಶೀರ್ಷಿಕೆಗಳಿಲ್ಲ.</translation>
-<translation id="1106741348836243114">ಧ್ವನಿ ಪ್ರತಿಕ್ರಿಯೆ (earcons) ಆನ್ ಅಥವಾ ಆಫ್ ಮಾಡಿ.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="NUM" /> ಐಟಂಗಳೊಂದಿಗೆ <ph name="TAG" /> ಸಂಗ್ರಹಣೆ</translation>
-<translation id="1155043339247954670">ಮುಂದಿನ ಯಾವುದೇ ಪಟ್ಟಿ ಐಟಂಯಿಲ್ಲ.</translation>
-<translation id="1157782847298808853">ಕೀಬೋರ್ಡ್ ಸಹಾಯ</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, ಕಾಂಬೊ ಬಾಕ್ಸ್</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, ಉಪಮೆನುವಿನೊಂದಿಗೆ, ಮೆನು ಐಟಂ</translation>
-<translation id="1177863135347784049">ಕಸ್ಟಮ್</translation>
-<translation id="1188858454923323853">ಪೂರಕವಾಗಿ</translation>
-<translation id="1206619573307042055">ಮಾರ್ಕ್ಯೂ</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome ಗೆ ಧ್ವನಿ ನೀಡುವುದು</translation>
-<translation id="1229276918471378188">ಹಿಂದಿನ ಜಂಪ್</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">ಮುಂದಿನ ಹಂತದ 6 ಶಿರೋನಾಮೆ</translation>
-<translation id="1275718070701477396">ಆಯ್ಕೆ ಮಾಡಿದ</translation>
-<translation id="1319608975892113573">ಹಿಂದಿನ ಬ್ಲಾಕ್‌ಕೋಟ್ ಇಲ್ಲ.</translation>
-<translation id="1321576897702511272">ChromeVox ಸಹಾಯವನ್ನು ಮರೆಮಾಡಿ</translation>
-<translation id="1331702245475014624"><ph name="TOTAL" /> / <ph name="INDEX" /></translation>
-<translation id="1334095593597963605">ಅಕ್ಷರ ಮತ್ತು ಪದ ಇಕೋ</translation>
-<translation id="1339428534620983148">ಹಿಂದಿನ ಕೋಷ್ಟಕದ ಕಾಲಮ್</translation>
-<translation id="1342835525016946179">ಲೇಖನ</translation>
-<translation id="1346748346194534595">ಬಲಕ್ಕೆ</translation>
-<translation id="136718599399906424">ಮುಂದಿನ ಕೋಷ್ಟಕ ಸಾಲು</translation>
-<translation id="1383876407941801731">ಹುಡುಕಾಟ</translation>
-<translation id="1385214448885562192">ಸಮ್ಮತಿಸಲು enter ಒತ್ತಿರಿ ಅಥವಾ ರದ್ದುಗೊಳಿಸಲು escape ಒತ್ತಿರಿ, ಮುಂದಿನದ್ದಕ್ಕೆ ಹೋಗಲು ಕೆಳಕ್ಕೆ ಒತ್ತಿರಿ ಮತ್ತು ಹಿಂದಿನದ್ದಕ್ಕೆ ಹೋಗಲು ಮೇಲಕ್ಕೆ ಒತ್ತಿರಿ.</translation>
-<translation id="1396114365388024581">ಟ್ಯಾಬ್ ಪಟ್ಟಿ</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, ಪಾಸ್‌ವರ್ಡ್ ಪಠ್ಯ ಬಾಕ್ಸ್</translation>
-<translation id="1467432559032391204">ಎಡಕ್ಕೆ</translation>
-<translation id="1474557363159888097">ಹಿಂದಿನ ಆಧಾರವಿಲ್ಲ.</translation>
-<translation id="1502086903961450562">ಹಿಂದಿನ ಗ್ರಾಫಿಕ್</translation>
-<translation id="1506187449813838456">ಪಿಚ್ ಹೆಚ್ಚಿಸಿ</translation>
-<translation id="151784044608172266">ಮುಂದಿನ ವಾಕ್ಯ</translation>
-<translation id="1524531499102321782">ಬ್ರೈಲಿ ಮುಂದಿನ ಸಾಲು</translation>
-<translation id="1546370775711804143">ಸ್ಕ್ರಾಲ್ ಪಟ್ಟಿ</translation>
-<translation id="1559739829547075274">ಹಿಂದಕ್ಕೆ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ</translation>
-<translation id="1571643229714746283">ChromeVox ಸಿದ್ಧವಾಗಿದೆ</translation>
-<translation id="158493514907962286">ಡಿಸೆಂಬರ್</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6 ಡಾಟ್‌ ಬ್ರೈಲಿಗೆ ಬದಲಿಸಿ</translation>
-<translation id="1611168825862729585">ಕಾಲಮ್ ಶಿರೋನಾಮೆ:</translation>
-<translation id="1613476421962910979">Earcons ಆನ್ ಆಗಿದೆ</translation>
-<translation id="1618597272655350600">ಪ್ರಸ್ತುತ ಸ್ಥಾನದ ಸಂಪೂರ್ಣ ವಿವರಣೆಯನ್ನು ಪ್ರಕಟಿಸುತ್ತದೆ</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{ಹೆಚ್ಚು ಸೂಚಕ}one{# ಹೆಚ್ಚು ಸೂಚಕ ಚಿಹ್ನೆಗಳು}other{# ಹೆಚ್ಚು ಸೂಚಕ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="1653266918374749391">ಹಿಂದಿನ ಹಂತದ 3 ಶಿರೋನಾಮೆ</translation>
-<translation id="1659072772017912254">ಪರೀಕ್ಷಿಸಲಾಗಿಲ್ಲ</translation>
-<translation id="1669290819662866522">ವಾರ</translation>
-<translation id="1674262202423278359">ChromeVox ನ್ಯಾವಿಗೇಷನ್</translation>
-<translation id="16777221443363124">ಮೆನು ಬಾರ್‌</translation>
-<translation id="1692077714702418899">ವ್ಯವಸ್ಥಿತ ಸಾಲು</translation>
-<translation id="1700517974991662022">ಭೇಟಿ ನೀಡಲಾಗಿದೆ</translation>
-<translation id="1722567105086139392">ಲಿಂಕ್</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">ಮುಂದಿನ ಗ್ರಾಫಿಕ್</translation>
-<translation id="1781173782405573156">ಕೀ ಮೂಲಕ ಹಾದುಹೋಗುತ್ತವೆ</translation>
-<translation id="1787176709638001873">ಪಾಸ್‌ವರ್ಡ್ ಸಂಪಾದನೆ ಪಠ್ಯ</translation>
-<translation id="1810107444790159527">ಪಟ್ಟಿಯ ಬಾಕ್ಸ್</translation>
-<translation id="1828385960365606039">ಮೇ</translation>
-<translation id="1834891354138622109">ಕಾಲಮ್</translation>
-<translation id="1865601187525349519">ಪಠ್ಯದ ಕೊನೆ</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">ಪ್ರಸ್ತುತ ಸಮಯ ಮತ್ತು ದಿನಾಂಕವನ್ನು ಮಾತನಾಡಿ.</translation>
-<translation id="1902396333223336119">ಸೆಲ್</translation>
-<translation id="1905379170753160525">ಶಿರೋನಾಮೆಗಳ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">ವರ್ಷದ ವಾರದ ನಿಯಂತ್ರಣ</translation>
-<translation id="1964135212174907577">ಮುಂದಿನ ವಿಷಯ</translation>
-<translation id="1969092762068865084">ಜುಲೈ</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">ಸಾಲಿನ ಶಿರೋನಾಮೆ:</translation>
-<translation id="2002895034995108595">ಪ್ರಸ್ತುತ ಕೀಮ್ಯಾಪ್ ಮರುಹೊಂದಿಸಿ</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{ಎಡ ಆವರಣ}one{# ಎಡ ಆವರಣಗಳು}other{# ಎಡ ಆವರಣಗಳು}}</translation>
-<translation id="2045490512405922022">ಗುರುತಿಸಲಾಗಿಲ್ಲ</translation>
-<translation id="20601713649439366">ಯಾವುದೇ ಹಿಂದಿನ ಗಣಿತ ಅಭಿವ್ಯಕ್ತಿ ಇಲ್ಲ.</translation>
-<translation id="207477615537953741">ಶಬ್ದಾರ್ಥಗಳು ಆಫ್ ಆಗಿದೆ</translation>
-<translation id="2086961585857038472">ಮುಂದಿನ ಪದ</translation>
-<translation id="2089387485033699258">kn</translation>
-<translation id="2091933974477985526">ಹಿಂದಿನದನ್ನು ಸಂಪಾದಿಸಬಹುದಾದ ಪಠ್ಯ ಪ್ರದೇಶ</translation>
-<translation id="2100350898815792233">ಎಲ್ಲ ವಿರಾಮಚಿಹ್ನೆಗಳು</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">ಪ್ರವೇಶ ಕೀ:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">ಕೆಳಗಿನ ಪಟ್ಟಿಯಿಂದ ಆಯ್ಕೆಯೊಂದನ್ನು ಆಯ್ಕೆ ಮಾಡುವ ಮೂಲಕ ಪ್ರಸ್ತುತ 6 ಡಾಟ್ ಬ್ರೈಲಿ ಕೋಷ್ಟಕವನ್ನು ಬದಲಾಯಿಸಿ.</translation>
-<translation id="2169714232367507776">ಪ್ರಸ್ತುತ ಐಟಂ ಕ್ಲಿಕ್ ಮಾಡಿ</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{ಮುಚ್ಚಿದ ಆವರಣ}one{# ಮುಚ್ಚಿದ ಆವರಣಗಳು}other{# ಮುಚ್ಚಿದ ಆವರಣಗಳು}}</translation>
-<translation id="2199994615414171367">ಹಿಂದಿನ ಗಣಿತ</translation>
-<translation id="2223693656926968778">ಪ್ರಸ್ತುತ ಐಟಂ ಕುರಿತು ಕ್ರಮ ಕೈಗೊಳ್ಳಿ</translation>
-<translation id="225732394367814946">ಮಾತಿನ ಪ್ರಮಾಣವನ್ನು ಹೆಚ್ಚಿಸಿ</translation>
-<translation id="2267945578749931355">ಮುಂದಿನ ಅಕ್ಷರ</translation>
-<translation id="2281234842553884450">ಹಿಂದಿನ ಸ್ಲೈಡರ್</translation>
-<translation id="2318372665160196757">ಮುಖ್ಯ</translation>
-<translation id="2329324941084714723">ಟ್ಯಾಬ್ ಫಲಕ</translation>
-<translation id="2344193891939537199">ದಿನಾಂಕ ಸಮಯ ನಿಯಂತ್ರಣ</translation>
-<translation id="2359897517538099099">ಕೋಷ್ಟಕದ ಮೋಡ್‌‌ನಲ್ಲಿ ಇಲ್ಲ.</translation>
-<translation id="241124561063364910">ಇದರ ನಂತರ</translation>
-<translation id="2417569100218200841">ವಿಷಯ ಮಾಹಿತಿ</translation>
-<translation id="2422937916923936891">ಮೆನು ಐಟಂ ಚೆಕ್‌ಬಾಕ್ಸ್</translation>
-<translation id="2429669115401274487">ಸಂಜೆ</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> ಇದೀಗ ಹೊಸ ChromeVox ಮಾರ್ಪಡಿಸುವಿಕೆಯಾಗಿದೆ.</translation>
-<translation id="2450814015951372393">ಚೆಕ್‌ಬಾಕ್ಸ್</translation>
-<translation id="2462626033734746142">ರೇಡಿಯೊ ಬಟನ್ ಗುಂಪು</translation>
-<translation id="2471138580042810658">ಶೀರ್ಷಿಕೆ 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{ನಕ್ಷತ್ರ ಚಿಹ್ನೆ}one{# ನಕ್ಷತ್ರ ಚಿಹ್ನೆಗಳು}other{# ನಕ್ಷತ್ರ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗಿದೆ.</translation>
-<translation id="2553108862507765288">ವ್ಯಾಕರಣ ದೋಷ</translation>
-<translation id="257674075312929031">ಗುಂಪು</translation>
-<translation id="2582407057977008361">ಹೊರತಾಗಿ</translation>
-<translation id="2589102159832527089">PDF ಫೈಲ್‌ನಿಂದ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಬೇರ್ಪಡಿಸಲಾಗಿರುವ ಪಠ್ಯವನ್ನು ಈ ಪುಟ ಒಳಗೊಂಡಿದೆ &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;.&lt;a href="<ph name="URL" />"&gt;ಮೂಲಕ್ಕಾಗಿ ಇಲ್ಲಿ ಕ್ಲಿಕ್ ಮಾಡಿ.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">ಜೊತೆ {COUNT,plural, =1{# ಐಟಂ}one{# ಐಟಂಗಳು}other{# ಐಟಂಗಳು}}</translation>
-<translation id="2614981083756825552">ಗಣಿತ ML ಲೇಔಟ್</translation>
-<translation id="2626530649491650971">ಕ್ಲಿಕ್ ಮಾಡಬಹುದಾದ</translation>
-<translation id="2628764385451019380">ಮುಂದಿನ ಕಾಂಬೊ ಪೆಟ್ಟಿಗೆಯಿಲ್ಲ.</translation>
-<translation id="2637227747952042642">ಗಣಿತ</translation>
-<translation id="2639750663247012216">ChromeVox ಪರಿವರ್ತಕ</translation>
-<translation id="2644542693584024604">ತಪ್ಪು ಕಾಗುಣಿತ</translation>
-<translation id="2667291555398229137">ರೂಟಿಂಗ್ ಕೀ ಅಡಿಯಲ್ಲಿ ಐಟಂ ಕ್ಲಿಕ್ ಮಾಡಿ</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{ತೆರೆದ ಆವರಣ}one{# ತೆರೆದ ಆವರಣಗಳು}other{# ತೆರೆದ ಆವರಣಗಳು}}</translation>
-<translation id="2705875883745373140">ಒತ್ತಿಲ್ಲ</translation>
-<translation id="2706462751667573066">ಮೇಲಕ್ಕೆ</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ಆಡಿಯೋ</translation>
-<translation id="2732718972699418926">ಬೆಳಿಗ್ಗೆ</translation>
-<translation id="2749275490991666823">ಗುರುತಿಸಲಾಗಿದೆ</translation>
-<translation id="27527859628328957">ಮುಂದೆ ಗಮನಹರಿಸಬಹುದಾದ ಐಟಂಗೆ ಹೋಗಿ</translation>
-<translation id="2770781857296573485">ಗುಂಪು ಪರಿಶೋಧನೆಯನ್ನು ನಮೂದಿಸಿ</translation>
-<translation id="2777845298774924149">ನಿರ್ಗಮಿಸಲಾಗಿದೆ</translation>
-<translation id="2800204403141299078">ಹೆಚ್ಚಿನ ವಿಭಿನ್ನ ಅಂಶಗಳಿಲ್ಲ.</translation>
-<translation id="2800780099804980316">ಹಿಂದಿನ ಹಂತದ 1 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="2811204574343810641">ಸಾಲು</translation>
-<translation id="2816654101880605877">ಮುಂದಿನ ಸ್ಲೈಡರ್ ಇಲ್ಲ.</translation>
-<translation id="2841013758207633010">ಸಮಯ</translation>
-<translation id="2843837985843789981">ಹಿಂದಿನ ಗುಂಪು</translation>
-<translation id="2844995807198708617">ಸಂದರ್ಭ ಮೆನು</translation>
-<translation id="2849332794118375855">ಮುಂದಿನ ಚೆಕ್‌ಬಾಕ್ಸ್ ಇಲ್ಲ.</translation>
-<translation id="2864481629947106776">ಹಿಂದಿನ ಲಿಂಕ್</translation>
-<translation id="2873259058405069099">ಕೋಷ್ಟಕದ ಆರಂಭಕ್ಕೆ ಹೋಗಿ</translation>
-<translation id="2894654529758326923">ಮಾಹಿತಿ</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{ಎಡ ಪುಷ್ಪಾವರಣ}one{# ಎಡ ಪುಷ್ಪಾವರಣಗಳು}other{# ಎಡ ಪುಷ್ಪಾವರಣಗಳು}}</translation>
-<translation id="2911433807131383493">ChromeVox ಟ್ಯುಟೋರಿಯಲ್ ತೆರೆಯಿರಿ</translation>
-<translation id="2932083475399492303">ವ್ಯವಸ್ಥಿತ ಅಥವಾ ಲೇಔಟ್ ನಡುವೆ ಸಾಲು ಪ್ರಕಾರವನ್ನು ಟಾಗಲ್ ಮಾಡಿ</translation>
-<translation id="2964026537669811554">ಶಿರೋನಾಮೆಯ ಗುಂಪು</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{ಟ್ಯಾಬ್}one{# ಟ್ಯಾಬ್‌ಗಳು}other{# ಟ್ಯಾಬ್‌ಗಳು}}</translation>
-<translation id="2972078295414139404">ಹಿಂದೆ ಯಾವುದೇ ಭೇಟಿ ನೀಡಿದ ಲಿಂಕ್ ಇಲ್ಲ.</translation>
-<translation id="2972205263822847197">ಟೂಲ್‌ ಟಿಪ್‌</translation>
-<translation id="2998131015536248178">ಹಿಂದಿನ ಅಕ್ಷರ</translation>
-<translation id="2999559350546931576">ಪಿಚ್ ಇಳಿಸಿ</translation>
-<translation id="2999945368667127852">ಯಾವುದೇ ಮುಂದಿನ ಮಾಧ್ಯಮ ವಿಜೆಟ್ ಇಲ್ಲ.</translation>
-<translation id="3012414509011670858">ಯಾವುದೇ ಹಿಂದಿನ ವಿಭಾಗವಿಲ್ಲ.</translation>
-<translation id="3030432017085518523">ಮೆನು ಐಟಂ ರೇಡಿಯೋ ಬಟನ್</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{ಸಂಬೋಧನೆಯ ಚಿಹ್ನೆ}one{# ಸಂಬೋಧನೆಯ ಚಿಹ್ನೆಗಳು}other{# ಸಂಬೋಧನೆಯ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="3046838483509668188">ChromeVox ಆಯ್ಕೆಗಳು</translation>
-<translation id="3047143736589213134">ಪ್ರಾಯೋಗಿಕ ಕೀಮ್ಯಾಪ್</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> ಮೆನು ತೆರೆಯಲಾಗಿದೆ</translation>
-<translation id="3078345202707391975">ಮುಂದಿನ ಹಂತದ 2 ಶಿರೋನಾಮೆ</translation>
-<translation id="3078740164268491126">ಕೋಷ್ಟಕ</translation>
-<translation id="3082557070674409251">ಕ್ಲಿಕ್ ಮಾಡಲಾಗಿದೆ</translation>
-<translation id="3084806535845658316">ಯಾವುದೇ ಟೈಪಿಂಗ್ ಎಕೋ ಇಲ್ಲ</translation>
-<translation id="3086746722712840547">ಟಿಪ್ಪಣಿ</translation>
-<translation id="308895241372589742">ಯಾವುದೇ ಮುಂದಿನ ಗಣಿತ ಅಭಿವ್ಯಕ್ತಿ ಇಲ್ಲ.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">ಮುಂದಿನ ಹೆಗ್ಗುರುತು</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">ಕುಗ್ಗಿಸಿದ</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">ಹೆಗ್ಗುರುತುಗಳ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">ಮುಂದಿನ ಸಾಲು</translation>
-<translation id="3155083529632865074">ಹಿಂದಿನ ಬಟನ್‌ ಇಲ್ಲ.</translation>
-<translation id="3163593631834463955">ಕಾಲಮ್ ಶಿರೋನಾಮೆ ಖಾಲಿಯಿದೆ</translation>
-<translation id="316542773973815724">ನ್ಯಾವಿಗೇಷನ್</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{ಅಂತರ}one{# ಅಂತರಗಳು}other{# ಅಂತರಗಳು}}</translation>
-<translation id="320961988183078793">ನಮೂದಿಸಲಾಗಿದೆ <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, ಟ್ಯಾಬ್</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">ಭೇಟಿ ನೀಡಿದ ಲಿಂಕ್</translation>
-<translation id="323731244387692321">ChromeVox ಕೀಬೋರ್ಡ್ ಸಹಾಯವನ್ನು ತೆರೆಯಿರಿ</translation>
-<translation id="3241052487511142956">ಹಿಂದಿನ ಭೇಟಿ ನೀಡಿದ ಲಿಂಕ್</translation>
-<translation id="3286390186030710347">ಸ್ಲೈಡರ್</translation>
-<translation id="3299925995433437805">ಮುಂದೆ ಯಾವುದೇ ಭೇಟಿ ನೀಡಿದ ಲಿಂಕ್ ಇಲ್ಲ.</translation>
-<translation id="3303384412438961941">ಈ ಹೆಸರನ್ನು ತಿಳಿಯಲು ಯಾವುದೇ ಕೀಯನ್ನು ಒತ್ತಿರಿ. Ctrl+W ಕೀಬೋರ್ಡ್ ಎಕ್ಸ್‌ಪ್ಲೋರರ್ ಅನ್ನು ಮುಚ್ಚುತ್ತದೆ.</translation>
-<translation id="3307886118343381874">ಕೋಷ್ಟಕದ ಅಂತ್ಯಕ್ಕೆ ಹೋಗಿ</translation>
-<translation id="3311969765485641742">ಎಚ್ಚರಿಕೆಗಳನ್ನು ಪರಿಶೀಸಲು Alt+Shift+A ಒತ್ತಿರಿ</translation>
-<translation id="3312997241656799641">ಮುಂದಿನ ಭೇಟಿ ನೀಡಿದ ಲಿಂಕ್</translation>
-<translation id="3321460131042519426">ವರ್ಡ್ ವ್ರ್ಯಾಪ್ ಸಕ್ರಿಯಗೊಳಿಸಿ</translation>
-<translation id="3322936298410871309">ಹಿಂದಿನ ಹಂತದ 1 ಶಿರೋನಾಮೆ</translation>
-<translation id="3323447499041942178">ಪಠ್ಯ ಪೆಟ್ಟಿಗೆ</translation>
-<translation id="3353420241558113817">{"ar": "ಅರೇಬಿಕ್",
- "bg": "ಬಲ್ಗೇರಿಯನ್",
- "ca": "ಕೆಟಲಾನ್",
- "cs": "ಜೆಕ್",
- "da": "ಡ್ಯಾನಿಶ್",
- "de": "ಜರ್ಮನ್",
- "de_CH": "ಜರ್ಮನ್ (ಸ್ವಿಟ್ಜರ್‌ಲ್ಯಾಂಡ್)",
- "de_DE": "ಜರ್ಮನ್ (ಜರ್ಮನಿ)",
- "el": "ಗ್ರೀಕ್",
- "en": "ಇಂಗ್ಲಿಷ್",
- "en_CA": "ಇಂಗ್ಲಿಷ್ (ಕೆನಡಾ)",
- "en_GB": "ಇಂಗ್ಲಿಷ್ (ಯುನೈಟೆಡ್ ಕಿಂಗ್‌ಡಮ್)",
- "en_US": "ಇಂಗ್ಲಿಷ್ (ಯುನೈಟೆಡ್ ಸ್ಟೇಟ್ಸ್)",
- "es": "ಸ್ಪ್ಯಾನಿಶ್",
- "et": "ಎಸ್ಟೊನಿಯನ್",
- "fr": "ಫ್ರೆಂಚ್",
- "fr_CA": "ಫ್ರೆಂಚ್ (ಕೆನಡಾ)",
- "fr_FR": "ಫ್ರೆಂಚ್ (ಫ್ರಾನ್ಸ್)",
- "fi": "ಫಿನ್ನಿಶ್",
- "he": "ಹಿಬ್ರೂ",
- "hi": "ಹಿಂದಿ",
- "hr": "ಕ್ರೊಯೇಶಿಯನ್",
- "hu": "ಹಂಗೇರಿಯನ್",
- "is": "ಐಸ್‌ಲ್ಯಾಂಡಿಕ್",
- "it": "ಇಟಾಲಿಯನ್",
- "ko": "ಕೊರಿಯನ್",
- "lt": "ಲಿಥುವೇನಿಯನ್",
- "lv": "ಲ್ಯಾಟ್ವಿಯನ್",
- "nb": "ನಾರ್ವೇಜಿಯನ್ ಬೊಕ್ಮಲ್",
- "nl": "ಡಚ್",
- "pl": "ಪೋಲಿಷ್",
- "pt": "ಪೋರ್ಚುಗೀಸ್",
- "ro": "ರೊಮೇನಿಯನ್",
- "ru": "ರಷ್ಯನ್",
- "sk": "ಸ್ಲೋವಾಕ್",
- "sl": "ಸ್ಲೋವೇನಿಯನ್",
- "sr": "ಸೆರ್ಬಿಯನ್",
- "sv": "ಸ್ವೀಡಿಷ್",
- "tr": "ಟರ್ಕಿಶ್",
- "vi": "ವಿಯೆಟ್ನಾಮೀಸ್",
- "zh": "ಚೈನೀಸ್",
- "zh_TW": "ಚೈನೀಸ್ (ಸಾಂಪ್ರದಾಯಿಕ ಹಾನ್)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{ಸಂಕಲನ}one{# ಸಂಕಲನ ಚಿಹ್ನೆಗಳು}other{# ಸಂಕಲನ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="338583716107319301">ವಿಭಾಜಕ</translation>
-<translation id="3389259863310851658">ಹಿಂದಿನ ಫಾರ್ಮ್ ಕ್ಷೇತ್ರ</translation>
-<translation id="3390225400784126843">ಮುಂದಿನ ವಿಭಿನ್ನ ಅಂಶ.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, ಮೆನು ಐಟಂ</translation>
-<translation id="3406283310380167331">ಫಾರ್ಮ್‌ಗಳ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ</translation>
-<translation id="3422338090358345848">ಕೀಬೋರ್ಡ್ ಎಕ್ಸ್‌ಪ್ಲೋರರ್ ಅನ್ನು ತೆರೆಯಿರಿ</translation>
-<translation id="3457000393508828486">ಭಾಗಶಃ ಒತ್ತಿದಾಗ</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, ಬಟನ್</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> ನಿಂದ <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{ಬಲ ಆವರಣ}one{# ಬಲ ಆವರಣಗಳು}other{# ಬಲ ಆವರಣಗಳು}}</translation>
-<translation id="3493915602752813531">ಮುಂದಿನ ಆಧಾರವಿಲ್ಲ.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{ಪ್ರಶ್ನಾರ್ಥಕ ಚಿಹ್ನೆ}one{# ಪ್ರಶ್ನಾರ್ಥಕ ಚಿಹ್ನೆಗಳು}other{# ಪ್ರಶ್ನಾರ್ಥಕ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{ಕ್ಯಾರೆಟ್}one{# ಕ್ಯಾರೆಟ್‌‌ಗಳು}other{# ಕ್ಯಾರೆಟ್‌‌ಗಳು}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, ಚೆಕ್‌ಬಾಕ್ಸ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿಲ್ಲ</translation>
-<translation id="3599054940393788245">ಮ್ಯಾಥ್ ಒಳಗೆ ಇಲ್ಲ</translation>
-<translation id="3616113530831147358">ಆಡಿಯೋ</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{ಬ್ಯಾಕ್‌ಟಿಕ್}one{# ಬ್ಯಾಕ್‌ಟಿಕ್‌ಗಳು}other{# ಬ್ಯಾಕ್‌ಟಿಕ್‌ಗಳು}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{ಡಾಲರ್}one{# ಡಾಲರ್ ಚಿಹ್ನೆಗಳು}other{# ಡಾಲರ್ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, ಪಟ್ಟಿಯ ಬಾಕ್ಸ್</translation>
-<translation id="3687295507293856493">ಪ್ರಸ್ತುತ ಸೆಲ್‌ನ ಕಾಲಮ್ ಶಿರೋನಾಮೆಯ ಬಗ್ಗೆ ಊಹೆ ಮಾಡಿ</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">ಮಾತಿನ ನಿಯಂತ್ರಣ</translation>
-<translation id="3716845769494773620">ಬಹು ಸಾಲು</translation>
-<translation id="3731746171184829332">ಹಿಂದಿನ ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="3762198587642264450">ಪ್ರಸ್ತುತ ಸಾಲಿನ ಅಂತ್ಯಕ್ಕೆ ಹೋಗಿ</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">ನಿರ್ಗಮಿಸಲಾದ ಸಂವಾದ.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">ಸ್ವಯಂಪೂರ್ಣಗೊಳಿಸುವಿಕೆ ಪಟ್ಟಿ</translation>
-<translation id="3810838688059735925">ವೀಡಿಯೊ</translation>
-<translation id="3816633764618089385">ಮುಂದಿನ ಮಾಧ್ಯಮ</translation>
-<translation id="3819376190738087562">ಯಾವುದೇ ಜಂಪ್‌ಗಳಿಲ್ಲ.</translation>
-<translation id="385383972552776628">ಆಯ್ಕೆಗಳ ಪುಟವನ್ನು ತೆರೆಯಿರಿ</translation>
-<translation id="3856075812838139784">ಓದಲು ಮಾತ್ರ</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">ಮೆನು</translation>
-<translation id="3909320334364316587">ಹಿಂದಿನ ಹಂತದ 6 ಶಿರೋನಾಮೆ</translation>
-<translation id="3914173277599553213">ಅಗತ್ಯವಿರುವುದು</translation>
-<translation id="3962990492275676168">ಪ್ರಸ್ತುತ ಸ್ಥಾನದಿಂದ ಓದುವಿಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ</translation>
-<translation id="4004802134384979325">ಗುರುತಿಸಲಾಗಿದೆ</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">ತಿಂಗಳು ನಿಯಂತ್ರಣ</translation>
-<translation id="4039983576244166038">ಖಾಲಿ ಸಾಲಿನ ಶಿರೋನಾಮೆ</translation>
-<translation id="4042843249978639960">ಮುಂದಿನ ಹಂತದಲ್ಲಿ 2 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="4043348641337972076">ಯಾವುದೇ ಹಿಂದಿನ ARIA ಹೆಗ್ಗುರುತಿಲ್ಲ.</translation>
-<translation id="4047216625641135770">ಗುರುತು</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{ಟಿಲ್ಡ್‌}one{# ಟಿಲ್ಡ್‌ಗಳು}other{# ಟಿಲ್ಡ್‌ಗಳು}}</translation>
-<translation id="409334809956508737">ಹಿಂದಿನ ವಿಷಯ</translation>
-<translation id="4099274309791143834">ಉಪಮೆನುವಿನೊಂದಿಗೆ</translation>
-<translation id="4107807507418787238">ಕೆಳಗಿನ ಯಾವುದೇ ಸೆಲ್ ಇಲ್ಲ.</translation>
-<translation id="4116415223832267137">ಎಚ್ಚರಿಕೆ</translation>
-<translation id="4147126331795725888">ಯಾವುದೇ ಮುಂದಿನ ನಿಯಂತ್ರಣವಿಲ್ಲ.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{ಬಲ ಪುಷ್ಪಾವರಣ}one{# ಬಲ ಪುಷ್ಪಾವರಣಗಳು}other{# ಬಲ ಪುಷ್ಪಾವರಣಗಳು}}</translation>
-<translation id="4158704014418536539">ಕೇಸ್-ಸೆನ್ಸಿಟಿವ್‌.</translation>
-<translation id="4161663686871496107">ChromeVox ಮಾತನಾಡುವ ಪ್ರತಿಕ್ರಿಯೆಯು ಸಿದ್ಧವಾಗಿದೆ</translation>
-<translation id="4173994908659439270">ಮುಂದಿನ ಸಂಪಾದನೆಯ ಪಠ್ಯ ಕ್ಷೇತ್ರವಿಲ್ಲ.</translation>
-<translation id="4176463684765177261">ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation>
-<translation id="4188530942454211480">ಹಿಂದಿನ ವಾಕ್ಯ</translation>
-<translation id="4202186506458631436">ಬಲಕ್ಕೆ ಸೇರಿಸಿ</translation>
-<translation id="4206289001967551965">ಕೋಷ್ಟಕದ ಒಳಗೆ</translation>
-<translation id="4215733775853809057">ಮುಂದಿನ ಸ್ಲೈಡರ್</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{ಡ್ಯಾಶ್}one{# ಡ್ಯಾಶ್‌ಗಳು}other{# ಡ್ಯಾಶ್‌ಗಳು}}</translation>
-<translation id="421884353938374759">ಬಣ್ಣದ ಆಯ್ಕೆಮಾಡುವಿಕೆ</translation>
-<translation id="4229646983878045487">ದಿನಾಂಕದ ಸಮಯ</translation>
-<translation id="423334822609210999">ಯಾವುದೇ ಎಡ ಸೆಲ್ ಇಲ್ಲ.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, ಗ್ರೇಡ್‌ <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">ಟಿಪ್ಪಣಿ</translation>
-<translation id="4254798249533888099">ಮರ</translation>
-<translation id="4255943572433203166">ChromeVox ಅನ್ನು ಕಸ್ಟಮೈಜ್‌‍ಗೊಳಿಸಲು ಈ ಆಯ್ಕೆಗಳನ್ನು ಬಳಸಿ. ಬದಲಾವಣೆಗಳು ತಕ್ಷಣವೇ ಕಾರ್ಯಗತಗೊಳ್ಳುತ್ತವೆ.</translation>
-<translation id="4271220233568730077">ಮುಂದಿನ ಗಣಿತ</translation>
-<translation id="4271521365602459209">ಹೆಚ್ಚಿನ ಫಲಿತಾಂಶಗಳಿಲ್ಲ.</translation>
-<translation id="4287520460805643128">ಯಾವುದೇ ಮುಂದಿನ ಲೇಖನವಿಲ್ಲ.</translation>
-<translation id="4289540628985791613">ಅವಲೋಕನ</translation>
-<translation id="4300318234632215983">ಲಿಂಕ್‌ ಹಿಂದಿರುವ URL ಅನ್ನು ಪ್ರಕಟಿಸಿ</translation>
-<translation id="4301352596632316575">ಉಪಮೆನು ಹೊಂದಿದೆ</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{ಪೂರ್ಣ ವಿರಾಮ}=3{ದೀರ್ಘವೃತ್ತಗಳು}one{# ಪೂರ್ಣ ವಿರಾಮಗಳು}other{# ಪೂರ್ಣ ವಿರಾಮಗಳು}}</translation>
-<translation id="4347461890115250064">ಯಾವುದೇ ಮುಂದಿನ ಪಠ್ಯವಿಲ್ಲ.</translation>
-<translation id="4367650418938037324">ಗಣಿತ ML ಲೀಫ್</translation>
-<translation id="4372435075475052704">ಕನಿಷ್ಟ:<ph name="X" /></translation>
-<translation id="4372705107434148843">ಮಾತು ನಿಲ್ಲಿಸಿ</translation>
-<translation id="4373197658375206385">ಹಿಂದಿನ ಯಾವುದೇ ಐಟಂ ಲಿಂಕ್ ಆಗಿಲ್ಲ</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">ಮರುಹೊಂದಿಸು</translation>
-<translation id="4471074325120394300">ಯಾವುದೇ ಲಿಂಕ್‌ಗಳಿಲ್ಲ.</translation>
-<translation id="4476183483923481720">ಹೊಸ ಸಾಲು</translation>
-<translation id="4482330759234983253">ಹಿಂದಿನ ಕೋಷ್ಟಕ</translation>
-<translation id="4491109536499578614">ಚಿತ್ರ</translation>
-<translation id="4529987814483543472">ಕ್ಲಾಸಿಕ್ ಕೀಮ್ಯಾಪ್</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{ಸ್ಲ್ಯಾಷ್‌}one{# ಸ್ಲ್ಯಾಷ್‌ಗಳು}other{# ಸ್ಲ್ಯಾಷ್‌ಗಳು}}</translation>
-<translation id="4547556996012970016">ಮುಂದಿನ ಹಂತ 5 ಶಿರೋನಾಮೆ</translation>
-<translation id="4562381607973973258">ಶಿರೋಲೇಖ</translation>
-<translation id="4591507479202817876">, ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ</translation>
-<translation id="4597532268155981612">ಫಾರ್ಮ್</translation>
-<translation id="4597896406374528575">ಏಪ್ರಿಲ್</translation>
-<translation id="4615592953348396470">ಮುಂದಿನ ಕೀ ಒತ್ತುವಿಕೆಯನ್ನು ನಿರ್ಲಕ್ಷಿಸಲಾಗುತ್ತಿದೆ</translation>
-<translation id="461613135510474570">ವಾಕ್ಯ</translation>
-<translation id="4647836961514597010">ಬಣ್ಣ ಆಯ್ಕೆಮಾಡುವಿಕೆ</translation>
-<translation id="4661075872484491155">ಮರ</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">ಹಿಂದಿನ ಹೆಗ್ಗುರುತು</translation>
-<translation id="4696413482802371445">ಮುಂದಿನ ಹಂತದ 5 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="4729095194763193578">ಹಿಂದಿನ ಕೋಷ್ಟಕದ ಸಾಲು</translation>
-<translation id="4736221692378411923">ಆಗಸ್ಟ್</translation>
-<translation id="4740661827607246557">ಸಹಾಯ ಆದೇಶಗಳು</translation>
-<translation id="4759716709594980008">ChromeOS ಕೀಬೋರ್ಡ್ ಎಕ್ಸ್‌ಫ್ಲೋರರ್</translation>
-<translation id="4763296182459741068">ಕೆಳಕ್ಕೆ ಆವರಿಸಲಾಗಿದೆ</translation>
-<translation id="4763480195061959176">ವೀಡಿಯೊ</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">ಪ್ರಸ್ತುತ ಪುಟದ ಶೀರ್ಷಿಕೆಯನ್ನು ಪ್ರಕಟಿಸಿ</translation>
-<translation id="4826415162591436065">ಮುಂದಕ್ಕೆ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ</translation>
-<translation id="4826604887384865800">ಮುಂದೆ ಹೋಗು</translation>
-<translation id="4827410568042294688">ಆಯ್ಕೆ ಮಾಡಲಾಗಿಲ್ಲ</translation>
-<translation id="4842108708071771135">ಯಾವುದೇ ಮುಂದಿನ ಬ್ಲಾಕ್‌ಕೋಟ್ ಇಲ್ಲ.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">ಹಿಂದಿನ ಒಂದೇ ರೀತಿಯ ಅಂಶ.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS ಲಾಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</translation>
-<translation id="4877261390094455813">ಹುಡುಕಾಟದ ಪ್ರಶ್ನೆಯನ್ನು ನಮೂದಿಸಿ.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">ಆಂತರಿಕ ಲಿಂಕ್</translation>
-<translation id="4953585991029886728">ಪಠ್ಯ ಸಂಪಾದಿಸಿ</translation>
-<translation id="4954534434583049121">ಹಿಂದಿನ ನಿರ್ಬಂಧನೆಯ ಖೋಟ್</translation>
-<translation id="4973717656530883744">ಗರಿಷ್ಟ <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> ಗೆ ಬದಲಿಸಲಾಗಿದೆ.</translation>
-<translation id="4975416682604111799">ಮಿಲಿಸೆಕೆಂಡುಗಳು</translation>
-<translation id="49787999531187221">ChromeVox ಈಗ ನಿಷ್ಕ್ರಿಯವಾಗಿದೆ.</translation>
-<translation id="4979404613699303341">ಹಿಂದಿನ ಬಟನ್</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, ಪಟ್ಟಿ ಬಾಕ್ಸ್</translation>
-<translation id="4983588134362688868">ಪುಟದ ಮೇಲಕ್ಕೆ ಹೋಗಿ</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, ವಿಂಡೊ</translation>
-<translation id="4993152509206108683">ದರ <ph name="PERCENT" /> ಶೇಕಡಾ</translation>
-<translation id="4996716799442435517">ದೃಷ್ಟಿ</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, ರೇಡಿಯೊ ಬಟನ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</translation>
-<translation id="4997475792277222884">ಲಿಂಕ್ ಅಲ್ಲದ ಮುಂದಿನ ಐಟಂ ಇಲ್ಲ.</translation>
-<translation id="5000760171916499057">ಯಾವುದೇ ಫಾರ್ಮ್‌ಗಳಿಲ್ಲ.</translation>
-<translation id="5005670136041063723">ಇನ್ಯಾವುದೇ ಒಂದೇ ರೀತಿಯ ಅಂಶಗಳಿಲ್ಲ</translation>
-<translation id="501473567976723023">ಜನವರಿ</translation>
-<translation id="5041394372352067729">ಬ್ರೈಲಿ ಪ್ರದರ್ಶನವನ್ನು ಪುಟದ ಮೇಲ್ಭಾಗಕ್ಕೆ ಸರಿಸು</translation>
-<translation id="5042770794184672516">ಧ್ವನಿಯ ವಾಲ್ಯೂಮ್ ಹೆಚ್ಚಿಸಿ</translation>
-<translation id="5050015258024679800">ಹಿಂದಿನ ಹಂತದ 4 ಶಿರೋನಾಮೆ</translation>
-<translation id="5054047268577924192">ಹಿಂದಿನ ಪಟ್ಟಿಯ ಐಟಂ</translation>
-<translation id="5078661581131202757">ಫೈಲ್ ಆಯ್ಕೆ</translation>
-<translation id="5080758118274074384">ಡಬಲ್ ಕ್ಲಿಕ್ ಮಾಡಲಾಗಿದೆ</translation>
-<translation id="5098541983634824365">ಗ್ರಿಡ್ ತೊರೆಯಲಾಗುತ್ತಿದೆ.</translation>
-<translation id="5102981729317424850">ಪರಿಕರ ಪಟ್ಟಿ</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">ಯಾವುದೇ ಹಿಂದಿನ ಫಾರ್ಮ್ ಕ್ಷೇತ್ರವಿಲ್ಲ.</translation>
-<translation id="5111640677200759579">ಕಾಲಮ್ ಶಿರೋನಾಮೆ</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">ಯಾವುದೇ ಹಿಂದಿನ ಲಿಂಕ್ ಇಲ್ಲ.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, ಆಯ್ಕೆ ಮಾಡಲಾಗಿಲ್ಲ</translation>
-<translation id="5183440668879371625">ಬ್ರೈಲಿ ಹಿಂದಿನ ಸಾಲು</translation>
-<translation id="5184944171021383281">ಯಾವುದೇ ಮುಂದಿನ ಫಾರ್ಮ್ ಕ್ಷೇತ್ರವಿಲ್ಲ.</translation>
-<translation id="5189244881767082992">ಸಾಲು</translation>
-<translation id="5203930734796605961">ಆದೇಶಕ್ಕೆ <ph name="KEY" /> ಅನ್ನು ಈಗಾಗಲೇ ನಿಯೋಜಿಸಲಾಗಿದೆ.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> ಪಟ್ಟಿ.</translation>
-<translation id="520883772648104506">ಮುಂದಿನ ರೇಡಿಯೊ ಬಟನ್ ಇಲ್ಲ.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">ಅಂತ್ಯ</translation>
-<translation id="5291783959063340370">ವಸ್ತು</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, ಟ್ಯಾಬ್</translation>
-<translation id="5310788376443009632">ತೆಗೆದುಹಾಕಲಾಗಿದೆ:</translation>
-<translation id="5320727453979144100">ಜಟಿಲವಾದ ಮೋಡ್ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{ಅರ್ಧವಿರಾಮ ಚಿಹ್ನೆ}one{# ಅರ್ಧವಿರಾಮ ಚಿಹ್ನೆಗಳು}other{# ಅರ್ಧವಿರಾಮ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, ಪಠ್ಯ ಪೆಟ್ಟಿಗೆ</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, ಲಿಂಕ್</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">ನಿರಂತರ ಓದುವಿಕೆ ಸಮಯದಲ್ಲಿ ಹಿಂದಿನದನ್ನು ಬಿಟ್ಟುಬಿಡಿ</translation>
-<translation id="5368000168321181111">Earcons ಆಫ್ ಆಗಿದೆ</translation>
-<translation id="5374320867641260420">ಮುಂದೆ ಬಟನ್‌ ಇಲ್ಲ.</translation>
-<translation id="5382299583965267720">ಮುಂದಿನ ಹಂತದ 1 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="5402367795255837559">ಬ್ರೈಲಿ</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{ಅಲ್ಪವಿರಾಮ ಚಿಹ್ನೆ}one{# ಅರ್ಧವಿರಾಮ ಚಿಹ್ನೆಗಳು}other{# ಅರ್ಧವಿರಾಮ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="5411891038905756502">ಯಾವುದೇ ಹಿಂದಿನ ಅಂಶವಿಲ್ಲ.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{ಕಡಿಮೆ ಸೂಚಕ}one{# ಕಡಿಮೆ ಸೂಚಕ ಚಿಹ್ನೆಗಳು}other{# ಕಡಿಮೆ ಸೂಚಕ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="5455441614648621694">ಪೂರಕವಾಗಿ</translation>
-<translation id="5485036206801896268">ಹಿಂದಿನ ಗ್ರಾಫಿಕ್‌ಯಿಲ್ಲ.</translation>
-<translation id="5486947920110100234">ಯಾವುದೇ ಮುಂದಿನ ಅಂಶವಿಲ್ಲ.</translation>
-<translation id="549602578321198708">ಪದ</translation>
-<translation id="5500932716852106146">ಹಿಂದಿನ ಸಂಪಾದನೆಯ ಪಠ್ಯ ಕ್ಷೇತ್ರವಿಲ್ಲ.</translation>
-<translation id="5502713021410870035">ಸೆಪ್ಟೆಂಬರ್</translation>
-<translation id="5507663321906818013">ಬೆಂಚ್‌ಮಾರ್ಕ್ ಅನ್ನು ಡೀಬಗ್ ಮಾಡಿ</translation>
-<translation id="5518443085409638729">ಪಠ್ಯವನ್ನು ಸಂಪಾದಿಸುತ್ತಿರುವಾಗ (Mac OS X ನಂತಹ) ಅಕ್ಷರಗಳ ನಡುವೆ ಕರ್ಸರ್ ಇರಿಸಿ.</translation>
-<translation id="552195134157544755">ರೇಡಿಯೊ ಬಟನ್</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">ಹಿಂದಿನ ಹಂತದ 5 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="556042886152191864">ಬಟನ್</translation>
-<translation id="5561345396546889625">ಮುಂದಿನ ಪಟ್ಟಿ</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">ಪಠ್ಯ ಸಂಪಾದಿಸಿ, ಇಮೇಲ್ ನಮೂದಿಸಿ</translation>
-<translation id="5597170376237141345">ಮುಂದಿನ ಚೆಕ್‌ಬಾಕ್ಸ್</translation>
-<translation id="5597933780944041114">ಯಾವುದೇ ಮುಂದಿನ ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, ರೇಡಿಯೊ ಬಟನ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಲಾಗಲಿಲ್ಲ</translation>
-<translation id="5601172225407283979">ಡೀಫಾಲ್ಟ್ ಕ್ರಮವನ್ನು ಮಾಡಿ</translation>
-<translation id="5608798115546226984">ಸ್ವಯಂಪೂರ್ಣಗೊಳಿಸುವಿಕೆಯ ಇನ್‌ಲೈನ್</translation>
-<translation id="561939826962581046">ಸಮಯ</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">ಲಾಗ್</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">ಯಾವುದೇ ಹಿಂದಿನ ಕೋಷ್ಟಕವಿಲ್ಲ.</translation>
-<translation id="5655682562155942719">ಆಜ್ಞೆಗಳಿಗೆ ಹೋಗು</translation>
-<translation id="56637627897541303">ಪಠ್ಯ ಪ್ರದೇಶ</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">ಹೆಗ್ಗುರುತು</translation>
-<translation id="5683155931978483559">ಹಿಂದಿನ ಚೆಕ್‌ಬಾಕ್ಸ್</translation>
-<translation id="5684277895745049190">ಪಟ್ಟಿ</translation>
-<translation id="5700650669149824506">ಯಾವುದೇ ಹಿಂದಿನ ಮಟ್ಟದ 4 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="5709192780268610569">ಯಾವುದೇ ದೀರ್ಘ ವಿವರಣೆಯಿಲ್ಲ</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">ಮುಂದಿನ ಕೋಷ್ಟಕದ ಕಾಲಮ್</translation>
-<translation id="571866080859340309">ಗುಂಪುಗಳನ್ನು ಪರಿಶೋಧಿಸಲಾಗುತ್ತದೆ</translation>
-<translation id="5728409797179002635">ಯಾವುದೇ ಕೋಷ್ಟಕ ಕಂಡುಬಂದಿಲ್ಲ.</translation>
-<translation id="5748623122140342504">ಹಿಂದಿನ ಹಂತದ 5 ಶಿರೋನಾಮೆ</translation>
-<translation id="5750633686117194034">ಯಾವುದೇ ಮಾರ್ಪಡಿಸುವಿಕೆಯನ್ನು ಒತ್ತಲಾಗಿಲ್ಲ; ದಯವಿಟ್ಟು ಒಂದು ಅಥವಾ ಇನ್ನಷ್ಟು ಮಾರ್ಪಾಡುಗಳನ್ನು ಒತ್ತಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ; ಒಮ್ಮೆ ಮುಗಿದ ನಂತರ ನಿಮ್ಮ ಬೆರಳುಗಳನ್ನು ಮೇಲೆಕ್ಕೆತ್ತಿ ಹಾಗೂ ನೀವು ಕೀಲಿಗಳ ಹೊಂದಿಸುವಿಕೆಯನ್ನು ಕೇಳುವಿರಿ. ನಿರ್ಗಮಿಸಲು ಟ್ಯಾಬ್.</translation>
-<translation id="5788275253279308023">ಅಜ್ಞಾತ ವಿಂಡೋ <ph name="TITLE" /> ಟ್ಯಾಬ್</translation>
-<translation id="5806206155699461681">ನಿರ್ದಿಷ್ಟ ಸೈಟ್‌ಗಳನ್ನು ವರ್ಧಿಸಿ (Google ಹುಡುಕಾಟದಂತಹದು).</translation>
-<translation id="5819072574982403430">ಟ್ರೀ ಐಟಂ</translation>
-<translation id="5826479389509458994">ಸಾಲು <ph name="ROW" /> ಕಾಲಮ್ <ph name="COL" /></translation>
-<translation id="5850707923114094062">ಹಿಮ್ಮುಖವಾಗಿ ಪ್ಯಾನ್ ಮಾಡಿ</translation>
-<translation id="5851548754964597211">ಟ್ಯಾಬ್ ಪಟ್ಟಿ</translation>
-<translation id="5859752971144398932">ಪುಟದಲ್ಲಿ ಹುಡುಕುವುದನ್ನು ನಿರ್ಗಮಿಸಲಾಗಿದೆ.</translation>
-<translation id="5866042630553435010">ಭಾಗಶಃ ಪರೀಕ್ಷಿಸಲಾಗಿದೆ</translation>
-<translation id="5869546221129391014">ಗ್ರಿಡ್</translation>
-<translation id="5876817486144482042">ಧ್ವನಿಯ ವಾಲ್ಯೂಮ್ ಕಡಿಮೆ ಮಾಡಿ</translation>
-<translation id="5887397643266327462">ಬ್ರೈಲಿ ಶೀರ್ಷಿಕೆಗಳು ಸಕ್ರಿಯವಾಗಿವೆ.</translation>
-<translation id="5891934789323004067">ಕೋಷ್ಠಕ</translation>
-<translation id="5919442531159595654">ನಕಲು ಮಾಡಿ.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{ಸಮ}one{# ಸಮ ಚಿಹ್ನೆಗಳು}other{# ಸಮ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="5939518447894949180">ಮರುಹೊಂದಿಸು</translation>
-<translation id="5948123859135882163">ರಚನಾತ್ಮಕ ಮತ್ತು ಶಬ್ದಾರ್ಥದ ನಡುವಿನ ಗಣಿತದ ಅಭಿವ್ಯಕ್ತಿಗಳ ವ್ಯಾಖ್ಯಾನವನ್ನು ಬದಲಾಯಿಸಿ</translation>
-<translation id="5955304353782037793">ಅಪ್ಲಿಕೇಶನ್‌</translation>
-<translation id="5956928062748260866">ಸಂವಾದ</translation>
-<translation id="5963413905009737549">ವಿಭಾಗ</translation>
-<translation id="5968607524793740041">ಸಂದರ್ಭದ ಮೆನು ತೋರಿಸಿ</translation>
-<translation id="5983179082906765664">ನ್ಯಾವಿಗೇಶನ್ ರಚನೆಯನ್ನು ಹೆಚ್ಚಿಸಿ</translation>
-<translation id="5999630716831179808">ಧ್ವನಿಗಳು</translation>
-<translation id="6000417740266304866">ಕೆಳಗಿನ ಪಟ್ಟಿಯಿಂದ ಆಯ್ಕೆಯೊಂದನ್ನು ಆಯ್ಕೆ ಮಾಡುವ ಮೂಲಕ ಪ್ರಸ್ತುತ 8 ಡಾಟ್ ಬ್ರೈಲಿ ಕೋಷ್ಟಕವನ್ನು ಬದಲಾಯಿಸಿ.</translation>
-<translation id="6006050241733874051">ಫಾರ್ಮ್</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{ಬ್ಯಾಕ್‌ಸ್ಲ್ಯಾಶ್‌}one{# ಬ್ಯಾಕ್‌ಸ್ಲ್ಯಾಶ್‌ಗಳು}other{# ಬ್ಯಾಕ್‌ಸ್ಲ್ಯಾಶ್‌ಗಳು}}</translation>
-<translation id="6037602951055904232">ಮುಂದಕ್ಕೆ ಪ್ಯಾನ್ ಮಾಡಿ</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">ಸೆಲ್‌ನ ಅಂತ್ಯ.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">ಸ್ಪೇಸ್</translation>
-<translation id="6142308968191113180">ಶೀರ್ಷಿಕೆ 4</translation>
-<translation id="6169420925157477918">ದೀರ್ಘ ವಿವರಣೆಯೊಂದಿಗೆ ಚಿತ್ರ</translation>
-<translation id="6172087735260766220">ನಕಲು ರಕ್ಷಿತ PDF ನಿಂದ ಪ್ರವೇಶಿಸಬಹುದಾದ ಪಠ್ಯವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ.</translation>
-<translation id="6186305613600865047">ಪುಟದ ಕೆಳಕ್ಕೆ ಹೋಗಿ</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">ಕೆಳಗೆ</translation>
-<translation id="6236061028292614533">ಮುಂದಿನ ಶಿರೋನಾಮೆ</translation>
-<translation id="6254901459154107917">ಮುಂದಿನ ಸಂಪಾದಿಸಬಹುದಾದ ಪಠ್ಯ ಪ್ರದೇಶ</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> ನಿರ್ಗಮಿಸಲಾಗಿದೆ.</translation>
-<translation id="6281876499889881039">ಮುಂದಿನ ಒಂದೇ ರೀತಿಯ ಅಂಶ.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">ಮುಂದಿನ ಕಾಂಬೊ ಪೆಟ್ಟಿಗೆಯಿಲ್ಲ.</translation>
-<translation id="6307969636681130414">ಒತ್ತಿದ</translation>
-<translation id="6324551002951139333">ವ್ಯಾಕರಣ ತಪ್ಪು ಕಂಡುಬಂದಿದೆ</translation>
-<translation id="6348657800373377022">ಕಾಂಬೊ ಬಾಕ್ಸ್</translation>
-<translation id="6355910664415701303">ಮುಂದಿನ ಯಾವುದೇ ಪಟ್ಟಿ ಐಟಂಯಿಲ್ಲ.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">ಹಿಂದಿನ ಶಿರೋನಾಮೆ</translation>
-<translation id="6387719785439924554">ಪಕ್ಕದಲ್ಲಿ</translation>
-<translation id="6411426777058107714">ಹಿಂದಿನ ರೇಡಿಯೊ ಬಟನ್ ಇಲ್ಲ.</translation>
-<translation id="6414968628640960377">ಹಿಂದಿನ ವಿಭಿನ್ನ ಅಂಶ.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{ವಿವರಣೆ ಚಿಹ್ನೆ}one{# ವಿವರಣೆ ಚಿಹ್ನೆಗಳು}other{# ವಿವರಣೆ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, ಮೆನು</translation>
-<translation id="6444046323172968959">ಎಚ್ಚರಿಕೆ ಸಂವಾದ</translation>
-<translation id="6459511626086141404">ಚಪ್ಪಟೆ ಕೀಮ್ಯಾಪ್</translation>
-<translation id="6468049171101508116">ಮುಂದಿನ ಬಟನ್</translation>
-<translation id="6491972999578897419">ಕೆಳಗಿನ ಪಟ್ಟಿಯಿಂದ ಆಯ್ಕೆವೊಂದನ್ನು ಆಯ್ಕೆ‌ಮಾಡುವುದರ ಮೂಲಕ ಪ್ರಸ್ತುತ ಧ್ವನಿಯನ್ನು ಬದಲಾಯಿಸಿ.</translation>
-<translation id="6508059270146105198">ಬ್ರೈಲಿ ಪ್ರದರ್ಶನವನ್ನು ಪುಟದ ಕೆಳಭಾಗಕ್ಕೆ ಸರಿಸಿ</translation>
-<translation id="6536864053412760904">ಗಣಿತ ML ಟೋಕನ್</translation>
-<translation id="6550720799683018100">ಕೆಳಗಿನ ಪಟ್ಟಿಯಿಂದ ಆಯ್ಕೆವೊಂದನ್ನು ಆಯ್ಕೆ‌ಮಾಡುವುದರ ಮೂಲಕ ಪ್ರಸ್ತುತ ಕೀಮ್ಯಾಪ್ ಅನ್ನು ಬದಲಾಯಿಸಿ.</translation>
-<translation id="6561818612645211875">ಪ್ರಸ್ತುತ ಸಾಲಿನ ಆರಂಭಕ್ಕೆ ಹೋಗಿ</translation>
-<translation id="6587021927234520429">ಯಾವುದೇ ಮುಂದಿನ ಮಟ್ಟದ 4 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="6601344353291556895">ಅತಿಮಾತಿನ ವಿವರಣೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ.</translation>
-<translation id="6615602925644411249">ಪುಟದಲ್ಲಿ ಹುಡುಕಿ</translation>
-<translation id="6633350132811819843">ಮುಂದಿನ ಕೋಷ್ಟಕವಿಲ್ಲ.</translation>
-<translation id="6637586476836377253">ಲಾಗ್</translation>
-<translation id="6657128831881431364">ಪ್ರಗತಿ ಪಟ್ಟಿ</translation>
-<translation id="6659594942844771486">ಟ್ಯಾಬ್</translation>
-<translation id="667999046851023355">ಡಾಕ್ಯುಮೆಂಟ್</translation>
-<translation id="6697092096875747123">ಹಿಂದಿನ ಕಾಂಬೊ ಬಾಕ್ಸ್</translation>
-<translation id="6714813999819678458">ಹಿಂದಿನ ಹಂತದ 2 ಶಿರೋನಾಮೆ</translation>
-<translation id="6716505898850596801">ಮಾರ್ಪಡಿಸುವ ಕೀಗಳು</translation>
-<translation id="671916444866103745">ಯಾವುದೇ ಮುಂದಿನ ARIA ಹೆಗ್ಗುರುತಿಲ್ಲ.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, ಕಾಂಬೊ ಬಾಕ್ಸ್</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> ಐಟಂಗಳೊಂದಿಗೆ</translation>
-<translation id="6736510033526053669">ಟ್ಯಾಬ್ ರಚಿಸಲಾಗಿದೆ</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">ಆರ್ಟಿಕಲ್</translation>
-<translation id="6787839852456839824">ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">ಅಡಿಟಿಪ್ಪಣಿ</translation>
-<translation id="6871161210040114857">ಕೇಸ್ ನಿರ್ಲಕ್ಷಿಸಲಾಗಿದೆ.</translation>
-<translation id="6877435256196695200">ಮುಂದಿನ ಗ್ರಾಫಿಕ್‌ಯಿಲ್ಲ.</translation>
-<translation id="6897341342232909480">ಎಡಕ್ಕೆ ಸೇರಿಸಿ</translation>
-<translation id="6901540140423170855">ದಿನಾಂಕ</translation>
-<translation id="6910211073230771657">ಅಳಿಸಲಾಗಿದೆ</translation>
-<translation id="6911965441508464308">ಮೇಲೆ ಯಾವುದೇ ಸೆಲ್ ಇಲ್ಲ.</translation>
-<translation id="6919104639734799681">ಕೋಷ್ಟಕಗಳ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ</translation>
-<translation id="6964088412282673743">ಯಾವುದೇ ಹಿಂದಿನ ನಿಯಂತ್ರಣವಿಲ್ಲ.</translation>
-<translation id="6996566555547746822">ಮುಂದಿನ ಕಾಂಬೊ ಬಾಕ್ಸ್</translation>
-<translation id="7005146664810010831">ಯಾವುದೇ URL ಕಂಡುಬಂದಿಲ್ಲ</translation>
-<translation id="7010712454773919705">ChromeVox ಮಾರ್ಪಡಿಸುವ ಕೀ</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">ಹಿಂದಿನ ಪಟ್ಟಿ</translation>
-<translation id="7041173719775863268">ಆಯ್ಕೆಯನ್ನು ಕೊನೆಗೊಳಿಸಿ</translation>
-<translation id="7095834689119144465">ಪಠ್ಯ ಸಂಖ್ಯೆ ಮಾತ್ರ ಸಂಪಾದಿಸಿ</translation>
-<translation id="7096001299300236431">ಹಿಂದಿನ ಮಾಧ್ಯಮ</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">ಪದ ಎಕೋ</translation>
-<translation id="713824876195128146">ಮುಂದಿನ ನಿರ್ಬಂಧ ಖೋಟ್</translation>
-<translation id="7161771961008409533">ಪಾಪ್-ಅಪ್ ಬಟನ್</translation>
-<translation id="7167657087543110">ಅಕ್ಷರ ಇಕೋ</translation>
-<translation id="7170733337935166589">ನಿರಂತರ ಓದುವಿಕೆ ಸಮಯದಲ್ಲಿ ಮುಂದಿನದನ್ನು ಬಿಟ್ಟುಬಿಡಿ</translation>
-<translation id="7181697990050180700">ಪದೇ ಪದೇ ಬಳಸಲಾದ ಆದೇಶಗಳಿಗೆ ಕೆಳಗಿನ ಅನುಗುಣವಾದ ಕ್ಷೇತ್ರಗಳಲ್ಲಿ ಅವುಗಳನ್ನು ಟೈಪ್ ಮಾಡುವುದರ ಮೂಲಕ ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ.</translation>
-<translation id="7203150201908454328">ವಿಸ್ತೃತವಾದ</translation>
-<translation id="7210211103303402262">ನಿಮಿಷಗಳು</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">ಸಾಲು</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">ಶೀರ್ಷಿಕೆ</translation>
-<translation id="7241683698754534149">ಹೊಸ ಟ್ಯಾಬ್‌ನಲ್ಲಿ ದೀರ್ಘ ವಿವರಣೆಯನ್ನು ತೆರೆಯಿರಿ</translation>
-<translation id="7248671827512403053">ಅಪ್ಲಿಕೇಶನ್</translation>
-<translation id="725969808843520477">ಮುಂದಿನ ರೇಡಿಯೊ ಬಟನ್</translation>
-<translation id="7269119382257320590">ವಿರಾಮಚಿಹ್ನೆಗಳಿಲ್ಲ</translation>
-<translation id="7273174640290488576">ಖಾಲಿ</translation>
-<translation id="7285387653379749618">ಕೋಷ್ಠಕಗಳು</translation>
-<translation id="7289186959554153431">ಶೀರ್ಷಿಕೆ 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">ಬ್ರೈಲಿ ಶೀರ್ಷಿಕೆಗಳು ನಿಷ್ಕ್ರಿಯವಾಗಿವೆ.</translation>
-<translation id="7318872822751139669">ಗಮನ ಬದಲಾಯಿಸಲು ಮೌಸ್ ಬಳಸಿ.</translation>
-<translation id="7322388933135261569">ಫೆಬ್ರವರಿ</translation>
-<translation id="7332592614823088566"><ph name="ROWINDEX" /> / <ph name="ROWTOTAL" /> ಸಾಲು, <ph name="COLINDEX" /> / <ph name="COLTOTAL" /> ಕಾಲಮ್‌</translation>
-<translation id="7336596009609913925">ಪಾಪ್ಅಪ್ ಹೊಂದಿದೆ</translation>
-<translation id="7356165926712028380">8 ಡಾಟ್‌ ಬ್ರೈಲಿಗೆ ಬದಲಿಸಿ</translation>
-<translation id="7362871137496673139">ಯಾವುದೇ ಹಿಂದಿನ ಮಟ್ಟದ 2 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ಮತ್ತು}one{# ಮತ್ತು ಚಿಹ್ನೆಗಳು}other{# ಮತ್ತು ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">ಕೋಷ್ಟಕವನ್ನು ತೊರೆಯಲಾಗುತ್ತಿದೆ.</translation>
-<translation id="739763518212184081">ಹಿಂದಿನ ಸಾಲು</translation>
-<translation id="7400575256015741911">ಕಾಗುಣಿತ ತಪ್ಪು ಕಂಡುಬಂದಿಲ್ಲ</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">ರಿಟರ್ನ್</translation>
-<translation id="7434509671034404296">ಡೆವಲಪರ್</translation>
-<translation id="7439060726180460871">ಡೈರೆಕ್ಟರಿ</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">ಟ್ಯಾಬ್</translation>
-<translation id="7492049978501397201">ಸಂವಾದವನ್ನು ನಮೂದಿಸಲಾಗಿದೆ</translation>
-<translation id="7532613204005497612">ಜೂನ್</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, ಸ್ಲೈಡರ್</translation>
-<translation id="7586163296341959563">ಅಂಟಿಸು.</translation>
-<translation id="7596919493010894443">ಆಯ್ಕೆ ತೆರವುಗೊಳಿಸಲಾಗಿದೆ</translation>
-<translation id="7604026522577407655">ಪ್ರಸ್ತುತ ಕಾಲಮ್‌ನ ಆರಂಭಕ್ಕೆ ಹೋಗಿ</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">ಪ್ರಸ್ತುತದ ಪುಟದ URL ಅನ್ನು ಪ್ರಕಟಿಸಿ</translation>
-<translation id="7609363189280667021">ಬ್ರೇಲ್ ಶೀರ್ಷಿಕೆಗಳನ್ನು ಟಾಗಲ್ ಮಾಡಿ</translation>
-<translation id="762020119231868829">ಪ್ರಸ್ತುತ ಪ್ಲೇ ಆಗುತ್ತಿರುವ ಎಲ್ಲಾ ಮಾಧ್ಯಮ ವಿಜೆಟ್‌ಗಳನ್ನು ವಿರಾಮಗೊಳಿಸುತ್ತದೆ</translation>
-<translation id="7625690649919402823">ಮುಂದಿನ ಕೋಷ್ಟಕ</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), ಗ್ರೇಡ್‌ <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">ಯಾವುದೇ ಹಿಂದಿನ ಮಟ್ಟದ 3 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, ಪಠ್ಯ ಪೆಟ್ಟಿಗೆ</translation>
-<translation id="7663318257180412551">ಶೀರ್ಷಿಕೆ 2</translation>
-<translation id="7674576868851035240">ಮುಂದಿನ ಲಿಂಕ್</translation>
-<translation id="7674768236845044097">ಗುರುತು</translation>
-<translation id="7684431668231950609">ಪಠ್ಯ ಸಂಪಾದಿಸಿ, URL ನಮೂದಿಸಿ</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">ಹಿಂದಿನ ರೇಡಿಯೊ ಬಟನ್</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, ಪಾಸ್‌ವರ್ಡ್ ಪಠ್ಯ ಬಾಕ್ಸ್</translation>
-<translation id="7805247615045262757">ಡೀಫಾಲ್ಟ್ ನ್ಯಾವಿಗೇಷನ್</translation>
-<translation id="7805768142964895445">ಸ್ಥಿತಿ</translation>
-<translation id="7810781339813764006">ಮುಂದಿನ ಗುಂಪು</translation>
-<translation id="7819187121850078213">ವಿಂಡೋ <ph name="TITLE" /> ಟ್ಯಾಬ್</translation>
-<translation id="7828956995407538686">ಅಕ್ಟೋಬರ್</translation>
-<translation id="7839679365527550018">ಹಿಂದಿನ ಪದ</translation>
-<translation id="7851816175263618915">ಕೆಲವು ವಿರಾಮಚಿಹ್ನೆಗಳು</translation>
-<translation id="7870596830398826354">ಗಣಿತ ML ಟ್ರಿ</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox ಕ್ಲಾಸಿಕ್‌‌ ಟಾಗಲ್ ಮಾಡಿ</translation>
-<translation id="7895896691902835279">ಅಜ್ಞಾತ ಲಿಂಕ್</translation>
-<translation id="7927711904086083099">ಆಯ್ಕೆಮಾಡಲಾಗಿಲ್ಲ</translation>
-<translation id="7935627501098484003">ಸಮಯ ನಿಯಂತ್ರಣ</translation>
-<translation id="7939428177581522200">ಆಯ್ಕೆಗೆ ಸೇರಿಸಲಾಗಿದೆ</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{ಅಟ್}one{# ಅಟ್ ಚಿಹ್ನೆಗಳು}other{# ಅಟ್ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="7965147473449754028">ಮೆನು ಮುಚ್ಚಲಾಗಿದೆ</translation>
-<translation id="7974390230414479278">ಮೆನು ಐಟಂ</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ಭಾವ ಸೂಚಕ ಚಿಹ್ನೆ}one{# ಭಾವಸೂಚಕ ಚಿಹ್ನೆಗಳು}other{# ಭಾವಸೂಚಕ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{ಉದ್ದರಣ}one{# ಉದ್ದರಣ ಚಿಹ್ನೆಗಳು}other{# ಉದ್ದರಣ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="8033827949643255796">ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ</translation>
-<translation id="8035962149453661158">ಗರಿಷ್ಟ:<ph name="X" /></translation>
-<translation id="8042761080832772327">ಪಠ್ಯ ಸಂಪಾದಿಸಿ, ಹುಡುಕಾಟ ನಮೂದಿಸಿ</translation>
-<translation id="8049189770492311300">ಟೈಮರ್</translation>
-<translation id="8065607967589909823">ಆಯ್ಕೆಯು</translation>
-<translation id="8066678206530322333">ಬ್ಯಾನರ್</translation>
-<translation id="8110647606445335195">ಯಾವುದೇ ARIA ಹೆಗ್ಗುರುತುಗಳಿಲ್ಲ.</translation>
-<translation id="8153880621934657047">ಕೋಷ್ಟಕದ ಒಳಗೆ ಇಲ್ಲ.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{ಅಡಿಗೆರೆ}one{# ಅಡಿಗೆರೆಗಳು}other{# ಅಡಿಗೆರೆಗಳು}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">ಕತ್ತರಿಸಿ.</translation>
-<translation id="8199231515320852133">ಪ್ರಸ್ತುತ ಸೆಲ್‌ನ ಶಿರೋನಾಮೆಗಳನ್ನು ಪ್ರಕಟಿಸಿ</translation>
-<translation id="820417203470636242">ಕೋಶವನ್ನು ಖಾಲಿಗೊಳಿಸಿ.</translation>
-<translation id="8215202828671303819">ಬಹು ಆಯ್ಕೆ</translation>
-<translation id="8276439074553447000">ಹಿಂದೆ ಗಮನಹರಿಸಿದಂತಹ ಐಟಂಗೆ ಹೋಗಿ</translation>
-<translation id="8278417001922463147">ಯಾವುದೇ ಹಿಂದಿನ ಲೇಖನವಿಲ್ಲ.</translation>
-<translation id="8283603667300770666">ಮುಂದಿನ ಫಾರ್ಮ್ ಕ್ಷೇತ್ರ</translation>
-<translation id="831207808878314375">ವಿವರಣೆ</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">ಗಂಟೆಗಳು</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{ಪೌಂಡ್ ಚಿಹ್ನೆಗಳು}one{# ಪೌಂಡ್ ಚಿಹ್ನೆಗಳು}other{# ಪೌಂಡ್ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="8374154622594089836">ತಿಂಗಳು</translation>
-<translation id="8378855320830505539">ಪ್ರದೇಶ</translation>
-<translation id="8382679411218029383">ಸ್ವಯಂಪೂರ್ಣಗೊಳಿಸುವಿಕೆ ಇನ್‌ಲೈನ್ ಮತ್ತು ಪಟ್ಟಿ</translation>
-<translation id="8428603554127842284">ಮಟ್ಟ <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">ಯಾವುದೇ ಮುಂದಿನ ಮಟ್ಟದ 3 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">ಹಿಂದಿನ ಚೆಕ್‌ಬಾಕ್ಸ್ ಇಲ್ಲ</translation>
-<translation id="8455868257606149352">ಗರಿಷ್ಟ <ph name="X" /></translation>
-<translation id="84575901236241018">ಪ್ರವೇಶ ಕೀ ಹೊಂದಿದೆ, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">ನ್ಯಾವಿಗೇಶನ್ ರಚನೆಯನ್ನು ಇಳಿಸಿ</translation>
-<translation id="8520472399088452386">ಸ್ಪಿನ್ ಬಟನ್</translation>
-<translation id="8538744478902126321">ಪ್ರಸ್ತುತ ಸೆಲ್‌ನಲ್ಲಿರುವ ಶಿರೋನಾಮೆಯ ಬಗ್ಗೆ ಊಹೆ ಮಾಡಿ</translation>
-<translation id="8540054775867439484">ಮೇಲಕ್ಕೆ ಆವರಿಸಲಾಗಿದೆ</translation>
-<translation id="8548973727659841685">ಅಕ್ಷರ</translation>
-<translation id="8561322612995434619">ಪಾಪ್ ಅಪ್ ಹೊಂದಿದೆ</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">ಮುಂದಿನ ಪಟ್ಟಿಯ ಐಟಂ</translation>
-<translation id="860150890330522909"><ph name="NAME" /> ಚೆಕ್‌ಬಾಕ್ಸ್ ಗುರುತಿಸಲಾಗಿದೆ</translation>
-<translation id="8606621670302093223">ದಿನಾಂಕ ನಿಯಂತ್ರಣ</translation>
-<translation id="8631359288236106450">ಆಯ್ಕೆಮಾಡಿದ <ph name="COUNT" /> ಐಟಂಗಳು</translation>
-<translation id="8638532244051952400">ಪ್ರಸ್ತುತ ಕೋಶ ಸಂಘಟನೆಗಳನ್ನು ಪ್ರಕಟಿಸಿ</translation>
-<translation id="8650576015643545550">ಯಾವುದೇ ಹಿಂದಿನ ಪಟ್ಟಿಯಿಲ್ಲ.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">ಲಿಂಕ್‌ಗಳ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ</translation>
-<translation id="8664519043722036194">ಸೆಕೆಂಡುಗಳು</translation>
-<translation id="867187640362843212">ಶೀರ್ಷಿಕೆ 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{ಪೈಪ್}one{# ಲಂಬ ಪೈಪ್‌ಗಳು}other{# ಲಂಬ ಪೈಪ್‌ಗಳು}}</translation>
-<translation id="8735450637152821465">ಆಯ್ಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ</translation>
-<translation id="8743786158317878347">ಕೋಷ್ಟಕಗಳಂತಹ, ವ್ಯವಸ್ಥಿತಗೊಳಿಸಿದ ವಿಷಯ ನಮೂದಿಸಿ</translation>
-<translation id="8747966237988593539">ವ್ಯವಸ್ಥಿತವಾದ ಪಟ್ಟಿ</translation>
-<translation id="8759334257841767240">ಯಾವುದೇ ಮುಂದಿನ ಲಿಂಕ್ ಇಲ್ಲ.</translation>
-<translation id="8767968232364267681">ಮುಂದಿನ ಹಂತದ 4 ಶಿರೋನಾಮೆ</translation>
-<translation id="8770473310765924354">ಕೋಷ್ಟಕಗಳಂತಹ, ವ್ಯವಸ್ಥಿತಗೊಳಿಸಿದ ವಿಷಯ ನಿರ್ಗಮಿಸಿ</translation>
-<translation id="8791025954632646584">ಶಬ್ದಾರ್ಥಗಳು ಆನ್ ಆಗಿದೆ</translation>
-<translation id="8796411681063377102">ಮುಂದಿನ ಹಂತ 3 ಶಿರೋನಾಮೆ</translation>
-<translation id="8808582214901541005">ಮಾರ್ಚ್</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">ಮುಖ್ಯ</translation>
-<translation id="8856538297388979332">ಆದೇಶಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಮೇಲೆ ಅಥವಾ ಕೆಳಗೆ ಒತ್ತಿರಿ, ಸಕ್ರಿಯಗೊಳಿಸಲು ಎಂಟರ್ ಒತ್ತಿರಿ</translation>
-<translation id="8864099967139188018">ಮುಂದಿನ ಹಂತದ 6 ಶಿರೋನಾಮೆಯಿಲ್ಲ.</translation>
-<translation id="8882002077197914455">ಸಾಲಿನ ಶಿರೋನಾಮೆ</translation>
-<translation id="8896347895970027998">ChromeVox ಅನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಕ್ಕೆ ಟಾಗಲ್ ಮಾಡಿ.</translation>
-<translation id="8898516272131543774">ಸೈಕಲ್ ಪಂಚುಯೇಶನ್ ಎಕೋ</translation>
-<translation id="8900148057318340779">ಪೂರ್ವಪ್ರತ್ಯಯ ಕೀ</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">ಖಾಲಿ ಶಿರೋನಾಮೆಗಳು</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">ಮಾರ್ಪಡಿಸುವ ಕೀಗಳು</translation>
-<translation id="8943175951035496220">ಯಾವುದೇ ಬಲ ಸೆಲ್ ಇಲ್ಲ.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">ಫೈಲ್</translation>
-<translation id="9027462562263121875">ಯಾವುದೇ ಕೋಷ್ಟಕಗಳಿಲ್ಲ.</translation>
-<translation id="9040132695316389094">ಶೀರ್ಷಿಕೆ 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">ಹುಡುಕಾಟ ವಿಜೆಟ್ ಅನ್ನು ಟಾಗಲ್ ಮಾಡಿ</translation>
-<translation id="9065283790526219006">+ಪಾಪ್‌ಅಪ್‌</translation>
-<translation id="9077213568694924680">ಆಯ್ಕೆಯಿಂದ ತೆಗೆದುಹಾಕಲಾಗಿದೆ</translation>
-<translation id="9082874451376019682">ಹಿಂದಿನ ಸ್ಲೈಡರ್ ಇಲ್ಲ.</translation>
-<translation id="9089864840575085222">ಸೈಕಲ್ ಟೈಪಿಂಗ್ ಇಕೋ</translation>
-<translation id="9107530006868467849">ಯಾವುದೇ ಹಿಂದಿನ ಮಾಧ್ಯಮ ವಿಜೆಟ್ ಇಲ್ಲ.</translation>
-<translation id="9108370397979208512">ಮ್ಯಾಥ್</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{ಶೇಕಡಾ}one{# ಶೇಕಡಾ ಚಿಹ್ನೆಗಳು}other{# ಶೇಕಡಾ ಚಿಹ್ನೆಗಳು}}</translation>
-<translation id="9115913704608474258">ನವೆಂಬರ್</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">ಪ್ರಸ್ತುತ ಸ್ಥಾನದ ಸಂಕ್ಷಿಪ್ತ ವಿವರಣೆಯ ಪ್ರಕಟಣೆ</translation>
-<translation id="9153606228985488238">ಪಿಚ್‌ <ph name="PERCENT" /> ಶೇಕಡಾ ಹೊಂದಿದೆ</translation>
-<translation id="9160096769946561184">ಪ್ರಸ್ತುತ ಕಾಲಮ್‌ನ ಅಂತ್ಯಕ್ಕೆ ಹೋಗಿ</translation>
-<translation id="9173115498289768110">ಶೇಕಡಾ <ph name="PERCENT" /> ವಾಲ್ಯೂಮ್‌</translation>
-<translation id="9178973770513562274">ಬ್ರೌಸ್ ಮಾಡಲು ಮೇಲಿನ ಅಥವಾ ಕೆಳಗಿನ ಬಾಣದ ಕೀಗಳನ್ನು ಬಳಸಿ, ಅಥವಾ ಹುಡುಕಲು ಟೈಪ್ ಮಾಡಿ.</translation>
-<translation id="9192904702577636854">ಮಾರ್ಕ್ಯೂ</translation>
-<translation id="9212322457209634662">ಯಾವುದೇ ಮುಂದಿನ ವಿಭಾಗವಿಲ್ಲ.</translation>
-<translation id="930275611743429116">ಪ್ರಾರಂಭ ಅಥವಾ ಅಂತ್ಯದ ಆಯ್ಕೆ.</translation>
-<translation id="948171205378458592">ಮಾತಿನ ಪ್ರಮಾಣವನ್ನು ಇಳಿಸಿ</translation>
-<translation id="962913030769097253">ಮುಂದಿನ ಹಂತದ 1 ಶಿರೋನಾಮೆ</translation>
-<translation id="973955474346881951">ಜಟಿಲವಾದ ಮೋಡ್‌ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ/ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ko.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ko.xtb
deleted file mode 100644
index 0a46d98e2a6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ko.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ko">
-<translation id="1012173283529841972">목록 항목</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">병합되었습니다.</translation>
-<translation id="1025074108959230262">고정 모드 사용 중지됨</translation>
-<translation id="1031961866430398710">플러스</translation>
-<translation id="1044777062731150180">헤더 없음</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">입력이 잘못됨</translation>
-<translation id="1082209053475788238">이전 수준 6 제목이 없습니다.</translation>
-<translation id="1088219014394087294">제목이 없습니다.</translation>
-<translation id="1106741348836243114">음성 피드백(이어콘)을 사용 또는 사용 안함으로 설정합니다.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "fox", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="NUM" />개 항목을 포함한 <ph name="TAG" /> 컬렉션</translation>
-<translation id="1155043339247954670">다음 목록 항목이 없습니다.</translation>
-<translation id="1157782847298808853">키보드 도움말</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, 콤보 상자</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, 메뉴 항목, 하위 메뉴 포함</translation>
-<translation id="1177863135347784049">맞춤</translation>
-<translation id="1188858454923323853">상호 보완</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome이 말을 합니다.</translation>
-<translation id="1229276918471378188">이전 점프</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">다음 수준 6 제목</translation>
-<translation id="1275718070701477396">선택됨</translation>
-<translation id="1319608975892113573">이전 인용구가 없습니다.</translation>
-<translation id="1321576897702511272">ChromeVox 도움말 숨기기</translation>
-<translation id="1331702245475014624"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">문자 및 단어 에코</translation>
-<translation id="1339428534620983148">이전 열</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">오른쪽</translation>
-<translation id="136718599399906424">다음 행</translation>
-<translation id="1383876407941801731">검색</translation>
-<translation id="1385214448885562192">동의하려면 Enter를 누르고 취소하려면 Esc를 누르세요. 다음으로 이동하려면 아래를 누르고 이전으로 이동하려면 위를 누르세요.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, 비밀번호 입력란</translation>
-<translation id="1467432559032391204">왼쪽</translation>
-<translation id="1474557363159888097">이전 앵커가 없습니다.</translation>
-<translation id="1502086903961450562">이전 그래픽</translation>
-<translation id="1506187449813838456">음조 높임</translation>
-<translation id="151784044608172266">다음 문장</translation>
-<translation id="1524531499102321782">점자 다음 행으로 이동</translation>
-<translation id="1546370775711804143">스크롤바</translation>
-<translation id="1559739829547075274">뒤로 탐색</translation>
-<translation id="1571643229714746283">ChromeVox 사용할 수 있음</translation>
-<translation id="158493514907962286">12월</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6점 점자로 전환</translation>
-<translation id="1611168825862729585">열 헤더:</translation>
-<translation id="1613476421962910979">이어콘 사용</translation>
-<translation id="1618597272655350600">현재 위치에 대한 자세한 설명을 들려줍니다.</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{큼 부호}other{큼 부호 #개}}</translation>
-<translation id="1653266918374749391">이전 수준 3 제목</translation>
-<translation id="1659072772017912254">선택 안함</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">ChromeVox 탐색</translation>
-<translation id="16777221443363124">메뉴 바</translation>
-<translation id="1692077714702418899">구조 선</translation>
-<translation id="1700517974991662022">방문함</translation>
-<translation id="1722567105086139392">링크</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">다음 그래픽</translation>
-<translation id="1781173782405573156">통과 키</translation>
-<translation id="1787176709638001873">비밀번호 수정 텍스트</translation>
-<translation id="1810107444790159527">목록 상자</translation>
-<translation id="1828385960365606039">5월</translation>
-<translation id="1834891354138622109">열</translation>
-<translation id="1865601187525349519">텍스트의 끝</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">현재 날짜와 시간을 말합니다.</translation>
-<translation id="1902396333223336119">셀</translation>
-<translation id="1905379170753160525">제목 목록 표시</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">해당 연도의 주 컨트롤</translation>
-<translation id="1964135212174907577">다음 객체</translation>
-<translation id="1969092762068865084">7월</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">행 헤더:</translation>
-<translation id="2002895034995108595">현재 키맵 재설정</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{왼쪽 꺾음 괄호}other{왼쪽 꺾음 괄호 #개}}</translation>
-<translation id="2045490512405922022">선택 안함</translation>
-<translation id="20601713649439366">이전 수식이 없습니다.</translation>
-<translation id="207477615537953741">의미 해석 사용 안함</translation>
-<translation id="2086961585857038472">다음 단어</translation>
-<translation id="2089387485033699258">ko</translation>
-<translation id="2091933974477985526">이전 수정 가능 텍스트 영역</translation>
-<translation id="2100350898815792233">모든 구두점을 읽음</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">액세스 키:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">아래의 목록에서 옵션을 선택하여 현재의 6점 점자 표를 변경합니다.</translation>
-<translation id="2169714232367507776">현재 항목 클릭</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{닫는 괄호}other{닫는 괄호 #개}}</translation>
-<translation id="2199994615414171367">이전 수식</translation>
-<translation id="2223693656926968778">현재 항목에서 작업 수행</translation>
-<translation id="225732394367814946">말하기 속도 증가</translation>
-<translation id="2267945578749931355">다음 문자</translation>
-<translation id="2281234842553884450">이전 슬라이더</translation>
-<translation id="2318372665160196757">기본</translation>
-<translation id="2329324941084714723">탭 패널</translation>
-<translation id="2344193891939537199">날짜 시간 컨트롤</translation>
-<translation id="2359897517538099099">표 모드가 아닙니다.</translation>
-<translation id="241124561063364910">플러스</translation>
-<translation id="2417569100218200841">콘텐츠 정보</translation>
-<translation id="2422937916923936891">메뉴 항목 체크박스</translation>
-<translation id="2429669115401274487">오후</translation>
-<translation id="2435413342408885429"><ph name="KEY" />이(가) 새로운 ChromeVox 특수키로 설정되었습니다.</translation>
-<translation id="2450814015951372393">체크박스</translation>
-<translation id="2462626033734746142">라디오 버튼 그룹</translation>
-<translation id="2471138580042810658">제목 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{별표}other{별표 #개}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" />이(가) 재설정되었습니다.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">그룹</translation>
-<translation id="2582407057977008361">사이드 바</translation>
-<translation id="2589102159832527089">이 페이지에는 PDF 파일인 &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;에서 자동으로 추출된 텍스트가 포함되어 있습니다. &lt;a href="<ph name="URL" />"&gt;원본을 보려면 여기를 클릭하세요.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">에{COUNT,plural, =1{항목 #개 포함}other{항목 #개 포함}}</translation>
-<translation id="2614981083756825552">Math ML 레이아웃</translation>
-<translation id="2626530649491650971">clickable</translation>
-<translation id="2628764385451019380">이전 콤보 상자가 없습니다.</translation>
-<translation id="2637227747952042642">Math</translation>
-<translation id="2639750663247012216">ChromeVox 특수키</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">라우팅 키에서 항목을 클릭합니다.</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{여는 괄호}other{여는 괄호 #개}}</translation>
-<translation id="2705875883745373140">누르지 않음</translation>
-<translation id="2706462751667573066">위</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">오디오</translation>
-<translation id="2732718972699418926">오전</translation>
-<translation id="2749275490991666823">선택됨</translation>
-<translation id="27527859628328957">다음 초점 가능 항목으로 이동</translation>
-<translation id="2770781857296573485">그룹 탐색 입력</translation>
-<translation id="2777845298774924149">종료함</translation>
-<translation id="2800204403141299078">더 이상 다른 요소가 없습니다.</translation>
-<translation id="2800780099804980316">이전 수준 1 제목이 없습니다.</translation>
-<translation id="2811204574343810641">행</translation>
-<translation id="2816654101880605877">다음 슬라이더가 없습니다.</translation>
-<translation id="2841013758207633010">시간</translation>
-<translation id="2843837985843789981">이전 그룹</translation>
-<translation id="2844995807198708617">컨텍스트 메뉴</translation>
-<translation id="2849332794118375855">다음 체크박스가 없습니다.</translation>
-<translation id="2864481629947106776">이전 링크</translation>
-<translation id="2873259058405069099">표의 처음으로 이동</translation>
-<translation id="2894654529758326923">정보</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{왼쪽 중괄호}other{왼쪽 중괄호 #개}}</translation>
-<translation id="2911433807131383493">ChromeVox 가이드 열기</translation>
-<translation id="2932083475399492303">구조 선/레이아웃 선 간의 선 유형 전환</translation>
-<translation id="2964026537669811554">제목 그룹</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{탭}other{탭 #개}}</translation>
-<translation id="2972078295414139404">이전 방문한 링크가 없습니다.</translation>
-<translation id="2972205263822847197">툴팁</translation>
-<translation id="2998131015536248178">이전 문자</translation>
-<translation id="2999559350546931576">음조 낮춤</translation>
-<translation id="2999945368667127852">다음 미디어 위젯이 없습니다.</translation>
-<translation id="3012414509011670858">이전 섹션이 없음</translation>
-<translation id="3030432017085518523">메뉴 항목 라디오 버튼</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{아포스트로피}other{아포스트로피 #개}}</translation>
-<translation id="3046838483509668188">ChromeVox 옵션</translation>
-<translation id="3047143736589213134">실험용 키맵</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> 메뉴 열림</translation>
-<translation id="3078345202707391975">다음 수준 2 제목</translation>
-<translation id="3078740164268491126">표</translation>
-<translation id="3082557070674409251">클릭함</translation>
-<translation id="3084806535845658316">입력 에코 없음</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">다음 수식이 없습니다.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">다음 랜드마크</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">접힘</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">랜드마크 목록 표시</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">다음 행</translation>
-<translation id="3155083529632865074">이전 버튼이 없습니다.</translation>
-<translation id="3163593631834463955">열 헤더가 비어 있음</translation>
-<translation id="316542773973815724">탐색</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{공백}other{공백 #개}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> 입력함</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, 탭</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">방문한 링크입니다.</translation>
-<translation id="323731244387692321">ChromeVox 키보드 도움말 열기</translation>
-<translation id="3241052487511142956">이전 방문한 링크</translation>
-<translation id="3286390186030710347">슬라이더</translation>
-<translation id="3299925995433437805">다음 방문한 링크가 없습니다.</translation>
-<translation id="3303384412438961941">아무 키나 눌러서 이름을 알아 보세요. Ctrl+W를 누르면 키보드 탐색기가 닫힙니다.</translation>
-<translation id="3307886118343381874">표의 마지막으로 이동</translation>
-<translation id="3311969765485641742">알림을 검토하려면 Alt+Shift+A를 누릅니다.</translation>
-<translation id="3312997241656799641">다음 방문한 링크</translation>
-<translation id="3321460131042519426">줄바꿈 사용</translation>
-<translation id="3322936298410871309">이전 수준 1 제목</translation>
-<translation id="3323447499041942178">입력란</translation>
-<translation id="3353420241558113817">{"ar": "아랍어",
- "bg": "불가리아어",
- "ca": "카탈로니아어",
- "cs": "체코어",
- "da": "덴마크어",
- "de": "독일어",
- "de_CH": "독일어(스위스)",
- "de_DE": "독일어(독일)",
- "el": "그리스어",
- "en": "영어",
- "en_CA": "영어(캐나다)",
- "en_GB": "영어(영국)",
- "en_US": "영어(미국)",
- "es": "스페인어",
- "et": "에스토니아어",
- "fr": "프랑스어",
- "fr_CA": "프랑스어(캐나다)",
- "fr_FR": "프랑스어(프랑스)",
- "fi": "핀란드어",
- "he": "히브리어",
- "hi": "힌디어",
- "hr": "크로아티아어",
- "hu": "헝가리어",
- "is": "아이슬란드어",
- "it": "이탈리아어",
- "ko": "한국어",
- "lt": "리투아니아어",
- "lv": "라트비아어",
- "nb": "노르웨이어 보크몰",
- "nl": "네덜란드어",
- "pl": "폴란드어",
- "pt": "포르투갈어",
- "ro": "루마니아어",
- "ru": "러시아어",
- "sk": "슬로바키아어",
- "sl": "슬로베니아어",
- "sr": "세르비아어",
- "sv": "스웨덴어",
- "tr": "터키어",
- "vi": "베트남어",
- "zh": "중국어",
- "zh_TW": "중국어(번체)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{더하기 기호}other{더하기 기호 #개}}</translation>
-<translation id="338583716107319301">구분자</translation>
-<translation id="3389259863310851658">이전 양식 입력란</translation>
-<translation id="3390225400784126843">다음 다른 요소</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, 메뉴 항목</translation>
-<translation id="3406283310380167331">양식 목록 표시</translation>
-<translation id="3422338090358345848">키보드 탐색기 열기</translation>
-<translation id="3457000393508828486">부분적으로 누름</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, 버튼</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" />에서 <ph name="V2" />까지</translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{오른쪽 꺾음 괄호}other{오른쪽 꺾음 괄호 #개}}</translation>
-<translation id="3493915602752813531">다음 앵커가 없습니다.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{물음표}other{물음표 #개}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{탈자 기호}other{탈자 기호 #개}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, 체크박스 선택 안 됨</translation>
-<translation id="3599054940393788245">수학 영역에 있지 않음</translation>
-<translation id="3616113530831147358">오디오</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{백틱 기호}other{백틱 기호 #개}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{달러 기호}other{달러 기호 #개}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, 목록 상자</translation>
-<translation id="3687295507293856493">현재 셀의 열 헤더 추측</translation>
-<translation id="3692274950075847560">결과:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">음성 관리</translation>
-<translation id="3716845769494773620">여러 행</translation>
-<translation id="3731746171184829332">이전 제목이 없습니다.</translation>
-<translation id="3762198587642264450">현재 행의 마지막으로 이동</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">대화상자를 종료했습니다.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">자동완성 목록</translation>
-<translation id="3810838688059735925">동영상</translation>
-<translation id="3816633764618089385">다음 미디어</translation>
-<translation id="3819376190738087562">점프가 없습니다.</translation>
-<translation id="385383972552776628">옵션 페이지 열기</translation>
-<translation id="3856075812838139784">읽기 전용</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">메뉴</translation>
-<translation id="3909320334364316587">이전 수준 6 제목</translation>
-<translation id="3914173277599553213">필수</translation>
-<translation id="3962990492275676168">현재 위치부터 읽기 시작</translation>
-<translation id="4004802134384979325">선택됨</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">월 설정</translation>
-<translation id="4039983576244166038">행 헤더가 비어 있음</translation>
-<translation id="4042843249978639960">다음 수준 2 제목이 없습니다.</translation>
-<translation id="4043348641337972076">이전 ARIA 랜드마크가 없습니다.</translation>
-<translation id="4047216625641135770">표시</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{물결표}other{물결표 #개}}</translation>
-<translation id="409334809956508737">이전 객체</translation>
-<translation id="4099274309791143834">하위 메뉴 포함</translation>
-<translation id="4107807507418787238">아래에 셀이 없습니다.</translation>
-<translation id="4116415223832267137">알림</translation>
-<translation id="4147126331795725888">다음 컨트롤이 없습니다.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{오른쪽 중괄호}other{오른쪽 중괄호 #개}}</translation>
-<translation id="4158704014418536539">대소문자를 구분합니다.</translation>
-<translation id="4161663686871496107">ChromeVox 음성 피드백 사용할 수 있음</translation>
-<translation id="4173994908659439270">다음 수정 가능한 텍스트 입력란이 없습니다.</translation>
-<translation id="4176463684765177261">사용 중지</translation>
-<translation id="4188530942454211480">이전 문장</translation>
-<translation id="4202186506458631436">오른쪽으로 이동</translation>
-<translation id="4206289001967551965">표 내부</translation>
-<translation id="4215733775853809057">다음 슬라이더</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{대시}other{대시 #개}}</translation>
-<translation id="421884353938374759">color picker</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">왼쪽에 셀이 없습니다.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" />등급</translation>
-<translation id="4253168017788158739">메모</translation>
-<translation id="4254798249533888099">트리</translation>
-<translation id="4255943572433203166">아래 옵션을 사용하여 ChromeVox를 맞춤설정하세요. 변경사항은 바로 적용됩니다.</translation>
-<translation id="4271220233568730077">다음 수식</translation>
-<translation id="4271521365602459209">결과가 더 이상 없습니다.</translation>
-<translation id="4287520460805643128">다음 도움말이 없습니다.</translation>
-<translation id="4289540628985791613">개요</translation>
-<translation id="4300318234632215983">링크 이면의 URL 알림</translation>
-<translation id="4301352596632316575">하위 메뉴 있음</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{마침표}=3{생략 부호}other{마침표 #개}}</translation>
-<translation id="4347461890115250064">다음 목록이 없습니다.</translation>
-<translation id="4367650418938037324">Math ML 리프</translation>
-<translation id="4372435075475052704">최소:<ph name="X" /></translation>
-<translation id="4372705107434148843">음성 중지</translation>
-<translation id="4373197658375206385">링크가 아닌 이전 항목이 없습니다.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">링크가 없습니다.</translation>
-<translation id="4476183483923481720">새로운 행</translation>
-<translation id="4482330759234983253">이전 표</translation>
-<translation id="4491109536499578614">이미지</translation>
-<translation id="4529987814483543472">기본 키맵</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{슬래시}other{슬래시 #개}}</translation>
-<translation id="4547556996012970016">다음 수준 5 제목</translation>
-<translation id="4562381607973973258">머리글</translation>
-<translation id="4591507479202817876">, 선택됨</translation>
-<translation id="4597532268155981612">양식</translation>
-<translation id="4597896406374528575">4월</translation>
-<translation id="4615592953348396470">다음 키 누름 무시</translation>
-<translation id="461613135510474570">문장</translation>
-<translation id="4647836961514597010">색상선택 도구</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">이전 랜드마크</translation>
-<translation id="4696413482802371445">다음 수준 5 제목이 없습니다.</translation>
-<translation id="4729095194763193578">이전 행</translation>
-<translation id="4736221692378411923">8월</translation>
-<translation id="4740661827607246557">도움말 명령어</translation>
-<translation id="4759716709594980008">Chrome OS 키보드 탐색기</translation>
-<translation id="4763296182459741068">페이지 하단으로 행 이동</translation>
-<translation id="4763480195061959176">동영상</translation>
-<translation id="479989351350248267">검색</translation>
-<translation id="481165870889056555">현재 페이지의 제목 알림</translation>
-<translation id="4826415162591436065">앞으로 탐색</translation>
-<translation id="4826604887384865800">다음 점프</translation>
-<translation id="4827410568042294688">선택되지 않음</translation>
-<translation id="4842108708071771135">다음 인용구가 없습니다.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">이전 유사한 요소</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS 로깅 사용</translation>
-<translation id="4877261390094455813">검색어를 입력하세요.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">내부 링크</translation>
-<translation id="4953585991029886728">텍스트 수정</translation>
-<translation id="4954534434583049121">이전 블록 인용</translation>
-<translation id="4973717656530883744">최소 <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" />(으)로 전환했습니다.</translation>
-<translation id="4975416682604111799">밀리초</translation>
-<translation id="49787999531187221">ChromeVox가 비활성화되었습니다.</translation>
-<translation id="4979404613699303341">이전 버튼</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, 목록 상자</translation>
-<translation id="4983588134362688868">페이지 처음으로 이동</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, 창</translation>
-<translation id="4993152509206108683">속도: <ph name="PERCENT" />퍼센트</translation>
-<translation id="4996716799442435517">시각적</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, 라디오 버튼이 선택됨</translation>
-<translation id="4997475792277222884">링크가 아닌 다음 항목이 없습니다.</translation>
-<translation id="5000760171916499057">양식이 없습니다.</translation>
-<translation id="5005670136041063723">더 이상 유사한 요소가 없습니다.</translation>
-<translation id="501473567976723023">1월</translation>
-<translation id="5041394372352067729">점자 디스플레이를 페이지 상단으로 이동합니다.</translation>
-<translation id="5042770794184672516">음성 볼륨 높이기</translation>
-<translation id="5050015258024679800">이전 수준 4 제목</translation>
-<translation id="5054047268577924192">이전 목록 항목</translation>
-<translation id="5078661581131202757">파일 선택</translation>
-<translation id="5080758118274074384">더블 클릭함</translation>
-<translation id="5098541983634824365">격자를 종료합니다.</translation>
-<translation id="5102981729317424850">툴바</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">이전 양식 입력란이 없습니다.</translation>
-<translation id="5111640677200759579">열 헤더</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">이전 링크가 없습니다.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, 선택되지 않음</translation>
-<translation id="5183440668879371625">점자 이전 행으로 이동</translation>
-<translation id="5184944171021383281">다음 양식 입력란이 없습니다.</translation>
-<translation id="5189244881767082992">행</translation>
-<translation id="5203930734796605961"><ph name="KEY" />에는 이미 명령어가 할당되어 있습니다.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> 목록입니다.</translation>
-<translation id="520883772648104506">다음 라디오 버튼이 없습니다.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">객체</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, 탭</translation>
-<translation id="5310788376443009632">삭제됨:</translation>
-<translation id="5320727453979144100">고정 모드 사용함</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{쉼표}other{쉼표 #개}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, 입력란</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, 링크</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">계속 읽고 있는 중에 뒤로 건너뛰기</translation>
-<translation id="5368000168321181111">이어콘 사용 안함</translation>
-<translation id="5374320867641260420">다음 버튼이 없습니다.</translation>
-<translation id="5382299583965267720">다음 수준 1 제목이 없습니다.</translation>
-<translation id="5402367795255837559">점자</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{세미콜론}other{세미콜론 #개}}</translation>
-<translation id="5411891038905756502">이전 점프 지점이 없습니다.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{작음 부호}other{작음 부호 #개}}</translation>
-<translation id="5455441614648621694">상호 보완</translation>
-<translation id="5485036206801896268">이전 그래픽이 없습니다.</translation>
-<translation id="5486947920110100234">다음 점프 지점이 없습니다.</translation>
-<translation id="549602578321198708">단어</translation>
-<translation id="5500932716852106146">이전 수정 가능한 텍스트 입력란이 없습니다.</translation>
-<translation id="5502713021410870035">9월</translation>
-<translation id="5507663321906818013">디버그 벤치마크</translation>
-<translation id="5518443085409638729">텍스트 수정 시 커서를 문자 사이에 위치합니다(Mac OS X처럼).</translation>
-<translation id="552195134157544755">라디오 버튼</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">이전 수준 5 제목이 없습니다.</translation>
-<translation id="556042886152191864">버튼</translation>
-<translation id="5561345396546889625">다음 목록</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">텍스트 수정, 이메일 항목</translation>
-<translation id="5597170376237141345">다음 체크박스</translation>
-<translation id="5597933780944041114">다음 제목이 없습니다.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, 라디오 버튼 선택 안 됨</translation>
-<translation id="5601172225407283979">기본 작업 수행</translation>
-<translation id="5608798115546226984">자동완성 본문</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">로그</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">이전 표가 없습니다.</translation>
-<translation id="5655682562155942719">이동 명령어</translation>
-<translation id="56637627897541303">텍스트 영역</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">랜드마크</translation>
-<translation id="5683155931978483559">이전 체크박스</translation>
-<translation id="5684277895745049190">목록</translation>
-<translation id="5700650669149824506">이전 수준 4 제목이 없습니다.</translation>
-<translation id="5709192780268610569">자세한 설명 없음</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">다음 열</translation>
-<translation id="571866080859340309">그룹 탐색</translation>
-<translation id="5728409797179002635">표를 찾을 수 없습니다.</translation>
-<translation id="5748623122140342504">이전 수준 5 제목</translation>
-<translation id="5750633686117194034">특수키를 누르지 않았습니다. 하나 이상의 특수키를 길게 누르세요. 완료 후 손가락을 떼면 키가 설정되었다는 메시지가 나옵니다. 탭하여 종료하세요.</translation>
-<translation id="5788275253279308023">시크릿 창, <ph name="TITLE" /> 탭</translation>
-<translation id="5806206155699461681">특정 사이트 개선(예: Google 검색)</translation>
-<translation id="5819072574982403430">트리 항목</translation>
-<translation id="5826479389509458994"><ph name="ROW" />행 <ph name="COL" />열</translation>
-<translation id="5850707923114094062">뒤로 이동합니다.</translation>
-<translation id="5851548754964597211">탭 목록</translation>
-<translation id="5859752971144398932">페이지의 찾기를 종료했습니다.</translation>
-<translation id="5866042630553435010">일부 확인됨</translation>
-<translation id="5869546221129391014">격자</translation>
-<translation id="5876817486144482042">음성 볼륨 줄이기</translation>
-<translation id="5887397643266327462">점자 캡션을 사용 설정했습니다.</translation>
-<translation id="5891934789323004067">표</translation>
-<translation id="5919442531159595654">복사합니다.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{등호}other{등호 #개}}</translation>
-<translation id="5939518447894949180">재설정</translation>
-<translation id="5948123859135882163">수식 해석을 구조 해석과 의미 해석 간에 전환</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">대화상자</translation>
-<translation id="5963413905009737549">섹션</translation>
-<translation id="5968607524793740041">컨텍스트 메뉴 표시</translation>
-<translation id="5983179082906765664">탐색 세밀도 높이기</translation>
-<translation id="5999630716831179808">음성</translation>
-<translation id="6000417740266304866">아래의 목록에서 옵션을 선택하여 현재의 8점 점자 표를 변경합니다.</translation>
-<translation id="6006050241733874051">양식</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{역슬래시}other{역슬래시 #개}}</translation>
-<translation id="6037602951055904232">앞으로 이동</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">마지막 셀입니다.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">공백</translation>
-<translation id="6142308968191113180">제목 4</translation>
-<translation id="6169420925157477918">자세한 설명이 있는 이미지</translation>
-<translation id="6172087735260766220">복제 방지된 PDF에서 액세스 가능한 텍스트에 액세스할 수 없습니다.</translation>
-<translation id="6186305613600865047">페이지 끝으로 이동</translation>
-<translation id="6193330012414963395">오전/오후</translation>
-<translation id="622484624075952240">아래</translation>
-<translation id="6236061028292614533">다음 제목</translation>
-<translation id="6254901459154107917">다음 수정 가능 텍스트 영역</translation>
-<translation id="6259464875943891919"><ph name="TYPE" />을(를) 종료합니다.</translation>
-<translation id="6281876499889881039">다음 유사한 요소</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">다음 콤보 상자가 없습니다.</translation>
-<translation id="6307969636681130414">누름</translation>
-<translation id="6324551002951139333">문법 오류 발견됨</translation>
-<translation id="6348657800373377022">콤보 상자</translation>
-<translation id="6355910664415701303">이전 목록 항목이 없습니다.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">이전 제목</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">이전 라디오 버튼이 없습니다.</translation>
-<translation id="6414968628640960377">이전 다른 요소</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{콜론}other{콜론 #개}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, 메뉴</translation>
-<translation id="6444046323172968959">알림 대화상자</translation>
-<translation id="6459511626086141404">플랫 키맵</translation>
-<translation id="6468049171101508116">다음 버튼</translation>
-<translation id="6491972999578897419">아래 목록에서 옵션을 선택하여 현재 음성을 변경합니다.</translation>
-<translation id="6508059270146105198">점자 디스플레이를 페이지 하단으로 이동합니다.</translation>
-<translation id="6536864053412760904">Math ML 토큰</translation>
-<translation id="6550720799683018100">아래 목록에서 옵션을 선택하여 현재 키맵을 변경합니다.</translation>
-<translation id="6561818612645211875">현재 행의 처음으로 이동</translation>
-<translation id="6587021927234520429">다음 수준 4 제목이 없습니다.</translation>
-<translation id="6601344353291556895">상세한 설명을 사용합니다.</translation>
-<translation id="6615602925644411249">페이지에서 찾습니다.</translation>
-<translation id="6633350132811819843">다음 표가 없습니다.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">진행률 표시줄</translation>
-<translation id="6659594942844771486">탭</translation>
-<translation id="667999046851023355">문서</translation>
-<translation id="6697092096875747123">이전 콤보 상자</translation>
-<translation id="6714813999819678458">이전 수준 2 제목</translation>
-<translation id="6716505898850596801">특수키</translation>
-<translation id="671916444866103745">다음 ARIA 랜드마크가 없습니다.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, 콤보 상자</translation>
-<translation id="6735257939857578167"><ph name="NUM" />개 항목 포함</translation>
-<translation id="6736510033526053669">탭이 생성됨</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">도움말</translation>
-<translation id="6787839852456839824">단축키</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">바닥글</translation>
-<translation id="6871161210040114857">대소문자를 구분하지 않습니다.</translation>
-<translation id="6877435256196695200">다음 그래픽이 없습니다.</translation>
-<translation id="6897341342232909480">왼쪽으로 이동</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">삭제됨</translation>
-<translation id="6911965441508464308">위에 셀이 없습니다.</translation>
-<translation id="6919104639734799681">표 목록 표시</translation>
-<translation id="6964088412282673743">이전 컨트롤이 없습니다.</translation>
-<translation id="6996566555547746822">다음 콤보 상자</translation>
-<translation id="7005146664810010831">URL을 찾을 수 없음</translation>
-<translation id="7010712454773919705">ChromeVox 특수키</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">이전 목록</translation>
-<translation id="7041173719775863268">선택 종료</translation>
-<translation id="7095834689119144465">텍스트 숫자만 수정</translation>
-<translation id="7096001299300236431">이전 미디어</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">단어 에코</translation>
-<translation id="713824876195128146">다음 블록 인용</translation>
-<translation id="7161771961008409533">팝업 버튼</translation>
-<translation id="7167657087543110">문자 에코</translation>
-<translation id="7170733337935166589">계속 읽고 있는 중에 앞으로 건너뛰기</translation>
-<translation id="7181697990050180700">아래의 해당 입력란에 자주 사용하는 명령어를 입력하여 단축키를 맞춤설정합니다.</translation>
-<translation id="7203150201908454328">펼쳐짐</translation>
-<translation id="7210211103303402262">분</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">선</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">제목</translation>
-<translation id="7241683698754534149">새 탭에서 자세한 설명 열기</translation>
-<translation id="7248671827512403053">애플리케이션</translation>
-<translation id="725969808843520477">다음 라디오 버튼</translation>
-<translation id="7269119382257320590">구두점을 읽지 않음</translation>
-<translation id="7273174640290488576">비어 있음</translation>
-<translation id="7285387653379749618">표</translation>
-<translation id="7289186959554153431">제목 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" />(<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">점자 캡션을 사용 중지했습니다.</translation>
-<translation id="7318872822751139669">마우스를 사용하여 초점을 변경하세요.</translation>
-<translation id="7322388933135261569">2월</translation>
-<translation id="7332592614823088566"><ph name="ROWTOTAL" />개 중 <ph name="ROWINDEX" />번째 행, <ph name="COLTOTAL" />개 중 <ph name="COLINDEX" />번째 열</translation>
-<translation id="7336596009609913925">팝업있음</translation>
-<translation id="7356165926712028380">8점 점자로 전환</translation>
-<translation id="7362871137496673139">이전 수준 2 제목이 없습니다.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{앰퍼샌드}other{앰퍼샌드 #개}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">표를 종료합니다.</translation>
-<translation id="739763518212184081">이전 행</translation>
-<translation id="7400575256015741911">철자 오류 발견됨</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">리턴</translation>
-<translation id="7434509671034404296">개발자 정보</translation>
-<translation id="7439060726180460871">디렉토리</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">대화상자 입력함</translation>
-<translation id="7532613204005497612">6월</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, 슬라이더</translation>
-<translation id="7586163296341959563">붙여넣습니다.</translation>
-<translation id="7596919493010894443">선택항목 삭제됨</translation>
-<translation id="7604026522577407655">현재 열의 처음으로 이동</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">현재 페이지의 URL 알림</translation>
-<translation id="7609363189280667021">점자 캡션 전환</translation>
-<translation id="762020119231868829">현재 재생 중인 미디어 위젯 모두 일시중지</translation>
-<translation id="7625690649919402823">다음 표</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" />(<ph name="VARIANT" />), <ph name="GRADE" />등급</translation>
-<translation id="7641134354185483015">이전 수준 3 제목이 없습니다.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, 입력란</translation>
-<translation id="7663318257180412551">제목 2</translation>
-<translation id="7674576868851035240">다음 링크</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">텍스트 수정, URL 항목</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">이전 라디오 버튼</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, 비밀번호 입력란</translation>
-<translation id="7805247615045262757">기본 탐색</translation>
-<translation id="7805768142964895445">상태</translation>
-<translation id="7810781339813764006">다음 그룹</translation>
-<translation id="7819187121850078213">창, <ph name="TITLE" /> 탭</translation>
-<translation id="7828956995407538686">10월</translation>
-<translation id="7839679365527550018">이전 단어</translation>
-<translation id="7851816175263618915">일부 구두점만 읽음</translation>
-<translation id="7870596830398826354">Math ML 트리</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox 클래식으로 전환합니다.</translation>
-<translation id="7895896691902835279">알 수 없는 링크</translation>
-<translation id="7927711904086083099">선택되지 않음</translation>
-<translation id="7935627501098484003">시간 컨트롤</translation>
-<translation id="7939428177581522200">선택에 추가됨</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{애트 기호}other{애트 기호 #개}}</translation>
-<translation id="7965147473449754028">메뉴 닫힘</translation>
-<translation id="7974390230414479278">메뉴 항목</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{느낌표}other{느낌표 #개}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{따옴표}other{따옴표 #개}}</translation>
-<translation id="8033827949643255796">선택됨</translation>
-<translation id="8035962149453661158">최대:<ph name="X" /></translation>
-<translation id="8042761080832772327">텍스트 수정, 검색어 항목</translation>
-<translation id="8049189770492311300">타이머</translation>
-<translation id="8065607967589909823">현재 선택</translation>
-<translation id="8066678206530322333">배너</translation>
-<translation id="8110647606445335195">ARIA 랜드마크가 없습니다.</translation>
-<translation id="8153880621934657047">표 내부가 아닙니다.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{밑줄}other{밑줄 기호 #개}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">잘라냅니다.</translation>
-<translation id="8199231515320852133">현재 셀의 헤더 알림</translation>
-<translation id="820417203470636242">빈 셀입니다.</translation>
-<translation id="8215202828671303819">다중 선택</translation>
-<translation id="8276439074553447000">이전 초점 가능 항목으로 이동</translation>
-<translation id="8278417001922463147">이전 도움말이 없습니다.</translation>
-<translation id="8283603667300770666">다음 양식 입력란</translation>
-<translation id="831207808878314375">정의</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">시간</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{파운드 기호}other{파운드 기호 #개}}</translation>
-<translation id="8374154622594089836">month</translation>
-<translation id="8378855320830505539">지역</translation>
-<translation id="8382679411218029383">자동완성 본문 및 목록</translation>
-<translation id="8428603554127842284">수준 <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">다음 수준 3 제목이 없습니다.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">이전 체크박스가 없습니다.</translation>
-<translation id="8455868257606149352">최대 <ph name="X" /></translation>
-<translation id="84575901236241018">액세스 키(<ph name="KEY" />) 있음</translation>
-<translation id="8503360654911991865">탐색 세밀도 낮추기</translation>
-<translation id="8520472399088452386">스핀 버튼</translation>
-<translation id="8538744478902126321">현재 셀의 행 헤더 추측</translation>
-<translation id="8540054775867439484">페이지 상단으로 행 이동</translation>
-<translation id="8548973727659841685">문자</translation>
-<translation id="8561322612995434619">팝업 있음</translation>
-<translation id="8571096049907249734">다중 선택</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">다음 목록 항목</translation>
-<translation id="860150890330522909"><ph name="NAME" /> 체크박스 선택됨</translation>
-<translation id="8606621670302093223">날짜 컨트롤</translation>
-<translation id="8631359288236106450"><ph name="COUNT" />개 항목 선택됨</translation>
-<translation id="8638532244051952400">현재 셀 좌표 알림</translation>
-<translation id="8650576015643545550">이전 목록이 없습니다.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">링크 목록 표시</translation>
-<translation id="8664519043722036194">초</translation>
-<translation id="867187640362843212">제목 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{수직 기호}other{수직 기호 #개}}</translation>
-<translation id="8735450637152821465">선택 시작</translation>
-<translation id="8743786158317878347">구조화된 콘텐츠(예: 표) 입력</translation>
-<translation id="8747966237988593539">정렬된 목록</translation>
-<translation id="8759334257841767240">다음 링크가 없습니다.</translation>
-<translation id="8767968232364267681">다음 수준 4 제목</translation>
-<translation id="8770473310765924354">구조화된 콘텐츠(예: 표) 종료</translation>
-<translation id="8791025954632646584">의미 해석 사용</translation>
-<translation id="8796411681063377102">다음 수준 3 제목</translation>
-<translation id="8808582214901541005">3월</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">명령어를 확인하려면 위/아래를 누르고 실행하려면 Enter 키를 누릅니다.</translation>
-<translation id="8864099967139188018">다음 수준 6 제목이 없습니다.</translation>
-<translation id="8882002077197914455">행 헤더</translation>
-<translation id="8896347895970027998">ChromeVox를 활성화 또는 비활성화로 전환</translation>
-<translation id="8898516272131543774">순환 구두점 에코</translation>
-<translation id="8900148057318340779">Prefix 키</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">헤더가 비어 있음</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">특수키</translation>
-<translation id="8943175951035496220">오른쪽에 셀이 없습니다.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">표가 없습니다.</translation>
-<translation id="9040132695316389094">제목 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">검색 위젯 전환</translation>
-<translation id="9065283790526219006">팝업있음</translation>
-<translation id="9077213568694924680">선택 항목에서 삭제</translation>
-<translation id="9082874451376019682">이전 슬라이더가 없습니다.</translation>
-<translation id="9089864840575085222">순환 입력 에코</translation>
-<translation id="9107530006868467849">이전 미디어 위젯이 없습니다.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{퍼센트 기호}other{퍼센트 기호 #개}}</translation>
-<translation id="9115913704608474258">11월</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">현재 위치에 대한 간단한 설명을 들려줍니다.</translation>
-<translation id="9153606228985488238">음조: <ph name="PERCENT" />퍼센트</translation>
-<translation id="9160096769946561184">현재 열의 마지막으로 이동</translation>
-<translation id="9173115498289768110">볼륨: <ph name="PERCENT" />퍼센트</translation>
-<translation id="9178973770513562274">위쪽 또는 아래쪽 화살표 키를 사용하여 탐색하거나 검색어를 입력하세요.</translation>
-<translation id="9192904702577636854">마키</translation>
-<translation id="9212322457209634662">다음 섹션이 없습니다.</translation>
-<translation id="930275611743429116">선택을 시작 또는 종료합니다.</translation>
-<translation id="948171205378458592">말하기 속도 줄이기</translation>
-<translation id="962913030769097253">다음 수준 1 제목</translation>
-<translation id="973955474346881951">고정 모드 사용/사용 중지</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lt.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lt.xtb
deleted file mode 100644
index f94267cb3b2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lt.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="lt">
-<translation id="1012173283529841972">Sąrašo elementas</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Apimta.</translation>
-<translation id="1025074108959230262">Fiksuojamasis režimas neleidžiamas</translation>
-<translation id="1031961866430398710">tada</translation>
-<translation id="1044777062731150180">Nėra antraščių</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Įvestis negalioja</translation>
-<translation id="1082209053475788238">Nėra ankstesnės 6 lygio antraštės.</translation>
-<translation id="1088219014394087294">Nėra antraščių.</translation>
-<translation id="1106741348836243114">Įjunkite arba išjunkite garsinius atsiliepimus (garsinius ženklelius).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="TAG" /> rinkinys, kuriame yra <ph name="NUM" /> element.</translation>
-<translation id="1155043339247954670">Nėra kito sąrašo elemento.</translation>
-<translation id="1157782847298808853">Klaviatūros pagalba</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, jungtinis laukelis</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, meniu elementas, su submeniu</translation>
-<translation id="1177863135347784049">Priskirtas</translation>
-<translation id="1188858454923323853">papildomas</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">„ChromeVox“ suteikia „Chrome“ balsą</translation>
-<translation id="1229276918471378188">Ankstesnis perėjimas</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Kita 6 lygio antraštė</translation>
-<translation id="1275718070701477396">Pasirinkta</translation>
-<translation id="1319608975892113573">Nėra ankstesnės įtraukos.</translation>
-<translation id="1321576897702511272">Slėpti „ChromeVox“ pagalbą</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> iš <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">simbolio ir žodžio aidas</translation>
-<translation id="1339428534620983148">Ankstesnis lentelės stulpelis</translation>
-<translation id="1342835525016946179">artikelis</translation>
-<translation id="1346748346194534595">Dešinė</translation>
-<translation id="136718599399906424">Kita lentelės eilutė</translation>
-<translation id="1383876407941801731">Ieškoti</translation>
-<translation id="1385214448885562192">Jei norite priimti, spustelėkite „Enter“, jei atšaukti – „Cancel“. Rodyklėmis aukštyn ir žemyn galite peržiūrėti ankstesnius ir kitus pasiūlymus.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, slaptažodžio teksto laukelis</translation>
-<translation id="1467432559032391204">Kairė</translation>
-<translation id="1474557363159888097">Nėra ankstesnio prieraišo.</translation>
-<translation id="1502086903961450562">Ankstesnis grafinis elementas</translation>
-<translation id="1506187449813838456">Padidinti aukštį</translation>
-<translation id="151784044608172266">Kitas sakinys</translation>
-<translation id="1524531499102321782">Kita Brailio rašmenų eilutė</translation>
-<translation id="1546370775711804143">Slinkties juosta</translation>
-<translation id="1559739829547075274">Eiti atgal</translation>
-<translation id="1571643229714746283">„ChromeVox“ parengtas</translation>
-<translation id="158493514907962286">Gruodis</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Perjungti į 6 taškų Brailio rašmenis</translation>
-<translation id="1611168825862729585">Stulpelio antraštė:</translation>
-<translation id="1613476421962910979">Garsiniai ženkleliai įjungti</translation>
-<translation id="1618597272655350600">Paskelbiamas išsamus esamos pozicijos aprašas</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{ženklas daugiau}one{# ženklas daugiau}few{# ženklai daugiau}many{# greater than signs}other{# ženklų daugiau}}</translation>
-<translation id="1653266918374749391">Ankstesnė 3 lygio antraštė</translation>
-<translation id="1659072772017912254">Nepažymėta</translation>
-<translation id="1669290819662866522">sav.</translation>
-<translation id="1674262202423278359">„ChromeVox“ naršymas</translation>
-<translation id="16777221443363124">Meniu juosta</translation>
-<translation id="1692077714702418899">struktūrinė linija</translation>
-<translation id="1700517974991662022">Apsilankyta</translation>
-<translation id="1722567105086139392">Nuoroda</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Kitas grafinis elementas</translation>
-<translation id="1781173782405573156">Praleidimo klavišas</translation>
-<translation id="1787176709638001873">Redaguoti slaptažodžio tekstą</translation>
-<translation id="1810107444790159527">Sąrašo laukelis</translation>
-<translation id="1828385960365606039">Geg.</translation>
-<translation id="1834891354138622109">Stulpelis</translation>
-<translation id="1865601187525349519">Teksto pabaiga</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Pasakykite dabartinį laiką ir datą.</translation>
-<translation id="1902396333223336119">Langelis</translation>
-<translation id="1905379170753160525">Rodyti antraščių sąrašą</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Metų savaitės valdiklis</translation>
-<translation id="1964135212174907577">Kitas objektas</translation>
-<translation id="1969092762068865084">Liepa</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Eilutės antraštė:</translation>
-<translation id="2002895034995108595">Nustatyti dabartinį klavišų žemėlapį iš naujo</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{atidaromasis laužtinis skliaustas}one{# atidaromasis laužtinis skliaustas}few{# atidaromieji laužtiniai skliaustai}many{# left brackets}other{# atidaromųjų laužtinių skliaustų}}</translation>
-<translation id="2045490512405922022">nepažymėta</translation>
-<translation id="20601713649439366">Nėra ankstesnės matematinės išraiškos.</translation>
-<translation id="207477615537953741">Semantinis interpretavimas išjungtas</translation>
-<translation id="2086961585857038472">Kitas žodis</translation>
-<translation id="2089387485033699258">lt</translation>
-<translation id="2091933974477985526">Ankstesnė teksto sritis, kurią galima redaguoti</translation>
-<translation id="2100350898815792233">Su visais skyrybos ženklais</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">prieigos klavišas: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Pakeisti dabartinę 6 taškų Brailio rašmenų lentelę pasirinkus parinktį iš toliau pateikiamo sąrašo.</translation>
-<translation id="2169714232367507776">Spustelėti dabartinį elementą</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{uždaromasis skliaustas}one{# uždaromasis skliaustas}few{# uždaromieji skliaustai}many{# close parens}other{# uždaromųjų skliaustų}}</translation>
-<translation id="2199994615414171367">Ankstesnis matematinis raktas</translation>
-<translation id="2223693656926968778">Imtis veiksmų dėl dabartinio elemento</translation>
-<translation id="225732394367814946">Padidinti kalbos tempą</translation>
-<translation id="2267945578749931355">Kitas simbolis</translation>
-<translation id="2281234842553884450">Ankstesnis šliaužiklis</translation>
-<translation id="2318372665160196757">Pagrindinis</translation>
-<translation id="2329324941084714723">Skirtuko skydelis</translation>
-<translation id="2344193891939537199">Datos ir laiko valdiklis</translation>
-<translation id="2359897517538099099">Ne lentelės režimu.</translation>
-<translation id="241124561063364910">ir</translation>
-<translation id="2417569100218200841">Turinio informacija</translation>
-<translation id="2422937916923936891">Meniu elemento žymimasis laukelis</translation>
-<translation id="2429669115401274487">popiet</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> dabar yra naujasis „ChromeVox“ modifikatorius.</translation>
-<translation id="2450814015951372393">Žymimasis laukelis</translation>
-<translation id="2462626033734746142">Akučių grupė</translation>
-<translation id="2471138580042810658">6 antraštė</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{žvaigždutė}one{# žvaigždutė}few{# žvaigždutės}many{# asterisks}other{# žvaigždučių}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> nustatytas iš naujo.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Grupė</translation>
-<translation id="2582407057977008361">Šalia</translation>
-<translation id="2589102159832527089">Šiame puslapyje yra automatiškai iš PDF failo &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; ištrauktas tekstas. &lt;a href="<ph name="URL" />"&gt;Jei reikia originalo, spustelėkite čia.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">su {COUNT,plural, =1{# elementu}one{# elementu}few{# elementais}many{# elemento}other{# elementų}}</translation>
-<translation id="2614981083756825552">Matematikos žymėjimo kalbos išdėstymas</translation>
-<translation id="2626530649491650971">spustelėjamas</translation>
-<translation id="2628764385451019380">Nėra ankstesnio išskleidžiamojo laukelio.</translation>
-<translation id="2637227747952042642">Matematika</translation>
-<translation id="2639750663247012216">„ChromeVox“ modifikatorius</translation>
-<translation id="2644542693584024604">netaisyklingai parašyta</translation>
-<translation id="2667291555398229137">Spustelėkite maršruto parinkimo rakto elementą</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{atidaromasis skliaustas}one{# atidaromasis skliaustas}few{# atidaromieji skliaustai}many{# open parens}other{# atidaromųjų skliaustų}}</translation>
-<translation id="2705875883745373140">Nepaspausta</translation>
-<translation id="2706462751667573066">Aukštyn</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">garso įrašas</translation>
-<translation id="2732718972699418926">priešpiet</translation>
-<translation id="2749275490991666823">Pažymėta</translation>
-<translation id="27527859628328957">Pereiti prie kito elemento, kurį galima fokusuoti</translation>
-<translation id="2770781857296573485">Pradėti grupės tyrinėjimą</translation>
-<translation id="2777845298774924149">Išeita</translation>
-<translation id="2800204403141299078">Daugiau skirtingų elementų nėra.</translation>
-<translation id="2800780099804980316">Nėra ankstesnės 1 lygio antraštės.</translation>
-<translation id="2811204574343810641">Eilutė</translation>
-<translation id="2816654101880605877">Nėra kito šliaužiklio.</translation>
-<translation id="2841013758207633010">Laikas</translation>
-<translation id="2843837985843789981">Ankstesnė grupė</translation>
-<translation id="2844995807198708617">Kontekstinis meniu</translation>
-<translation id="2849332794118375855">Nėra kito žymimojo laukelio.</translation>
-<translation id="2864481629947106776">Ankstesnė nuoroda</translation>
-<translation id="2873259058405069099">Eiti į lentelės pradžią</translation>
-<translation id="2894654529758326923">Informacija</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{atidaromasis riestinis skliaustas}one{# atidaromasis riestinis skliaustas}few{# atidaromieji riestiniai skliaustai}many{# left braces}other{# atidaromųjų riestinių skliaustų}}</translation>
-<translation id="2911433807131383493">Atidaryti „ChromeVox“ mokymo programą</translation>
-<translation id="2932083475399492303">Perjungti linijos tipą iš struktūrinio į išdėstymo</translation>
-<translation id="2964026537669811554">Antraščių grupė</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabuliavimo ženklas}one{# tabuliavimo ženklas}few{# tabuliavimo ženklai}many{# tabs}other{# tabuliavimo ženklų}}</translation>
-<translation id="2972078295414139404">Nėra ankstesnės aplankytos nuorodos.</translation>
-<translation id="2972205263822847197">Patarimas</translation>
-<translation id="2998131015536248178">Ankstesnis simbolis</translation>
-<translation id="2999559350546931576">Sumažinti aukštį</translation>
-<translation id="2999945368667127852">Nėra kito medijų valdiklio.</translation>
-<translation id="3012414509011670858">Nėra ankstesnės skilties.</translation>
-<translation id="3030432017085518523">Meniu elemento akutė</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrofas}one{# apostrofas}few{# apostrofai}many{# apostrophes}other{# apostrofų}}</translation>
-<translation id="3046838483509668188">„ChromeVox“ parinktys</translation>
-<translation id="3047143736589213134">Eksperimentinis klavišų žemėlapis</translation>
-<translation id="3060756054951570867">„<ph name="TITLE" />“, meniu atidarytas</translation>
-<translation id="3078345202707391975">Kita 2 lygio antraštė</translation>
-<translation id="3078740164268491126">lentelė</translation>
-<translation id="3082557070674409251">Spustelėta</translation>
-<translation id="3084806535845658316">nėra įvedimo aido</translation>
-<translation id="3086746722712840547">pastaba</translation>
-<translation id="308895241372589742">Nėra kitos matematinės išraiškos.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Kitas orientyras</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Suskleista</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Rodyti orientyrų sąrašą</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Kita linija</translation>
-<translation id="3155083529632865074">Nėra ankstesnio mygtuko.</translation>
-<translation id="3163593631834463955">Tuščia stulpelio antraštė</translation>
-<translation id="316542773973815724">Naršymas</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{tarpas}one{# tarpas}few{# tarpai}many{# spaces}other{# tarpų}}</translation>
-<translation id="320961988183078793">įvesta <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, skirtukas</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Nuoroda, kuria apsilankyta</translation>
-<translation id="323731244387692321">Atidaryti „ChromeVox“ klaviatūros pagalbą</translation>
-<translation id="3241052487511142956">Ankstesnė aplankyta nuoroda</translation>
-<translation id="3286390186030710347">Šliaužiklis</translation>
-<translation id="3299925995433437805">Nėra kitos aplankytos nuorodos.</translation>
-<translation id="3303384412438961941">Jei norite sužinoti šį pavadinimą, paspauskite bet kurį klavišą. „Ctrl“ + W uždarys klaviatūros naršyklę.</translation>
-<translation id="3307886118343381874">Eiti į lentelės pabaigą</translation>
-<translation id="3311969765485641742">Jei norite peržiūrėti įspėjimus, paspauskite „Alt“ + „Shift“ + A</translation>
-<translation id="3312997241656799641">Kita aplankyta nuoroda</translation>
-<translation id="3321460131042519426">Įgalinti teksto skaidymą į eilutes</translation>
-<translation id="3322936298410871309">Ankstesnė 1 lygio antraštė</translation>
-<translation id="3323447499041942178">Teksto laukelis</translation>
-<translation id="3353420241558113817">{"ar": "arabų k.",
- "bg": "bulgarų k.",
- "ca": "katalonų k.",
- "cs": "čekų k.",
- "da": "danų k.",
- "de": "vokiečių k.",
- "de_CH": "vokiečių k. (Šveicarija)",
- "de_DE": "vokiečių k. (Vokietija)",
- "el": "graikų k.",
- "en": "anglų k.",
- "en_CA": "anglų k. (Kanada)",
- "en_GB": "anglų k. (Jungtinė Karalystė)",
- "en_US": "anglų k. (Jungtinės Amerikos Valstijos)",
- "es": "ispanų k.",
- "et": "estų k.",
- "fr": "prancūzų k.",
- "fr_CA": "prancūzų k. (Kanada)",
- "fr_FR": "prancūzų k. (Prancūzija)",
- "fi": "suomių k.",
- "he": "hebrajų k.",
- "hi": "hindi k.",
- "hr": "kroatų k.",
- "hu": "vengrų k.",
- "is": "islandų k.",
- "it": "italų k.",
- "ko": "korėjiečių k.",
- "lt": "lietuvių k.",
- "lv": "latvių k.",
- "nb": "norvegų k. (Bokmål)",
- "nl": "danų k.",
- "pl": "lenkų k.",
- "pt": "portugalų k.",
- "ro": "rumunų k.",
- "ru": "rusų k.",
- "sk": "slovakų k.",
- "sl": "slovėnų k.",
- "sr": "serbų k.",
- "sv": "švedų k.",
- "tr": "turkų k.",
- "vi": "vietnamiečių k.",
- "zh": "kinų k.",
- "zh_TW": "kinų k. (tradicinė hanių)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{pliuso ženklas}one{# pliuso ženklas}few{# pliuso ženklai}many{# plus signs}other{# pliuso ženklų}}</translation>
-<translation id="338583716107319301">Skyriklis</translation>
-<translation id="3389259863310851658">Ankstesnis formos laukas</translation>
-<translation id="3390225400784126843">Kitas kitoks elementas.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, meniu elementas</translation>
-<translation id="3406283310380167331">Rodyti formų sąrašą</translation>
-<translation id="3422338090358345848">Atidaryti klaviatūros naršyklę</translation>
-<translation id="3457000393508828486">Iš dalies paspausta</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, mygtukas</translation>
-<translation id="3473644018603298796">pas. elem.: <ph name="COUNT" /></translation>
-<translation id="3486232535569802404">Nuo <ph name="V1" /> iki <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{uždaromasis laužtinis skliaustas}one{# uždaromasis laužtinis skliaustas}few{# uždaromieji laužtiniai skliaustai}many{# right brackets}other{# uždaromųjų laužtinių skliaustų}}</translation>
-<translation id="3493915602752813531">Nėra kito prieraišo.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{klaustukas}one{# klaustukas}few{# klaustukai}many{# question marks}other{# klaustukų}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{stogelio ženklas}one{# stogelio ženklas}few{# stogelio ženklai}many{# carets}other{# stogelio ženklų}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, žymimasis laukelis nepažymėtas</translation>
-<translation id="3599054940393788245">Ne matematinis</translation>
-<translation id="3616113530831147358">Garsas</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{gravis}one{# gravis}few{# graviai}many{# backticks}other{# gravių}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolerio ženklas}one{# dolerio ženklas}few{# dolerio ženklai}many{# dollar signs}other{# dolerio ženklų}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, sąrašo laukelis</translation>
-<translation id="3687295507293856493">Parinkti dabartinio langelio stulpelio antraštę</translation>
-<translation id="3692274950075847560">P.: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Kalbos valdymas</translation>
-<translation id="3716845769494773620">Kelios eilutės</translation>
-<translation id="3731746171184829332">Nėra ankstesnės antraštės.</translation>
-<translation id="3762198587642264450">Eiti į dabartinės eilutės pabaigą</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Išeita iš dialogo lango.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}few{#}many{#}other{#}}</translation>
-<translation id="3801735343383419236">Sąrašo automatinis užbaigimas</translation>
-<translation id="3810838688059735925">Vaizdo</translation>
-<translation id="3816633764618089385">Kitas medijų raktas</translation>
-<translation id="3819376190738087562">Nėra perėjimų.</translation>
-<translation id="385383972552776628">Atidaryti parinkčių puslapį</translation>
-<translation id="3856075812838139784">Tik skaitoma</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Meniu</translation>
-<translation id="3909320334364316587">Ankstesnė 6 lygio antraštė</translation>
-<translation id="3914173277599553213">Būtina</translation>
-<translation id="3962990492275676168">Pradėti skaityti nuo dabartinės vietos</translation>
-<translation id="4004802134384979325">pažymėta</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Mėnesio valdymas</translation>
-<translation id="4039983576244166038">Tuščia eilutės antraštė</translation>
-<translation id="4042843249978639960">Nėra kitos 2 lygio antraštės.</translation>
-<translation id="4043348641337972076">Nėra ankstesnio ARIA orientyro.</translation>
-<translation id="4047216625641135770">Žymėjimas</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{tildė}one{# tildė}few{# tildės}many{# tildes}other{# tildžių}}</translation>
-<translation id="409334809956508737">Ankstesnis objektas</translation>
-<translation id="4099274309791143834">su submeniu</translation>
-<translation id="4107807507418787238">Nėra kito langelio.</translation>
-<translation id="4116415223832267137">Įspėjimas</translation>
-<translation id="4147126331795725888">Nėra kito valdiklio.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{uždaromasis riestinis skliaustas}one{# uždaromasis riestinis skliaustas}few{# uždaromieji riestiniai skliaustas}many{# right braces}other{# uždaromųjų riestinių skliaustų}}</translation>
-<translation id="4158704014418536539">Skirti didžiąsias ir mažąsias raides.</translation>
-<translation id="4161663686871496107">„ChromeVox“ žodinis atsiliepimas parengtas</translation>
-<translation id="4173994908659439270">Nėra kito redaguotino teksto lauko.</translation>
-<translation id="4176463684765177261">Neleista</translation>
-<translation id="4188530942454211480">Ankstesnis sakinys</translation>
-<translation id="4202186506458631436">Į dešinę</translation>
-<translation id="4206289001967551965">Lentelės viduje</translation>
-<translation id="4215733775853809057">Kitas šliaužiklis</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{brūkšnys}one{# brūkšnys}few{# brūkšniai}many{# dashes}other{# brūkšnių}}</translation>
-<translation id="421884353938374759">spalvos parinkiklis</translation>
-<translation id="4229646983878045487">data ir laikas</translation>
-<translation id="423334822609210999">Nėra langelio kairėje.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" /> klasė</translation>
-<translation id="4253168017788158739">Pastaba</translation>
-<translation id="4254798249533888099">Medis</translation>
-<translation id="4255943572433203166">Naudodami toliau pateiktas parinktis galite tinkinti „ChromeVox“. Pakeitimai rodomi iš karto.</translation>
-<translation id="4271220233568730077">Kitas matematinis raktas</translation>
-<translation id="4271521365602459209">Nėra daugiau rezultatų.</translation>
-<translation id="4287520460805643128">Nėra jokių kitų straipsnių.</translation>
-<translation id="4289540628985791613">Apžvalga</translation>
-<translation id="4300318234632215983">Pranešti apie nuorodos URL</translation>
-<translation id="4301352596632316575">yra submeniu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{taškas}=3{daugtaškis}one{# taškas}few{# taškai}many{# dots}other{# taškų}}</translation>
-<translation id="4347461890115250064">Nėra kito sąrašo.</translation>
-<translation id="4367650418938037324">Matematikos žymėjimo kalbos lapas</translation>
-<translation id="4372435075475052704">min. <ph name="X" /></translation>
-<translation id="4372705107434148843">Sustabdyti kalbą</translation>
-<translation id="4373197658375206385">Nėra ankstesnio elemento, kuris nebūtų nuoroda.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Nėra nuorodų.</translation>
-<translation id="4476183483923481720">nauja eilutė</translation>
-<translation id="4482330759234983253">Ankstesnė lentelė</translation>
-<translation id="4491109536499578614">Vaizdas</translation>
-<translation id="4529987814483543472">Klasikinis klavišų žemėlapis</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{pasvirasis brūkšnys}one{# pasvirasis brūkšnys}few{# pasvirieji brūkšniai}many{# slashes}other{# pasvirųjų brūkšnių}}</translation>
-<translation id="4547556996012970016">Kita 5 lygio antraštė</translation>
-<translation id="4562381607973973258">Antraštė</translation>
-<translation id="4591507479202817876">, pasirinkta</translation>
-<translation id="4597532268155981612">forma</translation>
-<translation id="4597896406374528575">Balandis</translation>
-<translation id="4615592953348396470">Ignoruojamas kitas klavišo paspaudimas</translation>
-<translation id="461613135510474570">Sakinys</translation>
-<translation id="4647836961514597010">Spalvos parinkiklis</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Ankstesnis orientyras</translation>
-<translation id="4696413482802371445">Nėra kitos 5 lygio antraštės.</translation>
-<translation id="4729095194763193578">Ankstesnė lentelės eilutė</translation>
-<translation id="4736221692378411923">Rugpjūtis</translation>
-<translation id="4740661827607246557">Pagalbos komandos</translation>
-<translation id="4759716709594980008">„Chrome“ OS klaviatūros naršyklė</translation>
-<translation id="4763296182459741068">Skaidyti į apačią</translation>
-<translation id="4763480195061959176">vaizdo įrašas</translation>
-<translation id="479989351350248267">ieškoti</translation>
-<translation id="481165870889056555">Pranešti apie dabartinio puslapio pavadinimą</translation>
-<translation id="4826415162591436065">Eiti į priekį</translation>
-<translation id="4826604887384865800">Kitas perėjimas</translation>
-<translation id="4827410568042294688">nepasirinkta</translation>
-<translation id="4842108708071771135">Nėra kitos įtraukos.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Ankstesnis panašus elementas.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Įgalinti TĮK įrašymą į žurnalą</translation>
-<translation id="4877261390094455813">Įveskite paieškos užklaus.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" /> / <ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Vidinė nuoroda</translation>
-<translation id="4953585991029886728">Redaguoti tekstą</translation>
-<translation id="4954534434583049121">Ankstesnė įtrauka</translation>
-<translation id="4973717656530883744">Min. <ph name="X" /></translation>
-<translation id="4973762002207131920">Perjungta į <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisekundės</translation>
-<translation id="49787999531187221">„ChromeVox“ aktyvus.</translation>
-<translation id="4979404613699303341">Ankstesnis mygtukas</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, sąrašo laukelis</translation>
-<translation id="4983588134362688868">Pereinama į puslapio viršų</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, langas</translation>
-<translation id="4993152509206108683">Tempas <ph name="PERCENT" /> proc.</translation>
-<translation id="4996716799442435517">Vaizdas</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, pasirinkta akutė</translation>
-<translation id="4997475792277222884">Nėra kito elemento, kuris nebūtų nuoroda.</translation>
-<translation id="5000760171916499057">Nėra formų.</translation>
-<translation id="5005670136041063723">Daugiau panašių elementų nėra.</translation>
-<translation id="501473567976723023">Sausis</translation>
-<translation id="5041394372352067729">Perkelti Brailio rašmenų pateiktį į puslapio viršų</translation>
-<translation id="5042770794184672516">Didinti kalbos garsumą</translation>
-<translation id="5050015258024679800">Ankstesnė 4 lygio antraštė</translation>
-<translation id="5054047268577924192">Ankstesnis sąrašo elementas</translation>
-<translation id="5078661581131202757">Failo pasirinkimas</translation>
-<translation id="5080758118274074384">dukart spustelėta</translation>
-<translation id="5098541983634824365">Išeinama iš tinklelio.</translation>
-<translation id="5102981729317424850">Įrankių juosta</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Nėra ankstesnio formos lauko.</translation>
-<translation id="5111640677200759579">Stulpelio antraštė</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Nėra ankstesnės nuorodos.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, nepasirinkta</translation>
-<translation id="5183440668879371625">Ankstesnė Brailio rašmenų eilutė</translation>
-<translation id="5184944171021383281">Nėra kito formos lauko.</translation>
-<translation id="5189244881767082992">Linija</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> jau priskirta komandai.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> sąrašas.</translation>
-<translation id="520883772648104506">Nėra kitos akutės.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Pabaiga</translation>
-<translation id="5291783959063340370">Objektas</translation>
-<translation id="5304943142864553931">„<ph name="TITLE" />“, skirtukas</translation>
-<translation id="5310788376443009632">pašalinta:</translation>
-<translation id="5320727453979144100">Fiksuojamasis režimas įgalintas</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{kablelis}one{# kablelis}few{# kableliai}many{# commas}other{# kablelių}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, teksto laukelis</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, nuoroda</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Praleisti atgal nepertraukiamai skaitant</translation>
-<translation id="5368000168321181111">Garsiniai ženkleliai išjungti</translation>
-<translation id="5374320867641260420">Nėra kito mygtuko.</translation>
-<translation id="5382299583965267720">Nėra kitos 1 lygio antraštės.</translation>
-<translation id="5402367795255837559">Brailio rašmenys</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{kabliataškis}one{# kabliataškis}few{# kabliataškiai}many{# semicolons}other{# kabliataškių}}</translation>
-<translation id="5411891038905756502">Nėra ankstesnės perėjimo vietos.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{ženklas mažiau}one{# ženklas mažiau}few{# ženklai mažiau}many{# less than signs}other{# ženklų mažiau}}</translation>
-<translation id="5455441614648621694">Papildomas</translation>
-<translation id="5485036206801896268">Nėra ankstesnio grafinio vaizdo.</translation>
-<translation id="5486947920110100234">Nėra kitos perėjimo vietos.</translation>
-<translation id="549602578321198708">Žodis</translation>
-<translation id="5500932716852106146">Nėra ankstesnio redaguotino teksto lauko.</translation>
-<translation id="5502713021410870035">Rugsėjis</translation>
-<translation id="5507663321906818013">Derinimo palyginimas</translation>
-<translation id="5518443085409638729">Redaguodami tekstą nuveskite žymeklį tarp simbolių (pvz., „Mac OS X“).</translation>
-<translation id="552195134157544755">Akutė</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Nėra ankstesnės 5 lygio antraštės.</translation>
-<translation id="556042886152191864">Mygtukas</translation>
-<translation id="5561345396546889625">Kitas sąrašas</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Grįžties klavišas</translation>
-<translation id="5585044216466955529">Teksto redagavimas, el. pašto įrašas</translation>
-<translation id="5597170376237141345">Kitas žymimasis laukelis</translation>
-<translation id="5597933780944041114">Nėra kitos antraštės.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, akutės pasirinkimas panaikintas</translation>
-<translation id="5601172225407283979">Atlikti numatytąjį veiksmą</translation>
-<translation id="5608798115546226984">Automatinis eilutės užbaigimas</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Žurnalas</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Nėra ankstesnės lentelės.</translation>
-<translation id="5655682562155942719">Praleisti komandas</translation>
-<translation id="56637627897541303">Teksto sritis</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Orientyras</translation>
-<translation id="5683155931978483559">Ankstesnis žymimasis laukelis</translation>
-<translation id="5684277895745049190">Sąrašas</translation>
-<translation id="5700650669149824506">Nėra ankstesnės 4 lygio antraštės.</translation>
-<translation id="5709192780268610569">Nėra ilgo aprašo</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Kitas lentelės stulpelis</translation>
-<translation id="571866080859340309">Tyrinėjamos grupės</translation>
-<translation id="5728409797179002635">Nerasta jokia lentelė.</translation>
-<translation id="5748623122140342504">Ankstesnė 5 lygio antraštė</translation>
-<translation id="5750633686117194034">Nepaspausta jokių modifikatorių; paspauskite ir palaikykite vieną ar daugiau modifikatorių; pakelkite pirštus, kai bus atlikta, ir išgirsite klavišų rinkinį. Paspauskite tabuliavimo klavišą, kad išeitumėte.</translation>
-<translation id="5788275253279308023">inkognito langas, „<ph name="TITLE" />“, skirtukas</translation>
-<translation id="5806206155699461681">Patobulinti konkrečias svetaines (pvz., „Google“ paiešką).</translation>
-<translation id="5819072574982403430">Medžio elementas</translation>
-<translation id="5826479389509458994"><ph name="ROW" /> eilutė, <ph name="COL" /> stulpelis</translation>
-<translation id="5850707923114094062">Stumti atgal</translation>
-<translation id="5851548754964597211">Skirtukų sąrašas</translation>
-<translation id="5859752971144398932">Išeita iš paieškos puslapyje.</translation>
-<translation id="5866042630553435010">Iš dalies pažymėta</translation>
-<translation id="5869546221129391014">Tinklelis</translation>
-<translation id="5876817486144482042">Mažinti kalbos garsumą</translation>
-<translation id="5887397643266327462">Brailio rašmenų antraštės įgalintos.</translation>
-<translation id="5891934789323004067">Lentelė</translation>
-<translation id="5919442531159595654">kopijuoti.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{lygybės ženklas}one{# lygybės ženklas}few{# lygybės ženklai}many{# equal signs}other{# lygybės ženklų}}</translation>
-<translation id="5939518447894949180">Nustatyti iš naujo</translation>
-<translation id="5948123859135882163">Kaitalioti struktūrinį ir semantinį matematinių reiškinių interpretavimą</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialogo langas</translation>
-<translation id="5963413905009737549">Skiltis</translation>
-<translation id="5968607524793740041">Rodyti kontekstinį meniu</translation>
-<translation id="5983179082906765664">Padidinti naršymo detalumą</translation>
-<translation id="5999630716831179808">Balsai</translation>
-<translation id="6000417740266304866">Pakeisti dabartinę 8 taškų Brailio rašmenų lentelę pasirinkus parinktį iš toliau pateikiamo sąrašo.</translation>
-<translation id="6006050241733874051">Forma</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{kairinis brūkšnys}one{# kairinis brūkšnys}few{# kairiniai brūkšniai}many{# backslashes}other{# kairinių brūkšnių}}</translation>
-<translation id="6037602951055904232">Stumti pirmyn</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Langelio pabaiga.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Tarpas</translation>
-<translation id="6142308968191113180">4 antraštė</translation>
-<translation id="6169420925157477918">Vaizdas su ilgu aprašu</translation>
-<translation id="6172087735260766220">Nepavyko pasiekti pasiekiamo teksto iš nuo kopijavimo apsaugoto PDF.</translation>
-<translation id="6186305613600865047">Pereinama į puslapio apačią</translation>
-<translation id="6193330012414963395">iki pietų / po pietų</translation>
-<translation id="622484624075952240">Žemiau</translation>
-<translation id="6236061028292614533">Kita antraštė</translation>
-<translation id="6254901459154107917">Kita teksto sritis, kurią galima redaguoti</translation>
-<translation id="6259464875943891919">Išeita iš <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Kitas panašus elementas.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Nėra kito išskleidžiamojo laukelio.</translation>
-<translation id="6307969636681130414">Paspausta</translation>
-<translation id="6324551002951139333">Aptikta gramatikos klaida</translation>
-<translation id="6348657800373377022">Jungtinis laukelis</translation>
-<translation id="6355910664415701303">Nėra ankstesnio sąrašo elemento.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Ankstesnė antraštė</translation>
-<translation id="6387719785439924554">šalia</translation>
-<translation id="6411426777058107714">Nėra ankstesnės akutės.</translation>
-<translation id="6414968628640960377">Ankstesnis kitoks elementas.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dvitaškis}one{# dvitaškis}few{# dvitaškiai}many{# colons}other{# dvitaškių}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, meniu</translation>
-<translation id="6444046323172968959">Įspėjimo dialogo langas</translation>
-<translation id="6459511626086141404">Plokščiasis klavišų žemėlapis</translation>
-<translation id="6468049171101508116">Kitas mygtukas</translation>
-<translation id="6491972999578897419">Pakeiskite dabartinį balsą pasirinkę parinktį iš toliau pateikto sąrašo.</translation>
-<translation id="6508059270146105198">Perkelti Brailio rašmenų pateiktį į puslapio apačią</translation>
-<translation id="6536864053412760904">Matematikos žymėjimo kalbos prieigos raktas</translation>
-<translation id="6550720799683018100">Pakeiskite dabartinį klavišų žemėlapį pasirinkę parinktį iš toliau pateikto sąrašo.</translation>
-<translation id="6561818612645211875">Eiti į dabartinės eilutės pradžią</translation>
-<translation id="6587021927234520429">Nėra kitos 4 lygio antraštės.</translation>
-<translation id="6601344353291556895">Įgalinti daugiakalbius aprašus.</translation>
-<translation id="6615602925644411249">Rasti puslapyje.</translation>
-<translation id="6633350132811819843">Nėra kitos lentelės.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Eigos juosta</translation>
-<translation id="6659594942844771486">Skirtukas</translation>
-<translation id="667999046851023355">Dokumentas</translation>
-<translation id="6697092096875747123">Ankstesnis išskleidžiamasis sąrašas</translation>
-<translation id="6714813999819678458">Ankstesnė 2 lygio antraštė</translation>
-<translation id="6716505898850596801">Modifikavimo klavišai</translation>
-<translation id="671916444866103745">Nėra kito ARIA orientyro.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, jungtinis laukelis</translation>
-<translation id="6735257939857578167">su <ph name="NUM" /> element.</translation>
-<translation id="6736510033526053669">skirtukas sukurtas</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Straipsnis</translation>
-<translation id="6787839852456839824">Spartieji klavišai</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Poraštė</translation>
-<translation id="6871161210040114857">Nepaisoma didžiųjų ir mažųjų raidžių rašybos.</translation>
-<translation id="6877435256196695200">Nėra kito grafinio elemento.</translation>
-<translation id="6897341342232909480">Perkelti į kairę</translation>
-<translation id="6901540140423170855">data</translation>
-<translation id="6910211073230771657">Ištrintas</translation>
-<translation id="6911965441508464308">Nėra langelio aukščiau.</translation>
-<translation id="6919104639734799681">Rodyti lentelių sąrašą</translation>
-<translation id="6964088412282673743">Nėra ankstesnio valdiklio.</translation>
-<translation id="6996566555547746822">Kitas išskleidžiamasis sąrašas</translation>
-<translation id="7005146664810010831">Nerastas joks URL</translation>
-<translation id="7010712454773919705">„ChromeVox“ modifikavimo klavišas</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Ankstesnis sąrašas</translation>
-<translation id="7041173719775863268">Baigti rinktis</translation>
-<translation id="7095834689119144465">Redaguoti tik skaitinį tekstą</translation>
-<translation id="7096001299300236431">Ankstesnis medijų raktas</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">žodžio aidas</translation>
-<translation id="713824876195128146">Kita įtrauka</translation>
-<translation id="7161771961008409533">Iššokantysis mygtukas</translation>
-<translation id="7167657087543110">simbolio aidas</translation>
-<translation id="7170733337935166589">Praleisti pirmyn nepertraukiamai skaitant</translation>
-<translation id="7181697990050180700">Tinkinkite dažnai naudojamų komandų sparčiuosius klavišus įvedę juos į atitinkamus toliau pateiktus laukus.</translation>
-<translation id="7203150201908454328">Išskleista</translation>
-<translation id="7210211103303402262">minutės</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">eilutė</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Antraštė</translation>
-<translation id="7241683698754534149">Atidaryti ilgą aprašą naujame skirtuke</translation>
-<translation id="7248671827512403053">Programa</translation>
-<translation id="725969808843520477">Kita akutė</translation>
-<translation id="7269119382257320590">Be skyrybos ženklų</translation>
-<translation id="7273174640290488576">Tuščia</translation>
-<translation id="7285387653379749618">Lentelės</translation>
-<translation id="7289186959554153431">3 antraštė</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Brailio rašmenų antraštės išjungtos.</translation>
-<translation id="7318872822751139669">Pelės žymekliu pakeiskite židinį.</translation>
-<translation id="7322388933135261569">Vasaris</translation>
-<translation id="7332592614823088566">Eilutė: <ph name="ROWINDEX" /> iš <ph name="ROWTOTAL" />. Stulpelis: <ph name="COLINDEX" /> iš <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">yra iššokantysis elementas</translation>
-<translation id="7356165926712028380">Perjungti į 8 taškų Brailio rašmenis</translation>
-<translation id="7362871137496673139">Nėra ankstesnės 2 lygio antraštės.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersendas}one{# ampersendas}few{# ampersendai}many{# ampersands}other{# ampersendų}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Išeinama iš lentelės.</translation>
-<translation id="739763518212184081">Ankstesnė linija</translation>
-<translation id="7400575256015741911">Aptikta rašybos klaida</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">grįžimas į eilutės pradžią</translation>
-<translation id="7434509671034404296">Vykdymo programa</translation>
-<translation id="7439060726180460871">Katalogas</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">Tabuliavimo klavišas</translation>
-<translation id="7492049978501397201">Įeita į dialogo langą</translation>
-<translation id="7532613204005497612">Birželis</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, šliaužiklis</translation>
-<translation id="7586163296341959563">įklijuoti.</translation>
-<translation id="7596919493010894443">išvalytas pasirinkimas</translation>
-<translation id="7604026522577407655">Eiti į dabartinio stulpelio pradžią</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Pranešti apie dabartinio puslapio URL</translation>
-<translation id="7609363189280667021">Perjungti Brailio rašmenų subtitrus</translation>
-<translation id="762020119231868829">Pristabdo visus šiuo metu paleistus medijų valdiklius</translation>
-<translation id="7625690649919402823">Kita lentelė</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), <ph name="GRADE" /> klasė</translation>
-<translation id="7641134354185483015">Nėra ankstesnės 3 lygio antraštės.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, teksto laukelis</translation>
-<translation id="7663318257180412551">2 antraštė</translation>
-<translation id="7674576868851035240">Kita nuoroda</translation>
-<translation id="7674768236845044097">žymėjimas</translation>
-<translation id="7684431668231950609">Teksto redagavimas, URL įrašas</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Ankstesnė akutė</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, slaptažodžio teksto laukelis</translation>
-<translation id="7805247615045262757">numatytasis naršymas</translation>
-<translation id="7805768142964895445">Būsena</translation>
-<translation id="7810781339813764006">Kita grupė</translation>
-<translation id="7819187121850078213">langas, „<ph name="TITLE" />“, skirtukas</translation>
-<translation id="7828956995407538686">Spalis</translation>
-<translation id="7839679365527550018">Ankstesnis žodis</translation>
-<translation id="7851816175263618915">Su kai kuriais skyrybos ženklais</translation>
-<translation id="7870596830398826354">Matematikos žymėjimo kalbos medis</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Perjungti „ChromeVox“ klasikinę versiją.</translation>
-<translation id="7895896691902835279">Nežinoma nuoroda</translation>
-<translation id="7927711904086083099">Nepasirinkta</translation>
-<translation id="7935627501098484003">Laiko valdymas</translation>
-<translation id="7939428177581522200">pridėta prie rinkinio</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{kilpelės ženklas}one{# kilpelės ženklas}few{# kilpelės ženklai}many{# at signs}other{# kilpelės ženklų}}</translation>
-<translation id="7965147473449754028">meniu uždarytas</translation>
-<translation id="7974390230414479278">Meniu elementas</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{šauktukas}one{# šauktukas}few{# šauktukai}many{# exclamation points}other{# šauktukų}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{kabučių ženklas}one{# kabučių ženklas}few{# kabučių ženklai}many{# quotes}other{# kabučių ženklų}}</translation>
-<translation id="8033827949643255796">pasirinkta</translation>
-<translation id="8035962149453661158">maks. <ph name="X" /></translation>
-<translation id="8042761080832772327">Teksto redagavimas, paieškos įrašas</translation>
-<translation id="8049189770492311300">Laikmatis</translation>
-<translation id="8065607967589909823">Pasirinkimas yra</translation>
-<translation id="8066678206530322333">Reklamjuostė</translation>
-<translation id="8110647606445335195">Nėra ARIA orientyrų.</translation>
-<translation id="8153880621934657047">Ne lentelės viduje.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{apatinis brūkšnys}one{# apatinis brūkšnys}few{# apatiniai brūkšniai}many{# underscores}other{# apatinių brūkšnių}}</translation>
-<translation id="8179976553408161302">Įvesti</translation>
-<translation id="81960742267269908">iškirpti.</translation>
-<translation id="8199231515320852133">Pranešti apie dabartinio langelio antraštes</translation>
-<translation id="820417203470636242">Tuščias langelis.</translation>
-<translation id="8215202828671303819">Kelių elementų pasirinkimas</translation>
-<translation id="8276439074553447000">Pereiti prie ankstesni elemento, kurį galima fokusuoti</translation>
-<translation id="8278417001922463147">Nėra jokių ankstesnių straipsnių.</translation>
-<translation id="8283603667300770666">Kitas formos laukas</translation>
-<translation id="831207808878314375">Apibrėžtis</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">valandos</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{grotelių ženklas}one{# grotelių ženklas}few{# grotelių ženklai}many{# pound signs}other{# grotelių ženklas}}</translation>
-<translation id="8374154622594089836">mėnuo</translation>
-<translation id="8378855320830505539">Regionas</translation>
-<translation id="8382679411218029383">Automatinis eilutės ir sąrašo užbaigimas</translation>
-<translation id="8428603554127842284"><ph name="DEPTH" /> lygis</translation>
-<translation id="842922884199979200">Nėra kitos 3 lygio antraštės.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Nėra ankstesnio žymimojo laukelio.</translation>
-<translation id="8455868257606149352">Maks. <ph name="X" /></translation>
-<translation id="84575901236241018">turi prieigos klavišą, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Sumažinti naršymo detalumą</translation>
-<translation id="8520472399088452386">Sukimo mygtukas</translation>
-<translation id="8538744478902126321">Parinkti dabartinio langelio eilutės antraštę</translation>
-<translation id="8540054775867439484">Skaidyti į viršų</translation>
-<translation id="8548973727659841685">Simbolis</translation>
-<translation id="8561322612995434619">yra iššokantysis elementas</translation>
-<translation id="8571096049907249734">keli pasirinkimai</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Kitas sąrašo elementas</translation>
-<translation id="860150890330522909">Žymimasis laukelis „<ph name="NAME" />“ pažymėtas</translation>
-<translation id="8606621670302093223">Datos valdiklis</translation>
-<translation id="8631359288236106450">pasirinkta elementų: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Pranešti dabartines langelio koordinates</translation>
-<translation id="8650576015643545550">Nėra ankstesnio sąrašo.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Rodyti nuorodų sąrašą</translation>
-<translation id="8664519043722036194">sekundės</translation>
-<translation id="867187640362843212">5 antraštė</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{statusis brūkšnys}one{# statusis brūkšnys}few{# statieji brūkšniai}many{# vertical pipes}other{# stačiųjų brūkšnių}}</translation>
-<translation id="8735450637152821465">Pradėti rinktis</translation>
-<translation id="8743786158317878347">įveskite struktūrinį turinį, pvz., lenteles</translation>
-<translation id="8747966237988593539">Rūšiuotas sąrašas</translation>
-<translation id="8759334257841767240">Nėra kitos nuorodos.</translation>
-<translation id="8767968232364267681">Kita 4 lygio antraštė</translation>
-<translation id="8770473310765924354">išeiti iš struktūrinio turinio, pvz., lentelių</translation>
-<translation id="8791025954632646584">Semantinis interpretavimas įjungtas</translation>
-<translation id="8796411681063377102">Kita 3 lygio antraštė</translation>
-<translation id="8808582214901541005">Kovas</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Paspauskite aukštyn ar žemyn, kad peržiūrėtumėte komandas; paspauskite „Enter“, kad suaktyvintumėte</translation>
-<translation id="8864099967139188018">Nėra kitos 6 lygio antraštės.</translation>
-<translation id="8882002077197914455">Eilutės antraštė</translation>
-<translation id="8896347895970027998">Suaktyvinti arba išaktyvinti „ChromeVox“.</translation>
-<translation id="8898516272131543774">Ciklo skyrybos aidas</translation>
-<translation id="8900148057318340779">Kodo klavišas</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Tuščios antraštės</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Modifikavimo klavišai</translation>
-<translation id="8943175951035496220">Nėra langelio dešinėje.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">failas</translation>
-<translation id="9027462562263121875">Nėra lentelių.</translation>
-<translation id="9040132695316389094">1 antraštė</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Perjungti paieškos valdiklį</translation>
-<translation id="9065283790526219006">+iššokantysis langas</translation>
-<translation id="9077213568694924680">pašalinta iš pasirinkimo srities</translation>
-<translation id="9082874451376019682">Nėra ankstesnio šliaužiklio.</translation>
-<translation id="9089864840575085222">Ciklo įvedimo aidas</translation>
-<translation id="9107530006868467849">Nėra ankstesnio medijų valdiklio.</translation>
-<translation id="9108370397979208512">matematika</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{procento ženklas}one{# procento ženklas}few{# procento ženklai}many{# percent signs}other{# procento ženklų}}</translation>
-<translation id="9115913704608474258">Lapkritis</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Paskelbiamas trumpas esamos pozicijos aprašas</translation>
-<translation id="9153606228985488238">Aukštis <ph name="PERCENT" /> proc.</translation>
-<translation id="9160096769946561184">Eiti į dabartinio stulpelio pabaigą</translation>
-<translation id="9173115498289768110">Garsumas <ph name="PERCENT" /> proc.</translation>
-<translation id="9178973770513562274">Jei norite naršyti, naudokite rodyklių aukštyn ir žemyn klavišus arba įveskite tekstą, jei norite ieškoti.</translation>
-<translation id="9192904702577636854">Pažymėtoji sritis</translation>
-<translation id="9212322457209634662">Nėra kitos skilties.</translation>
-<translation id="930275611743429116">Pradėti arba baigti pasirinkimą.</translation>
-<translation id="948171205378458592">Sumažinti kalbos tempą</translation>
-<translation id="962913030769097253">Kita 1 lygio antraštė</translation>
-<translation id="973955474346881951">Įgalinti pritraukimo režimą / neleisti jo</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lv.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lv.xtb
deleted file mode 100644
index b092d2f06a1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lv.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="lv">
-<translation id="1012173283529841972">Saraksta vienums</translation>
-<translation id="1013742170491673792">meklēšana</translation>
-<translation id="1023866615269196768">Savienotas.</translation>
-<translation id="1025074108959230262">Saistošais režīms atspējots</translation>
-<translation id="1031961866430398710">, pēc tam</translation>
-<translation id="1044777062731150180">Bez virsrakstiem</translation>
-<translation id="106222400312645156">rindas galvene</translation>
-<translation id="1065552602950927991">Nepareiza ievade</translation>
-<translation id="1082209053475788238">Iepriekš nav neviena 6. līmeņa virsraksta.</translation>
-<translation id="1088219014394087294">Nav virsrakstu.</translation>
-<translation id="1106741348836243114">Ieslēgt vai izslēgt skaņas signālus.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Kolekcija (<ph name="TAG" />) <ph name="NUM" /> vienumiem</translation>
-<translation id="1155043339247954670">Tālāk nav neviena saraksta vienuma.</translation>
-<translation id="1157782847298808853">Tastatūras palīdzība</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, kombinētais lodziņš</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, izvēlnes vienums ar apakšizvēlni</translation>
-<translation id="1177863135347784049">Pielāgota</translation>
-<translation id="1188858454923323853">papildu</translation>
-<translation id="1206619573307042055">slīdošais teksts</translation>
-<translation id="1213216066620407844">ChromeVox — balss piešķiršana pārlūkam Chrome</translation>
-<translation id="1229276918471378188">Iepriekšējais pārejas punkts</translation>
-<translation id="1237866625126425153">radiopogu grupa</translation>
-<translation id="1251750620252348585">Nākamais 6. līmeņa virsraksts</translation>
-<translation id="1275718070701477396">Atlasīta</translation>
-<translation id="1319608975892113573">Iepriekš nav neviena citāta bloka.</translation>
-<translation id="1321576897702511272">Slēpt ChromeVox palīdzību</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> no <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">rakstzīmju un vārdu atbalss</translation>
-<translation id="1339428534620983148">Iepriekšējā tabulas sleja</translation>
-<translation id="1342835525016946179">raksts</translation>
-<translation id="1346748346194534595">Pa labi</translation>
-<translation id="136718599399906424">Nākamā tabulas rinda</translation>
-<translation id="1383876407941801731">Meklēt</translation>
-<translation id="1385214448885562192">Nospiediet ievadīšanas taustiņu, lai piekristu; atsoļa taustiņu — lai atceltu; lejupvērsto bulttaustiņu — lai pārietu uz nākamo rezultātu; augšupvērsto bulttaustiņu — lai pārietu uz iepriekšējo rezultātu.</translation>
-<translation id="1396114365388024581">ciļņu saraksts</translation>
-<translation id="1439316808600711881">reģions</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, paroles tekstlodziņš</translation>
-<translation id="1467432559032391204">Pa kreisi</translation>
-<translation id="1474557363159888097">Iepriekš nav neviena enkura.</translation>
-<translation id="1502086903961450562">Iepriekšējā grafika</translation>
-<translation id="1506187449813838456">Palielināt augstumu</translation>
-<translation id="151784044608172266">Nākamais teikums</translation>
-<translation id="1524531499102321782">Nākamā rindiņa Braila rakstā</translation>
-<translation id="1546370775711804143">Ritjosla</translation>
-<translation id="1559739829547075274">Pārvietoties atpakaļ</translation>
-<translation id="1571643229714746283">ChromeVox ir gatavs</translation>
-<translation id="158493514907962286">Decembris</translation>
-<translation id="1594072653727561613">izvēlne</translation>
-<translation id="1610130962244179598">Pāriet uz 6 punktu Braila rakstu</translation>
-<translation id="1611168825862729585">Slejas virsraksts:</translation>
-<translation id="1613476421962910979">Signāli ieslēgti</translation>
-<translation id="1618597272655350600">Sniedz pilnīgu aprakstu par pašreizējo pozīciju</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{zīme “lielāks par”}zero{# zīmju “lielāks par”}one{# zīme “lielāks par”}other{# zīmes “lielāks par”}}</translation>
-<translation id="1653266918374749391">Iepriekšējais 3. līmeņa virsraksts</translation>
-<translation id="1659072772017912254">Nav atzīmēts</translation>
-<translation id="1669290819662866522">nedēļa</translation>
-<translation id="1674262202423278359">ChromeVox navigācija</translation>
-<translation id="16777221443363124">Izvēļņu josla</translation>
-<translation id="1692077714702418899">struktūras līnija</translation>
-<translation id="1700517974991662022">Apmeklēta</translation>
-<translation id="1722567105086139392">Saite</translation>
-<translation id="1727806147743597030">kājene</translation>
-<translation id="174268867904053074">Nākamā grafika</translation>
-<translation id="1781173782405573156">Ignorēt taustiņa nospiešanu</translation>
-<translation id="1787176709638001873">Rediģējams teksts: parole</translation>
-<translation id="1810107444790159527">Sarakstlodziņš</translation>
-<translation id="1828385960365606039">Maijs</translation>
-<translation id="1834891354138622109">Sleja</translation>
-<translation id="1865601187525349519">Teksta beigas</translation>
-<translation id="1876229593313240038">dokuments</translation>
-<translation id="188130072164734898">Nosaukt pašreizējo laiku un datumu.</translation>
-<translation id="1902396333223336119">Šūna</translation>
-<translation id="1905379170753160525">Rādīt virsrakstu sarakstu</translation>
-<translation id="1912556590115083156">apmeklēta saite</translation>
-<translation id="1913761808037590218">numurs</translation>
-<translation id="1954623340234317532">Gada nedēļas vadīkla</translation>
-<translation id="1964135212174907577">Nākamais objekts</translation>
-<translation id="1969092762068865084">Jūlijs</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Rindas virsraksts:</translation>
-<translation id="2002895034995108595">Atiestatīt pašreizējo taustiņu piesaisti</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{atverošā kvadrātiekava}zero{# atverošo kvadrātiekavu}one{# atverošā kvadrātiekava}other{# atverošās kvadrātiekavas}}</translation>
-<translation id="2045490512405922022">nav atzīmēta</translation>
-<translation id="20601713649439366">Iepriekš nav nevienas matemātiskas izteiksmes.</translation>
-<translation id="207477615537953741">Semantiskā interpretācija izslēgta</translation>
-<translation id="2086961585857038472">Nākamais vārds</translation>
-<translation id="2089387485033699258">lv</translation>
-<translation id="2091933974477985526">Iepriekšējais rediģējamais teksta apgabals</translation>
-<translation id="2100350898815792233">Visas pieturzīmes</translation>
-<translation id="2119965627982867824">skaitītājpoga</translation>
-<translation id="2121067395472282800">piekļuves taustiņš: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Lai mainītu pašreizējo 6 punktu Braila tabulu, tālāk redzamajā sarakstā atlasiet attiecīgo opciju.</translation>
-<translation id="2169714232367507776">Noklikšķināt uz pašreizējā vienuma</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{aizverošā iekava}zero{# aizverošo iekavu}one{# aizverošā iekava}other{# aizverošās iekavas}}</translation>
-<translation id="2199994615414171367">Iepriekšējā matemātiskā izteiksme</translation>
-<translation id="2223693656926968778">Rīkoties ar pašreizējo vienumu</translation>
-<translation id="225732394367814946">Palielināt runas ātrumu</translation>
-<translation id="2267945578749931355">Nākamā rakstzīme</translation>
-<translation id="2281234842553884450">Iepriekšējais slīdnis</translation>
-<translation id="2318372665160196757">Galvenais</translation>
-<translation id="2329324941084714723">Ciļņu panelis</translation>
-<translation id="2344193891939537199">Datuma/laika vadīkla</translation>
-<translation id="2359897517538099099">Nav ieslēgts tabulas režīms.</translation>
-<translation id="241124561063364910">un pēc tam</translation>
-<translation id="2417569100218200841">Satura informācija</translation>
-<translation id="2422937916923936891">Izvēlnes vienuma izvēles rūtiņa</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">Tagad taustiņš <ph name="KEY" /> ir jaunais ChromeVox modificētājtaustiņš.</translation>
-<translation id="2450814015951372393">Izvēles rūtiņa</translation>
-<translation id="2462626033734746142">Radiopogu grupa</translation>
-<translation id="2471138580042810658">6. līmeņa virsraksts</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{zvaigznīte}zero{# zvaigznīšu}one{# zvaigznīte}other{# zvaigznītes}}</translation>
-<translation id="2549392850788122959">Taustiņš <ph name="KEY" /> ir atiestatīts.</translation>
-<translation id="2553108862507765288">gramatikas kļūda</translation>
-<translation id="257674075312929031">Grupa</translation>
-<translation id="2582407057977008361">malā novietots saturs</translation>
-<translation id="2589102159832527089">Šajā lapā ir ietverts teksts, kas ir automātiski izvilkts no PDF faila &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Noklikšķiniet šeit, lai skatītu oriģinālu&lt;/a&gt;.</translation>
-<translation id="2606210917827248971">ar {COUNT,plural, =1{# vienumu}zero{# vienumiem}one{# vienumu}other{# vienumiem}}</translation>
-<translation id="2614981083756825552">MathML izkārtojums</translation>
-<translation id="2626530649491650971">klikšķināms</translation>
-<translation id="2628764385451019380">Iepriekš nav neviena kombinētā lodziņa.</translation>
-<translation id="2637227747952042642">Matemātiska izteiksme</translation>
-<translation id="2639750663247012216">ChromeVox modificētājtaustiņš</translation>
-<translation id="2644542693584024604">pareizrakstības kļūda</translation>
-<translation id="2667291555398229137">Noklikšķināt uz vienuma zem maršrutēšanas atslēgas</translation>
-<translation id="2697408785920771974">iekļautā automātiskā pabeigšana</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{atverošā iekava}zero{# atverošo iekavu}one{# atverošā iekava}other{# atverošās iekavas}}</translation>
-<translation id="2705875883745373140">Nav nospiests</translation>
-<translation id="2706462751667573066">Augšup</translation>
-<translation id="2717271541250958000">ciļņu panelis</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Atzīmēts</translation>
-<translation id="27527859628328957">Pāriet uz nākamo fokusējamo vienumu</translation>
-<translation id="2770781857296573485">Sākt grupu izpēti</translation>
-<translation id="2777845298774924149">Tika aizvērts</translation>
-<translation id="2800204403141299078">Nav neviena cita atšķirīga elementa.</translation>
-<translation id="2800780099804980316">Iepriekš nav neviena 1. līmeņa virsraksta.</translation>
-<translation id="2811204574343810641">Rinda</translation>
-<translation id="2816654101880605877">Tālāk nav neviena slīdņa.</translation>
-<translation id="2841013758207633010">Laiks</translation>
-<translation id="2843837985843789981">Iepriekšējā grupa</translation>
-<translation id="2844995807198708617">Kontekstizvēlne</translation>
-<translation id="2849332794118375855">Tālāk nav nevienas izvēles rūtiņas.</translation>
-<translation id="2864481629947106776">Iepriekšējā saite</translation>
-<translation id="2873259058405069099">Pāriet uz tabulas sākumu</translation>
-<translation id="2894654529758326923">Informācija</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{atverošā figūriekava}zero{# atverošo figūriekavu}one{# atverošā figūriekava}other{# atverošās figūriekavas}}</translation>
-<translation id="2911433807131383493">Atvērt ChromeVox mācības</translation>
-<translation id="2932083475399492303">Mainīt līniju veidu uz struktūras līnijām vai izkārtojuma līnijām</translation>
-<translation id="2964026537669811554">Virsrakstu grupa</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulēšanas rakstzīme}zero{# tabulēšanas rakstzīmju}one{# tabulēšanas rakstzīme}other{# tabulēšanas rakstzīmes}}</translation>
-<translation id="2972078295414139404">Iepriekš nav nevienas apmeklētās saites.</translation>
-<translation id="2972205263822847197">Rīka padoms</translation>
-<translation id="2998131015536248178">Iepriekšējā rakstzīme</translation>
-<translation id="2999559350546931576">Samazināt augstumu</translation>
-<translation id="2999945368667127852">Tālāk nav neviena multivides logrīka.</translation>
-<translation id="3012414509011670858">Iepriekš nav nevienas sadaļas.</translation>
-<translation id="3030432017085518523">Izvēlnes vienuma radiopoga</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrofs}zero{# apostrofu}one{# apostrofs}other{# apostrofi}}</translation>
-<translation id="3046838483509668188">ChromeVox opcijas</translation>
-<translation id="3047143736589213134">Eksperimentāla taustiņu piesaiste</translation>
-<translation id="3060756054951570867">Tika atvērta izvēlne <ph name="TITLE" /></translation>
-<translation id="3078345202707391975">Nākamais 2. līmeņa virsraksts</translation>
-<translation id="3078740164268491126">tabula</translation>
-<translation id="3082557070674409251">Tika veikts klikšķis.</translation>
-<translation id="3084806535845658316">nav rakstīšanas atbalss</translation>
-<translation id="3086746722712840547">piezīme</translation>
-<translation id="308895241372589742">Tālāk nav nevienas matemātiskas izteiksmes.</translation>
-<translation id="3090532668523289635">grupa</translation>
-<translation id="3093176084511590672">Nākamais orientieris</translation>
-<translation id="3096671415663099226">kombinētais lodziņš</translation>
-<translation id="3104705064753753826">brīdinājuma dialoglodziņš</translation>
-<translation id="3109724472072898302">Sakļauts</translation>
-<translation id="3134461040845705080">tikai lasāms</translation>
-<translation id="3138767756593758860">Rādīt orientieru sarakstu</translation>
-<translation id="3143851963874289911">šūna</translation>
-<translation id="3149472044574196936">Nākamā rindiņa</translation>
-<translation id="3155083529632865074">Iepriekš nav nevienas pogas.</translation>
-<translation id="3163593631834463955">Tukšs slejas virsraksts</translation>
-<translation id="316542773973815724">Navigācija</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{atstarpe}zero{# atstarpju}one{# atstarpe}other{# atstarpes}}</translation>
-<translation id="320961988183078793">atvērts: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, cilne</translation>
-<translation id="3226035351387556942">izvēles rūtiņa</translation>
-<translation id="3229375994964697375">Apmeklēta saite</translation>
-<translation id="323731244387692321">Atvērt ChromeVox tastatūras palīdzību</translation>
-<translation id="3241052487511142956">Iepriekšējā apmeklētā saite</translation>
-<translation id="3286390186030710347">Slīdnis</translation>
-<translation id="3299925995433437805">Tālāk nav nevienas apmeklētās saites.</translation>
-<translation id="3303384412438961941">Nospiediet jebkuru taustiņu, lai uzzinātu tā nosaukumu. Nospiežot Crtl+W, tastatūras pārlūks tiks aizvērts.</translation>
-<translation id="3307886118343381874">Pāriet uz tabulas beigām</translation>
-<translation id="3311969765485641742">Lai skatītu brīdinājumus, nospiediet taustiņu kombināciju Alt+Shift+A.</translation>
-<translation id="3312997241656799641">Nākamā apmeklētā saite</translation>
-<translation id="3321460131042519426">Iespējot teksta aplaušanu</translation>
-<translation id="3322936298410871309">Iepriekšējais 1. līmeņa virsraksts</translation>
-<translation id="3323447499041942178">Tekstlodziņš</translation>
-<translation id="3353420241558113817">{"ar”: “Arābu”,
- “bg”: “Bulgāru”,
- “ca”: “Katalāņu”,
- “cs”: “Čehu”,
- “da”: “Dāņu”,
- “de”: “Vācu”,
- “de_CH”: “Vācu (Šveice)”,
- “de_DE”: “Vācu (Vācija)”,
- “el”: “Grieķu”,
- “en”: “Angļu”,
- “en_CA”: “Angļu (Kanāda)”,
- “en_GB”: “Angļu (Lielbritānija)”,
- “en_US”: “Angļu (Amerikas Savienotās Valstis)”,
- “es”: “Spāņu”,
- “et”: “Igauņu”,
- “fr”: “Franču”,
- “fr_CA”: “Franču (Kanāda)”,
- “fr_FR”: “Franču (Francija)”,
- “fi”: “Somu”,
- “he”: “Ivrits”,
- “hi”: “Hindi”,
- “hr”: “Horvātu”,
- “hu”: “Ungāru”,
- “is”: “Īslandiešu”,
- “it”: “Itāļu”,
- “ko”: “Korejiešu”,
- “lt”: “Lietuviešu”,
- “lv”: “Latviešu”,
- “nb”: “Norvēģu bukmols”,
- “nl”: “Holandiešu”,
- “pl”: “Poļu”,
- “pt”: “Portugāļu”,
- “ro”: “Rumāņu”,
- “ru”: “Krievu”,
- “sk”: “Slovāku”,
- “sl”: “Slovēņu”,
- “sr”: “Serbu”,
- “sv”: “Zviedru”,
- “tr”: “Turku”,
- “vi”: “Vjetnamiešu”,
- “zh”: “Ķīniešu”,
- “zh_TW”: “Ķīniešu (hanu tradicionālā)”}</translation>
-<translation id="3359142382821736686">atdalītājs</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{pluszīme}zero{# pluszīmju}one{# pluszīme}other{# pluszīmes}}</translation>
-<translation id="338583716107319301">Atdalītājs</translation>
-<translation id="3389259863310851658">Iepriekšējais veidlapas lauks</translation>
-<translation id="3390225400784126843">Nākamais atšķirīgais elements.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, izvēlnes vienums</translation>
-<translation id="3406283310380167331">Rādīt veidlapu sarakstu</translation>
-<translation id="3422338090358345848">Atvērt tastatūras pārlūku</translation>
-<translation id="3457000393508828486">Daļēji nospiests</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, poga</translation>
-<translation id="3473644018603298796">atlasīti vienumi: <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{aizverošā kvadrātiekava}zero{# aizverošo kvadrātiekavu}one{# aizverošā kvadrātiekava}other{# aizverošās kvadrātiekavas}}</translation>
-<translation id="3493915602752813531">Tālāk nav neviena enkura.</translation>
-<translation id="3494946239022273294">izvēlnes vienums</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{jautājuma zīme}zero{# jautājuma zīmju}one{# jautājuma zīme}other{# jautājuma zīmes}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{jumtiņš}zero{# jumtiņu}one{# jumtiņš}other{# jumtiņi}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, izvēles rūtiņa nav atzīmēta</translation>
-<translation id="3599054940393788245">Neatrodas matemātiskā izteiksmē</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{gravis}zero{# gravju}one{# gravis}other{# gravji}}</translation>
-<translation id="3650317109285159359">izvēlnes vienumu izvēles rūtiņa</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolāra zīme}zero{# dolāra zīmju}one{# dolāra zīme}other{# dolāra zīmes}}</translation>
-<translation id="3659787053479271466">brīdinājums</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, sarakstlodziņš</translation>
-<translation id="3687295507293856493">Izdarīt minējumu par pašreizējās šūnas slejas virsrakstu</translation>
-<translation id="3692274950075847560">M:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Runas kontrole</translation>
-<translation id="3716845769494773620">Daudzrindu</translation>
-<translation id="3731746171184829332">Iepriekš nav neviena virsraksta.</translation>
-<translation id="3762198587642264450">Pāriet uz pašreizējās rindas beigām</translation>
-<translation id="3777255250339039212">1. līmeņa virsraksts</translation>
-<translation id="3793710123303304873">Tika aizvērts dialoglodziņš.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}zero{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">Automātiskā pabeigšana: saraksts</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Nākamais multivides vienums</translation>
-<translation id="3819376190738087562">Nav pārejas punktu.</translation>
-<translation id="385383972552776628">Atvērt opciju lapu</translation>
-<translation id="3856075812838139784">Tikai lasāms</translation>
-<translation id="3887576927692165210">tekstlodziņš</translation>
-<translation id="3897092660631435901">Izvēlne</translation>
-<translation id="3909320334364316587">Iepriekšējais 6. līmeņa virsraksts</translation>
-<translation id="3914173277599553213">Obligātas</translation>
-<translation id="3962990492275676168">Sākt lasīšanu no pašreizējās atrašanās vietas</translation>
-<translation id="4004802134384979325">atzīmēts</translation>
-<translation id="4006140876663370126">attēls</translation>
-<translation id="4038349100599457191">Mēneša vadīkla</translation>
-<translation id="4039983576244166038">Tukšs rindas virsraksts</translation>
-<translation id="4042843249978639960">Tālāk nav neviena 2. līmeņa virsraksta.</translation>
-<translation id="4043348641337972076">Iepriekš nav neviena ARIA orientiera.</translation>
-<translation id="4047216625641135770">Iezīmēt</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">statuss</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}zero{# tilžu}one{# tilde}other{# tildes}}</translation>
-<translation id="409334809956508737">Iepriekšējais objekts</translation>
-<translation id="4099274309791143834">ietver apakšizvēlni</translation>
-<translation id="4107807507418787238">Tālāk nav nevienas šūnas.</translation>
-<translation id="4116415223832267137">Brīdinājums</translation>
-<translation id="4147126331795725888">Tālāk nav nevienas vadīklas.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{aizverošā figūriekava}zero{# aizverošo figūriekavu}one{# aizverošā figūriekava}other{# aizverošās figūriekavas}}</translation>
-<translation id="4158704014418536539">Reģistrjutīgs.</translation>
-<translation id="4161663686871496107">ChromeVox izrunas funkcija ir gatava</translation>
-<translation id="4173994908659439270">Tālāk nav neviena rediģējama teksta lauka.</translation>
-<translation id="4176463684765177261">Atspējots</translation>
-<translation id="4188530942454211480">Iepriekšējais teikums</translation>
-<translation id="4202186506458631436">Pārvietot pa labi</translation>
-<translation id="4206289001967551965">Tabulas iekšpusē</translation>
-<translation id="4215733775853809057">Nākamais slīdnis</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{defise}zero{# defišu}one{# defise}other{# defises}}</translation>
-<translation id="421884353938374759">krāsu izvēle</translation>
-<translation id="4229646983878045487">datums un laiks</translation>
-<translation id="423334822609210999">Pa kreisi nav nevienas šūnas.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" />. pakāpe</translation>
-<translation id="4253168017788158739">Piezīme</translation>
-<translation id="4254798249533888099">Koks</translation>
-<translation id="4255943572433203166">Izmantojiet tālāk norādītās opcijas, lai pielāgotu ChromeVox. Izmaiņas stājas spēkā nekavējoties.</translation>
-<translation id="4271220233568730077">Nākamā matemātiskā izteiksme</translation>
-<translation id="4271521365602459209">Nav neviena cita rezultāta.</translation>
-<translation id="4287520460805643128">Nav nākamā raksta.</translation>
-<translation id="4289540628985791613">Kopsavilkums</translation>
-<translation id="4300318234632215983">Paziņot par saites URL</translation>
-<translation id="4301352596632316575">ietver apakšizvēlni</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punkts}=3{daudzpunkte}zero{# punktu}one{# punkts}other{# punkti}}</translation>
-<translation id="4347461890115250064">Tālāk nav neviena saraksta.</translation>
-<translation id="4367650418938037324">MathML lapa</translation>
-<translation id="4372435075475052704">min.: <ph name="X" /></translation>
-<translation id="4372705107434148843">Apturēt runas izvadi</translation>
-<translation id="4373197658375206385">Nav neviena iepriekšējā vienuma, kas nav saite.</translation>
-<translation id="4391478986194775161">satura informācija</translation>
-<translation id="443163561286008705">atiestatīt</translation>
-<translation id="4471074325120394300">Nav saišu.</translation>
-<translation id="4476183483923481720">jauna rindiņa</translation>
-<translation id="4482330759234983253">Iepriekšējā tabula</translation>
-<translation id="4491109536499578614">Attēls</translation>
-<translation id="4529987814483543472">Klasiskā taustiņu piesaiste</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{slīpsvītra}zero{# slīpsvītru}one{# slīpsvītra}other{# slīpsvītras}}</translation>
-<translation id="4547556996012970016">Nākamais 5. līmeņa virsraksts</translation>
-<translation id="4562381607973973258">Galvene</translation>
-<translation id="4591507479202817876">, atlasīts</translation>
-<translation id="4597532268155981612">veidlapa</translation>
-<translation id="4597896406374528575">Aprīlis</translation>
-<translation id="4615592953348396470">Tiek ignorēta nākamā taustiņa nospiešana</translation>
-<translation id="461613135510474570">Teikums</translation>
-<translation id="4647836961514597010">Krāsu izvēle</translation>
-<translation id="4661075872484491155">koks</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">režģis</translation>
-<translation id="4693675773662933727">Iepriekšējais orientieris</translation>
-<translation id="4696413482802371445">Tālāk nav neviena 5. līmeņa virsraksta.</translation>
-<translation id="4729095194763193578">Iepriekšējā tabulas rinda</translation>
-<translation id="4736221692378411923">Augusts</translation>
-<translation id="4740661827607246557">Palīdzības komandas</translation>
-<translation id="4759716709594980008">ChromeOS tastatūras pārlūks</translation>
-<translation id="4763296182459741068">Doties uz beigām</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">meklēt</translation>
-<translation id="481165870889056555">Paziņot pašreizējas lapas nosaukumu</translation>
-<translation id="4826415162591436065">Pārvietoties uz priekšu</translation>
-<translation id="4826604887384865800">Nākamais pārejas punkts</translation>
-<translation id="4827410568042294688">nav atlasīts</translation>
-<translation id="4842108708071771135">Tālāk nav neviena citāta bloka.</translation>
-<translation id="4848993367330139335">taimeris</translation>
-<translation id="4850023505158945298">Iepriekšējais līdzīgais elements.</translation>
-<translation id="4866956062845190338">izvēlnes vienuma radiopoga</translation>
-<translation id="4867316986324544967">Iespējot teksta pārvēršanas runā reģistrēšanu</translation>
-<translation id="4877261390094455813">Ievadiet meklēšanas vaicājumu.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />. no <ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Iekšējā saite</translation>
-<translation id="4953585991029886728">Rediģējams teksts</translation>
-<translation id="4954534434583049121">Iepriekšējais citāta bloks</translation>
-<translation id="4973717656530883744">Min.: <ph name="X" /></translation>
-<translation id="4973762002207131920">Mainīts uz: <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisekundes</translation>
-<translation id="49787999531187221">ChromeVox nav aktīvs.</translation>
-<translation id="4979404613699303341">Iepriekšējā poga</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, sarakstlodziņš</translation>
-<translation id="4983588134362688868">Pāriet uz lapas sākumu</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, logs</translation>
-<translation id="4993152509206108683">Ātrums: <ph name="PERCENT" />%</translation>
-<translation id="4996716799442435517">Vizuāla</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, atlasīta radiopoga</translation>
-<translation id="4997475792277222884">Tālāk nav neviena vienuma, kas nav saite.</translation>
-<translation id="5000760171916499057">Nav veidlapu.</translation>
-<translation id="5005670136041063723">Nav neviena cita līdzīga elementa.</translation>
-<translation id="501473567976723023">Janvāris</translation>
-<translation id="5041394372352067729">Pārvietot Braila raksta attēlojumu uz lapas augšdaļu</translation>
-<translation id="5042770794184672516">Palielināt runas skaļumu</translation>
-<translation id="5050015258024679800">Iepriekšējais 4. līmeņa virsraksts</translation>
-<translation id="5054047268577924192">Iepriekšējais saraksta vienums</translation>
-<translation id="5078661581131202757">Failu atlase</translation>
-<translation id="5080758118274074384">Tika veikts dubultklikšķis.</translation>
-<translation id="5098541983634824365">Notiek iziešana no režģa.</translation>
-<translation id="5102981729317424850">Rīkjosla</translation>
-<translation id="5105050547967751155">nepieciešams</translation>
-<translation id="5110983769041734144">Iepriekš nav neviena veidlapas lauka.</translation>
-<translation id="5111640677200759579">Slejas virsraksts</translation>
-<translation id="5117636609870536415">e-pasts</translation>
-<translation id="5136967254288895616">Iepriekš nav nevienas saites.</translation>
-<translation id="513774504516943387">saite</translation>
-<translation id="517143700877085897">, nav atlasīts</translation>
-<translation id="5183440668879371625">Iepriekšējā rindiņa Braila rakstā</translation>
-<translation id="5184944171021383281">Tālāk nav neviena veidlapas lauka.</translation>
-<translation id="5189244881767082992">Rindiņa</translation>
-<translation id="5203930734796605961">Taustiņš <ph name="KEY" /> jau ir piešķirts komandai.</translation>
-<translation id="5205493599117157272">Saraksts: <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Tālāk nav nevienas radiopogas.</translation>
-<translation id="5263344797180442561">2. līmeņa virsraksts</translation>
-<translation id="528468243742722775">Beigas</translation>
-<translation id="5291783959063340370">Objekts</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, cilne</translation>
-<translation id="5310788376443009632">noņemts:</translation>
-<translation id="5320727453979144100">Saistošais režīms iespējots</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{komats}zero{# komatu}one{# komats}other{# komati}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, tekstlodziņš</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, saite</translation>
-<translation id="5336381510091010269">iekļautā automātiskā pabeigšana un saraksts</translation>
-<translation id="536031132345979795">Pāriet atpakaļ nepārtraukta lasījuma laikā</translation>
-<translation id="5368000168321181111">Signāli izslēgti</translation>
-<translation id="5374320867641260420">Tālāk nav nevienas pogas.</translation>
-<translation id="5382299583965267720">Tālāk nav neviena 1. līmeņa virsraksta.</translation>
-<translation id="5402367795255837559">Braila raksts</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{semikols}zero{# semikolu}one{# semikols}other{# semikoli}}</translation>
-<translation id="5411891038905756502">Iepriekš nav neviena pārejas punkta.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{zīme “mazāks par”}zero{# zīmju “mazāks par”}one{# zīme “mazāks par”}other{# zīmes “mazāks par”}}</translation>
-<translation id="5455441614648621694">Papildu</translation>
-<translation id="5485036206801896268">Iepriekš nav nevienas grafikas.</translation>
-<translation id="5486947920110100234">Tālāk nav neviena pārejas punkta.</translation>
-<translation id="549602578321198708">Vārds</translation>
-<translation id="5500932716852106146">Iepriekš nav neviena rediģējama teksta lauka.</translation>
-<translation id="5502713021410870035">Septembris</translation>
-<translation id="5507663321906818013">Atkļūdošanas etalonsalīdzinājumi</translation>
-<translation id="5518443085409638729">Rediģējot tekstu, novietot kursoru starp rakstzīmēm (kā operētājsistēmā Mac OS X)</translation>
-<translation id="552195134157544755">Radiopoga</translation>
-<translation id="5534303576632885660">Galvene</translation>
-<translation id="5546092960038624944">Iepriekš nav neviena 5. līmeņa virsraksta.</translation>
-<translation id="556042886152191864">Poga</translation>
-<translation id="5561345396546889625">Nākamais saraksts</translation>
-<translation id="5562645715554321347">virsrakstu grupa</translation>
-<translation id="5583640892426849032">Atkāpšanās taustiņš</translation>
-<translation id="5585044216466955529">Rediģējams teksts: e-pasta adreses ievade</translation>
-<translation id="5597170376237141345">Nākamā izvēles rūtiņa</translation>
-<translation id="5597933780944041114">Tālāk nav neviena virsraksta.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, neatlasīta radiopoga</translation>
-<translation id="5601172225407283979">Veikt noklusējuma darbību</translation>
-<translation id="5608798115546226984">Automātiskā pabeigšana: iekļauta</translation>
-<translation id="561939826962581046">laiks</translation>
-<translation id="5623778242535476823">radiopoga</translation>
-<translation id="5623842676595125836">Žurnāls</translation>
-<translation id="5628125749885014029">4. līmeņa virsraksts</translation>
-<translation id="5637871198229500030">Iepriekš nav nevienas tabulas.</translation>
-<translation id="5655682562155942719">Pārejas komandas</translation>
-<translation id="56637627897541303">Teksta apgabals</translation>
-<translation id="5678161956734658133">teksta apgabals</translation>
-<translation id="5681643281275621376">definīcija</translation>
-<translation id="5682113568322255809">Orientieris</translation>
-<translation id="5683155931978483559">Iepriekšējā izvēles rūtiņa</translation>
-<translation id="5684277895745049190">Saraksts</translation>
-<translation id="5700650669149824506">Iepriekš nav neviena 4. līmeņa virsraksta.</translation>
-<translation id="5709192780268610569">Nav garā apraksta.</translation>
-<translation id="5712244464475377681">uznirstošā poga</translation>
-<translation id="5712338278108304766">Nākamā tabulas sleja</translation>
-<translation id="571866080859340309">Tiek sākta grupu izpēte.</translation>
-<translation id="5728409797179002635">Neviena tabula nav atrasta.</translation>
-<translation id="5748623122140342504">Iepriekšējais 5. līmeņa virsraksts</translation>
-<translation id="5750633686117194034">Nav nospiests neviens modificētājtaustiņš. Lūdzu, turiet nospiestu vienu vai vairākus modificētājtaustiņus, pēc tam atlaidiet pirkstus, un tiks paziņots, ka taustiņi ir iestatīti. Lai izietu, nospiediet tabulēšanas taustiņu.</translation>
-<translation id="5788275253279308023">inkognito režīma loga cilne <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Uzlabojiet konkrētu vietņu darbību (piemēram, vietnes Google meklēšana darbību).</translation>
-<translation id="5819072574982403430">Koka vienums</translation>
-<translation id="5826479389509458994"><ph name="ROW" />. rinda, <ph name="COL" />. sleja</translation>
-<translation id="5850707923114094062">Pārvietot atpakaļ</translation>
-<translation id="5851548754964597211">Ciļņu saraksts</translation>
-<translation id="5859752971144398932">Lapā tika aizvērts meklēšanas logrīks.</translation>
-<translation id="5866042630553435010">Daļēji atzīmēts</translation>
-<translation id="5869546221129391014">Režģis</translation>
-<translation id="5876817486144482042">Samazināt runas skaļumu</translation>
-<translation id="5887397643266327462">Braila parakstu funkcija ir iespējota.</translation>
-<translation id="5891934789323004067">Tabula</translation>
-<translation id="5919442531159595654">kopēt.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{vienādības zīme}zero{# vienādības zīmju}one{# vienādības zīme}other{# vienādības zīmes}}</translation>
-<translation id="5939518447894949180">Atiestatīt</translation>
-<translation id="5948123859135882163">Pārslēgt matemātisko izteiksmju interpretāciju starp strukturālo un semantisko.</translation>
-<translation id="5955304353782037793">lietojumprogramma</translation>
-<translation id="5956928062748260866">Dialoglodziņš</translation>
-<translation id="5963413905009737549">Sadaļa</translation>
-<translation id="5968607524793740041">Rādīt kontekstizvēlni</translation>
-<translation id="5983179082906765664">Palielināt navigācijas precizitāti</translation>
-<translation id="5999630716831179808">Balss veidi</translation>
-<translation id="6000417740266304866">Lai mainītu pašreizējo 8 punktu Braila tabulu, tālāk redzamajā sarakstā atlasiet attiecīgo opciju.</translation>
-<translation id="6006050241733874051">Veidlapa</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{atpakaļvērstā slīpsvītra}zero{# atpakaļvērsto slīpsvītru}one{# atpakaļvērstā slīpsvītra}other{# atpakaļvērstās slīpsvītras}}</translation>
-<translation id="6037602951055904232">Pārvietot uz priekšu</translation>
-<translation id="611827076493383239">apmeklēta</translation>
-<translation id="6119955456199054975">Šūnas beigas.</translation>
-<translation id="6122013438240733403">poga</translation>
-<translation id="6129953537138746214">Atstarpe</translation>
-<translation id="6142308968191113180">4. līmeņa virsraksts</translation>
-<translation id="6169420925157477918">Attēls ar garu aprakstu</translation>
-<translation id="6172087735260766220">Nevar piekļūt pieejamajam tekstam no PDF faila, kas aizsargāts pret kopēšanu.</translation>
-<translation id="6186305613600865047">Pāriet uz lapas beigām</translation>
-<translation id="6193330012414963395">Priekšpusdiena/pēcpusdiena</translation>
-<translation id="622484624075952240">Lejup</translation>
-<translation id="6236061028292614533">Nākamais virsraksts</translation>
-<translation id="6254901459154107917">Nākamais rediģējamais teksta apgabals</translation>
-<translation id="6259464875943891919">Tika aizvērts <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Nākamais līdzīgais elements.</translation>
-<translation id="6282062888058716985">navigācija</translation>
-<translation id="6290434000785343030">Tālāk nav neviena kombinētā lodziņa.</translation>
-<translation id="6307969636681130414">Nospiests</translation>
-<translation id="6324551002951139333">Konstatēta gramatiska kļūda</translation>
-<translation id="6348657800373377022">Kombinētais lodziņš</translation>
-<translation id="6355910664415701303">Iepriekš nav neviena saraksta vienuma.</translation>
-<translation id="6364795331201459219">6. līmeņa virsraksts</translation>
-<translation id="6368143427468974988">Iepriekšējais virsraksts</translation>
-<translation id="6387719785439924554">malā novietots saturs</translation>
-<translation id="6411426777058107714">Iepriekš nav nevienas radiopogas.</translation>
-<translation id="6414968628640960377">Iepriekšējais atšķirīgais elements.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{kols}zero{# kolu}one{# kols}other{# koli}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, izvēlne</translation>
-<translation id="6444046323172968959">Brīdinājuma dialoglodziņš</translation>
-<translation id="6459511626086141404">Izplātā taustiņu piesaiste</translation>
-<translation id="6468049171101508116">Nākamā poga</translation>
-<translation id="6491972999578897419">Mainiet pašreizējo balsi, tālāk esošajā sarakstā atlasot vēlamo opciju.</translation>
-<translation id="6508059270146105198">Pārvietot Braila raksta attēlojumu uz lapas apakšdaļu</translation>
-<translation id="6536864053412760904">MathML marķieris</translation>
-<translation id="6550720799683018100">Mainiet pašreizējo taustiņu piesaisti, tālāk esošajā sarakstā atlasot vēlamo opciju.</translation>
-<translation id="6561818612645211875">Pāriet uz pašreizējās rindas sākumu</translation>
-<translation id="6587021927234520429">Tālāk nav neviena 4. līmeņa virsraksta.</translation>
-<translation id="6601344353291556895">Iespējot izvērstus aprakstus</translation>
-<translation id="6615602925644411249">Meklēšana lapā.</translation>
-<translation id="6633350132811819843">Tālāk nav nevienas tabulas.</translation>
-<translation id="6637586476836377253">žurnāls</translation>
-<translation id="6657128831881431364">Norises josla</translation>
-<translation id="6659594942844771486">Cilne</translation>
-<translation id="667999046851023355">Dokuments</translation>
-<translation id="6697092096875747123">Iepriekšējais kombinētais lodziņš</translation>
-<translation id="6714813999819678458">Iepriekšējais 2. līmeņa virsraksts</translation>
-<translation id="6716505898850596801">Modificētājtaustiņi</translation>
-<translation id="671916444866103745">Tālāk nav neviena ARIA orientiera.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, kombinētais lodziņš</translation>
-<translation id="6735257939857578167">ar <ph name="NUM" /> vienumiem</translation>
-<translation id="6736510033526053669">Tika izveidota cilne.</translation>
-<translation id="675895815784134693">progresa josla</translation>
-<translation id="6786800275320335305">Raksts</translation>
-<translation id="6787839852456839824">Īsinājumtaustiņi</translation>
-<translation id="6793101435925451627">sarakstlodziņš</translation>
-<translation id="6833103209700200188">Kājene</translation>
-<translation id="6871161210040114857">Reģistrjutība tiek ignorēta.</translation>
-<translation id="6877435256196695200">Tālāk nav nevienas grafikas.</translation>
-<translation id="6897341342232909480">Pārvietoties pa kreisi</translation>
-<translation id="6901540140423170855">datums</translation>
-<translation id="6910211073230771657">Dzēsts</translation>
-<translation id="6911965441508464308">Iepriekš nav nevienas šūnas.</translation>
-<translation id="6919104639734799681">Rādīt tabulu sarakstu</translation>
-<translation id="6964088412282673743">Iepriekš nav nevienas vadīklas.</translation>
-<translation id="6996566555547746822">Nākamais kombinētais lodziņš</translation>
-<translation id="7005146664810010831">Neviens URL nav atrasts.</translation>
-<translation id="7010712454773919705">ChromeVox modificētājtaustiņš</translation>
-<translation id="7031651751836475482">saraksta vienums</translation>
-<translation id="7037042857287298941">Iepriekšējais saraksts</translation>
-<translation id="7041173719775863268">Atlase ir pabeigta.</translation>
-<translation id="7095834689119144465">Rediģējams teksts: tikai skaitļi</translation>
-<translation id="7096001299300236431">Iepriekšējais multivides vienums</translation>
-<translation id="7116595520562830928">vairākrindu</translation>
-<translation id="712735679809149106">vārdu atbalss</translation>
-<translation id="713824876195128146">Nākamais citāta bloks</translation>
-<translation id="7161771961008409533">Uznirstoša poga</translation>
-<translation id="7167657087543110">rakstzīmju atbalss</translation>
-<translation id="7170733337935166589">Pāriet uz priekšu nepārtraukta lasījuma laikā</translation>
-<translation id="7181697990050180700">Pielāgojiet īsinājumtaustiņus bieži lietotām komandām, ierakstot tās tālāk esošajos atbilstošajos laukos.</translation>
-<translation id="7203150201908454328">Izvērsts</translation>
-<translation id="7210211103303402262">minūtes</translation>
-<translation id="7217912842225915592">vēl <ph name="NUM" /></translation>
-<translation id="7221740160534240920">rindiņa</translation>
-<translation id="7226216518520804442">saraksts</translation>
-<translation id="72393384879519786">Virsraksts</translation>
-<translation id="7241683698754534149">Atvērt garo aprakstu jaunā cilnē</translation>
-<translation id="7248671827512403053">Lietojumprogramma</translation>
-<translation id="725969808843520477">Nākamā radiopoga</translation>
-<translation id="7269119382257320590">Bez pieturzīmēm</translation>
-<translation id="7273174640290488576">Tukša</translation>
-<translation id="7285387653379749618">Tabulas</translation>
-<translation id="7289186959554153431">3. līmeņa virsraksts</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">koka vienums</translation>
-<translation id="731576946540457939">Braila parakstu funkcija ir atspējota.</translation>
-<translation id="7318872822751139669">Izmantot peli, lai mainītu fokusu</translation>
-<translation id="7322388933135261569">Februāris</translation>
-<translation id="7332592614823088566"><ph name="ROWINDEX" />. rinda no <ph name="ROWTOTAL" />, <ph name="COLINDEX" />. sleja no <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">ietver uznirstošu elementu</translation>
-<translation id="7356165926712028380">Pāriet uz 8 punktu Braila rakstu</translation>
-<translation id="7362871137496673139">Iepriekš nav neviena 2. līmeņa virsraksta.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersands}zero{# ampersandu}one{# ampersands}other{# ampersandi}}</translation>
-<translation id="737396357417333429">noklikšķināms elements</translation>
-<translation id="7374104575779636480">Notiek iziešana no tabulas.</translation>
-<translation id="739763518212184081">Iepriekšējā rindiņa</translation>
-<translation id="7400575256015741911">Konstatēta pareizrakstības kļūda</translation>
-<translation id="7408482676469142474">tabula</translation>
-<translation id="7425395583360211003">rindatgrieze</translation>
-<translation id="7434509671034404296">Izstrādātājs</translation>
-<translation id="7439060726180460871">Direktorijs</translation>
-<translation id="744163271241493234">parole</translation>
-<translation id="7491962110804786152">cilne</translation>
-<translation id="7492049978501397201">Tika atvērts dialoglodziņš.</translation>
-<translation id="7532613204005497612">Jūnijs</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, slīdnis</translation>
-<translation id="7586163296341959563">ielīmēt.</translation>
-<translation id="7596919493010894443">atlase noņemta</translation>
-<translation id="7604026522577407655">Pāriet uz pašreizējās slejas sākumu</translation>
-<translation id="7604451927827590395">virsraksts</translation>
-<translation id="7609342235116740824">Paziņot pašreizējas lapas URL</translation>
-<translation id="7609363189280667021">Pārslēgt Braila parakstu funkciju</translation>
-<translation id="762020119231868829">Tiek pārtraukta visu pašlaik aktīvo multivides logrīku darbība.</translation>
-<translation id="7625690649919402823">Nākamā tabula</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), <ph name="GRADE" />. līmenis</translation>
-<translation id="7641134354185483015">Iepriekš nav neviena 3. līmeņa virsraksta.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, tekstlodziņš</translation>
-<translation id="7663318257180412551">2. līmeņa virsraksts</translation>
-<translation id="7674576868851035240">Nākamā saite</translation>
-<translation id="7674768236845044097">iezīmēt</translation>
-<translation id="7684431668231950609">Rediģējams teksts: URL ievade</translation>
-<translation id="7685589220304187312">rīkjosla</translation>
-<translation id="7693840228159394336">Iepriekšējā radiopoga</translation>
-<translation id="7701196182766842984">automātiski pabeigts saraksts</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, paroles tekstlodziņš</translation>
-<translation id="7805247615045262757">noklusējuma navigācija</translation>
-<translation id="7805768142964895445">Statuss</translation>
-<translation id="7810781339813764006">Nākamā grupa</translation>
-<translation id="7819187121850078213">loga cilne <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Oktobris</translation>
-<translation id="7839679365527550018">Iepriekšējais vārds</translation>
-<translation id="7851816175263618915">Dažas pieturzīmes</translation>
-<translation id="7870596830398826354">MathML koks</translation>
-<translation id="78826985582142166">slīdnis</translation>
-<translation id="7894517696028036636">Pārslēgt klasisko ChromeVox.</translation>
-<translation id="7895896691902835279">Nezināma saite</translation>
-<translation id="7927711904086083099">Nav atlasīts</translation>
-<translation id="7935627501098484003">Laika kontrole</translation>
-<translation id="7939428177581522200">pievienots atlasei</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{“et” zīme}zero{# “et” zīmju}one{# “et” zīme}other{# “et” zīmes}}</translation>
-<translation id="7965147473449754028">izvēlne aizvērta</translation>
-<translation id="7974390230414479278">Izvēlnes vienums</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{izsaukuma zīme}zero{# izsaukuma zīmju}one{# izsaukuma zīme}other{# izsaukuma zīmes}}</translation>
-<translation id="8007540374018858731">3. līmeņa virsraksts</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{pēdiņu rakstzīme}zero{# pēdiņu rakstzīmju}one{# pēdiņu rakstzīme}other{# pēdiņu rakstzīmes}}</translation>
-<translation id="8033827949643255796">atlasīti</translation>
-<translation id="8035962149453661158">maks.: <ph name="X" /></translation>
-<translation id="8042761080832772327">Rediģējams teksts: meklēšanas vaicājuma ievade</translation>
-<translation id="8049189770492311300">Taimeris</translation>
-<translation id="8065607967589909823">Atlase ir</translation>
-<translation id="8066678206530322333">Reklāmkarogs</translation>
-<translation id="8110647606445335195">Nav ARIA orientieru.</translation>
-<translation id="8153880621934657047">Nav tabulas iekšpusē.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{pasvītra}zero{# pasvītru}one{# pasvītra}other{# pasvītras}}</translation>
-<translation id="8179976553408161302">Ievadīt</translation>
-<translation id="81960742267269908">izgriezt.</translation>
-<translation id="8199231515320852133">Paziņot pašreizējās šūnas virsrakstus</translation>
-<translation id="820417203470636242">Tukša šūna</translation>
-<translation id="8215202828671303819">Vairāku elementu atlase</translation>
-<translation id="8276439074553447000">Pāriet uz iepriekšējo fokusējamo vienumu</translation>
-<translation id="8278417001922463147">Iepriekš nav neviena raksta.</translation>
-<translation id="8283603667300770666">Nākamais veidlapas lauks</translation>
-<translation id="831207808878314375">Definīcija</translation>
-<translation id="8313653172105209786">direktorijs</translation>
-<translation id="8344569602005188545">stundas</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{numura zīme}zero{# numura zīmju}one{# numura zīme}other{# numura zīmes}}</translation>
-<translation id="8374154622594089836">mēnesis</translation>
-<translation id="8378855320830505539">Reģions</translation>
-<translation id="8382679411218029383">Automātiskā pabeigšana: iekļauta un sarakstā</translation>
-<translation id="8428603554127842284"><ph name="DEPTH" />. līmenis</translation>
-<translation id="842922884199979200">Tālāk nav neviena 3. līmeņa virsraksta.</translation>
-<translation id="8430049249787218991">izvēļņu josla</translation>
-<translation id="844681116543532394">Iepriekš nav nevienas izvēles rūtiņas.</translation>
-<translation id="8455868257606149352">maks.: <ph name="X" /></translation>
-<translation id="84575901236241018">ir piekļuves taustiņš: <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Samazināt navigācijas precizitāti</translation>
-<translation id="8520472399088452386">Skaitītājpoga</translation>
-<translation id="8538744478902126321">Izdarīt minējumu par pašreizējās šūnas rindas virsrakstu</translation>
-<translation id="8540054775867439484">Doties uz sākumu</translation>
-<translation id="8548973727659841685">Rakstzīme</translation>
-<translation id="8561322612995434619">ietver uznirstošu elementu</translation>
-<translation id="8571096049907249734">vairākatlase</translation>
-<translation id="8584721346566392021">5. līmeņa virsraksts</translation>
-<translation id="8587549812518406253">Nākamais saraksta vienums</translation>
-<translation id="860150890330522909">Atzīmēta izvēles rūtiņa <ph name="NAME" /></translation>
-<translation id="8606621670302093223">Datuma vadīkla</translation>
-<translation id="8631359288236106450">atlasīti vienumi: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Paziņot pašreizējās šūnas koordinātas</translation>
-<translation id="8650576015643545550">Iepriekš nav neviena saraksta.</translation>
-<translation id="8653031188082306838">ietver URL</translation>
-<translation id="8653646212587894517">Rādīt saišu sarakstu</translation>
-<translation id="8664519043722036194">sekundes</translation>
-<translation id="867187640362843212">5. līmeņa virsraksts</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{vertikālā svītra}zero{# vertikālo svītru}one{# vertikālā svītra}other{# vertikālās svītras}}</translation>
-<translation id="8735450637152821465">Sākt atlasi</translation>
-<translation id="8743786158317878347">ievadīt strukturētu saturu, piemēram, tabulas</translation>
-<translation id="8747966237988593539">Numurēts saraksts</translation>
-<translation id="8759334257841767240">Tālāk nav nevienas saites.</translation>
-<translation id="8767968232364267681">Nākamais 4. līmeņa virsraksts</translation>
-<translation id="8770473310765924354">aizvērt strukturētu saturu, piemēram, tabulas</translation>
-<translation id="8791025954632646584">Semantiskā interpretācija ieslēgta</translation>
-<translation id="8796411681063377102">Nākamais 3. līmeņa virsraksts</translation>
-<translation id="8808582214901541005">Marts</translation>
-<translation id="8825828890761629845">reklāmkarogs</translation>
-<translation id="8851136666856101339">galvenais</translation>
-<translation id="8856538297388979332">Nospiediet augšupvērsto vai lejupvērsto bulttaustiņu, lai pārskatītu komandas, un nospiediet ievadīšanas taustiņu, lai aktivizētu.</translation>
-<translation id="8864099967139188018">Tālāk nav neviena 6. līmeņa virsraksta.</translation>
-<translation id="8882002077197914455">Rindas virsraksts</translation>
-<translation id="8896347895970027998">Pārslēgt ChromeVox uz aktīvo vai neaktīvo režīmu.</translation>
-<translation id="8898516272131543774">Cikliska rakstzīmes atbalss</translation>
-<translation id="8900148057318340779">Prefiksa taustiņš</translation>
-<translation id="8908714597367957477">slejas galvene</translation>
-<translation id="8931936695772494138">Tukši virsraksti</translation>
-<translation id="8937112856099038376">iekšēja saite</translation>
-<translation id="8940925288729953902">Modificētājtaustiņi</translation>
-<translation id="8943175951035496220">Nav šūnas pa labi.</translation>
-<translation id="8978496506222343566">rīka padoms</translation>
-<translation id="900114243503212879">fails</translation>
-<translation id="9027462562263121875">Nav tabulu.</translation>
-<translation id="9040132695316389094">1. līmeņa virsraksts</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Pārslēgt meklēšanas logrīku</translation>
-<translation id="9065283790526219006">ietver uznirstošu elementu</translation>
-<translation id="9077213568694924680">noņemti no atlases</translation>
-<translation id="9082874451376019682">Iepriekš nav neviena slīdņa.</translation>
-<translation id="9089864840575085222">Cikliska rakstīšanas atbalss</translation>
-<translation id="9107530006868467849">Iepriekš nav neviena multivides logrīka.</translation>
-<translation id="9108370397979208512">matemātiska izteiksme</translation>
-<translation id="9108589040018540527">ritjosla</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{procentu zīme}zero{# procentu zīmju}one{# procentu zīme}other{# procentu zīmes}}</translation>
-<translation id="9115913704608474258">Novembris</translation>
-<translation id="9128414153595658330">dialoglodziņš</translation>
-<translation id="9149560530563164529">sadaļa</translation>
-<translation id="9151211641321628915">Sniedz īsu aprakstu par pašreizējo pozīciju</translation>
-<translation id="9153606228985488238">Augstums: <ph name="PERCENT" />%</translation>
-<translation id="9160096769946561184">Pāriet uz pašreizējās slejas beigām</translation>
-<translation id="9173115498289768110">Skaļums: <ph name="PERCENT" />%</translation>
-<translation id="9178973770513562274">Izmantojiet augšupvērsto vai lejupvērsto bulttaustiņu, lai pārlūkotu, vai ierakstiet tekstu, lai meklētu.</translation>
-<translation id="9192904702577636854">Slīdošais teksts</translation>
-<translation id="9212322457209634662">Tālāk nav nevienas sadaļas.</translation>
-<translation id="930275611743429116">Sākt vai beigt atlasi</translation>
-<translation id="948171205378458592">Samazināt runas ātrumu</translation>
-<translation id="962913030769097253">Nākamais 1. līmeņa virsraksts</translation>
-<translation id="973955474346881951">Ieslēgt/izslēgt saistošo režīmu</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ml.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ml.xtb
deleted file mode 100644
index 426c9e2fd3c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ml.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ml">
-<translation id="1012173283529841972">ലിസ്റ്റ് ഇനം</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">സ്‌പാൻ ചെയ്‌തു.</translation>
-<translation id="1025074108959230262">സ്റ്റിക്കി മോഡ് പ്രവർത്തനരഹിതമാക്കി</translation>
-<translation id="1031961866430398710">തുടർന്ന്</translation>
-<translation id="1044777062731150180">തലക്കെട്ടൊന്നുമില്ല</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">ഇൻപുട്ട് അസാധുവാണ്</translation>
-<translation id="1082209053475788238">മുൻ നില 6 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="1088219014394087294">ശീർഷകങ്ങളൊന്നുമില്ല.</translation>
-<translation id="1106741348836243114">ശബ്‌ദ ഫീഡ്‌ബാക്ക് (ഇയർകോൺസ്) ഓണാക്കുക അല്ലെങ്കിൽ ഓഫാക്കുക.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="NUM" /> ഇനങ്ങളുള്ള <ph name="TAG" /> ശേഖരം</translation>
-<translation id="1155043339247954670">അടുത്ത ലിസ്റ്റ് ഇനം ഒന്നുമില്ല.</translation>
-<translation id="1157782847298808853">കീബോർഡ് സഹായം</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, കോംബോ ബോക്സ്</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, ഉപമെനു ഉള്ള മെനു ഇനം</translation>
-<translation id="1177863135347784049">ഇഷ്ടാനുസൃതം</translation>
-<translation id="1188858454923323853">കോംപ്ലിമെന്ററി</translation>
-<translation id="1206619573307042055">മാർക്യൂ</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome-ന് ശബ്‌ദം നൽകുന്നു</translation>
-<translation id="1229276918471378188">മുൻ ജമ്പ്</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">അടുത്ത നില 6 ശീർഷകം</translation>
-<translation id="1275718070701477396">തിരഞ്ഞെടുത്തു</translation>
-<translation id="1319608975892113573">മുൻ ബ്ലോക്ക്ക്വോട്ട് ഒന്നുമില്ല.</translation>
-<translation id="1321576897702511272">ChromeVox സഹായം മറയ്ക്കുക</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> / <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">പ്രതീക, പദ എക്കോ</translation>
-<translation id="1339428534620983148">മുൻ പട്ടിക നിര</translation>
-<translation id="1342835525016946179">ലേഖനം</translation>
-<translation id="1346748346194534595">ശരി</translation>
-<translation id="136718599399906424">അടുത്ത പട്ടിക നിര</translation>
-<translation id="1383876407941801731">തിരയൂ</translation>
-<translation id="1385214448885562192">അംഗീകരിക്കുന്നതിന് എന്ററും റദ്ദാക്കുന്നതിന് എസ്‌കേപ്പും അടുത്തതിനായി താഴേക്കും മുമ്പത്തേതിനായി മുകളിലേക്കും അമർത്തുക.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, പാസ്‌വേഡ് വാചക ബോക്സ്</translation>
-<translation id="1467432559032391204">ഇടത്</translation>
-<translation id="1474557363159888097">മുൻ ആങ്കർ ഒന്നുമില്ല.</translation>
-<translation id="1502086903961450562">മുൻ ഗ്രാഫിക്</translation>
-<translation id="1506187449813838456">പിച്ച് വർദ്ധിപ്പിക്കുക</translation>
-<translation id="151784044608172266">അടുത്ത വാക്യം</translation>
-<translation id="1524531499102321782">അടുത്ത ബ്രെയ്‌ലി വരി</translation>
-<translation id="1546370775711804143">സ്‌ക്രോൾ ബാർ</translation>
-<translation id="1559739829547075274">പിന്നോട്ട് നാവിഗേറ്റ് ചെയ്യുക</translation>
-<translation id="1571643229714746283">ChromeVox തയ്യാറാണ്</translation>
-<translation id="158493514907962286">ഡിസംബർ</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6 ഡോട്ട് ബ്രെയ്‌ലിയിലേക്ക് മാറുക</translation>
-<translation id="1611168825862729585">നിര ശീർഷകം:</translation>
-<translation id="1613476421962910979">ഇയർകോൺസ് ഓണാണ്</translation>
-<translation id="1618597272655350600">നിലവിലെ അവസ്ഥയെക്കുറിച്ച് ഒരു പൂർണ്ണമായ വിവരണം പ്രഖ്യാപിക്കുന്നു</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{അവരോഹണ ചിഹ്നം}other{# അവരോഹണ ചിഹ്നങ്ങൾ}}</translation>
-<translation id="1653266918374749391">മുൻ നില 3 ശീർഷകം</translation>
-<translation id="1659072772017912254">ചെക്കുചെയ്യാത്തത്</translation>
-<translation id="1669290819662866522">ആഴ്‌ച</translation>
-<translation id="1674262202423278359">ChromeVox നാവിഗേഷൻ</translation>
-<translation id="16777221443363124">മെനു ബാർ</translation>
-<translation id="1692077714702418899">ഘടനാപരമായ വരി</translation>
-<translation id="1700517974991662022">സന്ദർശിച്ചു</translation>
-<translation id="1722567105086139392">ലിങ്ക്</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">അടുത്ത ഗ്രാഫിക്</translation>
-<translation id="1781173782405573156">പാസ് ത്രൂ കീ</translation>
-<translation id="1787176709638001873">പാസ്‌വേഡിനായി വാചകം എഡിറ്റുചെയ്യുക</translation>
-<translation id="1810107444790159527">പട്ടിക ബോക്സ്</translation>
-<translation id="1828385960365606039">മേയ്</translation>
-<translation id="1834891354138622109">നിര</translation>
-<translation id="1865601187525349519">വാചകത്തിന്റെ അവസാനം</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">നിലവിലെ സമയവും തീയതിയും പറയുക.</translation>
-<translation id="1902396333223336119">സെൽ</translation>
-<translation id="1905379170753160525">ശീർഷകങ്ങളുടെ ലിസ്റ്റ് കാണിക്കുക</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">വാർഷിക നിയന്ത്രണത്തിലെ ആഴ്‌ച</translation>
-<translation id="1964135212174907577">അടുത്ത ഒബ്‌ജക്റ്റ്</translation>
-<translation id="1969092762068865084">ജൂലൈ</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">വരി ശീർഷകം:</translation>
-<translation id="2002895034995108595">നിലവിലുള്ള കീമാപ്പ് പുനഃസജ്ജമാക്കുക</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{ഇടത് ബ്രാക്കറ്റ്}other{# ഇടത് ബ്രാക്കറ്റുകൾ}}</translation>
-<translation id="2045490512405922022">ചെക്കുചെയ്യാത്തത്</translation>
-<translation id="20601713649439366">മുമ്പത്തെ മാത്ത് എക്‌സ്‌പ്രഷനുകളൊന്നുമില്ല.</translation>
-<translation id="207477615537953741">സെമാന്റിക്കുകൾ ഓഫാണ്</translation>
-<translation id="2086961585857038472">അടുത്ത വാക്ക്</translation>
-<translation id="2089387485033699258">ml</translation>
-<translation id="2091933974477985526">എഡിറ്റ് ചെയ്യാൻ കഴിയുന്ന മുമ്പത്തെ വാചക ഏരിയ</translation>
-<translation id="2100350898815792233">എല്ലാ വിരാമചിഹ്നങ്ങളും</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">ആക്‌സസ്സ് കീ:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">ചുവടെയുള്ള ലിസ്റ്റിൽ നിന്ന് ഒരു ഓപ്‌ഷൻ തിരഞ്ഞെടുത്തുകൊണ്ട് നിലവിലുള്ള 6 ഡോട്ട് ബ്രെയ്‌ലി പട്ടിക മാറ്റുക.</translation>
-<translation id="2169714232367507776">നിലവിലെ ഇനത്തിൽ ക്ലിക്കുചെയ്യുക</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{ക്ലോസ് പരാന്തിസിസ്}other{# ക്ലോസ് പരാന്തിസിസുകൾ}}</translation>
-<translation id="2199994615414171367">മുമ്പത്തെ മാത്ത്</translation>
-<translation id="2223693656926968778">നിലവിലുള്ള ഇനത്തിൽ പ്രവർത്തനം നടത്തുക</translation>
-<translation id="225732394367814946">സംഭാഷണ റേറ്റ് വർദ്ധിപ്പിക്കുക</translation>
-<translation id="2267945578749931355">അടുത്ത പ്രതീകം</translation>
-<translation id="2281234842553884450">മുൻ സ്ലൈഡർ</translation>
-<translation id="2318372665160196757">പ്രധാനപ്പെട്ടത്</translation>
-<translation id="2329324941084714723">ടാബ് പാനൽ</translation>
-<translation id="2344193891939537199">തീയതി, സമയ നിയന്ത്രണം</translation>
-<translation id="2359897517538099099">പട്ടിക മോഡിൽ അല്ല.</translation>
-<translation id="241124561063364910">അതിനുശേഷം</translation>
-<translation id="2417569100218200841">ഉള്ളടക്ക വിവരം</translation>
-<translation id="2422937916923936891">മെനു ഇനം ചെക്ക് ബോക്‌സ്</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">ഇപ്പോൾ പുതിയ ChromeVox മോഡിഫയർ <ph name="KEY" /> ആണ്.</translation>
-<translation id="2450814015951372393">ചെക്ക് ബോക്‌സ്</translation>
-<translation id="2462626033734746142">റേഡിയോ ബട്ടൺ ഗ്രൂപ്പ്</translation>
-<translation id="2471138580042810658">ശീർഷകം 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{നക്ഷത്രചിഹ്നം}other{# നക്ഷത്രചിഹ്നങ്ങൾ}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> പുനഃസജ്ജമാക്കി.</translation>
-<translation id="2553108862507765288">വ്യാകരണ പിശക്</translation>
-<translation id="257674075312929031">ഗ്രൂപ്പ്</translation>
-<translation id="2582407057977008361">അരികിൽ</translation>
-<translation id="2589102159832527089">ഈ പേജിൽ &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; എന്ന PDF ഫയലിൽ നിന്ന് എക്‌സ്‌ട്രാക്റ്റ് ചെയ്‌ത വാചകമുണ്ട്. &lt;a href="<ph name="URL" />"&gt;യഥാർത്ഥമായത് ലഭിക്കാൻ ഇവിടെ ക്ലിക്കുചെയ്യുക.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">ഇവ ഉൾപ്പെടുന്നു {COUNT,plural, =1{# ഇനം}other{# ഇനങ്ങൾ}}</translation>
-<translation id="2614981083756825552">മാത്ത് ML ലേഔട്ട്</translation>
-<translation id="2626530649491650971">ക്ലിക്കുചെയ്യാവുന്നത്</translation>
-<translation id="2628764385451019380">മുൻ കോമ്പോ ബോക്‌സ് ഒന്നുമില്ല.</translation>
-<translation id="2637227747952042642">മാത്ത്</translation>
-<translation id="2639750663247012216">ChromeVox മോഡിഫയർ</translation>
-<translation id="2644542693584024604">അക്ഷരത്തെറ്റ്</translation>
-<translation id="2667291555398229137">ഒരു റൂട്ടിംഗ് കീയുടെ ചുവടെയുള്ള ഇനത്തിൽ ക്ലിക്കുചെയ്യുക</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{ഓപ്പൺ പരാന്തിസിസ്}other{# ഓപ്പൺ പരാന്തിസിസുകൾ}}</translation>
-<translation id="2705875883745373140">അമർത്താത്തത്</translation>
-<translation id="2706462751667573066">മുകളിലേക്കുള്ള കീ</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ഓഡിയോ</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">ചെക്കുചെയ്‌തത്</translation>
-<translation id="27527859628328957">ഫോക്കസ് ചെയ്യാനാകുന്ന അടുത്ത ഇനത്തിലേക്ക് പോകുക</translation>
-<translation id="2770781857296573485">ഗ്രൂപ്പ് പര്യവേക്ഷണം നൽകുക</translation>
-<translation id="2777845298774924149">പുറത്തുകടന്നു</translation>
-<translation id="2800204403141299078">മറ്റ് വ്യത്യസ്‌ത ഘടകങ്ങൾ ഒന്നുമില്ല.</translation>
-<translation id="2800780099804980316">മുൻ നില 1 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="2811204574343810641">വരി</translation>
-<translation id="2816654101880605877">അടുത്ത സ്ലൈഡർ ഒന്നുമില്ല.</translation>
-<translation id="2841013758207633010">സമയം</translation>
-<translation id="2843837985843789981">മുമ്പത്തെ ഗ്രൂപ്പ്</translation>
-<translation id="2844995807198708617">സന്ദർഭ മെനു</translation>
-<translation id="2849332794118375855">അടുത്ത ചെക്ക്ബോക്‌സ് ഒന്നുമില്ല.</translation>
-<translation id="2864481629947106776">മുൻ ലിങ്ക്</translation>
-<translation id="2873259058405069099">പട്ടികയുടെ തുടക്കത്തിലേക്ക് പോകുക</translation>
-<translation id="2894654529758326923">വിവരം</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{ഇടത് ബ്രേസ്}other{# ഇടത് ബ്രേസുകൾ}}</translation>
-<translation id="2911433807131383493">ChromeVox ട്യൂട്ടോറിയൽ തുറക്കുക</translation>
-<translation id="2932083475399492303">ഘടനാപരമായവയ്‌ക്ക് അല്ലെങ്കിൽ ലേഔട്ടിന് ഇടയിലുള്ള ലൈൻ തരം ടോഗിൾ ചെയ്യുക</translation>
-<translation id="2964026537669811554">ശീർഷക ഗ്രൂപ്പ്</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{ടാബ്}other{# ടാബുകൾ}}</translation>
-<translation id="2972078295414139404">സന്ദർശിച്ച മുമ്പത്തെ ലിങ്കൊന്നുമില്ല.</translation>
-<translation id="2972205263822847197">ഉപകരണ നുറുങ്ങ്</translation>
-<translation id="2998131015536248178">മുമ്പത്തെ പ്രതീകം</translation>
-<translation id="2999559350546931576">പിച്ച് കുറയ്ക്കുക</translation>
-<translation id="2999945368667127852">അടുത്ത മീഡിയ വിജറ്റൊന്നുമില്ല.</translation>
-<translation id="3012414509011670858">മുമ്പത്തെ വിഭാഗങ്ങളൊന്നുമില്ല.</translation>
-<translation id="3030432017085518523">മെനു ഇനം റേഡിയോ ബട്ടൺ</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{വിശ്ലേഷം}other{# വിശ്ലേഷങ്ങൾ}}</translation>
-<translation id="3046838483509668188">ChromeVox ഓപ്‌ഷനുകൾ</translation>
-<translation id="3047143736589213134">പരീക്ഷണാത്മക കീമാപ്പ്</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> മെനു തുറന്നു</translation>
-<translation id="3078345202707391975">അടുത്ത നില 2 ശീർഷകം</translation>
-<translation id="3078740164268491126">പട്ടിക</translation>
-<translation id="3082557070674409251">ക്ലിക്കുചെയ്‌തു</translation>
-<translation id="3084806535845658316">ടൈപ്പുചെയ്യൽ എക്കോകളൊന്നുമില്ല</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">അടുത്ത മാത്ത് എക്‌സ്‌പ്രഷനുകളൊന്നുമില്ല.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">അടുത്ത ലാൻഡ്‌മാർക്ക്</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">ചുരുക്കിയത്</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">ലാൻഡ്‌മാർക്കുകളുടെ ലിസ്റ്റ് കാണിക്കുക</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">അടുത്ത വരി</translation>
-<translation id="3155083529632865074">മുൻ ബട്ടൺ ഒന്നുമില്ല.</translation>
-<translation id="3163593631834463955">ശൂന്യമായ നിര ശീർഷകം</translation>
-<translation id="316542773973815724">നാവിഗേഷൻ</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{സ്‌പെയ്‌സ്}other{# സ്‌പെയ്‌സുകൾ}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> നൽകി</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, ടാബ്</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">സന്ദർശിച്ച ലിങ്ക്</translation>
-<translation id="323731244387692321">ChromeVox കീ‌ബോർഡ് സഹായം തുറക്കുക</translation>
-<translation id="3241052487511142956">സന്ദർശിച്ച മുമ്പത്തെ ലിങ്ക്</translation>
-<translation id="3286390186030710347">സ്ലൈഡർ</translation>
-<translation id="3299925995433437805">സന്ദർശിച്ച അടുത്ത ലിങ്കൊന്നുമില്ല.</translation>
-<translation id="3303384412438961941">അതിന്റെ പേര് അറിയുന്നതിന് ഏതെങ്കിലും കീ അമർത്തുക. Ctrl+W കീബോർഡ് എക്സ്പ്ലോറർ അടയ്ക്കും.</translation>
-<translation id="3307886118343381874">പട്ടികയുടെ അവസാനം പോകുക</translation>
-<translation id="3311969765485641742">അലേർട്ടുകൾ അവലോകനം ചെയ്യാൻ Alt+Shift+A അമർത്തുക</translation>
-<translation id="3312997241656799641">സന്ദർശിച്ച അടുത്ത ലിങ്ക്</translation>
-<translation id="3321460131042519426">വേഡ് റാപ്പ് പ്രവർത്തനക്ഷമമാക്കുക</translation>
-<translation id="3322936298410871309">മുൻ നില 1 ശീർഷകം</translation>
-<translation id="3323447499041942178">പാഠബോക്‌സ്</translation>
-<translation id="3353420241558113817">{"ar": "അറബിക്",
- "bg": "ബൾഗേറിയൻ",
- "ca": "കറ്റാലൻ",
- "cs": "ചെക്ക്",
- "da": "ഡാനിഷ്",
- "de": "ജർമ്മൻ",
- "de_CH": "ജർമ്മൻ (സ്വിറ്റ്‌സർലാന്റ്)",
- "de_DE": "ജർമ്മൻ (ജർമ്മനി)",
- "el": "ഗ്രീക്ക്",
- "en": "ഇംഗ്ലീഷ്",
- "en_CA": "ഇംഗ്ലീഷ് (കാനഡ)",
- "en_GB": "ഇംഗ്ലീഷ് (യുണൈറ്റഡ് കിംഗ്‌ഡം)",
- "en_US": "ഇംഗ്ലീഷ് (യുണൈറ്റഡ് സ്റ്റേറ്റ്‌സ്)",
- "es": "സ്‌പാനിഷ്",
- "et": "എസ്റ്റോണിയൻ",
- "fr": "ഫ്രഞ്ച്",
- "fr_CA": "ഫ്രഞ്ച് (കാനഡ)",
- "fr_FR": "ഫ്രഞ്ച് (ഫ്രാൻസ്)",
- "fi": "ഫിന്നിഷ്",
- "he": "ഹീബ്രൂ",
- "hi": "ഹിന്ദി",
- "hr": "ക്രൊയേഷ്യൻ",
- "hu": "ഹംഗേറിയൻ",
- "is": "ഐസ്‌ലാൻഡിക്",
- "it": "ഇറ്റാലിയൻ",
- "ko": "കൊറിയൻ",
- "lt": "ലിത്വാനിയൻ",
- "lv": "ലാറ്റ്‌വിയൻ",
- "nb": "നോർവീജിയൻ ബൊക്‌മൽ",
- "nl": "ഡച്ച്",
- "pl": "പോളിഷ്",
- "pt": "പോർച്ചുഗീസ്",
- "ro": "റൊമാനിയൻ",
- "ru": "റഷ്യൻ",
- "sk": "സ്ലൊവാക്",
- "sl": "സ്ലൊവേനിയൻ",
- "sr": "സെർബിയൻ",
- "sv": "സ്വീഡിഷ്",
- "tr": "ടർക്കിഷ്",
- "vi": "വിയറ്റ്‌നാമീസ്",
- "zh": "ചൈനീസ്",
- "zh_TW": "ചൈനീസ് (പരമ്പരാഗത ഹാൻ)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{അധിക ചിഹ്നം}other{# അധിക ചിഹ്നങ്ങൾ}}</translation>
-<translation id="338583716107319301">സെപ്പറേറ്റര്‍</translation>
-<translation id="3389259863310851658">മുൻ ഫോം ഫീൽഡ്</translation>
-<translation id="3390225400784126843">അടുത്ത മറ്റൊരു ഘടകം</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, മെനു ഇനം</translation>
-<translation id="3406283310380167331">ഫോമുകളുടെ ലിസ്റ്റ് കാണിക്കുക</translation>
-<translation id="3422338090358345848">കീബോർഡ് എക്സ്പ്ലോറർ തുറക്കുക</translation>
-<translation id="3457000393508828486">ഭാഗികമായി അമർത്തിയത്</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, ബട്ടൺ</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> മുതൽ <ph name="V2" /> വരെ</translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{വലത് ബ്രാക്കറ്റ്}other{# വലത് ബ്രാക്കറ്റുകൾ}}</translation>
-<translation id="3493915602752813531">അടുത്ത ആങ്കർ ഒന്നുമില്ല.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{ചോദ്യചിഹ്നം}other{# ചോദ്യചിഹ്നങ്ങൾ}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{കാരറ്റ്}other{# കാരറ്റുകൾ}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, ചെക്ക്‌ബോക്സ് ചെക്കുചെയ്‌തിട്ടില്ല</translation>
-<translation id="3599054940393788245">ആന്തരിക മാത്ത് അല്ല</translation>
-<translation id="3616113530831147358">ഓഡിയോ</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{ബാക്ക്‌ടിക്ക്}other{# ബാക്ക്‌ടിക്കുകൾ}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{ഡോളർ}other{# ഡോളർ ചിഹ്നങ്ങൾ}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, ലിസ്റ്റ് ബോക്സ്</translation>
-<translation id="3687295507293856493">നിലവിലെ സെല്ലിന്റെ നിര ശീർഷകത്തിൽ ഒരു ഊഹം നടത്തുക</translation>
-<translation id="3692274950075847560">തി:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">സംഭാഷണ നിയന്ത്രണം</translation>
-<translation id="3716845769494773620">ഒന്നിലധികം രേഖകൾ</translation>
-<translation id="3731746171184829332">മുൻ തലക്കെട്ടൊന്നുമില്ല.</translation>
-<translation id="3762198587642264450">നിലവിലെ വരിയുടെ അവസാനത്തിലേക്ക് പോകുക</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">ഡയലോഗിൽ നിന്ന് പുറത്തുകടന്നു.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">യാന്ത്രികപൂർത്തീകരണം ലിസ്റ്റ്</translation>
-<translation id="3810838688059735925">വീഡിയോ</translation>
-<translation id="3816633764618089385">അടുത്ത മീഡിയ</translation>
-<translation id="3819376190738087562">ജംപുകൾ ഒന്നുമില്ല.</translation>
-<translation id="385383972552776628">ഓപ്ഷനുകളുടെ പേജ് തുറക്കുക</translation>
-<translation id="3856075812838139784">വായനമാത്രം</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">മെനു</translation>
-<translation id="3909320334364316587">മുൻ നില 6 ശീർഷകം</translation>
-<translation id="3914173277599553213">ആവശ്യമായത്</translation>
-<translation id="3962990492275676168">നിലവിലെ സ്ഥാനത്ത് നിന്ന് വായിക്കാൻ ആരംഭിക്കുക</translation>
-<translation id="4004802134384979325">ചെക്കുചെയ്‌തു</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">മാസ നിയന്ത്രണം</translation>
-<translation id="4039983576244166038">ശൂന്യമായ വരി ശീർഷകം</translation>
-<translation id="4042843249978639960">അടുത്ത നില 2 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="4043348641337972076">മുൻ ARIA ലാൻഡ്‌മാർക്ക് ഒന്നുമില്ല.</translation>
-<translation id="4047216625641135770">അടയാളപ്പെടുത്തൽ</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{ടിൽഡ്}other{# ടിൽഡുകൾ}}</translation>
-<translation id="409334809956508737">മുമ്പത്തെ ഒബ്‌ജക്റ്റ്</translation>
-<translation id="4099274309791143834">ഉപമെനു ഉള്ളത്</translation>
-<translation id="4107807507418787238">ചുവടെ കോളമൊന്നുമില്ല.</translation>
-<translation id="4116415223832267137">അലേർട്ട്</translation>
-<translation id="4147126331795725888">അടുത്ത നിയന്ത്രണങ്ങളൊന്നുമില്ല.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{വലത് ബ്രേസ്}other{# വലത് ബ്രേസുകൾ}}</translation>
-<translation id="4158704014418536539">കേസ് സെൻസിറ്റീവ്.</translation>
-<translation id="4161663686871496107">ChromeVox സംഭാഷണ ഫീഡ്‌ബാക്ക് തയ്യാറാണ്</translation>
-<translation id="4173994908659439270">എഡിറ്റുചെയ്യാൻ കഴിയുന്ന അടുത്ത വാചക ഫീൽഡ് ഒന്നുമില്ല.</translation>
-<translation id="4176463684765177261">അപ്രാപ്‌തമാക്കി</translation>
-<translation id="4188530942454211480">മുമ്പത്തെ വാക്യം</translation>
-<translation id="4202186506458631436">വലതുവശത്തേക്ക് നീക്കുക</translation>
-<translation id="4206289001967551965">പട്ടികയ്‌ക്കുള്ളിൽ</translation>
-<translation id="4215733775853809057">അടുത്ത സ്ലൈഡർ</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{ഡാഷ്}other{# ഡാഷുകൾ}}</translation>
-<translation id="421884353938374759">വർണ്ണ പിക്കർ</translation>
-<translation id="4229646983878045487">തീയതിയും സമയവും</translation>
-<translation id="423334822609210999">ഇടതുഭാഗത്ത് കോളമൊന്നുമില്ല.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, ഗ്രേഡ് <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">കുറിപ്പ്</translation>
-<translation id="4254798249533888099">ട്രീ</translation>
-<translation id="4255943572433203166">ChromeVox ഇഷ്ടാനുസൃതമാക്കുന്നതിന് ചുവടെയുള്ള ഓപ്ഷനുകൾ ഉപയോഗിക്കുക. മാറ്റങ്ങൾ പെട്ടെന്ന് പ്രാബല്യത്തിൽ വരും.</translation>
-<translation id="4271220233568730077">അടുത്ത മാത്ത്</translation>
-<translation id="4271521365602459209">കൂടുതൽ ഫലങ്ങളൊന്നുമില്ല.</translation>
-<translation id="4287520460805643128">അടുത്ത ലേഖനമൊന്നുമില്ല.</translation>
-<translation id="4289540628985791613">അവലോകനം</translation>
-<translation id="4300318234632215983">ഒരു ലിങ്കിന് പുറകിലുള്ള URL അറിയിക്കുക</translation>
-<translation id="4301352596632316575">ഉപമെനു ഉണ്ട്</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{ഡോട്ട്}=3{എല്ലിപ്‌സിസ്}other{# ഡോട്ടുകൾ}}</translation>
-<translation id="4347461890115250064">അടുത്ത ലിസ്റ്റ് ഒന്നുമില്ല.</translation>
-<translation id="4367650418938037324">മാത്ത് ML ലീഫ്</translation>
-<translation id="4372435075475052704">കുറഞ്ഞത്:<ph name="X" /></translation>
-<translation id="4372705107434148843">സംഭാഷണം അവസാനിപ്പിക്കുക</translation>
-<translation id="4373197658375206385">ഒരു ലിങ്ക് അല്ലാത്ത മുൻ ഇനം ഒന്നുമില്ല.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">പുനഃസജ്ജമാക്കുക</translation>
-<translation id="4471074325120394300">ലിങ്കുകൾ ഒന്നുമില്ല.</translation>
-<translation id="4476183483923481720">പുതിയ വരി</translation>
-<translation id="4482330759234983253">മുൻ പട്ടിക</translation>
-<translation id="4491109536499578614">ചിത്രം</translation>
-<translation id="4529987814483543472">ക്ലാസിക്ക് കീമാപ്പ്</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{സ്ലാഷ്}other{# സ്ലാഷുകൾ}}</translation>
-<translation id="4547556996012970016">അടുത്ത നില 5 ശീർഷകം</translation>
-<translation id="4562381607973973258">ശീർഷകം</translation>
-<translation id="4591507479202817876">, തിരഞ്ഞെടുത്തു</translation>
-<translation id="4597532268155981612">ഫോം</translation>
-<translation id="4597896406374528575">ഏപ്രിൽ</translation>
-<translation id="4615592953348396470">അടുത്ത കീ അമർത്തുന്നത് ഒഴിവാക്കുന്നു</translation>
-<translation id="461613135510474570">വാക്യം</translation>
-<translation id="4647836961514597010">വർണ്ണ പിക്കർ</translation>
-<translation id="4661075872484491155">ട്രീ</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">മുമ്പത്തെ ലാൻഡ്മാർക്ക്</translation>
-<translation id="4696413482802371445">അടുത്ത നില 5 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="4729095194763193578">മുൻ പട്ടിക വരി</translation>
-<translation id="4736221692378411923">ഓഗസ്റ്റ്</translation>
-<translation id="4740661827607246557">സഹായ കമാൻഡുകൾ</translation>
-<translation id="4759716709594980008">ChromeOS കീബോർഡ് എക്സ്പ്ലോറർ</translation>
-<translation id="4763296182459741068">താഴേയ്‌ക്ക് റാപ്പുചെ‌യ്‌തു</translation>
-<translation id="4763480195061959176">വീഡിയോ</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">നിലവിലെ പേജിന്റെ ശീർഷകം അറിയിക്കുക</translation>
-<translation id="4826415162591436065">മുന്നോട്ട് നാവിഗേറ്റ് ചെയ്യുക</translation>
-<translation id="4826604887384865800">അടുത്ത ജമ്പ്</translation>
-<translation id="4827410568042294688">തിരഞ്ഞെടുത്തത് ഒഴിവാക്കി</translation>
-<translation id="4842108708071771135">അടുത്ത ബ്ലോക്ക്ക്വോട്ട് ഒന്നുമില്ല.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">മുൻ സമാന ഘടകം.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക</translation>
-<translation id="4877261390094455813">ഒരു തിരയൽ ചോദ്യം നൽകുക.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">ആന്തരിക ലിങ്ക്</translation>
-<translation id="4953585991029886728">വാചകം എഡിറ്റുചെയ്യുക</translation>
-<translation id="4954534434583049121">മുൻ ബ്ലോക്ക് ഉദ്ധരണി</translation>
-<translation id="4973717656530883744">കുറഞ്ഞത് <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> എന്നതിലേക്ക് മാറി.</translation>
-<translation id="4975416682604111799">മില്ലിസെക്കൻഡ്</translation>
-<translation id="49787999531187221">ChromeVox ഇപ്പോൾ നിർജ്ജീവമാണ്.</translation>
-<translation id="4979404613699303341">മുൻ ബട്ടൺ</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, ലിസ്റ്റ് ബോക്സ്</translation>
-<translation id="4983588134362688868">പേജിന്റെ മുകളിലേയ്‌ക്ക് പോകുക</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, വിൻഡോ</translation>
-<translation id="4993152509206108683"><ph name="PERCENT" /> ശതമാനം റേറ്റുചെയ്യുക</translation>
-<translation id="4996716799442435517">വിഷ്വൽ</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, റേഡിയോ ബട്ടൺ തിരഞ്ഞെടുത്തു</translation>
-<translation id="4997475792277222884">ഒരു ലിങ്ക് അല്ലാത്ത അടുത്ത ഇനം ഒന്നുമില്ല.</translation>
-<translation id="5000760171916499057">ഫോമുകൾ ഒന്നുമില്ല.</translation>
-<translation id="5005670136041063723">മറ്റ് സമാന ഘടകങ്ങൾ ഒന്നുമില്ല.</translation>
-<translation id="501473567976723023">ജനുവരി</translation>
-<translation id="5041394372352067729">ബ്രെയ്‌ലി ഡിസ്‌പ്ലേ പേജിന് മുകളിലേക്ക് നീക്കുക</translation>
-<translation id="5042770794184672516">സംഭാഷണ ശബ്ദം വർദ്ധിപ്പിക്കുക</translation>
-<translation id="5050015258024679800">മുൻ നില 4 ശീർഷകം</translation>
-<translation id="5054047268577924192">മുൻ ലിസ്റ്റ് ഇനം</translation>
-<translation id="5078661581131202757">ഫയൽ തിരഞ്ഞെടുക്കൽ</translation>
-<translation id="5080758118274074384">ഇരട്ട ക്ലിക്കുചെയ്‌തു</translation>
-<translation id="5098541983634824365">ഗ്രിഡ് ഉപേക്ഷിക്കുന്നു.</translation>
-<translation id="5102981729317424850">ഉപകരണ ബാർ</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">മുൻ ഫോം ഫീൽഡ് ഒന്നുമില്ല.</translation>
-<translation id="5111640677200759579">നിര ശീർഷകം</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">മുൻ ലിങ്ക് ഒന്നുമില്ല.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, തിരഞ്ഞെടുത്തത് ഒഴിവാക്കി</translation>
-<translation id="5183440668879371625">മുമ്പത്തെ ബ്രെയ്‌ലി വരി</translation>
-<translation id="5184944171021383281">അടുത്ത ഫോം ഫീൽഡ് ഒന്നുമില്ല.</translation>
-<translation id="5189244881767082992">വരി</translation>
-<translation id="5203930734796605961">ഒരു കമാൻഡിനായി <ph name="KEY" /> ഇതിനകം നൽകിയിട്ടുണ്ട്.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> ലിസ്റ്റ്.</translation>
-<translation id="520883772648104506">അടുത്ത റേഡിയോ ബട്ടൺ ഒന്നുമില്ല.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">അവസാനം</translation>
-<translation id="5291783959063340370">ഒബ്‌ജക്‌റ്റ്</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, ടാബ്</translation>
-<translation id="5310788376443009632">നീക്കംചെയ്‌തു:</translation>
-<translation id="5320727453979144100">സ്‌റ്റിക്കി മോഡ് പ്രവർത്തനക്ഷമമാക്കി</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{കോമ}other{# കോമകൾ}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, വാചക ബോക്സ്</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, ലിങ്ക്</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">വായന തുടരുന്നതിനിടയിൽ പുറകിലേക്ക് പോകുക</translation>
-<translation id="5368000168321181111">ഇയർകോൺസ് ഓഫാണ്</translation>
-<translation id="5374320867641260420">അടുത്ത ബട്ടൺ ഒന്നുമില്ല.</translation>
-<translation id="5382299583965267720">അടുത്ത നില 1 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="5402367795255837559">ബ്രെയ്‌ലി</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{അർദ്ധവിരാമം}other{# അർദ്ധവിരാമങ്ങൾ}}</translation>
-<translation id="5411891038905756502">മുൻ ജംപ് പോയിന്റ് ഒന്നുമില്ല.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{ആരോഹണ ചിഹ്നം}other{# ആരോഹണ ചിഹ്നങ്ങൾ}}</translation>
-<translation id="5455441614648621694">കോംപ്ലിമെന്ററി</translation>
-<translation id="5485036206801896268">മുൻ ഗ്രാഫിക് ഒന്നുമില്ല.</translation>
-<translation id="5486947920110100234">അടുത്ത ജംപ് പോയിന്റ് ഒന്നുമില്ല.</translation>
-<translation id="549602578321198708">പദം</translation>
-<translation id="5500932716852106146">എഡിറ്റുചെയ്യാൻ കഴിയുന്ന മുൻ വാചക ഫീൽഡ് ഒന്നുമില്ല.</translation>
-<translation id="5502713021410870035">സെപ്റ്റംബർ</translation>
-<translation id="5507663321906818013">ബെഞ്ച്മാർക്ക് ഡീബഗ് ചെയ്യുക</translation>
-<translation id="5518443085409638729">വാചകം എഡിറ്റുചെയ്യുമ്പോൾ കഴ്‌സർ പ്രതീകങ്ങൾക്കിടയിൽ വയ്‌ക്കുക (Mac OS X എന്നതുപോലെ).</translation>
-<translation id="552195134157544755">റേഡിയോ ബട്ടൺ</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">മുൻ നില 5 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="556042886152191864">ബട്ടണ്‍</translation>
-<translation id="5561345396546889625">അടുത്ത ലിസ്റ്റ്</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">ബാക്ക്‌സ്പെയ്‌സ്</translation>
-<translation id="5585044216466955529">വാചകം എഡിറ്റുചെയ്യുക, ഇമെയിൽ എൻട്രി</translation>
-<translation id="5597170376237141345">അടുത്ത ചെക്ക്ബോക്സ്</translation>
-<translation id="5597933780944041114">അടുത്ത ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, റേഡിയോ ബട്ടൺ തിരഞ്ഞെടുത്തത് മാറ്റി</translation>
-<translation id="5601172225407283979">സ്ഥിര പ്രവർത്തനം നിർവഹിക്കുക</translation>
-<translation id="5608798115546226984">യാന്ത്രികപൂർത്തീകരണം ഇൻലൈൻ</translation>
-<translation id="561939826962581046">സമയം</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">ലോഗ്</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">മുൻ പട്ടിക ഒന്നുമില്ല.</translation>
-<translation id="5655682562155942719">കമാൻഡുകൾ ഒഴിവാക്കുക</translation>
-<translation id="56637627897541303">വാചക ഏരിയ</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">ലാൻഡ്‌മാർക്ക്</translation>
-<translation id="5683155931978483559">മുൻ ചെക്ക്‌ബോക്സ്</translation>
-<translation id="5684277895745049190">ലിസ്റ്റ്</translation>
-<translation id="5700650669149824506">മുൻ നില 4 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="5709192780268610569">ദൈർഘ്യമേറിയ വിവരണങ്ങളൊന്നുമില്ല</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">അടുത്ത പട്ടിക നിര</translation>
-<translation id="571866080859340309">പര്യവേക്ഷണ ഗ്രൂപ്പുകൾ</translation>
-<translation id="5728409797179002635">പട്ടികയൊന്നും കണ്ടെത്തിയില്ല.</translation>
-<translation id="5748623122140342504">മുൻ നില 5 ശീർഷകം</translation>
-<translation id="5750633686117194034">മോഡിഫയർ ഒന്നും അമർത്തിയില്ല; ഒന്നോ അതിലധികമോ മോഡിഫയറുകൾ അമർത്തിപ്പിടിക്കുക; പൂർത്തിയാക്കിക്കഴിഞ്ഞാൽ വിരലുകൾ എടുക്കുക, തുടർന്ന് നിങ്ങൾ സജ്ജമാക്കിയ കീകൾ കേൾക്കും. പുറത്തുകടക്കാൻ ടാബ് അമർത്തുക.</translation>
-<translation id="5788275253279308023">ആൾമാറാട്ട വിൻഡോ <ph name="TITLE" /> ടാബ്</translation>
-<translation id="5806206155699461681">നിർദ്ദിഷ്‌ട സൈറ്റുകൾ മെച്ചപ്പെടുത്തുക (Google തിരയൽ പോലെയുള്ളവ).</translation>
-<translation id="5819072574982403430">ട്രീ ഇനം</translation>
-<translation id="5826479389509458994">വരി <ph name="ROW" /> നിര <ph name="COL" /></translation>
-<translation id="5850707923114094062">പിന്നിലേക്ക് പാൻ ചെയ്യുക</translation>
-<translation id="5851548754964597211">ടാബ് ലിസ്റ്റ്</translation>
-<translation id="5859752971144398932">പേജിൽ കണ്ടെത്തുക എന്നതിൽ നിന്ന് പുറത്തുകടന്നു.</translation>
-<translation id="5866042630553435010">ഭാഗികമായി ചെക്കുചെയ്‌തു</translation>
-<translation id="5869546221129391014">ഗ്രിഡ്</translation>
-<translation id="5876817486144482042">സംഭാഷണ ശബ്ദം കുറയ്‌ക്കുക</translation>
-<translation id="5887397643266327462">ബ്രെയ്‌ലി അടിക്കുറിപ്പുകൾ പ്രവർത്തനക്ഷമമാക്കി.</translation>
-<translation id="5891934789323004067">പട്ടിക</translation>
-<translation id="5919442531159595654">പകര്‍ത്തുക.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{സമചിഹ്നം}other{# സമചിഹ്നങ്ങൾ}}</translation>
-<translation id="5939518447894949180">വീണ്ടും സജ്ജീകരിക്കുക</translation>
-<translation id="5948123859135882163">ഘടനാപരമായതിനും സെമാന്റിക്കിനുമിടയിൽ മാത്ത് എക്‌സ്‌പ്രഷനുകളുടെ വ്യാഖ്യാനം ടോഗിൾ ചെയ്യുക</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">ഡയലോഗ്</translation>
-<translation id="5963413905009737549">വിഭാഗം</translation>
-<translation id="5968607524793740041">സന്ദർഭ മെനു കാണിക്കുക</translation>
-<translation id="5983179082906765664">നാവിഗേഷൻ ഗ്രാനുലാരിറ്റി വർദ്ധിപ്പിക്കുക</translation>
-<translation id="5999630716831179808">വോയ്‌സുകൾ</translation>
-<translation id="6000417740266304866">ചുവടെയുള്ള ലിസ്റ്റിൽ നിന്ന് ഒരു ഓപ്‌ഷൻ തിരഞ്ഞെടുത്തുകൊണ്ട് നിലവിലുള്ള 8 ഡോട്ട് ബ്രെയ്‌ലി പട്ടിക മാറ്റുക.</translation>
-<translation id="6006050241733874051">ഫോം</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{ബാക്ക്‌സ്ലാഷ്}other{# ബാക്ക്‌സ്ലാഷുകൾ}}</translation>
-<translation id="6037602951055904232">മുന്നിലേക്ക് പാൻ ചെയ്യുക</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">സെല്ലിന്റെ അവസാനം.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">സ്പെയ്സ്</translation>
-<translation id="6142308968191113180">ശീർഷകം 4</translation>
-<translation id="6169420925157477918">ദൈർഘ്യമേറിയ വിവരണമുള്ള ചിത്രം</translation>
-<translation id="6172087735260766220">പകർപ്പ് പരിരക്ഷിത PDF-ൽ നിന്ന് ആക്‌സസ്സ് ചെയ്യാനാകുന്ന ടെക്‌സ്റ്റ് ആക്‌സസ്സ് ചെയ്യാനാകുന്നില്ല.</translation>
-<translation id="6186305613600865047">പേജിന്റെ താഴേയ്‌ക്ക് പോകുക</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">താഴേക്കുള്ള കീ</translation>
-<translation id="6236061028292614533">അടുത്ത ശീർഷകം</translation>
-<translation id="6254901459154107917">എഡിറ്റ് ചെയ്യാൻ കഴിയുന്ന അടുത്ത വാചക ഏരിയ</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> എന്നതിൽനിന്ന് പുറത്തുകടന്നു.</translation>
-<translation id="6281876499889881039">അടുത്ത സമാന ഘടകം.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">അടുത്ത കോമ്പോ ബോക്‌സ് ഒന്നുമില</translation>
-<translation id="6307969636681130414">അമർത്തിയത്</translation>
-<translation id="6324551002951139333">വ്യാകരണത്തെറ്റ് കണ്ടെത്തി</translation>
-<translation id="6348657800373377022">കോമ്പോ ബോക്സ്</translation>
-<translation id="6355910664415701303">മുൻ ലിസ്റ്റ് ഇനം ഒന്നുമില്ല.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">മുൻ ശീർഷകം</translation>
-<translation id="6387719785439924554">അരികിൽ</translation>
-<translation id="6411426777058107714">മുൻ റേഡിയോ ബട്ടൺ ഒന്നുമില്ല.</translation>
-<translation id="6414968628640960377">വ്യത്യസ്‌തമായ മുൻ ഘടകം.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{കോളൻ}other{# കോളനുകൾ}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, മെനു</translation>
-<translation id="6444046323172968959">അലേർട്ട് ഡയലോഗ്</translation>
-<translation id="6459511626086141404">ഫ്ലാറ്റ് കീമാപ്പ്</translation>
-<translation id="6468049171101508116">അടുത്ത ബട്ടൺ</translation>
-<translation id="6491972999578897419">ചുവടെയുള്ള ലിസ്റ്റിൽ നിന്നും ഒരു ഓപ്‌ഷൻ തിരഞ്ഞെടുക്കുന്നതിലൂടെ നിലവിലെ വോയ്‌സ് മാറ്റുക.</translation>
-<translation id="6508059270146105198">ബ്രെയ്‌ലി ഡിസ്‌പ്ലേ പേജിന് ചുവടേക്ക് നീക്കുക</translation>
-<translation id="6536864053412760904">മാത്ത് ML ടോക്കൺ</translation>
-<translation id="6550720799683018100">ചുവടെയുള്ള ലിസ്റ്റിൽ നിന്നും ഒരു ഓപ്‌ഷൻ തിരഞ്ഞെടുക്കുന്നതിലൂടെ നിലവിലെ കീമാപ്പ് മാറ്റുക.</translation>
-<translation id="6561818612645211875">നിലവിലെ വരിയുടെ തുടക്കത്തിലേക്ക് പോകുക</translation>
-<translation id="6587021927234520429">അടുത്ത നില 4 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="6601344353291556895">സംഭാഷണ വിവരണങ്ങൾ പ്രവർത്തനക്ഷമമാക്കുക.</translation>
-<translation id="6615602925644411249">പേജിൽ കണ്ടെത്തുക.</translation>
-<translation id="6633350132811819843">അടുത്ത പട്ടിക ഒന്നുമില്ല.</translation>
-<translation id="6637586476836377253">ലോഗ്</translation>
-<translation id="6657128831881431364">വർദ്ധനവ് ബാർ</translation>
-<translation id="6659594942844771486">ടാബ്</translation>
-<translation id="667999046851023355">പ്രമാണം</translation>
-<translation id="6697092096875747123">മുൻ കോംബോ ബോക്സ്</translation>
-<translation id="6714813999819678458">മുൻ നില 2 ശീർഷകം</translation>
-<translation id="6716505898850596801">മോഡിഫയര്‍ കീകള്‍</translation>
-<translation id="671916444866103745">അടുത്ത ARIA ലാൻഡ്‌മാർക്ക് ഒന്നുമില്ല.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, കോംബോ ബോക്സ്</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> ഇനങ്ങൾ ഉപയോഗിച്ച്</translation>
-<translation id="6736510033526053669">ടാബ് സൃഷ്‌ടിച്ചു</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">ലേഖനം</translation>
-<translation id="6787839852456839824">കീബോർഡ് കുറുക്കുവഴികൾ</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">അടിക്കുറിപ്പ്</translation>
-<translation id="6871161210040114857">കേസ് സെൻസിറ്റീവല്ല.</translation>
-<translation id="6877435256196695200">അടുത്ത ഗ്രാഫിക് ഒന്നുമില്ല.</translation>
-<translation id="6897341342232909480">ഇടതുവശത്തേക്ക് നീക്കുക</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">ഇല്ലാതാക്കി</translation>
-<translation id="6911965441508464308">മുകളിൽ സെല്ലുകളൊന്നുമില്ല.</translation>
-<translation id="6919104639734799681">പട്ടിക ലിസ്റ്റ് കാണിക്കുക</translation>
-<translation id="6964088412282673743">മുമ്പത്തെ നിയന്ത്രണങ്ങളൊന്നുമില്ല.</translation>
-<translation id="6996566555547746822">അടുത്ത കോംബോ ബോക്സ്</translation>
-<translation id="7005146664810010831">URL ഒന്നും കണ്ടെത്തിയില്ല</translation>
-<translation id="7010712454773919705">ChromeVox മോഡിഫയർ കീ</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">മുൻ ലിസ്റ്റ്</translation>
-<translation id="7041173719775863268">തിരഞ്ഞെടുക്കൽ അവസാനിപ്പിക്കുക</translation>
-<translation id="7095834689119144465">വാചക സംഖ്യ മാത്രം എഡിറ്റുചെയ്യുക</translation>
-<translation id="7096001299300236431">മുമ്പത്തെ മീഡിയ</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">പദ എക്കൊ</translation>
-<translation id="713824876195128146">അടുത്ത ബ്ലോക്ക് ഉദ്ധരണി</translation>
-<translation id="7161771961008409533">പോപ്പ്-അപ്പ് ബട്ടൺ</translation>
-<translation id="7167657087543110">പ്രതീക എക്കൊ</translation>
-<translation id="7170733337935166589">വായന തുടരുന്നതിനിടയിൽ മുന്നോട്ട് പോകുക</translation>
-<translation id="7181697990050180700">ചുവടെയുള്ള അനുയോജ്യമായ ഫീൽഡുകളിൽ കീബോർഡ് കുറുക്കുവഴികൾ ടൈപ്പുചെയ്യുന്നതിലൂടെ ഇടയ്‌ക്കിടെ ഉപയോഗിക്കുന്ന കമാൻഡുകൾക്കായി അവ ഇഷ്‌ടാനുസൃതമാക്കുക.</translation>
-<translation id="7203150201908454328">വിപുലീകരിച്ചത്</translation>
-<translation id="7210211103303402262">മിനിറ്റ്</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">വരി</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">ശീർഷകം</translation>
-<translation id="7241683698754534149">ദൈർഘ്യമേറിയ വിവരണം പുതിയ ടാബിൽ തുറക്കുക</translation>
-<translation id="7248671827512403053">അപ്ലിക്കേഷൻ</translation>
-<translation id="725969808843520477">അടുത്ത റേഡിയോ ബട്ടൺ</translation>
-<translation id="7269119382257320590">ചിഹ്നനങ്ങളൊന്നുമില്ല</translation>
-<translation id="7273174640290488576">ശൂന്യം</translation>
-<translation id="7285387653379749618">പട്ടികകൾ</translation>
-<translation id="7289186959554153431">ശീർഷകം 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">ബ്രെയ്‌ലി അടിക്കുറിപ്പുകൾ പ്രവർത്തനരഹിതമാക്കി.</translation>
-<translation id="7318872822751139669">ഫോക്കസ് മാറ്റുന്നതിന് മൗസ് ഉപയോഗിക്കുക.</translation>
-<translation id="7322388933135261569">ഫെബ്രുവരി</translation>
-<translation id="7332592614823088566">വരി <ph name="ROWINDEX" /> / <ph name="ROWTOTAL" />, നിര <ph name="COLINDEX" /> / <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">പോപ്പ്അപ്പ് ഉണ്ട്</translation>
-<translation id="7356165926712028380">8 ഡോട്ട് ബ്രെയ്‌ലിയിലേക്ക് മാറുക</translation>
-<translation id="7362871137496673139">മുൻ നില 2 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{സമുച്ചയം}other{# സമുച്ചയങ്ങൾ}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">പട്ടിക ഉപേക്ഷിക്കുന്നു.</translation>
-<translation id="739763518212184081">മുമ്പത്തെ വരി</translation>
-<translation id="7400575256015741911">അക്ഷരത്തെറ്റ് കണ്ടെത്തി</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">മടങ്ങുക</translation>
-<translation id="7434509671034404296">വികാസകന്‍</translation>
-<translation id="7439060726180460871">ഡയറക്‌ടറി</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">ടാബ്</translation>
-<translation id="7492049978501397201">ഡയലോഗ് നൽകി</translation>
-<translation id="7532613204005497612">ജൂൺ</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, സ്ലൈഡർ</translation>
-<translation id="7586163296341959563">ഒട്ടിക്കുക.</translation>
-<translation id="7596919493010894443">തിരഞ്ഞെടുത്തവ മായ്‌ച്ചു</translation>
-<translation id="7604026522577407655">നിലവിലെ നിരയുടെ തുടക്കത്തിലേക്ക് പോകുക</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">നിലവിലുള്ള പേജിന്റെ URL അറിയിക്കുക</translation>
-<translation id="7609363189280667021">ബ്രെയ്‌ലി അടിക്കുറിപ്പുകൾ ടോഗിൾ ചെയ്യുക</translation>
-<translation id="762020119231868829">നിലവിൽ പ്ലേ ചെയ്യുന്ന എല്ലാ മീഡിയ വിജറ്റുകളും താൽക്കാലികമായി നിർത്തുന്നു</translation>
-<translation id="7625690649919402823">അടുത്ത പട്ടിക</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), ഗ്രേഡ് <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">മുൻ നില 3 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, വാചക ബോക്സ്</translation>
-<translation id="7663318257180412551">ശീർഷകം 2</translation>
-<translation id="7674576868851035240">അടുത്ത ലിങ്ക്</translation>
-<translation id="7674768236845044097">അടയാളപ്പെടുത്തുക</translation>
-<translation id="7684431668231950609">വാചകം എഡിറ്റുചെയ്യുക, URL എൻട്രി</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">മുൻ റേഡിയോ ബട്ടൺ</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, പാസ്‌വേഡ് വാചക ബോക്സ്</translation>
-<translation id="7805247615045262757">സ്ഥിര നാവിഗേഷൻ</translation>
-<translation id="7805768142964895445">നില</translation>
-<translation id="7810781339813764006">അടുത്ത ഗ്രൂപ്പ്</translation>
-<translation id="7819187121850078213">വിൻഡോ <ph name="TITLE" /> ടാബ്</translation>
-<translation id="7828956995407538686">ഒക്‌ടോബർ</translation>
-<translation id="7839679365527550018">മുമ്പത്തെ വാക്ക്</translation>
-<translation id="7851816175263618915">ചില വിരാമചിഹ്നങ്ങൾ</translation>
-<translation id="7870596830398826354">മാത്ത് ML ട്രീ</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox ക്ലാസിക് ടോഗിൾ ചെയ്യുക.</translation>
-<translation id="7895896691902835279">അജ്ഞാത ലിങ്ക്</translation>
-<translation id="7927711904086083099">തിരഞ്ഞെടുക്കാത്തത്</translation>
-<translation id="7935627501098484003">സമയ നിയന്ത്രണം</translation>
-<translation id="7939428177581522200">തിരഞ്ഞെടുത്തതിലേക്ക് ചേർത്തു</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{അറ്റ്}other{# അറ്റ് ചിഹ്നങ്ങൾ}}</translation>
-<translation id="7965147473449754028">മെനു അടച്ചു</translation>
-<translation id="7974390230414479278">മെനു ഇനം</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ആശ്ചര്യചിഹ്നം}other{# ആശ്ചര്യചിഹ്നങ്ങൾ}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{ഉദ്ധരണി}other{# ഉദ്ധരണികൾ}}</translation>
-<translation id="8033827949643255796">തിരഞ്ഞെടുത്തു</translation>
-<translation id="8035962149453661158">പരമാവധി:<ph name="X" /></translation>
-<translation id="8042761080832772327">വാചകം എഡിറ്റുചെയ്യുക, തിരയൽ എൻട്രി</translation>
-<translation id="8049189770492311300">ടൈമർ</translation>
-<translation id="8065607967589909823">തിരഞ്ഞെടുത്തത് ഇതാണ്</translation>
-<translation id="8066678206530322333">ബാനര്‍‌</translation>
-<translation id="8110647606445335195">ARIA ലാൻഡ്‌മാർക്കുകൾ ഒന്നുമില്ല.</translation>
-<translation id="8153880621934657047">പട്ടികയ്‌ക്കുള്ളിലല്ല.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{അടിവര}other{# അടിവരകൾ}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">മുറിക്കുക.</translation>
-<translation id="8199231515320852133">നിലവിലുള്ള സെല്ലിന്റെ ശീർഷകങ്ങൾ അറിയിക്കുക</translation>
-<translation id="820417203470636242">ശൂന്യ സെൽ.</translation>
-<translation id="8215202828671303819">ഒന്നിലധികം തിരഞ്ഞെടുക്കൽ</translation>
-<translation id="8276439074553447000">ഫോക്കസ് ചെയ്യാനാകുന്ന മുമ്പത്തെ ഇനത്തിലേക്ക് പോകുക</translation>
-<translation id="8278417001922463147">മുമ്പത്തെ ലേഖനമൊന്നുമില്ല.</translation>
-<translation id="8283603667300770666">അടുത്ത ഫോം ഫീൽഡ്</translation>
-<translation id="831207808878314375">നിർവചനം</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">മണിക്കൂര്‍</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{പൗണ്ട്}other{# പൗണ്ട് അടയാളങ്ങൾ}}</translation>
-<translation id="8374154622594089836">മാസം</translation>
-<translation id="8378855320830505539">പ്രദേശം</translation>
-<translation id="8382679411218029383">യാന്ത്രികപൂർത്തീകരണം ഇൻലൈനും ലിസ്റ്റും</translation>
-<translation id="8428603554127842284">ലെവൽ <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">അടുത്ത നില 3 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">മുൻ ചെക്ക്ബോക്‌സ് ഒന്നുമില്ല.</translation>
-<translation id="8455868257606149352">പരമാവധി <ph name="X" /></translation>
-<translation id="84575901236241018">ഇതിന് ആക്‌സസ്സ് കീ <ph name="KEY" /> ഉണ്ട്</translation>
-<translation id="8503360654911991865">നാവിഗേഷൻ ഗ്രാനുലാരിറ്റി കുറയ്ക്കുക</translation>
-<translation id="8520472399088452386">സ്‌പിൻ ബട്ടൺ</translation>
-<translation id="8538744478902126321">നിലവിലുള്ള സെല്ലിന്റെ വരി ശീർഷകത്തിൽ ഒരു ഊഹം നടത്തുക</translation>
-<translation id="8540054775867439484">മുകളിലേയ്‌ക്ക് റാപ്പുചെ‌യ്‌തു</translation>
-<translation id="8548973727659841685">പ്രതീകം</translation>
-<translation id="8561322612995434619">പോപ്പ് അപ്പ് ഉണ്ട്</translation>
-<translation id="8571096049907249734">ഒന്നിലധികം തിരഞ്ഞെടുക്കൽ</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">അടുത്ത ലിസ്റ്റ് ഇനം</translation>
-<translation id="860150890330522909"><ph name="NAME" /> ചെക്ക്ബോക്‌സ് ചെക്കുചെയ്‌തു</translation>
-<translation id="8606621670302093223">തീയതി നിയന്ത്രണം</translation>
-<translation id="8631359288236106450">തിരഞ്ഞെടുത്ത <ph name="COUNT" /> ഇനങ്ങൾ</translation>
-<translation id="8638532244051952400">നിലവിലെ സെൽ കോർഡിനേറ്റുകൾ അറിയിക്കുക</translation>
-<translation id="8650576015643545550">മുൻ ലിസ്റ്റ് ഒന്നുമില്ല.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">ലിങ്കുകളുടെ ലിസ്റ്റ് കാണിക്കുക</translation>
-<translation id="8664519043722036194">സെക്കൻഡ്</translation>
-<translation id="867187640362843212">ശീർഷകം 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{പൈപ്പ്}other{# ലംബമായ പൈപ്പുകൾ}}</translation>
-<translation id="8735450637152821465">തിരഞ്ഞെടുക്കൽ ആരംഭിക്കുക</translation>
-<translation id="8743786158317878347">പട്ടികകൾ പോലുള്ള ഘടനാപരമായ ഉള്ളടക്കം നൽകുക</translation>
-<translation id="8747966237988593539">ക്രമപ്പെടുത്തിയ ലിസ്റ്റ്</translation>
-<translation id="8759334257841767240">അടുത്ത ലിങ്ക് ഒന്നുമില്ല.</translation>
-<translation id="8767968232364267681">അടുത്ത നില 4 ശീർഷകം</translation>
-<translation id="8770473310765924354">പട്ടികകൾ പോലുള്ള ഘടനാപരമായ ഉള്ളടക്കത്തിൽ നിന്ന് പുറത്തുകടക്കുക</translation>
-<translation id="8791025954632646584">സെമാന്റിക്കുകൾ ഓണാണ്</translation>
-<translation id="8796411681063377102">അടുത്ത നില 3 ശീർഷകം</translation>
-<translation id="8808582214901541005">മാര്‍ച്ച്</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">കമാൻഡുകൾ അവലോകനം ചെയ്യാൻ മുകളിലേക്കോ താഴേക്കോ അമർത്തുക, സജീവമാക്കുന്നതിന് എന്റർ അമർത്തുക</translation>
-<translation id="8864099967139188018">അടുത്ത നില 6 ശീർഷകം ഒന്നുമില്ല.</translation>
-<translation id="8882002077197914455">വരി ശീർഷകം</translation>
-<translation id="8896347895970027998">ChromeVox സജീവ അല്ലെങ്കിൽ നിഷ്‌ക്രിയ അവസ്ഥകളിലേക്ക് ടോഗിൾ ചെയ്യുക.</translation>
-<translation id="8898516272131543774">സൈക്കിൾ വിരാമചിഹ്ന എക്കൊ</translation>
-<translation id="8900148057318340779">പ്രിഫിക്‌സ് കീ</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">ശുന്യമായ ശീർഷകങ്ങൾ</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">മോഡിഫയർ കീകൾ</translation>
-<translation id="8943175951035496220">വലതുഭാഗത്ത് കോളമൊന്നുമില്ല.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">പട്ടികകൾ ഒന്നുമില്ല.</translation>
-<translation id="9040132695316389094">ശീർഷകം 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">തിരയൽ വിജറ്റ് ടോഗിൾ ചെയ്യുക</translation>
-<translation id="9065283790526219006">+പോപ്പ്അപ്പ്</translation>
-<translation id="9077213568694924680">തിരഞ്ഞെടുത്തതിൽ നിന്നും നീക്കംചെയ്‌തു</translation>
-<translation id="9082874451376019682">മുൻ സ്ലൈഡർ ഒന്നുമില്ല.</translation>
-<translation id="9089864840575085222">സൈക്കിൾ ടൈപ്പുചെയ്യൽ എക്കൊ</translation>
-<translation id="9107530006868467849">മുമ്പത്തെ മീഡിയ വിജറ്റൊന്നുമില്ല.</translation>
-<translation id="9108370397979208512">മാത്ത്</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{ശതമാനം}other{# ശതമാന ചിഹ്നങ്ങൾ}}</translation>
-<translation id="9115913704608474258">നവംബർ</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">നിലവിലുള്ള അവസ്ഥയുടെ ഒരു സംക്ഷിപ്‌ത വിവരണം അറിയിക്കുന്നു</translation>
-<translation id="9153606228985488238"><ph name="PERCENT" /> ശതമാനം ആവൃത്തി</translation>
-<translation id="9160096769946561184">നിലവിലെ നിരയുടെ അവസാനം പോകുക</translation>
-<translation id="9173115498289768110"><ph name="PERCENT" /> ശതമാനം ശബ്‌ദം</translation>
-<translation id="9178973770513562274">ബ്രൗസുചെയ്യുന്നതിന് മുകളിലേക്കും താഴേക്കുമുള്ള കീകൾ ഉപയോഗിക്കുക അല്ലെങ്കിൽ തിരയുന്നതിന് ടൈപ്പുചെയ്യുക.</translation>
-<translation id="9192904702577636854">മാർക്യൂ</translation>
-<translation id="9212322457209634662">അടുത്ത വിഭാഗങ്ങളൊന്നുമില്ല.</translation>
-<translation id="930275611743429116">തിരഞ്ഞെടുക്കൽ ആരംഭിക്കുകയോ അവസാനിപ്പിക്കുകയോ ചെയ്യുക.</translation>
-<translation id="948171205378458592">സംഭാഷണ റേറ്റ് കുറയ്ക്കുക</translation>
-<translation id="962913030769097253">അടുത്ത നില 1 ശീർഷകം</translation>
-<translation id="973955474346881951">സ്റ്റിക്കി മോഡ് പ്രവർത്തനക്ഷമമാക്കുക/പ്രവർത്തനരഹിതമാക്കുക</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_mr.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_mr.xtb
deleted file mode 100644
index 31dd3c99be8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_mr.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="mr">
-<translation id="1012173283529841972">सूची आयटम</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">विस्तृत.</translation>
-<translation id="1025074108959230262">रोचक मोड अक्षम</translation>
-<translation id="1031961866430398710">नंतर</translation>
-<translation id="1044777062731150180">कोणतेही शीर्षलेख नाहीत</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">अवैध इनपुट</translation>
-<translation id="1082209053475788238">मागील स्‍तर 6 मथळा नाही.</translation>
-<translation id="1088219014394087294">कोणतेही मथळे नाहीत.</translation>
-<translation id="1106741348836243114">ध्वनी अभिप्राय (इअरकॉन) चालू किंवा बंद करा.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="NUM" /> आयटमसह <ph name="TAG" /> संकलन</translation>
-<translation id="1155043339247954670">पुढील सूची आयटम नाही.</translation>
-<translation id="1157782847298808853">कीबोर्ड मदत</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, कॉम्बो बॉक्स</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, सबमेनूसह मेनू आयटम</translation>
-<translation id="1177863135347784049">सानुकूल</translation>
-<translation id="1188858454923323853">पूरक</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome ला आवाज देत आहे</translation>
-<translation id="1229276918471378188">मागील जंप</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">पुढील स्तर 6 शीर्षक</translation>
-<translation id="1275718070701477396">निवडलेले</translation>
-<translation id="1319608975892113573">मागील ब्लॉककोट नाही.</translation>
-<translation id="1321576897702511272">ChromeVox मदत लपवा</translation>
-<translation id="1331702245475014624"><ph name="TOTAL" /> पैकी <ph name="INDEX" /></translation>
-<translation id="1334095593597963605">वर्ण आणि शब्द प्रतिध्वनी</translation>
-<translation id="1339428534620983148">मागील सारणी स्तंभ</translation>
-<translation id="1342835525016946179">लेख</translation>
-<translation id="1346748346194534595">उजवे</translation>
-<translation id="136718599399906424">पुढील सारणी पंक्ती</translation>
-<translation id="1383876407941801731">शोधा</translation>
-<translation id="1385214448885562192">स्‍वीकार करण्‍यासाठी enter किंवा रद्द करण्‍यासाठी escape, पुढीलसाठी down आणि मागीलसाठी up दाबा.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, संकेतशब्द मजकूर बॉक्स</translation>
-<translation id="1467432559032391204">डावे</translation>
-<translation id="1474557363159888097">मागील अँकर नाही.</translation>
-<translation id="1502086903961450562">मागील ग्राफिक्स</translation>
-<translation id="1506187449813838456">पीच वाढवा</translation>
-<translation id="151784044608172266">पुढील वाक्य</translation>
-<translation id="1524531499102321782">ब्रेल पुढील रेखा</translation>
-<translation id="1546370775711804143">स्‍क्रोल बार</translation>
-<translation id="1559739829547075274">मागे नेव्हीगेट करा</translation>
-<translation id="1571643229714746283">ChromeVox सज्ज</translation>
-<translation id="158493514907962286">डिसेंबर</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6 बिंदू ब्रेलवर स्विच करा</translation>
-<translation id="1611168825862729585">स्‍तंभ शीर्षलेख:</translation>
-<translation id="1613476421962910979">इअरकॉन चालू आहेत</translation>
-<translation id="1618597272655350600">वर्तमान स्‍थितीबद्दल पूर्ण वर्णन घोषित करते</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{पेक्षा मोठे}one{# पेक्षा मोठे चिन्हे}other{# पेक्षा मोठे चिन्हे}}</translation>
-<translation id="1653266918374749391">मागील स्तर 3 शीर्षक</translation>
-<translation id="1659072772017912254">न चेक केलेले</translation>
-<translation id="1669290819662866522">आठवडा</translation>
-<translation id="1674262202423278359">ChromeVox नेव्हिगेशन</translation>
-<translation id="16777221443363124">मेनू बार</translation>
-<translation id="1692077714702418899">संरचनात्मक रेखा</translation>
-<translation id="1700517974991662022">भेट दिलेला</translation>
-<translation id="1722567105086139392">दुवा</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">पुढील ग्राफिक</translation>
-<translation id="1781173782405573156">की द्वारे पास करा</translation>
-<translation id="1787176709638001873">संकेतशब्द संपादन मजकूर</translation>
-<translation id="1810107444790159527">सूची बॉक्स</translation>
-<translation id="1828385960365606039">मे</translation>
-<translation id="1834891354138622109">स्तंभ</translation>
-<translation id="1865601187525349519">मजकूराची समाप्ती</translation>
-<translation id="1876229593313240038">दस्तऐवज</translation>
-<translation id="188130072164734898">वर्तमान वेळ आणि तारीख बोला.</translation>
-<translation id="1902396333223336119">सेल</translation>
-<translation id="1905379170753160525">शीर्षक सूची दर्शवा</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">वर्ष नियंत्रणाचा आठवडा</translation>
-<translation id="1964135212174907577">पुढील ऑब्जेक्ट</translation>
-<translation id="1969092762068865084">जुलै</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">पंक्ती शीर्षलेख:</translation>
-<translation id="2002895034995108595">वर्तमान मुख्य नकाशा रीसेट करा</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{डावा चौकोनी कंस}one{# डावे चौकोनी कंस}other{# डावे चौकोनी कंस}}</translation>
-<translation id="2045490512405922022">चेक न केलेले</translation>
-<translation id="20601713649439366">मागील कोणतीही गणित पदावली नाही.</translation>
-<translation id="207477615537953741">सिमेंटिक बंद</translation>
-<translation id="2086961585857038472">पुढील शब्द</translation>
-<translation id="2089387485033699258">en</translation>
-<translation id="2091933974477985526">मागील संपादन करता येणारे मजकूर क्षेत्र</translation>
-<translation id="2100350898815792233">सर्व विरामचिन्‍ह</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">प्रवेश की:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">खालील सूचीमधून एखादा पर्याय निवडून वर्तमान 6 बिंदू ब्रेल सारणी बदला.</translation>
-<translation id="2169714232367507776">वर्तमान आयटमवर क्लिक करा</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{बंद कंस}one{# बंद कंस}other{# बंद कंस}}</translation>
-<translation id="2199994615414171367">मागील गणित</translation>
-<translation id="2223693656926968778">वर्तमान आयटमवर कार्यवाही करा</translation>
-<translation id="225732394367814946">बोलण्‍याचा दर वाढवा</translation>
-<translation id="2267945578749931355">पुढील वर्ण</translation>
-<translation id="2281234842553884450">मागील स्लायडर</translation>
-<translation id="2318372665160196757">मुख्य</translation>
-<translation id="2329324941084714723">टॅब पॅनेल</translation>
-<translation id="2344193891939537199">तारीख वेळ नियंत्रण</translation>
-<translation id="2359897517538099099">सारणी मोडमध्ये नाही.</translation>
-<translation id="241124561063364910">च्या मागून येणारे</translation>
-<translation id="2417569100218200841">सामग्री माहिती</translation>
-<translation id="2422937916923936891">मेनू आयटम चेक बॉक्‍स</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> आता नवीन ChromeVox सुधारक की आहे.</translation>
-<translation id="2450814015951372393">चेक बॉक्‍स</translation>
-<translation id="2462626033734746142">रेडिओ बटण गट</translation>
-<translation id="2471138580042810658">मथळा 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{चौफुली}one{# चौफुली}other{# चौफुली}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> रीसेट केली गेली.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">गट</translation>
-<translation id="2582407057977008361">बाजूचा</translation>
-<translation id="2589102159832527089">या पृष्ठामध्ये &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; PDF फायलीमधून स्वयंचलितपणे काढलेला मजकूर आहे. &lt;a href="<ph name="URL" />"&gt;मूळ साठी येथे क्लिक करा.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">यासह {COUNT,plural, =1{# आयटम}one{# आयटम}other{# आयटम}}</translation>
-<translation id="2614981083756825552">Math ML लेआउट</translation>
-<translation id="2626530649491650971">क्लिक करण्‍यायोग्य</translation>
-<translation id="2628764385451019380">मागील कॉम्‍बो बॉक्‍स नाही.</translation>
-<translation id="2637227747952042642">गणित</translation>
-<translation id="2639750663247012216">ChromeVox सुधारक</translation>
-<translation id="2644542693584024604">चुकीचे शब्दलेखन केले</translation>
-<translation id="2667291555398229137">एका रूटिंग की अंतर्गत आयटम क्लिक करा</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{उघडा कंस}one{# उघडे कंस}other{# उघडे कंस}}</translation>
-<translation id="2705875883745373140">न दाबलेले</translation>
-<translation id="2706462751667573066">Up</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ऑडिओ</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">चेक केलेले</translation>
-<translation id="27527859628328957">पुढील फोकस करण्यायोग्य आयटमवर जंप करा</translation>
-<translation id="2770781857296573485">गट अन्वेषण प्रविष्ट करा</translation>
-<translation id="2777845298774924149">निर्गमन केले</translation>
-<translation id="2800204403141299078">आणखी भिन्न घटक नाहीत.</translation>
-<translation id="2800780099804980316">मागील स्‍तर 1 मथळा नाही.</translation>
-<translation id="2811204574343810641">पंक्ती</translation>
-<translation id="2816654101880605877">पुढील स्‍लायडर नाही.</translation>
-<translation id="2841013758207633010">वेळ</translation>
-<translation id="2843837985843789981">मागील गट</translation>
-<translation id="2844995807198708617">संदर्भ मेनू</translation>
-<translation id="2849332794118375855">पुढील चेकबॉक्‍स नाही.</translation>
-<translation id="2864481629947106776">मागील दुवा</translation>
-<translation id="2873259058405069099">सारणीच्या सुरवातीस जा</translation>
-<translation id="2894654529758326923">माहिती</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{डावा महिरपी कंस}one{# डावे महिरपी कंस}other{# डावे महिरपी कंस}}</translation>
-<translation id="2911433807131383493">ChromeVox ट्यूटोरियल उघडा</translation>
-<translation id="2932083475399492303">संरचनात्मक किंवा लेआउट मधील रेखा प्रकार टॉगल करा</translation>
-<translation id="2964026537669811554">मथळा गट</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{1 टॅब}one{# टॅब}other{# टॅब}}</translation>
-<translation id="2972078295414139404">मागील भेट दिलेला दुवा .</translation>
-<translation id="2972205263822847197">साधन टीप</translation>
-<translation id="2998131015536248178">मागील वर्ण</translation>
-<translation id="2999559350546931576">पीच कमी करा</translation>
-<translation id="2999945368667127852">पुढील माध्यम विजेट नाही.</translation>
-<translation id="3012414509011670858">मागील निवड नाही.</translation>
-<translation id="3030432017085518523">मेनू आयटम रेडिओ बटण</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{परोक्षसंबोधन}one{# परोक्षसंबोधने}other{# परोक्षसंबोधने}}</translation>
-<translation id="3046838483509668188">ChromeVox पर्याय</translation>
-<translation id="3047143736589213134">प्रायोगिक मुख्य नकाशा</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> मेनू उघडला</translation>
-<translation id="3078345202707391975">पुढील स्तर 2 शीर्षक</translation>
-<translation id="3078740164268491126">सारणी</translation>
-<translation id="3082557070674409251">क्‍लिक केले</translation>
-<translation id="3084806535845658316">कोणताही टायपिंग प्रतिध्वनी नाही</translation>
-<translation id="3086746722712840547">टीप</translation>
-<translation id="308895241372589742">पुढे कोणतीही गणित पदावली नाही.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">पुढील महत्त्वाची खूण</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">संकुचित केलेले</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">महत्त्वाच्या खूणांची सूची दर्शवा</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">पुढील रेखा</translation>
-<translation id="3155083529632865074">मागील बटण नाही.</translation>
-<translation id="3163593631834463955">रिक्त स्‍तंभ शीर्षलेख</translation>
-<translation id="316542773973815724">नेव्हिगेशन</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{जागा}one{# जागा}other{# जागा}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> प्रविष्ट केला</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, टॅब</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">भेट दिलेला दुवा</translation>
-<translation id="323731244387692321">ChromeVox कीबोर्ड मदत उघडा</translation>
-<translation id="3241052487511142956">मागील भेट दिलेला दुवा</translation>
-<translation id="3286390186030710347">स्‍लायडर</translation>
-<translation id="3299925995433437805">पुढील भेट दिलेला दुवा नाही.</translation>
-<translation id="3303384412438961941">याचे नाव जाणून घेण्‍यासाठी कोणतीही की दाबा. Ctrl+W कीबोर्ड एक्सप्लोरर बंद करेल.</translation>
-<translation id="3307886118343381874">सारणीच्या शेवटी जा</translation>
-<translation id="3311969765485641742">सूचनांचे पुनरावलोकन करण्यासाठी Alt+Shift+A दाबा</translation>
-<translation id="3312997241656799641">पुढील भेट दिलेला दुवा</translation>
-<translation id="3321460131042519426">शब्द ओघ वळविणे सक्षम करा</translation>
-<translation id="3322936298410871309">मागील स्तर 1 मथळा</translation>
-<translation id="3323447499041942178">मजकूर बॉक्स</translation>
-<translation id="3353420241558113817">{"ar": "अरबी",
- "bg": "बल्गेरियन",
- "ca": "कॅटलान",
- "cs": "चेक",
- "da": "दानिश",
- "de": "जर्मन",
- "de_CH": "जर्मन (स्वित्झर्लंड)",
- "de_DE": "जर्मन (जर्मनी)",
- "el": "ग्रीक",
- "en": "इंग्रजी",
- "en_CA": "इंग्रजी (कॅनडा)",
- "en_GB": "इंग्रजी (युनायटेड किंगडम)",
- "en_US": "इंग्रजी (युनायटेड स्टेट्स)",
- "es": "स्पॅनिश",
- "et": "एस्टोनियन",
- "fr": "फ्रेंच",
- "fr_CA": "फ्रेंच (कॅनडा)",
- "fr_FR": "फ्रेंच (फ्रान्स)",
- "fi": "फिन्न‍िश",
- "he": "‍हिब्रू",
- "hi": "हिंदी",
- "hr": "क्रोएशियन",
- "hu": "हंगेरियन",
- "is": "हंगेरियन",
- "it": "इटालियन",
- "ko": "कोरियन",
- "lt": "लिथुआनियन",
- "lv": "लाटवियन",
- "nb": "नॉर्वेजियन बोकमाल",
- "nl": "डच",
- "pl": "पोलिश",
- "pt": "पोर्तुगीज",
- "ro": "रोमानियन",
- "ru": "रशियन",
- "sk": "स्लोव्हाक",
- "sl": "स्लोव्हेनियन",
- "sr": "सर्बियन",
- "sv": "सर्बियन",
- "tr": "तुर्की",
- "vi": "व्हिएतनामी",
- "zh": "चीनी",
- "zh_TW": "चीनी (पारंपारिक हान)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{प्लस}one{# प्लस चिन्हे}other{# प्लस चिन्हे}}</translation>
-<translation id="338583716107319301">विभाजक</translation>
-<translation id="3389259863310851658">मागील फॉर्म फील्ड</translation>
-<translation id="3390225400784126843">पुढील वेगळा घटक.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, मेनू आयटम</translation>
-<translation id="3406283310380167331">फॉर्म सूची दर्शवा</translation>
-<translation id="3422338090358345848">कीबोर्ड एक्सप्लोरर उघडा</translation>
-<translation id="3457000393508828486">अंशत: दाबलेले</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, बटण</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> ते <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{उजवा चौकोनी कंस}one{# उजवे चौकोनी कंस}other{# उजवे चौकोनी कंस}}</translation>
-<translation id="3493915602752813531">पुढील अँकर नाही.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{प्रश्नचिन्ह}one{# प्रश्नचिन्हे}other{# प्रश्नचिन्हे}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{कॅरेट}one{# कॅरेट}other{# कॅरेट}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, चेकबॉक्स चेक केलेला नाही</translation>
-<translation id="3599054940393788245">गणितात नाही</translation>
-<translation id="3616113530831147358">ऑडिओ</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{बॅकटिक}one{# बॅकटिक}other{# बॅकटिक}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{डॉलर}one{# डॉलर चिन्हे}other{# डॉलर चिन्हे}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, सूची बॉक्स</translation>
-<translation id="3687295507293856493">वर्तमान सेलच्या स्तंभ शीर्षकावर अंदाज करा</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">उच्चार नियंत्रण</translation>
-<translation id="3716845769494773620">एकाधिक रेखा</translation>
-<translation id="3731746171184829332">मागील मथळा नाही.</translation>
-<translation id="3762198587642264450">वर्तमान पंक्तीच्या शेवटी जा</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">संवादाच्या बाहेर पडले.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">स्‍वयंपूर्ण सूची</translation>
-<translation id="3810838688059735925">व्हिडिओ</translation>
-<translation id="3816633764618089385">पुढील माध्यम</translation>
-<translation id="3819376190738087562">जंप नाहीत.</translation>
-<translation id="385383972552776628">पर्याय पृष्‍ठ उघडा</translation>
-<translation id="3856075812838139784">केवळ वाचनीय</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">मेनू</translation>
-<translation id="3909320334364316587">मागील स्तर 6 शीर्षक</translation>
-<translation id="3914173277599553213">आवश्यक</translation>
-<translation id="3962990492275676168">वर्तमान स्‍थानावरून वाचन प्रारंभ करा</translation>
-<translation id="4004802134384979325">चेक केलेले</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">महिना नियंत्रण</translation>
-<translation id="4039983576244166038">रिक्त पंक्ती शीर्षलेख</translation>
-<translation id="4042843249978639960">पुढील स्‍तर 2 मथळा नाही.</translation>
-<translation id="4043348641337972076">मागील ARIA महत्त्वाची खूण नाही.</translation>
-<translation id="4047216625641135770">चिन्ह</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{टिल्डि}one{# टिल्डि}other{# टिल्डि}}</translation>
-<translation id="409334809956508737">मागील ऑब्जेक्ट</translation>
-<translation id="4099274309791143834">उपमेनू सह</translation>
-<translation id="4107807507418787238">खाली सेल नाही.</translation>
-<translation id="4116415223832267137">सूचना</translation>
-<translation id="4147126331795725888">पुढील नियंत्रण नाही.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{उजवा महिरपी कंस}one{# उजवे महिरपी कंस}other{# उजवे महिरपी कंस}}</translation>
-<translation id="4158704014418536539">केस संवेदनशील.</translation>
-<translation id="4161663686871496107">ChromeVox बोललेला अभिप्राय सज्ज आहे</translation>
-<translation id="4173994908659439270">पुढील संपादन करण्‍यायोग्‍य मजकूर फील्‍ड नाही.</translation>
-<translation id="4176463684765177261">अक्षम</translation>
-<translation id="4188530942454211480">मागील वाक्य</translation>
-<translation id="4202186506458631436">उजवीकडे हलवा</translation>
-<translation id="4206289001967551965">सारणीमध्‍ये</translation>
-<translation id="4215733775853809057">पुढील स्‍लायडर</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{डॅश}one{# डॅश}other{# डॅश}}</translation>
-<translation id="421884353938374759">रंग निवडक</translation>
-<translation id="4229646983878045487">तारीख वेळ</translation>
-<translation id="423334822609210999">डावीकडे सेल नाही.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" /> , ग्रेड <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">टीप</translation>
-<translation id="4254798249533888099">झाड</translation>
-<translation id="4255943572433203166">ChromeVox सानुकूल करण्‍यासाठी खालील पर्याय वापरा. बदल त्वरीत प्रभावी होतील.</translation>
-<translation id="4271220233568730077">पुढील गणित</translation>
-<translation id="4271521365602459209">अधिक परिणाम नाहीत.</translation>
-<translation id="4287520460805643128">पुढील लेख नाही.</translation>
-<translation id="4289540628985791613">विहंगावलोकन</translation>
-<translation id="4300318234632215983">दुव्यामागील URL घोषित करा</translation>
-<translation id="4301352596632316575">यास उपमेनू आहे</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{टिंब}=3{पदलोप}one{# टिंब}other{# टिंब}}</translation>
-<translation id="4347461890115250064">पुढील सूची नाही.</translation>
-<translation id="4367650418938037324">Math ML लीफ</translation>
-<translation id="4372435075475052704">किमान:<ph name="X" /></translation>
-<translation id="4372705107434148843">भाषण थांबवा</translation>
-<translation id="4373197658375206385">दुवा नसलेला मागील आयटम नाही.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">रीसेट करा</translation>
-<translation id="4471074325120394300">कोणतेही दुवे नाहीत.</translation>
-<translation id="4476183483923481720">नवीन रेखा</translation>
-<translation id="4482330759234983253">मागील सारणी</translation>
-<translation id="4491109536499578614">प्रतिमा</translation>
-<translation id="4529987814483543472">क्लासिक मुख्य नकाशा</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{स्लॅश}one{# स्लॅश}other{# स्लॅश}}</translation>
-<translation id="4547556996012970016">पुढील स्तर 5 मथळा</translation>
-<translation id="4562381607973973258">शीर्षलेख</translation>
-<translation id="4591507479202817876">, निवडले</translation>
-<translation id="4597532268155981612">फॉर्म</translation>
-<translation id="4597896406374528575">एप्रिल</translation>
-<translation id="4615592953348396470">पुढील की दाबणे दुर्लक्षित करत आहे</translation>
-<translation id="461613135510474570">वाक्य</translation>
-<translation id="4647836961514597010">रंग निवडक</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">मागील महत्त्वाची खूण</translation>
-<translation id="4696413482802371445">पुढील स्‍तर 5 मथळा नाही.</translation>
-<translation id="4729095194763193578">मागील सारणी पंक्ती</translation>
-<translation id="4736221692378411923">ऑगस्ट</translation>
-<translation id="4740661827607246557">मदत आदेश</translation>
-<translation id="4759716709594980008">ChromeOS कीबोर्ड एक्सप्लोरर</translation>
-<translation id="4763296182459741068">तळाकडे ओघ वळविला</translation>
-<translation id="4763480195061959176">व्हिडिओ</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">वर्तमान पृष्‍ठाचे शीर्षक घोषित करा</translation>
-<translation id="4826415162591436065">अग्रेषित करणे नेव्हिगेट करा</translation>
-<translation id="4826604887384865800">पुढील जंप</translation>
-<translation id="4827410568042294688">न निवडलेले</translation>
-<translation id="4842108708071771135">पुढील ब्लॉककोट नाही.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">मागील समान घटक.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS लॉगिंग सक्षम करा</translation>
-<translation id="4877261390094455813">एक शोध क्वेरी प्रविष्ट करा.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">अंतर्गत दुवा</translation>
-<translation id="4953585991029886728">मजकूर संपादित करा</translation>
-<translation id="4954534434583049121">मागील ब्लॉक कोट</translation>
-<translation id="4973717656530883744">किमान <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> वर स्विच केले.</translation>
-<translation id="4975416682604111799">मिलिसेकंद</translation>
-<translation id="49787999531187221">ChromeVox आता निष्क्रिय झाले.</translation>
-<translation id="4979404613699303341">मागील बटण</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, सूची बॉक्स</translation>
-<translation id="4983588134362688868">पृष्ठाच्या शीर्षस्थानी जा</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, विंडो</translation>
-<translation id="4993152509206108683">दर <ph name="PERCENT" /> टक्के</translation>
-<translation id="4996716799442435517">दृश्य</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, रेडिओ बटण निवडले</translation>
-<translation id="4997475792277222884">दुवा नसलेला पुढील आयटम नाही.</translation>
-<translation id="5000760171916499057">कोणतेही फॉर्म नाहीत.</translation>
-<translation id="5005670136041063723">आणखी सारखे घटक नाहीत.</translation>
-<translation id="501473567976723023">जानेवारी</translation>
-<translation id="5041394372352067729">पृष्ठाच्या शीर्षस्थानी ब्रेल प्रदर्शन हलवा</translation>
-<translation id="5042770794184672516">बोलण्‍याचा आवाज वाढवा</translation>
-<translation id="5050015258024679800">मागील स्तर 4 शीर्षक</translation>
-<translation id="5054047268577924192">मागील सूची आयटम</translation>
-<translation id="5078661581131202757">फाइल निवड</translation>
-<translation id="5080758118274074384">दोनदा क्लिक केला</translation>
-<translation id="5098541983634824365">ग्रिड सोडत आहे.</translation>
-<translation id="5102981729317424850">टूलबार</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">मागील फॉर्म फील्‍ड नाही.</translation>
-<translation id="5111640677200759579">स्‍तंभ शीर्षलेख</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">मागील दुवा नाही.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, न निवडलेले</translation>
-<translation id="5183440668879371625">ब्रेल मागील रेखा</translation>
-<translation id="5184944171021383281">पुढील फॉर्म फील्‍ड नाही.</translation>
-<translation id="5189244881767082992">रेखा</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> आधीपासूनच एका आदेशामध्ये नियुक्त केली आहे.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> सूची.</translation>
-<translation id="520883772648104506">पुढील रेडिओ बटण नाही.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">समाप्त</translation>
-<translation id="5291783959063340370">ऑब्जेक्ट</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, टॅब</translation>
-<translation id="5310788376443009632">काढले:</translation>
-<translation id="5320727453979144100">रोचक मोड सक्षम</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{स्वल्पविराम}one{# स्वल्पविराम}other{# स्वल्पविराम}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, मजकूर बॉक्स</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, दुवा</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">सतत वाचन करताना मागील वगळा</translation>
-<translation id="5368000168321181111">इअरकॉन बंद आहेत</translation>
-<translation id="5374320867641260420">पुढील बटण नाही.</translation>
-<translation id="5382299583965267720">कोणताही पुढील स्‍तर 1 मथळा नाही.</translation>
-<translation id="5402367795255837559">ब्रेल</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{अर्धविराम}one{# अर्धविराम}other{# अर्धविराम}}</translation>
-<translation id="5411891038905756502">मागील जंप बिंदू नाही.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{पेक्षा कमी}one{# पेक्षा कमी चिन्हे}other{# पेक्षा कमी चिन्हे}}</translation>
-<translation id="5455441614648621694">पूरक</translation>
-<translation id="5485036206801896268">मागील ग्राफिक नाही.</translation>
-<translation id="5486947920110100234">पुढील जंप बिंदू नाही.</translation>
-<translation id="549602578321198708">शब्द</translation>
-<translation id="5500932716852106146">मागील संपादित करण्‍यायोग्‍य मजकूर फील्‍ड नाही.</translation>
-<translation id="5502713021410870035">सप्टेंबर</translation>
-<translation id="5507663321906818013">बेंचमार्क डीबग करा</translation>
-<translation id="5518443085409638729">मजकूर संपादित करताना वर्णांमध्ये कर्सर ठेवा (Mac OS X सारखे).</translation>
-<translation id="552195134157544755">रेडिओ बटण</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">मागील स्‍तर 5 मथळा नाही.</translation>
-<translation id="556042886152191864">बटण</translation>
-<translation id="5561345396546889625">पुढील सूची</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">मजकूर, ईमेल प्रविष्टी संपादित करा</translation>
-<translation id="5597170376237141345">पुढील चेकबॉक्स</translation>
-<translation id="5597933780944041114">पुढील मथळा नाही.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, रेडिओ बटण निवडले नाही</translation>
-<translation id="5601172225407283979">डीफॉल्ट क्रिया करा</translation>
-<translation id="5608798115546226984">स्‍वयंपूर्ण इनलाइन</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">लॉग</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">मागील सारणी नाही.</translation>
-<translation id="5655682562155942719">जाण्याचे आदेश</translation>
-<translation id="56637627897541303">मजकूर क्षेत्र</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">महत्त्वाची खुण</translation>
-<translation id="5683155931978483559">मागील चेकबॉक्स</translation>
-<translation id="5684277895745049190">सूची</translation>
-<translation id="5700650669149824506">मागील स्‍तर 4 मथळा नाही.</translation>
-<translation id="5709192780268610569">कोणतेही मोठे वर्णन नाही</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">पुढील सारणी स्तंभ</translation>
-<translation id="571866080859340309">गट संशोधन करत आहे</translation>
-<translation id="5728409797179002635">कोणतीही सारणी आढळली नाही.</translation>
-<translation id="5748623122140342504">मागील स्तर 5 शीर्षक</translation>
-<translation id="5750633686117194034">कोणताही सुधारक दाबलेला नाही; कृपया एक किंवा अधिक मॉडिफायर दाबा आणि धरून ठेवा; एकदा पूर्ण झाल्यानंतर आपली बोटे उचलून घ्या म्हणजे आपल्याला सेट झालेल्या की ऐकू येतील. बाहेर पडण्यासाठी टॅब.</translation>
-<translation id="5788275253279308023">गुप्त विंडो <ph name="TITLE" /> टॅब</translation>
-<translation id="5806206155699461681">विशिष्ट साइट वर्धित करा (Google शोध सारख्या).</translation>
-<translation id="5819072574982403430">Tree आयटम</translation>
-<translation id="5826479389509458994">पंक्ती <ph name="ROW" /> स्तंभ <ph name="COL" /></translation>
-<translation id="5850707923114094062">मागे पॅन करा</translation>
-<translation id="5851548754964597211">टॅब सूची</translation>
-<translation id="5859752971144398932">पृष्ठामध्ये सापडलेल्याच्या बाहेर पडले.</translation>
-<translation id="5866042630553435010">अंशत: चेक केलेले</translation>
-<translation id="5869546221129391014">ग्रिड</translation>
-<translation id="5876817486144482042">आवाज कमी करा</translation>
-<translation id="5887397643266327462">ब्रेल मथळे सक्षम केले.</translation>
-<translation id="5891934789323004067">सारणी</translation>
-<translation id="5919442531159595654">कॉपी करा.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{समान}one{# समान चिन्हे}other{# समान चिन्हे}}</translation>
-<translation id="5939518447894949180">रीसेट करा</translation>
-<translation id="5948123859135882163">संरचना आणि सिमेंटिक मधील गणितीय पदावलीचे प्रस्तुतीकरण टॉगल करा</translation>
-<translation id="5955304353782037793">अ‍ॅप</translation>
-<translation id="5956928062748260866">संवाद</translation>
-<translation id="5963413905009737549">विभाग</translation>
-<translation id="5968607524793740041">संदर्भ मेनू दर्शवा</translation>
-<translation id="5983179082906765664">नेव्हिगेशन ग्रॅन्यूलॅरिटी वाढवा</translation>
-<translation id="5999630716831179808">व्हॉइस</translation>
-<translation id="6000417740266304866">खालील सूचीमधून एखादा पर्याय निवडून वर्तमान 8 बिंदू ब्रेल सारणी बदला.</translation>
-<translation id="6006050241733874051">फॉर्म</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{बॅकस्लॅश}one{# बॅकस्लॅश}other{# बॅकस्लॅश}}</translation>
-<translation id="6037602951055904232">अग्रेषित करणे पॅन करा</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">सेल समाप्त.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">जागा</translation>
-<translation id="6142308968191113180">मथळा 4</translation>
-<translation id="6169420925157477918">मोठ्या वर्णनासह प्रतिमा</translation>
-<translation id="6172087735260766220">कॉपी-संरक्षित PDF वरून प्रवेशयोग्य मजकूरामध्ये प्रवेश करण्यात अक्षम.</translation>
-<translation id="6186305613600865047">पृष्ठाच्या तळाशी जंप करा</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Down</translation>
-<translation id="6236061028292614533">पुढील शीर्षक</translation>
-<translation id="6254901459154107917">पुढील संपादनयोग्य मजकूर क्षेत्र</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> निर्गमन केले.</translation>
-<translation id="6281876499889881039">पुढील समान घटक.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">पुढील कॉम्‍बो बॉक्‍स नाही.</translation>
-<translation id="6307969636681130414">दाबलेले</translation>
-<translation id="6324551002951139333">व्‍याकरण चूक आढळली</translation>
-<translation id="6348657800373377022">काँबो बॉक्स</translation>
-<translation id="6355910664415701303">मागील सूची आयटम नाही.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">मागील मथळा</translation>
-<translation id="6387719785439924554">बाजूस</translation>
-<translation id="6411426777058107714">मागील रेडिओ बटण नाही.</translation>
-<translation id="6414968628640960377">मागील वेगळा घटक.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{अपूर्ण विराम}one{# अपूर्ण विराम}other{# अपूर्ण विराम}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, मेनू</translation>
-<translation id="6444046323172968959">सूचना संवाद</translation>
-<translation id="6459511626086141404">सपाट मुख्य नकाशा</translation>
-<translation id="6468049171101508116">पुढील बटण</translation>
-<translation id="6491972999578897419">खाली असलेल्या सूचीमधील पर्याय निवडून वर्तमान व्हॉइस बदला.</translation>
-<translation id="6508059270146105198">पृष्ठाच्या तळाशी ब्रेल प्रदर्शन हलवा</translation>
-<translation id="6536864053412760904">Math ML टोकन</translation>
-<translation id="6550720799683018100">खाली असलेल्या सूचीमधील पर्याय निवडून वर्तमान मुख्य नकाशा बदला.</translation>
-<translation id="6561818612645211875">वर्तमान पंक्तीच्या सुरुवातीस जा</translation>
-<translation id="6587021927234520429">पुढील स्‍तर 4 मथळा नाही.</translation>
-<translation id="6601344353291556895">पाल्हाळीक वर्णने सक्षम करा.</translation>
-<translation id="6615602925644411249">पृष्ठामध्ये शोधा.</translation>
-<translation id="6633350132811819843">पुढील सारणी नाही.</translation>
-<translation id="6637586476836377253">लॉग</translation>
-<translation id="6657128831881431364">प्रगती बार</translation>
-<translation id="6659594942844771486">टॅब</translation>
-<translation id="667999046851023355">दस्तऐवज</translation>
-<translation id="6697092096875747123">मागील कॉम्बो बॉक्स</translation>
-<translation id="6714813999819678458">मागील स्तर 2 शीर्षक</translation>
-<translation id="6716505898850596801">सुधारणा की</translation>
-<translation id="671916444866103745">पुढील ARIA महत्त्वाची खूण नाही.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, कॉम्बो बॉक्स</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> आयटमसह</translation>
-<translation id="6736510033526053669">टॅब तयार केला</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">लेख</translation>
-<translation id="6787839852456839824">कीबोर्ड शॉर्टकट</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">तळटीप</translation>
-<translation id="6871161210040114857">केसकडे दुर्लक्ष करीत आहे.</translation>
-<translation id="6877435256196695200">पुढील ग्राफिक नाही.</translation>
-<translation id="6897341342232909480">डावीकडे हलवा</translation>
-<translation id="6901540140423170855">तारीख</translation>
-<translation id="6910211073230771657">हटविला</translation>
-<translation id="6911965441508464308">वर सेल नाही.</translation>
-<translation id="6919104639734799681">सारणी सू‍ची दर्शवा</translation>
-<translation id="6964088412282673743">मागील नियंत्रण नाही.</translation>
-<translation id="6996566555547746822">पुढील कॉम्बो बॉक्स</translation>
-<translation id="7005146664810010831">कोणतीही URL आढळली नाही</translation>
-<translation id="7010712454773919705">ChromeVox सुधारणा की</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">मागील सूची</translation>
-<translation id="7041173719775863268">निवड समाप्त करा</translation>
-<translation id="7095834689119144465">केवळ अंकीय मजकूर संपादित करा</translation>
-<translation id="7096001299300236431">मागील माध्यम</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">शब्द प्रतिध्वनी</translation>
-<translation id="713824876195128146">पुढील ब्लॉक कोट</translation>
-<translation id="7161771961008409533">पॉप-अप बटण</translation>
-<translation id="7167657087543110">वर्ण प्रतिध्वनी</translation>
-<translation id="7170733337935166589">सतत वाचन करताना समोरील वगळा</translation>
-<translation id="7181697990050180700">वारंवार वापरलेल्या आदेशांसाठी ते खाली असलेल्या संबंधित फील्डमध्ये टाइप करून कीबोर्ड शॉर्टकट सानुकूल करा.</translation>
-<translation id="7203150201908454328">विस्‍तृत केलेले</translation>
-<translation id="7210211103303402262">मिनिटे</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">रेखा</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">मथळा</translation>
-<translation id="7241683698754534149">एका नवीन टॅबमध्ये मोठे वर्णन उघडा</translation>
-<translation id="7248671827512403053">अनुप्रयोग</translation>
-<translation id="725969808843520477">पुढील रेडिओ बटण</translation>
-<translation id="7269119382257320590">कोणतेही विरामचिन्‍ह नाही</translation>
-<translation id="7273174640290488576">रिक्त</translation>
-<translation id="7285387653379749618">सारण्या</translation>
-<translation id="7289186959554153431">मथळा 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tr itm</translation>
-<translation id="731576946540457939">ब्रेल मथळे अक्षम केले.</translation>
-<translation id="7318872822751139669">फोकस बदलण्यासाठी माऊस वापरा.</translation>
-<translation id="7322388933135261569">फेब्रुवारी</translation>
-<translation id="7332592614823088566"><ph name="ROWTOTAL" /> पैकी <ph name="ROWINDEX" /> पंक्ती, <ph name="COLTOTAL" /> पैकी <ph name="COLINDEX" /> स्तंभ</translation>
-<translation id="7336596009609913925">यास पॉपअप आहे</translation>
-<translation id="7356165926712028380">8 बिंदू ब्रेलवर स्विच करा</translation>
-<translation id="7362871137496673139">मागील स्‍तर 2 मथळा नाही.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{अँपरसँड}one{# अँपरसँड}other{# अँपरसँड}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">सारणी सोडत आहे.</translation>
-<translation id="739763518212184081">मागील रेखा</translation>
-<translation id="7400575256015741911">शब्दलेखन चूक आढळली</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">मिळालेले</translation>
-<translation id="7434509671034404296">विकसक</translation>
-<translation id="7439060726180460871">निर्देशिका</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">टॅब</translation>
-<translation id="7492049978501397201">संवाद प्रविष्ट केला</translation>
-<translation id="7532613204005497612">जून</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, स्लायडर</translation>
-<translation id="7586163296341959563">पेस्ट करा.</translation>
-<translation id="7596919493010894443">निवड साफ केली</translation>
-<translation id="7604026522577407655">वर्तमान स्तंभाच्या सुरुवातीस जा</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">वर्तमान पृष्‍ठाची URL घोषित करा</translation>
-<translation id="7609363189280667021">ब्रेल मथळे टॉगल करा</translation>
-<translation id="762020119231868829">सध्या प्ले होत असलेल्या सर्व माध्यम विजेटला विराम देते</translation>
-<translation id="7625690649919402823">पुढील सारणी</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> ( <ph name="VARIANT" /> ), ग्रेड <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">मागील स्‍तर 3 मथळा नाही.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, मजकूर बॉक्स</translation>
-<translation id="7663318257180412551">मथळा 2</translation>
-<translation id="7674576868851035240">पुढील दुवा</translation>
-<translation id="7674768236845044097">चिन्ह</translation>
-<translation id="7684431668231950609">मजकूर, URL प्रविष्टी संपादित करा</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">मागील रेडिओ बटण</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, संकेतशब्द मजकूर बॉक्स</translation>
-<translation id="7805247615045262757">डीफॉल्ट नेव्हिगेशन</translation>
-<translation id="7805768142964895445">स्थिती</translation>
-<translation id="7810781339813764006">पुढील गट</translation>
-<translation id="7819187121850078213">विंडो <ph name="TITLE" /> टॅब</translation>
-<translation id="7828956995407538686">ऑक्टोबर</translation>
-<translation id="7839679365527550018">मागील शब्द</translation>
-<translation id="7851816175263618915">काही विरामचिन्‍ह</translation>
-<translation id="7870596830398826354">Math ML ट्री</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox क्लासिक टॉगल करा.</translation>
-<translation id="7895896691902835279">अज्ञात दुवा</translation>
-<translation id="7927711904086083099">न निवडलेले</translation>
-<translation id="7935627501098484003">वेळ नियंत्रण</translation>
-<translation id="7939428177581522200">निवडीमध्ये जोडलेले</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{यावर}one{# यावर चिन्हे}other{# यावर चिन्हे}}</translation>
-<translation id="7965147473449754028">मेनू बंद केला</translation>
-<translation id="7974390230414479278">मेनू आयटम</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{उद्गार चिन्ह}one{# उद्गार चिन्ह}other{# उद्गार चिन्ह}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{अवतरण चिन्ह}one{# अवतरण चिन्हे}other{# अवतरण चिन्हे}}</translation>
-<translation id="8033827949643255796">निवडलेले</translation>
-<translation id="8035962149453661158">कमाल:<ph name="X" /></translation>
-<translation id="8042761080832772327">मजकूर, शोध प्रविष्टी संपादित करा</translation>
-<translation id="8049189770492311300">टायमर</translation>
-<translation id="8065607967589909823">निवड ही आहे</translation>
-<translation id="8066678206530322333">बॅनर</translation>
-<translation id="8110647606445335195">कोणत्याही ARIA च्‍या महत्त्वाच्या खुणा नाहीत.</translation>
-<translation id="8153880621934657047">सारणीमध्ये नाही.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{अंडरस्कोअर}one{# अंडरस्कोअर}other{# अंडरस्कोअर}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">कट करा.</translation>
-<translation id="8199231515320852133">सध्‍याच्या सेलची शीर्षके घोषित करा</translation>
-<translation id="820417203470636242">रिक्त सेल.</translation>
-<translation id="8215202828671303819">एकाधिक निवड</translation>
-<translation id="8276439074553447000">मागील फोकस करण्यायोग्य आयटमवर जा</translation>
-<translation id="8278417001922463147">मागील लेख नाही.</translation>
-<translation id="8283603667300770666">पुढील फॉर्म फील्‍ड</translation>
-<translation id="831207808878314375">परिभाषा</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">तास</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{पाउंड}one{# पाउंड चिन्हे}other{# पाउंड चिन्हे}}</translation>
-<translation id="8374154622594089836">महिना</translation>
-<translation id="8378855320830505539">प्रदेश</translation>
-<translation id="8382679411218029383">स्‍वयंपूर्ण इनलाइन आणि सूची</translation>
-<translation id="8428603554127842284">स्तर <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">पुढील स्‍तर 3 मथळा नाही.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">मागील चेकबॉक्‍स नाही.</translation>
-<translation id="8455868257606149352">कमाल <ph name="X" /></translation>
-<translation id="84575901236241018">प्रवेश की आहे, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">नॅव्हिगेशन ग्रॅन्युलॅरिटी कमी करा</translation>
-<translation id="8520472399088452386">स्पिन बटण</translation>
-<translation id="8538744478902126321">वर्तमान सेलच्या पंक्ती शीर्षलेखावर अंदाज करा</translation>
-<translation id="8540054775867439484">शीर्षस्थानी ओघ वळविला</translation>
-<translation id="8548973727659841685">वर्ण</translation>
-<translation id="8561322612995434619">यास पॉप अप आहे</translation>
-<translation id="8571096049907249734">एकाधिक निवड</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">पुढील सूची आयटम</translation>
-<translation id="860150890330522909"><ph name="NAME" /> चेकबॉक्स चेक केला</translation>
-<translation id="8606621670302093223">तारीख नियंत्रण</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> आयटम निवडले</translation>
-<translation id="8638532244051952400">वर्तमान कक्ष समन्वय घोषित करा</translation>
-<translation id="8650576015643545550">मागील सूची नाही.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">दुव्यांची सूची दर्शवा</translation>
-<translation id="8664519043722036194">सेकंद</translation>
-<translation id="867187640362843212">मथळा 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{पाइप}one{# अनुलंब पाइप}other{# अनुलंब पाइप}}</translation>
-<translation id="8735450637152821465">निवड प्रारंभ करा</translation>
-<translation id="8743786158317878347">संरचित सामग्री प्रविष्ट करा, जसे की सारण्या</translation>
-<translation id="8747966237988593539">क्रमांकित सूची</translation>
-<translation id="8759334257841767240">पुढील दुवा नाही.</translation>
-<translation id="8767968232364267681">पुढील स्तर 4 शीर्षक</translation>
-<translation id="8770473310765924354">संरचित सामग्रीच्या बाहेर पडा, जसे की सारण्या</translation>
-<translation id="8791025954632646584">सिमेंटिक चालू</translation>
-<translation id="8796411681063377102">पुढील स्तर 3 शीर्षक</translation>
-<translation id="8808582214901541005">मार्च</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">मुख्य</translation>
-<translation id="8856538297388979332">आदेशाचे पुनरावलोकन करण्यासाठी वर किंवा खाली दाबा, सक्रिय करण्यासाठी प्रविष्ट करा दाबा</translation>
-<translation id="8864099967139188018">पुढील स्‍तर 6 मथळा नाही.</translation>
-<translation id="8882002077197914455">पंक्ती शीर्षलेख</translation>
-<translation id="8896347895970027998">ChromeVox सक्रिय किंवा निष्क्रिय टॉगल करा.</translation>
-<translation id="8898516272131543774">विरामचिन्ह प्रतिध्वनी आवर्तन</translation>
-<translation id="8900148057318340779">प्रत्यय की</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">रिक्त शीर्षलेख</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">सुधारणा की</translation>
-<translation id="8943175951035496220">उजवीकडे सेल नाही.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">फाईल</translation>
-<translation id="9027462562263121875">कोणत्याही सारण्‍या नाहीत.</translation>
-<translation id="9040132695316389094">मथळा 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">टॉगल शोध विजेट</translation>
-<translation id="9065283790526219006">+पॉपअप</translation>
-<translation id="9077213568694924680">निवडीमधून काढले</translation>
-<translation id="9082874451376019682">मागील स्‍लायडर नाही.</translation>
-<translation id="9089864840575085222">टायपिंग प्रतिध्वनी आवर्तन</translation>
-<translation id="9107530006868467849">मागील माध्यम विजेट नाही.</translation>
-<translation id="9108370397979208512">गणित</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{टक्के}one{# टक्के चिन्हे}other{# टक्के चिन्हे}}</translation>
-<translation id="9115913704608474258">नोव्हेंबर</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">वर्तमान स्‍थितीबद्दल संक्षिप्त वर्णन घोषित करते</translation>
-<translation id="9153606228985488238">पिच <ph name="PERCENT" /> टक्के</translation>
-<translation id="9160096769946561184">वर्तमान स्तंभाच्या शेवटी जा</translation>
-<translation id="9173115498289768110">व्हॉल्यूम <ph name="PERCENT" /> टक्के</translation>
-<translation id="9178973770513562274">ब्राउझ करण्यासाठी वर आणि खाली बाण की वापरा किंवा शोधण्यासाठी टाइप करा.</translation>
-<translation id="9192904702577636854">विस्तीर्ण</translation>
-<translation id="9212322457209634662">पुढील निवड नाही.</translation>
-<translation id="930275611743429116">निवड प्रारंभ किंवा समाप्त करा.</translation>
-<translation id="948171205378458592">बोलण्याचा दर कमी करा</translation>
-<translation id="962913030769097253">पुढील स्तर 1 मथळा</translation>
-<translation id="973955474346881951">स्‍टिकी मोड सक्षम/अक्षम करा</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ms.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ms.xtb
deleted file mode 100644
index 5d9b2ff368c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ms.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ms">
-<translation id="1012173283529841972">Item senarai</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Merentang.</translation>
-<translation id="1025074108959230262">Mod lekit dilumpuhkan</translation>
-<translation id="1031961866430398710">kemudian</translation>
-<translation id="1044777062731150180">Tiada pengepala</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Input tidak sah</translation>
-<translation id="1082209053475788238">Tiada tajuk tahap 6 terdahulu.</translation>
-<translation id="1088219014394087294">Tiada tajuk.</translation>
-<translation id="1106741348836243114">Hidupkan atau matikan maklum balas bunyi (earcon).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Koleksi <ph name="TAG" /> dengan <ph name="NUM" /> item</translation>
-<translation id="1155043339247954670">Tiada item senarai seterusnya.</translation>
-<translation id="1157782847298808853">Bantuan Papan Kekunci</translation>
-<translation id="1157843803349774103">Kotak kombo, <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="1167230103353892028">item menu, <ph name="NAME" />, dengan submenu</translation>
-<translation id="1177863135347784049">Tersuai</translation>
-<translation id="1188858454923323853">pelengkap</translation>
-<translation id="1206619573307042055">marki</translation>
-<translation id="1213216066620407844">ChromeVox - Memberikan Suara kepada Chrome</translation>
-<translation id="1229276918471378188">Langkauan sebelumnya</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Tajuk tahap 6 seterusnya</translation>
-<translation id="1275718070701477396">Dipilih</translation>
-<translation id="1319608975892113573">Tiada petikan blok terdahulu.</translation>
-<translation id="1321576897702511272">Sembunyikan bantuan ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> daripada <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">gema aksara dan perkataan</translation>
-<translation id="1339428534620983148">Lajur jadual sebelumnya</translation>
-<translation id="1342835525016946179">artikel</translation>
-<translation id="1346748346194534595">Kanan</translation>
-<translation id="136718599399906424">Baris jadual seterusnya</translation>
-<translation id="1383876407941801731">Carian</translation>
-<translation id="1385214448885562192">Tekan enter untuk menerima atau escape untuk membatalkan, ke bawah untuk seterusnya dan ke atas untuk sebelumnya.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652">Kotak teks kata laluan, <ph name="VALUE" /></translation>
-<translation id="1467432559032391204">Kiri</translation>
-<translation id="1474557363159888097">Tiada penambat terdahulu.</translation>
-<translation id="1502086903961450562">Grafik sebelumnya</translation>
-<translation id="1506187449813838456">Tingkatkan nada</translation>
-<translation id="151784044608172266">Ayat Seterusnya</translation>
-<translation id="1524531499102321782">Baris Braille seterusnya</translation>
-<translation id="1546370775711804143">Bar tatal</translation>
-<translation id="1559739829547075274">Navigasi ke belakang</translation>
-<translation id="1571643229714746283">ChromeVox sudah sedia</translation>
-<translation id="158493514907962286">Disember</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Tukar kepada braille 6 titik</translation>
-<translation id="1611168825862729585">Pengepala lajur:</translation>
-<translation id="1613476421962910979">Earcon hidup</translation>
-<translation id="1618597272655350600">Mengumumkan huraian lengkap tentang kedudukan semasa</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{lebih besar daripada}other{# tanda lebih besar daripada}}</translation>
-<translation id="1653266918374749391">Tajuk tahap 3 sebelumnya</translation>
-<translation id="1659072772017912254">Tidak ditandai</translation>
-<translation id="1669290819662866522">minggu</translation>
-<translation id="1674262202423278359">Navigasi ChromeVox</translation>
-<translation id="16777221443363124">Bar menu</translation>
-<translation id="1692077714702418899">garis struktur</translation>
-<translation id="1700517974991662022">Dilawati</translation>
-<translation id="1722567105086139392">Pautan</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Grafik seterusnya</translation>
-<translation id="1781173782405573156">Kekunci lintasan</translation>
-<translation id="1787176709638001873">Teks edit kata laluan</translation>
-<translation id="1810107444790159527">Kotak senarai</translation>
-<translation id="1828385960365606039">Mei</translation>
-<translation id="1834891354138622109">Lajur</translation>
-<translation id="1865601187525349519">Penghujung teks</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Sebutkan masa dan tarikh semasa.</translation>
-<translation id="1902396333223336119">Sel</translation>
-<translation id="1905379170753160525">Paparkan senarai tajuk</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Kawalan minggu untuk tahun</translation>
-<translation id="1964135212174907577">Objek Seterusnya</translation>
-<translation id="1969092762068865084">Julai</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Pengepala baris:</translation>
-<translation id="2002895034995108595">Tetapkan semula peta kekunci semasa</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{tanda kurung kiri}other{# tanda kurung kiri}}</translation>
-<translation id="2045490512405922022">tidak ditandai</translation>
-<translation id="20601713649439366">Tiada ungkapan matematik sebelumnya.</translation>
-<translation id="207477615537953741">Semantik dimatikan</translation>
-<translation id="2086961585857038472">Perkataan Seterusnya</translation>
-<translation id="2089387485033699258">ms</translation>
-<translation id="2091933974477985526">Kawasan teks boleh edit sebelumnya</translation>
-<translation id="2100350898815792233">Semua tanda baca</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">kekunci akses:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Tukar jadual semasa braille 6 titik dengan membuat pilihan daripada senarai di bawah.</translation>
-<translation id="2169714232367507776">Klik pada item semasa</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{tanda kurung tutup}other{# tanda kurung tutup}}</translation>
-<translation id="2199994615414171367">Matematik sebelumnya</translation>
-<translation id="2223693656926968778">Ambil tindakan terhadap item semasa</translation>
-<translation id="225732394367814946">Tingkatkan kadar pertuturan</translation>
-<translation id="2267945578749931355">Aksara Seterusnya</translation>
-<translation id="2281234842553884450">Peluncur sebelumnya</translation>
-<translation id="2318372665160196757">Utama</translation>
-<translation id="2329324941084714723">Panel tab</translation>
-<translation id="2344193891939537199">Kawalan tarikh masa</translation>
-<translation id="2359897517538099099">Bukan dalam mod jadual.</translation>
-<translation id="241124561063364910">diikuti oleh</translation>
-<translation id="2417569100218200841">Maklumat kandungan</translation>
-<translation id="2422937916923936891">Kotak pilihan item menu</translation>
-<translation id="2429669115401274487">P/M</translation>
-<translation id="2435413342408885429">Kini <ph name="KEY" /> menjadi pengubah suai ChromeVox baharu.</translation>
-<translation id="2450814015951372393">Kotak pilihan</translation>
-<translation id="2462626033734746142">Kumpulan butang radio</translation>
-<translation id="2471138580042810658">Tajuk 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisk}other{# asterisk}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> telah ditetapkan semula.</translation>
-<translation id="2553108862507765288">kesilapan tatabahasa</translation>
-<translation id="257674075312929031">Kumpulan</translation>
-<translation id="2582407057977008361">Ke sebelah</translation>
-<translation id="2589102159832527089">Halaman ini mengandungi teks yang dikeluarkan secara automatik daripada fail PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Klik di sini untuk melihat yang asal.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">dengan {COUNT,plural, =1{# item}other{# item}}</translation>
-<translation id="2614981083756825552">Reka Letak ML Matematik</translation>
-<translation id="2626530649491650971">boleh klik</translation>
-<translation id="2628764385451019380">Tiada kotak kombo terdahulu.</translation>
-<translation id="2637227747952042642">Matematik</translation>
-<translation id="2639750663247012216">Pengubah suai ChromeVox</translation>
-<translation id="2644542693584024604">tersalah eja</translation>
-<translation id="2667291555398229137">Klik item di bawah kekunci penghalaan</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{tanda kurung buka}other{# tanda kurung buka}}</translation>
-<translation id="2705875883745373140">Tidak ditekan</translation>
-<translation id="2706462751667573066">Atas</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">PG</translation>
-<translation id="2749275490991666823">Ditandai</translation>
-<translation id="27527859628328957">Langkau ke item boleh fokus seterusnya</translation>
-<translation id="2770781857296573485">Masukkan penerokaan kumpulan</translation>
-<translation id="2777845298774924149">Keluar</translation>
-<translation id="2800204403141299078">Tiada lagi unsur yang berbeza.</translation>
-<translation id="2800780099804980316">Tiada tajuk tahap 1 terdahulu.</translation>
-<translation id="2811204574343810641">Baris</translation>
-<translation id="2816654101880605877">Tiada peluncur seterusnya.</translation>
-<translation id="2841013758207633010">Masa</translation>
-<translation id="2843837985843789981">Kumpulan Sebelumnya</translation>
-<translation id="2844995807198708617">Menu Konteks</translation>
-<translation id="2849332794118375855">Tiada kotak pilihan seterusnya.</translation>
-<translation id="2864481629947106776">Pautan sebelumnya</translation>
-<translation id="2873259058405069099">Pergi ke permulaan jadual</translation>
-<translation id="2894654529758326923">Maklumat</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{kurung panah kiri}other{# kurung panah kiri}}</translation>
-<translation id="2911433807131383493">Buka tutorial ChromeVox</translation>
-<translation id="2932083475399492303">Togol jenis baris antara struktur atau reka letak</translation>
-<translation id="2964026537669811554">Kumpulan tajuk</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tab}other{# tab}}</translation>
-<translation id="2972078295414139404">Tiada pautan yang dilawati sebelumnya.</translation>
-<translation id="2972205263822847197">Petua alat</translation>
-<translation id="2998131015536248178">Aksara Sebelumnya</translation>
-<translation id="2999559350546931576">Kurangkan nada</translation>
-<translation id="2999945368667127852">Tiada widget media seterusnya.</translation>
-<translation id="3012414509011670858">Tiada bahagian sebelumnya.</translation>
-<translation id="3030432017085518523">Butang radio item menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{koma atas}other{# koma atas}}</translation>
-<translation id="3046838483509668188">Pilihan ChromeVox</translation>
-<translation id="3047143736589213134">Peta kekunci percubaan</translation>
-<translation id="3060756054951570867">Menu <ph name="TITLE" /> dibuka</translation>
-<translation id="3078345202707391975">Tajuk tahap 2 seterusnya</translation>
-<translation id="3078740164268491126">jadual</translation>
-<translation id="3082557070674409251">Diklik</translation>
-<translation id="3084806535845658316">tiada gema penaipan</translation>
-<translation id="3086746722712840547">nota</translation>
-<translation id="308895241372589742">Tiada ungkapan matematik seterusnya.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Mercu tanda seterusnya</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Diruntuhkan</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Paparkan senarai mercu tanda</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Baris Seterusnya</translation>
-<translation id="3155083529632865074">Tiada butang terdahulu.</translation>
-<translation id="3163593631834463955">Pengepala lajur kosong</translation>
-<translation id="316542773973815724">Navigasi</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{ruang}other{# ruang}}</translation>
-<translation id="320961988183078793">memasukkan <ph name="TYPE" /></translation>
-<translation id="3223701887221307104">Tab, <ph name="NAME" /></translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Pautan yang dilawati</translation>
-<translation id="323731244387692321">Buka bantuan papan kekunci ChromeVox</translation>
-<translation id="3241052487511142956">Pautan yang dilawati sebelumnya</translation>
-<translation id="3286390186030710347">Peluncur</translation>
-<translation id="3299925995433437805">Tiada pautan yang dilawati seterusnya.</translation>
-<translation id="3303384412438961941">Tekan sebarang kekunci untuk mengetahui namanya. Ctrl+W akan menutup penjelajah papan kekunci.</translation>
-<translation id="3307886118343381874">Pergi ke hujung jadual</translation>
-<translation id="3311969765485641742">Tekan Alt+Shift+A untuk menyemak makluman</translation>
-<translation id="3312997241656799641">Pautan yang dilawati seterusnya</translation>
-<translation id="3321460131042519426">Dayakan balut kata</translation>
-<translation id="3322936298410871309">Tajuk tahap 1 sebelumnya</translation>
-<translation id="3323447499041942178">Kotak teks</translation>
-<translation id="3353420241558113817">{"ar": "Arab",
- "bg": "Bulgaria",
- "ca": "Catalonia",
- "cs": "Czech",
- "da": "Denmark",
- "de": "Jerman",
- "de_CH": "Jerman (Switzerland)",
- "de_DE": "Jerman (Jerman)",
- "el": "Yunani",
- "en": "Inggeris",
- "en_CA": "Inggeris (Kanada)",
- "en_GB": "Inggeris (United Kingdom)",
- "en_US": "Inggeris (Amerika Syarikat)",
- "es": "Sepanyol",
- "et": "Estonia",
- "fr": "Perancis",
- "fr_CA": "Perancis (Kanada)",
- "fr_FR": "Perancis (Perancis)",
- "fi": "Finland",
- "he": "Ibrani",
- "hi": "Hindi",
- "hr": "Croatia",
- "hu": "Hungary",
- "is": "Iceland",
- "it": "Itali",
- "ko": "Korea",
- "lt": "Lithuania",
- "lv": "Latvia",
- "nb": "Norway Bokmål",
- "nl": "Belanda",
- "pl": "Poland",
- "pt": "Portugis",
- "ro": "Romania",
- "ru": "Rusia",
- "sk": "Slovakia",
- "sl": "Slovenia",
- "sr": "Serbia",
- "sv": "Sweden",
- "tr": "Turki",
- "vi": "Vietnam",
- "zh": "Cina",
- "zh_TW": "Cina (Han Tradisional)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{campur}other{# tanda campur}}</translation>
-<translation id="338583716107319301">Pemisah</translation>
-<translation id="3389259863310851658">Medan borang sebelumnya</translation>
-<translation id="3390225400784126843">Elemen berbeza seterusnya.</translation>
-<translation id="3392045790598181549">Item menu, <ph name="NAME" /></translation>
-<translation id="3406283310380167331">Paparkan senarai borang</translation>
-<translation id="3422338090358345848">Buka penjelajah papan kekunci</translation>
-<translation id="3457000393508828486">Separuh ditekan</translation>
-<translation id="3462439746547587373">Butang, <ph name="NAME" /></translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> hingga <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{tanda kurung kanan}other{# tanda kurung kanan}}</translation>
-<translation id="3493915602752813531">Tiada penambat seterusnya.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{tanda soal}other{# tanda soal}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{karet}other{# karet}}</translation>
-<translation id="3568702578574425662">Kotak pilihan, <ph name="NAME" /> tidak ditandai</translation>
-<translation id="3599054940393788245">Bukan dalam matematik</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{tanda belakang}other{# tanda belakang}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolar}other{# tanda dolar}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755">Kotak senarai, <ph name="VALUE" /></translation>
-<translation id="3687295507293856493">Buat tekaan pada pengepala lajur sel semasa</translation>
-<translation id="3692274950075847560">C:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Mengawal Pertuturan</translation>
-<translation id="3716845769494773620">Berbilang baris</translation>
-<translation id="3731746171184829332">Tiada tajuk terdahulu.</translation>
-<translation id="3762198587642264450">Pergi ke penghujung baris semasa</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Keluar dari dialog.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Senarai autolengkap</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Media seterusnya</translation>
-<translation id="3819376190738087562">Tiada langkauan.</translation>
-<translation id="385383972552776628">Buka halaman pilihan</translation>
-<translation id="3856075812838139784">Baca sahaja</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Tajuk tahap 6 sebelumnya</translation>
-<translation id="3914173277599553213">Diperlukan</translation>
-<translation id="3962990492275676168">Mula membaca dari lokasi semasa</translation>
-<translation id="4004802134384979325">ditandai</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Kawalan bulan</translation>
-<translation id="4039983576244166038">Pengepala baris kosong</translation>
-<translation id="4042843249978639960">Tiada tajuk tahap 2 seterusnya.</translation>
-<translation id="4043348641337972076">Tiada mercu tanda ARIA terdahulu.</translation>
-<translation id="4047216625641135770">Tanda</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}other{# tilde}}</translation>
-<translation id="409334809956508737">Objek Sebelumnya</translation>
-<translation id="4099274309791143834">dengan submenu</translation>
-<translation id="4107807507418787238">Tiada sel di bawah.</translation>
-<translation id="4116415223832267137">Makluman</translation>
-<translation id="4147126331795725888">Tiada kawalan seterusnya.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{kurung panah kanan}other{# kurung panah kanan}}</translation>
-<translation id="4158704014418536539">Sensitif huruf.</translation>
-<translation id="4161663686871496107">Maklum balas pertuturan ChromeVox sudah sedia</translation>
-<translation id="4173994908659439270">Tiada medan teks boleh edit seterusnya.</translation>
-<translation id="4176463684765177261">Dilumpuhkan</translation>
-<translation id="4188530942454211480">Ayat Sebelumnya</translation>
-<translation id="4202186506458631436">Alih ke kanan</translation>
-<translation id="4206289001967551965">Dalam jadual</translation>
-<translation id="4215733775853809057">Peluncur seterusnya</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{sengkang}other{# sengkang}}</translation>
-<translation id="421884353938374759">pemilih warna</translation>
-<translation id="4229646983878045487">tarikh masa</translation>
-<translation id="423334822609210999">Tiada sel di kiri.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, Gred <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Nota</translation>
-<translation id="4254798249533888099">Pohon</translation>
-<translation id="4255943572433203166">Gunakan pilihan di bawah untuk menyesuaikan ChromeVox. Perubahan berkuat kuasa serta-merta.</translation>
-<translation id="4271220233568730077">Matematik seterusnya</translation>
-<translation id="4271521365602459209">Tiada lagi hasil carian.</translation>
-<translation id="4287520460805643128">Tiada artikel seterusnya.</translation>
-<translation id="4289540628985791613">Gambaran keseluruhan</translation>
-<translation id="4300318234632215983">Umumkan URL di sebalik pautan</translation>
-<translation id="4301352596632316575">mempunyai submenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{titik}=3{elipsis}other{# titik}}</translation>
-<translation id="4347461890115250064">Tiada senarai seterusnya.</translation>
-<translation id="4367650418938037324">Dedaun ML Matematik</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Hentikan pertuturan</translation>
-<translation id="4373197658375206385">Tiada item terdahulu yang bukan pautan.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">tetapkan semula</translation>
-<translation id="4471074325120394300">Tiada pautan.</translation>
-<translation id="4476183483923481720">garisan baharu</translation>
-<translation id="4482330759234983253">Jadual sebelumnya</translation>
-<translation id="4491109536499578614">Imej</translation>
-<translation id="4529987814483543472">Peta kekunci klasik</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{garis condong}other{# garis condong}}</translation>
-<translation id="4547556996012970016">Tajuk tahap 5 seterusnya</translation>
-<translation id="4562381607973973258">Pengepala</translation>
-<translation id="4591507479202817876">, dipilih</translation>
-<translation id="4597532268155981612">borang</translation>
-<translation id="4597896406374528575">April</translation>
-<translation id="4615592953348396470">Mengabaikan tekanan kekunci seterusnya</translation>
-<translation id="461613135510474570">Ayat</translation>
-<translation id="4647836961514597010">Pemilih warna</translation>
-<translation id="4661075872484491155">pohon</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Mercu tanda sebelumnya</translation>
-<translation id="4696413482802371445">Tiada tajuk tahap 5 seterusnya.</translation>
-<translation id="4729095194763193578">Baris jadual sebelumnya</translation>
-<translation id="4736221692378411923">Ogos</translation>
-<translation id="4740661827607246557">Perintah Bantuan</translation>
-<translation id="4759716709594980008">Penjelajah Papan Kekunci ChromeOS</translation>
-<translation id="4763296182459741068">Dibalut ke bawah</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Umumkan tajuk halaman semasa</translation>
-<translation id="4826415162591436065">Navigasi ke hadapan</translation>
-<translation id="4826604887384865800">Langkauan seterusnya</translation>
-<translation id="4827410568042294688">dinyahpilih</translation>
-<translation id="4842108708071771135">Tiada petikan blok seterusnya.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Elemen serupa terdahulu.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Dayakan pengelogan TTS</translation>
-<translation id="4877261390094455813">Masukkan carian pertanyaan.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Pautan dalaman</translation>
-<translation id="4953585991029886728">Edit teks</translation>
-<translation id="4954534434583049121">Petikan blok sebelumnya</translation>
-<translation id="4973717656530883744">Min <ph name="X" /></translation>
-<translation id="4973762002207131920">Beralih kepada <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisaat</translation>
-<translation id="49787999531187221">ChromeVox kini tidak aktif.</translation>
-<translation id="4979404613699303341">Butang sebelumnya</translation>
-<translation id="4982773647088557172">Kotak senarai, <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="4983588134362688868">Langkau ke bahagian atas halaman</translation>
-<translation id="4986606102545753256">Tetingkap, <ph name="NAME" /></translation>
-<translation id="4993152509206108683">Kadar <ph name="PERCENT" /> peratus</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877">Butang radio, <ph name="NAME" /> dipilih</translation>
-<translation id="4997475792277222884">Tiada item seterusnya yang bukan pautan.</translation>
-<translation id="5000760171916499057">Tiada borang.</translation>
-<translation id="5005670136041063723">Tiada lagi unsur yang serupa.</translation>
-<translation id="501473567976723023">Januari</translation>
-<translation id="5041394372352067729">Alihkan paparan braille ke bahagian atas halaman</translation>
-<translation id="5042770794184672516">Tingkatkan kelantangan pertuturan</translation>
-<translation id="5050015258024679800">Tajuk tahap 4 sebelumnya</translation>
-<translation id="5054047268577924192">Item senarai sebelumnya</translation>
-<translation id="5078661581131202757">Pemilihan fail</translation>
-<translation id="5080758118274074384">diklik dua kali</translation>
-<translation id="5098541983634824365">Meninggalkan grid.</translation>
-<translation id="5102981729317424850">Bar alat</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Tiada medan borang terdahulu.</translation>
-<translation id="5111640677200759579">Pengepala lajur</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Tiada pautan terdahulu.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, dinyahpilih</translation>
-<translation id="5183440668879371625">Baris braille terdahulu</translation>
-<translation id="5184944171021383281">Tiada medan borang seterusnya.</translation>
-<translation id="5189244881767082992">Baris</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> telah ditugaskan kepada perintah.</translation>
-<translation id="5205493599117157272">Senarai <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Tiada butang radio seterusnya.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objek</translation>
-<translation id="5304943142864553931">Tab, <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">dialih keluar:</translation>
-<translation id="5320727453979144100">Mod lekit didayakan</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{koma}other{# koma}}</translation>
-<translation id="532371086589123547">Kotak teks, <ph name="VALUE" /></translation>
-<translation id="5330443287809544590">Pautan, <ph name="NAME" /></translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Langkau ke belakang semasa membaca berterusan</translation>
-<translation id="5368000168321181111">Earcon mati</translation>
-<translation id="5374320867641260420">Tiada butang seterusnya.</translation>
-<translation id="5382299583965267720">Tiada tajuk tahap 1 seterusnya.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{koma bertitik}other{# koma bertitik}}</translation>
-<translation id="5411891038905756502">Tiada titik langkau terdahulu.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{kurang daripada}other{# tanda kurang daripada}}</translation>
-<translation id="5455441614648621694">Percuma</translation>
-<translation id="5485036206801896268">Tiada grafik terdahulu.</translation>
-<translation id="5486947920110100234">Tiada titik langkau seterusnya.</translation>
-<translation id="549602578321198708">Perkataan</translation>
-<translation id="5500932716852106146">Tiada medan teks boleh edit terdahulu.</translation>
-<translation id="5502713021410870035">September</translation>
-<translation id="5507663321906818013">Penanda aras nyahpepijat</translation>
-<translation id="5518443085409638729">Letakkan kursor antara aksara apabila mengedit teks (seperti Mac OS X).</translation>
-<translation id="552195134157544755">Butang radio</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Tiada tajuk tahap 5 terdahulu.</translation>
-<translation id="556042886152191864">Butang</translation>
-<translation id="5561345396546889625">Senarai seterusnya</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Undur ruang</translation>
-<translation id="5585044216466955529">Edit teks, masukan e-mel</translation>
-<translation id="5597170376237141345">Kotak pilihan seterusnya</translation>
-<translation id="5597933780944041114">Tiada tajuk seterusnya.</translation>
-<translation id="5598905979683743333">Butang radio, <ph name="NAME" /> dinyahpilih</translation>
-<translation id="5601172225407283979">Lakukan tindakan lalai</translation>
-<translation id="5608798115546226984">Autolengkap sebaris</translation>
-<translation id="561939826962581046">masa</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Log</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Tiada jadual terdahulu.</translation>
-<translation id="5655682562155942719">Perintah Melangkau</translation>
-<translation id="56637627897541303">Kawasan teks</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Mercu Tanda</translation>
-<translation id="5683155931978483559">Kotak pilihan sebelumnya</translation>
-<translation id="5684277895745049190">Senarai</translation>
-<translation id="5700650669149824506">Tiada tajuk tahap 4 terdahulu.</translation>
-<translation id="5709192780268610569">Tiada huraian panjang</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Lajur jadual seterusnya</translation>
-<translation id="571866080859340309">Meneroka kumpulan</translation>
-<translation id="5728409797179002635">Tiada jadual dijumpai.</translation>
-<translation id="5748623122140342504">Tajuk tahap 5 sebelumnya</translation>
-<translation id="5750633686117194034">Tiada pengubah suai ditekan; sila tekan terus satu atau lebih pengubah suai; angkat jari anda setelah selesai dan anda akan mendengar kekunci ditetapkan. Ketik untuk keluar.</translation>
-<translation id="5788275253279308023">tab <ph name="TITLE" /> tetingkap inkognito</translation>
-<translation id="5806206155699461681">Tingkatkan tapak tertentu (seperti Carian Google).</translation>
-<translation id="5819072574982403430">Item pepohon</translation>
-<translation id="5826479389509458994">baris <ph name="ROW" /> lajur <ph name="COL" /></translation>
-<translation id="5850707923114094062">Sorot ke belakang</translation>
-<translation id="5851548754964597211">Senarai tab</translation>
-<translation id="5859752971144398932">Keluar dari mencari dalam halaman.</translation>
-<translation id="5866042630553435010">Separuh ditandai</translation>
-<translation id="5869546221129391014">Grid</translation>
-<translation id="5876817486144482042">Kurangkan kelantangan pertuturan</translation>
-<translation id="5887397643266327462">Kapsyen braille didayakan.</translation>
-<translation id="5891934789323004067">Jadual</translation>
-<translation id="5919442531159595654">salin.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{sama dengan}other{# tanda sama dengan}}</translation>
-<translation id="5939518447894949180">Tetapkan semula</translation>
-<translation id="5948123859135882163">Togol tafsiran ungkapan matematik antara struktur dan semantik</translation>
-<translation id="5955304353782037793">apl</translation>
-<translation id="5956928062748260866">Dialog</translation>
-<translation id="5963413905009737549">Bahagian</translation>
-<translation id="5968607524793740041">Paparkan menu konteks</translation>
-<translation id="5983179082906765664">Tingkatkan kebutiran navigasi</translation>
-<translation id="5999630716831179808">Suara</translation>
-<translation id="6000417740266304866">Tukar jadual semasa braille 8 titik dengan membuat pilihan daripada senarai di bawah.</translation>
-<translation id="6006050241733874051">Borang</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{garis condong songsang}other{# garis condong songsang}}</translation>
-<translation id="6037602951055904232">Sorot ke hadapan</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Sel akhir.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Ruang</translation>
-<translation id="6142308968191113180">Tajuk 4</translation>
-<translation id="6169420925157477918">Imej dengan huraian panjang</translation>
-<translation id="6172087735260766220">Tidak dapat mengakses teks yang boleh diakses daripada fail PDF yang dilindung salin.</translation>
-<translation id="6186305613600865047">Langkau ke bahagian bawah halaman</translation>
-<translation id="6193330012414963395">PG PTG/MLM</translation>
-<translation id="622484624075952240">Bawah</translation>
-<translation id="6236061028292614533">Tajuk seterusnya</translation>
-<translation id="6254901459154107917">Kawasan teks boleh edit seterusnya</translation>
-<translation id="6259464875943891919">Keluar dari <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Elemen serupa seterusnya.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Tiada kotak kombo seterusnya.</translation>
-<translation id="6307969636681130414">Ditekan</translation>
-<translation id="6324551002951139333">Kesilapan tatabahasa dikesan</translation>
-<translation id="6348657800373377022">Kotak kombo</translation>
-<translation id="6355910664415701303">Tiada item senarai terdahulu.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Tajuk sebelumnya</translation>
-<translation id="6387719785439924554">ke sebelah</translation>
-<translation id="6411426777058107714">Tiada butang radio terdahulu.</translation>
-<translation id="6414968628640960377">Elemen berbeza terdahulu.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{titik bertindih}other{# titik bertindih}}</translation>
-<translation id="6438968337250688271">Menu, <ph name="NAME" /></translation>
-<translation id="6444046323172968959">Dialog makluman</translation>
-<translation id="6459511626086141404">Peta kekunci datar</translation>
-<translation id="6468049171101508116">Butang seterusnya</translation>
-<translation id="6491972999578897419">Tukar suara semasa dengan membuat pilihan daripada senarai di bawah.</translation>
-<translation id="6508059270146105198">Alihkan paparan braille ke bahagian bawah halaman</translation>
-<translation id="6536864053412760904">Token ML Matematik</translation>
-<translation id="6550720799683018100">Tukar peta kekunci semasa dengan membuat pilihan daripada senarai di bawah.</translation>
-<translation id="6561818612645211875">Pergi ke permulaan baris semasa</translation>
-<translation id="6587021927234520429">Tiada tajuk tahap 4 seterusnya.</translation>
-<translation id="6601344353291556895">Dayakan huraian yang berjela-jela.</translation>
-<translation id="6615602925644411249">Cari dalam halaman.</translation>
-<translation id="6633350132811819843">Tiada jadual seterusnya.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Bar kemajuan</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Dokumen</translation>
-<translation id="6697092096875747123">Kotak kombo sebelumnya</translation>
-<translation id="6714813999819678458">Tajuk tahap 2 sebelumnya</translation>
-<translation id="6716505898850596801">Kunci pengubah suai</translation>
-<translation id="671916444866103745">Tiada mercu tanda ARIA seterusnya.</translation>
-<translation id="6734854816611871228">Kotak kombo, <ph name="VALUE" /></translation>
-<translation id="6735257939857578167">dengan <ph name="NUM" /> item</translation>
-<translation id="6736510033526053669">tab dibuat</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artikel</translation>
-<translation id="6787839852456839824">Pintasan papan kekunci</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Pengaki</translation>
-<translation id="6871161210040114857">Mengabaikan huruf.</translation>
-<translation id="6877435256196695200">Tiada grafik seterusnya.</translation>
-<translation id="6897341342232909480">Alih ke kiri</translation>
-<translation id="6901540140423170855">tarikh</translation>
-<translation id="6910211073230771657">Dipadamkan</translation>
-<translation id="6911965441508464308">Tiada sel di atas.</translation>
-<translation id="6919104639734799681">Paparkan senarai jadual</translation>
-<translation id="6964088412282673743">Tiada kawalan sebelumnya.</translation>
-<translation id="6996566555547746822">Kotak kombo seterusnya</translation>
-<translation id="7005146664810010831">Tiada URL dijumpai</translation>
-<translation id="7010712454773919705">Kunci pengubah suai ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Senarai sebelumnya</translation>
-<translation id="7041173719775863268">Tamatkan pemilihan</translation>
-<translation id="7095834689119144465">Edit teks angka sahaja</translation>
-<translation id="7096001299300236431">Media sebelumnya</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">gema perkataan</translation>
-<translation id="713824876195128146">Petikan blok seterusnya</translation>
-<translation id="7161771961008409533">Butang pop timbul</translation>
-<translation id="7167657087543110">gema aksara</translation>
-<translation id="7170733337935166589">Langkau ke hadapan semasa membaca berterusan</translation>
-<translation id="7181697990050180700">Sesuaikan pintasan papan kekunci untuk perintah yang kerap digunakan dengan menaipnya ke dalam medan yang sepadan di bawah.</translation>
-<translation id="7203150201908454328">Diperluas</translation>
-<translation id="7210211103303402262">minit</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">baris</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Tajuk</translation>
-<translation id="7241683698754534149">Buka huraian panjang dalam tab baharu</translation>
-<translation id="7248671827512403053">Aplikasi</translation>
-<translation id="725969808843520477">Butang radio seterusnya</translation>
-<translation id="7269119382257320590">Tiada tanda baca</translation>
-<translation id="7273174640290488576">Kosong</translation>
-<translation id="7285387653379749618">Jadual</translation>
-<translation id="7289186959554153431">Tajuk 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Kapsyen Braille dilumpuhkan.</translation>
-<translation id="7318872822751139669">Gunakan tetikus untuk menukar fokus.</translation>
-<translation id="7322388933135261569">Februari</translation>
-<translation id="7332592614823088566">Baris <ph name="ROWINDEX" /> daripada <ph name="ROWTOTAL" />, Lajur <ph name="COLINDEX" /> daripada <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">mempunyai pop timbul</translation>
-<translation id="7356165926712028380">Tukar kepada braille 8 titik</translation>
-<translation id="7362871137496673139">Tiada tajuk tahap 2 terdahulu.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersan}other{# ampersan}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Meninggalkan jadual.</translation>
-<translation id="739763518212184081">Baris Sebelumnya</translation>
-<translation id="7400575256015741911">Kesilapan ejaan dikesan</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">pulangan</translation>
-<translation id="7434509671034404296">Pembangun</translation>
-<translation id="7439060726180460871">Direktori</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Memasuki dialog</translation>
-<translation id="7532613204005497612">Jun</translation>
-<translation id="7540083713905917247">Peluncur, <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="7586163296341959563">tampal.</translation>
-<translation id="7596919493010894443">pilihan dikosongkan</translation>
-<translation id="7604026522577407655">Pergi ke permulaan lajur semasa</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Umumkan URL halaman semasa</translation>
-<translation id="7609363189280667021">Togol kapsyen braille</translation>
-<translation id="762020119231868829">Menjeda semua widget media yang sedang dimainkan</translation>
-<translation id="7625690649919402823">Jadual seterusnya</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Gred <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Tiada tajuk tahap 3 terdahulu.</translation>
-<translation id="7659376057562985921">Kotak teks, <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="7663318257180412551">Tajuk 2</translation>
-<translation id="7674576868851035240">Pautan seterusnya</translation>
-<translation id="7674768236845044097">tanda</translation>
-<translation id="7684431668231950609">Edit teks, masukan URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Butang radio sebelumnya</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748">Kotak teks kata laluan, <ph name="VALUE" />, <ph name="NAME" /></translation>
-<translation id="7805247615045262757">navigasi lalai</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Kumpulan Seterusnya</translation>
-<translation id="7819187121850078213">tab <ph name="TITLE" /> tetingkap</translation>
-<translation id="7828956995407538686">Oktober</translation>
-<translation id="7839679365527550018">Perkataan Sebelumnya</translation>
-<translation id="7851816175263618915">Beberapa tanda baca</translation>
-<translation id="7870596830398826354">Pepohon ML Matematik</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Togol ChromeVox klasik.</translation>
-<translation id="7895896691902835279">Pautan tidak diketahui</translation>
-<translation id="7927711904086083099">Tidak dipilih</translation>
-<translation id="7935627501098484003">Kawalan masa</translation>
-<translation id="7939428177581522200">ditambahkan pada pilihan</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{di}other{# tanda di}}</translation>
-<translation id="7965147473449754028">menu ditutup</translation>
-<translation id="7974390230414479278">Item menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{titik seru}other{# titik seru}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{tanda petikan}other{# tanda petikan}}</translation>
-<translation id="8033827949643255796">dipilih</translation>
-<translation id="8035962149453661158">maks:<ph name="X" /></translation>
-<translation id="8042761080832772327">Edit teks, masukan carian</translation>
-<translation id="8049189770492311300">Pemasa</translation>
-<translation id="8065607967589909823">Pilihannya ialah</translation>
-<translation id="8066678206530322333">Sepanduk</translation>
-<translation id="8110647606445335195">Tiada mercu tanda ARIA.</translation>
-<translation id="8153880621934657047">Bukan dalam jadual.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{garis bawah}other{# garis bawah}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">potong.</translation>
-<translation id="8199231515320852133">Umumkan pengepala sel semasa</translation>
-<translation id="820417203470636242">Sel kosong.</translation>
-<translation id="8215202828671303819">Berbilang pilihan</translation>
-<translation id="8276439074553447000">Langkau ke item boleh fokus sebelumnya</translation>
-<translation id="8278417001922463147">Tiada artikel sebelumnya.</translation>
-<translation id="8283603667300770666">Medan borang seterusnya</translation>
-<translation id="831207808878314375">Takrif</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">jam</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{paun}other{# tanda paun}}</translation>
-<translation id="8374154622594089836">bulan</translation>
-<translation id="8378855320830505539">Wilayah</translation>
-<translation id="8382679411218029383">Autolengkap sebaris dan senarai</translation>
-<translation id="8428603554127842284">tahap <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Tiada tajuk tahap 3 seterusnya.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Tiada kotak pilihan terdahulu.</translation>
-<translation id="8455868257606149352">Maks <ph name="X" /></translation>
-<translation id="84575901236241018">mempunyai kekunci akses, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Kurangkan kebutiran navigasi</translation>
-<translation id="8520472399088452386">Butang putar</translation>
-<translation id="8538744478902126321">Buat tekaan pada pengepala baris sel semasa</translation>
-<translation id="8540054775867439484">Dibalut ke atas</translation>
-<translation id="8548973727659841685">Aksara</translation>
-<translation id="8561322612995434619">mempunyai pop timbul</translation>
-<translation id="8571096049907249734">multisel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Item senarai seterusnya</translation>
-<translation id="860150890330522909">Kotak pilihan <ph name="NAME" /> ditandai</translation>
-<translation id="8606621670302093223">Kawalan tarikh</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> item dipilih</translation>
-<translation id="8638532244051952400">Umumkan koordinat sel semasa</translation>
-<translation id="8650576015643545550">Tiada senarai terdahulu.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Paparkan senarai pautan</translation>
-<translation id="8664519043722036194">saat</translation>
-<translation id="867187640362843212">Tajuk 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{paip}other{# paip menegak}}</translation>
-<translation id="8735450637152821465">Mulakan pemilihan</translation>
-<translation id="8743786158317878347">masukkan kandungan berstruktur, seperti jadual</translation>
-<translation id="8747966237988593539">Senarai Bertertib</translation>
-<translation id="8759334257841767240">Tiada pautan seterusnya.</translation>
-<translation id="8767968232364267681">Tajuk tahap 4 seterusnya</translation>
-<translation id="8770473310765924354">keluar dari kandungan berstruktur, seperti jadual</translation>
-<translation id="8791025954632646584">Semantik dihidupkan</translation>
-<translation id="8796411681063377102">Tajuk tahap 3 seterusnya</translation>
-<translation id="8808582214901541005">Mac</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">utama</translation>
-<translation id="8856538297388979332">Tekan atas atau bawah untuk menyemak perintah, tekan enter untuk mengaktifkannya</translation>
-<translation id="8864099967139188018">Tiada tajuk tahap 6 seterusnya.</translation>
-<translation id="8882002077197914455">Pengepala baris</translation>
-<translation id="8896347895970027998">Togol ChromeVox aktif atau tidak aktif.</translation>
-<translation id="8898516272131543774">Gema tanda baca kitaran</translation>
-<translation id="8900148057318340779">Kekunci awalan</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Pengepala kosong</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Kunci Pengubah Suai</translation>
-<translation id="8943175951035496220">Tiada sel di kanan.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">fail</translation>
-<translation id="9027462562263121875">Tiada jadual.</translation>
-<translation id="9040132695316389094">Tajuk 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Togol widget carian</translation>
-<translation id="9065283790526219006">+pop timbul</translation>
-<translation id="9077213568694924680">dialih keluar daripada pilihan</translation>
-<translation id="9082874451376019682">Tiada peluncur terdahulu.</translation>
-<translation id="9089864840575085222">Gema penaipan kitaran</translation>
-<translation id="9107530006868467849">Tiada widget media sebelumnya.</translation>
-<translation id="9108370397979208512">matematik</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{peratus}other{# tanda peratus}}</translation>
-<translation id="9115913704608474258">November</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Mengumumkan penerangan ringkas tentang kedudukan semasa</translation>
-<translation id="9153606228985488238">Nada <ph name="PERCENT" /> peratus</translation>
-<translation id="9160096769946561184">Pergi ke penghujung lajur semasa</translation>
-<translation id="9173115498289768110">Kelantangan <ph name="PERCENT" /> peratus</translation>
-<translation id="9178973770513562274">Gunakan kekunci anak panah atas dan bawah untuk menyemak imbas atau taip untuk mencari.</translation>
-<translation id="9192904702577636854">Marki</translation>
-<translation id="9212322457209634662">Tiada bahagian seterusnya.</translation>
-<translation id="930275611743429116">Mulakan atau tamatkan pemilihan.</translation>
-<translation id="948171205378458592">Kurangkan kadar pertuturan</translation>
-<translation id="962913030769097253">Tajuk tahap 1 seterusnya</translation>
-<translation id="973955474346881951">Dayakan/Lumpuhkan mod lekit</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_nl.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_nl.xtb
deleted file mode 100644
index 6fe7b575bc8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_nl.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="nl">
-<translation id="1012173283529841972">Lijstitem</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Omspannen.</translation>
-<translation id="1025074108959230262">Modus voor vastzetten uitgeschakeld</translation>
-<translation id="1031961866430398710">dan</translation>
-<translation id="1044777062731150180">Geen koppen</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Ongeldige invoer.</translation>
-<translation id="1082209053475788238">Geen vorige kop voor niveau 6.</translation>
-<translation id="1088219014394087294">Geen koppen.</translation>
-<translation id="1106741348836243114">Geluidsfeedback (earcons) in- of uitschakelen.</translation>
-<translation id="1120743664840974483">{"a": "alfa", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliett","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="TAG" />-collectie met <ph name="NUM" /> items</translation>
-<translation id="1155043339247954670">Geen volgend lijstitem.</translation>
-<translation id="1157782847298808853">Help bij toetsenbord</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, keuzelijst met invoervak</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, menu-item, met submenu</translation>
-<translation id="1177863135347784049">Aangepast</translation>
-<translation id="1188858454923323853">aanvullend</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Geef Chrome een stem</translation>
-<translation id="1229276918471378188">Vorige sprong</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Volgende kop voor niveau 6</translation>
-<translation id="1275718070701477396">Geselecteerd</translation>
-<translation id="1319608975892113573">Geen vorig blok met geciteerde tekst.</translation>
-<translation id="1321576897702511272">Help van ChromeVox verbergen</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> van <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">teken- en woordecho</translation>
-<translation id="1339428534620983148">Vorige kolom van tabel</translation>
-<translation id="1342835525016946179">artikel</translation>
-<translation id="1346748346194534595">Rechts</translation>
-<translation id="136718599399906424">Volgende rij van tabel</translation>
-<translation id="1383876407941801731">Zoeken</translation>
-<translation id="1385214448885562192">Druk op Enter om door te gaan of op Escape om te annuleren. Druk op de pijl-omlaag voor het volgende resultaat en op de pijl-omhoog voor het vorige resultaat.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">regio</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, tekstvak voor wachtwoord</translation>
-<translation id="1467432559032391204">Links</translation>
-<translation id="1474557363159888097">Geen vorig anker.</translation>
-<translation id="1502086903961450562">Vorige afbeelding</translation>
-<translation id="1506187449813838456">Toonhoogte verhogen</translation>
-<translation id="151784044608172266">Volgende zin</translation>
-<translation id="1524531499102321782">Volgende brailleregel</translation>
-<translation id="1546370775711804143">Schuifbalk</translation>
-<translation id="1559739829547075274">Terug navigeren</translation>
-<translation id="1571643229714746283">ChromeVox gereed</translation>
-<translation id="158493514907962286">december</translation>
-<translation id="1594072653727561613">menu</translation>
-<translation id="1610130962244179598">Overschakelen naar zespuntsbraille</translation>
-<translation id="1611168825862729585">Koptekst kolom:</translation>
-<translation id="1613476421962910979">Earcons aan</translation>
-<translation id="1618597272655350600">Geeft een volledige beschrijving van de huidige positie</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{groter-dan-teken}other{# groter-dan-tekens}}</translation>
-<translation id="1653266918374749391">Vorige kop voor niveau 3</translation>
-<translation id="1659072772017912254">Niet aangevinkt</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">ChromeVox-navigatie</translation>
-<translation id="16777221443363124">Menubalk</translation>
-<translation id="1692077714702418899">structurele regel</translation>
-<translation id="1700517974991662022">Bezocht</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">footer</translation>
-<translation id="174268867904053074">Volgende afbeelding</translation>
-<translation id="1781173782405573156">Overslatoets</translation>
-<translation id="1787176709638001873">Tekst voor bewerken wachtwoord</translation>
-<translation id="1810107444790159527">Keuzelijst</translation>
-<translation id="1828385960365606039">mei</translation>
-<translation id="1834891354138622109">Kolom</translation>
-<translation id="1865601187525349519">Einde van tekst</translation>
-<translation id="1876229593313240038">document</translation>
-<translation id="188130072164734898">De huidige datum en tijd uitspreken.</translation>
-<translation id="1902396333223336119">Cel</translation>
-<translation id="1905379170753160525">Lijst met koppen weergeven</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">genummerd</translation>
-<translation id="1954623340234317532">Bedieningselement voor week van het jaar</translation>
-<translation id="1964135212174907577">Volgend object</translation>
-<translation id="1969092762068865084">juli</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Koptekst rij:</translation>
-<translation id="2002895034995108595">Huidige toetsenindeling opnieuw instellen</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{vierkante haak links}other{# vierkante haken links}}</translation>
-<translation id="2045490512405922022">niet aangevinkt</translation>
-<translation id="20601713649439366">Geen vorige wiskundige uitdrukking.</translation>
-<translation id="207477615537953741">Semantiek uit</translation>
-<translation id="2086961585857038472">Volgend woord</translation>
-<translation id="2089387485033699258">nl</translation>
-<translation id="2091933974477985526">Vorig bewerkbaar tekstgebied</translation>
-<translation id="2100350898815792233">Volledige interpunctie</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">toegangstoets: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Wijzig de huidige tabel voor zespuntsbraille door een optie te selecteren in de onderstaande lijst.</translation>
-<translation id="2169714232367507776">Klikken op huidig item</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{haakje sluiten}other{# haakjes sluiten}}</translation>
-<translation id="2199994615414171367">Vorige wiskundige uitdrukking</translation>
-<translation id="2223693656926968778">Actie ondernemen voor huidig item</translation>
-<translation id="225732394367814946">Spreeksnelheid verhogen</translation>
-<translation id="2267945578749931355">Volgend teken</translation>
-<translation id="2281234842553884450">Vorige schuifbalk</translation>
-<translation id="2318372665160196757">Hoofd</translation>
-<translation id="2329324941084714723">Deelvenster met tabblad</translation>
-<translation id="2344193891939537199">Bedieningselement voor datum/tijd</translation>
-<translation id="2359897517538099099">Niet in tabelmodus.</translation>
-<translation id="241124561063364910">gevolgd door</translation>
-<translation id="2417569100218200841">Informatie over inhoud</translation>
-<translation id="2422937916923936891">Selectievakje voor menu-item</translation>
-<translation id="2429669115401274487">p.m.</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> is nu de nieuwe functietoets voor ChromeVox.</translation>
-<translation id="2450814015951372393">Selectievakje</translation>
-<translation id="2462626033734746142">Groep met keuzerondjes</translation>
-<translation id="2471138580042810658">Kop 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{sterretje}other{# sterretjes}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> is opnieuw ingesteld.</translation>
-<translation id="2553108862507765288">grammaticafout</translation>
-<translation id="257674075312929031">Groep</translation>
-<translation id="2582407057977008361">Terzijde</translation>
-<translation id="2589102159832527089">Deze pagina bevat de tekst die automatisch is opgehaald uit het pdf-bestand &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Klik hier voor het origineel.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">met {COUNT,plural, =1{# item}other{# items}}</translation>
-<translation id="2614981083756825552">MathML-indeling</translation>
-<translation id="2626530649491650971">klikbaar</translation>
-<translation id="2628764385451019380">Geen vorige keuzelijst met invoervak.</translation>
-<translation id="2637227747952042642">Wiskunde</translation>
-<translation id="2639750663247012216">ChromeVox-functietoets</translation>
-<translation id="2644542693584024604">spelfout</translation>
-<translation id="2667291555398229137">Klik op het item onder een routeringstoets</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{haakje openen}other{# haakjes openen}}</translation>
-<translation id="2705875883745373140">Niet ingedrukt</translation>
-<translation id="2706462751667573066">Omhoog</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">a.m.</translation>
-<translation id="2749275490991666823">Aangevinkt</translation>
-<translation id="27527859628328957">Springen naar volgend actief item</translation>
-<translation id="2770781857296573485">Groepsverkenning openen</translation>
-<translation id="2777845298774924149">Afgesloten</translation>
-<translation id="2800204403141299078">Niet meer verschillende elementen.</translation>
-<translation id="2800780099804980316">Geen vorige kop voor niveau 1.</translation>
-<translation id="2811204574343810641">Rij</translation>
-<translation id="2816654101880605877">Geen volgende schuifregelaar.</translation>
-<translation id="2841013758207633010">Tijd</translation>
-<translation id="2843837985843789981">Vorige groep</translation>
-<translation id="2844995807198708617">Contextmenu</translation>
-<translation id="2849332794118375855">Geen volgend selectievakje.</translation>
-<translation id="2864481629947106776">Vorige link</translation>
-<translation id="2873259058405069099">Naar het begin van de tabel gaan</translation>
-<translation id="2894654529758326923">Informatie</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{accolade links}other{# accolades links}}</translation>
-<translation id="2911433807131383493">ChromeVox-handleiding openen</translation>
-<translation id="2932083475399492303">Regeltype schakelen tussen structureel en indeling</translation>
-<translation id="2964026537669811554">Kopgroep</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tab}other{# tabs}}</translation>
-<translation id="2972078295414139404">Geen vorige bezochte link.</translation>
-<translation id="2972205263822847197">Knopinfo</translation>
-<translation id="2998131015536248178">Vorig teken</translation>
-<translation id="2999559350546931576">Toonhoogte verlagen</translation>
-<translation id="2999945368667127852">Geen volgende mediawidget.</translation>
-<translation id="3012414509011670858">Geen vorig gedeelte.</translation>
-<translation id="3030432017085518523">Keuzerondje voor menu-item</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}other{# apostrofs}}</translation>
-<translation id="3046838483509668188">ChromeVox-opties</translation>
-<translation id="3047143736589213134">Experimentele toetsenbordindeling</translation>
-<translation id="3060756054951570867">menu <ph name="TITLE" /> geopend</translation>
-<translation id="3078345202707391975">Volgende kop voor niveau 2</translation>
-<translation id="3078740164268491126">tabel</translation>
-<translation id="3082557070674409251">Aangeklikt</translation>
-<translation id="3084806535845658316">geen typecho</translation>
-<translation id="3086746722712840547">opmerking</translation>
-<translation id="308895241372589742">Geen volgende wiskundige uitdrukking.</translation>
-<translation id="3090532668523289635">groep</translation>
-<translation id="3093176084511590672">Volgend oriëntatiepunt</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">waarschuwingsvenster</translation>
-<translation id="3109724472072898302">Samengevouwen</translation>
-<translation id="3134461040845705080">alleen-lezen</translation>
-<translation id="3138767756593758860">Lijst met oriëntatiepunten weergeven</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Volgende regel</translation>
-<translation id="3155083529632865074">Geen vorige knop.</translation>
-<translation id="3163593631834463955">Lege koptekst kolom</translation>
-<translation id="316542773973815724">Navigatie</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{spatie}other{# spaties}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> geopend</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, tabblad</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Bezochte link</translation>
-<translation id="323731244387692321">Help voor ChromeVox-toetsenbord openen</translation>
-<translation id="3241052487511142956">Vorige bezochte link</translation>
-<translation id="3286390186030710347">Schuifregelaar</translation>
-<translation id="3299925995433437805">Geen volgende bezochte link.</translation>
-<translation id="3303384412438961941">Druk op een willekeurige toets om de naam ervan te horen. Met Ctrl+W sluit je de toetsenbordverkennner.</translation>
-<translation id="3307886118343381874">Naar het einde van de tabel gaan</translation>
-<translation id="3311969765485641742">Druk op Alt+Shift+A om waarschuwingen te bekijken</translation>
-<translation id="3312997241656799641">Volgende bezochte link</translation>
-<translation id="3321460131042519426">Tekstterugloop inschakelen</translation>
-<translation id="3322936298410871309">Vorige kop voor niveau 1</translation>
-<translation id="3323447499041942178">Tekstvak</translation>
-<translation id="3353420241558113817">{"ar": "Arabisch",
- "bg": "Bulgaars",
- "ca": "Catalaans",
- "cs": "Tsjechisch",
- "da": "Deens",
- "de": "Duits",
- "de_CH": "Duits (Zwitserland)",
- "de_DE": "Duits (Duitsland)",
- "el": "Grieks",
- "en": "Engels",
- "en_CA": "Engels (Canada)",
- "en_GB": "Engels (Verenigd Koninkrijk)",
- "en_US": "Engels (Verenigde Staten)",
- "es": "Spaans",
- "et": "Ests",
- "fr": "Frans",
- "fr_CA": "Frans (Canada)",
- "fr_FR": "Frans (Frankrijk)",
- "fi": "Fins",
- "he": "Hebreeuws",
- "hi": "Hindi",
- "hr": "Kroatisch",
- "hu": "Hongaars",
- "is": "IJslands",
- "it": "Italiaans",
- "ko": "Koreaans",
- "lt": "Litouws",
- "lv": "Lets",
- "nb": "Noors (Bokmål)",
- "nl": "Nederlands",
- "pl": "Pools",
- "pt": "Portugees",
- "ro": "Roemeens",
- "ru": "Russisch",
- "sk": "Slowaaks",
- "sl": "Sloveens",
- "sr": "Servisch",
- "sv": "Zweeds",
- "tr": "Turks",
- "vi": "Vietnamees",
- "zh": "Chinees",
- "zh_TW": "Chinees (Traditioneel Han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plusteken}other{# plustekens}}</translation>
-<translation id="338583716107319301">Separator</translation>
-<translation id="3389259863310851658">Vorig formulierveld</translation>
-<translation id="3390225400784126843">Volgend ander element.</translation>
-<translation id="3392045790598181549"><ph name="NAME" /> , menu-item</translation>
-<translation id="3406283310380167331">Lijst met formulieren weergeven</translation>
-<translation id="3422338090358345848">Toetsenbordverkenner openen</translation>
-<translation id="3457000393508828486">Gedeeltelijk ingedrukt</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, knop</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> gesel.</translation>
-<translation id="3486232535569802404"><ph name="V1" /> tot en met <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{vierkante haak rechts}other{# vierkante haken rechts}}</translation>
-<translation id="3493915602752813531">Geen volgend anker.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{vraagteken}other{# vraagtekens}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{caret-teken}other{# caret-tekens}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" /> , selectievakje niet aangevinkt</translation>
-<translation id="3599054940393788245">Valt niet onder wiskunde</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{accent grave}other{# accents grave}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollarteken}other{# dollartekens}}</translation>
-<translation id="3659787053479271466">waarschuwing</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, keuzelijst</translation>
-<translation id="3687295507293856493">Schat de kop van de kolom van de huidige cel</translation>
-<translation id="3692274950075847560">Z:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Spraak beheren</translation>
-<translation id="3716845769494773620">Meerdere regels</translation>
-<translation id="3731746171184829332">Geen vorige kop.</translation>
-<translation id="3762198587642264450">Naar het einde van de huidige rij gaan</translation>
-<translation id="3777255250339039212">k1</translation>
-<translation id="3793710123303304873">Dialoogvenster afgesloten.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Automatisch lijst aanvullen</translation>
-<translation id="3810838688059735925">Videobestanden</translation>
-<translation id="3816633764618089385">Volgende media</translation>
-<translation id="3819376190738087562">Geen sprongen.</translation>
-<translation id="385383972552776628">Pagina met opties openen</translation>
-<translation id="3856075812838139784">Alleen-lezen</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Vorige kop voor niveau 6</translation>
-<translation id="3914173277599553213">Vereist</translation>
-<translation id="3962990492275676168">Beginnen met lezen vanaf huidige locatie</translation>
-<translation id="4004802134384979325">aangevinkt</translation>
-<translation id="4006140876663370126">afbeelding</translation>
-<translation id="4038349100599457191">Maandbeheer</translation>
-<translation id="4039983576244166038">Lege koptekst rij</translation>
-<translation id="4042843249978639960">Geen volgende kop voor niveau 2.</translation>
-<translation id="4043348641337972076">Geen vorig ARIA-oriëntatiepunt.</translation>
-<translation id="4047216625641135770">Markeren</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">status</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{tilde}other{# tildes}}</translation>
-<translation id="409334809956508737">Vorig object</translation>
-<translation id="4099274309791143834">met submenu</translation>
-<translation id="4107807507418787238">Geen cel hieronder beschikbaar.</translation>
-<translation id="4116415223832267137">Waarschuwing</translation>
-<translation id="4147126331795725888">Geen volgend besturingselement.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{accolade rechts}other{# accolades rechts}}</translation>
-<translation id="4158704014418536539">Hoofdlettergevoelig</translation>
-<translation id="4161663686871496107">Gesproken ChromeVox-feedback is gereed</translation>
-<translation id="4173994908659439270">Geen volgend bewerkbaar tekstveld.</translation>
-<translation id="4176463684765177261">Uitgeschakeld</translation>
-<translation id="4188530942454211480">Vorige zin</translation>
-<translation id="4202186506458631436">Naar rechts verplaatsen</translation>
-<translation id="4206289001967551965">In tabel</translation>
-<translation id="4215733775853809057">Volgende schuifbalk</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{streepje}other{# streepjes}}</translation>
-<translation id="421884353938374759">kleurkiezer</translation>
-<translation id="4229646983878045487">datum tijd</translation>
-<translation id="423334822609210999">Geen cel aan de linkerkant beschikbaar.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, niveau <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Opmerking</translation>
-<translation id="4254798249533888099">Structuur</translation>
-<translation id="4255943572433203166">Gebruik de opties hieronder om ChromeVox aan te passen. Wijzigingen worden onmiddellijk van kracht.</translation>
-<translation id="4271220233568730077">Volgende wiskundige uitdrukking</translation>
-<translation id="4271521365602459209">Geen andere resultaten.</translation>
-<translation id="4287520460805643128">Geen volgend artikel.</translation>
-<translation id="4289540628985791613">Overzicht</translation>
-<translation id="4300318234632215983">De URL achter een link melden</translation>
-<translation id="4301352596632316575">heeft submenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punt}=3{ellipsis}other{# punten}}</translation>
-<translation id="4347461890115250064">Geen volgende lijst.</translation>
-<translation id="4367650418938037324">MathML-blad</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Spraak stoppen</translation>
-<translation id="4373197658375206385">Geen vorig item dat geen link is.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Geen links.</translation>
-<translation id="4476183483923481720">nieuwe regel</translation>
-<translation id="4482330759234983253">Vorige tabel</translation>
-<translation id="4491109536499578614">Afbeelding</translation>
-<translation id="4529987814483543472">Klassieke toetsenbordindeling</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{slash}other{# slashes}}</translation>
-<translation id="4547556996012970016">Volgende kop voor niveau 5</translation>
-<translation id="4562381607973973258">Koptekst</translation>
-<translation id="4591507479202817876">, geselecteerd</translation>
-<translation id="4597532268155981612">formulier</translation>
-<translation id="4597896406374528575">april</translation>
-<translation id="4615592953348396470">Volgende toetsaanslag wordt genegeerd</translation>
-<translation id="461613135510474570">Zin</translation>
-<translation id="4647836961514597010">Kleurenkiezer</translation>
-<translation id="4661075872484491155">structuur</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">raster</translation>
-<translation id="4693675773662933727">Vorig oriëntatiepunt</translation>
-<translation id="4696413482802371445">Geen volgende kop voor niveau 5.</translation>
-<translation id="4729095194763193578">Vorige rij van tabel</translation>
-<translation id="4736221692378411923">augustus</translation>
-<translation id="4740661827607246557">Help-opdrachten</translation>
-<translation id="4759716709594980008">ChromeOS-toetsenbordverkenner</translation>
-<translation id="4763296182459741068">Omloop naar beneden</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">zoeken</translation>
-<translation id="481165870889056555">De titel van de huidige pagina melden</translation>
-<translation id="4826415162591436065">Verder navigeren</translation>
-<translation id="4826604887384865800">Volgende sprong</translation>
-<translation id="4827410568042294688">niet geselecteerd</translation>
-<translation id="4842108708071771135">Geen volgend blok met geciteerde tekst.</translation>
-<translation id="4848993367330139335">timer</translation>
-<translation id="4850023505158945298">Vorig vergelijkbaar element.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS-registratie inschakelen</translation>
-<translation id="4877261390094455813">Een zoekopdracht opgeven.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Interne link</translation>
-<translation id="4953585991029886728">Tekst bewerken</translation>
-<translation id="4954534434583049121">Vorig blok met geciteerde tekst</translation>
-<translation id="4973717656530883744">Min. <ph name="X" /></translation>
-<translation id="4973762002207131920">Overgeschakeld naar <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milliseconden</translation>
-<translation id="49787999531187221">ChromeVox is nu inactief.</translation>
-<translation id="4979404613699303341">Knop 'Vorige'</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, keuzelijst</translation>
-<translation id="4983588134362688868">Naar de bovenkant van de pagina</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, venster</translation>
-<translation id="4993152509206108683">Snelheid <ph name="PERCENT" /> procent</translation>
-<translation id="4996716799442435517">Visueel</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, keuzerondje geselecteerd</translation>
-<translation id="4997475792277222884">Geen volgend item dat geen link is.</translation>
-<translation id="5000760171916499057">Geen formulieren.</translation>
-<translation id="5005670136041063723">Niet meer vergelijkbare elementen.</translation>
-<translation id="501473567976723023">januari</translation>
-<translation id="5041394372352067729">Brailleweergave naar bovenkant pagina verplaatsen</translation>
-<translation id="5042770794184672516">Spraakvolume verhogen</translation>
-<translation id="5050015258024679800">Vorige kop voor niveau 4</translation>
-<translation id="5054047268577924192">Vorig item in de lijst</translation>
-<translation id="5078661581131202757">Bestand selecteren</translation>
-<translation id="5080758118274074384">Gedubbelklikt</translation>
-<translation id="5098541983634824365">Raster verlaten.</translation>
-<translation id="5102981729317424850">Werkbalk</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Geen vorig formulierveld.</translation>
-<translation id="5111640677200759579">Kolomkop</translation>
-<translation id="5117636609870536415">gemaild</translation>
-<translation id="5136967254288895616">Geen vorige link.</translation>
-<translation id="513774504516943387">link</translation>
-<translation id="517143700877085897">, niet geselecteerd</translation>
-<translation id="5183440668879371625">Vorige brailleregel</translation>
-<translation id="5184944171021383281">Geen volgend formulierveld.</translation>
-<translation id="5189244881767082992">Regel</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> is al toegewezen aan een opdracht.</translation>
-<translation id="5205493599117157272">Lijst voor <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Geen volgend keuzerondje.</translation>
-<translation id="5263344797180442561">k2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Object</translation>
-<translation id="5304943142864553931">tabblad <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">verwijderd:</translation>
-<translation id="5320727453979144100">Modus voor vastzetten ingeschakeld</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{komma}other{# komma's}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, tekstvak</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Achteruit springen tijdens doorlopend lezen</translation>
-<translation id="5368000168321181111">Earcons uit</translation>
-<translation id="5374320867641260420">Geen volgende knop.</translation>
-<translation id="5382299583965267720">Geen volgende kop voor niveau 1.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{puntkomma}other{# puntkomma's}}</translation>
-<translation id="5411891038905756502">Geen vorig punt om naar te springen.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{kleiner-dan-teken}other{# kleiner-dan-tekens}}</translation>
-<translation id="5455441614648621694">Aanvullend</translation>
-<translation id="5485036206801896268">Geen vorige afbeelding.</translation>
-<translation id="5486947920110100234">Geen volgend punt om naar te springen.</translation>
-<translation id="549602578321198708">Woord</translation>
-<translation id="5500932716852106146">Geen vorig bewerkbaar tekstveld.</translation>
-<translation id="5502713021410870035">september</translation>
-<translation id="5507663321906818013">Benchmarkfouten opsporen</translation>
-<translation id="5518443085409638729">De cursor tussen tekens plaatsen bij het bewerken van tekst (zoals Mac OS X).</translation>
-<translation id="552195134157544755">Keuzerondje</translation>
-<translation id="5534303576632885660">header</translation>
-<translation id="5546092960038624944">Geen vorige kop voor niveau 5.</translation>
-<translation id="556042886152191864">Knop</translation>
-<translation id="5561345396546889625">Volgende lijst</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Tekst bewerken, e-mailinvoer</translation>
-<translation id="5597170376237141345">Volgend selectievakje</translation>
-<translation id="5597933780944041114">Geen volgende kop.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, keuzerondje niet geselecteerd</translation>
-<translation id="5601172225407283979">Standaardactie uitvoeren</translation>
-<translation id="5608798115546226984">Automatisch inline aanvullen</translation>
-<translation id="561939826962581046">tijd</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Logboek</translation>
-<translation id="5628125749885014029">k4</translation>
-<translation id="5637871198229500030">Geen vorige tabel.</translation>
-<translation id="5655682562155942719">Navigatieopdrachten</translation>
-<translation id="56637627897541303">Tekstgebied</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">definitie</translation>
-<translation id="5682113568322255809">Oriëntatiepunt</translation>
-<translation id="5683155931978483559">Vorig selectievakje</translation>
-<translation id="5684277895745049190">Lijst</translation>
-<translation id="5700650669149824506">Geen vorige kop voor niveau 4.</translation>
-<translation id="5709192780268610569">Geen lange beschrijving</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Volgende kolom van tabel</translation>
-<translation id="571866080859340309">Groepen verkennen</translation>
-<translation id="5728409797179002635">Geen tabel gevonden.</translation>
-<translation id="5748623122140342504">Vorige kop voor niveau 5</translation>
-<translation id="5750633686117194034">Er is geen functietoets ingedrukt. Raak een of meer functietoetsen aan, til je vingers op zodra je klaar bent en je hoort dat de toetsen zijn ingedrukt. Druk op Tab om te sluiten.</translation>
-<translation id="5788275253279308023">incognitovenster, tabblad <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Specifieke sites (zoals Google Zoeken) verbeteren.</translation>
-<translation id="5819072574982403430">Structuuritem</translation>
-<translation id="5826479389509458994">rij <ph name="ROW" /> kolom <ph name="COL" /></translation>
-<translation id="5850707923114094062">Achteruitschuiven</translation>
-<translation id="5851548754964597211">Tabbladlijst</translation>
-<translation id="5859752971144398932">Zoeken op pagina afgesloten.</translation>
-<translation id="5866042630553435010">Gedeeltelijk gecontroleerd</translation>
-<translation id="5869546221129391014">Raster</translation>
-<translation id="5876817486144482042">Spraakvolume verlagen</translation>
-<translation id="5887397643266327462">Braille-ondertiteling ingeschakeld.</translation>
-<translation id="5891934789323004067">Tabel</translation>
-<translation id="5919442531159595654">kopiëren.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{gelijkteken}other{# gelijktekens}}</translation>
-<translation id="5939518447894949180">Terugzetten</translation>
-<translation id="5948123859135882163">Interpretatie van wiskundige formules schakelen tussen structureel en semantisch</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialoogvenster</translation>
-<translation id="5963413905009737549">Sectie</translation>
-<translation id="5968607524793740041">Contextmenu weergeven</translation>
-<translation id="5983179082906765664">Detailniveau van navigatie vergroten</translation>
-<translation id="5999630716831179808">Stemmen</translation>
-<translation id="6000417740266304866">Wijzig de huidige tabel voor achtpuntsbraille door een optie te selecteren in de onderstaande lijst.</translation>
-<translation id="6006050241733874051">Formulier</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{backslash}other{# backslashes}}</translation>
-<translation id="6037602951055904232">Vooruit schuiven</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Einde van de cel.</translation>
-<translation id="6122013438240733403">knop</translation>
-<translation id="6129953537138746214">Spatie</translation>
-<translation id="6142308968191113180">Kop 4</translation>
-<translation id="6169420925157477918">Afbeelding met lange beschrijving</translation>
-<translation id="6172087735260766220">Kan toegankelijke tekst niet openen vanuit een pdf met kopieerbeveiliging.</translation>
-<translation id="6186305613600865047">Naar de onderkant van de pagina</translation>
-<translation id="6193330012414963395">a.m./p.m.</translation>
-<translation id="622484624075952240">Omlaag</translation>
-<translation id="6236061028292614533">Volgende kop</translation>
-<translation id="6254901459154107917">Volgend bewerkbaar tekstgebied</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> afgesloten.</translation>
-<translation id="6281876499889881039">Volgend vergelijkbaar element.</translation>
-<translation id="6282062888058716985">navigatie</translation>
-<translation id="6290434000785343030">Geen volgende keuzelijst met invoervak.</translation>
-<translation id="6307969636681130414">Ingedrukt.</translation>
-<translation id="6324551002951139333">Grammaticafout ontdekt</translation>
-<translation id="6348657800373377022">Keuzelijst met invoervak</translation>
-<translation id="6355910664415701303">Geen vorig lijstitem.</translation>
-<translation id="6364795331201459219">k6</translation>
-<translation id="6368143427468974988">Vorige kop</translation>
-<translation id="6387719785439924554">terzijde</translation>
-<translation id="6411426777058107714">Geen vorig keuzerondje.</translation>
-<translation id="6414968628640960377">Vorig ander element.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dubbelepunt}other{# dubbelepunten}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Dialoogvenster voor meldingen</translation>
-<translation id="6459511626086141404">Platte toetsenbordindeling</translation>
-<translation id="6468049171101508116">Volgende knop</translation>
-<translation id="6491972999578897419">Wijzig de huidige stem door een optie in de onderstaande lijst te selecteren.</translation>
-<translation id="6508059270146105198">Brailleweergave naar onderkant pagina verplaatsen</translation>
-<translation id="6536864053412760904">MathML-token</translation>
-<translation id="6550720799683018100">Wijzig de huidige toetsenbordindeling door een optie in de onderstaande lijst te selecteren.</translation>
-<translation id="6561818612645211875">Naar het begin van de huidige rij gaan</translation>
-<translation id="6587021927234520429">Geen volgende kop voor niveau 4.</translation>
-<translation id="6601344353291556895">Uitgebreide beschrijvingen inschakelen.</translation>
-<translation id="6615602925644411249">Zoeken op pagina.</translation>
-<translation id="6633350132811819843">Geen volgende tabel.</translation>
-<translation id="6637586476836377253">logboek</translation>
-<translation id="6657128831881431364">Voortgangsbalk</translation>
-<translation id="6659594942844771486">Tabblad</translation>
-<translation id="667999046851023355">Document</translation>
-<translation id="6697092096875747123">Vorige keuzelijst met invoervak</translation>
-<translation id="6714813999819678458">Vorige kop voor niveau 2</translation>
-<translation id="6716505898850596801">Functietoetsen</translation>
-<translation id="671916444866103745">Geen volgend ARIA-oriëntatiepunt.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, keuzelijst met invoervak</translation>
-<translation id="6735257939857578167">met <ph name="NUM" /> items</translation>
-<translation id="6736510033526053669">tabblad gemaakt</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artikel</translation>
-<translation id="6787839852456839824">Sneltoetsen</translation>
-<translation id="6793101435925451627">keuzelijst</translation>
-<translation id="6833103209700200188">Voettekst</translation>
-<translation id="6871161210040114857">Hoofdlettergebruik wordt genegeerd.</translation>
-<translation id="6877435256196695200">Geen volgende afbeelding.</translation>
-<translation id="6897341342232909480">Naar links verplaatsen</translation>
-<translation id="6901540140423170855">datum</translation>
-<translation id="6910211073230771657">Verwijderd</translation>
-<translation id="6911965441508464308">Geen cel hierboven beschikbaar.</translation>
-<translation id="6919104639734799681">Lijst met tabellen weergeven</translation>
-<translation id="6964088412282673743">Geen vorig besturingselement.</translation>
-<translation id="6996566555547746822">Volgende keuzelijst met invoervak</translation>
-<translation id="7005146664810010831">Geen URL gevonden</translation>
-<translation id="7010712454773919705">ChromeVox-functietoets</translation>
-<translation id="7031651751836475482">lijstitem</translation>
-<translation id="7037042857287298941">Vorige lijst</translation>
-<translation id="7041173719775863268">Selectie eindigen</translation>
-<translation id="7095834689119144465">Tekst alleen numeriek bewerken</translation>
-<translation id="7096001299300236431">Vorige media</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">woordecho</translation>
-<translation id="713824876195128146">Volgend blok met geciteerde tekst</translation>
-<translation id="7161771961008409533">Pop-up-knop</translation>
-<translation id="7167657087543110">tekenecho</translation>
-<translation id="7170733337935166589">Vooruit springen tijdens doorlopend lezen</translation>
-<translation id="7181697990050180700">Pas de sneltoetsen voor vaak gebruikte opdrachten aan door deze in de bijbehorende velden hieronder te typen.</translation>
-<translation id="7203150201908454328">Uitgevouwen</translation>
-<translation id="7210211103303402262">minuten</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">regel</translation>
-<translation id="7226216518520804442">lijst</translation>
-<translation id="72393384879519786">Kop</translation>
-<translation id="7241683698754534149">Lange beschrijving openen op een nieuw tabblad</translation>
-<translation id="7248671827512403053">Applicatie</translation>
-<translation id="725969808843520477">Volgend keuzerondje</translation>
-<translation id="7269119382257320590">Geen interpunctie</translation>
-<translation id="7273174640290488576">Leeg</translation>
-<translation id="7285387653379749618">Tabellen</translation>
-<translation id="7289186959554153431">Kop 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Braille-ondertiteling uitgeschakeld.</translation>
-<translation id="7318872822751139669">Gebruik de muis om de focus te wijzigen.</translation>
-<translation id="7322388933135261569">februari</translation>
-<translation id="7332592614823088566">Rij <ph name="ROWINDEX" /> van <ph name="ROWTOTAL" />, kolom <ph name="COLINDEX" /> van <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">heeft pop-up</translation>
-<translation id="7356165926712028380">Overschakelen naar achtpuntsbraille</translation>
-<translation id="7362871137496673139">Geen vorige kop voor niveau 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersand}other{# ampersands}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Tabel verlaten.</translation>
-<translation id="739763518212184081">Vorige regel</translation>
-<translation id="7400575256015741911">Spelfout gedetecteerd</translation>
-<translation id="7408482676469142474">tabel</translation>
-<translation id="7425395583360211003">Enter-teken</translation>
-<translation id="7434509671034404296">Ontwikkelaar</translation>
-<translation id="7439060726180460871">Directory</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Geopend dialoogvenster</translation>
-<translation id="7532613204005497612">juni</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, schuifbalk</translation>
-<translation id="7586163296341959563">plakken.</translation>
-<translation id="7596919493010894443">selectie gewist</translation>
-<translation id="7604026522577407655">Naar het begin van de huidige kolom gaan</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">De URL van de huidige pagina melden</translation>
-<translation id="7609363189280667021">Brailleondertiteling in- en uitschakelen</translation>
-<translation id="762020119231868829">Hiermee worden alle actieve mediawidgets onderbroken</translation>
-<translation id="7625690649919402823">Volgende tabel</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), niveau <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Geen vorige kop voor niveau 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, tekstvak</translation>
-<translation id="7663318257180412551">Kop 2</translation>
-<translation id="7674576868851035240">Volgende link</translation>
-<translation id="7674768236845044097">markeren</translation>
-<translation id="7684431668231950609">Tekst bewerken, URL-invoer</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Vorig keuzerondje</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, tekstvak voor wachtwoord</translation>
-<translation id="7805247615045262757">standaardnavigatie</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Volgende groep</translation>
-<translation id="7819187121850078213">venster, tabblad <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">oktober</translation>
-<translation id="7839679365527550018">Vorig woord</translation>
-<translation id="7851816175263618915">Gedeeltelijke interpunctie</translation>
-<translation id="7870596830398826354">MathML-structuur</translation>
-<translation id="78826985582142166">schuif</translation>
-<translation id="7894517696028036636">Overschakelen naar klassieke versie van ChromeVox.</translation>
-<translation id="7895896691902835279">Onbekende link</translation>
-<translation id="7927711904086083099">Niet geselecteerd</translation>
-<translation id="7935627501098484003">Tijdbeheer</translation>
-<translation id="7939428177581522200">toegevoegd aan selectie</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{apenstaartje}other{# apenstaartjes}}</translation>
-<translation id="7965147473449754028">menu gesloten</translation>
-<translation id="7974390230414479278">Menu-item</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{uitroepteken}other{# uitroeptekens}}</translation>
-<translation id="8007540374018858731">k3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{aanhalingsteken}other{# aanhalingstekens}}</translation>
-<translation id="8033827949643255796">geselecteerd</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">Tekst bewerken, zoekinvoer</translation>
-<translation id="8049189770492311300">Timer</translation>
-<translation id="8065607967589909823">Selectie is</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Geen ARIA-oriëntatiepunten.</translation>
-<translation id="8153880621934657047">Niet in tabel.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{underscore}other{# underscores}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">knippen.</translation>
-<translation id="8199231515320852133">De koppen van de huidige cel melden</translation>
-<translation id="820417203470636242">Lege cel.</translation>
-<translation id="8215202828671303819">Meervoudige selectie</translation>
-<translation id="8276439074553447000">Springen naar vorig actief item</translation>
-<translation id="8278417001922463147">Geen vorig artikel.</translation>
-<translation id="8283603667300770666">Volgend formulierveld</translation>
-<translation id="831207808878314375">Definitie</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">uren</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{hekje}other{# hekjes}}</translation>
-<translation id="8374154622594089836">maand</translation>
-<translation id="8378855320830505539">Regio</translation>
-<translation id="8382679411218029383">Automatisch inline en lijst aanvullen</translation>
-<translation id="8428603554127842284">niveau <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Geen volgende kop voor niveau 3.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Geen vorig selectievakje.</translation>
-<translation id="8455868257606149352">Max. <ph name="X" /></translation>
-<translation id="84575901236241018">heeft toegangscode, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Detailniveau van navigatie verkleinen</translation>
-<translation id="8520472399088452386">Kringveld</translation>
-<translation id="8538744478902126321">Schat de kop van de rij van de huidige cel</translation>
-<translation id="8540054775867439484">Omloop naar boven</translation>
-<translation id="8548973727659841685">Teken</translation>
-<translation id="8561322612995434619">heeft pop-up</translation>
-<translation id="8571096049907249734">multisel</translation>
-<translation id="8584721346566392021">k5</translation>
-<translation id="8587549812518406253">Volgend item in de lijst</translation>
-<translation id="860150890330522909">selectievakje <ph name="NAME" /> aangevinkt</translation>
-<translation id="8606621670302093223">Datumbeheer</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> items geselecteerd</translation>
-<translation id="8638532244051952400">Huidige celcoördinaten bekendmaken</translation>
-<translation id="8650576015643545550">Geen vorige lijst.</translation>
-<translation id="8653031188082306838">met url</translation>
-<translation id="8653646212587894517">Lijst met links weergeven</translation>
-<translation id="8664519043722036194">seconden</translation>
-<translation id="867187640362843212">Kop 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{pijpteken}other{# verticale pijptekens}}</translation>
-<translation id="8735450637152821465">Selectie beginnen</translation>
-<translation id="8743786158317878347">gestructureerde inhoud openen, zoals tabellen</translation>
-<translation id="8747966237988593539">Geordende lijst</translation>
-<translation id="8759334257841767240">Geen volgende link.</translation>
-<translation id="8767968232364267681">Volgende kop voor niveau 4</translation>
-<translation id="8770473310765924354">gestructureerde inhoud verlaten, zoals tabellen</translation>
-<translation id="8791025954632646584">Semantiek aan</translation>
-<translation id="8796411681063377102">Volgende kop voor niveau 3</translation>
-<translation id="8808582214901541005">maart</translation>
-<translation id="8825828890761629845">banner</translation>
-<translation id="8851136666856101339">hoofd</translation>
-<translation id="8856538297388979332">Druk de toets omhoog of omlaag om opdrachten te bekijken of druk op Enter om te activeren</translation>
-<translation id="8864099967139188018">Geen volgende kop voor niveau 6.</translation>
-<translation id="8882002077197914455">Rijkop</translation>
-<translation id="8896347895970027998">ChromeVox instellen op actief of inactief.</translation>
-<translation id="8898516272131543774">Interpunctie-echo doorlopen</translation>
-<translation id="8900148057318340779">Voorvoegseltoets</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Lege koppen</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Aanpassingstoetsen</translation>
-<translation id="8943175951035496220">Geen cel aan de rechterkant.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">bestand</translation>
-<translation id="9027462562263121875">Geen tabellen.</translation>
-<translation id="9040132695316389094">Kop 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Zoekwidget in-/uitschakelen</translation>
-<translation id="9065283790526219006">+pop-up</translation>
-<translation id="9077213568694924680">uit selectie verwijderd</translation>
-<translation id="9082874451376019682">Geen vorige schuifregelaar.</translation>
-<translation id="9089864840575085222">Typecho doorlopen</translation>
-<translation id="9107530006868467849">Geen vorige mediawidget.</translation>
-<translation id="9108370397979208512">wiskunde</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{procentteken}other{# procenttekens}}</translation>
-<translation id="9115913704608474258">november</translation>
-<translation id="9128414153595658330">dialoogvenster</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Geeft een korte beschrijving van de huidige positie</translation>
-<translation id="9153606228985488238">Toonhoogte <ph name="PERCENT" /> procent</translation>
-<translation id="9160096769946561184">Naar het einde van de huidige kolom gaan</translation>
-<translation id="9173115498289768110">Volume <ph name="PERCENT" /> procent</translation>
-<translation id="9178973770513562274">Gebruik de pijl-omhoog en -omlaag om te browsen of typ om te zoeken.</translation>
-<translation id="9192904702577636854">Rollende tekst (marquee)</translation>
-<translation id="9212322457209634662">Geen volgend gedeelte.</translation>
-<translation id="930275611743429116">Selectie starten of beëindigen.</translation>
-<translation id="948171205378458592">Spreeksnelheid verlagen</translation>
-<translation id="962913030769097253">Volgende kop voor niveau 1</translation>
-<translation id="973955474346881951">Modus voor vastzetten in-/uitschakelen</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_no.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_no.xtb
deleted file mode 100644
index 23f67edbd1a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_no.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="no">
-<translation id="1012173283529841972">Listeelement</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Sammenslåtte celler.</translation>
-<translation id="1025074108959230262">Trege taster er slått av</translation>
-<translation id="1031961866430398710">deretter</translation>
-<translation id="1044777062731150180">Ingen overskrifter</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Ugyldige inndata</translation>
-<translation id="1082209053475788238">Det finnes ikke tidligere overskrifter på nivå 6.</translation>
-<translation id="1088219014394087294">Det fins ingen overskrifter.</translation>
-<translation id="1106741348836243114">Slå tilbakemelding via lydsignaler av eller på.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu", "æ": "ærlig", "ø": "østen", "å": "Åse"}</translation>
-<translation id="113582498867142724">Samling av <ph name="TAG" /> med <ph name="NUM" /> elementer</translation>
-<translation id="1155043339247954670">Det finnes ikke flere listeelementer.</translation>
-<translation id="1157782847298808853">Tastaturhjelp</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, kombinasjonsfelt</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, menyelement, med undermeny</translation>
-<translation id="1177863135347784049">Tilpasset</translation>
-<translation id="1188858454923323853">komplementær</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – gir Chrome en stemme</translation>
-<translation id="1229276918471378188">Forrige hopp</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Neste overskrift på nivå 6</translation>
-<translation id="1275718070701477396">Valgt</translation>
-<translation id="1319608975892113573">Det finnes ingen tidligere blokksitat-elementer.</translation>
-<translation id="1321576897702511272">Skjul hjelp for ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> av <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">tegn- og ordekko</translation>
-<translation id="1339428534620983148">Forrige tabellkolonne</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Høyre</translation>
-<translation id="136718599399906424">Neste tabellrad</translation>
-<translation id="1383876407941801731">Søk</translation>
-<translation id="1385214448885562192">Trykk på Enter for å godta, Esc for å avbryte, ned for neste eller opp for forrige.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, tekstfelt for passord</translation>
-<translation id="1467432559032391204">Venstre</translation>
-<translation id="1474557363159888097">Det finnes ingen tidligere ankere.</translation>
-<translation id="1502086903961450562">Forrige illustrasjon</translation>
-<translation id="1506187449813838456">Øk stemmeleiet</translation>
-<translation id="151784044608172266">Neste setning</translation>
-<translation id="1524531499102321782">Punktskrift – neste linje</translation>
-<translation id="1546370775711804143">Rullefelt</translation>
-<translation id="1559739829547075274">Naviger bakover</translation>
-<translation id="1571643229714746283">ChromeVox er klar</translation>
-<translation id="158493514907962286">Desember</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Bytt til 6-punkts punktskrift</translation>
-<translation id="1611168825862729585">Kolonneoverskrift:</translation>
-<translation id="1613476421962910979">Lydsignaler er på</translation>
-<translation id="1618597272655350600">Kunngjør en fullstendig beskrivelse av den gjeldende posisjonen</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{større enn}other{# større enn-tegn}}</translation>
-<translation id="1653266918374749391">Forrige overskrift på nivå 3</translation>
-<translation id="1659072772017912254">Ikke avmerket</translation>
-<translation id="1669290819662866522">uke</translation>
-<translation id="1674262202423278359">ChromeVox-navigering</translation>
-<translation id="16777221443363124">Menyrad</translation>
-<translation id="1692077714702418899">strukturlinje</translation>
-<translation id="1700517974991662022">Besøkt.</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Neste illustrasjon</translation>
-<translation id="1781173782405573156">Passér-tast</translation>
-<translation id="1787176709638001873">Tekst for redigering av passord</translation>
-<translation id="1810107444790159527">Listeboks:</translation>
-<translation id="1828385960365606039">Mai</translation>
-<translation id="1834891354138622109">Kolonne</translation>
-<translation id="1865601187525349519">Slutt på teksten</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Snakk inn nåværende dato og klokkeslett.</translation>
-<translation id="1902396333223336119">Rutenettcelle</translation>
-<translation id="1905379170753160525">Vis overskriftsliste</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Kontroll av ukenummer</translation>
-<translation id="1964135212174907577">Neste objekt</translation>
-<translation id="1969092762068865084">Juli</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Radoverskrift:</translation>
-<translation id="2002895034995108595">Tilbakestill gjeldende tastaturoppsett</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{venstre hakeparentes}other{# venstre hakeparenteser}}</translation>
-<translation id="2045490512405922022">ikke avmerket</translation>
-<translation id="20601713649439366">Det finnes ingen tidligere matteuttrykk.</translation>
-<translation id="207477615537953741">Semantikk av</translation>
-<translation id="2086961585857038472">Neste ord</translation>
-<translation id="2089387485033699258">no</translation>
-<translation id="2091933974477985526">Forrige redigerbare tekstområde</translation>
-<translation id="2100350898815792233">All tegnsetting</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">tilgangsnøkkel: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Endre den gjeldende tabellen for 6-punkts punktskrift ved å velge et alternativ fra listen nedenfor.</translation>
-<translation id="2169714232367507776">Klikk på det aktuelle elementet</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{høyreparentes}other{# høyreparenteser}}</translation>
-<translation id="2199994615414171367">Forrige matteuttrykk</translation>
-<translation id="2223693656926968778">Gjør noe med det aktuelle elementet</translation>
-<translation id="225732394367814946">Øk talehastigheten</translation>
-<translation id="2267945578749931355">Neste tegn</translation>
-<translation id="2281234842553884450">Forrige glidebryter</translation>
-<translation id="2318372665160196757">Hovedelement</translation>
-<translation id="2329324941084714723">Fanepanel</translation>
-<translation id="2344193891939537199">Kontroll av dato/tidspunkt</translation>
-<translation id="2359897517538099099">Tabellmodus er ikke aktiv.</translation>
-<translation id="241124561063364910">etterfulgt av</translation>
-<translation id="2417569100218200841">Innholdsinformasjon</translation>
-<translation id="2422937916923936891">Avmerkingsrute for menyelement</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> er nå den nye ChromeVox-modifikatoren.</translation>
-<translation id="2450814015951372393">Avmerkingsrute</translation>
-<translation id="2462626033734746142">Gruppe med alternativknapper</translation>
-<translation id="2471138580042810658">Overskrift 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisk}other{# asterisker}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> er tilbakestilt.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Gruppe</translation>
-<translation id="2582407057977008361">Aside-tag</translation>
-<translation id="2589102159832527089">Denne siden inneholder teksten som automatisk ble hentet ut av PDF-filen &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Klikk her for å se originalen.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">med {COUNT,plural, =1{# element}other{# elementer}}</translation>
-<translation id="2614981083756825552">MathML-utforming</translation>
-<translation id="2626530649491650971">klikkbart</translation>
-<translation id="2628764385451019380">Det finnes ingen tidligere kombinasjonsbokser.</translation>
-<translation id="2637227747952042642">Matematikk</translation>
-<translation id="2639750663247012216">ChromeVox-modifikator</translation>
-<translation id="2644542693584024604">feilstavet</translation>
-<translation id="2667291555398229137">Klikk på elementet under en rutingnøkkel</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{venstreparentes}other{# venstreparenteser}}</translation>
-<translation id="2705875883745373140">Ikke trykket på</translation>
-<translation id="2706462751667573066">Opp</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">lyd</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Avmerket</translation>
-<translation id="27527859628328957">Gå til neste fokuserbare element</translation>
-<translation id="2770781857296573485">Kjør gruppeutforsking</translation>
-<translation id="2777845298774924149">Lukket</translation>
-<translation id="2800204403141299078">Det er ingen flere ulike elementer.</translation>
-<translation id="2800780099804980316">Det finnes ikke tidligere overskrifter på nivå 1.</translation>
-<translation id="2811204574343810641">Rad</translation>
-<translation id="2816654101880605877">Det fins ikke flere glidebrytere.</translation>
-<translation id="2841013758207633010">Klokkeslett</translation>
-<translation id="2843837985843789981">Forrige gruppe</translation>
-<translation id="2844995807198708617">Hurtigmeny</translation>
-<translation id="2849332794118375855">Det er ikke flere avmerkingsruter.</translation>
-<translation id="2864481629947106776">Forrige link</translation>
-<translation id="2873259058405069099">Gå til øverst i tabellen</translation>
-<translation id="2894654529758326923">Informasjon</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{venstre klammeparentes}other{# venstre klammeparenteser}}</translation>
-<translation id="2911433807131383493">Åpne ChromeVox-veiledningen</translation>
-<translation id="2932083475399492303">Veksle linjetypen mellom strukturell og utforming</translation>
-<translation id="2964026537669811554">Overskriftsgruppe</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulator}other{# tabulatorer}}</translation>
-<translation id="2972078295414139404">Ingen tidligere besøkt link.</translation>
-<translation id="2972205263822847197">Verktøytips</translation>
-<translation id="2998131015536248178">Forrige tegn</translation>
-<translation id="2999559350546931576">Reduser stemmeleiet</translation>
-<translation id="2999945368667127852">Det finnes ingen neste mediamodul.</translation>
-<translation id="3012414509011670858">Det finnes ingen forrige del.</translation>
-<translation id="3030432017085518523">Alternativknapp for menyelement</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}other{# apostrofer}}</translation>
-<translation id="3046838483509668188">Alternativer for ChromeVox</translation>
-<translation id="3047143736589213134">Eksperimentelt tastaturoppsett</translation>
-<translation id="3060756054951570867"><ph name="TITLE" />-menyen er åpen</translation>
-<translation id="3078345202707391975">Neste overskrift på nivå 2</translation>
-<translation id="3078740164268491126">tabell</translation>
-<translation id="3082557070674409251">Ble klikket på</translation>
-<translation id="3084806535845658316">uten inntastingsekko</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Det finnes ingen neste matteuttrykk.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Neste landemerke</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Skjult</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Vis liste over landemerker</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Neste linje</translation>
-<translation id="3155083529632865074">Det fins ingen foregående knapp.</translation>
-<translation id="3163593631834463955">Tom kolonneoverskrift</translation>
-<translation id="316542773973815724">Navigering</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{mellomrom}other{# mellomrom}}</translation>
-<translation id="320961988183078793">angitt <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />-fane</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Besøkt link.</translation>
-<translation id="323731244387692321">Åpne tastaturhjelp for ChromeVox</translation>
-<translation id="3241052487511142956">Tidligere besøkt link</translation>
-<translation id="3286390186030710347">Glidebryter</translation>
-<translation id="3299925995433437805">Ingen neste besøkte link.</translation>
-<translation id="3303384412438961941">Trykk på en tast for å finne ut hva den heter. Ctrl + W lukker tastaturutforskeren.</translation>
-<translation id="3307886118343381874">Gå til slutten av tabellen</translation>
-<translation id="3311969765485641742">Trykk på Alt+Shift+A for å gjennomgå varslene</translation>
-<translation id="3312997241656799641">Neste besøkte link</translation>
-<translation id="3321460131042519426">Slå på tekstbryting</translation>
-<translation id="3322936298410871309">Forrige overskrift på nivå 1</translation>
-<translation id="3323447499041942178">Tekstboks</translation>
-<translation id="3353420241558113817">{"ar": "Arabisk",
- "bg": "Bulgarsk",
- "ca": "Katalansk",
- "cs": "Tsjekkisk",
- "da": "Dansk",
- "de": "Tysk",
- "de_CH": "Tysk (Sveits)",
- "de_DE": "Tysk (Tyskland)",
- "el": "Gresk",
- "en": "Engelsk",
- "en_CA": "Engelsk (Canada)",
- "en_GB": "Engelsk (Storbritannia)",
- "en_US": "Engelsk (USA)",
- "es": "Spansk",
- "et": "Estisk",
- "fr": "Fransk",
- "fr_CA": "Fransk (Canada)",
- "fr_FR": "Fransk (Frankrike)",
- "fi": "Finsk",
- "he": "Hebraisk",
- "hi": "Hindi",
- "hr": "Kroatisk",
- "hu": "Ungarsk",
- "is": "Islandsk",
- "it": "Italiensk",
- "ko": "Koreansk",
- "lt": "Litauisk",
- "lv": "Latvisk",
- "nb": "Norsk bokmål",
- "nl": "Nederlandsk",
- "pl": "Polsk",
- "pt": "Portugisisk",
- "ro": "Rumensk",
- "ru": "Russisk",
- "sk": "Slovakisk",
- "sl": "Slovensk",
- "sr": "Serbisk",
- "sv": "Svensk",
- "tr": "Tyrkisk",
- "vi": "Vietnamesisk",
- "zh": "Kinesisk",
- "zh_TW": "Kinesisk (tradisjonell han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{pluss}other{# plusstegn}}</translation>
-<translation id="338583716107319301">Skillelinje</translation>
-<translation id="3389259863310851658">Forrige skjemafelt</translation>
-<translation id="3390225400784126843">Neste ulike element.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, menyelement</translation>
-<translation id="3406283310380167331">Vis skjemalisten</translation>
-<translation id="3422338090358345848">Åpne tastaturutforskeren</translation>
-<translation id="3457000393508828486">Delvis trykket på</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, knapp</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> til <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{høyre hakeparentes}other{# høyre hakeparenteser}}</translation>
-<translation id="3493915602752813531">Det er ikke flere ankere.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{spørsmålstegn}other{# spørsmålstegn}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{circumflekstegn}other{# circumflekstegn}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, avmerkingsruten er ikke avmerket</translation>
-<translation id="3599054940393788245">Utenfor matematisk uttrykk</translation>
-<translation id="3616113530831147358">Lyd</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{venstreaksent}other{# venstreaksenter}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollar}other{# dollartegn}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, listefelt</translation>
-<translation id="3687295507293856493">Gjett kolonneoverskriften i den nåværende cellen</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Kontroll av tale</translation>
-<translation id="3716845769494773620">Flere linjer</translation>
-<translation id="3731746171184829332">Det finnes ingen tidligere overskrifter.</translation>
-<translation id="3762198587642264450">Gå til slutten av den gjeldende raden</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Lukket dialogen.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Autofullføringsliste</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Neste media</translation>
-<translation id="3819376190738087562">Det finnes ingenting å gå til.</translation>
-<translation id="385383972552776628">Åpne siden med alternativer</translation>
-<translation id="3856075812838139784">Skrivebeskyttet</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Meny</translation>
-<translation id="3909320334364316587">Forrige overskrift på nivå 6</translation>
-<translation id="3914173277599553213">Påkrevd</translation>
-<translation id="3962990492275676168">Begynn å lese fra nåværende plassering</translation>
-<translation id="4004802134384979325">merket av</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Månedskontroll</translation>
-<translation id="4039983576244166038">Tom radoverskrift</translation>
-<translation id="4042843249978639960">Det finnes ikke flere overskrifter på nivå 2.</translation>
-<translation id="4043348641337972076">Det finnes ingen tidligere ARIA-landemerker.</translation>
-<translation id="4047216625641135770">Mark-tag</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDE}other{# tilder}}</translation>
-<translation id="409334809956508737">Forrige objekt</translation>
-<translation id="4099274309791143834">med undermeny</translation>
-<translation id="4107807507418787238">Det finnes ikke noen celler nedenfor.</translation>
-<translation id="4116415223832267137">Varsel</translation>
-<translation id="4147126331795725888">Det finnes ingen neste kontroll.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{høyre klammeparentes}other{# høyre klammeparenteser}}</translation>
-<translation id="4158704014418536539">Skiller mellom store og små bokstaver.</translation>
-<translation id="4161663686871496107">Muntlig tilbakemelding med ChromeVox er klar</translation>
-<translation id="4173994908659439270">Det finnes ingen flere redigerbare tekstområder.</translation>
-<translation id="4176463684765177261">Deaktivert</translation>
-<translation id="4188530942454211480">Forrige setning</translation>
-<translation id="4202186506458631436">Flytt til høyre</translation>
-<translation id="4206289001967551965">Inne i tabellen</translation>
-<translation id="4215733775853809057">Neste glidebryter</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{tankestrek}other{# tankestreker}}</translation>
-<translation id="421884353938374759">fargevelger</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">Det er ingen celler igjen.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, klasse <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Merknad</translation>
-<translation id="4254798249533888099">Tre</translation>
-<translation id="4255943572433203166">Bruk alternativene nedenfor for å tilpasse ChromeVox. Endringene trer i kraft umiddelbart.</translation>
-<translation id="4271220233568730077">Neste matteuttrykk</translation>
-<translation id="4271521365602459209">Det er ingen flere resultater.</translation>
-<translation id="4287520460805643128">Det finnes ikke flere artikler.</translation>
-<translation id="4289540628985791613">Oversikt</translation>
-<translation id="4300318234632215983">Kunngjør nettadressen bak en link</translation>
-<translation id="4301352596632316575">har undermeny</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punktum}=3{ellipse}other{# punktum}}</translation>
-<translation id="4347461890115250064">Det finnes ikke flere lister.</translation>
-<translation id="4367650418938037324">MathML-blad</translation>
-<translation id="4372435075475052704">min.: <ph name="X" /></translation>
-<translation id="4372705107434148843">Stopp tale</translation>
-<translation id="4373197658375206385">Det finnes ingen tidligere elementer som ikke er linker.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Det fins ingen linker.</translation>
-<translation id="4476183483923481720">ny linje</translation>
-<translation id="4482330759234983253">Forrige tabell</translation>
-<translation id="4491109536499578614">Bilde</translation>
-<translation id="4529987814483543472">Klassisk tastaturoppsett</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{skråstrek}other{# skråstreker}}</translation>
-<translation id="4547556996012970016">Neste overskrift på nivå 5</translation>
-<translation id="4562381607973973258">Topptekst</translation>
-<translation id="4591507479202817876">, valgt</translation>
-<translation id="4597532268155981612">skjema</translation>
-<translation id="4597896406374528575">April</translation>
-<translation id="4615592953348396470">Ignorerer neste tastetrykk</translation>
-<translation id="461613135510474570">Setning</translation>
-<translation id="4647836961514597010">Fargevelger</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Forrige landemerke</translation>
-<translation id="4696413482802371445">Det finnes ikke flere overskrifter på nivå 5.</translation>
-<translation id="4729095194763193578">Forrige tabellrad</translation>
-<translation id="4736221692378411923">August</translation>
-<translation id="4740661827607246557">Kommandoer for Hjelp</translation>
-<translation id="4759716709594980008">Tastaturutforsker for Chrome OS</translation>
-<translation id="4763296182459741068">Legges sammen nederst</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">søk</translation>
-<translation id="481165870889056555">Kunngjør tittelen på den nåværende siden</translation>
-<translation id="4826415162591436065">Naviger fremover</translation>
-<translation id="4826604887384865800">Neste hopp</translation>
-<translation id="4827410568042294688">fjernet fra utvalget</translation>
-<translation id="4842108708071771135">Det finnes ikke flere blokksitat-elementer.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Forrige lignende element.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Slå på TTS-loggføring</translation>
-<translation id="4877261390094455813">Angi et søkeord.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Intern link</translation>
-<translation id="4953585991029886728">Rediger teksten</translation>
-<translation id="4954534434583049121">Forrige blokksitat</translation>
-<translation id="4973717656530883744">Minimum <ph name="X" /></translation>
-<translation id="4973762002207131920">Byttet til <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">millisekunder</translation>
-<translation id="49787999531187221">Nå er ChromeVox slått av.</translation>
-<translation id="4979404613699303341">Forrige-knappen</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, listefelt</translation>
-<translation id="4983588134362688868">Går til begynnelsen av siden</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, vindu</translation>
-<translation id="4993152509206108683">Hastighet – <ph name="PERCENT" /> prosent</translation>
-<translation id="4996716799442435517">Visuell</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, alternativknappen valgt</translation>
-<translation id="4997475792277222884">Det finnes ingen påfølgende elementer som ikke er linker.</translation>
-<translation id="5000760171916499057">Det finnes ingen skjemaer.</translation>
-<translation id="5005670136041063723">Det er ingen flere lignende elementer.</translation>
-<translation id="501473567976723023">Januar</translation>
-<translation id="5041394372352067729">Flytt leselisten til toppen av siden</translation>
-<translation id="5042770794184672516">Øk talevolumet</translation>
-<translation id="5050015258024679800">Forrige overskrift på nivå 4</translation>
-<translation id="5054047268577924192">Forrige listeelement</translation>
-<translation id="5078661581131202757">Filvalg</translation>
-<translation id="5080758118274074384">ble dobbeltklikket på</translation>
-<translation id="5098541983634824365">Forlater rutenettet.</translation>
-<translation id="5102981729317424850">Verktøyrad</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Det fins ikke noe foregående skjemafelt.</translation>
-<translation id="5111640677200759579">Kolonneoverskrift</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Det finnes ingen tidligere linker.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, ikke valgt</translation>
-<translation id="5183440668879371625">Punktskrift – forrige linje</translation>
-<translation id="5184944171021383281">Det finnes ikke flere skjemafelt.</translation>
-<translation id="5189244881767082992">Linje</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> er allerede tilordnet en kommando.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" />-liste.</translation>
-<translation id="520883772648104506">Det finnes ikke flere alternativknapper.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objekt</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />-fane</translation>
-<translation id="5310788376443009632">fjernet:</translation>
-<translation id="5320727453979144100">Trege taster er slått på</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{komma}other{# kommaer}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, tekstfelt</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Hopp bakover under kontinuerlig lesing</translation>
-<translation id="5368000168321181111">Lydsignaler er av</translation>
-<translation id="5374320867641260420">Det finnes ikke flere knapper.</translation>
-<translation id="5382299583965267720">Det fins ikke flere overskrifter på nivå 1.</translation>
-<translation id="5402367795255837559">Punktskrift</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{semikolon}other{# semikolontegn}}</translation>
-<translation id="5411891038905756502">Det finnes ingen tidligere punkter å gå til.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{mindre enn}other{# mindre enn-tegn}}</translation>
-<translation id="5455441614648621694">Komplementær</translation>
-<translation id="5485036206801896268">Det finnes ingen tidligere bilder.</translation>
-<translation id="5486947920110100234">Det finnes ingen flere punkter å gå til.</translation>
-<translation id="549602578321198708">Ord</translation>
-<translation id="5500932716852106146">Det finnes ingen tidligere redigerbare tekstområder.</translation>
-<translation id="5502713021410870035">September</translation>
-<translation id="5507663321906818013">Feilsøk referansemålingen</translation>
-<translation id="5518443085409638729">Plasser markøren mellom tegn når du redigerer tekst (som i Mac OS X).</translation>
-<translation id="552195134157544755">Alternativknapp</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Det finnes ikke tidligere overskrifter på nivå 5.</translation>
-<translation id="556042886152191864">Knapp</translation>
-<translation id="5561345396546889625">Neste liste</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Tilbake-tasten</translation>
-<translation id="5585044216466955529">Rediger tekst – e-postinnhold</translation>
-<translation id="5597170376237141345">Neste avmerkingsrute</translation>
-<translation id="5597933780944041114">Det finnes ikke flere overskrifter.</translation>
-<translation id="5598905979683743333">Alternativknappen <ph name="NAME" /> er ikke valgt</translation>
-<translation id="5601172225407283979">Utfør standardhandling</translation>
-<translation id="5608798115546226984">Innebygd autofullføring</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Logg</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Det finnes ingen tidligere tabeller.</translation>
-<translation id="5655682562155942719">Gå til-kommandoer</translation>
-<translation id="56637627897541303">Tekstområde</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Landemerke</translation>
-<translation id="5683155931978483559">Forrige avmerkingsrute</translation>
-<translation id="5684277895745049190">Liste</translation>
-<translation id="5700650669149824506">Det finnes ikke tidligere overskrifter på nivå 4.</translation>
-<translation id="5709192780268610569">Ingen lang beskrivelse</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Neste tabellkolonne</translation>
-<translation id="571866080859340309">Utforsking av grupper</translation>
-<translation id="5728409797179002635">Fant ingen tabell.</translation>
-<translation id="5748623122140342504">Forrige overskrift på nivå 5</translation>
-<translation id="5750633686117194034">Du har ikke trykt på noen modifikatorer. Trykk på og hold inne én eller flere modifikatorer. Slipp dem når du er ferdig for å høre tastene du har trykket på. Trykk på tabulatortasten for å avslutte.</translation>
-<translation id="5788275253279308023">inkognitovinduet med <ph name="TITLE" />-fanen</translation>
-<translation id="5806206155699461681">Forbedre bestemte nettsteder (som Google Søk).</translation>
-<translation id="5819072574982403430">Treelementet</translation>
-<translation id="5826479389509458994">rad <ph name="ROW" /> kolonne <ph name="COL" /></translation>
-<translation id="5850707923114094062">Panorer bakover</translation>
-<translation id="5851548754964597211">Faneliste</translation>
-<translation id="5859752971144398932">Lukket «finn på siden».</translation>
-<translation id="5866042630553435010">Delvis avmerket</translation>
-<translation id="5869546221129391014">Rutenett</translation>
-<translation id="5876817486144482042">Reduser talevolumet</translation>
-<translation id="5887397643266327462">Punktskrift-teksting er slått på.</translation>
-<translation id="5891934789323004067">Tabell</translation>
-<translation id="5919442531159595654">kopiér.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{likhetstegn}other{# likhetstegn}}</translation>
-<translation id="5939518447894949180">Tilbakestill</translation>
-<translation id="5948123859135882163">Bytt mellom strukturell og semantisk tolkning av matematiske uttrykk</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialog</translation>
-<translation id="5963413905009737549">Del</translation>
-<translation id="5968607524793740041">Vis den kontekstuelle menyen</translation>
-<translation id="5983179082906765664">Øk detaljnivået for navigeringen</translation>
-<translation id="5999630716831179808">Stemmer</translation>
-<translation id="6000417740266304866">Endre den gjeldende tabellen for 8-punkts punktskrift ved å velge et alternativ fra listen nedenfor.</translation>
-<translation id="6006050241733874051">Skjema</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{omvendt skråstrek}other{# omvendte skråstreker}}</translation>
-<translation id="6037602951055904232">Panorer frem</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Slutten av cellen.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Mellomrom</translation>
-<translation id="6142308968191113180">Overskrift 4</translation>
-<translation id="6169420925157477918">Bilde med lang beskrivelse</translation>
-<translation id="6172087735260766220">Kan ikke åpne tilgjengelig tekst fra kopibeskyttet PDF-fil.</translation>
-<translation id="6186305613600865047">Gå til nederst på siden</translation>
-<translation id="6193330012414963395">AM/PM</translation>
-<translation id="622484624075952240">Ned</translation>
-<translation id="6236061028292614533">Neste overskrift</translation>
-<translation id="6254901459154107917">Neste redigerbare tekstområde</translation>
-<translation id="6259464875943891919">Avsluttet <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Neste lignende element.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Det finnes ikke flere kombinasjonsfelt.</translation>
-<translation id="6307969636681130414">Trykket på</translation>
-<translation id="6324551002951139333">En grammatisk feil er oppdaget</translation>
-<translation id="6348657800373377022">Kombinasjonsboks</translation>
-<translation id="6355910664415701303">Det finnes ingen tidligere listeelementer.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Forrige overskrift</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Det finnes ingen tidligere alternativknapper.</translation>
-<translation id="6414968628640960377">Forrige ulike element.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{kolon}other{# kolontegn}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, meny</translation>
-<translation id="6444046323172968959">Varseldialog</translation>
-<translation id="6459511626086141404">Flatt tastaturoppsett</translation>
-<translation id="6468049171101508116">Neste-knappen</translation>
-<translation id="6491972999578897419">Endre den gjeldende stemmen ved å velge et alternativ fra listen nedenfor.</translation>
-<translation id="6508059270146105198">Flytt leselisten til nederst på siden</translation>
-<translation id="6536864053412760904">MathML-token</translation>
-<translation id="6550720799683018100">Endre det gjeldende tastaturoppsettet ved å velge et alternativ fra listen nedenfor.</translation>
-<translation id="6561818612645211875">Gå til begynnelsen av nåværende rad</translation>
-<translation id="6587021927234520429">Det finnes ikke flere overskrifter på nivå 4.</translation>
-<translation id="6601344353291556895">Slå på omfattende beskrivelser.</translation>
-<translation id="6615602925644411249">Finn på siden.</translation>
-<translation id="6633350132811819843">Det finnes ikke flere tabeller.</translation>
-<translation id="6637586476836377253">logg</translation>
-<translation id="6657128831881431364">Fremdriftsrad</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Forrige kombinasjonsfelt</translation>
-<translation id="6714813999819678458">Forrige overskrift på nivå 2</translation>
-<translation id="6716505898850596801">Modifikatortaster</translation>
-<translation id="671916444866103745">Det finnes ikke flere ARIA-landemerker.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, kombinasjonsfelt</translation>
-<translation id="6735257939857578167">med <ph name="NUM" /> elementer</translation>
-<translation id="6736510033526053669">fanen er opprettet</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artikkel</translation>
-<translation id="6787839852456839824">Hurtigtaster</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Bunntekst</translation>
-<translation id="6871161210040114857">Skiller ikke mellom store og små bokstaver.</translation>
-<translation id="6877435256196695200">Det finnes ikke flere illustrasjoner.</translation>
-<translation id="6897341342232909480">Flytt til venstre</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Slettet</translation>
-<translation id="6911965441508464308">Det finnes ikke noen celler ovenfor.</translation>
-<translation id="6919104639734799681">Vis tabellisten</translation>
-<translation id="6964088412282673743">Det finnes ingen forrige kontroll.</translation>
-<translation id="6996566555547746822">Neste kombinasjonsfelt</translation>
-<translation id="7005146664810010831">Fant ingen nettadresse</translation>
-<translation id="7010712454773919705">ChromeVox-modifikatortast</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Forrige liste</translation>
-<translation id="7041173719775863268">Avslutt markeringen</translation>
-<translation id="7095834689119144465">Rediger bare tallene i teksten</translation>
-<translation id="7096001299300236431">Forrige media</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">ordekko</translation>
-<translation id="713824876195128146">Neste blokksitat-element</translation>
-<translation id="7161771961008409533">Knapp med forgrunnsvindu</translation>
-<translation id="7167657087543110">tegnekko</translation>
-<translation id="7170733337935166589">Hopp fremover under kontinuerlig lesing</translation>
-<translation id="7181697990050180700">Tilpass hurtigtaster for kommandoer du bruker ofte, ved å skrive dem inn i de tilhørende feltene nedenfor.</translation>
-<translation id="7203150201908454328">Utvidet</translation>
-<translation id="7210211103303402262">minutter</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">linje</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Overskrift</translation>
-<translation id="7241683698754534149">Åpne lange beskrivelser i en ny fane</translation>
-<translation id="7248671827512403053">App</translation>
-<translation id="725969808843520477">Neste alternativknapp</translation>
-<translation id="7269119382257320590">Ingen tegnsetting</translation>
-<translation id="7273174640290488576">Tom</translation>
-<translation id="7285387653379749618">Tabeller</translation>
-<translation id="7289186959554153431">Overskrift 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Punktskrift-teksting er slått av.</translation>
-<translation id="7318872822751139669">Bruk musen til å endre fokuset.</translation>
-<translation id="7322388933135261569">Februar</translation>
-<translation id="7332592614823088566">Rad <ph name="ROWINDEX" /> av <ph name="ROWTOTAL" />, kolonne <ph name="COLINDEX" /> av <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">har forgrunnsvindu</translation>
-<translation id="7356165926712028380">Bytt til 8-punkts punktskrift</translation>
-<translation id="7362871137496673139">Det finnes ikke tidligere overskrifter på nivå 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{og-tegn}other{# og-tegn}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Forlater tabellen.</translation>
-<translation id="739763518212184081">Forrige linje</translation>
-<translation id="7400575256015741911">En stavefeil er oppdaget</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">retur</translation>
-<translation id="7434509671034404296">Utvikler</translation>
-<translation id="7439060726180460871">Katalog</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Åpnet dialogen</translation>
-<translation id="7532613204005497612">Juni</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, glidebryter</translation>
-<translation id="7586163296341959563">lim inn.</translation>
-<translation id="7596919493010894443">utvalget ble tømt</translation>
-<translation id="7604026522577407655">Gå til begynnelsen av den nåværende kolonnen</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Kunngjør nettadressen til den nåværende siden</translation>
-<translation id="7609363189280667021">Slå punktskriftteksting av eller på</translation>
-<translation id="762020119231868829">Setter alle mediemoduler som spilles av, på pause</translation>
-<translation id="7625690649919402823">Neste tabell</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), grad <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Det finnes ikke tidligere overskrifter på nivå 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, tekstfelt</translation>
-<translation id="7663318257180412551">Overskrift 2</translation>
-<translation id="7674576868851035240">Neste link</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">Rediger tekst – nettadresseoppføring</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Forrige alternativknapp</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, tekstfelt for passord</translation>
-<translation id="7805247615045262757">standardnavigasjon</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Neste gruppe</translation>
-<translation id="7819187121850078213">vinduet med <ph name="TITLE" />-fanen</translation>
-<translation id="7828956995407538686">Oktober</translation>
-<translation id="7839679365527550018">Forrige ord</translation>
-<translation id="7851816175263618915">Noe tegnsetting</translation>
-<translation id="7870596830398826354">MathML-tre</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Slå klassisk ChromeVox på eller av.</translation>
-<translation id="7895896691902835279">Ukjent link</translation>
-<translation id="7927711904086083099">Ikke valgt</translation>
-<translation id="7935627501098484003">Tidskontroll</translation>
-<translation id="7939428177581522200">lagt til i utvalget</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{krøllalfa}other{# krøllalfategn}}</translation>
-<translation id="7965147473449754028">menyen er lukket</translation>
-<translation id="7974390230414479278">Menyelement</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{utropstegn}other{# utropstegn}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{anførselstegn}other{# anførselstegn}}</translation>
-<translation id="8033827949643255796">valgt</translation>
-<translation id="8035962149453661158">maks.: <ph name="X" /></translation>
-<translation id="8042761080832772327">Rediger tekst – søkeord</translation>
-<translation id="8049189770492311300">Tidtaker</translation>
-<translation id="8065607967589909823">Utvalget er</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Det finnes ingen ARIA-landmerker.</translation>
-<translation id="8153880621934657047">Ikke inne i tabellen.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{understrek}other{# understreker}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">klipp ut.</translation>
-<translation id="8199231515320852133">Kunngjør overskriftene i den nåværende cellen</translation>
-<translation id="820417203470636242">Tom celle.</translation>
-<translation id="8215202828671303819">Flervalg</translation>
-<translation id="8276439074553447000">Gå til forrige fokuserbare element</translation>
-<translation id="8278417001922463147">Ingen tidligere artikler.</translation>
-<translation id="8283603667300770666">Neste skjemafelt</translation>
-<translation id="831207808878314375">Definisjon</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">timer</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{firkanttegn}other{# firkanttegn}}</translation>
-<translation id="8374154622594089836">måned</translation>
-<translation id="8378855320830505539">Region</translation>
-<translation id="8382679411218029383">Autofullføring – innebygd og liste</translation>
-<translation id="8428603554127842284">nivå <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Det finnes ikke flere overskrifter på nivå 3.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Det finnes ingen tidligere avmerkingsruter.</translation>
-<translation id="8455868257606149352">Maksimum <ph name="X" /></translation>
-<translation id="84575901236241018">har tilgangstast, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Reduser detaljnivået på navigeringen</translation>
-<translation id="8520472399088452386">Verdisettingsknapp</translation>
-<translation id="8538744478902126321">Gjett radoverskriften i den nåværende cellen</translation>
-<translation id="8540054775867439484">Legges sammen øverst</translation>
-<translation id="8548973727659841685">Tegn</translation>
-<translation id="8561322612995434619">har forgrunnsvindu</translation>
-<translation id="8571096049907249734">flervalg</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Neste listepunkt</translation>
-<translation id="860150890330522909"><ph name="NAME" />-ruten er avmerket</translation>
-<translation id="8606621670302093223">Datokontroll</translation>
-<translation id="8631359288236106450">valgte <ph name="COUNT" /> elementer</translation>
-<translation id="8638532244051952400">Les opp gjeldende cellekoordinater</translation>
-<translation id="8650576015643545550">Det finnes ingen tidligere lister.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Vis linklisten</translation>
-<translation id="8664519043722036194">sekunder</translation>
-<translation id="867187640362843212">Overskrift 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{loddrett strek}other{# loddrette streker}}</translation>
-<translation id="8735450637152821465">Start markeringen</translation>
-<translation id="8743786158317878347">åpne strukturert innhold, for eksempel tabeller</translation>
-<translation id="8747966237988593539">Nummerert liste</translation>
-<translation id="8759334257841767240">Det finnes ikke flere linker.</translation>
-<translation id="8767968232364267681">Neste overskrift på nivå 4</translation>
-<translation id="8770473310765924354">avslutt strukturert innhold, for eksempel tabeller</translation>
-<translation id="8791025954632646584">Semantikk på</translation>
-<translation id="8796411681063377102">Neste overskrift på nivå 3</translation>
-<translation id="8808582214901541005">Mars</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Trykk opp eller ned for å se gjennom kommandoene, og trykk på Enter for å slå på</translation>
-<translation id="8864099967139188018">Det finnes ikke flere overskrifter på nivå 6.</translation>
-<translation id="8882002077197914455">Radoverskrift</translation>
-<translation id="8896347895970027998">Velg om ChromeVox skal være på eller av.</translation>
-<translation id="8898516272131543774">Slå av eller på tegnsettingsekko</translation>
-<translation id="8900148057318340779">Prefikstast</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Tomme overskrifter</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Modifikatortaster</translation>
-<translation id="8943175951035496220">Det finnes ingen celler til høyre.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Det finnes ingen tabeller.</translation>
-<translation id="9040132695316389094">Overskrift 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Slå av og på søkemodulen</translation>
-<translation id="9065283790526219006">+forgrunnsvindu</translation>
-<translation id="9077213568694924680">fjernet fra utvalget</translation>
-<translation id="9082874451376019682">Det fins ingen tidligere glidebrytere.</translation>
-<translation id="9089864840575085222">Slå av eller på innskrivingsekko</translation>
-<translation id="9107530006868467849">Det finnes ingen tidligere mediemoduler.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{prosent}other{# prosenttegn}}</translation>
-<translation id="9115913704608474258">November</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Kunngjør en kort beskrivelse av den gjeldende posisjonen</translation>
-<translation id="9153606228985488238">Stemmeleie – <ph name="PERCENT" /> prosent</translation>
-<translation id="9160096769946561184">Gå til slutten av den gjeldende kolonnen</translation>
-<translation id="9173115498289768110">Volum – <ph name="PERCENT" /> prosent</translation>
-<translation id="9178973770513562274">Bruk piltastene for opp og ned for å bla gjennom, eller skriv inn tekst for å søke.</translation>
-<translation id="9192904702577636854">Rulletekst</translation>
-<translation id="9212322457209634662">Det finnes ingen neste del.</translation>
-<translation id="930275611743429116">Start eller avslutt utvalget.</translation>
-<translation id="948171205378458592">Reduser talehastigheten</translation>
-<translation id="962913030769097253">Neste overskrift på nivå 1</translation>
-<translation id="973955474346881951">Slå av eller på trege taster</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pl.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pl.xtb
deleted file mode 100644
index a081136948a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pl.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="pl">
-<translation id="1012173283529841972">Element listy</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Rozciągnięta.</translation>
-<translation id="1025074108959230262">Tryb przylegania wyłączony</translation>
-<translation id="1031961866430398710">następnie</translation>
-<translation id="1044777062731150180">Bez nagłówków</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Nieprawidłowe informacje wejściowe</translation>
-<translation id="1082209053475788238">Brak poprzedniego nagłówka poziomu 6.</translation>
-<translation id="1088219014394087294">Bez nagłówków.</translation>
-<translation id="1106741348836243114">Włącz lub wyłącz powiadamianie dźwiękiem (ikony akustyczne).</translation>
-<translation id="1120743664840974483">{"a": "alfa", "b": "brawo", "c": "czarli", "d": "delta", "e": "eko", "f": "fokstrot", "g": "golf", "h": "hotel", "i": "india", "j": "dżuliet","k": "kilo", "l": "lima", "m": "majk", "n": "nowember", "o": "oskar","p": "papa", "q": "kebek", "r": "romeo", "s": "sjera", "t": "tango", "u": "juniform", "v": "wiktor", "w": "łyski","x": "eks-rej", "y": "janki", "z": "zulu"}</translation>
-<translation id="113582498867142724">Kolekcja elementów <ph name="TAG" />. Liczba elementów: <ph name="NUM" /></translation>
-<translation id="1155043339247954670">Brak następnego elementu listy.</translation>
-<translation id="1157782847298808853">Klawiatura – pomoc</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, pole złożone</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, element menu mający podmenu</translation>
-<translation id="1177863135347784049">Niestandardowe</translation>
-<translation id="1188858454923323853">pomocniczy</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – niech Chrome przemówi</translation>
-<translation id="1229276918471378188">Poprzednie przejście</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Następny nagłówek poziomu 6</translation>
-<translation id="1275718070701477396">Zaznaczone</translation>
-<translation id="1319608975892113573">Brak poprzedniego cytatu blokowego.</translation>
-<translation id="1321576897702511272">Ukryj pomoc dotyczącą ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> z <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">odczytywanie znaków i słów</translation>
-<translation id="1339428534620983148">Poprzednia kolumna tabeli</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">W prawo</translation>
-<translation id="136718599399906424">Następny wiersz tabeli</translation>
-<translation id="1383876407941801731">Szukaj</translation>
-<translation id="1385214448885562192">Naciśnij enter, by zaakceptować, escape, by anulować, strzałkę w dół, by przejść dalej, lub strzałkę w górę, by się cofnąć.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, pole tekstowe hasła</translation>
-<translation id="1467432559032391204">W lewo</translation>
-<translation id="1474557363159888097">Brak poprzedniej kotwicy.</translation>
-<translation id="1502086903961450562">Poprzednia grafika</translation>
-<translation id="1506187449813838456">Podnieś tonację.</translation>
-<translation id="151784044608172266">Następne zdanie</translation>
-<translation id="1524531499102321782">Pismo Braille'a – następny wiersz</translation>
-<translation id="1546370775711804143">Pasek przewijania</translation>
-<translation id="1559739829547075274">Przejdź wstecz</translation>
-<translation id="1571643229714746283">ChromeVox gotowe</translation>
-<translation id="158493514907962286">grudzień</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Przełącz na pismo 6-punktowe Braille'a</translation>
-<translation id="1611168825862729585">Nagłówek kolumny:</translation>
-<translation id="1613476421962910979">Ikony akustyczne są włączone</translation>
-<translation id="1618597272655350600">Przedstawia pełny opis aktualnej pozycji</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{większy niż}few{# znaki większości}many{# znaków większości}other{# greater than signs}}</translation>
-<translation id="1653266918374749391">Poprzedni nagłówek poziomu 3</translation>
-<translation id="1659072772017912254">Niezaznaczone</translation>
-<translation id="1669290819662866522">tydzień</translation>
-<translation id="1674262202423278359">Nawigacja ChromeVox</translation>
-<translation id="16777221443363124">Pasek menu</translation>
-<translation id="1692077714702418899">linia struktury</translation>
-<translation id="1700517974991662022">Kliknięty</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Następna grafika</translation>
-<translation id="1781173782405573156">Klawisz przejścia</translation>
-<translation id="1787176709638001873">Edytowanie tekstu, hasło</translation>
-<translation id="1810107444790159527">Pole listy</translation>
-<translation id="1828385960365606039">maj</translation>
-<translation id="1834891354138622109">Kolumna</translation>
-<translation id="1865601187525349519">Koniec tekstu</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Powiedz bieżącą godzinę i datę.</translation>
-<translation id="1902396333223336119">Komórka</translation>
-<translation id="1905379170753160525">Pokaż listę nagłówków</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Element wyboru tygodnia w roku</translation>
-<translation id="1964135212174907577">Następny obiekt</translation>
-<translation id="1969092762068865084">lipiec</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Nagłówek wiersza:</translation>
-<translation id="2002895034995108595">Zresetuj bieżącą mapę klawiszy</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{lewy nawias kwadratowy}few{# lewe nawiasy kwadratowe}many{# lewych nawiasów kwadratowych}other{# left brackets}}</translation>
-<translation id="2045490512405922022">niezaznaczone</translation>
-<translation id="20601713649439366">Brak poprzedniego wyrażenia matematycznego.</translation>
-<translation id="207477615537953741">Semantyka wyłączona</translation>
-<translation id="2086961585857038472">Następne słowo</translation>
-<translation id="2089387485033699258">pl</translation>
-<translation id="2091933974477985526">Poprzedni obszar tekstowy do edytowania</translation>
-<translation id="2100350898815792233">Pełna interpunkcja</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">klawisz dostępu:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Zmień bieżącą tabelę 6-punktowego pisma Braille'a, wybierając opcję z listy poniżej.</translation>
-<translation id="2169714232367507776">Kliknij bieżący element</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{nawias okrągły zamykający}few{# nawiasy okrągłe zamykające}many{# nawiasów okrągłych zamykających}other{# close parens}}</translation>
-<translation id="2199994615414171367">Poprzednie wyrażenie matematyczne</translation>
-<translation id="2223693656926968778">Wykonaj działanie na bieżącym elemencie</translation>
-<translation id="225732394367814946">Zwiększ tempo mowy</translation>
-<translation id="2267945578749931355">Następny znak</translation>
-<translation id="2281234842553884450">Poprzedni suwak</translation>
-<translation id="2318372665160196757">Główny</translation>
-<translation id="2329324941084714723">Panel karty</translation>
-<translation id="2344193891939537199">Element wyboru daty i godziny</translation>
-<translation id="2359897517538099099">Nie jesteś w trybie tabeli.</translation>
-<translation id="241124561063364910">, a następnie naciśnij</translation>
-<translation id="2417569100218200841">Informacje o zawartości</translation>
-<translation id="2422937916923936891">Pole wyboru elementu menu</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> to nowy modyfikator ChromeVox.</translation>
-<translation id="2450814015951372393">Pole wyboru</translation>
-<translation id="2462626033734746142">Grupa przycisków radiowych</translation>
-<translation id="2471138580042810658">Nagłówek 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{gwiazdka}few{# znaki gwiazdki}many{# znaków gwiazdki}other{# asterisks}}</translation>
-<translation id="2549392850788122959">Klawisz <ph name="KEY" /> został zresetowany.</translation>
-<translation id="2553108862507765288">błąd gramatyczny</translation>
-<translation id="257674075312929031">Grupa</translation>
-<translation id="2582407057977008361">Z boku</translation>
-<translation id="2589102159832527089">Ta strona zawiera tekst automatycznie wyodrębniony z pliku PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Kliknij tutaj, aby wyświetlić oryginał&lt;/a&gt;.</translation>
-<translation id="2606210917827248971">z {COUNT,plural, =1{# elementem}few{# elementami}many{# elementami}other{# elementu}}</translation>
-<translation id="2614981083756825552">Układ MathML</translation>
-<translation id="2626530649491650971">klikalny</translation>
-<translation id="2628764385451019380">Brak poprzedniego pola złożonego.</translation>
-<translation id="2637227747952042642">Matematyczny</translation>
-<translation id="2639750663247012216">Modyfikator ChromeVox</translation>
-<translation id="2644542693584024604">błędny zapis</translation>
-<translation id="2667291555398229137">Kliknij element pod kluczem routingu</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{nawias okrągły otwierający}few{# nawiasy okrągłe otwierające}many{# nawiasów okrągłych otwierających}other{# open parens}}</translation>
-<translation id="2705875883745373140">Nienaciśnięte</translation>
-<translation id="2706462751667573066">W górę</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">dźwięk</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Zaznaczony</translation>
-<translation id="27527859628328957">Przejdź do następnego elementu, na którym można ustawić fokus</translation>
-<translation id="2770781857296573485">Otwórz poznawanie grup</translation>
-<translation id="2777845298774924149">Zamknięty</translation>
-<translation id="2800204403141299078">Nie ma więcej różnych elementów.</translation>
-<translation id="2800780099804980316">Brak poprzedniego nagłówka poziomu 1.</translation>
-<translation id="2811204574343810641">Wiersz</translation>
-<translation id="2816654101880605877">Brak następnego suwaka.</translation>
-<translation id="2841013758207633010">Godzina</translation>
-<translation id="2843837985843789981">Poprzednia grupa</translation>
-<translation id="2844995807198708617">Menu kontekstowe</translation>
-<translation id="2849332794118375855">Brak następnego pola wyboru.</translation>
-<translation id="2864481629947106776">Poprzedni link</translation>
-<translation id="2873259058405069099">Przejdź na początek tabeli.</translation>
-<translation id="2894654529758326923">Informacje</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{lewy nawias klamrowy}few{# lewe nawiasy klamrowe}many{# lewych nawiasów klamrowych}other{# left braces}}</translation>
-<translation id="2911433807131383493">Otwórz samouczek ChromeVox</translation>
-<translation id="2932083475399492303">Zmień typ linii na strukturę lub układ</translation>
-<translation id="2964026537669811554">Grupa nagłówka</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulator}few{# tabulatory}many{# tabulatorów}other{# tabs}}</translation>
-<translation id="2972078295414139404">Brak poprzedniego klikniętego linku.</translation>
-<translation id="2972205263822847197">Wskazówka do elementu</translation>
-<translation id="2998131015536248178">Poprzedni znak</translation>
-<translation id="2999559350546931576">Obniż tonację.</translation>
-<translation id="2999945368667127852">Brak widżetu następnego pliku multimedialnego.</translation>
-<translation id="3012414509011670858">Brak poprzedniej sekcji.</translation>
-<translation id="3030432017085518523">Przycisk opcji elementu menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}few{# apostrofy}many{# apostrofów}other{# apostrophes}}</translation>
-<translation id="3046838483509668188">Opcje ChromeVox</translation>
-<translation id="3047143736589213134">Eksperymentalna mapa klawiatury</translation>
-<translation id="3060756054951570867">otwarte menu <ph name="TITLE" /></translation>
-<translation id="3078345202707391975">Następny nagłówek poziomu 2</translation>
-<translation id="3078740164268491126">tabela</translation>
-<translation id="3082557070674409251">Kliknięte</translation>
-<translation id="3084806535845658316">bez odczytywania podczas pisania</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Brak następnego wyrażenia matematycznego.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Następny punkt orientacyjny</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Zwinięty</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Pokaż listę punktów orientacyjnych</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Następny wiersz</translation>
-<translation id="3155083529632865074">Brak poprzedniego przycisku.</translation>
-<translation id="3163593631834463955">Pusty nagłówek kolumny</translation>
-<translation id="316542773973815724">Nawigacja</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{spacja}few{# spacje}many{# spacji}other{# spaces}}</translation>
-<translation id="320961988183078793">wpisano: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, karta</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Kliknięty link</translation>
-<translation id="323731244387692321">Otwórz pomoc do klawiatury ChromeVox</translation>
-<translation id="3241052487511142956">Poprzedni kliknięty link</translation>
-<translation id="3286390186030710347">Suwak</translation>
-<translation id="3299925995433437805">Brak następnego klikniętego linku.</translation>
-<translation id="3303384412438961941">Naciśnij dowolny klawisz, aby poznać jego nazwę. Ctrl+W zamyka eksploratora klawiatury.</translation>
-<translation id="3307886118343381874">Przejdź na koniec tabeli.</translation>
-<translation id="3311969765485641742">Naciśnij Alt+Shift+A, by zobaczyć alerty</translation>
-<translation id="3312997241656799641">Następny kliknięty link</translation>
-<translation id="3321460131042519426">Włącz zawijanie wyrazów</translation>
-<translation id="3322936298410871309">Poprzedni nagłówek poziomu 1</translation>
-<translation id="3323447499041942178">Pole tekstowe</translation>
-<translation id="3353420241558113817">{"ar": "arabski",
- "bg": "bułgarski",
- "ca": "kataloński",
- "cs": "czeski",
- "da": "duński",
- "de": "niemiecki",
- "de_CH": "niemiecki (Szwajcaria)",
- "de_DE": "niemiecki (Niemcy)",
- "el": "grecki",
- "en": "angielski",
- "en_CA": "angielski (Kanada)",
- "en_GB": "angielski (Wielka Brytania)",
- "en_US": "angielski (Stany Zjednoczone)",
- "es": "hiszpański",
- "et": "estoński",
- "fr": "francuski",
- "fr_CA": "francuski (Kanada)",
- "fr_FR": "francuski (Francja)",
- "fi": "fiński",
- "he": "hebrajski",
- "hi": "hindi",
- "hr": "chorwacki",
- "hu": "węgierski",
- "is": "islandzki",
- "it": "włoski",
- "ko": "koreański",
- "lt": "litewski",
- "lv": "łotewski",
- "nb": "norweski Bokmål",
- "nl": "holenderski",
- "pl": "polski",
- "pt": "portugalski",
- "ro": "rumuński",
- "ru": "rosyjski",
- "sk": "słowacki",
- "sl": "słoweński",
- "sr": "serbski",
- "sv": "szwedzki",
- "tr": "turecki",
- "vi": "wietnamski",
- "zh": "chiński",
- "zh_TW": "chiński (tradycyjny Han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{znak plus}few{# znaki plus}many{# znaków plus}other{# plus signs}}</translation>
-<translation id="338583716107319301">Separator</translation>
-<translation id="3389259863310851658">Poprzednie pole formularza</translation>
-<translation id="3390225400784126843">Następny różniący się element.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, element menu</translation>
-<translation id="3406283310380167331">Pokaż listę formularzy</translation>
-<translation id="3422338090358345848">Otwórz eksploratora klawiatury</translation>
-<translation id="3457000393508828486">Częściowo naciśnięte</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, przycisk</translation>
-<translation id="3473644018603298796">zaznaczono <ph name="COUNT" /></translation>
-<translation id="3486232535569802404">Od <ph name="V1" /> do <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{prawy nawias kwadratowy}few{# prawe nawiasy kwadratowe}many{# prawych nawiasów kwadratowych}other{# right brackets}}</translation>
-<translation id="3493915602752813531">Brak następnej kotwicy.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{pytajnik}few{# pytajniki}many{# pytajników}other{# question marks}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{kareta}few{# znaki karety}many{# znaków karety}other{# carets}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, niezaznaczone pole wyboru</translation>
-<translation id="3599054940393788245">Nie w środku wyrażenia matematycznego</translation>
-<translation id="3616113530831147358">Dźwięk</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{grawis}few{# grawisy}many{# grawisów}other{# backticks}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolar}few{# znaki dolara}many{# znaków dolara}other{# dollar signs}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, pole listy</translation>
-<translation id="3687295507293856493">Odgadnij nagłówek kolumny bieżącej komórki.</translation>
-<translation id="3692274950075847560">W:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Sterowanie mową</translation>
-<translation id="3716845769494773620">Wiele linii</translation>
-<translation id="3731746171184829332">Brak poprzedniego nagłówka.</translation>
-<translation id="3762198587642264450">Przejdź na koniec bieżącego wiersza.</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Okno dialogowe zostało zamknięte</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}few{#}many{#}other{#}}</translation>
-<translation id="3801735343383419236">Autouzupełnianie list</translation>
-<translation id="3810838688059735925">Wideo</translation>
-<translation id="3816633764618089385">Następny plik multimedialny</translation>
-<translation id="3819376190738087562">Brak przejść.</translation>
-<translation id="385383972552776628">Otwórz stronę opcji</translation>
-<translation id="3856075812838139784">Tylko do odczytu</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Poprzedni nagłówek poziomu 6</translation>
-<translation id="3914173277599553213">Wymagane</translation>
-<translation id="3962990492275676168">Zacznij czytać od bieżącego miejsca</translation>
-<translation id="4004802134384979325">zaznaczone</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Element wyboru miesiąca</translation>
-<translation id="4039983576244166038">Pusty nagłówek wiersza</translation>
-<translation id="4042843249978639960">Brak następnego nagłówka poziomu 2.</translation>
-<translation id="4043348641337972076">Brak poprzedniego punktu orientacyjnego ARIA.</translation>
-<translation id="4047216625641135770">Zaznaczenie</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{tylda}few{# tylda}many{# tyld}other{# tildes}}</translation>
-<translation id="409334809956508737">Poprzedni obiekt</translation>
-<translation id="4099274309791143834">z menu podrzędnym</translation>
-<translation id="4107807507418787238">Brak komórki poniżej.</translation>
-<translation id="4116415223832267137">Alert</translation>
-<translation id="4147126331795725888">Brak następnego elementu sterującego.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{prawy nawias klamrowy}few{# prawe nawiasy klamrowe}many{# prawych nawiasów klamrowych}other{# right braces}}</translation>
-<translation id="4158704014418536539">Rozróżnianie wielkości liter.</translation>
-<translation id="4161663686871496107">Powiadamianie głosowe ChromeVox jest gotowe</translation>
-<translation id="4173994908659439270">Brak następnego pola tekstowego do edytowania.</translation>
-<translation id="4176463684765177261">Wyłączone</translation>
-<translation id="4188530942454211480">Poprzednie zdanie</translation>
-<translation id="4202186506458631436">Przejdź w prawo</translation>
-<translation id="4206289001967551965">Wewnątrz tabeli</translation>
-<translation id="4215733775853809057">Następny suwak</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{pauza}few{# pauzy}many{# pauz}other{# dashes}}</translation>
-<translation id="421884353938374759">selektor kolorów</translation>
-<translation id="4229646983878045487">data i godzina</translation>
-<translation id="423334822609210999">Brak komórki z lewej strony.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, klasa <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Uwaga</translation>
-<translation id="4254798249533888099">Tree</translation>
-<translation id="4255943572433203166">Użyj poniższych opcji, aby dostosować ChromeVox. Zmiany są wprowadzane natychmiast.</translation>
-<translation id="4271220233568730077">Następne wyrażenie matematyczne</translation>
-<translation id="4271521365602459209">Brak innych wyników.</translation>
-<translation id="4287520460805643128">Nie ma następnego artykułu.</translation>
-<translation id="4289540628985791613">Omówienie</translation>
-<translation id="4300318234632215983">Przeczytaj URL linku</translation>
-<translation id="4301352596632316575">ma menu podrzędne</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{kropka}=3{wielokropek}few{# kropki}many{# kropek}other{# dots}}</translation>
-<translation id="4347461890115250064">Brak następnej listy.</translation>
-<translation id="4367650418938037324">Liść MathML</translation>
-<translation id="4372435075475052704">minimalnie: <ph name="X" /></translation>
-<translation id="4372705107434148843">Zakończ mowę</translation>
-<translation id="4373197658375206385">Brak poprzedniego elementu niebędącego linkiem.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">zresetuj</translation>
-<translation id="4471074325120394300">Brak linków.</translation>
-<translation id="4476183483923481720">nowy wiersz</translation>
-<translation id="4482330759234983253">Poprzednia tabela</translation>
-<translation id="4491109536499578614">Obraz</translation>
-<translation id="4529987814483543472">Klasyczny układ klawiatury</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{ukośnik}few{# ukośniki}many{# ukośników}other{# slashes}}</translation>
-<translation id="4547556996012970016">Następny nagłówek poziomu 5</translation>
-<translation id="4562381607973973258">Nagłówek</translation>
-<translation id="4591507479202817876">, wybrany</translation>
-<translation id="4597532268155981612">formularz</translation>
-<translation id="4597896406374528575">kwiecień</translation>
-<translation id="4615592953348396470">Ignorowanie następnego naciśnięcia klawisza</translation>
-<translation id="461613135510474570">Zdanie</translation>
-<translation id="4647836961514597010">Selektor kolorów</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Poprzedni punkt orientacyjny</translation>
-<translation id="4696413482802371445">Brak następnego nagłówka poziomu 5.</translation>
-<translation id="4729095194763193578">Poprzedni wiersz tabeli</translation>
-<translation id="4736221692378411923">sierpień</translation>
-<translation id="4740661827607246557">Polecenia pomocy</translation>
-<translation id="4759716709594980008">Eksplorator klawiatury systemu operacyjnego Chrome</translation>
-<translation id="4763296182459741068">Zawijanie do dołu</translation>
-<translation id="4763480195061959176">film</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Przeczytaj tytuł bieżącej strony</translation>
-<translation id="4826415162591436065">Przejdź dalej</translation>
-<translation id="4826604887384865800">Następne przejście</translation>
-<translation id="4827410568042294688">nie wybrano</translation>
-<translation id="4842108708071771135">Brak następnego cytatu blokowego.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Poprzedni taki sam element.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Włącz rejestrowanie TTS</translation>
-<translation id="4877261390094455813">Wpisz zapytanie.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Link wewnętrzny</translation>
-<translation id="4953585991029886728">Edytowanie tekstu</translation>
-<translation id="4954534434583049121">Poprzedni cytat blokowy</translation>
-<translation id="4973717656530883744">Minimalnie <ph name="X" /></translation>
-<translation id="4973762002207131920">Zmiana na <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisekundy</translation>
-<translation id="49787999531187221">ChromeVox jest obecnie nieaktywny.</translation>
-<translation id="4979404613699303341">Poprzedni przycisk</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, pole listy</translation>
-<translation id="4983588134362688868">Przejdź do góry strony</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, okno</translation>
-<translation id="4993152509206108683">Szybkość: <ph name="PERCENT" /> procent</translation>
-<translation id="4996716799442435517">Obrazowo</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, wybrany przycisk opcji</translation>
-<translation id="4997475792277222884">Brak następnego elementu niebędącego linkiem.</translation>
-<translation id="5000760171916499057">Brak formularzy.</translation>
-<translation id="5005670136041063723">Nie ma więcej podobnych elementów.</translation>
-<translation id="501473567976723023">styczeń</translation>
-<translation id="5041394372352067729">Przenieś wyświetlacz brajlowski na górę strony</translation>
-<translation id="5042770794184672516">Zwiększ głośność mowy</translation>
-<translation id="5050015258024679800">Poprzedni nagłówek poziomu 4</translation>
-<translation id="5054047268577924192">Poprzedni element listy</translation>
-<translation id="5078661581131202757">Wybór pliku</translation>
-<translation id="5080758118274074384">kliknięte dwukrotnie</translation>
-<translation id="5098541983634824365">Opuszczasz siatkę.</translation>
-<translation id="5102981729317424850">Pasek narzędzi</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Brak poprzedniego pola formularza.</translation>
-<translation id="5111640677200759579">Nagłówek kolumny</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Brak poprzedniego linku.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, nie wybrano</translation>
-<translation id="5183440668879371625">Pismo Braille'a – poprzedni wiersz</translation>
-<translation id="5184944171021383281">Brak następnego pola formularza.</translation>
-<translation id="5189244881767082992">Wiersz</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> jest już przyporządkowany do polecenia.</translation>
-<translation id="5205493599117157272">Lista: <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Brak następnego przycisku radiowego.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Obiekt</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, karta</translation>
-<translation id="5310788376443009632">usunięto:</translation>
-<translation id="5320727453979144100">Tryb przylegania włączony</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{przecinek}few{# przecinki}many{# przecinków}other{# commas}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, pole tekstowe</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Cofnij podczas ciągłego czytania</translation>
-<translation id="5368000168321181111">Ikony akustyczne są wyłączone</translation>
-<translation id="5374320867641260420">Brak przycisku Dalej.</translation>
-<translation id="5382299583965267720">Brak następnego nagłówka poziomu 1.</translation>
-<translation id="5402367795255837559">Pismo Braille'a</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{średnik}few{# średniki}many{# średników}other{# semicolons}}</translation>
-<translation id="5411891038905756502">Brak poprzedniego punktu przejścia.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{mniejszy niż}few{# znaki mniejszości}many{# znaków mniejszości}other{# less than signs}}</translation>
-<translation id="5455441614648621694">Pomocniczy</translation>
-<translation id="5485036206801896268">Brak poprzedniej grafiki.</translation>
-<translation id="5486947920110100234">Brak następnego punktu przejścia.</translation>
-<translation id="549602578321198708">Słowo</translation>
-<translation id="5500932716852106146">Brak poprzedniego pola tekstowego do edytowania.</translation>
-<translation id="5502713021410870035">wrzesień</translation>
-<translation id="5507663321906818013">Narzędzie debugowania</translation>
-<translation id="5518443085409638729">Podczas edytowania tekstu umieść kursor między znakami (jak w Mac OS X).</translation>
-<translation id="552195134157544755">Przycisk radiowy</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Brak poprzedniego nagłówka poziomu 5.</translation>
-<translation id="556042886152191864">Przycisk</translation>
-<translation id="5561345396546889625">Następna lista</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Edytowanie tekstu, pisanie e-maila</translation>
-<translation id="5597170376237141345">Następne pole wyboru</translation>
-<translation id="5597933780944041114">Brak następnego nagłówka.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, niewybrany przycisk opcji</translation>
-<translation id="5601172225407283979">Wykonaj domyślne działanie</translation>
-<translation id="5608798115546226984">Autouzupełnianie w tekście</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Dziennik</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Brak poprzedniej tabeli.</translation>
-<translation id="5655682562155942719">Polecenia nawigacyjne</translation>
-<translation id="56637627897541303">Obszar tekstu</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Punkt orientacyjny</translation>
-<translation id="5683155931978483559">Poprzednie pole wyboru</translation>
-<translation id="5684277895745049190">Lista</translation>
-<translation id="5700650669149824506">Brak poprzedniego nagłówka poziomu 4.</translation>
-<translation id="5709192780268610569">Brak długiego opisu</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Następna kolumna tabeli</translation>
-<translation id="571866080859340309">Poznawanie grup</translation>
-<translation id="5728409797179002635">Nie znaleziono tabel.</translation>
-<translation id="5748623122140342504">Poprzedni nagłówek poziomu 5</translation>
-<translation id="5750633686117194034">Nie naciśnięto modyfikatora. Naciśnij i przytrzymaj przynajmniej jeden modyfikator, a później unieś palce – usłyszysz, że klawisze zostały ustawione. Naciśnij Tab, by wyjść.</translation>
-<translation id="5788275253279308023">okno incognito, karta <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Ulepsz określone strony (np. wyszukiwarkę Google).</translation>
-<translation id="5819072574982403430">Element drzewa</translation>
-<translation id="5826479389509458994">wiersz <ph name="ROW" />, kolumna <ph name="COL" /></translation>
-<translation id="5850707923114094062">Przesuń do tyłu</translation>
-<translation id="5851548754964597211">Lista kart</translation>
-<translation id="5859752971144398932">Znajdowanie na stronie zostało zamknięte.</translation>
-<translation id="5866042630553435010">Częściowo zaznaczony</translation>
-<translation id="5869546221129391014">Siatka</translation>
-<translation id="5876817486144482042">Zmniejsz głośność mowy</translation>
-<translation id="5887397643266327462">Napisy brajlowskie włączone.</translation>
-<translation id="5891934789323004067">Tabela</translation>
-<translation id="5919442531159595654">kopiuj.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{równy}few{# znaki równości}many{# znaków równości}other{# equal signs}}</translation>
-<translation id="5939518447894949180">Resetuj</translation>
-<translation id="5948123859135882163">Włącz/wyłącz strukturalne lub semantyczne interpretowanie wyrażeń matematycznych</translation>
-<translation id="5955304353782037793">aplikacja</translation>
-<translation id="5956928062748260866">Okno dialogowe</translation>
-<translation id="5963413905009737549">Sekcja</translation>
-<translation id="5968607524793740041">Pokaż menu kontekstowe</translation>
-<translation id="5983179082906765664">Zwiększ dokładność nawigacji.</translation>
-<translation id="5999630716831179808">Głosy</translation>
-<translation id="6000417740266304866">Zmień bieżącą tabelę 8-punktowego pisma Braille'a, wybierając opcję z listy poniżej.</translation>
-<translation id="6006050241733874051">Formularz</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{ukośnik wsteczny}few{# ukośniki wsteczne}many{# ukośników wstecznych}other{# backslashes}}</translation>
-<translation id="6037602951055904232">Przesuń do przodu</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Koniec komórki.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Spacja</translation>
-<translation id="6142308968191113180">Nagłówek 4</translation>
-<translation id="6169420925157477918">Obraz z długim opisem</translation>
-<translation id="6172087735260766220">W pliku PDF zabezpieczonym przed kopiowaniem nie można uzyskać dostępu do tekstu.</translation>
-<translation id="6186305613600865047">Przejdź na dół strony</translation>
-<translation id="6193330012414963395">Do południa Po południu</translation>
-<translation id="622484624075952240">W dół</translation>
-<translation id="6236061028292614533">Następny nagłówek</translation>
-<translation id="6254901459154107917">Następny obszar tekstowy do edytowania</translation>
-<translation id="6259464875943891919">Zamknięto <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Następny taki sam element.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Brak następnego pola złożonego.</translation>
-<translation id="6307969636681130414">Naciśnięty</translation>
-<translation id="6324551002951139333">Wykryto błąd gramatyczny</translation>
-<translation id="6348657800373377022">Pole złożone</translation>
-<translation id="6355910664415701303">Brak poprzedniego elementu listy.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Poprzedni nagłówek</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Brak poprzedniego przycisku radiowego.</translation>
-<translation id="6414968628640960377">Poprzedni różniący się element.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dwukropek}few{# dwukropki}many{# dwukropków}other{# colons}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Okno dialogowe alertu</translation>
-<translation id="6459511626086141404">Płaska mapa klawiszy</translation>
-<translation id="6468049171101508116">Następny przycisk</translation>
-<translation id="6491972999578897419">Zmień bieżący głos, wybierając opcję z listy poniżej.</translation>
-<translation id="6508059270146105198">Przenieś wyświetlacz brajlowski na dół strony</translation>
-<translation id="6536864053412760904">Token MathML</translation>
-<translation id="6550720799683018100">Zmień bieżący układ klawiatury, wybierając opcję z listy poniżej.</translation>
-<translation id="6561818612645211875">Przejdź na początek bieżącego wiersza</translation>
-<translation id="6587021927234520429">Brak następnego nagłówka poziomu 4.</translation>
-<translation id="6601344353291556895">Włącz szczegółowe opisy.</translation>
-<translation id="6615602925644411249">Znajdź na stronie.</translation>
-<translation id="6633350132811819843">Brak następnej tabeli.</translation>
-<translation id="6637586476836377253">dziennik</translation>
-<translation id="6657128831881431364">Pasek postępu</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Poprzednie pole złożone</translation>
-<translation id="6714813999819678458">Poprzedni nagłówek poziomu 2</translation>
-<translation id="6716505898850596801">Klawisze modyfikujące</translation>
-<translation id="671916444866103745">Brak następnego punktu orientacyjnego ARIA.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, pole złożone</translation>
-<translation id="6735257939857578167">z <ph name="NUM" /> elementami</translation>
-<translation id="6736510033526053669">karta została utworzona</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artykuł</translation>
-<translation id="6787839852456839824">Skróty klawiaturowe</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Stopka</translation>
-<translation id="6871161210040114857">Ignorowanie wielkości liter.</translation>
-<translation id="6877435256196695200">Brak następnej grafiki.</translation>
-<translation id="6897341342232909480">Przejdź w lewo</translation>
-<translation id="6901540140423170855">data</translation>
-<translation id="6910211073230771657">Usunięto</translation>
-<translation id="6911965441508464308">Brak komórki powyżej.</translation>
-<translation id="6919104639734799681">Pokaż listę tabel.</translation>
-<translation id="6964088412282673743">Brak poprzedniego elementu sterującego.</translation>
-<translation id="6996566555547746822">Następne pole złożone</translation>
-<translation id="7005146664810010831">Nie znaleziono URL-a</translation>
-<translation id="7010712454773919705">Klawisz modyfikujący ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Poprzednia lista</translation>
-<translation id="7041173719775863268">Zakończ wybieranie</translation>
-<translation id="7095834689119144465">Edytowanie tekstu, tylko liczby</translation>
-<translation id="7096001299300236431">Poprzedni plik multimedialny</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">odczytywanie słów</translation>
-<translation id="713824876195128146">Następny cytat blokowy</translation>
-<translation id="7161771961008409533">Przycisk wyskakującego okienka</translation>
-<translation id="7167657087543110">odczytywanie znaków</translation>
-<translation id="7170733337935166589">Przewiń do przodu podczas ciągłego czytania</translation>
-<translation id="7181697990050180700">Dostosuj skróty klawiszowe częstych poleceń, wpisując je do odpowiednich pól poniżej.</translation>
-<translation id="7203150201908454328">Rozwinięty</translation>
-<translation id="7210211103303402262">minuty</translation>
-<translation id="7217912842225915592">+ <ph name="NUM" /></translation>
-<translation id="7221740160534240920">wiersz</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Nagłówek</translation>
-<translation id="7241683698754534149">Otwórz długi opis na nowej karcie</translation>
-<translation id="7248671827512403053">Aplikacja</translation>
-<translation id="725969808843520477">Następny przycisk opcji</translation>
-<translation id="7269119382257320590">Bez interpunkcji</translation>
-<translation id="7273174640290488576">Pusty</translation>
-<translation id="7285387653379749618">Tabele</translation>
-<translation id="7289186959554153431">Nagłówek 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Napisy brajlowskie wyłączone.</translation>
-<translation id="7318872822751139669">Użyj myszy, by zmienić aktywne elementy.</translation>
-<translation id="7322388933135261569">luty</translation>
-<translation id="7332592614823088566">Wiersz <ph name="ROWINDEX" /> z <ph name="ROWTOTAL" />, kolumna <ph name="COLINDEX" /> z <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">ma wyskakujące okienko</translation>
-<translation id="7356165926712028380">Przełącz na pismo 8-punktowe Braille'a</translation>
-<translation id="7362871137496673139">Brak poprzedniego nagłówka poziomu 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{et}few{# znaki et}many{# znaków et}other{# ampersands}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Opuszczasz tabelę.</translation>
-<translation id="739763518212184081">Poprzedni wiersz</translation>
-<translation id="7400575256015741911">Wykryto błąd pisowni</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">powrót</translation>
-<translation id="7434509671034404296">Programista</translation>
-<translation id="7439060726180460871">Katalog</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Otworzyłeś okno dialogowe</translation>
-<translation id="7532613204005497612">czerwiec</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, suwak</translation>
-<translation id="7586163296341959563">wklej.</translation>
-<translation id="7596919493010894443">zaznaczenie zostało wyczyszczone</translation>
-<translation id="7604026522577407655">Przejdź na początek bieżącej kolumny</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Przeczytaj URL bieżącej strony</translation>
-<translation id="7609363189280667021">Przełącz napisy brajlowskie</translation>
-<translation id="762020119231868829">Wstrzymuje odtwarzanie we wszystkich aktywnych widżetach multimedialnych</translation>
-<translation id="7625690649919402823">Następna tabela</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), klasa <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Brak poprzedniego nagłówka poziomu 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, pole tekstowe</translation>
-<translation id="7663318257180412551">Nagłówek 2</translation>
-<translation id="7674576868851035240">Następny link</translation>
-<translation id="7674768236845044097">zaznaczenie</translation>
-<translation id="7684431668231950609">Edytowanie tekstu, podanie URL-a</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Poprzedni przycisk opcji</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, pole tekstowe hasła</translation>
-<translation id="7805247615045262757">domyślna nawigacja</translation>
-<translation id="7805768142964895445">Stan</translation>
-<translation id="7810781339813764006">Następna grupa</translation>
-<translation id="7819187121850078213">karta <ph name="TITLE" /> w oknie</translation>
-<translation id="7828956995407538686">październik</translation>
-<translation id="7839679365527550018">Poprzednie słowo</translation>
-<translation id="7851816175263618915">Częściowa interpunkcja</translation>
-<translation id="7870596830398826354">Drzewo MathML</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Przełącz klasyczny ChromeVox.</translation>
-<translation id="7895896691902835279">Nieznany link</translation>
-<translation id="7927711904086083099">Niewybrany</translation>
-<translation id="7935627501098484003">Kontrola czasu</translation>
-<translation id="7939428177581522200">dodano do zaznaczenia</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{małpa}few{# małpy}many{# małp}other{# at signs}}</translation>
-<translation id="7965147473449754028">menu zamknięte</translation>
-<translation id="7974390230414479278">Element menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{wykrzyknik}few{# wykrzykniki}many{# wykrzykników}other{# exclamation points}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{cudzysłów}few{# cudzysłowy}many{# cudzysłówów}other{# quotes}}</translation>
-<translation id="8033827949643255796">wybrano</translation>
-<translation id="8035962149453661158">maksymalnie: <ph name="X" /></translation>
-<translation id="8042761080832772327">Edytowanie tekstu, wpisanie zapytania</translation>
-<translation id="8049189770492311300">Licznik czasu</translation>
-<translation id="8065607967589909823">Bieżący wybór to</translation>
-<translation id="8066678206530322333">Baner</translation>
-<translation id="8110647606445335195">Brak punktów orientacyjnych ARIA.</translation>
-<translation id="8153880621934657047">Poza tabelą.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{podkreślenie}few{# znaki podkreślenia}many{# znaków podkreślenia}other{# underscores}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">wytnij.</translation>
-<translation id="8199231515320852133">Przeczytaj nagłówki bieżącej komórki</translation>
-<translation id="820417203470636242">Pusta komórka.</translation>
-<translation id="8215202828671303819">Wybór wielokrotny</translation>
-<translation id="8276439074553447000">Przejdź do poprzedniego elementu, na którym można ustawić fokus</translation>
-<translation id="8278417001922463147">Nie ma poprzedniego artykułu.</translation>
-<translation id="8283603667300770666">Następne pole formularza</translation>
-<translation id="831207808878314375">Definicja</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">godziny</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{funt}few{# znaki funta}many{# znaków funta}other{# pound signs}}</translation>
-<translation id="8374154622594089836">miesiąc</translation>
-<translation id="8378855320830505539">Region</translation>
-<translation id="8382679411218029383">Autouzupełnianie tekstu i listy</translation>
-<translation id="8428603554127842284">poziom <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Brak następnego nagłówka poziomu 3.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Brak poprzedniego pola wyboru.</translation>
-<translation id="8455868257606149352">Maksymalnie <ph name="X" /></translation>
-<translation id="84575901236241018">ma klawisz dostępu, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Zmniejsz dokładność nawigacji</translation>
-<translation id="8520472399088452386">Przycisk przewijany</translation>
-<translation id="8538744478902126321">Odgadnij nagłówek wiersza bieżącej komórki.</translation>
-<translation id="8540054775867439484">Zawijanie do góry</translation>
-<translation id="8548973727659841685">Znak</translation>
-<translation id="8561322612995434619">ma wyskakujące okienko</translation>
-<translation id="8571096049907249734">wybór wielokrotny</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Następny element listy</translation>
-<translation id="860150890330522909"><ph name="NAME" />, zaznaczone pole wyboru</translation>
-<translation id="8606621670302093223">Element wyboru daty</translation>
-<translation id="8631359288236106450">zaznaczone elementy: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Podawaj współrzędne bieżących komórek</translation>
-<translation id="8650576015643545550">Brak poprzedniej listy.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Pokaż listę linków</translation>
-<translation id="8664519043722036194">sekundy</translation>
-<translation id="867187640362843212">Nagłówek 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{kreska pionowa}few{# kreski pionowe}many{# kresek pionowych}other{# vertical pipes}}</translation>
-<translation id="8735450637152821465">Zacznij wybierać</translation>
-<translation id="8743786158317878347">otwórz treści strukturalne, na przykład tabele</translation>
-<translation id="8747966237988593539">Lista numerowana</translation>
-<translation id="8759334257841767240">Brak następnego linku.</translation>
-<translation id="8767968232364267681">Następny nagłówek poziomu 4</translation>
-<translation id="8770473310765924354">zamknij treści strukturalne, na przykład tabele</translation>
-<translation id="8791025954632646584">Semantyka włączona</translation>
-<translation id="8796411681063377102">Następny nagłówek poziomu 3</translation>
-<translation id="8808582214901541005">marzec</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">główny</translation>
-<translation id="8856538297388979332">Aby przejrzeć polecenia, naciśnij w górę lub w dół. Aby aktywować, naciśnij Enter</translation>
-<translation id="8864099967139188018">Brak następnego nagłówka poziomu 6.</translation>
-<translation id="8882002077197914455">Nagłówek wiersza</translation>
-<translation id="8896347895970027998">Włącz lub wyłącz ChromeVox.</translation>
-<translation id="8898516272131543774">Włącz/wyłącz odczytywanie interpunkcji</translation>
-<translation id="8900148057318340779">Przedrostek</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Puste nagłówki</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Klawisze modyfikujące</translation>
-<translation id="8943175951035496220">Brak komórki z prawej strony.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">plik</translation>
-<translation id="9027462562263121875">Brak tabel.</translation>
-<translation id="9040132695316389094">Nagłówek 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Przełącz widżet wyszukiwania</translation>
-<translation id="9065283790526219006">+wyskakujące okienko</translation>
-<translation id="9077213568694924680">usunięto zaznaczenie</translation>
-<translation id="9082874451376019682">Brak poprzedniego suwaka.</translation>
-<translation id="9089864840575085222">Włącz/wyłącz odczytywanie podczas pisania</translation>
-<translation id="9107530006868467849">Brak widżetu poprzedniego pliku multimedialnego.</translation>
-<translation id="9108370397979208512">matematyczny</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{procent}few{# znaki procent}many{# znaków procent}other{# percent signs}}</translation>
-<translation id="9115913704608474258">listopad</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Przedstawia skrócony opis aktualnej pozycji</translation>
-<translation id="9153606228985488238">Ton: <ph name="PERCENT" /> procent</translation>
-<translation id="9160096769946561184">Przejdź na koniec bieżącej kolumny</translation>
-<translation id="9173115498289768110">Głośność: <ph name="PERCENT" /> procent</translation>
-<translation id="9178973770513562274">Użyj klawiszy strzałek w górę i w dół, aby przeglądać, lub wpisz hasło, które chcesz wyszukać.</translation>
-<translation id="9192904702577636854">Transparent</translation>
-<translation id="9212322457209634662">Brak następnej sekcji.</translation>
-<translation id="930275611743429116">Rozpocznij lub zakończ wybieranie.</translation>
-<translation id="948171205378458592">Zmniejsz tempo mowy</translation>
-<translation id="962913030769097253">Następny nagłówek poziomu 1</translation>
-<translation id="973955474346881951">Włącz/wyłącz tryb przylegania</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-BR.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-BR.xtb
deleted file mode 100644
index a804810eec9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-BR.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="pt-BR">
-<translation id="1012173283529841972">Item da lista</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Expandido.</translation>
-<translation id="1025074108959230262">Modo aderente desativado</translation>
-<translation id="1031961866430398710">e depois</translation>
-<translation id="1044777062731150180">Nenhum cabeçalho</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Entrada inválida</translation>
-<translation id="1082209053475788238">Nenhum cabeçalho anterior de nível 6.</translation>
-<translation id="1088219014394087294">Nenhum cabeçalho.</translation>
-<translation id="1106741348836243114">Ativa ou desativa o feedback sonoro (earcons).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Coleção de <ph name="TAG" /> com <ph name="NUM" /> itens</translation>
-<translation id="1155043339247954670">Nenhum item a seguir na lista.</translation>
-<translation id="1157782847298808853">Ajuda do teclado</translation>
-<translation id="1157843803349774103">Caixa de texto <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="1167230103353892028">Item de menu <ph name="NAME" />, com submenu</translation>
-<translation id="1177863135347784049">Personalizado</translation>
-<translation id="1188858454923323853">complementar</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox: dando voz ao Google Chrome</translation>
-<translation id="1229276918471378188">Atalho anterior</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Próximo cabeçalho de nível 6</translation>
-<translation id="1275718070701477396">Selecionado</translation>
-<translation id="1319608975892113573">Nenhum bloco de texto anterior.</translation>
-<translation id="1321576897702511272">Ocultar ajuda do ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> de <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">eco de caractere e de palavra</translation>
-<translation id="1339428534620983148">Coluna anterior da tabela</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Para a direita</translation>
-<translation id="136718599399906424">Próxima linha de tabela</translation>
-<translation id="1383876407941801731">Pesquisar</translation>
-<translation id="1385214448885562192">Pressione Enter para aceitar, Esc para cancelar, seta para baixo para ir para o próximo e seta para cima para ir para o anterior.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652">Caixa de texto de senha <ph name="VALUE" /></translation>
-<translation id="1467432559032391204">Para a esquerda</translation>
-<translation id="1474557363159888097">Nenhuma âncora anterior.</translation>
-<translation id="1502086903961450562">Gráfico anterior</translation>
-<translation id="1506187449813838456">Aumentar tom de voz</translation>
-<translation id="151784044608172266">Próxima frase</translation>
-<translation id="1524531499102321782">Próxima linha Braille</translation>
-<translation id="1546370775711804143">Barra de rolagem</translation>
-<translation id="1559739829547075274">Navegar para trás</translation>
-<translation id="1571643229714746283">ChromeVox pronto</translation>
-<translation id="158493514907962286">Dezembro</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Alternar para braille de seis pontos</translation>
-<translation id="1611168825862729585">Cabeçalho da coluna:</translation>
-<translation id="1613476421962910979">Earcons ativados</translation>
-<translation id="1618597272655350600">Anuncia uma descrição completa da posição atual</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{sinal maior que}one{# sinais de maior que}other{# sinais de maior que}}</translation>
-<translation id="1653266918374749391">Cabeçalho de nível 3 anterior</translation>
-<translation id="1659072772017912254">Não marcado</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">Navegação no ChromeVox</translation>
-<translation id="16777221443363124">Barra de menu</translation>
-<translation id="1692077714702418899">linha estrutural</translation>
-<translation id="1700517974991662022">Visitado</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Próximo gráfico</translation>
-<translation id="1781173782405573156">Ignorar a tecla</translation>
-<translation id="1787176709638001873">Texto de alteração de senha</translation>
-<translation id="1810107444790159527">Caixa de listagem</translation>
-<translation id="1828385960365606039">Maio</translation>
-<translation id="1834891354138622109">Coluna</translation>
-<translation id="1865601187525349519">Fim do texto</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Fala a hora e a data atuais.</translation>
-<translation id="1902396333223336119">Célula</translation>
-<translation id="1905379170753160525">Mostrar lista de cabeçalhos</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Controle de semana do ano</translation>
-<translation id="1964135212174907577">Próximo objeto</translation>
-<translation id="1969092762068865084">Julho</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Cabeçalho de linha:</translation>
-<translation id="2002895034995108595">Redefinir keymap atual</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{colchete esquerdo}one{# colchetes esquerdos}other{# colchetes esquerdos}}</translation>
-<translation id="2045490512405922022">não selecionada</translation>
-<translation id="20601713649439366">Nenhuma expressão matemática anterior.</translation>
-<translation id="207477615537953741">Interpretação semântica desativada</translation>
-<translation id="2086961585857038472">Próxima palavra</translation>
-<translation id="2089387485033699258">pt-BR</translation>
-<translation id="2091933974477985526">Área de texto editável anterior</translation>
-<translation id="2100350898815792233">Todos os sinais de pontuação</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">access key:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Para alterar a tabela de braille de seis pontos atual, selecione uma opção na lista a seguir.</translation>
-<translation id="2169714232367507776">Clicar no item atual</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{parêntese de fechamento}one{# parênteses de fechamento}other{# parênteses de fechamento}}</translation>
-<translation id="2199994615414171367">Expressão matemática anterior</translation>
-<translation id="2223693656926968778">Clicar no item atual</translation>
-<translation id="225732394367814946">Acelerar ritmo da voz</translation>
-<translation id="2267945578749931355">Próximo caractere</translation>
-<translation id="2281234842553884450">Controle deslizante anterior</translation>
-<translation id="2318372665160196757">Principal</translation>
-<translation id="2329324941084714723">Painel da guia</translation>
-<translation id="2344193891939537199">Controle de data e hora</translation>
-<translation id="2359897517538099099">Não no modo de tabela.</translation>
-<translation id="241124561063364910">seguido de</translation>
-<translation id="2417569100218200841">Informações sobre o conteúdo</translation>
-<translation id="2422937916923936891">Caixa de seleção de item de menu</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> é agora o novo modificador do ChromeVox.</translation>
-<translation id="2450814015951372393">Caixa de seleção</translation>
-<translation id="2462626033734746142">Grupo de botões de opção</translation>
-<translation id="2471138580042810658">Cabeçalho 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisco}one{# asteriscos}other{# asteriscos}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> foi redefinido.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Grupo</translation>
-<translation id="2582407057977008361">Lateral</translation>
-<translation id="2589102159832527089">Esta página contém o texto extraído automaticamente do arquivo PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Clique aqui para acessar o original.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">com {COUNT,plural, =1{# item}one{# itens}other{# itens}}</translation>
-<translation id="2614981083756825552">Layout Math ML</translation>
-<translation id="2626530649491650971">clicável</translation>
-<translation id="2628764385451019380">Nenhuma caixa mista anterior.</translation>
-<translation id="2637227747952042642">Math</translation>
-<translation id="2639750663247012216">Teclas modificadoras do ChromeVox</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">Clique no item abaixo de uma chave de roteamento</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{parênteses de abertura}one{# parênteses de abertura}other{# parênteses de abertura}}</translation>
-<translation id="2705875883745373140">Não pressionado</translation>
-<translation id="2706462751667573066">Para cima</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">áudio</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Marcado</translation>
-<translation id="27527859628328957">Ir para o próximo item focalizável</translation>
-<translation id="2770781857296573485">Entrar na exploração de grupo</translation>
-<translation id="2777845298774924149">Saiu</translation>
-<translation id="2800204403141299078">Não há mais elementos diferentes.</translation>
-<translation id="2800780099804980316">Nenhum cabeçalho anterior de nível 1.</translation>
-<translation id="2811204574343810641">Linha</translation>
-<translation id="2816654101880605877">Nenhum controle deslizante a seguir.</translation>
-<translation id="2841013758207633010">Tempo</translation>
-<translation id="2843837985843789981">Grupo anterior</translation>
-<translation id="2844995807198708617">Menu de contexto</translation>
-<translation id="2849332794118375855">Nenhuma caixa de seleção a seguir.</translation>
-<translation id="2864481629947106776">Link anterior</translation>
-<translation id="2873259058405069099">Ir para o início da tabela</translation>
-<translation id="2894654529758326923">Informações</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{chave esquerda}one{# chaves esquerdas}other{# chaves esquerdas}}</translation>
-<translation id="2911433807131383493">Abrir tutorial do ChromeVox</translation>
-<translation id="2932083475399492303">Alternar tipo de linha entre estrutural e layout</translation>
-<translation id="2964026537669811554">Grupo de cabeçalhos</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulação}one{# tabulações}other{# tabulações}}</translation>
-<translation id="2972078295414139404">Não há link anterior visitado.</translation>
-<translation id="2972205263822847197">Dica</translation>
-<translation id="2998131015536248178">Caractere anterior</translation>
-<translation id="2999559350546931576">Diminuir tom de voz</translation>
-<translation id="2999945368667127852">Nenhum widget de mídia a seguir.</translation>
-<translation id="3012414509011670858">Nenhuma seção anterior.</translation>
-<translation id="3030432017085518523">Botão de opção de item de menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apóstrofo}one{# apóstrofos}other{# apóstrofos}}</translation>
-<translation id="3046838483509668188">Opções do ChromeVox</translation>
-<translation id="3047143736589213134">Mapa de teclado experimental</translation>
-<translation id="3060756054951570867">Menu <ph name="TITLE" /> aberto</translation>
-<translation id="3078345202707391975">Próximo cabeçalho de nível 2</translation>
-<translation id="3078740164268491126">tabela</translation>
-<translation id="3082557070674409251">foi clicado</translation>
-<translation id="3084806535845658316">sem eco de digitação</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Nenhuma expressão matemática a seguir.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Próximo ponto de referência</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Recolhido</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Mostrar lista de pontos de referência</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Próxima linha</translation>
-<translation id="3155083529632865074">Nenhum botão anterior.</translation>
-<translation id="3163593631834463955">Cabeçalho de coluna vazio</translation>
-<translation id="316542773973815724">Navegação</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{espaço}one{# espaços}other{# espaços}}</translation>
-<translation id="320961988183078793">inserção de <ph name="TYPE" /></translation>
-<translation id="3223701887221307104">Guia <ph name="NAME" /></translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Link visitado</translation>
-<translation id="323731244387692321">Abrir ajuda de teclado do ChromeVox</translation>
-<translation id="3241052487511142956">Link anterior visitado</translation>
-<translation id="3286390186030710347">Slide</translation>
-<translation id="3299925995433437805">Não há próximo link visitado.</translation>
-<translation id="3303384412438961941">Pressionar qualquer tecla para conhecer seu nome. Ctrl+W fecha o explorador do teclado.</translation>
-<translation id="3307886118343381874">Ir para o fim da tabela</translation>
-<translation id="3311969765485641742">Pressione Alt+Shift+A para analisar os alertas</translation>
-<translation id="3312997241656799641">Próximo link visitado</translation>
-<translation id="3321460131042519426">Ativar quebra de palavra</translation>
-<translation id="3322936298410871309">Cabeçalho de nível 1 anterior</translation>
-<translation id="3323447499041942178">Caixa de texto</translation>
-<translation id="3353420241558113817">{"ar": "árabe",
- "bg": "búlgaro",
- "ca": "catalão",
- "cs": "tcheco",
- "da": "dinamarquês",
- "de": "alemão",
- "de_CH": "alemão (Suíça)",
- "de_DE": "alemão (Alemanha)",
- "el": "grego",
- "en": "inglês",
- "en_CA": "inglês (Canadá)",
- "en_GB": "inglês (Reino Unido)",
- "en_US": "inglês (Estados Unidos)",
- "es": "espanhol",
- "et": "estoniano",
- "fr": "francês",
- "fr_CA": "francês (Canadá)",
- "fr_FR": "francês (França)",
- "fi": "finlandês",
- "he": "hebraico",
- "hi": "hindi",
- "hr": "croata",
- "hu": "húngaro",
- "is": "islandês",
- "it": "italiano",
- "ko": "coreano",
- "lt": "lituano",
- "lv": "letão",
- "nb": "bokmål norueguês",
- "nl": "holandês",
- "pl": "polonês",
- "pt": "português",
- "ro": "romeno",
- "ru": "russo",
- "sk": "eslovaco",
- "sl": "esloveno",
- "sr": "sérvio",
- "sv": "sueco",
- "tr": "turco",
- "vi": "vietnamita",
- "zh": "chinês",
- "zh_TW": "chinês (Han tradicional)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{sinal de mais}one{# sinais de mais}other{# sinais de mais}}</translation>
-<translation id="338583716107319301">Separador</translation>
-<translation id="3389259863310851658">Campo de formulário anterior</translation>
-<translation id="3390225400784126843">Próximo elemento diferente.</translation>
-<translation id="3392045790598181549">Item de menu <ph name="NAME" /></translation>
-<translation id="3406283310380167331">Mostrar lista de formulários</translation>
-<translation id="3422338090358345848">Abrir explorador de teclado</translation>
-<translation id="3457000393508828486">Parcialmente pressionado</translation>
-<translation id="3462439746547587373">Botão <ph name="NAME" /></translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> a <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{colchete direito}one{# colchetes direitos}other{# colchetes direitos}}</translation>
-<translation id="3493915602752813531">Nenhuma âncora a seguir.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{ponto de interrogação}one{# pontos de interrogação}other{# pontos de interrogação}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{acento circunflexo}one{# acentos circunflexos}other{# acentos circunflexos}}</translation>
-<translation id="3568702578574425662">Caixa de seleção <ph name="NAME" /> não marcada</translation>
-<translation id="3599054940393788245">Sem matemática interna</translation>
-<translation id="3616113530831147358">Áudio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{acento grave}one{# acentos graves}other{# acentos graves}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{cifrão}one{# sinais de cifrão}other{# sinais de cifrão}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755">Caixa de listagem <ph name="VALUE" /></translation>
-<translation id="3687295507293856493">Fazer estimativa do cabeçalho da coluna da célula atual</translation>
-<translation id="3692274950075847560">P:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Controle de voz</translation>
-<translation id="3716845769494773620">Multilinha</translation>
-<translation id="3731746171184829332">Nenhum cabeçalho anterior.</translation>
-<translation id="3762198587642264450">Ir para o fim da linha atual</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Caixa de diálogo fechada.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}other{#}}</translation>
-<translation id="3801735343383419236">Lista de preenchimento automático</translation>
-<translation id="3810838688059735925">Vídeo</translation>
-<translation id="3816633764618089385">Próxima mídia</translation>
-<translation id="3819376190738087562">Nenhum salto.</translation>
-<translation id="385383972552776628">Abrir página de opções</translation>
-<translation id="3856075812838139784">Somente leitura</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Cabeçalho de nível 6 anterior</translation>
-<translation id="3914173277599553213">Obrigatória</translation>
-<translation id="3962990492275676168">Iniciar a leitura na posição atual</translation>
-<translation id="4004802134384979325">marcada</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Controle de mês</translation>
-<translation id="4039983576244166038">Cabeçalho da linha vazio</translation>
-<translation id="4042843249978639960">Nenhum cabeçalho de nível 2 a seguir.</translation>
-<translation id="4043348641337972076">Nenhum ponto de referência ARIA anterior.</translation>
-<translation id="4047216625641135770">Mark</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{til}one{# sinais de til}other{# sinais de til}}</translation>
-<translation id="409334809956508737">Objeto anterior</translation>
-<translation id="4099274309791143834">com submenu</translation>
-<translation id="4107807507418787238">Nenhuma célula abaixo.</translation>
-<translation id="4116415223832267137">Alerta</translation>
-<translation id="4147126331795725888">Nenhum controle a seguir.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{chave direita}one{# chaves direitas}other{# chaves direitas}}</translation>
-<translation id="4158704014418536539">Diferencia maiúsculas de minúsculas.</translation>
-<translation id="4161663686871496107">O feedback falado do ChromeVox está pronto</translation>
-<translation id="4173994908659439270">Nenhum campo de texto editável a seguir.</translation>
-<translation id="4176463684765177261">Desativado</translation>
-<translation id="4188530942454211480">Frase anterior</translation>
-<translation id="4202186506458631436">Mover para a direita</translation>
-<translation id="4206289001967551965">Dentro da tabela</translation>
-<translation id="4215733775853809057">Próximo controle deslizante</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{traço}one{# traços}other{# traços}}</translation>
-<translation id="421884353938374759">Seletor de cores</translation>
-<translation id="4229646983878045487">data hora</translation>
-<translation id="423334822609210999">Nenhuma célula à esquerda.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, Grade <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Nota</translation>
-<translation id="4254798249533888099">Árvore</translation>
-<translation id="4255943572433203166">Use as opções abaixo para personalizar o ChromeVox. As alterações têm efeito imediato.</translation>
-<translation id="4271220233568730077">Próxima expressão matemática</translation>
-<translation id="4271521365602459209">Não há mais resultados.</translation>
-<translation id="4287520460805643128">Não há artigos a seguir.</translation>
-<translation id="4289540628985791613">Visão geral</translation>
-<translation id="4300318234632215983">Anunciar o URL associado a um link</translation>
-<translation id="4301352596632316575">possui submenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{ponto}=3{reticências}one{# pontos}other{# pontos}}</translation>
-<translation id="4347461890115250064">Nenhuma lista a seguir.</translation>
-<translation id="4367650418938037324">Math ML Leaf</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Parar voz</translation>
-<translation id="4373197658375206385">Nenhum link anterior que não seja um link.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Nenhum link.</translation>
-<translation id="4476183483923481720">linha nova</translation>
-<translation id="4482330759234983253">Tabela anterior</translation>
-<translation id="4491109536499578614">Imagem</translation>
-<translation id="4529987814483543472">Mapa de teclado clássico</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{barra}one{# barras}other{# barras}}</translation>
-<translation id="4547556996012970016">Próximo cabeçalho de nível 5</translation>
-<translation id="4562381607973973258">Cabeçalho</translation>
-<translation id="4591507479202817876">. selecionado</translation>
-<translation id="4597532268155981612">formulário</translation>
-<translation id="4597896406374528575">Abril</translation>
-<translation id="4615592953348396470">Ignorando o uso da tecla "Próximo"</translation>
-<translation id="461613135510474570">Sentença</translation>
-<translation id="4647836961514597010">Seletor de cores</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Ponto de referência anterior</translation>
-<translation id="4696413482802371445">Nenhum cabeçalho de nível 5 a seguir.</translation>
-<translation id="4729095194763193578">Linha anterior da tabela</translation>
-<translation id="4736221692378411923">Agosto</translation>
-<translation id="4740661827607246557">Comandos de ajuda</translation>
-<translation id="4759716709594980008">Explorador de teclado ChromeOS</translation>
-<translation id="4763296182459741068">Avançar para baixo</translation>
-<translation id="4763480195061959176">vídeo</translation>
-<translation id="479989351350248267">pesquisar</translation>
-<translation id="481165870889056555">Anunciar o título da página atual</translation>
-<translation id="4826415162591436065">Navegar para a frente</translation>
-<translation id="4826604887384865800">Próximo atalho</translation>
-<translation id="4827410568042294688">unselected</translation>
-<translation id="4842108708071771135">Nenhum bloco de texto a seguir.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Elemento semelhante anterior.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Ativar registros TTS</translation>
-<translation id="4877261390094455813">Inserir uma consulta de pesquisa.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Link interno</translation>
-<translation id="4953585991029886728">Texto de edição</translation>
-<translation id="4954534434583049121">Citação em bloco anterior</translation>
-<translation id="4973717656530883744">Min <ph name="X" /></translation>
-<translation id="4973762002207131920">Comutado para <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milésimos de segundo</translation>
-<translation id="49787999531187221">O ChromeVox está desativado.</translation>
-<translation id="4979404613699303341">Botão anterior</translation>
-<translation id="4982773647088557172">Caixa de listagem <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="4983588134362688868">Vai para a parte superior da página</translation>
-<translation id="4986606102545753256">Janela <ph name="NAME" /></translation>
-<translation id="4993152509206108683">Velocidade <ph name="PERCENT" /> por cento</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877">Botão de opção <ph name="NAME" /> selecionado</translation>
-<translation id="4997475792277222884">Nenhum item a seguir que não seja link.</translation>
-<translation id="5000760171916499057">Não há formulários.</translation>
-<translation id="5005670136041063723">Não há mais elementos semelhantes.</translation>
-<translation id="501473567976723023">Janeiro</translation>
-<translation id="5041394372352067729">Mover exibição braille para o topo da página</translation>
-<translation id="5042770794184672516">Aumentar volume da voz</translation>
-<translation id="5050015258024679800">Cabeçalho de nível 4 anterior</translation>
-<translation id="5054047268577924192">Item anterior da lista</translation>
-<translation id="5078661581131202757">Seleção de arquivo</translation>
-<translation id="5080758118274074384">clicado duas vezes</translation>
-<translation id="5098541983634824365">Saindo da grade.</translation>
-<translation id="5102981729317424850">Barra de ferramentas</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Nenhum campo de formulário anterior.</translation>
-<translation id="5111640677200759579">Cabeçalho da coluna</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Não há link anterior.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, seleção cancelada</translation>
-<translation id="5183440668879371625">Linha Braille anterior</translation>
-<translation id="5184944171021383281">Nenhum campo de formulário a seguir.</translation>
-<translation id="5189244881767082992">Linha</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> já está atribuído a um comando.</translation>
-<translation id="5205493599117157272">Lista de <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Nenhum botão de opção a seguir.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objeto</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, tab</translation>
-<translation id="5310788376443009632">removido:</translation>
-<translation id="5320727453979144100">Modo aderente ativado</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{vírgula}one{# vírgulas}other{# vírgulas}}</translation>
-<translation id="532371086589123547">Caixa de texto <ph name="VALUE" /></translation>
-<translation id="5330443287809544590">Link <ph name="NAME" /></translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Ir para trás durante a leitura contínua</translation>
-<translation id="5368000168321181111">Earcons desativados</translation>
-<translation id="5374320867641260420">Nenhum botão a seguir.</translation>
-<translation id="5382299583965267720">Nenhum cabeçalho de nível 1 a seguir.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{sinal de ponto-e-vírgula}one{# sinais de ponto-e-vírgula}other{# sinais de ponto-e-vírgula}}</translation>
-<translation id="5411891038905756502">No previous jump point.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{sinal de menor que}one{# sinais de menor que}other{# sinais de menor que}}</translation>
-<translation id="5455441614648621694">Complementar</translation>
-<translation id="5485036206801896268">Nenhum gráfico anterior.</translation>
-<translation id="5486947920110100234">Nenhum ponto de salto a seguir.</translation>
-<translation id="549602578321198708">Palavra</translation>
-<translation id="5500932716852106146">Nenhum campo de texto editável anterior.</translation>
-<translation id="5502713021410870035">Setembro</translation>
-<translation id="5507663321906818013">Depurar ponto de partida</translation>
-<translation id="5518443085409638729">Ao editar um texto, coloque o cursor entre os caracteres (como o Mac OS X).</translation>
-<translation id="552195134157544755">Botão de opção</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Nenhum cabeçalho anterior de nível 5.</translation>
-<translation id="556042886152191864">Botão</translation>
-<translation id="5561345396546889625">Próxima lista</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Editar texto, entrada de e-mail</translation>
-<translation id="5597170376237141345">Próxima caixa de seleção</translation>
-<translation id="5597933780944041114">Nenhum cabeçalho a seguir.</translation>
-<translation id="5598905979683743333">Botão de opção <ph name="NAME" /> desmarcado</translation>
-<translation id="5601172225407283979">Executar ação padrão</translation>
-<translation id="5608798115546226984">Preenchimento automático em linha</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Registro</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Nenhuma tabela anterior.</translation>
-<translation id="5655682562155942719">Comandos de avanço e retorno</translation>
-<translation id="56637627897541303">Área de texto</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Ponto de referência</translation>
-<translation id="5683155931978483559">Caixa de seleção anterior</translation>
-<translation id="5684277895745049190">Lista</translation>
-<translation id="5700650669149824506">Nenhum cabeçalho anterior de nível 4.</translation>
-<translation id="5709192780268610569">Nenhuma descrição longa</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Próxima coluna da tabela</translation>
-<translation id="571866080859340309">Explorando grupos</translation>
-<translation id="5728409797179002635">Nenhuma tabela encontrada.</translation>
-<translation id="5748623122140342504">Cabeçalho de nível 5 anterior</translation>
-<translation id="5750633686117194034">Nenhum modificador foi pressionado. Pressione e mantenha pressionado um ou mais modificadores. Levante os dedos uma vez e você ouvirá as teclas definidas. Pressione "Tab" para sair.</translation>
-<translation id="5788275253279308023">Janela anônima, guia <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Aprimore sites específicos (como a Pesquisa Google).</translation>
-<translation id="5819072574982403430">Item de árvore</translation>
-<translation id="5826479389509458994">linha <ph name="ROW" /> coluna <ph name="COL" /></translation>
-<translation id="5850707923114094062">Movimentar para trás</translation>
-<translation id="5851548754964597211">Lista de guias</translation>
-<translation id="5859752971144398932">Saiu da localização na página.</translation>
-<translation id="5866042630553435010">Parcialmente marcado</translation>
-<translation id="5869546221129391014">Grade</translation>
-<translation id="5876817486144482042">Diminuir volume da voz</translation>
-<translation id="5887397643266327462">Legendas em Braille ativadas.</translation>
-<translation id="5891934789323004067">Tabela</translation>
-<translation id="5919442531159595654">copiar.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{sinal de igual}one{# sinais de igual}other{# sinais de igual}}</translation>
-<translation id="5939518447894949180">Redefinir</translation>
-<translation id="5948123859135882163">Alternar a interpretação de expressões matemáticas entre estrutural e semântica</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Diálogo</translation>
-<translation id="5963413905009737549">Seção</translation>
-<translation id="5968607524793740041">Mostrar menu de contexto</translation>
-<translation id="5983179082906765664">Aumentar granularidade de navegação</translation>
-<translation id="5999630716831179808">Vozes</translation>
-<translation id="6000417740266304866">Para alterar a tabela de braille de oito pontos atual, selecione uma opção na lista a seguir.</translation>
-<translation id="6006050241733874051">Formulário</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{barra invertida}one{# barras invertidas}other{# barras invertidas}}</translation>
-<translation id="6037602951055904232">Mover para a frente</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Final da célula.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Espaço</translation>
-<translation id="6142308968191113180">Cabeçalho 4</translation>
-<translation id="6169420925157477918">Imagem com descrição longa</translation>
-<translation id="6172087735260766220">Não foi possível acessar o texto acessível a partir do PDF protegido contra cópia.</translation>
-<translation id="6186305613600865047">Vai para a parte inferior da página</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Seta para baixo</translation>
-<translation id="6236061028292614533">Próximo cabeçalho</translation>
-<translation id="6254901459154107917">Próxima área de texto editável</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> fechado.</translation>
-<translation id="6281876499889881039">Próximo elemento semelhante.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Nenhuma caixa mista a seguir.</translation>
-<translation id="6307969636681130414">Pressionado</translation>
-<translation id="6324551002951139333">Erro gramatical detectado</translation>
-<translation id="6348657800373377022">Caixa de combinação</translation>
-<translation id="6355910664415701303">Nenhum item a seguir na lista.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Cabeçalho anterior</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Nenhum botão de opção anterior.</translation>
-<translation id="6414968628640960377">Elemento diferente anterior.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{um sinal de dois-pontos}one{# sinais de dois-pontos}other{# sinais de dois-pontos}}</translation>
-<translation id="6438968337250688271">Menu <ph name="NAME" /></translation>
-<translation id="6444046323172968959">Diálogo de alerta</translation>
-<translation id="6459511626086141404">Keymap plano</translation>
-<translation id="6468049171101508116">Próximo botão</translation>
-<translation id="6491972999578897419">Alterar a voz atual, selecionando uma opção na lista abaixo.</translation>
-<translation id="6508059270146105198">Mover exibição braille para o fim da página</translation>
-<translation id="6536864053412760904">Token Math ML</translation>
-<translation id="6550720799683018100">Alterar o mapa de teclado atual, selecionando uma opção na lista abaixo.</translation>
-<translation id="6561818612645211875">Ir para o início da linha atual</translation>
-<translation id="6587021927234520429">Nenhum cabeçalho de nível 4 a seguir.</translation>
-<translation id="6601344353291556895">Ativar descrições detalhadas.</translation>
-<translation id="6615602925644411249">Localizar na página.</translation>
-<translation id="6633350132811819843">Nenhuma tabela a seguir.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Barra de progresso</translation>
-<translation id="6659594942844771486">Guia</translation>
-<translation id="667999046851023355">Documento</translation>
-<translation id="6697092096875747123">Caixa de combinação anterior</translation>
-<translation id="6714813999819678458">Cabeçalho de nível 2 anterior</translation>
-<translation id="6716505898850596801">Teclas modificadoras.</translation>
-<translation id="671916444866103745">Nenhum ponto de referência ARIA a seguir.</translation>
-<translation id="6734854816611871228">Caixa de texto: <ph name="VALUE" /></translation>
-<translation id="6735257939857578167">com <ph name="NUM" /> itens</translation>
-<translation id="6736510033526053669">guia criada</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artigo</translation>
-<translation id="6787839852456839824">Atalhos do teclado</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Rodapé</translation>
-<translation id="6871161210040114857">Não diferencia maiúsculas de minúsculas.</translation>
-<translation id="6877435256196695200">Nenhum gráfico a seguir.</translation>
-<translation id="6897341342232909480">Mover para a esquerda</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Excluído</translation>
-<translation id="6911965441508464308">Nenhuma célula acima.</translation>
-<translation id="6919104639734799681">Mostrar lista de tabelas</translation>
-<translation id="6964088412282673743">Nenhum controle anterior.</translation>
-<translation id="6996566555547746822">Próxima caixa de combinação</translation>
-<translation id="7005146664810010831">Nenhum URL encontrado</translation>
-<translation id="7010712454773919705">Teclas modificadoras do ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Lista anterior</translation>
-<translation id="7041173719775863268">Concluir seleção</translation>
-<translation id="7095834689119144465">Editar apenas texto numérico</translation>
-<translation id="7096001299300236431">Mídia anterior</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">eco de palavra</translation>
-<translation id="713824876195128146">Próxima citação em bloco</translation>
-<translation id="7161771961008409533">Botão pop-up</translation>
-<translation id="7167657087543110">eco de caractere</translation>
-<translation id="7170733337935166589">Ir para a frente durante a leitura contínua</translation>
-<translation id="7181697990050180700">Personalizar atalhos de teclado para os comandos usados com frequência, digitando-os nos campos correspondentes abaixo.</translation>
-<translation id="7203150201908454328">Expandido</translation>
-<translation id="7210211103303402262">minutos</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">linha</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Cabeçalho</translation>
-<translation id="7241683698754534149">Abrir descrição longa em uma nova página</translation>
-<translation id="7248671827512403053">Aplicativo</translation>
-<translation id="725969808843520477">Próximo botão de opção</translation>
-<translation id="7269119382257320590">Sem pontuação</translation>
-<translation id="7273174640290488576">Em branco</translation>
-<translation id="7285387653379749618">Tabelas</translation>
-<translation id="7289186959554153431">Cabeçalho 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Legendas em Braille desativadas.</translation>
-<translation id="7318872822751139669">Use o mouse para alterar o foco.</translation>
-<translation id="7322388933135261569">Fevereiro</translation>
-<translation id="7332592614823088566">Linha <ph name="ROWINDEX" /> de <ph name="ROWTOTAL" />, Coluna <ph name="COLINDEX" /> de <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">possui pop-up</translation>
-<translation id="7356165926712028380">Alternar para braille de oito pontos</translation>
-<translation id="7362871137496673139">Nenhum cabeçalho anterior de nível 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{sinal de "E" comercial}one{# sinais de "E" comercial}other{# sinais de "E" comercial}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Saindo da tabela.</translation>
-<translation id="739763518212184081">Linha anterior</translation>
-<translation id="7400575256015741911">Erro ortográfico detectado</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">retorna</translation>
-<translation id="7434509671034404296">Desenvolvedor</translation>
-<translation id="7439060726180460871">Diretório</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Diálogo introduzido</translation>
-<translation id="7532613204005497612">Junho</translation>
-<translation id="7540083713905917247">Controle deslizante <ph name="VALUE" />, <ph name="NAME" />,</translation>
-<translation id="7586163296341959563">colar.</translation>
-<translation id="7596919493010894443">seleção cancelada</translation>
-<translation id="7604026522577407655">Ir para o início da coluna atual</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Anunciar o URL da página atual</translation>
-<translation id="7609363189280667021">Alternar para legendas em braille</translation>
-<translation id="762020119231868829">Pausa todos os widgets de mídia em execução no momento</translation>
-<translation id="7625690649919402823">Próxima tabela</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), grau <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Nenhum cabeçalho anterior de nível 3.</translation>
-<translation id="7659376057562985921">Caixa de texto <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="7663318257180412551">Cabeçalho 2</translation>
-<translation id="7674576868851035240">Próximo link</translation>
-<translation id="7674768236845044097">marcar</translation>
-<translation id="7684431668231950609">Editar texto, entrada de URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Botão de opção anterior</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748">Caixa de texto de senha <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="7805247615045262757">navegação padrão</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Próximo grupo</translation>
-<translation id="7819187121850078213">Janela, guia <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Outubro</translation>
-<translation id="7839679365527550018">Palavra anterior</translation>
-<translation id="7851816175263618915">Alguns sinais de pontuação</translation>
-<translation id="7870596830398826354">Math ML Tree</translation>
-<translation id="78826985582142166">slider</translation>
-<translation id="7894517696028036636">Alternar ChromeVox classic.</translation>
-<translation id="7895896691902835279">Link desconhecido</translation>
-<translation id="7927711904086083099">Não selecionado</translation>
-<translation id="7935627501098484003">Controle de hora</translation>
-<translation id="7939428177581522200">adicionados a seleção</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{sinal de arroba}one{# sinais de arroba}other{# sinais de arroba}}</translation>
-<translation id="7965147473449754028">menu fechado</translation>
-<translation id="7974390230414479278">Item de menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ponto de exclamação}one{# pontos de exclamação}other{# pontos de exclamação}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{aspas}one{# sinais de aspas}other{# sinais de aspas}}</translation>
-<translation id="8033827949643255796">selecionado</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">Editar texto, entrada de pesquisa</translation>
-<translation id="8049189770492311300">Timer</translation>
-<translation id="8065607967589909823">A seleção é</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Nenhum ponto de referência ARIA.</translation>
-<translation id="8153880621934657047">Não está dentro da tabela.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{sublinhado}one{# sublinhados}other{# sublinhados}}</translation>
-<translation id="8179976553408161302">Entrar</translation>
-<translation id="81960742267269908">recortar.</translation>
-<translation id="8199231515320852133">Anunciar cabeçalhos da célula atual</translation>
-<translation id="820417203470636242">Célula vazia.</translation>
-<translation id="8215202828671303819">Seleção múltipla</translation>
-<translation id="8276439074553447000">Ir para o item focalizável anterior</translation>
-<translation id="8278417001922463147">Não há artigos anteriores.</translation>
-<translation id="8283603667300770666">Próximo campo do formulário</translation>
-<translation id="831207808878314375">Definição</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">horas</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{sinal de cerquilha}one{# sinais de cerquilha}other{# sinais de cerquilha}}</translation>
-<translation id="8374154622594089836">mês</translation>
-<translation id="8378855320830505539">Região</translation>
-<translation id="8382679411218029383">Preenchimento automático em linha e lista</translation>
-<translation id="8428603554127842284">nível <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Nenhum cabeçalho de nível 3 a seguir.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Nenhuma caixa de seleção anterior.</translation>
-<translation id="8455868257606149352">Máximo <ph name="X" /></translation>
-<translation id="84575901236241018">tem chave de acesso: <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Diminuir granularidade da navegação</translation>
-<translation id="8520472399088452386">Botão de rotação</translation>
-<translation id="8538744478902126321">Fazer estimativa do cabeçalho da linha da célula atual</translation>
-<translation id="8540054775867439484">Retornar para o topo</translation>
-<translation id="8548973727659841685">Caractere</translation>
-<translation id="8561322612995434619">possui pop-up</translation>
-<translation id="8571096049907249734">mult sel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Próximo item da lista</translation>
-<translation id="860150890330522909">Caixa de seleção <ph name="NAME" /> marcada</translation>
-<translation id="8606621670302093223">Controle de data</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> itens selecionados</translation>
-<translation id="8638532244051952400">Anunciar coordenadas da célula atual</translation>
-<translation id="8650576015643545550">Nenhuma lista anterior.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Mostrar lista de links</translation>
-<translation id="8664519043722036194">segundos</translation>
-<translation id="867187640362843212">Cabeçalho 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{barra vertical}one{# barras verticais}other{# barras verticais}}</translation>
-<translation id="8735450637152821465">Iniciar seleção</translation>
-<translation id="8743786158317878347">insere conteúdo estruturado, como tabelas</translation>
-<translation id="8747966237988593539">Lista ordenada</translation>
-<translation id="8759334257841767240">Nenhum link a seguir.</translation>
-<translation id="8767968232364267681">Próximo cabeçalho de nível 4</translation>
-<translation id="8770473310765924354">sai de conteúdo estruturado, como tabelas</translation>
-<translation id="8791025954632646584">Interpretação semântica ativada</translation>
-<translation id="8796411681063377102">Próximo cabeçalho de nível 3</translation>
-<translation id="8808582214901541005">Março</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Pressione a seta para cima ou para baixo para revisar os comandos, ou pressione Enter para ativar</translation>
-<translation id="8864099967139188018">Nenhum cabeçalho de nível 6 a seguir.</translation>
-<translation id="8882002077197914455">Cabeçalho de linha</translation>
-<translation id="8896347895970027998">Ativar ou desativar ChromeVox.</translation>
-<translation id="8898516272131543774">Percorrer eco de pontuação</translation>
-<translation id="8900148057318340779">Tecla de prefixo</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Cabeçalhos vazios</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Teclas modificadoras</translation>
-<translation id="8943175951035496220">Nenhuma célula à direita.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Nenhuma tabela.</translation>
-<translation id="9040132695316389094">Cabeçalho 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Alternar para widget de pesquisa</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">removido da seleção</translation>
-<translation id="9082874451376019682">Nenhum controle deslizante anterior.</translation>
-<translation id="9089864840575085222">Percorrer eco de digitação</translation>
-<translation id="9107530006868467849">Nenhum widget de mídia anterior.</translation>
-<translation id="9108370397979208512">matemática</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{porcentagem}one{# sinais de porcentagem}other{# sinais de porcentagem}}</translation>
-<translation id="9115913704608474258">Novembro</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Anuncia uma breve descrição da situação atual</translation>
-<translation id="9153606228985488238">Tom <ph name="PERCENT" /> por cento</translation>
-<translation id="9160096769946561184">Ir para o fim da coluna atual</translation>
-<translation id="9173115498289768110">Volume <ph name="PERCENT" /> por cento</translation>
-<translation id="9178973770513562274">Use as teclas de seta para cima e para baixo para navegar ou digite para pesquisar.</translation>
-<translation id="9192904702577636854">Letreiro</translation>
-<translation id="9212322457209634662">Nenhuma seção a seguir.</translation>
-<translation id="930275611743429116">Iniciar ou finalizar seleção.</translation>
-<translation id="948171205378458592">Desacelerar ritmo da voz</translation>
-<translation id="962913030769097253">Próximo cabeçalho de nível 1</translation>
-<translation id="973955474346881951">Ativar/desativar modo aderente</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-PT.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-PT.xtb
deleted file mode 100644
index 0e1885069b1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-PT.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="pt-PT">
-<translation id="1012173283529841972">Item de lista</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Expandido.</translation>
-<translation id="1025074108959230262">Modo aderente desativado</translation>
-<translation id="1031961866430398710">em seguida</translation>
-<translation id="1044777062731150180">Sem cabeçalhos</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Entrada inválida</translation>
-<translation id="1082209053475788238">Não existe nenhum título de nível 6 anterior.</translation>
-<translation id="1088219014394087294">Não existe nenhum título.</translation>
-<translation id="1106741348836243114">Ativar ou desativar respostas sonoras (ícones sonoros).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Coleção de <ph name="TAG" /> com <ph name="NUM" /> itens</translation>
-<translation id="1155043339247954670">Não existe nenhum item de lista seguinte.</translation>
-<translation id="1157782847298808853">Ajuda do teclado</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, caixa de combinação</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, item de menu, com submenu</translation>
-<translation id="1177863135347784049">Personalizado</translation>
-<translation id="1188858454923323853">complementar</translation>
-<translation id="1206619573307042055">painel rolante</translation>
-<translation id="1213216066620407844">ChromeVox - A dar voz ao Chrome</translation>
-<translation id="1229276918471378188">Avanço anterior</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Título de nível 6 seguinte</translation>
-<translation id="1275718070701477396">Selecionado</translation>
-<translation id="1319608975892113573">Não existe nenhum blockquote anterior.</translation>
-<translation id="1321576897702511272">Ocultar ajuda do ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> de <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">eco do caráter e da palavra</translation>
-<translation id="1339428534620983148">Coluna anterior da tabela</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Direita</translation>
-<translation id="136718599399906424">Linha seguinte da tabela</translation>
-<translation id="1383876407941801731">Pesquisar</translation>
-<translation id="1385214448885562192">Prima Enter para aceitar ou escape para cancelar, seta para baixo para seguinte e seta para cima para anterior.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, caixa de texto da palavra-passe</translation>
-<translation id="1467432559032391204">Esquerda</translation>
-<translation id="1474557363159888097">Não existe nenhuma âncora anterior.</translation>
-<translation id="1502086903961450562">Gráfico anterior</translation>
-<translation id="1506187449813838456">Aumentar timbre</translation>
-<translation id="151784044608172266">Frase seguinte</translation>
-<translation id="1524531499102321782">Linha braille seguinte</translation>
-<translation id="1546370775711804143">Barra de deslocamento</translation>
-<translation id="1559739829547075274">Navegar para trás</translation>
-<translation id="1571643229714746283">ChromeVox pronto</translation>
-<translation id="158493514907962286">Dezembro</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Mudar para braille de 6 pontos</translation>
-<translation id="1611168825862729585">Cabeçalho da coluna:</translation>
-<translation id="1613476421962910979">Ícones sonoros ativados</translation>
-<translation id="1618597272655350600">Anuncia uma descrição completa da posição atual</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{maior que}other{# sinais de maior que}}</translation>
-<translation id="1653266918374749391">Título de nível 3 anterior</translation>
-<translation id="1659072772017912254">Não marcado</translation>
-<translation id="1669290819662866522">semana</translation>
-<translation id="1674262202423278359">Navegação do ChromeVox</translation>
-<translation id="16777221443363124">Barra de menu</translation>
-<translation id="1692077714702418899">linha estrutural</translation>
-<translation id="1700517974991662022">Visitado</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Gráfico seguinte</translation>
-<translation id="1781173782405573156">Tecla de passagem</translation>
-<translation id="1787176709638001873">Texto de edição de palavra-passe</translation>
-<translation id="1810107444790159527">Caixa de listagem</translation>
-<translation id="1828385960365606039">Maio</translation>
-<translation id="1834891354138622109">Coluna</translation>
-<translation id="1865601187525349519">Fim do texto</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Diga a data e hora atuais.</translation>
-<translation id="1902396333223336119">Célula</translation>
-<translation id="1905379170753160525">Mostrar lista de títulos</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Controlo da semana do ano</translation>
-<translation id="1964135212174907577">Objeto seguinte</translation>
-<translation id="1969092762068865084">Julho</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Cabeçalho da linha:</translation>
-<translation id="2002895034995108595">Repor mapa de teclas atual</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{parêntese reto esquerdo}other{# parênteses retos esquerdos}}</translation>
-<translation id="2045490512405922022">desmarcada</translation>
-<translation id="20601713649439366">Não existe nenhuma expressão matemática anterior.</translation>
-<translation id="207477615537953741">Semântica desativada</translation>
-<translation id="2086961585857038472">Palavra seguinte</translation>
-<translation id="2089387485033699258">pt-PT</translation>
-<translation id="2091933974477985526">Área de texto editável anterior</translation>
-<translation id="2100350898815792233">Pontuação total</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">access key:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Alterar a tabela atual de braille de 6 pontos ao selecionar uma opção na lista abaixo.</translation>
-<translation id="2169714232367507776">Clicar no item atual</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{parêntese direito}other{# parênteses direitos}}</translation>
-<translation id="2199994615414171367">Matemática anterior</translation>
-<translation id="2223693656926968778">Exercer ação sobre o item atual</translation>
-<translation id="225732394367814946">Aumentar a velocidade de voz</translation>
-<translation id="2267945578749931355">Caráter seguinte</translation>
-<translation id="2281234842553884450">Controlo de deslize anterior</translation>
-<translation id="2318372665160196757">Principal</translation>
-<translation id="2329324941084714723">Painel de separadores</translation>
-<translation id="2344193891939537199">Controlo de hora e data</translation>
-<translation id="2359897517538099099">Não está no modo de tabela.</translation>
-<translation id="241124561063364910">seguido de</translation>
-<translation id="2417569100218200841">Informações do conteúdo</translation>
-<translation id="2422937916923936891">Caixa de verificação do item de menu</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> é agora o novo modificador do ChromeVox.</translation>
-<translation id="2450814015951372393">Caixa de verificação</translation>
-<translation id="2462626033734746142">Grupo de botões de opção</translation>
-<translation id="2471138580042810658">Título 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisco}other{# asteriscos}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> foi reposto.</translation>
-<translation id="2553108862507765288">erro gramatical</translation>
-<translation id="257674075312929031">Grupo</translation>
-<translation id="2582407057977008361">À parte</translation>
-<translation id="2589102159832527089">Esta página contém o texto extraído automaticamente do ficheiro PDF &lt;b&gt;<ph name="FILENAME" />&lt;/ b&gt;. &lt;a href="<ph name="URL" />"&gt;Clique aqui para obter o original.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">com {COUNT,plural, =1{# item}other{# itens}}</translation>
-<translation id="2614981083756825552">Esquema de Matemática ML</translation>
-<translation id="2626530649491650971">clicável</translation>
-<translation id="2628764385451019380">Não existe nenhuma caixa de combinação anterior.</translation>
-<translation id="2637227747952042642">Matemática</translation>
-<translation id="2639750663247012216">Modificador do ChromeVox</translation>
-<translation id="2644542693584024604">erro ortográfico</translation>
-<translation id="2667291555398229137">Clique no item sob uma chave de encaminhamento</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{parêntese esquerdo}other{# parênteses esquerdos}}</translation>
-<translation id="2705875883745373140">Não premido</translation>
-<translation id="2706462751667573066">Para cima</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">áudio</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Marcado</translation>
-<translation id="27527859628328957">Ir para o item a focar seguinte</translation>
-<translation id="2770781857296573485">Entrar na exploração de grupos</translation>
-<translation id="2777845298774924149">Saiu</translation>
-<translation id="2800204403141299078">Não existem mais elementos diferentes.</translation>
-<translation id="2800780099804980316">Não existe nenhum título de nível 1 anterior.</translation>
-<translation id="2811204574343810641">Linha</translation>
-<translation id="2816654101880605877">Não existe nenhum controlo de deslize seguinte.</translation>
-<translation id="2841013758207633010">Tempo</translation>
-<translation id="2843837985843789981">Grupo anterior</translation>
-<translation id="2844995807198708617">Menu de contexto</translation>
-<translation id="2849332794118375855">Não existe nenhuma caixa de verificação seguinte.</translation>
-<translation id="2864481629947106776">Link anterior</translation>
-<translation id="2873259058405069099">Ir para o início da tabela</translation>
-<translation id="2894654529758326923">Informações</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{chaveta esquerda}other{# chavetas esquerdas}}</translation>
-<translation id="2911433807131383493">Abrir tutorial do ChromeVox</translation>
-<translation id="2932083475399492303">Tipo de linha de alternância entre estrutural ou esquema</translation>
-<translation id="2964026537669811554">Grupo de títulos</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tecla Tab}other{# teclas Tab}}</translation>
-<translation id="2972078295414139404">Não existe nenhum link visitado anterior.</translation>
-<translation id="2972205263822847197">Sugestão</translation>
-<translation id="2998131015536248178">Caráter anterior</translation>
-<translation id="2999559350546931576">Diminuir timbre</translation>
-<translation id="2999945368667127852">Não existe nenhum widget multimédia seguinte.</translation>
-<translation id="3012414509011670858">Não existe nenhuma secção anterior.</translation>
-<translation id="3030432017085518523">Botão de opção de item de menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apóstrofo}other{# apóstrofos}}</translation>
-<translation id="3046838483509668188">Opções do ChromeVox</translation>
-<translation id="3047143736589213134">Mapa de teclas experimental</translation>
-<translation id="3060756054951570867">menu <ph name="TITLE" /> aberto</translation>
-<translation id="3078345202707391975">Título de nível 2 seguinte</translation>
-<translation id="3078740164268491126">tabela</translation>
-<translation id="3082557070674409251">Clicado</translation>
-<translation id="3084806535845658316">sem eco de digitação</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Não existe nenhuma expressão matemática seguinte.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Ponto de referência seguinte</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Fechado</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Mostrar lista de pontos de referência</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Linha seguinte</translation>
-<translation id="3155083529632865074">Não existe nenhum botão anterior.</translation>
-<translation id="3163593631834463955">Cabeçalho da coluna vazio</translation>
-<translation id="316542773973815724">Navegação</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{espaço}other{# espaços}}</translation>
-<translation id="320961988183078793">introduziu <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, separador</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Link visitado</translation>
-<translation id="323731244387692321">Abrir ajuda do teclado do ChromeVox</translation>
-<translation id="3241052487511142956">Link visitado anterior</translation>
-<translation id="3286390186030710347">Controlo de deslize</translation>
-<translation id="3299925995433437805">Não existe nenhum link visitado seguinte.</translation>
-<translation id="3303384412438961941">Prima qualquer tecla para saber o respetivo nome. Ctrl + W fecha o explorador do teclado.</translation>
-<translation id="3307886118343381874">Ir para o fim da tabela</translation>
-<translation id="3311969765485641742">Prima Alt+Shift+A para consultar os alertas</translation>
-<translation id="3312997241656799641">Link visitado seguinte</translation>
-<translation id="3321460131042519426">Ativar mudança de linha</translation>
-<translation id="3322936298410871309">Título de nível 1 anterior</translation>
-<translation id="3323447499041942178">Caixa de texto</translation>
-<translation id="3353420241558113817">{"ar": "árabe",
- "bg": "búlgaro",
- "ca": "catalão",
- "cs": "checo",
- "da": "dinamarquês",
- "de": "alemão",
- "de_CH": "alemão (Suíça)",
- "de_DE": "alemão (Alemanha)",
- "el": "grego",
- "en": "inglês",
- "en_CA": "inglês (Canadá)",
- "en_GB": "inglês (Reino Unido)",
- "en_US": "inglês (Estados Unidos da América)",
- "es": "espanhol",
- "et": "estoniao",
- "fr": "francês",
- "fr_CA": "francês (Canadá)",
- "fr_FR": "francês (França)",
- "fi": "finlandês",
- "he": "hebraico",
- "hi": "hindi",
- "hr": "croata",
- "hu": "húngaro",
- "is": "islandês",
- "it": "italiano",
- "ko": "coreano",
- "lt": "lituano",
- "lv": "letão",
- "nb": "bokmål norueguês",
- "nl": "neerlandês",
- "pl": "polaco",
- "pt": "português",
- "ro": "romeno",
- "ru": "russo",
- "sk": "eslovaco",
- "sl": "esloveno",
- "sr": "sérvio",
- "sv": "sueco",
- "tr": "turco",
- "vi": "vietnamita",
- "zh": "chinês",
- "zh_TW": "chinês (han tradicional)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{mais}other{# sinais de mais}}</translation>
-<translation id="338583716107319301">Separador</translation>
-<translation id="3389259863310851658">Campo anterior do formulário</translation>
-<translation id="3390225400784126843">Elemento diferente seguinte.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, item de menu</translation>
-<translation id="3406283310380167331">Mostrar lista de formulários</translation>
-<translation id="3422338090358345848">Abrir explorador do teclado</translation>
-<translation id="3457000393508828486">Parcialmente premido</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, botão</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> a <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{parêntese reto direito}other{# parênteses retos direitos}}</translation>
-<translation id="3493915602752813531">Não existe nenhuma âncora seguinte.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{ponto de interrogação}other{# pontos de interrogação}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{acento circunflexo}other{# acentos circunflexos}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, caixa de verificação não marcada</translation>
-<translation id="3599054940393788245">Não em matemática</translation>
-<translation id="3616113530831147358">Áudio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{acento grave}other{# acentos graves}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dólar}other{# sinais de dólar}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, caixa de lista</translation>
-<translation id="3687295507293856493">Adivinhar o cabeçalho da coluna da célula atual</translation>
-<translation id="3692274950075847560">P:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Controlar voz</translation>
-<translation id="3716845769494773620">Multilinha</translation>
-<translation id="3731746171184829332">Não existe nenhum título anterior.</translation>
-<translation id="3762198587642264450">Ir para o fim da linha atual</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Saiu da caixa de diálogo.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Lista de preenchimento automático</translation>
-<translation id="3810838688059735925">Vídeo</translation>
-<translation id="3816633764618089385">Multimédia seguinte</translation>
-<translation id="3819376190738087562">Não existem avanços.</translation>
-<translation id="385383972552776628">Abrir página de opções</translation>
-<translation id="3856075812838139784">Apenas leitura</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Título de nível 6 anterior</translation>
-<translation id="3914173277599553213">Necessário</translation>
-<translation id="3962990492275676168">Iniciar a leitura a partir da localização atual</translation>
-<translation id="4004802134384979325">marcada</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Controlo de mês</translation>
-<translation id="4039983576244166038">Cabeçalho da linha vazio</translation>
-<translation id="4042843249978639960">Não existe nenhum título de nível 2 seguinte.</translation>
-<translation id="4043348641337972076">Não existe nenhum ponto de referência ARIA anterior.</translation>
-<translation id="4047216625641135770">Mark</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TIL}other{# sinais de til}}</translation>
-<translation id="409334809956508737">Objeto anterior</translation>
-<translation id="4099274309791143834">com submenu</translation>
-<translation id="4107807507418787238">Não existe nenhuma célula abaixo.</translation>
-<translation id="4116415223832267137">Alerta</translation>
-<translation id="4147126331795725888">Não existe nenhum controlo seguinte.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{chaveta direita}other{# chavetas direitas}}</translation>
-<translation id="4158704014418536539">Sensível a maiúsculas e minúsculas.</translation>
-<translation id="4161663686871496107">As respostas faladas do ChromeVox estão prontas</translation>
-<translation id="4173994908659439270">Não existe nenhum campo de texto editável seguinte.</translation>
-<translation id="4176463684765177261">Desativado</translation>
-<translation id="4188530942454211480">Frase anterior</translation>
-<translation id="4202186506458631436">Mover para a direita</translation>
-<translation id="4206289001967551965">Dentro da tabela</translation>
-<translation id="4215733775853809057">Controlo de deslize seguinte</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{traço}other{# traços}}</translation>
-<translation id="421884353938374759">seletor de cores</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">Não existe nenhuma célula à esquerda.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, grau <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Nota</translation>
-<translation id="4254798249533888099">Árvore</translation>
-<translation id="4255943572433203166">Utilize as opções abaixo para personalizar o ChromeVox. As alterações são aplicadas de imediato.</translation>
-<translation id="4271220233568730077">Matemática seguinte</translation>
-<translation id="4271521365602459209">Sem resultados novos.</translation>
-<translation id="4287520460805643128">Não existe nenhum artigo seguinte.</translation>
-<translation id="4289540628985791613">Vista geral</translation>
-<translation id="4300318234632215983">Anunciar o URL por detrás de um link</translation>
-<translation id="4301352596632316575">inclui submenu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{ponto}=3{reticências}other{# pontos}}</translation>
-<translation id="4347461890115250064">Não existe nenhuma lista seguinte.</translation>
-<translation id="4367650418938037324">Folha de matemática ML</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Parar voz</translation>
-<translation id="4373197658375206385">Não existe nenhum item anterior que não seja um link.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Não existem links.</translation>
-<translation id="4476183483923481720">nova linha</translation>
-<translation id="4482330759234983253">Tabela anterior</translation>
-<translation id="4491109536499578614">Imagem</translation>
-<translation id="4529987814483543472">Mapa de teclas clássico</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{barra}other{# barras}}</translation>
-<translation id="4547556996012970016">Título de nível 5 seguinte</translation>
-<translation id="4562381607973973258">Cabeçalho</translation>
-<translation id="4591507479202817876">, selecionado</translation>
-<translation id="4597532268155981612">formulário</translation>
-<translation id="4597896406374528575">Abril</translation>
-<translation id="4615592953348396470">Ignorar tecla premida seguinte</translation>
-<translation id="461613135510474570">Frase</translation>
-<translation id="4647836961514597010">Seletor de cores</translation>
-<translation id="4661075872484491155">árvore</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Ponto de referência anterior</translation>
-<translation id="4696413482802371445">Não existe nenhum título de nível 5 seguinte.</translation>
-<translation id="4729095194763193578">Linha anterior da tabela</translation>
-<translation id="4736221692378411923">Agosto</translation>
-<translation id="4740661827607246557">Comandos de ajuda</translation>
-<translation id="4759716709594980008">Explorador de teclado do SO Chrome</translation>
-<translation id="4763296182459741068">Direcionado para o fundo da página</translation>
-<translation id="4763480195061959176">vídeo</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Anunciar o título da página atual</translation>
-<translation id="4826415162591436065">Navegar para a frente</translation>
-<translation id="4826604887384865800">Avanço seguinte</translation>
-<translation id="4827410568042294688">não selecionado</translation>
-<translation id="4842108708071771135">Não existe nenhum blockquote seguinte.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Elemento semelhante anterior.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Ativar registo TTS</translation>
-<translation id="4877261390094455813">Introduza uma consulta de pesquisa.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Link interno</translation>
-<translation id="4953585991029886728">Editar texto</translation>
-<translation id="4954534434583049121">Blockquote anterior</translation>
-<translation id="4973717656530883744">Máx.: <ph name="X" /></translation>
-<translation id="4973762002207131920">Alterado para <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milissegundos</translation>
-<translation id="49787999531187221">O ChromeVox está inativo.</translation>
-<translation id="4979404613699303341">Botão anterior</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, caixa de lista</translation>
-<translation id="4983588134362688868">Ir para o início da página</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, janela</translation>
-<translation id="4993152509206108683">Velocidade: <ph name="PERCENT" />%</translation>
-<translation id="4996716799442435517">Visual</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, botão de opção selecionado</translation>
-<translation id="4997475792277222884">Não existe nenhum item seguinte que não seja um link.</translation>
-<translation id="5000760171916499057">Não existem formulários.</translation>
-<translation id="5005670136041063723">Não existem mais elementos semelhantes.</translation>
-<translation id="501473567976723023">Janeiro</translation>
-<translation id="5041394372352067729">Mover linha braille para o início da página</translation>
-<translation id="5042770794184672516">Aumentar o volume de voz</translation>
-<translation id="5050015258024679800">Título de nível 4 anterior</translation>
-<translation id="5054047268577924192">Item de lista anterior</translation>
-<translation id="5078661581131202757">Seleção de ficheiro</translation>
-<translation id="5080758118274074384">clicado duas vezes</translation>
-<translation id="5098541983634824365">A sair da grelha.</translation>
-<translation id="5102981729317424850">Barra de ferramentas</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Não existe nenhum campo de formulário anterior.</translation>
-<translation id="5111640677200759579">Cabeçalho da coluna</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Não existe nenhum link anterior.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, não selecionado</translation>
-<translation id="5183440668879371625">Linha braille anterior</translation>
-<translation id="5184944171021383281">Não existe nenhum campo de formulário seguinte.</translation>
-<translation id="5189244881767082992">Linha</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> já foi atribuído a um comando.</translation>
-<translation id="5205493599117157272">Lista de <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Não existe nenhum botão de opção seguinte.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objeto</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, separador</translation>
-<translation id="5310788376443009632">removido:</translation>
-<translation id="5320727453979144100">Modo aderente ativado</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{vírgula}other{# vírgulas}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, caixa de texto</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Retroceder durante a leitura contínua</translation>
-<translation id="5368000168321181111">Ícones sonoros desativados</translation>
-<translation id="5374320867641260420">Não existe nenhum botão seguinte.</translation>
-<translation id="5382299583965267720">Não existe nenhum título de nível 1 seguinte.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{ponto e vírgula}other{# pontos e vírgulas}}</translation>
-<translation id="5411891038905756502">Não existe nenhum ponto de avanço anterior.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{menor que}other{# sinais de menor que}}</translation>
-<translation id="5455441614648621694">Complementar</translation>
-<translation id="5485036206801896268">Não existe nenhum gráfico anterior.</translation>
-<translation id="5486947920110100234">Não existe nenhum ponto de avanço seguinte.</translation>
-<translation id="549602578321198708">Palavra</translation>
-<translation id="5500932716852106146">Não existe nenhum campo de texto editável anterior.</translation>
-<translation id="5502713021410870035">Setembro</translation>
-<translation id="5507663321906818013">Padrão de referência de depuração</translation>
-<translation id="5518443085409638729">Colocar o cursor entre os carateres ao editar o texto (como o Mac OS X).</translation>
-<translation id="552195134157544755">Botão de opção</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Não existe nenhum título de nível 5 anterior.</translation>
-<translation id="556042886152191864">Botão</translation>
-<translation id="5561345396546889625">Lista seguinte</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Retrocesso</translation>
-<translation id="5585044216466955529">Editar texto, entrada de email</translation>
-<translation id="5597170376237141345">Caixa de verificação seguinte</translation>
-<translation id="5597933780944041114">Não existe nenhum título seguinte.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, botão de opção desmarcado</translation>
-<translation id="5601172225407283979">Executar ação predefinida</translation>
-<translation id="5608798115546226984">Preenchimento automático inline</translation>
-<translation id="561939826962581046">hora</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Registo</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Não existe nenhuma tabela anterior.</translation>
-<translation id="5655682562155942719">Comandos para avançar</translation>
-<translation id="56637627897541303">Área de texto</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Ponto de referência</translation>
-<translation id="5683155931978483559">Caixa de verificação anterior</translation>
-<translation id="5684277895745049190">Lista</translation>
-<translation id="5700650669149824506">Não existe nenhum título de nível 4 anterior.</translation>
-<translation id="5709192780268610569">Sem descrição longa</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Coluna seguinte da tabela</translation>
-<translation id="571866080859340309">A explorar grupos</translation>
-<translation id="5728409797179002635">Não foi encontrada nenhuma tabela.</translation>
-<translation id="5748623122140342504">Título de nível 5 anterior</translation>
-<translation id="5750633686117194034">Nenhum modificador premido. Prima sem soltar um ou mais modificadores. Levante os dedos assim que tiver terminado e ouvirá as teclas definidas. Toque para sair.</translation>
-<translation id="5788275253279308023">separador da janela de navegação anónima <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Melhorar sites específicos (como a Pesquisa Google).</translation>
-<translation id="5819072574982403430">Item de árvore</translation>
-<translation id="5826479389509458994">linha <ph name="ROW" />, coluna <ph name="COL" /></translation>
-<translation id="5850707923114094062">Deslocar para trás</translation>
-<translation id="5851548754964597211">Lista de separadores</translation>
-<translation id="5859752971144398932">Saiu de localizar na página.</translation>
-<translation id="5866042630553435010">Parcialmente marcado</translation>
-<translation id="5869546221129391014">Grelha</translation>
-<translation id="5876817486144482042">Diminuir volume de voz</translation>
-<translation id="5887397643266327462">Legendas braille ativadas.</translation>
-<translation id="5891934789323004067">Tabela</translation>
-<translation id="5919442531159595654">copiar.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{igual}other{# sinais de igual}}</translation>
-<translation id="5939518447894949180">Repor</translation>
-<translation id="5948123859135882163">Alternar interpretação de expressões matemáticas entre estrutural e semântica</translation>
-<translation id="5955304353782037793">aplicação</translation>
-<translation id="5956928062748260866">Caixa de diálogo</translation>
-<translation id="5963413905009737549">Secção</translation>
-<translation id="5968607524793740041">Mostrar menu de contexto</translation>
-<translation id="5983179082906765664">Aumentar nível de detalhe da navegação</translation>
-<translation id="5999630716831179808">Vozes</translation>
-<translation id="6000417740266304866">Alterar a tabela atual de braille de 8 pontos ao selecionar uma opção na lista abaixo.</translation>
-<translation id="6006050241733874051">Formulário</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{barra invertida}other{# barras invertidas}}</translation>
-<translation id="6037602951055904232">Deslocar para a frente</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Fim da célula.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Espaço</translation>
-<translation id="6142308968191113180">Titulo 4</translation>
-<translation id="6169420925157477918">Imagem com descrição longa</translation>
-<translation id="6172087735260766220">Não é possível aceder ao texto acessível do PDF protegido contra cópia.</translation>
-<translation id="6186305613600865047">Ir para o fundo da página</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Para baixo</translation>
-<translation id="6236061028292614533">Título seguinte</translation>
-<translation id="6254901459154107917">Área de texto editável seguinte</translation>
-<translation id="6259464875943891919">Saiu de <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Elemento semelhante seguinte.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Não existe nenhuma caixa de combinação seguinte.</translation>
-<translation id="6307969636681130414">Premido</translation>
-<translation id="6324551002951139333">Erro gramatical detetado</translation>
-<translation id="6348657800373377022">Caixa de combinação</translation>
-<translation id="6355910664415701303">Não existe nenhum item de lista anterior.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Título anterior</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Não existe nenhum botão de opção anterior.</translation>
-<translation id="6414968628640960377">Elemento diferente anterior.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dois pontos}other{# sinais de dois pontos}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Caixa de diálogo de alerta</translation>
-<translation id="6459511626086141404">Mapa de teclas simples</translation>
-<translation id="6468049171101508116">Botão seguinte</translation>
-<translation id="6491972999578897419">Alterar a voz atual ao selecionar uma opção da lista abaixo.</translation>
-<translation id="6508059270146105198">Mover linha braille para o fim da página</translation>
-<translation id="6536864053412760904">Token de matemática ML</translation>
-<translation id="6550720799683018100">Alterar o mapa de teclas atual ao selecionar uma opção da lista abaixo.</translation>
-<translation id="6561818612645211875">Ir para o início da linha atual</translation>
-<translation id="6587021927234520429">Não existe nenhum título de nível 4 seguinte.</translation>
-<translation id="6601344353291556895">Ativar descrições detalhadas.</translation>
-<translation id="6615602925644411249">Localizar na página.</translation>
-<translation id="6633350132811819843">Não existe nenhuma tabela seguinte.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Barra de progresso</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Documento</translation>
-<translation id="6697092096875747123">Caixa de combinação anterior</translation>
-<translation id="6714813999819678458">Título de nível 2 anterior</translation>
-<translation id="6716505898850596801">Teclas de modificação</translation>
-<translation id="671916444866103745">Não existe nenhum ponto de referência ARIA seguinte.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, caixa de combinação</translation>
-<translation id="6735257939857578167">com <ph name="NUM" /> itens</translation>
-<translation id="6736510033526053669">separador criado</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Artigo</translation>
-<translation id="6787839852456839824">Atalhos de teclado</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Rodapé</translation>
-<translation id="6871161210040114857">A ignorar maiúsculas e minúsculas.</translation>
-<translation id="6877435256196695200">Não existe nenhum gráfico seguinte.</translation>
-<translation id="6897341342232909480">Mover para a esquerda</translation>
-<translation id="6901540140423170855">data</translation>
-<translation id="6910211073230771657">Eliminado</translation>
-<translation id="6911965441508464308">Não existe nenhuma célula acima.</translation>
-<translation id="6919104639734799681">Mostrar lista de tabelas</translation>
-<translation id="6964088412282673743">Não existe nenhum controlo anterior.</translation>
-<translation id="6996566555547746822">Caixa de combinação seguinte</translation>
-<translation id="7005146664810010831">Não foi encontrado nenhum URL</translation>
-<translation id="7010712454773919705">Tecla de modificação do ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Lista anterior</translation>
-<translation id="7041173719775863268">Terminar seleção</translation>
-<translation id="7095834689119144465">Editar apenas números</translation>
-<translation id="7096001299300236431">Multimédia anterior</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">eco da palavra</translation>
-<translation id="713824876195128146">Blockquote seguinte</translation>
-<translation id="7161771961008409533">Botão pop-up</translation>
-<translation id="7167657087543110">eco dos carateres</translation>
-<translation id="7170733337935166589">Ir para a frente durante a leitura contínua</translation>
-<translation id="7181697990050180700">Personalize os atalhos de teclado para os comandos utilizados com frequência ao introduzi-los nos campos correspondentes abaixo.</translation>
-<translation id="7203150201908454328">Expandido</translation>
-<translation id="7210211103303402262">minutos</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">linha</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Título</translation>
-<translation id="7241683698754534149">Abrir descrição longa num novo separador</translation>
-<translation id="7248671827512403053">Aplicação</translation>
-<translation id="725969808843520477">Botão de opção seguinte</translation>
-<translation id="7269119382257320590">Sem pontuação</translation>
-<translation id="7273174640290488576">Em branco</translation>
-<translation id="7285387653379749618">Tabelas</translation>
-<translation id="7289186959554153431">Título 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Legendas braille desativadas.</translation>
-<translation id="7318872822751139669">Utilize o rato para alterar o elemento focado.</translation>
-<translation id="7322388933135261569">Fevereiro</translation>
-<translation id="7332592614823088566">Linha <ph name="ROWINDEX" /> de <ph name="ROWTOTAL" />, coluna <ph name="COLINDEX" /> de <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">inclui pop-up</translation>
-<translation id="7356165926712028380">Mudar para braille de 8 pontos</translation>
-<translation id="7362871137496673139">Não existe nenhum título de nível 2 anterior.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{e comercial}other{# e comerciais}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">A sair da tabela.</translation>
-<translation id="739763518212184081">Linha anterior</translation>
-<translation id="7400575256015741911">Erro ortográfico detetado</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">retorno</translation>
-<translation id="7434509671034404296">Programador</translation>
-<translation id="7439060726180460871">Diretório</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Caixa de diálogo introduzida</translation>
-<translation id="7532613204005497612">Junho</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, controlo de deslize</translation>
-<translation id="7586163296341959563">colar.</translation>
-<translation id="7596919493010894443">seleção limpa</translation>
-<translation id="7604026522577407655">Ir para o início da coluna atual</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Anunciar o URL da página atual</translation>
-<translation id="7609363189280667021">Alternar legendas em braille</translation>
-<translation id="762020119231868829">Interrompe todos os widgets de multimédia atualmente em reprodução</translation>
-<translation id="7625690649919402823">Tabela seguinte</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), grau <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Não existe nenhum título de nível 3 anterior.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, caixa de texto</translation>
-<translation id="7663318257180412551">Título 2</translation>
-<translation id="7674576868851035240">Link seguinte</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">Editar texto, entrada de URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Botão de opção anterior</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, caixa de texto da palavra-passe</translation>
-<translation id="7805247615045262757">navegação predefinida</translation>
-<translation id="7805768142964895445">Estado</translation>
-<translation id="7810781339813764006">Grupo seguinte</translation>
-<translation id="7819187121850078213">separador da janela <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Outubro</translation>
-<translation id="7839679365527550018">Palavra anterior</translation>
-<translation id="7851816175263618915">Alguma pontuação</translation>
-<translation id="7870596830398826354">Árvore de matemática ML</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Ativar/desativar o ChromeVox clássico</translation>
-<translation id="7895896691902835279">Link desconhecido</translation>
-<translation id="7927711904086083099">Não selecionado</translation>
-<translation id="7935627501098484003">Controlo da hora</translation>
-<translation id="7939428177581522200">adicionado à seleção</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{arroba}other{# sinais de arroba}}</translation>
-<translation id="7965147473449754028">menu fechado</translation>
-<translation id="7974390230414479278">Item de menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ponto de exclamação}other{# pontos de exclamação}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{sinal de aspas}other{# sinais de aspas}}</translation>
-<translation id="8033827949643255796">selecionado</translation>
-<translation id="8035962149453661158">máx.:<ph name="X" /></translation>
-<translation id="8042761080832772327">Editar texto, entrada de pesquisa</translation>
-<translation id="8049189770492311300">Temporizador</translation>
-<translation id="8065607967589909823">A seleção é</translation>
-<translation id="8066678206530322333">Faixa</translation>
-<translation id="8110647606445335195">Não existe nenhum ponto de referência ARIA.</translation>
-<translation id="8153880621934657047">Não está dentro da tabela.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{sublinhado}other{# sublinhados}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">cortar.</translation>
-<translation id="8199231515320852133">Anunciar os cabeçalhos da célula atual</translation>
-<translation id="820417203470636242">Célula vazia.</translation>
-<translation id="8215202828671303819">Seleção múltipla</translation>
-<translation id="8276439074553447000">Ir para o anterior item a focar</translation>
-<translation id="8278417001922463147">Nenhum artigo anterior.</translation>
-<translation id="8283603667300770666">Campo de formulário seguinte</translation>
-<translation id="831207808878314375">Definição</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">horas</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{libra}other{# sinais de libra}}</translation>
-<translation id="8374154622594089836">mês</translation>
-<translation id="8378855320830505539">Região</translation>
-<translation id="8382679411218029383">Preenchimento automático inline e lista</translation>
-<translation id="8428603554127842284">nível <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Não existe nenhum título de nível 3 seguinte.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Não existe nenhuma caixa de verificação anterior.</translation>
-<translation id="8455868257606149352">Máx.: <ph name="X" /></translation>
-<translation id="84575901236241018">tem chave de acesso, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Diminuir nível de detalhe da navegação</translation>
-<translation id="8520472399088452386">Botão giratório</translation>
-<translation id="8538744478902126321">Adivinhar o cabeçalho da linha da célula atual</translation>
-<translation id="8540054775867439484">Direcionado para o início</translation>
-<translation id="8548973727659841685">Caráter</translation>
-<translation id="8561322612995434619">inclui pop-up</translation>
-<translation id="8571096049907249734">mult sel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Item de lista seguinte</translation>
-<translation id="860150890330522909">Caixa de verificação <ph name="NAME" /> marcada</translation>
-<translation id="8606621670302093223">Controlo de data</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> itens selecionados</translation>
-<translation id="8638532244051952400">Anunciar coordenadas da célula atual</translation>
-<translation id="8650576015643545550">Não existe nenhuma lista anterior.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Mostrar lista de links</translation>
-<translation id="8664519043722036194">segundos</translation>
-<translation id="867187640362843212">Título 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{traço vertical}other{# traços verticais}}</translation>
-<translation id="8735450637152821465">Iniciar seleção</translation>
-<translation id="8743786158317878347">inserir o conteúdo estruturado, por exemplo, tabelas</translation>
-<translation id="8747966237988593539">Lista ordenada</translation>
-<translation id="8759334257841767240">Não existe nenhum link seguinte.</translation>
-<translation id="8767968232364267681">Título de nível 4 seguinte</translation>
-<translation id="8770473310765924354">sair do conteúdo estruturado, por exemplo, tabelas</translation>
-<translation id="8791025954632646584">Semântica ativada</translation>
-<translation id="8796411681063377102">Título de nível 3 seguinte</translation>
-<translation id="8808582214901541005">Março</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Prima para cima ou para baixo para rever os comandos, prima Enter para ativar</translation>
-<translation id="8864099967139188018">Não existe nenhum título de nível 6 seguinte.</translation>
-<translation id="8882002077197914455">Cabeçalho da linha</translation>
-<translation id="8896347895970027998">Ative ou desative o ChromeVox.</translation>
-<translation id="8898516272131543774">Eco da pontuação de ciclo</translation>
-<translation id="8900148057318340779">Tecla de prefixo</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Cabeçalhos vazios</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Teclas de modificação</translation>
-<translation id="8943175951035496220">Não existe nenhuma célula à direita.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">ficheiro</translation>
-<translation id="9027462562263121875">Não existem tabelas.</translation>
-<translation id="9040132695316389094">Título 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Ativar/desativar widget de pesquisa</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">removido da seleção</translation>
-<translation id="9082874451376019682">Não existe nenhum controlo de deslize anterior.</translation>
-<translation id="9089864840575085222">Eco da digitação de ciclo</translation>
-<translation id="9107530006868467849">Não existe nenhum widget multimédia anterior.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{percentagem}other{# sinais de percentagem}}</translation>
-<translation id="9115913704608474258">Novembro</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Anuncia uma breve descrição da posição atual</translation>
-<translation id="9153606228985488238">Timbre: <ph name="PERCENT" />%</translation>
-<translation id="9160096769946561184">Ir para o fim da coluna atual</translation>
-<translation id="9173115498289768110">Volume: <ph name="PERCENT" />%</translation>
-<translation id="9178973770513562274">Utilize as teclas de seta para cima e para baixo para navegar ou escreva para pesquisar.</translation>
-<translation id="9192904702577636854">Painel rolante</translation>
-<translation id="9212322457209634662">Não existe nenhuma secção seguinte.</translation>
-<translation id="930275611743429116">Iniciar ou terminar a seleção.</translation>
-<translation id="948171205378458592">Diminuir velocidade de voz</translation>
-<translation id="962913030769097253">Título de nível 1 seguinte</translation>
-<translation id="973955474346881951">Ativar/desativar o modo aderente</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ro.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ro.xtb
deleted file mode 100644
index ec965ad535a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ro.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ro">
-<translation id="1012173283529841972">Element din listă</translation>
-<translation id="1013742170491673792">căutare</translation>
-<translation id="1023866615269196768">Extinsă.</translation>
-<translation id="1025074108959230262">Modul persistent este dezactivat</translation>
-<translation id="1031961866430398710">apoi</translation>
-<translation id="1044777062731150180">Niciun antet</translation>
-<translation id="106222400312645156">antet rând</translation>
-<translation id="1065552602950927991">Intrare nevalidă</translation>
-<translation id="1082209053475788238">Nu există un titlu de nivel 6 anterior.</translation>
-<translation id="1088219014394087294">Nu există titluri.</translation>
-<translation id="1106741348836243114">Activați/dezactivați feedbackul sonor (semnalele audio).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Colecția <ph name="TAG" /> cu <ph name="NUM" /> (de) elemente</translation>
-<translation id="1155043339247954670">Nu există un element de listă următor.</translation>
-<translation id="1157782847298808853">Ajutor tastatură</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, casetă combo</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, element din meniu cu submeniu</translation>
-<translation id="1177863135347784049">Personalizează</translation>
-<translation id="1188858454923323853">complementar</translation>
-<translation id="1206619573307042055">text derulant</translation>
-<translation id="1213216066620407844">ChromeVox - Voce pentru Chrome</translation>
-<translation id="1229276918471378188">Saltul anterior</translation>
-<translation id="1237866625126425153">grup radio</translation>
-<translation id="1251750620252348585">Titlul de nivel 6 următor</translation>
-<translation id="1275718070701477396">Selectat</translation>
-<translation id="1319608975892113573">Nu există un blockquote anterior.</translation>
-<translation id="1321576897702511272">Ascundeți ajutorul pentru ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> din <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">ecou caracter și cuvânt</translation>
-<translation id="1339428534620983148">Coloana anterioară din tabel</translation>
-<translation id="1342835525016946179">articol</translation>
-<translation id="1346748346194534595">Dreapta</translation>
-<translation id="136718599399906424">Rândul următor din tabel</translation>
-<translation id="1383876407941801731">Caută</translation>
-<translation id="1385214448885562192">Apăsați pe Enter pentru a accepta sau pe Escape pentru a anula, pe săgeata în jos pentru Înainte și pe săgeata în sus pentru Înapoi.</translation>
-<translation id="1396114365388024581">listă de file</translation>
-<translation id="1439316808600711881">regiune</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, casetă text pentru parolă</translation>
-<translation id="1467432559032391204">Stânga</translation>
-<translation id="1474557363159888097">Nu există o ancoră anterioară.</translation>
-<translation id="1502086903961450562">Graficul anterior</translation>
-<translation id="1506187449813838456">Creșteți înălțimea sunetului</translation>
-<translation id="151784044608172266">Propoziția următoare</translation>
-<translation id="1524531499102321782">Rândul Braille următor</translation>
-<translation id="1546370775711804143">Bară de defilare</translation>
-<translation id="1559739829547075274">Navigați înapoi</translation>
-<translation id="1571643229714746283">ChromeVox configurat</translation>
-<translation id="158493514907962286">Decembrie</translation>
-<translation id="1594072653727561613">meniu</translation>
-<translation id="1610130962244179598">Comutați la tabelul Braille cu 6 puncte</translation>
-<translation id="1611168825862729585">Antet de coloană:</translation>
-<translation id="1613476421962910979">Semnalele audio sunt activate</translation>
-<translation id="1618597272655350600">Anunță o descriere completă a poziției curente</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{semn mai mare}few{# semne mai mare}other{# de semne mai mare}}</translation>
-<translation id="1653266918374749391">Titlul de nivel 3 anterior</translation>
-<translation id="1659072772017912254">Nebifat</translation>
-<translation id="1669290819662866522">săptămână</translation>
-<translation id="1674262202423278359">Navigare ChromeVox</translation>
-<translation id="16777221443363124">Bară de meniu</translation>
-<translation id="1692077714702418899">linie de structură</translation>
-<translation id="1700517974991662022">Accesat</translation>
-<translation id="1722567105086139392">Link</translation>
-<translation id="1727806147743597030">notă subsol</translation>
-<translation id="174268867904053074">Graficul următor</translation>
-<translation id="1781173782405573156">Ignoră tasta</translation>
-<translation id="1787176709638001873">Câmp text de editare a parolei</translation>
-<translation id="1810107444790159527">Casetă listă</translation>
-<translation id="1828385960365606039">Mai</translation>
-<translation id="1834891354138622109">Coloană</translation>
-<translation id="1865601187525349519">Sfârșitul textului</translation>
-<translation id="1876229593313240038">document</translation>
-<translation id="188130072164734898">Rostește ora și data actuale.</translation>
-<translation id="1902396333223336119">Celulă</translation>
-<translation id="1905379170753160525">Afișați lista de titluri</translation>
-<translation id="1912556590115083156">link accesat</translation>
-<translation id="1913761808037590218">număr</translation>
-<translation id="1954623340234317532">Comandă pentru săptămâna din an</translation>
-<translation id="1964135212174907577">Obiectul următor</translation>
-<translation id="1969092762068865084">Iulie</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Antet de rând:</translation>
-<translation id="2002895034995108595">Resetați harta actuală a tastelor</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{paranteză pătrată stânga}few{# paranteze pătrate stânga}other{# de paranteze pătrate stânga}}</translation>
-<translation id="2045490512405922022">nebifată</translation>
-<translation id="20601713649439366">Nu există o expresie matematică anterioară.</translation>
-<translation id="207477615537953741">Interpretare semantică dezactivată</translation>
-<translation id="2086961585857038472">Cuvântul următor</translation>
-<translation id="2089387485033699258">ro</translation>
-<translation id="2091933974477985526">Zona de text editabil anterioară</translation>
-<translation id="2100350898815792233">Toate semnele de punctuație</translation>
-<translation id="2119965627982867824">buton rotire</translation>
-<translation id="2121067395472282800">tastă de acces: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Schimbați tabelul Braille actual cu 6 puncte selectând o opțiune din lista de mai jos.</translation>
-<translation id="2169714232367507776">Dați clic pe elementul curent</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{paranteză închisă}few{# paranteze închise}other{# de paranteze închise}}</translation>
-<translation id="2199994615414171367">Expresia matematică anterioară</translation>
-<translation id="2223693656926968778">Acționați asupra elementului curent</translation>
-<translation id="225732394367814946">Creșteți viteza de vorbire</translation>
-<translation id="2267945578749931355">Caracterul următor</translation>
-<translation id="2281234842553884450">Glisorul anterior</translation>
-<translation id="2318372665160196757">Principal</translation>
-<translation id="2329324941084714723">Panou file</translation>
-<translation id="2344193891939537199">Comandă pentru dată/oră</translation>
-<translation id="2359897517538099099">Nu ești în modul tabel.</translation>
-<translation id="241124561063364910">urmată de</translation>
-<translation id="2417569100218200841">Informații privind conținutul</translation>
-<translation id="2422937916923936891">Casetă de selectare pentru element de meniu</translation>
-<translation id="2429669115401274487">p.m.</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> este noul modificator ChromeVox.</translation>
-<translation id="2450814015951372393">Casetă de selectare</translation>
-<translation id="2462626033734746142">Grup buton radio</translation>
-<translation id="2471138580042810658">Titlu 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisc}few{# asteriscuri}other{# de asteriscuri}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> a fost resetată.</translation>
-<translation id="2553108862507765288">greșeală gramaticală</translation>
-<translation id="257674075312929031">Grup</translation>
-<translation id="2582407057977008361">Separat</translation>
-<translation id="2589102159832527089">Această pagină conține textul extras automat din fișierul PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Dați clic aici pentru original.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">cu {COUNT,plural, =1{# element}few{# elemente}other{# de elemente}}</translation>
-<translation id="2614981083756825552">Aspect Math ML</translation>
-<translation id="2626530649491650971">pe care se poate da clic</translation>
-<translation id="2628764385451019380">Nu există o casetă combo anterioară.</translation>
-<translation id="2637227747952042642">Matematică</translation>
-<translation id="2639750663247012216">modificator ChromeVox</translation>
-<translation id="2644542693584024604">scris greșit</translation>
-<translation id="2667291555398229137">Dați clic pe elementul de sub o tastă de deplasare</translation>
-<translation id="2697408785920771974">completare automată inline</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{paranteză deschisă}few{# paranteze deschise}other{# de paranteze deschise}}</translation>
-<translation id="2705875883745373140">Neapăsat</translation>
-<translation id="2706462751667573066">În sus</translation>
-<translation id="2717271541250958000">panou de file</translation>
-<translation id="2723001399770238859">audio</translation>
-<translation id="2732718972699418926">a.m.</translation>
-<translation id="2749275490991666823">Verificat</translation>
-<translation id="27527859628328957">Salt la elementul focalizabil următor</translation>
-<translation id="2770781857296573485">Trece la explorarea grupului</translation>
-<translation id="2777845298774924149">S-a ieșit</translation>
-<translation id="2800204403141299078">Nu mai există elemente diferite.</translation>
-<translation id="2800780099804980316">Nu există un titlu de nivel 1 anterior.</translation>
-<translation id="2811204574343810641">Rând</translation>
-<translation id="2816654101880605877">Nu există un glisor următor.</translation>
-<translation id="2841013758207633010">Oră</translation>
-<translation id="2843837985843789981">Grupul anterior</translation>
-<translation id="2844995807198708617">Meniu contextual</translation>
-<translation id="2849332794118375855">Nu există o casetă de selectare următoare.</translation>
-<translation id="2864481629947106776">Linkul anterior</translation>
-<translation id="2873259058405069099">Accesați începutul tabelului</translation>
-<translation id="2894654529758326923">Informații</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{acoladă stânga}few{# acolade stânga}other{# de acolade stânga}}</translation>
-<translation id="2911433807131383493">Deschideți programul de instruire ChromeVox</translation>
-<translation id="2932083475399492303">Comutați tipul de linie între cel de structură și cel de aspect</translation>
-<translation id="2964026537669811554">Grup de titluri</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulator}few{# tabulatori}other{# de tabulatori}}</translation>
-<translation id="2972078295414139404">Nu există niciun link accesat anterior.</translation>
-<translation id="2972205263822847197">Balon explicativ</translation>
-<translation id="2998131015536248178">Caracterul anterior</translation>
-<translation id="2999559350546931576">Scădeți înălțimea sunetului</translation>
-<translation id="2999945368667127852">Niciun widget media următor.</translation>
-<translation id="3012414509011670858">Nu există o secțiune anterioară.</translation>
-<translation id="3030432017085518523">Buton radio pentru element de meniu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}few{# apostrofuri}other{# de apostrofuri}}</translation>
-<translation id="3046838483509668188">Opțiuni ChromeVox</translation>
-<translation id="3047143736589213134">Hartă taste experimentală</translation>
-<translation id="3060756054951570867">Meniu <ph name="TITLE" /> deschis</translation>
-<translation id="3078345202707391975">Titlul de nivel 2 următor</translation>
-<translation id="3078740164268491126">tabel</translation>
-<translation id="3082557070674409251">Ați dat clic</translation>
-<translation id="3084806535845658316">fără ecou la tastare</translation>
-<translation id="3086746722712840547">notă</translation>
-<translation id="308895241372589742">Nu există o expresie matematică următoare.</translation>
-<translation id="3090532668523289635">grup</translation>
-<translation id="3093176084511590672">Reperul următor</translation>
-<translation id="3096671415663099226">casetă combo</translation>
-<translation id="3104705064753753826">casetă de dialog alertă</translation>
-<translation id="3109724472072898302">Restrâns</translation>
-<translation id="3134461040845705080">numai în citire</translation>
-<translation id="3138767756593758860">Afișați lista de repere</translation>
-<translation id="3143851963874289911">celulă din grilă</translation>
-<translation id="3149472044574196936">Rândul următor</translation>
-<translation id="3155083529632865074">Nu există un buton anterior.</translation>
-<translation id="3163593631834463955">Antet de coloană gol</translation>
-<translation id="316542773973815724">Navigare</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{spațiu}few{# spații}other{# de spații}}</translation>
-<translation id="320961988183078793">s-a accesat <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, filă</translation>
-<translation id="3226035351387556942">casetă de selectare</translation>
-<translation id="3229375994964697375">Link accesat</translation>
-<translation id="323731244387692321">Deschideți ajutorul pentru tastatură ChromeVox</translation>
-<translation id="3241052487511142956">Link accesat anterior</translation>
-<translation id="3286390186030710347">Glisor</translation>
-<translation id="3299925995433437805">Nu există un link accesat următor.</translation>
-<translation id="3303384412438961941">Apăsați pe orice tastă pentru a afla numele acesteia. Ctrl+W va închide exploratorul comenzilor de la tastatură.</translation>
-<translation id="3307886118343381874">Accesați finalul tabelului</translation>
-<translation id="3311969765485641742">Apăsați pe Alt+Shift+A pentru a examina alertele</translation>
-<translation id="3312997241656799641">Următorul link accesat</translation>
-<translation id="3321460131042519426">Activează încadrarea cuvintelor</translation>
-<translation id="3322936298410871309">Titlul de nivel 1 anterior</translation>
-<translation id="3323447499041942178">Casetă de text</translation>
-<translation id="3353420241558113817">{"ar": "Arabă",
- "bg": "Bulgară",
- "ca": "Catalană",
- "cs": "Cehă",
- "da": "Daneză",
- "de": "Germană",
- "de_CH": "Germană (Elveția)",
- "de_DE": "Germană (Germania)",
- "el": "Greacă",
- "en": "Engleză",
- "en_CA": "Engleză (Canada)",
- "en_GB": "Engleză (Regatul Unit)",
- "en_US": "Engleză (Statele Unite ale Americii)",
- "es": "Spaniolă",
- "et": "Estonă",
- "fr": "Franceză",
- "fr_CA": "Franceză (Canada)",
- "fr_FR": "Franceză (Franța)",
- "fi": "Finlandeză",
- "he": "Ebraică",
- "hi": "Hindi",
- "hr": "Croată",
- "hu": "Maghiară",
- "is": "Islandeză",
- "it": "Italiană",
- "ko": "Coreeană",
- "lt": "Lituaniană",
- "lv": "Letonă",
- "nb": "Norvegiană (Bokmål)",
- "nl": "Neerlandeză",
- "pl": "Poloneză",
- "pt": "Portugheză",
- "ro": "Română",
- "ru": "Rusă",
- "sk": "Slovacă",
- "sl": "Slovenă",
- "sr": "Sârbă",
- "sv": "Suedeză",
- "tr": "Turcă",
- "vi": "Vietnameză",
- "zh": "Chineză",
- "zh_TW": "Chineză (Han tradițional)"}</translation>
-<translation id="3359142382821736686">separator</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plus}few{# semne plus}other{# de semne plus}}</translation>
-<translation id="338583716107319301">Separator</translation>
-<translation id="3389259863310851658">Câmpul anterior din formular</translation>
-<translation id="3390225400784126843">Elementul diferit următor.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, element din meniu</translation>
-<translation id="3406283310380167331">Afișați lista de formulare</translation>
-<translation id="3422338090358345848">Deschideți exploratorul comenzilor de la tastatură</translation>
-<translation id="3457000393508828486">Apăsat parțial</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, buton</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> selectate</translation>
-<translation id="3486232535569802404">De la <ph name="V1" /> la <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{paranteză pătrată dreapta}few{# paranteze pătrate dreapta}other{# de paranteze pătrate dreapta}}</translation>
-<translation id="3493915602752813531">Nu există o ancoră următoare.</translation>
-<translation id="3494946239022273294">element meniu</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{semn de întrebare}few{# semne de întrebare}other{# de semne de întrebare}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{accent circumflex}few{# accente circumflexe}other{# de accente circumflexe}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, casetă de selectare nebifată</translation>
-<translation id="3599054940393788245">Nu este în expresie matematică</translation>
-<translation id="3616113530831147358">Audio</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{ghilimea simplă}few{# ghilimele simple}other{# de ghilimele simple}}</translation>
-<translation id="3650317109285159359">casetă de selectare element meniu</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolar}few{# semne dolar}other{# de semne dolar}}</translation>
-<translation id="3659787053479271466">alertă</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, casetă listă</translation>
-<translation id="3687295507293856493">Faceți o încercare la antetul coloanei pentru celula curentă</translation>
-<translation id="3692274950075847560">C:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Comenzi pentru vorbire</translation>
-<translation id="3716845769494773620">Mai multe linii</translation>
-<translation id="3731746171184829332">Nu există un titlu anterior.</translation>
-<translation id="3762198587642264450">Accesați finalul rândului curent</translation>
-<translation id="3777255250339039212">titlu 1</translation>
-<translation id="3793710123303304873">S-a ieșit din caseta de dialog.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}few{#}other{#}}</translation>
-<translation id="3801735343383419236">Completare automată listă</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Conținut media următor</translation>
-<translation id="3819376190738087562">Nu există puncte de accesare directă.</translation>
-<translation id="385383972552776628">Deschideți pagina de opțiuni</translation>
-<translation id="3856075812838139784">Numai în citire</translation>
-<translation id="3887576927692165210">casetă text</translation>
-<translation id="3897092660631435901">Meniu</translation>
-<translation id="3909320334364316587">Titlul de nivel 6 anterior</translation>
-<translation id="3914173277599553213">Solicitate</translation>
-<translation id="3962990492275676168">Începeți să citiți din poziția curentă</translation>
-<translation id="4004802134384979325">bifată</translation>
-<translation id="4006140876663370126">imagine</translation>
-<translation id="4038349100599457191">Comandă pentru lună</translation>
-<translation id="4039983576244166038">Antet de rând gol</translation>
-<translation id="4042843249978639960">Nu există un titlu de nivel 2 următor.</translation>
-<translation id="4043348641337972076">Nu există un reper ARIA anterior.</translation>
-<translation id="4047216625641135770">Marcaj</translation>
-<translation id="404803211695627272"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="4054936709456751127">stare</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDĂ}few{# tilde}other{# de tilde}}</translation>
-<translation id="409334809956508737">Obiectul anterior</translation>
-<translation id="4099274309791143834">cu submeniu</translation>
-<translation id="4107807507418787238">Nu există celule mai jos.</translation>
-<translation id="4116415223832267137">Alertă</translation>
-<translation id="4147126331795725888">Nu există o comandă următoare.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{acoladă dreapta}few{# acolade dreapta}other{# de acolade dreapta}}</translation>
-<translation id="4158704014418536539">Distinge între scrierea cu minuscule/majuscule.</translation>
-<translation id="4161663686871496107">Feedbackul vocal ChromeVox este configurat</translation>
-<translation id="4173994908659439270">Nu există un câmp de text editabil următor.</translation>
-<translation id="4176463684765177261">Dezactivat</translation>
-<translation id="4188530942454211480">Propoziția anterioară</translation>
-<translation id="4202186506458631436">Deplasează spre dreapta</translation>
-<translation id="4206289001967551965">În interiorul tabelului</translation>
-<translation id="4215733775853809057">Glisorul următor</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{cratimă}few{# cratime}other{# de cratime}}</translation>
-<translation id="421884353938374759">selector de culoare</translation>
-<translation id="4229646983878045487">dată oră</translation>
-<translation id="423334822609210999">Nu există celule în stânga.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, nivelul <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Notă</translation>
-<translation id="4254798249533888099">Arbore</translation>
-<translation id="4255943572433203166">Folosiți opțiunile de mai jos pentru a personaliza ChromeVox. Modificările intră în vigoare imediat.</translation>
-<translation id="4271220233568730077">Expresia matematică următoare</translation>
-<translation id="4271521365602459209">Nu există alte rezultate.</translation>
-<translation id="4287520460805643128">Nu există un articol următor.</translation>
-<translation id="4289540628985791613">Prezentare generală</translation>
-<translation id="4300318234632215983">Anunță adresa URL la care trimite un link</translation>
-<translation id="4301352596632316575">are submeniu</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punct}=3{puncte de suspensie}few{# puncte}other{# de puncte}}</translation>
-<translation id="4347461890115250064">Nu există o listă următoare.</translation>
-<translation id="4367650418938037324">Frunză Math ML</translation>
-<translation id="4372435075475052704">min.:<ph name="X" /></translation>
-<translation id="4372705107434148843">Oprește vorbirea</translation>
-<translation id="4373197658375206385">Nu există un element anterior care nu este link.</translation>
-<translation id="4391478986194775161">informații conținut</translation>
-<translation id="443163561286008705">resetați</translation>
-<translation id="4471074325120394300">Nu există linkuri.</translation>
-<translation id="4476183483923481720">rând nou</translation>
-<translation id="4482330759234983253">Tabelul anterior</translation>
-<translation id="4491109536499578614">Imagine</translation>
-<translation id="4529987814483543472">Harta clasică a tastelor</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{bară oblică spre dreapta}few{# bare oblice spre dreapta}other{# de bare oblice spre dreapta}}</translation>
-<translation id="4547556996012970016">Titlul de nivel 5 următor</translation>
-<translation id="4562381607973973258">Antet</translation>
-<translation id="4591507479202817876">, selectat</translation>
-<translation id="4597532268155981612">formular</translation>
-<translation id="4597896406374528575">Aprilie</translation>
-<translation id="4615592953348396470">Se ignoră următoarea apăsare de tastă</translation>
-<translation id="461613135510474570">Propoziție</translation>
-<translation id="4647836961514597010">Selector de culoare</translation>
-<translation id="4661075872484491155">arbore</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grilă</translation>
-<translation id="4693675773662933727">Reperul anterior</translation>
-<translation id="4696413482802371445">Nu există un titlu de nivel 5 următor.</translation>
-<translation id="4729095194763193578">Rândul anterior din tabel</translation>
-<translation id="4736221692378411923">August</translation>
-<translation id="4740661827607246557">Comenzi pentru ajutor</translation>
-<translation id="4759716709594980008">Explorator pentru comenzile de la tastatură în sistemul de operare Chrome</translation>
-<translation id="4763296182459741068">Încadrare jos</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">căutați</translation>
-<translation id="481165870889056555">Anunță titlul paginii curente</translation>
-<translation id="4826415162591436065">Navigați înainte</translation>
-<translation id="4826604887384865800">Saltul următor</translation>
-<translation id="4827410568042294688">neselectat</translation>
-<translation id="4842108708071771135">Nu există un blockquote următor.</translation>
-<translation id="4848993367330139335">temporizator</translation>
-<translation id="4850023505158945298">Elementul similar anterior.</translation>
-<translation id="4866956062845190338">buton radio element meniu</translation>
-<translation id="4867316986324544967">Activați înregistrarea TTS</translation>
-<translation id="4877261390094455813">Introduceți o interogare de căutare.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Link intern</translation>
-<translation id="4953585991029886728">Câmp text de editare</translation>
-<translation id="4954534434583049121">Citatul anterior</translation>
-<translation id="4973717656530883744">Min. <ph name="X" /></translation>
-<translation id="4973762002207131920">S-a comutat la <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisecunde</translation>
-<translation id="49787999531187221">Acum, ChromeVox este inactiv.</translation>
-<translation id="4979404613699303341">Butonul anterior</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, casetă listă</translation>
-<translation id="4983588134362688868">Navigați la începutul paginii</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, fereastră</translation>
-<translation id="4993152509206108683">Rată de <ph name="PERCENT" />%</translation>
-<translation id="4996716799442435517">Vizual</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, buton radio selectat</translation>
-<translation id="4997475792277222884">Nu există un element următor care nu este link.</translation>
-<translation id="5000760171916499057">Nu există formulare.</translation>
-<translation id="5005670136041063723">Nu mai există elemente similare.</translation>
-<translation id="501473567976723023">Ianuarie</translation>
-<translation id="5041394372352067729">Deplasează afișajul Braille în partea de sus a paginii</translation>
-<translation id="5042770794184672516">Creșteți volumul vocii</translation>
-<translation id="5050015258024679800">Titlul de nivel 4 anterior</translation>
-<translation id="5054047268577924192">Elementul anterior din listă</translation>
-<translation id="5078661581131202757">Selectare fișier</translation>
-<translation id="5080758118274074384">ați dat dublu clic</translation>
-<translation id="5098541983634824365">Se iese din grilă.</translation>
-<translation id="5102981729317424850">Bară de instrumente</translation>
-<translation id="5105050547967751155">obligatoriu</translation>
-<translation id="5110983769041734144">Nu există un câmp de formular anterior.</translation>
-<translation id="5111640677200759579">Antet de coloană</translation>
-<translation id="5117636609870536415">e-mail</translation>
-<translation id="5136967254288895616">Nu există un link anterior.</translation>
-<translation id="513774504516943387">link</translation>
-<translation id="517143700877085897">, deselectat</translation>
-<translation id="5183440668879371625">Rândul Braille anterior</translation>
-<translation id="5184944171021383281">Nu există un câmp de formular următor.</translation>
-<translation id="5189244881767082992">Rând</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> este deja atribuită pentru o comandă.</translation>
-<translation id="5205493599117157272">Listă <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Nu există un buton radio următor.</translation>
-<translation id="5263344797180442561">titlu 2</translation>
-<translation id="528468243742722775">Sfârșit</translation>
-<translation id="5291783959063340370">Obiect</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, filă</translation>
-<translation id="5310788376443009632">eliminate:</translation>
-<translation id="5320727453979144100">Modul persistent este activat</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{virgulă}few{# virgule}other{# de virgule}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, casetă text</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, link</translation>
-<translation id="5336381510091010269">completare automată inline+listă</translation>
-<translation id="536031132345979795">Treceți înapoi în timpul lecturii continue</translation>
-<translation id="5368000168321181111">Semnalele audio sunt dezactivate</translation>
-<translation id="5374320867641260420">Nu există un buton următor.</translation>
-<translation id="5382299583965267720">Nu există un titlu de nivel 1 următor.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{semn punct și virgulă}few{# semne punct și virgulă}other{# de semne punct și virgulă}}</translation>
-<translation id="5411891038905756502">Nu există un punct de accesare directă anterior.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{semn mai mic}few{# semne mai mic}other{# de semne mai mic}}</translation>
-<translation id="5455441614648621694">Complementar</translation>
-<translation id="5485036206801896268">Nu există un grafic anterior.</translation>
-<translation id="5486947920110100234">Nu există un punct de accesare directă următor.</translation>
-<translation id="549602578321198708">Cuvânt</translation>
-<translation id="5500932716852106146">Nu există un câmp de text editabil anterior.</translation>
-<translation id="5502713021410870035">Septembrie</translation>
-<translation id="5507663321906818013">Testare pentru depanare</translation>
-<translation id="5518443085409638729">La editarea textului plasați cursorul între caractere (ca în Mac OS X).</translation>
-<translation id="552195134157544755">Buton radio</translation>
-<translation id="5534303576632885660">antet</translation>
-<translation id="5546092960038624944">Nu există un titlu de nivel 5 anterior.</translation>
-<translation id="556042886152191864">Buton</translation>
-<translation id="5561345396546889625">Lista următoare</translation>
-<translation id="5562645715554321347">grup de titluri</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Câmp pentru editare text de tip e-mail</translation>
-<translation id="5597170376237141345">Caseta de selectare următoare</translation>
-<translation id="5597933780944041114">Nu există un titlu următor.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, buton radio deselectat</translation>
-<translation id="5601172225407283979">Efectuează acțiunea prestabilită</translation>
-<translation id="5608798115546226984">Completare automată inline</translation>
-<translation id="561939826962581046">oră</translation>
-<translation id="5623778242535476823">buton radio</translation>
-<translation id="5623842676595125836">Jurnal</translation>
-<translation id="5628125749885014029">titlu 4</translation>
-<translation id="5637871198229500030">Nu există un tabel anterior.</translation>
-<translation id="5655682562155942719">Comenzi de accesare</translation>
-<translation id="56637627897541303">Zonă de text</translation>
-<translation id="5678161956734658133">zonă text</translation>
-<translation id="5681643281275621376">definiție</translation>
-<translation id="5682113568322255809">Reper</translation>
-<translation id="5683155931978483559">Caseta de selectare anterioară</translation>
-<translation id="5684277895745049190">Listă</translation>
-<translation id="5700650669149824506">Nu există un titlu de nivel 4 anterior.</translation>
-<translation id="5709192780268610569">Fără descriere lungă</translation>
-<translation id="5712244464475377681">buton pop-up</translation>
-<translation id="5712338278108304766">Coloana următoare din tabel</translation>
-<translation id="571866080859340309">Explorarea grupurilor</translation>
-<translation id="5728409797179002635">Nu a fost găsit niciun tabel.</translation>
-<translation id="5748623122140342504">Titlul de nivel 5 anterior</translation>
-<translation id="5750633686117194034">Nu a fost apăsat niciun modificator; apăsați și mențineți apăsat pe unul sau mai mulți modificatori; după efectuare, ridicați degetele și veți auzi tastele setate. Apăsați pe tasta Tab pentru a ieși.</translation>
-<translation id="5788275253279308023">fila ferestrei incognito <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Îmbunătățește experiența utilizatorilor pe anumite site-uri, cum ar fi Căutarea Google.</translation>
-<translation id="5819072574982403430">Element arbore</translation>
-<translation id="5826479389509458994">rândul <ph name="ROW" />, coloana <ph name="COL" /></translation>
-<translation id="5850707923114094062">Deplasează înapoi</translation>
-<translation id="5851548754964597211">Listă de file</translation>
-<translation id="5859752971144398932">S-a ieșit din Găsiți în pagină.</translation>
-<translation id="5866042630553435010">Verificat parțial</translation>
-<translation id="5869546221129391014">Grilă</translation>
-<translation id="5876817486144482042">Scădeți volumul vocii</translation>
-<translation id="5887397643266327462">Subtitrările Braille sunt activate.</translation>
-<translation id="5891934789323004067">Tabel</translation>
-<translation id="5919442531159595654">copiați.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{egal}few{# semne egal}other{# de semne egal}}</translation>
-<translation id="5939518447894949180">Resetează</translation>
-<translation id="5948123859135882163">Comutați interpretarea expresiilor matematice între structurală și semantică</translation>
-<translation id="5955304353782037793">aplicație</translation>
-<translation id="5956928062748260866">Dialog</translation>
-<translation id="5963413905009737549">Secțiune</translation>
-<translation id="5968607524793740041">Afișează meniul contextual</translation>
-<translation id="5983179082906765664">Creșteți granularitatea de navigare</translation>
-<translation id="5999630716831179808">Voci</translation>
-<translation id="6000417740266304866">Schimbați tabelul Braille actual cu 8 puncte selectând o opțiune din lista de mai jos.</translation>
-<translation id="6006050241733874051">Formular</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{bară oblică inversă}few{# bare oblice inverse}other{# de bare oblice inverse}}</translation>
-<translation id="6037602951055904232">Deplasează înainte</translation>
-<translation id="611827076493383239">accesat</translation>
-<translation id="6119955456199054975">Sfârșitul celulei.</translation>
-<translation id="6122013438240733403">buton</translation>
-<translation id="6129953537138746214">Spațiu</translation>
-<translation id="6142308968191113180">Titlu 4</translation>
-<translation id="6169420925157477918">Imagine cu descriere lungă</translation>
-<translation id="6172087735260766220">Textul accesibil din fișierul PDF protejat la copiere nu poate fi accesat.</translation>
-<translation id="6186305613600865047">Navigați la sfârșitul paginii</translation>
-<translation id="6193330012414963395">a.m. p.m.</translation>
-<translation id="622484624075952240">Jos</translation>
-<translation id="6236061028292614533">Titlul următor</translation>
-<translation id="6254901459154107917">Următoarea zonă de text editabil</translation>
-<translation id="6259464875943891919">S-a ieșit din <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Elementul similar următor.</translation>
-<translation id="6282062888058716985">navigare</translation>
-<translation id="6290434000785343030">Nu există o casetă combo următoare.</translation>
-<translation id="6307969636681130414">Apăsat</translation>
-<translation id="6324551002951139333">Greșeală de gramatică detectată</translation>
-<translation id="6348657800373377022">Casetă combo</translation>
-<translation id="6355910664415701303">Nu există un element de listă anterior.</translation>
-<translation id="6364795331201459219">titlu 6</translation>
-<translation id="6368143427468974988">Titlul anterior</translation>
-<translation id="6387719785439924554">separat</translation>
-<translation id="6411426777058107714">Nu există un buton radio anterior.</translation>
-<translation id="6414968628640960377">Elementul diferit anterior.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{semn două puncte}few{# semne două puncte}other{# de semne două puncte}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, meniu</translation>
-<translation id="6444046323172968959">Casetă de dialog de alertă</translation>
-<translation id="6459511626086141404">Hartă taste plată</translation>
-<translation id="6468049171101508116">Butonul următor</translation>
-<translation id="6491972999578897419">Schimbați vocea actuală selectând o opțiune din lista de mai jos.</translation>
-<translation id="6508059270146105198">Deplasează afișajul Braille în partea de jos a paginii</translation>
-<translation id="6536864053412760904">Indicativ Math ML</translation>
-<translation id="6550720799683018100">Schimbați harta tastelor actuală selectând o opțiune din lista de mai jos.</translation>
-<translation id="6561818612645211875">Accesați începutul rândului curent</translation>
-<translation id="6587021927234520429">Nu există un titlu de nivel 4 următor.</translation>
-<translation id="6601344353291556895">Activați descrierile detaliate.</translation>
-<translation id="6615602925644411249">Găsiți în pagină.</translation>
-<translation id="6633350132811819843">Nu există un tabel următor.</translation>
-<translation id="6637586476836377253">jurnal</translation>
-<translation id="6657128831881431364">Bara de progres</translation>
-<translation id="6659594942844771486">Filă</translation>
-<translation id="667999046851023355">Document</translation>
-<translation id="6697092096875747123">Caseta combo anterioară</translation>
-<translation id="6714813999819678458">Titlul de nivel 2 anterior</translation>
-<translation id="6716505898850596801">Taste de modificare</translation>
-<translation id="671916444866103745">Nu există un reper ARIA următor.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, casetă combo</translation>
-<translation id="6735257939857578167">cu <ph name="NUM" /> (de) elemente</translation>
-<translation id="6736510033526053669">filă creată</translation>
-<translation id="675895815784134693">bară de progres</translation>
-<translation id="6786800275320335305">Articol</translation>
-<translation id="6787839852456839824">Comenzi rapide de la tastatură</translation>
-<translation id="6793101435925451627">casetă listă</translation>
-<translation id="6833103209700200188">Notă de subsol</translation>
-<translation id="6871161210040114857">Se ignoră scrierea cu minuscule/majuscule.</translation>
-<translation id="6877435256196695200">Nu există un grafic următor.</translation>
-<translation id="6897341342232909480">Deplasează spre stânga</translation>
-<translation id="6901540140423170855">dată</translation>
-<translation id="6910211073230771657">Șters</translation>
-<translation id="6911965441508464308">Nu există celule mai sus.</translation>
-<translation id="6919104639734799681">Afișați lista de tabele</translation>
-<translation id="6964088412282673743">Nu există o comandă anterioară.</translation>
-<translation id="6996566555547746822">Caseta combo următoare</translation>
-<translation id="7005146664810010831">Nu a fost găsită nicio adresă URL.</translation>
-<translation id="7010712454773919705">Tasta de modificare ChromeVox</translation>
-<translation id="7031651751836475482">element listă</translation>
-<translation id="7037042857287298941">Lista anterioară</translation>
-<translation id="7041173719775863268">Încheiați selectarea</translation>
-<translation id="7095834689119144465">Câmp text de editare exclusiv numeric</translation>
-<translation id="7096001299300236431">Conținut media anterior</translation>
-<translation id="7116595520562830928">linii multiple</translation>
-<translation id="712735679809149106">ecou cuvânt</translation>
-<translation id="713824876195128146">Citatul următor</translation>
-<translation id="7161771961008409533">Buton pop-up</translation>
-<translation id="7167657087543110">ecou caracter</translation>
-<translation id="7170733337935166589">Treceți înainte în timpul lecturii continue</translation>
-<translation id="7181697990050180700">Personalizați comenzi rapide de la tastatură pentru comenzile folosite frecvent, prin introducerea acestora în câmpurile corespunzătoare de mai jos.</translation>
-<translation id="7203150201908454328">Extins</translation>
-<translation id="7210211103303402262">minute</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">rând</translation>
-<translation id="7226216518520804442">listă</translation>
-<translation id="72393384879519786">Titlu</translation>
-<translation id="7241683698754534149">Deschideți descrierea lungă într-o filă nouă</translation>
-<translation id="7248671827512403053">Aplicație</translation>
-<translation id="725969808843520477">Butonul radio următor</translation>
-<translation id="7269119382257320590">Niciun semn de punctuație</translation>
-<translation id="7273174640290488576">Necompletată</translation>
-<translation id="7285387653379749618">Tabele</translation>
-<translation id="7289186959554153431">Titlu 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">element arbore</translation>
-<translation id="731576946540457939">Subtitrările Braille sunt dezactivate.</translation>
-<translation id="7318872822751139669">Utilizați mouse-ul pentru a schimba focalizarea.</translation>
-<translation id="7322388933135261569">Februarie</translation>
-<translation id="7332592614823088566">Rândul <ph name="ROWINDEX" /> din <ph name="ROWTOTAL" />, coloana <ph name="COLINDEX" /> din <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">are fereastră pop-up</translation>
-<translation id="7356165926712028380">Comutați la tabelul Braille cu 8 puncte</translation>
-<translation id="7362871137496673139">Nu există un titlu de nivel 2 anterior.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{semn de legătură}few{# semne de legătură}other{# de semne de legătură}}</translation>
-<translation id="737396357417333429">pe care se poate da clic</translation>
-<translation id="7374104575779636480">Se iese din tabel.</translation>
-<translation id="739763518212184081">Rândul anterior</translation>
-<translation id="7400575256015741911">Greșeală de scriere detectată</translation>
-<translation id="7408482676469142474">tabel</translation>
-<translation id="7425395583360211003">sfârșit de rând</translation>
-<translation id="7434509671034404296">Dezvoltator</translation>
-<translation id="7439060726180460871">Catalog</translation>
-<translation id="744163271241493234">parolă</translation>
-<translation id="7491962110804786152">filă</translation>
-<translation id="7492049978501397201">Ați intrat în caseta de dialog</translation>
-<translation id="7532613204005497612">Iunie</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, glisor</translation>
-<translation id="7586163296341959563">inserați.</translation>
-<translation id="7596919493010894443">secțiune eliminată</translation>
-<translation id="7604026522577407655">Accesați începutul coloanei curente</translation>
-<translation id="7604451927827590395">titlu</translation>
-<translation id="7609342235116740824">Anunță adresa URL a paginii curente</translation>
-<translation id="7609363189280667021">Activați/dezactivați subtitrările Braille</translation>
-<translation id="762020119231868829">Întrerupe toate widgeturile care redau conținut media</translation>
-<translation id="7625690649919402823">Tabelul următor</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), nivelul <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Nu există un titlu de nivel 3 anterior.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, casetă text</translation>
-<translation id="7663318257180412551">Titlu 2</translation>
-<translation id="7674576868851035240">Linkul următor</translation>
-<translation id="7674768236845044097">marcaj</translation>
-<translation id="7684431668231950609">Câmp editare text de tip adresă URL</translation>
-<translation id="7685589220304187312">bară de instrumente</translation>
-<translation id="7693840228159394336">Butonul radio anterior</translation>
-<translation id="7701196182766842984">completare automată listă</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, casetă text pentru parolă</translation>
-<translation id="7805247615045262757">navigare prestabilită</translation>
-<translation id="7805768142964895445">Stare</translation>
-<translation id="7810781339813764006">Grupul următor</translation>
-<translation id="7819187121850078213">fila ferestrei <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Octombrie</translation>
-<translation id="7839679365527550018">Cuvânt anterior</translation>
-<translation id="7851816175263618915">Unele semne de punctuație</translation>
-<translation id="7870596830398826354">Arbore Math ML</translation>
-<translation id="78826985582142166">cursor</translation>
-<translation id="7894517696028036636">Activează/dezactivează ChromeVox classic.</translation>
-<translation id="7895896691902835279">Link necunoscut</translation>
-<translation id="7927711904086083099">Neselectat</translation>
-<translation id="7935627501098484003">Comandă pentru oră</translation>
-<translation id="7939428177581522200">adăugate la selecție</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{arond}few{# aronduri}other{# de aronduri}}</translation>
-<translation id="7965147473449754028">meniu închis</translation>
-<translation id="7974390230414479278">Element din meniu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{semn de exclamare}few{# semne de exclamare}other{# de semne de exclamare}}</translation>
-<translation id="8007540374018858731">titlu 3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{ghilimea}few{# ghilimele}other{# de ghilimele}}</translation>
-<translation id="8033827949643255796">selectate</translation>
-<translation id="8035962149453661158">max.:<ph name="X" /></translation>
-<translation id="8042761080832772327">Câmp pentru editare text de tip căutare</translation>
-<translation id="8049189770492311300">Temporizator</translation>
-<translation id="8065607967589909823">Selecția este</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Nu există repere ARIA.</translation>
-<translation id="8153880621934657047">Nu vă aflați în interiorul tabelului.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{caracter de subliniere}few{# caractere de subliniere}other{# de caractere de subliniere}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">decupați.</translation>
-<translation id="8199231515320852133">Anunță anteturile celulei curente</translation>
-<translation id="820417203470636242">Celulă goală.</translation>
-<translation id="8215202828671303819">Selectare multiplă</translation>
-<translation id="8276439074553447000">Salt la elementul focalizabil anterior</translation>
-<translation id="8278417001922463147">Nu există niciun articol anterior.</translation>
-<translation id="8283603667300770666">Câmpul următor din formular</translation>
-<translation id="831207808878314375">Definiție</translation>
-<translation id="8313653172105209786">director</translation>
-<translation id="8344569602005188545">ore</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{liră}few{# semne liră}other{# de semne de liră}}</translation>
-<translation id="8374154622594089836">lună</translation>
-<translation id="8378855320830505539">Regiune</translation>
-<translation id="8382679411218029383">Completare automată inline și listă</translation>
-<translation id="8428603554127842284">nivelul <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Nu există un titlu de nivel 3 următor.</translation>
-<translation id="8430049249787218991">bară meniu</translation>
-<translation id="844681116543532394">Nu există o casetă de selectare anterioară.</translation>
-<translation id="8455868257606149352">Max. <ph name="X" /></translation>
-<translation id="84575901236241018">are tastă de acces, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Scădeți granularitatea de navigare</translation>
-<translation id="8520472399088452386">Buton numeric</translation>
-<translation id="8538744478902126321">Faceți o încercare la antetul rândului pentru celula curentă</translation>
-<translation id="8540054775867439484">Încadrare sus</translation>
-<translation id="8548973727659841685">Caracter</translation>
-<translation id="8561322612995434619">are fereastră pop-up</translation>
-<translation id="8571096049907249734">selectare multiplă</translation>
-<translation id="8584721346566392021">titlu 5</translation>
-<translation id="8587549812518406253">Elementul următor din listă</translation>
-<translation id="860150890330522909">Casetă de validare <ph name="NAME" /> bifată</translation>
-<translation id="8606621670302093223">Comandă pentru dată</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> (de) elemente selectate</translation>
-<translation id="8638532244051952400">Anunță coordonatele celulei curente</translation>
-<translation id="8650576015643545550">Nu există o listă anterioară.</translation>
-<translation id="8653031188082306838">adresă URL</translation>
-<translation id="8653646212587894517">Afișați lista de linkuri</translation>
-<translation id="8664519043722036194">secunde</translation>
-<translation id="867187640362843212">Titlu 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{bară verticală}few{# bare verticale}other{# de bare verticale}}</translation>
-<translation id="8735450637152821465">S-a început selectarea</translation>
-<translation id="8743786158317878347">intrați în conținut structurat, cum ar fi tabelele</translation>
-<translation id="8747966237988593539">Listă ordonată</translation>
-<translation id="8759334257841767240">Nu există un link următor.</translation>
-<translation id="8767968232364267681">Titlul de nivel 4 următor</translation>
-<translation id="8770473310765924354">se iese din conținutul structurat, cum ar fi tabelele</translation>
-<translation id="8791025954632646584">Interpretare semantică activată</translation>
-<translation id="8796411681063377102">Următorul titlu de nivel 3</translation>
-<translation id="8808582214901541005">Martie</translation>
-<translation id="8825828890761629845">banner</translation>
-<translation id="8851136666856101339">principal</translation>
-<translation id="8856538297388979332">Apăsați în sus sau în jos pentru a examina comenzile, apăsați pe enter pentru activare</translation>
-<translation id="8864099967139188018">Nu există un titlu de nivel 6 următor.</translation>
-<translation id="8882002077197914455">Antet de rând</translation>
-<translation id="8896347895970027998">Comutați ChromeVox la activ sau inactiv.</translation>
-<translation id="8898516272131543774">Repetă ecoul la punctuație</translation>
-<translation id="8900148057318340779">Tastă prefix</translation>
-<translation id="8908714597367957477">antet coloană</translation>
-<translation id="8931936695772494138">Anteturi goale</translation>
-<translation id="8937112856099038376">link intern</translation>
-<translation id="8940925288729953902">Taste de modificare</translation>
-<translation id="8943175951035496220">Nu există celule în dreapta.</translation>
-<translation id="8978496506222343566">balon explicativ</translation>
-<translation id="900114243503212879">fișier</translation>
-<translation id="9027462562263121875">Nu există tabele.</translation>
-<translation id="9040132695316389094">Titlu 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Afișați/ascundeți widgetul de căutare</translation>
-<translation id="9065283790526219006">+fereastră pop-up</translation>
-<translation id="9077213568694924680">eliminate din selecție</translation>
-<translation id="9082874451376019682">Nu există un glisor anterior.</translation>
-<translation id="9089864840575085222">Repetă ecoul la tastare</translation>
-<translation id="9107530006868467849">Niciun widget media anterior.</translation>
-<translation id="9108370397979208512">matematică</translation>
-<translation id="9108589040018540527">bară de derulare</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{procent}few{# semne de procent}other{# de semne de procent}}</translation>
-<translation id="9115913704608474258">Noiembrie</translation>
-<translation id="9128414153595658330">casetă de dialog</translation>
-<translation id="9149560530563164529">secțiune</translation>
-<translation id="9151211641321628915">Anunță o scurtă descriere a poziției curente</translation>
-<translation id="9153606228985488238">Înălțime a sunetului de <ph name="PERCENT" /></translation>
-<translation id="9160096769946561184">Accesați finalul coloanei curente</translation>
-<translation id="9173115498289768110">Volum <ph name="PERCENT" />%</translation>
-<translation id="9178973770513562274">Folosiți tastele săgeată în sus și în jos pentru a naviga sau introduceți text pentru a căuta.</translation>
-<translation id="9192904702577636854">Text derulant</translation>
-<translation id="9212322457209634662">Nu există o secțiune următoare.</translation>
-<translation id="930275611743429116">Începe sau încheie selecția.</translation>
-<translation id="948171205378458592">Scădeți viteza de vorbire</translation>
-<translation id="962913030769097253">Titlul de nivel 1 următor</translation>
-<translation id="973955474346881951">Activează/dezactivează modul taste persistente</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ru.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ru.xtb
deleted file mode 100644
index 0842f26120f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ru.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ru">
-<translation id="1012173283529841972">Пункт списка</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Объединенные ячейки.</translation>
-<translation id="1025074108959230262">Режим залипания отключен</translation>
-<translation id="1031961866430398710">затем</translation>
-<translation id="1044777062731150180">Заголовков нет</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Неправильный ввод</translation>
-<translation id="1082209053475788238">Предыдущего заголовка шестого уровня нет.</translation>
-<translation id="1088219014394087294">Заголовков нет.</translation>
-<translation id="1106741348836243114">Включить или отключить озвучивание (звуковые сигналы)</translation>
-<translation id="1120743664840974483">{"а": "анна", "б": "борис", "в": "василий", "г": "григорий", "д": "дмитрий", "е": "елена", "ё": "ёлка", "ж": "женя", "з": "зинаида", "и": "иван", "й": "йот", "к": "константин", "л": "леонид", "м": "михаил", "н": "николай", "о": "ольга", "п": "павел", "р": "роман", "с": "семён", "т": "татьяна", "у": "ульяна", "ф": "фёдор", "х": "харитон", "ц": "цапля", "ч": "человек", "ш": "шура", "щ": "щука", "ъ": "твёрдый знак", "ы": "игрек", "ь": "мягкий знак", "э": "эхо", "ю": "юрий", "я": "яков"}</translation>
-<translation id="113582498867142724">Элементов в коллекции "<ph name="TAG" />": <ph name="NUM" /></translation>
-<translation id="1155043339247954670">Следующего пункта списка нет.</translation>
-<translation id="1157782847298808853">Справка по клавиатуре.</translation>
-<translation id="1157843803349774103">Поле со списком "<ph name="NAME" />" со значением "<ph name="VALUE" />"</translation>
-<translation id="1167230103353892028">Пункт меню "<ph name="NAME" />", есть подменю</translation>
-<translation id="1177863135347784049">Персонализированные</translation>
-<translation id="1188858454923323853">дополнительно</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox – голосовой интерфейс для Chrome</translation>
-<translation id="1229276918471378188">Предыдущий переход</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Перейти к следующему заголовку шестого уровня</translation>
-<translation id="1275718070701477396">Выбрано</translation>
-<translation id="1319608975892113573">Предыдущей цитаты нет.</translation>
-<translation id="1321576897702511272">Скрыть справку ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> из <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">Озвучивание символов и слов.</translation>
-<translation id="1339428534620983148">Перейти к предыдущему столбцу таблицы</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Вправо</translation>
-<translation id="136718599399906424">Перейти к следующей строке таблицы</translation>
-<translation id="1383876407941801731">Поиск</translation>
-<translation id="1385214448885562192">Нажмите ВВОД, чтобы принять, или ОТМЕНА, чтобы отменить изменения. Для перехода к следующему или предыдущему элементу используйте стрелки вниз и вверх.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652">Поле для ввода пароля, <ph name="VALUE" /></translation>
-<translation id="1467432559032391204">Влево</translation>
-<translation id="1474557363159888097">Предыдущей привязки нет.</translation>
-<translation id="1502086903961450562">Перейти к предыдущей диаграмме</translation>
-<translation id="1506187449813838456">Повысить тон</translation>
-<translation id="151784044608172266">К следующему предложению</translation>
-<translation id="1524531499102321782">Перейти к следующей строке</translation>
-<translation id="1546370775711804143">Полоса прокрутки</translation>
-<translation id="1559739829547075274">Перейти к предыдущему элементу</translation>
-<translation id="1571643229714746283">Расширение ChromeVox включено</translation>
-<translation id="158493514907962286">декабрь</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Переключиться на 6-точечный шрифт</translation>
-<translation id="1611168825862729585">Заголовок столбца:</translation>
-<translation id="1613476421962910979">Звуковые сигналы включены.</translation>
-<translation id="1618597272655350600">Озвучить полное описание текущего элемента</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{знак "больше"}one{# знак "больше"}few{# знака "больше"}many{# знаков "больше"}other{# greater than signs}}</translation>
-<translation id="1653266918374749391">Перейти к предыдущему заголовку третьего уровня</translation>
-<translation id="1659072772017912254">Не проверено</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">Навигация ChromeVox</translation>
-<translation id="16777221443363124">Строка меню</translation>
-<translation id="1692077714702418899">Структурная линия.</translation>
-<translation id="1700517974991662022">Посещено</translation>
-<translation id="1722567105086139392">Ссылка</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Перейти к следующей диаграмме</translation>
-<translation id="1781173782405573156">Пропустить нажатие</translation>
-<translation id="1787176709638001873">Поле для ввода пароля</translation>
-<translation id="1810107444790159527">Список</translation>
-<translation id="1828385960365606039">май</translation>
-<translation id="1834891354138622109">Столбец.</translation>
-<translation id="1865601187525349519">Конец текста.</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Озвучить текущее время и дату</translation>
-<translation id="1902396333223336119">Ячейка</translation>
-<translation id="1905379170753160525">Показать список заголовков</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Элемент управления "номер недели"</translation>
-<translation id="1964135212174907577">Перейти к следующему элементу</translation>
-<translation id="1969092762068865084">июль</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Заголовок строки:</translation>
-<translation id="2002895034995108595">Сбросить раскладку</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{открывающая квадратная скобка}one{# открывающая квадратная скобка}few{# открывающие квадратные скобки}many{# открывающих квадратных скобок}other{# left brackets}}</translation>
-<translation id="2045490512405922022">не установлен</translation>
-<translation id="20601713649439366">Предыдущего математического выражения нет.</translation>
-<translation id="207477615537953741">Семантический метод отключен.</translation>
-<translation id="2086961585857038472">Следующее слово</translation>
-<translation id="2089387485033699258">ru</translation>
-<translation id="2091933974477985526">Перейти к предыдущей редактируемой области текста</translation>
-<translation id="2100350898815792233">Со всеми знаками препинания.</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">access key:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Чтобы сменить 6-точечный шрифт Брайля, выберите вариант из списка ниже</translation>
-<translation id="2169714232367507776">Нажать на текущий элемент</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{закрывающая круглая скобка}one{# закрывающая круглая скобка}few{# закрывающие круглые скобки}many{# закрывающих круглых скобок}other{# close parens}}</translation>
-<translation id="2199994615414171367">Перейти к предыдущему математическому выражению</translation>
-<translation id="2223693656926968778">Выполнить действие с текущим элементом</translation>
-<translation id="225732394367814946">Ускорить речь</translation>
-<translation id="2267945578749931355">Перейти к следующему символу</translation>
-<translation id="2281234842553884450">Перейти к предыдущему ползунку</translation>
-<translation id="2318372665160196757">Основное</translation>
-<translation id="2329324941084714723">Панель вкладок</translation>
-<translation id="2344193891939537199">Выбор даты и времени</translation>
-<translation id="2359897517538099099">Режим таблицы выключен.</translation>
-<translation id="241124561063364910">а затем</translation>
-<translation id="2417569100218200841">Сведения о контенте</translation>
-<translation id="2422937916923936891">Элемент меню: флажок</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">Клавиша <ph name="KEY" /> выбрана в качестве модификатора.</translation>
-<translation id="2450814015951372393">Флажок</translation>
-<translation id="2462626033734746142">Группа переключателей</translation>
-<translation id="2471138580042810658">Заголовок шестого уровня.</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{звездочка}one{# звездочка}few{# звездочки}many{# звездочек}other{# asterisks}}</translation>
-<translation id="2549392850788122959">Сброс до состояния по умолчанию для клавиши <ph name="KEY" /> выполнен.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Группа.</translation>
-<translation id="2582407057977008361">Боковой блок.</translation>
-<translation id="2589102159832527089">На странице содержится текст, извлеченный из PDF-файла &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Открыть оригинал&lt;/a&gt;</translation>
-<translation id="2606210917827248971">из {COUNT,plural, =1{# пункта}one{# пункта}few{# пунктов}many{# пунктов}other{# пункта}}</translation>
-<translation id="2614981083756825552">Схема MathML.</translation>
-<translation id="2626530649491650971">clickable</translation>
-<translation id="2628764385451019380">Предыдущего поля со списком нет.</translation>
-<translation id="2637227747952042642">Math</translation>
-<translation id="2639750663247012216">Модификатор ChromeVox.</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">Нажать на элемент под ключом маршрутизации</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{открывающая круглая скобка}one{# открывающая круглая скобка}few{# открывающие круглые скобки}many{# открывающих круглых скобок}other{# open parens}}</translation>
-<translation id="2705875883745373140">Не нажато</translation>
-<translation id="2706462751667573066">Вверх</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">аудио</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Выбрано</translation>
-<translation id="27527859628328957">Перейти к следующему активируемому элементу</translation>
-<translation id="2770781857296573485">Ввести значение для перехода по группам</translation>
-<translation id="2777845298774924149">Окно закрыто.</translation>
-<translation id="2800204403141299078">Отличающихся элементов больше нет.</translation>
-<translation id="2800780099804980316">Предыдущего заголовка первого уровня нет.</translation>
-<translation id="2811204574343810641">Строка.</translation>
-<translation id="2816654101880605877">Следующего ползунка нет.</translation>
-<translation id="2841013758207633010">Время</translation>
-<translation id="2843837985843789981">Перейти к предыдущей группе</translation>
-<translation id="2844995807198708617">Контекстное меню.</translation>
-<translation id="2849332794118375855">Следующего флажка нет.</translation>
-<translation id="2864481629947106776">Перейти к предыдущей ссылке</translation>
-<translation id="2873259058405069099">Перейти к началу таблицы</translation>
-<translation id="2894654529758326923">Подробные сведения</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{открывающая фигурная скобка}one{# открывающая фигурная скобка}few{# открывающие фигурные скобки}many{# открывающих фигурных скобок}other{# left braces}}</translation>
-<translation id="2911433807131383493">Открыть руководство ChromeVox</translation>
-<translation id="2932083475399492303">Переключиться между структурной и контурной линией</translation>
-<translation id="2964026537669811554">Группировка заголовков.</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{вкладка}one{# вкладка}few{# вкладки}many{# вкладок}other{# tabs}}</translation>
-<translation id="2972078295414139404">Предыдущей открытой ссылки нет.</translation>
-<translation id="2972205263822847197">Подсказка</translation>
-<translation id="2998131015536248178">Перейти к предыдущему символу</translation>
-<translation id="2999559350546931576">Понизить тон</translation>
-<translation id="2999945368667127852">Следующего виджета мультимедиа нет.</translation>
-<translation id="3012414509011670858">Предыдущего раздела нет.</translation>
-<translation id="3030432017085518523">Пункт меню переключатель</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{апостроф}one{# апостроф}few{# апострофа}many{# апострофов}other{# apostrophes}}</translation>
-<translation id="3046838483509668188">Параметры ChromeVox</translation>
-<translation id="3047143736589213134">Экспериментальная раскладка</translation>
-<translation id="3060756054951570867">Открыто меню <ph name="TITLE" />.</translation>
-<translation id="3078345202707391975">Перейти к следующему заголовку второго уровня</translation>
-<translation id="3078740164268491126">таблица</translation>
-<translation id="3082557070674409251">Нажато.</translation>
-<translation id="3084806535845658316">Без озвучивания.</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Следующего математического выражения нет.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Перейти к следующему ориентиру</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Свернуто</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Показать список ориентиров</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Перейти к следующей строке</translation>
-<translation id="3155083529632865074">Предыдущей кнопки нет.</translation>
-<translation id="3163593631834463955">Нет заголовка столбца</translation>
-<translation id="316542773973815724">Навигация</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{пробел}one{# пробел}few{# пробела}many{# пробелов}other{# spaces}}</translation>
-<translation id="320961988183078793">Введено <ph name="TYPE" />.</translation>
-<translation id="3223701887221307104">Вкладка "<ph name="NAME" />"</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Посещенная ссылка</translation>
-<translation id="323731244387692321">Открыть справку о горячих клавишах ChromeVox</translation>
-<translation id="3241052487511142956">Перейти к предыдущей открытой ссылке</translation>
-<translation id="3286390186030710347">Ползунок</translation>
-<translation id="3299925995433437805">Следующей открытой ссылки нет.</translation>
-<translation id="3303384412438961941">Чтобы узнать, какая это клавиша, нажмите на нее. Чтобы выйти из режима обзора клавиш, нажмите CTRL + W.</translation>
-<translation id="3307886118343381874">Перейти к концу таблицы</translation>
-<translation id="3311969765485641742">Нажмите ALT + SHIFT + A, чтобы посмотреть оповещения</translation>
-<translation id="3312997241656799641">Перейти к следующей открытой ссылке</translation>
-<translation id="3321460131042519426">Переносить по словам</translation>
-<translation id="3322936298410871309">Перейти к предыдущему заголовку первого уровня</translation>
-<translation id="3323447499041942178">Текстовое поле</translation>
-<translation id="3353420241558113817">{"ar": "арабский",
- "bg": "болгарский",
- "ca": "каталанский",
- "cs": "чешский",
- "da": "датский",
- "de": "немецкий",
- "de_CH": "немецкий (Швейцария)",
- "de_DE": "немецкий (Германия)",
- "el": "греческий",
- "en": "английский",
- "en_CA": "английский (Канада)",
- "en_GB": "английский (Великобритания)",
- "en_US": "английский (США)",
- "es": "испанский",
- "et": "эстонский",
- "fr": "французский",
- "fr_CA": "французский (Канада)",
- "fr_FR": "французский (Франция)",
- "fi": "финский",
- "he": "иврит",
- "hi": "хинди",
- "hr": "хорватский",
- "hu": "венгерский",
- "is": "исландский",
- "it": "итальянский",
- "ko": "корейский",
- "lt": "литовский",
- "lv": "латышский",
- "nb": "букмол",
- "nl": "нидерландский",
- "pl": "польский",
- "pt": "португальский",
- "ro": "румынский",
- "ru": "русский",
- "sk": "словацкий",
- "sl": "словенский",
- "sr": "сербский",
- "sv": "шведский",
- "tr": "турецкий",
- "vi": "вьетнамский",
- "zh": "китайский",
- "zh_TW": "китайский (традиционный)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{знак плюс}one{# знак плюс}few{# знака плюс}many{# знаков плюс}other{# plus signs}}</translation>
-<translation id="338583716107319301">Разделитель</translation>
-<translation id="3389259863310851658">Перейти к предыдущему полю формы</translation>
-<translation id="3390225400784126843">Перейти к следующему отличающемуся элементу</translation>
-<translation id="3392045790598181549">Пункт меню <ph name="NAME" /></translation>
-<translation id="3406283310380167331">Показать список форм</translation>
-<translation id="3422338090358345848">Перейти в режим обзора клавиш</translation>
-<translation id="3457000393508828486">Частично нажато</translation>
-<translation id="3462439746547587373">Кнопка "<ph name="NAME" />"</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{закрывающая квадратная скобка}one{# закрывающая квадратная скобка}few{# закрывающие квадратные скобки}many{# закрывающих квадратных скобок}other{# right brackets}}</translation>
-<translation id="3493915602752813531">Следующей привязки нет.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{вопросительный знак}one{# вопросительный знак}few{# вопросительных знака}many{# вопросительных знаков}other{# question marks}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{циркумфлекс}one{# циркумфлекс}few{# циркумфлекса}many{# циркумфлексов}other{# carets}}</translation>
-<translation id="3568702578574425662">Флажок "<ph name="NAME" />", не установлен</translation>
-<translation id="3599054940393788245">Не математический символ</translation>
-<translation id="3616113530831147358">Аудио</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{обратная кавычка}one{# обратная кавычка}few{# обратные кавычки}many{# обратных кавычек}other{# backticks}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{знак доллара}one{# знак доллара}few{# знака доллара}many{# знаков доллара}other{# dollar signs}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755">Список, <ph name="VALUE" /></translation>
-<translation id="3687295507293856493">Определить тип данных в заголовке столбца текущей ячейки</translation>
-<translation id="3692274950075847560">П: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Управление речью</translation>
-<translation id="3716845769494773620">Несколько строк</translation>
-<translation id="3731746171184829332">Предыдущего заголовка нет.</translation>
-<translation id="3762198587642264450">Перейти к концу текущей строки</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Диалоговое окно закрыто.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}few{#}many{#}other{#}}</translation>
-<translation id="3801735343383419236">Список автозаполнения</translation>
-<translation id="3810838688059735925">Видео</translation>
-<translation id="3816633764618089385">Перейти к следующему файлу мультимедиа</translation>
-<translation id="3819376190738087562">Переходов нет.</translation>
-<translation id="385383972552776628">Открыть страницу параметров</translation>
-<translation id="3856075812838139784">Только чтение</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Меню</translation>
-<translation id="3909320334364316587">Перейти к предыдущему заголовку шестого уровня</translation>
-<translation id="3914173277599553213">Обязательно</translation>
-<translation id="3962990492275676168">Читать с текущего места</translation>
-<translation id="4004802134384979325">установлен</translation>
-<translation id="4006140876663370126">изображение</translation>
-<translation id="4038349100599457191">Элемент управления "месяц"</translation>
-<translation id="4039983576244166038">Нет заголовка для строки</translation>
-<translation id="4042843249978639960">Следующего заголовка второго уровня нет.</translation>
-<translation id="4043348641337972076">Предыдущего ориентира ARIA нет.</translation>
-<translation id="4047216625641135770">Пометка.</translation>
-<translation id="404803211695627272"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{тильда}one{# тильда}few{# тильды}many{# тильд}other{# tildes}}</translation>
-<translation id="409334809956508737">К предыдущему элементу</translation>
-<translation id="4099274309791143834">есть подменю</translation>
-<translation id="4107807507418787238">Ячейки ниже нет.</translation>
-<translation id="4116415223832267137">Оповещение</translation>
-<translation id="4147126331795725888">Следующего элемента управления нет.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{закрывающая фигурная скобка}one{# закрывающая фигурная скобка}few{# закрывающие фигурные скобки}many{# закрывающих фигурных скобок}other{# right braces}}</translation>
-<translation id="4158704014418536539">С учетом регистра.</translation>
-<translation id="4161663686871496107">Расширение ChromeVox включено.</translation>
-<translation id="4173994908659439270">Следующего редактируемого текстового поля нет.</translation>
-<translation id="4176463684765177261">Отключено</translation>
-<translation id="4188530942454211480">Перейти к предыдущему предложению</translation>
-<translation id="4202186506458631436">Переместить вправо</translation>
-<translation id="4206289001967551965">Открыта таблица.</translation>
-<translation id="4215733775853809057">Перейти к следующему ползунку</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{тире}one{# тире}few{# тире}many{# тире}other{# dashes}}</translation>
-<translation id="421884353938374759">color picker</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">Ячейки слева нет.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, уровень <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Примечание</translation>
-<translation id="4254798249533888099">Дерево</translation>
-<translation id="4255943572433203166">Эти параметры позволяют настроить ChromeVox. Изменения вступят в силу немедленно.</translation>
-<translation id="4271220233568730077">Перейти к следующему математическому выражению</translation>
-<translation id="4271521365602459209">Больше ничего не найдено.</translation>
-<translation id="4287520460805643128">Следующей статьи нет.</translation>
-<translation id="4289540628985791613">Обзор</translation>
-<translation id="4300318234632215983">Произносить URL после названия ссылки</translation>
-<translation id="4301352596632316575">содержит подменю.</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{точка}=3{многоточие}one{# точка}few{# точки}many{# точек}other{# dots}}</translation>
-<translation id="4347461890115250064">Следующего списка нет.</translation>
-<translation id="4367650418938037324">Конечные узлы Math ML.</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Отключить озвучивание</translation>
-<translation id="4373197658375206385">Предыдущего элемента, не являющегося ссылкой, нет.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Ссылок нет.</translation>
-<translation id="4476183483923481720">Новая строка.</translation>
-<translation id="4482330759234983253">Перейти к предыдущей таблице</translation>
-<translation id="4491109536499578614">Изображение</translation>
-<translation id="4529987814483543472">Классическая раскладка</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{косая черта}one{# косая черта}few{# косые черты}many{# косых черт}other{# slashes}}</translation>
-<translation id="4547556996012970016">Перейти к следующему заголовку пятого уровня</translation>
-<translation id="4562381607973973258">Заголовок.</translation>
-<translation id="4591507479202817876">, выбрано.</translation>
-<translation id="4597532268155981612">форма</translation>
-<translation id="4597896406374528575">апрель</translation>
-<translation id="4615592953348396470">Игнорировать нажатие следующей клавиши.</translation>
-<translation id="461613135510474570">Предложение.</translation>
-<translation id="4647836961514597010">Палитра цветов</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Перейти к предыдущему ориентиру</translation>
-<translation id="4696413482802371445">Следующего заголовка пятого уровня нет.</translation>
-<translation id="4729095194763193578">Перейти к предыдущей строке таблицы</translation>
-<translation id="4736221692378411923">август</translation>
-<translation id="4740661827607246557">Справка по командам</translation>
-<translation id="4759716709594980008">Озвучивание клавиатуры ChromeOS</translation>
-<translation id="4763296182459741068">Смещение вниз</translation>
-<translation id="4763480195061959176">видео</translation>
-<translation id="479989351350248267">поиск</translation>
-<translation id="481165870889056555">Назвать заголовок текущей страницы</translation>
-<translation id="4826415162591436065">Перейти к следующему элементу</translation>
-<translation id="4826604887384865800">Следующий переход</translation>
-<translation id="4827410568042294688">Выделение отменено.</translation>
-<translation id="4842108708071771135">Следующей цитаты нет.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Предыдущий похожий элемент</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Включить ведение журнала синтеза речи</translation>
-<translation id="4877261390094455813">Введите поисковый запрос.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" /> из <ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Внутренняя ссылка.</translation>
-<translation id="4953585991029886728">Изменение текста</translation>
-<translation id="4954534434583049121">Перейти к предыдущей цитате</translation>
-<translation id="4973717656530883744">Минимум <ph name="X" />.</translation>
-<translation id="4973762002207131920">Выбрана раскладка <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">миллисекунды</translation>
-<translation id="49787999531187221">Расширение ChromeVox отключено.</translation>
-<translation id="4979404613699303341">Перейти к предыдущей кнопке</translation>
-<translation id="4982773647088557172">Поле списка "<ph name="NAME" />" со значением "<ph name="VALUE" />"</translation>
-<translation id="4983588134362688868">Вернуться к началу страницы</translation>
-<translation id="4986606102545753256">Окно "<ph name="NAME" />"</translation>
-<translation id="4993152509206108683">Скорость речи: <ph name="PERCENT" />%</translation>
-<translation id="4996716799442435517">Визуальный.</translation>
-<translation id="4997282455736854877">Переключатель "<ph name="NAME" />", установлен</translation>
-<translation id="4997475792277222884">Следующего элемента, не являющегося ссылкой, нет.</translation>
-<translation id="5000760171916499057">Форм нет.</translation>
-<translation id="5005670136041063723">Похожих элементов больше нет.</translation>
-<translation id="501473567976723023">январь</translation>
-<translation id="5041394372352067729">Разместить дисплей Брайля вверху страницы</translation>
-<translation id="5042770794184672516">Увеличить громкость речи</translation>
-<translation id="5050015258024679800">Перейти к предыдущему заголовку четвертого уровня</translation>
-<translation id="5054047268577924192">Перейти к предыдущему пункту списка</translation>
-<translation id="5078661581131202757">Выбор файла</translation>
-<translation id="5080758118274074384">Выполнено двойное нажатие.</translation>
-<translation id="5098541983634824365">Выход из сетки.</translation>
-<translation id="5102981729317424850">Панель инструментов</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Предыдущего поля формы нет.</translation>
-<translation id="5111640677200759579">Заголовок столбца</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Предыдущей ссылки нет.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, выделение снято.</translation>
-<translation id="5183440668879371625">Перейти к предыдущей строке</translation>
-<translation id="5184944171021383281">Следующего поля формы нет.</translation>
-<translation id="5189244881767082992">Строка.</translation>
-<translation id="5203930734796605961">Клавише <ph name="KEY" /> уже назначена команда.</translation>
-<translation id="5205493599117157272">Список: <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Следующего переключателя нет.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Завершить</translation>
-<translation id="5291783959063340370">Объект.</translation>
-<translation id="5304943142864553931">Вкладка <ph name="TITLE" />.</translation>
-<translation id="5310788376443009632">Удалено:</translation>
-<translation id="5320727453979144100">Режим залипания включен</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{запятая}one{# запятая}few{# запятые}many{# запятых}other{# commas}}</translation>
-<translation id="532371086589123547">Текстовое поле, <ph name="VALUE" /></translation>
-<translation id="5330443287809544590">Ссылка "<ph name="NAME" />"</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Вернуться назад во время непрерывного чтения</translation>
-<translation id="5368000168321181111">Звуковые сигналы отключены.</translation>
-<translation id="5374320867641260420">Следующей кнопки нет.</translation>
-<translation id="5382299583965267720">Следующего заголовка первого уровня нет.</translation>
-<translation id="5402367795255837559">Шрифт Брайля</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{точка с запятой}one{# точка с запятой}few{# точки с запятой}many{# точек с запятой}other{# semicolons}}</translation>
-<translation id="5411891038905756502">Предыдущей точки перехода нет.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{знак "меньше"}one{# знак "меньше"}few{# знака "меньше"}many{# знаков "меньше"}other{# less than signs}}</translation>
-<translation id="5455441614648621694">Дополнительно</translation>
-<translation id="5485036206801896268">Предыдущей диаграммы нет.</translation>
-<translation id="5486947920110100234">Следующей точки перехода нет.</translation>
-<translation id="549602578321198708">Слово.</translation>
-<translation id="5500932716852106146">Предыдущего редактируемого текстового поля нет.</translation>
-<translation id="5502713021410870035">сентябрь</translation>
-<translation id="5507663321906818013">Эталон для отладки</translation>
-<translation id="5518443085409638729">Показывать курсор между символами (как в Mac OS X)</translation>
-<translation id="552195134157544755">Переключатель</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Предыдущего заголовка пятого уровня нет.</translation>
-<translation id="556042886152191864">Кнопка</translation>
-<translation id="5561345396546889625">Перейти к следующему списку</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Клавиша возврата (Backspace)</translation>
-<translation id="5585044216466955529">Редактирование текста, поле для адреса электронной почты</translation>
-<translation id="5597170376237141345">Следующий флажок</translation>
-<translation id="5597933780944041114">Следующего заголовка нет.</translation>
-<translation id="5598905979683743333">Переключатель "<ph name="NAME" />", не выбран</translation>
-<translation id="5601172225407283979">Выполнить действие по умолчанию</translation>
-<translation id="5608798115546226984">Строка автозаполнения</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Журнал</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Предыдущей таблицы нет.</translation>
-<translation id="5655682562155942719">Команды для перехода</translation>
-<translation id="56637627897541303">Область текста.</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Ориентир</translation>
-<translation id="5683155931978483559">Перейти к предыдущему флажку</translation>
-<translation id="5684277895745049190">Список</translation>
-<translation id="5700650669149824506">Предыдущего заголовка четвертого уровня нет.</translation>
-<translation id="5709192780268610569">Подробного описания нет</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Перейти к следующему столбцу</translation>
-<translation id="571866080859340309">Переход по группам.</translation>
-<translation id="5728409797179002635">Таблицы не найдены.</translation>
-<translation id="5748623122140342504">Перейти к предыдущему заголовку пятого уровня</translation>
-<translation id="5750633686117194034">Модификаторы не нажаты. Нажмите и удерживайте один или несколько модификаторов, а затем отпустите. Вы услышите, какие клавиши заданы. Чтобы выйти, нажмите клавишу табуляции.</translation>
-<translation id="5788275253279308023">Окно с вкладкой <ph name="TITLE" /> в режиме инкогнито.</translation>
-<translation id="5806206155699461681">Расширить функциональность определенных сайтов (например, Google Поиска)</translation>
-<translation id="5819072574982403430">Элемент дерева</translation>
-<translation id="5826479389509458994">Строка <ph name="ROW" />, столбец <ph name="COL" /></translation>
-<translation id="5850707923114094062">Переместить назад</translation>
-<translation id="5851548754964597211">Список вкладок</translation>
-<translation id="5859752971144398932">Виджет поиска закрыт.</translation>
-<translation id="5866042630553435010">Частично отмечено</translation>
-<translation id="5869546221129391014">Сетка</translation>
-<translation id="5876817486144482042">Уменьшить громкость речи</translation>
-<translation id="5887397643266327462">Титры шрифтом Брайля включены.</translation>
-<translation id="5891934789323004067">Таблица.</translation>
-<translation id="5919442531159595654">Копировать.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{знак равенства}one{# знак равенства}few{# знака равенства}many{# знаков равенства}other{# equal signs}}</translation>
-<translation id="5939518447894949180">Сбросить</translation>
-<translation id="5948123859135882163">Переключение между структурным и семантическим методами интерпретации математических выражений</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Диалоговое окно</translation>
-<translation id="5963413905009737549">Раздел</translation>
-<translation id="5968607524793740041">Показать контекстное меню</translation>
-<translation id="5983179082906765664">Увеличить точность навигации</translation>
-<translation id="5999630716831179808">Голоса</translation>
-<translation id="6000417740266304866">Чтобы сменить 8-точечный шрифт Брайля, выберите вариант из списка ниже.</translation>
-<translation id="6006050241733874051">Форма</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{обратная косая черта}one{# обратная косая черта}few{# обратные косые черты}many{# обратных косых черт}other{# backslashes}}</translation>
-<translation id="6037602951055904232">Перейти вперед</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Конец ячейки.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Пробел</translation>
-<translation id="6142308968191113180">Заголовок четвертого уровня</translation>
-<translation id="6169420925157477918">Изображение с подробным описанием</translation>
-<translation id="6172087735260766220">Невозможно получить доступ к озвучиваемому тексту PDF-документа, защищенного от копирования.</translation>
-<translation id="6186305613600865047">Перейти в конец страницы</translation>
-<translation id="6193330012414963395">AM/PM</translation>
-<translation id="622484624075952240">Вниз</translation>
-<translation id="6236061028292614533">Перейти к следующему заголовку</translation>
-<translation id="6254901459154107917">Перейти к следующей редактируемой области текста</translation>
-<translation id="6259464875943891919">Выход из контейнера <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Перейти к следующему похожему элементу</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Следующего поля со списком нет.</translation>
-<translation id="6307969636681130414">Нажато</translation>
-<translation id="6324551002951139333">Найдена грамматическая ошибка</translation>
-<translation id="6348657800373377022">Поле со списком</translation>
-<translation id="6355910664415701303">Предыдущего пункта списка нет.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Перейти к предыдущему заголовку</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Предыдущего переключателя нет.</translation>
-<translation id="6414968628640960377">Перейти к предыдущему отличающемуся элементу</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{двоеточие}one{# двоеточие}few{# двоеточия}many{# двоеточий}other{# colons}}</translation>
-<translation id="6438968337250688271">Меню "<ph name="NAME" />"</translation>
-<translation id="6444046323172968959">Диалоговое окно оповещения</translation>
-<translation id="6459511626086141404">Обычная раскладка</translation>
-<translation id="6468049171101508116">Перейти к следующей кнопке</translation>
-<translation id="6491972999578897419">Выберите голос из списка ниже</translation>
-<translation id="6508059270146105198">Разместить дисплей Брайля внизу страницы</translation>
-<translation id="6536864053412760904">Токены MathML.</translation>
-<translation id="6550720799683018100">Выберите комбинацию клавиш из списка ниже</translation>
-<translation id="6561818612645211875">Перейти к началу текущей строки</translation>
-<translation id="6587021927234520429">Следующего заголовка четвертого уровня нет.</translation>
-<translation id="6601344353291556895">Озвучивать подробно</translation>
-<translation id="6615602925644411249">Поиск на странице.</translation>
-<translation id="6633350132811819843">Следующей таблицы нет.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Строка состояния</translation>
-<translation id="6659594942844771486">Вкладка</translation>
-<translation id="667999046851023355">Документ</translation>
-<translation id="6697092096875747123">Перейти к предыдущему полю со списком</translation>
-<translation id="6714813999819678458">Перейти к предыдущему заголовку второго уровня</translation>
-<translation id="6716505898850596801">Клавиши-модификаторы</translation>
-<translation id="671916444866103745">Следующего ориентира ARIA нет.</translation>
-<translation id="6734854816611871228">Поле со списком, <ph name="VALUE" /></translation>
-<translation id="6735257939857578167">элементов: <ph name="NUM" /></translation>
-<translation id="6736510033526053669">Открыта новая вкладка.</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Статья</translation>
-<translation id="6787839852456839824">Быстрые клавиши</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Нижний колонтитул.</translation>
-<translation id="6871161210040114857">Без учета регистра.</translation>
-<translation id="6877435256196695200">Следующей диаграммы нет.</translation>
-<translation id="6897341342232909480">Переместить влево</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Удалено</translation>
-<translation id="6911965441508464308">Предыдущей строки нет.</translation>
-<translation id="6919104639734799681">Показать список таблиц</translation>
-<translation id="6964088412282673743">Предыдущего элемента управления нет.</translation>
-<translation id="6996566555547746822">Перейти к следующему полю со списком</translation>
-<translation id="7005146664810010831">URL не найден.</translation>
-<translation id="7010712454773919705">Клавиши-модификаторы ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Перейти к предыдущему списку</translation>
-<translation id="7041173719775863268">Выделение завершено.</translation>
-<translation id="7095834689119144465">Изменение текста: только цифры</translation>
-<translation id="7096001299300236431">Перейти к предыдущему файлу мультимедиа</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">Озвучивание слов.</translation>
-<translation id="713824876195128146">Перейти к следующей цитате</translation>
-<translation id="7161771961008409533">Кнопка-переключатель</translation>
-<translation id="7167657087543110">Озвучивание символов.</translation>
-<translation id="7170733337935166589">Перейти вперед во время непрерывного чтения</translation>
-<translation id="7181697990050180700">Ниже укажите быстрые клавиши для часто используемых команд.</translation>
-<translation id="7203150201908454328">Развернуто</translation>
-<translation id="7210211103303402262">минуты</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">Линия.</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Заголовок</translation>
-<translation id="7241683698754534149">Открыть подробное описание в новой вкладке</translation>
-<translation id="7248671827512403053">Приложение</translation>
-<translation id="725969808843520477">Перейти к следующему переключателю</translation>
-<translation id="7269119382257320590">Без знаков препинания.</translation>
-<translation id="7273174640290488576">Пусто</translation>
-<translation id="7285387653379749618">Таблицы</translation>
-<translation id="7289186959554153431">Заголовок третьего уровня.</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Титры шрифтом Брайля отключены.</translation>
-<translation id="7318872822751139669">Выделять элемент, на который наведен указатель мыши</translation>
-<translation id="7322388933135261569">февраль</translation>
-<translation id="7332592614823088566">Строка <ph name="ROWINDEX" /> из <ph name="ROWTOTAL" />, столбец <ph name="COLINDEX" /> из <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">has popup</translation>
-<translation id="7356165926712028380">Переключиться на 8-точечный шрифт</translation>
-<translation id="7362871137496673139">Предыдущего заголовка второго уровня нет.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{амперсанд}one{# амперсанд}few{# амперсанда}many{# амперсандов}other{# ampersands}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Выход из таблицы.</translation>
-<translation id="739763518212184081">Перейти к предыдущей строке</translation>
-<translation id="7400575256015741911">Найдена орфографическая ошибка</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">Перенос строки.</translation>
-<translation id="7434509671034404296">Разработчикам</translation>
-<translation id="7439060726180460871">Каталог</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Открыто диалоговое окно.</translation>
-<translation id="7532613204005497612">июнь</translation>
-<translation id="7540083713905917247">Ползунок "<ph name="NAME" />" со значением "<ph name="VALUE" />"</translation>
-<translation id="7586163296341959563">Вставить.</translation>
-<translation id="7596919493010894443">Отмена выбора.</translation>
-<translation id="7604026522577407655">Перейти к началу текущего столбца</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Назвать URL текущей страницы</translation>
-<translation id="7609363189280667021">Включить/выключить титры шрифтом Брайля</translation>
-<translation id="762020119231868829">Приостановить воспроизведение в виджетах мультимедиа</translation>
-<translation id="7625690649919402823">Перейти к следующей таблице</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), уровень <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Предыдущего заголовка третьего уровня нет.</translation>
-<translation id="7659376057562985921">Текстовое поле <ph name="NAME" /> со значением <ph name="VALUE" /></translation>
-<translation id="7663318257180412551">Заголовок второго уровня.</translation>
-<translation id="7674576868851035240">Перейти к следующей ссылке</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">Редактирование текста, URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Перейти к предыдущему переключателю</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748">Поле для ввода пароля "<ph name="NAME" />" со значением "<ph name="VALUE" />"</translation>
-<translation id="7805247615045262757">навигация по умолчанию</translation>
-<translation id="7805768142964895445">Состояние</translation>
-<translation id="7810781339813764006">Перейти к следующей группе</translation>
-<translation id="7819187121850078213">Окно с вкладкой <ph name="TITLE" />.</translation>
-<translation id="7828956995407538686">октябрь</translation>
-<translation id="7839679365527550018">К предыдущему слову</translation>
-<translation id="7851816175263618915">Некоторые знаки препинания.</translation>
-<translation id="7870596830398826354">Дерево Math ML.</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Включить или отключить ChromeVox Classic.</translation>
-<translation id="7895896691902835279">Неизвестная ссылка</translation>
-<translation id="7927711904086083099">Не выбрано</translation>
-<translation id="7935627501098484003">Выбор времени</translation>
-<translation id="7939428177581522200">Добавлено к выделенному фрагменту.</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{коммерческое "эт"}one{# коммерческое "эт"}few{# коммерческих "эт"}many{# коммерческих "эт"}other{# at signs}}</translation>
-<translation id="7965147473449754028">меню закрыто</translation>
-<translation id="7974390230414479278">Элемент меню</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{восклицательный знак}one{# восклицательный знак}few{# восклицательных знака}many{# восклицательных знаков}other{# exclamation points}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{кавычка}one{# кавычка}few{# кавычки}many{# кавычек}other{# quotes}}</translation>
-<translation id="8033827949643255796">Выделено.</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">Редактирование текста, поисковый запрос</translation>
-<translation id="8049189770492311300">Таймер</translation>
-<translation id="8065607967589909823">Выбранный фрагмент.</translation>
-<translation id="8066678206530322333">Баннер</translation>
-<translation id="8110647606445335195">Ориентиров ARIA нет.</translation>
-<translation id="8153880621934657047">Ошибка. Перейдите в таблицу.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{символ подчеркивания}one{# символ подчеркивания}few{# символа подчеркивания}many{# символов подчеркивания}other{# underscores}}</translation>
-<translation id="8179976553408161302">ВВОД</translation>
-<translation id="81960742267269908">Вырезать.</translation>
-<translation id="8199231515320852133">Назвать заголовки текущей ячейки</translation>
-<translation id="820417203470636242">Пустая ячейка.</translation>
-<translation id="8215202828671303819">Множественный выбор</translation>
-<translation id="8276439074553447000">Перейти к предыдущему активируемому элементу</translation>
-<translation id="8278417001922463147">Предыдущей статьи нет.</translation>
-<translation id="8283603667300770666">Перейти к следующему полю формы</translation>
-<translation id="831207808878314375">Определение</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">час.</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{решетка}one{# решетка}few{# решетки}many{# решеток}other{# pound signs}}</translation>
-<translation id="8374154622594089836">month</translation>
-<translation id="8378855320830505539">Регион</translation>
-<translation id="8382679411218029383">Строка и список автозаполнения</translation>
-<translation id="8428603554127842284">Уровень <ph name="DEPTH" />.</translation>
-<translation id="842922884199979200">Следующего заголовка третьего уровня нет.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Предыдущего флажка нет.</translation>
-<translation id="8455868257606149352">Максимум <ph name="X" />.</translation>
-<translation id="84575901236241018">имеет ключ доступа <ph name="KEY" />.</translation>
-<translation id="8503360654911991865">Уменьшить точность навигации</translation>
-<translation id="8520472399088452386">Счетчик</translation>
-<translation id="8538744478902126321">Определить тип данных в заголовке строки текущей ячейки</translation>
-<translation id="8540054775867439484">Смещение вверх</translation>
-<translation id="8548973727659841685">Символ.</translation>
-<translation id="8561322612995434619">вызывает всплывающее окно.</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Перейти к следующему пункту списка</translation>
-<translation id="860150890330522909">Флажок "<ph name="NAME" />", установлен</translation>
-<translation id="8606621670302093223">Выбор даты</translation>
-<translation id="8631359288236106450">Выбрано: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Назвать координаты текущей ячейки</translation>
-<translation id="8650576015643545550">Предыдущего списка нет.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Показать список ссылок</translation>
-<translation id="8664519043722036194">сек.</translation>
-<translation id="867187640362843212">Заголовок пятого уровня.</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{вертикальная черта}one{# вертикальная черта}few{# вертикальные черты}many{# вертикальных черт}other{# vertical pipes}}</translation>
-<translation id="8735450637152821465">Выделение начато.</translation>
-<translation id="8743786158317878347">Ввести структурированное содержание, например таблицу</translation>
-<translation id="8747966237988593539">Нумерованный список.</translation>
-<translation id="8759334257841767240">Следующей ссылки нет.</translation>
-<translation id="8767968232364267681">Перейти к следующему заголовку четвертого уровня</translation>
-<translation id="8770473310765924354">Закончить ввод структурированного содержания, например таблицы</translation>
-<translation id="8791025954632646584">Семантический метод включен.</translation>
-<translation id="8796411681063377102">Перейти к следующему заголовку третьего уровня</translation>
-<translation id="8808582214901541005">март</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">С помощью стрелок вверх и вниз выберите команду. Чтобы активировать ее, нажмите клавишу ВВОД.</translation>
-<translation id="8864099967139188018">Следующего заголовка шестого уровня нет.</translation>
-<translation id="8882002077197914455">Заголовок строки</translation>
-<translation id="8896347895970027998">Включить или отключить ChromeVox.</translation>
-<translation id="8898516272131543774">Повторно озвучивать пунктуацию</translation>
-<translation id="8900148057318340779">Клавиша-префикс</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Заголовков нет</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Клавиши-модификаторы</translation>
-<translation id="8943175951035496220">Ячейки справа нет.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Таблиц нет.</translation>
-<translation id="9040132695316389094">Заголовок первого уровня</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Переключить виджет поиска</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">Удалено из выбранного фрагмента.</translation>
-<translation id="9082874451376019682">Предыдущего ползунка нет.</translation>
-<translation id="9089864840575085222">Повторно озвучивать вводимый текст</translation>
-<translation id="9107530006868467849">Предыдущего виджета мультимедиа нет.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{знак процента}one{# знак процента}few{# знака процента}many{# знаков процента}other{# percent signs}}</translation>
-<translation id="9115913704608474258">ноябрь</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Озвучить краткое описание текущего элемента</translation>
-<translation id="9153606228985488238">Высота звука: <ph name="PERCENT" />%</translation>
-<translation id="9160096769946561184">Перейти к концу текущего столбца</translation>
-<translation id="9173115498289768110">Громкость: <ph name="PERCENT" />%</translation>
-<translation id="9178973770513562274">Перемещайтесь по списку с помощью стрелок вверх и вниз или введите поисковый запрос.</translation>
-<translation id="9192904702577636854">Бегущая строка</translation>
-<translation id="9212322457209634662">Следующего раздела нет.</translation>
-<translation id="930275611743429116">Начать или завершить выделение</translation>
-<translation id="948171205378458592">Замедлить речь</translation>
-<translation id="962913030769097253">Перейти к следующему заголовку первого уровня</translation>
-<translation id="973955474346881951">Включить или выключить режим залипания</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sk.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sk.xtb
deleted file mode 100644
index c429621e433..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sk.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="sk">
-<translation id="1012173283529841972">Položka zoznamu</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Rozšírené</translation>
-<translation id="1025074108959230262">Rýchly režim bol zakázaný</translation>
-<translation id="1031961866430398710">a potom</translation>
-<translation id="1044777062731150180">Žiadne hlavičky</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Neplatný vstup</translation>
-<translation id="1082209053475788238">Žiadny predchádzajúci nadpis 6. úrovne</translation>
-<translation id="1088219014394087294">Žiadne nadpisy</translation>
-<translation id="1106741348836243114">Zapnúť alebo vypnúť zvukovú spätnú väzbu (zvukové signály</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Počet položiek v zbierke <ph name="TAG" />: <ph name="NUM" /></translation>
-<translation id="1155043339247954670">Žiadna ďalšia položka zoznamu</translation>
-<translation id="1157782847298808853">Pomocník pre klávesnicu</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, rozbaľovacie pole</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, položka ponuky s podponukou</translation>
-<translation id="1177863135347784049">Vlastné</translation>
-<translation id="1188858454923323853">doplnkové</translation>
-<translation id="1206619573307042055">pohyblivý prvok</translation>
-<translation id="1213216066620407844">ChromeVox – hlas prehliadača Chrome</translation>
-<translation id="1229276918471378188">Predchádzajúci skok</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Ďalší nadpis 6. úrovne</translation>
-<translation id="1275718070701477396">Vybraté</translation>
-<translation id="1319608975892113573">Žiadny predchádzajúci prvok blockquote</translation>
-<translation id="1321576897702511272">Skryť pomocníka rozšírenia ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> z <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">zvuková odozva na znaky a slová</translation>
-<translation id="1339428534620983148">Predchádzajúci stĺpec tabuľky</translation>
-<translation id="1342835525016946179">článok</translation>
-<translation id="1346748346194534595">Doprava</translation>
-<translation id="136718599399906424">Ďalší riadok tabuľky</translation>
-<translation id="1383876407941801731">Vyhľadávanie</translation>
-<translation id="1385214448885562192">Klávesom Enter položku prijmete, klávesom Escape zrušíte akciu, šípkou dole prejdete na ďalšiu položku a šípkou hore na predchádzajúcu položku.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">oblasť</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, textové pole pre heslo</translation>
-<translation id="1467432559032391204">Doľava</translation>
-<translation id="1474557363159888097">Žiadne predchádzajúce ukotvenie</translation>
-<translation id="1502086903961450562">Predchádzajúci obrázok</translation>
-<translation id="1506187449813838456">Zvýšiť výšku hlasu</translation>
-<translation id="151784044608172266">Ďalšia veta</translation>
-<translation id="1524531499102321782">Braille – ďalší riadok</translation>
-<translation id="1546370775711804143">Panel posúvania</translation>
-<translation id="1559739829547075274">Prejsť späť</translation>
-<translation id="1571643229714746283">Služba ChromeVox je pripravená</translation>
-<translation id="158493514907962286">december</translation>
-<translation id="1594072653727561613">ponuka</translation>
-<translation id="1610130962244179598">Prepnúť na šesťbodové Braillovo písmo</translation>
-<translation id="1611168825862729585">Hlavička stĺpca:</translation>
-<translation id="1613476421962910979">Zvukové signály sú zapnuté</translation>
-<translation id="1618597272655350600">Oznamuje úplný popis aktuálnej pozície</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{znak je väčšie ako}few{# znaky je väčšie ako}many{# greater than signs}other{# znakov je väčšie ako}}</translation>
-<translation id="1653266918374749391">Predchádzajúci nadpis 3. úrovne</translation>
-<translation id="1659072772017912254">Nezačiarknuté</translation>
-<translation id="1669290819662866522">týždeň</translation>
-<translation id="1674262202423278359">Navigácia rozšírenia ChromeVox</translation>
-<translation id="16777221443363124">Panel ponuky</translation>
-<translation id="1692077714702418899">riadok štruktúry</translation>
-<translation id="1700517974991662022">Navštívené</translation>
-<translation id="1722567105086139392">Odkaz</translation>
-<translation id="1727806147743597030">päta</translation>
-<translation id="174268867904053074">Ďalší obrázok</translation>
-<translation id="1781173782405573156">Preskočiť kláves</translation>
-<translation id="1787176709638001873">Text úpravy hesla</translation>
-<translation id="1810107444790159527">Pole s ponukou</translation>
-<translation id="1828385960365606039">máj</translation>
-<translation id="1834891354138622109">Stĺpec</translation>
-<translation id="1865601187525349519">Koniec textu</translation>
-<translation id="1876229593313240038">dokument</translation>
-<translation id="188130072164734898">Prečítať nahlas aktuálny čas a dátum</translation>
-<translation id="1902396333223336119">Bunka</translation>
-<translation id="1905379170753160525">Zobraziť zoznam nadpisov</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Ovládací prvok Týždeň roka</translation>
-<translation id="1964135212174907577">Ďalší objekt</translation>
-<translation id="1969092762068865084">júl</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Hlavička riadka:</translation>
-<translation id="2002895034995108595">Obnoviť aktuálnu mapu klávesov</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{ľavá hranatá zátvorka}few{# ľavé hranaté zátvorky}many{# left brackets}other{# ľavých hranatých zátvoriek}}</translation>
-<translation id="2045490512405922022">nezačiarknuté</translation>
-<translation id="20601713649439366">Žiadny predchádzajúci matematický výraz</translation>
-<translation id="207477615537953741">Sémantika je vypnutá</translation>
-<translation id="2086961585857038472">Ďalšie slovo</translation>
-<translation id="2089387485033699258">sk</translation>
-<translation id="2091933974477985526">Predchádzajúca upraviteľná textová oblasť</translation>
-<translation id="2100350898815792233">Úplná interpunkcia</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">prístupový kľúč:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Zmeniť aktuálnu tabuľku šesťbodového Braillovho písma na možnosť zo zoznamu uvedeného nižšie.</translation>
-<translation id="2169714232367507776">Kliknúť na aktuálnu položku</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{pravá zátvorka}few{# pravé zátvorky}many{# close parens}other{# pravých zátvoriek}}</translation>
-<translation id="2199994615414171367">Predchádzajúci matematický výraz</translation>
-<translation id="2223693656926968778">Prejsť na aktuálnu položku</translation>
-<translation id="225732394367814946">Zvýšiť rýchlosť reči</translation>
-<translation id="2267945578749931355">Ďalší znak</translation>
-<translation id="2281234842553884450">Predchádzajúci posúvač</translation>
-<translation id="2318372665160196757">Hlavné</translation>
-<translation id="2329324941084714723">Panel karty</translation>
-<translation id="2344193891939537199">Ovládanie dátumu a času</translation>
-<translation id="2359897517538099099">Nie ste v režime tabuľky.</translation>
-<translation id="241124561063364910">a potom zadajte</translation>
-<translation id="2417569100218200841">Informácie o obsahu</translation>
-<translation id="2422937916923936891">Začiarkavacie políčko položky ponuky</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">Kláves <ph name="KEY" /> je teraz nový modifikátor služby ChromeVox.</translation>
-<translation id="2450814015951372393">Začiarkavacie políčko</translation>
-<translation id="2462626033734746142">Skupina prepínačov</translation>
-<translation id="2471138580042810658">Nadpis 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{hviezdička}few{# hviezdičky}many{# asterisks}other{# hviezdičiek}}</translation>
-<translation id="2549392850788122959">Kláves <ph name="KEY" /> bol obnovený</translation>
-<translation id="2553108862507765288">gramatická chyba</translation>
-<translation id="257674075312929031">Skupina</translation>
-<translation id="2582407057977008361">Vedľa</translation>
-<translation id="2589102159832527089">Táto stránka obsahuje text, ktorý bol automaticky extrahovaný zo súboru PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Ak chcete zobraziť pôvodný súbor, kliknite tu.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">s {COUNT,plural, =1{# položkou}few{# položkami}many{# položkami}other{# položkami}}</translation>
-<translation id="2614981083756825552">Rozloženie jazyka Math ML</translation>
-<translation id="2626530649491650971">kliknuteľné</translation>
-<translation id="2628764385451019380">Žiadne predchádzajúce rozbaľovacie pole</translation>
-<translation id="2637227747952042642">Matematika</translation>
-<translation id="2639750663247012216">Modifikátor služby ChromeVox</translation>
-<translation id="2644542693584024604">preklep</translation>
-<translation id="2667291555398229137">Kliknite na položku pod navigačným klávesom</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{ľavá zátvorka}few{# ľavé zátvorky}many{# open parens}other{# ľavých zátvoriek}}</translation>
-<translation id="2705875883745373140">Nestlačené</translation>
-<translation id="2706462751667573066">Hore</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">zvuk</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Začiarknuté</translation>
-<translation id="27527859628328957">Prejsť na ďalšiu zamerateľnú položku</translation>
-<translation id="2770781857296573485">Vstúpiť do režimu preskúmavania skupín</translation>
-<translation id="2777845298774924149">Ukončené</translation>
-<translation id="2800204403141299078">Žiadne ďalšie odlišné prvky</translation>
-<translation id="2800780099804980316">Žiadny predchádzajúci nadpis 1. úrovne</translation>
-<translation id="2811204574343810641">Riadok</translation>
-<translation id="2816654101880605877">Žiadny ďalší posúvač</translation>
-<translation id="2841013758207633010">Čas</translation>
-<translation id="2843837985843789981">Predchádzajúca skupina</translation>
-<translation id="2844995807198708617">Kontextová ponuka</translation>
-<translation id="2849332794118375855">Žiadne ďalšie začiarkavacie políčko</translation>
-<translation id="2864481629947106776">Predchádzajúci odkaz</translation>
-<translation id="2873259058405069099">Prejsť na začiatok tabuľky</translation>
-<translation id="2894654529758326923">Informácie</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{ľavá zložená zátvorka}few{# ľavé zložené zátvorky}many{# left braces}other{# ľavých zložených zátvoriek}}</translation>
-<translation id="2911433807131383493">Otvoriť príručku rozšírenia ChromeVox</translation>
-<translation id="2932083475399492303">Prepnúť typ riadku medzi riadkom štruktúry a rozloženia</translation>
-<translation id="2964026537669811554">Skupina nadpisov</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulátor}few{# tabulátory}many{# tabs}other{# tabulátorov}}</translation>
-<translation id="2972078295414139404">Žiadny predchádzajúci navštívený odkaz</translation>
-<translation id="2972205263822847197">Popis</translation>
-<translation id="2998131015536248178">Predchádzajúci znak</translation>
-<translation id="2999559350546931576">Znížiť výšku hlasu</translation>
-<translation id="2999945368667127852">Žiadna ďalšia miniaplikácia pre médiá</translation>
-<translation id="3012414509011670858">Žiadna predchádzajúca sekcia</translation>
-<translation id="3030432017085518523">Prepínač položky ponuky</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}few{# apostrofy}many{# apostrophes}other{# apostrofov}}</translation>
-<translation id="3046838483509668188">Možnosti rozšírenia ChromeVox</translation>
-<translation id="3047143736589213134">Experimentálna mapa klávesov</translation>
-<translation id="3060756054951570867">otvorila sa ponuka <ph name="TITLE" /></translation>
-<translation id="3078345202707391975">Ďalší nadpis 2. úrovne</translation>
-<translation id="3078740164268491126">tabuľka</translation>
-<translation id="3082557070674409251">Kliknuté</translation>
-<translation id="3084806535845658316">bez zvukovej odozvy na zadávanie textu</translation>
-<translation id="3086746722712840547">poznámka</translation>
-<translation id="308895241372589742">Žiadny nasledujúci matematický výraz</translation>
-<translation id="3090532668523289635">skupina</translation>
-<translation id="3093176084511590672">Ďalší orientačný bod</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">dialóg s upozornením</translation>
-<translation id="3109724472072898302">Zbalené</translation>
-<translation id="3134461040845705080">iba na čítanie</translation>
-<translation id="3138767756593758860">Zobraziť zoznam orientačných bodov</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Ďalší riadok</translation>
-<translation id="3155083529632865074">Žiadne predchádzajúce tlačidlo</translation>
-<translation id="3163593631834463955">Prázdna hlavička stĺpca</translation>
-<translation id="316542773973815724">Navigácia</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{medzera}few{# medzery}many{# spaces}other{# medzier}}</translation>
-<translation id="320961988183078793">zadané: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, karta</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Navštívený odkaz</translation>
-<translation id="323731244387692321">Otvoriť pomocníka pre klávesnicu rozšírenia ChromeVox</translation>
-<translation id="3241052487511142956">Predchádzajúci navštívený odkaz</translation>
-<translation id="3286390186030710347">Posuvník</translation>
-<translation id="3299925995433437805">Žiadny ďalší navštívený odkaz</translation>
-<translation id="3303384412438961941">Po stlačení ľubovoľného klávesa sa dozviete jeho názov. Kombináciou klávesov Ctrl+W prieskumníka klávesnice ukončíte.</translation>
-<translation id="3307886118343381874">Prejsť na koniec tabuľky</translation>
-<translation id="3311969765485641742">Ak chcete upozornenia skontrolovať, stlačte klávesy Alt+Shift+A</translation>
-<translation id="3312997241656799641">Ďalší navštívený odkaz</translation>
-<translation id="3321460131042519426">Povoliť zalamovanie slov</translation>
-<translation id="3322936298410871309">Predchádzajúci nadpis 1. úrovne</translation>
-<translation id="3323447499041942178">Textové pole</translation>
-<translation id="3353420241558113817">{"ar": "arabčina",
- "bg": "bulharčina",
- "ca": "katalánčina",
- "cs": "čeština",
- "da": "dánčina",
- "de": "nemčina",
- "de_CH": "nemčina (Švajčiarsko)",
- "de_DE": "nemčina (Nemecko)",
- "el": "gréčtina",
- "en": "angličtina",
- "en_CA": "angličtina (Kanada)",
- "en_GB": "angličtina (Spojené kráľovstvo)",
- "en_US": "angličtina (Spojené štáty)",
- "es": "španielčina",
- "et": "estónčina",
- "fr": "francúzština",
- "fr_CA": "francúzština (Kanada)",
- "fr_FR": "francúzština (Francúzsko)",
- "fi": "fínčina",
- "he": "hebrejčina",
- "hi": "hindčina",
- "hr": "chorvátčina",
- "hu": "maďarčina",
- "is": "islandčina",
- "it": "taliančina",
- "ko": "kórejčina",
- "lt": "litovčina",
- "lv": "lotyština",
- "nb": "nórčina bokmål",
- "nl": "holandčina",
- "pl": "poľština",
- "pt": "portugalčina",
- "ro": "rumunčina",
- "ru": "ruština",
- "sk": "slovenčina",
- "sl": "slovinčina",
- "sr": "srbčina",
- "sv": "švédčina",
- "tr": "turečtina",
- "vi": "vietnamčina",
- "zh": "čínština",
- "zh_TW": "čínština (tradičná)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{znak plus}few{# znaky plus}many{# plus signs}other{# znakov plus}}</translation>
-<translation id="338583716107319301">Oddeľovač</translation>
-<translation id="3389259863310851658">Predchádzajúce pole formulára</translation>
-<translation id="3390225400784126843">Ďalší odlišný prvok</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, položka ponuky</translation>
-<translation id="3406283310380167331">Zobraziť zoznam formulárov</translation>
-<translation id="3422338090358345848">Otvoriť prieskumníka klávesnice</translation>
-<translation id="3457000393508828486">Čiastočne stlačené</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, tlačidlo</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> až <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{pravá hranatá zátvorka}few{# pravé hranaté zátvorky}many{# right brackets}other{# pravých hranatých zátvoriek}}</translation>
-<translation id="3493915602752813531">Žiadne ďalšie ukotvenie</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{otáznik}few{# otázniky}many{# question marks}other{# otáznikov}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{vsuvka}few{# vsuvky}many{# carets}other{# vsuviek}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, začiarkavacie políčko nie je začiarknuté</translation>
-<translation id="3599054940393788245">Nejde o matematiku</translation>
-<translation id="3616113530831147358">Zvuk</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{obrátený dĺžeň}few{# obrátené dĺžne}many{# backticks}other{# obrátených dĺžňov}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolár}few{# znaky dolára}many{# dollar signs}other{# znakov dolára}}</translation>
-<translation id="3659787053479271466">upozornenie</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, pole zoznamu</translation>
-<translation id="3687295507293856493">Vykonať odhad v hlavičke stĺpca aktuálnej bunky</translation>
-<translation id="3692274950075847560">V:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Ovládanie reči</translation>
-<translation id="3716845769494773620">Viac riadkov</translation>
-<translation id="3731746171184829332">Žiadny predchádzajúci nadpis</translation>
-<translation id="3762198587642264450">Prejsť na koniec aktuálneho riadka</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Ukončili ste dialógové okno</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}few{#}many{#}other{#}}</translation>
-<translation id="3801735343383419236">Zoznam automatického dopĺňania</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Ďalšie médiá</translation>
-<translation id="3819376190738087562">Žiadne preskočenia</translation>
-<translation id="385383972552776628">Otvoriť stránku možností</translation>
-<translation id="3856075812838139784">Iba na čítanie</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Ponuka</translation>
-<translation id="3909320334364316587">Predchádzajúca hlavička 6. úrovne</translation>
-<translation id="3914173277599553213">Povinné</translation>
-<translation id="3962990492275676168">Začať čítať z aktuálneho miesta</translation>
-<translation id="4004802134384979325">začiarknuté</translation>
-<translation id="4006140876663370126">obrázok</translation>
-<translation id="4038349100599457191">Ovládací prvok Mesiac</translation>
-<translation id="4039983576244166038">Prázdna hlavička riadka</translation>
-<translation id="4042843249978639960">Žiadny ďalší nadpis 2. úrovne</translation>
-<translation id="4043348641337972076">Žiadny predchádzajúci orientačný bod ARIA</translation>
-<translation id="4047216625641135770">Značka</translation>
-<translation id="404803211695627272"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="4054936709456751127">stav</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{VLNOVKA}few{# vlnovky}many{# tildes}other{# vlnoviek}}</translation>
-<translation id="409334809956508737">Predchádzajúci objekt</translation>
-<translation id="4099274309791143834">s podponukou</translation>
-<translation id="4107807507418787238">Nižšie nie je žiadna bunka</translation>
-<translation id="4116415223832267137">Upozornenie</translation>
-<translation id="4147126331795725888">Žiadny nasledujúci ovládací prvok</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{pravá zložená zátvorka}few{# pravé zložené zátvorky}many{# right braces}other{# pravých zložených zátvoriek}}</translation>
-<translation id="4158704014418536539">Rozlišujú sa malé a veľké písmená.</translation>
-<translation id="4161663686871496107">Hovorená spätná väzba ChromeVox je pripravená</translation>
-<translation id="4173994908659439270">Žiadne ďalšie upraviteľné textové pole</translation>
-<translation id="4176463684765177261">Zakázané</translation>
-<translation id="4188530942454211480">Predchádzajúca veta</translation>
-<translation id="4202186506458631436">Posunúť doprava</translation>
-<translation id="4206289001967551965">V tabuľke</translation>
-<translation id="4215733775853809057">Ďalší posúvač</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{pomlčka}few{# pomlčky}many{# dashes}other{# pomlčiek}}</translation>
-<translation id="421884353938374759">výber farieb</translation>
-<translation id="4229646983878045487">dátum a čas</translation>
-<translation id="423334822609210999">Vľavo nie je žiadna bunka</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, stupeň <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Poznámka</translation>
-<translation id="4254798249533888099">Strom</translation>
-<translation id="4255943572433203166">Pomocou možností nižšie si môžete prispôsobiť rozšírenie ChromeVox. Zmeny sa prejavia okamžite.</translation>
-<translation id="4271220233568730077">Ďalší matematický výraz</translation>
-<translation id="4271521365602459209">Žiadne ďalšie výsledky</translation>
-<translation id="4287520460805643128">Žiadny ďalší článok</translation>
-<translation id="4289540628985791613">Prehľad</translation>
-<translation id="4300318234632215983">Oznámiť webovú adresu za odkazom</translation>
-<translation id="4301352596632316575">má podponuku</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{bodka}=3{výpustka}few{# bodky}many{# dots}other{# bodiek}}</translation>
-<translation id="4347461890115250064">Žiadny ďalší zoznam</translation>
-<translation id="4367650418938037324">List jazyka Math ML</translation>
-<translation id="4372435075475052704">min:<ph name="X" /></translation>
-<translation id="4372705107434148843">Zastaviť reč</translation>
-<translation id="4373197658375206385">Žiadna predchádzajúca položka, ktorá nie je odkazom</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">obnovenie</translation>
-<translation id="4471074325120394300">Žiadne odkazy</translation>
-<translation id="4476183483923481720">nový riadok</translation>
-<translation id="4482330759234983253">Predchádzajúca tabuľka</translation>
-<translation id="4491109536499578614">Obrázok</translation>
-<translation id="4529987814483543472">Klasická klávesová mapa</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{lomka}few{# lomky}many{# slashes}other{# lomiek}}</translation>
-<translation id="4547556996012970016">Ďalší nadpis 5. úrovne</translation>
-<translation id="4562381607973973258">Hlavička</translation>
-<translation id="4591507479202817876">, vybrané</translation>
-<translation id="4597532268155981612">formulár</translation>
-<translation id="4597896406374528575">apríl</translation>
-<translation id="4615592953348396470">Ďalšie stlačenie klávesa bude ignorované</translation>
-<translation id="461613135510474570">Veta</translation>
-<translation id="4647836961514597010">Výber farieb</translation>
-<translation id="4661075872484491155">strom</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">mriežka</translation>
-<translation id="4693675773662933727">Prechádzajúci orientačný bod</translation>
-<translation id="4696413482802371445">Žiadny ďalší nadpis 5. úrovne</translation>
-<translation id="4729095194763193578">Predchádzajúci riadok tabuľky</translation>
-<translation id="4736221692378411923">august</translation>
-<translation id="4740661827607246557">Príkazy pomocníka</translation>
-<translation id="4759716709594980008">Prieskumník klávesnice systému OS Chrome</translation>
-<translation id="4763296182459741068">Skok na koniec</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Oznámiť názov aktuálnej stránky</translation>
-<translation id="4826415162591436065">Prejsť dopredu</translation>
-<translation id="4826604887384865800">Ďalší skok</translation>
-<translation id="4827410568042294688">nevybrané</translation>
-<translation id="4842108708071771135">Žiadny ďalší prvok blockquote</translation>
-<translation id="4848993367330139335">časovač</translation>
-<translation id="4850023505158945298">Predchádzajúci podobný prvok</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Povoliť zapisovanie do denníka TTS</translation>
-<translation id="4877261390094455813">Zadajte vyhľadávací dopyt</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Interný odkaz</translation>
-<translation id="4953585991029886728">Upraviť text</translation>
-<translation id="4954534434583049121">Predchádzajúci blok citácie</translation>
-<translation id="4973717656530883744">Min. <ph name="X" /></translation>
-<translation id="4973762002207131920">Prepnuté na kláves <ph name="KEY" /></translation>
-<translation id="4975416682604111799">milisekundy</translation>
-<translation id="49787999531187221">Rozšírenie ChromeVox je teraz neaktívne</translation>
-<translation id="4979404613699303341">Predchádzajúce tlačidlo</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, pole zoznamu</translation>
-<translation id="4983588134362688868">Prechod do hornej časti stránky</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, okno</translation>
-<translation id="4993152509206108683">Hodnotenie: <ph name="PERCENT" /> %</translation>
-<translation id="4996716799442435517">Vizuálne</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, prepínač bol vybraný</translation>
-<translation id="4997475792277222884">Žiadna ďalšia položka, ktorá nie je odkazom</translation>
-<translation id="5000760171916499057">Žiadne formuláre</translation>
-<translation id="5005670136041063723">Žiadne ďalšie podobné prvky</translation>
-<translation id="501473567976723023">január</translation>
-<translation id="5041394372352067729">Presunúť zobrazenie Braillovho písma do hornej časti stránky</translation>
-<translation id="5042770794184672516">Zvýšiť hlasitosť reči</translation>
-<translation id="5050015258024679800">Predchádzajúci nadpis 4. úrovne</translation>
-<translation id="5054047268577924192">Predchádzajúca položka v zozname</translation>
-<translation id="5078661581131202757">Výber súboru</translation>
-<translation id="5080758118274074384">dvakrát kliknuté</translation>
-<translation id="5098541983634824365">Opúšťate mriežku</translation>
-<translation id="5102981729317424850">Panel s nástrojmi</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Žiadne predchádzajúce pole formulára</translation>
-<translation id="5111640677200759579">Hlavička stĺpca</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Žiadny predchádzajúci odkaz</translation>
-<translation id="513774504516943387">odkaz</translation>
-<translation id="517143700877085897">, nevybrané</translation>
-<translation id="5183440668879371625">Braille – predchádzajúci riadok</translation>
-<translation id="5184944171021383281">Žiadne ďalšie pole formulára</translation>
-<translation id="5189244881767082992">Riadok</translation>
-<translation id="5203930734796605961">Kláves <ph name="KEY" /> je už k príkazu priradený</translation>
-<translation id="5205493599117157272">Zoznam <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Žiadny ďalší prepínač</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objekt</translation>
-<translation id="5304943142864553931">karta <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">odstránené:</translation>
-<translation id="5320727453979144100">Rýchly režim bol povolený</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{čiarka}few{# čiarky}many{# commas}other{# čiarok}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, textové pole</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, odkaz</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Prejsť späť počas nepretržitého čítania</translation>
-<translation id="5368000168321181111">Zvukové signály sú vypnuté</translation>
-<translation id="5374320867641260420">Žiadne ďalšie tlačidlo</translation>
-<translation id="5382299583965267720">Žiadny ďalší nadpis 1. úrovne</translation>
-<translation id="5402367795255837559">Braillovo písmo</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{bodkočiarka}few{# bodkočiarky}many{# semicolons}other{# bodkočiarok}}</translation>
-<translation id="5411891038905756502">Žiadny predchádzajúci bod preskočenia</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{znak je menšie ako}few{# znaky je menšie ako}many{# less than signs}other{# znakov je menšie ako}}</translation>
-<translation id="5455441614648621694">Doplnkové</translation>
-<translation id="5485036206801896268">Žiadna predchádzajúca grafika</translation>
-<translation id="5486947920110100234">Žiadny ďalší bod preskočenia</translation>
-<translation id="549602578321198708">Slovo</translation>
-<translation id="5500932716852106146">Žiadne predchádzajúce upraviteľné textové pole</translation>
-<translation id="5502713021410870035">september</translation>
-<translation id="5507663321906818013">Ukazovateľ ladenia</translation>
-<translation id="5518443085409638729">Pri úprave textu umiestnite kurzor medzi znaky (podobne ako v systéme Mac OS X).</translation>
-<translation id="552195134157544755">Prepínač</translation>
-<translation id="5534303576632885660">hlavička</translation>
-<translation id="5546092960038624944">Žiadny predchádzajúci nadpis 5. úrovne</translation>
-<translation id="556042886152191864">Tlačidlo</translation>
-<translation id="5561345396546889625">Ďalší zoznam</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Upraviť text, vstup e-mailovej adresy</translation>
-<translation id="5597170376237141345">Ďalšie začiarkavacie políčko</translation>
-<translation id="5597933780944041114">Žiadny ďalší nadpis</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, prepínač nie je vybraný</translation>
-<translation id="5601172225407283979">Vykonať predvolenú akciu</translation>
-<translation id="5608798115546226984">Vložené automatické dopĺňanie</translation>
-<translation id="561939826962581046">čas</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Denník</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Žiadna predchádzajúca tabuľka</translation>
-<translation id="5655682562155942719">Príkazy na preskočenie</translation>
-<translation id="56637627897541303">Textová oblasť</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">definícia</translation>
-<translation id="5682113568322255809">Orientačný bod</translation>
-<translation id="5683155931978483559">Predchádzajúce začiarkavacie políčko</translation>
-<translation id="5684277895745049190">Zoznam</translation>
-<translation id="5700650669149824506">Žiaden predchádzajúci nadpis 4. úrovne</translation>
-<translation id="5709192780268610569">Žiadny dlhý popis</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Ďalší stĺpec tabuľky</translation>
-<translation id="571866080859340309">Preskúmavanie skupín</translation>
-<translation id="5728409797179002635">Nenašla sa žiadna tabuľka</translation>
-<translation id="5748623122140342504">Predchádzajúci nadpis 5. úrovne</translation>
-<translation id="5750633686117194034">Nestlačili ste žiadny modifikátor. Stlačte a podržte jeden alebo viac modifikátorov. Po dokončení zdvihnite prsty. Ozve sa hlásenie o tom, ktoré klávesy boli nastavené. Klávesom Tab túto akciu ukončíte.</translation>
-<translation id="5788275253279308023">okno inkognito, karta <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Vylepšenie špecifických webových stránok (napríklad Vyhľadávania Google)</translation>
-<translation id="5819072574982403430">Položka stromu</translation>
-<translation id="5826479389509458994">riadok <ph name="ROW" /> stĺpec <ph name="COL" /></translation>
-<translation id="5850707923114094062">Posunúť späť</translation>
-<translation id="5851548754964597211">Zoznam kariet</translation>
-<translation id="5859752971144398932">Vyhľadávanie na stránke bolo ukončené</translation>
-<translation id="5866042630553435010">Čiastočne začiarknuté</translation>
-<translation id="5869546221129391014">Mriežka</translation>
-<translation id="5876817486144482042">Znížiť hlasitosť reči</translation>
-<translation id="5887397643266327462">Titulky v Braillovom písme sú zapnuté</translation>
-<translation id="5891934789323004067">Tabuľka</translation>
-<translation id="5919442531159595654">kopírovať</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{znak rovnosti}few{# znaky rovnosti}many{# equal signs}other{# znakov rovnosti}}</translation>
-<translation id="5939518447894949180">Obnoviť</translation>
-<translation id="5948123859135882163">Prepnúť medzi štrukturálnou a sémantickou interpretáciou matematických výrazov</translation>
-<translation id="5955304353782037793">aplikácia</translation>
-<translation id="5956928062748260866">Dialógové okno</translation>
-<translation id="5963413905009737549">Sekcia</translation>
-<translation id="5968607524793740041">Zobraziť kontextovú ponuku</translation>
-<translation id="5983179082906765664">Zvýšiť podrobnosť navigácie</translation>
-<translation id="5999630716831179808">Hlasy</translation>
-<translation id="6000417740266304866">Zmeniť aktuálnu tabuľku osembodového Braillovho písma na možnosť zo zoznamu uvedeného nižšie.</translation>
-<translation id="6006050241733874051">Formulár</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{opačná lomka}few{# opačné lomky}many{# backslashes}other{# opačných lomiek}}</translation>
-<translation id="6037602951055904232">Posunúť zobrazenie dopredu</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Koniec bunky</translation>
-<translation id="6122013438240733403">tlačidlo</translation>
-<translation id="6129953537138746214">Medzera</translation>
-<translation id="6142308968191113180">Nadpis 4</translation>
-<translation id="6169420925157477918">Obrázok s dlhým popisom</translation>
-<translation id="6172087735260766220">K dostupnému textu nie je možné pristupovať z dokumentu PDF s ochranou proti kopírovaniu.</translation>
-<translation id="6186305613600865047">Prechod do spodnej časti stránky</translation>
-<translation id="6193330012414963395">AM / PM</translation>
-<translation id="622484624075952240">Dole</translation>
-<translation id="6236061028292614533">Ďalší nadpis</translation>
-<translation id="6254901459154107917">Ďalšia upraviteľná textová oblasť</translation>
-<translation id="6259464875943891919">Ukončené <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Ďalší podobný prvok</translation>
-<translation id="6282062888058716985">navigácia</translation>
-<translation id="6290434000785343030">Žiadne ďalšie rozbaľovacie pole</translation>
-<translation id="6307969636681130414">Stlačené</translation>
-<translation id="6324551002951139333">Našla sa gramatická chyba</translation>
-<translation id="6348657800373377022">Pole s výberom</translation>
-<translation id="6355910664415701303">Žiadna predchádzajúca položka zoznamu</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Predchádzajúci nadpis</translation>
-<translation id="6387719785439924554">odsadený text</translation>
-<translation id="6411426777058107714">Žiadny predchádzajúci prepínač</translation>
-<translation id="6414968628640960377">Predchádzajúci odlišný prvok</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dvojbodka}few{# dvojbodky}many{# colons}other{# dvojbodiek}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, ponuka</translation>
-<translation id="6444046323172968959">Dialógové okno s upozornením</translation>
-<translation id="6459511626086141404">Plochá mapa klávesov</translation>
-<translation id="6468049171101508116">Ďalšie tlačidlo</translation>
-<translation id="6491972999578897419">Ak chcete zmeniť aktuálny hlas, vyberte možnosť zo zoznamu nižšie.</translation>
-<translation id="6508059270146105198">Presunúť zobrazenie Braillovho písma do dolnej časti stránky</translation>
-<translation id="6536864053412760904">Token jazyka Math ML</translation>
-<translation id="6550720799683018100">Ak chcete zmeniť aktuálnu klávesovú mapu, vyberte možnosť zo zoznamu nižšie.</translation>
-<translation id="6561818612645211875">Prejsť na začiatok aktuálneho riadka</translation>
-<translation id="6587021927234520429">Žiadny ďalší nadpis 4. úrovne</translation>
-<translation id="6601344353291556895">Povoliť podrobné popisy.</translation>
-<translation id="6615602925644411249">Nájsť na stránke</translation>
-<translation id="6633350132811819843">Žiadna ďalšia tabuľka</translation>
-<translation id="6637586476836377253">denník</translation>
-<translation id="6657128831881431364">Panel priebehu</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Predchádzajúce rozbaľovacie pole</translation>
-<translation id="6714813999819678458">Predchádzajúci nadpis 2. úrovne</translation>
-<translation id="6716505898850596801">Klávesy modifikátora</translation>
-<translation id="671916444866103745">Žiadny ďalší orientačný bod ARIA</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, rozbaľovacie pole</translation>
-<translation id="6735257939857578167">s <ph name="NUM" /> položkami</translation>
-<translation id="6736510033526053669">karta sa vytvorila</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Článok</translation>
-<translation id="6787839852456839824">Klávesové skratky</translation>
-<translation id="6793101435925451627">pole zoznamu</translation>
-<translation id="6833103209700200188">Päta</translation>
-<translation id="6871161210040114857">Malé a veľké písmená sa ignorujú.</translation>
-<translation id="6877435256196695200">Žiadna ďalšia grafika</translation>
-<translation id="6897341342232909480">Posunúť doľava</translation>
-<translation id="6901540140423170855">dátum</translation>
-<translation id="6910211073230771657">Odstránené</translation>
-<translation id="6911965441508464308">Vyššie nie je žiadna bunka</translation>
-<translation id="6919104639734799681">Zobraziť zoznam tabuliek</translation>
-<translation id="6964088412282673743">Žiadny predchádzajúci ovládací prvok</translation>
-<translation id="6996566555547746822">Ďalšie rozbaľovacie pole</translation>
-<translation id="7005146664810010831">Nenašla sa žiadna webová adresa</translation>
-<translation id="7010712454773919705">Kláves modifikátora služby ChromeVox</translation>
-<translation id="7031651751836475482">položka zoznamu</translation>
-<translation id="7037042857287298941">Predchádzajúci zoznam</translation>
-<translation id="7041173719775863268">Ukončiť výber</translation>
-<translation id="7095834689119144465">Úprava iba numerického textu</translation>
-<translation id="7096001299300236431">Predchádzajúce médiá</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">zvuková odozva na slová</translation>
-<translation id="713824876195128146">Ďalší blok citácie</translation>
-<translation id="7161771961008409533">Kontextové tlačidlo</translation>
-<translation id="7167657087543110">zvuková odozva na znaky</translation>
-<translation id="7170733337935166589">Prejsť dopredu počas nepretržitého čítania</translation>
-<translation id="7181697990050180700">Ak chcete prispôsobiť klávesové skratky pre často používané príkazy, zadajte ich do zodpovedajúcich polí nižšie.</translation>
-<translation id="7203150201908454328">Rozbalené</translation>
-<translation id="7210211103303402262">minúty</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">riadok</translation>
-<translation id="7226216518520804442">zoznam</translation>
-<translation id="72393384879519786">Nadpis</translation>
-<translation id="7241683698754534149">Otvoriť dlhý popis na novej karte</translation>
-<translation id="7248671827512403053">Aplikácia</translation>
-<translation id="725969808843520477">Ďalší prepínač</translation>
-<translation id="7269119382257320590">Žiadna interpunkcia</translation>
-<translation id="7273174640290488576">Prázdne</translation>
-<translation id="7285387653379749618">Tabuľky</translation>
-<translation id="7289186959554153431">Nadpis 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Titulky v Braillovom písme sú vypnuté</translation>
-<translation id="7318872822751139669">Zameranie zmeníte pomocou myši.</translation>
-<translation id="7322388933135261569">február</translation>
-<translation id="7332592614823088566">riadok <ph name="ROWINDEX" /> z <ph name="ROWTOTAL" />, stĺpec <ph name="COLINDEX" /> z <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">má kontextové okno</translation>
-<translation id="7356165926712028380">Prepnúť na osembodové Braillovo písmo</translation>
-<translation id="7362871137496673139">Žiadny predchádzajúci nadpis 2. úrovne</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ampersand}few{# ampersandy}many{# ampersands}other{# ampersandov}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Opúšťate tabuľku</translation>
-<translation id="739763518212184081">Predchádzajúci riadok</translation>
-<translation id="7400575256015741911">Zistila sa pravopisná chyba</translation>
-<translation id="7408482676469142474">tabuľka</translation>
-<translation id="7425395583360211003">vrátiť</translation>
-<translation id="7434509671034404296">Vývojár</translation>
-<translation id="7439060726180460871">Adresár</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">karta</translation>
-<translation id="7492049978501397201">Vstup do dialógového okna</translation>
-<translation id="7532613204005497612">jún</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, posúvač</translation>
-<translation id="7586163296341959563">prilepiť</translation>
-<translation id="7596919493010894443">výber bol vymazaný</translation>
-<translation id="7604026522577407655">Prejsť na začiatok aktuálneho stĺpca</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Oznámiť webovú adresu aktuálnej stránky</translation>
-<translation id="7609363189280667021">Prepnúť Braillove titulky</translation>
-<translation id="762020119231868829">Pozastaví všetky aktuálne hrajúce mediálne miniaplikácie</translation>
-<translation id="7625690649919402823">Ďalšia tabuľka</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), úroveň <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Žiadny predchádzajúci nadpis 3. úrovne</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, textové pole</translation>
-<translation id="7663318257180412551">Nadpis 2</translation>
-<translation id="7674576868851035240">Ďalší odkaz</translation>
-<translation id="7674768236845044097">značka</translation>
-<translation id="7684431668231950609">Upraviť text, vstup webovej adresy</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Predchádzajúci prepínač</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, textové pole pre heslo</translation>
-<translation id="7805247615045262757">predvolená navigácia</translation>
-<translation id="7805768142964895445">Stav</translation>
-<translation id="7810781339813764006">Ďalšia skupina</translation>
-<translation id="7819187121850078213">okno, karta <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">október</translation>
-<translation id="7839679365527550018">Predchádzajúce slovo</translation>
-<translation id="7851816175263618915">Čiastočná interpunkcia</translation>
-<translation id="7870596830398826354">Strom jazyka Math ML</translation>
-<translation id="78826985582142166">posúvač</translation>
-<translation id="7894517696028036636">Prepnutie na klasický režim ChromeVox.</translation>
-<translation id="7895896691902835279">Neznámy odkaz</translation>
-<translation id="7927711904086083099">Nevybrané</translation>
-<translation id="7935627501098484003">Ovládací prvok času</translation>
-<translation id="7939428177581522200">pridané do výberu</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{zavináč}few{# zavináče}many{# at signs}other{# zavináčov}}</translation>
-<translation id="7965147473449754028">ponuka zatvorená</translation>
-<translation id="7974390230414479278">Položka ponuky</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{výkričník}few{# výkričníky}many{# exclamation points}other{# výkričníkov}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{úvodzovka}few{# úvodzovky}many{# quotes}other{# úvodzoviek}}</translation>
-<translation id="8033827949643255796">vybrané</translation>
-<translation id="8035962149453661158">max:<ph name="X" /></translation>
-<translation id="8042761080832772327">Upraviť text, vstup vyhľadávania</translation>
-<translation id="8049189770492311300">Časovač</translation>
-<translation id="8065607967589909823">Výber je</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Žiadne orientačné body ARIA</translation>
-<translation id="8153880621934657047">Mimo tabuľky</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{podčiarkovník}few{# podčiarkovníky}many{# underscores}other{# podčiarkovníkov}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">vystrihnúť</translation>
-<translation id="8199231515320852133">Oznámiť hlavičky aktuálnej bunky</translation>
-<translation id="820417203470636242">Prázdna bunka</translation>
-<translation id="8215202828671303819">Hromadný výber</translation>
-<translation id="8276439074553447000">Prejsť na predchádzajúcu zamerateľnú položku</translation>
-<translation id="8278417001922463147">Žiadny predchádzajúci článok</translation>
-<translation id="8283603667300770666">Ďalšie pole formulára</translation>
-<translation id="831207808878314375">Definícia</translation>
-<translation id="8313653172105209786">adresár</translation>
-<translation id="8344569602005188545">hod.</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{mriežka}few{# mriežky}many{# pound signs}other{# mriežok}}</translation>
-<translation id="8374154622594089836">mesiac</translation>
-<translation id="8378855320830505539">Oblasť</translation>
-<translation id="8382679411218029383">Vložené automatické dopĺňanie a zoznam</translation>
-<translation id="8428603554127842284">úroveň <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Žiadny ďalší nadpis 3. úrovne</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Žiadne prechádzajúce začiarkavacie políčko</translation>
-<translation id="8455868257606149352">Max. <ph name="X" /></translation>
-<translation id="84575901236241018">má prístupový kľúč <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Znížiť podrobnosť navigácie</translation>
-<translation id="8520472399088452386">Tlačidlo otáčania</translation>
-<translation id="8538744478902126321">Vykonať odhad v hlavičke riadka aktuálnej bunky</translation>
-<translation id="8540054775867439484">Skok na začiatok</translation>
-<translation id="8548973727659841685">Znak</translation>
-<translation id="8561322612995434619">má kontextové okno</translation>
-<translation id="8571096049907249734">viac volieb</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Ďalšia položka zoznamu</translation>
-<translation id="860150890330522909">začiarkavacie políčko <ph name="NAME" /> je začiarknuté</translation>
-<translation id="8606621670302093223">Ovládací prvok Dátum</translation>
-<translation id="8631359288236106450">Počet vybraných položiek: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Oznámiť aktuálne súradnice bunky</translation>
-<translation id="8650576015643545550">Žiadny predchádzajúci zoznam</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Zobraziť zoznam odkazov</translation>
-<translation id="8664519043722036194">sekundy</translation>
-<translation id="867187640362843212">Nadpis 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{zvislá čiara}few{# zvislé čiary}many{# vertical pipes}other{# zvislých čiar}}</translation>
-<translation id="8735450637152821465">Začnite výber</translation>
-<translation id="8743786158317878347">zadať štruktúrovaný obsah, ako sú napríklad tabuľky</translation>
-<translation id="8747966237988593539">Zoradený zoznam</translation>
-<translation id="8759334257841767240">Žiadny ďalší odkaz</translation>
-<translation id="8767968232364267681">Ďalšia hlavička 4. úrovne</translation>
-<translation id="8770473310765924354">ukončiť štruktúrovaný obsah, ako sú napríklad tabuľky</translation>
-<translation id="8791025954632646584">Sémantika je zapnutá</translation>
-<translation id="8796411681063377102">Ďalší nadpis 3. úrovne</translation>
-<translation id="8808582214901541005">marec</translation>
-<translation id="8825828890761629845">banner</translation>
-<translation id="8851136666856101339">hlavné</translation>
-<translation id="8856538297388979332">Stlačením tlačidiel hore alebo dole si prehliadnete príkazy a tlačidlom Enter ich aktivujete</translation>
-<translation id="8864099967139188018">Žiadny ďalší nadpis 6. úrovne</translation>
-<translation id="8882002077197914455">Hlavička riadka</translation>
-<translation id="8896347895970027998">Aktivácia a deaktivácia rozšírenia ChromeVox.</translation>
-<translation id="8898516272131543774">Cyklicky striedať zvukovú odozvu na interpunkciu</translation>
-<translation id="8900148057318340779">Kľúč predpony</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Prázdne hlavičky</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Kláves modifikátora</translation>
-<translation id="8943175951035496220">Vpravo nie je žiadna bunka</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">súbor</translation>
-<translation id="9027462562263121875">Žiadne tabuľky</translation>
-<translation id="9040132695316389094">Nadpis 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Prepnúť miniaplikáciu vyhľadávania</translation>
-<translation id="9065283790526219006">+kontextové okno</translation>
-<translation id="9077213568694924680">odstránené z výberu</translation>
-<translation id="9082874451376019682">Žiadny predchádzajúci posúvač</translation>
-<translation id="9089864840575085222">Cyklicky striedať zvukovú odozvu na zadávanie textu</translation>
-<translation id="9107530006868467849">Žiadna predchádzajúca miniaplikácia pre médiá</translation>
-<translation id="9108370397979208512">matematika</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{percento}few{# znaky percenta}many{# percent signs}other{# znakov percenta}}</translation>
-<translation id="9115913704608474258">november</translation>
-<translation id="9128414153595658330">dialógové okno</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Oznamuje stručný popis aktuálnej pozície</translation>
-<translation id="9153606228985488238">Výška: <ph name="PERCENT" /> %</translation>
-<translation id="9160096769946561184">Prejsť na koniec aktuálneho stĺpca</translation>
-<translation id="9173115498289768110">Hlasitosť: <ph name="PERCENT" /> %</translation>
-<translation id="9178973770513562274">Ak chcete prehliadať, použite klávesy hore a dole. Ak chcete hľadať, začnite písať.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">Žiadna ďalšia sekcia</translation>
-<translation id="930275611743429116">Začať alebo ukončiť výber</translation>
-<translation id="948171205378458592">Znížiť rýchlosť reči</translation>
-<translation id="962913030769097253">Ďalší nadpis 1. úrovne</translation>
-<translation id="973955474346881951">Povoliť alebo zakázať rýchly režim</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sl.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sl.xtb
deleted file mode 100644
index c639e14d155..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sl.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="sl">
-<translation id="1012173283529841972">Element seznama</translation>
-<translation id="1013742170491673792">iskel</translation>
-<translation id="1023866615269196768">Razpeta.</translation>
-<translation id="1025074108959230262">Način zaklepanja je onemogočen</translation>
-<translation id="1031961866430398710">nato</translation>
-<translation id="1044777062731150180">Brez glav</translation>
-<translation id="106222400312645156">glvrs</translation>
-<translation id="1065552602950927991">Neveljaven vnos</translation>
-<translation id="1082209053475788238">Ni prejšnjega naslova na ravni 6.</translation>
-<translation id="1088219014394087294">Ni naslovov.</translation>
-<translation id="1106741348836243114">Vklop/izklop zvočnih povratnih informacij (zvočnih ikon).</translation>
-<translation id="1120743664840974483">{"a": "alfa", "b": "bravo", "c": "celje", "d": "delta", "e": "eho", "f": "fokstrot", "g": "golf", "h": "hotel", "i": "indija", "j": "julija","k": "kilo", "l": "lima", "m": "maribor", "n": "november", "o": "oskar","p": "postojna", "q": "quebec", "r": "romeo", "s": "sežana", "t": "tango", "u": "uniforma", "v": "viktor", "w": "wroclaw","x": "xenia", "y": "yukon", "z": "zulu"}</translation>
-<translation id="113582498867142724">Zbirka <ph name="TAG" /> s toliko elementi: <ph name="NUM" /></translation>
-<translation id="1155043339247954670">Ni naslednjega elementa seznama.</translation>
-<translation id="1157782847298808853">Pomoč za tipkovnico</translation>
-<translation id="1157843803349774103">Kombinirano polje z vrednostjo <ph name="VALUE" /> in imenom <ph name="NAME" /></translation>
-<translation id="1167230103353892028">Menijski element <ph name="NAME" /> s podmenijem</translation>
-<translation id="1177863135347784049">Po meri</translation>
-<translation id="1188858454923323853">dopolnilno</translation>
-<translation id="1206619573307042055">potujoči napis</translation>
-<translation id="1213216066620407844">ChromeVox – naj Chrome govori</translation>
-<translation id="1229276918471378188">Prejšnji skok</translation>
-<translation id="1237866625126425153">izbskp</translation>
-<translation id="1251750620252348585">Naslednji naslov na ravni 6</translation>
-<translation id="1275718070701477396">Izbrano</translation>
-<translation id="1319608975892113573">Ni prejšnjega daljšega citata.</translation>
-<translation id="1321576897702511272">Skritje pomoči za ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> od <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">izgovarjanje znakov in besed ob vnosu</translation>
-<translation id="1339428534620983148">Prejšnji stolpec tabele</translation>
-<translation id="1342835525016946179">člnk</translation>
-<translation id="1346748346194534595">V desno</translation>
-<translation id="136718599399906424">Naslednja vrstica tabele</translation>
-<translation id="1383876407941801731">Išči</translation>
-<translation id="1385214448885562192">Pritisnite »enter« za sprejetje ali »escape« za preklic, dol za naprej in gor za nazaj.</translation>
-<translation id="1396114365388024581">sezzav</translation>
-<translation id="1439316808600711881">obm</translation>
-<translation id="1452236308086741652">Polje z besedilom za geslo z vrednostjo <ph name="VALUE" /></translation>
-<translation id="1467432559032391204">V levo</translation>
-<translation id="1474557363159888097">Ni prejšnjega sidra.</translation>
-<translation id="1502086903961450562">Prejšnja grafika</translation>
-<translation id="1506187449813838456">Povečanje višine tona</translation>
-<translation id="151784044608172266">Naslednji stavek</translation>
-<translation id="1524531499102321782">Braillova pisava – naslednja vrstica</translation>
-<translation id="1546370775711804143">Drsni trak</translation>
-<translation id="1559739829547075274">Pomik nazaj</translation>
-<translation id="1571643229714746283">Funkcija ChromeVox je pripravljena</translation>
-<translation id="158493514907962286">december</translation>
-<translation id="1594072653727561613">men</translation>
-<translation id="1610130962244179598">Preklop na braillovo pisavo s 6 pikami</translation>
-<translation id="1611168825862729585">Glava stolpca:</translation>
-<translation id="1613476421962910979">Zvočne ikone vklopljene</translation>
-<translation id="1618597272655350600">Objavi popoln opis trenutnega položaja</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{znak za več}one{# znak za več}two{# znaka za več}few{# znaki za več}other{# znakov za več}}</translation>
-<translation id="1653266918374749391">Prejšnji naslov na ravni 3</translation>
-<translation id="1659072772017912254">Ni potrjeno</translation>
-<translation id="1669290819662866522">tdn</translation>
-<translation id="1674262202423278359">Krmarjenje ChromeVox</translation>
-<translation id="16777221443363124">Menijska vrstica</translation>
-<translation id="1692077714702418899">strukturna vrstica</translation>
-<translation id="1700517974991662022">Obiskano</translation>
-<translation id="1722567105086139392">Povezava</translation>
-<translation id="1727806147743597030">ng</translation>
-<translation id="174268867904053074">Naslednja grafika</translation>
-<translation id="1781173782405573156">Prehodna tipka</translation>
-<translation id="1787176709638001873">Besedilo za urejanje gesla</translation>
-<translation id="1810107444790159527">Polje s seznamom</translation>
-<translation id="1828385960365606039">maj</translation>
-<translation id="1834891354138622109">Stolpec</translation>
-<translation id="1865601187525349519">Konec besedila</translation>
-<translation id="1876229593313240038">dok</translation>
-<translation id="188130072164734898">Izgovori trenutna čas in datum.</translation>
-<translation id="1902396333223336119">Celica</translation>
-<translation id="1905379170753160525">Prikaz seznama naslovov</translation>
-<translation id="1912556590115083156">obpv</translation>
-<translation id="1913761808037590218">#el</translation>
-<translation id="1954623340234317532">Nadzor tedna v letu</translation>
-<translation id="1964135212174907577">Naslednji predmet</translation>
-<translation id="1969092762068865084">julij</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Glava vrstice:</translation>
-<translation id="2002895034995108595">Ponastavi trenutno razporeditev tipk</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{oglati oklepaj}one{# oglati oklepaj}two{# oglata oklepaja}few{# oglati oklepaji}other{# oglatih oklepajev}}</translation>
-<translation id="2045490512405922022">ni potrjeno</translation>
-<translation id="20601713649439366">Ni prejšnjega matematičnega izraza.</translation>
-<translation id="207477615537953741">Semantični način je izklopljen</translation>
-<translation id="2086961585857038472">Naslednja beseda</translation>
-<translation id="2089387485033699258">sl</translation>
-<translation id="2091933974477985526">Prejšnje besedilno polje, ki ga je mogoče urejati</translation>
-<translation id="2100350898815792233">Vsa ločila</translation>
-<translation id="2119965627982867824">pomik</translation>
-<translation id="2121067395472282800">tipka za dostop: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Spremenite trenutno tabelo braillove pisave s 6 pikami z izbiro možnosti s spodnjega seznama.</translation>
-<translation id="2169714232367507776">Klik trenutnega elementa</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{zaklepaj}one{# zaklepaj}two{# zaklepaja}few{# zaklepaji}other{# zaklepajev}}</translation>
-<translation id="2199994615414171367">Prejšnji matematični izraz</translation>
-<translation id="2223693656926968778">Ukrepanje za trenutni element</translation>
-<translation id="225732394367814946">Povečanje hitrosti govora</translation>
-<translation id="2267945578749931355">Naslednji znak</translation>
-<translation id="2281234842553884450">Prejšnji drsnik</translation>
-<translation id="2318372665160196757">Glavni</translation>
-<translation id="2329324941084714723">Podokno z zavihki</translation>
-<translation id="2344193891939537199">Kontrolnik za datum in čas</translation>
-<translation id="2359897517538099099">Ni v tabelarnem načinu.</translation>
-<translation id="241124561063364910">in še</translation>
-<translation id="2417569100218200841">Informacije o vsebini</translation>
-<translation id="2422937916923936891">Potrditveno polje menijskega elementa</translation>
-<translation id="2429669115401274487">pop.</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> je zdaj novi modifikator ChromeVox.</translation>
-<translation id="2450814015951372393">Potrditveno polje</translation>
-<translation id="2462626033734746142">Skupina izbirnih gumbov</translation>
-<translation id="2471138580042810658">Naslov 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{zvezdica}one{# zvezdica}two{# zvezdici}few{# zvezdice}other{# zvezdic}}</translation>
-<translation id="2549392850788122959">Tipka <ph name="KEY" /> je ponastavljena.</translation>
-<translation id="2553108862507765288">slovnična napaka</translation>
-<translation id="257674075312929031">Skupina</translation>
-<translation id="2582407057977008361">Razen</translation>
-<translation id="2589102159832527089">Na tej strani je besedilo, ki je bilo samodejno kopirano iz datoteke PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Kliknite tukaj za izvirnik.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">s/z {COUNT,plural, =1{# elementom}one{# elementom}two{# elementoma}few{# elementi}other{# elementi}}</translation>
-<translation id="2614981083756825552">Postavitev Math ML</translation>
-<translation id="2626530649491650971">omogoča klikanje</translation>
-<translation id="2628764385451019380">Ni prejšnjega kombiniranega polja.</translation>
-<translation id="2637227747952042642">Mat</translation>
-<translation id="2639750663247012216">Modifikator ChromeVox</translation>
-<translation id="2644542693584024604">napačno črkovano</translation>
-<translation id="2667291555398229137">Kliknite element pod tipko za usmerjanje</translation>
-<translation id="2697408785920771974">samovvr</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{oklepaj}one{# oklepaj}two{# oklepaja}few{# oklepaji}other{# oklepajev}}</translation>
-<translation id="2705875883745373140">Ni pritisnjeno</translation>
-<translation id="2706462751667573066">Gor</translation>
-<translation id="2717271541250958000">pdzzav</translation>
-<translation id="2723001399770238859">zvok</translation>
-<translation id="2732718972699418926">dop.</translation>
-<translation id="2749275490991666823">Potrjeno</translation>
-<translation id="27527859628328957">Pomik na naslednji element, ki ga je mogoče izbrati</translation>
-<translation id="2770781857296573485">Vnos raziskovanja skupine</translation>
-<translation id="2777845298774924149">Izhod</translation>
-<translation id="2800204403141299078">Ni več različnih elementov.</translation>
-<translation id="2800780099804980316">Ni prejšnjega naslova na ravni 1.</translation>
-<translation id="2811204574343810641">Vrstica</translation>
-<translation id="2816654101880605877">Ni naslednjega drsnika.</translation>
-<translation id="2841013758207633010">Čas</translation>
-<translation id="2843837985843789981">Prejšnja skupina</translation>
-<translation id="2844995807198708617">Kontekstni meni</translation>
-<translation id="2849332794118375855">Ni naslednjega potrditvenega polja.</translation>
-<translation id="2864481629947106776">Prejšnja povezava</translation>
-<translation id="2873259058405069099">Pomik na začetek tabele</translation>
-<translation id="2894654529758326923">Podatki</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{zaviti oklepaj}one{# zaviti oklepaj}two{# zavita oklepaja}few{# zaviti oklepaji}other{# zavitih oklepajev}}</translation>
-<translation id="2911433807131383493">Odpiranje vadnice za ChromeVox</translation>
-<translation id="2932083475399492303">Preklapljanje med strukturno vrstico in vrstico postavitve</translation>
-<translation id="2964026537669811554">Skupina naslova</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabulator}one{# tabulator}two{# tabulatorja}few{# tabulatorji}other{# tabulatorjev}}</translation>
-<translation id="2972078295414139404">Ni prejšnje obiskane povezave</translation>
-<translation id="2972205263822847197">Opis orodja</translation>
-<translation id="2998131015536248178">Prejšnji znak</translation>
-<translation id="2999559350546931576">Zmanjšanje višine tona</translation>
-<translation id="2999945368667127852">Ni pripomočka za naslednjo predstavnost.</translation>
-<translation id="3012414509011670858">Ni prejšnjega razdelka.</translation>
-<translation id="3030432017085518523">Izbirni gumb menijskega elementa</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{opuščaj}one{# opuščaj}two{# opuščaja}few{# opuščaji}other{# opuščajev}}</translation>
-<translation id="3046838483509668188">Možnosti za ChromeVox</translation>
-<translation id="3047143736589213134">Poskusni zemljevid tipk</translation>
-<translation id="3060756054951570867">Meni <ph name="TITLE" /> je odprt</translation>
-<translation id="3078345202707391975">Naslednji naslov na ravni 2</translation>
-<translation id="3078740164268491126">tabela</translation>
-<translation id="3082557070674409251">Kliknjeno</translation>
-<translation id="3084806535845658316">brez izgovarjanja ob vnosu</translation>
-<translation id="3086746722712840547">opmb</translation>
-<translation id="308895241372589742">Ni naslednjega matematičnega izraza.</translation>
-<translation id="3090532668523289635">skp</translation>
-<translation id="3093176084511590672">Naslednji mejnik</translation>
-<translation id="3096671415663099226">kpo</translation>
-<translation id="3104705064753753826">okn opoz</translation>
-<translation id="3109724472072898302">Strnjeno</translation>
-<translation id="3134461040845705080">samo br</translation>
-<translation id="3138767756593758860">Prikaz seznama mejnikov</translation>
-<translation id="3143851963874289911">cel</translation>
-<translation id="3149472044574196936">Naslednja vrstica</translation>
-<translation id="3155083529632865074">Ni prejšnjega gumba.</translation>
-<translation id="3163593631834463955">Prazna glava stolpca</translation>
-<translation id="316542773973815724">Krmarjenje</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{presledek}one{# presledek}two{# presledka}few{# presledki}other{# presledkov}}</translation>
-<translation id="320961988183078793">vnos: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104">Zavihek <ph name="NAME" /></translation>
-<translation id="3226035351387556942">ptp</translation>
-<translation id="3229375994964697375">Obiskana povezava</translation>
-<translation id="323731244387692321">Odpiranje pomoči za tipkovnico ChromeVox</translation>
-<translation id="3241052487511142956">Prejšnja obiskana povezava</translation>
-<translation id="3286390186030710347">Drsnik</translation>
-<translation id="3299925995433437805">Ni naslednje obiskane povezave</translation>
-<translation id="3303384412438961941">Če želite izvedeti ime poljubne tipke, jo pritisnite. Če pritisnete Ctrl + W, boste zaprli raziskovalca tipkovnice.</translation>
-<translation id="3307886118343381874">Pomik na konec tabele</translation>
-<translation id="3311969765485641742">Pritisnite Alt + Shift + A, če želite pregledati opozorila</translation>
-<translation id="3312997241656799641">Naslednja obiskana povezava</translation>
-<translation id="3321460131042519426">Omogočanje združevanja besed</translation>
-<translation id="3322936298410871309">Prejšnji naslov na ravni 1</translation>
-<translation id="3323447499041942178">Besedilno polje</translation>
-<translation id="3353420241558113817">{"ar": "arabščina",
- "bg": "bolgarščina",
- "ca": "katalonščina",
- "cs": "češčina",
- "da": "danščina",
- "de": "nemščina",
- "de_CH": "nemščina (Švica)",
- "de_DE": "nemščina (Nemčija)",
- "el": "grščina",
- "en": "angleščina",
- "en_CA": "angleščina (Kanada)",
- "en_GB": "angleščina (Združeno kraljestvo)",
- "en_US": "angleščina (Združene države)",
- "es": "španščina",
- "et": "estonščina",
- "fr": "francoščina",
- "fr_CA": "francoščina (Kanada)",
- "fr_FR": "francoščina (Francija)",
- "fi": "finščina",
- "he": "hebrejščina",
- "hi": "hindijščina",
- "hr": "hrvaščina",
- "hu": "madžarščina",
- "is": "islandščina",
- "it": "italijanščina",
- "ko": "korejščina",
- "lt": "litovščina",
- "lv": "latvijščina",
- "nb": "norveščina (Bokmål)",
- "nl": "nizozemščina",
- "pl": "poljščina",
- "pt": "portugalščina",
- "ro": "romunščina",
- "ru": "ruščina",
- "sk": "slovaščina",
- "sl": "slovenščina",
- "sr": "srbščina",
- "sv": "švedščina",
- "tr": "turščina",
- "vi": "vietnamščina",
- "zh": "kitajščina",
- "zh_TW": "kitajščina (tradicionalna han)"}</translation>
-<translation id="3359142382821736686">loččrt</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{znak za plus}one{# znak za plus}two{# znaka za plus}few{# znaki za plus}other{# znakov za plus}}</translation>
-<translation id="338583716107319301">Ločilo</translation>
-<translation id="3389259863310851658">Prejšnje polje obrazca</translation>
-<translation id="3390225400784126843">Naslednji drugačni element.</translation>
-<translation id="3392045790598181549">Menijski element <ph name="NAME" /></translation>
-<translation id="3406283310380167331">Prikaz seznama obrazcev</translation>
-<translation id="3422338090358345848">Odpiranje raziskovalca tipkovnice</translation>
-<translation id="3457000393508828486">Delno pritisnjeno</translation>
-<translation id="3462439746547587373">Gumb <ph name="NAME" /></translation>
-<translation id="3473644018603298796">izb <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{oglati zaklepaj}one{# oglati zaklepaj}two{# oglata zaklepaja}few{# oglati zaklepaji}other{# oglatih zaklepajev}}</translation>
-<translation id="3493915602752813531">Ni naslednjega sidra.</translation>
-<translation id="3494946239022273294">elmen</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{vprašaj}one{# vprašaj}two{# vprašaja}few{# vprašaji}other{# vprašajev}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{strešica}one{# strešica}two{# strešici}few{# strešice}other{# strešic}}</translation>
-<translation id="3568702578574425662">Potrditveno polje <ph name="NAME" /> ni označeno</translation>
-<translation id="3599054940393788245">Ni znotraj matematičnih enačb</translation>
-<translation id="3616113530831147358">Zvok</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{znak za krativec}one{# znak za krativec}two{# znaka za krativec}few{# znaki za krativec}other{# znakov za krativec}}</translation>
-<translation id="3650317109285159359">potokelmen</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{znak za dolar}one{# znak za dolar}two{# znaka za dolar}few{# znaki za dolar}other{# znakov za dolar}}</translation>
-<translation id="3659787053479271466">opoz</translation>
-<translation id="3665563998540286755">Polje s seznamom z vrednostjo <ph name="VALUE" /></translation>
-<translation id="3687295507293856493">Ugibanje glave stolpca v trenutni celici</translation>
-<translation id="3692274950075847560">I: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Nadzor govora</translation>
-<translation id="3716845769494773620">V več vrsticah</translation>
-<translation id="3731746171184829332">Ni prejšnjega naslova.</translation>
-<translation id="3762198587642264450">Pomik na konec trenutne vrstice</translation>
-<translation id="3777255250339039212">n1</translation>
-<translation id="3793710123303304873">Izhod iz pogovornega okna.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}two{#}few{#}other{#}}</translation>
-<translation id="3801735343383419236">Samodokončanje seznama</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Naslednja predstavnost</translation>
-<translation id="3819376190738087562">Ni skokov.</translation>
-<translation id="385383972552776628">Odpiranje strani z možnostmi</translation>
-<translation id="3856075812838139784">Samo za branje</translation>
-<translation id="3887576927692165210">el</translation>
-<translation id="3897092660631435901">Meni</translation>
-<translation id="3909320334364316587">Prejšnji naslov na ravni 6</translation>
-<translation id="3914173277599553213">Obvezno</translation>
-<translation id="3962990492275676168">Začetek branja na trenutni lokaciji</translation>
-<translation id="4004802134384979325">potrjeno</translation>
-<translation id="4006140876663370126">slk</translation>
-<translation id="4038349100599457191">Nadzor meseca</translation>
-<translation id="4039983576244166038">Prazna glava vrstice</translation>
-<translation id="4042843249978639960">Ni naslednjega naslova na ravni 2.</translation>
-<translation id="4043348641337972076">Ni prejšnjega mejnika točke v različici ARIA.</translation>
-<translation id="4047216625641135770">Oznaka</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">stn</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{TILDA}one{# tilda}two{# tildi}few{# tilde}other{# tild}}</translation>
-<translation id="409334809956508737">Prejšnji predmet</translation>
-<translation id="4099274309791143834">ima podmeni</translation>
-<translation id="4107807507418787238">Ni celice spodaj.</translation>
-<translation id="4116415223832267137">Opozorilo</translation>
-<translation id="4147126331795725888">Ni naslednjega kontrolnika.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{zaviti zaklepaj}one{# zaviti zaklepaj}two{# zavita zaklepaja}few{# zaviti zaklepaji}other{# zavitih zaklepajev}}</translation>
-<translation id="4158704014418536539">Razlikuje velike in male črke.</translation>
-<translation id="4161663686871496107">Možnost izgovorjenih povratnih informacij ChromeVox je pripravljena</translation>
-<translation id="4173994908659439270">Ni naslednjega besedilnega polja, ki ga je mogoče urejati.</translation>
-<translation id="4176463684765177261">Onemogočeno</translation>
-<translation id="4188530942454211480">Prejšnji stavek</translation>
-<translation id="4202186506458631436">Pomik v desno</translation>
-<translation id="4206289001967551965">V tabeli</translation>
-<translation id="4215733775853809057">Naslednji drsnik</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{pomišljaj}one{# pomišljaj}two{# pomišljaja}few{# pomišljaji}other{# pomišljajev}}</translation>
-<translation id="421884353938374759">izbirnik barve</translation>
-<translation id="4229646983878045487">datum čas</translation>
-<translation id="423334822609210999">Ni več celic.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" />. raven</translation>
-<translation id="4253168017788158739">Opomba</translation>
-<translation id="4254798249533888099">Drevo</translation>
-<translation id="4255943572433203166">S spodnjimi možnostmi prilagodite ChromeVox. Spremembe začnejo veljati takoj.</translation>
-<translation id="4271220233568730077">Naslednji matematični znak</translation>
-<translation id="4271521365602459209">Ni več rezultatov.</translation>
-<translation id="4287520460805643128">Ni naslednjega članka.</translation>
-<translation id="4289540628985791613">Pregled</translation>
-<translation id="4300318234632215983">Obvestilo o URL-ju povezave</translation>
-<translation id="4301352596632316575">ima podmeni</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{pika}=3{tropičje}one{# pika}two{# piki}few{# pike}other{# pik}}</translation>
-<translation id="4347461890115250064">Ni naslednjega seznama.</translation>
-<translation id="4367650418938037324">List Math ML</translation>
-<translation id="4372435075475052704">najmanj:<ph name="X" /></translation>
-<translation id="4372705107434148843">Ustavitev govora</translation>
-<translation id="4373197658375206385">Ni prejšnjega elementa, ki ni povezava.</translation>
-<translation id="4391478986194775161">podovseb</translation>
-<translation id="443163561286008705">pnst</translation>
-<translation id="4471074325120394300">Ni povezav.</translation>
-<translation id="4476183483923481720">nova vrstica</translation>
-<translation id="4482330759234983253">Prejšnja tabela</translation>
-<translation id="4491109536499578614">Slika</translation>
-<translation id="4529987814483543472">Klasična razporeditev tipk</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{poševnica}one{# poševnica}two{# poševnici}few{# poševnice}other{# poševnic}}</translation>
-<translation id="4547556996012970016">Naslednji naslov na ravni 5</translation>
-<translation id="4562381607973973258">Glava</translation>
-<translation id="4591507479202817876">je izbran</translation>
-<translation id="4597532268155981612">obrazec</translation>
-<translation id="4597896406374528575">april</translation>
-<translation id="4615592953348396470">Prezrtje naslednjega pritiska tipke</translation>
-<translation id="461613135510474570">Stavčna</translation>
-<translation id="4647836961514597010">Izbirnik barve</translation>
-<translation id="4661075872484491155">drevo</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">mrež</translation>
-<translation id="4693675773662933727">Prejšnji mejnik</translation>
-<translation id="4696413482802371445">Ni naslednjega naslova na ravni 5.</translation>
-<translation id="4729095194763193578">Prejšnja vrstica tabele</translation>
-<translation id="4736221692378411923">avgust</translation>
-<translation id="4740661827607246557">Ukazi za pomoč</translation>
-<translation id="4759716709594980008">Raziskovalec tipkovnice Chrome OS</translation>
-<translation id="4763296182459741068">Prelom do dna</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Obvestilo o naslovu trenutne strani</translation>
-<translation id="4826415162591436065">Pomik naprej</translation>
-<translation id="4826604887384865800">Naslednji skok</translation>
-<translation id="4827410568042294688">neizbrano</translation>
-<translation id="4842108708071771135">Ni naslednjega daljšega citata.</translation>
-<translation id="4848993367330139335">časov</translation>
-<translation id="4850023505158945298">Prejšnji podobni element.</translation>
-<translation id="4866956062845190338">izelmen</translation>
-<translation id="4867316986324544967">Omogočanje zapisovanja dnevnikov TTS</translation>
-<translation id="4877261390094455813">Vnesite iskalno poizvedbo.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Notranja povezava</translation>
-<translation id="4953585991029886728">Urejanje besedila</translation>
-<translation id="4954534434583049121">Prejšnji citat v bloku</translation>
-<translation id="4973717656530883744">Najmanj <ph name="X" /></translation>
-<translation id="4973762002207131920">Preklopljeno na <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">ms</translation>
-<translation id="49787999531187221">ChromeVox je zdaj onemogočen.</translation>
-<translation id="4979404613699303341">Gumb Nazaj</translation>
-<translation id="4982773647088557172">Polje s seznamom z vrednostjo <ph name="VALUE" /> in imenom <ph name="NAME" /></translation>
-<translation id="4983588134362688868">Na vrh strani</translation>
-<translation id="4986606102545753256">Okno <ph name="NAME" /></translation>
-<translation id="4993152509206108683">Hitrost: <ph name="PERCENT" /> %</translation>
-<translation id="4996716799442435517">Vidno</translation>
-<translation id="4997282455736854877">Izbirni gumb <ph name="NAME" /> je izbran</translation>
-<translation id="4997475792277222884">Ni naslednjega elementa, ki ni povezava.</translation>
-<translation id="5000760171916499057">Ni obrazcev.</translation>
-<translation id="5005670136041063723">Ni več podobnih elementov.</translation>
-<translation id="501473567976723023">januar</translation>
-<translation id="5041394372352067729">Premik Braillove vrstice na vrh strani</translation>
-<translation id="5042770794184672516">Povečanje glasnosti govora</translation>
-<translation id="5050015258024679800">Prejšnji naslov na ravni 4</translation>
-<translation id="5054047268577924192">Prejšnji element seznama</translation>
-<translation id="5078661581131202757">Izbor datoteke</translation>
-<translation id="5080758118274074384">dvokliknjeno</translation>
-<translation id="5098541983634824365">Izhod iz mreže.</translation>
-<translation id="5102981729317424850">Orodna vrstica</translation>
-<translation id="5105050547967751155">zh</translation>
-<translation id="5110983769041734144">Ni prejšnjega polja obrazca.</translation>
-<translation id="5111640677200759579">Glava stolpca</translation>
-<translation id="5117636609870536415">@el</translation>
-<translation id="5136967254288895616">Ni prejšnje povezave.</translation>
-<translation id="513774504516943387">pvz</translation>
-<translation id="517143700877085897">, neizbran</translation>
-<translation id="5183440668879371625">Braillova pisava – prejšnja vrstica</translation>
-<translation id="5184944171021383281">Ni naslednjega polja obrazca.</translation>
-<translation id="5189244881767082992">Vrstica</translation>
-<translation id="5203930734796605961">Tipki <ph name="KEY" /> je že dodeljen ukaz.</translation>
-<translation id="5205493599117157272">Seznam za <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Ni naslednjega izbirnega gumba.</translation>
-<translation id="5263344797180442561">n2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Predmetna</translation>
-<translation id="5304943142864553931">zavihek <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">odstranjeno:</translation>
-<translation id="5320727453979144100">Način zaklepanja je omogočen</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{vejica}one{# vejica}two{# vejici}few{# vejice}other{# vejic}}</translation>
-<translation id="532371086589123547">Polje z besedilom z vrednostjo <ph name="VALUE" /></translation>
-<translation id="5330443287809544590">Povezava <ph name="NAME" /></translation>
-<translation id="5336381510091010269">samovvr+szn</translation>
-<translation id="536031132345979795">Nazaj med neprekinjenim branjem</translation>
-<translation id="5368000168321181111">Zvočne ikone izklopljene</translation>
-<translation id="5374320867641260420">Ni naslednjega gumba.</translation>
-<translation id="5382299583965267720">Ni naslednjega naslova na ravni 1.</translation>
-<translation id="5402367795255837559">Braillova pisava</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{podpičje}one{# podpičje}two{# podpičji}few{# podpičja}other{# podpičij}}</translation>
-<translation id="5411891038905756502">Ni prejšnje točke skoka.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{znak za manj}one{# znak za manj}two{# znaka za manj}few{# znaki za manj}other{# znakov za manj}}</translation>
-<translation id="5455441614648621694">Dopolnilno</translation>
-<translation id="5485036206801896268">Ni prejšnje grafike.</translation>
-<translation id="5486947920110100234">Ni naslednje točke skoka.</translation>
-<translation id="549602578321198708">Beseda</translation>
-<translation id="5500932716852106146">Ni prejšnjega besedilnega polja, ki ga je mogoče urejati.</translation>
-<translation id="5502713021410870035">september</translation>
-<translation id="5507663321906818013">Odpravljanje napak v mejniku</translation>
-<translation id="5518443085409638729">Pri urejanju besedila naj bo kazalec med znakoma (kot v Mac OS X).</translation>
-<translation id="552195134157544755">Izbirni gumb</translation>
-<translation id="5534303576632885660">nsl</translation>
-<translation id="5546092960038624944">Ni prejšnjega naslova na ravni 5.</translation>
-<translation id="556042886152191864">Gumb</translation>
-<translation id="5561345396546889625">Naslednji seznam</translation>
-<translation id="5562645715554321347">skpglv</translation>
-<translation id="5583640892426849032">Vračalka</translation>
-<translation id="5585044216466955529">Urejanje besedila, vnos e-poštnega naslova</translation>
-<translation id="5597170376237141345">Naslednje potrditveno polje</translation>
-<translation id="5597933780944041114">Ni naslednjega naslova.</translation>
-<translation id="5598905979683743333">Izbirni gumb <ph name="NAME" /> ni izbran</translation>
-<translation id="5601172225407283979">Izvedba privzetega dejanja</translation>
-<translation id="5608798115546226984">Samodokončanje v vrstici</translation>
-<translation id="561939826962581046">čas</translation>
-<translation id="5623778242535476823">izgm</translation>
-<translation id="5623842676595125836">Dnevnik</translation>
-<translation id="5628125749885014029">n4</translation>
-<translation id="5637871198229500030">Ni prejšnje tabele.</translation>
-<translation id="5655682562155942719">Skočni ukazi</translation>
-<translation id="56637627897541303">Besedilno polje</translation>
-<translation id="5678161956734658133">vvel</translation>
-<translation id="5681643281275621376">opr</translation>
-<translation id="5682113568322255809">Mejnik</translation>
-<translation id="5683155931978483559">Prejšnje potrditveno polje</translation>
-<translation id="5684277895745049190">Seznam</translation>
-<translation id="5700650669149824506">Ni prejšnjega naslova na ravni 4.</translation>
-<translation id="5709192780268610569">Ni dolgega opisa</translation>
-<translation id="5712244464475377681">pojgmb</translation>
-<translation id="5712338278108304766">Naslednji stolpec tabele</translation>
-<translation id="571866080859340309">Raziskovanje skupin</translation>
-<translation id="5728409797179002635">Ni tabel.</translation>
-<translation id="5748623122140342504">Prejšnji naslov na ravni 5</translation>
-<translation id="5750633686117194034">Pritisnjen ni noben modifikator; pritisnite in pridržite najmanj en modifikator; ko končate, dvignite prste, in zaslišali boste nastavitev tipk. Dotaknite se, da zaprete.</translation>
-<translation id="5788275253279308023">zavihek v oknu brez beleženja zgodovine <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Izboljšaj določena spletna mesta (na primer Iskanje Google).</translation>
-<translation id="5819072574982403430">Element drevesa</translation>
-<translation id="5826479389509458994">vrstica <ph name="ROW" />, stolpec <ph name="COL" /></translation>
-<translation id="5850707923114094062">Panoramsko premikanje nazaj</translation>
-<translation id="5851548754964597211">Seznam zavihkov</translation>
-<translation id="5859752971144398932">Zaprta funkcija »Najdi na strani«.</translation>
-<translation id="5866042630553435010">Delno potrjeno</translation>
-<translation id="5869546221129391014">Mreža</translation>
-<translation id="5876817486144482042">Zmanjšanje glasnosti govora</translation>
-<translation id="5887397643266327462">Braillovi napisi so omogočeni.</translation>
-<translation id="5891934789323004067">Tabela</translation>
-<translation id="5919442531159595654">kopiraj.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{enačaj}one{# enačaj}two{# enačaja}few{# enačaji}other{# enačajev}}</translation>
-<translation id="5939518447894949180">Ponastavi</translation>
-<translation id="5948123859135882163">Preklop načina obravnavanja matematičnih obrazcev med strukturnim in semantičnim načinom</translation>
-<translation id="5955304353782037793">prog</translation>
-<translation id="5956928062748260866">Pogovorno okno</translation>
-<translation id="5963413905009737549">Razdelek</translation>
-<translation id="5968607524793740041">Prikaz kontekstnega menija</translation>
-<translation id="5983179082906765664">Povečanje razdrobljenosti krmarjenja</translation>
-<translation id="5999630716831179808">Glasovi</translation>
-<translation id="6000417740266304866">Spremenite trenutno tabelo braillove pisave z 8 pikami z izbiro možnosti s spodnjega seznama.</translation>
-<translation id="6006050241733874051">Obrazec</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{poševnica nazaj}one{# poševnica nazaj}two{# poševnici nazaj}few{# poševnice nazaj}other{# poševnic nazaj}}</translation>
-<translation id="6037602951055904232">Panoramsko premikanje naprej</translation>
-<translation id="611827076493383239">obs</translation>
-<translation id="6119955456199054975">Konec celice.</translation>
-<translation id="6122013438240733403">bgmb</translation>
-<translation id="6129953537138746214">Presledek</translation>
-<translation id="6142308968191113180">Naslov 4</translation>
-<translation id="6169420925157477918">Slika z dolgim opisom</translation>
-<translation id="6172087735260766220">Dostop do besedila, dostopnega v datoteki PDF, zaščiteni pred kopiranjem, ni mogoč.</translation>
-<translation id="6186305613600865047">Na dno strani</translation>
-<translation id="6193330012414963395">Dopoldne/popoldne</translation>
-<translation id="622484624075952240">Dol</translation>
-<translation id="6236061028292614533">Naslednji naslov</translation>
-<translation id="6254901459154107917">Naslednje besedilno polje, ki ga je mogoče urejati</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> zaprt.</translation>
-<translation id="6281876499889881039">Naslednji podobni element.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Ni naslednjega kombiniranega polja.</translation>
-<translation id="6307969636681130414">Pritisnjeno</translation>
-<translation id="6324551002951139333">Zaznana je bila slovnična napaka</translation>
-<translation id="6348657800373377022">Kombinirano polje</translation>
-<translation id="6355910664415701303">Ni prejšnjega elementa seznama.</translation>
-<translation id="6364795331201459219">n6</translation>
-<translation id="6368143427468974988">Prejšnji naslov</translation>
-<translation id="6387719785439924554">poleg</translation>
-<translation id="6411426777058107714">Ni prejšnjega izbirnega gumba.</translation>
-<translation id="6414968628640960377">Prejšnji drugačni element.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dvopičje}one{# dvopičje}two{# dvopičji}few{# dvopičja}other{# dvopičij}}</translation>
-<translation id="6438968337250688271">Meni <ph name="NAME" /></translation>
-<translation id="6444046323172968959">Pogovorno okno z opozorilom</translation>
-<translation id="6459511626086141404">Ploska razporeditev tipk</translation>
-<translation id="6468049171101508116">Gumb Naprej</translation>
-<translation id="6491972999578897419">Trenutni glas spremenite tako, da izberete možnost na spodnjem seznamu.</translation>
-<translation id="6508059270146105198">Premik Braillove vrstice na dno strani</translation>
-<translation id="6536864053412760904">Žeton Math ML</translation>
-<translation id="6550720799683018100">Trenutno razporeditev tipk spremenite tako, da izberete možnost na spodnjem seznamu.</translation>
-<translation id="6561818612645211875">Pomik na začetek trenutne vrstice</translation>
-<translation id="6587021927234520429">Ni naslednjega naslova na ravni 4.</translation>
-<translation id="6601344353291556895">Omogoči podrobne opise.</translation>
-<translation id="6615602925644411249">Najdi na strani.</translation>
-<translation id="6633350132811819843">Ni naslednje tabele.</translation>
-<translation id="6637586476836377253">dnevn</translation>
-<translation id="6657128831881431364">Vrstica za potek</translation>
-<translation id="6659594942844771486">Tabulator</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Prejšnje kombinirano polje</translation>
-<translation id="6714813999819678458">Prejšnji naslov na ravni 2</translation>
-<translation id="6716505898850596801">Modifikacijske tipke</translation>
-<translation id="671916444866103745">Ni naslednjega mejnika v različici ARIA.</translation>
-<translation id="6734854816611871228">Kombinirano polje z vrednostjo <ph name="VALUE" /></translation>
-<translation id="6735257939857578167">s toliko elementi: <ph name="NUM" /></translation>
-<translation id="6736510033526053669">zavihek ustvarjen</translation>
-<translation id="675895815784134693">vrnap</translation>
-<translation id="6786800275320335305">Članek</translation>
-<translation id="6787839852456839824">Bližnjične tipke</translation>
-<translation id="6793101435925451627">pol szn</translation>
-<translation id="6833103209700200188">Noga</translation>
-<translation id="6871161210040114857">Prezrtje razlikovanja velikih in malih črk.</translation>
-<translation id="6877435256196695200">Ni naslednje grafike.</translation>
-<translation id="6897341342232909480">Pomik v levo</translation>
-<translation id="6901540140423170855">datum</translation>
-<translation id="6910211073230771657">Izbrisano</translation>
-<translation id="6911965441508464308">Ni celice zgoraj.</translation>
-<translation id="6919104639734799681">Prikaz seznama tabel</translation>
-<translation id="6964088412282673743">Ni prejšnjega kontrolnika.</translation>
-<translation id="6996566555547746822">Naslednje kombinirano polje</translation>
-<translation id="7005146664810010831">URL-ja ni mogoče najti</translation>
-<translation id="7010712454773919705">Modifikacijska tipka ChromeVox</translation>
-<translation id="7031651751836475482">el szn</translation>
-<translation id="7037042857287298941">Prejšnji seznam</translation>
-<translation id="7041173719775863268">Konec izbora</translation>
-<translation id="7095834689119144465">Urejanje besedila – samo številke</translation>
-<translation id="7096001299300236431">Prejšnja predstavnost</translation>
-<translation id="7116595520562830928">večvrst</translation>
-<translation id="712735679809149106">izgovarjanje besed ob vnosu</translation>
-<translation id="713824876195128146">Naslednji citat v bloku</translation>
-<translation id="7161771961008409533">Pojavni gumb</translation>
-<translation id="7167657087543110">izgovarjanje znakov ob vnosu</translation>
-<translation id="7170733337935166589">Naprej med neprekinjenim branjem</translation>
-<translation id="7181697990050180700">Bližnjične tipke za pogosto uporabljane ukaze prilagodite tako, da jih vnesete v ustrezna polja spodaj.</translation>
-<translation id="7203150201908454328">Razširjeno</translation>
-<translation id="7210211103303402262">min</translation>
-<translation id="7217912842225915592">+ <ph name="NUM" /></translation>
-<translation id="7221740160534240920">črta</translation>
-<translation id="7226216518520804442">sezn</translation>
-<translation id="72393384879519786">Naslov</translation>
-<translation id="7241683698754534149">Odpiranje dolgega opisa na novem zavihku</translation>
-<translation id="7248671827512403053">Aplikacija</translation>
-<translation id="725969808843520477">Naslednji izbirni gumb</translation>
-<translation id="7269119382257320590">Ni ločil</translation>
-<translation id="7273174640290488576">Prazno</translation>
-<translation id="7285387653379749618">Tabele</translation>
-<translation id="7289186959554153431">Naslov 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">eldrv</translation>
-<translation id="731576946540457939">Braillovi napisi so onemogočeni.</translation>
-<translation id="7318872822751139669">Če želite spremeniti izbiro, uporabite miško.</translation>
-<translation id="7322388933135261569">februar</translation>
-<translation id="7332592614823088566"><ph name="ROWINDEX" />. vrstica od <ph name="ROWTOTAL" />; <ph name="COLINDEX" />. stolpec od <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">ima pojavno okno</translation>
-<translation id="7356165926712028380">Preklop na braillovo pisavo z 8 pikami</translation>
-<translation id="7362871137496673139">Ni prejšnjega naslova na ravni 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{znak &amp;}one{# znak &amp;}two{# znaka &amp;}few{# znaki &amp;}other{# znakov &amp;}}</translation>
-<translation id="737396357417333429">klk</translation>
-<translation id="7374104575779636480">Izhod iz tabele.</translation>
-<translation id="739763518212184081">Prejšnja vrstica</translation>
-<translation id="7400575256015741911">Zaznana je bila napaka v črkovanju</translation>
-<translation id="7408482676469142474">tab</translation>
-<translation id="7425395583360211003">vračalka</translation>
-<translation id="7434509671034404296">Razvijalec</translation>
-<translation id="7439060726180460871">Imenik</translation>
-<translation id="744163271241493234">gesel</translation>
-<translation id="7491962110804786152">tabulatorka</translation>
-<translation id="7492049978501397201">Odprto pogovorno okno</translation>
-<translation id="7532613204005497612">junij</translation>
-<translation id="7540083713905917247">drsnik z vrednostjo <ph name="VALUE" /> in imenom <ph name="NAME" /></translation>
-<translation id="7586163296341959563">prilepi.</translation>
-<translation id="7596919493010894443">izbor počiščen</translation>
-<translation id="7604026522577407655">Pomik na začetek trenutnega stolpca</translation>
-<translation id="7604451927827590395">glav</translation>
-<translation id="7609342235116740824">Obvestilo o URL-ju trenutne strani</translation>
-<translation id="7609363189280667021">Preklop na braillove napise</translation>
-<translation id="762020119231868829">Začasno ustavi vse pripomočke, ki predvajajo predstavnost</translation>
-<translation id="7625690649919402823">Naslednja tabela</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), <ph name="GRADE" />. raven</translation>
-<translation id="7641134354185483015">Ni prejšnjega naslova na ravni 3.</translation>
-<translation id="7659376057562985921">Polje za besedilo z vrednostjo <ph name="VALUE" /> in imenom <ph name="NAME" /></translation>
-<translation id="7663318257180412551">Naslov 2</translation>
-<translation id="7674576868851035240">Naslednja povezava</translation>
-<translation id="7674768236845044097">oznk</translation>
-<translation id="7684431668231950609">Urejanje besedila, vnos URL-ja</translation>
-<translation id="7685589220304187312">orvrs</translation>
-<translation id="7693840228159394336">Prejšnji izbirni gumb</translation>
-<translation id="7701196182766842984">samosez</translation>
-<translation id="7770823902658038748">Polje z besedilom za geslo z vrednostjo <ph name="VALUE" /> in imenom <ph name="NAME" /></translation>
-<translation id="7805247615045262757">privzeto krmarjenje</translation>
-<translation id="7805768142964895445">Stanje</translation>
-<translation id="7810781339813764006">Naslednja skupina</translation>
-<translation id="7819187121850078213">zavihek v oknu <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">oktober</translation>
-<translation id="7839679365527550018">Prejšnja beseda</translation>
-<translation id="7851816175263618915">Nekaj ločil</translation>
-<translation id="7870596830398826354">Drevo Math ML</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Preklop klasične funkcije ChromeVox.</translation>
-<translation id="7895896691902835279">Neznana povezava</translation>
-<translation id="7927711904086083099">Ni izbrano</translation>
-<translation id="7935627501098484003">Kontrolnik za čas</translation>
-<translation id="7939428177581522200">dodani v izbor</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{afna}one{# afna}two{# afni}few{# afne}other{# afen}}</translation>
-<translation id="7965147473449754028">meni je bil zaprt</translation>
-<translation id="7974390230414479278">Menijski element</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{klicaj}one{# klicaj}two{# klicaja}few{# klicaji}other{# klicajev}}</translation>
-<translation id="8007540374018858731">n3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{narekovaj}one{# narekovaj}two{# narekovaja}few{# narekovaji}other{# narekovajev}}</translation>
-<translation id="8033827949643255796">izbrani</translation>
-<translation id="8035962149453661158">največ:<ph name="X" /></translation>
-<translation id="8042761080832772327">Urejanje besedila, vnos poizvedbe</translation>
-<translation id="8049189770492311300">Časovnik</translation>
-<translation id="8065607967589909823">Izbrano je</translation>
-<translation id="8066678206530322333">Pasica</translation>
-<translation id="8110647606445335195">Ni mejnika v različici ARIA.</translation>
-<translation id="8153880621934657047">Zunaj tabele.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{podčrtaj}one{# podčrtaj}two{# podčrtaja}few{# podčrtaji}other{# podčrtajev}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">izreži.</translation>
-<translation id="8199231515320852133">Obvestilo o glavah trenutne celice</translation>
-<translation id="820417203470636242">Prazna celica.</translation>
-<translation id="8215202828671303819">Sočasna izbira več elementov</translation>
-<translation id="8276439074553447000">Pomik na prejšnji element, ki ga je mogoče izbrati</translation>
-<translation id="8278417001922463147">Ni prejšnjega članka.</translation>
-<translation id="8283603667300770666">Naslednje polje obrazca</translation>
-<translation id="831207808878314375">Opredelitev</translation>
-<translation id="8313653172105209786">imn</translation>
-<translation id="8344569602005188545">h</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{lojtra}one{# lojtra}two{# lojtri}few{# lojtre}other{# lojter}}</translation>
-<translation id="8374154622594089836">mesec</translation>
-<translation id="8378855320830505539">Območje</translation>
-<translation id="8382679411218029383">Samodokončanje v vrstici in s seznama</translation>
-<translation id="8428603554127842284">raven <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Ni naslednjega naslova na ravni 3.</translation>
-<translation id="8430049249787218991">menvrst</translation>
-<translation id="844681116543532394">Ni prejšnjega potrditvenega polja.</translation>
-<translation id="8455868257606149352">Največ <ph name="X" /></translation>
-<translation id="84575901236241018">ima tipko za dostop <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Zmanjšanje razdrobljenosti krmarjenja</translation>
-<translation id="8520472399088452386">Pomikalnik</translation>
-<translation id="8538744478902126321">Ugibanje glave vrstice v trenutni celici</translation>
-<translation id="8540054775867439484">Prelom do vrha</translation>
-<translation id="8548973727659841685">Znakovna</translation>
-<translation id="8561322612995434619">ima pojavno okno</translation>
-<translation id="8571096049907249734">večizb</translation>
-<translation id="8584721346566392021">n5</translation>
-<translation id="8587549812518406253">Naslednji element seznama</translation>
-<translation id="860150890330522909">Potrditveno polje <ph name="NAME" /> je označeno</translation>
-<translation id="8606621670302093223">Nadzor datuma</translation>
-<translation id="8631359288236106450">št. izbranih elementov: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Izgovorjava trenutnih koordinat celice</translation>
-<translation id="8650576015643545550">Ni prejšnjega seznama.</translation>
-<translation id="8653031188082306838">urlel</translation>
-<translation id="8653646212587894517">Prikaz seznama povezav</translation>
-<translation id="8664519043722036194">s</translation>
-<translation id="867187640362843212">Naslov 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{navpičnica}one{# navpičnica}two{# navpičnici}few{# navpičnice}other{# navpičnic}}</translation>
-<translation id="8735450637152821465">Začetek izbora</translation>
-<translation id="8743786158317878347">odpiranje strukturirane vsebine, npr. tabele</translation>
-<translation id="8747966237988593539">Naročeni seznam</translation>
-<translation id="8759334257841767240">Ni naslednje povezave.</translation>
-<translation id="8767968232364267681">Naslednji naslov na ravni 4</translation>
-<translation id="8770473310765924354">zapiranje strukturirane vsebine, na primer tabele</translation>
-<translation id="8791025954632646584">Semantični način je vklopljen</translation>
-<translation id="8796411681063377102">Naslednji naslov na ravni 3</translation>
-<translation id="8808582214901541005">marec</translation>
-<translation id="8825828890761629845">psc</translation>
-<translation id="8851136666856101339">glavn</translation>
-<translation id="8856538297388979332">Pritisnite gor ali dol, če si želite ogledati ukaze; sprožite jih s pritiskom na »enter«</translation>
-<translation id="8864099967139188018">Ni naslednjega naslova na ravni 6.</translation>
-<translation id="8882002077197914455">Glava vrstice</translation>
-<translation id="8896347895970027998">Omogočanje ali onemogočanje funkcije ChromeVox.</translation>
-<translation id="8898516272131543774">Kroženje med možnostmi izgovarjanja ločil</translation>
-<translation id="8900148057318340779">Ključ predpone</translation>
-<translation id="8908714597367957477">glvstp</translation>
-<translation id="8931936695772494138">Prazne glave</translation>
-<translation id="8937112856099038376">intpvz</translation>
-<translation id="8940925288729953902">Modifikacijske tipke</translation>
-<translation id="8943175951035496220">Ni celice desno.</translation>
-<translation id="8978496506222343566">opord</translation>
-<translation id="900114243503212879">dat</translation>
-<translation id="9027462562263121875">Ni tabel.</translation>
-<translation id="9040132695316389094">Naslov 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Preklop pripomočka za iskanje</translation>
-<translation id="9065283790526219006">+pojavnookno</translation>
-<translation id="9077213568694924680">odstranjeni iz izbora</translation>
-<translation id="9082874451376019682">Ni prejšnjega drsnika.</translation>
-<translation id="9089864840575085222">Kroženje med možnostmi izgovarjanja tipkanja</translation>
-<translation id="9107530006868467849">Ni pripomočka za prejšnjo predstavnost</translation>
-<translation id="9108370397979208512">matematika</translation>
-<translation id="9108589040018540527">drsn</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{znak za odstotek}one{# znak za odstotek}two{# znaka za odstotek}few{# znaki za odstotek}other{# znakov za odstotek}}</translation>
-<translation id="9115913704608474258">november</translation>
-<translation id="9128414153595658330">pog ok</translation>
-<translation id="9149560530563164529">razd</translation>
-<translation id="9151211641321628915">Objavi kratek opis trenutnega položaja</translation>
-<translation id="9153606228985488238">Višina tona: <ph name="PERCENT" /> %</translation>
-<translation id="9160096769946561184">Pomik na konec trenutnega stolpca</translation>
-<translation id="9173115498289768110">Glasnost: <ph name="PERCENT" /> %</translation>
-<translation id="9178973770513562274">S puščicama za gor in dol lahko brskate; če želite iskati, začnite vnašati.</translation>
-<translation id="9192904702577636854">Potujoči napis</translation>
-<translation id="9212322457209634662">Ni naslednjega razdelka.</translation>
-<translation id="930275611743429116">Začetek ali konec izbora.</translation>
-<translation id="948171205378458592">Zmanjšanje hitrosti govora</translation>
-<translation id="962913030769097253">Naslednji naslov na ravni 1</translation>
-<translation id="973955474346881951">Omogočanje/onemogočanje načina zaklepanja</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sr.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sr.xtb
deleted file mode 100644
index 9cf86f26b43..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sr.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="sr">
-<translation id="1012173283529841972">Ставка листе</translation>
-<translation id="1013742170491673792">претрага</translation>
-<translation id="1023866615269196768">Спојено.</translation>
-<translation id="1025074108959230262">Лепљиви режим је онемогућен</translation>
-<translation id="1031961866430398710">и</translation>
-<translation id="1044777062731150180">Нема заглавља</translation>
-<translation id="106222400312645156">заглавље реда</translation>
-<translation id="1065552602950927991">Неважећи унос</translation>
-<translation id="1082209053475788238">Нема претходног заглавља 6. нивоа.</translation>
-<translation id="1088219014394087294">Нема заглавља.</translation>
-<translation id="1106741348836243114">Укључивање или искључивање звучних повратних информација (звучна обавештења).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Колекција <ph name="TAG" /> са <ph name="NUM" /> ставке(и)</translation>
-<translation id="1155043339247954670">Нема следеће ставке листе.</translation>
-<translation id="1157782847298808853">Помоћ за тастатуру</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, комбиновани оквир</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, ставка менија, са подменијем</translation>
-<translation id="1177863135347784049">Прилагођено</translation>
-<translation id="1188858454923323853">комплементарно</translation>
-<translation id="1206619573307042055">покретни текст</translation>
-<translation id="1213216066620407844">ChromeVox – даје глас Chrome-у</translation>
-<translation id="1229276918471378188">Претходни прелазак</translation>
-<translation id="1237866625126425153">група за избор</translation>
-<translation id="1251750620252348585">Следеће заглавље 6. нивоа</translation>
-<translation id="1275718070701477396">Изабрано</translation>
-<translation id="1319608975892113573">Нема претходног издвојеног цитата.</translation>
-<translation id="1321576897702511272">Скривање помоћи за ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> од <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">одјек знакова и речи</translation>
-<translation id="1339428534620983148">Претходна колона табеле</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Удесно</translation>
-<translation id="136718599399906424">Следећи ред табеле</translation>
-<translation id="1383876407941801731">Претражи</translation>
-<translation id="1385214448885562192">Притисните enter да бисте прихватили или escape да бисте отказали, стрелицу надоле за следеће и стрелицу нагоре за претходно.</translation>
-<translation id="1396114365388024581">листа картица</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, оквир за лозинку</translation>
-<translation id="1467432559032391204">Улево</translation>
-<translation id="1474557363159888097">Нема претходног сидра.</translation>
-<translation id="1502086903961450562">Претходна слика</translation>
-<translation id="1506187449813838456">Повећавање регистра</translation>
-<translation id="151784044608172266">Следећа реченица</translation>
-<translation id="1524531499102321782">Следећи ред на Брајевој азбуци</translation>
-<translation id="1546370775711804143">Трака за померање</translation>
-<translation id="1559739829547075274">Кретање уназад</translation>
-<translation id="1571643229714746283">ChromeVox је спреман</translation>
-<translation id="158493514907962286">децембар</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Пребаци на Брајеву азбуку са 6 тачака</translation>
-<translation id="1611168825862729585">Заглавље колоне:</translation>
-<translation id="1613476421962910979">Звучна обавештења су укључена</translation>
-<translation id="1618597272655350600">Објављује потпун опис актуелног положаја</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{знак „веће од“}one{# знак „веће од“}few{# знака „веће од“}other{# знакова „веће од“}}</translation>
-<translation id="1653266918374749391">Претходно заглавље 3. нивоа</translation>
-<translation id="1659072772017912254">Није проверено</translation>
-<translation id="1669290819662866522">недеља</translation>
-<translation id="1674262202423278359">ChromeVox навигација</translation>
-<translation id="16777221443363124">Трака са менијима</translation>
-<translation id="1692077714702418899">линија структуре</translation>
-<translation id="1700517974991662022">Посећено</translation>
-<translation id="1722567105086139392">Веза</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Следећа слика</translation>
-<translation id="1781173782405573156">Пролазни тастер</translation>
-<translation id="1787176709638001873">Текст за измену лозинке</translation>
-<translation id="1810107444790159527">Оквир са листом</translation>
-<translation id="1828385960365606039">мај</translation>
-<translation id="1834891354138622109">Колона</translation>
-<translation id="1865601187525349519">Крај текста</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Изговара актуелно време и датум.</translation>
-<translation id="1902396333223336119">Ћелија</translation>
-<translation id="1905379170753160525">Приказивање листе заглавља</translation>
-<translation id="1912556590115083156">посећени линк</translation>
-<translation id="1913761808037590218">број</translation>
-<translation id="1954623340234317532">Контрола недеље у години</translation>
-<translation id="1964135212174907577">Следећи објекат</translation>
-<translation id="1969092762068865084">јул</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Заглавље реда:</translation>
-<translation id="2002895034995108595">Ресетуј актуелну мапу тастера</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{лева угласта заграда}one{# лева угласта заграда}few{# леве угласте заграде}other{# левих угластих заграда}}</translation>
-<translation id="2045490512405922022">није означено</translation>
-<translation id="20601713649439366">Нема претходног математичког израза.</translation>
-<translation id="207477615537953741">Семантичко тумачење је искључено</translation>
-<translation id="2086961585857038472">Следећа реч</translation>
-<translation id="2089387485033699258">sr</translation>
-<translation id="2091933974477985526">Претходна изменљива област за текст</translation>
-<translation id="2100350898815792233">Сва интерпункција</translation>
-<translation id="2119965627982867824">дугме за промену вредности</translation>
-<translation id="2121067395472282800">приступни тастер:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Промените актуелну табелу Брајеве азбуке са 6 тачака тако што ћете изабрати опцију са листе у наставку.</translation>
-<translation id="2169714232367507776">Клик на актуелну ставку</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{затворена заграда}one{# затворена заграда}few{# затворене заграде}other{# затворених заграда}}</translation>
-<translation id="2199994615414171367">Претходни математички израз</translation>
-<translation id="2223693656926968778">Предузимање радње за актуелну ставку</translation>
-<translation id="225732394367814946">Повећавање брзине говора</translation>
-<translation id="2267945578749931355">Следећи знак</translation>
-<translation id="2281234842553884450">Претходни клизач</translation>
-<translation id="2318372665160196757">Главно</translation>
-<translation id="2329324941084714723">Табла са картицама</translation>
-<translation id="2344193891939537199">Контрола датума и времена</translation>
-<translation id="2359897517538099099">Не у режиму табеле.</translation>
-<translation id="241124561063364910">па</translation>
-<translation id="2417569100218200841">Информације о садржају</translation>
-<translation id="2422937916923936891">Поље за потврду ставке менија</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> је сада нови модификатор за ChromeVox.</translation>
-<translation id="2450814015951372393">Поље за потврду</translation>
-<translation id="2462626033734746142">Група дугмади за избор</translation>
-<translation id="2471138580042810658">Заглавље 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{звездица}one{# звездица}few{# звездице}other{# звездица}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> је ресетован.</translation>
-<translation id="2553108862507765288">граматичка грешка</translation>
-<translation id="257674075312929031">Група</translation>
-<translation id="2582407057977008361">Додатно</translation>
-<translation id="2589102159832527089">Ова страница садржи текст који је аутоматски издвојен из PDF датотеке &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Кликните овде за оригинал.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">са {COUNT,plural, =1{# ставком}one{# ставком}few{# ставке}other{# ставки}}</translation>
-<translation id="2614981083756825552">Math ML распоред</translation>
-<translation id="2626530649491650971">елемент на који може да се кликне</translation>
-<translation id="2628764385451019380">Нема претходног комбинованог оквира.</translation>
-<translation id="2637227747952042642">Математика</translation>
-<translation id="2639750663247012216">ChromeVox модификатор</translation>
-<translation id="2644542693584024604">погрешно написано</translation>
-<translation id="2667291555398229137">Кликните на ставку испод тастера за усмеравање</translation>
-<translation id="2697408785920771974">аутоматско довршавање уметнутог текста</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{отворена заграда}one{# отворена заграда}few{# отворене заграде}other{# отворених заграда}}</translation>
-<translation id="2705875883745373140">Није притиснуто</translation>
-<translation id="2706462751667573066">Нагоре</translation>
-<translation id="2717271541250958000">табла са картицама</translation>
-<translation id="2723001399770238859">аудио</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Проверено</translation>
-<translation id="27527859628328957">Прелазак на следећу ставку која може да се фокусира</translation>
-<translation id="2770781857296573485">Улазак у истраживање група</translation>
-<translation id="2777845298774924149">Изашли сте</translation>
-<translation id="2800204403141299078">Нема више различитих елемената.</translation>
-<translation id="2800780099804980316">Нема претходног заглавља 1. нивоа.</translation>
-<translation id="2811204574343810641">Ред</translation>
-<translation id="2816654101880605877">Нема следећег клизача.</translation>
-<translation id="2841013758207633010">Време</translation>
-<translation id="2843837985843789981">Претходна група</translation>
-<translation id="2844995807198708617">Контекстуални мени</translation>
-<translation id="2849332794118375855">Нема следећег поља за потврду.</translation>
-<translation id="2864481629947106776">Претходни линк</translation>
-<translation id="2873259058405069099">Прелазак на почетак табеле</translation>
-<translation id="2894654529758326923">Информације</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{лева витичаста заграда}one{# лева витичаста заграда}few{# леве витичасте заграде}other{# левих витичастих заграда}}</translation>
-<translation id="2911433807131383493">Отварање ChromeVox водича</translation>
-<translation id="2932083475399492303">Пребацивање типа линије са линије структуре на линију распореда и обрнуто</translation>
-<translation id="2964026537669811554">Група заглавља</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{табулатор}one{# табулатор}few{# табулатора}other{# табулатора}}</translation>
-<translation id="2972078295414139404">Нема претходног посећеног линка.</translation>
-<translation id="2972205263822847197">Опис алатке</translation>
-<translation id="2998131015536248178">Претходни знак</translation>
-<translation id="2999559350546931576">Смањивање регистра</translation>
-<translation id="2999945368667127852">Не постоји виџет за следећу медијску датотеку.</translation>
-<translation id="3012414509011670858">Нема претходног одељка.</translation>
-<translation id="3030432017085518523">Дугме за избор ставке менија</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{апостроф}one{# апостроф}few{# апострофа}other{# апострофа}}</translation>
-<translation id="3046838483509668188">Опције за ChromeVox</translation>
-<translation id="3047143736589213134">Експериментална мапа тастера</translation>
-<translation id="3060756054951570867">Отворен је мени <ph name="TITLE" /></translation>
-<translation id="3078345202707391975">Следеће заглавље 2. нивоа</translation>
-<translation id="3078740164268491126">табела</translation>
-<translation id="3082557070674409251">Кликнуто</translation>
-<translation id="3084806535845658316">нема одјека знакова</translation>
-<translation id="3086746722712840547">белешка</translation>
-<translation id="308895241372589742">Нема следећег математичког израза.</translation>
-<translation id="3090532668523289635">група</translation>
-<translation id="3093176084511590672">Следеће обележје</translation>
-<translation id="3096671415663099226">комбиновани оквир</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Скупљено</translation>
-<translation id="3134461040845705080">само за читање</translation>
-<translation id="3138767756593758860">Приказивање листе обележја</translation>
-<translation id="3143851963874289911">ћелија мреже</translation>
-<translation id="3149472044574196936">Следећи ред</translation>
-<translation id="3155083529632865074">Нема претходног дугмета.</translation>
-<translation id="3163593631834463955">Празно заглавље колоне</translation>
-<translation id="316542773973815724">Навигација</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{размак}one{# размак}few{# размака}other{# размака}}</translation>
-<translation id="320961988183078793">унета је ставка <ph name="TYPE" /></translation>
-<translation id="3223701887221307104">Картица <ph name="NAME" /></translation>
-<translation id="3226035351387556942">поље за потврду</translation>
-<translation id="3229375994964697375">Посећени линк</translation>
-<translation id="323731244387692321">Отварање помоћи за ChromeVox тастатуру</translation>
-<translation id="3241052487511142956">Претходни посећени линк</translation>
-<translation id="3286390186030710347">Клизач</translation>
-<translation id="3299925995433437805">Нема следећег посећеног линка.</translation>
-<translation id="3303384412438961941">Притисните било који тастер да бисте сазнали његов назив. Притиском тастера Ctrl+W затварате истраживач тастатуре.</translation>
-<translation id="3307886118343381874">Прелазак на крај табеле</translation>
-<translation id="3311969765485641742">Притисните Alt+Shift+A да бисте прегледали обавештења</translation>
-<translation id="3312997241656799641">Следећи посећени линк</translation>
-<translation id="3321460131042519426">Омогући прелом реда</translation>
-<translation id="3322936298410871309">Претходно заглавље 1. нивоа</translation>
-<translation id="3323447499041942178">Оквир за текст</translation>
-<translation id="3353420241558113817">{"ar": "арапски",
- "bg": "бугарски",
- "ca": "каталонски",
- "cs": "чешки",
- "da": "дански",
- "de": "немачки",
- "de_CH": "немачки (Швајцарска)",
- "de_DE": "немачки (Немачка)",
- "el": "грчки",
- "en": "енглески",
- "en_CA": "енглески (Канада)",
- "en_GB": "енглески (Уједињено Краљевство)",
- "en_US": "енглески (Сједињене Америчке Државе)",
- "es": "шпански",
- "et": "естонски",
- "fr": "француски",
- "fr_CA": "француски (Канада)",
- "fr_FR": "француски (Француска)",
- "fi": "фински",
- "he": "хебрејски",
- "hi": "хинди",
- "hr": "хрватски",
- "hu": "мађарски",
- "is": "исландски",
- "it": "италијански",
- "ko": "корејски",
- "lt": "литвански",
- "lv": "летонски",
- "nb": "норвешки (бокмал)",
- "nl": "холандски",
- "pl": "пољски",
- "pt": "португалски",
- "ro": "румунски",
- "ru": "руски",
- "sk": "словачки",
- "sl": "словеначки",
- "sr": "српски",
- "sv": "шведски",
- "tr": "турски",
- "vi": "вијетнамски",
- "zh": "кинески",
- "zh_TW": "кинески (традиционални Хан)"}</translation>
-<translation id="3359142382821736686">разделник</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{знак плус}one{# знак плус}few{# знака плус}other{# знакова плус}}</translation>
-<translation id="338583716107319301">Разделник</translation>
-<translation id="3389259863310851658">Претходно поље обрасца</translation>
-<translation id="3390225400784126843">Следећи другачији елемент.</translation>
-<translation id="3392045790598181549">Ставка менија <ph name="NAME" /></translation>
-<translation id="3406283310380167331">Приказивање листе образаца</translation>
-<translation id="3422338090358345848">Отварање истраживача тастатуре</translation>
-<translation id="3457000393508828486">Делимично притиснуто</translation>
-<translation id="3462439746547587373">Дугме <ph name="NAME" /></translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> до <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{десна угласта заграда}one{# десна угласта заграда}few{# десне угласте заграде}other{# десних угластих заграда}}</translation>
-<translation id="3493915602752813531">Нема следећег сидра.</translation>
-<translation id="3494946239022273294">ставка менија</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{знак питања}one{# знак питања}few{# знака питања}other{# знакова питања}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{карет}one{# карет}few{# карета}other{# карета}}</translation>
-<translation id="3568702578574425662">Поље за потврду <ph name="NAME" /> није означено</translation>
-<translation id="3599054940393788245">Није у оквиру вредности за улогу математичког израза</translation>
-<translation id="3616113530831147358">Аудио</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{обрнути полунаводник}one{# обрнути полунаводник}few{# обрнута полунаводника}other{# обрнутих полунаводника}}</translation>
-<translation id="3650317109285159359">поље за потврду ставке менија</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{знак за долар}one{# знак за долар}few{# знака за долар}other{# знакова за долар}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, оквир листе</translation>
-<translation id="3687295507293856493">Предвиђање наслова колоне актуелне ћелије</translation>
-<translation id="3692274950075847560">П:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Контролисање говора</translation>
-<translation id="3716845769494773620">Вишелинијско</translation>
-<translation id="3731746171184829332">Нема претходног заглавља.</translation>
-<translation id="3762198587642264450">Прелазак на крај актуелног реда</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Изашли сте из дијалога.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}few{#}other{#}}</translation>
-<translation id="3801735343383419236">Аутоматско довршавање листе</translation>
-<translation id="3810838688059735925">Видео</translation>
-<translation id="3816633764618089385">Следећа медијска датотека</translation>
-<translation id="3819376190738087562">Нема прелазака.</translation>
-<translation id="385383972552776628">Отварање странице опција</translation>
-<translation id="3856075812838139784">Само за читање</translation>
-<translation id="3887576927692165210">оквир за текст</translation>
-<translation id="3897092660631435901">Мени</translation>
-<translation id="3909320334364316587">Претходно заглавље 6. нивоа</translation>
-<translation id="3914173277599553213">Обавезно</translation>
-<translation id="3962990492275676168">Читање почиње од актуелне локације</translation>
-<translation id="4004802134384979325">означено</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Контрола месеца</translation>
-<translation id="4039983576244166038">Празно заглавље реда</translation>
-<translation id="4042843249978639960">Нема следећег заглавља 2. нивоа.</translation>
-<translation id="4043348641337972076">Нема претходног ARIA обележја.</translation>
-<translation id="4047216625641135770">Ознака</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{ТИЛДА}one{# тилда}few{# тилде}other{# тилда}}</translation>
-<translation id="409334809956508737">Претходни објекат</translation>
-<translation id="4099274309791143834">са подменијем</translation>
-<translation id="4107807507418787238">Нема ћелија испод.</translation>
-<translation id="4116415223832267137">Обавештење</translation>
-<translation id="4147126331795725888">Нема следеће контроле.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{десна витичаста заграда}one{# десна витичаста заграда}few{# десне витичасте заграде}other{# десних витичастих заграда}}</translation>
-<translation id="4158704014418536539">Разликује велика и мала слова.</translation>
-<translation id="4161663686871496107">ChromeVox говорне повратне информације су спремне</translation>
-<translation id="4173994908659439270">Нема следећег изменљивог поља за текст.</translation>
-<translation id="4176463684765177261">Онемогућено</translation>
-<translation id="4188530942454211480">Претходна реченица</translation>
-<translation id="4202186506458631436">Премештање удесно</translation>
-<translation id="4206289001967551965">Унутар табеле</translation>
-<translation id="4215733775853809057">Следећи клизач</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{црта}one{# црта}few{# црте}other{# црта}}</translation>
-<translation id="421884353938374759">бирач боја</translation>
-<translation id="4229646983878045487">датум време</translation>
-<translation id="423334822609210999">Нема ћелија лево.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" />. ниво</translation>
-<translation id="4253168017788158739">Напомена</translation>
-<translation id="4254798249533888099">Стабло</translation>
-<translation id="4255943572433203166">Користите доленаведене опције да бисте прилагодили ChromeVox. Промене одмах ступају на снагу.</translation>
-<translation id="4271220233568730077">Следећи математички израз</translation>
-<translation id="4271521365602459209">Нема више резултата.</translation>
-<translation id="4287520460805643128">Нема следећег чланка.</translation>
-<translation id="4289540628985791613">Преглед</translation>
-<translation id="4300318234632215983">Објављивање URL-а иза линка</translation>
-<translation id="4301352596632316575">има подмени</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{тачка}=3{три тачке}one{# тачка}few{# тачке}other{# тачака}}</translation>
-<translation id="4347461890115250064">Нема следеће листе.</translation>
-<translation id="4367650418938037324">Math ML лист</translation>
-<translation id="4372435075475052704">најмање: <ph name="X" /></translation>
-<translation id="4372705107434148843">Заустављање говора</translation>
-<translation id="4373197658375206385">Нема претходне ставке која није линк.</translation>
-<translation id="4391478986194775161">информације о садржају</translation>
-<translation id="443163561286008705">ресетуј</translation>
-<translation id="4471074325120394300">Нема линкова.</translation>
-<translation id="4476183483923481720">нови ред</translation>
-<translation id="4482330759234983253">Претходна табела</translation>
-<translation id="4491109536499578614">Слика</translation>
-<translation id="4529987814483543472">Класична мапа тастера</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{коса црта}one{# коса црта}few{# косе црте}other{# косих црта}}</translation>
-<translation id="4547556996012970016">Следеће заглавље 5. нивоа</translation>
-<translation id="4562381607973973258">Заглавље</translation>
-<translation id="4591507479202817876">, изабрано</translation>
-<translation id="4597532268155981612">образац</translation>
-<translation id="4597896406374528575">април</translation>
-<translation id="4615592953348396470">Занемарујемо следећи притисак на тастер</translation>
-<translation id="461613135510474570">Реченица</translation>
-<translation id="4647836961514597010">Бирач боја</translation>
-<translation id="4661075872484491155">стабло</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">мрежа</translation>
-<translation id="4693675773662933727">Претходно обележје</translation>
-<translation id="4696413482802371445">Нема следећег заглавља 5. нивоа.</translation>
-<translation id="4729095194763193578">Претходни ред табеле</translation>
-<translation id="4736221692378411923">август</translation>
-<translation id="4740661827607246557">Команде помоћи</translation>
-<translation id="4759716709594980008">Истраживач Chrome ОС тастатуре</translation>
-<translation id="4763296182459741068">Пребачено на дно</translation>
-<translation id="4763480195061959176">видео</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Објављивање наслова актуелне странице</translation>
-<translation id="4826415162591436065">Кретање унапред</translation>
-<translation id="4826604887384865800">Следећи прелазак</translation>
-<translation id="4827410568042294688">избор је опозван</translation>
-<translation id="4842108708071771135">Нема следећег издвојеног цитата.</translation>
-<translation id="4848993367330139335">тајмер</translation>
-<translation id="4850023505158945298">Претходни слични елемент.</translation>
-<translation id="4866956062845190338">ставка менија за избор</translation>
-<translation id="4867316986324544967">Омогућавање TTS евидентирања</translation>
-<translation id="4877261390094455813">Унесите упит за претрагу.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Интерни линк</translation>
-<translation id="4953585991029886728">Измена текста</translation>
-<translation id="4954534434583049121">Претходни издвојени цитат</translation>
-<translation id="4973717656530883744">Најмање <ph name="X" /></translation>
-<translation id="4973762002207131920">Пребачено је на <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">милисекунде</translation>
-<translation id="49787999531187221">ChromeVox је сада неактиван.</translation>
-<translation id="4979404613699303341">Претходно дугме</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, оквир листе</translation>
-<translation id="4983588134362688868">Прелазак на врх странице</translation>
-<translation id="4986606102545753256">Прозор <ph name="NAME" /></translation>
-<translation id="4993152509206108683">Брзина у процентима: <ph name="PERCENT" /></translation>
-<translation id="4996716799442435517">Визуелно</translation>
-<translation id="4997282455736854877">Дугме за избор <ph name="NAME" /> је изабрано</translation>
-<translation id="4997475792277222884">Нема следеће ставке која није линк.</translation>
-<translation id="5000760171916499057">Нема образаца.</translation>
-<translation id="5005670136041063723">Нема више сличних елемената.</translation>
-<translation id="501473567976723023">јануар</translation>
-<translation id="5041394372352067729">Померање екрана са Брајевом азбуком у врх странице</translation>
-<translation id="5042770794184672516">Повећавање јачине звука говора</translation>
-<translation id="5050015258024679800">Претходно заглавље 4. нивоа</translation>
-<translation id="5054047268577924192">Претходна ставка листе</translation>
-<translation id="5078661581131202757">Избор датотека</translation>
-<translation id="5080758118274074384">кликнуто двапут</translation>
-<translation id="5098541983634824365">Напуштање мреже.</translation>
-<translation id="5102981729317424850">Трака с алаткама</translation>
-<translation id="5105050547967751155">обавезно</translation>
-<translation id="5110983769041734144">Нема претходног поља обрасца.</translation>
-<translation id="5111640677200759579">Заглавље колоне</translation>
-<translation id="5117636609870536415">имејл</translation>
-<translation id="5136967254288895616">Нема претходног линка.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, није изабрано</translation>
-<translation id="5183440668879371625">Претходни ред на Брајевој азбуци</translation>
-<translation id="5184944171021383281">Нема следећег поља обрасца.</translation>
-<translation id="5189244881767082992">Ред</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> је већ додељен команди.</translation>
-<translation id="5205493599117157272">Листа за <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Нема следећег дугмета за избор.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Објекат</translation>
-<translation id="5304943142864553931">картица <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">уклоњено:</translation>
-<translation id="5320727453979144100">Лепљиви режим је омогућен</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{зарез}one{# зарез}few{# зареза}other{# зареза}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, оквир за текст</translation>
-<translation id="5330443287809544590">Линк <ph name="NAME" /></translation>
-<translation id="5336381510091010269">аутоматско довршавање уметнутог текста+листе</translation>
-<translation id="536031132345979795">Прескакање уназад током непрекидног читања</translation>
-<translation id="5368000168321181111">Звучна обавештења су искључена</translation>
-<translation id="5374320867641260420">Нема следећег дугмета.</translation>
-<translation id="5382299583965267720">Нема следећег заглавља 1. нивоа.</translation>
-<translation id="5402367795255837559">Брајева азбука</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{тачка и зарез}one{# тачка и зарез}few{# тачке и зареза}other{# тачака и зареза}}</translation>
-<translation id="5411891038905756502">Нема претходне тачке преласка.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{знак „мање од“}one{# знак „мање од“}few{# знака „мање од“}other{# знакова „мање од“}}</translation>
-<translation id="5455441614648621694">Комплементарно</translation>
-<translation id="5485036206801896268">Нема претходне слике.</translation>
-<translation id="5486947920110100234">Нема следеће тачке преласка.</translation>
-<translation id="549602578321198708">Реч</translation>
-<translation id="5500932716852106146">Нема претходног изменљивог поља за текст.</translation>
-<translation id="5502713021410870035">септембар</translation>
-<translation id="5507663321906818013">Отклањање грешака при мерењу перформанси</translation>
-<translation id="5518443085409638729">Постави показивач између знакова при измени текста (као Mac OS X).</translation>
-<translation id="552195134157544755">Дугме за избор</translation>
-<translation id="5534303576632885660">header</translation>
-<translation id="5546092960038624944">Нема претходног заглавља 5. нивоа.</translation>
-<translation id="556042886152191864">Дугме</translation>
-<translation id="5561345396546889625">Следећа листа</translation>
-<translation id="5562645715554321347">група наслова</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Измените текст, унос за имејл</translation>
-<translation id="5597170376237141345">Следеће поље за потврду</translation>
-<translation id="5597933780944041114">Нема следећег заглавља.</translation>
-<translation id="5598905979683743333">Није изабрано дугме за избор <ph name="NAME" /></translation>
-<translation id="5601172225407283979">Обављање подразумеване радње</translation>
-<translation id="5608798115546226984">Аутоматско довршавање уметнутог текста</translation>
-<translation id="561939826962581046">време</translation>
-<translation id="5623778242535476823">дугме за избор</translation>
-<translation id="5623842676595125836">Евиденција</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Нема претходне табеле.</translation>
-<translation id="5655682562155942719">Команде за прелазак</translation>
-<translation id="56637627897541303">Област за текст</translation>
-<translation id="5678161956734658133">млед</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Обележје</translation>
-<translation id="5683155931978483559">Претходно поље за потврду</translation>
-<translation id="5684277895745049190">Листа</translation>
-<translation id="5700650669149824506">Нема претходног заглавља 4. нивоа.</translation>
-<translation id="5709192780268610569">Нема дугог описа</translation>
-<translation id="5712244464475377681">искачуће дугме</translation>
-<translation id="5712338278108304766">Следећа колона табеле</translation>
-<translation id="571866080859340309">Истраживање група</translation>
-<translation id="5728409797179002635">Није пронађена ниједна табела.</translation>
-<translation id="5748623122140342504">Претходно заглавље 5. нивоа</translation>
-<translation id="5750633686117194034">Није притиснут ниједан модификатор; притисните и задржите један модификатор или више њих; подигните прсте када завршите и чућете звук подешавања тастера. Притисните тастер Tab да бисте изашли.</translation>
-<translation id="5788275253279308023">прозор Без архивирања, картица <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Побољшај одређене сајтове (попут Google претраге).</translation>
-<translation id="5819072574982403430">Ставка стабла</translation>
-<translation id="5826479389509458994"><ph name="ROW" />. ред <ph name="COL" />. колона</translation>
-<translation id="5850707923114094062">Померање уназад</translation>
-<translation id="5851548754964597211">Листа картица</translation>
-<translation id="5859752971144398932">Изашли сте из функције Пронађи на страници.</translation>
-<translation id="5866042630553435010">Делимично проверено</translation>
-<translation id="5869546221129391014">Мрежа</translation>
-<translation id="5876817486144482042">Смањивање јачине звука говора</translation>
-<translation id="5887397643266327462">Титлови на Брајевој азбуци су омогућени.</translation>
-<translation id="5891934789323004067">Табела</translation>
-<translation id="5919442531159595654">копирај.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{знак једнакости}one{# знак једнакости}few{# знака једнакости}other{# знакова једнакости}}</translation>
-<translation id="5939518447894949180">Ресетуј</translation>
-<translation id="5948123859135882163">Пребацујте тумачење математичких израза са структуралног на семантичко и обрнуто</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Дијалог</translation>
-<translation id="5963413905009737549">Одељак</translation>
-<translation id="5968607524793740041">Прикажи контекстуални мени</translation>
-<translation id="5983179082906765664">Повећавање грануларности навигације</translation>
-<translation id="5999630716831179808">Гласови</translation>
-<translation id="6000417740266304866">Промените актуелну табелу Брајеве азбуке са 8 тачака тако што ћете изабрати опцију са листе у наставку.</translation>
-<translation id="6006050241733874051">Образац</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{обрнута коса црта}one{# обрнута коса црта}few{# обрнуте косе црте}other{# обрнутих косих црта}}</translation>
-<translation id="6037602951055904232">Померање унапред</translation>
-<translation id="611827076493383239">посећено</translation>
-<translation id="6119955456199054975">Крај ћелије.</translation>
-<translation id="6122013438240733403">дугме</translation>
-<translation id="6129953537138746214">Размак</translation>
-<translation id="6142308968191113180">Заглавље 4</translation>
-<translation id="6169420925157477918">Слика са дугим описом</translation>
-<translation id="6172087735260766220">Приступачан текст из PDF документа заштићеног од копирања није доступан.</translation>
-<translation id="6186305613600865047">Прелазак на дно странице</translation>
-<translation id="6193330012414963395">пре подне/по подне</translation>
-<translation id="622484624075952240">Надоле</translation>
-<translation id="6236061028292614533">Следеће заглавље</translation>
-<translation id="6254901459154107917">Следећа изменљива област за текст</translation>
-<translation id="6259464875943891919">Изашли сте из контејнера <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Следећи слични елемент.</translation>
-<translation id="6282062888058716985">навигација</translation>
-<translation id="6290434000785343030">Нема следећег комбинованог оквира.</translation>
-<translation id="6307969636681130414">Притиснуто</translation>
-<translation id="6324551002951139333">Откривена је граматичка грешка</translation>
-<translation id="6348657800373377022">Комбиновани оквир</translation>
-<translation id="6355910664415701303">Нема претходне ставке листе.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Претходно заглавље</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Нема претходног дугмета за избор.</translation>
-<translation id="6414968628640960377">Претходни другачији елемент.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{две тачке}one{# знак две тачке}few{# знака две тачке}other{# знакова две тачке}}</translation>
-<translation id="6438968337250688271">Мени <ph name="NAME" /></translation>
-<translation id="6444046323172968959">Дијалог обавештења</translation>
-<translation id="6459511626086141404">Равна мапа тастера</translation>
-<translation id="6468049171101508116">Следеће дугме</translation>
-<translation id="6491972999578897419">Промените актуелни глас тако што ћете изабрати неку од опција са листе у наставку.</translation>
-<translation id="6508059270146105198">Померање екрана са Брајевом азбуком на дно странице</translation>
-<translation id="6536864053412760904">Math ML токен</translation>
-<translation id="6550720799683018100">Промените актуелну мапу тастера тако што ћете изабрати неку од опција са листе у наставку.</translation>
-<translation id="6561818612645211875">Прелазак на почетак актуелног реда</translation>
-<translation id="6587021927234520429">Нема следећег заглавља 4. нивоа.</translation>
-<translation id="6601344353291556895">Омогући детаљне описе.</translation>
-<translation id="6615602925644411249">Пронађи на страници.</translation>
-<translation id="6633350132811819843">Нема следеће табеле.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">Трака напретка</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Документ</translation>
-<translation id="6697092096875747123">Претходни комбиновани оквир</translation>
-<translation id="6714813999819678458">Претходно заглавље 2. нивоа</translation>
-<translation id="6716505898850596801">Модификујући тастери</translation>
-<translation id="671916444866103745">Нема следећег ARIA обележја.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, комбиновани оквир</translation>
-<translation id="6735257939857578167">са <ph name="NUM" /> ставке(и)</translation>
-<translation id="6736510033526053669">картица је направљена</translation>
-<translation id="675895815784134693">трака напретка</translation>
-<translation id="6786800275320335305">Чланак</translation>
-<translation id="6787839852456839824">Тастерске пречице</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Подножје</translation>
-<translation id="6871161210040114857">Занемарује велика и мала слова.</translation>
-<translation id="6877435256196695200">Нема следеће слике.</translation>
-<translation id="6897341342232909480">Померање улево</translation>
-<translation id="6901540140423170855">датум</translation>
-<translation id="6910211073230771657">Избрисано</translation>
-<translation id="6911965441508464308">Нема ћелија изнад.</translation>
-<translation id="6919104639734799681">Приказивање листе табела</translation>
-<translation id="6964088412282673743">Нема претходне контроле.</translation>
-<translation id="6996566555547746822">Следећи комбиновани оквир</translation>
-<translation id="7005146664810010831">Није пронађен ниједан URL</translation>
-<translation id="7010712454773919705">ChromeVox модификујући тастер</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Претходна листа</translation>
-<translation id="7041173719775863268">Крај избора</translation>
-<translation id="7095834689119144465">Измена само нумеричког текста</translation>
-<translation id="7096001299300236431">Претходна медијска датотека</translation>
-<translation id="7116595520562830928">више редова</translation>
-<translation id="712735679809149106">одјек речи</translation>
-<translation id="713824876195128146">Следећи издвојени цитат</translation>
-<translation id="7161771961008409533">Искачуће дугме</translation>
-<translation id="7167657087543110">одјек знакова</translation>
-<translation id="7170733337935166589">Прескакање унапред током непрекидног читања</translation>
-<translation id="7181697990050180700">Прилагодите тастерске пречице за честе команде тако што ћете их унети у одговарајућа поља у наставку.</translation>
-<translation id="7203150201908454328">Проширено</translation>
-<translation id="7210211103303402262">минути</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">ред</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Заглавље</translation>
-<translation id="7241683698754534149">Отварање дугог описа на новој картици</translation>
-<translation id="7248671827512403053">Апликација</translation>
-<translation id="725969808843520477">Следеће дугме за избор</translation>
-<translation id="7269119382257320590">Без интерпункције</translation>
-<translation id="7273174640290488576">Празно</translation>
-<translation id="7285387653379749618">Табеле</translation>
-<translation id="7289186959554153431">Заглавље 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">ставка стабла</translation>
-<translation id="731576946540457939">Титлови на Брајевој азбуци су онемогућени.</translation>
-<translation id="7318872822751139669">Мењајте фокус помоћу миша.</translation>
-<translation id="7322388933135261569">фебруар</translation>
-<translation id="7332592614823088566">Ред <ph name="ROWINDEX" /> од <ph name="ROWTOTAL" />, колона <ph name="COLINDEX" /> од <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">има искачући прозор</translation>
-<translation id="7356165926712028380">Пребаци на Брајеву азбуку са 8 тачака</translation>
-<translation id="7362871137496673139">Нема претходног заглавља 2. нивоа.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{знак &amp;}one{# знак &amp;}few{# знака &amp;}other{# знакова &amp;}}</translation>
-<translation id="737396357417333429">клик</translation>
-<translation id="7374104575779636480">Напуштање табеле.</translation>
-<translation id="739763518212184081">Претходни ред</translation>
-<translation id="7400575256015741911">Откривена је грешка у куцању</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">почетак реда</translation>
-<translation id="7434509671034404296">Програмер</translation>
-<translation id="7439060726180460871">Каталог</translation>
-<translation id="744163271241493234">лозинка</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Ушли сте у дијалог</translation>
-<translation id="7532613204005497612">јун</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, клизач</translation>
-<translation id="7586163296341959563">налепи.</translation>
-<translation id="7596919493010894443">избор је обрисан</translation>
-<translation id="7604026522577407655">Прелазак на почетак актуелне колоне</translation>
-<translation id="7604451927827590395">наслов</translation>
-<translation id="7609342235116740824">Објављивање URL-а актуелне странице</translation>
-<translation id="7609363189280667021">Укључивање/искључивање титлова на Брајевој азбуци</translation>
-<translation id="762020119231868829">Паузира све тренутно пуштене виџете за медијске датотеке</translation>
-<translation id="7625690649919402823">Следећа табела</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), <ph name="GRADE" />. ниво</translation>
-<translation id="7641134354185483015">Нема претходног заглавља 3. нивоа.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, оквир за текст</translation>
-<translation id="7663318257180412551">Заглавље 2</translation>
-<translation id="7674576868851035240">Следећи линк</translation>
-<translation id="7674768236845044097">ознака</translation>
-<translation id="7684431668231950609">Измените текст, унос за URL</translation>
-<translation id="7685589220304187312">трака с алаткама</translation>
-<translation id="7693840228159394336">Претходно дугме за избор</translation>
-<translation id="7701196182766842984">аутоматско довршавање листе</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, оквир за лозинку</translation>
-<translation id="7805247615045262757">подразумевана навигација</translation>
-<translation id="7805768142964895445">Статус</translation>
-<translation id="7810781339813764006">Следећа група</translation>
-<translation id="7819187121850078213">прозор, картица <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">октобар</translation>
-<translation id="7839679365527550018">Претходна реч</translation>
-<translation id="7851816175263618915">Делимична интерпункција</translation>
-<translation id="7870596830398826354">Math ML стабло</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Укључујте и искључујте ChromeVox Classic.</translation>
-<translation id="7895896691902835279">Непознати линк</translation>
-<translation id="7927711904086083099">Није изабрано</translation>
-<translation id="7935627501098484003">Контрола времена</translation>
-<translation id="7939428177581522200">додато у избор</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{знак @}one{# знак @}few{# знака @}other{# знакова @}}</translation>
-<translation id="7965147473449754028">мени је затворен</translation>
-<translation id="7974390230414479278">Ставка менија</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{знак узвика}one{# знак узвика}few{# знака узвика}other{# знакова узвика}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{знак навода}one{# знак навода}few{# знака навода}other{# знакова навода}}</translation>
-<translation id="8033827949643255796">изабрано</translation>
-<translation id="8035962149453661158">највише: <ph name="X" /></translation>
-<translation id="8042761080832772327">Измените текст, унос за претрагу</translation>
-<translation id="8049189770492311300">Тајмер</translation>
-<translation id="8065607967589909823">Избор је</translation>
-<translation id="8066678206530322333">Банер</translation>
-<translation id="8110647606445335195">Нема ARIA обележја.</translation>
-<translation id="8153880621934657047">Нисте унутар табеле.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{доња црта}one{# доња црта}few{# доње црте}other{# доњих црта}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">исеци.</translation>
-<translation id="8199231515320852133">Објављивање заглавља актуелне ћелије</translation>
-<translation id="820417203470636242">Празна ћелија.</translation>
-<translation id="8215202828671303819">Вишеструки избор</translation>
-<translation id="8276439074553447000">Прелазак на претходну ставку која може да се фокусира</translation>
-<translation id="8278417001922463147">Нема претходног чланка.</translation>
-<translation id="8283603667300770666">Следеће поље обрасца</translation>
-<translation id="831207808878314375">Дефиниција</translation>
-<translation id="8313653172105209786">каталог</translation>
-<translation id="8344569602005188545">сати</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{знак „тараба“}one{# знак „тараба“}few{# знака „тараба“}other{# знакова „тараба“}}</translation>
-<translation id="8374154622594089836">месец</translation>
-<translation id="8378855320830505539">Област</translation>
-<translation id="8382679411218029383">Аутоматско довршавање уметнутог текста и листе</translation>
-<translation id="8428603554127842284"><ph name="DEPTH" />. ниво</translation>
-<translation id="842922884199979200">Нема следећег заглавља 3. нивоа.</translation>
-<translation id="8430049249787218991">трака менија</translation>
-<translation id="844681116543532394">Нема претходног поља за потврду.</translation>
-<translation id="8455868257606149352">Највише <ph name="X" /></translation>
-<translation id="84575901236241018">има приступну шифру, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Смањивање грануларности навигације</translation>
-<translation id="8520472399088452386">Дугме за промену вредности</translation>
-<translation id="8538744478902126321">Предвиђање наслова реда актуелне ћелије</translation>
-<translation id="8540054775867439484">Пребачено на врх</translation>
-<translation id="8548973727659841685">Знак</translation>
-<translation id="8561322612995434619">има искачући прозор</translation>
-<translation id="8571096049907249734">вишеизб</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Следећа ставка листе</translation>
-<translation id="860150890330522909">Поље за потврду <ph name="NAME" /> је означено</translation>
-<translation id="8606621670302093223">Контрола датума</translation>
-<translation id="8631359288236106450">број изабраних ставки је <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Објављивање координата актуелне ћелије</translation>
-<translation id="8650576015643545550">Нема претходне листе.</translation>
-<translation id="8653031188082306838">URL</translation>
-<translation id="8653646212587894517">Приказивање листе линкова</translation>
-<translation id="8664519043722036194">секундe</translation>
-<translation id="867187640362843212">Заглавље 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{усправна црта}one{# усправна црта}few{# усправне црте}other{# усправних црта}}</translation>
-<translation id="8735450637152821465">Почетак избора</translation>
-<translation id="8743786158317878347">уђите у структурирани садржај, попут табела</translation>
-<translation id="8747966237988593539">Уређена листа</translation>
-<translation id="8759334257841767240">Нема следећег линка.</translation>
-<translation id="8767968232364267681">Следеће заглавље 4. нивоа</translation>
-<translation id="8770473310765924354">изађите из структурираног садржаја, попут табела</translation>
-<translation id="8791025954632646584">Семантичко тумачење је укључено</translation>
-<translation id="8796411681063377102">Следеће заглавље 3. нивоа</translation>
-<translation id="8808582214901541005">март</translation>
-<translation id="8825828890761629845">банер</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Притисните нагоре или надоле да бисте прегледали команде и притисните Enter за активацију</translation>
-<translation id="8864099967139188018">Нема следећег заглавља 6. нивоа.</translation>
-<translation id="8882002077197914455">Заглавље реда</translation>
-<translation id="8896347895970027998">Активирање или деактивирање ChromeVox-а.</translation>
-<translation id="8898516272131543774">Циклични одјек интерпункције</translation>
-<translation id="8900148057318340779">Тастер за префикс</translation>
-<translation id="8908714597367957477">заглавље колоне</translation>
-<translation id="8931936695772494138">Празна заглавља</translation>
-<translation id="8937112856099038376">интерни линк</translation>
-<translation id="8940925288729953902">Модификујући тастери</translation>
-<translation id="8943175951035496220">Нема ћелија десно.</translation>
-<translation id="8978496506222343566">објашњење</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Нема табела.</translation>
-<translation id="9040132695316389094">Заглавље 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Укључивање/искључивање виџета за претрагу</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">уклоњено из избора</translation>
-<translation id="9082874451376019682">Нема претходног клизача.</translation>
-<translation id="9089864840575085222">Циклични одјек уноса</translation>
-<translation id="9107530006868467849">Не постоји виџет за претходну медијску датотеку.</translation>
-<translation id="9108370397979208512">математички</translation>
-<translation id="9108589040018540527">трака за померање</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{знак за проценат}one{# знак за проценат}few{# знака за проценат}other{# знакова за проценат}}</translation>
-<translation id="9115913704608474258">новембар</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">одељак</translation>
-<translation id="9151211641321628915">Објављује кратак опис актуелног положаја</translation>
-<translation id="9153606228985488238">Регистар у процентима: <ph name="PERCENT" /></translation>
-<translation id="9160096769946561184">Прелазак на крај актуелне колоне</translation>
-<translation id="9173115498289768110">Јачина звука у процентима: <ph name="PERCENT" /></translation>
-<translation id="9178973770513562274">Користите тастере са стрелицама нагоре и надоле за прегледање или куцајте да бисте претраживали.</translation>
-<translation id="9192904702577636854">Покретни текст</translation>
-<translation id="9212322457209634662">Нема следећег одељка.</translation>
-<translation id="930275611743429116">Започните или завршите избор.</translation>
-<translation id="948171205378458592">Смањивање брзине говора</translation>
-<translation id="962913030769097253">Следеће заглавље 1. нивоа</translation>
-<translation id="973955474346881951">Омогућавање/онемогућавање лепљивог режима</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sv.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sv.xtb
deleted file mode 100644
index ed3e3fbbba3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sv.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="sv">
-<translation id="1012173283529841972">Post i lista</translation>
-<translation id="1013742170491673792">sökfält</translation>
-<translation id="1023866615269196768">Består av flera sammanfogade celler.</translation>
-<translation id="1025074108959230262">Låsta knappar har inaktiverats</translation>
-<translation id="1031961866430398710">sedan</translation>
-<translation id="1044777062731150180">Inga rubriker</translation>
-<translation id="106222400312645156">radrubrik</translation>
-<translation id="1065552602950927991">Ogiltig indata</translation>
-<translation id="1082209053475788238">Det finns ingen föregående rubrik på nivå 6.</translation>
-<translation id="1088219014394087294">Det finns inga rubriker.</translation>
-<translation id="1106741348836243114">Aktivera eller inaktivera ljudsignaler (ljudikoner).</translation>
-<translation id="1120743664840974483">{"a": "Adam", "b": "Bertil", "c": "Cesar", "d": "David", "e": "Erik", "f": "Filip", "g": "Gustav", "h": "Helge", "i": "Ivar", "j": "Johan","k": "Kalle", "l": "Ludvig", "m": "Martin", "n": "Niklas", "o": "Olof","p": "Petter", "q": "Quintus", "r": "Rudolf", "s": "Sigurd", "t": "Tore", "u": "Urban", "v": "Viktor", "w": "Wilhelm","x": "Xerxes", "y": "Yngve", "z": "Zäta", "å": "Åke", "ä": "Ärlig", "ö": "Östen"}</translation>
-<translation id="113582498867142724"><ph name="TAG" />-samling med <ph name="NUM" /> objekt</translation>
-<translation id="1155043339247954670">Det finns inga fler poster i listan.</translation>
-<translation id="1157782847298808853">Tangentbordshjälp</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, kombinationsruta</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, menyalternativ, med undermeny</translation>
-<translation id="1177863135347784049">Anpassad</translation>
-<translation id="1188858454923323853">kompletterande</translation>
-<translation id="1206619573307042055">markör</translation>
-<translation id="1213216066620407844">ChromeVox – ger röst åt Chrome</translation>
-<translation id="1229276918471378188">Föregående hopp</translation>
-<translation id="1237866625126425153">alternativknappsgrupp</translation>
-<translation id="1251750620252348585">Nästa rubrik på nivå 6</translation>
-<translation id="1275718070701477396">Markerad</translation>
-<translation id="1319608975892113573">Det finns inget föregående citatblock.</translation>
-<translation id="1321576897702511272">Dölj hjälpen för ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> av <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">eko för tecken och ord</translation>
-<translation id="1339428534620983148">Föregående tabellkolumn</translation>
-<translation id="1342835525016946179">artikel</translation>
-<translation id="1346748346194534595">Höger</translation>
-<translation id="136718599399906424">Nästa tabellrad</translation>
-<translation id="1383876407941801731">Sök</translation>
-<translation id="1385214448885562192">Tryck Retur om du vill godkänna, Esc om du vill avbryta, ned för nästa och upp för föregående.</translation>
-<translation id="1396114365388024581">fliklista</translation>
-<translation id="1439316808600711881">region</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, lösenordsruta</translation>
-<translation id="1467432559032391204">Vänster</translation>
-<translation id="1474557363159888097">Det finns inget föregående ankare.</translation>
-<translation id="1502086903961450562">Föregående bild</translation>
-<translation id="1506187449813838456">Öka tonhöjden</translation>
-<translation id="151784044608172266">Nästa mening</translation>
-<translation id="1524531499102321782">Punktskrift på nästa rad</translation>
-<translation id="1546370775711804143">Rullningslist</translation>
-<translation id="1559739829547075274">Navigera bakåt</translation>
-<translation id="1571643229714746283">ChromeVox har aktiverats</translation>
-<translation id="158493514907962286">december</translation>
-<translation id="1594072653727561613">meny</translation>
-<translation id="1610130962244179598">Byt till punktskrift med sex punkter</translation>
-<translation id="1611168825862729585">Kolumnrubrik:</translation>
-<translation id="1613476421962910979">Ljudikoner har aktiverats</translation>
-<translation id="1618597272655350600">Ger en komplett beskrivning av den aktuella positionen</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{större än-tecken}other{# större än-tecken}}</translation>
-<translation id="1653266918374749391">Föregående rubrik på nivå 3</translation>
-<translation id="1659072772017912254">Inte markerat</translation>
-<translation id="1669290819662866522">vecka</translation>
-<translation id="1674262202423278359">Navigering med ChromeVox</translation>
-<translation id="16777221443363124">Menyfält</translation>
-<translation id="1692077714702418899">rad i strukturen</translation>
-<translation id="1700517974991662022">Har besökts</translation>
-<translation id="1722567105086139392">Länk</translation>
-<translation id="1727806147743597030">sidfot</translation>
-<translation id="174268867904053074">Nästa bild</translation>
-<translation id="1781173782405573156">Pass through-tangent</translation>
-<translation id="1787176709638001873">Lösenordsinmatning</translation>
-<translation id="1810107444790159527">Listruta</translation>
-<translation id="1828385960365606039">maj</translation>
-<translation id="1834891354138622109">Kolumn</translation>
-<translation id="1865601187525349519">Slutet på texten</translation>
-<translation id="1876229593313240038">dok</translation>
-<translation id="188130072164734898">Säg aktuell tid och aktuellt datum.</translation>
-<translation id="1902396333223336119">Cell</translation>
-<translation id="1905379170753160525">Visa rubriklistan</translation>
-<translation id="1912556590115083156">besökt länk</translation>
-<translation id="1913761808037590218">sifferfält</translation>
-<translation id="1954623340234317532">Inmatning av vecka</translation>
-<translation id="1964135212174907577">Nästa objekt</translation>
-<translation id="1969092762068865084">juli</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Radrubrik:</translation>
-<translation id="2002895034995108595">Återställ aktuell tangentuppsättning</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{vänster hakparentes}other{# vänster-hakparenteser}}</translation>
-<translation id="2045490512405922022">inte markerad</translation>
-<translation id="20601713649439366">Det finns inget föregående matematiskt uttryck.</translation>
-<translation id="207477615537953741">Semantisk tolkning inaktiverad</translation>
-<translation id="2086961585857038472">Nästa ord</translation>
-<translation id="2089387485033699258">se</translation>
-<translation id="2091933974477985526">Föregående redigerbara textområde</translation>
-<translation id="2100350898815792233">Alla skiljetecken</translation>
-<translation id="2119965627982867824">snurrknapp</translation>
-<translation id="2121067395472282800">snabbtangent:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Ändra den aktuella tabellen för punktskrift med sex punkter genom att välja ett alternativ i listan nedan.</translation>
-<translation id="2169714232367507776">Klicka på det aktuella objektet</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{högerparentes}other{# högerparenteser}}</translation>
-<translation id="2199994615414171367">Föregående matematiska uttryck</translation>
-<translation id="2223693656926968778">Vidta åtgärd för det aktuella objektet</translation>
-<translation id="225732394367814946">Öka talhastigheten</translation>
-<translation id="2267945578749931355">Nästa tecken</translation>
-<translation id="2281234842553884450">Föregående skjutreglage</translation>
-<translation id="2318372665160196757">Huvud</translation>
-<translation id="2329324941084714723">Flikpanel</translation>
-<translation id="2344193891939537199">Inmatning av datum och tid</translation>
-<translation id="2359897517538099099">Inte i tabelläge.</translation>
-<translation id="241124561063364910">följt av</translation>
-<translation id="2417569100218200841">Innehållsinformation</translation>
-<translation id="2422937916923936891">Kryssruta för menyalternativ</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> är nu den nya ChromeVox-specialtangenten.</translation>
-<translation id="2450814015951372393">Kryssruta</translation>
-<translation id="2462626033734746142">Alternativknappsgrupp</translation>
-<translation id="2471138580042810658">Rubrik 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{asterisk}other{# asterisker}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> har återställts.</translation>
-<translation id="2553108862507765288">grammatiskt fel</translation>
-<translation id="257674075312929031">Grupp</translation>
-<translation id="2582407057977008361">Sidopanel</translation>
-<translation id="2589102159832527089">Den här sidan innehåller text som extraherats automatiskt från PDF-filen &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Klicka här om du vill öppna originalet.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">med {COUNT,plural, =1{# objekt}other{# objekt}}</translation>
-<translation id="2614981083756825552">Math ML-layout</translation>
-<translation id="2626530649491650971">klickbart</translation>
-<translation id="2628764385451019380">Det finns ingen föregående kombinationsruta.</translation>
-<translation id="2637227747952042642">Matematiskt</translation>
-<translation id="2639750663247012216">ChromeVox-specialtangent</translation>
-<translation id="2644542693584024604">felstavat</translation>
-<translation id="2667291555398229137">Klicka på objektet under en markörhämtare</translation>
-<translation id="2697408785920771974">autoslutförande på raden</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{vänsterparentes}other{# vänsterparenteser}}</translation>
-<translation id="2705875883745373140">Inte nedtryckt</translation>
-<translation id="2706462751667573066">Upp</translation>
-<translation id="2717271541250958000">flikpanel</translation>
-<translation id="2723001399770238859">ljud</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Markerat</translation>
-<translation id="27527859628328957">Hoppa till nästa fokuserbara objekt</translation>
-<translation id="2770781857296573485">Börja utforska grupper</translation>
-<translation id="2777845298774924149">Stängdes</translation>
-<translation id="2800204403141299078">Inga flera olika element.</translation>
-<translation id="2800780099804980316">Det finns ingen föregående rubrik på nivå 1.</translation>
-<translation id="2811204574343810641">Rad</translation>
-<translation id="2816654101880605877">Det finns inga fler skjutreglage.</translation>
-<translation id="2841013758207633010">Tid</translation>
-<translation id="2843837985843789981">Föregående grupp</translation>
-<translation id="2844995807198708617">Snabbmeny</translation>
-<translation id="2849332794118375855">Det finns inga fler kryssrutor.</translation>
-<translation id="2864481629947106776">Föregående länk</translation>
-<translation id="2873259058405069099">Till början av tabellen</translation>
-<translation id="2894654529758326923">Information</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{vänster klammerparentes}other{# vänster-klammerparenteser}}</translation>
-<translation id="2911433807131383493">Öppna självstudierna för ChromeVox</translation>
-<translation id="2932083475399492303">Byt mellan rader i strukturen och rader i layouten</translation>
-<translation id="2964026537669811554">Rubrikgrupp</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{tabbtecken}other{# tabbtecken}}</translation>
-<translation id="2972078295414139404">Det finns inga länkar som har besökts tidigare.</translation>
-<translation id="2972205263822847197">Beskrivning</translation>
-<translation id="2998131015536248178">Föregående tecken</translation>
-<translation id="2999559350546931576">Minska tonhöjden</translation>
-<translation id="2999945368667127852">Det finns ingen annan mediewidget.</translation>
-<translation id="3012414509011670858">Det finns inget föregående avsnitt.</translation>
-<translation id="3030432017085518523">Alternativknapp för menyalternativ</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrof}other{# apostrofer}}</translation>
-<translation id="3046838483509668188">Alternativ för ChromeVox</translation>
-<translation id="3047143736589213134">Experimentell tangentuppsättning</translation>
-<translation id="3060756054951570867">Menyn <ph name="TITLE" /> har öppnats</translation>
-<translation id="3078345202707391975">Nästa rubrik på nivå 2</translation>
-<translation id="3078740164268491126">tabell</translation>
-<translation id="3082557070674409251">Klickat</translation>
-<translation id="3084806535845658316">inget eko vid inmatning</translation>
-<translation id="3086746722712840547">anm</translation>
-<translation id="308895241372589742">Det finns inga fler matematiska uttryck.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Nästa landmärke</translation>
-<translation id="3096671415663099226">kombinationsruta</translation>
-<translation id="3104705064753753826">varnruta</translation>
-<translation id="3109724472072898302">Komprimerat</translation>
-<translation id="3134461040845705080">skrivskydd</translation>
-<translation id="3138767756593758860">Visa listan över landmärken</translation>
-<translation id="3143851963874289911">cell</translation>
-<translation id="3149472044574196936">Nästa rad</translation>
-<translation id="3155083529632865074">Det finns ingen föregående knapp.</translation>
-<translation id="3163593631834463955">Tom kolumnrubrik</translation>
-<translation id="316542773973815724">Navigering</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{blanksteg}other{# blanksteg}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> har angetts</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, flik</translation>
-<translation id="3226035351387556942">kryssruta</translation>
-<translation id="3229375994964697375">Besökt länk</translation>
-<translation id="323731244387692321">Öppna tangentbordshjälpen för ChromeVox</translation>
-<translation id="3241052487511142956">Föregående länk som har besökts</translation>
-<translation id="3286390186030710347">Skjutreglage</translation>
-<translation id="3299925995433437805">Det finns inga fler länkar som har besökts.</translation>
-<translation id="3303384412438961941">Tryck på valfri tangent om du vill veta vad den heter. Ctrl + W stänger tangentbordsutforskaren.</translation>
-<translation id="3307886118343381874">Flytta till slutet av tabellen</translation>
-<translation id="3311969765485641742">Tryck på Alt+Skift+A om du vill granska varningar</translation>
-<translation id="3312997241656799641">Nästa länk som har besökts</translation>
-<translation id="3321460131042519426">Aktivera radbrytning</translation>
-<translation id="3322936298410871309">Föregående rubrik på nivå 1</translation>
-<translation id="3323447499041942178">Textruta</translation>
-<translation id="3353420241558113817">{"ar": "arabiska",
- "bg": "bulgariska",
- "ca": "katalanska",
- "cs": "tjeckiska",
- "da": "danska",
- "de": "tyska",
- "de_CH": "tyska (Schweiz)",
- "de_DE": "tyska (Tyskland)",
- "el": "grekiska",
- "en": "engelska",
- "en_CA": "engelska (Kanada)",
- "en_GB": "engelska (Storbritannien)",
- "en_US": "engelska (USA)",
- "es": "spanska",
- "et": "estniska",
- "fr": "franska",
- "fr_CA": "franska (Kanada)",
- "fr_FR": "franska (Frankrike)",
- "fi": "finska",
- "he": "hebreiska",
- "hi": "hindi",
- "hr": "kroatiska",
- "hu": "ungerska",
- "is": "isländska",
- "it": "italienska",
- "ko": "koreanska",
- "lt": "litauiska",
- "lv": "lettiska",
- "nb": "norska (bokmål)",
- "nl": "nederländska",
- "pl": "polska",
- "pt": "portugisiska",
- "ro": "rumänska",
- "ru": "ryska",
- "sk": "slovakiska",
- "sl": "slovenska",
- "sr": "serbiska",
- "sv": "svenska",
- "tr": "turkiska",
- "vi": "vietnamesiska",
- "zh": "kinesiska",
- "zh_TW": "kinesiska (traditionell)"}</translation>
-<translation id="3359142382821736686">avgränsare</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{plustecken}other{# plustecken}}</translation>
-<translation id="338583716107319301">Avgränsare</translation>
-<translation id="3389259863310851658">Föregående formulärfält</translation>
-<translation id="3390225400784126843">Nästa element av annan typ.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, menyalternativ</translation>
-<translation id="3406283310380167331">Visa formulärlistan</translation>
-<translation id="3422338090358345848">Öppna tangentbordsutforskaren</translation>
-<translation id="3457000393508828486">Delvis nedtryckt</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, knapp</translation>
-<translation id="3473644018603298796"><ph name="COUNT" /> markerade</translation>
-<translation id="3486232535569802404"><ph name="V1" /> till <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{höger hakparentes}other{# höger-hakparenteser}}</translation>
-<translation id="3493915602752813531">Det finns inga fler ankare.</translation>
-<translation id="3494946239022273294">menyalt</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{frågetecken}other{# frågetecken}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{cirkumflex}other{# cirkumflextecken}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, omarkerad kryssruta</translation>
-<translation id="3599054940393788245">Inte i ett matematiskt uttryck</translation>
-<translation id="3616113530831147358">Ljud</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{grav accent}other{# grav accent-tecken}}</translation>
-<translation id="3650317109285159359">menyalternativ med kryssruta</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dollartecken}other{# dollartecken}}</translation>
-<translation id="3659787053479271466">varning</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, listruta</translation>
-<translation id="3687295507293856493">Gissa kolumnrubriken för den aktuella cellen</translation>
-<translation id="3692274950075847560">S:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Röstkontroller</translation>
-<translation id="3716845769494773620">Flerradigt</translation>
-<translation id="3731746171184829332">Det finns ingen föregående rubrik.</translation>
-<translation id="3762198587642264450">Flytta till slutet av aktuell rad</translation>
-<translation id="3777255250339039212">rubr1</translation>
-<translation id="3793710123303304873">Dialogrutan stängdes.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Autoslutförande med lista</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Nästa media</translation>
-<translation id="3819376190738087562">Det finns inga hopp.</translation>
-<translation id="385383972552776628">Öppna alternativsidan</translation>
-<translation id="3856075812838139784">Skrivskyddat</translation>
-<translation id="3887576927692165210">textfält</translation>
-<translation id="3897092660631435901">Meny</translation>
-<translation id="3909320334364316587">Föregående rubrik på nivå 6</translation>
-<translation id="3914173277599553213">Obligatoriskt</translation>
-<translation id="3962990492275676168">Börja läsa från aktuell plats</translation>
-<translation id="4004802134384979325">markerad</translation>
-<translation id="4006140876663370126">bild</translation>
-<translation id="4038349100599457191">Inmatning av månad</translation>
-<translation id="4039983576244166038">Tom radrubrik</translation>
-<translation id="4042843249978639960">Det finns inga fler rubriker på nivå 2.</translation>
-<translation id="4043348641337972076">Det finns inget föregående ARIA-landmärke.</translation>
-<translation id="4047216625641135770">Markering</translation>
-<translation id="404803211695627272"><ph name="V1" />–<ph name="V2" /></translation>
-<translation id="4054936709456751127">status</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{tilde}other{# tildetecken}}</translation>
-<translation id="409334809956508737">Föregående objekt</translation>
-<translation id="4099274309791143834">med undermeny</translation>
-<translation id="4107807507418787238">Det finns inga celler nedanför den här.</translation>
-<translation id="4116415223832267137">Varning</translation>
-<translation id="4147126331795725888">Det finns inga fler kontroller.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{höger klammerparentes}other{# höger-klammerparenteser}}</translation>
-<translation id="4158704014418536539">Skiftlägeskänslig.</translation>
-<translation id="4161663686871496107">Uppläst feedback från ChromeVox har aktiverats</translation>
-<translation id="4173994908659439270">Det finns inga fler redigerbara textfält.</translation>
-<translation id="4176463684765177261">Inaktiverad</translation>
-<translation id="4188530942454211480">Föregående mening</translation>
-<translation id="4202186506458631436">Flytta åt höger</translation>
-<translation id="4206289001967551965">I tabellen</translation>
-<translation id="4215733775853809057">Nästa skjutreglage</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{bindestreck}other{# bindestreck}}</translation>
-<translation id="421884353938374759">färgval</translation>
-<translation id="4229646983878045487">datum och tid</translation>
-<translation id="423334822609210999">Det finns inga celler till vänster.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, grad <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Kommentar</translation>
-<translation id="4254798249533888099">Träd</translation>
-<translation id="4255943572433203166">Anpassa ChromeVox med alternativen nedan. Ändringarna börjar gälla direkt.</translation>
-<translation id="4271220233568730077">Nästa matematiska uttryck</translation>
-<translation id="4271521365602459209">Inga fler resultat.</translation>
-<translation id="4287520460805643128">Det finns inga fler artiklar.</translation>
-<translation id="4289540628985791613">Översikt</translation>
-<translation id="4300318234632215983">Läs upp webbadressen bakom en länk</translation>
-<translation id="4301352596632316575">med undermeny</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{punkt}=3{tre punkter}other{# punkter}}</translation>
-<translation id="4347461890115250064">Det finns inga fler listor.</translation>
-<translation id="4367650418938037324">Math ML-löv</translation>
-<translation id="4372435075475052704">min: <ph name="X" /></translation>
-<translation id="4372705107434148843">Stoppa tal</translation>
-<translation id="4373197658375206385">Det finns inget föregående objekt som inte är en länk.</translation>
-<translation id="4391478986194775161">innehållsinformation</translation>
-<translation id="443163561286008705">återställ</translation>
-<translation id="4471074325120394300">Inga länkar.</translation>
-<translation id="4476183483923481720">ny rad</translation>
-<translation id="4482330759234983253">Föregående tabell</translation>
-<translation id="4491109536499578614">Bild</translation>
-<translation id="4529987814483543472">Klassisk tangentuppsättning</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{snedstreck}other{# snedstreck}}</translation>
-<translation id="4547556996012970016">Nästa rubrik på nivå 5</translation>
-<translation id="4562381607973973258">Sidhuvud</translation>
-<translation id="4591507479202817876">, valt</translation>
-<translation id="4597532268155981612">formulär</translation>
-<translation id="4597896406374528575">april</translation>
-<translation id="4615592953348396470">Ignorera nästa tangenttryckning</translation>
-<translation id="461613135510474570">Mening</translation>
-<translation id="4647836961514597010">Färgval</translation>
-<translation id="4661075872484491155">träd</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">rutnät</translation>
-<translation id="4693675773662933727">Föregående landmärke</translation>
-<translation id="4696413482802371445">Det finns inga fler rubriker på nivå 5.</translation>
-<translation id="4729095194763193578">Föregående tabellrad</translation>
-<translation id="4736221692378411923">augusti</translation>
-<translation id="4740661827607246557">Hjälpkommandon</translation>
-<translation id="4759716709594980008">Tangentbordsutforskaren för ChromeOS</translation>
-<translation id="4763296182459741068">Till slutet</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">sök</translation>
-<translation id="481165870889056555">Läs upp den aktuella sidans titel</translation>
-<translation id="4826415162591436065">Navigera framåt</translation>
-<translation id="4826604887384865800">Nästa hopp</translation>
-<translation id="4827410568042294688">omarkerad</translation>
-<translation id="4842108708071771135">Det finns inga fler citatblock.</translation>
-<translation id="4848993367330139335">timer</translation>
-<translation id="4850023505158945298">Föregående element av liknande typ.</translation>
-<translation id="4866956062845190338">menyalternativ med alternativknapp</translation>
-<translation id="4867316986324544967">Aktivera loggning av text-till-tal</translation>
-<translation id="4877261390094455813">Ange en sökfråga.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Intern länk</translation>
-<translation id="4953585991029886728">Textinmatning</translation>
-<translation id="4954534434583049121">Föregående citatblock</translation>
-<translation id="4973717656530883744">Minst <ph name="X" /></translation>
-<translation id="4973762002207131920">Bytte till <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">millisekunder</translation>
-<translation id="49787999531187221">ChromeVox är nu inaktiverat.</translation>
-<translation id="4979404613699303341">Föregående knapp</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, listruta</translation>
-<translation id="4983588134362688868">Till början av sidan</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, fönster</translation>
-<translation id="4993152509206108683">Hastighet: <ph name="PERCENT" /> procent</translation>
-<translation id="4996716799442435517">Visuell</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, markerad alternativknapp</translation>
-<translation id="4997475792277222884">Det finns inga fler objekt som inte är länkar.</translation>
-<translation id="5000760171916499057">Det finns inga formulär.</translation>
-<translation id="5005670136041063723">Det finns inga fler liknande element.</translation>
-<translation id="501473567976723023">januari</translation>
-<translation id="5041394372352067729">Flytta punktskriftsskärmen till sidans början</translation>
-<translation id="5042770794184672516">Höj talvolymen</translation>
-<translation id="5050015258024679800">Föregående rubrik på nivå 4</translation>
-<translation id="5054047268577924192">Föregående post i listan</translation>
-<translation id="5078661581131202757">Filval</translation>
-<translation id="5080758118274074384">dubbelklickat</translation>
-<translation id="5098541983634824365">Lämnar rutnätet.</translation>
-<translation id="5102981729317424850">Verktygsfält</translation>
-<translation id="5105050547967751155">obligatoriskt</translation>
-<translation id="5110983769041734144">Det finns inget föregående formulärfält.</translation>
-<translation id="5111640677200759579">Kolumnrubrik</translation>
-<translation id="5117636609870536415">e-postadressfält</translation>
-<translation id="5136967254288895616">Det finns ingen föregående länk.</translation>
-<translation id="513774504516943387">länk</translation>
-<translation id="517143700877085897">, inte markerat</translation>
-<translation id="5183440668879371625">Punktskrift på föregående rad</translation>
-<translation id="5184944171021383281">Det finns inga fler formulärfält.</translation>
-<translation id="5189244881767082992">Rad</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> har redan tilldelats ett kommando</translation>
-<translation id="5205493599117157272"><ph name="TYPE" />-lista.</translation>
-<translation id="520883772648104506">Det finns inga fler alternativknappar.</translation>
-<translation id="5263344797180442561">rubr2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Objekt</translation>
-<translation id="5304943142864553931">Fliken <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">har tagits bort:</translation>
-<translation id="5320727453979144100">Låsta knappar har aktiverats</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{komma}other{# komman}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, textruta</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, länk</translation>
-<translation id="5336381510091010269">autoslutförande på raden och i lista</translation>
-<translation id="536031132345979795">Hoppa bakåt under kontinuerlig uppläsning</translation>
-<translation id="5368000168321181111">Ljudikoner har inaktiverats</translation>
-<translation id="5374320867641260420">Det finns inga fler knappar.</translation>
-<translation id="5382299583965267720">Det finns inga fler rubriker på nivå 1.</translation>
-<translation id="5402367795255837559">Punktskrift</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{semikolon}other{# semikolon}}</translation>
-<translation id="5411891038905756502">Det finns inga tidigare punkter att hoppa till.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{mindre än-tecken}other{# mindre än-tecken}}</translation>
-<translation id="5455441614648621694">Kompletterande</translation>
-<translation id="5485036206801896268">Det finns ingen föregående bild.</translation>
-<translation id="5486947920110100234">Det finns inga punkter att hoppa till.</translation>
-<translation id="549602578321198708">Ord</translation>
-<translation id="5500932716852106146">Det finns inget föregående redigerbart textfält.</translation>
-<translation id="5502713021410870035">september</translation>
-<translation id="5507663321906818013">Utvärdering vid felsökning</translation>
-<translation id="5518443085409638729">Visa markören mellan tecken vid redigering av text (som i Mac OS X).</translation>
-<translation id="552195134157544755">Alternativknapp</translation>
-<translation id="5534303576632885660">rubr</translation>
-<translation id="5546092960038624944">Det finns ingen föregående rubrik på nivå 5.</translation>
-<translation id="556042886152191864">Knapp</translation>
-<translation id="5561345396546889625">Nästa lista</translation>
-<translation id="5562645715554321347">rubrikgrupp</translation>
-<translation id="5583640892426849032">Backsteg</translation>
-<translation id="5585044216466955529">Textinmatning, e-post</translation>
-<translation id="5597170376237141345">Nästa kryssruta</translation>
-<translation id="5597933780944041114">Det finns inga fler rubriker.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, omarkerad alternativknapp</translation>
-<translation id="5601172225407283979">Utför standardåtgärd</translation>
-<translation id="5608798115546226984">Autoslutförande med direktinfogning</translation>
-<translation id="561939826962581046">tid</translation>
-<translation id="5623778242535476823">alternativknapp</translation>
-<translation id="5623842676595125836">Logg</translation>
-<translation id="5628125749885014029">rubr4</translation>
-<translation id="5637871198229500030">Det finns ingen föregående tabell.</translation>
-<translation id="5655682562155942719">Hoppkommandon</translation>
-<translation id="56637627897541303">Textområde</translation>
-<translation id="5678161956734658133">flerradigt textfält</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Landmärke</translation>
-<translation id="5683155931978483559">Föregående kryssruta</translation>
-<translation id="5684277895745049190">Lista</translation>
-<translation id="5700650669149824506">Det finns ingen föregående rubrik på nivå 4.</translation>
-<translation id="5709192780268610569">Det finns ingen lång beskrivning</translation>
-<translation id="5712244464475377681">popup-knapp</translation>
-<translation id="5712338278108304766">Nästa tabellkolumn</translation>
-<translation id="571866080859340309">Utforskar grupper</translation>
-<translation id="5728409797179002635">Inga tabeller hittades.</translation>
-<translation id="5748623122140342504">Föregående rubrik på nivå 5</translation>
-<translation id="5750633686117194034">Ingen specialtangent har tryckts in. Tryck länge på en eller flera specialtangenter. Lyft fingrarna när du är klar så får du höra vilka tangenter som har konfigurerats. Avsluta genom att trycka på tabbtangenten.</translation>
-<translation id="5788275253279308023">inkognitofönster, fliken <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Förbättra specifika webbplatser (t.ex. Google Sök).</translation>
-<translation id="5819072574982403430">Trädobjekt</translation>
-<translation id="5826479389509458994">rad <ph name="ROW" /> kolumn <ph name="COL" /></translation>
-<translation id="5850707923114094062">Panorera bakåt</translation>
-<translation id="5851548754964597211">Fliklista</translation>
-<translation id="5859752971144398932">Sök på sidan avslutades.</translation>
-<translation id="5866042630553435010">Delvis markerat</translation>
-<translation id="5869546221129391014">Rutnät</translation>
-<translation id="5876817486144482042">Sänk talvolymen</translation>
-<translation id="5887397643266327462">Textning med punktskrift har aktiverats.</translation>
-<translation id="5891934789323004067">Tabell</translation>
-<translation id="5919442531159595654">kopiera.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{likhetstecken}other{# likhetstecken}}</translation>
-<translation id="5939518447894949180">Återställ</translation>
-<translation id="5948123859135882163">Växla mellan strukturell och semantisk tolkning av matematiska uttryck</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Dialogruta</translation>
-<translation id="5963413905009737549">Avsnitt</translation>
-<translation id="5968607524793740041">Visa snabbmeny</translation>
-<translation id="5983179082906765664">Öka navigeringens granularitet</translation>
-<translation id="5999630716831179808">Röster</translation>
-<translation id="6000417740266304866">Ändra den aktuella tabellen för punktskrift med åtta punkter genom att välja ett alternativ i listan nedan.</translation>
-<translation id="6006050241733874051">Formulär</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{bakstreck}other{# bakstreck}}</translation>
-<translation id="6037602951055904232">Panorera framåt</translation>
-<translation id="611827076493383239">besökt</translation>
-<translation id="6119955456199054975">Slutet av cellen.</translation>
-<translation id="6122013438240733403">knapp</translation>
-<translation id="6129953537138746214">Blanksteg</translation>
-<translation id="6142308968191113180">Rubrik 4</translation>
-<translation id="6169420925157477918">Bild med lång beskrivning</translation>
-<translation id="6172087735260766220">Texten i en kopieringsskyddad PDF-fil är inte åtkomlig med tillgänglighetsfunktionen.</translation>
-<translation id="6186305613600865047">Till slutet av sidan</translation>
-<translation id="6193330012414963395">FM/EM</translation>
-<translation id="622484624075952240">Ner</translation>
-<translation id="6236061028292614533">Nästa rubrik</translation>
-<translation id="6254901459154107917">Nästa redigerbara textområde</translation>
-<translation id="6259464875943891919">Lämnade <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Nästa element av liknande typ.</translation>
-<translation id="6282062888058716985">navig</translation>
-<translation id="6290434000785343030">Det finns inga fler kombinationsrutor.</translation>
-<translation id="6307969636681130414">Nedtryckt</translation>
-<translation id="6324551002951139333">Ett grammatiskt fel har upptäckts</translation>
-<translation id="6348657800373377022">Kombinationsruta</translation>
-<translation id="6355910664415701303">Det finns ingen föregående post i listan.</translation>
-<translation id="6364795331201459219">rubr6</translation>
-<translation id="6368143427468974988">Föregående rubrik</translation>
-<translation id="6387719785439924554">sidoruta</translation>
-<translation id="6411426777058107714">Det finns ingen föregående alternativknapp.</translation>
-<translation id="6414968628640960377">Föregående element av annan typ.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{kolon}other{# kolon}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, meny</translation>
-<translation id="6444046323172968959">Varningsdialogruta</translation>
-<translation id="6459511626086141404">Platt tangentuppsättning</translation>
-<translation id="6468049171101508116">Nästa knapp</translation>
-<translation id="6491972999578897419">Ändra den nuvarande rösten genom att välja ett alternativ i listan nedan.</translation>
-<translation id="6508059270146105198">Flytta punktskriftsskärmen till sidans slut</translation>
-<translation id="6536864053412760904">Math ML-token</translation>
-<translation id="6550720799683018100">Ändra den nuvarande tangentuppsättningen genom att välja ett alternativ i listan nedan.</translation>
-<translation id="6561818612645211875">Flytta till början av den aktuella raden</translation>
-<translation id="6587021927234520429">Det finns inga fler rubriker på nivå 4.</translation>
-<translation id="6601344353291556895">Aktivera utförliga beskrivningar.</translation>
-<translation id="6615602925644411249">Hitta på sidan.</translation>
-<translation id="6633350132811819843">Det finns inga fler tabeller.</translation>
-<translation id="6637586476836377253">logg</translation>
-<translation id="6657128831881431364">Förloppsindikator</translation>
-<translation id="6659594942844771486">Flik</translation>
-<translation id="667999046851023355">Dokument</translation>
-<translation id="6697092096875747123">Föregående kombinationsruta</translation>
-<translation id="6714813999819678458">Föregående rubrik på nivå 2</translation>
-<translation id="6716505898850596801">Specialtangenter</translation>
-<translation id="671916444866103745">Det finns inga fler ARIA-landmärken.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, kombinationsruta</translation>
-<translation id="6735257939857578167">med <ph name="NUM" /> objekt</translation>
-<translation id="6736510033526053669">ny flik har öppnats</translation>
-<translation id="675895815784134693">förloppsindikator</translation>
-<translation id="6786800275320335305">Artikel</translation>
-<translation id="6787839852456839824">Kortkommandon</translation>
-<translation id="6793101435925451627">listruta</translation>
-<translation id="6833103209700200188">Sidfot</translation>
-<translation id="6871161210040114857">Inte skiftlägeskänsligt.</translation>
-<translation id="6877435256196695200">Det finns inga fler bilder.</translation>
-<translation id="6897341342232909480">Flytta åt vänster</translation>
-<translation id="6901540140423170855">datum</translation>
-<translation id="6910211073230771657">Borttagen</translation>
-<translation id="6911965441508464308">Det finns inga celler ovanför den här.</translation>
-<translation id="6919104639734799681">Visa tabellistan</translation>
-<translation id="6964088412282673743">Det finns inga föregående kontroller.</translation>
-<translation id="6996566555547746822">Nästa kombinationsruta</translation>
-<translation id="7005146664810010831">Ingen webbadress hittades</translation>
-<translation id="7010712454773919705">ChromeVox-specialtangent</translation>
-<translation id="7031651751836475482">listpost</translation>
-<translation id="7037042857287298941">Föregående lista</translation>
-<translation id="7041173719775863268">Avsluta markering</translation>
-<translation id="7095834689119144465">Textinmatning, endast tal</translation>
-<translation id="7096001299300236431">Föregående media</translation>
-<translation id="7116595520562830928">flerradigt</translation>
-<translation id="712735679809149106">eko för ord</translation>
-<translation id="713824876195128146">Nästa citatblock</translation>
-<translation id="7161771961008409533">Popup-knapp</translation>
-<translation id="7167657087543110">eko för tecken</translation>
-<translation id="7170733337935166589">Hoppa framåt under kontinuerlig uppläsning</translation>
-<translation id="7181697990050180700">Ange kortkommandon som du använder ofta genom att skriva dem i de avsedda fälten nedan.</translation>
-<translation id="7203150201908454328">Utökat</translation>
-<translation id="7210211103303402262">minuter</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">rad</translation>
-<translation id="7226216518520804442">lista</translation>
-<translation id="72393384879519786">Rubrik</translation>
-<translation id="7241683698754534149">Öppna lång beskrivning på ny flik</translation>
-<translation id="7248671827512403053">Program</translation>
-<translation id="725969808843520477">Nästa alternativknapp</translation>
-<translation id="7269119382257320590">Inga skiljetecken</translation>
-<translation id="7273174640290488576">Tom</translation>
-<translation id="7285387653379749618">Tabeller</translation>
-<translation id="7289186959554153431">Rubrik 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">trädobjekt</translation>
-<translation id="731576946540457939">Textning med punktskrift har inaktiverats.</translation>
-<translation id="7318872822751139669">Ändra fokus med hjälp av musen.</translation>
-<translation id="7322388933135261569">februari</translation>
-<translation id="7332592614823088566">Rad <ph name="ROWINDEX" /> av <ph name="ROWTOTAL" />, kolumn <ph name="COLINDEX" /> av <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">med popup</translation>
-<translation id="7356165926712028380">Byt till punktskrift med åtta punkter</translation>
-<translation id="7362871137496673139">Det finns ingen föregående rubrik på nivå 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{et-tecken}other{# et-tecken}}</translation>
-<translation id="737396357417333429">klickbart</translation>
-<translation id="7374104575779636480">Lämnar tabellen.</translation>
-<translation id="739763518212184081">Föregående rad</translation>
-<translation id="7400575256015741911">Ett stavfel har upptäckts</translation>
-<translation id="7408482676469142474">tabell</translation>
-<translation id="7425395583360211003">retur</translation>
-<translation id="7434509671034404296">Utvecklare</translation>
-<translation id="7439060726180460871">Katalog</translation>
-<translation id="744163271241493234">lösenordsfält</translation>
-<translation id="7491962110804786152">tabb</translation>
-<translation id="7492049978501397201">Dialogruta öppnad</translation>
-<translation id="7532613204005497612">juni</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, skjutreglage</translation>
-<translation id="7586163296341959563">klistra in.</translation>
-<translation id="7596919493010894443">markering borttagen</translation>
-<translation id="7604026522577407655">Flytta till början av den aktuella kolumnen</translation>
-<translation id="7604451927827590395">rubrik</translation>
-<translation id="7609342235116740824">Läs upp den aktuella sidans webbadress</translation>
-<translation id="7609363189280667021">Byt till punktskrift och text</translation>
-<translation id="762020119231868829">Pausar uppspelningen på alla mediawidgetar</translation>
-<translation id="7625690649919402823">Nästa tabell</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), grad <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Det finns ingen föregående rubrik på nivå 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, textruta</translation>
-<translation id="7663318257180412551">Rubrik 2</translation>
-<translation id="7674576868851035240">Nästa länk</translation>
-<translation id="7674768236845044097">markering</translation>
-<translation id="7684431668231950609">Textinmatning, webbadress</translation>
-<translation id="7685589220304187312">verktygsfält</translation>
-<translation id="7693840228159394336">Föregående alternativknapp</translation>
-<translation id="7701196182766842984">autoslutförande i lista</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, lösenordsruta</translation>
-<translation id="7805247615045262757">standardnavigering</translation>
-<translation id="7805768142964895445">Status</translation>
-<translation id="7810781339813764006">Nästa grupp</translation>
-<translation id="7819187121850078213">fönster, fliken <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">oktober</translation>
-<translation id="7839679365527550018">Föregående ord</translation>
-<translation id="7851816175263618915">Vissa skiljetecken</translation>
-<translation id="7870596830398826354">Math ML-träd</translation>
-<translation id="78826985582142166">skjutregl</translation>
-<translation id="7894517696028036636">Aktivera/inaktivera klassisk ChromeVox.</translation>
-<translation id="7895896691902835279">Okänd länk</translation>
-<translation id="7927711904086083099">Inte markerat</translation>
-<translation id="7935627501098484003">Tidsfält</translation>
-<translation id="7939428177581522200">har lagts till i det markerade avsnittet</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{snabel-a}other{# snabel-an}}</translation>
-<translation id="7965147473449754028">menyn stängdes</translation>
-<translation id="7974390230414479278">Menyalternativ</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{utropstecken}other{# utropstecken}}</translation>
-<translation id="8007540374018858731">rubr3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{citattecken}other{# citattecken}}</translation>
-<translation id="8033827949643255796">markerat</translation>
-<translation id="8035962149453661158">max: <ph name="X" /></translation>
-<translation id="8042761080832772327">Textinmatning, sökning</translation>
-<translation id="8049189770492311300">Timer</translation>
-<translation id="8065607967589909823">Du har markerat</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">Det finns inga ARIA-landmärken.</translation>
-<translation id="8153880621934657047">Inte i tabellen.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{understreck}other{# understreck}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">klipp ut.</translation>
-<translation id="8199231515320852133">Läs upp rubriker för den aktuella cellen</translation>
-<translation id="820417203470636242">Tom cell.</translation>
-<translation id="8215202828671303819">Flerval</translation>
-<translation id="8276439074553447000">Hoppa till föregående fokuserbara objekt</translation>
-<translation id="8278417001922463147">Det finns ingen föregående artikel.</translation>
-<translation id="8283603667300770666">Nästa formulärfält</translation>
-<translation id="831207808878314375">Definition</translation>
-<translation id="8313653172105209786">kat</translation>
-<translation id="8344569602005188545">timmar</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{nummertecken}other{# nummertecken}}</translation>
-<translation id="8374154622594089836">månad</translation>
-<translation id="8378855320830505539">Område</translation>
-<translation id="8382679411218029383">Autoslutförande med både direktinfogning och lista</translation>
-<translation id="8428603554127842284">nivå <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Det finns inga fler rubriker på nivå 3.</translation>
-<translation id="8430049249787218991">menyfält</translation>
-<translation id="844681116543532394">Det finns ingen föregående kryssruta.</translation>
-<translation id="8455868257606149352">Högst <ph name="X" /></translation>
-<translation id="84575901236241018">har snabbtangenten <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Minska navigeringens granularitet</translation>
-<translation id="8520472399088452386">Snurrknapp</translation>
-<translation id="8538744478902126321">Gissa radrubrik för den aktuella cellen</translation>
-<translation id="8540054775867439484">Till början</translation>
-<translation id="8548973727659841685">Tecken</translation>
-<translation id="8561322612995434619">med popup</translation>
-<translation id="8571096049907249734">flerval</translation>
-<translation id="8584721346566392021">rubr5</translation>
-<translation id="8587549812518406253">Nästa post i listan</translation>
-<translation id="860150890330522909">Kryssrutan <ph name="NAME" /> har markerats</translation>
-<translation id="8606621670302093223">Inmatning av datum</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> markerade objekt</translation>
-<translation id="8638532244051952400">Läs upp koordinaterna för aktuell cell</translation>
-<translation id="8650576015643545550">Det finns ingen föregående lista.</translation>
-<translation id="8653031188082306838">webbadressfält</translation>
-<translation id="8653646212587894517">Visa länklistan</translation>
-<translation id="8664519043722036194">sekunder</translation>
-<translation id="867187640362843212">Rubrik 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{lodstreck}other{# lodstreck}}</translation>
-<translation id="8735450637152821465">Börja markering</translation>
-<translation id="8743786158317878347">öppna strukturerat innehåll, t.ex. tabeller</translation>
-<translation id="8747966237988593539">Sorterad lista</translation>
-<translation id="8759334257841767240">Det finns inga fler länkar.</translation>
-<translation id="8767968232364267681">Nästa rubrik på nivå 4</translation>
-<translation id="8770473310765924354">stäng strukturerat innehåll, t.ex. tabeller</translation>
-<translation id="8791025954632646584">Semantisk tolkning aktiverad</translation>
-<translation id="8796411681063377102">Nästa rubrik på nivå 3</translation>
-<translation id="8808582214901541005">mars</translation>
-<translation id="8825828890761629845">banner</translation>
-<translation id="8851136666856101339">huvud</translation>
-<translation id="8856538297388979332">Bläddra bland kommandon genom att trycka på uppåtpil eller nedåtpil, aktivera genom att trycka på retur</translation>
-<translation id="8864099967139188018">Det finns inga fler rubriker på nivå 6.</translation>
-<translation id="8882002077197914455">Radrubrik</translation>
-<translation id="8896347895970027998">Växla mellan att aktivera och inaktivera ChromeVox.</translation>
-<translation id="8898516272131543774">eko för skiljetecken</translation>
-<translation id="8900148057318340779">Prefixtangent</translation>
-<translation id="8908714597367957477">kolumnrubrik</translation>
-<translation id="8931936695772494138">Tomma rubriker</translation>
-<translation id="8937112856099038376">intern länk</translation>
-<translation id="8940925288729953902">Specialtangenter</translation>
-<translation id="8943175951035496220">Det finns ingen cell till höger.</translation>
-<translation id="8978496506222343566">beskrivning</translation>
-<translation id="900114243503212879">fil</translation>
-<translation id="9027462562263121875">Det finns inga tabeller.</translation>
-<translation id="9040132695316389094">Rubrik 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" /> %</translation>
-<translation id="9061915073547935367">Aktivera/inaktivera sökwidget</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">togs bort från markeringen</translation>
-<translation id="9082874451376019682">Det finns inget föregående skjutreglage.</translation>
-<translation id="9089864840575085222">eko för inmatning</translation>
-<translation id="9107530006868467849">Det finns ingen föregående mediewidget.</translation>
-<translation id="9108370397979208512">matte</translation>
-<translation id="9108589040018540527">rullningslist</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{procenttecken}other{# procenttecken}}</translation>
-<translation id="9115913704608474258">november</translation>
-<translation id="9128414153595658330">dialogruta</translation>
-<translation id="9149560530563164529">avsnitt</translation>
-<translation id="9151211641321628915">Ger en kort beskrivning av den aktuella positionen</translation>
-<translation id="9153606228985488238">Tonhöjd: <ph name="PERCENT" /> procent</translation>
-<translation id="9160096769946561184">Flytta till slutet av den aktuella kolumnen</translation>
-<translation id="9173115498289768110">Volym: <ph name="PERCENT" /> procent</translation>
-<translation id="9178973770513562274">Bläddra med hjälp av tangenterna uppåtpil och nedåtpil eller skriv vad du vill söka efter.</translation>
-<translation id="9192904702577636854">Markör</translation>
-<translation id="9212322457209634662">Det finns inga fler avsnitt.</translation>
-<translation id="930275611743429116">Börja eller sluta markera.</translation>
-<translation id="948171205378458592">Sänk talhastigheten</translation>
-<translation id="962913030769097253">Nästa rubrik på nivå 1</translation>
-<translation id="973955474346881951">Aktivera/inaktivera låsta knappar</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sw.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sw.xtb
deleted file mode 100644
index 1b76cdd6f29..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sw.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="sw">
-<translation id="1012173283529841972">Kipengee cha orodha</translation>
-<translation id="1013742170491673792">imetafuta</translation>
-<translation id="1023866615269196768">Kimejumuishwa.</translation>
-<translation id="1025074108959230262">Hali ya kunata imezimwa</translation>
-<translation id="1031961866430398710">kisha</translation>
-<translation id="1044777062731150180">Hakuna vichwa</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Ulichoweka si sahihi</translation>
-<translation id="1082209053475788238">Hakuna kichwa cha ngazi ya 6 iliyotangulia.</translation>
-<translation id="1088219014394087294">Hakuna vichwa.</translation>
-<translation id="1106741348836243114">Washa au zima maoni ya sauti (earcons).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="TAG" /> mkusanyiko ulio na vipengee <ph name="NUM" /></translation>
-<translation id="1155043339247954670">Hakuna kipengee cha orodha kinachofuata.</translation>
-<translation id="1157782847298808853">Usaidizi wa Kibodi</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, kikasha mseto</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, kipengee cha menyu, na menyu ndogo</translation>
-<translation id="1177863135347784049">Maalum</translation>
-<translation id="1188858454923323853">nyongeza</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Inaipa Chrome Sauti</translation>
-<translation id="1229276918471378188">Kuruka kulikotangulia</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Kichwa cha ngazi ya 6 kinachofuata</translation>
-<translation id="1275718070701477396">Imechaguliwa</translation>
-<translation id="1319608975892113573">Hakuna nukuu la msingi lililotangulia.</translation>
-<translation id="1321576897702511272">Ficha usaidizi wa ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> kati ya <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">herufi na mwangwi wa neno</translation>
-<translation id="1339428534620983148">Safu wima ya jedwali lililotangulia</translation>
-<translation id="1342835525016946179">makala</translation>
-<translation id="1346748346194534595">Kulia</translation>
-<translation id="136718599399906424">Safu mlalo ya jedwali linalofuata</translation>
-<translation id="1383876407941801731">Tafuta</translation>
-<translation id="1385214448885562192">Bonyeza "enter" ili kukubali au "escape" ili kughairi, "down" kwenda inayofuata na "up" kurudi iliyotangulia.</translation>
-<translation id="1396114365388024581">orodha ya vichupo</translation>
-<translation id="1439316808600711881">eneo</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, kikasha maandishi cha nenosiri</translation>
-<translation id="1467432559032391204">Kushoto</translation>
-<translation id="1474557363159888097">Hakuna nanga iliyotangulia.</translation>
-<translation id="1502086903961450562">Mchoro uliotangulia</translation>
-<translation id="1506187449813838456">Ongeza sauti</translation>
-<translation id="151784044608172266">Sentensi Inayofuata</translation>
-<translation id="1524531499102321782">Mstari unaofuata wa Breli</translation>
-<translation id="1546370775711804143">Sehemu ya kusogeza</translation>
-<translation id="1559739829547075274">Rudi nyuma</translation>
-<translation id="1571643229714746283">ChromeVox iko tayari</translation>
-<translation id="158493514907962286">Desemba</translation>
-<translation id="1594072653727561613">menyu</translation>
-<translation id="1610130962244179598">Badilisha hadi Breli ya vitone 6</translation>
-<translation id="1611168825862729585">Kichwa cha safu wima:</translation>
-<translation id="1613476421962910979">Earcons zimewashwa</translation>
-<translation id="1618597272655350600">Hutangaza maelezo kamili ya nafasi ya sasa</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{kubwa kuliko}other{alama # za kubwa kuliko}}</translation>
-<translation id="1653266918374749391">Kichwa cha ngazi ya 3 kilichotangulia</translation>
-<translation id="1659072772017912254">Haijateuliwa</translation>
-<translation id="1669290819662866522">wiki</translation>
-<translation id="1674262202423278359">Kudurusu ChromeVox</translation>
-<translation id="16777221443363124">Upau wa menyu</translation>
-<translation id="1692077714702418899">mstari wa muundo</translation>
-<translation id="1700517974991662022">Lililotembelewa</translation>
-<translation id="1722567105086139392">Kiungo</translation>
-<translation id="1727806147743597030">kijachini</translation>
-<translation id="174268867904053074">Mchoro unaofuata</translation>
-<translation id="1781173782405573156">Nenosiri la kuingia</translation>
-<translation id="1787176709638001873">Maandishi ya kubadilisha nenosiri</translation>
-<translation id="1810107444790159527">Kikasha orodha</translation>
-<translation id="1828385960365606039">Mei</translation>
-<translation id="1834891354138622109">Safu wima</translation>
-<translation id="1865601187525349519">Mwisho wa maandishi</translation>
-<translation id="1876229593313240038">hati</translation>
-<translation id="188130072164734898">Tamka saa ya sasa na tarehe.</translation>
-<translation id="1902396333223336119">Kisanduku</translation>
-<translation id="1905379170753160525">Onyesha orodha ya vichwa</translation>
-<translation id="1912556590115083156">kiungo kilichotembelewa</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Udhibiti wa wiki ya mwaka</translation>
-<translation id="1964135212174907577">Kifaa Kinachofuata</translation>
-<translation id="1969092762068865084">Julai</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Kichwa cha safu mlalo:</translation>
-<translation id="2002895034995108595">Weka ramani msingi ya sasa upya</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{bano la kushoto}other{mabano # ya kushoto}}</translation>
-<translation id="2045490512405922022">hakijateuliwa</translation>
-<translation id="20601713649439366">Hakuna mlingano wa hisabati uliotangulia.</translation>
-<translation id="207477615537953741">Ufasiri wa semantiki umezimwa</translation>
-<translation id="2086961585857038472">Neno Linalofuata</translation>
-<translation id="2089387485033699258">sw</translation>
-<translation id="2091933974477985526">Eneo lililotangulia la maandishi linaloweza kubadilishwa</translation>
-<translation id="2100350898815792233">Vituo vyote vya maandishi</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">kitufe cha ufikiaji: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Badilisha jedwali la sasa la breli ya vitone 6 kwa kuteua chaguo kutoka kwenye orodha iliyo hapa chini.</translation>
-<translation id="2169714232367507776">Bofya kipengee cha sasa</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{alama ya kufunga mabano}other{alama # za kufunga mabano}}</translation>
-<translation id="2199994615414171367">Hisabati iliyotangulia</translation>
-<translation id="2223693656926968778">Chukua hatua kwenye kipengee cha sasa</translation>
-<translation id="225732394367814946">Ongeza kasi ya usemi</translation>
-<translation id="2267945578749931355">Herufi Inayofuata</translation>
-<translation id="2281234842553884450">Kitelezi kilichotangulia</translation>
-<translation id="2318372665160196757">Kuu</translation>
-<translation id="2329324941084714723">Kidirisha cha kichupo</translation>
-<translation id="2344193891939537199">Kidhibiti cha tarehe na saa</translation>
-<translation id="2359897517538099099">Haiko katika hali ya jedwali.</translation>
-<translation id="241124561063364910">inafuatwa na</translation>
-<translation id="2417569100218200841">Maelezo ya maudhui</translation>
-<translation id="2422937916923936891">Kisanduku cha kuteua cha kipengee cha menyu</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> sasa ni kirekebishaji kipya cha ChromeVox.</translation>
-<translation id="2450814015951372393">Kisanduku cha kuteua</translation>
-<translation id="2462626033734746142">Kikundi cha kitufe cha redio</translation>
-<translation id="2471138580042810658">Kichwa 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{nyota}other{nyota #}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> imewekwa upya.</translation>
-<translation id="2553108862507765288">kosa la sarufi</translation>
-<translation id="257674075312929031">Kikundi</translation>
-<translation id="2582407057977008361">Kando</translation>
-<translation id="2589102159832527089">Ukurasa huu una maandishi yaliyotolewa kwenye faili ya PDF kiotomatiki &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Bofya hapa kwa faili ya awali.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">ina {COUNT,plural, =1{Kipengee #}other{Vipengee #}}</translation>
-<translation id="2614981083756825552">Mpangilio wa Hisabati ML</translation>
-<translation id="2626530649491650971">kinabofyeka</translation>
-<translation id="2628764385451019380">Hakuna kikasha mseto kilichotangulia.</translation>
-<translation id="2637227747952042642">Hisabati</translation>
-<translation id="2639750663247012216">Kirekebishaji cha ChromeVox</translation>
-<translation id="2644542693584024604">kosa la tahajia</translation>
-<translation id="2667291555398229137">Boyfa kipengee kilicho chini ya ufunguo wa ruta</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{alama ya kufungua mabano}other{alama # za kufungua mabano}}</translation>
-<translation id="2705875883745373140">Haijabonyezwa</translation>
-<translation id="2706462751667573066">Juu</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">sauti</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">Imeteuliwa</translation>
-<translation id="27527859628328957">Ruka hadi kipengee kinachoweza kulengwa kinachofuata</translation>
-<translation id="2770781857296573485">Ingia ugunduaji wa kikundi</translation>
-<translation id="2777845298774924149">Imeondoka</translation>
-<translation id="2800204403141299078">Hakuna vipengee zaidi tofauti.</translation>
-<translation id="2800780099804980316">Hakuna kichwa cha ngazi ya 1 iliyotangulia.</translation>
-<translation id="2811204574343810641">Safu mlalo</translation>
-<translation id="2816654101880605877">Hakuna kitelezi kinachofuata.</translation>
-<translation id="2841013758207633010">Muda</translation>
-<translation id="2843837985843789981">Kikundi Kilichotangulia</translation>
-<translation id="2844995807198708617">Menyu</translation>
-<translation id="2849332794118375855">Hakuna kisanduku cha kuteua kinachofuata.</translation>
-<translation id="2864481629947106776">Kiungo kilichotangulia</translation>
-<translation id="2873259058405069099">Nenda hadi mwanzo wa jedwali</translation>
-<translation id="2894654529758326923">Maelezo</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{parandesi ya kushoto}other{parandesi # za kushoto}}</translation>
-<translation id="2911433807131383493">Fungua mafunzo ya ChromeVox</translation>
-<translation id="2932083475399492303">Geuza aina ya mstari kati ya muundo au mpangilio</translation>
-<translation id="2964026537669811554">Kichwa cha kikundi</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{kichupo}other{vichupo #}}</translation>
-<translation id="2972078295414139404">Hakuna kiungo kilichotembelewa kilichotangulia.</translation>
-<translation id="2972205263822847197">Kidokezo cha zana</translation>
-<translation id="2998131015536248178">Herufi Iliyotangulia</translation>
-<translation id="2999559350546931576">Punguza kiwango cha sauti</translation>
-<translation id="2999945368667127852">Hakuna wijeti ya maudhui inayofuata.</translation>
-<translation id="3012414509011670858">Hakuna sehemu iliyotangulia.</translation>
-<translation id="3030432017085518523">Kitufe cha redio cha kipengee cha menyu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{apostrofi}other{apostrofi #}}</translation>
-<translation id="3046838483509668188">Chaguo za ChromeVox</translation>
-<translation id="3047143736589213134">Ramani msingi ya majaribio</translation>
-<translation id="3060756054951570867">Menyu <ph name="TITLE" /> imefunguliwa</translation>
-<translation id="3078345202707391975">Kichwa cha ngazi ya 2 kinachofuata</translation>
-<translation id="3078740164268491126">jedwali</translation>
-<translation id="3082557070674409251">Kimebofiwa</translation>
-<translation id="3084806535845658316">hakuna mwangwi wa kuchapa</translation>
-<translation id="3086746722712840547">dokezo</translation>
-<translation id="308895241372589742">Hakuna mlingano wa hisabati unaofuata.</translation>
-<translation id="3090532668523289635">kikundi</translation>
-<translation id="3093176084511590672">Kivutio kinachofuata</translation>
-<translation id="3096671415663099226">kisanduku mseto</translation>
-<translation id="3104705064753753826">arifa ya mazungumzo</translation>
-<translation id="3109724472072898302">Imekunjwa</translation>
-<translation id="3134461040845705080">soma tu</translation>
-<translation id="3138767756593758860">Onyesha orodha ya vivutio</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Mstari Unaofuata</translation>
-<translation id="3155083529632865074">Hakuna kitufe kilichotangulia.</translation>
-<translation id="3163593631834463955">Kichwa kitupu cha safu wima</translation>
-<translation id="316542773973815724">Kudurusu</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{nafasi}other{nafasi #}}</translation>
-<translation id="320961988183078793">umeingiza <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, kichupo</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Kiungo kilichotembelewa</translation>
-<translation id="323731244387692321">Fungua usaidizi wa kibodi wa ChromeVox</translation>
-<translation id="3241052487511142956">Kiungo kilichotembelewa kilichotangulia</translation>
-<translation id="3286390186030710347">Kitelezi</translation>
-<translation id="3299925995433437805">Hakuna kiungo kilichotembelewa kinachofuata.</translation>
-<translation id="3303384412438961941">Bonyeza kitufe chochote kufahamu jina lake. Ctrl+W kutafunga kigunduzi cha kibodi.</translation>
-<translation id="3307886118343381874">Nenda hadi mwisho wa jedwali</translation>
-<translation id="3311969765485641742">Bonyeza Alt+Shift+A ili kukagua arifa</translation>
-<translation id="3312997241656799641">Kiungo kilichotembelewa kinachofuata</translation>
-<translation id="3321460131042519426">Washa kipengee cha kufunga neno</translation>
-<translation id="3322936298410871309">Kichwa cha ngazi ya 1 kilichotangulia</translation>
-<translation id="3323447499041942178">Kikasha maandishi</translation>
-<translation id="3353420241558113817">{"ar": "Kiarabu",
- "bg": "Kibulgaria",
- "ca": "Kikatalani",
- "cs": "Kicheki",
- "da": "Kideni",
- "de": "Kijerumani",
- "de_CH": "Kijerumani (Uswizi)",
- "de_DE": "Kijerumani (Ujerumani)",
- "el": "Kigiriki",
- "en": "Kiingereza",
- "en_CA": "Kiingereza (Kanada)",
- "en_GB": "Kiingereza (Uingereza)",
- "en_US": "Kiingereza (Marekani)",
- "es": "Kihispania",
- "et": "Kiestonia",
- "fr": "Kifaransa",
- "fr_CA": "Kifaransa (Kanada)",
- "fr_FR": "Kifaransa (Ufaransa)",
- "fi": "Kifini",
- "he": "Kiyahudi",
- "hi": "Kihindi",
- "hr": "Kikoreshia",
- "hu": "Kihangari",
- "is": "Kiasilandi",
- "it": "Kitaliano",
- "ko": "Kikorea",
- "lt": "Kiluthania",
- "lv": "Kilatvia",
- "nb": "Kinorwei cha Bokmål",
- "nl": "Kidachi",
- "pl": "Kipoli",
- "pt": "Kireno",
- "ro": "Kiroma",
- "ru": "Kirusi",
- "sk": "Kislovakia",
- "sl": "Kislovenia",
- "sr": "Kiserbia",
- "sv": "Kiswidi",
- "tr": "Kituruki",
- "vi": "Kivietnamu",
- "zh": "Kichina",
- "zh_TW": "Kichina (Kihani cha jadi)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{alama ya kuongeza}other{alama # za kuongeza}}</translation>
-<translation id="338583716107319301">Kitenganishi</translation>
-<translation id="3389259863310851658">Sehemu ya fomu iliyotangulia</translation>
-<translation id="3390225400784126843">Kipengee tofauti kinachofuata.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, kipengee cha menyu</translation>
-<translation id="3406283310380167331">Onyesha orodha ya fomu</translation>
-<translation id="3422338090358345848">Fungua kigunduzi cha kibodi</translation>
-<translation id="3457000393508828486">Imebonyezwa kiasi</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, kitufe</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> hadi <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{bano la kulia}other{mabano # ya kulia}}</translation>
-<translation id="3493915602752813531">Hakuna nanga inayofuata.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{alama ya kuuliza}other{alama # za kuuliza}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{kareti}other{alama # za kareti}}</translation>
-<translation id="3568702578574425662">Kisanduku cha kuteua <ph name="NAME" /> hakijateuliwa</translation>
-<translation id="3599054940393788245">Siyo ndani ya hisabati</translation>
-<translation id="3616113530831147358">Sauti</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{kingo`ngo}other{ving`ong`o #}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dola}other{alama # za dola}}</translation>
-<translation id="3659787053479271466">arifa</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, kisanduku cha orodha</translation>
-<translation id="3687295507293856493">Kiasia kichwa cha safu wima ya kisanduku cha sasa</translation>
-<translation id="3692274950075847560">S: <ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Kudhibiti Usemi</translation>
-<translation id="3716845769494773620">Mistari mingi</translation>
-<translation id="3731746171184829332">Hakuna kichwa kilichotangulia.</translation>
-<translation id="3762198587642264450">Nenda hadi mwisho wa safu mlalo ya sasa</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Umeondoka kwenye kidirisha.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Orodha inayojijaza kiotomatiki</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Maudhui yanayofuata</translation>
-<translation id="3819376190738087562">Hakuna kuruka.</translation>
-<translation id="385383972552776628">Fungua ukurasa wa chaguo</translation>
-<translation id="3856075812838139784">Soma tu</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menyu</translation>
-<translation id="3909320334364316587">Kichwa cha ngazi ya 6 kilichotangulia</translation>
-<translation id="3914173277599553213">Inahitajika</translation>
-<translation id="3962990492275676168">Anza kusoma kutoka mahali pa sasa</translation>
-<translation id="4004802134384979325">kimeteuliwa</translation>
-<translation id="4006140876663370126">picha</translation>
-<translation id="4038349100599457191">Udhibiti wa mwezi</translation>
-<translation id="4039983576244166038">Kichwa kitupu cha safu mlalo</translation>
-<translation id="4042843249978639960">Hakuna kichwa cha ngazi ya 2 kinachofuata.</translation>
-<translation id="4043348641337972076">Hakuna kivutio cha ARIA kilichotangulia.</translation>
-<translation id="4047216625641135770">Alama</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">hali</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{KISTARI}other{vistari #}}</translation>
-<translation id="409334809956508737">Kifaa Kilichotangulia</translation>
-<translation id="4099274309791143834">ina menyu ndogo</translation>
-<translation id="4107807507418787238">Hakuna kisanduku chini.</translation>
-<translation id="4116415223832267137">Arifa</translation>
-<translation id="4147126331795725888">Hakuna kidhibiti kinachofuata.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{parandesi ya kulia}other{parandesi # za kulia}}</translation>
-<translation id="4158704014418536539">Inajali herufi kubwa au ndogo.</translation>
-<translation id="4161663686871496107">Maoni ya kusemwa ya ChromeVox yako tayari</translation>
-<translation id="4173994908659439270">Hakuna sehemu ya maandishi inayoweza kubadilishwa inayofuata.</translation>
-<translation id="4176463684765177261">Kimelemazwa</translation>
-<translation id="4188530942454211480">Sentensi Iliyotangulia</translation>
-<translation id="4202186506458631436">Sogeza kulia</translation>
-<translation id="4206289001967551965">Ndani ya jedwali</translation>
-<translation id="4215733775853809057">Kitelezi kinachofuata</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{dashi}other{dashi #}}</translation>
-<translation id="421884353938374759">kiteua rangi</translation>
-<translation id="4229646983878045487">tarehe na saa</translation>
-<translation id="423334822609210999">Hakuna kisanduku kushoto.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" /> Daraja la <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Dokezo</translation>
-<translation id="4254798249533888099">Mti</translation>
-<translation id="4255943572433203166">Tumia chaguo zilizo hapa chini ili kubadilisha ChromeVox ikufae. Mabadiliko yataanza kufanya kazi mara moja.</translation>
-<translation id="4271220233568730077">Hisabati inayofuata</translation>
-<translation id="4271521365602459209">Hakuna matokeo zaidi.</translation>
-<translation id="4287520460805643128">Hakuna makala yanayofuata.</translation>
-<translation id="4289540628985791613">Muhtasari</translation>
-<translation id="4300318234632215983">Tangaza URL nyuma ya kiungo</translation>
-<translation id="4301352596632316575">Ina menyu ndogo</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{kitone}=3{vitone}other{vitone #}}</translation>
-<translation id="4347461890115250064">Hakuna orodha inayofuata.</translation>
-<translation id="4367650418938037324">Tawi la Hisabati ML</translation>
-<translation id="4372435075475052704">kiwango cha chini:<ph name="X" /></translation>
-<translation id="4372705107434148843">Achisha usemi</translation>
-<translation id="4373197658375206385">Hakuna kipengee kilichotangulia ambacho si kiungo.</translation>
-<translation id="4391478986194775161">maelezo ya maudhui</translation>
-<translation id="443163561286008705">weka upya</translation>
-<translation id="4471074325120394300">Hakuna viungo.</translation>
-<translation id="4476183483923481720">mstari mpya</translation>
-<translation id="4482330759234983253">Jedwali lililotangulia</translation>
-<translation id="4491109536499578614">Picha</translation>
-<translation id="4529987814483543472">Ramani msingi ya zamani</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{mkwaju}other{mikwaju #}}</translation>
-<translation id="4547556996012970016">Kichwa cha ngazi ya 5 kinachofuata</translation>
-<translation id="4562381607973973258">Kichwa</translation>
-<translation id="4591507479202817876">, kimechaguliwa</translation>
-<translation id="4597532268155981612">fomu</translation>
-<translation id="4597896406374528575">Aprili</translation>
-<translation id="4615592953348396470">Inapuuza kubonyeza kwa kitufe kunakofuata</translation>
-<translation id="461613135510474570">Sentensi</translation>
-<translation id="4647836961514597010">Kiteua rangi</translation>
-<translation id="4661075872484491155">mti</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">gridi</translation>
-<translation id="4693675773662933727">Kivutio kilichotangulia</translation>
-<translation id="4696413482802371445">Hakuna kichwa cha ngazi ya 5 inayofuata.</translation>
-<translation id="4729095194763193578">Safu mlalo ya jedwali lililotangulia</translation>
-<translation id="4736221692378411923">Agosti</translation>
-<translation id="4740661827607246557">Amri za Usaidizi</translation>
-<translation id="4759716709594980008">Kigunduzi cha Kibodi cha Mfumo wa Uendeshaji wa Chrome</translation>
-<translation id="4763296182459741068">Imefungwa hadi mwisho</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">tafuta</translation>
-<translation id="481165870889056555">Tangaza kichwa cha ukurasa wa sasa</translation>
-<translation id="4826415162591436065">Nenda mbele</translation>
-<translation id="4826604887384865800">Kuruka kunakofuata</translation>
-<translation id="4827410568042294688">yameondolewa uteuzi</translation>
-<translation id="4842108708071771135">Hakuna nukuu la msingi linalofuata.</translation>
-<translation id="4848993367330139335">kipima muda</translation>
-<translation id="4850023505158945298">Vipengee vinavyofanana vilivyotangulia.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Washa uwekaji kumbukumbu ya TTS</translation>
-<translation id="4877261390094455813">Ingiza hoja ya utafutaji.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Kiungo cha ndani</translation>
-<translation id="4953585991029886728">Badilisha maandishi</translation>
-<translation id="4954534434583049121">Nukuu la msingi lililotangulia</translation>
-<translation id="4973717656530883744">Kiwango cha chini <ph name="X" /></translation>
-<translation id="4973762002207131920">Imebadilishwa kwenda <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">milisekunde</translation>
-<translation id="49787999531187221">ChromeVox sasa haitumiki.</translation>
-<translation id="4979404613699303341">Kitufe kilichotangulia</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, kisanduku cha orodha</translation>
-<translation id="4983588134362688868">Ruka hadi mwanzo wa ukurasa</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, dirisha</translation>
-<translation id="4993152509206108683">Kadiria asilimia <ph name="PERCENT" /></translation>
-<translation id="4996716799442435517">Yanayoonekana</translation>
-<translation id="4997282455736854877">Kitufe <ph name="NAME" />, kimeteuliwa</translation>
-<translation id="4997475792277222884">Hakuna kipengee kinachofuata ambacho si kiungo.</translation>
-<translation id="5000760171916499057">Hakuna fomu.</translation>
-<translation id="5005670136041063723">Hakuna vipengee vinavyofanana tena.</translation>
-<translation id="501473567976723023">Januari</translation>
-<translation id="5041394372352067729">Sogeza onyesho la breli hadi mwanzo wa ukurasa</translation>
-<translation id="5042770794184672516">Ongeza sauti ya usemi</translation>
-<translation id="5050015258024679800">Kichwa cha ngazi ya 4 kilichotangulia</translation>
-<translation id="5054047268577924192">Kipengee cha orodha kilichotangulia</translation>
-<translation id="5078661581131202757">Uchaguzi wa faili</translation>
-<translation id="5080758118274074384">kimebofiwa mara mbili</translation>
-<translation id="5098541983634824365">Unaondoka kwenye gridi.</translation>
-<translation id="5102981729317424850">Upau zana</translation>
-<translation id="5105050547967751155">inahitajika</translation>
-<translation id="5110983769041734144">Hakuna sehemu ya fomu iliyotangulia.</translation>
-<translation id="5111640677200759579">Kichwa cha safu wima</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Hakuna kiungo kilichotangulia.</translation>
-<translation id="513774504516943387">kiungo</translation>
-<translation id="517143700877085897">, kimeondolewa uteuzi</translation>
-<translation id="5183440668879371625">Mstari uliotangulia wa Breli</translation>
-<translation id="5184944171021383281">Hakuna sehemu ya fomu inayofuata.</translation>
-<translation id="5189244881767082992">Mstari</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> tayari kimehawilishwa kwa amri.</translation>
-<translation id="5205493599117157272">Orodha ya <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Hakuna kitufe kinachofuata.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">Mwisho</translation>
-<translation id="5291783959063340370">Kitu</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, kichupo</translation>
-<translation id="5310788376443009632">limeondolewa:</translation>
-<translation id="5320727453979144100">Hali ya kunata imewashwa</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{koma}other{koma #}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, kikasha maandishi</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, kiungo</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Ruka kwenda nyuma wakati wa kusoma mfululizo</translation>
-<translation id="5368000168321181111">Earcons zimezimwa</translation>
-<translation id="5374320867641260420">Hakuna kitufe kinachofuata.</translation>
-<translation id="5382299583965267720">Hakuna kichwa cha ngazi ya 1 kinachofuata.</translation>
-<translation id="5402367795255837559">Breli</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{nuktamkato}other{nuktamikato #}}</translation>
-<translation id="5411891038905756502">Hakuna mahali pa kuruka palipotangulia.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{ndogo kuliko}other{alama # za ndogo kuliko}}</translation>
-<translation id="5455441614648621694">Nyongeza</translation>
-<translation id="5485036206801896268">Hakuna mchoro uliotangulia.</translation>
-<translation id="5486947920110100234">Hakuna mahali pa kuruka panapofuata.</translation>
-<translation id="549602578321198708">Neno</translation>
-<translation id="5500932716852106146">Hakuna sehemu ya maandishi inayoweza kubadilishwa iliyotangulia.</translation>
-<translation id="5502713021410870035">Septemba</translation>
-<translation id="5507663321906818013">Mfumo wa kutatua hitilafu</translation>
-<translation id="5518443085409638729">Weka kishale kati ya herufi unapohariri maandishi (kama vile Mac OS X).</translation>
-<translation id="552195134157544755">Kitufe cha redio</translation>
-<translation id="5534303576632885660">kichwa</translation>
-<translation id="5546092960038624944">Hakuna kichwa cha ngazi ya 5 iliyotangulia.</translation>
-<translation id="556042886152191864">Kitufe</translation>
-<translation id="5561345396546889625">Orodha inayofuata</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Badilisha maandishi, ingizo la barua pepe</translation>
-<translation id="5597170376237141345">Kisanduku cha kuteua kinachofuata</translation>
-<translation id="5597933780944041114">Hakuna kichwa kinachofuata.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, kitufe cha redio kimeondolewa uteuzi</translation>
-<translation id="5601172225407283979">Tekeleza kitendo chaguo-msingi</translation>
-<translation id="5608798115546226984">Inayojijaza kiotomatiki kulingana na maandishi</translation>
-<translation id="561939826962581046">wakati</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Kumbukumbu</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Hakuna jedwali lililotangulia.</translation>
-<translation id="5655682562155942719">Amri za Kuruka</translation>
-<translation id="56637627897541303">Eneo la maandishi</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">Ufafanuzi</translation>
-<translation id="5682113568322255809">Kivutio</translation>
-<translation id="5683155931978483559">Kisanduku cha kuteua kilichotangulia</translation>
-<translation id="5684277895745049190">Orodha</translation>
-<translation id="5700650669149824506">Hakuna kichwa cha ngazi ya 4 kilichotangulia.</translation>
-<translation id="5709192780268610569">Hakuna maelezo marefu</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Safu wima ya jedwali linalofuata</translation>
-<translation id="571866080859340309">Inagundua vikundi</translation>
-<translation id="5728409797179002635">Hakuna jedwali lililopatikana.</translation>
-<translation id="5748623122140342504">Kichwa cha ngazi ya 5 kilichotangulia</translation>
-<translation id="5750633686117194034">Hakuna kirekebishaji kilichobonyezwa; tafadhali bonyeza na ushikilie kirekebishaji kimoja au zaidi; ondoa kidole chako unapomaliza na utasikia vitufe vikiwekwa. Gonga kichupo ili kuondoka.</translation>
-<translation id="5788275253279308023">dirisha fiche la kichupo cha <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Boresha tovuti mahususi (kama vile Huduma ya Tafuta na Google).</translation>
-<translation id="5819072574982403430">Kipengee cha mti</translation>
-<translation id="5826479389509458994">safu mlalo <ph name="ROW" /> safu wima <ph name="COL" /></translation>
-<translation id="5850707923114094062">Sogeza kurudi nyuma</translation>
-<translation id="5851548754964597211">Orodha ya vichupo</translation>
-<translation id="5859752971144398932">Imeondoka kwenye tafuta katika ukurasa.</translation>
-<translation id="5866042630553435010">Imeteuliwa kiasi</translation>
-<translation id="5869546221129391014">Gridi</translation>
-<translation id="5876817486144482042">Punguza sauti ya usemi</translation>
-<translation id="5887397643266327462">Manukuu ya breli yamewashwa.</translation>
-<translation id="5891934789323004067">Jedwali</translation>
-<translation id="5919442531159595654">nakili.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{sawa}other{alama # za sawa}}</translation>
-<translation id="5939518447894949180">Weka upya</translation>
-<translation id="5948123859135882163">Geuza fasiri ya ulinganisho wa hisabati kati ya ufafanuzi wa muundo na semantiki</translation>
-<translation id="5955304353782037793">programu</translation>
-<translation id="5956928062748260866">Mazungumzo</translation>
-<translation id="5963413905009737549">Sehemu</translation>
-<translation id="5968607524793740041">Onyesha menyu</translation>
-<translation id="5983179082906765664">Ongeza kiwango cha maelezo unapodurusu</translation>
-<translation id="5999630716831179808">Sauti</translation>
-<translation id="6000417740266304866">Badilisha jedwali la sasa la breli ya vitone 8 kwa kuchagua chaguo kutoka kwenye orodha iliyo hapa chini.</translation>
-<translation id="6006050241733874051">Fomu</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{mkwaju wa nyuma}other{mikwaju # ya nyuma}}</translation>
-<translation id="6037602951055904232">Elekeza mbele</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Mwisho wa kisanduku.</translation>
-<translation id="6122013438240733403">kitufe</translation>
-<translation id="6129953537138746214">Nafasi</translation>
-<translation id="6142308968191113180">Kichwa cha 4</translation>
-<translation id="6169420925157477918">Picha yenye maelezo marefu</translation>
-<translation id="6172087735260766220">Imeshindwa kufikia maandishi yanayoweza kufikiwa kutoka kwenye nakala ya PDF inayolindwa.</translation>
-<translation id="6186305613600865047">Ruka hadi mwisho wa ukurasa</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Chini</translation>
-<translation id="6236061028292614533">Kichwa kinachofuata</translation>
-<translation id="6254901459154107917">Eneo linalofauata la maandishi linaloweza kubadilishwa</translation>
-<translation id="6259464875943891919">Umeondoka <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Kipengee kinachofanana kinachofuata.</translation>
-<translation id="6282062888058716985">kudurusu</translation>
-<translation id="6290434000785343030">Hakuna kikasha mseto kinachofuata.</translation>
-<translation id="6307969636681130414">Imebonyezwa</translation>
-<translation id="6324551002951139333">Kosa la sarufi limegunduliwa</translation>
-<translation id="6348657800373377022">Kikasha cha Combo</translation>
-<translation id="6355910664415701303">Hakuna kipengee cha orodha kilichotangulia.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Kichwa kilichotangulia</translation>
-<translation id="6387719785439924554">kando</translation>
-<translation id="6411426777058107714">Hakuna kitufe kilichotangulia.</translation>
-<translation id="6414968628640960377">Kipengee tofauti kilichotangulia.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{nuktambili}other{nuktambili #}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menyu</translation>
-<translation id="6444046323172968959">Arifa ya mazungumzo</translation>
-<translation id="6459511626086141404">Ramani msingi bapa</translation>
-<translation id="6468049171101508116">Kitufe kinachofuata</translation>
-<translation id="6491972999578897419">Badilisha sauti ya sasa kwa kuchagua chaguo kutoka kwenye orodha hapa chini.</translation>
-<translation id="6508059270146105198">Sogeza onyesho la breli hadi mwisho wa ukurasa</translation>
-<translation id="6536864053412760904">Tokeni ya Hisabati ML</translation>
-<translation id="6550720799683018100">Badilisha ramani msingi ya sasa kwa kuchagua chaguo kutoka kwenye orodha hapa chini.</translation>
-<translation id="6561818612645211875">Nenda hadi mwanzo wa safu mlalo ya sasa</translation>
-<translation id="6587021927234520429">Hakuna kichwa cha ngazi ya 4 kinachofuata.</translation>
-<translation id="6601344353291556895">Washa maelezo yenye maneno mengi.</translation>
-<translation id="6615602925644411249">Tafuta katika ukurasa.</translation>
-<translation id="6633350132811819843">Hakuna jedwali linalofuata.</translation>
-<translation id="6637586476836377253">kumbukumbu</translation>
-<translation id="6657128831881431364">Upau wa maendeleo</translation>
-<translation id="6659594942844771486">Kichupo</translation>
-<translation id="667999046851023355">Hati</translation>
-<translation id="6697092096875747123">Kikasha mseto kilichotangulia</translation>
-<translation id="6714813999819678458">Kichwa cha ngazi ya 2 kilichotangulia</translation>
-<translation id="6716505898850596801">Vitufe vya kurekebisha</translation>
-<translation id="671916444866103745">Hakuna kivutio cha ARIA kinachofuata.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, kikasha mseto</translation>
-<translation id="6735257939857578167">na vipengee <ph name="NUM" /></translation>
-<translation id="6736510033526053669">kichupo kimeundwa</translation>
-<translation id="675895815784134693">upau wa maendeleo</translation>
-<translation id="6786800275320335305">Makala</translation>
-<translation id="6787839852456839824">Mikato ya kibodi</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Kijachini</translation>
-<translation id="6871161210040114857">Inapuuza herufi kubwa au ndogo.</translation>
-<translation id="6877435256196695200">Hakuna mchoro unaofuata.</translation>
-<translation id="6897341342232909480">Sogeza kushoto</translation>
-<translation id="6901540140423170855">tarehe</translation>
-<translation id="6910211073230771657">Imeondolewa</translation>
-<translation id="6911965441508464308">Hakuna kisanduku juu.</translation>
-<translation id="6919104639734799681">Onyesha orodha ya majedwali</translation>
-<translation id="6964088412282673743">Hakuna kidhibiti kilichotangulia.</translation>
-<translation id="6996566555547746822">Kikasha mseto kinachofuata</translation>
-<translation id="7005146664810010831">Hakuna URL iliyopatikana</translation>
-<translation id="7010712454773919705">Kitufe cha kurekebisha cha ChromeVox</translation>
-<translation id="7031651751836475482">orodha ya kipengee</translation>
-<translation id="7037042857287298941">Orodha iliyotangulia</translation>
-<translation id="7041173719775863268">Maliza uchaguzi</translation>
-<translation id="7095834689119144465">Badilisha maandishi ya nambari pekee</translation>
-<translation id="7096001299300236431">Maudhui yaliyotangulia</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">mwangwi wa neno</translation>
-<translation id="713824876195128146">Nukuu la msingi linalofuata</translation>
-<translation id="7161771961008409533">Kitufe cha dirisha ibukizi</translation>
-<translation id="7167657087543110">mwangwi wa herufi</translation>
-<translation id="7170733337935166589">Ruka kwenda mbele wakati wa kusoma mfululizo</translation>
-<translation id="7181697990050180700">Badilisha mikato ya kibodi ikufae kwa amri zinazotumika mara kwa mara kwa kuzichapa katika sehemu zinazohusiana hapa chini.</translation>
-<translation id="7203150201908454328">Imepanuliwa</translation>
-<translation id="7210211103303402262">dakika</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">mstari</translation>
-<translation id="7226216518520804442">orodha</translation>
-<translation id="72393384879519786">Kichwa</translation>
-<translation id="7241683698754534149">Fungua maelezo marefu katika kichupo kipya</translation>
-<translation id="7248671827512403053">Programu</translation>
-<translation id="725969808843520477">Kitufe cha redio kinachofuata</translation>
-<translation id="7269119382257320590">Hakuna vituo vya maandishi</translation>
-<translation id="7273174640290488576">Mtupu</translation>
-<translation id="7285387653379749618">Majedwali</translation>
-<translation id="7289186959554153431">Kichwa 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Manukuu ya Breli yamezimwa.</translation>
-<translation id="7318872822751139669">Tumia kipanya kubadilisha kinacholengwa.</translation>
-<translation id="7322388933135261569">Februari</translation>
-<translation id="7332592614823088566">Safu mlalo <ph name="ROWINDEX" /> kati ya <ph name="ROWTOTAL" />, Safu wima <ph name="COLINDEX" /> kati ya <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">ina dirisha ibukizi</translation>
-<translation id="7356165926712028380">Badilisha hadi Breli ya vitone 8</translation>
-<translation id="7362871137496673139">Hakuna kichwa cha ngazi ya 2 kilichotangulia.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{alama ya na}other{alama # za na}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Unaondoka katika jedwali.</translation>
-<translation id="739763518212184081">Mstari Uliotangulia</translation>
-<translation id="7400575256015741911">Kosa la tahajia limegunduliwa</translation>
-<translation id="7408482676469142474">jedwali</translation>
-<translation id="7425395583360211003">rudi</translation>
-<translation id="7434509671034404296">Wasanidi Programu</translation>
-<translation id="7439060726180460871">Saraka</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">kichupo</translation>
-<translation id="7492049978501397201">umeingiza mazungumzo</translation>
-<translation id="7532613204005497612">Juni</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, kitelezi</translation>
-<translation id="7586163296341959563">bandika.</translation>
-<translation id="7596919493010894443">uchaguzi umefutwa</translation>
-<translation id="7604026522577407655">Nenda hadi mwanzo wa safu wima ya sasa</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Tangaza URL ya ukurasa wa sasa</translation>
-<translation id="7609363189280667021">Geuza manukuu ya breli</translation>
-<translation id="762020119231868829">Inasitisha wijeti zote za maudhui zinazocheza kwa sasa</translation>
-<translation id="7625690649919402823">Jedwali linalofuata</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Daraja la <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Hakuna kichwa cha ngazi ya 3 kilichotangulia.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, kikasha maandishi</translation>
-<translation id="7663318257180412551">Kichwa 2</translation>
-<translation id="7674576868851035240">Kiungo kinachofuata</translation>
-<translation id="7674768236845044097">alama</translation>
-<translation id="7684431668231950609">Hariri maandishi, ingizo la URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Kitufe cha redio kilichotangulia</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, kikasha maandishi cha nenosiri</translation>
-<translation id="7805247615045262757">kudurusu chaguo-msingi</translation>
-<translation id="7805768142964895445">Hali</translation>
-<translation id="7810781339813764006">Kikundi Kinachofuata</translation>
-<translation id="7819187121850078213">dirisha la kichupo cha <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">Oktoba</translation>
-<translation id="7839679365527550018">Neno Lililotangulia</translation>
-<translation id="7851816175263618915">Baadhi ya vituo vya maandishi</translation>
-<translation id="7870596830398826354">Mti wa Hisabati ML</translation>
-<translation id="78826985582142166">kitelezi</translation>
-<translation id="7894517696028036636">Geuza ChromeVox ya kawaida.</translation>
-<translation id="7895896691902835279">Kiungo kisichojulikana</translation>
-<translation id="7927711904086083099">Haijachaguliwa</translation>
-<translation id="7935627501098484003">Kudhibiti muda</translation>
-<translation id="7939428177581522200">zimeongezwa kwenye uchaguzi</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{katika}other{alama # za katika}}</translation>
-<translation id="7965147473449754028">menyu imefungwa</translation>
-<translation id="7974390230414479278">Kipengee cha menyu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{alama hisi}other{alama hisi #}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{nukuu}other{manukuu #}}</translation>
-<translation id="8033827949643255796">kimechaguliwa</translation>
-<translation id="8035962149453661158">upeo wa juu:<ph name="X" /></translation>
-<translation id="8042761080832772327">Badilisha maandishi, ingizo la utafutaji</translation>
-<translation id="8049189770492311300">Kipima muda</translation>
-<translation id="8065607967589909823">Uchaguzi ni</translation>
-<translation id="8066678206530322333">Bango</translation>
-<translation id="8110647606445335195">Hakuna vivutio vya ARIA.</translation>
-<translation id="8153880621934657047">Haimo ndani ya jedwali.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{kistari cha chini}other{vistari # vya chini}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">kata.</translation>
-<translation id="8199231515320852133">Tangaza vichwa vya kisanduku cha sasa</translation>
-<translation id="820417203470636242">Kisanduku kitupu.</translation>
-<translation id="8215202828671303819">Chaguo nyingi</translation>
-<translation id="8276439074553447000">Ruka hadi kipengee kinachoweza kulengwa kilichotangulia</translation>
-<translation id="8278417001922463147">Hakuna makala yaliyotangulia.</translation>
-<translation id="8283603667300770666">Sehemu ya fomu inayofuata</translation>
-<translation id="831207808878314375">Ufafanuzi</translation>
-<translation id="8313653172105209786">saraka</translation>
-<translation id="8344569602005188545">saa</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{pauni}other{alama # za pauni}}</translation>
-<translation id="8374154622594089836">mwezi</translation>
-<translation id="8378855320830505539">Eneo</translation>
-<translation id="8382679411218029383">Inayojijaza kiotomatiki kulingana na maandishi na orodha</translation>
-<translation id="8428603554127842284">ngazi ya <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Hakuna kichwa cha ngazi ya 3 kinachofuata.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Hakuna kisanduku cha kuteua kilichotangulia.</translation>
-<translation id="8455868257606149352">Upeo wa juu <ph name="X" /></translation>
-<translation id="84575901236241018">ina kitufe cha ufikiaji, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Punguza kiwango cha maelezo unapodurusu</translation>
-<translation id="8520472399088452386">Kitufe cha kusokota</translation>
-<translation id="8538744478902126321">Kisia kichwa cha safu mlalo ya kisanduku cha sasa</translation>
-<translation id="8540054775867439484">Imefungwa hadi juu</translation>
-<translation id="8548973727659841685">Herufi</translation>
-<translation id="8561322612995434619">ina dirisha ibukizi</translation>
-<translation id="8571096049907249734">chagua nyingi</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Kipengee cha orodha kinachofuata</translation>
-<translation id="860150890330522909">Kisanduku cha kuteua <ph name="NAME" /> kimeteuliwa</translation>
-<translation id="8606621670302093223">Kidhibiti cha tarehe</translation>
-<translation id="8631359288236106450">vipengee <ph name="COUNT" /> vimechaguliwa</translation>
-<translation id="8638532244051952400">Tangaza anwani za visanduku vya sasa</translation>
-<translation id="8650576015643545550">Hakuna orodha iliyotangulia.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Onyesha orodha ya viungo</translation>
-<translation id="8664519043722036194">sekunde</translation>
-<translation id="867187640362843212">Kichwa 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{kistari}other{vistari wima #}}</translation>
-<translation id="8735450637152821465">Anza uchaguzi</translation>
-<translation id="8743786158317878347">ingiza maudhui yenye muundo, kama vile majedwali</translation>
-<translation id="8747966237988593539">Orodha yenye Mpangilio</translation>
-<translation id="8759334257841767240">Hakuna kiungo kinachofuata.</translation>
-<translation id="8767968232364267681">Kichwa cha ngazi ya 4 kinachofuata</translation>
-<translation id="8770473310765924354">ondoka kwenye maudhui yenye muundo, kama vile majedwali</translation>
-<translation id="8791025954632646584">Semantiki imewashwa</translation>
-<translation id="8796411681063377102">Kichwa cha ngazi ya 3 kinachofuata</translation>
-<translation id="8808582214901541005">Machi</translation>
-<translation id="8825828890761629845">bango</translation>
-<translation id="8851136666856101339">kuu</translation>
-<translation id="8856538297388979332">Bonyeza "up" au "down" ili kukagua amri, bonyeza "enter" ili kuwasha</translation>
-<translation id="8864099967139188018">Hakuna kichwa cha ngazi ya 6 kinachofuata.</translation>
-<translation id="8882002077197914455">Kichwa cha safu mlalo</translation>
-<translation id="8896347895970027998">Geuza ChromeVox itumike au isitumike.</translation>
-<translation id="8898516272131543774">Mwangwi wa mduara wa vituo vya maandishi</translation>
-<translation id="8900148057318340779">Ufunguo wa kiambishi</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Vichwa vitupu</translation>
-<translation id="8937112856099038376">kiungo cha ndani</translation>
-<translation id="8940925288729953902">Vitufe vya Kurekebisha</translation>
-<translation id="8943175951035496220">Hakuna kisanduku kulia.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">faili</translation>
-<translation id="9027462562263121875">Hakuna majedwali.</translation>
-<translation id="9040132695316389094">Kichwa cha 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Badilisha wijeti ya utafutaji</translation>
-<translation id="9065283790526219006">+dirisha ibukizi</translation>
-<translation id="9077213568694924680">imeondolewa kwenye uchaguzi</translation>
-<translation id="9082874451376019682">Hakuna kitelezi kilichotangulia.</translation>
-<translation id="9089864840575085222">Mwangwi wa mduara wa kuchapa</translation>
-<translation id="9107530006868467849">Hakuna wijeti ya maudhui.</translation>
-<translation id="9108370397979208512">hisabati</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{asilimia}other{alama # za asilimia}}</translation>
-<translation id="9115913704608474258">Novemba</translation>
-<translation id="9128414153595658330">mazungumzo</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Hutangaza maelezo mafupi ya nafasi ya sasa</translation>
-<translation id="9153606228985488238">Kiwango cha sauti asilimia <ph name="PERCENT" /></translation>
-<translation id="9160096769946561184">Nenda hadi mwisho wa safu wima ya sasa</translation>
-<translation id="9173115498289768110">Sauti asilimia <ph name="PERCENT" /></translation>
-<translation id="9178973770513562274">Tumia vitufe vya juu na chini ili kuvinjari, au charaza ili kutafuta.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">Hakuna sehemu inayofuata.</translation>
-<translation id="930275611743429116">Anza au maliza uchaguzi.</translation>
-<translation id="948171205378458592">Punguza kasi ya usemi</translation>
-<translation id="962913030769097253">Kichwa cha ngazi ya 1 kinachofuata</translation>
-<translation id="973955474346881951">Washa/Zima hali ya kunata</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ta.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ta.xtb
deleted file mode 100644
index 3aaec837138..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ta.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="ta">
-<translation id="1012173283529841972">பட்டியல் உருப்படி</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">நீட்டிக்கப்பட்டது.</translation>
-<translation id="1025074108959230262">ஸ்டிக்கி முறை முடக்கப்பட்டது</translation>
-<translation id="1031961866430398710">பின்னர்</translation>
-<translation id="1044777062731150180">மேற்தலைப்புகள் இல்லை</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">தவறான உள்ளீடு</translation>
-<translation id="1082209053475788238">முந்தைய 6 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="1088219014394087294">தலைப்புகள் இல்லை.</translation>
-<translation id="1106741348836243114">ஒலி மறுமொழியை (ஆடியோ செய்திகள்) இயக்கு அல்லது முடக்கு.</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724"><ph name="NUM" /> உருப்படிகளின் <ph name="TAG" /> தொகுப்பு</translation>
-<translation id="1155043339247954670">அடுத்த பட்டியல் உருப்படி இல்லை.</translation>
-<translation id="1157782847298808853">விசைப்பலகை உதவி</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, சேர்க்கைப் பெட்டி</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, மெனு உருப்படி, துணைமெனுவுடன்</translation>
-<translation id="1177863135347784049">தனிப்பயன்</translation>
-<translation id="1188858454923323853">ஈடுசெய்யக்கூடியது</translation>
-<translation id="1206619573307042055">மார்கியூ</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome க்கு குரல் கொடுக்கிறது</translation>
-<translation id="1229276918471378188">முந்தைய தாவல்</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">அடுத்த 6 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="1275718070701477396">தேர்ந்தெடுக்கப்பட்டது</translation>
-<translation id="1319608975892113573">முன் மேற்கோள் குறி இல்லை</translation>
-<translation id="1321576897702511272">ChromeVox உதவியை மறை</translation>
-<translation id="1331702245475014624"><ph name="TOTAL" /> / <ph name="INDEX" /></translation>
-<translation id="1334095593597963605">எழுத்து மற்றும் சொல் எதிரொலி</translation>
-<translation id="1339428534620983148">முந்தைய அட்டவணை நெடுவரிசை</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">வலது</translation>
-<translation id="136718599399906424">அடுத்த அட்டவணை வரிசை</translation>
-<translation id="1383876407941801731">தேடல்</translation>
-<translation id="1385214448885562192">ஏற்றுக்கொள்ள enter உம், ரத்துசெய்ய escape உம் அழுத்தவும் மேலும் அடுத்ததற்குச் செல்ல கீழ் என்பதையும் முந்தையதற்குச் செல்ல மேல் என்பதையும் அழுத்தவும்.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, கடவுச்சொல் உரைப் பெட்டி</translation>
-<translation id="1467432559032391204">இடது</translation>
-<translation id="1474557363159888097">முந்தைய ஆங்கர் இல்லை.</translation>
-<translation id="1502086903961450562">முந்தைய கிராஃபிக்</translation>
-<translation id="1506187449813838456">ஸ்ருதியை அதிகரி</translation>
-<translation id="151784044608172266">அடுத்த வாக்கியம்</translation>
-<translation id="1524531499102321782">பிரெய்ல் அடுத்த வரி</translation>
-<translation id="1546370775711804143">உருட்டல் பட்டி</translation>
-<translation id="1559739829547075274">பின்னோக்கிச் செல்</translation>
-<translation id="1571643229714746283">ChromeVox தயார்</translation>
-<translation id="158493514907962286">டிசம்பர்</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6 புள்ளி பிரெய்லுக்கு மாறு</translation>
-<translation id="1611168825862729585">நெடுவரிசை மேற்தலைப்பு:</translation>
-<translation id="1613476421962910979">ஆடியோ செய்திகளை இயக்கு</translation>
-<translation id="1618597272655350600">தற்போதைய நிலையின் முழு விளக்கத்தை அறிவிக்கிறது</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{அதிகத்திற்கான குறி}other{# அதிகத்திற்கான குறிகள்}}</translation>
-<translation id="1653266918374749391">முந்தைய, 3 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="1659072772017912254">தேர்ந்தெடுக்கப்படவில்லை</translation>
-<translation id="1669290819662866522">வாரம்</translation>
-<translation id="1674262202423278359">ChromeVox வழிநடத்துதல்</translation>
-<translation id="16777221443363124">மெனுப் பட்டி</translation>
-<translation id="1692077714702418899">கட்டமைப்பு வரி</translation>
-<translation id="1700517974991662022">பார்வையிட்டது</translation>
-<translation id="1722567105086139392">இணைப்பு</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">அடுத்த கிராஃபிக்</translation>
-<translation id="1781173782405573156">பாஸ் த்ரூ விசை</translation>
-<translation id="1787176709638001873">கடவுச்சொல் திருத்த உரை</translation>
-<translation id="1810107444790159527">பட்டியல் பெட்டி</translation>
-<translation id="1828385960365606039">மே</translation>
-<translation id="1834891354138622109">நெடுவரிசை</translation>
-<translation id="1865601187525349519">உரையின் இறுதி</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">தற்போதைய நேரம் மற்றும் தேதியைக் கூறவும்.</translation>
-<translation id="1902396333223336119">கலம்</translation>
-<translation id="1905379170753160525">தலைப்புகள் பட்டியலைக் காட்டு</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">ஆண்டு கட்டுப்பாட்டிற்கான வாரம்</translation>
-<translation id="1964135212174907577">அடுத்த பொருள்</translation>
-<translation id="1969092762068865084">ஜூலை</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">வரிசை மேற்தலைப்பு:</translation>
-<translation id="2002895034995108595">நடப்பு விசைவரைபடத்தை மீட்டமை</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{இடது அடைப்புக்குறி}other{# இடது அடைப்புக்குறிகள்}}</translation>
-<translation id="2045490512405922022">தேர்வுசெய்யப்படவில்லை</translation>
-<translation id="20601713649439366">முந்தைய கணிதக் கோவை இல்லை.</translation>
-<translation id="207477615537953741">பொருள்விளக்கம் முடக்கப்பட்டது</translation>
-<translation id="2086961585857038472">அடுத்த வார்த்தை</translation>
-<translation id="2089387485033699258">ta</translation>
-<translation id="2091933974477985526">முந்தைய திருத்தக்கூடிய உரைப் பகுதி</translation>
-<translation id="2100350898815792233">எல்லா நிறுத்தற்குறிகளும்</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">அணுகல் விசை:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">கீழே உள்ள பட்டியலில் இருந்து விருப்பத்தைத் தேர்ந்தெடுப்பதன் மூலம் நடப்பிலுள்ள 6 புள்ளி பிரெய்ல் அட்டவணையை மாற்றலாம்.</translation>
-<translation id="2169714232367507776">தற்போதைய உருப்படியில் கிளிக் செய்க</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{மூடு அடைப்புக்குறி}other{# மூடு அடைப்புக்குறிகள்}}</translation>
-<translation id="2199994615414171367">முந்தைய கணிதம்</translation>
-<translation id="2223693656926968778">நடப்பு உருப்படியில் நடவடிக்கை எடு</translation>
-<translation id="225732394367814946">பேச்சு விகிதத்தை அதிகரி</translation>
-<translation id="2267945578749931355">அடுத்த எழுத்து</translation>
-<translation id="2281234842553884450">முந்தைய ஸ்லைடர்</translation>
-<translation id="2318372665160196757">முதன்மை</translation>
-<translation id="2329324941084714723">தாவல் பலகம்</translation>
-<translation id="2344193891939537199">நாள் நேரக் கட்டுப்பாடு</translation>
-<translation id="2359897517538099099">அட்டவணைப் பயன்முறையில் இல்லை</translation>
-<translation id="241124561063364910">தொடர்ந்து</translation>
-<translation id="2417569100218200841">உள்ளடக்கத் தகவல்</translation>
-<translation id="2422937916923936891">மெனு உருப்படி செக் பாக்ஸ்</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> என்பதே இப்போது புதிய ChromeVox மாற்றியாகும்.</translation>
-<translation id="2450814015951372393">செக் பாக்ஸ்</translation>
-<translation id="2462626033734746142">ரேடியோ பொத்தான் குழு</translation>
-<translation id="2471138580042810658">தலைப்பு 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{உடுக்குறி}other{# உடுக்குறிகள்}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> மீட்டமைக்கப்பட்டுள்ளது.</translation>
-<translation id="2553108862507765288">இலக்கணப் பிழை</translation>
-<translation id="257674075312929031">குழு</translation>
-<translation id="2582407057977008361">Aside</translation>
-<translation id="2589102159832527089">PDF கோப்பு &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; இலிருந்து தானாக பிரித்தெடுக்கப்பட்ட உரையை இந்தப் பக்கம் கொண்டுள்ளது. &lt;a href="<ph name="URL" />"&gt;அசலுக்கு இங்கே கிளிக் செய்க.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">பட்டியலில் {COUNT,plural, =1{# உருப்படி}other{# உருப்படிகள்}}</translation>
-<translation id="2614981083756825552">கணித ML தளவமைப்பு</translation>
-<translation id="2626530649491650971">கிளிக் செய்யத்தக்கது</translation>
-<translation id="2628764385451019380">முந்தைய சேர்க்கைப் பெட்டி இல்லை.</translation>
-<translation id="2637227747952042642">கணிதம்</translation>
-<translation id="2639750663247012216">ChromeVox மாற்றி</translation>
-<translation id="2644542693584024604">தவறான வார்த்தைகள்</translation>
-<translation id="2667291555398229137">ரூட்டிங் விசைக்குக் கீழே உள்ள உருப்படியைக் கிளிக் செய்</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{திறந்த அடைப்புக்குறி}other{# திறந்த அடைப்புக்குறிகள்}}</translation>
-<translation id="2705875883745373140">அழுத்தப்படவில்லை</translation>
-<translation id="2706462751667573066">Up</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ஆடியோ</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">தேர்ந்தெடுக்கப்பட்டது</translation>
-<translation id="27527859628328957">கவனிக்க வேண்டிய அடுத்த உருப்படிக்குத் தாவு</translation>
-<translation id="2770781857296573485">குழு ஆராய்ச்சியில் நுழை</translation>
-<translation id="2777845298774924149">வெளியேறிவிட்டது</translation>
-<translation id="2800204403141299078">மேலும் வேறுபட்ட கூறுகள் இல்லை.</translation>
-<translation id="2800780099804980316">முந்தைய 1 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="2811204574343810641">வரிசை</translation>
-<translation id="2816654101880605877">அடுத்த ஸ்லைடர் இல்லை.</translation>
-<translation id="2841013758207633010">நேரம்</translation>
-<translation id="2843837985843789981">முந்தைய குழு</translation>
-<translation id="2844995807198708617">சூழல் மெனு</translation>
-<translation id="2849332794118375855">அடுத்த செக் பாக்ஸ் இல்லை.</translation>
-<translation id="2864481629947106776">முந்தைய இணைப்பு</translation>
-<translation id="2873259058405069099">அட்டவணையின் தொடக்கத்திற்குச் செல்</translation>
-<translation id="2894654529758326923">தகவல்</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{இடது பிறை அடைப்புக்குறி}other{# இடது பிறை அடைப்புக்குறிகள்}}</translation>
-<translation id="2911433807131383493">ChromeVox பயிற்சியைத் திற</translation>
-<translation id="2932083475399492303">வரியின் வகையை கட்டமைப்பு அல்லது தளவமைப்புக்கு இடையில் மாற்றவும்</translation>
-<translation id="2964026537669811554">தலைப்புக் குழு</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{தாவல்}other{# தாவல்கள்}}</translation>
-<translation id="2972078295414139404">முந்தையதாக பார்வையிட்ட இணைப்பு இல்லை.</translation>
-<translation id="2972205263822847197">உதவிக்குறிப்பு</translation>
-<translation id="2998131015536248178">முந்தைய எழுத்து</translation>
-<translation id="2999559350546931576">ஸ்ருதியைக் குறை</translation>
-<translation id="2999945368667127852">அடுத்த ஊடக விட்ஜெட் இல்லை.</translation>
-<translation id="3012414509011670858">முந்தைய பிரிவு இல்லை.</translation>
-<translation id="3030432017085518523">மெனு உருப்படி ரேடியோ பொத்தான்</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{தனி மேற்கோள் குறி}other{# தனி மேற்கோள் குறிகள்}}</translation>
-<translation id="3046838483509668188">ChromeVox விருப்பங்கள்</translation>
-<translation id="3047143736589213134">சோதனை விசைவரைபடம்</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> மெனு திறக்கப்பட்டது</translation>
-<translation id="3078345202707391975">அடுத்த 2 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="3078740164268491126">அட்டவணை</translation>
-<translation id="3082557070674409251">கிளிக் செய்யப்பட்டது</translation>
-<translation id="3084806535845658316">தட்டச்சிடும் எதிரொலி இல்லை</translation>
-<translation id="3086746722712840547">குறிப்பு</translation>
-<translation id="308895241372589742">அடுத்த கணிதக் கோவை இல்லை.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">அடுத்த லேண்ட்மார்க்</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">சுருக்கப்பட்டது</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">லேண்ட்மார்க்குகளின் பட்டியலைக் காட்டு</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">அடுத்த வரி</translation>
-<translation id="3155083529632865074">முந்தைய பொத்தான் இல்லை.</translation>
-<translation id="3163593631834463955">காலியான நெடுவரிசை மேற்தலைப்பு</translation>
-<translation id="316542773973815724">வழிச்செலுத்தல்</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{இடைவெளி}other{# இடைவெளிகள்}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> ஐ உள்ளிட்டுள்ளீர்கள்</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, தாவல்</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">பார்வையிட்ட இணைப்பு</translation>
-<translation id="323731244387692321">ChromeVox விசைப்பலகை உதவியைத் திற</translation>
-<translation id="3241052487511142956">முந்தையதாக பார்வையிட்ட இணைப்பு</translation>
-<translation id="3286390186030710347">ஸ்லைடர்</translation>
-<translation id="3299925995433437805">அடுத்ததாக பார்வையிட்ட இணைப்பு இல்லை.</translation>
-<translation id="3303384412438961941">இதன் பெயரை அறிய ஏதாவது ஒரு விசையை அழுத்தவும். Ctrl+W அழுத்தினால் விசைப்பலகை உலவி மூடப்படும்.</translation>
-<translation id="3307886118343381874">அட்டவணையின் இறுதிக்குச் செல்</translation>
-<translation id="3311969765485641742">விழிப்பூட்டல்களைப் பார்க்க Alt+Shift+A ஐ அழுத்தவும்</translation>
-<translation id="3312997241656799641">அடுத்ததாக பார்வையிட்ட இணைப்பு</translation>
-<translation id="3321460131042519426">சொல் மடிப்பை இயக்கு</translation>
-<translation id="3322936298410871309">முந்தைய 1 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="3323447499041942178">உரை பெட்டி</translation>
-<translation id="3353420241558113817">{"ar": "அரபிக்",
- "bg": "பல்கேரியன்",
- "ca": "கேடலன்",
- "cs": "செக்",
- "da": "டேனிஷ்",
- "de": "ஜெர்மன்",
- "de_CH": "ஜெர்மன் (ஸ்விட்சர்லாந்து)",
- "de_DE": "ஜெர்மன் (ஜெர்மனி)",
- "el": "கிரேக்கம்",
- "en": "ஆங்கிலம்",
- "en_CA": "ஆங்கிலம் (கனடா)",
- "en_GB": "ஆங்கிலம் (யுனைடட் கிங்டம்)",
- "en_US": "ஆங்கிலம் (அமெரிக்கா)",
- "es": "ஸ்பானிஷ்",
- "et": "ஈஸ்டோனியன்",
- "fr": "ஃபிரஞ்ச்",
- "fr_CA": "ஃபிரஞ்ச் (கனடா)",
- "fr_FR": "ஃபிரஞ்ச் (ஃபிரான்ஸ்)",
- "fi": "ஃபின்னிஷ்",
- "he": "எபிரேயம்",
- "hi": "இந்தி",
- "hr": "குரோஷியன்",
- "hu": "ஹங்கேரியன்",
- "is": "ஐஸ்லாண்டிக்",
- "it": "இத்தாலியன்",
- "ko": "கொரியன்",
- "lt": "லிதுவேனியன்",
- "lv": "லத்வியன்",
- "nb": "நார்வேஜியன் போக்மால்",
- "nl": "டச்சு",
- "pl": "போலிஷ்",
- "pt": "போர்சுகீஸ்",
- "ro": "ரோமானியன்",
- "ru": "ரஷ்யன்",
- "sk": "ஸ்லோவாக்",
- "sl": "ஸ்லோவேனியன்",
- "sr": "செர்பியன்",
- "sv": "ஸ்வேடிஷ்",
- "tr": "துருக்கி",
- "vi": "வியட்னாமீஸ்",
- "zh": "சீனம்",
- "zh_TW": "சீனம் (பாரம்பரிய ஹான்)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{கூட்டல் குறி}other{# கூட்டல் குறிகள்}}</translation>
-<translation id="338583716107319301">பிரிப்பான்</translation>
-<translation id="3389259863310851658">முந்தைய படிவப் புலம்</translation>
-<translation id="3390225400784126843">வேறுபட்ட அடுத்த உறுப்பு.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, மெனு உருப்படி</translation>
-<translation id="3406283310380167331">படிவங்கள் பட்டியலைக் காட்டு</translation>
-<translation id="3422338090358345848">விசைப்பலகை உலவியைத் திற</translation>
-<translation id="3457000393508828486">பகுதியளவு அழுத்தப்பட்டது</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, பொத்தான்</translation>
-<translation id="3473644018603298796">தேர்ந்தெடுத்தவை <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> முதல் <ph name="V2" /> வரை</translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{வலது அடைப்புக்குறி}other{# வலது அடைப்புக்குறிகள்}}</translation>
-<translation id="3493915602752813531">அடுத்த ஆங்கர் இல்லை.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{கேள்விக் குறி}other{# கேள்விக் குறிகள்}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{கூரைக் குறி}other{# கூரைக் குறிகள்}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, பெட்டி தேர்ந்தெடுக்கப்படவில்லை</translation>
-<translation id="3599054940393788245">உள்கணிதம் இல்லை</translation>
-<translation id="3616113530831147358">ஆடியோ</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{பேக்டிக்}other{# பேக்டிக்குகள்}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{டாலர் குறி}other{# டாலர் குறிகள்}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, பட்டியல் பெட்டி</translation>
-<translation id="3687295507293856493">நடப்புக் கலத்தின் நெடுவரிசைத் தலைப்பில் யூகத்தை உருவாக்கு</translation>
-<translation id="3692274950075847560">தே.:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">பேச்சைக் கட்டுப்படுத்துகிறது</translation>
-<translation id="3716845769494773620">பல வரிகள்</translation>
-<translation id="3731746171184829332">முந்தைய தலைப்பு இல்லை.</translation>
-<translation id="3762198587642264450">நடப்பு வரிசையின் இறுதிக்குச் செல்</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">செய்தியில் இருந்து வெளியேறினார்.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">தானே நிரப்புதல் பட்டியல்</translation>
-<translation id="3810838688059735925">வீடியோ</translation>
-<translation id="3816633764618089385">அடுத்த ஊடகம்</translation>
-<translation id="3819376190738087562">தாவல்கள் இல்லை.</translation>
-<translation id="385383972552776628">விருப்பங்கள் பக்கத்தைத் திற</translation>
-<translation id="3856075812838139784">படிக்க மட்டும்</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">மெனு</translation>
-<translation id="3909320334364316587">முந்தைய 6 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="3914173277599553213">அவசியம்</translation>
-<translation id="3962990492275676168">நடப்பு இருப்பிடத்திலிருந்து படிக்கத் தொடங்கு</translation>
-<translation id="4004802134384979325">தேர்ந்தெடுக்கப்பட்டது</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">மாதக் கட்டுப்பாடு</translation>
-<translation id="4039983576244166038">காலியான வரிசை மேற்தலைப்பு</translation>
-<translation id="4042843249978639960">அடுத்த 2 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="4043348641337972076">முந்தைய ARIA லேண்ட்மார்க் இல்லை.</translation>
-<translation id="4047216625641135770">Mark</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{தலை பெய் குறி}other{# தலை பெய் குறிகள்}}</translation>
-<translation id="409334809956508737">முந்தைய பொருள்</translation>
-<translation id="4099274309791143834">துணைமெனுவுடன்</translation>
-<translation id="4107807507418787238">கீழே கலம் இல்லை.</translation>
-<translation id="4116415223832267137">விழிப்பூட்டல்</translation>
-<translation id="4147126331795725888">அடுத்த கட்டுப்பாடு இல்லை.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{வலது பிறை அடைப்புக்குறி}other{# வலது பிறை அடைப்புக்குறிகள்}}</translation>
-<translation id="4158704014418536539">எழுத்து உணர்வு கொண்டது.</translation>
-<translation id="4161663686871496107">ChromeVox இன் பேச்சுவடிவக் கருத்து தயாராக உள்ளது</translation>
-<translation id="4173994908659439270">அடுத்த திருத்தக்கூடிய உரை புலம் இல்லை.</translation>
-<translation id="4176463684765177261">முடக்கப்பட்டது</translation>
-<translation id="4188530942454211480">முந்தைய வாக்கியம்</translation>
-<translation id="4202186506458631436">வலப்புறமாக நகர்த்து</translation>
-<translation id="4206289001967551965">அட்டவணை உள்ளே இருக்கிறீர்கள்</translation>
-<translation id="4215733775853809057">அடுத்த ஸ்லைடர்</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{சிறுகோடு}other{# சிறுகோடுகள்}}</translation>
-<translation id="421884353938374759">வண்ணத் தேர்வி</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">இடதுபக்கம் கலம் இல்லை.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, தரம் <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">குறிப்பு</translation>
-<translation id="4254798249533888099">Tree</translation>
-<translation id="4255943572433203166">ChromeVox ஐத் தனிப்பயனாக்க, கீழேயுள்ள விருப்பங்களைப் பயன்படுத்துக. மாற்றங்கள் உடனடியாகச் செயல்படுத்தப்படும்.</translation>
-<translation id="4271220233568730077">அடுத்த கணிதம்</translation>
-<translation id="4271521365602459209">மேலும் முடிவுகள் இல்லை.</translation>
-<translation id="4287520460805643128">அடுத்த உறுப்பு இல்லை.</translation>
-<translation id="4289540628985791613">மேலோட்டம்</translation>
-<translation id="4300318234632215983">இணைப்புக்குப் பின் இருக்கும் URL ஐ அறிவிக்கவும்</translation>
-<translation id="4301352596632316575">துணைமெனு உள்ளது</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{புள்ளி}=3{முப்புள்ளி}other{# புள்ளிகள்}}</translation>
-<translation id="4347461890115250064">அடுத்த பட்டியல் இல்லை.</translation>
-<translation id="4367650418938037324">கணித ML லீஃப்</translation>
-<translation id="4372435075475052704">குறை.:<ph name="X" /></translation>
-<translation id="4372705107434148843">பேசுவதை நிறுத்தும்</translation>
-<translation id="4373197658375206385">இணைப்பாக இல்லாத முந்தைய உருப்படி இல்லை.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">இணைப்புகள் இல்லை.</translation>
-<translation id="4476183483923481720">புதிய வரி</translation>
-<translation id="4482330759234983253">முந்தைய அட்டவணை</translation>
-<translation id="4491109536499578614">படம்</translation>
-<translation id="4529987814483543472">கிளாஸிக் விசைவரைபடம்</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{சாய்கோடு}other{# சாய்கோடுகள்}}</translation>
-<translation id="4547556996012970016">அடுத்த 5 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="4562381607973973258">தலைப்பு</translation>
-<translation id="4591507479202817876">, தேர்ந்தெடுத்தது</translation>
-<translation id="4597532268155981612">படிவம்</translation>
-<translation id="4597896406374528575">ஏப்ரல்</translation>
-<translation id="4615592953348396470">அடுத்த விசை அழுத்தத்தைத் தவிர்க்கிறது</translation>
-<translation id="461613135510474570">வாக்கியம்</translation>
-<translation id="4647836961514597010">வண்ணத் தேர்வி</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">முந்தைய லேண்ட்மார்க்</translation>
-<translation id="4696413482802371445">அடுத்த 5 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="4729095194763193578">முந்தைய அட்டவணை வரிசை</translation>
-<translation id="4736221692378411923">ஆகஸ்ட்</translation>
-<translation id="4740661827607246557">உதவி கட்டளைகள்</translation>
-<translation id="4759716709594980008">ChromeOS விசைப்பலகை உலவி</translation>
-<translation id="4763296182459741068">கீழ்பகுதிக்கு மடிக்கப்படும்</translation>
-<translation id="4763480195061959176">வீடியோ</translation>
-<translation id="479989351350248267">Search</translation>
-<translation id="481165870889056555">தற்போதைய பக்கத்தின் தலைப்பை அறிவிக்கவும்</translation>
-<translation id="4826415162591436065">முன்னோக்கிச் செல்</translation>
-<translation id="4826604887384865800">அடுத்த தாவல்</translation>
-<translation id="4827410568042294688">தேர்ந்தெடுக்கப்படவில்லை</translation>
-<translation id="4842108708071771135">அடுத்த மேற்கோள் குறி இல்லை.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">இதேபோன்ற முந்தைய உறுப்பு.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS பதிவுசெய்தலை இயக்கு</translation>
-<translation id="4877261390094455813">தேடல் வினவலை உள்ளிடவும்.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">அக இணைப்பு</translation>
-<translation id="4953585991029886728">உரையைத் திருத்து</translation>
-<translation id="4954534434583049121">முந்தைய மேற்கோள் குறி</translation>
-<translation id="4973717656530883744">குறைந்தபட்சம் <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> க்கு மாற்றப்பட்டது.</translation>
-<translation id="4975416682604111799">மில்லிவினாடிகள்</translation>
-<translation id="49787999531187221">ChromeVox இப்போது செயலற்று உள்ளது.</translation>
-<translation id="4979404613699303341">முந்தைய பொத்தான்</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, பட்டியல் பெட்டி</translation>
-<translation id="4983588134362688868">பக்கத்தின் மேல்பகுதிக்குச் செல்லவும்</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, சாளரம்</translation>
-<translation id="4993152509206108683">பேச்சு விகிதம் <ph name="PERCENT" /> சதவீதம்</translation>
-<translation id="4996716799442435517">பார்வை</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, ரேடியோ பொத்தான் தேர்ந்தெடுக்கப்பட்டது</translation>
-<translation id="4997475792277222884">இணைப்பாக இல்லாத அடுத்த உருப்படி இல்லை.</translation>
-<translation id="5000760171916499057">வடிவங்கள் இல்லை.</translation>
-<translation id="5005670136041063723">மேலும் ஒத்த கூறுகள் இல்லை.</translation>
-<translation id="501473567976723023">ஜனவரி</translation>
-<translation id="5041394372352067729">பக்கத்தின் மேல்பகுதிக்கு பிரெய்ல் காட்சியை நகர்த்து</translation>
-<translation id="5042770794184672516">பேச்சு ஒலியளவை அதிகரி</translation>
-<translation id="5050015258024679800">முந்தைய 4 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="5054047268577924192">முந்தைய பட்டியல் உருப்படி</translation>
-<translation id="5078661581131202757">கோப்பு தேர்வு</translation>
-<translation id="5080758118274074384">இரு கிளிக் செய்யப்பட்டது</translation>
-<translation id="5098541983634824365">கட்டத்தை விட்டு விலகுகிறீர்கள்.</translation>
-<translation id="5102981729317424850">கருவிப் பட்டி</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">முந்தைய படிவப் புலம் இல்லை.</translation>
-<translation id="5111640677200759579">நெடுவரிசை மேற்தலைப்பு</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">முந்தைய இணைப்பு இல்லை.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, தேர்வுநீக்கப்பட்டது</translation>
-<translation id="5183440668879371625">பிரெய்ல் முந்தைய வரி</translation>
-<translation id="5184944171021383281">அடுத்த படிவப் புலம் இல்லை.</translation>
-<translation id="5189244881767082992">வரி</translation>
-<translation id="5203930734796605961">ஏற்கனவே ஒரு கட்டளைக்கு <ph name="KEY" /> ஒதுக்கப்பட்டுள்ளது.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> பட்டியல்.</translation>
-<translation id="520883772648104506">அடுத்த ரேடியோ பொத்தான் இல்லை.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">பொருள்</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, தாவல்</translation>
-<translation id="5310788376443009632">அகற்றப்பட்டவை:</translation>
-<translation id="5320727453979144100">ஸ்டிக்கி முறை இயக்கப்பட்டது</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{காற்புள்ளி}other{# காற்புள்ளிகள்}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, உரைப் பெட்டி</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, இணைப்பு</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">தொடர்ந்து படிக்கும் போது பின்னோக்கிச் செல்வதை தவிர்க்கலாம்</translation>
-<translation id="5368000168321181111">ஆடியோ செய்திகளை முடக்கு</translation>
-<translation id="5374320867641260420">அடுத்த பொத்தான் இல்லை.</translation>
-<translation id="5382299583965267720">அடுத்த 1 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="5402367795255837559">பிரெய்ல்</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{அரைப்புள்ளி}other{# அரைப்புள்ளிகள்}}</translation>
-<translation id="5411891038905756502">முந்தைய தாவல் புள்ளி இல்லை.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{குறைவிற்கான குறி}other{# குறைவிற்கான குறிகள்}}</translation>
-<translation id="5455441614648621694">ஈடுசெய்தல்</translation>
-<translation id="5485036206801896268">முந்தைய கிராஃபிக் இல்லை.</translation>
-<translation id="5486947920110100234">அடுத்த தாவல் புள்ளி இல்லை.</translation>
-<translation id="549602578321198708">வார்த்தை</translation>
-<translation id="5500932716852106146">முந்தைய திருத்தக்கூடிய உரைப் புலம் இல்லை.</translation>
-<translation id="5502713021410870035">செப்டம்பர்</translation>
-<translation id="5507663321906818013">பென்ச்மார்க்கைப் பிழைத்திருத்துதல்</translation>
-<translation id="5518443085409638729">உரையைத் திருத்தும்போது எழுத்துகளுக்கு இடையே இடஞ்சுட்டியை வை (Mac OS X போன்று).</translation>
-<translation id="552195134157544755">ரேடியோ பொத்தான்</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">முந்தைய 5 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="556042886152191864">பொத்தான்</translation>
-<translation id="5561345396546889625">அடுத்த பட்டியல்</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">உரையைத் திருத்து, மின்னஞ்சல் உள்ளீடு</translation>
-<translation id="5597170376237141345">அடுத்த செக்பாக்ஸ்</translation>
-<translation id="5597933780944041114">அடுத்த தலைப்பு இல்லை.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, ரேடியோ பொத்தான் தேர்ந்தெடுக்கப்படவில்லை</translation>
-<translation id="5601172225407283979">இயல்பான செயலைச் செயல்படுத்து</translation>
-<translation id="5608798115546226984">தானே நிரப்புதல் இன்லைன்</translation>
-<translation id="561939826962581046">நேரம்</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">பதிவு</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">முந்தைய அட்டவணை இல்லை.</translation>
-<translation id="5655682562155942719">தாவல் கட்டளைகள்</translation>
-<translation id="56637627897541303">உரைப் பகுதி</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">லேண்ட்மார்க்</translation>
-<translation id="5683155931978483559">முந்தைய செக் பாக்ஸ்</translation>
-<translation id="5684277895745049190">பட்டியல்</translation>
-<translation id="5700650669149824506">முந்தைய 4 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="5709192780268610569">நீண்ட விளக்கம் இல்லை</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">அடுத்த அட்டவணை நெடுவரிசை</translation>
-<translation id="571866080859340309">குழுக்களை ஆராய்கிறது</translation>
-<translation id="5728409797179002635">அட்டவணை காணப்படவில்லை.</translation>
-<translation id="5748623122140342504">முந்தைய 5 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="5750633686117194034">மாற்றி எதுவும் அழுத்தப்படவில்லை; ஒன்று அல்லது அதற்கு மேற்பட்ட மாற்றிகளை அழுத்திப் பிடிக்கவும்; முடித்தவுடன் உங்கள் விரல்களை எடுக்கவும், விசைகள் அமைக்கப்படுவதைக் கேட்பீர்கள். வெளியேறத் தட்டவும்.</translation>
-<translation id="5788275253279308023">மறைநிலை சாளரம் <ph name="TITLE" /> தாவல்</translation>
-<translation id="5806206155699461681">குறிப்பிட்ட தளங்களை மேம்படுத்துக (Google தேடல் போன்றவை).</translation>
-<translation id="5819072574982403430">ட்ரீ உருப்படி</translation>
-<translation id="5826479389509458994"><ph name="ROW" /> வரிசை <ph name="COL" /> நெடுவரிசை</translation>
-<translation id="5850707923114094062">பின்னோக்கி நகர்த்து</translation>
-<translation id="5851548754964597211">தாவல் பட்டியல்</translation>
-<translation id="5859752971144398932">பக்கத்தில் கண்டறிவதிலிருந்து வெளியேறியது.</translation>
-<translation id="5866042630553435010">பகுதியளவு சரிபார்க்கப்பட்டது</translation>
-<translation id="5869546221129391014">கட்டம்</translation>
-<translation id="5876817486144482042">பேச்சு ஒலியளவைக் குறை</translation>
-<translation id="5887397643266327462">பிரெய்ல் தலைப்புகள் இயக்கப்பட்டுள்ளன.</translation>
-<translation id="5891934789323004067">அட்டவணை</translation>
-<translation id="5919442531159595654">நகலெடு.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{சமக்குறி}other{# சமக்குறிகள்}}</translation>
-<translation id="5939518447894949180">மீட்டமை</translation>
-<translation id="5948123859135882163">அமைப்பு மற்றும் பொருள்விளக்கத்திற்கு இடையே கணிதக் கோவைகளின் விளக்கத்தை நிலைமாற்றவும்</translation>
-<translation id="5955304353782037793">பயன்பாடு</translation>
-<translation id="5956928062748260866">செய்தி</translation>
-<translation id="5963413905009737549">பிரிவு</translation>
-<translation id="5968607524793740041">சூழல் மெனுவைக் காட்டு</translation>
-<translation id="5983179082906765664">வழிசெலுத்தும் நுணுக்கத்தை அதிகரி</translation>
-<translation id="5999630716831179808">குரல்கள்</translation>
-<translation id="6000417740266304866">கீழே உள்ள பட்டியலில் இருந்து விருப்பத்தைத் தேர்ந்தெடுப்பதன் மூலம் நடப்பிலுள்ள 8 புள்ளி பிரெய்ல் அட்டவணையை மாற்றலாம்.</translation>
-<translation id="6006050241733874051">படிவம்</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{பின்கோடு}other{# பின்கோடுகள்}}</translation>
-<translation id="6037602951055904232">முன்னோக்கி நகர்த்து</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">கலத்தின் இறுதி.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">இடைவெளி</translation>
-<translation id="6142308968191113180">தலைப்பு 4</translation>
-<translation id="6169420925157477918">நீண்ட விளக்கத்துடன் உள்ள படம்</translation>
-<translation id="6172087735260766220">நகலெடுத்தல் பாதுகாக்கப்பட்ட PDF இலிருந்து அணுகல் உரையை அணுக முடியவில்லை.</translation>
-<translation id="6186305613600865047">பக்கத்தின் கீழ்பகுதிக்குச் செல்லவும்</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">கீழ்</translation>
-<translation id="6236061028292614533">அடுத்த தலைப்பு</translation>
-<translation id="6254901459154107917">அடுத்த திருத்தக்கூடிய உரைப் பகுதி</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> இலிருந்து வெளியேறினார்.</translation>
-<translation id="6281876499889881039">இதேபோன்ற அடுத்த உறுப்பு.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">அடுத்த சேர்க்கைப் பெட்டி இல்லை.</translation>
-<translation id="6307969636681130414">அழுத்தப்பட்டது</translation>
-<translation id="6324551002951139333">இலக்கணத் தவறு கண்டுபிடிக்கப்பட்டது</translation>
-<translation id="6348657800373377022">தொகுப்பு பெட்டி</translation>
-<translation id="6355910664415701303">முந்தைய பட்டியல் உருப்படி இல்லை.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">முந்தைய தலைப்பு</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">முந்தைய ரேடியோ பொத்தான் இல்லை.</translation>
-<translation id="6414968628640960377">வேறுபட்ட முந்தைய உறுப்பு.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{முக்காற்புள்ளி}other{# முக்காற்புள்ளிகள்}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, மெனு</translation>
-<translation id="6444046323172968959">விழிப்பூட்டல் செய்தி</translation>
-<translation id="6459511626086141404">தட்டையான விசைவரைபடம்</translation>
-<translation id="6468049171101508116">அடுத்த பொத்தான்</translation>
-<translation id="6491972999578897419">கீழேயுள்ள பட்டியலிலிருந்து விருப்பத்தைத் தேர்ந்தெடுப்பதன் மூலம் தற்போதைய குரலை மாற்றலாம்.</translation>
-<translation id="6508059270146105198">பக்கத்தின் கீழ்ப்பகுதிக்கு பிரெய்ல் காட்சியை நகர்த்து</translation>
-<translation id="6536864053412760904">கணித ML டோக்கன்</translation>
-<translation id="6550720799683018100">கீழேயுள்ள பட்டியலிலிருந்து விருப்பத்தைத் தேர்ந்தெடுப்பதன் மூலம் தற்போதைய விசைவரைபடத்தை மாற்றலாம்.</translation>
-<translation id="6561818612645211875">நடப்பு வரிசையின் தொடக்கத்திற்குச் செல்</translation>
-<translation id="6587021927234520429">அடுத்த 4 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="6601344353291556895">சொற்களஞ்சிய விளக்கங்களை இயக்கு.</translation>
-<translation id="6615602925644411249">பக்கத்தில் கண்டறி.</translation>
-<translation id="6633350132811819843">அடுத்த அட்டவணை இல்லை.</translation>
-<translation id="6637586476836377253">பதிவு</translation>
-<translation id="6657128831881431364">செயல்நிலைப் பட்டி</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">ஆவணம்</translation>
-<translation id="6697092096875747123">முந்தைய சேர்க்கைப் பெட்டி</translation>
-<translation id="6714813999819678458">முந்தைய, 2 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="6716505898850596801">மாற்றி விசைகள்</translation>
-<translation id="671916444866103745">அடுத்த ARIA லேண்ட்மார்க் இல்லை.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, சேர்க்கைப் பெட்டி</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> உருப்படிகளுடன்</translation>
-<translation id="6736510033526053669">தாவல் உருவாக்கப்பட்டது</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">உறுப்பு</translation>
-<translation id="6787839852456839824">விசைப்பலகைக் குறுக்குவழிகள்</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">அடிக்குறிப்பு</translation>
-<translation id="6871161210040114857">எழுத்து உணர்வு புறக்கணிக்கப்பட்டது.</translation>
-<translation id="6877435256196695200">அடுத்த கிராஃபிக் இல்லை.</translation>
-<translation id="6897341342232909480">இடப்புறம் நகர்த்து</translation>
-<translation id="6901540140423170855">தேதி</translation>
-<translation id="6910211073230771657">நீக்கப்பட்டது</translation>
-<translation id="6911965441508464308">மேலே கலம் இல்லை.</translation>
-<translation id="6919104639734799681">அட்டவணைகள் பட்டியலைக் காட்டு</translation>
-<translation id="6964088412282673743">முந்தைய கட்டுப்பாடு இல்லை.</translation>
-<translation id="6996566555547746822">அடுத்த சேர்க்கைப் பெட்டி</translation>
-<translation id="7005146664810010831">URL இல்லை</translation>
-<translation id="7010712454773919705">ChromeVox மாற்றி விசை</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">முந்தைய பட்டியல்</translation>
-<translation id="7041173719775863268">தேர்வின் இறுதி</translation>
-<translation id="7095834689119144465">உரை எண்ணை மட்டும் திருத்து</translation>
-<translation id="7096001299300236431">முந்தைய ஊடகம்</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">சொல் எதிரொலி</translation>
-<translation id="713824876195128146">அடுத்த மேற்கோள் குறி</translation>
-<translation id="7161771961008409533">பாப்-அப் பொத்தான்</translation>
-<translation id="7167657087543110">எழுத்து எதிரொலி</translation>
-<translation id="7170733337935166589">தொடர்ந்து படிக்கும் போது முன்னோக்கிச் செல்வதை தவிர்க்கலாம்</translation>
-<translation id="7181697990050180700">கீழே தொடர்புடைய புலங்களில் விசைப்பலகை குறுக்குவழிகளைத் தட்டச்சு செய்வதன் மூலம் அடிக்கடி பயன்படுத்தப்படும் கட்டளைகளுக்கு அவற்றைத் தனிப்பயனாக்கலாம்.</translation>
-<translation id="7203150201908454328">விரிவாக்கப்பட்டது</translation>
-<translation id="7210211103303402262">நிமிடங்கள்</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">வரி</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">தலைப்பு</translation>
-<translation id="7241683698754534149">நீண்ட விளக்கத்தைப் புதிய தாவலில் திறக்கவும்</translation>
-<translation id="7248671827512403053">பயன்பாடு</translation>
-<translation id="725969808843520477">அடுத்த ரேடியோ பொத்தான்</translation>
-<translation id="7269119382257320590">நிறுத்தற்குறி இல்லை</translation>
-<translation id="7273174640290488576">வெற்று</translation>
-<translation id="7285387653379749618">அட்டவணைகள்</translation>
-<translation id="7289186959554153431">தலைப்பு 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">பிரெய்ல் தலைப்புகள் முடக்கப்பட்டுள்ளன.</translation>
-<translation id="7318872822751139669">கவனத்தை மாற்ற சுட்டியைப் பயன்படுத்துக.</translation>
-<translation id="7322388933135261569">பிப்ரவரி</translation>
-<translation id="7332592614823088566"><ph name="ROWTOTAL" /> இல் <ph name="ROWINDEX" /> வது வரிசை, <ph name="COLTOTAL" /> இல் <ph name="COLINDEX" /> வது நெடுவரிசை</translation>
-<translation id="7336596009609913925">பாப்அப் உள்ளது</translation>
-<translation id="7356165926712028380">8 புள்ளி பிரெய்லுக்கு மாறு</translation>
-<translation id="7362871137496673139">முந்தைய 2 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{உம்மைக்குறி}other{# உம்மைக்குறிகள்}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">அட்டவணையிலிருந்து வெளியேறுகிறீர்கள்</translation>
-<translation id="739763518212184081">முந்தைய வரி</translation>
-<translation id="7400575256015741911">எழுத்துப் பிழை கண்டுபிடிக்கப்பட்டது</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">வரியின் தொடக்கம்</translation>
-<translation id="7434509671034404296">டெவலப்பர்</translation>
-<translation id="7439060726180460871">கோப்பகம்</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">உரையாடலை உள்ளிட்டுள்ளீர்கள்</translation>
-<translation id="7532613204005497612">ஜூன்</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, ஸ்லைடர்</translation>
-<translation id="7586163296341959563">ஒட்டு.</translation>
-<translation id="7596919493010894443">தேர்வுகள் அழிக்கப்பட்டன</translation>
-<translation id="7604026522577407655">நடப்பு நெடுவரிசையின் தொடக்கத்திற்குச் செல்</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">தற்போதைய பக்கத்தின் URL ஐ அறிவி</translation>
-<translation id="7609363189280667021">பிரெய்ல் தலைப்புகளை நிலைமாற்று</translation>
-<translation id="762020119231868829">தற்போது இயங்கும் எல்லா ஊடக விட்ஜெட்டுகளையும் இடைநிறுத்தும்</translation>
-<translation id="7625690649919402823">அடுத்த அட்டவணை</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), தரம் <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">முந்தைய 3 ஆம் படிநிலை தலைப்பு இல்லை.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, உரைப் பெட்டி</translation>
-<translation id="7663318257180412551">தலைப்பு 2</translation>
-<translation id="7674576868851035240">அடுத்த இணைப்பு</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">உரையைத் திருத்து, URL உள்ளீடு</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">முந்தைய ரேடியோ பொத்தான்</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, கடவுச்சொல் உரைப் பெட்டி</translation>
-<translation id="7805247615045262757">இயல்பு வழிநடத்தல்</translation>
-<translation id="7805768142964895445">நிலை</translation>
-<translation id="7810781339813764006">அடுத்த குழு</translation>
-<translation id="7819187121850078213">சாளரம் <ph name="TITLE" /> தாவல்</translation>
-<translation id="7828956995407538686">அக்டோபர்</translation>
-<translation id="7839679365527550018">முந்தைய வார்த்தை</translation>
-<translation id="7851816175263618915">சில நிறுத்தற்குறிகள் இருக்கலாம்</translation>
-<translation id="7870596830398826354">கணித ML ட்ரீ</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox கிளாசிக்கை நிலைமாற்று.</translation>
-<translation id="7895896691902835279">அறியப்படாத இணைப்பு</translation>
-<translation id="7927711904086083099">தேர்ந்தெடுக்கப்படவில்லை</translation>
-<translation id="7935627501098484003">நேரக் கட்டுப்பாடு</translation>
-<translation id="7939428177581522200">தேர்வில் சேர்க்கப்பட்டது</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{வீதக் குறி}other{# வீதக் குறிகள்}}</translation>
-<translation id="7965147473449754028">மெனு மூடப்பட்டது</translation>
-<translation id="7974390230414479278">மெனு உருப்படி</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ஆச்சர்யக் குறி}other{# ஆச்சர்யக் குறிகள்}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{மேற்கோள்}other{# மேற்கோள்கள்}}</translation>
-<translation id="8033827949643255796">தேர்ந்தெடுக்கப்பட்டன</translation>
-<translation id="8035962149453661158">அதிகபட்சம்:<ph name="X" /></translation>
-<translation id="8042761080832772327">உரையைத் திருத்து, தேடல் உள்ளீடு</translation>
-<translation id="8049189770492311300">டைமர்</translation>
-<translation id="8065607967589909823">நடப்பு தேர்வு</translation>
-<translation id="8066678206530322333">பேனர்</translation>
-<translation id="8110647606445335195">ARIA லேண்ட்மார்க்குகள் இல்லை.</translation>
-<translation id="8153880621934657047">அட்டவணையின் உள்ளே கிடையாது.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{அடிக்கோடு}other{# அடிக்கோடுகள்}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">வெட்டு.</translation>
-<translation id="8199231515320852133">நடப்புக் கலத்தின் தலைப்புகளை அறிவிக்கும்</translation>
-<translation id="820417203470636242">வெற்றுக் கலம்.</translation>
-<translation id="8215202828671303819">பலவற்றைத் தேர்ந்தெடுத்தல்</translation>
-<translation id="8276439074553447000">முன்பு கவனிக்கப்பட்ட உருப்படிக்குத் தாவு</translation>
-<translation id="8278417001922463147">முந்தைய உறுப்பு இல்லை.</translation>
-<translation id="8283603667300770666">அடுத்தப் படிவப் புலம்</translation>
-<translation id="831207808878314375">விளக்கம்</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">மணிநேரம்</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{எண் குறியீடு}other{# எண் குறியீடுகள்}}</translation>
-<translation id="8374154622594089836">மாதம்</translation>
-<translation id="8378855320830505539">பகுதி</translation>
-<translation id="8382679411218029383">தானே நிரப்புதல் இன்லைன் மற்றும் பட்டியல்</translation>
-<translation id="8428603554127842284">நிலை <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">அடுத்த 3 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">முந்தைய செக் பாக்ஸ் இல்லை.</translation>
-<translation id="8455868257606149352">அதிகபட்சம் <ph name="X" /></translation>
-<translation id="84575901236241018">அணுகல் விசை உள்ளது, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">வழிசெலுத்தும் நுணுக்கத்தைக் குறை</translation>
-<translation id="8520472399088452386">சுழல் பொத்தான்</translation>
-<translation id="8538744478902126321">நடப்புக் கலத்தின் வரிசைத் தலைப்பில் யூகத்தை உருவாக்கு</translation>
-<translation id="8540054775867439484">மேல்பகுதிக்கு மடிக்கப்படும்</translation>
-<translation id="8548973727659841685">எழுத்து</translation>
-<translation id="8561322612995434619">பாப்-அப் உள்ளது</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">அடுத்த பட்டியல் உருப்படி</translation>
-<translation id="860150890330522909"><ph name="NAME" /> செக் பாக்ஸ் தேர்ந்தெடுக்கப்பட்டது</translation>
-<translation id="8606621670302093223">தேதிக் கட்டுப்பாடு</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> உருப்படிகள் தேர்ந்தெடுக்கப்பட்டன</translation>
-<translation id="8638532244051952400">தற்போதைய கல அச்சுகளைத் தெரிவி</translation>
-<translation id="8650576015643545550">முந்தைய பட்டியல் இல்லை.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">இணைப்புகளின் பட்டியலைக் காட்டு</translation>
-<translation id="8664519043722036194">வினாடிகள்</translation>
-<translation id="867187640362843212">தலைப்பு 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{குத்துக் கோடு}other{# செங்குத்தான குத்துக் கோடுகள்}}</translation>
-<translation id="8735450637152821465">தேர்வைத் தொடங்கு</translation>
-<translation id="8743786158317878347">அட்டவணைகள் போன்ற கட்டமைக்கப்பட்ட உள்ளடக்கத்தை உள்ளிடும்</translation>
-<translation id="8747966237988593539">வரிசைப்படுத்தப்பட்ட பட்டியல்</translation>
-<translation id="8759334257841767240">அடுத்த இணைப்பு இல்லை.</translation>
-<translation id="8767968232364267681">அடுத்த 4 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="8770473310765924354">அட்டவணைகள் போன்ற கட்டமைக்கப்பட்ட உள்ளடக்கத்தை வெளியேற்றும்</translation>
-<translation id="8791025954632646584">பொருள்விளக்கம் இயக்கப்பட்டது</translation>
-<translation id="8796411681063377102">அடுத்த 3 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="8808582214901541005">மார்ச்</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">முதன்மை</translation>
-<translation id="8856538297388979332">கட்டளைகளை மதிப்புரை செய்ய மேல் அல்லது கீழ் அம்புக்குறியை அழுத்தவும், செயல்படுத்த enter ஐ அழுத்தவும்</translation>
-<translation id="8864099967139188018">அடுத்த 6 ஆம் நிலை தலைப்பு இல்லை.</translation>
-<translation id="8882002077197914455">வரிசை தலைப்பு</translation>
-<translation id="8896347895970027998">ChromeVox ஐ செயலில் அல்லது செயலற்ற நிலைக்கு மாற்றுக.</translation>
-<translation id="8898516272131543774">தொடர் நிறுத்தற்குறி எதிரொலி</translation>
-<translation id="8900148057318340779">முன்னொட்டு விசை</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">காலியான மேற்தலைப்புகள்</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">மாற்றி விசைகள்</translation>
-<translation id="8943175951035496220">வலப்புறத்தில் கலம் இல்லை.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">கோப்பு</translation>
-<translation id="9027462562263121875">அட்டவணைகள் இல்லை.</translation>
-<translation id="9040132695316389094">தலைப்பு 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">தேடல் விட்ஜெட்டை மாற்று</translation>
-<translation id="9065283790526219006">+பாப்அப்</translation>
-<translation id="9077213568694924680">தேர்விலிருந்து அகற்றப்பட்டது</translation>
-<translation id="9082874451376019682">முந்தைய ஸ்லைடர் இல்லை.</translation>
-<translation id="9089864840575085222">தொடர் தட்டச்சிடும் எதிரொலி</translation>
-<translation id="9107530006868467849">முந்தைய ஊடக விட்ஜெட் இல்லை.</translation>
-<translation id="9108370397979208512">கணிதம்</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{விழுக்காட்டுச் சின்னம்}other{# விழுக்காட்டுச் சின்னங்கள்}}</translation>
-<translation id="9115913704608474258">நவம்பர்</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">தற்போதைய நிலையின் சுருக்கமான விளக்கத்தை அறிவிக்கிறது</translation>
-<translation id="9153606228985488238">ஸ்ருதி <ph name="PERCENT" /> சதவீதம்</translation>
-<translation id="9160096769946561184">நடப்பு நெடுவரிசையின் இறுதிக்கு செல்</translation>
-<translation id="9173115498289768110">ஒலியளவு <ph name="PERCENT" /> சதவீதம்</translation>
-<translation id="9178973770513562274">உலாவ மேல் மற்றும் கீழ் அம்புக்குறியைப் பயன்படுத்தவும் அல்லது தேட உள்ளிடவும்.</translation>
-<translation id="9192904702577636854">மார்கியூ</translation>
-<translation id="9212322457209634662">அடுத்த பிரிவு இல்லை.</translation>
-<translation id="930275611743429116">தொடக்க அல்லது இறுதித் தேர்வு.</translation>
-<translation id="948171205378458592">பேச்சின் விகிதத்தைக் குறை</translation>
-<translation id="962913030769097253">அடுத்த 1 ஆம் படிநிலை தலைப்பு</translation>
-<translation id="973955474346881951">ஸ்டிக்கி பயன்முறையை இயக்கு/முடக்கு</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb
deleted file mode 100644
index 455070479b9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="te">
-<translation id="1012173283529841972">జాబితా అంశం</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">వ్యాపించింది.</translation>
-<translation id="1025074108959230262">స్టిక్కీ మోడ్ నిలిపివేయబడింది</translation>
-<translation id="1031961866430398710">తర్వాత</translation>
-<translation id="1044777062731150180">ముఖ్య శీర్షికలు లేవు</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">ఇన్‌పుట్ చెల్లదు</translation>
-<translation id="1082209053475788238">మునుపటి స్థాయి 6 శీర్షిక లేదు.</translation>
-<translation id="1088219014394087294">శీర్షికలు లేవు.</translation>
-<translation id="1106741348836243114">ధ్వని అభిప్రాయాన్ని (శబ్ద హెచ్చరికలు) ప్రారంభించండి లేదా ఆపివేయండి.</translation>
-<translation id="1120743664840974483">{"a": "ఆల్ఫా", "b": "బ్రావో", "c": "చార్లీ", "d": "డెల్టా", "e": "ఎకో", "f": "ఫాక్స్‌ట్రాట్", "g": "గోల్ఫ్", "h": "హోటల్", "i": "ఇండియా", "j": "జూలియట్","k": "కిలో", "l": "లీమా", "m": "మైక్", "n": "నవంబర్", "o": "ఆస్కార్","p": "పాపా", "q": "క్యూబెక్", "r": "రోమియో", "s": "సియెర్రా", "t": "ట్యాంగో", "u": "యూనిఫారమ్", "v": "విక్టర్", "w": "విస్కీ","x": "ఎక్స్‌రే", "y": "యాంకీ", "z": "జూలూ"}</translation>
-<translation id="113582498867142724"><ph name="NUM" /> అంశాలు గల <ph name="TAG" /> సేకరణ</translation>
-<translation id="1155043339247954670">తదుపరి జాబితా అంశం లేదు.</translation>
-<translation id="1157782847298808853">కీబోర్డ్ సహాయం</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, కాంబో పెట్టె</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, మెను అంశం, ఉపమెనుని కలిగి ఉంది</translation>
-<translation id="1177863135347784049">అనుకూలీకరించిన</translation>
-<translation id="1188858454923323853">బహుమానపూర్వకం</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Chromeకు వాయిస్‌ను ఇస్తోంది</translation>
-<translation id="1229276918471378188">మునుపటి జంప్</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">తదుపరి స్థాయి 6 శీర్షిక</translation>
-<translation id="1275718070701477396">ఎంపికైంది</translation>
-<translation id="1319608975892113573">మునుపటి బ్లాక్‌కోట్ లేదు.</translation>
-<translation id="1321576897702511272">ChromeVox సహాయాన్ని దాచండి</translation>
-<translation id="1331702245475014624"><ph name="TOTAL" />లో <ph name="INDEX" /></translation>
-<translation id="1334095593597963605">అక్షరం మరియు పదం అనుకరణ</translation>
-<translation id="1339428534620983148">మునుపటి పట్టిక నిలువు వరుస</translation>
-<translation id="1342835525016946179">కథనం</translation>
-<translation id="1346748346194534595">కుడి</translation>
-<translation id="136718599399906424">తదుపరి పట్టిక అడ్డు వరుస</translation>
-<translation id="1383876407941801731">శోధించు</translation>
-<translation id="1385214448885562192">ఆమోదించడానికి enterని లేదా రద్దు చేయడానికి escapeని, తదుపరి దాని కోసం క్రిందికి మరియు మునుపటి దాని కోసం పైకి నొక్కండి.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, పాస్‌వర్డ్ వచన పెట్టె</translation>
-<translation id="1467432559032391204">ఎడమ</translation>
-<translation id="1474557363159888097">మునుపటి యాంకర్ లేదు.</translation>
-<translation id="1502086903961450562">మునుపటి గ్రాఫిక్</translation>
-<translation id="1506187449813838456">స్వర స్థాయిని పెంచండి</translation>
-<translation id="151784044608172266">తదుపరి వాక్యం</translation>
-<translation id="1524531499102321782">బ్రెయిలీ తదుపరి పంక్తి</translation>
-<translation id="1546370775711804143">స్క్రోల్ పట్టీ</translation>
-<translation id="1559739829547075274">వెనుకకు నావిగేట్ చేయండి</translation>
-<translation id="1571643229714746283">ChromeVox సిద్ధంగా ఉంది</translation>
-<translation id="158493514907962286">డిసెంబర్</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6 చుక్కల బ్రెయిలీకి మార్చు</translation>
-<translation id="1611168825862729585">నిలువు వరుస శీర్షిక:</translation>
-<translation id="1613476421962910979">శబ్ద హెచ్చరికలు ప్రారంభించబడ్డాయి</translation>
-<translation id="1618597272655350600">ప్రస్తుత స్థానం యొక్క పూర్తి వివరణను తెలియజేస్తుంది</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{గురుతర గుర్తు}other{# గురుతర గుర్తులు}}</translation>
-<translation id="1653266918374749391">మునుపటి స్థాయి 3 శీర్షిక</translation>
-<translation id="1659072772017912254">ఎంచుకోబడలేదు</translation>
-<translation id="1669290819662866522">వారం</translation>
-<translation id="1674262202423278359">ChromeVox నావిగేషన్</translation>
-<translation id="16777221443363124">మెను పట్టీ</translation>
-<translation id="1692077714702418899">ఆకృతీకరణ పంక్తి</translation>
-<translation id="1700517974991662022">సందర్శించబడింది</translation>
-<translation id="1722567105086139392">లింక్</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">తదుపరి గ్రాఫిక్</translation>
-<translation id="1781173782405573156">పాస్ థ్రూ కీ</translation>
-<translation id="1787176709638001873">పాస్‌వర్డ్ సవరణ వచనం</translation>
-<translation id="1810107444790159527">జాబితా పెట్టె</translation>
-<translation id="1828385960365606039">మే</translation>
-<translation id="1834891354138622109">నిలువు వరుస</translation>
-<translation id="1865601187525349519">వచనం యొక్క ముగింపు</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">ప్రస్తుత సమయాన్ని మరియు తేదీని చదివి వినిపించండి.</translation>
-<translation id="1902396333223336119">సెల్</translation>
-<translation id="1905379170753160525">శీర్షికల జాబితాను చూపండి</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">సంవత్సరంలో వారం నియంత్రణ</translation>
-<translation id="1964135212174907577">తదుపరి ఆబ్జెక్ట్</translation>
-<translation id="1969092762068865084">జూలై</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">అడ్డు వరుస శీర్షిక:</translation>
-<translation id="2002895034995108595">ప్రస్తుత కీమ్యాప్‌ను రీసెట్ చేయి</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{ఎడమ కుండలీకరణ గుర్తు}other{# ఎడమ కుండలీకరణ గుర్తులు}}</translation>
-<translation id="2045490512405922022">ఎంచుకోబడలేదు</translation>
-<translation id="20601713649439366">మునుపటి గణిత వ్యక్తీకరణ లేదు.</translation>
-<translation id="207477615537953741">అర్థ వివరణలు ఆపివేయబడ్డాయి</translation>
-<translation id="2086961585857038472">తదుపరి పదం</translation>
-<translation id="2089387485033699258">en</translation>
-<translation id="2091933974477985526">మునుపటి సవరించగల వచన ప్రదేశం</translation>
-<translation id="2100350898815792233">అన్ని విరామచిహ్నాలు</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">ప్రాప్యత కీ:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">దిగువ జాబితా నుండి ఎంపికను ఎంచుకోవడం ద్వారా ప్రస్తుత 6 చుక్కల బ్రెయిలీ పట్టికను మార్చండి.</translation>
-<translation id="2169714232367507776">ప్రస్తుత అంశంపై క్లిక్ చేయండి</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{మూసిన కుండలీకరణ గుర్తు}other{# మూసిన కుండలీకరణ గుర్తులు}}</translation>
-<translation id="2199994615414171367">మునుపటి గణితం</translation>
-<translation id="2223693656926968778">ప్రస్తుత అంశంపై చర్య తీసుకోండి</translation>
-<translation id="225732394367814946">ప్రసంగ రేటు పెంచండి</translation>
-<translation id="2267945578749931355">తదుపరి అక్షరం</translation>
-<translation id="2281234842553884450">మునుపటి స్లయిడర్</translation>
-<translation id="2318372665160196757">ప్రధానం</translation>
-<translation id="2329324941084714723">ట్యాబ్ ప్యానెల్</translation>
-<translation id="2344193891939537199">తేదీ సమయ నియంత్రణ</translation>
-<translation id="2359897517538099099">పట్టిక మోడ్‌లో లేదు.</translation>
-<translation id="241124561063364910">దీని తర్వాత</translation>
-<translation id="2417569100218200841">కంటెంట్ సమాచారం</translation>
-<translation id="2422937916923936891">మెను అంశం తనిఖీపెట్టె</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> ఇప్పుడు కొత్త ChromeVox మాడిఫైయర్.</translation>
-<translation id="2450814015951372393">తనిఖీపెట్టె</translation>
-<translation id="2462626033734746142">రేడియో బటన్ సమూహం</translation>
-<translation id="2471138580042810658">శీర్షిక 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{నక్షత్రం గుర్తు}other{# నక్షత్రం గుర్తులు}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> రీసెట్ చేయబడింది.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">సమూహం</translation>
-<translation id="2582407057977008361">ప్రక్కన</translation>
-<translation id="2589102159832527089">ఈ పేజీ PDF ఫైల్ &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; నుండి స్వయంచాలకంగా సంగ్రహించిన వచనాన్ని కలిగి ఉంది. &lt;a href="<ph name="URL" />"&gt;అసలైనదాని కోసం ఇక్కడ క్లిక్ చేయండి.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">{COUNT,plural, =1{# అంశంతో}other{# అంశాలతో}}</translation>
-<translation id="2614981083756825552">గణిత ML లేఅవుట్</translation>
-<translation id="2626530649491650971">క్లిక్ చేయదగినది</translation>
-<translation id="2628764385451019380">మునుపటి కాంబో పెట్టె లేదు.</translation>
-<translation id="2637227747952042642">గణితం</translation>
-<translation id="2639750663247012216">ChromeVox మాడిఫైయర్</translation>
-<translation id="2644542693584024604">అక్షరక్రమం తప్పుగా ఉంది</translation>
-<translation id="2667291555398229137">రూటింగ్ కీ దిగువ ఉన్న అంశాన్ని క్లిక్ చేయండి</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{తెరిచిన కుండలీకరణ గుర్తు}other{# తెరిచిన కుండలీకరణ గుర్తులు}}</translation>
-<translation id="2705875883745373140">నొక్కబడలేదు</translation>
-<translation id="2706462751667573066">Up</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ఆడియో</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">తనిఖీ చేయబడింది</translation>
-<translation id="27527859628328957">తదుపరి ఫోకస్ చేయగల అంశానికి వెళ్లండి</translation>
-<translation id="2770781857296573485">సమూహ విశ్లేషణలోకి ప్రవేశించండి</translation>
-<translation id="2777845298774924149">నిష్క్రమించింది</translation>
-<translation id="2800204403141299078">ఇక విభిన్న మూలకాలు లేవు.</translation>
-<translation id="2800780099804980316">మునుపటి స్థాయి 1 శీర్షిక లేదు.</translation>
-<translation id="2811204574343810641">అడ్డు వరుస</translation>
-<translation id="2816654101880605877">తదుపరి స్లయిడర్ లేదు.</translation>
-<translation id="2841013758207633010">సమయం</translation>
-<translation id="2843837985843789981">మునుపటి సమూహం</translation>
-<translation id="2844995807198708617">సందర్భోచిత మెను</translation>
-<translation id="2849332794118375855">తదుపరి తనిఖీపెట్టె లేదు.</translation>
-<translation id="2864481629947106776">మునుపటి లింక్</translation>
-<translation id="2873259058405069099">పట్టిక ప్రారంభానికి వెళ్లండి</translation>
-<translation id="2894654529758326923">సమాచారం</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{ఎడమ ధనుర్బంధ గుర్తు}other{# ఎడమ ధనుర్బంధ గుర్తులు}}</translation>
-<translation id="2911433807131383493">ChromeVox ట్యుటోరియల్‌ను తెరవండి</translation>
-<translation id="2932083475399492303">ఆకృతీకరణ లేదా లేఅవుట్ మధ్య పంక్తి రకాన్ని టోగుల్ చేయండి</translation>
-<translation id="2964026537669811554">శీర్షిక సమూహం</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{ట్యాబ్}other{# ట్యాబ్‌లు}}</translation>
-<translation id="2972078295414139404">మునుపు సందర్శించిన లింక్ లేదు.</translation>
-<translation id="2972205263822847197">సాధన చిట్కా</translation>
-<translation id="2998131015536248178">మునుపటి అక్షరం</translation>
-<translation id="2999559350546931576">స్వర స్థాయి తగ్గించండి</translation>
-<translation id="2999945368667127852">తదుపరి మీడియా విడ్జెట్ లేదు.</translation>
-<translation id="3012414509011670858">మునుపటి విభాగం లేదు.</translation>
-<translation id="3030432017085518523">మెను అంశం రేడియో బటన్</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{సంగ్రాహక గుర్తు}other{# సంగ్రాహక గుర్తులు}}</translation>
-<translation id="3046838483509668188">ChromeVox ఎంపికలు</translation>
-<translation id="3047143736589213134">ప్రయోగాత్మక కీమ్యాప్</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> మెను తెరవబడింది</translation>
-<translation id="3078345202707391975">తదుపరి స్థాయి 2 శీర్షిక</translation>
-<translation id="3078740164268491126">పట్టిక</translation>
-<translation id="3082557070674409251">క్లిక్ చేయబడింది</translation>
-<translation id="3084806535845658316">టైపింగ్ అనుకరణ లేదు</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">తదుపరి గణిత వ్యక్తీకరణ లేదు.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">తదుపరి మైలురాయి</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">కుదించబడింది</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">మైలురాళ్ల జాబితాను చూపండి</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">తదుపరి పంక్తి</translation>
-<translation id="3155083529632865074">మునుపటి బటన్ లేదు.</translation>
-<translation id="3163593631834463955">ఖాళీ నిలువు వరుస శీర్షిక</translation>
-<translation id="316542773973815724">నావిగేషన్</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{ఖాళీ}other{# ఖాళీలు}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" />లోకి ప్రవేశించారు</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, ట్యాబ్</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">సందర్శించిన లింక్</translation>
-<translation id="323731244387692321">ChromeVox కీబోర్డ్ సహాయాన్ని తెరవండి</translation>
-<translation id="3241052487511142956">మునుపు సందర్శించిన లింక్</translation>
-<translation id="3286390186030710347">స్లయిడర్</translation>
-<translation id="3299925995433437805">తదుపరి సందర్శించిన లింక్ లేదు.</translation>
-<translation id="3303384412438961941">దీని పేరు తెలుసుకోవడానికి ఏ కీ అయినా నొక్కండి. Ctrl+W కీబోర్డ్ ఎక్స్‌ప్లోరర్‌ను మూసివేస్తుంది.</translation>
-<translation id="3307886118343381874">పట్టిక చివరకు వెళ్లండి</translation>
-<translation id="3311969765485641742">హెచ్చరికలను సమీక్షించడానికి Alt+Shift+A నొక్కండి</translation>
-<translation id="3312997241656799641">తదుపరి సందర్శించిన లింక్</translation>
-<translation id="3321460131042519426">పదాల సర్దుబాటుని ప్రారంభించు</translation>
-<translation id="3322936298410871309">మునుపటి స్థాయి 1 శీర్షిక</translation>
-<translation id="3323447499041942178">టెక్స్ట్ బాక్స్</translation>
-<translation id="3353420241558113817">{"ar": "అరబిక్",
- "bg": "బల్గేరియన్",
- "ca": "క్యాటలాన్",
- "cs": "చెక్",
- "da": "డానిష్",
- "de": "జర్మన్",
- "de_CH": "జర్మన్ (స్విట్జర్లాండ్)",
- "de_DE": "జర్మన్ (జర్మనీ)",
- "el": "గ్రీక్",
- "en": "ఆంగ్లం",
- "en_CA": "ఆంగ్లం (కెనడా)",
- "en_GB": "ఆంగ్లం (యునైటెడ్ కింగ్‌డమ్)",
- "en_US": "ఆంగ్లం (యునైటెడ్ స్టేట్స్)",
- "es": "స్పానిష్",
- "et": "ఎస్టోనియన్",
- "fr": "ఫ్రెంచ్",
- "fr_CA": "ఫ్రెంచ్ (కెనడా)",
- "fr_FR": "ఫ్రెంచ్ (ఫ్రాన్స్)",
- "fi": "ఫిన్నిష్",
- "he": "హిబ్రూ",
- "hi": "హిందీ",
- "hr": "క్రొయేషియన్",
- "hu": "హంగేరియన్",
- "is": "ఐస్‌ల్యాండిక్",
- "it": "ఇటాలియన్",
- "ko": "కొరియన్",
- "lt": "లిథువేనియన్",
- "lv": "లాత్వియన్",
- "nb": "నార్వేజియన్ బొక్మాల్",
- "nl": "డచ్",
- "pl": "పోలిష్",
- "pt": "పోర్చుగీస్",
- "ro": "రొమేనియన్",
- "ru": "రష్యన్",
- "sk": "స్లోవక్",
- "sl": "స్లొవేనియన్",
- "sr": "సెర్బియన్",
- "sv": "స్వీడిష్",
- "tr": "టర్కిష్",
- "vi": "వియత్నామీస్",
- "zh": "చైనీస్",
- "zh_TW": "చైనీస్ (సాంప్రదాయక హాన్)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{కూడిక గుర్తు}other{# కూడిక గుర్తులు}}</translation>
-<translation id="338583716107319301">విభాగిని</translation>
-<translation id="3389259863310851658">మునుపటి ఫారమ్ ఫీల్డ్</translation>
-<translation id="3390225400784126843">తదుపరి విభిన్న మూలకం.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, మెను అంశం</translation>
-<translation id="3406283310380167331">ఫారమ్‌ల జాబితాను చూపండి</translation>
-<translation id="3422338090358345848">కీబోర్డ్ ఎక్స్‌ప్లోరర్‌ను తెరవండి</translation>
-<translation id="3457000393508828486">పాక్షికంగా నొక్కబడింది</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, బటన్</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> నుండి <ph name="V2" /> వరకు</translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{కుడి కుండలీకరణ గుర్తు}other{# కుడి కుండలీకరణ గుర్తులు}}</translation>
-<translation id="3493915602752813531">తదుపరి యాంకర్ లేదు.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{ప్రశ్నార్థక గుర్తు}other{# ప్రశ్నార్థక గుర్తులు}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{హంసపాదు గుర్తు}other{# హంసపాదు గుర్తులు}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, తనిఖీపెట్టె ఎంచుకోబడలేదు</translation>
-<translation id="3599054940393788245">లోపల గణితం కాదు</translation>
-<translation id="3616113530831147358">ఆడియో</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{బ్యాక్‌టిక్ గుర్తు}other{# బ్యాక్‌టిక్ గుర్తులు}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{డాలర్ గుర్తు}other{# డాలర్ గుర్తులు}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, జాబితా పెట్టె</translation>
-<translation id="3687295507293856493">ప్రస్తుత సెల్ యొక్క నిలువు వరుస శీర్షిక వద్ద అంచనా వేయండి</translation>
-<translation id="3692274950075847560">శో:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">ప్రసంగాన్ని నియంత్రించడం</translation>
-<translation id="3716845769494773620">బహుళ పంక్తి</translation>
-<translation id="3731746171184829332">మునుపటి శీర్షిక లేదు.</translation>
-<translation id="3762198587642264450">ప్రస్తుత అడ్డు వరుస యొక్క చివరకు వెళ్లండి</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">నిష్క్రమణ డైలాగ్.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">స్వీయపూర్తి జాబితా</translation>
-<translation id="3810838688059735925">వీడియో</translation>
-<translation id="3816633764618089385">తదుపరి మీడియా</translation>
-<translation id="3819376190738087562">జంప్‌లు లేవు.</translation>
-<translation id="385383972552776628">ఎంపికల పేజీని తెరవండి</translation>
-<translation id="3856075812838139784">చదవడానికి మాత్రమే</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">మెను</translation>
-<translation id="3909320334364316587">మునుపటి స్థాయి 6 శీర్షిక</translation>
-<translation id="3914173277599553213">అవసరమైనవి</translation>
-<translation id="3962990492275676168">ప్రస్తుత స్థానం నుండి చదవడం ప్రారంభించండి</translation>
-<translation id="4004802134384979325">ఎంచుకోబడింది</translation>
-<translation id="4006140876663370126">చిత్రం</translation>
-<translation id="4038349100599457191">నెల నియంత్రణ</translation>
-<translation id="4039983576244166038">ఖాళీ అడ్డు వరుస శీర్షిక</translation>
-<translation id="4042843249978639960">తదుపరి స్థాయి 2 శీర్షిక లేదు.</translation>
-<translation id="4043348641337972076">మునుపటి ARIA మైలురాయి లేదు.</translation>
-<translation id="4047216625641135770">గుర్తు పెట్టండి</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{టిల్డ్ గుర్తు}other{# టిల్డ్ గుర్తులు}}</translation>
-<translation id="409334809956508737">మునుపటి ఆబ్జెక్ట్</translation>
-<translation id="4099274309791143834">ఉపమెనును కలిగి ఉంది</translation>
-<translation id="4107807507418787238">దిగువ సెల్ లేదు.</translation>
-<translation id="4116415223832267137">హెచ్చరిక</translation>
-<translation id="4147126331795725888">తదుపరి నియంత్రణ లేదు.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{కుడి ధనుర్బంధ గుర్తు}other{# కుడి ధనుర్బంధ గుర్తులు}}</translation>
-<translation id="4158704014418536539">కేస్ ఆధారితం.</translation>
-<translation id="4161663686871496107">ChromeVox చదివి వినిపించే అభిప్రాయం సిద్ధంగా ఉంది</translation>
-<translation id="4173994908659439270">తదుపరి సవరించగల వచనం ఫీల్డ్ లేదు.</translation>
-<translation id="4176463684765177261">ఆపివేయబడింది</translation>
-<translation id="4188530942454211480">మునుపటి వాక్యం</translation>
-<translation id="4202186506458631436">కుడివైపు తరలించండి</translation>
-<translation id="4206289001967551965">పట్టిక లోపల ఉన్నారు</translation>
-<translation id="4215733775853809057">తదుపరి స్లయిడర్</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{అడ్డగీత}other{# అడ్డగీతలు}}</translation>
-<translation id="421884353938374759">రంగు ఎంపిక</translation>
-<translation id="4229646983878045487">తేదీ సమయం</translation>
-<translation id="423334822609210999">ఎడమవైపు సెల్ లేదు.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" />వ గ్రేడ్</translation>
-<translation id="4253168017788158739">గమనిక</translation>
-<translation id="4254798249533888099">ట్రీ</translation>
-<translation id="4255943572433203166">ChromeVoxను అనుకూలీకరించడానికి దిగువ ఎంపికలను ఉపయోగించండి. మార్పులు వెంటనే ప్రభావవంతమవుతాయి.</translation>
-<translation id="4271220233568730077">తదుపరి గణితం</translation>
-<translation id="4271521365602459209">ఇక ఫలితాలు లేవు.</translation>
-<translation id="4287520460805643128">తదుపరి కథనం లేదు.</translation>
-<translation id="4289540628985791613">స్థూలదృష్టి</translation>
-<translation id="4300318234632215983">లింక్ వెనుక URLను తెలియజేయండి</translation>
-<translation id="4301352596632316575">ఉపమెనుని కలిగి ఉంది</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{చుక్క}=3{మూడు చుక్కలు}other{# చుక్కలు}}</translation>
-<translation id="4347461890115250064">తదుపరి జాబితా లేదు.</translation>
-<translation id="4367650418938037324">గణిత ML చిన్న భాగం</translation>
-<translation id="4372435075475052704">కనిష్టం:<ph name="X" /></translation>
-<translation id="4372705107434148843">ప్రసంగాన్ని ఆపివేయండి</translation>
-<translation id="4373197658375206385">లింక్ కానటువంటి మునుపటి అంశం లేదు.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">రీసెట్</translation>
-<translation id="4471074325120394300">లింక్‌లు లేవు.</translation>
-<translation id="4476183483923481720">కొత్త పంక్తి</translation>
-<translation id="4482330759234983253">మునుపటి పట్టిక</translation>
-<translation id="4491109536499578614">చిత్రం</translation>
-<translation id="4529987814483543472">క్లాసిక్ కీమ్యాప్</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{స్లాష్ గుర్తు}other{# స్లాష్ గుర్తులు}}</translation>
-<translation id="4547556996012970016">తదుపరి స్థాయి 5 శీర్షిక</translation>
-<translation id="4562381607973973258">ముఖ్య శీర్షిక</translation>
-<translation id="4591507479202817876">, ఎంచుకోబడింది</translation>
-<translation id="4597532268155981612">ఫారమ్</translation>
-<translation id="4597896406374528575">ఏప్రిల్</translation>
-<translation id="4615592953348396470">తదుపరి కీ ప్రెస్‌ను విస్మరిస్తోంది</translation>
-<translation id="461613135510474570">వాక్యం</translation>
-<translation id="4647836961514597010">రంగు ఎంపిక</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">మునుపటి మైలురాయి</translation>
-<translation id="4696413482802371445">తదుపరి స్థాయి 5 శీర్షిక లేదు.</translation>
-<translation id="4729095194763193578">మునుపటి పట్టిక అడ్డు వరుస</translation>
-<translation id="4736221692378411923">ఆగస్టు</translation>
-<translation id="4740661827607246557">సహాయ ఆదేశాలు</translation>
-<translation id="4759716709594980008">ChromeOS కీబోర్డ్ ఎక్స్‌ప్లోరర్</translation>
-<translation id="4763296182459741068">దిగువకు సర్దుబాటు చేయబడింది</translation>
-<translation id="4763480195061959176">వీడియో</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">ప్రస్తుత పేజీ యొక్క శీర్షికను తెలియజేయండి</translation>
-<translation id="4826415162591436065">ముందుకు నావిగేట్ చేయండి</translation>
-<translation id="4826604887384865800">తదుపరి జంప్</translation>
-<translation id="4827410568042294688">ఎంపిక తీసివేయబడింది</translation>
-<translation id="4842108708071771135">తదుపరి బ్లాక్‌కోట్ లేదు.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">మునుపటి సారూప్య మూలకం.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS లాగ్ చేయడాన్ని ప్రారంభించండి</translation>
-<translation id="4877261390094455813">శోధన ప్రశ్నను నమోదు చేయండి.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">అంతర్గత లింక్</translation>
-<translation id="4953585991029886728">వచనాన్ని సవరించండి</translation>
-<translation id="4954534434583049121">మునుపటి బ్లాక్ కోట్</translation>
-<translation id="4973717656530883744">కనిష్టం <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" />కి మారింది.</translation>
-<translation id="4975416682604111799">మిల్లీసెకన్లు</translation>
-<translation id="49787999531187221">ChromeVox ఇప్పుడు క్రియారహితం చేయబడింది.</translation>
-<translation id="4979404613699303341">మునుపటి బటన్</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, జాబితా పెట్టె</translation>
-<translation id="4983588134362688868">పేజీ ఎగువకు వెళ్లండి</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, విండో</translation>
-<translation id="4993152509206108683">రేటు <ph name="PERCENT" /> శాతం</translation>
-<translation id="4996716799442435517">దృశ్యమానం</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, రేడియో బటన్ ఎంచుకోబడింది</translation>
-<translation id="4997475792277222884">లింక్ కానటువంటి తదుపరి అంశం లేదు.</translation>
-<translation id="5000760171916499057">ఫారమ్‌లు లేవు.</translation>
-<translation id="5005670136041063723">మరిన్ని సారూప్య మూలకాలు లేవు.</translation>
-<translation id="501473567976723023">జనవరి</translation>
-<translation id="5041394372352067729">బ్రెయిలీ డిస్‌ప్లేను పేజీ పైకి తరలించండి</translation>
-<translation id="5042770794184672516">ప్రసంగ వాల్యూమ్‌ను పెంచండి</translation>
-<translation id="5050015258024679800">మునుపటి స్థాయి 4 శీర్షిక</translation>
-<translation id="5054047268577924192">మునుపటి జాబితా అంశం</translation>
-<translation id="5078661581131202757">పైల్ ఎంపిక</translation>
-<translation id="5080758118274074384">రెండుసార్లు క్లిక్ చేయబడింది</translation>
-<translation id="5098541983634824365">గ్రిడ్ నుండి నిష్క్రమిస్తున్నారు.</translation>
-<translation id="5102981729317424850">సాధనపట్టీ</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">మునుపటి ఫారమ్ ఫీల్డ్ లేదు.</translation>
-<translation id="5111640677200759579">నిలువు వరుస ముఖ్య శీర్షిక</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">మునుపటి లింక్ లేదు.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, ఎంపిక తీసివేయబడింది</translation>
-<translation id="5183440668879371625">బ్రెయిలీ మునుపటి పంక్తి</translation>
-<translation id="5184944171021383281">తదుపరి ఫారమ్ ఫీల్డ్ లేదు.</translation>
-<translation id="5189244881767082992">పంక్తి</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> ఇప్పటికే ఆదేశానికి కేటాయించబడింది.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> జాబితా.</translation>
-<translation id="520883772648104506">తదుపరి రేడియో బటన్ లేదు.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">ముగింపు</translation>
-<translation id="5291783959063340370">ఆబ్జెక్ట్</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, ట్యాబ్</translation>
-<translation id="5310788376443009632">తీసివేయబడినది:</translation>
-<translation id="5320727453979144100">స్టిక్కీ మోడ్ ప్రారంభించబడింది</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{కామా గుర్తు}other{# కామా గుర్తులు}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, వచన పెట్టె</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, లింక్</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">నిరంతరంగా చదివేటప్పుడు వెనుకకు దాటవేయండి</translation>
-<translation id="5368000168321181111">శబ్ద హెచ్చరికలు ఆపివేయబడ్డాయి</translation>
-<translation id="5374320867641260420">తదుపరి బటన్ లేదు.</translation>
-<translation id="5382299583965267720">తదుపరి స్థాయి 1 శీర్షిక లేదు.</translation>
-<translation id="5402367795255837559">బ్రెయిలీ</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{సెమీకోలన్ గుర్తు}other{# సెమీకోలన్ గుర్తులు}}</translation>
-<translation id="5411891038905756502">మునుపటి జంప్ పాయింట్ లేదు.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{న్యూన గుర్తు}other{# న్యూన గుర్తులు}}</translation>
-<translation id="5455441614648621694">బహుమానపూర్వకం</translation>
-<translation id="5485036206801896268">మునుపటి గ్రాఫిక్ లేదు.</translation>
-<translation id="5486947920110100234">తదుపరి జంప్ పాయింట్ లేదు.</translation>
-<translation id="549602578321198708">పదం</translation>
-<translation id="5500932716852106146">మునుపటి సవరించగల వచన ఫీల్డ్ లేదు.</translation>
-<translation id="5502713021410870035">సెప్టెంబర్</translation>
-<translation id="5507663321906818013">బెంచ్‌మార్క్‌ను డీబగ్ చేయండి</translation>
-<translation id="5518443085409638729">వచనాన్ని సవరిస్తున్నప్పుడు కర్సర్‌ను అక్షరాల మధ్య ఉంచండి (Mac OS X వంటిది).</translation>
-<translation id="552195134157544755">రేడియో బటన్</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">మునుపటి స్థాయి 5 శీర్షిక లేదు.</translation>
-<translation id="556042886152191864">బటన్</translation>
-<translation id="5561345396546889625">తదుపరి జాబితా</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">వచనం, ఇమెయిల్ నమోదును సవరించండి</translation>
-<translation id="5597170376237141345">తదుపరి తనిఖీపెట్టె</translation>
-<translation id="5597933780944041114">తదుపరి శీర్షిక లేదు.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, రేడియో బటన్ ఎంపిక తీసివేయబడింది</translation>
-<translation id="5601172225407283979">డిఫాల్ట్ చర్యను అమలు చేయండి</translation>
-<translation id="5608798115546226984">స్వీయపూర్తి ఇన్‌లైన్</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">లాగ్</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">మునుపటి పట్టిక లేదు.</translation>
-<translation id="5655682562155942719">దాటివేసే ఆదేశాలు</translation>
-<translation id="56637627897541303">వచన ప్రదేశం</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">మైలురాయి</translation>
-<translation id="5683155931978483559">మునుపటి తనిఖీపెట్టె</translation>
-<translation id="5684277895745049190">జాబితా</translation>
-<translation id="5700650669149824506">మునుపటి స్థాయి 4 శీర్షిక లేదు.</translation>
-<translation id="5709192780268610569">పెద్ద వివరణ లేదు</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">తదుపరి పట్టిక నిలువు వరుస</translation>
-<translation id="571866080859340309">విశ్లేషణ సమూహాలు</translation>
-<translation id="5728409797179002635">పట్టిక కనుగొనబడలేదు.</translation>
-<translation id="5748623122140342504">మునుపటి స్థాయి 5 శీర్షిక</translation>
-<translation id="5750633686117194034">మాడిఫైయర్‌ను నొక్కలేదు; దయచేసి ఒకటి లేదా అంతకంటే ఎక్కువ మాడిఫైయర్‌లను నొక్కి ఉంచి; పూర్తయిన తర్వాత మీ వేళ్లను తీసివేయండి మరియు మీరు కీల సెట్‌ను వింటారు. నిష్క్రమించడానికి ట్యాబ్ నొక్కండి.</translation>
-<translation id="5788275253279308023">అజ్ఞాత విండో <ph name="TITLE" /> ట్యాబ్</translation>
-<translation id="5806206155699461681">నిర్దిష్ట సైట్‌లను (Google శోధన వంటివి) మెరుగుపరచండి.</translation>
-<translation id="5819072574982403430">ట్రీ అంశం</translation>
-<translation id="5826479389509458994"><ph name="ROW" />వ అడ్డు వరుస <ph name="COL" />వ నిలువు వరుస</translation>
-<translation id="5850707923114094062">వెనుకవైపుకు ప్యాన్ చేయండి</translation>
-<translation id="5851548754964597211">ట్యాబ్ జాబితా</translation>
-<translation id="5859752971144398932">పేజీలో కనుగొనడం నుండి నిష్క్రమించారు.</translation>
-<translation id="5866042630553435010">పాక్షికంగా తనిఖీ చేయబడింది</translation>
-<translation id="5869546221129391014">గ్రిడ్</translation>
-<translation id="5876817486144482042">ప్రసంగ వాల్యూమ్‌ను తగ్గించండి</translation>
-<translation id="5887397643266327462">బ్రెయిలీ శీర్షికలు ప్రారంభించబడ్డాయి.</translation>
-<translation id="5891934789323004067">పట్టిక</translation>
-<translation id="5919442531159595654">కాపీ చేయండి.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{సమాన గుర్తు}other{# సమాన గుర్తులు}}</translation>
-<translation id="5939518447894949180">రీసెట్ చేయి</translation>
-<translation id="5948123859135882163">గణిత వ్యక్తీకరణల వ్యాఖ్యానాన్ని వ్యవస్థీకృత వివరణ మరియు అర్థ వివరణ మధ్య టోగుల్ చేయండి</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">డైలాగ్</translation>
-<translation id="5963413905009737549">విభాగం</translation>
-<translation id="5968607524793740041">సందర్భ మెనుని చూపుతుంది</translation>
-<translation id="5983179082906765664">నావిగేషన్ గ్రాన్యులారిటీని పెంచండి</translation>
-<translation id="5999630716831179808">వాయిస్‌లు</translation>
-<translation id="6000417740266304866">దిగువ జాబితా నుండి ఎంపికను ఎంచుకోవడం ద్వారా ప్రస్తుత 8 చుక్కల బ్రెయిలీ పట్టికను మార్చండి.</translation>
-<translation id="6006050241733874051">ఫారమ్</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{బ్యాక్‌స్లాష్ గుర్తు}other{# బ్యాక్‌స్లాష్ గుర్తులు}}</translation>
-<translation id="6037602951055904232">ముందుకు ప్యాన్ చేయండి</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">సెల్ ముగింపు.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">ఖాళీ</translation>
-<translation id="6142308968191113180">శీర్షిక 4</translation>
-<translation id="6169420925157477918">పెద్ద వివరణ గల చిత్రం</translation>
-<translation id="6172087735260766220">కాపీ-రక్షిత PDF నుండి ప్రాప్యత చేయదగిన వచనాన్ని ప్రాప్యత చేయడం సాధ్యపడలేదు.</translation>
-<translation id="6186305613600865047">పేజీ దిగువకు వెళ్లండి</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">Down</translation>
-<translation id="6236061028292614533">తదుపరి శీర్షిక</translation>
-<translation id="6254901459154107917">తదుపరి సవరించగల వచన ప్రదేశం</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> నుండి నిష్క్రమించారు.</translation>
-<translation id="6281876499889881039">తదుపరి సారూప్య మూలకం.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">తదుపరి కాంబో పెట్టె లేదు.</translation>
-<translation id="6307969636681130414">నొక్కబడింది</translation>
-<translation id="6324551002951139333">వ్యాకరణ తప్పు కనుగొనబడింది</translation>
-<translation id="6348657800373377022">కోంబో బాక్స్</translation>
-<translation id="6355910664415701303">మునుపటి జాబితా అంశం లేదు.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">మునుపటి శీర్షిక</translation>
-<translation id="6387719785439924554">ప్రక్కన</translation>
-<translation id="6411426777058107714">మునుపటి రేడియో బటన్ లేదు.</translation>
-<translation id="6414968628640960377">మునుపటి విభిన్న మూలకం.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{కోలన్ గుర్తు}other{# కోలన్ గుర్తులు}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, మెను</translation>
-<translation id="6444046323172968959">హెచ్చరిక డైలాగ్</translation>
-<translation id="6459511626086141404">సమతల కీమ్యాప్</translation>
-<translation id="6468049171101508116">తదుపరి బటన్</translation>
-<translation id="6491972999578897419">దిగువ జాబితా నుండి ఎంపికను ఎంచుకోవడం ద్వారా ప్రస్తుత వాయిస్‌ను మార్చండి.</translation>
-<translation id="6508059270146105198">బ్రెయిలీ డిస్‌ప్లేను పేజీ దిగువకు తరలించండి</translation>
-<translation id="6536864053412760904">గణిత ML టోకెన్</translation>
-<translation id="6550720799683018100">దిగువ జాబితా నుండి ఎంపికను ఎంచుకోవడం ద్వారా ప్రస్తుత కీమ్యాప్‌ను మార్చండి.</translation>
-<translation id="6561818612645211875">ప్రస్తుత అడ్డు వరుస ప్రారంభానికి వెళ్లండి</translation>
-<translation id="6587021927234520429">తదుపరి స్థాయి 4 శీర్షిక లేదు.</translation>
-<translation id="6601344353291556895">విశదీకృత వివరణలను ప్రారంభించండి.</translation>
-<translation id="6615602925644411249">పేజీలో కనుగొనండి.</translation>
-<translation id="6633350132811819843">తదుపరి పట్టిక లేదు.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">ప్రోగ్రెస్ పట్టీ</translation>
-<translation id="6659594942844771486">టాబ్</translation>
-<translation id="667999046851023355">పత్రం</translation>
-<translation id="6697092096875747123">మునుపటి కాంబో పెట్టె</translation>
-<translation id="6714813999819678458">మునుపటి స్థాయి 2 శీర్షిక</translation>
-<translation id="6716505898850596801">మాడిఫైయర్ కీలు</translation>
-<translation id="671916444866103745">తదుపరి ARIA మైలురాయి లేదు.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, కాంబో పెట్టె</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> అంశాలు గల జాబితా</translation>
-<translation id="6736510033526053669">ట్యాబ్ సృష్టించబడింది</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">కథనం</translation>
-<translation id="6787839852456839824">కీబోర్డ్ సత్వరమార్గాలు</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">ఫుటర్</translation>
-<translation id="6871161210040114857">కేస్‌ను విస్మరిస్తోంది.</translation>
-<translation id="6877435256196695200">తదుపరి గ్రాఫిక్ లేదు.</translation>
-<translation id="6897341342232909480">ఎడమవైపు తరలించండి</translation>
-<translation id="6901540140423170855">తేదీ</translation>
-<translation id="6910211073230771657">తొలగించబడింది</translation>
-<translation id="6911965441508464308">ఎగువ సెల్ లేదు.</translation>
-<translation id="6919104639734799681">పట్టికల జాబితాను చూపండి</translation>
-<translation id="6964088412282673743">మునుపటి నియంత్రణ లేదు.</translation>
-<translation id="6996566555547746822">తదుపరి కాంబో పెట్టె</translation>
-<translation id="7005146664810010831">URL కనుగొనబడలేదు</translation>
-<translation id="7010712454773919705">ChromeVox మాడిఫైయర్ కీ</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">మునుపటి జాబితా</translation>
-<translation id="7041173719775863268">ఎంపికను ముగించండి</translation>
-<translation id="7095834689119144465">వచన సంఖ్యను మాత్రమే సవరించండి</translation>
-<translation id="7096001299300236431">మునుపటి మీడియా</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">పదం అనుకరణ</translation>
-<translation id="713824876195128146">తదుపరి బ్లాక్ కోట్</translation>
-<translation id="7161771961008409533">పాప్-అప్ బటన్</translation>
-<translation id="7167657087543110">అక్షర అనుకరణ</translation>
-<translation id="7170733337935166589">నిరంతరంగా చదివేటప్పుడు ముందుకు దాటవేయండి</translation>
-<translation id="7181697990050180700">తరచుగా ఉపయోగించే ఆదేశాల కోసం కీబోర్డ్ సత్వర మార్గాలను దిగువ సంబంధిత ఫీల్డ్‌ల్లో టైప్ చేయడం ద్వారా వాటిని అనుకూలీకరించండి.</translation>
-<translation id="7203150201908454328">విస్తరించబడింది</translation>
-<translation id="7210211103303402262">నిమిషాలు</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">పంక్తి</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">శీర్షిక</translation>
-<translation id="7241683698754534149">పెద్ద వివరణను కొత్త ట్యాబ్‌లో తెరవండి</translation>
-<translation id="7248671827512403053">అనువర్తనం</translation>
-<translation id="725969808843520477">తదుపరి రేడియో బటన్</translation>
-<translation id="7269119382257320590">విరామచిహ్నాలు లేవు</translation>
-<translation id="7273174640290488576">ఖాళీ</translation>
-<translation id="7285387653379749618">పట్టికలు</translation>
-<translation id="7289186959554153431">శీర్షిక 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">బ్రెయిలీ శీర్షికలు నిలిపివేయబడ్డాయి.</translation>
-<translation id="7318872822751139669">ఫోకస్‌ను మార్చడానికి మౌస్‌ను ఉపయోగించండి.</translation>
-<translation id="7322388933135261569">ఫిబ్రవరి</translation>
-<translation id="7332592614823088566"><ph name="ROWTOTAL" />లో <ph name="ROWINDEX" />వ అడ్డు వరుస, <ph name="COLTOTAL" />లో <ph name="COLINDEX" />వ నిలువు వరుస</translation>
-<translation id="7336596009609913925">పాప్అప్‌ను కలిగి ఉంది</translation>
-<translation id="7356165926712028380">8 చుక్కల బ్రెయిలీకి మార్చు</translation>
-<translation id="7362871137496673139">మునుపటి స్థాయి 2 శీర్షిక లేదు.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ఆంపర్సండ్ గుర్తు}other{# ఆంపర్సండ్ గుర్తులు}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">పట్టిక నుండి నిష్క్రమిస్తున్నారు.</translation>
-<translation id="739763518212184081">మునుపటి పంక్తి</translation>
-<translation id="7400575256015741911">అక్షరదోషం కనుగొనబడింది</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">తిరిగి వెళ్లడం</translation>
-<translation id="7434509671034404296">డెవలపర్</translation>
-<translation id="7439060726180460871">డైరెక్టరీ</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">డైలాగ్‌లోకి ప్రవేశించారు</translation>
-<translation id="7532613204005497612">జూన్</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, స్లయిడర్</translation>
-<translation id="7586163296341959563">అతికించండి.</translation>
-<translation id="7596919493010894443">ఎంపిక క్లియర్ చేయబడింది</translation>
-<translation id="7604026522577407655">ప్రస్తుత నిలువు వరుస ప్రారంభానికి వెళ్లండి</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">ప్రస్తుత పేజీ యొక్క URLను తెలియజేయండి</translation>
-<translation id="7609363189280667021">బ్రెయిలీ శీర్షికలను టోగుల్ చేయండి</translation>
-<translation id="762020119231868829">ప్రస్తుతం ప్లే అవుతున్న అన్ని మీడియా విడ్జెట్‌లను పాజ్ చేస్తుంది</translation>
-<translation id="7625690649919402823">తదుపరి పట్టిక</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), గ్రేడ్ <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">మునుపటి స్థాయి 3 శీర్షిక లేదు.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, వచన పెట్టె</translation>
-<translation id="7663318257180412551">శీర్షిక 2</translation>
-<translation id="7674576868851035240">తదుపరి లింక్</translation>
-<translation id="7674768236845044097">గుర్తు పెట్టండి</translation>
-<translation id="7684431668231950609">వచనం, URL నమోదును సవరించండి</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">మునుపటి రేడియో బటన్</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, పాస్‌వర్డ్ వచన పెట్టె</translation>
-<translation id="7805247615045262757">డిఫాల్ట్ నావిగేషన్</translation>
-<translation id="7805768142964895445">స్థితి</translation>
-<translation id="7810781339813764006">తదుపరి సమూహం</translation>
-<translation id="7819187121850078213">విండో <ph name="TITLE" /> ట్యాబ్</translation>
-<translation id="7828956995407538686">అక్టోబర్</translation>
-<translation id="7839679365527550018">మునుపటి పదం</translation>
-<translation id="7851816175263618915">కొన్ని విరామచిహ్నాలు</translation>
-<translation id="7870596830398826354">గణిత ML ట్రీ</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox క్లాసిక్‌ను టోగుల్ చేస్తుంది.</translation>
-<translation id="7895896691902835279">తెలియని లింక్</translation>
-<translation id="7927711904086083099">ఎంచుకోబడలేదు</translation>
-<translation id="7935627501098484003">సమయ నియంత్రణ</translation>
-<translation id="7939428177581522200">ఎంపికకు జోడించబడింది</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{@ గుర్తు}other{# @ గుర్తులు}}</translation>
-<translation id="7965147473449754028">మెనుని మూసివేసారు</translation>
-<translation id="7974390230414479278">మెను అంశం</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ఆశ్చర్యార్థక గుర్తు}other{# ఆశ్చర్యార్థక గుర్తులు}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{కోట్ గుర్తు}other{# కోట్ గుర్తులు}}</translation>
-<translation id="8033827949643255796">ఎంచుకోబడ్డాయి</translation>
-<translation id="8035962149453661158">గరిష్టం:<ph name="X" /></translation>
-<translation id="8042761080832772327">వచనం, శోధన నమోదును సవరించండి</translation>
-<translation id="8049189770492311300">టైమర్</translation>
-<translation id="8065607967589909823">ఎంచుకున్నది</translation>
-<translation id="8066678206530322333">బ్యానర్</translation>
-<translation id="8110647606445335195">ARIA మైలురాళ్లు లేవు.</translation>
-<translation id="8153880621934657047">లోపల పట్టిక కాదు.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{అండర్‌స్కోర్ గుర్తు}other{# అండర్‌స్కోర్ గుర్తులు}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">కత్తిరించండి.</translation>
-<translation id="8199231515320852133">ప్రస్తుత సెల్ యొక్క ముఖ్య శీర్షికలను తెలియజేయండి</translation>
-<translation id="820417203470636242">ఖాళీ సెల్.</translation>
-<translation id="8215202828671303819">బహుళ ఎంపిక</translation>
-<translation id="8276439074553447000">మునుపటి ఫోకస్ చేయగల అంశానికి వెళ్లండి</translation>
-<translation id="8278417001922463147">మునుపటి కథనం లేదు.</translation>
-<translation id="8283603667300770666">తదుపరి ఫారమ్ ఫీల్డ్</translation>
-<translation id="831207808878314375">నిర్వచనం</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">గంటలు</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{పౌండ్ గుర్తు}other{# పౌండ్ గుర్తులు}}</translation>
-<translation id="8374154622594089836">నెల</translation>
-<translation id="8378855320830505539">ప్రాంతం</translation>
-<translation id="8382679411218029383">స్వీయపూర్తి ఇన్‌లైన్ మరియు జాబితా</translation>
-<translation id="8428603554127842284">స్థాయి <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">తదుపరి స్థాయి 3 శీర్షిక లేదు.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">మునుపటి తనిఖీపెట్టె లేదు.</translation>
-<translation id="8455868257606149352">గరిష్టం <ph name="X" /></translation>
-<translation id="84575901236241018">ప్రాప్యత కీ కలిగి ఉంది, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">నావిగేషన్ గ్రాన్యులారిటీని తగ్గించండి</translation>
-<translation id="8520472399088452386">స్పిన్ బటన్</translation>
-<translation id="8538744478902126321">ప్రస్తుత సెల్ యొక్క అడ్డు వరుస శీర్షిక వద్ద అంచనా వేయండి</translation>
-<translation id="8540054775867439484">ఎగువకు సర్దుబాటు చేయబడింది</translation>
-<translation id="8548973727659841685">అక్షరం</translation>
-<translation id="8561322612995434619">పాప్ అప్‌ను కలిగి ఉంది</translation>
-<translation id="8571096049907249734">బహు ఎంపి</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">తదుపరి జాబితా అంశం</translation>
-<translation id="860150890330522909"><ph name="NAME" /> తనిఖీపెట్టె ఎంచుకోబడింది</translation>
-<translation id="8606621670302093223">తేదీ నియంత్రణ</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> అంశాలు ఎంచుకోబడ్డాయి</translation>
-<translation id="8638532244051952400">ప్రస్తుత సెల్ అక్షాలను తెలియజేయండి</translation>
-<translation id="8650576015643545550">మునుపటి జాబితా లేదు.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">లింక్‌ల జాబితాను చూపండి</translation>
-<translation id="8664519043722036194">సెకన్లు</translation>
-<translation id="867187640362843212">శీర్షిక 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{పైప్ గుర్తు}other{# నిలువు పైప్ గుర్తులు}}</translation>
-<translation id="8735450637152821465">ఎంపికను ప్రారంభించండి</translation>
-<translation id="8743786158317878347">పట్టికల వంటి ఆకృతీకరించిన కంటెంట్‌లోకి ప్రవేశించండి</translation>
-<translation id="8747966237988593539">క్రమం చేసిన జాబితా</translation>
-<translation id="8759334257841767240">తదుపరి లింక్ లేదు.</translation>
-<translation id="8767968232364267681">తదుపరి స్థాయి 4 శీర్షిక</translation>
-<translation id="8770473310765924354">పట్టికల వంటి ఆకృతీకరించిన కంటెంట్ నుండి నిష్క్రమించండి</translation>
-<translation id="8791025954632646584">అర్థ వివరణలు ప్రారంభించబడ్డాయి</translation>
-<translation id="8796411681063377102">తదుపరి స్థాయి 3 శీర్షిక</translation>
-<translation id="8808582214901541005">మార్చి</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">ఆదేశాలను సమీక్షించడానికి పైకి లేదా క్రిందికి నొక్కండి, సక్రియం చేయడానికి enter నొక్కండి</translation>
-<translation id="8864099967139188018">తదుపరి స్థాయి 6 శీర్షిక లేదు.</translation>
-<translation id="8882002077197914455">అడ్డు వరుస శీర్షిక</translation>
-<translation id="8896347895970027998">ChromeVoxని సక్రియం లేదా క్రియారహితానికి టోగుల్ చేయండి.</translation>
-<translation id="8898516272131543774">సైకిల్ విరామచిహ్న అనుకరణ</translation>
-<translation id="8900148057318340779">ఆదిప్రత్యయ కీ</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">ఖాళీ ముఖ్య శీర్షికలు</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">మాడిఫైయర్ కీలు</translation>
-<translation id="8943175951035496220">కుడివైపు సెల్ లేదు.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">ఫైల్</translation>
-<translation id="9027462562263121875">పట్టికలు లేవు.</translation>
-<translation id="9040132695316389094">శీర్షిక 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">శోధన విడ్జెట్‌ను టోగుల్ చేయండి</translation>
-<translation id="9065283790526219006">+పాప్అప్</translation>
-<translation id="9077213568694924680">ఎంపిక నుండి తీసివేయబడింది</translation>
-<translation id="9082874451376019682">మునుపటి స్లయిడర్ లేదు.</translation>
-<translation id="9089864840575085222">సైకిల్ టైపింగ్ అనుకరణ</translation>
-<translation id="9107530006868467849">మునుపటి మీడియా విడ్జెట్ లేదు.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{శాతం గుర్తు}other{# శాతం గుర్తులు}}</translation>
-<translation id="9115913704608474258">నవంబర్</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">ప్రస్తుత స్థానం యొక్క సంక్షిప్త వివరణను తెలియజేస్తుంది</translation>
-<translation id="9153606228985488238">స్వర స్థాయి <ph name="PERCENT" /> శాతం</translation>
-<translation id="9160096769946561184">ప్రస్తుత నిలువు వరుస యొక్క చివరకు వెళ్లండి</translation>
-<translation id="9173115498289768110">వాల్యూమ్ <ph name="PERCENT" /> శాతం</translation>
-<translation id="9178973770513562274">బ్రౌజ్ చేయడానికి పైకి మరియు క్రిందికి బాణం కీలను ఉపయోగించండి లేదా శోధించడానికి టైప్ చేయండి.</translation>
-<translation id="9192904702577636854">మార్కీ</translation>
-<translation id="9212322457209634662">తదుపరి విభాగం లేదు.</translation>
-<translation id="930275611743429116">ఎంపికను ప్రారంభించండి లేదా ముగించండి.</translation>
-<translation id="948171205378458592">ప్రసంగ రేటుని తగ్గించండి</translation>
-<translation id="962913030769097253">తదుపరి స్థాయి 1 శీర్షిక</translation>
-<translation id="973955474346881951">స్టిక్కీ మోడ్‌ను ప్రారంభించండి/ఆపివేయండి</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_th.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_th.xtb
deleted file mode 100644
index c06f086a7e1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_th.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="th">
-<translation id="1012173283529841972">รายการ</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">มีการขยาย</translation>
-<translation id="1025074108959230262">ปิดโหมดติดหนึบแล้ว</translation>
-<translation id="1031961866430398710">จากนั้น</translation>
-<translation id="1044777062731150180">ไม่มีส่วนหัว</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">อินพุตไม่ถูกต้อง</translation>
-<translation id="1082209053475788238">ไม่มีส่วนหัวระดับ 6 ก่อนหน้า</translation>
-<translation id="1088219014394087294">ไม่มีส่วนหัว</translation>
-<translation id="1106741348836243114">เปิดหรือปิดเสียงความคิดเห็น (earcons)</translation>
-<translation id="1120743664840974483">{"a": "อัลฟ่า", "b": "บราโว่", "c": "ชาร์ลี", "d": "เดลต้า", "e": "เอคโค่", "f": "ฟอกซ์ทรอต", "g": "กอล์ฟ", "h": "โฮเท็ล", "i": "อินเดีย", "j": "จูเลียต","k": "กิโล", "l": "ลิมา", "m": "ไมค์", "n": "โนเวมเบอร์", "o": "ออสการ์","p": "ปาป้า", "q": "ควิเบค", "r": "โรมิโอ", "s": "เซียร์ร่า", "t": "แทงโก้", "u": "ยูนิฟอร์ม", "v": "วิคเตอร์", "w": "วิสกี้","x": "เอ็กซเรย์", "y": "แยงกี้", "z": "ซูลู"}</translation>
-<translation id="113582498867142724">คอลเล็กชัน <ph name="TAG" /> ที่มี <ph name="NUM" /> รายการ</translation>
-<translation id="1155043339247954670">ไม่มีรายการถัดไป</translation>
-<translation id="1157782847298808853">ความช่วยเหลือเกี่ยวกับแป้นพิมพ์</translation>
-<translation id="1157843803349774103">ช่องตัวเลือกรวม <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="1167230103353892028">รายการเมนู <ph name="NAME" /> ที่มีเมนูย่อย</translation>
-<translation id="1177863135347784049">ที่กำหนดเอง</translation>
-<translation id="1188858454923323853">ส่วนเสริม</translation>
-<translation id="1206619573307042055">ตัวอักษรวิ่ง</translation>
-<translation id="1213216066620407844">ChromeVox - ทำให้ Chrome สามารถพูดได้</translation>
-<translation id="1229276918471378188">การข้ามก่อนหน้า</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">ส่วนหัวระดับ 6 ถัดไป</translation>
-<translation id="1275718070701477396">เลือกแล้ว</translation>
-<translation id="1319608975892113573">ไม่มีข้อความที่ยกมาก่อนหน้า</translation>
-<translation id="1321576897702511272">ซ่อนความช่วยเหลือของ ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> จาก <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">พูดอักขระและคำ</translation>
-<translation id="1339428534620983148">คอลัมน์ตารางก่อนหน้า</translation>
-<translation id="1342835525016946179">บทความ</translation>
-<translation id="1346748346194534595">ขวา</translation>
-<translation id="136718599399906424">แถวตารางถัดไป</translation>
-<translation id="1383876407941801731">ค้นหา</translation>
-<translation id="1385214448885562192">กด Enter เพื่อยอมรับหรือ ESC เพื่อยกเลิก กดลงเพื่อไปยังรายการถัดไป และกดขึ้นเพื่อไปยังรายการก่อนหน้า</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">ภูมิภาค</translation>
-<translation id="1452236308086741652">ช่องข้อความรหัสผ่าน <ph name="VALUE" /></translation>
-<translation id="1467432559032391204">ซ้าย</translation>
-<translation id="1474557363159888097">ไม่มีการเชื่อมโยงก่อนหน้า</translation>
-<translation id="1502086903961450562">กราฟิกก่อนหน้า</translation>
-<translation id="1506187449813838456">เพิ่มระดับเสียง</translation>
-<translation id="151784044608172266">ประโยคถัดไป</translation>
-<translation id="1524531499102321782">เบรลล์บรรทัดถัดไป</translation>
-<translation id="1546370775711804143">แถบเลื่อน</translation>
-<translation id="1559739829547075274">นำทางกลับหลัง</translation>
-<translation id="1571643229714746283">ChromeVox พร้อมใช้งาน</translation>
-<translation id="158493514907962286">ธันวาคม</translation>
-<translation id="1594072653727561613">เมนู</translation>
-<translation id="1610130962244179598">เปลี่ยนเป็นเบรลล์แบบ 6 จุด</translation>
-<translation id="1611168825862729585">ส่วนหัวคอลัมน์:</translation>
-<translation id="1613476421962910979">Earcons เปิด</translation>
-<translation id="1618597272655350600">แจ้งคำอธิบายแบบเต็มของตำแหน่งปัจจุบัน</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{เครื่องหมายมากกว่า}other{# เครื่องหมายมากกว่า}}</translation>
-<translation id="1653266918374749391">ส่วนหัวระดับ 3 ก่อนหน้า</translation>
-<translation id="1659072772017912254">ไม่ได้เลือก</translation>
-<translation id="1669290819662866522">สัปดาห์</translation>
-<translation id="1674262202423278359">การนำทางของ ChromeVox</translation>
-<translation id="16777221443363124">แถบเมนู</translation>
-<translation id="1692077714702418899">บรรทัดแบบโครงสร้าง</translation>
-<translation id="1700517974991662022">เคยเข้าชม</translation>
-<translation id="1722567105086139392">ลิงก์</translation>
-<translation id="1727806147743597030">ส่วนท้าย</translation>
-<translation id="174268867904053074">กราฟิกถัดไป</translation>
-<translation id="1781173782405573156">แป้นส่งผ่าน</translation>
-<translation id="1787176709638001873">ข้อความแก้ไขรหัสผ่าน</translation>
-<translation id="1810107444790159527">ช่องรายการ</translation>
-<translation id="1828385960365606039">พฤษภาคม</translation>
-<translation id="1834891354138622109">คอลัมน์</translation>
-<translation id="1865601187525349519">สิ้นสุดข้อความ</translation>
-<translation id="1876229593313240038">เอกสาร</translation>
-<translation id="188130072164734898">พูดเวลาและวันที่ปัจจุบัน</translation>
-<translation id="1902396333223336119">เซลล์</translation>
-<translation id="1905379170753160525">แสดงรายการส่วนหัว</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">การควบคุมสัปดาห์ของปี</translation>
-<translation id="1964135212174907577">ออบเจ็กต์ถัดไป</translation>
-<translation id="1969092762068865084">กรกฎาคม</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">ส่วนหัวของแถว:</translation>
-<translation id="2002895034995108595">รีเซ็ตรูปแบบแป้นปัจจุบัน</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{วงเล็บซ้าย}other{# วงเล็บซ้าย}}</translation>
-<translation id="2045490512405922022">ไม่ได้เลือก</translation>
-<translation id="20601713649439366">ไม่มีสูตรคณิตศาสตร์ก่อนหน้า</translation>
-<translation id="207477615537953741">ปิดความหมาย</translation>
-<translation id="2086961585857038472">คำถัดไป</translation>
-<translation id="2089387485033699258">th</translation>
-<translation id="2091933974477985526">พื้นที่ข้อความที่สามารถแก้ไขได้ก่อนหน้า</translation>
-<translation id="2100350898815792233">เครื่องหมายวรรคตอนทั้งหมด</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">รหัสการเข้าถึง: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">เปลี่ยนตารางเบรลล์แบบ 6 จุดปัจจุบันโดยเลือกหนึ่งตัวเลือกจากรายการด้านล่าง</translation>
-<translation id="2169714232367507776">คลิกรายการปัจจุบัน</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{วงเล็บปิด}other{# วงเล็บปิด}}</translation>
-<translation id="2199994615414171367">คณิตศาสตร์ก่อนหน้า</translation>
-<translation id="2223693656926968778">ดำเนินการกับรายการปัจจุบัน</translation>
-<translation id="225732394367814946">เพิ่มอัตราการพูด</translation>
-<translation id="2267945578749931355">อักขระถัดไป</translation>
-<translation id="2281234842553884450">แถบเลื่อนก่อนหน้า</translation>
-<translation id="2318372665160196757">หลัก</translation>
-<translation id="2329324941084714723">แผงแท็บ</translation>
-<translation id="2344193891939537199">การควบคุมวันที่และเวลา</translation>
-<translation id="2359897517538099099">ไม่ได้อยู่ในโหมดตาราง</translation>
-<translation id="241124561063364910">ตามด้วย</translation>
-<translation id="2417569100218200841">ข้อมูลเนื้อหา</translation>
-<translation id="2422937916923936891">ช่องทำเครื่องหมายรายการเมนู</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> เป็นคีย์ตัวปรับแต่ง ChromeVox ใหม่แล้ว</translation>
-<translation id="2450814015951372393">ช่องทำเครื่องหมาย</translation>
-<translation id="2462626033734746142">กลุ่มปุ่มตัวเลือก</translation>
-<translation id="2471138580042810658">ส่วนหัวระดับ 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{เครื่องหมายดอกจัน}other{# เครื่องหมายดอกจัน}}</translation>
-<translation id="2549392850788122959">รีเซ็ต <ph name="KEY" /> แล้ว</translation>
-<translation id="2553108862507765288">ข้อผิดพลาดทางไวยากรณ์</translation>
-<translation id="257674075312929031">กลุ่ม</translation>
-<translation id="2582407057977008361">ส่วนที่ไม่เกี่ยวข้อง</translation>
-<translation id="2589102159832527089">หน้าเว็บนี้มีข้อความที่ดึงออกมาจากไฟล์ PDF โดยอัตโนมัติ &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; &lt;a href="<ph name="URL" />"&gt;คลิกที่นี่เพื่อดูต้นฉบับ&lt;/a&gt;</translation>
-<translation id="2606210917827248971">ที่มี {COUNT,plural, =1{# รายการ}other{# รายการ}}</translation>
-<translation id="2614981083756825552">รูปแบบ ML คณิตศาสตร์</translation>
-<translation id="2626530649491650971">คลิกได้</translation>
-<translation id="2628764385451019380">ไม่มีช่องตัวเลือกรวมก่อนหน้า</translation>
-<translation id="2637227747952042642">คณิตศาสตร์</translation>
-<translation id="2639750663247012216">คีย์ตัวปรับแต่ง ChromeVox</translation>
-<translation id="2644542693584024604">สะกดผิด</translation>
-<translation id="2667291555398229137">คลิกรายการใต้คีย์การกำหนดเส้นทาง</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{วงเล็บเปิด}other{# วงเล็บเปิด}}</translation>
-<translation id="2705875883745373140">ไม่ได้กด</translation>
-<translation id="2706462751667573066">ขึ้น</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">เสียง</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">เลือกแล้ว</translation>
-<translation id="27527859628328957">ข้ามไปยังรายการที่สามารถโฟกัสถัดไป</translation>
-<translation id="2770781857296573485">ป้อนการสำรวจกลุ่ม</translation>
-<translation id="2777845298774924149">ออกแล้ว</translation>
-<translation id="2800204403141299078">ไม่มีองค์ประกอบที่ต่างกันเพิ่มเติม</translation>
-<translation id="2800780099804980316">ไม่มีส่วนหัวระดับ 1 ก่อนหน้า</translation>
-<translation id="2811204574343810641">แถว</translation>
-<translation id="2816654101880605877">ไม่มีแถบเลื่อนถัดไป</translation>
-<translation id="2841013758207633010">เวลา</translation>
-<translation id="2843837985843789981">กลุ่มก่อนหน้า</translation>
-<translation id="2844995807198708617">เมนูบริบท</translation>
-<translation id="2849332794118375855">ไม่มีช่องทำเครื่องหมายถัดไป</translation>
-<translation id="2864481629947106776">ลิงก์ก่อนหน้านี้</translation>
-<translation id="2873259058405069099">ไปที่ด้านบนของตาราง</translation>
-<translation id="2894654529758326923">ข้อมูล</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{วงเล็บปีกกาซ้าย}other{# วงเล็บปีกกาซ้าย}}</translation>
-<translation id="2911433807131383493">เปิดบทแนะนำ ChromeVox</translation>
-<translation id="2932083475399492303">สลับประเภทบรรทัดระหว่างโครงสร้างหรือรูปแบบ</translation>
-<translation id="2964026537669811554">กลุ่มของส่วนหัว</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{เครื่องหมายแท็บ}other{# เครื่องหมายแท็บ}}</translation>
-<translation id="2972078295414139404">ไม่มีลิงก์ที่เคยเข้าชมก่อนหน้า</translation>
-<translation id="2972205263822847197">เคล็ดลับเครื่องมือ</translation>
-<translation id="2998131015536248178">อักขระก่อนหน้า</translation>
-<translation id="2999559350546931576">ลดระดับเสียง</translation>
-<translation id="2999945368667127852">ไม่มีวิดเจ็ตสื่อถัดไป</translation>
-<translation id="3012414509011670858">ไม่มีส่วนก่อนหน้า</translation>
-<translation id="3030432017085518523">ปุ่มตัวเลือกรายการเมนู</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{อะโพสโทรฟี}other{# อะโพสโทรฟี}}</translation>
-<translation id="3046838483509668188">ตัวเลือก ChromeVox</translation>
-<translation id="3047143736589213134">รูปแบบแป้นแบบทดลอง</translation>
-<translation id="3060756054951570867">เปิดเมนู <ph name="TITLE" /> แล้ว</translation>
-<translation id="3078345202707391975">ส่วนหัวระดับถัดไป 2</translation>
-<translation id="3078740164268491126">ตาราง</translation>
-<translation id="3082557070674409251">คลิกแล้ว</translation>
-<translation id="3084806535845658316">ไม่พูดขณะพิมพ์</translation>
-<translation id="3086746722712840547">หมายเหตุ</translation>
-<translation id="308895241372589742">ไม่มีสูตรคณิตศาสตร์ถัดไป</translation>
-<translation id="3090532668523289635">กลุ่ม</translation>
-<translation id="3093176084511590672">จุดสังเกตถัดไป</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">ข้อความแจ้งเตือน</translation>
-<translation id="3109724472072898302">ยุบแล้ว</translation>
-<translation id="3134461040845705080">อ่านอย่างเดียว</translation>
-<translation id="3138767756593758860">แสดงรายการจุดสังเกต</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">บรรทัดถัดไป</translation>
-<translation id="3155083529632865074">ไม่มีปุ่มก่อนหน้า</translation>
-<translation id="3163593631834463955">ส่วนหัวของคอลัมน์ว่างเปล่า</translation>
-<translation id="316542773973815724">การนำทาง</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{ช่องว่าง}other{# ช่องว่าง}}</translation>
-<translation id="320961988183078793">ป้อน <ph name="TYPE" /> แล้ว</translation>
-<translation id="3223701887221307104">แท็บ <ph name="NAME" /></translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">ลิงก์ที่เคยเข้าชม</translation>
-<translation id="323731244387692321">เปิดความช่วยเหลือเกี่ยวกับแป้นพิมพ์ของ ChromeVox</translation>
-<translation id="3241052487511142956">ลิงก์ที่เคยเข้าชมก่อนหน้า</translation>
-<translation id="3286390186030710347">แถบเลื่อน</translation>
-<translation id="3299925995433437805">ไม่มีลิงก์ที่เคยเข้าชมถัดไป</translation>
-<translation id="3303384412438961941">กดปุ่มใดๆ เพื่อเรียนรู้ชื่อของปุ่มนั้น Ctrl+W จะปิดการสำรวจแป้นพิมพ์</translation>
-<translation id="3307886118343381874">ไปที่ด้านล่างของตาราง</translation>
-<translation id="3311969765485641742">กด Alt+Shift+A เพื่อดูการแจ้งเตือน</translation>
-<translation id="3312997241656799641">ลิงก์ที่เคยเข้าชมถัดไป</translation>
-<translation id="3321460131042519426">เปิดใช้การตัดคำ</translation>
-<translation id="3322936298410871309">ส่วนหัวระดับ 1 ก่อนหน้า</translation>
-<translation id="3323447499041942178">ช่องข้อความ</translation>
-<translation id="3353420241558113817">{"ar": "อาหรับ",
- "bg": "บัลแกเรีย",
- "ca": "คาตาลัน",
- "cs": "เช็ก",
- "da": "เดนมาร์ก",
- "de": "เยอรมัน",
- "de_CH": "เยอรมัน (สวิตเซอร์แลนด์)",
- "de_DE": "เยอรมัน (เยอรมนี)",
- "el": "กรีก",
- "en": "อังกฤษ",
- "en_CA": "อังกฤษ (แคนาดา)",
- "en_GB": "อังกฤษ (สหราชอาณาจักร)",
- "en_US": "อังกฤษ (สหรัฐอเมริกา)",
- "es": "สเปน",
- "et": "เอสโตเนีย",
- "fr": "ฝรั่งเศส",
- "fr_CA": "ฝรั่งเศส (แคนาดา)",
- "fr_FR": "ฝรั่งเศส (ฝรั่งเศส)",
- "fi": "ฟินแลนด์",
- "he": "ฮิบรู",
- "hi": "ฮินดี",
- "hr": "โครเอเชีย",
- "hu": "ฮังการี",
- "is": "ไอซ์แลนด์",
- "it": "อิตาลี",
- "ko": "เกาหลี",
- "lt": "ลิทัวเนีย",
- "lv": "ลัตเวีย",
- "nb": "นอร์เวย์บุคมอล",
- "nl": "ดัตช์",
- "pl": "โปแลนด์",
- "pt": "โปรตุเกส",
- "ro": "โรมาเนีย",
- "ru": "รัสเซีย",
- "sk": "สโลวัก",
- "sl": "สโลวีเนีย",
- "sr": "เซอร์เบีย",
- "sv": "สวีเดน",
- "tr": "ตุรกี",
- "vi": "เวียดนาม",
- "zh": "จีน",
- "zh_TW": "จีน (อักษรฮั่นตัวเต็ม)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{เครื่องหมายบวก}other{# เครื่องหมายบวก}}</translation>
-<translation id="338583716107319301">ตัวแยก</translation>
-<translation id="3389259863310851658">ช่องฟอร์มก่อนหน้า</translation>
-<translation id="3390225400784126843">เอลิเมนต์ที่ต่างกันถัดไป</translation>
-<translation id="3392045790598181549">รายการเมนู <ph name="NAME" /></translation>
-<translation id="3406283310380167331">แสดงรายการฟอร์ม</translation>
-<translation id="3422338090358345848">เปิดการสำรวจแป้นพิมพ์</translation>
-<translation id="3457000393508828486">กดบางส่วน</translation>
-<translation id="3462439746547587373">ปุ่ม <ph name="NAME" /></translation>
-<translation id="3473644018603298796">เลือก <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> ถึง <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{วงเล็บขวา}other{# วงเล็บขวา}}</translation>
-<translation id="3493915602752813531">ไม่มีการเชื่อมโยงถัดไป</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{เครื่องหมายคำถาม}other{# เครื่องหมายคำถาม}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{เครื่องหมาย caret}other{# เครื่องหมาย caret}}</translation>
-<translation id="3568702578574425662">ไม่ได้เลือกช่องทำเครื่องหมาย <ph name="NAME" /></translation>
-<translation id="3599054940393788245">ไม่ได้อยู่ในคณิตศาสตร์</translation>
-<translation id="3616113530831147358">เสียง</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{เครื่องหมายแบ็กทิก}other{# เครื่องหมายแบ็กทิก}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{เครื่องหมายดอลลาร์}other{# เครื่องหมายดอลลาร์}}</translation>
-<translation id="3659787053479271466">การแจ้งเตือน</translation>
-<translation id="3665563998540286755">ช่องรายการ <ph name="VALUE" /></translation>
-<translation id="3687295507293856493">เดาส่วนหัวของคอลัมน์ของเซลล์ปัจจุบัน</translation>
-<translation id="3692274950075847560">ค้นหา:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">การควบคุมการพูด</translation>
-<translation id="3716845769494773620">หลายบรรทัด</translation>
-<translation id="3731746171184829332">ไม่มีส่วนหัวก่อนหน้า</translation>
-<translation id="3762198587642264450">ไปที่ด้านล่างของแถวปัจจุบัน</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">ออกจากช่องโต้ตอบแล้ว</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">รายการเติมข้อความอัตโนมัติ</translation>
-<translation id="3810838688059735925">วิดีโอ</translation>
-<translation id="3816633764618089385">สื่อถัดไป</translation>
-<translation id="3819376190738087562">ไม่มีการข้าม</translation>
-<translation id="385383972552776628">เปิดหน้าตัวเลือก</translation>
-<translation id="3856075812838139784">อ่านอย่างเดียว</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">เมนู</translation>
-<translation id="3909320334364316587">ส่วนหัวระดับ 6 ก่อนหน้า</translation>
-<translation id="3914173277599553213">จำเป็น</translation>
-<translation id="3962990492275676168">เริ่มอ่านจากตำแหน่งปัจจุบัน</translation>
-<translation id="4004802134384979325">เลือกแล้ว</translation>
-<translation id="4006140876663370126">รูปภาพ</translation>
-<translation id="4038349100599457191">การควบคุมเดือน</translation>
-<translation id="4039983576244166038">ส่วนหัวของแถวว่างเปล่า</translation>
-<translation id="4042843249978639960">ไม่มีส่วนหัวระดับ 2 ถัดไป</translation>
-<translation id="4043348641337972076">ไม่มีจุดสังเกต ARIA ก่อนหน้า</translation>
-<translation id="4047216625641135770">เครื่องหมาย</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">สถานะ</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{เครื่องหมายตัวหนอน}other{# เครื่องหมายตัวหนอน}}</translation>
-<translation id="409334809956508737">ออบเจ็กต์ก่อนหน้า</translation>
-<translation id="4099274309791143834">มีเมนูย่อย</translation>
-<translation id="4107807507418787238">ไม่มีเซลล์ด้านล่าง</translation>
-<translation id="4116415223832267137">การแจ้งเตือน</translation>
-<translation id="4147126331795725888">ไม่มีการควบคุมถัดไป</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{วงเล็บปีกกาขวา}other{# วงเล็บปีกกาขวา}}</translation>
-<translation id="4158704014418536539">พิจารณาตัวพิมพ์เล็กและใหญ่</translation>
-<translation id="4161663686871496107">การตอบสนองด้วยเสียงของ ChromeVox พร้อมใช้งาน</translation>
-<translation id="4173994908659439270">ไม่มีช่องข้อความที่สามารถแก้ไขได้ถัดไป</translation>
-<translation id="4176463684765177261">ปิดการใช้งานแล้ว</translation>
-<translation id="4188530942454211480">ประโยคก่อนหน้า</translation>
-<translation id="4202186506458631436">เลื่อนไปทางขวา</translation>
-<translation id="4206289001967551965">ภายในตาราง</translation>
-<translation id="4215733775853809057">แถบเลื่อนถัดไป</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{เครื่องหมายขีดกลาง}other{# เครื่องหมายขีดกลาง}}</translation>
-<translation id="421884353938374759">ตัวเลือกสี</translation>
-<translation id="4229646983878045487">วันที่ เวลา</translation>
-<translation id="423334822609210999">ไม่มีเซลล์ทางด้านซ้าย</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" /> ระดับ <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">หมายเหตุ</translation>
-<translation id="4254798249533888099">แผนผัง</translation>
-<translation id="4255943572433203166">ใช้ตัวเลือกด้านล่างในการกำหนดค่า ChromeVox การเปลี่ยนแปลงจะส่งผลทันที</translation>
-<translation id="4271220233568730077">คณิตศาสตร์ถัดไป</translation>
-<translation id="4271521365602459209">ไม่มีผลการค้นหาเพิ่มเติม</translation>
-<translation id="4287520460805643128">ไม่มีบทความถัดไป</translation>
-<translation id="4289540628985791613">ภาพรวม</translation>
-<translation id="4300318234632215983">แจ้ง URL ของลิงก์</translation>
-<translation id="4301352596632316575">มีเมนูย่อย</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{จุด}=3{จุดไข่ปลา}other{# จุด}}</translation>
-<translation id="4347461890115250064">ไม่มีรายการถัดไป</translation>
-<translation id="4367650418938037324">Leaf ML คณิตศาสตร์</translation>
-<translation id="4372435075475052704">ขั้นต่ำ: <ph name="X" /></translation>
-<translation id="4372705107434148843">หยุดการพูด</translation>
-<translation id="4373197658375206385">ไม่มีรายการก่อนหน้าที่ไม่ใช่ลิงก์</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">รีเซ็ต</translation>
-<translation id="4471074325120394300">ไม่มีลิงก์</translation>
-<translation id="4476183483923481720">บรรทัดใหม่</translation>
-<translation id="4482330759234983253">ตารางก่อนหน้า</translation>
-<translation id="4491109536499578614">รูปภาพ</translation>
-<translation id="4529987814483543472">รูปแบบแป้นคลาสสิก</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{เครื่องหมายทับ}other{# เครื่องหมายทับ}}</translation>
-<translation id="4547556996012970016">ส่วนหัวระดับ 5 ถัดไป</translation>
-<translation id="4562381607973973258">ส่วนหัว</translation>
-<translation id="4591507479202817876">, เลือกไว้</translation>
-<translation id="4597532268155981612">ฟอร์ม</translation>
-<translation id="4597896406374528575">เมษายน</translation>
-<translation id="4615592953348396470">เพิกเฉยการกดแป้นครั้งถัดไป</translation>
-<translation id="461613135510474570">ประโยค</translation>
-<translation id="4647836961514597010">ตัวเลือกสี</translation>
-<translation id="4661075872484491155">แผนผัง</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">ตาราง</translation>
-<translation id="4693675773662933727">จุดสังเกตก่อนหน้า</translation>
-<translation id="4696413482802371445">ไม่มีส่วนหัวระดับ 5 ถัดไป</translation>
-<translation id="4729095194763193578">แถวตารางก่อนหน้า</translation>
-<translation id="4736221692378411923">สิงหาคม</translation>
-<translation id="4740661827607246557">คำสั่งช่วยเหลือ</translation>
-<translation id="4759716709594980008">สำรวจแป้นพิมพ์ของ ChromeOS</translation>
-<translation id="4763296182459741068">ข้ามไปด้านล่าง</translation>
-<translation id="4763480195061959176">วิดีโอ</translation>
-<translation id="479989351350248267">ค้นหา</translation>
-<translation id="481165870889056555">แจ้งชื่อของหน้าเว็บปัจจุบัน</translation>
-<translation id="4826415162591436065">นำทางไปข้างหน้า</translation>
-<translation id="4826604887384865800">การข้ามถัดไป</translation>
-<translation id="4827410568042294688">ไม่ได้เลือก</translation>
-<translation id="4842108708071771135">ไม่มีข้อความที่ยกมาถัดไป</translation>
-<translation id="4848993367330139335">เครื่องตั้งเวลา</translation>
-<translation id="4850023505158945298">เอลิเมนต์ที่คล้ายกันก่อนหน้า</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">เปิดใช้การสลับ TTS</translation>
-<translation id="4877261390094455813">ป้อนคำค้นหา</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">ลิงก์ภายใน</translation>
-<translation id="4953585991029886728">แก้ไขข้อความ</translation>
-<translation id="4954534434583049121">ข้อความอ้างอิงก่อนหน้า</translation>
-<translation id="4973717656530883744">ขั้นต่ำ <ph name="X" /></translation>
-<translation id="4973762002207131920">สลับเป็น <ph name="KEY" /> แล้ว</translation>
-<translation id="4975416682604111799">มิลลิวินาที</translation>
-<translation id="49787999531187221">ChromeVox ปิดใช้งานอยู่ในตอนนี้</translation>
-<translation id="4979404613699303341">ปุ่มก่อนหน้า</translation>
-<translation id="4982773647088557172">ช่องรายการ <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="4983588134362688868">ข้ามไปที่ส่วนบนสุดของหน้าเว็บ</translation>
-<translation id="4986606102545753256">หน้าต่าง <ph name="NAME" /></translation>
-<translation id="4993152509206108683">ระดับ <ph name="PERCENT" /> เปอร์เซ็นต์</translation>
-<translation id="4996716799442435517">ภาพ</translation>
-<translation id="4997282455736854877">ปุ่มตัวเลือก <ph name="NAME" /> ที่เลือกไว้</translation>
-<translation id="4997475792277222884">ไม่มีรายการถัดไปที่ไม่ใช่ลิงก์</translation>
-<translation id="5000760171916499057">ไม่มีฟอร์ม</translation>
-<translation id="5005670136041063723">ไม่มีเอลิเมนต์ที่คล้ายกันเพิ่มเติม</translation>
-<translation id="501473567976723023">มกราคม</translation>
-<translation id="5041394372352067729">เลื่อนการแสดงผลเบรลล์ไปที่ด้านบนของหน้า</translation>
-<translation id="5042770794184672516">เพิ่มความดังเสียงพูด</translation>
-<translation id="5050015258024679800">ส่วนหัวระดับ 4 ก่อนหน้า</translation>
-<translation id="5054047268577924192">รายการก่อนหน้า</translation>
-<translation id="5078661581131202757">การเลือกไฟล์</translation>
-<translation id="5080758118274074384">ดับเบิลคลิกแล้ว</translation>
-<translation id="5098541983634824365">ออกจากตาราง</translation>
-<translation id="5102981729317424850">แถบเครื่องมือ</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">ไม่มีช่องฟอร์มก่อนหน้า</translation>
-<translation id="5111640677200759579">ส่วนหัวของคอลัมน์</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">ไม่มีลิงก์ก่อนหน้า</translation>
-<translation id="513774504516943387">ลิงก์</translation>
-<translation id="517143700877085897">, ไม่ได้เลือกไว้</translation>
-<translation id="5183440668879371625">เบรลล์บรรทัดก่อนหน้า</translation>
-<translation id="5184944171021383281">ไม่มีช่องฟอร์มถัดไป</translation>
-<translation id="5189244881767082992">บรรทัด</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> ถูกกำหนดให้กับคำสั่งแล้ว</translation>
-<translation id="5205493599117157272">รายการ <ph name="TYPE" /></translation>
-<translation id="520883772648104506">ไม่มีปุ่มตัวเลือกถัดไป</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">ออบเจ็กต์</translation>
-<translation id="5304943142864553931">แท็บ <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">ลบออกแล้ว:</translation>
-<translation id="5320727453979144100">เปิดใช้งานโหมดติดหนึบแล้ว</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{เครื่องหมายจุลภาค}other{# เครื่องหมายจุลภาค}}</translation>
-<translation id="532371086589123547">ช่องข้อความ <ph name="VALUE" /></translation>
-<translation id="5330443287809544590">ลิงก์ <ph name="NAME" /></translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">ข้ามไปทางด้านหลังในระหว่างการอ่านอย่างต่อเนื่อง</translation>
-<translation id="5368000168321181111">Earcons ปิด</translation>
-<translation id="5374320867641260420">ไม่มีปุ่มถัดไป</translation>
-<translation id="5382299583965267720">ไม่มีส่วนหัวระดับ 1 ถัดไป</translation>
-<translation id="5402367795255837559">เบรลล์</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{เครื่องหมายอัฒภาค}other{# เครื่องหมายอัฒภาค}}</translation>
-<translation id="5411891038905756502">ไม่มีจุดสำหรับข้ามก่อนหน้า</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{เครื่องหมายน้อยกว่า}other{# เครื่องหมายน้อยกว่า}}</translation>
-<translation id="5455441614648621694">ส่วนเสริม</translation>
-<translation id="5485036206801896268">ไม่มีกราฟิกก่อนหน้า</translation>
-<translation id="5486947920110100234">ไม่มีจุดสำหรับข้ามถัดไป</translation>
-<translation id="549602578321198708">คำ</translation>
-<translation id="5500932716852106146">ไม่มีช่องข้อความที่สามารถแก้ไขได้ก่อนหน้า</translation>
-<translation id="5502713021410870035">กันยายน</translation>
-<translation id="5507663321906818013">แก้ไขข้อบกพร่องในการเปรียบเทียบ</translation>
-<translation id="5518443085409638729">วางเคอร์เซอร์ระหว่างอักขระเมื่อต้องการแก้ไขข้อความ (เช่น Mac OS X)</translation>
-<translation id="552195134157544755">ปุ่มตัวเลือก</translation>
-<translation id="5534303576632885660">ส่วนหัว</translation>
-<translation id="5546092960038624944">ไม่มีส่วนหัวระดับ 5 ก่อนหน้า</translation>
-<translation id="556042886152191864">ปุ่ม</translation>
-<translation id="5561345396546889625">รายการถัดไป</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">แก้ไขข้อความ, รายการอีเมล</translation>
-<translation id="5597170376237141345">ช่องทำเครื่องหมายถัดไป</translation>
-<translation id="5597933780944041114">ไม่มีส่วนหัวถัดไป</translation>
-<translation id="5598905979683743333">ปุ่มตัวเลือก <ph name="NAME" /> ที่ไม่ได้เลือกไว้</translation>
-<translation id="5601172225407283979">ดำเนินการการทำงานเริ่มต้น</translation>
-<translation id="5608798115546226984">การเติมข้อความอัตโนมัติแบบในบรรทัด</translation>
-<translation id="561939826962581046">เวลา</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">บันทึก</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">ไม่มีตารางก่อนหน้า</translation>
-<translation id="5655682562155942719">คำสั่งข้าม</translation>
-<translation id="56637627897541303">พื้นที่ข้อความ</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">คำนิยาม</translation>
-<translation id="5682113568322255809">จุดสังเกต</translation>
-<translation id="5683155931978483559">ช่องทำเครื่องหมายก่อนหน้า</translation>
-<translation id="5684277895745049190">รายการ</translation>
-<translation id="5700650669149824506">ไม่มีส่วนหัวระดับ 4 ก่อนหน้า</translation>
-<translation id="5709192780268610569">ไม่มีคำอธิบายแบบยาว</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">คอลัมน์ตารางถัดไป</translation>
-<translation id="571866080859340309">การสำรวจกลุ่ม</translation>
-<translation id="5728409797179002635">ไม่พบตาราง</translation>
-<translation id="5748623122140342504">ส่วนหัวระดับ 5 ก่อนหน้า</translation>
-<translation id="5750633686117194034">ไม่มีการกดคีย์ตัวปรับแต่ง โปรดกดคีย์ตัวปรับแต่งอย่างน้อยหนึ่งคีย์ค้างไว้ ยกนิ้วขึ้นเมื่อเสร็จสิ้นและคุณจะได้ยินเสียงการตั้งคีย์ แตะเพื่อออก</translation>
-<translation id="5788275253279308023">แท็บหน้าต่างที่ไม่ระบุตัวตน <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">เพิ่มประสิทธิภาพไซต์เฉพาะ (เช่น Google Search)</translation>
-<translation id="5819072574982403430">รายการแบบต้นไม้</translation>
-<translation id="5826479389509458994">แถว <ph name="ROW" /> คอลัมน์ <ph name="COL" /></translation>
-<translation id="5850707923114094062">เลื่อนย้อนกลับ</translation>
-<translation id="5851548754964597211">รายการแท็บ</translation>
-<translation id="5859752971144398932">ออกจากการค้นหาในหน้าเว็บแล้ว</translation>
-<translation id="5866042630553435010">เลือกบางส่วน</translation>
-<translation id="5869546221129391014">ตาราง</translation>
-<translation id="5876817486144482042">ลดความดังเสียงพูด</translation>
-<translation id="5887397643266327462">เปิดใช้คำบรรยายอักษรเบรลล์แล้ว</translation>
-<translation id="5891934789323004067">ตาราง</translation>
-<translation id="5919442531159595654">คัดลอก</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{เครื่องหมายเท่ากับ}other{# เครื่องหมายเท่ากับ}}</translation>
-<translation id="5939518447894949180">รีเซ็ต</translation>
-<translation id="5948123859135882163">สลับการตีความสูตรคณิตศาสตร์ระหว่างโครงสร้างและความหมาย</translation>
-<translation id="5955304353782037793">แอป</translation>
-<translation id="5956928062748260866">ช่องโต้ตอบ</translation>
-<translation id="5963413905009737549">ส่วน</translation>
-<translation id="5968607524793740041">แสดงเมนูตามบริบท</translation>
-<translation id="5983179082906765664">เพิ่มความละเอียดในการนำทาง</translation>
-<translation id="5999630716831179808">เสียง</translation>
-<translation id="6000417740266304866">เปลี่ยนตารางเบรลล์แบบ 8 จุดปัจจุบันโดยเลือกหนึ่งตัวเลือกจากรายการด้านล่าง</translation>
-<translation id="6006050241733874051">ฟอร์ม</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{เครื่องหมายแบ็คสแลช}other{# เครื่องหมายแบ็คสแลช}}</translation>
-<translation id="6037602951055904232">เลื่อนไปข้างหน้า</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">สิ้นสุดเซลล์</translation>
-<translation id="6122013438240733403">ปุ่ม</translation>
-<translation id="6129953537138746214">ช่องว่าง</translation>
-<translation id="6142308968191113180">ส่วนหัวระดับ 4</translation>
-<translation id="6169420925157477918">ภาพมีคำอธิบายยาว</translation>
-<translation id="6172087735260766220">ไม่สามารถเข้าถึงข้อความที่ควรเข้าถึงได้จาก PDF ที่ป้องกันการคัดลอก</translation>
-<translation id="6186305613600865047">ไปที่ส่วนล่างสุดของหน้าเว็บ</translation>
-<translation id="6193330012414963395">AM PM</translation>
-<translation id="622484624075952240">ลง</translation>
-<translation id="6236061028292614533">ส่วนหัวถัดไป</translation>
-<translation id="6254901459154107917">พื้นที่ข้อความที่สามารถแก้ไขได้ถัดไป</translation>
-<translation id="6259464875943891919">ออกจาก <ph name="TYPE" /> แล้ว</translation>
-<translation id="6281876499889881039">เอลิเมนต์ที่คล้ายกันถัดไป</translation>
-<translation id="6282062888058716985">นำทาง</translation>
-<translation id="6290434000785343030">ไม่มีช่องตัวเลือกรวมถัดไป</translation>
-<translation id="6307969636681130414">กดแล้ว</translation>
-<translation id="6324551002951139333">ตรวจพบข้อผิดพลาดทางไวยากรณ์</translation>
-<translation id="6348657800373377022">ช่องตัวเลือกรวม</translation>
-<translation id="6355910664415701303">ไม่มีรายการก่อนหน้า</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">ส่วนหัวก่อนหน้า</translation>
-<translation id="6387719785439924554">ส่วนที่ไม่เกี่ยวข้อง</translation>
-<translation id="6411426777058107714">ไม่มีปุ่มตัวเลือกก่อนหน้า</translation>
-<translation id="6414968628640960377">เอลิเมนต์ที่ต่างกันก่อนหน้า</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{เครื่องหมายทวิภาค}other{# เครื่องหมายทวิภาค}}</translation>
-<translation id="6438968337250688271">เมนู <ph name="NAME" /></translation>
-<translation id="6444046323172968959">ช่องโต้ตอบการแจ้งเตือน</translation>
-<translation id="6459511626086141404">รูปแบบแป้นแบบราบ</translation>
-<translation id="6468049171101508116">ปุ่มถัดไป</translation>
-<translation id="6491972999578897419">เปลี่ยนเสียงปัจจุบันด้วยการเลือกจากรายการตัวเลือกด้านล่างนี้</translation>
-<translation id="6508059270146105198">เลื่อนการแสดงผลเบรลล์ไปที่ด้านล่างของหน้า</translation>
-<translation id="6536864053412760904">โทเค็น ML คณิตศาสตร์</translation>
-<translation id="6550720799683018100">เปลี่ยนรูปแบบแป้นปัจจุบันด้วยการเลือกจากรายการตัวเลือกด้านล่างนี้</translation>
-<translation id="6561818612645211875">ไปที่ด้านบนของแถวปัจจุบัน</translation>
-<translation id="6587021927234520429">ไม่มีส่วนหัวระดับ 4 ถัดไป</translation>
-<translation id="6601344353291556895">เปิดใช้งานคำอธิบายขนาดยาว</translation>
-<translation id="6615602925644411249">ค้นหาในหน้าเว็บ</translation>
-<translation id="6633350132811819843">ไม่มีตารางถัดไป</translation>
-<translation id="6637586476836377253">บันทึก</translation>
-<translation id="6657128831881431364">แถบความคืบหน้า</translation>
-<translation id="6659594942844771486">แท็บ</translation>
-<translation id="667999046851023355">เอกสาร</translation>
-<translation id="6697092096875747123">ช่องตัวเลือกรวมก่อนหน้า</translation>
-<translation id="6714813999819678458">ส่วนหัวระดับ 2 ก่อนหน้า</translation>
-<translation id="6716505898850596801">คีย์ตัวปรับแต่ง</translation>
-<translation id="671916444866103745">ไม่มีจุดสังเกต ARIA ถัดไป</translation>
-<translation id="6734854816611871228">ช่องตัวเลือกรวม <ph name="VALUE" /></translation>
-<translation id="6735257939857578167">ที่มี <ph name="NUM" /> รายการ</translation>
-<translation id="6736510033526053669">สร้างแท็บแล้ว</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">บทความ</translation>
-<translation id="6787839852456839824">แป้นพิมพ์ลัด</translation>
-<translation id="6793101435925451627">กล่องรายการ</translation>
-<translation id="6833103209700200188">ส่วนท้าย</translation>
-<translation id="6871161210040114857">ไม่สนใจตัวพิมพ์เล็กหรือใหญ่</translation>
-<translation id="6877435256196695200">ไม่มีกราฟิกถัดไป</translation>
-<translation id="6897341342232909480">เลื่อนไปทางซ้าย</translation>
-<translation id="6901540140423170855">วันที่</translation>
-<translation id="6910211073230771657">ลบแล้ว</translation>
-<translation id="6911965441508464308">ไม่มีเซลล์ด้านบน</translation>
-<translation id="6919104639734799681">แสดงรายการตาราง</translation>
-<translation id="6964088412282673743">ไม่มีการควบคุมก่อนหน้า</translation>
-<translation id="6996566555547746822">ช่องตัวเลือกรวมถัดไป</translation>
-<translation id="7005146664810010831">ไม่พบ URL</translation>
-<translation id="7010712454773919705">คีย์ตัวปรับแต่ง ChromeVox</translation>
-<translation id="7031651751836475482">รายการ</translation>
-<translation id="7037042857287298941">รายการก่อนหน้า</translation>
-<translation id="7041173719775863268">สิ้นสุดการเลือก</translation>
-<translation id="7095834689119144465">แก้ไขข้อความตัวเลขเท่านั้น</translation>
-<translation id="7096001299300236431">สื่อก่อนหน้า</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">พูดคำ</translation>
-<translation id="713824876195128146">ข้อความอ้างอิงถัดไป</translation>
-<translation id="7161771961008409533">ปุ่มป๊อปอัป</translation>
-<translation id="7167657087543110">พูดอักขระ</translation>
-<translation id="7170733337935166589">ข้ามไปทางด้านหน้าในระหว่างการอ่านอย่างต่อเนื่อง</translation>
-<translation id="7181697990050180700">กำหนดค่าแป้นพิมพ์ลัดสำหรับคำสั่งที่ใช้เป็นประจำด้วยการพิมพ์ลงในช่องที่เหมาะสมด้านล่าง</translation>
-<translation id="7203150201908454328">ขยาย</translation>
-<translation id="7210211103303402262">นาที</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">บรรทัด</translation>
-<translation id="7226216518520804442">รายการ</translation>
-<translation id="72393384879519786">ส่วนหัว</translation>
-<translation id="7241683698754534149">เปิดคำอธิบายแบบยาวในแท็บใหม่</translation>
-<translation id="7248671827512403053">แอปพลิเคชัน</translation>
-<translation id="725969808843520477">ปุ่มตัวเลือกถัดไป</translation>
-<translation id="7269119382257320590">ไม่มีเครื่องหมายวรรคตอน</translation>
-<translation id="7273174640290488576">ว่าง</translation>
-<translation id="7285387653379749618">ตาราง</translation>
-<translation id="7289186959554153431">ส่วนหัวระดับ 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">ปิดใช้คำบรรยายอักษรเบรลล์แล้ว</translation>
-<translation id="7318872822751139669">ใช้เมาส์เพื่อเปลี่ยนโฟกัส</translation>
-<translation id="7322388933135261569">กุมภาพันธ์</translation>
-<translation id="7332592614823088566">แถว <ph name="ROWINDEX" /> จาก <ph name="ROWTOTAL" />, คอลัมน์ <ph name="COLINDEX" /> จาก <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">มีป๊อปอัป</translation>
-<translation id="7356165926712028380">เปลี่ยนเป็นเบรลล์แบบ 8 จุด</translation>
-<translation id="7362871137496673139">ไม่มีส่วนหัวระดับ 2 ก่อนหน้า</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{เครื่องหมายแอมเปอร์แซนด์}other{# เครื่องหมายแอมเปอร์แซนด์}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">ออกจากตาราง</translation>
-<translation id="739763518212184081">บรรทัดก่อนหน้า</translation>
-<translation id="7400575256015741911">ตรวจพบข้อผิดพลาดในการสะกด</translation>
-<translation id="7408482676469142474">ตาราง</translation>
-<translation id="7425395583360211003">บรรทัดใหม่ตำแหน่งแรก</translation>
-<translation id="7434509671034404296">นักพัฒนา</translation>
-<translation id="7439060726180460871">ไดเรกทอรี</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">แท็บ</translation>
-<translation id="7492049978501397201">ข้อความที่ป้อน</translation>
-<translation id="7532613204005497612">มิถุนายน</translation>
-<translation id="7540083713905917247">แถบเลื่อน <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="7586163296341959563">วาง</translation>
-<translation id="7596919493010894443">ล้างการเลือกแล้ว</translation>
-<translation id="7604026522577407655">ไปที่ด้านบนของคอลัมน์ปัจจุบัน</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">แจ้ง URL ของหน้าเว็บปัจจุบัน</translation>
-<translation id="7609363189280667021">สลับคำบรรยายอักษรเบรลล์แล้ว</translation>
-<translation id="762020119231868829">หยุดชั่วคราววิดเจ็ตสื่อที่กำลังเล่นอยู่ทั้งหมด</translation>
-<translation id="7625690649919402823">ตารางถัดไป</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />) ระดับ <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">ไม่มีส่วนหัวระดับ 3 ก่อนหน้า</translation>
-<translation id="7659376057562985921">ช่องข้อความ <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="7663318257180412551">ส่วนหัวระดับ 2</translation>
-<translation id="7674576868851035240">ลิงก์ถัดไป</translation>
-<translation id="7674768236845044097">เครื่องหมาย</translation>
-<translation id="7684431668231950609">แก้ไขข้อความ, รายการ URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">ปุ่มตัวเลือกก่อนหน้า</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748">ช่องข้อความรหัสผ่าน <ph name="NAME" /> <ph name="VALUE" /></translation>
-<translation id="7805247615045262757">การนำทางที่เป็นค่าเริ่มต้น</translation>
-<translation id="7805768142964895445">สถานะ</translation>
-<translation id="7810781339813764006">กลุ่มถัดไป</translation>
-<translation id="7819187121850078213">แท็บหน้าต่าง <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">ตุลาคม</translation>
-<translation id="7839679365527550018">คำก่อนหน้า</translation>
-<translation id="7851816175263618915">เครื่องหมายวรรคตอนบางอย่าง</translation>
-<translation id="7870596830398826354">ต้นไม้ ML คณิตศาสตร์</translation>
-<translation id="78826985582142166">แถบเลื่อน</translation>
-<translation id="7894517696028036636">สลับ ChromeVox แบบคลาสสิก</translation>
-<translation id="7895896691902835279">ลิงก์ที่ไม่รู้จัก</translation>
-<translation id="7927711904086083099">ไม่ได้เลือก</translation>
-<translation id="7935627501098484003">การควบคุมเวลา</translation>
-<translation id="7939428177581522200">เพิ่มไปยังรายการที่เลือกแล้ว</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{เครื่องหมาย at}other{# เครื่องหมาย at}}</translation>
-<translation id="7965147473449754028">ปิดเมนูแล้ว</translation>
-<translation id="7974390230414479278">รายการเมนู</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{เครื่องหมายอัศเจรีย์}other{# เครื่องหมายอัศเจรีย์}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{เครื่องหมายอัญประกาศ}other{# เครื่องหมายอัญประกาศ}}</translation>
-<translation id="8033827949643255796">เลือกแล้ว</translation>
-<translation id="8035962149453661158">สูงสุด: <ph name="X" /></translation>
-<translation id="8042761080832772327">แก้ไขข้อความ, ข้อความค้นหา</translation>
-<translation id="8049189770492311300">ตัวจับเวลา</translation>
-<translation id="8065607967589909823">รายการที่เลือกคือ</translation>
-<translation id="8066678206530322333">แบนเนอร์</translation>
-<translation id="8110647606445335195">ไม่มีจุดสังเกต ARIA</translation>
-<translation id="8153880621934657047">ไม่ได้อยู่ในตาราง</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{เครื่องหมายขีดล่าง}other{# เครื่องหมายขีดล่าง}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">ตัด</translation>
-<translation id="8199231515320852133">แจ้งส่วนหัวของเซลล์ปัจจุบัน</translation>
-<translation id="820417203470636242">เซลล์ว่างเปล่า</translation>
-<translation id="8215202828671303819">เลือกหลายรายการ</translation>
-<translation id="8276439074553447000">ข้ามไปยังรายการที่สามารถโฟกัสก่อนหน้า</translation>
-<translation id="8278417001922463147">ไม่มีบทความก่อนหน้า</translation>
-<translation id="8283603667300770666">ช่องฟอร์มถัดไป</translation>
-<translation id="831207808878314375">คำจำกัดความ</translation>
-<translation id="8313653172105209786">ไดเรกทอรี</translation>
-<translation id="8344569602005188545">ชั่วโมง</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{เครื่องหมายปอนด์}other{# เครื่องหมายปอนด์}}</translation>
-<translation id="8374154622594089836">เดือน</translation>
-<translation id="8378855320830505539">ภูมิภาค</translation>
-<translation id="8382679411218029383">การเติมข้อความอัตโนมัติแบบในบรรทัดและเป็นรายการ</translation>
-<translation id="8428603554127842284">ระดับ <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">ไม่มีส่วนหัวระดับ 3 ถัดไป</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">ไม่มีช่องทำเครื่องหมายก่อนหน้า</translation>
-<translation id="8455868257606149352">สูงสุด <ph name="X" /></translation>
-<translation id="84575901236241018">มีรหัสการเข้าถึง <ph name="KEY" /></translation>
-<translation id="8503360654911991865">ลดความละเอียดในการนำทาง</translation>
-<translation id="8520472399088452386">ปุ่มหมุน</translation>
-<translation id="8538744478902126321">เดาส่วนหัวของแถวของเซลล์ปัจจุบัน</translation>
-<translation id="8540054775867439484">ข้ามไปด้านบน</translation>
-<translation id="8548973727659841685">อักขระ</translation>
-<translation id="8561322612995434619">มีป๊อปอัป</translation>
-<translation id="8571096049907249734">multsel</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">รายการถัดไป</translation>
-<translation id="860150890330522909">เลือกช่องทำเครื่องหมาย <ph name="NAME" /> แล้ว</translation>
-<translation id="8606621670302093223">การควบคุมวันที่</translation>
-<translation id="8631359288236106450">เลือก <ph name="COUNT" /> รายการ</translation>
-<translation id="8638532244051952400">แจ้งพิกัดของเซลล์ปัจจุบัน</translation>
-<translation id="8650576015643545550">ไม่มีรายการก่อนหน้า</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">แสดงรายการลิงก์</translation>
-<translation id="8664519043722036194">วินาที</translation>
-<translation id="867187640362843212">ส่วนหัวระดับ 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{เครื่องหมายขีดตั้ง}other{# เครื่องหมายขีดตั้ง}}</translation>
-<translation id="8735450637152821465">เริ่มการเลือก</translation>
-<translation id="8743786158317878347">ป้อนเนื้อหาที่มีโครงสร้าง เช่น ตาราง</translation>
-<translation id="8747966237988593539">รายการที่มีลำดับ</translation>
-<translation id="8759334257841767240">ไม่มีลิงก์ถัดไป</translation>
-<translation id="8767968232364267681">ส่วนหัวระดับ 4 ถัดไป</translation>
-<translation id="8770473310765924354">ออกจากเนื้อหาที่มีโครงสร้าง เช่น ตาราง</translation>
-<translation id="8791025954632646584">เปิดความหมาย</translation>
-<translation id="8796411681063377102">ส่วนหัวระดับ 3 ถัดไป</translation>
-<translation id="8808582214901541005">มีนาคม</translation>
-<translation id="8825828890761629845">แบนเนอร์</translation>
-<translation id="8851136666856101339">หลัก</translation>
-<translation id="8856538297388979332">กดขึ้นหรือลงเพื่อดูคำสั่ง กด Enter เพื่อเปิดใช้งาน</translation>
-<translation id="8864099967139188018">ไม่มีส่วนหัวระดับ 6 ถัดไป</translation>
-<translation id="8882002077197914455">ส่วนหัวของแถว</translation>
-<translation id="8896347895970027998">สลับระหว่างการเปิด/ปิดใช้งาน ChromeVox</translation>
-<translation id="8898516272131543774">พูดรอบเครื่องหมายวรรคตอน</translation>
-<translation id="8900148057318340779">คีย์ส่วนหน้า</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">ส่วนหัวว่างเปล่า</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">คีย์ตัวปรับแต่ง</translation>
-<translation id="8943175951035496220">ไม่มีเซลล์ทางด้านขวา</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">ไฟล์</translation>
-<translation id="9027462562263121875">ไม่มีตาราง</translation>
-<translation id="9040132695316389094">ส่วนหัวระดับ 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">สลับวิดเจ็ตการค้นหา</translation>
-<translation id="9065283790526219006">+ป๊อปอัป</translation>
-<translation id="9077213568694924680">ลบออกจากการเลือกแล้ว</translation>
-<translation id="9082874451376019682">ไม่มีแถบเลื่อนก่อนหน้า</translation>
-<translation id="9089864840575085222">พูดรอบการพิมพ์</translation>
-<translation id="9107530006868467849">ไม่มีวิดเจ็ตสื่อก่อนหน้า</translation>
-<translation id="9108370397979208512">คณิตศาสตร์</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{เครื่องหมายเปอร์เซ็นต์}other{# เครื่องหมายเปอร์เซ็นต์}}</translation>
-<translation id="9115913704608474258">พฤศจิกายน</translation>
-<translation id="9128414153595658330">ข้อความ</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">แจ้งคำอธิบายโดยย่อของตำแหน่งปัจจุบัน</translation>
-<translation id="9153606228985488238">ระดับเสียง <ph name="PERCENT" /> เปอร์เซ็นต์</translation>
-<translation id="9160096769946561184">ไปที่ด้านล่างของคอลัมน์ปัจจุบัน</translation>
-<translation id="9173115498289768110">ความดัง <ph name="PERCENT" /> เปอร์เซ็นต์</translation>
-<translation id="9178973770513562274">ใช้แป้นลูกศรขึ้นและลงเพื่อเรียกดู หรือพิมพ์เพื่อค้นหา</translation>
-<translation id="9192904702577636854">ตัวอักษรวิ่ง</translation>
-<translation id="9212322457209634662">ไม่มีส่วนถัดไป</translation>
-<translation id="930275611743429116">เริ่มต้นหรือสิ้นสุดการเลือก</translation>
-<translation id="948171205378458592">ลดความเร็วการพูด</translation>
-<translation id="962913030769097253">ส่วนหัวระดับ 1 ถัดไป</translation>
-<translation id="973955474346881951">เปิด/ปิดโหมดติดหนึบ</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_tr.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_tr.xtb
deleted file mode 100644
index e2586b03082..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_tr.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="tr">
-<translation id="1012173283529841972">Liste öğesi</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Farklı satıra veya sütuna geçildi.</translation>
-<translation id="1025074108959230262">Yapışkan mod devre dışı bırakıldı</translation>
-<translation id="1031961866430398710">sonra</translation>
-<translation id="1044777062731150180">Üst bilgi yok.</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">Geçersiz giriş</translation>
-<translation id="1082209053475788238">Önceki 6. düzey başlık yok.</translation>
-<translation id="1088219014394087294">Başlık yok.</translation>
-<translation id="1106741348836243114">Sesli geri bildirimi (ses sinyalleri) aç veya kapat.</translation>
-<translation id="1120743664840974483">{"a": "adana", "b": "bolu", "c": "ceyhan", "ç": "çanakkale", "d": "denizli", "e": "edirne", "f": "fatsa", "g": "giresun", "ğ": "yumuşak ge", "h": "hatay", "ı": "ısparta", "i": "izmir", "j": "jandarma", "k": "kayseri", "l": "lüleburgaz", "m": "muş", "n": "niğde", "o": "ordu","p": "polatlı", "r": "rize", "s": "sinop", "ş": "şırnak", "t": "tokat", "u": "uşak", "ü": "ünye", "v": "van", "y": "yozgat", "z": "zonguldak"}</translation>
-<translation id="113582498867142724"><ph name="NUM" /> öğeye sahip <ph name="TAG" /> koleksiyonu</translation>
-<translation id="1155043339247954670">Sonraki liste öğesi yok.</translation>
-<translation id="1157782847298808853">Klavye Yardımı</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, birleşik kutu</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, menü öğesi, alt menüye sahip</translation>
-<translation id="1177863135347784049">Özel</translation>
-<translation id="1188858454923323853">tamamlayıcı</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - Chrome'un Sesi</translation>
-<translation id="1229276918471378188">Önceki atlama</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Sonraki 6. düzey başlık</translation>
-<translation id="1275718070701477396">Seçili</translation>
-<translation id="1319608975892113573">Önceki blok alıntı yok.</translation>
-<translation id="1321576897702511272">ChromeVox yardımını gizle</translation>
-<translation id="1331702245475014624">toplam: <ph name="TOTAL" />, öğe: <ph name="INDEX" /></translation>
-<translation id="1334095593597963605">karakter ve kelime yansıtma</translation>
-<translation id="1339428534620983148">Önceki tablo sütunu</translation>
-<translation id="1342835525016946179">article</translation>
-<translation id="1346748346194534595">Sağa</translation>
-<translation id="136718599399906424">Sonraki tablo satırı</translation>
-<translation id="1383876407941801731">Ara</translation>
-<translation id="1385214448885562192">Kabul etmek için enter veya iptal etmek için escape tuşuna, ileri gitmek için aşağı ve geri gitmek için yukarı tuşlarına basın.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, şifre metin kutusu</translation>
-<translation id="1467432559032391204">Sola</translation>
-<translation id="1474557363159888097">Önceki bağlantı yok.</translation>
-<translation id="1502086903961450562">Önceki grafik</translation>
-<translation id="1506187449813838456">Sesi incelt</translation>
-<translation id="151784044608172266">Sonraki Cümle</translation>
-<translation id="1524531499102321782">Braille sonraki Satır</translation>
-<translation id="1546370775711804143">Kaydırma çubuğu</translation>
-<translation id="1559739829547075274">Geri git</translation>
-<translation id="1571643229714746283">ChromeVox hazır</translation>
-<translation id="158493514907962286">Aralık</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">6 noktalı braille'e geç</translation>
-<translation id="1611168825862729585">Sütun üst bilgisi:</translation>
-<translation id="1613476421962910979">Ses sinyalleri açık</translation>
-<translation id="1618597272655350600">Mevcut konumun tam açıklamasını söyler</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{büyüktür işareti}other{# büyüktür işareti}}</translation>
-<translation id="1653266918374749391">Önceki 3. düzey başlık</translation>
-<translation id="1659072772017912254">İşaretli değil</translation>
-<translation id="1669290819662866522">week</translation>
-<translation id="1674262202423278359">ChromeVox Gezinme</translation>
-<translation id="16777221443363124">Menü çubuğu</translation>
-<translation id="1692077714702418899">yapısal satır</translation>
-<translation id="1700517974991662022">Ziyaret edildi</translation>
-<translation id="1722567105086139392">Bağlantı</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Sonraki grafik</translation>
-<translation id="1781173782405573156">Geçiş tuşu</translation>
-<translation id="1787176709638001873">Şifre düzenleme metni</translation>
-<translation id="1810107444790159527">Liste kutusu</translation>
-<translation id="1828385960365606039">Mayıs</translation>
-<translation id="1834891354138622109">Sütun</translation>
-<translation id="1865601187525349519">Metnin sonu</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Geçerli saati ve tarihi söyle.</translation>
-<translation id="1902396333223336119">Hücre</translation>
-<translation id="1905379170753160525">Başlıklar listesini göster</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Yılın haftası denetimi</translation>
-<translation id="1964135212174907577">Sonraki Nesne</translation>
-<translation id="1969092762068865084">Temmuz</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Satır üst bilgisi:</translation>
-<translation id="2002895034995108595">Geçerli tuş eşleşmesini sıfırla</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{sol köşeli ayraç}other{# sol köşeli ayraç}}</translation>
-<translation id="2045490512405922022">seçili değil</translation>
-<translation id="20601713649439366">Önceki matematik ifadesi yok.</translation>
-<translation id="207477615537953741">Anlamsal yorum kapalı</translation>
-<translation id="2086961585857038472">Sonraki Kelime</translation>
-<translation id="2089387485033699258">tr</translation>
-<translation id="2091933974477985526">Düzenlenebilir önceki metin alanı</translation>
-<translation id="2100350898815792233">Tüm noktalama işaretleri</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">erişim tuşu:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Aşağıdaki listeden bir seçenek belirleyerek mevcut 6 noktalı braille'i değiştirin.</translation>
-<translation id="2169714232367507776">Mevcut öğeyi tıkla</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{kapa parantez}other{# kapa parantez}}</translation>
-<translation id="2199994615414171367">Önceki matematik tuşu</translation>
-<translation id="2223693656926968778">Mevcut öğe üzerinde işlem yap</translation>
-<translation id="225732394367814946">Konuşma hızını artır</translation>
-<translation id="2267945578749931355">Sonraki Karakter</translation>
-<translation id="2281234842553884450">Önceki kaydırma çubuğu</translation>
-<translation id="2318372665160196757">Ana</translation>
-<translation id="2329324941084714723">Sekme paneli</translation>
-<translation id="2344193891939537199">Tarih/saat denetimi</translation>
-<translation id="2359897517538099099">Tablo modunda değil.</translation>
-<translation id="241124561063364910">ardından</translation>
-<translation id="2417569100218200841">İçerik bilgileri</translation>
-<translation id="2422937916923936891">Menü öğesi onay kutusu</translation>
-<translation id="2429669115401274487">ÖS</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> artık yeni ChromeVox değiştirici.</translation>
-<translation id="2450814015951372393">Onay kutusu</translation>
-<translation id="2462626033734746142">Radyo düğmesi grubu</translation>
-<translation id="2471138580042810658">Başlık 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{yıldız işareti}other{# yıldız işareti}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> sıfırlandı.</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">Grup</translation>
-<translation id="2582407057977008361">Kenar</translation>
-<translation id="2589102159832527089">Bu sayfada &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; adlı PDF dosyasından otomatik olarak ayıklanmış metin bulunmaktadır. &lt;a href="<ph name="URL" />"&gt;Orijinali görmek için burayı tıklayın.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">{COUNT,plural, =1{# öğeyle}other{# öğeyle}}</translation>
-<translation id="2614981083756825552">Matematik ML Düzeni</translation>
-<translation id="2626530649491650971">tıklanabilir</translation>
-<translation id="2628764385451019380">Önceki birleşik giriş kutusu yok</translation>
-<translation id="2637227747952042642">Matematik</translation>
-<translation id="2639750663247012216">ChromeVox değiştirici</translation>
-<translation id="2644542693584024604">misspelled</translation>
-<translation id="2667291555398229137">Bir yönlendirme tuşunun altındaki öğeyi tıklayın</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{aç parantez}other{# aç parantez}}</translation>
-<translation id="2705875883745373140">Basılmadı</translation>
-<translation id="2706462751667573066">Yukarı</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">ses</translation>
-<translation id="2732718972699418926">ÖÖ</translation>
-<translation id="2749275490991666823">İşaretli</translation>
-<translation id="27527859628328957">Odaklanabilir sonraki öğeye atla</translation>
-<translation id="2770781857296573485">Grup keşfine geç</translation>
-<translation id="2777845298774924149">Çıkıldı</translation>
-<translation id="2800204403141299078">Başka farklı öğe yok.</translation>
-<translation id="2800780099804980316">Önceki 1. düzey başlık yok.</translation>
-<translation id="2811204574343810641">Satır</translation>
-<translation id="2816654101880605877">Sonraki kaydırma çubuğu yok.</translation>
-<translation id="2841013758207633010">Zaman</translation>
-<translation id="2843837985843789981">Önceki Grup</translation>
-<translation id="2844995807198708617">Bağlam Menüsü</translation>
-<translation id="2849332794118375855">Sonraki onay kutusu yok.</translation>
-<translation id="2864481629947106776">Önceki bağlantı</translation>
-<translation id="2873259058405069099">Tablonun başına git</translation>
-<translation id="2894654529758326923">Bilgiler</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{sol küme parantezi}other{# sol küme parantezi}}</translation>
-<translation id="2911433807131383493">ChromeVox eğiticiyi aç</translation>
-<translation id="2932083475399492303">Yapısal veya düzen satır türü arasında geçiş yap</translation>
-<translation id="2964026537669811554">Başlık grubu</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{sekme}other{# sekme}}</translation>
-<translation id="2972078295414139404">Ziyaret edilmiş başka önceki bağlantı yok.</translation>
-<translation id="2972205263822847197">İpucu</translation>
-<translation id="2998131015536248178">Önceki Karakter</translation>
-<translation id="2999559350546931576">Sesi kalınlaştır</translation>
-<translation id="2999945368667127852">Sonraki medya widget'ı yok.</translation>
-<translation id="3012414509011670858">Önceki bölüm yok.</translation>
-<translation id="3030432017085518523">Menü öğesi radyo düğmesi</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{kesme işareti}other{# kesme işareti}}</translation>
-<translation id="3046838483509668188">ChromeVox Seçenekleri</translation>
-<translation id="3047143736589213134">Deneysel tuş eşleme</translation>
-<translation id="3060756054951570867"><ph name="TITLE" /> menüsü açıldı</translation>
-<translation id="3078345202707391975">Sonraki 2. düzey başlık</translation>
-<translation id="3078740164268491126">tablo</translation>
-<translation id="3082557070674409251">Tıklandı</translation>
-<translation id="3084806535845658316">yazma yansıtması yok</translation>
-<translation id="3086746722712840547">note</translation>
-<translation id="308895241372589742">Sonraki matematik ifadesi yok.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Sonraki önemli nokta</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Daraltılmış</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Önemli nokta listesini göster</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Sonraki Satır</translation>
-<translation id="3155083529632865074">Önceki düğme yok.</translation>
-<translation id="3163593631834463955">Boş sütun üst bilgisi</translation>
-<translation id="316542773973815724">Gezinme</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{boşluk}other{# boşluk}}</translation>
-<translation id="320961988183078793"><ph name="TYPE" /> girildi</translation>
-<translation id="3223701887221307104"><ph name="NAME" />, sekme</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Ziyaret edilmiş bağlantı</translation>
-<translation id="323731244387692321">ChromeVox klavye yardımını aç</translation>
-<translation id="3241052487511142956">Ziyaret edilmiş olan önceki bağlantı</translation>
-<translation id="3286390186030710347">Kaydırma çubuğu</translation>
-<translation id="3299925995433437805">Ziyaret edilmiş başka sonraki bağlantı yok.</translation>
-<translation id="3303384412438961941">Adını öğrenmek için herhangi bir tuşa basın. Ctrl+W klavye gezginini kapatır.</translation>
-<translation id="3307886118343381874">Tablonun sonuna git</translation>
-<translation id="3311969765485641742">Uyarıları incelemek için Alt+ÜstKrktr+A tuşuna basın</translation>
-<translation id="3312997241656799641">Ziyaret edilmiş olan sonraki bağlantı</translation>
-<translation id="3321460131042519426">Kelime kaydırmayı etkinleştir</translation>
-<translation id="3322936298410871309">Önceki 1. düzey başlık</translation>
-<translation id="3323447499041942178">Metin kutusu</translation>
-<translation id="3353420241558113817">{"ar": "Arapça",
- "bg": "Bulgarca",
- "ca": "Katalanca",
- "cs": "Çekçe",
- "da": "Danca",
- "de": "Almanca",
- "de_CH": "Almanca (İsviçre)",
- "de_DE": "Almanca (Almanya)",
- "el": "Yunanca",
- "en": "İngilizce",
- "en_CA": "İngilizce (Kanada)",
- "en_GB": "İngilizce (İngiltere)",
- "en_US": "İngilizce (ABD)",
- "es": "İspanyolca",
- "et": "Estonca",
- "fr": "Fransızca",
- "fr_CA": "Fransızca (Kanada)",
- "fr_FR": "Fransızca (Fransa)",
- "fi": "Fince",
- "he": "İbranice",
- "hi": "Hint Dili",
- "hr": "Hırvatça",
- "hu": "Macarca",
- "is": "İzlandaca",
- "it": "İtalyanca",
- "ko": "Korece",
- "lt": "Litvanca",
- "lv": "Letonca",
- "nb": "Norveççe Bokmål",
- "nl": "Felemenkçe",
- "pl": "Lehçe",
- "pt": "Portekizce",
- "ro": "Rumence",
- "ru": "Rusça",
- "sk": "Slovakça",
- "sl": "Slovence",
- "sr": "Sırpça",
- "sv": "İsveççe",
- "tr": "Türkçe",
- "vi": "Vietnamca",
- "zh": "Çince",
- "zh_TW": "Çince (Geleneksel Han)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{artı işareti}other{# artı işareti}}</translation>
-<translation id="338583716107319301">Ayırıcı</translation>
-<translation id="3389259863310851658">Önceki form alanı</translation>
-<translation id="3390225400784126843">Sonraki farklı öğe.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, menü öğesi</translation>
-<translation id="3406283310380167331">Form listesini göster</translation>
-<translation id="3422338090358345848">Klavye gezginini aç</translation>
-<translation id="3457000393508828486">Kısmen basıldı</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, düğme</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{sağ köşeli ayraç}other{# sağ köşeli ayraç}}</translation>
-<translation id="3493915602752813531">Sonraki bağlantı yok.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{soru işareti}other{# soru işareti}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{düzeltme işareti}other{# düzeltme işareti}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" /> adlı onay kutusu işaretli değil</translation>
-<translation id="3599054940393788245">Matematik sembol kullanımında değil</translation>
-<translation id="3616113530831147358">Ses</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{aksan işareti}other{# aksan işareti}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dolar işareti}other{# dolar işareti}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, liste kutusu</translation>
-<translation id="3687295507293856493">Mevcut hücrenin sütun üst bilgisini tahmin et</translation>
-<translation id="3692274950075847560">A:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Konuşmayı Denetleme</translation>
-<translation id="3716845769494773620">Çok satırlı</translation>
-<translation id="3731746171184829332">Önceki başlık yok.</translation>
-<translation id="3762198587642264450">Mevcut satırın sonuna git</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">İletişim kutusundan çıkıldı.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Otomatik tamamlama listesi</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Sonraki medya tuşu</translation>
-<translation id="3819376190738087562">Atlama yok.</translation>
-<translation id="385383972552776628">Seçenekler sayfasını aç</translation>
-<translation id="3856075812838139784">Salt okunur</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menü</translation>
-<translation id="3909320334364316587">Önceki 6. düzey başlık</translation>
-<translation id="3914173277599553213">Gerekli</translation>
-<translation id="3962990492275676168">Mevcut konumdan okumaya başla</translation>
-<translation id="4004802134384979325">işaretli</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Ay denetimi</translation>
-<translation id="4039983576244166038">Boş satır üst bilgisi</translation>
-<translation id="4042843249978639960">Sonraki 2. düzey başlık yok.</translation>
-<translation id="4043348641337972076">Önceki ARIA önemli noktası yok.</translation>
-<translation id="4047216625641135770">İşaretle</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{YAKLAŞIK İŞARETİ}other{# yaklaşık işareti}}</translation>
-<translation id="409334809956508737">Önceki Nesne</translation>
-<translation id="4099274309791143834">alt menü içerir</translation>
-<translation id="4107807507418787238">Aşağıda hücre yok.</translation>
-<translation id="4116415223832267137">Uyarı</translation>
-<translation id="4147126331795725888">Sonraki denetim yok.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{sağ küme parantezi}other{# sağ küme parantezi}}</translation>
-<translation id="4158704014418536539">Büyük/küçük harfe duyarlı.</translation>
-<translation id="4161663686871496107">ChromeVox sesli geri bildirim hazır</translation>
-<translation id="4173994908659439270">Düzenlenebilir sonraki metin alanı yok.</translation>
-<translation id="4176463684765177261">Devre dışı</translation>
-<translation id="4188530942454211480">Önceki Cümle</translation>
-<translation id="4202186506458631436">Sağa git</translation>
-<translation id="4206289001967551965">Tablo içinde</translation>
-<translation id="4215733775853809057">Sonraki kaydırma çubuğu</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{kısa çizgi}other{# kısa çizgi}}</translation>
-<translation id="421884353938374759">renk seçici</translation>
-<translation id="4229646983878045487">date time</translation>
-<translation id="423334822609210999">Solda hücre yok.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, <ph name="GRADE" />. Derece</translation>
-<translation id="4253168017788158739">Notlar</translation>
-<translation id="4254798249533888099">Tree</translation>
-<translation id="4255943572433203166">ChromeVox'u özelleştirmek için aşağıdaki seçenekleri kullanın. Değişiklikler anında geçerli olur.</translation>
-<translation id="4271220233568730077">Sonraki matematik tuşu</translation>
-<translation id="4271521365602459209">Başka sonuç yok.</translation>
-<translation id="4287520460805643128">Sonraki makale yok.</translation>
-<translation id="4289540628985791613">Genel bakış</translation>
-<translation id="4300318234632215983">Bir bağlantının arkasındaki URL'yi söyle</translation>
-<translation id="4301352596632316575">alt menüsü var</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{nokta}=3{üç nokta}other{# nokta}}</translation>
-<translation id="4347461890115250064">Sonraki liste yok.</translation>
-<translation id="4367650418938037324">Matematik ML Yaprağı</translation>
-<translation id="4372435075475052704">en az:<ph name="X" /></translation>
-<translation id="4372705107434148843">Konuşmayı durdur</translation>
-<translation id="4373197658375206385">Bağlantı olmayan önceki öğe yok.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">reset</translation>
-<translation id="4471074325120394300">Bağlantı yok.</translation>
-<translation id="4476183483923481720">yeni satır</translation>
-<translation id="4482330759234983253">Önceki tablo</translation>
-<translation id="4491109536499578614">Resim</translation>
-<translation id="4529987814483543472">Klasik tuş eşleşmesi</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{eğik çizgi}other{# eğik çizgi}}</translation>
-<translation id="4547556996012970016">Sonraki 5. düzey başlık</translation>
-<translation id="4562381607973973258">Üst bilgi</translation>
-<translation id="4591507479202817876">, seçili</translation>
-<translation id="4597532268155981612">form</translation>
-<translation id="4597896406374528575">Nisan</translation>
-<translation id="4615592953348396470">Basılacak bir sonraki tuş yoksayılacak</translation>
-<translation id="461613135510474570">Cümle</translation>
-<translation id="4647836961514597010">Renk seçici</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Önceki önemli nokta</translation>
-<translation id="4696413482802371445">Sonraki 5. düzey başlık yok.</translation>
-<translation id="4729095194763193578">Önceki tablo satırı</translation>
-<translation id="4736221692378411923">Ağustos</translation>
-<translation id="4740661827607246557">Yardım Komutları</translation>
-<translation id="4759716709594980008">ChromeOS Klavye Gezgini</translation>
-<translation id="4763296182459741068">Alta döner</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">ara</translation>
-<translation id="481165870889056555">Mevcut sayfanın başlığını söyle</translation>
-<translation id="4826415162591436065">İleri git</translation>
-<translation id="4826604887384865800">Sonraki atlama</translation>
-<translation id="4827410568042294688">seçili değil</translation>
-<translation id="4842108708071771135">Sonraki blok alıntı yok.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Önceki benzer öğe.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">TTS günlük kaydını etkinleştir</translation>
-<translation id="4877261390094455813">Arama sorgusunu girin.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" /> / <ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Dahili bağlantı</translation>
-<translation id="4953585991029886728">Metni düzenle</translation>
-<translation id="4954534434583049121">Önceki blok alıntı</translation>
-<translation id="4973717656530883744">En az <ph name="X" /></translation>
-<translation id="4973762002207131920"><ph name="KEY" /> tuş eşleşmesine geçildi.</translation>
-<translation id="4975416682604111799">milisaniye</translation>
-<translation id="49787999531187221">ChromeVox şu anda etkin.</translation>
-<translation id="4979404613699303341">Önceki düğmesi</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, liste kutusu</translation>
-<translation id="4983588134362688868">Sayfanın en üst kısmına atlar</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, pencere</translation>
-<translation id="4993152509206108683">Hız yüzde <ph name="PERCENT" /></translation>
-<translation id="4996716799442435517">Görsel</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, radyo düğmesi seçili</translation>
-<translation id="4997475792277222884">Bağlantı olmayan sonraki öğe yok.</translation>
-<translation id="5000760171916499057">Form yok.</translation>
-<translation id="5005670136041063723">Başka benzer öğe yok.</translation>
-<translation id="501473567976723023">Ocak</translation>
-<translation id="5041394372352067729">Braille ekranını sayfanın üstüne taşı</translation>
-<translation id="5042770794184672516">Konuşma ses düzeyini artır</translation>
-<translation id="5050015258024679800">Önceki 4. düzey başlık</translation>
-<translation id="5054047268577924192">Önceki liste öğesi</translation>
-<translation id="5078661581131202757">Dosya seçimi</translation>
-<translation id="5080758118274074384">çift tıklandı</translation>
-<translation id="5098541983634824365">Tablodan çıkılıyor.</translation>
-<translation id="5102981729317424850">Araç çubuğu</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Önceki form alanı yok.</translation>
-<translation id="5111640677200759579">Sütun üst bilgisi</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Önceki bağlantı yok.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, seçili değil</translation>
-<translation id="5183440668879371625">Braille önceki Satır</translation>
-<translation id="5184944171021383281">Sonraki form alanı yok</translation>
-<translation id="5189244881767082992">Satır</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> tuşu zaten bir komuta atanmış.</translation>
-<translation id="5205493599117157272"><ph name="TYPE" /> listesi.</translation>
-<translation id="520883772648104506">Sonraki radyo düğmesi yok.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Nesne</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, sekme</translation>
-<translation id="5310788376443009632">kaldırıldı:</translation>
-<translation id="5320727453979144100">Yapışkan mod etkinleştirildi</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{virgül}other{# virgül}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, metin kutusu</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, bağlantı</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Sürekli okuma sırasında geriye doğru atla</translation>
-<translation id="5368000168321181111">Ses sinyalleri kapalı</translation>
-<translation id="5374320867641260420">Sonraki düğme yok.</translation>
-<translation id="5382299583965267720">Sonraki 1. düzey başlık yok.</translation>
-<translation id="5402367795255837559">Braille</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{noktalı virgül}other{# noktalı virgül}}</translation>
-<translation id="5411891038905756502">Önceki atlama noktası yok.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{küçüktür işareti}other{# küçüktür işareti}}</translation>
-<translation id="5455441614648621694">Tamamlayıcı</translation>
-<translation id="5485036206801896268">Önceki grafik yok.</translation>
-<translation id="5486947920110100234">Sonraki atlama noktası yok.</translation>
-<translation id="549602578321198708">Kelime</translation>
-<translation id="5500932716852106146">Düzenlenebilir önceki metin alanı yok.</translation>
-<translation id="5502713021410870035">Eylül</translation>
-<translation id="5507663321906818013">Hata ayıklama değerlendirmesi</translation>
-<translation id="5518443085409638729">Metin düzenlerken karakterler arasına imleç koy (Mac OS X'teki gibi).</translation>
-<translation id="552195134157544755">Radyo düğmesi</translation>
-<translation id="5534303576632885660">hdr</translation>
-<translation id="5546092960038624944">Önceki 5. düzey başlık yok.</translation>
-<translation id="556042886152191864">Düğme</translation>
-<translation id="5561345396546889625">Sonraki liste</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Geri al tuşu</translation>
-<translation id="5585044216466955529">Metni düzenle, e-posta girişi</translation>
-<translation id="5597170376237141345">Sonraki onay kutusu</translation>
-<translation id="5597933780944041114">Sonraki başlık yok.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, radyo düğmesi seçili değil</translation>
-<translation id="5601172225407283979">Varsayılan işlemi gerçekleştir</translation>
-<translation id="5608798115546226984">Satır içi otomatik tamamlama</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Günlük</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Önceki tablo yok.</translation>
-<translation id="5655682562155942719">Atlama Komutları</translation>
-<translation id="56637627897541303">Metin alanı</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Önemli Nokta</translation>
-<translation id="5683155931978483559">Önceki onay kutusu</translation>
-<translation id="5684277895745049190">Liste</translation>
-<translation id="5700650669149824506">Önceki 4. düzey başlık yok.</translation>
-<translation id="5709192780268610569">Uzun açıklama yok</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Sonraki tablo sütunu</translation>
-<translation id="571866080859340309">Gruplar keşfediliyor</translation>
-<translation id="5728409797179002635">Tablo bulunamadı.</translation>
-<translation id="5748623122140342504">Önceki 5. düzey başlık</translation>
-<translation id="5750633686117194034">Herhangi bir değiştiriciye basılmadı; lütfen en az bir değiştiriciyi basılı tutun; tamamlandığında parmaklarınızı kaldırın; tuşların ayarlandığını duyacaksınız. Çıkmak için Sekme'ye basın.</translation>
-<translation id="5788275253279308023">gizli mod penceresi <ph name="TITLE" /> sekmesi</translation>
-<translation id="5806206155699461681">(Google Arama gibi) belirli siteleri geliştir.</translation>
-<translation id="5819072574982403430">Ağaç öğesi</translation>
-<translation id="5826479389509458994"><ph name="ROW" />. satır, <ph name="COL" />. sütun</translation>
-<translation id="5850707923114094062">Geriye doğru kaydır</translation>
-<translation id="5851548754964597211">Sekme listesi</translation>
-<translation id="5859752971144398932">Sayfada bulma özelliğinden çıkıldı.</translation>
-<translation id="5866042630553435010">Kısmen işaretli</translation>
-<translation id="5869546221129391014">Tablo</translation>
-<translation id="5876817486144482042">Konuşma ses düzeyini düşür</translation>
-<translation id="5887397643266327462">Braille altyazıları etkinleştirildi.</translation>
-<translation id="5891934789323004067">Tablo</translation>
-<translation id="5919442531159595654">kopyala.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{eşit işareti}other{# eşit işareti}}</translation>
-<translation id="5939518447894949180">Sıfırla</translation>
-<translation id="5948123859135882163">Matematik ifadelerde yapısal ve anlamsal yorum arasında geçiş yap</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">İletişim Kutusu</translation>
-<translation id="5963413905009737549">Bölüm</translation>
-<translation id="5968607524793740041">İçerik menüsünü göster</translation>
-<translation id="5983179082906765664">Gezinme hassasiyetini artır</translation>
-<translation id="5999630716831179808">Sesler</translation>
-<translation id="6000417740266304866">Aşağıdaki listeden bir seçenek belirleyerek mevcut 8 noktalı braille'i değiştirin.</translation>
-<translation id="6006050241733874051">Form</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{ters eğik çizgi}other{# ters eğik çizgi}}</translation>
-<translation id="6037602951055904232">İleri kaydır</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Hücrenin sonu.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Boşluk</translation>
-<translation id="6142308968191113180">Başlık 4</translation>
-<translation id="6169420925157477918">Uzun açıklamalı resim</translation>
-<translation id="6172087735260766220">Kopyalamaya karşı korumalı PDF dosyasındaki erişilebilir metne erişilemiyor.</translation>
-<translation id="6186305613600865047">Sayfanın en alt kısmına atlar</translation>
-<translation id="6193330012414963395">ÖÖ ÖS</translation>
-<translation id="622484624075952240">Aşağı</translation>
-<translation id="6236061028292614533">Sonraki başlık</translation>
-<translation id="6254901459154107917">Düzenlenebilir sonraki metin alanı</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> kapsayıcısından çıkıldı.</translation>
-<translation id="6281876499889881039">Sonraki benzer öğe.</translation>
-<translation id="6282062888058716985">nav</translation>
-<translation id="6290434000785343030">Sonraki birleşik giriş kutusu yok.</translation>
-<translation id="6307969636681130414">Basıldı</translation>
-<translation id="6324551002951139333">Dil bilgisi hatası algılandı</translation>
-<translation id="6348657800373377022">Birleşik giriş kutusu</translation>
-<translation id="6355910664415701303">Önceki liste öğesi yok.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Önceki başlık</translation>
-<translation id="6387719785439924554">aside</translation>
-<translation id="6411426777058107714">Önceki radyo düğmesi yok.</translation>
-<translation id="6414968628640960377">Önceki farklı öğe.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{iki nokta}other{# iki nokta}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menü</translation>
-<translation id="6444046323172968959">Uyarı iletişim kutusu</translation>
-<translation id="6459511626086141404">Düz tuş eşleme</translation>
-<translation id="6468049171101508116">Sonraki düğmesi</translation>
-<translation id="6491972999578897419">Aşağıdaki listeden bir seçeneği belirleyerek mevcut sesi değiştirin.</translation>
-<translation id="6508059270146105198">Braille ekranını sayfanın altına taşı</translation>
-<translation id="6536864053412760904">Matematik ML Jetonu</translation>
-<translation id="6550720799683018100">Aşağıdaki listeden bir seçeneği belirleyerek mevcut tuş eşleşmesini değiştirin.</translation>
-<translation id="6561818612645211875">Mevcut satırın başına git</translation>
-<translation id="6587021927234520429">Sonraki 4. düzey başlık yok.</translation>
-<translation id="6601344353291556895">Ayrıntılı açıklamaları etkinleştir.</translation>
-<translation id="6615602925644411249">Sayfada bul.</translation>
-<translation id="6633350132811819843">Sonraki tablo yok.</translation>
-<translation id="6637586476836377253">log</translation>
-<translation id="6657128831881431364">İlerleme çubuğu</translation>
-<translation id="6659594942844771486">Sekme</translation>
-<translation id="667999046851023355">Doküman</translation>
-<translation id="6697092096875747123">Önceki birleşik kutu</translation>
-<translation id="6714813999819678458">Önceki 2. düzey başlık</translation>
-<translation id="6716505898850596801">Değiştirici tuşlar</translation>
-<translation id="671916444866103745">Sonraki ARIA önemli noktası yok.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, birleşik kutu</translation>
-<translation id="6735257939857578167"><ph name="NUM" /> öğeli</translation>
-<translation id="6736510033526053669">sekme oluşturuldu</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Makale</translation>
-<translation id="6787839852456839824">Klavye kısayolları</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Alt bilgi</translation>
-<translation id="6871161210040114857">Büyük/küçük harf kullanımı yoksayılıyor.</translation>
-<translation id="6877435256196695200">Sonraki grafik yok.</translation>
-<translation id="6897341342232909480">Sola git</translation>
-<translation id="6901540140423170855">date</translation>
-<translation id="6910211073230771657">Silindi</translation>
-<translation id="6911965441508464308">Yukarıda hücre yok.</translation>
-<translation id="6919104639734799681">Tablo listesini göster</translation>
-<translation id="6964088412282673743">Önceki denetim yok.</translation>
-<translation id="6996566555547746822">Sonraki birleşik kutu</translation>
-<translation id="7005146664810010831">URL bulunamadı.</translation>
-<translation id="7010712454773919705">ChromeVox değiştirici tuş</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Önceki liste</translation>
-<translation id="7041173719775863268">Seçme sonu</translation>
-<translation id="7095834689119144465">Yalnızca sayısal düzenleme metni</translation>
-<translation id="7096001299300236431">Önceki medya tuşu</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">kelime yansıtma</translation>
-<translation id="713824876195128146">Sonraki blok alıntı</translation>
-<translation id="7161771961008409533">Pop-up düğme</translation>
-<translation id="7167657087543110">karakter yansıtma</translation>
-<translation id="7170733337935166589">Sürekli okuma sırasında ileriye doğru atla</translation>
-<translation id="7181697990050180700">Sık kullanılan komutlara ait kısayolları, karşılık gelen alanlara yazarak klavye kısayollarını özelleştirin.</translation>
-<translation id="7203150201908454328">Genişletilmiş</translation>
-<translation id="7210211103303402262">dakika</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">satır</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Başlık</translation>
-<translation id="7241683698754534149">Uzun açıklamayı yeni sekmede aç</translation>
-<translation id="7248671827512403053">Uygulama</translation>
-<translation id="725969808843520477">Sonraki radyo düğmesi</translation>
-<translation id="7269119382257320590">Noktalama işareti yok</translation>
-<translation id="7273174640290488576">Boş</translation>
-<translation id="7285387653379749618">Tablolar</translation>
-<translation id="7289186959554153431">Başlık 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Braille altyazıları devre dışı bırakıldı.</translation>
-<translation id="7318872822751139669">Odağı değiştirmek için fareyi kullan.</translation>
-<translation id="7322388933135261569">Şubat</translation>
-<translation id="7332592614823088566">Satır: <ph name="ROWINDEX" /> / <ph name="ROWTOTAL" />, Sütun: <ph name="COLINDEX" /> / <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">pop-up'ı var</translation>
-<translation id="7356165926712028380">8 noktalı braille'e geç</translation>
-<translation id="7362871137496673139">Önceki 2. düzey başlık yok.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{ve işareti}other{# ve işareti}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Tablodan çıkılıyor.</translation>
-<translation id="739763518212184081">Önceki Satır</translation>
-<translation id="7400575256015741911">Yazım hatası algılandı</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">satır başı</translation>
-<translation id="7434509671034404296">Geliştirici</translation>
-<translation id="7439060726180460871">Dizin</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">İletişim kutusuna girildi</translation>
-<translation id="7532613204005497612">Haziran</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, kaydırma çubuğu</translation>
-<translation id="7586163296341959563">yapıştır.</translation>
-<translation id="7596919493010894443">seçim temizlendi</translation>
-<translation id="7604026522577407655">Mevcut sütunun başlangıcına git</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Mevcut sayfanın URL'sini söyle</translation>
-<translation id="7609363189280667021">Braille altyazılarını aç/kapat</translation>
-<translation id="762020119231868829">Şu anda oynatılan tüm medya widget'larını duraklatır</translation>
-<translation id="7625690649919402823">Sonraki tablo</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), <ph name="GRADE" />. Derece</translation>
-<translation id="7641134354185483015">Önceki 3. düzey başlık yok.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, metin kutusu</translation>
-<translation id="7663318257180412551">Başlık 2</translation>
-<translation id="7674576868851035240">Sonraki bağlantı</translation>
-<translation id="7674768236845044097">mark</translation>
-<translation id="7684431668231950609">Metni düzenle, URL girişi</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Önceki radyo düğmesi</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, şifre metin kutusu</translation>
-<translation id="7805247615045262757">varsayılan gezinme</translation>
-<translation id="7805768142964895445">Durum</translation>
-<translation id="7810781339813764006">Sonraki Grup</translation>
-<translation id="7819187121850078213">pencere <ph name="TITLE" /> sekmesi</translation>
-<translation id="7828956995407538686">Ekim</translation>
-<translation id="7839679365527550018">Önceki Kelime</translation>
-<translation id="7851816175263618915">Bazı noktalama işaretleri</translation>
-<translation id="7870596830398826354">Matematik ML Ağacı</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">ChromeVox klasiği aç/kapat.</translation>
-<translation id="7895896691902835279">Bilinmeyen bağlantı</translation>
-<translation id="7927711904086083099">Seçili değil</translation>
-<translation id="7935627501098484003">Zaman kontrolü</translation>
-<translation id="7939428177581522200">seçime eklendi</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{kuyruklu a işareti}other{# kuyruklu a işareti}}</translation>
-<translation id="7965147473449754028">menü kapandı</translation>
-<translation id="7974390230414479278">Menü öğesi</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{ünlem işareti}other{# ünlem işareti}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{tırnak işareti}other{# tırnak işareti}}</translation>
-<translation id="8033827949643255796">seçildi</translation>
-<translation id="8035962149453661158">en çok:<ph name="X" /></translation>
-<translation id="8042761080832772327">Metni düzenle, arama girişi</translation>
-<translation id="8049189770492311300">Zamanlayıcı</translation>
-<translation id="8065607967589909823">Yapılan seçim:</translation>
-<translation id="8066678206530322333">Banner</translation>
-<translation id="8110647606445335195">ARIA önemli noktası yok.</translation>
-<translation id="8153880621934657047">Tablonun içinde değil.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{alt çizgi}other{# alt çizgi}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">kesildi.</translation>
-<translation id="8199231515320852133">Mevcut hücrenin üst bilgilerini söyle</translation>
-<translation id="820417203470636242">Boş hücre.</translation>
-<translation id="8215202828671303819">Çoklu seçim</translation>
-<translation id="8276439074553447000">Odaklanabilir önceki öğeye atla</translation>
-<translation id="8278417001922463147">Önceki makale yok.</translation>
-<translation id="8283603667300770666">Sonraki form alanı</translation>
-<translation id="831207808878314375">Tanım</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">saat</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{pound işareti}other{# pound işareti}}</translation>
-<translation id="8374154622594089836">month</translation>
-<translation id="8378855320830505539">Bölge</translation>
-<translation id="8382679411218029383">Satır içi ve liste otomatik tamamlama</translation>
-<translation id="8428603554127842284">seviye: <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Sonraki 3. düzey başlık yok.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Önceki onay kutusu yok.</translation>
-<translation id="8455868257606149352">En çok: <ph name="X" /></translation>
-<translation id="84575901236241018">erişim tuşu var, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Gezinme hassasiyetini azalt</translation>
-<translation id="8520472399088452386">Dönme düğmesi</translation>
-<translation id="8538744478902126321">Mevcut hücrenin satır üst bilgisini tahmin et</translation>
-<translation id="8540054775867439484">Üste döner</translation>
-<translation id="8548973727659841685">Karakter</translation>
-<translation id="8561322612995434619">pop-up'ı var</translation>
-<translation id="8571096049907249734">çoklsçm</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Sonraki liste öğesi</translation>
-<translation id="860150890330522909"><ph name="NAME" /> onay kutusu işaretli</translation>
-<translation id="8606621670302093223">Tarih denetimi</translation>
-<translation id="8631359288236106450"><ph name="COUNT" /> öğe seçildi</translation>
-<translation id="8638532244051952400">Geçerli hücre koordinatlarını söyle</translation>
-<translation id="8650576015643545550">Önceki liste yok.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Bağlantı listesini göster</translation>
-<translation id="8664519043722036194">saniye</translation>
-<translation id="867187640362843212">Başlık 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{dikey çizgi işareti}other{# dikey çizgi işareti}}</translation>
-<translation id="8735450637152821465">Seçme başlangıcı</translation>
-<translation id="8743786158317878347">tablo gibi yapısal içeriğe gir</translation>
-<translation id="8747966237988593539">Sıralı Liste</translation>
-<translation id="8759334257841767240">Sonraki bağlantı yok.</translation>
-<translation id="8767968232364267681">Sonraki 2. düzey başlık</translation>
-<translation id="8770473310765924354">tablo gibi yapısal içerikten çık</translation>
-<translation id="8791025954632646584">Anlamsal yorum açık</translation>
-<translation id="8796411681063377102">Sonraki 3. düzey başlık</translation>
-<translation id="8808582214901541005">Mart</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">main</translation>
-<translation id="8856538297388979332">Komutları görmek için yukarı veya aşağı tuşlarına, etkinleştirmek için enter tuşuna basın</translation>
-<translation id="8864099967139188018">Sonraki 6. düzey başlık yok.</translation>
-<translation id="8882002077197914455">Satır üst bilgisi</translation>
-<translation id="8896347895970027998">ChromeVox'u etkinleştirin veya devre dışı bırakın.</translation>
-<translation id="8898516272131543774">Noktalama yansıtmayı döngüsel yap</translation>
-<translation id="8900148057318340779">Ön ek tuşu</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Boş üst bilgiler</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Değiştirici Tuşlar</translation>
-<translation id="8943175951035496220">Sağda hücre yok.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">file</translation>
-<translation id="9027462562263121875">Tablo yok.</translation>
-<translation id="9040132695316389094">Başlık 1</translation>
-<translation id="9043969572162476692">%<ph name="NUM" /></translation>
-<translation id="9061915073547935367">Arama widget'ını değiştir</translation>
-<translation id="9065283790526219006">+popup</translation>
-<translation id="9077213568694924680">seçimden kaldırıldı</translation>
-<translation id="9082874451376019682">Önceki kaydırma çubuğu yok.</translation>
-<translation id="9089864840575085222">Yazma yansıtmayı döngüsel yap</translation>
-<translation id="9107530006868467849">Önceki media widget'ı yok.</translation>
-<translation id="9108370397979208512">math</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{yüzde işareti}other{# yüzde işareti}}</translation>
-<translation id="9115913704608474258">Kasım</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Mevcut konumun kısa açıklamasını söyler</translation>
-<translation id="9153606228985488238">Ses kalınlığı yüzde <ph name="PERCENT" /></translation>
-<translation id="9160096769946561184">Mevcut sütunun sonuna git</translation>
-<translation id="9173115498289768110">Ses düzeyi yüzde <ph name="PERCENT" /></translation>
-<translation id="9178973770513562274">Göz atmak için yukarı veya aşağı tuşlarını kullanın ya da arama yapmak için aranan metni yazın.</translation>
-<translation id="9192904702577636854">Marquee</translation>
-<translation id="9212322457209634662">Sonraki bölüm yok.</translation>
-<translation id="930275611743429116">Seçimi başlat veya bitir.</translation>
-<translation id="948171205378458592">Konuşma hızını düşür</translation>
-<translation id="962913030769097253">Sonraki 1. düzey başlık</translation>
-<translation id="973955474346881951">Yapışkan modu etkinleştir/devre dışı bırak</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_uk.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_uk.xtb
deleted file mode 100644
index e82d1543f28..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_uk.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="uk">
-<translation id="1012173283529841972">Пункт списку</translation>
-<translation id="1013742170491673792">пошук</translation>
-<translation id="1023866615269196768">Розтягнута.</translation>
-<translation id="1025074108959230262">Закріплений режим вимкнено</translation>
-<translation id="1031961866430398710">тоді</translation>
-<translation id="1044777062731150180">Немає заголовків</translation>
-<translation id="106222400312645156">заголовок рядка</translation>
-<translation id="1065552602950927991">Неправильно введені дані</translation>
-<translation id="1082209053475788238">Немає попереднього заголовка рівня 6.</translation>
-<translation id="1088219014394087294">Немає заголовків.</translation>
-<translation id="1106741348836243114">Увімкнути або вимкнути звуковий сигнал (звуковий ефект).</translation>
-<translation id="1120743664840974483">{"а": "а-зОт", "б": "бОн-да-рів-на", "в": "віт-ро-гон", "г": "га-ра-кі-рі", "ґ": "ґо-ґо-дзи", "д": "до-ли-на", "е": "ерг", "є": "єд-ність-то-си-ла", "ж": "жа-б'є-се-ло", "з": "зо-ло-ту-ха", "и": "то-не-во-но", "і": "І-ван", "ї": "їж-хто-го-ло-ден", "й": "йди-хо-лод-ком", "к": "ко-лі-но", "л": "лі-со-ру-би", "м": "мо-роз", "н": "но-га", "о": "о-ко-лот", "п": "при-мо-роз-ки", "р": "ри-бонь-ка", "с": "са-ха-ра", "т": "тон", "у": "у-па-док", "ф": "фі-лан-тро-пи", "х": "хо-ло-до-чок", "ц": "цьо-ця-дор-ця", "ч": "чор-но-го-ра", "ш": "шо-ло-ви-ло", "щ": "що-ро-ку-мо-роз", "ь": "то-м'я-кий-тон" "ю": "ю-рій-ко-роль", "я": "я-ро-шен-ко"}</translation>
-<translation id="113582498867142724">Збірка <ph name="TAG" /> з такою кількістю елементів: <ph name="NUM" /></translation>
-<translation id="1155043339247954670">Немає наступного пункту списку.</translation>
-<translation id="1157782847298808853">Довідка клавіатури</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, комбіноване вікно</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, пункт меню з підменю</translation>
-<translation id="1177863135347784049">Спеціальне</translation>
-<translation id="1188858454923323853">додатково</translation>
-<translation id="1206619573307042055">область виділення</translation>
-<translation id="1213216066620407844">ChromeVox – голосовий супровід Chrome</translation>
-<translation id="1229276918471378188">Попередній перехід</translation>
-<translation id="1237866625126425153">група перемикачів</translation>
-<translation id="1251750620252348585">Наступний заголовок рівня 6</translation>
-<translation id="1275718070701477396">Вибрано</translation>
-<translation id="1319608975892113573">Немає попереднього блоку цитати.</translation>
-<translation id="1321576897702511272">Сховати довідку ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> з <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">озвучення символів і слів</translation>
-<translation id="1339428534620983148">Попередній стовпець таблиці</translation>
-<translation id="1342835525016946179">стаття</translation>
-<translation id="1346748346194534595">Праворуч</translation>
-<translation id="136718599399906424">Наступний рядок таблиці</translation>
-<translation id="1383876407941801731">Пошук</translation>
-<translation id="1385214448885562192">Натисніть клавішу Enter, щоб прийняти, клавішу Escape, щоб скасувати, стрілку вниз, щоб перейти далі, стрілку вгору, щоб перейти назад.</translation>
-<translation id="1396114365388024581">список вкладок</translation>
-<translation id="1439316808600711881">регіон</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, текстове поле пароля</translation>
-<translation id="1467432559032391204">Ліворуч</translation>
-<translation id="1474557363159888097">Немає попередньої прив’язки.</translation>
-<translation id="1502086903961450562">Попереднє зображення</translation>
-<translation id="1506187449813838456">Збільшити висоту звуку</translation>
-<translation id="151784044608172266">Наступне речення</translation>
-<translation id="1524531499102321782">Наступний рядок шрифтом Брайля</translation>
-<translation id="1546370775711804143">Панель прокручування</translation>
-<translation id="1559739829547075274">Перейти назад</translation>
-<translation id="1571643229714746283">ChromeVox активовано</translation>
-<translation id="158493514907962286">грудень</translation>
-<translation id="1594072653727561613">меню</translation>
-<translation id="1610130962244179598">Перейти до 6-крапкового шрифту Брайля</translation>
-<translation id="1611168825862729585">Заголовок стовпця:</translation>
-<translation id="1613476421962910979">Звуковий ефект увімкнено</translation>
-<translation id="1618597272655350600">Повідомляє повний опис поточної позиції</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{знак "більше"}one{# знак "більше"}few{# знаки "більше"}many{# знаків "більше"}other{# greater than signs}}</translation>
-<translation id="1653266918374749391">Попередній заголовок рівня 3</translation>
-<translation id="1659072772017912254">Без прапорця</translation>
-<translation id="1669290819662866522">тиждень</translation>
-<translation id="1674262202423278359">Навігація в ChromeVox</translation>
-<translation id="16777221443363124">Панель меню</translation>
-<translation id="1692077714702418899">структурна лінія</translation>
-<translation id="1700517974991662022">Натиснуто</translation>
-<translation id="1722567105086139392">Посилання</translation>
-<translation id="1727806147743597030">нижній колонтитул</translation>
-<translation id="174268867904053074">Наступне зображення</translation>
-<translation id="1781173782405573156">Клавіша наскрізного проходу</translation>
-<translation id="1787176709638001873">Редагування тексту пароля</translation>
-<translation id="1810107444790159527">Вікно списку</translation>
-<translation id="1828385960365606039">травень</translation>
-<translation id="1834891354138622109">Стовпець</translation>
-<translation id="1865601187525349519">Кінець тексту</translation>
-<translation id="1876229593313240038">документ</translation>
-<translation id="188130072164734898">Диктувати поточну дату та час.</translation>
-<translation id="1902396333223336119">Клітинка</translation>
-<translation id="1905379170753160525">Показати список заголовків</translation>
-<translation id="1912556590115083156">натиснуте посилання</translation>
-<translation id="1913761808037590218">номер</translation>
-<translation id="1954623340234317532">Елемент керування для вибору тижня в році</translation>
-<translation id="1964135212174907577">Наступний об’єкт</translation>
-<translation id="1969092762068865084">липень</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Заголовок рядка:</translation>
-<translation id="2002895034995108595">Скинути поточну розкладку клавіатури</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{ліва квадратна дужка}one{# ліва квадратна дужка}few{# ліві квадратні дужки}many{# лівих квадратних дужок}other{# left brackets}}</translation>
-<translation id="2045490512405922022">без прапорця</translation>
-<translation id="20601713649439366">Немає попереднього математичного виразу.</translation>
-<translation id="207477615537953741">Семантичний аналіз вимкнено</translation>
-<translation id="2086961585857038472">Наступне слово</translation>
-<translation id="2089387485033699258">uk</translation>
-<translation id="2091933974477985526">Попередня область тексту для редагування</translation>
-<translation id="2100350898815792233">Усі розділові знаки</translation>
-<translation id="2119965627982867824">лічильник</translation>
-<translation id="2121067395472282800">клавіша доступу: <ph name="KEY" /></translation>
-<translation id="2155457205053847599">Змініть поточний 6-крапковий шрифт Брайля, вибравши опцію зі списку нижче.</translation>
-<translation id="2169714232367507776">Натиснути поточний елемент</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{права кругла дужка}one{# права кругла дужка}few{# праві круглі дужки}many{# правих круглих дужок}other{# close parens}}</translation>
-<translation id="2199994615414171367">Математичний – назад</translation>
-<translation id="2223693656926968778">Виконати дію з поточним елементом</translation>
-<translation id="225732394367814946">Збільшити темп мовлення</translation>
-<translation id="2267945578749931355">Наступний символ</translation>
-<translation id="2281234842553884450">Попередній повзунок</translation>
-<translation id="2318372665160196757">Головний</translation>
-<translation id="2329324941084714723">Панель вкладок</translation>
-<translation id="2344193891939537199">Елемент керування для вибору дати та часу</translation>
-<translation id="2359897517538099099">Не в режимі таблиці.</translation>
-<translation id="241124561063364910">а потім –</translation>
-<translation id="2417569100218200841">Інформація про вміст</translation>
-<translation id="2422937916923936891">Прапорець пункту меню</translation>
-<translation id="2429669115401274487">пп</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> – тепер нова клавіша-модифікатор ChromeVox.</translation>
-<translation id="2450814015951372393">Прапорець</translation>
-<translation id="2462626033734746142">Група перемикачів</translation>
-<translation id="2471138580042810658">Заголовок 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{зірочка}one{# зірочка}few{# зірочки}many{# зірочок}other{# asterisks}}</translation>
-<translation id="2549392850788122959">Налаштування клавіші <ph name="KEY" /> скинуто.</translation>
-<translation id="2553108862507765288">граматична помилка</translation>
-<translation id="257674075312929031">Група</translation>
-<translation id="2582407057977008361">Бічний колонтитул</translation>
-<translation id="2589102159832527089">Ця сторінка містить текст, автоматично отриманий із файлу &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; у форматі PDF. &lt;a href="<ph name="URL" />"&gt;Натисніть тут, щоб переглянути оригінал.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">з {COUNT,plural, =1{1 пунктом}one{# пунктом}few{# пунктами}many{# пунктами}other{# пункту}}</translation>
-<translation id="2614981083756825552">Розмітка Math ML</translation>
-<translation id="2626530649491650971">інтерактивний</translation>
-<translation id="2628764385451019380">Немає попереднього комбінованого вікна.</translation>
-<translation id="2637227747952042642">Матем.</translation>
-<translation id="2639750663247012216">Модифікатор ChromeVox</translation>
-<translation id="2644542693584024604">орфографічна помилка</translation>
-<translation id="2667291555398229137">Натиснути елемент під ключем маршрутизації</translation>
-<translation id="2697408785920771974">вбудоване автозавершення</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{ліва кругла дужка}one{# ліва кругла дужка}few{# ліві круглі дужки}many{# лівих круглих дужок}other{# open parens}}</translation>
-<translation id="2705875883745373140">Не натиснуто</translation>
-<translation id="2706462751667573066">Вгору</translation>
-<translation id="2717271541250958000">панель вкладок</translation>
-<translation id="2723001399770238859">аудіо</translation>
-<translation id="2732718972699418926">дп</translation>
-<translation id="2749275490991666823">З прапорцем</translation>
-<translation id="27527859628328957">Перейти до наступного інтерактивного елемента</translation>
-<translation id="2770781857296573485">Почати вивчення груп</translation>
-<translation id="2777845298774924149">Ви закрили</translation>
-<translation id="2800204403141299078">Інших несхожих елементів немає.</translation>
-<translation id="2800780099804980316">Немає попереднього заголовка рівня 1.</translation>
-<translation id="2811204574343810641">Рядок</translation>
-<translation id="2816654101880605877">Немає наступного повзунка.</translation>
-<translation id="2841013758207633010">Час</translation>
-<translation id="2843837985843789981">Попередня група</translation>
-<translation id="2844995807198708617">Контекстне меню</translation>
-<translation id="2849332794118375855">Немає наступного прапорця.</translation>
-<translation id="2864481629947106776">Попереднє посилання</translation>
-<translation id="2873259058405069099">Перейти на початок таблиці</translation>
-<translation id="2894654529758326923">Інформація</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{ліва фігурна дужка}one{# ліва фігурна дужка}few{# ліві фігурні дужки}many{# лівих фігурних дужок}other{# left braces}}</translation>
-<translation id="2911433807131383493">Відкрити навчальний посібник ChromeVox</translation>
-<translation id="2932083475399492303">Переключення між структурною лінією та лінією розмітки</translation>
-<translation id="2964026537669811554">Група заголовків</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{знак табуляції}one{# знак табуляції}few{# знаки табуляції}many{# знаків табуляції}other{# tabs}}</translation>
-<translation id="2972078295414139404">Немає попереднього натиснутого посилання.</translation>
-<translation id="2972205263822847197">Підказка</translation>
-<translation id="2998131015536248178">Попередній символ</translation>
-<translation id="2999559350546931576">Зменшити висоту звуку</translation>
-<translation id="2999945368667127852">Немає наступного медіа-віджета.</translation>
-<translation id="3012414509011670858">Немає попереднього розділу.</translation>
-<translation id="3030432017085518523">Перемикач пунктів меню</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{апостроф}one{# апостроф}few{# апострофи}many{# апострофів}other{# apostrophes}}</translation>
-<translation id="3046838483509668188">Параметри ChromeVox</translation>
-<translation id="3047143736589213134">Експериментальна розкладка клавіатури</translation>
-<translation id="3060756054951570867">меню <ph name="TITLE" /> відкрито</translation>
-<translation id="3078345202707391975">Наступний заголовок рівня 2</translation>
-<translation id="3078740164268491126">таблиця</translation>
-<translation id="3082557070674409251">Натиснуто</translation>
-<translation id="3084806535845658316">без озвучення введення тексту</translation>
-<translation id="3086746722712840547">примітка</translation>
-<translation id="308895241372589742">Немає наступного математичного виразу.</translation>
-<translation id="3090532668523289635">група</translation>
-<translation id="3093176084511590672">Наступний орієнтир</translation>
-<translation id="3096671415663099226">комбіноване вікно</translation>
-<translation id="3104705064753753826">вікно сповіщення</translation>
-<translation id="3109724472072898302">Згорнуто</translation>
-<translation id="3134461040845705080">лише читання</translation>
-<translation id="3138767756593758860">Показати список орієнтирів</translation>
-<translation id="3143851963874289911">клітинка</translation>
-<translation id="3149472044574196936">Наступний рядок</translation>
-<translation id="3155083529632865074">Немає попередньої кнопки.</translation>
-<translation id="3163593631834463955">Порожній заголовок стовпця</translation>
-<translation id="316542773973815724">Навігація</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{пробіл}one{# пробіл}few{# пробіли}many{# пробілів}other{# spaces}}</translation>
-<translation id="320961988183078793">введено: <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, вкладка</translation>
-<translation id="3226035351387556942">прапорець</translation>
-<translation id="3229375994964697375">Натиснуте посилання</translation>
-<translation id="323731244387692321">Відкрити довідку клавіатури ChromeVox</translation>
-<translation id="3241052487511142956">Попереднє натиснуте посилання</translation>
-<translation id="3286390186030710347">Повзунок</translation>
-<translation id="3299925995433437805">Немає наступного натиснутого посилання.</translation>
-<translation id="3303384412438961941">Натисніть будь-яку клавішу, щоб дізнатися її назву. Ctrl+W закриє огляд клавіатури.</translation>
-<translation id="3307886118343381874">Перейти в кінець таблиці</translation>
-<translation id="3311969765485641742">Натисніть Alt+Shift+A, щоб переглянути попередження</translation>
-<translation id="3312997241656799641">Наступне натиснуте посилання</translation>
-<translation id="3321460131042519426">Увімкнути перенесення слів</translation>
-<translation id="3322936298410871309">Попередній заголовок рівня 1</translation>
-<translation id="3323447499041942178">Текстове поле</translation>
-<translation id="3353420241558113817">{"ar": "арабська",
- "bg": "болгарська",
- "ca": "каталонська",
- "cs": "чеська",
- "da": "данська",
- "de": "німецька",
- "de_CH": "німецька (Швейцарія)",
- "de_DE": "німецька (Німеччина)",
- "el": "грецька",
- "en": "англійська",
- "en_CA": "англійська (Канада)",
- "en_GB": "англійська (Велика Британія)",
- "en_US": "англійська (США)",
- "es": "іспанська",
- "et": "естонська",
- "fr": "французька",
- "fr_CA": "французька (Канада)",
- "fr_FR": "французька (Франція)",
- "fi": "фінська",
- "he": "іврит",
- "hi": "гінді",
- "hr": "хорватська",
- "hu": "угорська",
- "is": "ісландська",
- "it": "італійська",
- "ko": "корейська",
- "lt": "литовська",
- "lv": "латвійська",
- "nb": "норвезька букмол",
- "nl": "нідерландська",
- "pl": "польська",
- "pt": "португальська",
- "ro": "румунська",
- "ru": "російська",
- "sk": "словацька",
- "sl": "словенська",
- "sr": "сербська",
- "sv": "шведська",
- "tr": "турецька",
- "vi": "в’єтнамська",
- "zh": "китайська",
- "zh_TW": "китайська (традиційна хань)"}</translation>
-<translation id="3359142382821736686">розділювач</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{плюс}one{# знак плюс}few{# знаки плюс}many{# знаків плюс}other{# plus signs}}</translation>
-<translation id="338583716107319301">Розділювач</translation>
-<translation id="3389259863310851658">Попереднє поле форми</translation>
-<translation id="3390225400784126843">Наступний несхожий елемент.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, пункт меню</translation>
-<translation id="3406283310380167331">Показати список форм</translation>
-<translation id="3422338090358345848">Відкрити огляд клавіатури</translation>
-<translation id="3457000393508828486">Частково натиснуто</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, кнопка</translation>
-<translation id="3473644018603298796">виділено: <ph name="COUNT" /></translation>
-<translation id="3486232535569802404">Від <ph name="V1" /> до <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{права квадратна дужка}one{# права квадратна дужка}few{# праві квадратні дужки}many{# правих квадратних дужок}other{# right brackets}}</translation>
-<translation id="3493915602752813531">Немає наступної прив’язки.</translation>
-<translation id="3494946239022273294">пункт меню</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{знак запитання}one{# знак запитання}few{# знаки запитання}many{# знаків запитання}other{# question marks}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{знак вставки}one{# знак вставки}few{# знаки вставки}many{# знаків вставки}other{# carets}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, прапорець не поставлено</translation>
-<translation id="3599054940393788245">Не для математичних виразів</translation>
-<translation id="3616113530831147358">Звук</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{зворотний апостроф}one{# зворотний апостроф}few{# зворотні апострофи}many{# зворотних апострофів}other{# backticks}}</translation>
-<translation id="3650317109285159359">прапорець пункту меню</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{долар}one{# символ долара}few{# символи долара}many{# символів долара}other{# dollar signs}}</translation>
-<translation id="3659787053479271466">сповіщення</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, вікно списку</translation>
-<translation id="3687295507293856493">Зробити припущення щодо заголовка стовпця поточної клітинки</translation>
-<translation id="3692274950075847560">П:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Керування мовленням</translation>
-<translation id="3716845769494773620">Багаторядковий</translation>
-<translation id="3731746171184829332">Немає попереднього заголовка.</translation>
-<translation id="3762198587642264450">Перейти в кінець поточного рядка</translation>
-<translation id="3777255250339039212">заголовок 1</translation>
-<translation id="3793710123303304873">Ви закрили діалогове вікно.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}one{#}few{#}many{#}other{#}}</translation>
-<translation id="3801735343383419236">Список автозавершення</translation>
-<translation id="3810838688059735925">Відео</translation>
-<translation id="3816633764618089385">Медіа – далі</translation>
-<translation id="3819376190738087562">Немає переходів.</translation>
-<translation id="385383972552776628">Відкрити сторінку параметрів</translation>
-<translation id="3856075812838139784">Лише читання</translation>
-<translation id="3887576927692165210">текстове поле</translation>
-<translation id="3897092660631435901">Меню</translation>
-<translation id="3909320334364316587">Попередній заголовок рівня 6</translation>
-<translation id="3914173277599553213">Обов’язково</translation>
-<translation id="3962990492275676168">Почати читати з поточного місця</translation>
-<translation id="4004802134384979325">з прапорцем</translation>
-<translation id="4006140876663370126">зображення</translation>
-<translation id="4038349100599457191">Елемент керування для вибору місяця</translation>
-<translation id="4039983576244166038">Порожній заголовок рядка</translation>
-<translation id="4042843249978639960">Немає наступного заголовка рівня 2.</translation>
-<translation id="4043348641337972076">Немає попереднього орієнтира ARIA.</translation>
-<translation id="4047216625641135770">Виділений текст</translation>
-<translation id="404803211695627272"><ph name="V1" /> – <ph name="V2" /></translation>
-<translation id="4054936709456751127">стан</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{ТИЛЬДА}one{# тильда}few{# тильди}many{# тильд}other{# tildes}}</translation>
-<translation id="409334809956508737">Попередній об’єкт</translation>
-<translation id="4099274309791143834">містить вкладене меню</translation>
-<translation id="4107807507418787238">Немає клітинки нижче.</translation>
-<translation id="4116415223832267137">Сповіщення</translation>
-<translation id="4147126331795725888">Немає наступного елемента керування.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{права фігурна дужка}one{# права фігурна дужка}few{# праві фігурні дужки}many{# правих фігурних дужок}other{# right braces}}</translation>
-<translation id="4158704014418536539">Ураховується регістр.</translation>
-<translation id="4161663686871496107">Голосові підказки ChromeVox активовано</translation>
-<translation id="4173994908659439270">Немає наступного текстового поля для редагування.</translation>
-<translation id="4176463684765177261">Вимкнено</translation>
-<translation id="4188530942454211480">Попереднє речення</translation>
-<translation id="4202186506458631436">Перемістити праворуч</translation>
-<translation id="4206289001967551965">Усередині таблиці</translation>
-<translation id="4215733775853809057">Наступний повзунок</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{тире}one{# тире}few{# тире}many{# тире}other{# dashes}}</translation>
-<translation id="421884353938374759">вибір кольору</translation>
-<translation id="4229646983878045487">дата й час</translation>
-<translation id="423334822609210999">Немає клітинки ліворуч.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, ступінь <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Примітка</translation>
-<translation id="4254798249533888099">Дерево</translation>
-<translation id="4255943572433203166">Щоб налаштувати ChromeVox, використовуйте параметри нижче. Зміни почнуть діяти негайно.</translation>
-<translation id="4271220233568730077">Математичний – далі</translation>
-<translation id="4271521365602459209">Більше результатів немає.</translation>
-<translation id="4287520460805643128">Немає наступної статті.</translation>
-<translation id="4289540628985791613">Огляд</translation>
-<translation id="4300318234632215983">Повідомити URL-адресу посилання</translation>
-<translation id="4301352596632316575">має вкладене меню</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{крапка}=3{трикрапка}one{# крапка}few{# крапки}many{# крапок}other{# dots}}</translation>
-<translation id="4347461890115250064">Немає наступного списку.</translation>
-<translation id="4367650418938037324">Кінцевий об’єкт Math ML</translation>
-<translation id="4372435075475052704">мін.: <ph name="X" /></translation>
-<translation id="4372705107434148843">Припинити мовлення</translation>
-<translation id="4373197658375206385">Немає попереднього елемента, який не є посиланням.</translation>
-<translation id="4391478986194775161">інформація про вміст</translation>
-<translation id="443163561286008705">скинути</translation>
-<translation id="4471074325120394300">Немає посилань.</translation>
-<translation id="4476183483923481720">новий рядок</translation>
-<translation id="4482330759234983253">Попередня таблиця</translation>
-<translation id="4491109536499578614">Зображення</translation>
-<translation id="4529987814483543472">Класична розкладка клавіатури</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{коса риска}one{# коса риска}few{# косі риски}many{# косих рисок}other{# slashes}}</translation>
-<translation id="4547556996012970016">Наступний заголовок рівня 5</translation>
-<translation id="4562381607973973258">Заголовок</translation>
-<translation id="4591507479202817876">, вибрано</translation>
-<translation id="4597532268155981612">форма</translation>
-<translation id="4597896406374528575">квітень</translation>
-<translation id="4615592953348396470">Натискання наступної клавіші ігнорується</translation>
-<translation id="461613135510474570">Речення</translation>
-<translation id="4647836961514597010">Вибір кольору</translation>
-<translation id="4661075872484491155">дерево</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">сітка</translation>
-<translation id="4693675773662933727">Попередній орієнтир</translation>
-<translation id="4696413482802371445">Немає наступного заголовка рівня 5.</translation>
-<translation id="4729095194763193578">Попередній рядок таблиці</translation>
-<translation id="4736221692378411923">серпень</translation>
-<translation id="4740661827607246557">Команди довідки</translation>
-<translation id="4759716709594980008">Огляд клавіатури ОС Chrome</translation>
-<translation id="4763296182459741068">Перенесення вниз</translation>
-<translation id="4763480195061959176">відео</translation>
-<translation id="479989351350248267">пошук</translation>
-<translation id="481165870889056555">Повідомити назву поточної сторінки</translation>
-<translation id="4826415162591436065">Перейти вперед</translation>
-<translation id="4826604887384865800">Наступний перехід</translation>
-<translation id="4827410568042294688">виділення скасовано</translation>
-<translation id="4842108708071771135">Немає наступного блоку цитати.</translation>
-<translation id="4848993367330139335">таймер</translation>
-<translation id="4850023505158945298">Попередній схожий елемент.</translation>
-<translation id="4866956062845190338">перемикач пунктів меню</translation>
-<translation id="4867316986324544967">Увімкнути реєстрацію TTS</translation>
-<translation id="4877261390094455813">Введіть пошуковий запит.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Внутрішнє посилання</translation>
-<translation id="4953585991029886728">Редагування тексту</translation>
-<translation id="4954534434583049121">Цитування попереднього блока</translation>
-<translation id="4973717656530883744">Мін. <ph name="X" /></translation>
-<translation id="4973762002207131920">Змінено на <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">мілісекунд</translation>
-<translation id="49787999531187221">Розширення ChromeVox зараз неактивне.</translation>
-<translation id="4979404613699303341">Попередня кнопка</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, вікно списку</translation>
-<translation id="4983588134362688868">Перейти вгору сторінки</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, вікно</translation>
-<translation id="4993152509206108683">Швидкість мовлення у відсотках: <ph name="PERCENT" /></translation>
-<translation id="4996716799442435517">Візуальна</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, перемикач вибрано</translation>
-<translation id="4997475792277222884">Немає наступного елемента, який не є посиланням.</translation>
-<translation id="5000760171916499057">Немає форм.</translation>
-<translation id="5005670136041063723">Немає інших схожих елементів.</translation>
-<translation id="501473567976723023">січень</translation>
-<translation id="5041394372352067729">Перемістити брайлівський дисплей угору сторінки</translation>
-<translation id="5042770794184672516">Збільшити гучність мовлення</translation>
-<translation id="5050015258024679800">Попередній заголовок рівня 4</translation>
-<translation id="5054047268577924192">Попередній пункт списку</translation>
-<translation id="5078661581131202757">Вибір файлу</translation>
-<translation id="5080758118274074384">двічі натиснуто</translation>
-<translation id="5098541983634824365">Вихід із сітки.</translation>
-<translation id="5102981729317424850">Панель інструментів</translation>
-<translation id="5105050547967751155">обов’язково</translation>
-<translation id="5110983769041734144">Немає попереднього поля форми.</translation>
-<translation id="5111640677200759579">Заголовок стовпця</translation>
-<translation id="5117636609870536415">електронна адреса</translation>
-<translation id="5136967254288895616">Немає попереднього посилання.</translation>
-<translation id="513774504516943387">посилання</translation>
-<translation id="517143700877085897">, не вибрано</translation>
-<translation id="5183440668879371625">Попередній рядок шрифтом Брайля</translation>
-<translation id="5184944171021383281">Немає наступного поля форми.</translation>
-<translation id="5189244881767082992">Рядок</translation>
-<translation id="5203930734796605961">За клавішею <ph name="KEY" /> вже закріплено команду.</translation>
-<translation id="5205493599117157272">Список <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Немає наступного перемикача.</translation>
-<translation id="5263344797180442561">заголовок 2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Об’єкт</translation>
-<translation id="5304943142864553931">вкладка <ph name="TITLE" /></translation>
-<translation id="5310788376443009632">видалено:</translation>
-<translation id="5320727453979144100">Закріплений режим увімкнено</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{кома}one{# кома}few{# коми}many{# ком}other{# commas}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, текстове поле</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, посилання</translation>
-<translation id="5336381510091010269">вбудоване автозавершення та список</translation>
-<translation id="536031132345979795">Перехід назад під час безперервного читання</translation>
-<translation id="5368000168321181111">Звуковий ефект вимкнено</translation>
-<translation id="5374320867641260420">Немає наступної кнопки.</translation>
-<translation id="5382299583965267720">Немає наступного заголовка рівня 1.</translation>
-<translation id="5402367795255837559">Команди Брайля</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{крапка з комою}one{# крапка з комою}few{# крапки з комою}many{# крапок із комою}other{# semicolons}}</translation>
-<translation id="5411891038905756502">Немає попередньої точки переходу.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{знак "менше"}one{# знак "менше"}few{# знаки "менше"}many{# знаків "менше"}other{# less than signs}}</translation>
-<translation id="5455441614648621694">Додатково</translation>
-<translation id="5485036206801896268">Немає попереднього зображення.</translation>
-<translation id="5486947920110100234">Немає наступної точки переходу.</translation>
-<translation id="549602578321198708">Слово</translation>
-<translation id="5500932716852106146">Немає попереднього текстового поля для редагування.</translation>
-<translation id="5502713021410870035">вересень</translation>
-<translation id="5507663321906818013">Налагодити орієнтир</translation>
-<translation id="5518443085409638729">Розміщувати курсор між символами під час редагування тексту (як в ОС Mac X).</translation>
-<translation id="552195134157544755">Перемикач</translation>
-<translation id="5534303576632885660">заголовок</translation>
-<translation id="5546092960038624944">Немає попереднього заголовка рівня 5.</translation>
-<translation id="556042886152191864">Кнопка</translation>
-<translation id="5561345396546889625">Наступний список</translation>
-<translation id="5562645715554321347">група заголовків</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Редагування введеного тексту, електронної адреси</translation>
-<translation id="5597170376237141345">Наступний прапорець</translation>
-<translation id="5597933780944041114">Немає наступного заголовка.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, перемикач не вибрано</translation>
-<translation id="5601172225407283979">Виконати дію за умовчанням</translation>
-<translation id="5608798115546226984">Вбудоване автозавершення</translation>
-<translation id="561939826962581046">час</translation>
-<translation id="5623778242535476823">перемикач</translation>
-<translation id="5623842676595125836">Журнал</translation>
-<translation id="5628125749885014029">заголовок 4</translation>
-<translation id="5637871198229500030">Немає попередньої таблиці.</translation>
-<translation id="5655682562155942719">Команди переходу</translation>
-<translation id="56637627897541303">Область тексту</translation>
-<translation id="5678161956734658133">область тексту</translation>
-<translation id="5681643281275621376">визначення</translation>
-<translation id="5682113568322255809">Орієнтир</translation>
-<translation id="5683155931978483559">Попередній прапорець</translation>
-<translation id="5684277895745049190">Список</translation>
-<translation id="5700650669149824506">Немає попереднього заголовка рівня 4.</translation>
-<translation id="5709192780268610569">Немає докладного опису</translation>
-<translation id="5712244464475377681">кнопка підказки</translation>
-<translation id="5712338278108304766">Наступний стовпець таблиці</translation>
-<translation id="571866080859340309">Вивчення груп</translation>
-<translation id="5728409797179002635">Не знайдено жодної таблиці.</translation>
-<translation id="5748623122140342504">Попередній заголовок рівня 5</translation>
-<translation id="5750633686117194034">Ви не натиснули жодну клавішу-модифікатор. Натисніть і утримуйте одну чи декілька клавіш-модифікаторів. Коли закінчите, відпустіть – ви почуєте, які клавіші налаштовано. Натисніть Tab, щоб вийти.</translation>
-<translation id="5788275253279308023">анонімне вікно вкладки <ph name="TITLE" /></translation>
-<translation id="5806206155699461681">Покращувати певні сайти (як-от Пошук Google).</translation>
-<translation id="5819072574982403430">Елемент дерева</translation>
-<translation id="5826479389509458994">ряд <ph name="ROW" /> стовпець <ph name="COL" /></translation>
-<translation id="5850707923114094062">На передній план</translation>
-<translation id="5851548754964597211">Список вкладок</translation>
-<translation id="5859752971144398932">Ви закрили пошук на сторінці.</translation>
-<translation id="5866042630553435010">Частково з прапорцем</translation>
-<translation id="5869546221129391014">Сітка</translation>
-<translation id="5876817486144482042">Зменшити гучність мовлення</translation>
-<translation id="5887397643266327462">Брайлівські субтитри ввімкнено.</translation>
-<translation id="5891934789323004067">Таблиця</translation>
-<translation id="5919442531159595654">копіювати.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{знак рівності}one{# знак рівності}few{# знаки рівності}many{# знаків рівності}other{# equal signs}}</translation>
-<translation id="5939518447894949180">Скинути</translation>
-<translation id="5948123859135882163">Переключення між структурним і семантичним аналізом математичних виразів</translation>
-<translation id="5955304353782037793">додаток</translation>
-<translation id="5956928062748260866">Діалогове вікно</translation>
-<translation id="5963413905009737549">Розділ</translation>
-<translation id="5968607524793740041">Показати контекстне меню</translation>
-<translation id="5983179082906765664">Збільшити деталізацію навігації</translation>
-<translation id="5999630716831179808">Голоси</translation>
-<translation id="6000417740266304866">Змініть поточний 8-крапковий шрифт Брайля, вибравши опцію зі списку нижче.</translation>
-<translation id="6006050241733874051">Форма</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{зворотна коса риска}one{# зворотна коса риска}few{# зворотні косі риски}many{# зворотних косих рисок}other{# backslashes}}</translation>
-<translation id="6037602951055904232">На задній план</translation>
-<translation id="611827076493383239">натиснуто</translation>
-<translation id="6119955456199054975">Кінець клітинки.</translation>
-<translation id="6122013438240733403">кнопка</translation>
-<translation id="6129953537138746214">Пробіл</translation>
-<translation id="6142308968191113180">Заголовок 4</translation>
-<translation id="6169420925157477918">Зображення з докладним описом</translation>
-<translation id="6172087735260766220">Не вдалося показати текст із файлу PDF, який захищено від копіювання.</translation>
-<translation id="6186305613600865047">Перейти вниз сторінки</translation>
-<translation id="6193330012414963395">дп пп</translation>
-<translation id="622484624075952240">Донизу</translation>
-<translation id="6236061028292614533">Наступний заголовок</translation>
-<translation id="6254901459154107917">Наступна область тексту для редагування</translation>
-<translation id="6259464875943891919"><ph name="TYPE" /> закрито.</translation>
-<translation id="6281876499889881039">Наступний схожий елемент.</translation>
-<translation id="6282062888058716985">навігація</translation>
-<translation id="6290434000785343030">Немає наступного комбінованого вікна.</translation>
-<translation id="6307969636681130414">Натиснуто</translation>
-<translation id="6324551002951139333">Виявлено граматичну помилку</translation>
-<translation id="6348657800373377022">Комбіноване вікно</translation>
-<translation id="6355910664415701303">Немає попереднього пункту списку.</translation>
-<translation id="6364795331201459219">заголовок 6</translation>
-<translation id="6368143427468974988">Попередній заголовок</translation>
-<translation id="6387719785439924554">бічний колонтитул</translation>
-<translation id="6411426777058107714">Немає попереднього перемикача.</translation>
-<translation id="6414968628640960377">Попередній несхожий елемент.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{двокрапка}one{# двокрапка}few{# двокрапки}many{# двокрапок}other{# colons}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, меню</translation>
-<translation id="6444046323172968959">Діалогове вікно сповіщень</translation>
-<translation id="6459511626086141404">Звичайна розкладка</translation>
-<translation id="6468049171101508116">Наступна кнопка</translation>
-<translation id="6491972999578897419">Змініть поточний голос, вибравши один із варіантів зі списку нижче.</translation>
-<translation id="6508059270146105198">Перемістити брайлівський дисплей униз сторінки</translation>
-<translation id="6536864053412760904">Маркер Math ML</translation>
-<translation id="6550720799683018100">Змініть поточну розкладку клавіатури, вибравши один із варіантів зі списку нижче.</translation>
-<translation id="6561818612645211875">Перейти на початок поточного рядка</translation>
-<translation id="6587021927234520429">Немає наступного заголовка рівня 4.</translation>
-<translation id="6601344353291556895">Увімкнути докладні описи.</translation>
-<translation id="6615602925644411249">Знайти на сторінці.</translation>
-<translation id="6633350132811819843">Немає наступної таблиці.</translation>
-<translation id="6637586476836377253">журнал</translation>
-<translation id="6657128831881431364">Індикатор перебігу</translation>
-<translation id="6659594942844771486">Вкладка</translation>
-<translation id="667999046851023355">Документ</translation>
-<translation id="6697092096875747123">Попереднє комбіноване вікно</translation>
-<translation id="6714813999819678458">Попередній заголовок рівня 2</translation>
-<translation id="6716505898850596801">Клавіші-модифікатори</translation>
-<translation id="671916444866103745">Немає наступного орієнтира ARIA.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, комбіноване вікно</translation>
-<translation id="6735257939857578167">зі стількох пунктів: <ph name="NUM" /></translation>
-<translation id="6736510033526053669">вкладку створено</translation>
-<translation id="675895815784134693">панель перебігу</translation>
-<translation id="6786800275320335305">Стаття</translation>
-<translation id="6787839852456839824">Комбінації клавіш</translation>
-<translation id="6793101435925451627">спадний список</translation>
-<translation id="6833103209700200188">Нижній колонтитул</translation>
-<translation id="6871161210040114857">Регістр не враховується.</translation>
-<translation id="6877435256196695200">Немає наступного зображення.</translation>
-<translation id="6897341342232909480">Перемістити ліворуч</translation>
-<translation id="6901540140423170855">дата</translation>
-<translation id="6910211073230771657">Видалено</translation>
-<translation id="6911965441508464308">Немає клітинки вище.</translation>
-<translation id="6919104639734799681">Показати список таблиць</translation>
-<translation id="6964088412282673743">Немає попереднього елемента керування.</translation>
-<translation id="6996566555547746822">Наступне комбіноване вікно</translation>
-<translation id="7005146664810010831">Не знайдено жодної URL-адреси</translation>
-<translation id="7010712454773919705">Клавіша-модифікатор ChromeVox</translation>
-<translation id="7031651751836475482">пункт списку</translation>
-<translation id="7037042857287298941">Попередній список</translation>
-<translation id="7041173719775863268">Кінець виділення</translation>
-<translation id="7095834689119144465">Редагування тексту лише для цифр</translation>
-<translation id="7096001299300236431">Медіа – назад</translation>
-<translation id="7116595520562830928">багаторядковий</translation>
-<translation id="712735679809149106">озвучення слів</translation>
-<translation id="713824876195128146">Цитування наступного блока</translation>
-<translation id="7161771961008409533">Кнопка зі спливаючою підказкою</translation>
-<translation id="7167657087543110">озвучення символів</translation>
-<translation id="7170733337935166589">Перехід уперед під час безперервного читання</translation>
-<translation id="7181697990050180700">Налаштуйте комбінації клавіш для часто використовуваних команд, ввівши їх у відповідні поля нижче.</translation>
-<translation id="7203150201908454328">Розгорнуто</translation>
-<translation id="7210211103303402262">хв</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">рядок</translation>
-<translation id="7226216518520804442">маркований список</translation>
-<translation id="72393384879519786">Заголовок</translation>
-<translation id="7241683698754534149">Відкрити докладний опис у новій вкладці</translation>
-<translation id="7248671827512403053">Додаток</translation>
-<translation id="725969808843520477">Наступний перемикач</translation>
-<translation id="7269119382257320590">Без розділових знаків</translation>
-<translation id="7273174640290488576">Порожньо</translation>
-<translation id="7285387653379749618">Таблиці</translation>
-<translation id="7289186959554153431">Заголовок 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">елемент дерева</translation>
-<translation id="731576946540457939">Брайлівські субтитри вимкнено.</translation>
-<translation id="7318872822751139669">Змінювати фокус за допомогою миші.</translation>
-<translation id="7322388933135261569">лютий</translation>
-<translation id="7332592614823088566">Рядок <ph name="ROWINDEX" /> з <ph name="ROWTOTAL" />, стовпець <ph name="COLINDEX" /> з <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">має спливаюче вікно</translation>
-<translation id="7356165926712028380">Перейти до 8-крапкового шрифту Брайля</translation>
-<translation id="7362871137496673139">Немає попереднього заголовка рівня 2.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{амперсанд}one{# амперсанд}few{# амперсанди}many{# амперсандів}other{# ampersands}}</translation>
-<translation id="737396357417333429">інтерактивний елемент</translation>
-<translation id="7374104575779636480">Вихід із таблиці.</translation>
-<translation id="739763518212184081">Попередній рядок</translation>
-<translation id="7400575256015741911">Виявлено орфографічну помилку</translation>
-<translation id="7408482676469142474">таблиця</translation>
-<translation id="7425395583360211003">повернутись</translation>
-<translation id="7434509671034404296">Для розробників</translation>
-<translation id="7439060726180460871">Каталог</translation>
-<translation id="744163271241493234">пароль</translation>
-<translation id="7491962110804786152">вкладка</translation>
-<translation id="7492049978501397201">Ви відкрили діалогове вікно</translation>
-<translation id="7532613204005497612">червень</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, повзунок</translation>
-<translation id="7586163296341959563">вставити.</translation>
-<translation id="7596919493010894443">виділення очищено</translation>
-<translation id="7604026522577407655">Перейти на початок поточного стовпця</translation>
-<translation id="7604451927827590395">заголовок</translation>
-<translation id="7609342235116740824">Повідомити URL-адресу поточної сторінки</translation>
-<translation id="7609363189280667021">Увімкнути або вимкнути брайлівські субтитри</translation>
-<translation id="762020119231868829">Призупиняє всі активні на цей момент медіа-віджети</translation>
-<translation id="7625690649919402823">Наступна таблиця</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), <ph name="GRADE" /> рівень</translation>
-<translation id="7641134354185483015">Немає попереднього заголовка рівня 3.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, текстове поле</translation>
-<translation id="7663318257180412551">Заголовок 2</translation>
-<translation id="7674576868851035240">Наступне посилання</translation>
-<translation id="7674768236845044097">виділений текст</translation>
-<translation id="7684431668231950609">Редагування введеного тексту, URL-адреси</translation>
-<translation id="7685589220304187312">панель інструментів</translation>
-<translation id="7693840228159394336">Попередній перемикач</translation>
-<translation id="7701196182766842984">список автозавершення</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, текстове поле пароля</translation>
-<translation id="7805247615045262757">навігація за умовчанням</translation>
-<translation id="7805768142964895445">Статус</translation>
-<translation id="7810781339813764006">Наступна група</translation>
-<translation id="7819187121850078213">вікно вкладки <ph name="TITLE" /></translation>
-<translation id="7828956995407538686">жовтень</translation>
-<translation id="7839679365527550018">Попереднє слово</translation>
-<translation id="7851816175263618915">Деякі розділові знаки</translation>
-<translation id="7870596830398826354">Дерево Math ML</translation>
-<translation id="78826985582142166">повзунок</translation>
-<translation id="7894517696028036636">Увімкнути або вимкнути ChromeVox Classic.</translation>
-<translation id="7895896691902835279">Невідоме посилання</translation>
-<translation id="7927711904086083099">Не вибрано</translation>
-<translation id="7935627501098484003">Налаштування часу</translation>
-<translation id="7939428177581522200">додано до виділеного</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{"равлик"}one{# символ "равлик"}few{# символи "равлик"}many{# символів "равлик"}other{# at signs}}</translation>
-<translation id="7965147473449754028">меню закрито</translation>
-<translation id="7974390230414479278">Пункт меню</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{знак оклику}one{# знак оклику}few{# знаки оклику}many{# знаків оклику}other{# exclamation points}}</translation>
-<translation id="8007540374018858731">заголовок 3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{лапка}one{# лапка}few{# лапки}many{# лапок}other{# quotes}}</translation>
-<translation id="8033827949643255796">виділено</translation>
-<translation id="8035962149453661158">макс.: <ph name="X" /></translation>
-<translation id="8042761080832772327">Редагування введеного тексту, пошукового запиту</translation>
-<translation id="8049189770492311300">Таймер</translation>
-<translation id="8065607967589909823">Вибрано</translation>
-<translation id="8066678206530322333">Банер</translation>
-<translation id="8110647606445335195">Немає орієнтирів ARIA.</translation>
-<translation id="8153880621934657047">Не всередині таблиці.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{підкреслення}one{# підкреслення}few{# підкреслення}many{# підкреслень}other{# underscores}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">вирізати.</translation>
-<translation id="8199231515320852133">Повідомити заголовки поточної клітинки</translation>
-<translation id="820417203470636242">Порожня клітинка.</translation>
-<translation id="8215202828671303819">Вибір кількох елементів</translation>
-<translation id="8276439074553447000">Перейти до попереднього інтерактивного елемента</translation>
-<translation id="8278417001922463147">Немає попередньої статті.</translation>
-<translation id="8283603667300770666">Наступне поле форми</translation>
-<translation id="831207808878314375">Визначення</translation>
-<translation id="8313653172105209786">каталог</translation>
-<translation id="8344569602005188545">години</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{фунт}one{# символ фунта}few{# символи фунта}many{# символів фунта}other{# pound signs}}</translation>
-<translation id="8374154622594089836">місяць</translation>
-<translation id="8378855320830505539">Регіон</translation>
-<translation id="8382679411218029383">Вбудоване автозавершення та список</translation>
-<translation id="8428603554127842284">рівень <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Немає наступного заголовка рівня 3.</translation>
-<translation id="8430049249787218991">панель меню</translation>
-<translation id="844681116543532394">Немає попереднього прапорця.</translation>
-<translation id="8455868257606149352">Макс. <ph name="X" /></translation>
-<translation id="84575901236241018">має клавішу доступу: <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Зменшити деталізацію навігації</translation>
-<translation id="8520472399088452386">Кнопка обертання</translation>
-<translation id="8538744478902126321">Зробити припущення щодо заголовка рядка поточної клітинки</translation>
-<translation id="8540054775867439484">Перенесення вгору</translation>
-<translation id="8548973727659841685">Символ</translation>
-<translation id="8561322612995434619">має спливаюче вікно</translation>
-<translation id="8571096049907249734">вибір кількох пунктів</translation>
-<translation id="8584721346566392021">заголовок 5</translation>
-<translation id="8587549812518406253">Наступний пункт списку</translation>
-<translation id="860150890330522909"><ph name="NAME" /> вибрано</translation>
-<translation id="8606621670302093223">Елемент керування для вибору дати</translation>
-<translation id="8631359288236106450">виділено пунктів: <ph name="COUNT" /></translation>
-<translation id="8638532244051952400">Повідомити координати поточної клітинки</translation>
-<translation id="8650576015643545550">Немає попереднього списку.</translation>
-<translation id="8653031188082306838">посилання</translation>
-<translation id="8653646212587894517">Показати список посилань</translation>
-<translation id="8664519043722036194">секунд</translation>
-<translation id="867187640362843212">Заголовок 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{вертикальна риска}one{# вертикальна риска}few{# вертикальні риски}many{# вертикальних рисок}other{# vertical pipes}}</translation>
-<translation id="8735450637152821465">Початок виділення</translation>
-<translation id="8743786158317878347">відкрити структурований вміст, як-от таблиці</translation>
-<translation id="8747966237988593539">Упорядкований список</translation>
-<translation id="8759334257841767240">Немає наступного посилання.</translation>
-<translation id="8767968232364267681">Наступний заголовок рівня 4</translation>
-<translation id="8770473310765924354">закрити структурований вміст, як-от таблиці</translation>
-<translation id="8791025954632646584">Семантичний аналіз увімкнено</translation>
-<translation id="8796411681063377102">Наступний заголовок рівня 3</translation>
-<translation id="8808582214901541005">березень</translation>
-<translation id="8825828890761629845">банер</translation>
-<translation id="8851136666856101339">головний</translation>
-<translation id="8856538297388979332">Натискайте стрілки вгору чи вниз, щоб переглядати команди; натискайте Enter, щоб їх активувати</translation>
-<translation id="8864099967139188018">Немає наступного заголовка рівня 6.</translation>
-<translation id="8882002077197914455">Заголовок рядка</translation>
-<translation id="8896347895970027998">Зробити розширення ChromeVox активним чи неактивним.</translation>
-<translation id="8898516272131543774">Ще раз озвучити розділові знаки</translation>
-<translation id="8900148057318340779">Клавіша-префікс</translation>
-<translation id="8908714597367957477">заголовок стовпця</translation>
-<translation id="8931936695772494138">Порожні заголовки</translation>
-<translation id="8937112856099038376">внутрішнє посилання</translation>
-<translation id="8940925288729953902">Клавіші-модифікатори</translation>
-<translation id="8943175951035496220">Немає клітинки праворуч.</translation>
-<translation id="8978496506222343566">підказка</translation>
-<translation id="900114243503212879">файл</translation>
-<translation id="9027462562263121875">Немає таблиць.</translation>
-<translation id="9040132695316389094">Заголовок 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Увімкнути чи вимкнути віджет пошуку</translation>
-<translation id="9065283790526219006">+ спливаюче вікно</translation>
-<translation id="9077213568694924680">видалено з виділеного</translation>
-<translation id="9082874451376019682">Немає попереднього повзунка.</translation>
-<translation id="9089864840575085222">Ще раз озвучити введення тексту</translation>
-<translation id="9107530006868467849">Немає попереднього медіа-віджета.</translation>
-<translation id="9108370397979208512">математика</translation>
-<translation id="9108589040018540527">панель прокручування</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{процент}one{# символ процента}few{# символи процента}many{# символів процента}other{# percent signs}}</translation>
-<translation id="9115913704608474258">листопад</translation>
-<translation id="9128414153595658330">діалогове вікно</translation>
-<translation id="9149560530563164529">розділ</translation>
-<translation id="9151211641321628915">Повідомляє короткий опис поточної позиції</translation>
-<translation id="9153606228985488238">Висота звуку у відсотках: <ph name="PERCENT" /></translation>
-<translation id="9160096769946561184">Перейти в кінець поточного стовпця</translation>
-<translation id="9173115498289768110">Гучність у відсотках: <ph name="PERCENT" /></translation>
-<translation id="9178973770513562274">Натискайте клавіші зі стрілками вгору та вниз, щоб переглядати, або вводьте текст, щоб шукати.</translation>
-<translation id="9192904702577636854">Область виділення</translation>
-<translation id="9212322457209634662">Немає наступного розділу.</translation>
-<translation id="930275611743429116">Почати або закінчити вибір.</translation>
-<translation id="948171205378458592">Зменшити темп мовлення</translation>
-<translation id="962913030769097253">Наступний заголовок рівня 1</translation>
-<translation id="973955474346881951">Увімкнути чи вимкнути режим закріплення</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_vi.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_vi.xtb
deleted file mode 100644
index dcc4bdb1422..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_vi.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="vi">
-<translation id="1012173283529841972">Mục danh sách</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">Được mở rộng.</translation>
-<translation id="1025074108959230262">Đã tắt chế độ cố định</translation>
-<translation id="1031961866430398710">sau đó</translation>
-<translation id="1044777062731150180">Không có tiêu đề</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">dữ liệu nhập không hợp lệ</translation>
-<translation id="1082209053475788238">Không có tiêu đề cấp 6 trước nào.</translation>
-<translation id="1088219014394087294">Không có tiêu đề nào.</translation>
-<translation id="1106741348836243114">Bật hoặc tắt phản hồi bằng âm thanh (kết nối tai nghe).</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">Bộ sưu tập <ph name="TAG" /> có <ph name="NUM" /> mục</translation>
-<translation id="1155043339247954670">Không có mục danh sách tiếp theo nào.</translation>
-<translation id="1157782847298808853">Trợ giúp bàn phím</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />, <ph name="NAME" />, hộp kết hợp</translation>
-<translation id="1167230103353892028"><ph name="NAME" />, mục menu, có menu con</translation>
-<translation id="1177863135347784049">Tùy chỉnh</translation>
-<translation id="1188858454923323853">bổ sung</translation>
-<translation id="1206619573307042055">bảng chữ chạy</translation>
-<translation id="1213216066620407844">ChromeVox - Mang tính năng Thoại lên Chrome</translation>
-<translation id="1229276918471378188">Bước nhảy trước</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">Tiêu đề cấp 6 tiếp theo</translation>
-<translation id="1275718070701477396">Đã chọn</translation>
-<translation id="1319608975892113573">Không có khung trích dẫn trước nào.</translation>
-<translation id="1321576897702511272">Ẩn trợ giúp của ChromeVox</translation>
-<translation id="1331702245475014624"><ph name="INDEX" /> / <ph name="TOTAL" /></translation>
-<translation id="1334095593597963605">nói ký tự và từ</translation>
-<translation id="1339428534620983148">Cột trước của bảng</translation>
-<translation id="1342835525016946179">bài viết</translation>
-<translation id="1346748346194534595">Phải</translation>
-<translation id="136718599399906424">Hàng tiếp theo của bảng</translation>
-<translation id="1383876407941801731">Tìm kiếm</translation>
-<translation id="1385214448885562192">Nhấn enter để chấp nhận hoặc escape để hủy, mũi tên xuống để chuyển sang kết quả tiếp theo và mũi tên lên để chuyển sang kết quả trước.</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">rgn</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />, hộp văn bản nhập mật khẩu</translation>
-<translation id="1467432559032391204">Trái</translation>
-<translation id="1474557363159888097">Không có ký tự liên kết trước nào.</translation>
-<translation id="1502086903961450562">Hình trước</translation>
-<translation id="1506187449813838456">Tăng độ cao</translation>
-<translation id="151784044608172266">Câu tiếp theo</translation>
-<translation id="1524531499102321782">Dòng chữ nổi tiếp theo</translation>
-<translation id="1546370775711804143">Thanh cuộn</translation>
-<translation id="1559739829547075274">Điều hướng lui</translation>
-<translation id="1571643229714746283">ChromeVox đã sẵn sàng</translation>
-<translation id="158493514907962286">Tháng 12</translation>
-<translation id="1594072653727561613">mnu</translation>
-<translation id="1610130962244179598">Chuyển sang chữ nổi 6 chấm</translation>
-<translation id="1611168825862729585">Tiêu đề cột:</translation>
-<translation id="1613476421962910979">Bật kết nối tai nghe</translation>
-<translation id="1618597272655350600">Thông báo mô tả đầy đủ của vị trí hiện tại</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{dấu lớn hơn}other{# dấu lớn hơn}}</translation>
-<translation id="1653266918374749391">Tiêu đề cấp 3 trước</translation>
-<translation id="1659072772017912254">Chưa chọn</translation>
-<translation id="1669290819662866522">tuần</translation>
-<translation id="1674262202423278359">Điều hướng ChromeVox</translation>
-<translation id="16777221443363124">Thanh menu</translation>
-<translation id="1692077714702418899">dòng cấu trúc</translation>
-<translation id="1700517974991662022">Đã truy cập</translation>
-<translation id="1722567105086139392">Liên kết</translation>
-<translation id="1727806147743597030">ftr</translation>
-<translation id="174268867904053074">Hình tiếp theo</translation>
-<translation id="1781173782405573156">Phím truyền qua</translation>
-<translation id="1787176709638001873">Văn bản chỉnh sửa mật khẩu</translation>
-<translation id="1810107444790159527">Hộp danh sách</translation>
-<translation id="1828385960365606039">Tháng 5</translation>
-<translation id="1834891354138622109">Cột</translation>
-<translation id="1865601187525349519">Cuối văn bản</translation>
-<translation id="1876229593313240038">doc</translation>
-<translation id="188130072164734898">Nói thời gian và ngày tháng hiện tại.</translation>
-<translation id="1902396333223336119">Ô</translation>
-<translation id="1905379170753160525">Hiển thị danh sách tiêu đề</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">Kiểm soát tuần trong năm</translation>
-<translation id="1964135212174907577">Đối tượng tiếp theo</translation>
-<translation id="1969092762068865084">Tháng 7</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">Tiêu đề hàng:</translation>
-<translation id="2002895034995108595">Đặt lại sơ đồ bàn phím hiện tại</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{dấu mở ngoặc vuông}other{# dấu mở ngoặc vuông}}</translation>
-<translation id="2045490512405922022">chưa chọn</translation>
-<translation id="20601713649439366">Không có biểu thức toán học trước nào.</translation>
-<translation id="207477615537953741">Diễn giải ngữ nghĩa bị tắt</translation>
-<translation id="2086961585857038472">Từ tiếp theo</translation>
-<translation id="2089387485033699258">vi</translation>
-<translation id="2091933974477985526">Vùng văn bản có thể chỉnh sửa trước</translation>
-<translation id="2100350898815792233">Tất cả dấu câu</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">khóa truy cập:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">Thay đổi bảng chữ nổi 6 chấm hiện tại bằng cách chọn một tùy chọn từ danh sách bên dưới.</translation>
-<translation id="2169714232367507776">Nhấp vào mục hiện tại</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{dấu đóng ngoặc}other{# dấu đóng ngoặc}}</translation>
-<translation id="2199994615414171367">Biểu thức toán trước</translation>
-<translation id="2223693656926968778">Thực hiện tác vụ trên mục hiện tại</translation>
-<translation id="225732394367814946">Tăng tốc độ nói</translation>
-<translation id="2267945578749931355">Ký tự tiếp theo</translation>
-<translation id="2281234842553884450">Thanh trượt trước</translation>
-<translation id="2318372665160196757">Chính</translation>
-<translation id="2329324941084714723">Bảng điều khiển tab</translation>
-<translation id="2344193891939537199">Kiểm soát ngày giờ</translation>
-<translation id="2359897517538099099">Hiện không ở chế độ bảng.</translation>
-<translation id="241124561063364910">theo sau là</translation>
-<translation id="2417569100218200841">Thông tin nội dung</translation>
-<translation id="2422937916923936891">Hộp kiểm mục menu</translation>
-<translation id="2429669115401274487">CH</translation>
-<translation id="2435413342408885429"><ph name="KEY" /> giờ là phím bổ trợ ChromeVox mới.</translation>
-<translation id="2450814015951372393">Hộp kiểm</translation>
-<translation id="2462626033734746142">Nhóm nút radio</translation>
-<translation id="2471138580042810658">Tiêu đề 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{dấu hoa thị}other{# dấu hoa thị}}</translation>
-<translation id="2549392850788122959"><ph name="KEY" /> đã được đặt lại.</translation>
-<translation id="2553108862507765288">lỗi ngữ pháp</translation>
-<translation id="257674075312929031">Nhóm</translation>
-<translation id="2582407057977008361">Loại trừ</translation>
-<translation id="2589102159832527089">Trang này chứa văn bản được trích xuất tự động từ tệp PDF &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;. &lt;a href="<ph name="URL" />"&gt;Nhấp vào đây để xem văn bản gốc.&lt;/a&gt;</translation>
-<translation id="2606210917827248971">với {COUNT,plural, =1{# mục}other{# mục}}</translation>
-<translation id="2614981083756825552">Bố cục toán học ML</translation>
-<translation id="2626530649491650971">có thể nhấp được</translation>
-<translation id="2628764385451019380">Không có hộp kết hợp trước nào.</translation>
-<translation id="2637227747952042642">Toán học</translation>
-<translation id="2639750663247012216">Phím bổ trợ ChromeVox</translation>
-<translation id="2644542693584024604">sai chính tả</translation>
-<translation id="2667291555398229137">Nhấp vào mục dưới phím định tuyến</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{dấu mở ngoặc}other{# dấu mở ngoặc}}</translation>
-<translation id="2705875883745373140">Chưa nhấn</translation>
-<translation id="2706462751667573066">Lên</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">âm thanh</translation>
-<translation id="2732718972699418926">SA</translation>
-<translation id="2749275490991666823">Đã chọn</translation>
-<translation id="27527859628328957">Nhảy tới mục có thể đặt tiêu điểm tiếp theo</translation>
-<translation id="2770781857296573485">Nhập thăm dò nhóm</translation>
-<translation id="2777845298774924149">Đã thoát</translation>
-<translation id="2800204403141299078">Không có phần tử khác nào nữa.</translation>
-<translation id="2800780099804980316">Không có tiêu đề cấp 1 trước nào.</translation>
-<translation id="2811204574343810641">Hàng</translation>
-<translation id="2816654101880605877">Không có thanh trượt tiếp theo nào.</translation>
-<translation id="2841013758207633010">Thời gian</translation>
-<translation id="2843837985843789981">Nhóm trước</translation>
-<translation id="2844995807198708617">Menu ngữ cảnh</translation>
-<translation id="2849332794118375855">Không có hộp kiểm nào tiếp theo.</translation>
-<translation id="2864481629947106776">Liên kết trước</translation>
-<translation id="2873259058405069099">Đi tới đầu bảng</translation>
-<translation id="2894654529758326923">Thông tin</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{dấu mở ngoặc nhọn}other{# dấu mở ngoặc nhọn}}</translation>
-<translation id="2911433807131383493">Mở hướng dẫn ChromeVox</translation>
-<translation id="2932083475399492303">Chuyển đổi loại dòng giữa cấu trúc hoặc bố cục</translation>
-<translation id="2964026537669811554">Nhóm tiêu đề</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{dấu tab}other{# dấu tab}}</translation>
-<translation id="2972078295414139404">Không có liên kết đã truy cập trước nào.</translation>
-<translation id="2972205263822847197">Mẹo sử dụng công cụ</translation>
-<translation id="2998131015536248178">Ký tự trước</translation>
-<translation id="2999559350546931576">Giảm độ cao</translation>
-<translation id="2999945368667127852">Không có tiện ích phương tiện tiếp theo nào.</translation>
-<translation id="3012414509011670858">Không có phần trước nào.</translation>
-<translation id="3030432017085518523">Nút radio mục menu</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{dấu nháy đơn}other{# dấu nháy đơn}}</translation>
-<translation id="3046838483509668188">Tùy chọn của ChromeVox</translation>
-<translation id="3047143736589213134">Sơ đồ bàn phím thử nghiệm</translation>
-<translation id="3060756054951570867">Menu <ph name="TITLE" /> đã được mở</translation>
-<translation id="3078345202707391975">Tiêu đề cấp 2 tiếp theo</translation>
-<translation id="3078740164268491126">bảng</translation>
-<translation id="3082557070674409251">Được nhấp</translation>
-<translation id="3084806535845658316">không nói khi nhập</translation>
-<translation id="3086746722712840547">ghi chú</translation>
-<translation id="308895241372589742">Không có biểu thức toán tiếp theo nào.</translation>
-<translation id="3090532668523289635">grp</translation>
-<translation id="3093176084511590672">Điểm mốc tiếp theo</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">alrt dlg</translation>
-<translation id="3109724472072898302">Đã thu gọn</translation>
-<translation id="3134461040845705080">rdonly</translation>
-<translation id="3138767756593758860">Hiển thị danh sách điểm mốc</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">Dòng tiếp theo</translation>
-<translation id="3155083529632865074">Không có nút trước nào.</translation>
-<translation id="3163593631834463955">Tiêu đề cột trống</translation>
-<translation id="316542773973815724">Điều hướng</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{dấu cách}other{# dấu cách}}</translation>
-<translation id="320961988183078793">đã vào <ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />, tab</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">Liên kết đã truy cập</translation>
-<translation id="323731244387692321">Mở trợ giúp về bàn phím ChromeVox</translation>
-<translation id="3241052487511142956">Liên kết đã truy cập trước đó</translation>
-<translation id="3286390186030710347">Thanh trượt</translation>
-<translation id="3299925995433437805">Không có liên kết đã truy cập tiếp theo nào.</translation>
-<translation id="3303384412438961941">Nhấn phím bất kỳ để biết tên của phím. Nhấn Ctrl+W sẽ đóng trình khám phá bàn phím.</translation>
-<translation id="3307886118343381874">Đi tới cuối bảng</translation>
-<translation id="3311969765485641742">Nhấn Alt+Shift+A để xem lại thông báo</translation>
-<translation id="3312997241656799641">Liên kết đã truy cập tiếp theo</translation>
-<translation id="3321460131042519426">Bật xuống dòng tự động</translation>
-<translation id="3322936298410871309">Tiêu đề cấp 1 trước</translation>
-<translation id="3323447499041942178">Hộp văn bản</translation>
-<translation id="3353420241558113817">{"ar": "tiếng Ả Rập",
- "bg": "tiếng Bungari",
- "ca": "tiếng Catalan",
- "cs": "tiếng Séc",
- "da": "tiếng Đan Mạch",
- "de": "tiếng Đức",
- "de_CH": "tiếng Đức (Thụy Sĩ)",
- "de_DE": "tiếng Đức (Đức)",
- "el": "tiếng Hy Lạp",
- "en": "tiếng Anh",
- "en_CA": "tiếng Anh (Canada)",
- "en_GB": "tiếng Anh (Anh)",
- "en_US": "tiếng Anh (Mỹ)",
- "es": "tiếng Tây Ban Nha",
- "et": "tiếng Estonia",
- "fr": "tiếng Pháp",
- "fr_CA": "tiếng Pháp (Canada)",
- "fr_FR": "tiếng Pháp (Pháp)",
- "fi": "tiếng Phần Lan",
- "he": "tiếng Do Thái",
- "hi": "tiếng Hindi",
- "hr": "tiếng Croatia",
- "hu": "tiếng Hungary",
- "is": "tiếng Iceland",
- "it": "tiếng Ý",
- "ko": "tiếng Hàn",
- "lt": "tiếng Lithuania",
- "lv": "tiếng Latvia",
- "nb": "tiếng Bokmål Na Uy",
- "nl": "tiếng Hà Lan",
- "pl": "tiếng Ba Lan",
- "pt": "tiếng Bồ Đào Nha",
- "ro": "tiếng Rumani",
- "ru": "tiếng Nga",
- "sk": "tiếng Slovak",
- "sl": "tiếng Slovenia",
- "sr": "tiếng Serbia",
- "sv": "tiếng Thụy Điển",
- "tr": "tiếng Thổ Nhĩ Kỳ",
- "vi": "tiếng Việt",
- "zh": "tiếng Trung",
- "zh_TW": "tiếng Trung (tiếng Trung phồn thể)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{dấu cộng}other{# dấu cộng}}</translation>
-<translation id="338583716107319301">Dấu phân tách</translation>
-<translation id="3389259863310851658">Trường biểu mẫu trước</translation>
-<translation id="3390225400784126843">Phần tử khác tiếp theo.</translation>
-<translation id="3392045790598181549"><ph name="NAME" />, mục menu</translation>
-<translation id="3406283310380167331">Hiển thị danh sách biểu mẫu</translation>
-<translation id="3422338090358345848">Mở trình khám phá bàn phím</translation>
-<translation id="3457000393508828486">Được nhấn một phần</translation>
-<translation id="3462439746547587373"><ph name="NAME" />, nút</translation>
-<translation id="3473644018603298796">sld <ph name="COUNT" /></translation>
-<translation id="3486232535569802404"><ph name="V1" /> tới <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{dấu đóng ngoặc vuông}other{# dấu đóng ngoặc vuông}}</translation>
-<translation id="3493915602752813531">Không có ký tự liên kết tiếp theo nào.</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{dấu hỏi}other{# dấu hỏi}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{dấu mũ}other{# dấu mũ}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />, hộp kiểm không được chọn</translation>
-<translation id="3599054940393788245">Không có trong toán học</translation>
-<translation id="3616113530831147358">Âm thanh</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{dấu huyền}other{# dấu huyền}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{dấu đô la}other{# dấu đô la}}</translation>
-<translation id="3659787053479271466">alrt</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />, hộp danh sách</translation>
-<translation id="3687295507293856493">Đoán tại tiêu đề cột của ô hiện tại</translation>
-<translation id="3692274950075847560">T:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">Điều chỉnh giọng nói</translation>
-<translation id="3716845769494773620">Nhiều dòng</translation>
-<translation id="3731746171184829332">Không có tiêu đề trước nào.</translation>
-<translation id="3762198587642264450">Đi tới cuối hàng hiện tại</translation>
-<translation id="3777255250339039212">h1</translation>
-<translation id="3793710123303304873">Đã thoát khỏi hộp thoại.</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">Tự động hoàn thành danh sách</translation>
-<translation id="3810838688059735925">Video</translation>
-<translation id="3816633764618089385">Phương tiện tiếp theo</translation>
-<translation id="3819376190738087562">Không có điểm nhảy nào.</translation>
-<translation id="385383972552776628">Mở trang tùy chọn</translation>
-<translation id="3856075812838139784">Chỉ đọc</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">Menu</translation>
-<translation id="3909320334364316587">Tiêu đề cấp 6 trước</translation>
-<translation id="3914173277599553213">Bắt buộc</translation>
-<translation id="3962990492275676168">Bắt đầu đọc từ vị trí hiện tại</translation>
-<translation id="4004802134384979325">đã chọn</translation>
-<translation id="4006140876663370126">img</translation>
-<translation id="4038349100599457191">Kiểm soát tháng</translation>
-<translation id="4039983576244166038">Tiêu đề hàng trống</translation>
-<translation id="4042843249978639960">Không có tiêu đề cấp 2 tiếp theo nào.</translation>
-<translation id="4043348641337972076">Không có mốc ARIA trước nào.</translation>
-<translation id="4047216625641135770">Đánh dấu</translation>
-<translation id="404803211695627272"><ph name="V1" />-<ph name="V2" /></translation>
-<translation id="4054936709456751127">sts</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{DẤU NGÃ}other{# dấu ngã}}</translation>
-<translation id="409334809956508737">Đối tượng trước</translation>
-<translation id="4099274309791143834">có menu con</translation>
-<translation id="4107807507418787238">Không có ô nào bên dưới.</translation>
-<translation id="4116415223832267137">Thông báo</translation>
-<translation id="4147126331795725888">Không có điều khiển tiếp theo nào.</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{dấu đóng ngoặc nhọn}other{# dấu đóng ngoặc nhọn}}</translation>
-<translation id="4158704014418536539">Phân biệt chữ hoa / chữ thường.</translation>
-<translation id="4161663686871496107">Tính năng phản hồi bằng giọng nói ChromeVox đã sẵn sàng</translation>
-<translation id="4173994908659439270">Không có trường văn bản có thể chỉnh sửa tiếp theo nào.</translation>
-<translation id="4176463684765177261">Đã bị vô hiệu</translation>
-<translation id="4188530942454211480">Câu trước</translation>
-<translation id="4202186506458631436">Chuyển quyền</translation>
-<translation id="4206289001967551965">Bên trong bảng</translation>
-<translation id="4215733775853809057">Thanh trượt tiếp theo</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{dấu gạch ngang}other{# dấu gạch ngang}}</translation>
-<translation id="421884353938374759">công cụ chọn màu</translation>
-<translation id="4229646983878045487">ngày giờ</translation>
-<translation id="423334822609210999">Không có ô nào bên trái.</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />, Hạng <ph name="GRADE" /></translation>
-<translation id="4253168017788158739">Lưu ý</translation>
-<translation id="4254798249533888099">Cây</translation>
-<translation id="4255943572433203166">Sử dụng các tùy chọn bên dưới để tùy chỉnh ChromeVox. Các thay đổi sẽ có hiệu lực ngay lập tức.</translation>
-<translation id="4271220233568730077">Biểu thức toán tiếp theo</translation>
-<translation id="4271521365602459209">Không còn kết quả nào nữa.</translation>
-<translation id="4287520460805643128">Không có bài viết tiếp theo nào.</translation>
-<translation id="4289540628985791613">Tổng quan</translation>
-<translation id="4300318234632215983">Thông báo URL ở sau liên kết</translation>
-<translation id="4301352596632316575">có menu con</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{dấu chấm}=3{dấu chấm lửng}other{# dấu chấm}}</translation>
-<translation id="4347461890115250064">Không có danh sách tiếp theo nào.</translation>
-<translation id="4367650418938037324">Lá toán học ML</translation>
-<translation id="4372435075475052704">tối thiểu:<ph name="X" /></translation>
-<translation id="4372705107434148843">Dừng giọng nói</translation>
-<translation id="4373197658375206385">Không có mục trước nào không phải là liên kết.</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">đặt lại</translation>
-<translation id="4471074325120394300">Không có liên kết nào.</translation>
-<translation id="4476183483923481720">dòng mới</translation>
-<translation id="4482330759234983253">Bảng trước</translation>
-<translation id="4491109536499578614">Hình ảnh</translation>
-<translation id="4529987814483543472">Sơ đồ bàn phím cổ điển</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{dấu gạch chéo}other{# dấu gạch chéo}}</translation>
-<translation id="4547556996012970016">Tiêu đề cấp 5 tiếp theo</translation>
-<translation id="4562381607973973258">Tiêu đề</translation>
-<translation id="4591507479202817876">, đã được chọn</translation>
-<translation id="4597532268155981612">biểu mẫu</translation>
-<translation id="4597896406374528575">Tháng 4</translation>
-<translation id="4615592953348396470">Bỏ qua nhấn phím tiếp theo</translation>
-<translation id="461613135510474570">Câu</translation>
-<translation id="4647836961514597010">Công cụ chọn màu</translation>
-<translation id="4661075872484491155">cây</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">grd</translation>
-<translation id="4693675773662933727">Điểm mốc trước</translation>
-<translation id="4696413482802371445">Không có tiêu đề cấp 5 tiếp theo nào.</translation>
-<translation id="4729095194763193578">Hàng trước của bảng</translation>
-<translation id="4736221692378411923">Tháng 8</translation>
-<translation id="4740661827607246557">Lệnh trợ giúp</translation>
-<translation id="4759716709594980008">Trình khám phá bàn phím ChromeOS</translation>
-<translation id="4763296182459741068">Đã bao gồm cả cuối trang</translation>
-<translation id="4763480195061959176">video</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">Thông báo tiêu đề của trang hiện tại</translation>
-<translation id="4826415162591436065">Điều hướng tiến lên</translation>
-<translation id="4826604887384865800">Bước nhảy tiếp theo</translation>
-<translation id="4827410568042294688">đã bỏ chọn</translation>
-<translation id="4842108708071771135">Không có khung trích dẫn tiếp theo nào.</translation>
-<translation id="4848993367330139335">tmr</translation>
-<translation id="4850023505158945298">Phần tử tương tự trước.</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">Bật ghi nhật ký TTS</translation>
-<translation id="4877261390094455813">Nhập truy vấn tìm kiếm.</translation>
-<translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation>
-<translation id="489907760999452556">Liên kết bên trong</translation>
-<translation id="4953585991029886728">Chỉnh sửa văn bản</translation>
-<translation id="4954534434583049121">Khối trích dẫn trước</translation>
-<translation id="4973717656530883744">Tối thiểu <ph name="X" /></translation>
-<translation id="4973762002207131920">Được chuyển thành <ph name="KEY" />.</translation>
-<translation id="4975416682604111799">mili giây</translation>
-<translation id="49787999531187221">ChromeVox hiện không hoạt động.</translation>
-<translation id="4979404613699303341">Nút trước</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />, <ph name="NAME" />, hộp danh sách</translation>
-<translation id="4983588134362688868">Chuyển đến đầu trang</translation>
-<translation id="4986606102545753256"><ph name="NAME" />, cửa sổ</translation>
-<translation id="4993152509206108683">Tốc độ <ph name="PERCENT" /> phần trăm</translation>
-<translation id="4996716799442435517">Hình ảnh</translation>
-<translation id="4997282455736854877"><ph name="NAME" />, nút radio đã được chọn</translation>
-<translation id="4997475792277222884">Không có mục tiếp theo nào không phải là liên kết.</translation>
-<translation id="5000760171916499057">Không có biểu mẫu nào.</translation>
-<translation id="5005670136041063723">Không có phần tử tương tự nào khác.</translation>
-<translation id="501473567976723023">Tháng 1</translation>
-<translation id="5041394372352067729">Di chuyển màn hình chữ nổi về đầu trang</translation>
-<translation id="5042770794184672516">Tăng âm lượng giọng nói</translation>
-<translation id="5050015258024679800">Tiêu đề cấp 4 trước</translation>
-<translation id="5054047268577924192">Mục danh sách trước</translation>
-<translation id="5078661581131202757">Chọn tệp</translation>
-<translation id="5080758118274074384">được nhấp đúp</translation>
-<translation id="5098541983634824365">Thoát khỏi lưới.</translation>
-<translation id="5102981729317424850">Thanh công cụ</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">Không có trường biểu mẫu trước nào.</translation>
-<translation id="5111640677200759579">Tiêu đề cột</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">Không có liên kết trước nào.</translation>
-<translation id="513774504516943387">lnk</translation>
-<translation id="517143700877085897">, không được chọn</translation>
-<translation id="5183440668879371625">Dòng chữ nổi trước</translation>
-<translation id="5184944171021383281">Không có trường biểu mẫu tiếp theo nào.</translation>
-<translation id="5189244881767082992">Dòng</translation>
-<translation id="5203930734796605961"><ph name="KEY" /> đã được gán cho một lệnh.</translation>
-<translation id="5205493599117157272">Danh sách <ph name="TYPE" />.</translation>
-<translation id="520883772648104506">Không có nút radio tiếp theo nào.</translation>
-<translation id="5263344797180442561">h2</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">Đối tượng</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />, tab</translation>
-<translation id="5310788376443009632">đã xóa:</translation>
-<translation id="5320727453979144100">Đã bật chế độ cố định</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{dấu phẩy}other{# dấu phẩy}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />, hộp văn bản</translation>
-<translation id="5330443287809544590"><ph name="NAME" />, liên kết</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">Lùi lại đoạn trước đó trong khi tiếp tục đọc</translation>
-<translation id="5368000168321181111">Tắt kết nối tai nghe</translation>
-<translation id="5374320867641260420">Không có nút tiếp theo nào.</translation>
-<translation id="5382299583965267720">Không có tiêu đề cấp 1 tiếp theo nào.</translation>
-<translation id="5402367795255837559">Chữ nổi</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{dấu chấm phẩy}other{# dấu chấm phẩy}}</translation>
-<translation id="5411891038905756502">Không có điểm nhảy trước nào.</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{dấu nhỏ hơn}other{# dấu nhỏ hơn}}</translation>
-<translation id="5455441614648621694">Bổ sung</translation>
-<translation id="5485036206801896268">Không có hình trước nào.</translation>
-<translation id="5486947920110100234">Không có điểm nhảy tiếp theo nào.</translation>
-<translation id="549602578321198708">Từ</translation>
-<translation id="5500932716852106146">Không có trường văn bản có thể chỉnh sửa trước nào.</translation>
-<translation id="5502713021410870035">Tháng 9</translation>
-<translation id="5507663321906818013">Dấu gỡ lỗi</translation>
-<translation id="5518443085409638729">Đặt con trỏ giữa các ký tự khi chỉnh sửa văn bản (như Mac OS X).</translation>
-<translation id="552195134157544755">Nút radio</translation>
-<translation id="5534303576632885660">tiêu đề</translation>
-<translation id="5546092960038624944">Không có tiêu đề cấp 5 trước nào.</translation>
-<translation id="556042886152191864">Nút</translation>
-<translation id="5561345396546889625">Danh sách tiếp theo</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace</translation>
-<translation id="5585044216466955529">Chỉnh sửa văn bản, mục nhập email</translation>
-<translation id="5597170376237141345">Hộp kiểm tiếp theo</translation>
-<translation id="5597933780944041114">Không có tiêu đề nào tiếp theo.</translation>
-<translation id="5598905979683743333"><ph name="NAME" />, nút radio bị bỏ chọn</translation>
-<translation id="5601172225407283979">Thực hiện tác vụ mặc định</translation>
-<translation id="5608798115546226984">Tự động hoàn thành nội dòng</translation>
-<translation id="561939826962581046">thời gian</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">Nhật ký</translation>
-<translation id="5628125749885014029">h4</translation>
-<translation id="5637871198229500030">Không có bảng trước nào.</translation>
-<translation id="5655682562155942719">Chuyển lệnh</translation>
-<translation id="56637627897541303">Vùng văn bản</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">def</translation>
-<translation id="5682113568322255809">Mốc</translation>
-<translation id="5683155931978483559">Hộp kiểm trước</translation>
-<translation id="5684277895745049190">Danh sách</translation>
-<translation id="5700650669149824506">Không có tiêu đề cấp 4 trước nào.</translation>
-<translation id="5709192780268610569">Không có mô tả dài nào</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">Cột tiếp theo của bảng</translation>
-<translation id="571866080859340309">Thăm dò nhóm</translation>
-<translation id="5728409797179002635">Không tìm thấy bảng nào.</translation>
-<translation id="5748623122140342504">Tiêu đề cấp 5 trước</translation>
-<translation id="5750633686117194034">Không có phím bổ trợ nào được nhấn; vui lòng nhấn và giữ một hoặc nhiều phím bổ trợ; nhấc ngón tay khi hoàn tất và bạn sẽ nghe thấy phím được đặt. Nhấn tab để thoát.</translation>
-<translation id="5788275253279308023">tab <ph name="TITLE" /> trong cửa sổ ẩn danh</translation>
-<translation id="5806206155699461681">Cải thiện các trang web cụ thể (như Google Tìm kiếm).</translation>
-<translation id="5819072574982403430">Mục cây</translation>
-<translation id="5826479389509458994">hàng <ph name="ROW" /> cột <ph name="COL" /></translation>
-<translation id="5850707923114094062">Xoay về phía sau</translation>
-<translation id="5851548754964597211">Danh sách tab</translation>
-<translation id="5859752971144398932">Đã thoát khỏi tiện ích tìm trong trang.</translation>
-<translation id="5866042630553435010">Đã kiểm tra một phần</translation>
-<translation id="5869546221129391014">Lưới</translation>
-<translation id="5876817486144482042">Giảm âm lượng giọng nói</translation>
-<translation id="5887397643266327462">Phụ đề chữ nổi đã được bật.</translation>
-<translation id="5891934789323004067">Bảng</translation>
-<translation id="5919442531159595654">sao chép.</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{dấu bằng}other{# dấu bằng}}</translation>
-<translation id="5939518447894949180">Đặt lại</translation>
-<translation id="5948123859135882163">Chuyển đổi diễn giải biểu thức toán học giữa cấu trúc và ngữ nghĩa</translation>
-<translation id="5955304353782037793">app</translation>
-<translation id="5956928062748260866">Hộp thoại</translation>
-<translation id="5963413905009737549">Phần</translation>
-<translation id="5968607524793740041">Hiển thị menu ngữ cảnh</translation>
-<translation id="5983179082906765664">Tăng mức độ chi tiết của điều hướng</translation>
-<translation id="5999630716831179808">Giọng nói</translation>
-<translation id="6000417740266304866">Thay đổi bảng chữ nổi 8 chấm hiện tại bằng cách chọn một tùy chọn từ danh sách bên dưới.</translation>
-<translation id="6006050241733874051">Biểu mẫu</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{dấu gạch chéo ngược}other{# dấu gạch chéo ngược}}</translation>
-<translation id="6037602951055904232">Xoay về phía trước</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">Cuối ô.</translation>
-<translation id="6122013438240733403">btn</translation>
-<translation id="6129953537138746214">Dấu cách</translation>
-<translation id="6142308968191113180">Tiêu đề 4</translation>
-<translation id="6169420925157477918">Hình ảnh có mô tả dài</translation>
-<translation id="6172087735260766220">Không thể truy cập vào văn bản có thể truy cập từ bản PDF cấm sao chép.</translation>
-<translation id="6186305613600865047">Chuyển đến cuối trang</translation>
-<translation id="6193330012414963395">SA CH</translation>
-<translation id="622484624075952240">Xuống</translation>
-<translation id="6236061028292614533">Tiêu đề tiếp theo</translation>
-<translation id="6254901459154107917">Vùng văn bản có thể chỉnh sửa tiếp theo</translation>
-<translation id="6259464875943891919">Đã thoát <ph name="TYPE" />.</translation>
-<translation id="6281876499889881039">Phần tử tương tự tiếp theo.</translation>
-<translation id="6282062888058716985">điều hướng</translation>
-<translation id="6290434000785343030">Không có hộp kết hợp tiếp theo nào.</translation>
-<translation id="6307969636681130414">Đã nhấn</translation>
-<translation id="6324551002951139333">Đã phát hiện lỗi ngữ pháp</translation>
-<translation id="6348657800373377022">Hộp combo</translation>
-<translation id="6355910664415701303">Không có mục danh sách trước nào.</translation>
-<translation id="6364795331201459219">h6</translation>
-<translation id="6368143427468974988">Tiêu đề trước</translation>
-<translation id="6387719785439924554">loại trừ</translation>
-<translation id="6411426777058107714">Không có nút radio trước nào.</translation>
-<translation id="6414968628640960377">Phần tử khác trước.</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{dấu hai chấm}other{# dấu hai chấm}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />, menu</translation>
-<translation id="6444046323172968959">Hộp thoại thông báo</translation>
-<translation id="6459511626086141404">Sơ đồ bàn phím phẳng</translation>
-<translation id="6468049171101508116">Nút tiếp theo</translation>
-<translation id="6491972999578897419">Thay đổi giọng nói hiện tại bằng cách chọn tùy chọn từ danh sách bên dưới.</translation>
-<translation id="6508059270146105198">Di chuyển màn hình chữ nổi xuống cuối trang</translation>
-<translation id="6536864053412760904">Mã thông báo toán học ML</translation>
-<translation id="6550720799683018100">Thay đổi sơ đồ bàn phím hiện tại bằng cách chọn một tùy chọn từ danh sách bên dưới.</translation>
-<translation id="6561818612645211875">Đi tới đầu hàng hiện tại</translation>
-<translation id="6587021927234520429">Không có tiêu đề cấp 4 tiếp theo nào.</translation>
-<translation id="6601344353291556895">Bật mô tả chi tiết.</translation>
-<translation id="6615602925644411249">Tìm trong trang.</translation>
-<translation id="6633350132811819843">Không có bảng tiếp theo nào.</translation>
-<translation id="6637586476836377253">nhật ký</translation>
-<translation id="6657128831881431364">Thanh tiến độ</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">Tài liệu</translation>
-<translation id="6697092096875747123">Hộp kết hợp trước</translation>
-<translation id="6714813999819678458">Tiêu đề cấp 2 trước</translation>
-<translation id="6716505898850596801">Phím bổ trợ</translation>
-<translation id="671916444866103745">Không có mốc ARIA tiếp theo nào.</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />, hộp kết hợp</translation>
-<translation id="6735257939857578167">có <ph name="NUM" /> mục</translation>
-<translation id="6736510033526053669">tab đã được tạo</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">Bài viết</translation>
-<translation id="6787839852456839824">Phím tắt</translation>
-<translation id="6793101435925451627">lstbx</translation>
-<translation id="6833103209700200188">Chân trang</translation>
-<translation id="6871161210040114857">Không phân biệt chữ hoa / chữ thường.</translation>
-<translation id="6877435256196695200">Không có hình nào tiếp theo.</translation>
-<translation id="6897341342232909480">Di chuyển sang trái</translation>
-<translation id="6901540140423170855">ngày</translation>
-<translation id="6910211073230771657">Đã xóa</translation>
-<translation id="6911965441508464308">Không có ô nào phía trên.</translation>
-<translation id="6919104639734799681">Hiển thị danh sách bảng</translation>
-<translation id="6964088412282673743">Không có điều khiển trước nào.</translation>
-<translation id="6996566555547746822">Hộp kết hợp tiếp theo</translation>
-<translation id="7005146664810010831">Không tìm thấy URL nào</translation>
-<translation id="7010712454773919705">Phím bổ trợ ChromeVox</translation>
-<translation id="7031651751836475482">lstitm</translation>
-<translation id="7037042857287298941">Danh sách trước</translation>
-<translation id="7041173719775863268">Kết thúc chọn</translation>
-<translation id="7095834689119144465">Chỉnh sửa văn bản chỉ dành cho số</translation>
-<translation id="7096001299300236431">Phương tiện trước</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">nói từ</translation>
-<translation id="713824876195128146">Khối trích dẫn tiếp theo</translation>
-<translation id="7161771961008409533">Nút cửa sổ bật lên</translation>
-<translation id="7167657087543110">âm ký tự</translation>
-<translation id="7170733337935166589">Chuyển đến đoạn tiếp theo trong khi tiếp tục đọc</translation>
-<translation id="7181697990050180700">Tùy chỉnh phím tắt cho các lệnh được sử dụng thường xuyên bằng cách nhập chúng vào trường tương ứng bên dưới.</translation>
-<translation id="7203150201908454328">Được mở rộng</translation>
-<translation id="7210211103303402262">phút</translation>
-<translation id="7217912842225915592">+<ph name="NUM" /></translation>
-<translation id="7221740160534240920">dòng</translation>
-<translation id="7226216518520804442">lst</translation>
-<translation id="72393384879519786">Tiêu đề</translation>
-<translation id="7241683698754534149">Mở mô tả dài trong tab mới</translation>
-<translation id="7248671827512403053">Ứng dụng</translation>
-<translation id="725969808843520477">Nút radio tiếp theo</translation>
-<translation id="7269119382257320590">Không có dấu câu</translation>
-<translation id="7273174640290488576">Trống</translation>
-<translation id="7285387653379749618">Bảng</translation>
-<translation id="7289186959554153431">Tiêu đề 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">Phụ đề chữ nổi đã bị tắt.</translation>
-<translation id="7318872822751139669">Sử dụng chuột để thay đổi tiêu điểm.</translation>
-<translation id="7322388933135261569">Tháng 2</translation>
-<translation id="7332592614823088566">Hàng <ph name="ROWINDEX" /> / <ph name="ROWTOTAL" />, cột <ph name="COLINDEX" /> / <ph name="COLTOTAL" /></translation>
-<translation id="7336596009609913925">có cửa sổ bật lên</translation>
-<translation id="7356165926712028380">Chuyển sang chữ nổi 8 chấm</translation>
-<translation id="7362871137496673139">Không có tiêu đề cấp 2 trước nào.</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{dấu và}other{# dấu và}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">Thoát khỏi bảng.</translation>
-<translation id="739763518212184081">Dòng trước</translation>
-<translation id="7400575256015741911">Đã phát hiện lỗi chính tả</translation>
-<translation id="7408482676469142474">tbl</translation>
-<translation id="7425395583360211003">quay lại</translation>
-<translation id="7434509671034404296">Nhà phát triển</translation>
-<translation id="7439060726180460871">Thư mục</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">tab</translation>
-<translation id="7492049978501397201">Đã vào hộp thoại</translation>
-<translation id="7532613204005497612">Tháng 6</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />, <ph name="NAME" />, thanh trượt</translation>
-<translation id="7586163296341959563">dán.</translation>
-<translation id="7596919493010894443">đã xóa lựa chọn</translation>
-<translation id="7604026522577407655">Đi tới đầu cột hiện tại</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">Thông báo URL của trang hiện tại</translation>
-<translation id="7609363189280667021">Chuyển đổi phụ đề chữ nổi</translation>
-<translation id="762020119231868829">Tạm dừng tất cả các tiện ích con phương tiện hiện đang phát</translation>
-<translation id="7625690649919402823">Bảng tiếp theo</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), Lớp <ph name="GRADE" /></translation>
-<translation id="7641134354185483015">Không có tiêu đề cấp 3 trước nào.</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />, <ph name="NAME" />, hộp văn bản</translation>
-<translation id="7663318257180412551">Tiêu đề 2</translation>
-<translation id="7674576868851035240">Liên kết tiếp theo</translation>
-<translation id="7674768236845044097">đánh dấu</translation>
-<translation id="7684431668231950609">Chỉnh sửa văn bản, mục nhập URL</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">Nút radio trước</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />, <ph name="NAME" />, hộp văn bản nhập mật khẩu</translation>
-<translation id="7805247615045262757">điều hướng mặc định</translation>
-<translation id="7805768142964895445">Trạng thái</translation>
-<translation id="7810781339813764006">Nhóm tiếp theo</translation>
-<translation id="7819187121850078213">tab <ph name="TITLE" /> trong cửa sổ</translation>
-<translation id="7828956995407538686">Tháng 10</translation>
-<translation id="7839679365527550018">Từ trước</translation>
-<translation id="7851816175263618915">Một số dấu câu</translation>
-<translation id="7870596830398826354">Cây toán học ML</translation>
-<translation id="78826985582142166">sldr</translation>
-<translation id="7894517696028036636">Chuyển đổi sang ChromeVox cổ điển.</translation>
-<translation id="7895896691902835279">Liên kết không xác định</translation>
-<translation id="7927711904086083099">Chưa chọn</translation>
-<translation id="7935627501098484003">Kiểm soát thời gian</translation>
-<translation id="7939428177581522200">đã thêm vào lựa chọn</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{dấu @}other{# dấu @}}</translation>
-<translation id="7965147473449754028">đã đóng menu</translation>
-<translation id="7974390230414479278">Mục menu</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{dấu chấm than}other{# dấu chấm than}}</translation>
-<translation id="8007540374018858731">h3</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{dấu ngoặc kép}other{# dấu ngoặc kép}}</translation>
-<translation id="8033827949643255796">đã chọn</translation>
-<translation id="8035962149453661158">tối đa:<ph name="X" /></translation>
-<translation id="8042761080832772327">Chỉnh sửa văn bản, mục nhập tìm kiếm</translation>
-<translation id="8049189770492311300">Bộ tính giờ</translation>
-<translation id="8065607967589909823">Lựa chọn hiện tại là</translation>
-<translation id="8066678206530322333">Biểu ngữ</translation>
-<translation id="8110647606445335195">Không có mốc ARIA nào.</translation>
-<translation id="8153880621934657047">Không phải bên trong bảng.</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{dấu gạch dưới}other{# dấu gạch dưới}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">cắt.</translation>
-<translation id="8199231515320852133">Thông báo các tiêu đề của ô hiện tại</translation>
-<translation id="820417203470636242">Ô trống.</translation>
-<translation id="8215202828671303819">Đa chọn</translation>
-<translation id="8276439074553447000">Nhảy tới mục có thể đặt tiêu điểm trước</translation>
-<translation id="8278417001922463147">Không có bài viết trước nào.</translation>
-<translation id="8283603667300770666">Trường biểu mẫu tiếp theo</translation>
-<translation id="831207808878314375">Định nghĩa</translation>
-<translation id="8313653172105209786">dir</translation>
-<translation id="8344569602005188545">giờ</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{dấu thăng}other{# dấu thăng}}</translation>
-<translation id="8374154622594089836">tháng</translation>
-<translation id="8378855320830505539">Khu vực</translation>
-<translation id="8382679411218029383">Tự động hoàn thành nội dòng và danh sách</translation>
-<translation id="8428603554127842284">cấp <ph name="DEPTH" /></translation>
-<translation id="842922884199979200">Không có tiêu đề cấp 3 tiếp theo nào.</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">Không có hộp kiểm trước nào.</translation>
-<translation id="8455868257606149352">Tối đa <ph name="X" /></translation>
-<translation id="84575901236241018">có khóa truy cập, <ph name="KEY" /></translation>
-<translation id="8503360654911991865">Giảm mức độ chi tiết của điều hướng</translation>
-<translation id="8520472399088452386">Nút quay tròn</translation>
-<translation id="8538744478902126321">Đoán tại tiêu đề hàng của ô hiện tại</translation>
-<translation id="8540054775867439484">Đã bao gồm cả đầu trang</translation>
-<translation id="8548973727659841685">Ký tự</translation>
-<translation id="8561322612995434619">có cửa sổ bật lên</translation>
-<translation id="8571096049907249734">đa chọn</translation>
-<translation id="8584721346566392021">h5</translation>
-<translation id="8587549812518406253">Mục danh sách tiếp theo</translation>
-<translation id="860150890330522909">Hộp kiểm <ph name="NAME" /> đã được chọn</translation>
-<translation id="8606621670302093223">Kiểm soát ngày</translation>
-<translation id="8631359288236106450">đã chọn <ph name="COUNT" /> mục</translation>
-<translation id="8638532244051952400">Thông báo tọa độ ô hiện tại</translation>
-<translation id="8650576015643545550">Không có danh sách trước nào.</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">Hiển thị danh sách liên kết</translation>
-<translation id="8664519043722036194">giây</translation>
-<translation id="867187640362843212">Tiêu đề 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{dấu sổ thẳng}other{# dấu sổ thẳng}}</translation>
-<translation id="8735450637152821465">Bắt đầu chọn</translation>
-<translation id="8743786158317878347">vào nội dung có cấu trúc, chẳng hạn như bảng</translation>
-<translation id="8747966237988593539">Danh sách theo thứ tự</translation>
-<translation id="8759334257841767240">Không có liên kết tiếp theo nào.</translation>
-<translation id="8767968232364267681">Tiêu đề cấp 4 tiếp theo</translation>
-<translation id="8770473310765924354">thoát nội dung có cấu trúc, chẳng hạn như bảng</translation>
-<translation id="8791025954632646584">Diễn giải ngữ nghĩa được bật</translation>
-<translation id="8796411681063377102">Tiêu đề cấp 3 tiếp theo</translation>
-<translation id="8808582214901541005">Tháng 3</translation>
-<translation id="8825828890761629845">bnr</translation>
-<translation id="8851136666856101339">chính</translation>
-<translation id="8856538297388979332">Nhấn lên hoặc xuống để xem lại lệnh, nhấn enter để kích hoạt</translation>
-<translation id="8864099967139188018">Không có tiêu đề cấp 6 tiếp theo nào.</translation>
-<translation id="8882002077197914455">Tiêu đề hàng</translation>
-<translation id="8896347895970027998">Chuyển đổi ChromeVox giữa trạng thái hoạt động hoặc không hoạt động.</translation>
-<translation id="8898516272131543774">Nói dấu câu theo chu trình</translation>
-<translation id="8900148057318340779">Phím tiền tố</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">Tiêu đề trống</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">Phím bổ trợ</translation>
-<translation id="8943175951035496220">Không có ô nào bên phải.</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">tệp</translation>
-<translation id="9027462562263121875">Không có bảng nào.</translation>
-<translation id="9040132695316389094">Tiêu đề 1</translation>
-<translation id="9043969572162476692"><ph name="NUM" />%</translation>
-<translation id="9061915073547935367">Bật/tắt tiện ích tìm kiếm</translation>
-<translation id="9065283790526219006">+cửa sổ bật lên</translation>
-<translation id="9077213568694924680">đã xóa khỏi lựa chọn</translation>
-<translation id="9082874451376019682">Không có thanh trượt trước nào.</translation>
-<translation id="9089864840575085222">Nói khi nhập theo chu trình</translation>
-<translation id="9107530006868467849">Không có tiện ích phương tiện trước nào.</translation>
-<translation id="9108370397979208512">toán học</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{dấu phần trăm}other{# dấu phần trăm}}</translation>
-<translation id="9115913704608474258">Tháng 11</translation>
-<translation id="9128414153595658330">dlg</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">Thông báo mô tả ngắn của vị trí hiện tại</translation>
-<translation id="9153606228985488238">Cao độ <ph name="PERCENT" /> phần trăm</translation>
-<translation id="9160096769946561184">Đi tới cuối cột hiện tại</translation>
-<translation id="9173115498289768110">Âm lượng <ph name="PERCENT" /> phần trăm</translation>
-<translation id="9178973770513562274">Sử dụng phím mũi tên lên và xuống để duyệt hoặc nhập để tìm kiếm.</translation>
-<translation id="9192904702577636854">Bảng chữ chạy</translation>
-<translation id="9212322457209634662">Không có phần tiếp theo nào.</translation>
-<translation id="930275611743429116">Lựa chọn bắt đầu hoặc kết thúc.</translation>
-<translation id="948171205378458592">Giảm tốc độ nói</translation>
-<translation id="962913030769097253">Tiêu đề cấp 1 tiếp theo</translation>
-<translation id="973955474346881951">Bật/tắt chế độ cố định</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-CN.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-CN.xtb
deleted file mode 100644
index 7388b040558..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-CN.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="zh-CN">
-<translation id="1012173283529841972">列表项</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">已跨行或跨列。</translation>
-<translation id="1025074108959230262">已停用粘滞模式</translation>
-<translation id="1031961866430398710">再按</translation>
-<translation id="1044777062731150180">无标题</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">输入内容无效</translation>
-<translation id="1082209053475788238">不存在上一个6级标题。</translation>
-<translation id="1088219014394087294">无标题。</translation>
-<translation id="1106741348836243114">开启或关闭声音反馈(耳标)。</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">包含<ph name="NUM" />个项的“<ph name="TAG" />”集</translation>
-<translation id="1155043339247954670">不存在下一个列表项。</translation>
-<translation id="1157782847298808853">键盘帮助</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />,<ph name="NAME" />,组合框</translation>
-<translation id="1167230103353892028"><ph name="NAME" />,菜单项,包含子菜单</translation>
-<translation id="1177863135347784049">自定义</translation>
-<translation id="1188858454923323853">补充内容</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox - 为Chrome提供语音功能</translation>
-<translation id="1229276918471378188">上一个跳转</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">下一个6级标题</translation>
-<translation id="1275718070701477396">已选中</translation>
-<translation id="1319608975892113573">不存在上一段引用。</translation>
-<translation id="1321576897702511272">隐藏ChromeVox帮助</translation>
-<translation id="1331702245475014624">第<ph name="INDEX" />个,共<ph name="TOTAL" />个</translation>
-<translation id="1334095593597963605">字符和字词回显</translation>
-<translation id="1339428534620983148">表格上一列</translation>
-<translation id="1342835525016946179">文章标记</translation>
-<translation id="1346748346194534595">向右</translation>
-<translation id="136718599399906424">表格下一行</translation>
-<translation id="1383876407941801731">搜索</translation>
-<translation id="1385214448885562192">按回车键可接受,按退出键可取消;按向下箭头键可移至下一条搜索结果,按向上箭头键可移至上一条搜索结果。</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">区域</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />,密码文本框</translation>
-<translation id="1467432559032391204">向左</translation>
-<translation id="1474557363159888097">不存在上一个定位点。</translation>
-<translation id="1502086903961450562">上一个图形</translation>
-<translation id="1506187449813838456">调高音调</translation>
-<translation id="151784044608172266">下一个句子</translation>
-<translation id="1524531499102321782">下一行盲文</translation>
-<translation id="1546370775711804143">滚动条</translation>
-<translation id="1559739829547075274">向后导航</translation>
-<translation id="1571643229714746283">ChromeVox已就绪</translation>
-<translation id="158493514907962286">12月</translation>
-<translation id="1594072653727561613">菜单</translation>
-<translation id="1610130962244179598">切换到6点式盲文</translation>
-<translation id="1611168825862729585">列标题:</translation>
-<translation id="1613476421962910979">已开启耳标</translation>
-<translation id="1618597272655350600">读出关于当前位置的完整说明</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{1个大于号}other{#个大于号}}</translation>
-<translation id="1653266918374749391">上一个3级标题</translation>
-<translation id="1659072772017912254">未选中</translation>
-<translation id="1669290819662866522">周</translation>
-<translation id="1674262202423278359">ChromeVox导航</translation>
-<translation id="16777221443363124">菜单栏</translation>
-<translation id="1692077714702418899">结构线</translation>
-<translation id="1700517974991662022">访问过</translation>
-<translation id="1722567105086139392">链接</translation>
-<translation id="1727806147743597030">页脚标记</translation>
-<translation id="174268867904053074">下一个图形</translation>
-<translation id="1781173782405573156">忽略按键</translation>
-<translation id="1787176709638001873">密码编辑文本</translation>
-<translation id="1810107444790159527">列表框</translation>
-<translation id="1828385960365606039">5月</translation>
-<translation id="1834891354138622109">列</translation>
-<translation id="1865601187525349519">文本末尾</translation>
-<translation id="1876229593313240038">文档</translation>
-<translation id="188130072164734898">说出当前的日期和时间。</translation>
-<translation id="1902396333223336119">单元格</translation>
-<translation id="1905379170753160525">显示标题列表</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">年周数控件</translation>
-<translation id="1964135212174907577">下一个对象</translation>
-<translation id="1969092762068865084">7月</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">行标题:</translation>
-<translation id="2002895034995108595">重置当前的按键映射</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{1个左方括号}other{#个左方括号}}</translation>
-<translation id="2045490512405922022">未选中</translation>
-<translation id="20601713649439366">不存在上一个数学表达式。</translation>
-<translation id="207477615537953741">关闭语义解释</translation>
-<translation id="2086961585857038472">下一个字词</translation>
-<translation id="2089387485033699258">zh-CN</translation>
-<translation id="2091933974477985526">上一个可编辑的文本区域</translation>
-<translation id="2100350898815792233">读出所有标点符号</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">快捷键:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">从以下列表中选择某个选项,即可更改当前的6点式盲文表。</translation>
-<translation id="2169714232367507776">点击当前项</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{1个右圆括号}other{#个右圆括号}}</translation>
-<translation id="2199994615414171367">上一个数学元素</translation>
-<translation id="2223693656926968778">对当前项执行操作</translation>
-<translation id="225732394367814946">加快语速</translation>
-<translation id="2267945578749931355">下一个字符</translation>
-<translation id="2281234842553884450">上一个滑块</translation>
-<translation id="2318372665160196757">主体内容</translation>
-<translation id="2329324941084714723">标签面板</translation>
-<translation id="2344193891939537199">日期时间控件</translation>
-<translation id="2359897517538099099">当前不是表格模式。</translation>
-<translation id="241124561063364910">然后按</translation>
-<translation id="2417569100218200841">内容信息</translation>
-<translation id="2422937916923936891">菜单项复选框</translation>
-<translation id="2429669115401274487">下午</translation>
-<translation id="2435413342408885429">“<ph name="KEY" />”现已设为新的ChromeVox辅助键。</translation>
-<translation id="2450814015951372393">复选框</translation>
-<translation id="2462626033734746142">单选按钮组</translation>
-<translation id="2471138580042810658">6级标题标记</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{1个星号}other{#个星号}}</translation>
-<translation id="2549392850788122959">已重置“<ph name="KEY" />”。</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">群组</translation>
-<translation id="2582407057977008361">边栏内容</translation>
-<translation id="2589102159832527089">该网页包含自动从PDF文件&lt;b&gt;<ph name="FILENAME" />&lt;/b&gt;中提取的文本。&lt;a href="<ph name="URL" />"&gt;点击此处可获取原始文本&lt;/a&gt;。</translation>
-<translation id="2606210917827248971">包含 {COUNT,plural, =1{# 项内容}other{# 项内容}}</translation>
-<translation id="2614981083756825552">数学标记语言布局</translation>
-<translation id="2626530649491650971">可点击</translation>
-<translation id="2628764385451019380">不存在上一个组合框。</translation>
-<translation id="2637227747952042642">数学对象</translation>
-<translation id="2639750663247012216">ChromeVox辅助键</translation>
-<translation id="2644542693584024604">拼写错误</translation>
-<translation id="2667291555398229137">点击路由键下的项</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{1个左圆括号}other{#个左圆括号}}</translation>
-<translation id="2705875883745373140">未按下</translation>
-<translation id="2706462751667573066">向上箭头键</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">音频</translation>
-<translation id="2732718972699418926">上午</translation>
-<translation id="2749275490991666823">已选中</translation>
-<translation id="27527859628328957">跳转到下一个可设置为焦点的项</translation>
-<translation id="2770781857296573485">进入群组浏览</translation>
-<translation id="2777845298774924149">已退出</translation>
-<translation id="2800204403141299078">没有其他任何元素。</translation>
-<translation id="2800780099804980316">不存在上一个1级标题。</translation>
-<translation id="2811204574343810641">行</translation>
-<translation id="2816654101880605877">不存在下一个滑块。</translation>
-<translation id="2841013758207633010">时间</translation>
-<translation id="2843837985843789981">上一个群组</translation>
-<translation id="2844995807198708617">上下文菜单</translation>
-<translation id="2849332794118375855">不存在下一个复选框。</translation>
-<translation id="2864481629947106776">上一个链接</translation>
-<translation id="2873259058405069099">转到表格开头</translation>
-<translation id="2894654529758326923">信息</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{1个左大括号}other{#个左大括号}}</translation>
-<translation id="2911433807131383493">打开ChromeVox教程</translation>
-<translation id="2932083475399492303">在结构线或布局线类型之间切换</translation>
-<translation id="2964026537669811554">标题组</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{1个制表符}other{#个制表符}}</translation>
-<translation id="2972078295414139404">不存在上一个访问过的链接。</translation>
-<translation id="2972205263822847197">提示</translation>
-<translation id="2998131015536248178">上一个字符</translation>
-<translation id="2999559350546931576">调低音高</translation>
-<translation id="2999945368667127852">不存在下一个媒体小部件。</translation>
-<translation id="3012414509011670858">不存在上一章节。</translation>
-<translation id="3030432017085518523">菜单项单选按钮</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{1个单引号}other{#个单引号}}</translation>
-<translation id="3046838483509668188">ChromeVox选项</translation>
-<translation id="3047143736589213134">实验性按键映射</translation>
-<translation id="3060756054951570867">已打开“<ph name="TITLE" />”菜单</translation>
-<translation id="3078345202707391975">下一个2级标题</translation>
-<translation id="3078740164268491126">表格</translation>
-<translation id="3082557070674409251">已点击</translation>
-<translation id="3084806535845658316">无输入回显</translation>
-<translation id="3086746722712840547">备注</translation>
-<translation id="308895241372589742">不存在下一个数学表达式。</translation>
-<translation id="3090532668523289635">群组</translation>
-<translation id="3093176084511590672">下一个地标</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">提醒对话框</translation>
-<translation id="3109724472072898302">已收起</translation>
-<translation id="3134461040845705080">只读</translation>
-<translation id="3138767756593758860">显示地标列表</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">下一行</translation>
-<translation id="3155083529632865074">不存在上一个按钮。</translation>
-<translation id="3163593631834463955">列标题为空</translation>
-<translation id="316542773973815724">导航</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{1个空格}other{#个空格}}</translation>
-<translation id="320961988183078793">进入了<ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />,标签页</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">访问过的链接</translation>
-<translation id="323731244387692321">打开ChromeVox键盘帮助</translation>
-<translation id="3241052487511142956">上一个访问过的链接</translation>
-<translation id="3286390186030710347">滑块</translation>
-<translation id="3299925995433437805">不存在下一个访问过的链接。</translation>
-<translation id="3303384412438961941">按任意键可了解对应的名称。按CTRL+W可关闭Keyboard Explorer。</translation>
-<translation id="3307886118343381874">转到表格末尾</translation>
-<translation id="3311969765485641742">按Alt+Shift+A即可查看所有提醒</translation>
-<translation id="3312997241656799641">下一个访问过的链接</translation>
-<translation id="3321460131042519426">启用自动换行</translation>
-<translation id="3322936298410871309">上一个1级标题</translation>
-<translation id="3323447499041942178">文本框</translation>
-<translation id="3353420241558113817">{"ar": "阿拉伯语",
- "bg": "保加利亚语",
- "ca": "加泰罗尼亚语",
- "cs": "捷克语",
- "da": "丹麦语",
- "de": "德语",
- "de_CH": "德语(瑞士)",
- "de_DE": "德语(德国)",
- "el": "希腊语",
- "en": "英语",
- "en_CA": "英语(加拿大)",
- "en_GB": "英语(英国)",
- "en_US": "英语(美国)",
- "es": "西班牙语",
- "et": "爱沙尼亚语",
- "fr": "法语",
- "fr_CA": "法语(加拿大)",
- "fr_FR": "法语(法国)",
- "fi": "芬兰语",
- "he": "希伯来语",
- "hi": "印地语",
- "hr": "克罗地亚语",
- "hu": "匈牙利语",
- "is": "冰岛语",
- "it": "意大利语",
- "ko": "韩语",
- "lt": "立陶宛语",
- "lv": "拉脱维亚语",
- "nb": "挪威博克马尔语",
- "nl": "荷兰语",
- "pl": "波兰语",
- "pt": "葡萄牙语",
- "ro": "罗马尼亚语",
- "ru": "俄语",
- "sk": "斯洛伐克语",
- "sl": "斯洛文尼亚语",
- "sr": "塞尔维亚语",
- "sv": "瑞典语",
- "tr": "土耳其语",
- "vi": "越南语",
- "zh": "中文",
- "zh_TW": "中文(繁体)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{1个加号}other{#个加号}}</translation>
-<translation id="338583716107319301">分隔符</translation>
-<translation id="3389259863310851658">上一个表单字段</translation>
-<translation id="3390225400784126843">下一个不同元素。</translation>
-<translation id="3392045790598181549"><ph name="NAME" />,菜单项</translation>
-<translation id="3406283310380167331">显示表单列表</translation>
-<translation id="3422338090358345848">打开Keyboard Explorer</translation>
-<translation id="3457000393508828486">部分已按下</translation>
-<translation id="3462439746547587373"><ph name="NAME" />,按钮</translation>
-<translation id="3473644018603298796">已选择<ph name="COUNT" />项</translation>
-<translation id="3486232535569802404"><ph name="V1" />到<ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{1个右方括号}other{#个右方括号}}</translation>
-<translation id="3493915602752813531">不存在下一个定位点。</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{1个问号}other{#个问号}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{1个插入符号}other{#个插入符号}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />,未选中的复选框</translation>
-<translation id="3599054940393788245">非数学范畴</translation>
-<translation id="3616113530831147358">音频</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{1个反撇号}other{#个反撇号}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{1个美元符号}other{#个美元符号}}</translation>
-<translation id="3659787053479271466">提醒</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />,列表框</translation>
-<translation id="3687295507293856493">推测当前单元格的列标题</translation>
-<translation id="3692274950075847560">搜索结果:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">控制语音</translation>
-<translation id="3716845769494773620">多行</translation>
-<translation id="3731746171184829332">不存在上一个标题。</translation>
-<translation id="3762198587642264450">转到当前行的末尾</translation>
-<translation id="3777255250339039212">1级标题标记</translation>
-<translation id="3793710123303304873">已退出对话框。</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">自动填充列表</translation>
-<translation id="3810838688059735925">视频</translation>
-<translation id="3816633764618089385">下一个媒体内容</translation>
-<translation id="3819376190738087562">无跳转内容。</translation>
-<translation id="385383972552776628">打开选项页面</translation>
-<translation id="3856075812838139784">只读</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">菜单</translation>
-<translation id="3909320334364316587">上一个6级标题</translation>
-<translation id="3914173277599553213">必需</translation>
-<translation id="3962990492275676168">从当前位置开始读</translation>
-<translation id="4004802134384979325">已选中</translation>
-<translation id="4006140876663370126">图片</translation>
-<translation id="4038349100599457191">月份控件</translation>
-<translation id="4039983576244166038">行标题为空</translation>
-<translation id="4042843249978639960">不存在下一个2级标题。</translation>
-<translation id="4043348641337972076">不存在上一个ARIA地标。</translation>
-<translation id="4047216625641135770">标记</translation>
-<translation id="404803211695627272"><ph name="V1" />到<ph name="V2" /></translation>
-<translation id="4054936709456751127">状态</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{1个波浪号}other{#个波浪号}}</translation>
-<translation id="409334809956508737">上一个对象</translation>
-<translation id="4099274309791143834">包含子菜单</translation>
-<translation id="4107807507418787238">下方不存在单元格。</translation>
-<translation id="4116415223832267137">提醒</translation>
-<translation id="4147126331795725888">不存在下一个控件。</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{1个右大括号}other{#个右大括号}}</translation>
-<translation id="4158704014418536539">区分大小写。</translation>
-<translation id="4161663686871496107">ChromeVox语音反馈已就绪</translation>
-<translation id="4173994908659439270">不存在下一个可编辑的文本字段。</translation>
-<translation id="4176463684765177261">已停用</translation>
-<translation id="4188530942454211480">上一个句子</translation>
-<translation id="4202186506458631436">右移</translation>
-<translation id="4206289001967551965">在表格内</translation>
-<translation id="4215733775853809057">下一个滑块</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{1个破折号}other{#个破折号}}</translation>
-<translation id="421884353938374759">颜色选择器</translation>
-<translation id="4229646983878045487">日期时间</translation>
-<translation id="423334822609210999">左侧不存在单元格。</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />,<ph name="GRADE" />级</translation>
-<translation id="4253168017788158739">备注</translation>
-<translation id="4254798249533888099">树状</translation>
-<translation id="4255943572433203166">您可以使用以下选项来自定义ChromeVox。所有更改均会立即生效。</translation>
-<translation id="4271220233568730077">下一个数学元素</translation>
-<translation id="4271521365602459209">没有其他结果了。</translation>
-<translation id="4287520460805643128">不存在下一篇文章。</translation>
-<translation id="4289540628985791613">概述</translation>
-<translation id="4300318234632215983">读出链接网址</translation>
-<translation id="4301352596632316575">包含子菜单</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{1个点}=3{3个点}other{#个点}}</translation>
-<translation id="4347461890115250064">不存在下一个列表。</translation>
-<translation id="4367650418938037324">数学标记语言叶</translation>
-<translation id="4372435075475052704">最小值为<ph name="X" /></translation>
-<translation id="4372705107434148843">关闭语音</translation>
-<translation id="4373197658375206385">不存在上一个非链接项。</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">重置</translation>
-<translation id="4471074325120394300">无任何链接。</translation>
-<translation id="4476183483923481720">换行</translation>
-<translation id="4482330759234983253">上一个表格</translation>
-<translation id="4491109536499578614">图片</translation>
-<translation id="4529987814483543472">传统键映射</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{1个斜线符号}other{#个斜线符号}}</translation>
-<translation id="4547556996012970016">下一个5级标题</translation>
-<translation id="4562381607973973258">标头标记</translation>
-<translation id="4591507479202817876">,已选中</translation>
-<translation id="4597532268155981612">表单</translation>
-<translation id="4597896406374528575">4月</translation>
-<translation id="4615592953348396470">将忽略下一次按键</translation>
-<translation id="461613135510474570">逐句</translation>
-<translation id="4647836961514597010">颜色选择器</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">网格</translation>
-<translation id="4693675773662933727">上一个地标</translation>
-<translation id="4696413482802371445">不存在下一个5级标题。</translation>
-<translation id="4729095194763193578">表格上一行</translation>
-<translation id="4736221692378411923">8月</translation>
-<translation id="4740661827607246557">帮助命令</translation>
-<translation id="4759716709594980008">Chrome操作系统Keyboard Explorer</translation>
-<translation id="4763296182459741068">转至底部</translation>
-<translation id="4763480195061959176">视频</translation>
-<translation id="479989351350248267">搜索</translation>
-<translation id="481165870889056555">读出当前页面的标题</translation>
-<translation id="4826415162591436065">向前导航</translation>
-<translation id="4826604887384865800">下一个跳转</translation>
-<translation id="4827410568042294688">已取消选中</translation>
-<translation id="4842108708071771135">不存在下一个块引用。</translation>
-<translation id="4848993367330139335">计时器</translation>
-<translation id="4850023505158945298">上一个类似元素。</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">启用TTS日志记录</translation>
-<translation id="4877261390094455813">输入搜索查询内容。</translation>
-<translation id="4886524826165775965">第<ph name="INDEX" />项,共<ph name="TOTAL" />项</translation>
-<translation id="489907760999452556">内部链接</translation>
-<translation id="4953585991029886728">编辑文本</translation>
-<translation id="4954534434583049121">上一个块引用</translation>
-<translation id="4973717656530883744">最小值为<ph name="X" /></translation>
-<translation id="4973762002207131920">已切换到“<ph name="KEY" />”。</translation>
-<translation id="4975416682604111799">毫秒</translation>
-<translation id="49787999531187221">ChromeVox目前已停用。</translation>
-<translation id="4979404613699303341">上一个按钮</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />,<ph name="NAME" />,列表框</translation>
-<translation id="4983588134362688868">跳至页首</translation>
-<translation id="4986606102545753256"><ph name="NAME" />,窗口</translation>
-<translation id="4993152509206108683">语速为<ph name="PERCENT" />%</translation>
-<translation id="4996716799442435517">可视区域</translation>
-<translation id="4997282455736854877"><ph name="NAME" />,已选中的单选按钮</translation>
-<translation id="4997475792277222884">不存在下一个非链接项。</translation>
-<translation id="5000760171916499057">无表单。</translation>
-<translation id="5005670136041063723">不存在其他类似元素。</translation>
-<translation id="501473567976723023">1月</translation>
-<translation id="5041394372352067729">将盲文显示移动到页首</translation>
-<translation id="5042770794184672516">调大朗读音量</translation>
-<translation id="5050015258024679800">上一个4级标题</translation>
-<translation id="5054047268577924192">上一个列表项</translation>
-<translation id="5078661581131202757">文件选择</translation>
-<translation id="5080758118274074384">已双击</translation>
-<translation id="5098541983634824365">即将离开网格。</translation>
-<translation id="5102981729317424850">工具栏</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">不存在上一个表单字段。</translation>
-<translation id="5111640677200759579">列标题</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">不存在上一个链接。</translation>
-<translation id="513774504516943387">链接</translation>
-<translation id="517143700877085897">,未选中</translation>
-<translation id="5183440668879371625">上一行盲文</translation>
-<translation id="5184944171021383281">不存在下一个表单字段。</translation>
-<translation id="5189244881767082992">行</translation>
-<translation id="5203930734796605961"><ph name="KEY" />已分配给某个命令。</translation>
-<translation id="5205493599117157272"><ph name="TYPE" />类列表。</translation>
-<translation id="520883772648104506">不存在下一个单选按钮。</translation>
-<translation id="5263344797180442561">2级标题标记</translation>
-<translation id="528468243742722775">End</translation>
-<translation id="5291783959063340370">对象</translation>
-<translation id="5304943142864553931">切换到名为“<ph name="TITLE" />”的标签页</translation>
-<translation id="5310788376443009632">已移除:</translation>
-<translation id="5320727453979144100">已启用粘滞模式</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{1个英文逗号}other{#个英文逗号}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />,文本框</translation>
-<translation id="5330443287809544590"><ph name="NAME" />,链接</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">连续朗读时向后跳转</translation>
-<translation id="5368000168321181111">已关闭耳标</translation>
-<translation id="5374320867641260420">不存在下一个按钮。</translation>
-<translation id="5382299583965267720">不存在下一个1级标题。</translation>
-<translation id="5402367795255837559">盲文</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{1个分号}other{#个分号}}</translation>
-<translation id="5411891038905756502">不存在上一个跳转点。</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{1个小于号}other{#个小于号}}</translation>
-<translation id="5455441614648621694">补充的内容</translation>
-<translation id="5485036206801896268">不存在上一个图形。</translation>
-<translation id="5486947920110100234">不存在下一个跳转点。</translation>
-<translation id="549602578321198708">逐字</translation>
-<translation id="5500932716852106146">不存在上一个可编辑的文本字段。</translation>
-<translation id="5502713021410870035">9月</translation>
-<translation id="5507663321906818013">调试基准</translation>
-<translation id="5518443085409638729">编辑文本时将光标置于字符之间(与Mac OS X类似)。</translation>
-<translation id="552195134157544755">单选按钮</translation>
-<translation id="5534303576632885660">标头标记</translation>
-<translation id="5546092960038624944">不存在上一个5级标题。</translation>
-<translation id="556042886152191864">按钮</translation>
-<translation id="5561345396546889625">下一个列表</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">退格</translation>
-<translation id="5585044216466955529">编辑文本,电子邮件条目</translation>
-<translation id="5597170376237141345">下一个复选框</translation>
-<translation id="5597933780944041114">不存在下一个标题。</translation>
-<translation id="5598905979683743333"><ph name="NAME" />,未选中的单选按钮</translation>
-<translation id="5601172225407283979">执行默认操作</translation>
-<translation id="5608798115546226984">自动填充内嵌</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">日志</translation>
-<translation id="5628125749885014029">4级标题标记</translation>
-<translation id="5637871198229500030">不存在上一个表格。</translation>
-<translation id="5655682562155942719">跳转命令</translation>
-<translation id="56637627897541303">文本区域</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">定义</translation>
-<translation id="5682113568322255809">地标</translation>
-<translation id="5683155931978483559">上一个复选框</translation>
-<translation id="5684277895745049190">列表</translation>
-<translation id="5700650669149824506">不存在上一个4级标题。</translation>
-<translation id="5709192780268610569">无详细说明</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">表格下一列</translation>
-<translation id="571866080859340309">正在浏览群组</translation>
-<translation id="5728409797179002635">找不到表格。</translation>
-<translation id="5748623122140342504">上一个5级标题</translation>
-<translation id="5750633686117194034">尚未按下任何辅助键;请按住一个或多个辅助键;完成后即可松开您的手指,此时您会听到相应键已成功设置的提示音。要退出,请按Tab键。</translation>
-<translation id="5788275253279308023">在隐身窗口中打开“<ph name="TITLE" />”标签页</translation>
-<translation id="5806206155699461681">改善特定网站(如Google搜索)的用户体验。</translation>
-<translation id="5819072574982403430">树状目录项</translation>
-<translation id="5826479389509458994">第<ph name="ROW" />行,第<ph name="COL" />列</translation>
-<translation id="5850707923114094062">向后平移</translation>
-<translation id="5851548754964597211">标签列表</translation>
-<translation id="5859752971144398932">已退出“在网页中查找”。</translation>
-<translation id="5866042630553435010">部分选中</translation>
-<translation id="5869546221129391014">网格</translation>
-<translation id="5876817486144482042">调小朗读音量</translation>
-<translation id="5887397643266327462">已启用盲文字幕功能。</translation>
-<translation id="5891934789323004067">表格</translation>
-<translation id="5919442531159595654">复制。</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{1个等号}other{#个等号}}</translation>
-<translation id="5939518447894949180">重置</translation>
-<translation id="5948123859135882163">在数学表达式的结构化解释和语义解释之间来回切换</translation>
-<translation id="5955304353782037793">应用</translation>
-<translation id="5956928062748260866">对话框</translation>
-<translation id="5963413905009737549">章节标记</translation>
-<translation id="5968607524793740041">显示上下文菜单</translation>
-<translation id="5983179082906765664">提高导航精细度</translation>
-<translation id="5999630716831179808">语音</translation>
-<translation id="6000417740266304866">从以下列表中选择某个选项,即可更改当前的8点式盲文表。</translation>
-<translation id="6006050241733874051">表单</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{1个反斜线符号}other{#个反斜线符号}}</translation>
-<translation id="6037602951055904232">向前平移</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">单元格结束。</translation>
-<translation id="6122013438240733403">按钮</translation>
-<translation id="6129953537138746214">空格</translation>
-<translation id="6142308968191113180">4级标题标记</translation>
-<translation id="6169420925157477918">图片含有详细说明</translation>
-<translation id="6172087735260766220">无法读出受版权保护的 PDF 文档中的无障碍文字内容。</translation>
-<translation id="6186305613600865047">跳至页尾</translation>
-<translation id="6193330012414963395">上午 下午</translation>
-<translation id="622484624075952240">向下箭头键</translation>
-<translation id="6236061028292614533">下一个标题</translation>
-<translation id="6254901459154107917">下一个可编辑的文本区域</translation>
-<translation id="6259464875943891919">已退出“<ph name="TYPE" />”。</translation>
-<translation id="6281876499889881039">下一个类似元素。</translation>
-<translation id="6282062888058716985">导航</translation>
-<translation id="6290434000785343030">不存在下一个组合框。</translation>
-<translation id="6307969636681130414">已按下</translation>
-<translation id="6324551002951139333">检测到语法错误</translation>
-<translation id="6348657800373377022">组合框</translation>
-<translation id="6355910664415701303">不存在上一个列表项。</translation>
-<translation id="6364795331201459219">6级标题标记</translation>
-<translation id="6368143427468974988">上一个标题</translation>
-<translation id="6387719785439924554">边栏内容标记</translation>
-<translation id="6411426777058107714">不存在上一个单选按钮。</translation>
-<translation id="6414968628640960377">上一个不同元素。</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{1个冒号}other{#个冒号}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />,菜单</translation>
-<translation id="6444046323172968959">提醒对话框</translation>
-<translation id="6459511626086141404">降调按键映射</translation>
-<translation id="6468049171101508116">下一个按钮</translation>
-<translation id="6491972999578897419">从下面的列表中选择一个选项,即可更改当前语音。</translation>
-<translation id="6508059270146105198">将盲文显示移动到页底</translation>
-<translation id="6536864053412760904">数学标记语言令牌</translation>
-<translation id="6550720799683018100">从下面的列表中选择一个选项,以更改当前键映射。</translation>
-<translation id="6561818612645211875">转到当前行的开头</translation>
-<translation id="6587021927234520429">不存在下一个4级标题。</translation>
-<translation id="6601344353291556895">启用详细说明。</translation>
-<translation id="6615602925644411249">在网页中查找。</translation>
-<translation id="6633350132811819843">不存在下一个表格。</translation>
-<translation id="6637586476836377253">日志</translation>
-<translation id="6657128831881431364">进度条</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">文档</translation>
-<translation id="6697092096875747123">上一个组合框</translation>
-<translation id="6714813999819678458">上一个2级标题</translation>
-<translation id="6716505898850596801">辅助键</translation>
-<translation id="671916444866103745">不存在下一个ARIA地标。</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />,组合框</translation>
-<translation id="6735257939857578167">(包含<ph name="NUM" />个项)</translation>
-<translation id="6736510033526053669">已打开标签页</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">文章</translation>
-<translation id="6787839852456839824">键盘快捷键</translation>
-<translation id="6793101435925451627">列表框</translation>
-<translation id="6833103209700200188">页脚标记</translation>
-<translation id="6871161210040114857">不区分大小写。</translation>
-<translation id="6877435256196695200">不存在下一个图形。</translation>
-<translation id="6897341342232909480">向左移动</translation>
-<translation id="6901540140423170855">日期</translation>
-<translation id="6910211073230771657">已删除</translation>
-<translation id="6911965441508464308">不存在上方单元格。</translation>
-<translation id="6919104639734799681">显示表格列表</translation>
-<translation id="6964088412282673743">不存在上一个控件。</translation>
-<translation id="6996566555547746822">下一个组合框</translation>
-<translation id="7005146664810010831">找不到网址</translation>
-<translation id="7010712454773919705">ChromeVox辅助键</translation>
-<translation id="7031651751836475482">列表项</translation>
-<translation id="7037042857287298941">上一个列表</translation>
-<translation id="7041173719775863268">结束选择</translation>
-<translation id="7095834689119144465">仅修改数字文本</translation>
-<translation id="7096001299300236431">上一个媒体内容</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">字词回显</translation>
-<translation id="713824876195128146">下一个块引用</translation>
-<translation id="7161771961008409533">弹出式按钮</translation>
-<translation id="7167657087543110">字符回显</translation>
-<translation id="7170733337935166589">连续朗读时向前跳转</translation>
-<translation id="7181697990050180700">在下面的相应字段中输入相关内容,即可针对常用命令自定义键盘快捷键。</translation>
-<translation id="7203150201908454328">已展开</translation>
-<translation id="7210211103303402262">分钟</translation>
-<translation id="7217912842225915592">含<ph name="NUM" />项</translation>
-<translation id="7221740160534240920">布局线</translation>
-<translation id="7226216518520804442">列表</translation>
-<translation id="72393384879519786">标题</translation>
-<translation id="7241683698754534149">在新标签页中打开详细说明</translation>
-<translation id="7248671827512403053">应用</translation>
-<translation id="725969808843520477">下一个单选按钮</translation>
-<translation id="7269119382257320590">不读出任何标点符号</translation>
-<translation id="7273174640290488576">空白</translation>
-<translation id="7285387653379749618">表格</translation>
-<translation id="7289186959554153431">3级标题标记</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">已停用盲文字幕功能。</translation>
-<translation id="7318872822751139669">使用鼠标更改焦点内容。</translation>
-<translation id="7322388933135261569">2月</translation>
-<translation id="7332592614823088566">第<ph name="ROWINDEX" />行,共<ph name="ROWTOTAL" />行;第<ph name="COLINDEX" />列,共<ph name="COLTOTAL" />列</translation>
-<translation id="7336596009609913925">带有弹出式组件</translation>
-<translation id="7356165926712028380">切换到8点式盲文</translation>
-<translation id="7362871137496673139">不存在上一个2级标题。</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{1个&amp;号}other{#个&amp;号}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">即将离开表格。</translation>
-<translation id="739763518212184081">上一行</translation>
-<translation id="7400575256015741911">检测到拼写错误</translation>
-<translation id="7408482676469142474">表格标记</translation>
-<translation id="7425395583360211003">回车</translation>
-<translation id="7434509671034404296">开发者</translation>
-<translation id="7439060726180460871">目录</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">标签</translation>
-<translation id="7492049978501397201">已进入对话框</translation>
-<translation id="7532613204005497612">6月</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />,<ph name="NAME" />,滑块</translation>
-<translation id="7586163296341959563">粘贴。</translation>
-<translation id="7596919493010894443">已清除所选内容</translation>
-<translation id="7604026522577407655">转到当前列的开头</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">读出当前页面的网址</translation>
-<translation id="7609363189280667021">切换盲文字幕</translation>
-<translation id="762020119231868829">暂停目前正在播放的所有媒体小部件</translation>
-<translation id="7625690649919402823">下一个表格</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />),等级:<ph name="GRADE" /></translation>
-<translation id="7641134354185483015">不存在上一个3级标题。</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />,<ph name="NAME" />,文本框</translation>
-<translation id="7663318257180412551">2级标题标记</translation>
-<translation id="7674576868851035240">下一个链接</translation>
-<translation id="7674768236845044097">标记</translation>
-<translation id="7684431668231950609">编辑文本,网址条目</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">上一个单选按钮</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />,<ph name="NAME" />,密码文本框</translation>
-<translation id="7805247615045262757">默认导航</translation>
-<translation id="7805768142964895445">状态</translation>
-<translation id="7810781339813764006">下一个群组</translation>
-<translation id="7819187121850078213">在另一个窗口中打开“<ph name="TITLE" />”标签页</translation>
-<translation id="7828956995407538686">10月</translation>
-<translation id="7839679365527550018">上一个字词</translation>
-<translation id="7851816175263618915">读出部分标点符号</translation>
-<translation id="7870596830398826354">数学标记语言树</translation>
-<translation id="78826985582142166">滑块</translation>
-<translation id="7894517696028036636">切换 ChromeVox Classic。</translation>
-<translation id="7895896691902835279">未知链接</translation>
-<translation id="7927711904086083099">未选择</translation>
-<translation id="7935627501098484003">时间控制</translation>
-<translation id="7939428177581522200">已添加到所选文字</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{1个@符号}other{#个@符号}}</translation>
-<translation id="7965147473449754028">菜单已关闭</translation>
-<translation id="7974390230414479278">菜单项</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{1个感叹号}other{#个感叹号}}</translation>
-<translation id="8007540374018858731">3级标题标记</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{1个引号}other{#个引号}}</translation>
-<translation id="8033827949643255796">已选中</translation>
-<translation id="8035962149453661158">最大值为<ph name="X" /></translation>
-<translation id="8042761080832772327">编辑文本,搜索条目</translation>
-<translation id="8049189770492311300">计时器</translation>
-<translation id="8065607967589909823">当前选择为</translation>
-<translation id="8066678206530322333">横幅</translation>
-<translation id="8110647606445335195">无ARIA地标。</translation>
-<translation id="8153880621934657047">不在表格内。</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{1个下划线}other{#个下划线}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">剪切。</translation>
-<translation id="8199231515320852133">读出当前单元格的标题</translation>
-<translation id="820417203470636242">空白单元格。</translation>
-<translation id="8215202828671303819">多选</translation>
-<translation id="8276439074553447000">跳转到上一个可设置为焦点的项</translation>
-<translation id="8278417001922463147">不存在上一篇文章。</translation>
-<translation id="8283603667300770666">下一个表单字段</translation>
-<translation id="831207808878314375">定义</translation>
-<translation id="8313653172105209786">目录</translation>
-<translation id="8344569602005188545">小时</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{1个井号}other{#个井号}}</translation>
-<translation id="8374154622594089836">月份</translation>
-<translation id="8378855320830505539">区域</translation>
-<translation id="8382679411218029383">自动填充内嵌和列表</translation>
-<translation id="8428603554127842284"><ph name="DEPTH" />级</translation>
-<translation id="842922884199979200">不存在下一个3级标题。</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">不存在上一个复选框。</translation>
-<translation id="8455868257606149352">最大值为<ph name="X" /></translation>
-<translation id="84575901236241018">有快捷键,<ph name="KEY" /></translation>
-<translation id="8503360654911991865">降低导航精细度</translation>
-<translation id="8520472399088452386">数值调节按钮</translation>
-<translation id="8538744478902126321">推测当前单元格的行标题</translation>
-<translation id="8540054775867439484">转至顶部</translation>
-<translation id="8548973727659841685">逐个字符</translation>
-<translation id="8561322612995434619">包含弹出式窗口</translation>
-<translation id="8571096049907249734">多选</translation>
-<translation id="8584721346566392021">5级标题标记</translation>
-<translation id="8587549812518406253">下一个列表项</translation>
-<translation id="860150890330522909">已选中“<ph name="NAME" />”复选框</translation>
-<translation id="8606621670302093223">日期控件</translation>
-<translation id="8631359288236106450">已选中<ph name="COUNT" />项</translation>
-<translation id="8638532244051952400">说出当前单元格的坐标</translation>
-<translation id="8650576015643545550">不存在上一个列表。</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">显示链接列表</translation>
-<translation id="8664519043722036194">秒</translation>
-<translation id="867187640362843212">5级标题标记</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{1个竖线符号}other{#个竖线符号}}</translation>
-<translation id="8735450637152821465">开始选择</translation>
-<translation id="8743786158317878347">进入结构化内容,如表格</translation>
-<translation id="8747966237988593539">经过排序的列表</translation>
-<translation id="8759334257841767240">不存在下一个链接。</translation>
-<translation id="8767968232364267681">下一个4级标题</translation>
-<translation id="8770473310765924354">退出结构化内容,如表格</translation>
-<translation id="8791025954632646584">已启用语义解释</translation>
-<translation id="8796411681063377102">下一个3级标题</translation>
-<translation id="8808582214901541005">3月</translation>
-<translation id="8825828890761629845">横幅</translation>
-<translation id="8851136666856101339">主体内容</translation>
-<translation id="8856538297388979332">按上下箭头键可查看命令,按回车键可激活</translation>
-<translation id="8864099967139188018">不存在下一个6级标题。</translation>
-<translation id="8882002077197914455">行标题</translation>
-<translation id="8896347895970027998">在启用或停用ChromeVox之间切换。</translation>
-<translation id="8898516272131543774">循环标点符号回显</translation>
-<translation id="8900148057318340779">前缀键</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">标题为空</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">辅助键</translation>
-<translation id="8943175951035496220">不存在右侧单元格。</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">文件</translation>
-<translation id="9027462562263121875">无表格。</translation>
-<translation id="9040132695316389094">1级标题标记</translation>
-<translation id="9043969572162476692">百分之<ph name="NUM" /></translation>
-<translation id="9061915073547935367">切换搜索小工具</translation>
-<translation id="9065283790526219006">含弹出项</translation>
-<translation id="9077213568694924680">已从所选文字中移除</translation>
-<translation id="9082874451376019682">不存在上一个滑块。</translation>
-<translation id="9089864840575085222">循环输入回显</translation>
-<translation id="9107530006868467849">不存在上一个媒体小部件。</translation>
-<translation id="9108370397979208512">数学</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{1个百分号}other{#个百分号}}</translation>
-<translation id="9115913704608474258">11月</translation>
-<translation id="9128414153595658330">对话框</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">读出关于当前位置的简短说明</translation>
-<translation id="9153606228985488238">音高为<ph name="PERCENT" />%</translation>
-<translation id="9160096769946561184">转到当前列的末尾</translation>
-<translation id="9173115498289768110">音量:<ph name="PERCENT" />%</translation>
-<translation id="9178973770513562274">使用上下箭头键进行浏览,或者直接输入搜索字词。</translation>
-<translation id="9192904702577636854">滚动图片</translation>
-<translation id="9212322457209634662">不存在下一章节。</translation>
-<translation id="930275611743429116">开始或结束选择。</translation>
-<translation id="948171205378458592">减慢语速</translation>
-<translation id="962913030769097253">下一个1级标题</translation>
-<translation id="973955474346881951">启用/停用粘滞模式</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb
deleted file mode 100644
index d7d90fe6d8c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb
+++ /dev/null
@@ -1,748 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE translationbundle>
-<translationbundle lang="zh-TW">
-<translation id="1012173283529841972">清單項目</translation>
-<translation id="1013742170491673792">srched</translation>
-<translation id="1023866615269196768">已擴展。</translation>
-<translation id="1025074108959230262">固定模式已停用</translation>
-<translation id="1031961866430398710">然後按下</translation>
-<translation id="1044777062731150180">沒有標題</translation>
-<translation id="106222400312645156">rwhdr</translation>
-<translation id="1065552602950927991">輸入無效</translation>
-<translation id="1082209053475788238">沒有上一個第 6 階標題。</translation>
-<translation id="1088219014394087294">沒有標題。</translation>
-<translation id="1106741348836243114">開啟或關閉音效回饋 (聽覺標示)。</translation>
-<translation id="1120743664840974483">{"a": "alpha", "b": "bravo", "c": "charlie", "d": "delta", "e": "echo", "f": "foxtrot", "g": "golf", "h": "hotel", "i": "india", "j": "juliet","k": "kilo", "l": "lima", "m": "mike", "n": "november", "o": "oscar","p": "papa", "q": "quebec", "r": "romeo", "s": "sierra", "t": "tango", "u": "uniform", "v": "victor", "w": "whiskey","x": "xray", "y": "yankee", "z": "zulu"}</translation>
-<translation id="113582498867142724">「<ph name="TAG" />」集 (共 <ph name="NUM" /> 個項目)</translation>
-<translation id="1155043339247954670">沒有下一個清單項目。</translation>
-<translation id="1157782847298808853">鍵盤說明</translation>
-<translation id="1157843803349774103"><ph name="VALUE" />,<ph name="NAME" />,下拉式方塊</translation>
-<translation id="1167230103353892028"><ph name="NAME" />,選單項目 (含子選單)</translation>
-<translation id="1177863135347784049">自訂</translation>
-<translation id="1188858454923323853">補充</translation>
-<translation id="1206619573307042055">marquee</translation>
-<translation id="1213216066620407844">ChromeVox:為 Chrome 提供語音朗讀功能</translation>
-<translation id="1229276918471378188">上一個跳轉</translation>
-<translation id="1237866625126425153">rdgrp</translation>
-<translation id="1251750620252348585">下一個第 6 階標題</translation>
-<translation id="1275718070701477396">已選取</translation>
-<translation id="1319608975892113573">沒有上一個引用標記。</translation>
-<translation id="1321576897702511272">隱藏 ChromeVox 說明</translation>
-<translation id="1331702245475014624">第 <ph name="INDEX" /> 個,共 <ph name="TOTAL" /> 個</translation>
-<translation id="1334095593597963605">字元和字詞語音回應</translation>
-<translation id="1339428534620983148">上一個表格欄</translation>
-<translation id="1342835525016946179">文章</translation>
-<translation id="1346748346194534595">向右</translation>
-<translation id="136718599399906424">下一個表格列</translation>
-<translation id="1383876407941801731">搜尋</translation>
-<translation id="1385214448885562192">按 Enter 鍵接受或 Esc 鍵取消;按向下鍵可移至下一個搜尋結果,按向上鍵可移至上一個搜尋結果。</translation>
-<translation id="1396114365388024581">tablst</translation>
-<translation id="1439316808600711881">區域</translation>
-<translation id="1452236308086741652"><ph name="VALUE" />,密碼文字方塊</translation>
-<translation id="1467432559032391204">向左</translation>
-<translation id="1474557363159888097">沒有上一個錨點。</translation>
-<translation id="1502086903961450562">上一個圖形</translation>
-<translation id="1506187449813838456">提高音調</translation>
-<translation id="151784044608172266">下一句</translation>
-<translation id="1524531499102321782">下一行點字</translation>
-<translation id="1546370775711804143">捲軸</translation>
-<translation id="1559739829547075274">向後導覽</translation>
-<translation id="1571643229714746283">ChromeVox 已啟用</translation>
-<translation id="158493514907962286">12 月</translation>
-<translation id="1594072653727561613">選單</translation>
-<translation id="1610130962244179598">切換至 6 點點字</translation>
-<translation id="1611168825862729585">欄標題:</translation>
-<translation id="1613476421962910979">聽覺標示已開啟</translation>
-<translation id="1618597272655350600">朗讀目前位置的完整說明</translation>
-<translation id="1639634871799530612">{COUNT,plural, =1{大於符號}other{# 個大於符號}}</translation>
-<translation id="1653266918374749391">上一個第 3 階標題</translation>
-<translation id="1659072772017912254">未勾選</translation>
-<translation id="1669290819662866522">週</translation>
-<translation id="1674262202423278359">ChromeVox 導覽</translation>
-<translation id="16777221443363124">選單列</translation>
-<translation id="1692077714702418899">結構化的行</translation>
-<translation id="1700517974991662022">曾經造訪過</translation>
-<translation id="1722567105086139392">連結</translation>
-<translation id="1727806147743597030">頁尾</translation>
-<translation id="174268867904053074">下一個圖形</translation>
-<translation id="1781173782405573156">忽略按鍵</translation>
-<translation id="1787176709638001873">密碼文字</translation>
-<translation id="1810107444790159527">清單方塊</translation>
-<translation id="1828385960365606039">5 月</translation>
-<translation id="1834891354138622109">欄</translation>
-<translation id="1865601187525349519">文字結束</translation>
-<translation id="1876229593313240038">文件</translation>
-<translation id="188130072164734898">說出目前的時間和日期。</translation>
-<translation id="1902396333223336119">儲存格</translation>
-<translation id="1905379170753160525">顯示標題清單</translation>
-<translation id="1912556590115083156">vlnk</translation>
-<translation id="1913761808037590218">#ed</translation>
-<translation id="1954623340234317532">週次控制項</translation>
-<translation id="1964135212174907577">下一個物件</translation>
-<translation id="1969092762068865084">7 月</translation>
-<translation id="1973886230221301399">ChromeVox</translation>
-<translation id="1990932729021763163">列標題:</translation>
-<translation id="2002895034995108595">重設目前的按鍵對應配置</translation>
-<translation id="2007545860310005685">{COUNT,plural, =1{左中括弧}other{# 個左中括弧}}</translation>
-<translation id="2045490512405922022">未勾選</translation>
-<translation id="20601713649439366">沒有上一個數學運算式。</translation>
-<translation id="207477615537953741">語意轉譯功能已關閉</translation>
-<translation id="2086961585857038472">下一個字詞</translation>
-<translation id="2089387485033699258">en</translation>
-<translation id="2091933974477985526">上一個可編輯的文字區域</translation>
-<translation id="2100350898815792233">所有標點符號</translation>
-<translation id="2119965627982867824">spnbtn</translation>
-<translation id="2121067395472282800">快捷鍵:<ph name="KEY" /></translation>
-<translation id="2155457205053847599">如要變更目前的 6 點點字表,請從下方清單中選取適當的選項。</translation>
-<translation id="2169714232367507776">按一下目前的項目</translation>
-<translation id="2188751878842439466">{COUNT,plural, =1{右括弧}other{# 個右括弧}}</translation>
-<translation id="2199994615414171367">上一個數學元素</translation>
-<translation id="2223693656926968778">對目前的項目進行操作</translation>
-<translation id="225732394367814946">加快說話速度</translation>
-<translation id="2267945578749931355">下一個字元</translation>
-<translation id="2281234842553884450">上一個滑桿</translation>
-<translation id="2318372665160196757">主要元素</translation>
-<translation id="2329324941084714723">分頁面板</translation>
-<translation id="2344193891939537199">日期時間控制項</translation>
-<translation id="2359897517538099099">未切換至表格模式。</translation>
-<translation id="241124561063364910">然後按下</translation>
-<translation id="2417569100218200841">內容資訊</translation>
-<translation id="2422937916923936891">選單項目核取方塊</translation>
-<translation id="2429669115401274487">PM</translation>
-<translation id="2435413342408885429">「<ph name="KEY" />」現已設為新的 ChromeVox 輔助鍵。</translation>
-<translation id="2450814015951372393">核取方塊</translation>
-<translation id="2462626033734746142">圓形按鈕群組</translation>
-<translation id="2471138580042810658">標題 6</translation>
-<translation id="248982282205370495">{COUNT,plural, =1{星號}other{# 個星號}}</translation>
-<translation id="2549392850788122959">「<ph name="KEY" />」已重設。</translation>
-<translation id="2553108862507765288">grammatical mistake</translation>
-<translation id="257674075312929031">群組</translation>
-<translation id="2582407057977008361">獨立元素</translation>
-<translation id="2589102159832527089">這個網頁包含系統從 PDF 檔案 &lt;b&gt;<ph name="FILENAME" />&lt;/b&gt; 中自動擷取的文字。&lt;a href="<ph name="URL" />"&gt;按一下這裡即可取得原始檔案。&lt;/a&gt;</translation>
-<translation id="2606210917827248971">內含 {COUNT,plural, =1{# 個項目}other{# 個項目}}</translation>
-<translation id="2614981083756825552">MathML 版面配置</translation>
-<translation id="2626530649491650971">可點擊</translation>
-<translation id="2628764385451019380">沒有上一個下拉式方塊。</translation>
-<translation id="2637227747952042642">數學</translation>
-<translation id="2639750663247012216">ChromeVox 輔助鍵</translation>
-<translation id="2644542693584024604">拼字錯誤</translation>
-<translation id="2667291555398229137">按一下路由機碼下方的項目</translation>
-<translation id="2697408785920771974">autoinl</translation>
-<translation id="2704429362613743330">{COUNT,plural, =1{左括弧}other{# 個左括弧}}</translation>
-<translation id="2705875883745373140">未按下</translation>
-<translation id="2706462751667573066">向上鍵</translation>
-<translation id="2717271541250958000">tabpnl</translation>
-<translation id="2723001399770238859">音訊</translation>
-<translation id="2732718972699418926">AM</translation>
-<translation id="2749275490991666823">已勾選</translation>
-<translation id="27527859628328957">跳至下一個可選擇的項目</translation>
-<translation id="2770781857296573485">輸入群組探索</translation>
-<translation id="2777845298774924149">結束</translation>
-<translation id="2800204403141299078">已無其他元素。</translation>
-<translation id="2800780099804980316">沒有上一個第 1 階標題。</translation>
-<translation id="2811204574343810641">列</translation>
-<translation id="2816654101880605877">沒有下一個滑桿。</translation>
-<translation id="2841013758207633010">時間</translation>
-<translation id="2843837985843789981">上一個群組</translation>
-<translation id="2844995807198708617">內容選單</translation>
-<translation id="2849332794118375855">沒有下一個核取方塊。</translation>
-<translation id="2864481629947106776">上一個連結</translation>
-<translation id="2873259058405069099">前往表格開頭</translation>
-<translation id="2894654529758326923">資訊</translation>
-<translation id="2899328121302785497">{COUNT,plural, =1{左大括弧}other{# 個左大括弧}}</translation>
-<translation id="2911433807131383493">開啟 ChromeVox 教學課程</translation>
-<translation id="2932083475399492303">切換行類型 (結構化或版面配置)</translation>
-<translation id="2964026537669811554">標題群組</translation>
-<translation id="296951647852255825">{COUNT,plural, =1{Tab 字元}other{# 個 Tab 字元}}</translation>
-<translation id="2972078295414139404">沒有上一個已造訪的連結。</translation>
-<translation id="2972205263822847197">工具提示</translation>
-<translation id="2998131015536248178">上一個字元</translation>
-<translation id="2999559350546931576">降低音調</translation>
-<translation id="2999945368667127852">沒有下一個媒體小工具。</translation>
-<translation id="3012414509011670858">沒有上一個區段。</translation>
-<translation id="3030432017085518523">選單選項圓形按鈕</translation>
-<translation id="3037392361165431467">{COUNT,plural, =1{單引號}other{# 個單引號}}</translation>
-<translation id="3046838483509668188">ChromeVox 選項</translation>
-<translation id="3047143736589213134">實驗性按鍵對應配置</translation>
-<translation id="3060756054951570867">「<ph name="TITLE" />」選單已開啟</translation>
-<translation id="3078345202707391975">下一個第 2 階標題</translation>
-<translation id="3078740164268491126">表格</translation>
-<translation id="3082557070674409251">按了一下</translation>
-<translation id="3084806535845658316">無輸入語音回應</translation>
-<translation id="3086746722712840547">附註</translation>
-<translation id="308895241372589742">沒有下一個數學運算式。</translation>
-<translation id="3090532668523289635">群組</translation>
-<translation id="3093176084511590672">下一個地標</translation>
-<translation id="3096671415663099226">cbo</translation>
-<translation id="3104705064753753826">警示對話方塊</translation>
-<translation id="3109724472072898302">已收合</translation>
-<translation id="3134461040845705080">唯讀</translation>
-<translation id="3138767756593758860">顯示地標清單</translation>
-<translation id="3143851963874289911">cll</translation>
-<translation id="3149472044574196936">下一行</translation>
-<translation id="3155083529632865074">沒有上一個按鈕。</translation>
-<translation id="3163593631834463955">欄標題沒有內容</translation>
-<translation id="316542773973815724">導覽</translation>
-<translation id="3172700825913348768">{COUNT,plural, =1{空格}other{# 個空格}}</translation>
-<translation id="320961988183078793">已進入<ph name="TYPE" /></translation>
-<translation id="3223701887221307104"><ph name="NAME" />,分頁</translation>
-<translation id="3226035351387556942">chk</translation>
-<translation id="3229375994964697375">造訪過的連結</translation>
-<translation id="323731244387692321">開啟 ChromeVox 鍵盤說明</translation>
-<translation id="3241052487511142956">上一個造訪過的連結</translation>
-<translation id="3286390186030710347">滑桿</translation>
-<translation id="3299925995433437805">沒有下一個造訪過的連結。</translation>
-<translation id="3303384412438961941">按下任何按鍵即可聽到該按鍵的名稱,按下 Ctrl+W 鍵即可關閉鍵盤語音回饋工具。</translation>
-<translation id="3307886118343381874">前往表格結尾</translation>
-<translation id="3311969765485641742">按下 Alt+Shift+A 鍵即可查看警示內容</translation>
-<translation id="3312997241656799641">下一個造訪過的連結</translation>
-<translation id="3321460131042519426">允許自動換行</translation>
-<translation id="3322936298410871309">上一個第 1 階標題</translation>
-<translation id="3323447499041942178">文字框</translation>
-<translation id="3353420241558113817">{"ar": "阿拉伯文",
- "bg": "保加利亞文",
- "ca": "卡達隆尼亞文",
- "cs": "捷克文",
- "da": "丹麥文",
- "de": "德文",
- "de_CH": "德文 (瑞士)",
- "de_DE": "德文 (德國)",
- "el": "希臘文",
- "en": "英文",
- "en_CA": "英文 (加拿大)",
- "en_GB": "英文 (英國)",
- "en_US": "英文 (美國)",
- "es": "西班牙文",
- "et": "愛沙尼亞文",
- "fr": "法文",
- "fr_CA": "法文 (加拿大)",
- "fr_FR": "法文 (法國)",
- "fi": "芬蘭文",
- "he": "希伯來文",
- "hi": "北印度文",
- "hr": "克羅埃西亞文",
- "hu": "匈牙利文",
- "is": "冰島文",
- "it": "義大利文",
- "ko": "韓文",
- "lt": "立陶宛文",
- "lv": "拉脫維亞文",
- "nb": "挪威文 (巴克摩)",
- "nl": "荷蘭文",
- "pl": "波蘭文",
- "pt": "葡萄牙文",
- "ro": "羅馬尼亞文",
- "ru": "俄文",
- "sk": "斯洛伐克文",
- "sl": "斯洛維尼亞文",
- "sr": "塞爾維亞文",
- "sv": "瑞典文",
- "tr": "土耳其文",
- "vi": "越南文",
- "zh": "中文",
- "zh_TW": "中文 (繁體)"}</translation>
-<translation id="3359142382821736686">seprtr</translation>
-<translation id="3374537878095184207">{COUNT,plural, =1{加號}other{# 個加號}}</translation>
-<translation id="338583716107319301">分隔線</translation>
-<translation id="3389259863310851658">上一個表單欄位</translation>
-<translation id="3390225400784126843">下一個不同的元素。</translation>
-<translation id="3392045790598181549"><ph name="NAME" />,選單項目</translation>
-<translation id="3406283310380167331">顯示表單清單</translation>
-<translation id="3422338090358345848">開啟鍵盤語音回饋工具</translation>
-<translation id="3457000393508828486">部分已按下</translation>
-<translation id="3462439746547587373"><ph name="NAME" />,按鈕</translation>
-<translation id="3473644018603298796">已選取 <ph name="COUNT" /> 項</translation>
-<translation id="3486232535569802404"><ph name="V1" /> 至 <ph name="V2" /></translation>
-<translation id="3492609944033322585">{COUNT,plural, =1{右中括弧}other{# 個右中括弧}}</translation>
-<translation id="3493915602752813531">沒有下一個錨點。</translation>
-<translation id="3494946239022273294">mnuitm</translation>
-<translation id="3497063866483065785">{COUNT,plural, =1{問號}other{# 個問號}}</translation>
-<translation id="3514822174137761109">{COUNT,plural, =1{插入符號}other{# 個插入符號}}</translation>
-<translation id="3568702578574425662"><ph name="NAME" />,未勾選的核取方塊</translation>
-<translation id="3599054940393788245">非數學內部</translation>
-<translation id="3616113530831147358">音訊</translation>
-<translation id="3646890046000188562">{COUNT,plural, =1{反引號}other{# 個反引號}}</translation>
-<translation id="3650317109285159359">chkmnuitm</translation>
-<translation id="3655855170848725876">{COUNT,plural, =1{美元}other{# 個美元符號}}</translation>
-<translation id="3659787053479271466">警示</translation>
-<translation id="3665563998540286755"><ph name="VALUE" />,清單方塊</translation>
-<translation id="3687295507293856493">推測目前儲存格的欄標題</translation>
-<translation id="3692274950075847560">搜尋結果:<ph name="RESULT" /></translation>
-<translation id="3712520970944678024">控制語音</translation>
-<translation id="3716845769494773620">多行</translation>
-<translation id="3731746171184829332">沒有上一個標題。</translation>
-<translation id="3762198587642264450">前往目前列的結尾</translation>
-<translation id="3777255250339039212">第 1 階</translation>
-<translation id="3793710123303304873">結束對話方塊。</translation>
-<translation id="3795836767122514678">+{COUNT,plural, =1{#}other{#}}</translation>
-<translation id="3801735343383419236">自動即時查詢清單</translation>
-<translation id="3810838688059735925">影片</translation>
-<translation id="3816633764618089385">下一個媒體元素</translation>
-<translation id="3819376190738087562">沒有跳躍點。</translation>
-<translation id="385383972552776628">開啟選項頁面</translation>
-<translation id="3856075812838139784">唯讀</translation>
-<translation id="3887576927692165210">ed</translation>
-<translation id="3897092660631435901">選單</translation>
-<translation id="3909320334364316587">上一個第 6 階標題</translation>
-<translation id="3914173277599553213">必要</translation>
-<translation id="3962990492275676168">從目前位置開始朗讀</translation>
-<translation id="4004802134384979325">已勾選</translation>
-<translation id="4006140876663370126">圖片</translation>
-<translation id="4038349100599457191">月控制項</translation>
-<translation id="4039983576244166038">列標題沒有內容</translation>
-<translation id="4042843249978639960">沒有下一個第 2 階標題。</translation>
-<translation id="4043348641337972076">沒有上一個 ARIA 地標。</translation>
-<translation id="4047216625641135770">標記</translation>
-<translation id="404803211695627272"><ph name="V1" /> 至 <ph name="V2" /></translation>
-<translation id="4054936709456751127">狀態</translation>
-<translation id="4081085052247739398">{COUNT,plural, =1{波狀符號}other{# 個波狀符號}}</translation>
-<translation id="409334809956508737">上一個物件</translation>
-<translation id="4099274309791143834">含子選單</translation>
-<translation id="4107807507418787238">下方沒有儲存格。</translation>
-<translation id="4116415223832267137">警示</translation>
-<translation id="4147126331795725888">沒有下一個控制項。</translation>
-<translation id="4148180433151187540">{COUNT,plural, =1{右大括弧}other{# 個右大括弧}}</translation>
-<translation id="4158704014418536539">區分大小寫。</translation>
-<translation id="4161663686871496107">ChromeVox 互動朗讀已啟用</translation>
-<translation id="4173994908659439270">沒有可編輯的文字欄位。</translation>
-<translation id="4176463684765177261">已停用</translation>
-<translation id="4188530942454211480">上一句</translation>
-<translation id="4202186506458631436">右移</translation>
-<translation id="4206289001967551965">在表格內</translation>
-<translation id="4215733775853809057">下一個滑桿</translation>
-<translation id="4218529045364428769">{COUNT,plural, =1{破折號}other{# 個破折號}}</translation>
-<translation id="421884353938374759">顏色選擇器</translation>
-<translation id="4229646983878045487">日期時間</translation>
-<translation id="423334822609210999">左側沒有儲存格。</translation>
-<translation id="4243624244759495699"><ph name="LOCALE" />,第 <ph name="GRADE" /> 級</translation>
-<translation id="4253168017788158739">附註</translation>
-<translation id="4254798249533888099">樹狀結構</translation>
-<translation id="4255943572433203166">使用下方的選項自訂 ChromeVox。變更會立即生效。</translation>
-<translation id="4271220233568730077">下一個數學元素</translation>
-<translation id="4271521365602459209">沒有其他搜尋結果。</translation>
-<translation id="4287520460805643128">沒有下一篇文章。</translation>
-<translation id="4289540628985791613">總覽</translation>
-<translation id="4300318234632215983">朗讀連結的網址</translation>
-<translation id="4301352596632316575">含子選單</translation>
-<translation id="4342180618051828363">{COUNT,plural, =1{點}=3{刪節號}other{# 個點}}</translation>
-<translation id="4347461890115250064">沒有下一個清單。</translation>
-<translation id="4367650418938037324">MathML 分葉</translation>
-<translation id="4372435075475052704">最小值:<ph name="X" /></translation>
-<translation id="4372705107434148843">停止語音</translation>
-<translation id="4373197658375206385">沒有上一個非連結項目。</translation>
-<translation id="4391478986194775161">cntntinfo</translation>
-<translation id="443163561286008705">重設</translation>
-<translation id="4471074325120394300">沒有連結。</translation>
-<translation id="4476183483923481720">換行</translation>
-<translation id="4482330759234983253">上一個表格</translation>
-<translation id="4491109536499578614">圖片</translation>
-<translation id="4529987814483543472">傳統按鍵對應配置</translation>
-<translation id="4532633738839459153">{COUNT,plural, =1{斜線}other{# 個斜線}}</translation>
-<translation id="4547556996012970016">下一個第 5 階標題</translation>
-<translation id="4562381607973973258">頁首</translation>
-<translation id="4591507479202817876">,已選取</translation>
-<translation id="4597532268155981612">表單</translation>
-<translation id="4597896406374528575">4 月</translation>
-<translation id="4615592953348396470">忽略下一個按鍵</translation>
-<translation id="461613135510474570">句子</translation>
-<translation id="4647836961514597010">顏色選擇器</translation>
-<translation id="4661075872484491155">tree</translation>
-<translation id="4668929960204016307">,</translation>
-<translation id="4688873778442829762">格線</translation>
-<translation id="4693675773662933727">上一個地標</translation>
-<translation id="4696413482802371445">沒有下一個第 5 階標題。</translation>
-<translation id="4729095194763193578">上一個表格列</translation>
-<translation id="4736221692378411923">8 月</translation>
-<translation id="4740661827607246557">說明指令</translation>
-<translation id="4759716709594980008">Chrome 作業系統鍵盤語言回饋工具</translation>
-<translation id="4763296182459741068">自動換行至底部</translation>
-<translation id="4763480195061959176">影片</translation>
-<translation id="479989351350248267">search</translation>
-<translation id="481165870889056555">朗讀目前網頁的標題</translation>
-<translation id="4826415162591436065">向前導覽</translation>
-<translation id="4826604887384865800">下一個跳轉</translation>
-<translation id="4827410568042294688">已取消選取</translation>
-<translation id="4842108708071771135">沒有下一個引用標記。</translation>
-<translation id="4848993367330139335">計時器</translation>
-<translation id="4850023505158945298">上一個相似的元素。</translation>
-<translation id="4866956062845190338">rdmnuitm</translation>
-<translation id="4867316986324544967">啟用 TTS 記錄功能</translation>
-<translation id="4877261390094455813">輸入搜尋查詢。</translation>
-<translation id="4886524826165775965">第 <ph name="INDEX" /> 個,共 <ph name="TOTAL" /> 個</translation>
-<translation id="489907760999452556">內部連結</translation>
-<translation id="4953585991029886728">編輯文字</translation>
-<translation id="4954534434583049121">上一個區塊引述</translation>
-<translation id="4973717656530883744">最小值:<ph name="X" /></translation>
-<translation id="4973762002207131920">已切換至「<ph name="KEY" />」。</translation>
-<translation id="4975416682604111799">毫秒</translation>
-<translation id="49787999531187221">ChromeVox 現在已停用。</translation>
-<translation id="4979404613699303341">上一個按鈕</translation>
-<translation id="4982773647088557172"><ph name="VALUE" />,<ph name="NAME" />,清單方塊</translation>
-<translation id="4983588134362688868">前往網頁頂端</translation>
-<translation id="4986606102545753256"><ph name="NAME" />,視窗</translation>
-<translation id="4993152509206108683">速度為百分之 <ph name="PERCENT" /></translation>
-<translation id="4996716799442435517">視區</translation>
-<translation id="4997282455736854877">已選取「<ph name="NAME" />」圓形按鈕</translation>
-<translation id="4997475792277222884">沒有下一個非連結項目。</translation>
-<translation id="5000760171916499057">沒有表單。</translation>
-<translation id="5005670136041063723">已無類似元素。</translation>
-<translation id="501473567976723023">1 月</translation>
-<translation id="5041394372352067729">將點字顯示畫面移至頁面頂端</translation>
-<translation id="5042770794184672516">增加說話音量</translation>
-<translation id="5050015258024679800">上一個第 4 階標題</translation>
-<translation id="5054047268577924192">上一個清單項目</translation>
-<translation id="5078661581131202757">選取檔案</translation>
-<translation id="5080758118274074384">按了兩下</translation>
-<translation id="5098541983634824365">離開網格。</translation>
-<translation id="5102981729317424850">工具列</translation>
-<translation id="5105050547967751155">rq</translation>
-<translation id="5110983769041734144">沒有上一個表單欄位。</translation>
-<translation id="5111640677200759579">欄標題</translation>
-<translation id="5117636609870536415">@ed</translation>
-<translation id="5136967254288895616">沒有上一個連結。</translation>
-<translation id="513774504516943387">連結</translation>
-<translation id="517143700877085897">,未選取</translation>
-<translation id="5183440668879371625">上一行點字</translation>
-<translation id="5184944171021383281">沒有下一個表單欄位。</translation>
-<translation id="5189244881767082992">行</translation>
-<translation id="5203930734796605961">已將「<ph name="KEY" />」指派給另一個指令。</translation>
-<translation id="5205493599117157272"><ph name="TYPE" />類清單。</translation>
-<translation id="520883772648104506">沒有下一個圓形按鈕。</translation>
-<translation id="5263344797180442561">第 2 階</translation>
-<translation id="528468243742722775">結束</translation>
-<translation id="5291783959063340370">物件</translation>
-<translation id="5304943142864553931"><ph name="TITLE" />,分頁</translation>
-<translation id="5310788376443009632">已移除:</translation>
-<translation id="5320727453979144100">固定模式已啟用</translation>
-<translation id="5321085947096604457">{COUNT,plural, =1{逗號}other{# 個逗號}}</translation>
-<translation id="532371086589123547"><ph name="VALUE" />,文字方塊</translation>
-<translation id="5330443287809544590"><ph name="NAME" />,連結</translation>
-<translation id="5336381510091010269">autoinl+lst</translation>
-<translation id="536031132345979795">在連續朗讀時向後跳過</translation>
-<translation id="5368000168321181111">聽覺標示已關閉</translation>
-<translation id="5374320867641260420">沒有下一個按鈕。</translation>
-<translation id="5382299583965267720">沒有下一第 1 階標題。</translation>
-<translation id="5402367795255837559">點字</translation>
-<translation id="5407530583102765689">{COUNT,plural, =1{分號}other{# 個分號}}</translation>
-<translation id="5411891038905756502">沒有上一個跳躍點。</translation>
-<translation id="5436105723448703439">{COUNT,plural, =1{小於符號}other{# 個小於符號}}</translation>
-<translation id="5455441614648621694">互補</translation>
-<translation id="5485036206801896268">沒有上一個圖形。</translation>
-<translation id="5486947920110100234">沒有下一個跳躍點。</translation>
-<translation id="549602578321198708">單字</translation>
-<translation id="5500932716852106146">沒有上一個可編輯的文字欄位。</translation>
-<translation id="5502713021410870035">9 月</translation>
-<translation id="5507663321906818013">偵錯基準測試</translation>
-<translation id="5518443085409638729">編輯文字時將滑鼠游標置於字元之間 (例如 Mac OS X)。</translation>
-<translation id="552195134157544755">圓形按鈕</translation>
-<translation id="5534303576632885660">頁首</translation>
-<translation id="5546092960038624944">沒有上一個第 5 階標題。</translation>
-<translation id="556042886152191864">按鈕</translation>
-<translation id="5561345396546889625">下一個清單</translation>
-<translation id="5562645715554321347">hdnggrp</translation>
-<translation id="5583640892426849032">Backspace 鍵</translation>
-<translation id="5585044216466955529">編輯文字,電子郵件項目</translation>
-<translation id="5597170376237141345">下一個核取方塊</translation>
-<translation id="5597933780944041114">沒有下一個標題。</translation>
-<translation id="5598905979683743333"><ph name="NAME" />,未選取的圓形按鈕</translation>
-<translation id="5601172225407283979">執行預設動作</translation>
-<translation id="5608798115546226984">自動即時查詢內嵌元素</translation>
-<translation id="561939826962581046">time</translation>
-<translation id="5623778242535476823">rbtn</translation>
-<translation id="5623842676595125836">紀錄</translation>
-<translation id="5628125749885014029">第 4 階</translation>
-<translation id="5637871198229500030">沒有上一個表格。</translation>
-<translation id="5655682562155942719">跳躍指令</translation>
-<translation id="56637627897541303">文字區域</translation>
-<translation id="5678161956734658133">mled</translation>
-<translation id="5681643281275621376">定義</translation>
-<translation id="5682113568322255809">地標</translation>
-<translation id="5683155931978483559">上一個核取方塊</translation>
-<translation id="5684277895745049190">清單</translation>
-<translation id="5700650669149824506">沒有上一個第 4 階標題。</translation>
-<translation id="5709192780268610569">無詳細說明</translation>
-<translation id="5712244464475377681">popbtn</translation>
-<translation id="5712338278108304766">下一個表格欄</translation>
-<translation id="571866080859340309">正在探索群組</translation>
-<translation id="5728409797179002635">找不到表格。</translation>
-<translation id="5748623122140342504">上一個第 5 階標題</translation>
-<translation id="5750633686117194034">您尚未按下任何輔助鍵。請按住一或多個輔助鍵,完成後即可將手指移開,此時系統會透過語音說明按鍵已成功設定。如要結束,請按下 Tab 鍵。</translation>
-<translation id="5788275253279308023">無痕式視窗「<ph name="TITLE" />」分頁</translation>
-<translation id="5806206155699461681">增強特定網站 (例如 Google 搜尋)。</translation>
-<translation id="5819072574982403430">樹狀目錄項目</translation>
-<translation id="5826479389509458994">第 <ph name="ROW" /> 列,第 <ph name="COL" /> 欄</translation>
-<translation id="5850707923114094062">向後平移</translation>
-<translation id="5851548754964597211">分頁清單</translation>
-<translation id="5859752971144398932">結束從網頁中尋找。</translation>
-<translation id="5866042630553435010">部分已勾選</translation>
-<translation id="5869546221129391014">格線</translation>
-<translation id="5876817486144482042">降低說話音量</translation>
-<translation id="5887397643266327462">點字字幕已啟用。</translation>
-<translation id="5891934789323004067">表格</translation>
-<translation id="5919442531159595654">複製。</translation>
-<translation id="5937336320314038555">{COUNT,plural, =1{等號}other{# 個等號}}</translation>
-<translation id="5939518447894949180">重設</translation>
-<translation id="5948123859135882163">切換數學運算式的轉譯方式 (選擇結構化轉譯或語意轉譯)</translation>
-<translation id="5955304353782037793">應用程式</translation>
-<translation id="5956928062748260866">對話方塊</translation>
-<translation id="5963413905009737549">區段</translation>
-<translation id="5968607524793740041">顯示內容選單</translation>
-<translation id="5983179082906765664">增加導覽精細度</translation>
-<translation id="5999630716831179808">語音</translation>
-<translation id="6000417740266304866">如要變更目前的 8 點點字表,請從下方清單中選取適當的選項。</translation>
-<translation id="6006050241733874051">表單</translation>
-<translation id="6006064078185310784">{COUNT,plural, =1{反斜線}other{# 個反斜線}}</translation>
-<translation id="6037602951055904232">向前平移</translation>
-<translation id="611827076493383239">vtd</translation>
-<translation id="6119955456199054975">儲存格結尾。</translation>
-<translation id="6122013438240733403">按鈕</translation>
-<translation id="6129953537138746214">空格</translation>
-<translation id="6142308968191113180">標題 4</translation>
-<translation id="6169420925157477918">圖片具有詳細說明</translation>
-<translation id="6172087735260766220">PDF 含複製保護設定,無法存取其中的無障礙文字。</translation>
-<translation id="6186305613600865047">前往網頁底部</translation>
-<translation id="6193330012414963395">上午/下午</translation>
-<translation id="622484624075952240">向下鍵</translation>
-<translation id="6236061028292614533">下一個標題</translation>
-<translation id="6254901459154107917">下一個可編輯的文字區域</translation>
-<translation id="6259464875943891919">已離開<ph name="TYPE" />。</translation>
-<translation id="6281876499889881039">下一個相似的元素。</translation>
-<translation id="6282062888058716985">導覽</translation>
-<translation id="6290434000785343030">沒有下一個下拉式方塊。</translation>
-<translation id="6307969636681130414">已按下</translation>
-<translation id="6324551002951139333">偵測到文法錯誤</translation>
-<translation id="6348657800373377022">下拉式方塊</translation>
-<translation id="6355910664415701303">沒有上一個清單項目。</translation>
-<translation id="6364795331201459219">第 6 階</translation>
-<translation id="6368143427468974988">上一個標題</translation>
-<translation id="6387719785439924554">獨立元素</translation>
-<translation id="6411426777058107714">沒有上一個圓形按鈕。</translation>
-<translation id="6414968628640960377">上一個不同的元素。</translation>
-<translation id="641759969622533235">{COUNT,plural, =1{冒號}other{# 個冒號}}</translation>
-<translation id="6438968337250688271"><ph name="NAME" />,選單</translation>
-<translation id="6444046323172968959">警示對話方塊</translation>
-<translation id="6459511626086141404">一般按鍵對應配置</translation>
-<translation id="6468049171101508116">下一個按鈕</translation>
-<translation id="6491972999578897419">選取下方清單中的選項,即可變更目前的語音。</translation>
-<translation id="6508059270146105198">將點字顯示畫面移至頁面底部</translation>
-<translation id="6536864053412760904">MathML 符記</translation>
-<translation id="6550720799683018100">選取下方清單中的選項,即可變更目前的按鍵對應配置。</translation>
-<translation id="6561818612645211875">前往目前列的開頭</translation>
-<translation id="6587021927234520429">沒有下一個第 4 階標題。</translation>
-<translation id="6601344353291556895">啟用詳細說明。</translation>
-<translation id="6615602925644411249">從網頁中尋找。</translation>
-<translation id="6633350132811819843">沒有下一個表格。</translation>
-<translation id="6637586476836377253">紀錄</translation>
-<translation id="6657128831881431364">進度列</translation>
-<translation id="6659594942844771486">Tab</translation>
-<translation id="667999046851023355">文件</translation>
-<translation id="6697092096875747123">上一個下拉式方塊</translation>
-<translation id="6714813999819678458">上一個第 2 階標題</translation>
-<translation id="6716505898850596801">輔助鍵</translation>
-<translation id="671916444866103745">沒有下一個 ARIA 地標。</translation>
-<translation id="6734854816611871228"><ph name="VALUE" />,下拉式方塊</translation>
-<translation id="6735257939857578167">列出 <ph name="NUM" /> 個項目</translation>
-<translation id="6736510033526053669">已建立新分頁</translation>
-<translation id="675895815784134693">pgbar</translation>
-<translation id="6786800275320335305">文章</translation>
-<translation id="6787839852456839824">鍵盤快速鍵</translation>
-<translation id="6793101435925451627">清單方塊</translation>
-<translation id="6833103209700200188">頁尾</translation>
-<translation id="6871161210040114857">不區分大小寫。</translation>
-<translation id="6877435256196695200">沒有下一個圖形。</translation>
-<translation id="6897341342232909480">左移</translation>
-<translation id="6901540140423170855">日期</translation>
-<translation id="6910211073230771657">已刪除</translation>
-<translation id="6911965441508464308">上方沒有儲存格。</translation>
-<translation id="6919104639734799681">顯示表格清單</translation>
-<translation id="6964088412282673743">沒有上一個控制項。</translation>
-<translation id="6996566555547746822">下一個下拉式方塊</translation>
-<translation id="7005146664810010831">找不到網址</translation>
-<translation id="7010712454773919705">ChromeVox 輔助鍵</translation>
-<translation id="7031651751836475482">清單項目</translation>
-<translation id="7037042857287298941">上一個清單</translation>
-<translation id="7041173719775863268">結束選取</translation>
-<translation id="7095834689119144465">編輯文字時僅限輸入數字</translation>
-<translation id="7096001299300236431">上一個媒體元素</translation>
-<translation id="7116595520562830928">multln</translation>
-<translation id="712735679809149106">字詞語音回應</translation>
-<translation id="713824876195128146">下一個區塊引述</translation>
-<translation id="7161771961008409533">彈出式按鈕</translation>
-<translation id="7167657087543110">字元語音回應</translation>
-<translation id="7170733337935166589">在連續朗讀時向前跳過</translation>
-<translation id="7181697990050180700">在下方對應的欄位中輸入按鍵配置,即可為常用指令自訂鍵盤快速鍵。</translation>
-<translation id="7203150201908454328">已展開</translation>
-<translation id="7210211103303402262">分鐘</translation>
-<translation id="7217912842225915592">還有 <ph name="NUM" /> 個</translation>
-<translation id="7221740160534240920">行</translation>
-<translation id="7226216518520804442">清單</translation>
-<translation id="72393384879519786">標題</translation>
-<translation id="7241683698754534149">在新分頁中開啟詳細說明</translation>
-<translation id="7248671827512403053">應用程式</translation>
-<translation id="725969808843520477">下一個圓形按鈕</translation>
-<translation id="7269119382257320590">無標點符號</translation>
-<translation id="7273174640290488576">空白行</translation>
-<translation id="7285387653379749618">表格</translation>
-<translation id="7289186959554153431">標題 3</translation>
-<translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation>
-<translation id="731121099745151312">tritm</translation>
-<translation id="731576946540457939">點字字幕已停用。</translation>
-<translation id="7318872822751139669">使用滑鼠變更焦點。</translation>
-<translation id="7322388933135261569">2 月</translation>
-<translation id="7332592614823088566">第 <ph name="ROWINDEX" /> 列,第 <ph name="COLINDEX" /> 欄 (共 <ph name="ROWTOTAL" /> 列,<ph name="COLTOTAL" /> 欄)</translation>
-<translation id="7336596009609913925">含彈出式元件</translation>
-<translation id="7356165926712028380">切換至 8 點點字</translation>
-<translation id="7362871137496673139">沒有上一個第 2 階標題。</translation>
-<translation id="7370432716629432284">{COUNT,plural, =1{&amp; 符號}other{# 個 &amp; 符號}}</translation>
-<translation id="737396357417333429">clk</translation>
-<translation id="7374104575779636480">離開表格。</translation>
-<translation id="739763518212184081">上一行</translation>
-<translation id="7400575256015741911">偵測到拼字錯誤</translation>
-<translation id="7408482676469142474">表格</translation>
-<translation id="7425395583360211003">歸位字元</translation>
-<translation id="7434509671034404296">開發人員選項</translation>
-<translation id="7439060726180460871">目錄</translation>
-<translation id="744163271241493234">pwded</translation>
-<translation id="7491962110804786152">分頁</translation>
-<translation id="7492049978501397201">已進入對話方塊</translation>
-<translation id="7532613204005497612">6 月</translation>
-<translation id="7540083713905917247"><ph name="VALUE" />,<ph name="NAME" />,滑桿</translation>
-<translation id="7586163296341959563">貼上。</translation>
-<translation id="7596919493010894443">已清除所選項目</translation>
-<translation id="7604026522577407655">前往目前欄的開頭</translation>
-<translation id="7604451927827590395">hdng</translation>
-<translation id="7609342235116740824">朗讀目前網頁的網址</translation>
-<translation id="7609363189280667021">選擇啟用或停用點字說明文字</translation>
-<translation id="762020119231868829">暫停所有正在播放媒體的小工具</translation>
-<translation id="7625690649919402823">下一個表格</translation>
-<translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />),第 <ph name="GRADE" /> 級</translation>
-<translation id="7641134354185483015">沒有上一個第 3 階標題。</translation>
-<translation id="7659376057562985921"><ph name="VALUE" />,<ph name="NAME" />,文字方塊</translation>
-<translation id="7663318257180412551">標題 2</translation>
-<translation id="7674576868851035240">下一個連結</translation>
-<translation id="7674768236845044097">標記</translation>
-<translation id="7684431668231950609">編輯文字,網址項目</translation>
-<translation id="7685589220304187312">tlbar</translation>
-<translation id="7693840228159394336">上一個圓形按鈕</translation>
-<translation id="7701196182766842984">autolst</translation>
-<translation id="7770823902658038748"><ph name="VALUE" />,<ph name="NAME" />,密碼文字方塊</translation>
-<translation id="7805247615045262757">預設導覽</translation>
-<translation id="7805768142964895445">狀態</translation>
-<translation id="7810781339813764006">下一個群組</translation>
-<translation id="7819187121850078213">視窗「<ph name="TITLE" />」分頁</translation>
-<translation id="7828956995407538686">10 月</translation>
-<translation id="7839679365527550018">上一個字詞</translation>
-<translation id="7851816175263618915">部分標點符號</translation>
-<translation id="7870596830398826354">MathML 樹狀結構</translation>
-<translation id="78826985582142166">滑桿</translation>
-<translation id="7894517696028036636">切換 ChromeVox 傳統模式。</translation>
-<translation id="7895896691902835279">未知的連結</translation>
-<translation id="7927711904086083099">未選取</translation>
-<translation id="7935627501098484003">時間控制項</translation>
-<translation id="7939428177581522200">已加入選取範圍</translation>
-<translation id="794091007957014205">{COUNT,plural, =1{@ 符號}other{# 個 @ 符號}}</translation>
-<translation id="7965147473449754028">選單已關閉</translation>
-<translation id="7974390230414479278">選單項目</translation>
-<translation id="8002119852008410879">{COUNT,plural, =1{驚嘆號}other{# 個驚嘆號}}</translation>
-<translation id="8007540374018858731">第 3 階</translation>
-<translation id="8009786657110126785">{COUNT,plural, =1{引號}other{# 個引號}}</translation>
-<translation id="8033827949643255796">已選取</translation>
-<translation id="8035962149453661158">最大值:<ph name="X" /></translation>
-<translation id="8042761080832772327">編輯文字,搜尋項目</translation>
-<translation id="8049189770492311300">計時器</translation>
-<translation id="8065607967589909823">所選項目是</translation>
-<translation id="8066678206530322333">橫幅</translation>
-<translation id="8110647606445335195">沒有 ARIA 地標。</translation>
-<translation id="8153880621934657047">不在表格內。</translation>
-<translation id="817440585505441544">{COUNT,plural, =1{底線}other{# 個底線}}</translation>
-<translation id="8179976553408161302">Enter</translation>
-<translation id="81960742267269908">剪下。</translation>
-<translation id="8199231515320852133">朗讀目前儲存格的標題</translation>
-<translation id="820417203470636242">空白儲存格。</translation>
-<translation id="8215202828671303819">多重選取</translation>
-<translation id="8276439074553447000">跳至上一個可選擇的項目</translation>
-<translation id="8278417001922463147">沒有上一篇文章。</translation>
-<translation id="8283603667300770666">下一個表單欄位</translation>
-<translation id="831207808878314375">定義</translation>
-<translation id="8313653172105209786">目錄</translation>
-<translation id="8344569602005188545">小時</translation>
-<translation id="8345569862449483843">{COUNT,plural, =1{英鎊符號}other{# 個英鎊符號}}</translation>
-<translation id="8374154622594089836">月</translation>
-<translation id="8378855320830505539">區域</translation>
-<translation id="8382679411218029383">自動即時查詢內嵌元素和清單</translation>
-<translation id="8428603554127842284">第 <ph name="DEPTH" /> 階</translation>
-<translation id="842922884199979200">沒有下一個第 3 階標題。</translation>
-<translation id="8430049249787218991">mnubr</translation>
-<translation id="844681116543532394">沒有上一個核取方塊。</translation>
-<translation id="8455868257606149352">最大值:<ph name="X" /></translation>
-<translation id="84575901236241018">有快捷鍵「<ph name="KEY" />」</translation>
-<translation id="8503360654911991865">降低導覽精細度</translation>
-<translation id="8520472399088452386">微調按鈕</translation>
-<translation id="8538744478902126321">推測目前儲存格的列標題</translation>
-<translation id="8540054775867439484">自動換行至頂端</translation>
-<translation id="8548973727659841685">字元</translation>
-<translation id="8561322612995434619">含彈出式元件</translation>
-<translation id="8571096049907249734">複選</translation>
-<translation id="8584721346566392021">第 5 階</translation>
-<translation id="8587549812518406253">下一個清單項目</translation>
-<translation id="860150890330522909">「<ph name="NAME" />」核取方塊已勾選</translation>
-<translation id="8606621670302093223">日期控制項</translation>
-<translation id="8631359288236106450">已選取 <ph name="COUNT" /> 個項目</translation>
-<translation id="8638532244051952400">讀出目前的儲存格座標</translation>
-<translation id="8650576015643545550">沒有上一個清單。</translation>
-<translation id="8653031188082306838">urled</translation>
-<translation id="8653646212587894517">顯示連結清單</translation>
-<translation id="8664519043722036194">秒</translation>
-<translation id="867187640362843212">標題 5</translation>
-<translation id="8697111817566059991">{COUNT,plural, =1{直立線符號}other{# 個直立線符號}}</translation>
-<translation id="8735450637152821465">開始選取</translation>
-<translation id="8743786158317878347">進入結構化內容,例如表格</translation>
-<translation id="8747966237988593539">排序清單</translation>
-<translation id="8759334257841767240">沒有下一個連結。</translation>
-<translation id="8767968232364267681">下一個第 4 階標題</translation>
-<translation id="8770473310765924354">離開結構化內容,例如表格</translation>
-<translation id="8791025954632646584">語意轉譯功能已開啟</translation>
-<translation id="8796411681063377102">下一個第 3 階標題</translation>
-<translation id="8808582214901541005">3 月</translation>
-<translation id="8825828890761629845">橫幅</translation>
-<translation id="8851136666856101339">主要元素</translation>
-<translation id="8856538297388979332">按向上鍵或向下鍵可查看指令,按 Enter 鍵可啟動</translation>
-<translation id="8864099967139188018">沒有下一個第 6 階標題。</translation>
-<translation id="8882002077197914455">列標題</translation>
-<translation id="8896347895970027998">啟用或停用 ChromeVox。</translation>
-<translation id="8898516272131543774">循環標點符號語音回應</translation>
-<translation id="8900148057318340779">前置鍵</translation>
-<translation id="8908714597367957477">colhdr</translation>
-<translation id="8931936695772494138">標題沒有內容</translation>
-<translation id="8937112856099038376">intlnk</translation>
-<translation id="8940925288729953902">輔助鍵</translation>
-<translation id="8943175951035496220">右側沒有儲存格。</translation>
-<translation id="8978496506222343566">tltip</translation>
-<translation id="900114243503212879">檔案</translation>
-<translation id="9027462562263121875">沒有表格。</translation>
-<translation id="9040132695316389094">標題 1</translation>
-<translation id="9043969572162476692">百分之 <ph name="NUM" /></translation>
-<translation id="9061915073547935367">切換搜尋小工具</translation>
-<translation id="9065283790526219006">含彈出式元件</translation>
-<translation id="9077213568694924680">已從所選範圍中移除</translation>
-<translation id="9082874451376019682">沒有上一個滑桿。</translation>
-<translation id="9089864840575085222">循環輸入語音回應</translation>
-<translation id="9107530006868467849">沒有上一個媒體小工具。</translation>
-<translation id="9108370397979208512">數學</translation>
-<translation id="9108589040018540527">scbr</translation>
-<translation id="911476240645808512">{COUNT,plural, =1{百分比符號}other{# 個百分比符號}}</translation>
-<translation id="9115913704608474258">11 月</translation>
-<translation id="9128414153595658330">對話方塊</translation>
-<translation id="9149560530563164529">sctn</translation>
-<translation id="9151211641321628915">朗讀目前位置的簡短說明</translation>
-<translation id="9153606228985488238">音調為百分之 <ph name="PERCENT" /></translation>
-<translation id="9160096769946561184">前往目前欄的結尾</translation>
-<translation id="9173115498289768110">音量為百分之 <ph name="PERCENT" /></translation>
-<translation id="9178973770513562274">使用向上鍵和向下鍵瀏覽,或輸入字詞開始搜尋。</translation>
-<translation id="9192904702577636854">跑馬燈</translation>
-<translation id="9212322457209634662">沒有下一個區段。</translation>
-<translation id="930275611743429116">開始或結束選取。</translation>
-<translation id="948171205378458592">放慢說話速度</translation>
-<translation id="962913030769097253">下一個第 1 階標題</translation>
-<translation id="973955474346881951">啟用/停用固定模式</translation>
-</translationbundle> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/assert_additions.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/assert_additions.js
deleted file mode 100644
index c51cbc7c638..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/assert_additions.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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.
-
-/**
- * Asserts that a given argument's value is undefined.
- * @param {object} a The argument to check.
- */
-function assertUndefined(a) {
- if (a !== undefined) {
- throw new Error('Assertion failed: expected undefined');
- }
-}
-
-/**
- * Asserts that the argument is neither null nor undefined.
- * @param {object} obj The argument to check.
- * @param {string=} opt_message Error message if the condition is not met.
- */
-function assertNotNullNorUndefined(obj, opt_message) {
- if (obj === undefined || obj === null) {
- throw new Error('Can\'t be null or undefined: ' + (opt_message || '') +
- '\n' + 'Actual: ' + obj);
- }
-}
-
-/**
- * Asserts that a given function call throws an exception.
- * @param {string} msg Message to print if exception not thrown.
- * @param {Function} fn The function to call.
- * @param {string} error The name of the exception we expect {@code fn} to
- * throw.
- */
-function assertException(msg, fn, error) {
- try {
- fn();
- } catch (e) {
- if (error && e.name != error) {
- throw new Error('Expected to throw ' + error + ' but threw ' + e.name +
- ' - ' + msg);
- }
- return;
- }
-
- throw new Error('Expected to throw exception ' + error + ' - ' + msg);
-}
-
-/**
- * Asserts that two arrays of strings are equal.
- * @param {Array<string>} array1 The expected array.
- * @param {Array<string>} array2 The test array.
- */
-function assertEqualStringArrays(array1, array2) {
- var same = true;
- if (array1.length != array2.length) {
- same = false;
- }
- for (var i = 0; i < Math.min(array1.length, array2.length); i++) {
- if (array1[i].trim() != array2[i].trim()) {
- same = false;
- }
- }
- if (!same) {
- throw new Error('Expected ' + JSON.stringify(array1) +
- ', got ' + JSON.stringify(array2));
- }
-}
-
-/**
- * Asserts that two objects have the same JSON serialization.
- * @param {Object} expected The expected object.
- * @param {Object} actual The actual object.
- * @param {string=} opt_message Message used for errors.
- */
-function assertEqualsJSON(expected, actual, opt_message) {
- if (JSON.stringify(actual) !== JSON.stringify(expected)) {
- throw new Error((opt_message ? opt_message + '\n' : '') +
- 'Expected ' + JSON.stringify(expected) + '\n' +
- 'Got ' + JSON.stringify(actual));
- }
-}
-
-assertSame = assertEquals;
-assertNotSame = assertNotEquals;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/callback_helper.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/callback_helper.js
deleted file mode 100644
index 6f14d2f9c43..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/callback_helper.js
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Creates wrappers for callbacks and calls testDone() when all callbacks
- * have been invoked.
- * @param {testing.Test} fixture
- */
-function CallbackHelper(fixture) {
- /** @type {Object} fixture */
- this.fixture_ = fixture;
- /** @type {number} */
- this.pendingCallbacks_ = 0;
-}
-
-CallbackHelper.prototype = {
- /**
- * @param {Function=} opt_callback
- * @return {Function}
- */
- wrap: function(opt_callback) {
- var callback = opt_callback || function() {};
- var savedArgs = new SaveMockArguments();
- var lastCall = null;
- var completionAction = callFunctionWithSavedArgs(savedArgs, function() {
- if (lastCall) {
- throw new Error('Called more than once, first call here: ' + lastCall);
- } else {
- lastCall = new Error().stack;
- }
- callback.apply(this.fixture_, arguments);
- if (--this.pendingCallbacks_ <= 0)
- CallbackHelper.testDone_();
- }.bind(this));
- // runAllActionsAsync catches exceptions and puts them in the test
- // framework's list of errors and fails the test if appropriate.
- var runAll = runAllActionsAsync(WhenTestDone.ASSERT, completionAction);
- ++this.pendingCallbacks_;
- return function() {
- savedArgs.arguments = Array.prototype.slice.call(arguments);
- runAll.invoke();
- }
- }
-};
-
-/**
- * @private
- */
-CallbackHelper.testDone_ = this.testDone;
-// Remove testDone for public use since direclty using it conflicts with
-// this callback helper.
-delete this.testDone;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_e2e_test_base.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_e2e_test_base.js
deleted file mode 100644
index bc7744cae51..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_e2e_test_base.js
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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.
-
-GEN_INCLUDE([
- 'common.js',
- 'callback_helper.js']);
-
-/**
- * Base test fixture for ChromeVox end to end tests.
- *
- * These tests run against production ChromeVox inside of the extension's
- * background page context.
- * @constructor
- */
-function ChromeVoxE2ETest() {
- this.callbackHelper_ = new CallbackHelper(this);
-}
-
-ChromeVoxE2ETest.prototype = {
- __proto__: testing.Test.prototype,
-
- /**
- * @override
- * No UI in the background context.
- */
- runAccessibilityChecks: false,
-
- /** @override */
- isAsync: true,
-
- /** @override */
- browsePreload: null,
-
- /** @override */
- testGenCppIncludes: function() {
- GEN_BLOCK(function() {/*!
-#include "ash/accessibility_delegate.h"
-#include "base/bind.h"
-#include "base/callback.h"
-#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
-#include "chrome/common/extensions/extension_constants.h"
- */});
- },
-
- /** @override */
- testGenPreamble: function() {
- GEN_BLOCK(function() {/*!
- base::Closure load_cb =
- base::Bind(&chromeos::AccessibilityManager::EnableSpokenFeedback,
- base::Unretained(chromeos::AccessibilityManager::Get()),
- true,
- ui::A11Y_NOTIFICATION_NONE);
- WaitForExtension(extension_misc::kChromeVoxExtensionId, load_cb);
- */});
- },
-
- /**
- * Launch a new tab, wait until tab status complete, then run callback.
- * @param {function() : void} doc Snippet wrapped inside of a function.
- * @param {function()} callback Called once the document is ready.
- */
- runWithLoadedTab: function(doc, callback) {
- this.launchNewTabWithDoc(doc, function(tab) {
- chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) {
- if (tabId == tab.id && changeInfo.status == 'complete') {
- callback(tabId);
- }
- });
- });
- },
-
- /**
- * Launches the given document in a new tab.
- * @param {function() : void} doc Snippet wrapped inside of a function.
- * @param {function()} opt_callback Called once the document is created.
- */
- runWithTab: function(doc, opt_callback) {
- var docString = TestUtils.extractHtmlFromCommentEncodedString(doc);
- var url = 'data:text/html,<!doctype html>' +
- docString +
- '<!-- chromevox_next_test -->';
- var createParams = {
- active: true,
- url: url
- };
- chrome.tabs.create(createParams, opt_callback);
- },
-
- /**
- * Send a key to the page.
- * @param {number} tabId Of the page.
- * @param {string} key Name of the key (e.g. Down).
- * @param {string} elementQueryString
- */
- sendKeyToElement: function(tabId, key, elementQueryString) {
- var code = TestUtils.extractHtmlFromCommentEncodedString(function() {/*!
- var target = document.body.querySelector('$1');
- target.focus();
- var evt = document.createEvent('KeyboardEvent');
- evt.initKeyboardEvent('keydown', true, true, window, '$0', 0, false,
- false, false, false);
- document.activeElement.dispatchEvent(evt);
- */}, [key, elementQueryString]);
-
- chrome.tabs.executeScript(tabId, {code: code});
- },
-
- /**
- * Creates a callback that optionally calls {@code opt_callback} when
- * called. If this method is called one or more times, then
- * {@code testDone()} will be called when all callbacks have been called.
- * @param {Function=} opt_callback Wrapped callback that will have its this
- * reference bound to the test fixture.
- * @return {Function}
- */
- newCallback: function(opt_callback) {
- return this.callbackHelper_.wrap(opt_callback);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js
deleted file mode 100644
index 8822e31f453..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['chromevox_e2e_test_base.js']);
-
-/**
- * Base test fixture for ChromeVox Next end to end tests.
- *
- * These tests are identical to ChromeVoxE2ETests except for performing the
- * necessary setup to run ChromeVox Next.
- * @constructor
- * @extends {ChromeVoxE2ETest}
- */
-function ChromeVoxNextE2ETest() {
- ChromeVoxE2ETest.call(this);
-}
-
-ChromeVoxNextE2ETest.prototype = {
- __proto__: ChromeVoxE2ETest.prototype,
-
- /**
- * Gets the desktop from the automation API and Launches a new tab with
- * the given document, and runs |callback| when a load complete fires.
- * Arranges to call |testDone()| after |callback| returns.
- * NOTE: Callbacks creatd instide |opt_callback| must be wrapped with
- * |this.newCallback| if passed to asynchonous calls. Otherwise, the test
- * will be finished prematurely.
- * @param {function() : void} doc Snippet wrapped inside of a function.
- * @param {function(chrome.automation.AutomationNode)} callback
- * Called once the document is ready.
- */
- runWithLoadedTree: function(doc, callback) {
- callback = this.newCallback(callback);
- chrome.automation.getDesktop(function(r) {
- var listener = function(evt) {
- if (!evt.target.docUrl ||
- evt.target.docUrl.indexOf('test') == -1)
- return;
-
- r.removeEventListener(listener);
- callback && callback(evt.target);
- callback = null;
- };
- r.addEventListener('loadComplete', listener, true);
- this.runWithTab(doc);
- }.bind(this));
- },
-
- listenOnce: function(node, eventType, callback, capture) {
- var innerCallback = this.newCallback(function() {
- node.removeEventListener(eventType, innerCallback, capture);
- callback();
- });
- node.addEventListener(eventType, innerCallback, capture);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_unittest_base.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_unittest_base.js
deleted file mode 100644
index 4c99e15d07d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/chromevox_unittest_base.js
+++ /dev/null
@@ -1,215 +0,0 @@
-// 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.
-
-GEN_INCLUDE(['assert_additions.js']);
-GEN_INCLUDE(['common.js',
- 'callback_helper.js']);
-
-/**
- * Base test fixture for ChromeVox unit tests.
- *
- * Note that while conceptually these are unit tests, these tests need
- * to run in a full web page, so they're actually run as WebUI browser
- * tests.
- *
- * @constructor
- * @extends {testing.Test}
- */
-function ChromeVoxUnitTestBase() {
- if (this.isAsync) {
- this.callbackHelper_ = new CallbackHelper(this);
- }
-}
-
-ChromeVoxUnitTestBase.prototype = {
- __proto__: testing.Test.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.ChromeVoxTester',
- 'cvox.ChromeVoxUserCommands',
- 'cvox.SpokenListBuilder',
- ],
-
- /** @override */
- browsePreload: DUMMY_URL,
-
- /**
- * @override
- * It doesn't make sense to run the accessibility audit on these tests,
- * since many of them are deliberately testing inaccessible html.
- */
- runAccessibilityChecks: false,
-
- /**
- * Loads some inlined html into the body of the current document, replacing
- * whatever was there previously.
- * @param {string} html The html to load as a string.
- */
- loadHtml: function(html) {
- while (document.head.firstChild) {
- document.head.removeChild(document.head.firstChild);
- }
- while (document.body.firstChild) {
- document.body.removeChild(document.body.firstChild);
- }
- this.appendHtml(html);
- },
-
- /**
- * Loads some inlined html into the current document, replacing
- * whatever was there previously. This version takes the html
- * encoded as a comment inside a function, so you can use it like this:
- *
- * this.loadDoc(function() {/*!
- * <p>Html goes here</p>
- * * /});
- *
- * @param {Function} commentEncodedHtml The html to load, embedded as a
- * comment inside an anonymous function - see example, above.
- */
- loadDoc: function(commentEncodedHtml) {
- var html =
- TestUtils.extractHtmlFromCommentEncodedString(commentEncodedHtml);
- this.loadHtml(html);
- },
-
- /**
- * Appends some inlined html into the current document, at the end of
- * the body element. Takes the html encoded as a comment inside a function,
- * so you can use it like this:
- *
- * this.appendDoc(function() {/*!
- * <p>Html goes here</p>
- * * /});
- *
- * @param {Function} commentEncodedHtml The html to load, embedded as a
- * comment inside an anonymous function - see example, above.
- */
- appendDoc: function(commentEncodedHtml) {
- var html =
- TestUtils.extractHtmlFromCommentEncodedString(commentEncodedHtml);
- this.appendHtml(html);
- },
-
- /**
- * Appends some inlined html into the current document, at the end of
- * the body element.
- * @param {string} html The html to load as a string.
- */
- appendHtml: function(html) {
- var div = document.createElement('div');
- div.innerHTML = html;
- var fragment = document.createDocumentFragment();
- while (div.firstChild) {
- fragment.appendChild(div.firstChild);
- }
- document.body.appendChild(fragment);
- },
-
- /**
- * Waits for the queued events in ChromeVoxEventWatcher to be
- * handled, then calls a callback function with provided arguments
- * in the test case scope. Very useful for asserting the results of events.
- *
- * @param {function()} func A function to call when ChromeVox is ready.
- * @param {*} var_args Additional arguments to pass through to the function.
- * @return {ChromeVoxUnitTestBase} this.
- */
- waitForCalm: function(func, var_args) {
- var calmArguments = Array.prototype.slice.call(arguments);
- calmArguments.shift();
- cvox.ChromeVoxEventWatcher.addReadyCallback(this.newCallback(function() {
- func.apply(this, calmArguments);
- }));
- return this; // for chaining.
- },
-
- /**
- * Asserts the TTS engine spoke a certain string. Clears the TTS buffer.
- * @param {string} expectedText The expected text.
- * @return {ChromeVoxUnitTestBase} this.
- */
- assertSpoken: function(expectedText) {
- assertEquals(expectedText,
- cvox.ChromeVoxTester.testTts().getUtterancesAsString());
- cvox.ChromeVoxTester.clearUtterances();
- return this; // for chaining.
- },
-
- /**
- * Asserts a list of utterances are in the correct queue mode.
- * @param {cvox.SpokenListBuilder|Array} expectedList A list
- * of [text, queueMode] tuples OR a SpokenListBuilder with the expected
- * utterances.
- * @return {ChromeVoxUnitTestBase} this.
- */
- assertSpokenList: function(expectedList) {
- if (expectedList instanceof cvox.SpokenListBuilder) {
- expectedList = expectedList.build();
- }
-
- var ulist = cvox.ChromeVoxTester.testTts().getUtteranceInfoList();
- for (var i = 0; i < expectedList.length; i++) {
- var text = expectedList[i][0];
- var queueMode = expectedList[i][1];
- this.assertSingleUtterance_(text, queueMode,
- ulist[i].text, ulist[i].queueMode);
- }
- cvox.ChromeVoxTester.clearUtterances();
- return this; // for chaining.
- },
-
- assertSingleUtterance_: function(
- expectedText, expectedQueueMode, text, queueMode) {
- assertEquals(expectedQueueMode, queueMode);
- assertEquals(expectedText, text);
- },
-
- /**
- * Focuses an element.
- * @param {string} id The id of the element to focus.
- * @return {ChromeVoxUnitTestBase} this.
- */
- setFocus: function(id) {
- $(id).focus();
- return this; // for chaining.
- },
-
- /**
- * Executes a ChromeVox user command.
- * @param {string} command The name of the command to run.
- * @return {ChromeVoxUnitTestBase} this.
- */
- userCommand: function(command) {
- cvox.ChromeVoxUserCommands.commands[command]();
- return this; // for chaining.
- },
-
- /**
- * @return {cvox.SpokenListBuilder} A new builder.
- */
- spokenList: function() {
- return new cvox.SpokenListBuilder();
- },
-
- /**
- * @type {CallbackHelper}
- * @private
- */
- callbackHelper_: null,
-
- /**
- * Creates a callback that optionally calls {@code opt_callback} when
- * called. If this method is called one or more times, then
- * {@code testDone()} will be called when all callbacks have been called.
- * @param {Function=} opt_callback Wrapped callback that will have its this
- * reference bound to the test fixture.
- * @return {Function}
- */
- newCallback: function(opt_callback) {
- assertNotEquals(null, this.callbackHelper_);
- return this.callbackHelper_.wrap(opt_callback);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/common.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/common.js
deleted file mode 100644
index b6e6d33d492..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/common.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-// Common testing utilities.
-
-/**
- * Shortcut for document.getElementById.
- * @param {string} id of the element.
- * @return {HTMLElement} with the id.
- */
-function $(id) {
- return document.getElementById(id);
-}
-
-/**
- * @constructor
- */
-var TestUtils = function() {};
-
-/**
- * Extracts some inlined html encoded as a comment inside a function,
- * so you can use it like this:
- *
- * this.appendDoc(function() {/*!
- * <p>Html goes here</p>
- * * /});
- *
- * @param {Function} commentEncodedHtml The html , embedded as a
- * comment inside an anonymous function - see example, above.
- * @param {!Array=} opt_args Optional arguments to be substituted in the form
- * $0, ... within the code block.
- * @return {string} The html text.
- */
-TestUtils.extractHtmlFromCommentEncodedString =
- function(commentEncodedHtml, opt_args) {
- var stringified = commentEncodedHtml.toString();
- if (opt_args) {
- for (var i = 0; i < opt_args.length; i++)
- stringified = stringified.replace('$' + i, opt_args[i]);
- }
- return stringified.replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, '');
-};
-
-/**
- * Similar to |TEST_F|. Generates a test for the given |testFixture|,
- * |testName|, and |testFunction|.
- * Used this variant when an |isAsync| fixture wants to temporarily mix in an
- * sync test.
- * @param {string} testFixture Fixture name.
- * @param {string} testName Test name.
- * @param {function} testFunction The test impl.
- */
-function SYNC_TEST_F(testFixture, testName, testFunction) {
- TEST_F(testFixture, testName, function() {
- this.newCallback(testFunction)();
- });
-}
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/fake_objects.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/fake_objects.js
deleted file mode 100644
index 8c5419f7b28..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/fake_objects.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.
-
-/**
- * Fakes a Chrome event that supports one listener.
- * @constructor
- * @extends {ChromeEvent}
- */
-function FakeChromeEvent() {
- /**
- * @private
- * @type {Function}
- */
- this.listener_ = null;
-}
-
-FakeChromeEvent.prototype = {
- /**
- * Fakes the corresponding call on a Chrome event. Sets the listener and
- * fails the test if it is already set.
- * @param {Function} listener The new listener.
- */
- addListener: function(listener) {
- this.assertNoListener();
- this.listener_ = listener;
- },
-
- /**
- * Gets the listener of the event, failing the test if there's none.
- * @return {Function} The event's listener.
- */
- getListener: function() {
- assertNotEquals(null, this.listener_);
- return this.listener_;
- },
-
- /**
- * Asserts that this object doesn't have any listener added.
- */
- assertNoListener: function() {
- assertEquals(null, this.listener_);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js
deleted file mode 100644
index e3578aa0bf7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview This file contains the |MockFeedback| class which is a
- * combined mock class for speech and braille feedback. A test that uses
- * this class may add expectations for speech utterances and braille display
- * content to be output. The |install| method sets appropriate mock classes
- * as the |cvox.ChromeVox.tts| and |cvox.ChromeVox.braille| objects,
- * respectively. Output sent to those objects will then be collected in
- * an internal queue.
- *
- * Expectations can be added using the |expectSpeech| and |expectBraille|
- * methods. These methods take either strings or regular expressions to match
- * against. Strings must match a full utterance (or display content) exactly,
- * while a regular expression must match a substring (use anchor operators if
- * needed).
- *
- * Function calls may be inserted in the stream of expectations using the
- * |call| method. Such callbacks are called after all preceding expectations
- * have been met, and before any further expectations are matched. Callbacks
- * are called in the order they were added to the mock.
- *
- * The |replay| method starts processing any pending utterances and braille
- * display content and will try to match expectations as new feedback enters
- * the queue asynchronously. When all expectations have been met and callbacks
- * called, the finish callback, if any was provided to the constructor, is
- * called.
- *
- * This mock class is lean, meaning that feedback that doesn't match
- * any expectations is silently ignored.
- *
- * NOTE: for asynchronous tests, the processing will never finish if there
- * are unmet expectations. To help debugging in such situations, the mock
- * will output its pending state if there are pending expectations and no
- * output is received within a few seconds.
- *
- * See mock_feedback_test.js for example usage of this class.
- */
-
-/**
- * Combined mock class for braille and speech output.
- * @param {function=} opt_finishedCallback Called when all expectations have
- * been met.
- * @constructor
- */
-var MockFeedback = function(opt_finishedCallback) {
- /**
- * @type {function}
- * @private
- */
- this.finishedCallback_ = opt_finishedCallback || null;
- /**
- * True when |replay| has been called and actions are being replayed.
- * @type {boolean}
- * @private
- */
- this.replaying_ = false;
- /**
- * True when inside the |process| function to prevent nested calls.
- * @type {boolean}
- * @private
- */
- this.inProcess_ = false;
- /**
- * Pending expectations and callbacks.
- * @type {Array<{perform: function(): boolean, toString: function(): string}>}
- * @private
- */
- this.pendingActions_ = [];
- /**
- * Pending speech utterances.
- * @type {Array<{text: string, callback: (function|undefined)}>}
- * @private
- */
- this.pendingUtterances_ = [];
- /**
- * Pending braille output.
- * @type {Array<{text: string, callback: (function|undefined)}>}
- * @private
- */
- this.pendingBraille_ = [];
- /**
- * Handle for the timeout set for debug logging.
- * @type {number}
- * @private
- */
- this.logTimeoutId_ = 0;
- /**
- * @type {cvox.NavBraille}
- * @private
- */
- this.lastMatchedBraille_ = null;
-};
-
-MockFeedback.prototype = {
-
- /**
- * Install mock objects as |cvox.ChromeVox.tts| and |cvox.ChromeVox.braille|
- * to collect feedback.
- */
- install: function() {
- assertFalse(this.replaying_);
-
- var MockTts = function() {};
- MockTts.prototype = {
- __proto__: cvox.TtsInterface.prototype,
- speak: this.addUtterance_.bind(this)
- };
-
- cvox.ChromeVox.tts = new MockTts();
-
- var MockBraille = function() {};
- MockBraille.prototype = {
- __proto__: cvox.BrailleInterface.prototype,
- write: this.addBraille_.bind(this)
- };
-
- cvox.ChromeVox.braille = new MockBraille();
- },
-
- /**
- * Adds an expectation for one or more spoken utterances.
- * @param {...(string|RegExp)} var_args One or more utterance to add as
- * expectations.
- * @return {MockFeedback} |this| for chaining
- */
- expectSpeech: function() {
- assertFalse(this.replaying_);
- Array.prototype.forEach.call(arguments, function(text) {
- this.pendingActions_.push({
- perform: function() {
- return !!MockFeedback.matchAndConsume_(
- text, {}, this.pendingUtterances_);
- }.bind(this),
- toString: function() { return 'Speak \'' + text + '\''; }
- });
- }.bind(this));
- return this;
- },
-
- /**
- * Adds an expectation that the next spoken utterances do *not* match
- * the given arguments.
- *
- * This is only guaranteed to work for the immediately following utterance.
- * If you use it to check an utterance other than the immediately following
- * one the results may be flaky.
- *
- * @param {...(string|RegExp)} var_args One or more utterance to add as
- * negative expectations.
- * @return {MockFeedback} |this| for chaining
- */
- expectNextSpeechUtteranceIsNot: function() {
- assertFalse(this.replaying_);
- Array.prototype.forEach.call(arguments, function(text) {
- this.pendingActions_.push({
- perform: function() {
- if (this.pendingUtterances_.length == 0)
- return false;
- if (MockFeedback.matchAndConsume_(
- text, {}, this.pendingUtterances_)) {
- throw new Error('Got disallowed utterance "' + text + '".');
- }
- return true;
- }.bind(this),
- toString: function() { return 'Do not speak \'' + text + '\''; }
- });
- }.bind(this));
- return this;
- },
-
- /**
- * Adds an expectation for braille output.
- * @param {string|RegExp} text
- * @param {Object=} opt_props Additional properties to match in the
- * |NavBraille|
- * @return {MockFeedback} |this| for chaining
- */
- expectBraille: function(text, opt_props) {
- assertFalse(this.replaying_);
- var props = opt_props || {};
- this.pendingActions_.push({
- perform: function() {
- var match = MockFeedback.matchAndConsume_(
- text, props, this.pendingBraille_);
- if (match)
- this.lastMatchedBraille_ = match;
- return !!match;
- }.bind(this),
- toString: function() {
- return 'Braille \'' + text + '\' ' + JSON.stringify(props);
- }
- });
- return this;
- },
-
- /**
- * Arranges for a callback to be invoked when all expectations that were
- * added before this call have been met. Callbacks are called in the
- * order they are added.
- * @param {Function} callback
- * @return {MockFeedback} |this| for chaining
- */
- call: function(callback) {
- assertFalse(this.replaying_);
- this.pendingActions_.push({
- perform: function() {
- callback();
- return true;
- },
- toString: function() {
- return 'Callback';
- }
- });
- return this;
- },
-
- /**
- * Processes any feedback that has been received so far and treis to
- * satisfy the registered expectations. Any feedback that is received
- * after this call (via the installed mock objects) is processed immediately.
- * When all expectations are satisfied and registered callbacks called,
- * the finish callbcak, if any, is called.
- * This function may only be called once.
- */
- replay: function() {
- assertFalse(this.replaying_);
- this.replaying_ = true;
- this.process_();
- },
-
- /**
- * Returns the |NavBraille| that matched an expectation. This is
- * intended to be used by a callback to invoke braille commands that
- * depend on display contents.
- * @type {cvox.NavBraille}
- */
- get lastMatchedBraille() {
- assertTrue(this.replaying_);
- return this.lastMatchedBraille_;
- },
-
- /**
- * @param {string} textString
- * @param {cvox.QueueMode} queueMode
- * @param {Object=} properties
- * @private
- */
- addUtterance_: function(textString, queueMode, properties) {
- var callback;
- if (properties && (properties.startCallback || properties.endCallback)) {
- var startCallback = properties.startCallback;
- var endCallback = properties.endCallback;
- callback = function() {
- startCallback && startCallback();
- endCallback && endCallback();
- };
- }
- this.pendingUtterances_.push(
- {text: textString,
- callback: callback});
- this.process_();
- },
-
- /** @private */
- addBraille_: function(navBraille) {
- this.pendingBraille_.push(navBraille);
- this.process_();
- },
-
- /*** @private */
- process_: function() {
- if (!this.replaying_ || this.inProcess_)
- return;
- try {
- this.inProcess_ = true;
- while (this.pendingActions_.length > 0) {
- var action = this.pendingActions_[0];
- if (action.perform()) {
- this.pendingActions_.shift();
- if (this.logTimeoutId_) {
- window.clearTimeout(this.logTimeoutId_);
- this.logTimeoutId_ = 0;
- }
- } else {
- break;
- }
- }
- if (this.pendingActions_.length == 0) {
- if (this.finishedCallback_) {
- this.finishedCallback_();
- this.finishedCallback_ = null;
- }
- } else {
- // If there are pending actions and no matching feedback for a few
- // seconds, log the pending state to ease debugging.
- if (!this.logTimeoutId_) {
- this.logTimeoutId_ = window.setTimeout(
- this.logPendingState_.bind(this), 2000);
- }
- }
- } finally {
- this.inProcess_ = false;
- }
- },
-
- /** @private */
- logPendingState_: function() {
- if (this.pendingActions_.length > 0)
- console.log('Still waiting for ' + this.pendingActions_[0].toString());
- function logPending(desc, list) {
- if (list.length > 0)
- console.log('Pending ' + desc + ':\n ' +
- list.map(function(i) {
- var ret = '\'' + i.text + '\'';
- if ('startIndex' in i)
- ret += ' startIndex=' + i.startIndex;
- if ('endIndex' in i)
- ret += ' endIndex=' + i.endIndex;
- return ret;
- }).join('\n ') + '\n ');
- }
- logPending('speech utterances', this.pendingUtterances_);
- logPending('braille', this.pendingBraille_);
- this.logTimeoutId_ = 0;
- },
-};
-
-/**
- * @param {string} text
- * @param {Object} props
- * @param {Array<{text: (string|RegExp), callback: (function|undefined)}>}
- * pending
- * @return {Object}
- * @private
- */
-MockFeedback.matchAndConsume_ = function(text, props, pending) {
- for (var i = 0, candidate; candidate = pending[i]; ++i) {
- var candidateText = candidate.text.toString();
- if (text === candidateText ||
- (text instanceof RegExp && text.test(candidateText))) {
- var matched = true;
- for (prop in props) {
- if (candidate[prop] !== props[prop]) {
- matched = false;
- break;
- }
- }
- if (matched)
- break;
- }
- }
- if (candidate) {
- var consumed = pending.splice(0, i + 1);
- consumed.forEach(function(item) {
- if (item.callback)
- item.callback();
- });
- }
- return candidate;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback_test.unitjs
deleted file mode 100644
index 77c82201bb0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/mock_feedback_test.unitjs
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Include test fixture.
-GEN_INCLUDE(['chromevox_unittest_base.js',
- 'mock_feedback.js']);
-
-function speak(text, opt_properties) {
- cvox.ChromeVox.tts.speak(text, 0, opt_properties);
-}
-
-function braille(text) {
- var navBraille = cvox.NavBraille.fromText(text);
- cvox.ChromeVox.braille.write(navBraille);
- return navBraille;
-}
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function MockFeedbackUnitTest() {
- ChromeVoxUnitTestBase.call(this);
- this.expectedCalls = [];
-}
-
-MockFeedbackUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- setUp: function() {
- cvox.ChromeVox = cvox.ChromeVox || {};
- },
-
- closureModuleDeps: [
- 'cvox.BrailleInterface',
- 'cvox.NavBraille',
- 'cvox.TtsInterface'
- ]
-};
-
-TEST_F('MockFeedbackUnitTest', 'speechAndCallbacks', function() {
- var afterThirdStringCalled = false;
- var spruiousStringEndCallbackCalled = false;
- var finishCalled = false;
- var mock = new MockFeedback(function() {
- assertFalse(finishCalled);
- finishCalled = true;
-
- assertTrue(afterThirdStringCalled);
- assertTrue(spruiousStringEndCallbackCalled);
- });
- mock.install();
- speak('First string');
- speak('Second string');
- mock.expectSpeech('First string', 'Second string')
- .expectSpeech('Third string')
- .call(function() {
- assertFalse(afterThirdStringCalled);
- afterThirdStringCalled = true;
- speak('Spurious string', {endCallback: function() {
- assertFalse(spruiousStringEndCallbackCalled);
- spruiousStringEndCallbackCalled = true;
- }});
- speak('Fourth string');
- })
- .expectSpeech('Fourth string')
- .replay();
- assertFalse(finishCalled);
- speak('Third string');
- assertTrue(finishCalled);
-});
-
-TEST_F('MockFeedbackUnitTest', 'startAndEndCallbacks', function() {
- var onlyStartCallbackCalled = false;
- var onlyEndCallbackCalled = false;
- var bothCallbacksStartCalled = false;
- var bothCallbacksEndCalled = false;
- var mock = new MockFeedback();
- mock.install();
- speak('No callbacks', {});
- speak('Only start callback', {startCallback: function() {
- assertFalse(onlyStartCallbackCalled);
- onlyStartCallbackCalled = true;
- assertFalse(onlyEndCallbackCalled);
- }});
- speak('Only end callback', {endCallback: function() {
- assertTrue(onlyStartCallbackCalled);
- assertFalse(onlyEndCallbackCalled);
- onlyEndCallbackCalled = true;
- assertFalse(bothCallbacksStartCalled);
- }});
- speak('Both callbacks',
- {startCallback: function() {
- assertTrue(onlyEndCallbackCalled);
- assertFalse(bothCallbacksStartCalled);
- bothCallbacksStartCalled = true;
- assertFalse(bothCallbacksEndCalled);
- },
- endCallback: function() {
- assertTrue(bothCallbacksStartCalled);
- assertFalse(bothCallbacksEndCalled);
- bothCallbacksEndCalled = true;
- }});
- mock.expectSpeech('Both callbacks');
- mock.replay();
- assertTrue(bothCallbacksEndCalled);
-});
-
-TEST_F('MockFeedbackUnitTest', 'SpeechAndBraille', function() {
- var secondCallbackCalled = false;
- var finishCalled = false;
- var mock = new MockFeedback(function() { finishCalled = true; });
- var firstExpectedNavBraille;
- mock.install();
- braille('Some braille');
- speak('Some speech');
- mock.call(function() {
- assertEquals(null, mock.lastMatchedBraille);
- firstExpectedNavBraille = braille('First expected braille');
- speak('First expected speech');
- braille('Some other braille');
- })
- .expectSpeech('First expected speech')
- .expectBraille('First expected braille')
- .call(function() {
- secondCallbackCalled = true;
- assertEquals(firstExpectedNavBraille, mock.lastMatchedBraille);
- })
- .replay();
- assertTrue(secondCallbackCalled);
- assertTrue(finishCalled);
-});
-
-TEST_F('MockFeedbackUnitTest', 'expectWithRegex', function() {
- var done = false;
- var mock = new MockFeedback();
- mock.install();
- mock.call(function() { braille('Item 1 of 14'); })
- .expectBraille(/Item \d+ of \d+/)
- .call(function() { done = true;})
- .replay();
- assertTrue(done);
-});
-
-TEST_F('MockFeedbackUnitTest', 'expectAfterReplayThrows', function() {
- var mock = new MockFeedback();
- mock.replay();
- assertException('', function() {
- mock.expectSpeech('hello');
- }, 'Error');
-});
-
-TEST_F('MockFeedbackUnitTest', 'NoMatchDoesNotFinish', function() {
- var firstCallbackCalled = false;
- var mock = new MockFeedback(function() {
- throw Error('Should not be called');
- });
- mock.install();
- braille('Some string');
- mock.call(function() {
- braille('Some other string');
- firstCallbackCalled = true;
- })
- .expectBraille('Unmatched string')
- .call(function() {
- throw Error('Should not be called');
- })
- .replay();
- assertTrue(firstCallbackCalled);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/spoken_list_builder.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/spoken_list_builder.js
deleted file mode 100644
index 64bc467882e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/spoken_list_builder.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview The spoken list builder. Used in test cases.
- */
-
-goog.provide('cvox.SpokenListBuilder');
-goog.require('cvox.QueueMode');
-
-
-/**
- * Builds a spoken list.
- * @constructor
- */
-cvox.SpokenListBuilder = function() {
- this.list_ = [];
-};
-
-
-/**
- * Adds an expected flushed utterance to the builder.
- * @param {string} expectedText The expected text.
- * @return {cvox.SpokenListBuilder} this.
- */
-cvox.SpokenListBuilder.prototype.flush = function(expectedText) {
- this.list_.push([expectedText, cvox.QueueMode.FLUSH]);
- return this; // for chaining
-};
-
-
-/**
- * Adds an expected queued utterance to the builder.
- * @param {string} expectedText The expected text.
- * @return {cvox.SpokenListBuilder} this.
- */
-cvox.SpokenListBuilder.prototype.queue = function(expectedText) {
- this.list_.push([expectedText, cvox.QueueMode.QUEUE]);
- return this; // for chaining
-};
-
-
-/**
- * Adds an expected category-flush utterance to the builder.
- * @param {string} expectedText The expected text.
- * @return {cvox.SpokenListBuilder} this.
- */
-cvox.SpokenListBuilder.prototype.categoryFlush = function(expectedText) {
- this.list_.push([expectedText, cvox.QueueMode.CATEGORY_FLUSH]);
- return this; // for chaining
-};
-
-
-/**
- * Builds the list.
- * @return {Array} The array of utterances.
- */
-cvox.SpokenListBuilder.prototype.build = function() {
- return this.list_;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js
deleted file mode 100644
index e4dd01d5c36..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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.
-
-
-/**
- * @fileoverview Testing stub for messages.
- */
-
-goog.provide('TestMsgs');
-
-goog.require('Msgs');
-goog.require('cvox.TestMessages');
-
-/**
- * @constructor
- */
-TestMsgs = function() {};
-
-/**
- * @type {Object<string>}
- */
-TestMsgs.Untranslated = Msgs.Untranslated;
-
-/**
- * @return {string} The locale.
- */
-TestMsgs.getLocale = function() {
- return 'testing';
-};
-
-/**
- * @param {string} messageId
- * @param {Array<string>=} opt_subs
- * @return {string}
- */
-TestMsgs.getMsg = function(messageId, opt_subs) {
- if (!messageId) {
- throw Error('Message id required');
- }
- var message = TestMsgs.Untranslated[messageId.toUpperCase()];
- if (message !== undefined)
- return message;
- message = cvox.TestMessages[('chromevox_' + messageId).toUpperCase()];
- if (message === undefined) {
- throw Error('missing-msg: ' + messageId);
- }
-
- var messageString = message.message;
- if (opt_subs) {
- // Unshift a null to make opt_subs and message.placeholders line up.
- for (var i = 0; i < opt_subs.length; i++) {
- messageString = messageString.replace('$' + (i + 1), opt_subs[i]);
- }
- }
- return messageString;
-};
-
-/**
- * @param {number} num
- * @return {string}
- */
-TestMsgs.getNumber = Msgs.getNumber;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/testing/tester.js b/chromium/chrome/browser/resources/chromeos/chromevox/testing/tester.js
deleted file mode 100644
index bab5c6a1559..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/testing/tester.js
+++ /dev/null
@@ -1,138 +0,0 @@
-// 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.
-
-goog.provide('cvox.ChromeVoxTester');
-
-goog.require('TestMsgs');
-goog.require('cvox.AbstractEarcons');
-goog.require('cvox.BrailleInterface');
-goog.require('cvox.ChromeVoxEventWatcher');
-goog.require('cvox.ChromeVoxUserCommands');
-goog.require('cvox.LiveRegions');
-goog.require('cvox.NavigationManager');
-goog.require('cvox.NavigationShifter');
-goog.require('cvox.QueueMode');
-goog.require('cvox.TestHost');
-goog.require('cvox.TestMathJax');
-goog.require('cvox.TestTts');
-
-
-/**
- * @fileoverview Testing framework for ChromeVox.
- *
- */
-
-
-/**
- * Initializes cvox.ChromeVoxTester and sets up the mock ChromeVox
- * environment.
- * @param {!Document} doc The DOM document to add event listeners to.
- */
-cvox.ChromeVoxTester.setUp = function(doc) {
- cvox.ChromeVox.mathJax = new cvox.TestMathJax();
-
- cvox.ChromeVox.navigationManager = new cvox.NavigationManager();
- cvox.ChromeVoxTester.testTts_ = new cvox.TestTts();
- cvox.ChromeVox.tts = cvox.ChromeVoxTester.testTts_;
-
- // TODO(deboer): Factor this out as 'TestEarcons'
- cvox.ChromeVox.earcons = new cvox.AbstractEarcons();
- cvox.ChromeVox.earcons.playEarcon = function(earcon) { };
-
- cvox.ChromeVox.braille = new cvox.BrailleInterface();
- cvox.ChromeVox.braille.write = function(params) {};
-
- Msgs = TestMsgs;
-
- cvox.ChromeVox.host = new cvox.TestHost();
-
- // Init LiveRegions with a date of 0 so that the initial delay before
- // things is spoken is skipped.
- cvox.LiveRegions.init(new Date(0), cvox.QueueMode.QUEUE, false);
-
- cvox.ChromeVoxEventWatcher.init(doc);
- window.console.log('done setup');
-};
-
-/**
- * Tears down cvox.ChromeVoxTester.
- * @param {!Document} doc The DOM document where event listeners were added.
- */
-cvox.ChromeVoxTester.tearDown = function(doc) {
- cvox.ChromeVoxEventWatcher.cleanup(doc);
-};
-
-
-/**
- * Returns the cvox.TestTts created by the tester.
- * @return {cvox.TestTts} The TestTts.
- */
-cvox.ChromeVoxTester.testTts = function() {
- return cvox.ChromeVoxTester.testTts_;
-};
-
-
-/**
- * All calls to tts.speak are saved in an array of utterances.
- * Clear any utterances that were saved up to this poing.
- */
-cvox.ChromeVoxTester.clearUtterances = function() {
- cvox.ChromeVoxTester.testTts_.clearUtterances();
-};
-
-
-/**
- * Return a list of strings of what was spoken by tts.speak().
- * @return {Array<string>} A list of all utterances spoken since
- * initialization or the last call to clearUtterances.
- */
-cvox.ChromeVoxTester.getUtteranceList = function() {
- return cvox.ChromeVoxTester.testTts_.getUtteranceList();
-};
-
-/**
- * @type {Object<number>} Map from a navigation strategy name to the Navigation
- * Manager strategy enum.
- */
-cvox.ChromeVoxTester.STRATEGY_MAP = {
- 'lineardom': cvox.NavigationShifter.GRANULARITIES.OBJECT,
- 'smart': cvox.NavigationShifter.GRANULARITIES.GROUP,
- 'selection': cvox.NavigationShifter.GRANULARITIES.SENTENCE
-};
-
-/**
- * Switches to a different navigation strategy.
- * @param {string} strategy The desired navigation strategy.
- */
-cvox.ChromeVoxTester.setStrategy = function(strategy) {
- cvox.ChromeVox.navigationManager.ensureNotSubnavigating();
- cvox.ChromeVox.navigationManager.setGranularity(
- cvox.ChromeVoxTester.STRATEGY_MAP[strategy]);
-};
-
-/**
- * Starts reading the page from the current node.
- */
-cvox.ChromeVoxTester.readFromHere = function() {
- cvox.ChromeVox.navigationManager.startReading(
- cvox.QueueMode.FLUSH);
-};
-
-/**
- * Syncs to the given node in the test HTML
- * @param {Node} node The node to sync to.
- */
-cvox.ChromeVoxTester.syncToNode = function(node) {
- cvox.ChromeVox.navigationManager
- .updateSel(cvox.CursorSelection.fromNode(node));
- cvox.ChromeVox.navigationManager.sync();
-};
-
-/**
- * Syncs to the first node in the test.
- */
-cvox.ChromeVoxTester.syncToFirstNode = function() {
- cvox.ChromeVox.navigationManager.updateSel(cvox.CursorSelection.fromBody());
- cvox.ChromeVox.navigationManager.sync();
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/check_chromevox.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/check_chromevox.py
deleted file mode 100755
index bb5cb4d5a2e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/check_chromevox.py
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''Uses the closure compiler to check the ChromeVox javascript files.
-
-With no arguments, checks all ChromeVox scripts. If any arguments are
-specified, only scripts that include any of the specified files will be
-compiled. A useful argument list is the output of the command
-'git diff --name-only --relative'.
-'''
-
-import optparse
-import os
-import re
-import sys
-
-from multiprocessing import pool
-
-from jsbundler import Bundle, CalcDeps, ReadSources
-from jscompilerwrapper import RunCompiler
-
-_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-_CHROME_SOURCE_DIR = os.path.normpath(
- os.path.join(_SCRIPT_DIR, *[os.path.pardir] * 6))
-
-
-def CVoxPath(path='.'):
- '''Converts a path relative to the top-level chromevox directory to a
- path relative to the current directory.
- '''
- return os.path.relpath(os.path.join(_SCRIPT_DIR, '..', path))
-
-
-def ChromeRootPath(path='.'):
- '''Converts a path relative to the top-level chromevox directory to a
- path relative to the current directory.
- '''
- return os.path.relpath(os.path.join(_CHROME_SOURCE_DIR, path))
-
-
-# Name of chrome extensions externs file.
-_CHROME_EXTENSIONS_EXTERNS = (
- ChromeRootPath('third_party/closure_compiler/externs/chrome_extensions.js'))
-
-# Externs common to many ChromeVox scripts.
-_COMMON_EXTERNS = [
- CVoxPath('common/externs.js'),
- CVoxPath('common/chrome_extension_externs.js'),
- CVoxPath('chromevox/background/externs.js'),
- CVoxPath('chromevox/injected/externs.js'),
- CVoxPath('host/chrome/externs.js'),
- _CHROME_EXTENSIONS_EXTERNS]
-
-# List of top-level scripts and externs that we can check.
-_TOP_LEVEL_SCRIPTS = [
- [[CVoxPath('chromevox/background/kbexplorer_loader.js')],
- [_CHROME_EXTENSIONS_EXTERNS]],
- [[CVoxPath('chromevox/background/options_loader.js')], _COMMON_EXTERNS],
- [[CVoxPath('chromevox/injected/loader.js')], _COMMON_EXTERNS],
- [[CVoxPath('cvox2/background/loader.js')], _COMMON_EXTERNS],
- ]
-
-
-def _Compile(js_files, externs):
- try:
- return RunCompiler(js_files, externs)
- except KeyboardInterrupt:
- return (False, 'KeyboardInterrupt')
-
-
-def CheckChromeVox(changed_files=None):
- if changed_files is not None:
- changed_files_set = frozenset(
- (os.path.relpath(path) for path in changed_files))
- if len(changed_files_set) == 0:
- return (True, '')
- else:
- changed_files_set = None
- ret_success = True
- ret_output = ''
- roots = [CVoxPath(),
- os.path.relpath(
- os.path.join(
- _CHROME_SOURCE_DIR,
- 'chrome/third_party/chromevox/third_party/closure-library/'
- 'closure/goog'))]
- sources = ReadSources(roots, need_source_text=True,
- exclude=[re.compile('testing')])
- work_pool = pool.Pool(len(_TOP_LEVEL_SCRIPTS))
- try:
- results = []
- for top_level in _TOP_LEVEL_SCRIPTS:
- tl_files, externs = top_level
- bundle = Bundle()
- CalcDeps(bundle, sources, tl_files)
- bundle.Add((sources[name] for name in tl_files))
- ordered_paths = list(bundle.GetInPaths())
- if (changed_files_set is not None and
- changed_files_set.isdisjoint(ordered_paths + externs)):
- continue
- print 'Compiling %s' % ','.join(tl_files)
- results.append([tl_files,
- work_pool.apply_async(
- _Compile,
- args=[ordered_paths, externs])])
- for result in results:
- tl_files = result[0]
- success, output = result[1].get()
- if not success:
- ret_output += '\nFrom compiling %s:\n%s\n' % (','.join(tl_files),
- output)
- ret_success = False
- work_pool.close()
- except:
- work_pool.terminate()
- raise
- finally:
- work_pool.join()
- return (ret_success, ret_output)
-
-
-def main():
- parser = optparse.OptionParser(description=__doc__)
- parser.usage = '%prog [<changed_file>...]'
- _, args = parser.parse_args()
-
- changed_paths = None
- if len(args) > 0:
- changed_paths = (os.path.relpath(p) for p in args)
- success, output = CheckChromeVox(changed_paths)
- if len(output) > 0:
- print output
- return int(not success)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/find_js_files.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/find_js_files.py
deleted file mode 100755
index 6d459a3149c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/find_js_files.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''Scans one or more directory trees for .js files, printing filenames,
-relative to the current directory on stdout.
-'''
-
-import optparse
-import os
-import sys
-
-_SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__))
-_CHROME_SOURCE = os.path.realpath(
- os.path.join(_SCRIPT_DIR, *[os.path.pardir] * 6))
-sys.path.insert(
- 0, os.path.join(
- _CHROME_SOURCE, ('chrome/third_party/chromevox/third_party/' +
- 'closure-library/closure/bin/build')))
-import treescan
-
-
-def main():
- parser = optparse.OptionParser(description=__doc__)
- parser.usage = '%prog <tree_root>...'
- _, args = parser.parse_args()
- for root in args:
- print '\n'.join(treescan.ScanTreeForJsFiles(root))
-
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_deps.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_deps.py
deleted file mode 100755
index 4468b7f928c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_deps.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-''' Generates a deps.js file based on an input list of javascript files using
-Closure style provide/require calls.
-'''
-
-import optparse
-import os
-import sys
-
-from jsbundler import PathRewriter
-
-_SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__))
-_CHROME_SOURCE = os.path.realpath(
- os.path.join(_SCRIPT_DIR, *[os.path.pardir] * 6))
-sys.path.insert(0, os.path.join(
- _CHROME_SOURCE, ('chrome/third_party/chromevox/third_party/' +
- 'closure-library/closure/bin/build')))
-import source
-
-
-def _HasSameContent(filename, content):
- '''Returns true if the given file is readable and has the given content.'''
- try:
- with open(filename) as file:
- return file.read() == content
- except:
- # Ignore all errors and fall back on a safe bet.
- return False
-
-
-def main():
- parser = optparse.OptionParser(description=__doc__)
- parser.add_option('-w', '--rewrite_prefix', action='append', default=[],
- dest='prefix_map', metavar='SPEC',
- help=('Two path prefixes, separated by colons ' +
- 'specifying that a file whose (relative) path ' +
- 'name starts with the first prefix should have ' +
- 'that prefix replaced by the second prefix to ' +
- 'form a path relative to the output directory. ' +
- 'The resulting path is used in the deps mapping ' +
- 'file path to a list of provided and required ' +
- 'namespaces.'))
- parser.add_option('-o', '--output_file', action='store', default=[],
- metavar='SPEC',
- help=('Where to output the generated deps file.'))
- options, args = parser.parse_args()
-
- path_rewriter = PathRewriter(options.prefix_map)
-
- content = ''
- for path in args:
- js_deps = source.Source(source.GetFileContents(path))
- path = path_rewriter.RewritePath(path)
- content += 'goog.addDependency(\'%s\', %s, %s);\n' % (
- path, sorted(js_deps.provides), sorted(js_deps.requires))
- if _HasSameContent(options.output_file, content):
- return
- # Write the generated deps file.
- with open(options.output_file, 'w') as output:
- output.write(content)
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_manifest.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_manifest.py
deleted file mode 100755
index c3a2a4c070d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_manifest.py
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-import json
-import io
-import optparse
-import os
-import sys
-
-jinja2_path = os.path.normpath(os.path.join(os.path.abspath(__file__),
- *[os.path.pardir] * 7 + ['third_party']))
-nom_path = os.path.normpath(os.path.join(os.path.abspath(__file__),
- *[os.path.pardir] * 7 + ['tools/json_comment_eater']))
-version_py_path = os.path.normpath(os.path.join(os.path.abspath(__file__),
- *[os.path.pardir] * 7 + ['build/util']))
-sys.path.insert(0, jinja2_path)
-sys.path.insert(0, nom_path)
-sys.path.insert(0, version_py_path)
-import jinja2
-from json_comment_eater import Nom
-import version
-
-
-'''Generate an extension manifest based on a template.'''
-
-def getChromeVersion(version_file):
- values = version.fetch_values([version_file])
- return version.subst_template('@MAJOR@.@MINOR@.@BUILD@.@PATCH@', values)
-
-
-def processJinjaTemplate(input_file, output_file, context):
- (template_path, template_name) = os.path.split(input_file)
- env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_path),
- trim_blocks=True)
- template = env.get_template(template_name)
- rendered = template.render(context)
- rendered_without_comments = Nom(rendered)
- # Simply for validation.
- json.loads(rendered_without_comments)
- with io.open(output_file, 'w', encoding='utf-8') as manifest_file:
- manifest_file.write(rendered_without_comments)
-
-
-def main():
- parser = optparse.OptionParser(description=__doc__)
- parser.usage = '%prog [options] <template_manifest_path>'
- parser.add_option(
- '-o', '--output_manifest', action='store', metavar='OUTPUT_MANIFEST',
- help='File to place generated manifest')
- parser.add_option(
- '--is_guest_manifest', default='0', action='store', metavar='NUM',
- help='Whether to generate a guest mode capable manifest')
- parser.add_option(
- '--is_chromevox_classic', default='0', action='store', metavar='NUM',
- help='Whether to generate a ChromeVox Classic manifest')
- parser.add_option(
- '--is_js_compressed', default='1', action='store', metavar='NUM',
- help='Whether compressed JavaScript files are used')
- parser.add_option(
- '--set_version', action='store', metavar='SET_VERSION',
- help='Set the extension version')
- parser.add_option(
- '--key', action='store', metavar='KEY',
- help='Set the extension key')
- parser.add_option(
- '--version_file', action='store', metavar='NAME',
- help='File with version information')
-
- options, args = parser.parse_args()
- if len(args) != 1:
- print >>sys.stderr, 'Expected exactly one argument'
- sys.exit(1)
- if options.output_manifest is None:
- print >>sys.stderr, '--output_manifest option must be specified'
- sys.exit(1)
- if options.set_version is not None and options.version_file is not None:
- print >>sys.stderr, ('only one of --set_version and --version_file may ' +
- 'be specified')
- if options.set_version is None and options.version_file is None:
- print >>sys.stderr, ('one of --set_version or --version_file option ' +
- 'must be specified')
- sys.exit(1)
- context = {k: v for k, v in parser.values.__dict__.items() if v is not None}
- if options.version_file is not None:
- context['set_version'] = getChromeVersion(options.version_file)
- processJinjaTemplate(args[0], options.output_manifest, context)
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_test_messages.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_test_messages.py
deleted file mode 100755
index 17d4088ca34..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/generate_test_messages.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''Generates test_messages.js from an extension message json file.'''
-
-import optparse
-import sys
-
-def Die(message):
- '''Prints an error message and exit the program.'''
- print >>sys.stderr, message
- sys.exit(1)
-
-
-# Tempalte for the test_messages.js.
-_JS_TEMPLATE = '''// GENERATED FROM %(in_file)s
-
-goog.provide('cvox.TestMessages');
-
-cvox.TestMessages = %(json)s;
-'''
-
-
-def main():
- parser = optparse.OptionParser(description=__doc__)
- parser.add_option('-o', '--output_file', action='store',
- metavar='SPEC',
- help=('Where to output the generated deps file.'))
- options, args = parser.parse_args()
- if options.output_file is None:
- Die('Output file not specified')
- if len(args) != 1:
- Die('Exactly one input file must be specified')
- in_file_name = args[0]
- with open(in_file_name) as in_file:
- json = in_file.read().strip()
- with open(options.output_file, 'w') as out_file:
- out_file.write(_JS_TEMPLATE % {'in_file': in_file_name, 'json': json})
-
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/jsbundler.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/jsbundler.py
deleted file mode 100755
index 4b314389a2f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/jsbundler.py
+++ /dev/null
@@ -1,378 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''Produces various output formats from a set of JavaScript files with
-closure style require/provide calls.
-
-Scans one or more directory trees for JavaScript files. Then, from a
-given list of top-level files, sorts all required input files topologically.
-The top-level files are appended to the sorted list in the order specified
-on the command line. If no root directories are specified, the source
-files are assumed to be ordered already and no dependency analysis is
-performed. The resulting file list can then be used in one of the following
-ways:
-
-- list: a plain list of files, one per line is output.
-
-- html: a series of html <script> tags with src attributes containing paths
- is output.
-
-- bundle: a concatenation of all the files, separated by newlines is output.
-
-- compressed_bundle: A bundle where non-significant whitespace, including
- comments, has been stripped is output.
-
-- copy: the files are copied, or hard linked if possible, to the destination
- directory. In this case, no output is generated.
-'''
-
-
-import optparse
-import os
-import re
-import shutil
-import sys
-
-_SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__))
-_CHROME_SOURCE = os.path.realpath(
- os.path.join(_SCRIPT_DIR, *[os.path.pardir] * 6))
-sys.path.insert(0, os.path.join(
- _CHROME_SOURCE, 'third_party/WebKit/Source/build/scripts'))
-sys.path.insert(0, os.path.join(
- _CHROME_SOURCE, ('chrome/third_party/chromevox/third_party/' +
- 'closure-library/closure/bin/build')))
-import depstree
-import rjsmin
-import source
-import treescan
-
-
-def Die(message):
- '''Prints an error message and exit the program.'''
- print >>sys.stderr, message
- sys.exit(1)
-
-
-class SourceWithPaths(source.Source):
- '''A source.Source object with its relative input and output paths'''
-
- def __init__(self, content, in_path, out_path):
- super(SourceWithPaths, self).__init__(content)
- self._in_path = in_path
- self._out_path = out_path
-
- def GetInPath(self):
- return self._in_path
-
- def GetOutPath(self):
- return self._out_path
-
-
-class Bundle():
- '''An ordered list of sources without duplicates.'''
-
- def __init__(self):
- self._added_paths = set()
- self._added_sources = []
-
- def Add(self, sources):
- '''Appends one or more source objects the list if it doesn't already
- exist.
-
- Args:
- sources: A SourceWithPath or an iterable of such objects.
- '''
- if isinstance(sources, SourceWithPaths):
- sources = [sources]
- for source in sources:
- path = source.GetInPath()
- if path not in self._added_paths:
- self._added_paths.add(path)
- self._added_sources.append(source)
-
- def GetInPaths(self):
- return (source.GetInPath() for source in self._added_sources)
-
- def GetOutPaths(self):
- return (source.GetOutPath() for source in self._added_sources)
-
- def GetSources(self):
- return self._added_sources
-
- def GetUncompressedSource(self):
- return '\n'.join((s.GetSource() for s in self._added_sources))
-
- def GetCompressedSource(self):
- return rjsmin.jsmin(self.GetUncompressedSource())
-
-
-class PathRewriter():
- '''A list of simple path rewrite rules to map relative input paths to
- relative output paths.
- '''
-
- def __init__(self, specs=[]):
- '''Args:
- specs: A list of mappings, each consisting of the input prefix and
- the corresponding output prefix separated by colons.
- '''
- self._prefix_map = []
- for spec in specs:
- parts = spec.split(':')
- if len(parts) != 2:
- Die('Invalid prefix rewrite spec %s' % spec)
- if not parts[0].endswith('/') and parts[0] != '':
- parts[0] += '/'
- self._prefix_map.append(parts)
- self._prefix_map.sort(reverse=True)
-
- def RewritePath(self, in_path):
- '''Rewrites an input path according to the list of rules.
-
- Args:
- in_path, str: The input path to rewrite.
- Returns:
- str: The corresponding output path.
- '''
- for in_prefix, out_prefix in self._prefix_map:
- if in_path.startswith(in_prefix):
- return os.path.join(out_prefix, in_path[len(in_prefix):])
- return in_path
-
-
-def ReadSources(roots=[], source_files=[], need_source_text=False,
- path_rewriter=PathRewriter(), exclude=[]):
- '''Reads all source specified on the command line, including sources
- included by --root options.
- '''
-
- def EnsureSourceLoaded(in_path, sources):
- if in_path not in sources:
- out_path = path_rewriter.RewritePath(in_path)
- sources[in_path] = SourceWithPaths(source.GetFileContents(in_path),
- in_path, out_path)
-
- # Only read the actual source file if we will do a dependency analysis or
- # the caller asks for it.
- need_source_text = need_source_text or len(roots) > 0
- sources = {}
- for root in roots:
- for name in treescan.ScanTreeForJsFiles(root):
- if any((r.search(name) for r in exclude)):
- continue
- EnsureSourceLoaded(name, sources)
- for path in source_files:
- if need_source_text:
- EnsureSourceLoaded(path, sources)
- else:
- # Just add an empty representation of the source.
- sources[path] = SourceWithPaths(
- '', path, path_rewriter.RewritePath(path))
- return sources
-
-
-def _GetBase(sources):
- '''Gets the closure base.js file if present among the sources.
-
- Args:
- sources: Dictionary with input path names as keys and SourceWithPaths
- as values.
- Returns:
- SourceWithPath: The source file providing the goog namespace.
- '''
- for source in sources.itervalues():
- if (os.path.basename(source.GetInPath()) == 'base.js' and
- 'goog' in source.provides):
- return source
- Die('goog.base not provided by any file.')
-
-
-def CalcDeps(bundle, sources, top_level):
- '''Calculates dependencies for a set of top-level files.
-
- Args:
- bundle: Bundle to add the sources to.
- sources, dict: Mapping from input path to SourceWithPaths objects.
- top_level, list: List of top-level input paths to calculate dependencies
- for.
- '''
- providers = [s for s in sources.itervalues() if len(s.provides) > 0]
- deps = depstree.DepsTree(providers)
- namespaces = []
- for path in top_level:
- namespaces.extend(sources[path].requires)
- # base.js is an implicit dependency that always goes first.
- bundle.Add(_GetBase(sources))
- bundle.Add(deps.GetDependencies(namespaces))
-
-
-def _MarkAsCompiled(sources):
- '''Sets COMPILED to true in the Closure base.js source.
-
- Args:
- sources: Dictionary with input paths names as keys and SourcWithPaths
- objects as values.
- '''
- base = _GetBase(sources)
- new_content, count = re.subn('^var COMPILED = false;$',
- 'var COMPILED = true;',
- base.GetSource(),
- count=1,
- flags=re.MULTILINE)
- if count != 1:
- Die('COMPILED var assignment not found in %s' % base.GetInPath())
- sources[base.GetInPath()] = SourceWithPaths(
- new_content,
- base.GetInPath(),
- base.GetOutPath())
-
-def LinkOrCopyFiles(sources, dest_dir):
- '''Copies a list of sources to a destination directory.'''
-
- def LinkOrCopyOneFile(src, dst):
- if not os.path.exists(os.path.dirname(dst)):
- os.makedirs(os.path.dirname(dst))
- if os.path.exists(dst):
- os.unlink(dst)
- try:
- os.link(src, dst)
- except:
- shutil.copy(src, dst)
-
- for source in sources:
- LinkOrCopyOneFile(source.GetInPath(),
- os.path.join(dest_dir, source.GetOutPath()))
-
-
-def WriteOutput(bundle, format, out_file, dest_dir):
- '''Writes output in the specified format.
-
- Args:
- bundle: The ordered bundle iwth all sources already added.
- format: Output format, one of list, html, bundle, compressed_bundle.
- out_file: File object to receive the output.
- dest_dir: Prepended to each path mentioned in the output, if applicable.
- '''
- if format == 'list':
- paths = bundle.GetOutPaths()
- if dest_dir:
- paths = (os.path.join(dest_dir, p) for p in paths)
- paths = (os.path.normpath(p) for p in paths)
- out_file.write('\n'.join(paths))
- elif format == 'html':
- HTML_TEMPLATE = '<script src=\'%s\'>'
- script_lines = (HTML_TEMPLATE % p for p in bundle.GetOutPaths())
- out_file.write('\n'.join(script_lines))
- elif format == 'bundle':
- out_file.write(bundle.GetUncompressedSource())
- elif format == 'compressed_bundle':
- out_file.write(bundle.GetCompressedSource())
- out_file.write('\n')
-
-
-def WriteStampfile(stampfile):
- '''Writes a stamp file.
-
- Args:
- stampfile, string: name of stamp file to touch
- '''
- with open(stampfile, 'w') as file:
- os.utime(stampfile, None)
-
-
-def WriteDepfile(depfile, outfile, infiles):
- '''Writes a depfile.
-
- Args:
- depfile, string: name of dep file to write
- outfile, string: Name of output file to use as the target in the generated
- .d file.
- infiles, list: File names to list as dependencies in the .d file.
- '''
- content = '%s: %s' % (outfile, ' '.join(infiles))
- open(depfile, 'w').write(content)
-
-
-def CreateOptionParser():
- parser = optparse.OptionParser(description=__doc__)
- parser.usage = '%prog [options] <top_level_file>...'
- parser.add_option('-d', '--dest_dir', action='store', metavar='DIR',
- help=('Destination directory. Used when translating ' +
- 'input paths to output paths and when copying '
- 'files.'))
- parser.add_option('-o', '--output_file', action='store', metavar='FILE',
- help=('File to output result to for modes that output '
- 'a single file.'))
- parser.add_option('-r', '--root', dest='roots', action='append', default=[],
- metavar='ROOT',
- help='Roots of directory trees to scan for sources.')
- parser.add_option('-M', '--module', dest='modules', action='append',
- default=[], metavar='FILENAME',
- help='Source modules to load')
- parser.add_option('-w', '--rewrite_prefix', action='append', default=[],
- dest='prefix_map', metavar='SPEC',
- help=('Two path prefixes, separated by colons ' +
- 'specifying that a file whose (relative) path ' +
- 'name starts with the first prefix should have ' +
- 'that prefix replaced by the second prefix to ' +
- 'form a path relative to the output directory.'))
- parser.add_option('-m', '--mode', type='choice', action='store',
- choices=['list', 'html', 'bundle',
- 'compressed_bundle', 'copy'],
- default='list', metavar='MODE',
- help=("Otput mode. One of 'list', 'html', 'bundle', " +
- "'compressed_bundle' or 'copy'."))
- parser.add_option('-x', '--exclude', action='append', default=[],
- help=('Exclude files whose full path contains a match for '
- 'the given regular expression. Does not apply to '
- 'filenames given as arguments or with the '
- '-m option.'))
- parser.add_option('--depfile', metavar='FILENAME',
- help='Store .d style dependencies in FILENAME')
- parser.add_option('--stampfile', metavar='FILENAME',
- help='Write empty stamp file')
- return parser
-
-
-def main():
- options, args = CreateOptionParser().parse_args()
- if len(args) < 1:
- Die('At least one top-level source file must be specified.')
- if options.depfile and not options.output_file:
- Die('--depfile requires an output file')
- will_output_source_text = options.mode in ('bundle', 'compressed_bundle')
- path_rewriter = PathRewriter(options.prefix_map)
- exclude = [re.compile(r) for r in options.exclude]
- sources = ReadSources(options.roots, options.modules + args,
- will_output_source_text or len(options.modules) > 0,
- path_rewriter, exclude)
- if will_output_source_text:
- _MarkAsCompiled(sources)
- bundle = Bundle()
- if len(options.roots) > 0 or len(options.modules) > 0:
- CalcDeps(bundle, sources, args)
- bundle.Add((sources[name] for name in args))
- if options.mode == 'copy':
- if options.dest_dir is None:
- Die('Must specify --dest_dir when copying.')
- LinkOrCopyFiles(bundle.GetSources(), options.dest_dir)
- else:
- if options.output_file:
- out_file = open(options.output_file, 'w')
- else:
- out_file = sys.stdout
- try:
- WriteOutput(bundle, options.mode, out_file, options.dest_dir)
- finally:
- if options.output_file:
- out_file.close()
- if options.stampfile:
- WriteStampfile(options.stampfile)
- if options.depfile:
- WriteDepfile(options.depfile, options.output_file, bundle.GetInPaths())
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/jscompilerwrapper.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/jscompilerwrapper.py
deleted file mode 100755
index fb4b80dfad7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/jscompilerwrapper.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''Uses the closure compiler to check syntax and semantics of a js module
-with dependencies.'''
-
-import os
-import re
-import subprocess
-import sys
-
-_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-_CHROME_SOURCE_DIR = os.path.normpath(
- os.path.join(
- _SCRIPT_DIR, *[os.path.pardir] * 6))
-
-# Compiler path.
-_CLOSURE_COMPILER_JAR = os.path.join(
- _CHROME_SOURCE_DIR, 'third_party', 'closure_compiler', 'compiler',
- 'compiler.jar')
-
-# List of compilation errors to enable with the --jscomp_errors flag.
-_JSCOMP_ERRORS = [ 'accessControls', 'checkTypes', 'checkVars', 'invalidCasts',
- 'missingProperties', 'undefinedNames', 'undefinedVars',
- 'visibility' ]
-
-_java_executable = 'java'
-
-
-def _Error(msg):
- print >>sys.stderr, msg
- sys.exit(1)
-
-
-def _ExecuteCommand(args, ignore_exit_status=False):
- try:
- return subprocess.check_output(args, stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as e:
- if ignore_exit_status and e.returncode > 0:
- return e.output
- _Error('%s\nCommand \'%s\' returned non-zero exit status %d' %
- (e.output, ' '.join(e.cmd), e.returncode))
- except (OSError, IOError) as e:
- _Error('Error executing %s: %s' % (_java_executable, str(e)))
-
-
-def _CheckJava():
- global _java_executable
- java_home = os.environ.get('JAVAHOME')
- if java_home is not None:
- _java_executable = os.path.join(java_home, 'bin', 'java')
- output = _ExecuteCommand([_java_executable, '-version'])
- match = re.search(r'version "(?:\d+)\.(\d+)', output)
- if match is None or int(match.group(1)) < 7:
- _Error('Java 7 or later is required: \n%s' % output)
-
-_CheckJava()
-
-
-def RunCompiler(js_files, externs=[]):
- args = [_java_executable, '-jar', _CLOSURE_COMPILER_JAR]
- args.extend(['--compilation_level', 'SIMPLE_OPTIMIZATIONS'])
- args.extend(['--jscomp_error=%s' % error for error in _JSCOMP_ERRORS])
- args.extend(['--language_in', 'ECMASCRIPT5'])
- args.extend(['--externs=%s' % extern for extern in externs])
- args.extend(['--js=%s' % js for js in js_files])
- args.extend(['--js_output_file', '/dev/null'])
- output = _ExecuteCommand(args, ignore_exit_status=True)
- success = len(output) == 0
- return success, output
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/print_js_deps.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/print_js_deps.py
deleted file mode 100755
index 4782c3d6f8d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/print_js_deps.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''Print the dependency tree for a JavaScript module.
-
-Given one or more root directories, specified by -r options and one top-level
-file, walk the dependency tree and print all modules encountered.
-A module is only expanded once; on a second encounter, its dependencies
-are represented by a line containing the characters '[...]' as a short-hand.
-'''
-
-import optparse
-import os
-import sys
-
-from jsbundler import ReadSources
-
-
-def Die(message):
- '''Prints an error message and exit the program.'''
- print >>sys.stderr, message
- sys.exit(1)
-
-
-def CreateOptionParser():
- parser = optparse.OptionParser(description=__doc__)
- parser.usage = '%prog [options] <top_level_file>'
- parser.add_option('-r', '--root', dest='roots', action='append', default=[],
- metavar='ROOT',
- help='Roots of directory trees to scan for sources. '
- 'If none specified, all of ChromeVox and closure sources '
- 'are scanned.')
- return parser
-
-
-def DefaultRoots():
- script_dir = os.path.dirname(os.path.abspath(__file__))
- source_root_dir = os.path.join(script_dir, *[os.path.pardir] * 6)
- return [os.path.relpath(os.path.join(script_dir, os.path.pardir)),
- os.path.relpath(
- os.path.join(source_root_dir, 'chrome', 'third_party',
- 'chromevox', 'third_party',
- 'closure-library', 'closure'))]
-
-
-def WalkDeps(sources, start_source):
- def Walk(source, depth):
- indent = ' ' * depth
- if source.GetInPath() in expanded and len(source.requires) > 0:
- print '%s[...]' % indent
- return
- expanded.add(source.GetInPath())
- for require in source.requires:
- if not require in providers:
- Die('%s not provided, required by %s' % (require, source.GetInPath()))
- require_source = providers[require]
- print '%s%s (%s)' % (indent, require, require_source.GetInPath())
- Walk(require_source, depth + 1)
-
- # Create a map from provided module names to source objects.
- providers = {}
- expanded = set()
- for source in sources.values():
- for provide in source.provides:
- if provide in providers:
- Die('%s provided multiple times' % provide)
- providers[provide] = source
-
- print '(%s)' % start_source.GetInPath()
- Walk(start_source, 1)
-
-
-def main():
- parser = CreateOptionParser()
- options, args = parser.parse_args()
- if len(args) != 1:
- Die('Exactly one top-level source file must be specified.')
- start_path = args[0]
- roots = options.roots or DefaultRoots()
- sources = ReadSources(roots=roots, source_files=[start_path])
- start_source = sources[start_path]
- WalkDeps(sources, start_source)
-
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/publish_webstore_extension.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/publish_webstore_extension.py
deleted file mode 100755
index fe8af1ea44e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/publish_webstore_extension.py
+++ /dev/null
@@ -1,155 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''Publishes a set of extensions to the webstore.
- Given an unpacked extension, compresses and sends to the Chrome webstore.
-
- Releasing to the webstore should involve the following manual steps before
- running this script:
- 1. clean the output directory.
- 2. make a release build.
- 3. run manual smoke tests.
- 4. run automated tests.
-'''
-
-import webstore_extension_util
-import generate_manifest
-import json
-import optparse
-import os
-import sys
-import tempfile
-from zipfile import ZipFile
-
-_CHROMEVOX_ID = 'kgejglhpjiefppelpmljglcjbhoiplfn'
-_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-_CHROME_SOURCE_DIR = os.path.normpath(
- os.path.join(
- _SCRIPT_DIR, *[os.path.pardir] * 6))
-
-sys.path.insert(
- 0, os.path.join(_CHROME_SOURCE_DIR, 'build', 'util'))
-import version
-
-# A list of files (or directories) to exclude from the webstore build.
-EXCLUDE_PATHS = [
- 'manifest.json',
- 'manifest_guest.json',
- ]
-
-
-def CreateOptionParser():
- parser = optparse.OptionParser(description=__doc__)
- parser.usage = (
- '%prog --client_secret <client_secret> extension_id:extension_path ...')
- parser.add_option('-c', '--client_secret', dest='client_secret',
- action='store', metavar='CLIENT_SECRET')
- parser.add_option('-p', '--publish', action='store_true',
- help='publish the extension(s)')
- return parser
-
-
-def GetVersion():
- '''Returns the chrome version string.'''
- filename = os.path.join(_CHROME_SOURCE_DIR, 'chrome', 'VERSION')
- values = version.fetch_values([filename])
- return version.subst_template('@MAJOR@.@MINOR@.@BUILD@.@PATCH@', values)
-
-
-def MakeChromeVoxManifest():
- '''Create a manifest for the webstore.
-
- Returns:
- Temporary file with generated manifest.
- '''
- new_file = tempfile.NamedTemporaryFile(mode='w+a', bufsize=0)
- in_file_name = os.path.join(_SCRIPT_DIR, os.path.pardir,
- 'manifest.json.jinja2')
- context = {
- 'is_chromevox_classic': '1',
- 'is_guest_manifest': '0',
- 'is_js_compressed': '1',
- 'set_version': GetVersion()
- }
- generate_manifest.processJinjaTemplate(in_file_name, new_file.name, context)
- return new_file
-
-
-def RunInteractivePrompt(client_secret, output_path):
- input = ''
- while True:
- print 'u upload'
- print 'g get upload status'
- print 't publish trusted tester'
- print 'p publish public'
- print 'q quit'
- input = raw_input('Please select an option: ')
- input = input.strip()
- if input == 'g':
- print ('Upload status: %s' %
- webstore_extension_util.GetUploadStatus(client_secret).read())
- elif input == 'u':
- print ('Uploaded with status: %s' %
- webstore_extension_util.PostUpload(output_path.name, client_secret))
- elif input == 't':
- print ('Published to trusted testers with status: %s' %
- webstore_extension_util.PostPublishTrustedTesters(
- client_secret).read())
- elif input == 'p':
- print ('Published to public with status: %s' %
- webstore_extension_util.PostPublish(client_secret).read())
- elif input == 'q':
- sys.exit()
- else:
- print 'Unrecognized option: %s' % input
-
-def main():
- options, args = CreateOptionParser().parse_args()
- if len(args) < 1 or not options.client_secret:
- print 'Expected at least one argument and --client_secret flag'
- print str(args)
- sys.exit(1)
-
- client_secret = options.client_secret
-
- for extension in args:
- webstore_extension_util.g_app_id, extension_path = extension.split(':')
- output_path = tempfile.NamedTemporaryFile()
- extension_path = os.path.expanduser(extension_path)
-
- is_chromevox = webstore_extension_util.g_app_id == _CHROMEVOX_ID
-
- with ZipFile(output_path, 'w') as zip:
- for root, dirs, files in os.walk(extension_path):
- rel_path = os.path.join(os.path.relpath(root, extension_path), '')
-
- if is_chromevox and rel_path in EXCLUDE_PATHS:
- continue
-
- for extension_file in files:
- if is_chromevox and extension_file in EXCLUDE_PATHS:
- continue
-
- zip.write(os.path.join(root, extension_file),
- os.path.join(rel_path, extension_file))
-
- if is_chromevox:
- manifest_file = MakeChromeVoxManifest()
- zip.write(manifest_file.name, 'manifest.json')
-
- print 'Created extension zip file in %s' % output_path.name
- print 'Please run manual smoke tests before proceeding.'
- if options.publish:
- print('Uploading...%s' %
- webstore_extension_util.PostUpload(output_path.name, client_secret))
- print('publishing...%s' %
- webstore_extension_util.PostPublish(client_secret).read())
- else:
- RunInteractivePrompt(client_secret, output_path)
-
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/tools/webstore_extension_util.py b/chromium/chrome/browser/resources/chromeos/chromevox/tools/webstore_extension_util.py
deleted file mode 100755
index e0f8490f963..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/tools/webstore_extension_util.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-'''A set of utilities to interface with the Chrome Webstore API.'''
-
-import SimpleHTTPServer
-import SocketServer
-import httplib
-import json
-import os
-import re
-import sys
-import thread
-import urllib
-import webbrowser
-
-PROJECT_ARGS = {
- 'client_id': ('937534751394-gbj5334v9144c57qjqghl7d283plj5r4'
- '.apps.googleusercontent.com'),
- 'grant_type': 'authorization_code',
- 'redirect_uri': 'http://localhost:8000'
-}
-
-# Persists across all utility methods for authentication.
-g_auth_code = None
-g_oauth_token = None
-
-# The app id to use for all utility methods.
-g_app_id = ''
-
-# Constants.
-PORT = 8000
-OAUTH_DOMAIN = 'accounts.google.com'
-OAUTH_AUTH_COMMAND = '/o/oauth2/auth'
-OAUTH_TOKEN_COMMAND = '/o/oauth2/token'
-WEBSTORE_API_SCOPE = 'https://www.googleapis.com/auth/chromewebstore'
-API_ENDPOINT_DOMAIN = 'www.googleapis.com'
-
-def GetUploadStatusCommand():
- global g_app_id
- return '/chromewebstore/v1.1/items/%s?projection=draft' % g_app_id
-
-def GetPublishCommand():
- global g_app_id
- return '/chromewebstore/v1.1/items/%s/publish' % g_app_id
-
-def GetUploadCommand():
- global g_app_id
- return '/upload/chromewebstore/v1.1/items/%s' % g_app_id
-
-class CodeRequestHandler(SocketServer.StreamRequestHandler):
- def handle(self):
- content = self.rfile.readline()
- self.server.code = re.search('code=(.*) ', content).groups()[0]
- self.rfile.close()
-
-def GetAuthCode():
- global g_auth_code
- if g_auth_code:
- return g_auth_code
-
- Handler = CodeRequestHandler
- httpd = SocketServer.TCPServer(("", PORT), Handler)
- query = '&'.join(['response_type=code',
- 'scope=%s' % WEBSTORE_API_SCOPE,
- 'client_id=%(client_id)s' % PROJECT_ARGS,
- 'redirect_uri=%(redirect_uri)s' % PROJECT_ARGS])
- auth_url = 'https://%s%s?%s' % (OAUTH_DOMAIN, OAUTH_AUTH_COMMAND, query)
- print 'Navigating to %s' % auth_url
- webbrowser.open(auth_url)
- httpd.handle_request()
- httpd.server_close()
- g_auth_code = httpd.code
- return g_auth_code
-
-def GetOauthToken(code, client_secret):
- global g_oauth_token
- if g_oauth_token:
- return g_oauth_token
-
- PROJECT_ARGS['code'] = code
- PROJECT_ARGS['client_secret'] = client_secret
- body = urllib.urlencode(PROJECT_ARGS)
- conn = httplib.HTTPSConnection(OAUTH_DOMAIN)
- conn.putrequest('POST', OAUTH_TOKEN_COMMAND)
- conn.putheader('content-type', 'application/x-www-form-urlencoded')
- conn.putheader('content-length', len(body))
- conn.endheaders()
- conn.send(body)
- content = conn.getresponse().read()
- conn.close()
- g_oauth_token = json.loads(content)
- return g_oauth_token
-
-def GetPopulatedHeader(client_secret):
- code = GetAuthCode()
- access_token = GetOauthToken(code, client_secret)
-
- url = 'www.googleapis.com'
-
- return {'Authorization': 'Bearer %(access_token)s' % access_token,
- 'x-goog-api-version': 2,
- 'Content-Length': 0
- }
-
-def SendGetCommand(command, client_secret):
- headers = GetPopulatedHeader(client_secret)
- conn = httplib.HTTPSConnection(API_ENDPOINT_DOMAIN)
- conn.request('GET', command, '', headers)
- r = conn.getresponse()
- conn.close()
- return r
-
-def SendPostCommand(command, client_secret, header_additions = {}, body=None):
- headers = GetPopulatedHeader(client_secret)
- headers = dict(headers.items() + header_additions.items())
- conn = httplib.HTTPSConnection(API_ENDPOINT_DOMAIN)
- conn.request('POST', command, body, headers)
- r = conn.getresponse()
- conn.close()
- return r
-
-def GetUploadStatus(client_secret):
- '''Gets the status of a previous upload.
- Args:
- client_secret ChromeVox's client secret creds.
- '''
- return SendGetCommand(GetUploadStatusCommand(), client_secret)
-
-# httplib fails to persist the connection during upload; use curl instead.
-def PostUpload(file, client_secret):
- '''Posts an uploaded version of ChromeVox.
- Args:
- file A string path to the ChromeVox extension zip.
- client_secret ChromeVox's client secret creds.
- '''
- header = GetPopulatedHeader(client_secret)
- curl_command = ' '.join(['curl',
- '-H "Authorization: %(Authorization)s"' % header,
- '-H "x-goog-api-version: 2"',
- '-X PUT',
- '-T %s' % file,
- '-v',
- 'https://%s%s' % (API_ENDPOINT_DOMAIN,
- GetUploadCommand())])
-
- print 'Running %s' % curl_command
- if os.system(curl_command) != 0:
- sys.exit(-1)
-
-def PostPublishTrustedTesters(client_secret):
- '''Publishes a previously uploaded ChromeVox extension to trusted testers.
- Args:
- client_secret ChromeVox's client secret creds.
- '''
- return SendPostCommand(GetPublishCommand(),
- client_secret,
- { 'publishTarget': 'trustedTesters'})
-
-def PostPublish(client_secret):
- '''Publishes a previously uploaded ChromeVox extension publically.
- Args:
- client_secret ChromeVox's client secret creds.
- '''
- return SendPostCommand(GetPublishCommand(), client_secret)
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_node_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_node_walker.js
deleted file mode 100644
index 19faec63ec9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_node_walker.js
+++ /dev/null
@@ -1,115 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A base class for walkers that have a concept of lowest-level
- * node. Base classes must override the stopNodeDescent method to define
- * what a lowest-level node is. Then this walker will use those nodes as the
- * set of valid CursorSelections.
- */
-
-
-goog.provide('cvox.AbstractNodeWalker');
-
-goog.require('cvox.AbstractWalker');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.DomUtil');
-
-/**
- * @constructor
- * @extends {cvox.AbstractWalker}
- */
-cvox.AbstractNodeWalker = function() {
- goog.base(this);
-
- /**
- * To keep track of and break infinite loops when trying to call next on
- * a body that does not DomUtil.hasContent().
- * @type {boolean}
- * @private
- */
- this.wasBegin_ = false;
-};
-goog.inherits(cvox.AbstractNodeWalker, cvox.AbstractWalker);
-
-/**
- * @override
- */
-cvox.AbstractNodeWalker.prototype.next = function(sel) {
- var r = sel.isReversed();
- var node = sel.end.node || document.body;
-
- do {
- node = cvox.DomUtil.directedNextLeafLikeNode(node, r,
- goog.bind(this.stopNodeDescent, this));
- if (!node) {
- return null;
- }
- // and repeat all of the above until we have a node that is not empty
- } while (node && !cvox.DomUtil.hasContent(node));
-
- return cvox.CursorSelection.fromNode(node).setReversed(r);
-};
-
-/**
- * @override
- */
-cvox.AbstractNodeWalker.prototype.sync = function(sel) {
- var ret = this.privateSync_(sel);
- this.wasBegin_ = false;
- return ret;
-};
-
-
-/**
- * Private version of sync to ensure that when a body has no content, we
- * don't do an infinite loop trying to find an empty node.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The synced selection.
- * @private
- */
-cvox.AbstractNodeWalker.prototype.privateSync_ = function(sel) {
- var r = sel.isReversed();
-
- if (sel.equals(cvox.CursorSelection.fromBody())) {
- if (this.wasBegin_) {
- // if body is empty, we return just the body selection
- return cvox.CursorSelection.fromBody().setReversed(r);
- }
- this.wasBegin_ = true;
- }
-
- var node = sel.start.node;
-
- while (node != document.body && node.parentNode &&
- this.stopNodeDescent(node.parentNode)) {
- node = node.parentNode;
- }
-
- while (!this.stopNodeDescent(node)) {
- node = cvox.DomUtil.directedFirstChild(node, r);
- }
-
- var n = cvox.CursorSelection.fromNode(node);
- if (!cvox.DomUtil.hasContent(node)) {
- n = this.next(/** @type {!cvox.CursorSelection} */
- (cvox.CursorSelection.fromNode(node)).setReversed(r));
- }
- if (n) {
- return n.setReversed(r);
- }
- return this.begin({reversed: r});
-};
-
-/**
- * Returns true if this is "a leaf node" or lower. That is,
- * it is at the lowest valid level or lower for this granularity.
- * RESTRICTION: true for a node => true for all child nodes
- * RESTRICTION: true if node has no children
- * @param {!Node} node The node to check.
- * @return {boolean} true if this is at the "leaf node" level or lower
- * for this granularity.
- * @protected
- */
-cvox.AbstractNodeWalker.prototype.stopNodeDescent = goog.abstractMethod;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_selection_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_selection_walker.js
deleted file mode 100644
index e56b5d7a6a8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_selection_walker.js
+++ /dev/null
@@ -1,159 +0,0 @@
-// 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.
-
-/**
- * @fileoverview An abstract class for walking at the sub-element level.
- * For example, walking at the sentence, word, or character level.
- * This class is an adapter around TraverseContent which exposes the interface
- * required by walkers. Subclasses must override the this.grain attribute
- * on initialization.
- */
-
-
-goog.provide('cvox.AbstractSelectionWalker');
-
-goog.require('cvox.AbstractWalker');
-goog.require('cvox.BareObjectWalker');
-goog.require('cvox.DescriptionUtil');
-goog.require('cvox.DomUtil');
-goog.require('cvox.Spannable');
-goog.require('cvox.TraverseContent');
-
-/**
- * @constructor
- * @extends {cvox.AbstractWalker}
- */
-cvox.AbstractSelectionWalker = function() {
- cvox.AbstractWalker.call(this);
- this.objWalker_ = new cvox.BareObjectWalker();
- this.tc_ = cvox.TraverseContent.getInstance();
- this.grain /** @protected */ = ''; // child must override
-};
-goog.inherits(cvox.AbstractSelectionWalker, cvox.AbstractWalker);
-
-/**
- * @override
- */
-cvox.AbstractSelectionWalker.prototype.next = function(sel) {
- var r = sel.isReversed();
- this.tc_.syncToCursorSelection(sel.clone().setReversed(false));
- var ret = r ? this.tc_.prevElement(this.grain) :
- this.tc_.nextElement(this.grain);
- if (ret == null) {
- // Unfortunately, we can't trust TraverseContent; fall back to ObjectWalker.
- return this.objWalker_.next(sel);
- }
- var retSel = this.tc_.getCurrentCursorSelection().setReversed(r);
- var objSel = this.objWalker_.next(sel);
- objSel = objSel ? objSel.setReversed(r) : null;
-
- // ObjectWalker wins when there's a discrepancy between it and
- // TraverseContent. The only exception is with an end cursor on a text node.
- // In all other cases, this makes sure we visit the same selections as
- // object walker.
- if (objSel &&
- (retSel.end.node.constructor.name != 'Text' ||
- objSel.end.node.constructor.name != 'Text') &&
- !cvox.DomUtil.isDescendantOfNode(retSel.end.node, sel.end.node) &&
- !cvox.DomUtil.isDescendantOfNode(retSel.end.node, objSel.end.node)) {
- return objSel;
- }
- return retSel;
-};
-
-/**
- * @override
- */
-cvox.AbstractSelectionWalker.prototype.sync = function(sel) {
- var r = sel.isReversed();
- var newSel = null;
- if (sel.start.equals(sel.end) && sel.start.node.constructor.name != 'Text') {
- var node = sel.start.node;
-
- // Find the deepest visible node; written specifically here because we want
- // to move across siblings if necessary and take the deepest node which can
- // be BODY.
- while (node &&
- cvox.DomUtil.directedFirstChild(node, r) &&
- !cvox.TraverseUtil.treatAsLeafNode(node)) {
- var child = cvox.DomUtil.directedFirstChild(node, r);
-
- // Find the first visible child.
- while (child) {
- if (cvox.DomUtil.isVisible(child,
- {checkAncestors: false, checkDescendants: false})) {
- node = child;
- break;
- } else {
- child = cvox.DomUtil.directedNextSibling(child, r);
- }
- }
-
- // node has no visible children; it's therefore the deepest visible node.
- if (!child) {
- break;
- }
- }
- newSel = cvox.CursorSelection.fromNode(node);
- } else {
- newSel = sel.clone();
- if (r) {
- newSel.start = newSel.end;
- } else {
- newSel.end = newSel.start;
- }
- }
-
- // This.next places us at the correct initial position (except below).
- newSel = this.next(newSel.setReversed(false));
-
- // ObjectWalker wins when there's a discrepancy between it and
- // TraverseContent. The only exception is with an end cursor on a text node.
- // In all other cases, this makes sure we visit the same selections as
- // object walker.
- var objSel = this.objWalker_.sync(sel);
- objSel = objSel ? objSel.setReversed(r) : null;
-
- if (!newSel) {
- return objSel;
- }
-
- newSel.setReversed(r);
-
- if (objSel &&
- (newSel.end.node.constructor.name != 'Text' ||
- objSel.end.node.constructor.name != 'Text') &&
- !cvox.DomUtil.isDescendantOfNode(newSel.end.node, sel.end.node) &&
- !cvox.DomUtil.isDescendantOfNode(newSel.end.node, objSel.end.node)) {
- return objSel;
- }
- return newSel;
-};
-
-/**
- * @override
- */
-cvox.AbstractSelectionWalker.prototype.getDescription = function(prevSel, sel) {
- var description = cvox.DescriptionUtil.getDescriptionFromAncestors(
- cvox.DomUtil.getUniqueAncestors(prevSel.end.node, sel.start.node),
- true,
- cvox.ChromeVox.verbosity);
- description.text = sel.getText() || description.text;
- return [description];
-};
-
-/**
- * @override
- */
-cvox.AbstractSelectionWalker.prototype.getBraille = function(prevSel, sel) {
- var node = sel.absStart().node;
- var text = cvox.TraverseUtil.getNodeText(node);
- var spannable = new cvox.Spannable(text);
- spannable.setSpan(node, 0, text.length);
- return new cvox.NavBraille({
- text: spannable,
- startIndex: sel.absStart().index,
- endIndex: sel.absEnd().index
- });
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_shifter.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_shifter.js
deleted file mode 100644
index 3da50994e6b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_shifter.js
+++ /dev/null
@@ -1,166 +0,0 @@
-// 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.
-
-/**
- * @fileoverview An interface for an ordered collection of walkers, called a
- * shifter.
- */
-
-
-goog.provide('cvox.AbstractShifter');
-
-goog.require('cvox.AbstractWalker');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.NavBraille');
-
-
-/**
- * @constructor
- */
-cvox.AbstractShifter = function() {
- this.isSubnavigating_ = false;
-};
-
-
-/**
- * Moves to the next selection in the DOM, performing any walker shifts as
- * necessary.
- * @param {!cvox.CursorSelection} sel The selection to go next from.
- * @return {cvox.CursorSelection} The resulting selection.
- */
-cvox.AbstractShifter.prototype.next = goog.abstractMethod;
-
-
-/**
- * Gets the first (or last) selection for this shifter's current granularity.
- * @param {?} sel
- * @param {{reversed: (undefined|boolean)}=} kwargs Extra arguments.
- * reversed: If true, syncs to the end and returns a reversed selection.
- * False by default.
- * @return {!cvox.CursorSelection} The valid selection.
- */
-cvox.AbstractShifter.prototype.begin = function(sel, kwargs) {
- return this.currentWalker_.begin(kwargs);
-};
-
-
-/**
- * Syncs to this shifter.
- * @param {!cvox.CursorSelection} sel The selection to sync, if any.
- * @return {cvox.CursorSelection} The selection.
- */
-cvox.AbstractShifter.prototype.sync = goog.abstractMethod;
-
-
-/**
- * Name of this shifter.
- * @return {string} The shifter's name.
- */
-cvox.AbstractShifter.prototype.getName = goog.abstractMethod;
-
-
-/**
- * Gets the current description.
- * @param {!cvox.CursorSelection} prevSel The previous selection, for context.
- * @param {!cvox.CursorSelection} sel The current selection.
- * @return {Array<cvox.NavDescription>} The description array.
- */
-cvox.AbstractShifter.prototype.getDescription = goog.abstractMethod;
-
-
-/**
- * Gets the current braille.
- * @param {!cvox.CursorSelection} prevSel The previous selection, for context.
- * @param {!cvox.CursorSelection} sel The current selection.
- * @return {!cvox.NavBraille} The braille description.
- */
-cvox.AbstractShifter.prototype.getBraille = goog.abstractMethod;
-
-
-/**
- * Gets the granularity message.
- * @return {string} The message string.
- */
-cvox.AbstractShifter.prototype.getGranularityMsg = goog.abstractMethod;
-
-
-/**
- * Shifts to a less granular level.
- */
-cvox.AbstractShifter.prototype.makeLessGranular = function() {
- this.ensureNotSubnavigating();
-};
-
-
-/**
- * Shifts to a more granular level.
- * NOTE: after a shift, we are no longer subnavigating, if we were.
- */
-cvox.AbstractShifter.prototype.makeMoreGranular = function() {
- this.ensureNotSubnavigating();
-};
-
-
-/**
- * Enters subnavigation mode, if it was not already in it.
- * Subnavigation mode is where the shifter is temporarily one level
- * more granular (until either the next granularity shift or
- * ensureNotSubnavigating is called).
- */
-cvox.AbstractShifter.prototype.ensureSubnavigating = function() {
- if (this.isSubnavigating_ == false) {
- this.makeMoreGranular();
- this.isSubnavigating_ = true;
- }
-};
-
-
-/**
- * Exits subnavigation mode, if it was in it.
- */
-cvox.AbstractShifter.prototype.ensureNotSubnavigating = function() {
- if (this.isSubnavigating_ == true) {
- this.isSubnavigating_ = false;
- this.makeLessGranular();
- }
-};
-
-
-/**
- * Returns true if the shifter is currently in subnavigation mode.
- * @return {boolean} If in subnavigation mode.
- */
-cvox.AbstractShifter.prototype.isSubnavigating = function() {
- return this.isSubnavigating_;
-};
-
-
-/**
- * Delegates to current walker.
- * @param {string} name Action name.
- * @return {boolean} True if this shifter contains action.
- */
-cvox.AbstractShifter.prototype.hasAction = function(name) {
-return this.currentWalker_.hasAction(name);
-};
-
-
-/**
- * Delegates an action to the current walker.
- * @param {string} name The action name.
- * @param {!cvox.CursorSelection} sel The current selection.
- * @return {cvox.CursorSelection} The selection after the action.
- */
-cvox.AbstractShifter.prototype.performAction = function(name, sel) {
- return this.currentWalker_.performAction(name, sel);
-};
-
-
-/**
- * Factory method to create an instance of this shifter.
- * @param {!cvox.CursorSelection} sel The initial selection.
- * @return {cvox.AbstractShifter} The shifter or null if given a selection not
- * within the shifter's domain.
- */
-cvox.AbstractShifter.create = goog.abstractMethod;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_walker.js
deleted file mode 100644
index c704cd9f437..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/abstract_walker.js
+++ /dev/null
@@ -1,177 +0,0 @@
-// 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.
-
-/**
- * @fileoverview An interface (and partial implementation) for the basic
- * traversal through some piece of the dom.
- * For each different ordered (either in dom or by any other metric) set
- * of "valid selections" (just set from now on), a new
- * base class should be defined that implements this interface. For example,
- * there are subclasses for words, sentences, and lowest-level dom nodes.
- * These classes should all be stateless; this makes testing much more
- * effective at pinpointing errors.
- * For all of the operations in this interface, the position in the dom on
- * which to operate is given by a CursorSelection, see that file for
- * documentation.
- * The two main operations that currently exist for walkers are sync and
- * next. See the docs where those functions are defined.
- * Since most operations are hard to even define if there is no root element,
- * all operations may assume that the selection given is attached to the body
- * node. The behavior is undefined if any part of the selection passed in
- * is not attached to the body. As a user of this class, it is your
- * responsibility to make sure the selection is attached.
- * No operation may visibly modify any of its arguments. In particular, take
- * care with CursorSelections, since setReversed modifies the selection.
- * For all documentation, = refers to the method equals for CursorSelections
- * comparison.
- * Thinking of adding something in this class? Here are some good questions to
- * ask:
- * Is this an operation that applies to any element of any arbitrary set?
- * If not, then it probably doesn't belong here.
- * Does it need to know something other than the set that it operates on?
- * If so, then it probably doesn't belong here.
- *
- * This interface resembles a C++ STL bidirectional iterator. Additions should
- * keep this in mind.
- *
- */
-
-
-goog.provide('cvox.AbstractWalker');
-
-goog.require('cvox.CursorSelection');
-goog.require('cvox.NavBraille');
-
-/**
- * @constructor
- */
-cvox.AbstractWalker = function() {
-};
-
-
-/**
- * This takes a valid CursorSelection and returns the directed-next
- * valid CursorSelection in the dom, or null. For example, if the walker
- * navigates across sentences, this would return the selection of the sentence
- * following the selection passed in. If sel is at the "end" of a section,
- * this method may return null. In the example above, if we try to next on
- * the last sentence in the dom, we would return null.
- * Note that sel must be a valid selection. Undefined behavior if it isn't.
- * There are several invariants that must hold for any subclasses. There may
- * not be explicit tests for these, but subclasses are responsible for ensuring
- * them and callers may assume them:
- * 1) next(next(sel).setReversed(!sel.isReversed())) = sel for all sel if sel
- * is a valid CursorSelection and next(sel) != null.
- * That is, the valid elements for this walker are totally ordered; going
- * forward and then backward returns us to the same cell.
- * 2) next(sel).isReversed() = sel.isReversed() for all sel if sel is a
- * valid CursorSelection and next(sel) != null.
- * That is, next preserves direction.
- * @param {!cvox.CursorSelection} sel The valid selection to start moving from.
- * @return {cvox.CursorSelection} Returns the valid selection the walker moves
- * to. null if directed end of section is reached.
- */
-cvox.AbstractWalker.prototype.next = goog.abstractMethod;
-
-
-/**
- * Syncs and returns the first or last valid, non-null selection in the
- * this walker's linearization of the DOM.
- * @param {{reversed: (undefined|boolean)}=} kwargs Extra arguments.
- * reversed: If true, syncs to the end and returns a reversed selection.
- * False by default.
- * @return {!cvox.CursorSelection} The valid selection.
- */
-cvox.AbstractWalker.prototype.begin = function(kwargs) {
- kwargs = kwargs || {reversed: false};
-
- return /** @type {!cvox.CursorSelection} */ (this.sync(
- cvox.CursorSelection.fromBody().setReversed(kwargs.reversed)));
-};
-
-
-/**
- * This takes an arbitrary CursorSelection and returns a valid CursorSelection,
- * or null. For example, if the walker navigates across
- * text nodes, and the selection passed in is for a single character within a
- * larger text node, this method should return a text node. No restrictions
- * are made as to exactly what selection should be returned, but it should be
- * something "reasonable", and from the user's point of view, "close" to the
- * previous selection. If no such selection exists, null may be returned.
- * Note that, since CursorSelection has a direction, syncing to a selection
- * should make sense in either direction.
- * Note also that, as mentioned in the file overview, this operation has
- * undefined behavior if the input selection is not attached to the body.
- * There are several invariants that must hold for any subclasses. While they
- * may not all be tested for at the time, subclasses are responsible for
- * making sure these hold, and any caller may assume these to be true:
- * 1) sync(sel) = sel iff sel is a valid selection
- * This defines the set of valid selections for this walker.
- * Note, in particular, that this implies sync(sync(sel)) = sync(sel)
- * whenever sync(sel) != null.
- * 2) sync(sel).isReversed() = sel.isReversed() for all sel if sync(sel) != null
- * That is, sync preserves direction.
- * Why do these restrictions exist? Because it makes it much easier to reason
- * about the effect (and intent) of an operation if we can make these
- * assumptions.
- * @param {!cvox.CursorSelection} sel The (possibly unsynched) selection.
- * @return {cvox.CursorSelection} The synched selection.
- */
-cvox.AbstractWalker.prototype.sync = goog.abstractMethod;
-
-
-/**
- * Returns an array of NavDescriptions that defines what should be said
- * by the tts engine on traversal from prevSel to sel. While this is
- * introducing knowledge (of NavDescriptions) into this class that
- * it shouldn't know, this is currently the best place for this method
- * to reside, as the set of valid CursorSelections must be known.
- * sel must be valid CursorSelections for this walker, prevSel may be any
- * selection. Undefined behavior otherwise.
- * @param {!cvox.CursorSelection} prevSel The valid previous selection.
- * @param {!cvox.CursorSelection} sel The valid current selection.
- * @return {!Array<!cvox.NavDescription>} The description array.
- */
-cvox.AbstractWalker.prototype.getDescription = goog.abstractMethod;
-
-
-/**
- * Returns a NavBraille that defines what should be brailled on traversal from
- * prevSel to sel.
- * sel must be valid CursorSelections for this walker, prevSel may be any
- * selection. Undefined behavior otherwise.
- * @param {!cvox.CursorSelection} prevSel The valid previous selection.
- * @param {!cvox.CursorSelection} sel The valid current selection.
- * @return {!cvox.NavBraille} The braille description.
- */
-cvox.AbstractWalker.prototype.getBraille = goog.abstractMethod;
-
-
-/**
- * Returns if this walker supports the given action.
- * @param {string} name Action name.
- * @return {boolean} True if action supported.
- */
-cvox.AbstractWalker.prototype.hasAction = function(name) {
- return typeof(this[name]) == 'function';
-};
-
-/**
- * Performs an action specific to the walker.
- * @param {string} name Action name.
- * @param {!cvox.CursorSelection} sel The current selection.
- * @return {cvox.CursorSelection} Selection after action.
- */
-cvox.AbstractWalker.prototype.performAction = function(name, sel) {
- if (this.hasAction(name)) {
- return this[name](sel);
- }
- return null;
-};
-
-/**
- * Returns message string of the walker's granularity.
- * @return {string} The message string.
- */
-cvox.AbstractWalker.prototype.getGranularityMsg = goog.abstractMethod;
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/bare_object_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/bare_object_walker.js
deleted file mode 100644
index c45f3a8563b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/bare_object_walker.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A JavaScript class for walking the leaf nodes of the dom.
- * This is a bare class that tries to limit dependencies. It should only be used
- * when traversal of the leaf nodes is required (e.g. by other walkers), but
- * no other walker functionality (such as being able to describe the position).
- * It should not be used for user-visible navigation.
- */
-
-
-goog.provide('cvox.BareObjectWalker');
-
-goog.require('cvox.AbstractNodeWalker');
-
-/**
- * @constructor
- * @extends {cvox.AbstractNodeWalker}
- */
-cvox.BareObjectWalker = function() {
- goog.base(this);
-};
-goog.inherits(cvox.BareObjectWalker, cvox.AbstractNodeWalker);
-
-/**
- * @override
- */
-cvox.BareObjectWalker.prototype.stopNodeDescent = function(node) {
- return cvox.DomUtil.isLeafNode(node);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/character_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/character_walker.js
deleted file mode 100644
index 32621a67bde..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/character_walker.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for walking one character at a time.
- */
-
-
-goog.provide('cvox.CharacterWalker');
-
-goog.require('cvox.AbstractSelectionWalker');
-goog.require('cvox.TraverseContent');
-
-/**
- * @constructor
- * @extends {cvox.AbstractSelectionWalker}
- */
-cvox.CharacterWalker = function() {
- cvox.AbstractSelectionWalker.call(this);
- this.grain = cvox.TraverseContent.kCharacter;
-};
-goog.inherits(cvox.CharacterWalker, cvox.AbstractSelectionWalker);
-
-/**
- * @override
- */
-cvox.CharacterWalker.prototype.getDescription = function(prevSel, sel) {
- var desc = goog.base(this, 'getDescription', prevSel, sel);
- desc.forEach(function(item) {
- if (!item.personality) {
- item.personality = {};
- }
- item.personality['phoneticCharacters'] = true;
- });
- return desc;
-};
-
-/**
- * @override
- */
-cvox.CharacterWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('character_granularity');
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/character_walker_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/character_walker_test.unitjs
deleted file mode 100644
index d93d11a13ac..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/character_walker_test.unitjs
+++ /dev/null
@@ -1,117 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['walker_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {CvoxWalkerTestBase}
- */
-function CvoxCharacterWalkerUnitTest() {}
-
-CvoxCharacterWalkerUnitTest.prototype = {
- __proto__: CvoxWalkerUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: CvoxWalkerUnitTestBase.prototype.closureModuleDeps.concat(
- 'cvox.CharacterWalker'),
-
- /** @override */
- newWalker: function() {
- return new cvox.CharacterWalker();
- },
-
- /**
- * Set up for simple tests so we don't have to repeat.
- * @private
- */
- setUpSimpleHtml_: function() {
- this.loadDoc(function() {/*!
- <div id="a"><p id="b">Th</p><p id="c">e quick</p></div>
- */});
- }
-};
-
-CvoxWalkerUnitTestBase.addCommonTests('CvoxCharacterWalkerUnitTest');
-
-TEST_F('CvoxCharacterWalkerUnitTest', 'SimpleForwardSync', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode($('a'));
- var ret = this.go(sel, 'sync', {
- selText: 'Th',
- selParentNodeId: 'b',
- selStartIndex: 0,
- selEndIndex: 1,
- selReversed: false
- });
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxCharacterWalkerUnitTest', 'testSimpleReversedSync', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel.setReversed(true);
- var ret = this.go(sel, 'sync', {
- selText: 'e quick',
- selParentNodeId: 'c',
- selStartIndex: 0,
- selEndIndex: 1,
- selReversed: true
- });
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxCharacterWalkerUnitTest', 'testSimpleForwardNext', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel = this.walker.sync(sel);
- var ret = this.go(sel, 'next', {
- selText: 'Th',
- selParentNodeId: 'b',
- selStartIndex: 1,
- selEndIndex: 2,
- selReversed: false
- });
-});
-
-TEST_F('CvoxCharacterWalkerUnitTest', 'testSimpleReversedNext', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel = this.walker.sync(sel.setReversed(true));
- var ret = this.go(sel, 'next', {
- selText: 'Th',
- selParentNodeId: 'b',
- selStartIndex: 1,
- selEndIndex: 2,
- selReversed: true
- });
-});
-
-/**
- * Tests for how spaces should be navigated character by character.
- */
-TEST_F('CvoxCharacterWalkerUnitTest', 'testSpaces', function() {
- this.loadDoc(function() {/*!
- <div id="foo">a <i>b</i> c<input type="text" value="asdf"/></div>
- */});
- var node = $('foo');
- var sel = cvox.CursorSelection.fromNode(node);
- var ret = this.go(sel, 'next', {descText: 'a'});
- ret = this.go(ret, 'next', {descText: ' '});
- ret = this.go(ret, 'next', {descText: 'b'});
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/column_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/column_walker.js
deleted file mode 100644
index d39bea0fdab..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/column_walker.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for walking columns.
- */
-
-
-goog.provide('cvox.ColumnWalker');
-
-goog.require('cvox.TableWalker');
-
-
-/**
- * @constructor
- * @extends {cvox.TableWalker}
- */
-cvox.ColumnWalker = function() {
- goog.base(this);
-};
-goog.inherits(cvox.ColumnWalker, cvox.TableWalker);
-
-
-/**
- * @override
- */
-cvox.ColumnWalker.prototype.next = function(sel) {
- return this.nextCol(sel);
-};
-
-
-/**
- * @override
- */
-cvox.ColumnWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('column_granularity');
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/group_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/group_walker.js
deleted file mode 100644
index 5015d3f2bf0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/group_walker.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for walking "groups". Groups, intuitively, are logical
- * collections of dom elements. See AbstractNodeWalker and the
- * stopNodeDescent() method here for how groups are defined.
- */
-
-
-goog.provide('cvox.GroupWalker');
-
-goog.require('cvox.AbstractNodeWalker');
-goog.require('cvox.BrailleUtil');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.DescriptionUtil');
-goog.require('cvox.DomUtil');
-goog.require('cvox.GroupUtil');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractNodeWalker}
- */
-cvox.GroupWalker = function() {
- cvox.AbstractNodeWalker.call(this);
-};
-goog.inherits(cvox.GroupWalker, cvox.AbstractNodeWalker);
-
-
-/**
- * @override
- */
-cvox.GroupWalker.prototype.getDescription = function(prevSel, sel) {
- return cvox.DescriptionUtil.getCollectionDescription(prevSel, sel);
-};
-
-
-/**
- * @override
- */
-cvox.GroupWalker.prototype.getBraille = function(prevSel, sel) {
- throw 'getBraille is unsupported';
-};
-
-/**
- * @override
- */
-cvox.GroupWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('group_strategy');
-};
-
-/**
- * @override
- */
-cvox.GroupWalker.prototype.stopNodeDescent = function(node) {
- return cvox.GroupUtil.isLeafNode(node);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/group_walker_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/group_walker_test.unitjs
deleted file mode 100644
index d035f89e8c9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/group_walker_test.unitjs
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['walker_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {CvoxWalkerTestBase}
- */
-function CvoxGroupWalkerUnitTest() {}
-
-CvoxGroupWalkerUnitTest.prototype = {
- __proto__: CvoxWalkerUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: CvoxWalkerUnitTestBase.prototype.closureModuleDeps.concat(
- 'cvox.GroupWalker'),
-
- /** @override */
- newWalker: function() {
- return new cvox.GroupWalker();
- },
-
- /**
- * Set up for simple html tests.
- * @private
- */
- setUpSimpleHtml_: function() {
- this.loadDoc(function() {/*!
- <div id="asdf">
- <p id="a">a</p>
- <ul id="b">
- <li>cat</li>
- <li>in</li>
- <li>hat</li>
- </ul>
- <p id="c">c</p>
- </div>
- */});
- }
-};
-
-CvoxWalkerUnitTestBase.addCommonTests('CvoxGroupWalkerUnitTest');
-
-TEST_F('CvoxGroupWalkerUnitTest', 'testSimpleForwardSync', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode($('asdf'));
- var ret = this.go(sel, 'sync', {selNodeId: 'a', selReversed: false});
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxGroupWalkerUnitTest', 'testSimpleReversedSync', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode($('asdf'));
- sel.setReversed(true);
- var ret = this.go(sel, 'sync', {selNodeId: 'c', selReversed: true});
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxGroupWalkerUnitTest', 'testSimpleForwardNext', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode($('asdf'));
- sel = this.walker.sync(sel);
- var ret = this.go(sel, 'next', {selNodeId: 'b', selReversed: false});
-});
-
-TEST_F('CvoxGroupWalkerUnitTest', 'testSimpleReversedNext', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode($('asdf'));
- sel = this.walker.sync(sel.setReversed(true));
- var ret = this.go(sel, 'next', {selNodeId: 'b', selReversed: true});
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker.js
deleted file mode 100644
index ad8140e5369..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker.js
+++ /dev/null
@@ -1,245 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A JavaScript class for walking lines consisting of one or more
- * clickable nodes.
- */
-
-
-goog.provide('cvox.LayoutLineWalker');
-
-goog.require('cvox.AbstractWalker');
-goog.require('cvox.StructuralLineWalker');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractWalker}
- */
-cvox.LayoutLineWalker = function() {
- this.subWalker_ = new cvox.StructuralLineWalker();
-};
-goog.inherits(cvox.LayoutLineWalker, cvox.AbstractWalker);
-
-
-/**
- * @override
- */
-cvox.LayoutLineWalker.prototype.next = function(sel) {
- // Collapse selection to the directed end.
- var endSel = new cvox.CursorSelection(sel.end, sel.end, sel.isReversed());
-
- // Sync to the line.
- var sync = this.subWalker_.sync(endSel);
- if (!sync) {
- return null;
- }
-
- // Compute the next selection.
- var start = this.subWalker_.next(endSel);
- if (!start) {
- return null;
- }
- start.setReversed(sel.isReversed());
- return this.extend_(start).setReversed(false);
-};
-
-
-/**
- * @override
- */
-cvox.LayoutLineWalker.prototype.sync = function(sel) {
- var line = this.subWalker_.sync(sel);
- if (!line) {
- return null;
- }
-
- // Extend to both line breaks (in each direction).
- var end = this.extend_(line);
- var start = this.extend_(line.setReversed(!line.isReversed()));
-
- return new cvox.CursorSelection(start.end, end.end, sel.isReversed());
-};
-
-
-/**
- * @override
- */
-cvox.LayoutLineWalker.prototype.getDescription = function(prevSel, sel) {
- var descriptions = [];
- var prev = prevSel;
- var absSel = sel.clone().setReversed(false);
- var cur = new cvox.CursorSelection(absSel.start, absSel.start);
- cur = this.subWalker_.sync(cur);
- if (!cur) {
- return [];
- }
-
- // No need to accumulate descriptions.
- if (absSel.start.node == absSel.end.node) {
- return this.subWalker_.getDescription(prevSel, sel);
- }
-
- // Walk through and collect descriptions for each line.
- while (cur && !cur.end.equals(absSel.end)) {
- descriptions.push.apply(
- descriptions, this.subWalker_.getDescription(prev, cur));
- prev = cur;
- cur = this.subWalker_.next(cur);
- }
- if (cur) {
- descriptions.push.apply(
- descriptions, this.subWalker_.getDescription(prev, cur));
- }
- return descriptions;
-};
-
-
-/**
- * @override
- */
-cvox.LayoutLineWalker.prototype.getBraille = function(prevSel, sel) {
- var braille = new cvox.NavBraille({});
- var absSel = this.subWalker_.sync(sel.clone().setReversed(false));
- var layoutSel = this.sync(sel).setReversed(false);
- if (!layoutSel || !absSel) {
- return braille;
- }
- var cur = new cvox.CursorSelection(layoutSel.start, layoutSel.start);
- cur = this.subWalker_.sync(cur);
- if (!cur) {
- return braille;
- }
-
- // Walk through and collect braille for each line.
- while (cur && !cur.end.equals(layoutSel.end)) {
- this.appendBraille_(prevSel, absSel, cur, braille);
- prevSel = cur;
- cur = this.subWalker_.next(cur);
- }
- if (cur) {
- this.appendBraille_(prevSel, absSel, cur, braille);
- }
- return braille;
-};
-
-
-/**
- * @override
- */
-cvox.LayoutLineWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('layout_line');
-};
-
-
-/**
- * Compares two selections and determines if the lie on the same horizontal
- * line as determined by their bounding rectangles.
- * @param {!cvox.CursorSelection} lSel Left selection.
- * @param {!cvox.CursorSelection} rSel Right selection.
- * @return {boolean} Whether lSel and rSel are on different visual lines.
- * @private
- */
-cvox.LayoutLineWalker.prototype.isVisualLineBreak_ = function(lSel, rSel) {
- if (this.wantsOwnLine_(lSel.end.node) ||
- this.wantsOwnLine_(rSel.start.node)) {
- return true;
- }
- var lRect = lSel.getRange().getBoundingClientRect();
- var rRect = rSel.getRange().getBoundingClientRect();
-
- // Some ranges from the browser give us 0-sized rects (such as in the case of
- // select's). Detect these cases and use a more reliable method (take the
- // bounding rect of the actual element rather than the range).
- if (lRect.width == 0 &&
- lRect.height == 0 &&
- lSel.end.node.nodeType == Node.ELEMENT_NODE) {
- lRect = lSel.end.node.getBoundingClientRect();
- }
-
- if (rRect.width == 0 &&
- rRect.height == 0 &&
- rSel.start.node.nodeType == Node.ELEMENT_NODE) {
- rRect = rSel.start.node.getBoundingClientRect();
- }
- return lRect.bottom != rRect.bottom;
-};
-
-
-/**
- * Determines if node should force a line break.
- * This is used for elements with unusual semantics, such as multi-line
- * text fields, where the behaviour would otherwise be confusing.
- * @param {!Node} node Node.
- * @return {boolean} True if the node should appear next to a line break.
- * @private
- */
-cvox.LayoutLineWalker.prototype.wantsOwnLine_ = function(node) {
- return node instanceof HTMLTextAreaElement ||
- node.parentNode instanceof HTMLTextAreaElement;
-};
-
-
-/**
- * Extends a given cursor selection up to the next visual line break.
- * @param {!cvox.CursorSelection} start The selection.
- * @return {!cvox.CursorSelection} The resulting selection.
- * @private
- */
-cvox.LayoutLineWalker.prototype.extend_ = function(start) {
- // Extend the selection up to just before a new visual line break.
- var end = start;
- var next = start;
-
- do {
- end = next;
- next = this.subWalker_.next(end);
- } while (next && !this.isVisualLineBreak_(end, next));
- return new cvox.CursorSelection(start.start, end.end, start.isReversed());
-};
-
-
-/**
- * Private routine to append braille given three selections.
- * @param {!cvox.CursorSelection} prevSel A previous selection in walker
- * ordering.
- * @param {!cvox.CursorSelection} sel A selection that represents the location
- * of the braille cursor.
- * @param {!cvox.CursorSelection} cur The specific selection to append.
- * @param {!cvox.NavBraille} braille Braille on which to append.
- * @private
- */
-cvox.LayoutLineWalker.prototype.appendBraille_ = function(
- prevSel, sel, cur, braille) {
- var item = this.subWalker_.getBraille(prevSel, cur).text;
- var valueSelectionSpan = item.getSpanInstanceOf(cvox.ValueSelectionSpan);
-
- if (braille.text.getLength() > 0) {
- braille.text.append(cvox.BrailleUtil.ITEM_SEPARATOR);
- }
-
- // Find the surrounding logical "leaf node".
- // This prevents us from labelling the braille output with the wrong node,
- // such as a text node child of a <textarea>.
- var node = cur.start.node;
- while (node.parentNode && cvox.DomUtil.isLeafNode(node.parentNode)) {
- node = node.parentNode;
- }
-
- var nodeStart = braille.text.getLength();
- var nodeEnd = nodeStart + item.getLength();
- braille.text.append(item);
- braille.text.setSpan(node, nodeStart, nodeEnd);
-
- if (sel && cur.absEquals(sel)) {
- if (valueSelectionSpan) {
- braille.startIndex = nodeStart + item.getSpanStart(valueSelectionSpan);
- braille.endIndex = nodeStart + item.getSpanEnd(valueSelectionSpan);
- } else {
- braille.startIndex = nodeStart;
- braille.endIndex = nodeStart + 1;
- }
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker_test.unitjs
deleted file mode 100644
index b257dd948b0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/layout_line_walker_test.unitjs
+++ /dev/null
@@ -1,179 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxLayoutLineWalkerUnitTest() {}
-
-CvoxLayoutLineWalkerUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'TestMsgs',
- 'cvox.CursorSelection',
- 'cvox.LayoutLineWalker',
- ],
-
- /** @override */
- setUp: function() {
- this.loadHtml(
- '<div id="1">' +
- '<p id="a">Demonstrating that in-line links like ' +
- '<a id="aa" href="google.com">google</a> ' +
- 'are considered a single layout line.' +
- '</p>' +
- '<p id="b">' +
- 'This includes a paragraph that has a lot of text like this one. ' +
- '<a id="bb" href="wikipedia.com">Wikipedia</a> ' +
- 'is a great example of a site that this walker becomes valuable.<br>' +
- 'Braille also benefits greatly from this type of formatting since ' +
- 'some displays can handle lots of text like 80 cell displays!' +
- '</p>' +
- '</div>'
- );
- Msgs = TestMsgs;
- this.walker = new cvox.LayoutLineWalker();
-
- this.a = cvox.CursorSelection.fromNode($('a'));
- this.aa = cvox.CursorSelection.fromNode($('aa'));
- this.b = cvox.CursorSelection.fromNode($('b'));
- this.bb = cvox.CursorSelection.fromNode($('bb'));
-
- this.line1Text = 'Demonstrating that in-line links like google are' +
- ' considered a single layout line.';
-
- this.line2Text = 'This includes a paragraph that has a lot of text' +
- ' like this one. Wikipedia is a great example of a site that this' +
- ' walker becomes valuable.';
-
- this.line3Text =
- 'Braille also benefits greatly from this type of formatting since ' +
- 'some displays can handle lots of text like 80 cell displays!';
-
- this.line1Description =
- [{'context': '', 'text': 'Demonstrating that in-line links like',
- 'userValue': '', 'annotation': '', 'earcons': [], 'personality': null,
- 'hint': '', 'category': null},
- {'context': '', 'text': 'google', 'userValue': '', 'annotation': 'Link',
- 'earcons': [cvox.Earcon.LINK], 'personality': null,
- hint: '', 'category': null},
- {'context': '', 'text': 'are considered a single layout line.',
- 'userValue': '', 'annotation': '', 'earcons': [], 'personality': null,
- 'hint': '', 'category': null}];
-
- this.line2Description =
- [{'context': '', 'text':
- 'This includes a paragraph that has a lot of text like this one.',
- 'userValue': '', 'annotation': '', 'earcons': [], 'personality': null,
- 'hint': '', 'category': null},
- {'context': '',
- 'text': 'Wikipedia',
- 'userValue': '',
- 'annotation': 'Link',
- 'earcons': [cvox.Earcon.LINK],
- 'personality': null,
- 'hint': '', 'category': null},
- {'context': '', 'text':
- 'is a great example of a site that this walker becomes valuable.',
- 'userValue': '',
- 'annotation': '', 'earcons': [], 'personality': null,
- 'hint': '', 'category': null}];
- }
-};
-
-TEST_F('CvoxLayoutLineWalkerUnitTest', 'Sync', function() {
- var sel = cvox.CursorSelection.fromNode($('1'));
- sel = this.walker.sync(sel);
- assertEquals(this.line1Text, sel.getText());
-
- sel = this.walker.sync(this.a);
- assertEquals(this.line1Text, sel.getText());
-
- sel = this.walker.sync(this.aa);
- assertEquals(this.line1Text, sel.getText());
-
- sel = this.walker.sync(this.b);
- assertEquals(this.line2Text, sel.getText());
-
- sel = this.walker.sync(this.bb);
- assertEquals(this.line2Text, sel.getText());
-
- // Reversed sync.
- sel = this.walker.sync(this.a).setReversed(true);
- assertEquals(this.line1Text, sel.getText());
-
- sel = this.walker.sync(this.aa).setReversed(true);
- assertEquals(this.line1Text, sel.getText());
-
- sel = this.walker.sync(this.b).setReversed(true);
- assertEquals(this.line2Text, sel.getText());
-
- sel = this.walker.sync(this.bb).setReversed(true);
- assertEquals(this.line2Text, sel.getText());
-});
-
-/** Tests description of valid selections. */
-TEST_F('CvoxLayoutLineWalkerUnitTest', 'Description', function() {
- var sel = this.walker.sync(this.a);
- assertEqualsJSON(this.line1Description,
- this.walker.getDescription(sel, sel));
-
- var sel = this.walker.sync(this.b);
- assertEqualsJSON(this.line2Description, this.walker.getDescription(sel, sel));
-});
-
-
-/** Tests back/forward movement. */
-TEST_F('CvoxLayoutLineWalkerUnitTest', 'BackForward', function() {
- var sel = this.walker.sync(this.a);
-
- // Beginning of second line.
- sel = this.walker.next(sel);
- assertEquals(Text, sel.start.node.constructor);
- assertEquals(this.b.start.node.id, sel.start.node.parentNode.id);
- assertEquals(null, sel.start.node.previousSibling);
- assertEquals(this.bb.start.node.id, sel.start.node.nextSibling.id);
- assertEquals(0, sel.start.index);
-
- // End of second line.
- assertEquals(Text, sel.end.node.constructor);
- assertEquals(this.b.end.node.id, sel.end.node.parentNode.id);
- assertEquals(HTMLBRElement, sel.end.node.nextSibling.constructor);
- assertEquals(this.bb.start.node.id, sel.end.node.previousSibling.id);
- assertEquals(64, sel.end.index);
-
- // Last line.
- var last = this.walker.next(sel);
- assertEquals(this.line3Text, last.getText());
-
- // Wrap.
- assertEquals(null, this.walker.next(last));
-
- // Reverse.
- sel = last.setReversed(true);
-
- // Second line.
- sel = this.walker.next(sel);
- assertEquals(this.line2Text, sel.getText());
-
- // Next always returns an unreversed selection for line granularity. Reverse
- // it to move backward.
- sel.setReversed(true);
-
- // First line.
- sel = this.walker.next(sel);
- assertEquals(this.line1Text, sel.getText());
-
- // Wrap.
- sel.setReversed(true);
- sel = this.walker.next(sel);
- assertEquals(null, sel);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/math_shifter.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/math_shifter.js
deleted file mode 100644
index 6488bf7ca77..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/math_shifter.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for walking mathml expressions.
- */
-
-goog.provide('cvox.MathShifter');
-
-goog.require('cvox.AbstractShifter');
-goog.require('cvox.BrailleUtil');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.DomUtil');
-goog.require('cvox.MathmlStore');
-goog.require('cvox.MathmlStoreRules');
-goog.require('cvox.NavDescription');
-goog.require('cvox.SpeechRuleEngine');
-goog.require('cvox.TraverseMath');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractShifter}
- * @param {cvox.CursorSelection=} sel A cursor selection.
- */
-cvox.MathShifter = function(sel) {
- goog.base(this);
-
- /**
- * Indicates the depth of the currently read expression.
- * @type {number}
- * @private
- */
- this.level_ = 0;
-
- /**
- * Indicates the vertical direction of movement (true for up, false for down).
- * @type {boolean}
- * @private
- */
- this.direction_ = false;
-
- /**
- * Indicates whether or not we've bumped against an edge in the math
- * structure.
- * @private
- */
- this.bumped_ = false;
-
-cvox.TraverseMath.getInstance().initialize(sel.start.node);
-};
-goog.inherits(cvox.MathShifter, cvox.AbstractShifter);
-
-
-/**
- * @override
- */
-cvox.MathShifter.prototype.next = function(sel) {
- // Delegate to TraverseMath which manages selection inside of the math tree.
- var r = sel.isReversed();
- this.bumped_ = !cvox.TraverseMath.getInstance().nextSibling(r);
- var attachedNode = cvox.TraverseMath.getInstance().getAttachedActiveNode();
- return attachedNode ? cvox.CursorSelection.fromNode(attachedNode) : sel;
-};
-
-
-/**
- * @override
- */
-cvox.MathShifter.prototype.sync = function(sel) {
- var attachedNode = cvox.TraverseMath.getInstance().getAttachedActiveNode();
- return attachedNode ? cvox.CursorSelection.fromNode(attachedNode) : sel;
-};
-
-
-/**
- * @override
- */
-cvox.MathShifter.prototype.getName = function() {
- return Msgs.getMsg('math_shifter');
-};
-
-
-/**
- * @override
- */
-cvox.MathShifter.prototype.getDescription = function(prevSel, sel) {
- var descs = cvox.SpeechRuleEngine.getInstance().evaluateNode(
- cvox.TraverseMath.getInstance().activeNode);
- if (this.bumped_ && descs.length > 0) {
- descs[0].pushEarcon(cvox.Earcon.WRAP_EDGE);
- }
- return descs;
-};
-
-
-/**
- * @override
- */
-cvox.MathShifter.prototype.getBraille = function(prevSel, sel) {
- return new cvox.NavBraille({
- text: cvox.BrailleUtil.getTemplated(prevSel.start.node, sel.start.node)
- });
-};
-
-
-/**
- * @override
- */
-cvox.MathShifter.prototype.getGranularityMsg = function() {
- return this.direction_ ? 'up to level ' + this.level_ :
- 'down to level ' + this.level_;
-};
-
-
-/**
- * @override
- */
-cvox.MathShifter.prototype.makeLessGranular = function() {
- this.level_ = this.level_ > 0 ? this.level_ - 1 : 0;
- this.direction_ = true;
- this.bumped_ = !cvox.TraverseMath.getInstance().nextParentChild(true);
-};
-
-
-/**
- * @override
- */
-cvox.MathShifter.prototype.makeMoreGranular = function() {
- this.direction_ = false;
- this.bumped_ = !cvox.TraverseMath.getInstance().nextParentChild(false);
- if (!this.bumped_) {
- this.level_++;
- }
-};
-
-
-/**
- * @override
- */
-cvox.MathShifter.create = function(sel) {
- if (cvox.DomPredicates.mathPredicate(
- cvox.DomUtil.getAncestors(sel.start.node))) {
- var mathNode = cvox.DomUtil.getContainingMath(sel.end.node);
- cvox.TraverseMath.getInstance().initialize(mathNode);
- cvox.SpeechRuleEngine.getInstance().parameterize(
- cvox.MathmlStore.getInstance());
- // TODO (sorge) Embed these changes into a local context menu/options menu.
- var dynamicCstr = cvox.MathStore.createDynamicConstraint(
- cvox.TraverseMath.getInstance().domain,
- cvox.TraverseMath.getInstance().style);
- cvox.SpeechRuleEngine.getInstance().setDynamicConstraint(dynamicCstr);
- return new cvox.MathShifter(sel);
- }
- return null;
-};
-
-
-/**
- * The active domain of the MathShifter.
- *
- * @return {string} The name of the current Math Domain.
- */
-cvox.MathShifter.prototype.getDomainMsg = function() {
- return cvox.TraverseMath.getInstance().domain;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/math_shifter_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/math_shifter_test.unitjs
deleted file mode 100644
index ac25bb5d7a4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/math_shifter_test.unitjs
+++ /dev/null
@@ -1,136 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxMathShifterUnitTest() {}
-
-CvoxMathShifterUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- closureModuleDeps: [
- 'cvox.ChromeVoxTester',
- 'cvox.CursorSelection',
- 'cvox.DescriptionUtil',
- 'cvox.MathmlStoreRules'
- ],
-
- /** @override */
- setUp: function() {
- cvox.ChromeVoxTester.setUp(document);
- },
-
- /** @override */
- tearDown: function() {
- cvox.ChromeVoxTester.tearDown(document);
- },
-
- /**
- * Simulates speaking the node (only text, no annotations!).
- * @param {Node} node The node to be described.
- * @return {!string} The resulting string.
- */
- getNodeDescription: function(node) {
- if (node) {
- var descs = cvox.DescriptionUtil.getMathDescription(node);
- var descs_str = descs.map(function(desc) {return desc.text;});
- return descs_str.filter(function(str) {return str;}).join(' ');
- }
- return '';
- }
-};
-
-TEST_F('CvoxMathShifterUnitTest', 'MathmlMtext', function() {
- this.loadHtml(
- '<div><math xmlns="http://www.w3.org/1998/Math/MathML" id="m0">' +
- '<mtext>Quod erat demonstrandum</mtext>' +
- '</math></div>'
- );
- var node = $('m0');
- assertEquals('Quod erat demonstrandum', this.getNodeDescription(node));
-});
-
-
-/** Test MathML individual.
- * @export
- */
-TEST_F('CvoxMathShifterUnitTest', 'MathmlMi', function() {
- this.loadHtml(
- '<div><math xmlns="http://www.w3.org/1998/Math/MathML" id="m1">' +
- '<mi>x</mi>' +
- '</math></div>');
- var node = $('m1');
- assertEquals('x', this.getNodeDescription(node));
-});
-
-
-/** Test MathML numeral.
- * @export
- */
-TEST_F('CvoxMathShifterUnitTest', 'MathmlMn', function() {
- this.loadHtml(
- '<div><math xmlns="http://www.w3.org/1998/Math/MathML" id="m2">' +
- '<mn>123</mn>' +
- '</math></div>');
- var node = $('m2');
- assertEquals('123', this.getNodeDescription(node));
-});
-
-
-/** Test MathML operator
- * @export
- */
-TEST_F('CvoxMathShifterUnitTest', 'MathmlMo', function() {
- this.loadHtml(
- '<div><math xmlns="http://www.w3.org/1998/Math/MathML" id="m3">' +
- '<mo>+</mo>' +
- '</math></div>');
- var node = $('m3');
- assertEquals('+', this.getNodeDescription(node));
-});
-
-
-/** Test MathML superscript.
- * @export
- */
-TEST_F('CvoxMathShifterUnitTest', 'MathmlMsup', function() {
- this.loadHtml(
- '<div><math xmlns="http://www.w3.org/1998/Math/MathML" id="m4">' +
- '<msup><mi>x</mi><mn>4</mn></msup>' +
- '</math></div>');
- var node = $('m4');
- assertEquals('x super 4', this.getNodeDescription(node));
-});
-
-
-/** Test MathML subscript.
- * @export
- */
-TEST_F('CvoxMathShifterUnitTest', 'MathmlMsub', function() {
- this.loadHtml(
- '<div><math xmlns="http://www.w3.org/1998/Math/MathML" id="m5">' +
- '<msub><mi>x</mi><mn>3</mn></msub>' +
- '</math></div>');
- var node = $('m5');
- assertEquals('x sub 3', this.getNodeDescription(node));
-});
-
-
-/** Test MathML subsupscript.
- * @export
- */
-TEST_F('CvoxMathShifterUnitTest', 'MathmlMsubsup', function() {
- this.loadHtml(
- '<div><math xmlns="http://www.w3.org/1998/Math/MathML" id="m6">' +
- '<msubsup><mi>x</mi><mn>3</mn><mn>4</mn></msubsup>' +
- '</math></div>');
- var node = $('m6');
- assertEquals('x sub 3 super 4', this.getNodeDescription(node));
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/object_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/object_walker.js
deleted file mode 100644
index 63b328a98dd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/object_walker.js
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A JavaScript class for walking the leaf nodes of the dom.
- */
-
-
-goog.provide('cvox.ObjectWalker');
-
-goog.require('cvox.AbstractNodeWalker');
-goog.require('cvox.BrailleUtil');
-goog.require('cvox.DescriptionUtil');
-
-/**
- * @constructor
- * @extends {cvox.AbstractNodeWalker}
- */
-cvox.ObjectWalker = function() {
- goog.base(this);
-};
-goog.inherits(cvox.ObjectWalker, cvox.AbstractNodeWalker);
-
-/**
- * @override
- */
-cvox.ObjectWalker.prototype.stopNodeDescent = function(node) {
- return cvox.DomUtil.isLeafNode(node);
-};
-
-// TODO(dtseng): Causes a circular dependency if put into AbstractNodeWalker.
-/**
- * @override
- */
-cvox.AbstractNodeWalker.prototype.getDescription = function(prevSel, sel) {
- return cvox.DescriptionUtil.getDescriptionFromNavigation(
- prevSel.end.node,
- sel.start.node,
- true,
- cvox.ChromeVox.verbosity);
-};
-
-/**
- * @override
- */
-cvox.ObjectWalker.prototype.getBraille = function(prevSel, sel) {
- throw 'getBraille is unsupported';
-};
-
-/**
- * @override
- */
-cvox.ObjectWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('object_strategy');
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/object_walker_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/object_walker_test.unitjs
deleted file mode 100644
index 1b6fe4378a1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/object_walker_test.unitjs
+++ /dev/null
@@ -1,97 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['walker_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {CvoxWalkerTestBase}
- */
-function CvoxObjectWalkerUnitTest() {}
-
-CvoxObjectWalkerUnitTest.prototype = {
- __proto__: CvoxWalkerUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: CvoxWalkerUnitTestBase.prototype.closureModuleDeps.concat(
- 'cvox.ObjectWalker'),
-
- /** @override */
- newWalker: function() {
- return new cvox.ObjectWalker();
- },
-
- /**
- * Set up for simple html tests.
- * @private
- */
- setUpSimpleHtml_: function() {
- this.loadDoc(function() {/*!
- <div id="a">
- <p id="b">b</p>
- <p id="c">c</p>
- </div>
- */});
- }
-};
-
-CvoxWalkerUnitTestBase.addCommonTests('CvoxObjectWalkerUnitTest');
-
-TEST_F('CvoxObjectWalkerUnitTest', 'testSimpleForwardSync', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode($('a'));
- var ret = this.go(sel, 'sync', {selParentNodeId: 'b', selReversed: false});
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxObjectWalkerUnitTest', 'testSimpleReversedSync', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel.setReversed(true);
- var ret = this.go(sel, 'sync', {selParentNodeId: 'c', selReversed: true});
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxObjectWalkerUnitTest', 'testSimpleForwardNext', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel = this.walker.sync(sel);
- var ret = this.go(sel, 'next', {selParentNodeId: 'c', selReversed: false});
-});
-
-TEST_F('CvoxObjectWalkerUnitTest', 'testSimpleReversedNext', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel = this.walker.sync(sel.setReversed(true));
- var ret = this.go(sel, 'next', {selParentNodeId: 'b', selReversed: true});
-});
-
-/** tests for unbroken anchor link descriptions. */
-TEST_F('CvoxObjectWalkerUnitTest', 'testAnchorLinkDescriptions', function() {
- this.loadDoc(function() {/*!
- <a href='a1.html' id='a1'>
- This link <em>has</em> a few <strong>complications.</strong>
- </a>
- */});
-
- var sel = this.walker.sync(
- cvox.CursorSelection.fromNode($('a1')));
- assertEquals('A', sel.start.node.tagName);
- assertEquals('This link has a few complications.',
- this.walker.getDescription(sel, sel)[0].text);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/row_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/row_walker.js
deleted file mode 100644
index b6d94a3185b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/row_walker.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for walking rows.
- */
-
-
-goog.provide('cvox.RowWalker');
-
-goog.require('cvox.TableWalker');
-
-
-/**
- * @constructor
- * @extends {cvox.TableWalker}
- */
-cvox.RowWalker = function() {
- goog.base(this);
-};
-goog.inherits(cvox.RowWalker, cvox.TableWalker);
-
-
-/**
- * @override
- */
-cvox.RowWalker.prototype.next = function(sel) {
- return this.nextRow(sel);
-};
-
-
-/**
- * @override
- */
-cvox.RowWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('row_granularity');
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/sentence_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/sentence_walker.js
deleted file mode 100644
index 2213db3cd64..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/sentence_walker.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A JavaScript class for walking sentences.
- */
-
-
-goog.provide('cvox.SentenceWalker');
-
-goog.require('cvox.AbstractSelectionWalker');
-goog.require('cvox.TraverseContent');
-
-/**
- * @constructor
- * @extends {cvox.AbstractSelectionWalker}
- */
-cvox.SentenceWalker = function() {
- cvox.AbstractSelectionWalker.call(this);
- this.grain = cvox.TraverseContent.kSentence;
-};
-goog.inherits(cvox.SentenceWalker, cvox.AbstractSelectionWalker);
-
-/**
- * @override
- */
-cvox.SentenceWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('sentence_granularity');
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/sentence_walker_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/sentence_walker_test.unitjs
deleted file mode 100644
index f8997811f95..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/sentence_walker_test.unitjs
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['walker_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {CvoxWalkerTestBase}
- */
-function CvoxSentenceWalkerUnitTest() {}
-
-CvoxSentenceWalkerUnitTest.prototype = {
- __proto__: CvoxWalkerUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: CvoxWalkerUnitTestBase.prototype.closureModuleDeps.concat(
- 'cvox.SentenceWalker'),
-
- /** @override */
- newWalker: function() {
- return new cvox.SentenceWalker();
- },
-
- /**
- * Set up simple html.
- * @private
- */
- setUpSimpleHtml_: function() {
- this.loadDoc(function() {/*!
- <div id="a"><p id="b">The quick</p><p id="c">brown. fox.</p></div>
- */});
- }
-};
-
-CvoxWalkerUnitTestBase.addCommonTests('CvoxSentenceWalkerUnitTest');
-
-TEST_F('CvoxSentenceWalkerUnitTest', 'testSimpleForwardSync', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode($('a'));
- var ret = this.go(sel, 'sync', {
- selText: 'The quick',
- selParentNodeId: 'b',
- selStartIndex: 0,
- selEndIndex: 9,
- selReversed: false
- });
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxSentenceWalkerUnitTest', 'testSimpleReversedSync', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel.setReversed(true);
- var ret = this.go(sel, 'sync', {
- selText: 'brown. fox.',
- selParentNodeId: 'c',
- selStartIndex: 0,
- selEndIndex: 6,
- selReversed: true
- });
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxSentenceWalkerUnitTest', 'testSimpleForwardNext', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel = this.walker.sync(sel);
- var ret = this.go(sel, 'next', {
- selText: 'brown. fox.',
- selParentNodeId: 'c',
- selStartIndex: 0,
- selEndIndex: 6,
- selReversed: false
- });
-});
-
-TEST_F('CvoxSentenceWalkerUnitTest', 'testSimpleReversedNext', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode($('a'));
- sel = this.walker.sync(sel.setReversed(true));
- var ret = this.go(sel, 'next', {
- selText: 'The quick',
- selParentNodeId: 'b',
- selStartIndex: 0,
- selEndIndex: 9,
- selReversed: true
- });
- ret = this.go(ret, 'next', null);
-});
-
-TEST_F('CvoxSentenceWalkerUnitTest', 'testControlElements', function() {
- this.loadDoc(function() {/*!
- <div id="a"><p>Before</p><input type="text"/><p>After</p></div>
- */});
- var node = $('a');
- var sel = this.walker.sync(cvox.CursorSelection.fromNode(node));
- var ret = this.go(sel, 'next', {descAnnotation: 'Edit text'});
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/structural_line_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/structural_line_walker.js
deleted file mode 100644
index 3936248fc95..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/structural_line_walker.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A JavaScript class for walking lines.
- */
-
-
-goog.provide('cvox.StructuralLineWalker');
-
-goog.require('cvox.AbstractSelectionWalker');
-goog.require('cvox.BrailleUtil');
-goog.require('cvox.TraverseContent');
-
-/**
- * @constructor
- * @extends {cvox.AbstractSelectionWalker}
- */
-cvox.StructuralLineWalker = function() {
- goog.base(this);
- this.grain = cvox.TraverseContent.kLine;
-};
-goog.inherits(cvox.StructuralLineWalker, cvox.AbstractSelectionWalker);
-
-
-/**
- * @override
- */
-cvox.StructuralLineWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('structural_line');
-};
-
-
-/**
- * @override
- */
-cvox.StructuralLineWalker.prototype.getDescription = function(prevSel, sel) {
- var desc = goog.base(this, 'getDescription', prevSel, sel);
- desc[0].text = cvox.DomUtil.getPrefixText(
- sel.absStart().node, sel.absStart().index) + desc[0].text;
- return desc;
-};
-
-
-/**
- * @override
- */
-cvox.StructuralLineWalker.prototype.getBraille = function(prevSel, sel) {
- var braille = goog.base(this, 'getBraille', prevSel, sel);
-
- var objNode = this.objWalker_.sync(sel).absStart().node;
- var node = sel.absStart().node;
- var prevNode = prevSel.absEnd().node;
-
- // Show only the visible line in braille for DOM ranges. This overrides any
- // labels computed for the node.
- //
- // <textarea> needs to be treated specially. It may have TextNode children,
- // but these reflect the initial value of the node only, and are not updated
- // as content changes.
- var name = undefined;
- if (!sel.start.equals(sel.end) &&
- !cvox.DomPredicates.editTextPredicate([objNode])) {
- var prefix =
- cvox.DomUtil.getPrefixText(sel.absStart().node, sel.absStart().index);
- name = prefix + sel.getText();
- }
- var spannable =
- cvox.BrailleUtil.getTemplated(prevNode, objNode, {name: name});
- spannable.setSpan(objNode, 0, spannable.getLength());
- braille.text = spannable;
-
- // Remove any selections.
- braille.startIndex = 0;
- braille.endIndex = 0;
- return braille;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/structural_line_walker_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/structural_line_walker_test.unitjs
deleted file mode 100644
index 7e0c59ff93f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/structural_line_walker_test.unitjs
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxStructuralLineWalkerUnitTest() {}
-
-CvoxStructuralLineWalkerUnitTest.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'cvox.StructuralLineWalker',
- 'TestMsgs',
- ],
-
- /** @override */
- setUp: function() {
- this.loadDoc(function() {/*!
- <a id='1' href='google.com'>Click Here</a>
- <pre id='2'>This text will break
- immediately here!
- <a href='google.com'>And here!</a>
- </p>
- */});
-
- Msgs = TestMsgs;
-
- this.walker_ = new cvox.StructuralLineWalker();
- },
-};
-
-TEST_F('CvoxStructuralLineWalkerUnitTest', 'BrailleLine', function() {
- var aLink = $('1');
- var aLinkSel1 = this.walker_.sync(cvox.CursorSelection.fromNode(aLink));
- assertEquals('Click Here lnk',
- this.walker_.getBraille(aLinkSel1, aLinkSel1).text.toString());
-
- var aPSel1 = this.walker_.next(aLinkSel1);
- assertEquals('This text will break',
- this.walker_.getBraille(aLinkSel1, aPSel1).text.toString());
-
- var aPSel2 = this.walker_.next(aPSel1);
- assertEquals('immediately here!',
- this.walker_.getBraille(aPSel1, aPSel2).text.toString());
-
- aLinkSel2 = this.walker_.next(aPSel2);
- assertEquals('And here! lnk',
- this.walker_.getBraille(aPSel2, aLinkSel2).text.toString());
-});
-
-
-/** Tests sync'ing to a line in the middle of a paragraph. */
-TEST_F('CvoxStructuralLineWalkerUnitTest', 'Sync', function() {
- var p1Sel = this.walker_.sync(
- cvox.CursorSelection.fromNode($('2')));
-
- // The second structural line of the paragraph.
- var p2Sel = this.walker_.next(p1Sel);
- assertEquals(29, p2Sel.start.index);
- assertEquals(46, p2Sel.end.index);
-
- // Sync should never mutate a previously synced selection.
- assertTrue(p2Sel.equals(this.walker_.sync(p2Sel)));
-});
-
-/** Tests syncing into an element treated as a leaf by TraverseUtil. */
-TEST_F('CvoxStructuralLineWalkerUnitTest', 'SyncTraverseUtil', function() {
- this.loadDoc(function() {/*!
- <select id='leaf'>
- <option>apple
- <option>orange
- </select>
- */});
- var leaf = $('leaf');
- assertEquals('leaf',
- this.walker_.sync(cvox.CursorSelection.fromNode(leaf)).start.node.id);
-});
-
-
-/** Tests specialized name calc with listitems with prefixes. */
-TEST_F('CvoxStructuralLineWalkerUnitTest', 'ListitemPrefixes', function() {
- this.loadDoc(function() {/*!
- <ol>
- <li id='li_orange'>orange
- <li id='li_apple'>apple
- <li id='li_long'>hi broken<br>line here
- </ol>
- */});
- var li1 = $('li_orange');
- var li2 = $('li_apple');
- var li3 = $('li_long');
- var li1Sel = this.walker_.sync(cvox.CursorSelection.fromNode(li1));
- var li2Sel = this.walker_.sync(cvox.CursorSelection.fromNode(li2));
- var li3Sel = this.walker_.sync(cvox.CursorSelection.fromNode(li3));
- var li3SelNext = this.walker_.next(li3Sel);
-
- assertEquals('1. orange',
- this.walker_.getDescription(li1Sel, li1Sel)[0].text);
- assertEquals('2. apple', this.walker_.getDescription(li2Sel, li2Sel)[0].text);
- assertEquals(
- '3. hi broken',
- this.walker_.getDescription(li3Sel, li3Sel)[0].text);
- assertEquals('line here', this.walker_.getDescription(
- li3SelNext, li3SelNext)[0].text.toString());
-
- assertEquals('1. orange',
- this.walker_.getBraille(li1Sel, li1Sel).text.toString());
- assertEquals('2. apple',
- this.walker_.getBraille(li2Sel, li2Sel).text.toString());
- assertEquals(
- '3. hi broken',
- this.walker_.getBraille(li3Sel, li3Sel).text.toString());
- assertEquals('line here',
- this.walker_.getBraille(li3SelNext, li3SelNext).text.toString());
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_shifter.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_shifter.js
deleted file mode 100644
index 98409b7d345..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_shifter.js
+++ /dev/null
@@ -1,152 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Walkers to traverse a table.
- */
-
-
-goog.provide('cvox.TableShifter');
-
-goog.require('cvox.AbstractShifter');
-goog.require('cvox.ColumnWalker');
-goog.require('cvox.CursorSelection');
-goog.require('cvox.DomPredicates');
-goog.require('cvox.DomUtil');
-goog.require('cvox.NavBraille');
-goog.require('cvox.RowWalker');
-
-
-/**
- * @constructor
- * @extends {cvox.AbstractShifter}
- */
-cvox.TableShifter = function() {
- this.rowWalker_ = new cvox.RowWalker();
- this.columnWalker_ = new cvox.ColumnWalker();
- this.currentWalker_ = this.rowWalker_;
- this.bumpedEdge_ = false;
- this.begin_ = true;
- goog.base(this);
-};
-goog.inherits(cvox.TableShifter, cvox.AbstractShifter);
-
-
-/**
- * @override
- */
-cvox.TableShifter.prototype.next = function(sel) {
- var nextSel = this.currentWalker_.next(sel);
- if (!nextSel) {
- // Bumped edge.
- this.bumpedEdge_ = true;
- return sel;
- }
- return nextSel;
-};
-
-
-/**
- * @override
- */
-cvox.TableShifter.prototype.sync = function(sel) {
- if (sel.start.node.tagName == 'TABLE') {
- return sel.isReversed() ? this.currentWalker_.goToLastCell(sel) :
- this.currentWalker_.goToFirstCell(sel);
- }
- return this.currentWalker_.sync(sel);
-};
-
-
-/**
- * @override
- */
-cvox.TableShifter.prototype.getName = function() {
- return Msgs.getMsg('table_shifter');
-};
-
-
-/**
- * @override
- * @suppress {checkTypes} actual parameter 2 of
- * Msgs.prototype.getMsg does not match formal parameter
- * found : Array<number>
- * required: (Array<string>|null|undefined)
- */
-cvox.TableShifter.prototype.getDescription = function(prevSel, sel) {
- var descs = this.currentWalker_.getDescription(prevSel, sel);
- if (descs.length > 0) {
- if (this.bumpedEdge_) {
- descs[0].pushEarcon(cvox.Earcon.WRAP_EDGE);
- this.bumpedEdge_ = false;
- }
- if (this.begin_) {
- var len = descs.length;
- var summaryText = this.currentWalker_.tt.summaryText();
- var locationInfo = this.currentWalker_.getLocationInfo(sel);
- if (locationInfo != null) {
- descs.push(new cvox.NavDescription({
- context: Msgs.getMsg('table_location', locationInfo),
- text: '',
- annotation: summaryText ? summaryText + ' ' : ''
- }));
- }
- if (this.currentWalker_.tt.isSpanned()) {
- descs.push(new cvox.NavDescription({
- text: '',
- annotation: Msgs.getMsg('spanned')
- }));
- }
- this.begin_ = false;
- }
- }
- return descs;
-};
-
-
-/**
- * @override
- */
-cvox.TableShifter.prototype.getBraille = function(prevSel, sel) {
- return this.currentWalker_.getBraille(prevSel, sel);
-};
-
-
-/**
- * @override
- */
-cvox.TableShifter.prototype.getGranularityMsg = function() {
- return this.currentWalker_.getGranularityMsg();
-};
-
-
-/**
- * @override
- */
-cvox.TableShifter.prototype.makeLessGranular = function() {
- goog.base(this, 'makeLessGranular');
- this.currentWalker_ = this.rowWalker_;
-};
-
-
-/**
- * @override
- */
-cvox.TableShifter.prototype.makeMoreGranular = function() {
- goog.base(this, 'makeMoreGranular');
- this.currentWalker_ = this.columnWalker_;
-};
-
-
-/**
- * @override
- */
-cvox.TableShifter.create = function(sel) {
- var ancestors = cvox.DomUtil.getAncestors(sel.start.node);
- if (cvox.DomPredicates.tablePredicate(ancestors) &&
- !cvox.DomPredicates.captionPredicate(ancestors)) {
- return new cvox.TableShifter();
- }
- return null;
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_walker.js
deleted file mode 100644
index fa629cff824..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_walker.js
+++ /dev/null
@@ -1,422 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for walking tables.
- * NOTE: This class has a very different interface than the other walkers.
- * This means it does not lend itself easily to e.g. decorators.
- * TODO (stoarca): This might be able to be fixed by breaking it up into
- * separate walkers for cell, row and column.
- */
-
-
-goog.provide('cvox.TableWalker');
-
-goog.require('cvox.AbstractWalker');
-goog.require('cvox.BrailleUtil');
-goog.require('cvox.DescriptionUtil');
-goog.require('cvox.DomUtil');
-goog.require('cvox.NavDescription');
-goog.require('cvox.QueueMode');
-goog.require('cvox.TraverseTable');
-
-/**
- * @constructor
- * @extends {cvox.AbstractWalker}
- */
-cvox.TableWalker = function() {
- cvox.AbstractWalker.call(this);
-
- /**
- * Only used as a cache for faster lookup.
- * @type {!cvox.TraverseTable}
- */
- this.tt = new cvox.TraverseTable(null);
-};
-goog.inherits(cvox.TableWalker, cvox.AbstractWalker);
-
-/**
- * @override
- */
-cvox.TableWalker.prototype.next = function(sel) {
- // TODO (stoarca): See bug 6677953
- return this.nextRow(sel);
-};
-
-/**
- * @override
- */
-cvox.TableWalker.prototype.sync = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToCell(position);
- }, this));
-};
-
-/**
- * @override
- * @suppress {checkTypes} actual parameter 2 of
- * Msgs.prototype.getMsg does not match formal parameter
- * found : Array<number>
- * required: (Array<string>|null|undefined)
- */
-cvox.TableWalker.prototype.getDescription = function(prevSel, sel) {
- var position = this.syncPosition_(sel);
- if (!position) {
- return [];
- }
- this.tt.goToCell(position);
- var descs = cvox.DescriptionUtil.getCollectionDescription(prevSel, sel);
- if (descs.length == 0) {
- descs.push(new cvox.NavDescription({
- annotation: Msgs.getMsg('empty_cell')
- }));
- }
- return descs;
-};
-
-/**
- * @override
- */
-cvox.TableWalker.prototype.getBraille = function(prevSel, sel) {
- var ret = new cvox.NavBraille({});
- var position = this.syncPosition_(sel);
- if (position) {
- var text =
- cvox.BrailleUtil.getTemplated(prevSel.start.node, sel.start.node);
- text.append(' ' + ++position[0] + '/' + ++position[1]);
- }
- return new cvox.NavBraille({text: text});
-};
-
-/**
- * @override
- */
-cvox.TableWalker.prototype.getGranularityMsg = goog.abstractMethod;
-
-
-/** Table Actions. */
-
-
-/**
- * Returns the first cell of the table that this selection is inside.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The selection for first cell of the table.
- * @export
- */
-cvox.TableWalker.prototype.goToFirstCell = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToCell([0, 0]);
- }, this));
-};
-
-/**
- * Returns the last cell of the table that this selection is inside.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The selection for the last cell of the table.
- * @export
- */
-cvox.TableWalker.prototype.goToLastCell = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToLastCell();
- }, this));
-};
-
-/**
- * Returns the first cell of the row that the selection is in.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The selection for the first cell in the row.
- * @export
- */
-cvox.TableWalker.prototype.goToRowFirstCell = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToCell([position[0], 0]);
- }, this));
-};
-
-/**
- * Returns the last cell of the row that the selection is in.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The selection for the last cell in the row.
- * @export
- */
-cvox.TableWalker.prototype.goToRowLastCell = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToRowLastCell();
- }, this));
-};
-
-/**
- * Returns the first cell of the column that the selection is in.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The selection for the first cell in the col.
- * @export
- */
-cvox.TableWalker.prototype.goToColFirstCell = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToCell([0, position[1]]);
- }, this));
-};
-
-/**
- * Returns the last cell of the column that the selection is in.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The selection for the last cell in the col.
- * @export
- */
-cvox.TableWalker.prototype.goToColLastCell = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToColLastCell();
- }, this));
-};
-
-/**
- * Returns the first cell in the row after the current selection.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The selection for the first cell in the next
- * row.
- * @export
- */
-cvox.TableWalker.prototype.nextRow = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToCell([position[0] + (sel.isReversed() ? -1 : 1),
- position[1]]);
- }, this));
-};
-
-/**
- * Returns the first cell in the column after the current selection.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {cvox.CursorSelection} The selection for the first cell in the
- * next col.
- * @export
- */
-cvox.TableWalker.prototype.nextCol = function(sel) {
- return this.goTo_(sel, goog.bind(function(position) {
- return this.tt.goToCell([position[0],
- position[1] + (sel.isReversed() ? -1 : 1)]);
- }, this));
-};
-
-/**
- * @param {!cvox.CursorSelection} sel The current selection.
- * @return {cvox.CursorSelection} The resulting selection.
- * @export
- */
-cvox.TableWalker.prototype.announceHeaders = function(sel) {
- cvox.ChromeVox.tts.speak(this.getHeaderText_(sel),
- cvox.QueueMode.FLUSH,
- cvox.AbstractTts.PERSONALITY_ANNOTATION);
- return sel;
-};
-
-/**
- * @param {!cvox.CursorSelection} sel The current selection.
- * @return {cvox.CursorSelection} The resulting selection.
- * @export
- */
-cvox.TableWalker.prototype.speakTableLocation = function(sel) {
- cvox.ChromeVox.navigationManager.speakDescriptionArray(
- this.getLocationDescription_(sel),
- cvox.QueueMode.FLUSH,
- null);
- return sel;
-};
-
-
-/**
- * @param {!cvox.CursorSelection} sel The current selection.
- * @return {cvox.CursorSelection} The resulting selection.
- * @export
- */
-cvox.TableWalker.prototype.exitShifterContent = function(sel) {
- var tableNode = this.getTableNode_(sel);
- if (!tableNode) {
- return null;
- }
- var nextNode = cvox.DomUtil.directedNextLeafNode(tableNode, false);
- return cvox.CursorSelection.fromNode(nextNode);
-};
-
-
-/** End of actions. */
-
-
-/**
- * Returns the text content of the header(s) of the cell that contains sel.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {!string} The header text.
- * @private
- */
-cvox.TableWalker.prototype.getHeaderText_ = function(sel) {
- this.tt.initialize(this.getTableNode_(sel));
- var position = this.tt.findNearestCursor(sel.start.node);
- if (!position) {
- return Msgs.getMsg('not_inside_table');
- }
- if (!this.tt.goToCell(position)) {
- return Msgs.getMsg('not_inside_table');
- }
- return (
- this.getRowHeaderText_(position) +
- ' ' +
- this.getColHeaderText_(position));
-};
-
-/**
- * Returns the location description.
- * @param {!cvox.CursorSelection} sel A valid selection.
- * @return {Array<cvox.NavDescription>} The location description.
- * @suppress {checkTypes} actual parameter 2 of
- * Msgs.prototype.getMsg does not match
- * formal parameter
- * found : Array<number>
- * required: (Array<string>|null|undefined)
- * @private
- */
-cvox.TableWalker.prototype.getLocationDescription_ = function(sel) {
- var locationInfo = this.getLocationInfo(sel);
- if (locationInfo == null) {
- return null;
- }
- return [new cvox.NavDescription({
- text: Msgs.getMsg('table_location', locationInfo)
- })];
-};
-
-/**
- * Returns the text content of the row header(s) of the cell that contains sel.
- * @param {!Array<number>} position The selection.
- * @return {!string} The header text.
- * @private
- */
-cvox.TableWalker.prototype.getRowHeaderText_ = function(position) {
- // TODO(stoarca): OPTMZ Replace with join();
- var rowHeaderText = '';
-
- var rowHeaders = this.tt.getCellRowHeaders();
- if (rowHeaders.length == 0) {
- var firstCellInRow = this.tt.getCellAt([position[0], 0]);
- rowHeaderText += cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(firstCellInRow) + ' ' +
- cvox.DomUtil.getName(firstCellInRow));
- return Msgs.getMsg('row_header') + rowHeaderText;
- }
-
- for (var i = 0; i < rowHeaders.length; ++i) {
- rowHeaderText += cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(rowHeaders[i]) + ' ' +
- cvox.DomUtil.getName(rowHeaders[i]));
- }
- if (rowHeaderText == '') {
- return Msgs.getMsg('empty_row_header');
- }
- return Msgs.getMsg('row_header') + rowHeaderText;
-};
-
-/**
- * Returns the text content of the col header(s) of the cell that contains sel.
- * @param {!Array<number>} position The selection.
- * @return {!string} The header text.
- * @private
- */
-cvox.TableWalker.prototype.getColHeaderText_ = function(position) {
- // TODO(stoarca): OPTMZ Replace with join();
- var colHeaderText = '';
-
- var colHeaders = this.tt.getCellColHeaders();
- if (colHeaders.length == 0) {
- var firstCellInCol = this.tt.getCellAt([0, position[1]]);
- colHeaderText += cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(firstCellInCol) + ' ' +
- cvox.DomUtil.getName(firstCellInCol));
- return Msgs.getMsg('column_header') + colHeaderText;
- }
-
- for (var i = 0; i < colHeaders.length; ++i) {
- colHeaderText += cvox.DomUtil.collapseWhitespace(
- cvox.DomUtil.getValue(colHeaders[i]) + ' ' +
- cvox.DomUtil.getName(colHeaders[i]));
- }
- if (colHeaderText == '') {
- return Msgs.getMsg('empty_row_header');
- }
- return Msgs.getMsg('column_header') + colHeaderText;
-};
-
-/**
- * Returns the location info of sel within the containing table.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {Array<number>} The location info:
- * [row index, row count, col index, col count].
- */
-cvox.TableWalker.prototype.getLocationInfo = function(sel) {
- this.tt.initialize(this.getTableNode_(sel));
- var position = this.tt.findNearestCursor(sel.start.node);
- if (!position) {
- return null;
- }
- // + 1 to account for 0-indexed
- return [
- position[0] + 1,
- this.tt.rowCount,
- position[1] + 1,
- this.tt.colCount
- ].map(function(x) {return Msgs.getNumber(x);});
-};
-
-/**
- * Returns true if sel is inside a table.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {boolean} True if inside a table node.
- */
-cvox.TableWalker.prototype.isInTable = function(sel) {
- return this.getTableNode_(sel) != null;
-};
-
-/**
- * Wrapper for going to somewhere so that boilerplate is not repeated.
- * @param {!cvox.CursorSelection} sel The selection from which to base the
- * movement.
- * @param {function(Array<number>):boolean} f The function to use for moving.
- * Returns true on success and false on failure.
- * @return {cvox.CursorSelection} The resulting selection.
- * @private
- */
-cvox.TableWalker.prototype.goTo_ = function(sel, f) {
- this.tt.initialize(this.getTableNode_(sel));
- var position = this.tt.findNearestCursor(sel.end.node);
- if (!position) {
- return null;
- }
- this.tt.goToCell(position);
- if (!f(position)) {
- return null;
- }
- return cvox.CursorSelection.fromNode(this.tt.getCell()).
- setReversed(sel.isReversed());
-};
-
-/**
- * Returns the nearest table node containing the end of the selection
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {Node} The table node containing sel. null if not in a table.
- * @private
- */
-cvox.TableWalker.prototype.getTableNode_ = function(sel) {
- return cvox.DomUtil.getContainingTable(sel.end.node);
-};
-
-/**
- * Sync the backing traversal utility to the given selection.
- * @param {!cvox.CursorSelection} sel The selection.
- * @return {Array<number>} The position [x, y] of the selection.
- * @private
- */
-cvox.TableWalker.prototype.syncPosition_ = function(sel) {
- var tableNode = this.getTableNode_(sel);
- this.tt.initialize(tableNode);
- // we need to align the TraverseTable with our sel because our walker
- // uses parts of it (for example isSpanned relies on being at a specific cell)
- return this.tt.findNearestCursor(sel.end.node);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_walker_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_walker_test.unitjs
deleted file mode 100644
index f2e9e3dceea..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/table_walker_test.unitjs
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['walker_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {CvoxWalkerTestBase}
- */
-function CvoxTableWalkerUnitTest() {}
-
-CvoxTableWalkerUnitTest.prototype = {
- __proto__: CvoxWalkerUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: CvoxWalkerUnitTestBase.prototype.closureModuleDeps.concat(
- 'cvox.TableWalker'),
-
- /** @override */
- newWalker: function() {
- return new cvox.TableWalker();
- }
-
-};
-
-// NOTE: The common walker tests don't work for the table walker, so they are
-// not added here.
-
-/**
- * Simple tests for TableWalker
- */
-TEST_F('CvoxTableWalkerUnitTest', 'testSimpleTableWalker', function() {
- this.loadDoc(function() {/*!
- <p id="before">Before</p>
- <table id="table">
- <tr><td>A</td><td>1</td></tr>
- <tr><td>B</td><td>2</td></tr>
- </table>
- */});
- var node = document.getElementById('table');
- var sel = cvox.CursorSelection.fromNode(node);
- var ret = this.go(sel, 'sync', {descText: 'A'});
-});
-
-/**
- * Test navigating rows.
- */
-TEST_F('CvoxTableWalkerUnitTest', 'testNavigateRows', function() {
- this.loadDoc(function() {/*!
- <table id="table">
- <tr><td>A</td><td>1</td></tr>
- <tr><td>B</td><td>2</td></tr>
- </table>
- */});
- var node = document.getElementById('table');
- var sel = cvox.CursorSelection.fromNode(node);
- var ret = this.go(sel, 'sync', {descText: 'A'});
- ret = this.go(ret, 'nextRow', {descText: 'B'});
- this.go(ret, 'nextRow', null);
- ret.setReversed(true);
- ret = this.go(ret, 'nextRow', {descText: 'A'});
- this.go(ret, 'nextRow', null);
-});
-
-/**
- * Test navigating columns.
- */
-TEST_F('CvoxTableWalkerUnitTest', 'testNavigateCols', function() {
- this.loadDoc(function() {/*!
- <table id="table">
- <tr><td>A</td><td>1</td></tr>
- <tr><td>B</td><td>2</td></tr>
- </table>
- */});
- var node = document.getElementById('table');
- var sel = cvox.CursorSelection.fromNode(node);
- var ret = this.go(sel, 'sync', {descText: 'A'});
- ret = this.go(ret, 'nextCol', {descText: '1'});
- this.go(ret, 'nextCol', null);
- ret.setReversed(true);
- ret = this.go(ret, 'nextCol', {descText: 'A'});
- this.go(ret, 'nextCol', null);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/walker_unittest_base.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/walker_unittest_base.js
deleted file mode 100644
index b58b152f2e7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/walker_unittest_base.js
+++ /dev/null
@@ -1,234 +0,0 @@
-// 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.
-
-GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
-
-/**
- * Base class for walker test fixtures.
- * @constructor
- * @extends {ChromeVoxUnitTestBase}
- */
-function CvoxWalkerUnitTestBase() {}
-
-CvoxWalkerUnitTestBase.prototype = {
- __proto__: ChromeVoxUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: [
- 'TestMsgs',
- 'cvox.CursorSelection'
- ],
-
- /**
- * Common set up for all walker test cases.
- */
- setUp: function() {
- // Needed for getDescription and getGranularityMsg.
- Msgs = TestMsgs;
-
- // Delete all nodes in the body.
- while (document.body.hasChildNodes()) {
- document.body.removeChild(document.body.lastChild);
- }
-
- this.walker = this.newWalker();
- },
-
- /**
- * Returns a new walker appropriate for the child test.
- * @return {!cvox.AbstractWalker} The walker instance.
- */
- newWalker: goog.abstractMethod,
-
- /**
- * Makes testing much less verbose. Executes the command on the
- * selection, then asserts that for all the parameters passed in desc,
- * the new selection matches. Returns the new selections if assertion passes.
- * NOTE: If you change the parameters here, you should also change the
- * whitelist above.
- * @param {!cvox.CursorSelection} sel The selection.
- * @param {!string|!cvox.CursorSelection} opt_cmdOrDest The command to
- * execute, or the override returned selection.
- * @param {{selText: string=,
- * selNodeId: string=,
- * selParentNodeId: string=,
- * selStartIndex: number=,
- * selEndIndex: number=,
- * selReversed: boolean=,
- * descText: string=,
- * descContext: string=,
- * descAnnotation: string=,
- * descUserValue: string=,
- * descPersonality: string=}} desc The parameters to assert.
- * selText: The text in the new selection matches for both start and end.
- * selNodeId: The node in the new selection matches for both start and end.
- * selParentNodeId: The parent node of both start and end matches.
- * selStartIndex: The index of the absolute start.
- * selEndIndex: The index of the absolute end.
- * selReversed: True if should be reversed.
- * descText: The text in the NavDescription when getDescription is called.
- * descContext: The context in the NavDescription
- * descAnnotation: The annotation in the NavDescription
- * descUserValue: The userValue in the NavDescription
- * descPersonality: The personality in the NavDescription
- * @return {cvox.CursorSelection} The new selection.
- */
- go: function(sel, opt_cmdOrDest, desc) {
- if (opt_cmdOrDest instanceof cvox.CursorSelection) {
- var ret = opt_cmdOrDest;
- } else {
- if (CvoxWalkerUnitTestBase.CMD_WHITELIST.indexOf(opt_cmdOrDest) == -1) {
- // Intentionally fail the test if there's a typo.
- throw 'Got an invalid command: "' + opt_cmdOrDest + '".';
- }
-
- var ret = this.walker[opt_cmdOrDest](sel);
- }
-
- if (ret == null) {
- assertEquals(null, desc);
- return;
- }
- if (desc == null) {
- assertEquals(null, ret);
- return;
- }
-
- for (var key in desc) {
- if (CvoxWalkerUnitTestBase.DESC_WHITELIST.indexOf(key) == -1) {
- throw 'Invalid key in desc parameter: "' + key + '".';
- }
- }
-
- // Intentionally only check one-to-one and not onto. This allows us to
- // write tests that just ignore everything except what we care about.
- if (desc.hasOwnProperty('selText')) {
- assertEquals(desc.selText, ret.start.text);
- assertEquals(desc.selText, ret.end.text);
- }
- if (desc.hasOwnProperty('selNodeId')) {
- assertEquals(desc.selNodeId, ret.start.node.id);
- assertEquals(desc.selNodeId, ret.end.node.id);
- }
- if (desc.hasOwnProperty('selParentNodeId')) {
- assertEquals(desc.selParentNodeId, ret.start.node.parentNode.id);
- assertEquals(desc.selParentNodeId, ret.end.node.parentNode.id);
- }
- if (desc.hasOwnProperty('selStartIndex')) {
- assertEquals(desc.selStartIndex, ret.absStart().index);
- }
- if (desc.hasOwnProperty('selEndIndex')) {
- assertEquals(desc.selEndIndex, ret.absEnd().index);
- }
- if (desc.hasOwnProperty('selReversed')) {
- assertEquals(desc.selReversed, ret.isReversed());
- }
-
- var trueDesc = this.walker.getDescription(sel, ret)[0];
- if (desc.hasOwnProperty('descText')) {
- assertEquals(desc.descText, trueDesc.text);
- }
- if (desc.hasOwnProperty('descContext')) {
- assertEquals(desc.descContext, trueDesc.context);
- }
- if (desc.hasOwnProperty('descAnnotation')) {
- assertEquals(desc.descAnnotation, trueDesc.annotation);
- }
- if (desc.hasOwnProperty('descUserValue')) {
- assertEquals(desc.descUserValue, trueDesc.userValue);
- }
- if (desc.hasOwnProperty('descPersonality')) {
- assertEquals(desc.descPersonality, trueDesc.personality);
- }
-
- return ret;
- },
-};
-
-/**
- * Whitelist for the commands that are allowed to be executed with go().
- * @type {Array.string}
- * @const
- */
-CvoxWalkerUnitTestBase.CMD_WHITELIST = ['next', 'sync', 'nextRow', 'nextCol'];
-
-/**
- * Whitelist for the properties that can be asserted with go().
- * @type {Array.string}
- * @const
- */
-CvoxWalkerUnitTestBase.DESC_WHITELIST = ['selText', 'selNodeId',
-'selParentNodeId', 'selStartIndex', 'selEndIndex', 'selReversed', 'descText',
-'descContext', 'descAnnotation', 'descUserValue', 'descPersonality'];
-
-/**
- * Adds common walker tests
- * @param {string} testFixture Name of the test fixture class.
- */
-CvoxWalkerUnitTestBase.addCommonTests = function(testFixture) {
- /**
- * Ensures that syncing to the beginning and ends of the page return
- * not null.
- */
- TEST_F(testFixture, 'testSyncToPage', function() {
- this.loadDoc(function() {/*!
- <div><p id="a">a</p></div>
- */});
- var ret = this.walker.begin();
- assertNotEquals(null, ret);
- ret = this.walker.begin({reversed: true});
- assertNotEquals(null, ret);
- });
-
- /**
- * Ensures that sync(sync(sel)) = sync(sel)
- * TODO (stoarca): The interfaces are not frozen yet. In particular,
- * for TableWalker, sync can return null. Override if it doesn't work yet.
- */
- TEST_F(testFixture, 'testSyncInvariant', function() {
- this.loadDoc(function() {/*!
- <div id="outer">
- <p id="a">a</p>
- <p id="b">b</p>
- <p id="c">c</p>
- <p id="d">d</p>
- <h1 id="A">h1</h1>
- <p id="e">e</p>
- <h1 id="B">h1</h1>
- </div>
- */});
- var sel = cvox.CursorSelection.fromNode(
- $('outer').firstChild);
- var sync = this.walker.sync(sel);
- var syncsync = this.walker.sync(sync);
- assertEquals(true, sync.equals(syncsync));
-
- sel = cvox.CursorSelection.fromNode($('a'));
- sync = this.walker.sync(sel);
- syncsync = this.walker.sync(sync);
- assertEquals(true, sync.equals(syncsync));
-
- sel = cvox.CursorSelection.fromNode($('e'));
- sync = this.walker.sync(sel);
- syncsync = this.walker.sync(sync);
- assertEquals(true, sync.equals(syncsync));
-
- sel = cvox.CursorSelection.fromBody();
- sync = this.walker.sync(sel);
- syncsync = this.walker.sync(sync);
- assertEquals(true, sync.equals(syncsync));
- });
-
- /**
- * Ensures that all operations work on an empty body.
- */
- TEST_F(testFixture, 'testEmptyBody', function() {
- var sel = cvox.CursorSelection.fromBody();
-
- // Testing for infinite loop. If one exists, this test will fail by timing
- // out.
- var sync = this.walker.sync(sel);
- var next = this.walker.next(sel);
- });
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/word_walker.js b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/word_walker.js
deleted file mode 100644
index 6256387fd5d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/word_walker.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A class for walking one word at a time.
- */
-
-
-goog.provide('cvox.WordWalker');
-
-goog.require('cvox.AbstractSelectionWalker');
-goog.require('cvox.TraverseContent');
-
-/**
- * @constructor
- * @extends {cvox.AbstractSelectionWalker}
- */
-cvox.WordWalker = function() {
- cvox.AbstractSelectionWalker.call(this);
- this.grain = cvox.TraverseContent.kWord;
-};
-goog.inherits(cvox.WordWalker, cvox.AbstractSelectionWalker);
-
-/**
- * @override
- */
-cvox.WordWalker.prototype.getGranularityMsg = function() {
- return Msgs.getMsg('word_granularity');
-};
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/word_walker_test.unitjs b/chromium/chrome/browser/resources/chromeos/chromevox/walkers/word_walker_test.unitjs
deleted file mode 100644
index 2da6b522982..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/walkers/word_walker_test.unitjs
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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 test fixture.
-GEN_INCLUDE(['walker_unittest_base.js']);
-
-/**
- * Test fixture.
- * @constructor
- * @extends {CvoxWalkerTestBase}
- */
-function CvoxWordWalkerUnitTest() {}
-
-CvoxWordWalkerUnitTest.prototype = {
- __proto__: CvoxWalkerUnitTestBase.prototype,
-
- /** @override */
- closureModuleDeps: CvoxWalkerUnitTestBase.prototype.closureModuleDeps.concat(
- 'cvox.WordWalker'),
-
- /** @override */
- newWalker: function() {
- return new cvox.WordWalker();
- },
-
- /**
- * Set up for the simple tests so we don't have to repeat.
- * @private
- */
- setUpSimpleHtml_: function() {
- this.loadDoc(function() {/*!
- <div id="a"><p id="b">The </p><p id="c">quick brown.</p></div>
- */});
- }
-};
-
-CvoxWalkerUnitTestBase.addCommonTests('CvoxWordWalkerUnitTest');
-
-TEST_F('CvoxWordWalkerUnitTest', 'testSimpleForwardSync', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode(document.getElementById('a'));
- var ret = this.go(sel, 'sync', {
- selText: 'The ',
- selParentNodeId: 'b',
- selStartIndex: 0,
- selEndIndex: 3,
- selReversed: false
- });
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxWordWalkerUnitTest', 'testSimpleReversedSync', function() {
- this.setUpSimpleHtml_();
-
- // invalid selection
- var sel = cvox.CursorSelection.fromNode(document.getElementById('a'));
- sel.setReversed(true);
- var ret = this.go(sel, 'sync', {
- selText: 'quick brown.',
- selParentNodeId: 'c',
- selStartIndex: 0,
- selEndIndex: 5,
- selReversed: true
- });
-
- // valid selection
- var ret2 = this.walker.sync(ret);
- assertTrue(ret2.equals(ret));
-});
-
-TEST_F('CvoxWordWalkerUnitTest', 'testSimpleForwardNext', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode(document.getElementById('a'));
- sel = this.walker.sync(sel);
- var ret = this.go(sel, 'next', {
- selText: 'quick brown.',
- selParentNodeId: 'c',
- selStartIndex: 0,
- selEndIndex: 5,
- selReversed: false
- });
-});
-
-TEST_F('CvoxWordWalkerUnitTest', 'testSimpleReversedNext', function() {
- this.setUpSimpleHtml_();
-
- var sel = cvox.CursorSelection.fromNode(document.getElementById('a'));
- sel = this.walker.sync(sel.setReversed(true));
- var ret = this.go(sel, 'next', {
- selText: 'The ',
- selParentNodeId: 'b',
- selStartIndex: 0,
- selEndIndex: 3,
- selReversed: true
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/compiled_resources.gyp b/chromium/chrome/browser/resources/chromeos/compiled_resources.gyp
index 0cf95b6f53f..ed72f939aa1 100644
--- a/chromium/chrome/browser/resources/chromeos/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/chromeos/compiled_resources.gyp
@@ -4,8 +4,18 @@
{
'targets': [
{
+ 'target_name': 'bluetooth_pair_device',
+ 'variables': {
+ 'depends': [
+ '../../../../chrome/browser/resources/options/compiled_resources.gyp:options_bundle',
+ ],
+ 'externs': ['<(EXTERNS_DIR)/chrome_send.js'],
+ },
+ 'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
'target_name': 'certificate_manager_dialog',
- 'variables': {
+ 'variables': {
'depends': [
'../../../../chrome/browser/resources/options/compiled_resources.gyp:options_bundle',
],
diff --git a/chromium/chrome/browser/resources/chromeos/connectivity_diagnostics/OWNERS b/chromium/chrome/browser/resources/chromeos/connectivity_diagnostics/OWNERS
deleted file mode 100644
index 8da18d59b33..00000000000
--- a/chromium/chrome/browser/resources/chromeos/connectivity_diagnostics/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-ebeach@chromium.org
-xiaowenx@chromium.org
-zork@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/cryptohome.html b/chromium/chrome/browser/resources/chromeos/cryptohome.html
deleted file mode 100644
index 9e11f11a886..00000000000
--- a/chromium/chrome/browser/resources/chromeos/cryptohome.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>About Cryptohome</title>
- <meta charset="utf-8">
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <script src="chrome://resources/js/util.js"></script>
- <script src="chrome://cryptohome/cryptohome.js"></script>
- </head>
- <body>
- <div id="refresh-message">
- (To auto-refresh this page: about:cryptohome/&lt;secs&gt;)
- </div>
- <h3>Cryptohome:</h3>
- <table>
- <tr>
- <td>IsMounted</td>
- <td id="is-mounted"></td>
- </tr>
- <tr>
- <td>TpmIsReady</td>
- <td id="tpm-is-ready"></td>
- </tr>
- <tr>
- <td>TpmIsEnabled</td>
- <td id="tpm-is-enabled"></td>
- </tr>
- <tr>
- <td>TpmIsOwned</td>
- <td id="tpm-is-owned"></td>
- </tr>
- <tr>
- <td>TpmIsBeingOwned</td>
- <td id="tpm-is-being-owned"></td>
- </tr>
- <tr>
- <td>Pkcs11IsTpmTokenReady</td>
- <td id="pkcs11-is-tpm-token-ready"></td>
- </tr>
- </table>
- <h3>crypto:</h3>
- <table>
- <tr>
- <td>IsTPMTokenReady</td>
- <td id="is-tpm-token-ready"></td>
- </tr>
- </table>
- </body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/cryptohome.js b/chromium/chrome/browser/resources/chromeos/cryptohome.js
deleted file mode 100644
index 40b172045b0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/cryptohome.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Sets |value| to the element specified by |destination_id|.
- * Called from C++ code as a result of RequestCryptohomeProperty() call.
- * @param {string} destination_id Id of the element to be modified.
- * @param {string} value The value to be set.
- */
-function SetCryptohomeProperty(destination_id, value) {
- $(destination_id).textContent = value;
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- // Request update.
- chrome.send('pageLoaded');
-
- // Auto-refresh when interval is given as pathname.
- var interval = parseInt(window.location.pathname.split('/')[1]);
- if (interval > 0) {
- $('refresh-message').textContent =
- '(Auto-refreshing page every ' + interval + 's)';
- setTimeout(function() { window.location.reload(true); }, interval * 1000);
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/detected_sd.png b/chromium/chrome/browser/resources/chromeos/detected_sd.png
deleted file mode 100644
index fe3cf300c20..00000000000
--- a/chromium/chrome/browser/resources/chromeos/detected_sd.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/detected_usb.png b/chromium/chrome/browser/resources/chromeos/detected_usb.png
deleted file mode 100644
index 653613e1f83..00000000000
--- a/chromium/chrome/browser/resources/chromeos/detected_usb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/drive_internals.css b/chromium/chrome/browser/resources/chromeos/drive_internals.css
deleted file mode 100644
index b14b68fe8d5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/drive_internals.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#gcache-contents {
- font-size: small;
-}
-
-#file-system-contents {
- font-size: small;
-}
-
-#cache-contents {
- font-size: small;
-}
-
-.log-error {
- color: red;
- font-weight: bolder;
-}
-
-.log-warning {
- color: red;
-}
-
-.log-info {
-}
diff --git a/chromium/chrome/browser/resources/chromeos/drive_internals.html b/chromium/chrome/browser/resources/chromeos/drive_internals.html
deleted file mode 100644
index fe4c9f24be6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/drive_internals.html
+++ /dev/null
@@ -1,141 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>drive-internals</title>
- <meta charset="utf-8">
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" href="drive_internals.css">
- <script src="chrome://resources/js/util.js"></script>
- <script src="chrome://drive-internals/drive_internals.js"></script>
- </head>
- <body>
- <h1>Drive Internals</h1>
- <ul id="toc"></ul>
-
- <h2 id="connection-status-section">Connection Status</h2>
- <ul>
- <li>
- Status: <span id="connection-status"></span>
- </li>
- <li>
- Has refresh token: <span id="has-refresh-token"></span>
- <button id="button-clear-refresh-token">clear</button>
- </li>
- <li>
- Has access token: <span id="has-access-token"></span>
- <button id="button-clear-access-token">clear</button>
- </li>
- </ul>
-
- <h2 id="account-information-section">Account Information</h2>
- <ul>
- <li>Remote Changestamp:
- <span id="account-largest-changestamp-remote"></span>
- </li>
- <li>Quota Information: <span id="account-quota-info"></span></li>
- <li>Root Resource Id: <span id="root-resource-id"></span></li>
- </ul>
-
- <h2 id="local-metadata-section">Local Metadata</h2>
- <div>
- <button id="button-reset-drive-filesystem">
- Clear local data
- </button>
- <span id="reset-status-text"></span>
- </div>
- <ul>
- <li>Local Changestamp:
- <span id="account-largest-changestamp-local"></span>
- </li>
- <li>Local Free Space:
- <span id="local-storage-freespace"></span> MB
- </li>
- </ul>
-
- <h2 id="delta-update-status-section">Delta Update Status</h2>
- <ul>
- <li>Push notification is enabled:
- <span id="push-notification-enabled"></span></li>
- <li>Last update check time:
- <span id="last-update-check-time"></span></li>
- <li>Last update check result:
- <span id="last-update-check-error"></span></li>
- </ul>
-
- <h2 id="in-flight-operations-section">In-flight Operations</h2>
- <table>
- <tbody id="in-flight-operations-contents">
- <tr>
- <th>ID</th>
- <th>Type</th>
- <th>File Path</th>
- <th>State</th>
- <th>Progress</th>
- </tr>
- </tbody>
- </table>
-
- <h2 id="file-system-contents-section">File System Contents</h2>
- <button id="button-show-file-entries">Show</button>
- <div id="file-system-contents"></div>
-
- <h2 id="path-configurations-section">Path Configurations</h2>
- <ul id="path-configurations">
- </ul>
-
- <h2 id="gcache-contents-section">GCache Contents</h2>
- <table>
- <tbody id="gcache-contents">
- <tr>
- <th>Path</th>
- <th>Size</th>
- <th>Last Modified</th>
- <th>Permission</th>
- </tr>
- </tbody>
- </table>
-
- <ul>
- <li>
- Total Size:
- <span id="gcache-summary-total-size">(calculating...)</span> MB.
- </li>
- </ul>
-
- <h2 id="cache-contents-section">Cache Contents</h2>
- <table>
- <tbody id="cache-contents">
- <tr>
- <th>Local ID</th>
- <th>MD5</th>
- <th>Present</th>
- <th>Pinned</th>
- <th>Dirty</th>
- </tr>
- </tbody>
- </table>
-
- <h2 id="drive-related-preferences-section">Drive related Preferences</h2>
- <ul id="drive-related-preferences">
- </ul>
-
- <h2 id="app-list-section">Application List</h2>
- <ul>
- <li>ETag: <span id="app-list-etag"></span></li>
- </ul>
- <table>
- <tbody id="app-list-items">
- <tr>
- <th>App Name</th>
- <th>App ID</th>
- <th>Object Type</th>
- <th>Support Create</th>
- </tr>
- </tbody>
- </table>
-
- <h2 id="event-log-section">Event Log</h2>
- <ul id="event-log">
- </ul>
- </body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/drive_internals.js b/chromium/chrome/browser/resources/chromeos/drive_internals.js
deleted file mode 100644
index ac124cb7df6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/drive_internals.js
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Converts a number in bytes to a string in megabytes split by comma into
- * three digit block.
- * @param {number} bytes The number in bytes.
- * @return {string} Formatted string in megabytes.
- */
-function ToMegaByteString(bytes) {
- var mb = Math.floor(bytes / (1 << 20));
- return mb.toString().replace(
- /\d+?(?=(\d{3})+$)/g, // Digit sequence (\d+) followed (?=) by 3n digits.
- function(three_digit_block) { return three_digit_block + ','; }
- );
-}
-
-/**
- * Updates the Drive related Preferences section.
- * @param {Array} preferences List of dictionaries describing preferences.
- */
-function updateDriveRelatedPreferences(preferences) {
- var ul = $('drive-related-preferences');
- updateKeyValueList(ul, preferences);
-}
-
-/**
- * Updates the Connection Status section.
- * @param {Object} connStatus Dictionary containing connection status.
- */
-function updateConnectionStatus(connStatus) {
- $('connection-status').textContent = connStatus['status'];
- $('has-refresh-token').textContent = connStatus['has-refresh-token'];
- $('has-access-token').textContent = connStatus['has-access-token'];
-}
-
-/**
- * Updates the Path Configurations section.
- * @param {Array} paths List of dictionaries describing paths.
- */
-function updatePathConfigurations(paths) {
- var ul = $('path-configurations');
- updateKeyValueList(ul, paths);
-}
-
-/**
- * Updates the GCache Contents section.
- * @param {Array} gcacheContents List of dictionaries describing metadata
- * of files and directories under the GCache directory.
- * @param {Object} gcacheSummary Dictionary of summary of GCache.
- */
-function updateGCacheContents(gcacheContents, gcacheSummary) {
- var tbody = $('gcache-contents');
- for (var i = 0; i < gcacheContents.length; i++) {
- var entry = gcacheContents[i];
- var tr = document.createElement('tr');
-
- // Add some suffix based on the type.
- var path = entry.path;
- if (entry.is_directory)
- path += '/';
- else if (entry.is_symbolic_link)
- path += '@';
-
- tr.appendChild(createElementFromText('td', path));
- tr.appendChild(createElementFromText('td', entry.size));
- tr.appendChild(createElementFromText('td', entry.last_modified));
- tr.appendChild(createElementFromText('td', entry.permission));
- tbody.appendChild(tr);
- }
-
- $('gcache-summary-total-size').textContent =
- ToMegaByteString(gcacheSummary['total_size']);
-}
-
-/**
- * Updates the File System Contents section. The function is called from the
- * C++ side repeatedly with contents of a directory.
- * @param {string} directoryContentsAsText Pre-formatted string representation
- * of contents a directory in the file system.
- */
-function updateFileSystemContents(directoryContentsAsText) {
- var div = $('file-system-contents');
- div.appendChild(createElementFromText('pre', directoryContentsAsText));
-}
-
-/**
- * Updates the Cache Contents section.
- * @param {Object} cacheEntry Dictionary describing a cache entry.
- * The function is called from the C++ side repeatedly.
- */
-function updateCacheContents(cacheEntry) {
- var tr = document.createElement('tr');
- tr.appendChild(createElementFromText('td', cacheEntry.local_id));
- tr.appendChild(createElementFromText('td', cacheEntry.md5));
- tr.appendChild(createElementFromText('td', cacheEntry.is_present));
- tr.appendChild(createElementFromText('td', cacheEntry.is_pinned));
- tr.appendChild(createElementFromText('td', cacheEntry.is_dirty));
-
- $('cache-contents').appendChild(tr);
-}
-
-/**
- * Updates the Local Storage summary.
- * @param {Object} localStorageSummary Dictionary describing the status of local
- * stogage.
- */
-function updateLocalStorageUsage(localStorageSummary) {
- var freeSpaceInMB = ToMegaByteString(localStorageSummary.free_space);
- $('local-storage-freespace').innerText = freeSpaceInMB;
-}
-
-/**
- * Updates the summary about in-flight operations.
- * @param {Array} inFlightOperations List of dictionaries describing the status
- * of in-flight operations.
- */
-function updateInFlightOperations(inFlightOperations) {
- var container = $('in-flight-operations-contents');
-
- // Reset the table. Remove children in reverse order. Otherwides each
- // existingNodes[i] changes as a side effect of removeChild.
- var existingNodes = container.childNodes;
- for (var i = existingNodes.length - 1; i >= 0; i--) {
- var node = existingNodes[i];
- if (node.className == 'in-flight-operation')
- container.removeChild(node);
- }
-
- // Add in-flight operations.
- for (var i = 0; i < inFlightOperations.length; i++) {
- var operation = inFlightOperations[i];
- var tr = document.createElement('tr');
- tr.className = 'in-flight-operation';
- tr.appendChild(createElementFromText('td', operation.id));
- tr.appendChild(createElementFromText('td', operation.type));
- tr.appendChild(createElementFromText('td', operation.file_path));
- tr.appendChild(createElementFromText('td', operation.state));
- var progress = operation.progress_current + '/' + operation.progress_total;
- if (operation.progress_total > 0) {
- var percent = operation.progress_current / operation.progress_total * 100;
- progress += ' (' + Math.round(percent) + '%)';
- }
- tr.appendChild(createElementFromText('td', progress));
-
- container.appendChild(tr);
- }
-}
-
-/**
- * Updates the summary about about resource.
- * @param {Object} aboutResource Dictionary describing about resource.
- */
-function updateAboutResource(aboutResource) {
- var quotaTotalInMb = ToMegaByteString(aboutResource['account-quota-total']);
- var quotaUsedInMb = ToMegaByteString(aboutResource['account-quota-used']);
-
- $('account-quota-info').textContent =
- quotaUsedInMb + ' / ' + quotaTotalInMb + ' (MB)';
- $('account-largest-changestamp-remote').textContent =
- aboutResource['account-largest-changestamp-remote'];
- $('root-resource-id').textContent = aboutResource['root-resource-id'];
-}
-
-/**
- * Updates the summary about app list.
- * @param {Object} appList Dictionary describing app list.
- */
-function updateAppList(appList) {
- $('app-list-etag').textContent = appList['etag'];
-
- var itemContainer = $('app-list-items');
- for (var i = 0; i < appList['items'].length; i++) {
- var app = appList['items'][i];
- var tr = document.createElement('tr');
- tr.className = 'installed-app';
- tr.appendChild(createElementFromText('td', app.name));
- tr.appendChild(createElementFromText('td', app.application_id));
- tr.appendChild(createElementFromText('td', app.object_type));
- tr.appendChild(createElementFromText('td', app.supports_create));
-
- itemContainer.appendChild(tr);
- }
-}
-
-/**
- * Updates the local cache information about account metadata.
- * @param {Object} localMetadata Dictionary describing account metadata.
- */
-function updateLocalMetadata(localMetadata) {
- var changestamp = localMetadata['account-largest-changestamp-local'];
-
- $('account-largest-changestamp-local').textContent =
- changestamp.toString() +
- (changestamp > 0 ? ' (loaded)' : ' (not loaded)') +
- (localMetadata['account-metadata-refreshing'] ? ' (refreshing)' : '');
-}
-
-/**
- * Updates the summary about delta update status.
- * @param {Object} deltaUpdateStatus Dictionary describing delta update status.
- */
-function updateDeltaUpdateStatus(deltaUpdateStatus) {
- $('push-notification-enabled').textContent =
- deltaUpdateStatus['push-notification-enabled'];
- $('last-update-check-time').textContent =
- deltaUpdateStatus['last-update-check-time'];
- $('last-update-check-error').textContent =
- deltaUpdateStatus['last-update-check-error'];
-}
-
-/**
- * Updates the event log section.
- * @param {Array} log Array of events.
- */
-function updateEventLog(log) {
- var ul = $('event-log');
- updateKeyValueList(ul, log);
-}
-
-/**
- * Creates an element named |elementName| containing the content |text|.
- * @param {string} elementName Name of the new element to be created.
- * @param {string} text Text to be contained in the new element.
- * @return {HTMLElement} The newly created HTML element.
- */
-function createElementFromText(elementName, text) {
- var element = document.createElement(elementName);
- element.appendChild(document.createTextNode(text));
- return element;
-}
-
-/**
- * Updates <ul> element with the given key-value list.
- * @param {HTMLElement} ul <ul> element to be modified.
- * @param {Array} list List of dictionaries containing 'key', 'value' (optional)
- * and 'class' (optional). For each element <li> element with specified class is
- * created.
- */
-function updateKeyValueList(ul, list) {
- for (var i = 0; i < list.length; i++) {
- var item = list[i];
- var text = item.key;
- if (item.value != '')
- text += ': ' + item.value;
-
- var li = createElementFromText('li', text);
- if (item.class)
- li.classList.add(item.class);
- ul.appendChild(li);
- }
-}
-
-/**
- * Updates the text next to the 'reset' button to update the status.
- * @param {boolean} success whether or not resetting has succeeded.
- */
-function updateResetStatus(success) {
- $('reset-status-text').textContent = (success ? 'success' : 'failed');
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- chrome.send('pageLoaded');
-
- // Update the table of contents.
- var toc = $('toc');
- var sections = document.getElementsByTagName('h2');
- for (var i = 0; i < sections.length; i++) {
- var section = sections[i];
- var a = createElementFromText('a', section.textContent);
- a.href = '#' + section.id;
- var li = document.createElement('li');
- li.appendChild(a);
- toc.appendChild(li);
- }
-
- $('button-clear-access-token').addEventListener('click', function() {
- chrome.send('clearAccessToken');
- });
-
- $('button-clear-refresh-token').addEventListener('click', function() {
- chrome.send('clearRefreshToken');
- });
-
- $('button-reset-drive-filesystem').addEventListener('click', function() {
- $('reset-status-text').textContent = 'resetting...';
- chrome.send('resetDriveFileSystem');
- });
-
- $('button-show-file-entries').addEventListener('click', function() {
- var button = $('button-show-file-entries');
- button.parentNode.removeChild(button);
- chrome.send('listFileEntries');
- });
-
- window.setInterval(function() {
- chrome.send('periodicUpdate');
- }, 1000);
-});
diff --git a/chromium/chrome/browser/resources/chromeos/echo/OWNERS b/chromium/chrome/browser/resources/chromeos/echo/OWNERS
deleted file mode 100644
index c197453f458..00000000000
--- a/chromium/chrome/browser/resources/chromeos/echo/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-gauravsh@chromium.org
-jorgelo@chromium.org
-stephenlin@chromium.org
-andycai@chromium.org
-oscarpan@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.css b/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.css
deleted file mode 100644
index 260a191ed53..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.css
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. */
-
-paper-input {
- -webkit-margin-end: 15px;
- display: inline-block;
- width: 200px;
-}
-
-#editModal paper-checkbox {
- -webkit-margin-start: 15px;
-}
-
-paper-dialog {
- height: 90%;
- overflow-y: scroll;
- width: 40%;
-}
-
-.element-label {
- -webkit-padding-start: 0;
- color: rgb(82, 101, 162);
- display: block;
- font-size: 24px;
- font-weight: normal;
- height: 80px;
- letter-spacing: 0.05em;
- line-height: 80px;
-}
-
-.form-label {
- display: block;
-}
-
-.form-field-section {
- margin-top: 30px;
-}
-
-.form-field-section:first-of-type {
- margin-top: 0;
-}
-
-.icon-cell {
- text-align: center;
- width: 45%;
-}
-
-.icon-cell paper-icon-button {
- color: rgb(82, 101, 162);
-}
-
-.devices-table {
- border-collapse: collapse;
- padding: 20px 0;
-}
-
-.devices-table paper-icon-button[disabled] {
- color: rgb(150, 194, 244);
-}
-
-.devices-table.custom {
- margin-top: 40px;
-}
-
-.devices-table .icon-cell {
- width: 45%;
-}
-
-.devices-table .center-cell-label {
- text-align: center;
-}
-
-.devices-table .control-cell {
- text-align: center;
-}
-
-.devices-table paper-checkbox {
- --paper-checkbox-checked-color: rgb(82, 101, 162);
-}
-
-.devices-table td {
- padding: 10px;
-}
-
-.bold {
- font-weight: bold;
-}
-
-.devices-table tr.table-section-header {
- font-weight: bold;
-}
-
-.devices-table tbody:first-of-type::before {
- height: 0;
-}
-
-.devices-table tbody:last-of-type::before {
- content: '';
- display: block;
- height: 30px;
-}
-
-.devices-table tbody tr {
- border-bottom: 1px solid #dadada;
-}
-
-.devices-table tbody tr:last-of-type {
- border-bottom: 0;
-}
-
-.add-device-container {
- margin: 15px;
- text-align: right;
-}
-
-.add-device-container paper-button {
- color: rgb(82, 101, 162);
- width: 200px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.html b/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.html
deleted file mode 100644
index 2940b83ecb3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/av-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-
-<dom-module id="audio-settings">
- <link rel="import" type="css" href="audio_settings.css">
- <template>
- <paper-dialog on-iron-overlay-opened="editDialogOpened" modal
- id="editModal">
- <div class="element-label">[[currentEditableObject.deviceName]]</div>
- <div>
- <form>
- <div class="form-field-section">
- <paper-input value="{{currentEditableObject.deviceName}}"
- label="Device Name"></paper-input>
- <paper-input value="{{currentEditableObject.name}}"
- label="Tray Name"></paper-input>
- <paper-input value="{{currentEditableObject.id}}"
- label="ID" disabled></paper-input>
- </div>
- <div class="form-field-section">
- <span class="toggle-button-label">Is Input</span>
- <paper-checkbox
- checked="{{currentEditableObject.isInput}}"></paper-checkbox>
- </div>
- <div class="form-field-section">
- <span class="toggle-button-label">Active</span>
- <paper-checkbox
- checked="{{currentEditableObject.active}}"></paper-checkbox>
- </div>
- <div class="form-field-section">
- <div class="form-label">Audio Type</div>
- <paper-radio-group class="device-class-group"
- selected="{{currentEditableObject.type}}">
- <template is="dom-repeat"
- items="[[nodeTypeOptions]]" as="option">
- <paper-radio-button name="[[option.type]]"
- >[[option.name]]</paper-radio-button>
- </template>
- </paper-radio-group>
- </div>
- </form>
- </div>
- <div class="buttons">
- <paper-button on-click="insertEditedAudioNode"
- dialog-dismiss>Done</paper-button>
- </div>
- </paper-dialog>
-
- <div class="layout vertical">
- <div class="element-label">
- <paper-icon-button icon="av:volume-up"></paper-icon-button>
- <span>[[title]]</span>
- </div>
- <table class="devices-table">
- <tbody>
- <tr class="table-section-header">
- <td colspan="2">Devices</td>
- <td class="centered-cell-label">Is Input</td>
- <td class="centered-cell-label">Active</td>
- </tr>
- <template is="dom-repeat" items="[[nodes]]">
- <tr>
- <td class="alias-cell">[[item.deviceName]]</td>
- <td class="icon-cell">
- <paper-icon-button icon="content-copy" data-predefined="false"
- on-click="copyDevice"></paper-icon-button>
- <paper-icon-button icon="settings" on-click="showEditModal"
- ></paper-icon-button>
- <paper-icon-button icon="delete" on-click="removeAudioNode"
- ></paper-icon-button>
- </td>
- <td class="control-cell">
- <paper-checkbox checked="{{item.isInput}}"
- on-change="insertAudioNode"></paper-checkbox>
- </td>
- <td class="control-cell">
- <paper-checkbox checked="{{item.active}}"
- on-change="insertAudioNode"></paper-checkbox>
- </td>
- </tr>
- </template>
- </tbody>
- </table>
- <div class="add-device-container">
- <paper-button on-click="appendNewNode">
- Add Node
- </paper-button>
- </div>
- </div>
- </template>
- <script src="audio_settings.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.js b/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.js
deleted file mode 100644
index 739c21c6689..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/audio_settings.js
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/** @enum {string} */ var AudioNodeType = {
- HEADPHONE: 'HEADPHONE',
- MIC: 'MIC',
- USB: 'USB',
- BLUETOOTH: 'BLUETOOTH',
- HDMI: 'HDMI',
- INTERNAL_SPEAKER: 'INTERNAL_SPEAKER',
- INTERNAL_MIC: 'INTERNAL_MIC',
- KEYBOARD_MIC: 'KEYBOARD_MIC',
- AOKR: 'AOKR',
- POST_MIX_LOOPBACK: 'POST_MIX_LOOPBACK',
- POST_DSP_LOOPBACK: 'POST_DSP_LOOPBACK',
- OTHER: 'OTHER',
-};
-
-/**
- * An audio node. Based on the struct AudioNode found in audio_node.h.
- * @constructor
- */
-var AudioNode = function() {
- // Whether node will input or output audio.
- this.isInput = false;
-
- // Node ID. Set to 3000 because predefined output and input
- // nodes use 10000's and 20000's respectively and |nodeCount| will append it.
- this.id = '3000';
-
- // Display name of the node. When this is empty, cras will automatically
- // use |this.deviceName| as the display name.
- this.name = '';
-
- // The text label of the selected node name.
- this.deviceName = 'New Device';
-
- // Based on the AudioNodeType enum.
- this.type = AudioNodeType.OTHER;
-
- // Whether the node is active or not.
- this.active = false;
-
- // The time the node was plugged in (in seconds).
- this.pluggedTime = 0;
-};
-
-Polymer({
- is: 'audio-settings',
-
- properties: {
- /**
- * An AudioNode which is currently being edited.
- * @type {AudioNode}
- */
- currentEditableObject: {
- type: Object,
- value: function() { return {}; }
- },
-
- /**
- * The index of the audio node which is currently being edited.
- * This is initially set to -1 (i.e. no node selected) becuase no devices
- * have been copied.
- */
- currentEditIndex: {type: Number, value: function() { return -1; }},
-
- /**
- * A counter that will auto increment everytime a new node is added
- * or copied and used to set a new id. This allows the |AudioNode.id|
- * to allows be unique.
- */
- nodeCount: {type: Number, value: function() { return 0; }},
-
- /**
- * A set of audio nodes.
- * @type !Array<!AudioNode>
- */
- nodes: {type: Array, value: function() { return []; }},
-
- /**
- * A set of options for the possible audio node types.
- * AudioNodeType |type| is based on the AudioType emumation.
- * @type {!Array<!{name: string, type: string}>}
- */
- nodeTypeOptions: {
- type: Array,
- value: function() {
- return [
- {name: 'Headphones', type: AudioNodeType.HEADPHONE},
- {name: 'Mic', type: AudioNodeType.MIC},
- {name: 'Usb', type: AudioNodeType.USB},
- {name: 'Bluetooth', type: AudioNodeType.BLUETOOTH},
- {name: 'HDMI', type: AudioNodeType.HDMI},
- {name: 'Internal Speaker', type: AudioNodeType.INTERNAL_SPEAKER},
- {name: 'Internal Mic', type: AudioNodeType.INTERNAL_MIC},
- {name: 'Keyboard Mic', type: AudioNodeType.KEYBOARD_MIC},
- {name: 'Aokr', type: AudioNodeType.AOKR},
- {name: 'Post Mix Loopback', type: AudioNodeType.POST_MIX_LOOPBACK},
- {name: 'Post Dsp Loopback', type: AudioNodeType.POST_DSP_LOOPBACK},
- {name: 'Other', type: AudioNodeType.OTHER}
- ];
- }
- },
-
- /**
- * The title to be displayed in a heading element for the element.
- */
- title: {type: String},
- },
-
- ready: function() {
- this.title = 'Audio';
- },
-
- initialize: function() {
- if (!this.initialized) {
- chrome.send('requestAudioNodes');
- this.initialized = true;
- }
- },
-
- /**
- * Adds a new node with default settings to the list of nodes.
- */
- appendNewNode: function() {
- var newNode = new AudioNode();
- newNode.id += this.nodeCount;
- this.nodeCount++;
- this.push('nodes', newNode);
- },
-
- /**
- * This adds or modifies an audio node to the AudioNodeList.
- * @param {model: {index: number}} e Event with a model containing
- * the index in |nodes| to add.
- */
- insertAudioNode: function(e) {
- // Create a new audio node and add all the properties from |nodes[i]|.
- var info = this.nodes[e.model.index];
- chrome.send('insertAudioNode', [info]);
- },
-
- /**
- * This adds/modifies the audio node |nodes[currentEditIndex]| to/from the
- * AudioNodeList.
- * @param {model: {index: number}} e Event with a model containing
- * the index in |nodes| to add.
- */
- insertEditedAudioNode: function(e) {
- // Insert a new node or update an existing node using all the properties
- // in |node|.
- var node = this.nodes[this.currentEditIndex];
- chrome.send('insertAudioNode', [node]);
- },
-
- /**
- * Removes the audio node with id |id|.
- * @param {model: {index: number}} e Event with a model containing
- * the index in |nodes| to add.
- */
- removeAudioNode: function(e) {
- var info = this.nodes[e.model.index];
- chrome.send('removeAudioNode', [info.id]);
- },
-
- /**
- * Called on "copy" button from the device list clicked. Creates a copy of
- * the selected node.
- * @param {Event} event Contains event data. |event.model.index| is the index
- * of the item which the target is contained in.
- */
- copyDevice: function(event) {
- // Create a shallow copy of the selected device.
- var newNode = new AudioNode();
- Object.assign(newNode, this.nodes[event.model.index]);
- newNode.name += ' (Copy)';
- newNode.deviceName += ' (Copy)';
- newNode.id += this.nodeCount;
- this.nodeCount++;
-
- this.push('nodes', newNode);
- },
-
- /**
- * Shows a modal dialog to edit the selected node's properties.
- * @param {Event} event Contains event data. |event.model.index| is the index
- * of the item which the target is contained in.
- */
- showEditModal: function(event) {
- var index = event.model.index;
- this.currentEditIndex = index;
- this.currentEditableObject = this.nodes[index];
- this.$.editModal.toggle();
- },
-
- /**
- * Called by the WebUI which provides a list of nodes.
- * @param {!Array<!AudioNode>} nodeList A list of audio nodes.
- */
- updateAudioNodes: function(nodeList) {
- /** @type {!Array<!AudioNode>} */ var newNodeList = [];
- for (var i = 0; i < nodeList.length; ++i) {
- // Create a new audio node and add all the properties from |nodeList[i]|.
- var node = new AudioNode();
- Object.assign(node, nodeList[i]);
- newNodeList.push(node);
- }
- this.nodes = newNodeList;
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.css b/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.css
deleted file mode 100644
index 8b90fe8d7d2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. */
-
-paper-input {
- -webkit-margin-start: 15px;
- display: inline-block;
- width: 200px;
-}
-
-paper-toggle-button {
- -webkit-margin-start: 15px;
-}
-
-paper-slider {
- -webkit-margin-start: 15px;
-}
-
-paper-radio-button {
- display: inline-block;
-}
-
-.element-label {
- -webkit-padding-start: 0;
- color: rgb(82, 101, 162);
- font-size: 24px;
- font-weight: normal;
- height: 80px;
- letter-spacing: 0.05em;
- line-height: 80px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.html b/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.html
deleted file mode 100644
index 41e29e5e4cd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-slider/paper-slider.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html">
-
-<dom-module id="battery-settings">
- <link rel="import" type="css" href="battery_settings.css">
- <template>
- <div class="layout vertical">
- <div class="element-label">
- <paper-icon-button icon="device:battery-charging-full">
- </paper-icon-button>
- <span>{{title}}</span>
- </div>
- <form id="power-settings-form">
- <div>
- <p>
- <label>
- <span class="form-label">Battery Percentage</span>
- <paper-input value="{{batteryPercent}}"
- id="battery-percent-text" type="number">
- </paper-input>
- </label>
- </p>
- </div>
-
- <div>
- <p>
- <label>
- <span class="form-label">Battery State</span>
- <paper-radio-group selected="{{batteryState}}"
- id="battery-state-radio-group">
- <template is="dom-repeat" items="{{batteryStateOptions}}">
- <paper-radio-button
- name="{{item}}">{{item}}</paper-radio-button>
- </template>
- </paper-radio-group>
- </label>
- </p>
- </div>
-
- <div>
- <p>
- <label>
- <span class="form-label">External Power</span>
- <paper-radio-group selected="{{externalPower}}"
- id="external-power-radio-group">
- <template is="dom-repeat" items="{{externalPowerOptions}}">
- <paper-radio-button
- name="{{item}}">{{item}}</paper-radio-button>
- </template>
- </paper-radio-group>
- </label>
- </p>
- </div>
-
- <div>
- <p>
- <label>
- <span class="form-label">Time Until Battery Empty</span>
- <paper-input value="{{timeUntilEmpty}}"
- id="time-until-empty-text">
- </paper-input>
- </label>
- </p>
-
- <p>
- <label>
- <span class="form-label">Time Until Battery Full</span>
- <paper-input value="{{timeUntilFull}}" id="time-until-full-text">
- </paper-input>
- </label>
- </p>
- </div>
-
- </form>
- </div>
- </template>
- <script src="battery_settings.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.js b/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.js
deleted file mode 100644
index 9696161813c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/battery_settings.js
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var BatterySettings = Polymer({
- is: 'battery-settings',
-
- properties: {
- /**
- * The system's battery percentage.
- */
- batteryPercent: {
- type: Number,
- observer: 'batteryPercentChanged',
- },
-
- /**
- * A string representing a value in the
- * PowerSupplyProperties_BatteryState enumeration.
- */
- batteryState: {
- type: String,
- observer: 'batteryStateChanged',
- },
-
- /**
- * An array representing the battery state options.
- * The names are ordered based on the
- * PowerSupplyProperties_BatteryState enumeration. These values must be
- * in sync.
- */
- batteryStateOptions: {
- type: Array,
- value: function() { return ['Full', 'Charging', 'Disharging',
- 'Not Present']; },
- },
-
- /**
- * A string representing a value in the
- * PowerSupplyProperties_ExternalPower enumeration.
- */
- externalPower: {
- type: String,
- observer: 'externalPowerChanged',
- },
-
- /**
- * An array representing the external power options.
- * The names are ordered based on the
- * PowerSupplyProperties_ExternalPower enumeration. These values must be
- * in sync.
- */
- externalPowerOptions: {
- type: Array,
- value: function() { return ['AC', 'USB (Low Power)', 'Disconnected']; }
- },
-
- /**
- * A string representing the time left until the battery is discharged.
- */
- timeUntilEmpty: {
- type: String,
- observer: 'timeUntilEmptyChanged',
- },
-
- /**
- * A string representing the time left until the battery is at 100%.
- */
- timeUntilFull: {
- type: String,
- observer: 'timeUntilFullChanged',
- },
-
- /**
- * The title for the settings section.
- */
- title: {
- type: String,
- },
- },
-
- ready: function() {
- this.title = 'Power';
- },
-
- initialize: function() {
- if (!this.initialized) {
- chrome.send('requestPowerInfo');
- this.initialized = true;
- }
- },
-
- batteryPercentChanged: function(percent, oldPercent) {
- if (oldPercent != undefined)
- chrome.send('updateBatteryPercent', [parseInt(percent)]);
- },
-
- batteryStateChanged: function(state) {
- // Find the index of the selected battery state.
- var index = this.batteryStateOptions.indexOf(state);
- if (index >= 0)
- chrome.send('updateBatteryState', [index]);
- },
-
- externalPowerChanged: function(source) {
- // Find the index of the selected power source.
- var index = this.externalPowerOptions.indexOf(source);
- if (index >= 0)
- chrome.send('updateExternalPower', [index]);
- },
-
- timeUntilEmptyChanged: function(time, oldTime) {
- if (oldTime != undefined)
- chrome.send('updateTimeToEmpty', [parseInt(time)]);
- },
-
- timeUntilFullChanged: function(time, oldTime) {
- if (oldTime != undefined)
- chrome.send('updateTimeToFull', [parseInt(time)]);
- },
-
- updatePowerProperties: function(power_properties) {
- this.batteryPercent = power_properties.battery_percent;
- this.batteryState =
- this.batteryStateOptions[power_properties.battery_state];
- this.externalPower =
- this.externalPowerOptions[power_properties.external_power];
- this.timeUntilEmpty = power_properties.battery_time_to_empty_sec;
- this.timeUntilFull = power_properties.battery_time_to_full_sec;
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.css b/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.css
deleted file mode 100644
index a0fbd736d4c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.css
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. */
-
-paper-input {
- -webkit-margin-end: 15px;
- display: inline-block;
- width: 200px;
-}
-
-#editModal paper-checkbox {
- -webkit-margin-start: 15px;
-}
-
-paper-dialog {
- height: 90%;
- overflow-y: scroll;
- width: 40%;
-}
-
-.element-label {
- -webkit-padding-start: 0;
- color: rgb(82, 101, 162);
- display: block;
- font-size: 24px;
- font-weight: normal;
- height: 80px;
- letter-spacing: 0.05em;
- line-height: 80px;
-}
-
-.form-label {
- display: block;
-}
-
-.form-field-section {
- margin-top: 30px;
-}
-
-.form-field-section:first-of-type {
- margin-top: 0;
-}
-
-.icon-cell {
- text-align: center;
- width: 45%;
-}
-
-.icon-cell paper-icon-button {
- color: rgb(82, 101, 162);
-}
-
-.devices-table {
- border-collapse: collapse;
- padding: 20px 0;
-}
-
-.devices-table paper-icon-button[disabled] {
- color: rgb(150, 194, 244);
-}
-
-.devices-table.custom {
- margin-top: 40px;
-}
-
-.devices-table .icon-cell {
- width: 45%;
-}
-
-.devices-table .center-cell-label {
- text-align: center;
-}
-
-.devices-table .control-cell {
- text-align: center;
-}
-
-.devices-table paper-checkbox {
- --paper-checkbox-unchecked-color: rgb(82, 101, 162);
-}
-
-.devices-table td {
- padding: 10px;
-}
-
-.bold {
- font-weight: bold;
-}
-
-.devices-table tr.table-section-header {
- font-weight: bold;
-}
-
-.devices-table tbody:first-of-type::before {
- height: 0;
-}
-
-.devices-table tbody:last-of-type::before {
- content: '';
- display: block;
- height: 30px;
-}
-
-.devices-table tbody tr {
- border-bottom: 1px solid #dadada;
-}
-
-.devices-table tbody tr:last-of-type {
- border-bottom: 0;
-}
-
-.add-device-container {
- margin: 15px;
- text-align: right;
-}
-
-.add-device-container paper-button {
- color: rgb(82, 101, 162);
- width: 200px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html b/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html
deleted file mode 100644
index 7d4964cc2dd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.html
+++ /dev/null
@@ -1,165 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-
-<dom-module id="bluetooth-settings">
- <link rel="import" type="css" href="bluetooth_settings.css">
- <template>
- <paper-dialog on-iron-overlay-opened="editDialogOpened" modal
- id="editModal">
- <div class="element-label">[[currentEditableObject.alias]]</div>
- <div>
- <form>
- <div class="form-field-section">
- <paper-input value="{{currentEditableObject.alias}}"
- label="Alias"></paper-input>
- <paper-input on-input="validatePath"
- id="devicePathInput"
- value="{{currentEditableObject.path}}"
- label="Path" on-input="validatePath"></paper-input>
- <paper-input value="{{currentEditableObject.name}}"
- label="Name"></paper-input>
- <paper-input id="deviceAddressInput" on-input="handleAddressInput"
- value="{{currentEditableObject.address}}"
- label="Address (xx:xx:xx:xx:xx:xx)"
- maxlength="17"></paper-input>
- </div>
- <div class="form-field-section">
- <span class="toggle-button-label">Trusted</span>
- <paper-checkbox
- checked="{{currentEditableObject.isTrusted}}"></paper-checkbox>
- </div>
- <div class="form-field-section">
- <span class="toggle-button-label">Incoming Connnection</span>
- <paper-checkbox
- checked="{{currentEditableObject.incoming}}"></paper-checkbox>
- </div>
- <div class="form-field-section">
- <div class="form-label">Class</div>
- <paper-radio-group class="device-class-group"
- selected="{{currentEditableObject.class}}">
- <template is="dom-repeat"
- items="[[deviceClassOptions]]" as="option">
- <paper-radio-button name="[[option.text]]"
- >[[option.text]]</paper-radio-button>
- </template>
- </paper-radio-group>
- </div>
- <div class="form-field-section">
- <label>
- <span class="form-label">Pair Authentication</span>
- <paper-radio-group
- selected="{{currentEditableObject.pairingMethod}}">
- <template is="dom-repeat"
- items="[[deviceAuthenticationMethods]]" as="method">
- <paper-radio-button name="[[method]]"
- >[[method]]</paper-radio-button>
- </template>
- </paper-radio-group>
- </label>
- </div>
- <div>
- <div class="form-field-section"
- hidden$=
- "[[!showAuthToken(currentEditableObject.pairingMethod)]]"
- >
- <paper-input value="{{currentEditableObject.pairingAuthToken}}"
- label="Code"></paper-input>
- </div>
- <div class="form-field-section">
- <label>
- <span class="form-label">Pairing Action</span>
- <paper-radio-group
- selected="{{currentEditableObject.pairingAction}}">
- <template is="dom-repeat"
- items="[[deviceAuthenticationActions]]">
- <paper-radio-button name="[[item]]"
- >[[item]]</paper-radio-button>
- </template>
- </paper-radio-group>
- </label>
- </div>
- </div>
- </form>
- </div>
- <div class="buttons">
- <paper-button dialog-dismiss>Close</paper-button>
- </div>
- </paper-dialog>
-
- <div class="layout vertical">
- <div class="element-label">
- <paper-icon-button icon="device:bluetooth"></paper-icon-button>
- <span>[[title]]</span>
- </div>
- <table class="devices-table">
- <tbody>
- <tr class="table-section-header">
- <td colspan="2">Presets</td>
- <td class="centered-cell-label">Discoverable</td>
- <td class="centered-cell-label">Paired</td>
- </tr>
- <template is="dom-repeat" items="[[predefinedDevices]]">
- <tr>
- <td class="alias-cell">[[item.alias]]</td>
- <td class="icon-cell">
- <paper-icon-button icon="content-copy"
- on-click="copyDevice" data-predefined="true">
- </paper-icon-button>
- <paper-icon-button disabled icon="settings"></paper-icon-button>
- <paper-icon-button disabled icon="delete"></paper-icon-button>
- </td>
- <td class="control-cell">
- <paper-checkbox checked="{{item.discoverable}}"
- data-predefined="true"
- on-change="discoverDevice"></paper-checkbox>
- </td>
- <td class="control-cell">
- <paper-checkbox on-change="pairDevice" data-predefined="true"
- checked="{{item.paired}}"></paper-checkbox>
- </td>
- </tr>
- </template>
- </tbody>
- <tbody>
- <tr class="table-section-header">
- <td colspan="4">Custom</td>
- </tr>
- <template is="dom-repeat" items="[[devices]]">
- <tr>
- <td class="alias-cell">[[item.alias]]</td>
- <td class="icon-cell">
- <paper-icon-button icon="content-copy" data-predefined="false"
- on-click="copyDevice"></paper-icon-button>
- <paper-icon-button icon="settings" on-click="showEditModal"
- ></paper-icon-button>
- <paper-icon-button icon="delete" on-click="deleteDevice"
- ></paper-icon-button>
- </td>
- <td class="control-cell">
- <paper-checkbox checked="{{item.discoverable}}"
- data-predefined="false"
- on-change="discoverDevice"></paper-checkbox>
- </td>
- <td class="control-cell">
- <paper-checkbox checked="{{item.paired}}"
- data-predefined="false"
- on-change="pairDevice"></paper-checkbox>
- </td>
- </tr>
- </template>
- </tbody>
- </table>
- <div class="add-device-container">
- <paper-button on-click="appendNewDevice">
- Add Device
- </paper-button>
- </div>
- </div>
- </template>
- <script src="bluetooth_settings.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js b/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js
deleted file mode 100644
index 377f73d7b9d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * A bluetooth device.
- * @constructor
- */
-var BluetoothDevice = function() {
- // The device's address (MAC format, must be unique).
- this.address = '';
-
- // The label which shows up in the devices list for this device.
- this.alias = '';
-
- // The text label of the selected device class.
- this.class = 'Computer';
-
- // The uint32 value of the selected device class.
- this.classValue = 0x104;
-
- // Whether or not the device shows up in the system tray's observed list of
- // bluetooth devices.
- this.discoverable = false;
-
- // Whether Chrome OS pairs with this device, or this device tries to pair
- // with Chrome OS.
- this.incoming = false;
-
- // A trusted device is one which is plugged directly Chrome OS and therefore
- // is paired by default, but not connected.
- this.isTrusted = false;
-
- // The device's name.This is not the label which shows up in the devices list
- // here or in the system tray--use |.alias| to edit that label.
- this.name = '';
-
- // The designated path for the device. Must be unique.
- this.path = '';
-
- // Whether or not the device is paired with Chrome OS.
- this.paired = false;
-
- // The label of the selected pairing method option.
- this.pairingMethod = 'None';
-
- // The text containing a PIN key or passkey for pairing.
- this.pairingAuthToken = '';
-
- // The label of the selected pairing action option.
- this.pairingAction = '';
-};
-
-Polymer({
- is: 'bluetooth-settings',
-
- properties: {
- /**
- * The title to be displayed in a heading element for the element.
- */
- title: {type: String},
-
- /**
- * A set of bluetooth devices.
- * @type !Array<!BluetoothDevice>
- */
- devices: {type: Array, value: function() { return []; }},
-
- /**
- * A set of predefined bluetooth devices.
- * @type !Array<!Bluetooth>
- */
- predefinedDevices: {type: Array, value: function() { return []; }},
-
- /**
- * A bluetooth device object which is currently being edited.
- * @type {BluetoothDevice}
- */
- currentEditableObject: {
- type: Object,
- value: function() { return {}; }
- },
-
- /**
- * The index of the bluetooth device object which is currently being edited.
- * This is initially set to -1 (i.e. no device selected) because not custom
- * devices exist when the page loads.
- */
- currentEditIndex: {type: Number, value: function() { return -1; }},
-
- /**
- * A set of options for the possible bluetooth device classes/types.
- * Object |value| attribute comes from values in the WebUI, set in
- * setDeviceClassOptions.
- * @type !Array<! {text: string, value: int} >
- */
- deviceClassOptions: {
- type: Array,
- value: function() {
- return [
- {text: 'Unknown', value: 0},
- {text: 'Mouse', value: 0x2580},
- {text: 'Keyboard', value: 0x2540},
- {text: 'Audio', value: 0x240408},
- {text: 'Phone', value: 0x7a020c},
- {text: 'Computer', value: 0x104}
- ];
- }
- },
-
- /**
- * A set of strings representing the method to be used for
- * authenticating a device during a pair request.
- * @type !Array<string>
- */
- deviceAuthenticationMethods: {
- type: Array,
- value: function() { return []; }
- },
-
- /**
- * A set of strings representing the actions which can be done when
- * a secure device is paired/requests a pair.
- * @type !Array<string>
- */
- deviceAuthenticationActions: {
- type: Array,
- value: function() { return []; }
- },
- },
-
- /**
- * Contains keys for all the device paths which have been discovered. Used
- * to look up whether or not a device is listed already.
- * @type {Object}
- */
- devicePaths: {},
-
- ready: function() { this.title = 'Bluetooth'; },
-
- initialize: function() {
- if (!this.initialized) {
- this.initialized = true;
- chrome.send('requestBluetoothInfo');
- }
- },
-
- observers: ['currentEditableObjectChanged(currentEditableObject.*)'],
-
- /**
- * Called when a property of the currently editable object is edited.
- * Sets the corresponding property for the object in |this.devices|.
- * @param {Object} obj An object containing event information (ex. which
- * property of |this.currentEditableObject| was changed, what its value
- * is, etc.)
- */
- currentEditableObjectChanged: function(obj) {
- if (this.currentEditIndex >= 0) {
- var prop = obj.path.split('.')[1];
- this.set('devices.' + this.currentEditIndex.toString() + '.' + prop,
- obj.value);
- }
- },
-
- /**
- * Called when the device edit modal is opened. Re-validates necessary input
- * fields.
- */
- editDialogOpened: function() {
- this.validateAddress();
- this.validatePath();
- },
-
- handleAddressInput: function() {
- this.autoFormatAddress();
- this.validateAddress();
- },
-
- autoFormatAddress: function() {
- var input = this.$.deviceAddressInput;
- var regex = /([a-f0-9]{2})([a-f0-9]{2})/i;
- // Remove things that aren't hex characters from the string.
- var val = input.value.replace(/[^a-f0-9]/ig, '');
-
- // Insert a ':' in the middle of every four hex characters.
- while (regex.test(val))
- val = val.replace(regex, '$1:$2');
-
- input.value = val;
- },
-
- /**
- * Called on-input from an input element and on edit modal open.
- * Validates whether or not the
- * input's content matches a regular expression. If the input's value
- * satisfies the regex, then make sure that the address is not already
- * in use.
- */
- validateAddress: function() {
- var input = this.$.deviceAddressInput;
- var val = input.value;
- var exists = false;
- var addressRegex = RegExp('^([\\da-fA-F]{2}:){5}[\\da-fA-F]{2}$');
- if (addressRegex.test(val)) {
- for (var i = 0; i < this.predefinedDevices.length; ++i) {
- if (this.predefinedDevices[i].address == val) {
- exists = true;
- break;
- }
- }
-
- if (!exists) {
- for (var i = 0; i < this.devices.length; ++i) {
- if (this.devices[i].address == val && i != this.currentEditIndex) {
- exists = true;
- break;
- }
- }
- }
-
- if (exists) {
- input.invalid = true;
- input.errorMessage = 'This address is already being used.';
- } else {
- input.invalid = false;
- }
- } else {
- input.invalid = true;
- input.errorMessage = 'Invalid address.';
- }
- },
-
- /**
- * Makes sure that a path is not already used.
- */
- validatePath: function() {
- var input = this.$.devicePathInput;
- var val = input.value;
- var exists = false;
-
- for (var i = 0; i < this.predefinedDevices.length; ++i) {
- if (this.predefinedDevices[i].path == val) {
- exists = true;
- break;
- }
- }
-
- if (!exists) {
- for (var i = 0; i < this.devices.length; ++i) {
- if (this.devices[i].path == val && i != this.currentEditIndex) {
- exists = true;
- break;
- }
- }
- }
-
- if (exists) {
- input.invalid = true;
- input.errorMessage = 'This path is already being used.';
- } else {
- input.invalid = false;
- }
- },
-
- /**
- * Checks whether or not the PIN/passkey input field should be shown.
- * It should only be shown when the pair method is not 'None' or empty.
- * @param {string} pairMethod The label of the selected pair method option
- * for a particular device.
- * @return {boolean} Whether the PIN/passkey input field should be shown.
- */
- showAuthToken: function(pairMethod) {
- return pairMethod && pairMethod != 'None';
- },
-
- /**
- * Called by the WebUI which provides a list of devices which are connected
- * to the main adapter.
- * @param {!Array<!BluetoothDevice>} devices A list of bluetooth devices.
- */
- updateBluetoothInfo: function(predefinedDevices, loadedCustomDevices,
- pairingMethodOptions, pairingActionOptions) {
- this.predefinedDevices = this.loadDevicesFromList(predefinedDevices, true);
- this.devices = this.loadDevicesFromList(loadedCustomDevices, false);
- this.deviceAuthenticationMethods = pairingMethodOptions;
- this.deviceAuthenticationActions = pairingActionOptions;
- },
-
- /**
- * Builds complete BluetoothDevice objects for each element in |devices_list|.
- * @param {!Array<!BluetoothDevice>} devices_list A list of incomplete
- * BluetoothDevice provided by the C++ WebUI.
- * @param {boolean} predefined Whether or not the device is a predefined one.
- */
- loadDevicesFromList: function(devices, predefined) {
- /** @type {!Array<!BluetoothDevice>} */ var deviceList = [];
-
- for (var i = 0; i < devices.length; ++i) {
- if (this.devicePaths[devices[i].path] != undefined) continue;
-
- // Get the label for the device class which should be selected.
- devices[i].class = this.getTextForDeviceClass(devices[i].classValue);
- devices[i].pairingAuthToken = devices[i].pairingAuthToken.toString();
- deviceList.push(devices[i]);
- this.devicePaths[devices[i].path] = {
- predefined: predefined,
- index: deviceList.length - 1
- };
- }
-
- return deviceList;
- },
-
- /**
- * Called when a device is paired from the Tray. Checks the paired box for
- * the device with path |path|.
- */
- devicePairedFromTray: function(path) {
- var obj = this.devicePaths[path];
-
- if (obj == undefined) return;
-
- var index = obj.index;
- var devicePath = (obj.predefined ? 'predefinedDevices.' : 'devices.');
- devicePath += obj.index.toString();
- this.set(devicePath + '.paired', true);
- },
-
- /**
- * On-change handler for a checkbox in the device list. Pairs/unpairs the
- * device associated with the box checked/unchecked.
- * @param {Event} event Contains event data. |event.model.index| is the index
- * of the item which the target is contained in.
- */
- pairDevice: function(event) {
- var index = event.model.index;
- var predefined =
- /** @type {boolean} */ (event.target.dataset.predefined == 'true');
- var device =
- predefined ? this.predefinedDevices[index] : this.devices[index];
-
- if (event.target.checked) {
- var devicePath = (predefined ? 'predefinedDevices.' : 'devices.');
- devicePath += index.toString();
- this.set(devicePath + '.discoverable', true);
-
- // Send device info to the WebUI.
- chrome.send('requestBluetoothPair', [device]);
- this.devicePaths[device.path] = {predefined: predefined, index: index};
-
- var devicePath = (predefined ? 'predefinedDevices.' : 'devices.');
- devicePath += index.toString();
- this.set(devicePath + '.paired', false);
- } else {
- chrome.send('removeBluetoothDevice', [device.path]);
-
- var devicePath = (predefined ? 'predefinedDevices.' : 'devices.');
- devicePath += index.toString();
- this.set(devicePath + '.discoverable', false);
- }
- },
-
- /**
- * Called from Chrome OS back-end when a pair request fails.
- * @param {string} path The path of the device which failed to pair.
- */
- pairFailed: function(path) {
- var obj = this.devicePaths[path];
-
- if (obj == undefined) return;
-
- var devicePath = (obj.predefined ? 'predefinedDevices.' : 'devices.');
- devicePath += obj.index.toString();
- this.set(devicePath + '.paired', false);
- },
-
- /**
- * On-change event handler for a checkbox in the device list.
- * @param {Event} event Contains event data. |event.model.index| is the index
- * of the item which the target is contained in.
- */
- discoverDevice: function(event) {
- var index = event.model.index;
- var predefined =
- /** @type {boolean} */ (event.target.dataset.predefined == 'true');
- var device =
- predefined ? this.predefinedDevices[index] : this.devices[index];
-
- if (event.target.checked) {
- device.classValue = this.getValueForDeviceClass(device.class);
-
- // Send device info to WebUI.
- chrome.send('requestBluetoothDiscover', [device]);
-
- this.devicePaths[device.path] = {predefined: predefined, index: index};
- } else {
- chrome.send('removeBluetoothDevice', [device.path]);
-
- var devicePath = (predefined ? 'predefinedDevices.' : 'devices.');
- devicePath += index.toString();
- this.set(devicePath + '.paired', false);
- }
- },
-
- // Adds a new device with default settings to the list of devices.
- appendNewDevice: function() {
- var newDevice = new BluetoothDevice();
- newDevice.alias = 'New Device';
- this.push('devices', newDevice);
- },
-
- /**
- * This is called when a new device is discovered by the main adapter.
- * The device is only added to the view's list if it is not already in
- * the list (i.e. its path has not yet been recorded in |devicePaths|).
- * @param {BluetoothDevice} device A bluetooth device.
- */
- addBluetoothDevice: function(device) {
- if (this.devicePaths[device.path] != undefined) {
- var obj = this.devicePaths[device.path];
- var devicePath = (obj.predefined ? 'predefinedDevices.' : 'devices.');
- devicePath += obj.index.toString();
- this.set(devicePath + '.discoverable', true);
- return;
- }
-
- device.class = this.getTextForDeviceClass(device.classValue);
- device.discoverable = true;
- this.push('devices', device);
- this.devicePaths[device.path] = {
- predefined: false,
- index: this.devices.length - 1
- };
- },
-
- /**
- * Called on "copy" button from the device list clicked. Creates a copy of
- * the selected device and adds it to the "custom" devices list.
- * @param {Event} event Contains event data. |event.model.index| is the index
- * of the item which the target is contained in.
- */
- copyDevice: function(event) {
- var predefined = (event.target.dataset.predefined == 'true');
- var index = event.model.index;
- var copyDevice =
- predefined ? this.predefinedDevices[index] : this.devices[index];
- // Create a deep copy of the selected device.
- var newDevice = new BluetoothDevice();
- Object.assign(newDevice, copyDevice);
- newDevice.path = '';
- newDevice.address = '';
- newDevice.name += ' (Copy)';
- newDevice.alias += ' (Copy)';
- newDevice.discoverable = false;
- newDevice.paired = false;
- this.push('devices', newDevice);
- },
-
- /**
- * Shows a modal dialog to edit the selected device's properties.
- * @param {Event} event Contains event data. |event.model.index| is the index
- * of the item which the target is contained in.
- */
- showEditModal: function(event) {
- var index = event.model.index;
- this.currentEditIndex = index;
- this.currentEditableObject = this.devices[index];
- this.$.editModal.toggle();
- },
-
- /**
- * A click handler for the delete button on bluetooth devices.
- * @param {Event} event Contains event data. |event.model.index| is the index
- * of the item which the target is contained in.
- */
- deleteDevice: function(event) {
- var index = event.model.index;
- var device = this.devices[index];
-
- chrome.send('removeBluetoothDevice', [device.path]);
-
- this.devicePaths[device.path] = undefined;
- this.splice('devices', index, 1);
- },
-
- /**
- * This function is called when a device is removed from the main bluetooth
- * adapter's device list. It sets that device's |.discoverable| and |.paired|
- * attributes to false.
- * @param {string} path A bluetooth device's path.
- */
- deviceRemovedFromMainAdapter: function(path) {
- if (this.devicePaths[path] == undefined) return;
-
- var obj = this.devicePaths[path];
- var devicePath = (obj.predefined ? 'predefinedDevices.' : 'devices.');
- devicePath += obj.index.toString();
- this.set(devicePath + '.discoverable', false);
- this.set(devicePath + '.paired', false);
- },
-
- /**
- * Returns the text for the label that corresponds to |classValue|.
- * @param {number} classValue A number representing the bluetooth class
- * of a device.
- * @return {string} The label which represents |classValue|.
- */
- getTextForDeviceClass: function(classValue) {
- for (var i = 0; i < this.deviceClassOptions.length; ++i) {
- if (this.deviceClassOptions[i].value == classValue)
- return this.deviceClassOptions[i].text;
- }
- },
-
- /**
- * Returns the integer value which corresponds with the label |classText|.
- * @param {string} classText The label for a device class option.
- * @return {number} The value which |classText| represents.
- */
- getValueForDeviceClass: function(classText) {
- for (var i = 0; i < this.deviceClassOptions.length; ++i) {
- if (this.deviceClassOptions[i].text == classText)
- return this.deviceClassOptions[i].value;
- }
- return 0;
- },
-});
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.css b/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.css
deleted file mode 100644
index 5ba0039e944..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. */
-
-body {
- font-family: 'Roboto', Arial, Verdana, Helvetica;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.html b/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.html
deleted file mode 100644
index c7fe24145e9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.html
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8">
- <title>Device Emulator</title>
- <script src="chrome://resources/js/polymer_config.js"></script>
- <script src="chrome://resources/js/cr.js"></script>
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="strings.js"></script>
- <link rel="stylesheet" href="chrome://resources/css/roboto.css">
- <link rel="stylesheet" href="device_emulator.css">
- <link rel="import" href="audio_settings.html">
- <link rel="import" href="battery_settings.html">
- <link rel="import" href="bluetooth_settings.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/av-icons.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/paper-drawer-panel/paper-drawer-panel.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/paper-header-panel/paper-header-panel.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"
- <link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/paper-toolbar/paper-toolbar.html">
- <style is="custom-style">
- paper-drawer-panel {
- --paper-drawer-panel-main-container: {
- background-color: #ddd;
- };
- }
-
- paper-drawer-panel .bold { font-weight: bolder; }
- paper-drawer-panel .menu-item { margin: 20px 15px; }
-
- paper-drawer-panel .cards-container {
- overflow: scroll;
- }
-
- paper-drawer-panel .card {
- display: block;
- margin: 20px 20px 60px 20px;
- width: 95%;
- background-color: #fff;
- box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
- border-radius: 2px;
- }
-
- paper-drawer-panel .card .card-body {
- margin: 0 20px;
- padding-bottom: 20px;
- }
-
- paper-header-panel div paper-item:first {
- margin-top: 20px;
- }
- </style>
-</head>
-<body unresolved fullbleed layout vertical>
- <paper-drawer-panel>
- <paper-header-panel drawer>
- <paper-toolbar>
- <div><span class="bold">Chrome OS Device Emulator</span></div>
- </paper-toolbar>
- <div>
- <paper-item>
- <div class="menu-item">
- <paper-checkbox
- class="menu-item-toggle"
- data-content-id="audio-settings-card"></paper-checkbox>
- <paper-icon-button icon="av:volume-up"></paper-icon-button>
- <span>Audio</span>
- </div>
- </paper-item>
- <paper-item>
- <div class="menu-item">
- <paper-checkbox
- data-content-id="battery-settings-card"
- class="menu-item-toggle"></paper-checkbox>
- <paper-icon-button icon="device:battery-charging-full">
- </paper-icon-button>
- <span>Battery/Power</span>
- </div>
- </paper-item>
- <paper-item>
- <div class="menu-item">
- <paper-checkbox
- class="menu-item-toggle"
- data-content-id="bluetooth-settings-card"></paper-checkbox>
- <paper-icon-button icon="device:bluetooth"></paper-icon-button>
- <span>Bluetooth</span>
- </div>
- </paper-item>
- </div>
- </paper-header-panel>
- <paper-header-panel main>
- <paper-toolbar>
- </paper-toolbar>
- <div>
- <div id="cards-container">
- <div class="card" hidden id="audio-settings-card">
- <div class="card-body">
- <audio-settings id="audio-settings"></audio-settings>
- </div>
- </div>
- <div class="card" hidden id="battery-settings-card">
- <div class="card-body">
- <battery-settings id="battery-settings">
- </battery-settings>
- </div>
- </div>
- <div class="card" hidden id="bluetooth-settings-card">
- <div class="card-body">
- <bluetooth-settings id="bluetooth-settings"></bluetooth-settings>
- </div>
- </div>
- </div>
- </div>
- </paper-header-panel>
- </paper-drawer-panel>
- <script src="chrome://resources/js/i18n_template.js"></script>
- <script src="device_emulator.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.js b/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.js
deleted file mode 100644
index 3f49092c647..00000000000
--- a/chromium/chrome/browser/resources/chromeos/emulator/device_emulator.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('device_emulator', function() {
- 'use strict';
-
- var audioSettings = $('audio-settings');
- var batterySettings = $('battery-settings');
- var bluetoothSettings = $('bluetooth-settings');
-
- function initialize() {
- audioSettings.initialize();
- batterySettings.initialize();
- bluetoothSettings.initialize();
-
- var toggles = document.getElementsByClassName('menu-item-toggle');
- for (var i = 0; i < toggles.length; ++i) {
- toggles[i].addEventListener('click', handleDrawerItemClick);
- }
- }
-
- /**
- * Shows/hides a sidebar elements designated content.
- * The content is identified by the |data-content-id| attribute of the
- * sidebar element. This value is the ID of the HTML element to be toggled.
- * @param {Event} e Contains information about the event which was fired.
- */
- function handleDrawerItemClick(e) {
- var contentId = e.target.dataset.contentId;
- var card = $(contentId);
- card.hidden = !card.hidden;
- }
-
- // Return an object with all of the exports.
- return {
- initialize: initialize,
- audioSettings: audioSettings,
- batterySettings: batterySettings,
- bluetoothSettings: bluetoothSettings,
- };
-});
-
-document.addEventListener('DOMContentLoaded', device_emulator.initialize);
diff --git a/chromium/chrome/browser/resources/chromeos/fake_bluetooth_overlay_parent.js b/chromium/chrome/browser/resources/chromeos/fake_bluetooth_overlay_parent.js
deleted file mode 100644
index b6196af541b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/fake_bluetooth_overlay_parent.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
-
- /**
- * Encapsulated a fake parent page for bluetooth overlay page used by Web UI.
- * @constructor
- */
- function FakeBluetoothOverlayParent(model) {
- Page.call(this, 'bluetooth', '', 'bluetooth-container');
- }
-
- cr.addSingletonGetter(FakeBluetoothOverlayParent);
-
- FakeBluetoothOverlayParent.prototype = {
- // Inherit FakeBluetoothOverlayParent from Page.
- __proto__: Page.prototype,
- };
-
- // Export
- return {
- FakeBluetoothOverlayParent: FakeBluetoothOverlayParent
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/OWNERS b/chromium/chrome/browser/resources/chromeos/first_run/OWNERS
deleted file mode 100644
index df660f70946..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-dzhioev@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/background.js b/chromium/chrome/browser/resources/chromeos/first_run/app/background.js
deleted file mode 100644
index 5d1ba842e5d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/background.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-chrome.app.runtime.onLaunched.addListener(function() {
- chrome.app.window.create('main.html', {
- 'frame': 'none',
- 'resizable': false,
- 'hidden': true,
- }, function(appWindow) {
- appWindow.contentWindow.appWindow = appWindow;
- });
-});
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/greeting_image_disabled.html b/chromium/chrome/browser/resources/chromeos/first_run/app/greeting_image_disabled.html
deleted file mode 100644
index 8b137891791..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/greeting_image_disabled.html
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/greeting_image_enabled.html b/chromium/chrome/browser/resources/chromeos/first_run/app/greeting_image_enabled.html
deleted file mode 100644
index 28ae197e27d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/greeting_image_enabled.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div style="background-image: url(chrome://theme/IDR_FIRST_RUN_GREETING);
- display: inline-block;
- height: 235px;
- width: 662px;" class="greeting-image">
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/128.png b/chromium/chrome/browser/resources/chromeos/first_run/app/icon/128.png
deleted file mode 100644
index a3006d82c96..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/128.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/16.png b/chromium/chrome/browser/resources/chromeos/first_run/app/icon/16.png
deleted file mode 100644
index 8d9df98773a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/16.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/256.png b/chromium/chrome/browser/resources/chromeos/first_run/app/icon/256.png
deleted file mode 100644
index 3c2e64e9c7a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/256.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/32.png b/chromium/chrome/browser/resources/chromeos/first_run/app/icon/32.png
deleted file mode 100644
index ff6cf2aae5e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/32.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/48.png b/chromium/chrome/browser/resources/chromeos/first_run/app/icon/48.png
deleted file mode 100644
index 7efbb11c7c3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/48.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/64.png b/chromium/chrome/browser/resources/chromeos/first_run/app/icon/64.png
deleted file mode 100644
index b36dd294c38..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/64.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/96.png b/chromium/chrome/browser/resources/chromeos/first_run/app/icon/96.png
deleted file mode 100644
index 14f1ea1156a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/icon/96.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/main.html b/chromium/chrome/browser/resources/chromeos/first_run/app/main.html
deleted file mode 100644
index 32e52a3c0bc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/main.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;.style.fontFamily:fontfamily;lang:language">
- <head>
- <meta charset=utf-8>
- <title></title>
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" href="chrome://resources/css/widgets.css">
- <link rel="stylesheet" href="chrome://resources/css/apps/common.css">
- <link rel="stylesheet" href="chrome://resources/css/apps/topbutton_bar.css">
- <link rel="stylesheet" href="../step.css">
- <link rel="stylesheet" href="../preload.css">
- <link rel="stylesheet" href="style.css">
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="chrome://resources/js/i18n_template_no_process.js"></script>
- <script src="main.js"></script>
- </head>
- <body>
- <div id="greeting" class="step dialog">
- <div class="window-header">
- <div class="topbutton-bar">
- <div class="topbutton-wrapper">
- <button class="custom-appearance close-button"
- i18n-values="aria-label:closeButton" tabindex="1">
- </button>
- </div>
- </div>
- </div>
- <h1 i18n-content="greetingHeader"></h1>
- <p>
- <span i18n-content="greetingText1"></span><br>
- <span i18n-content="greetingText2"></span>
- </p>
- <div class="controls">
- <button i18n-content="greetingButton"
- class="next-button custom-appearance blue-button" tabindex="0">
- </button>
- </div>
- <include src="greeting_image_[GREETING_IMAGE].html">
- </div>
- </body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/main.js b/chromium/chrome/browser/resources/chromeos/first_run/app/main.js
deleted file mode 100644
index e1afc5b29d0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/main.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-function init() {
- var content = $('greeting');
- chrome.firstRunPrivate.getLocalizedStrings(function(strings) {
- loadTimeData.data = strings;
- i18nTemplate.process(document, loadTimeData);
- // Resizing and centering app's window.
- var bounds = {};
- bounds.width = content.offsetWidth;
- bounds.height = content.offsetHeight;
- bounds.left = Math.round(0.5 * (window.screen.availWidth - bounds.width));
- bounds.top = Math.round(0.5 * (window.screen.availHeight - bounds.height));
- appWindow.setBounds(bounds);
- appWindow.show();
- });
- var closeButton = content.getElementsByClassName('close-button')[0];
- // Make close unfocusable by mouse.
- closeButton.addEventListener('mousedown', function(e) {
- e.preventDefault();
- });
- closeButton.addEventListener('click', function(e) {
- appWindow.close();
- e.stopPropagation();
- });
- var tutorialButton = content.getElementsByClassName('next-button')[0];
- tutorialButton.addEventListener('click', function(e) {
- chrome.firstRunPrivate.launchTutorial();
- appWindow.close();
- e.stopPropagation();
- });
-}
-
-document.addEventListener('DOMContentLoaded', init);
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app/style.css b/chromium/chrome/browser/resources/chromeos/first_run/app/style.css
deleted file mode 100644
index 399b29ada46..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app/style.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-body {
- margin: 0;
- padding: 0;
-}
-
-.step.dialog {
- align-items: center;
- display: flex;
- flex-direction: column;
- padding: 40px;
- text-align: center;
- width: 720px;
-}
-
-.step.dialog h1 {
- font-size: 30px;
- margin-bottom: 16px;
- margin-top: 0;
-}
-
-.step.dialog p {
- font-size: 15px;
- margin-bottom: 0;
- margin-top: 0;
-}
-
-.step.dialog .controls {
- margin-bottom: 0;
- margin-top: 40px;
-}
-
-.step.dialog .controls button {
- font-size: 12px;
- min-width: 0;
- padding: 0 35px;
- text-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
-}
-
-.step.dialog .window-header {
- -webkit-app-region: drag;
- display: block;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-.step.dialog .topbutton-bar {
- display: block;
- margin-top: 10px;
-}
-
-.step.dialog .topbutton-wrapper {
- -webkit-padding-end: 10px;
- display: flex;
- justify-content: flex-end;
-}
-
-.step.dialog .topbutton-bar button {
- -webkit-app-region: no-drag;
- -webkit-margin-end: 0;
- display: inline;
-}
-
-.step.dialog .greeting-image {
- margin-bottom: 49px;
- margin-top: 64px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/app_list_step.html b/chromium/chrome/browser/resources/chromeos/first_run/app_list_step.html
deleted file mode 100644
index bdc51ce99fc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/app_list_step.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<div id="app-list" class="step bubble transparent hidden">
- <h1 i18n-content="appListHeader"></h1>
- <p>
- <span i18n-content="appListText1"></span><br>
- <span i18n-content="appListText2"></span>
- </p>
- <div class="controls">
- <button i18n-content="nextButton"
- class="next-button custom-appearance blue-button"></button>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/background.svg b/chromium/chrome/browser/resources/chromeos/first_run/background.svg
deleted file mode 100644
index befcbb35a91..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/background.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<div id="background-container" class="transparent">
- <svg id="background" xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <rect id="rectangular-hole-pattern" class="hole transparent"/>
- <circle id="round-hole-pattern" class="hole transparent"/>
- <mask id="mask" maskUnits="objectBoundingBox"
- maskContentUnits="userSpaceOnUse">
- <rect width="100%" height="100%" fill="white"/>
- </mask>
- </defs>
- <rect class="fill" width="100%" height="100%" mask="url(#mask)"/>
- </svg>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/bubble.css b/chromium/chrome/browser/resources/chromeos/first_run/bubble.css
deleted file mode 100644
index 7c11c0ebac9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/bubble.css
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.bubble .arrow {
- border: solid transparent;
- border-width: 6px;
- content: ' ';
- height: 0;
- pointer-events: none;
- position: absolute;
- width: 0;
-}
-
-.bubble .arrow.points-up {
- border-bottom-color: white;
- bottom: 100%;
-}
-
-.bubble .arrow.points-right {
- border-left-color: white;
- left: 100%;
-}
-
-.bubble .arrow.points-down {
- border-top-color: white;
- top: 100%;
-}
-
-.bubble .arrow.points-left {
- border-right-color: white;
- right: 100%;
-}
-
-.bubble .arrow.top {
- top: 12px;
-}
-
-.bubble .arrow.right {
- right: 12px;
-}
-
-.bubble .arrow.bottom {
- bottom: 12px;
-}
-
-.bubble .arrow.left {
- left: 12px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/first_run.css b/chromium/chrome/browser/resources/chromeos/first_run/first_run.css
deleted file mode 100644
index e5d5d0bd9b8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/first_run.css
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-[hidden] {
- display: none !important;
-}
-
-html,
-body {
- margin: 0;
- padding: 0;
-}
-
-body {
- background-color: rgba(0, 0, 0, 0);
- cursor: default;
- height: 100%;
- overflow: hidden;
- position: fixed;
- width: 100%;
-}
-
-.transparent {
- opacity: 0;
-}
-
-.show-animated,
-.hide-animated {
- transition-property: opacity;
-}
-
-.show-animated {
- transition-function: ease-in;
-}
-
-.hide-animated {
- transition-function: ease-out;
-}
-
-#background-container {
- height: 100%;
- left: 0;
- position: absolute;
- top: 0;
- width: 100%;
- z-index: -1;
-}
-
-#background {
- height: 100%;
- position: absolute;
- width: 100%;
-}
-
-#background .fill {
- fill: rgba(0, 0, 0, 0.5);
-}
-
-#steps {
- align-items: center;
- display: flex;
- flex-flow: row;
- height: 100%;
- justify-content: center;
- width: 100%;
-}
-
-#help #completion-image {
- background-image: url(chrome://theme/IDR_FIRST_RUN_COMPLETION);
- display: inline-block;
- height: 153px;
- width: 400px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/first_run.html b/chromium/chrome/browser/resources/chromeos/first_run/first_run.html
deleted file mode 100644
index 29fe952b2bf..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/first_run.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;shelf:shelfAlignment;.style.fontFamily:fontfamily;">
- <head>
- <meta charset=utf-8>
- <title></title>
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" href="chrome://resources/css/widgets.css">
- <link rel="stylesheet" href="chrome://resources/css/apps/common.css">
- <link rel="stylesheet" href="bubble.css">
- <link rel="stylesheet" href="first_run.css">
- <link rel="stylesheet" href="preload.css">
- <link rel="stylesheet" href="step.css">
- <link rel="stylesheet" href="step_bubble.css">
- <script src="chrome://resources/js/cr.js"></script>
- <script src="chrome://resources/js/cr/ui.js"></script>
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="chrome://first-run/first_run.js"></script>
- <script src="chrome://first-run/strings.js"></script>
- </head>
- <body>
- <include src="background.svg">
- <div id="steps">
- <include src="app_list_step.html">
- <include src="tray_step.html">
- <include src="help_step.html">
- </div>
- <script src="chrome://resources/js/i18n_template.js"></script>
- </body>
-</html>
-
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/first_run.js b/chromium/chrome/browser/resources/chromeos/first_run/first_run.js
deleted file mode 100644
index 10ba74bb3e5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/first_run.js
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview First run UI.
- */
-
-<include src="step.js">
-
-// Transitions durations.
-/** @const */ var DEFAULT_TRANSITION_DURATION_MS = 400;
-/** @const */ var BG_TRANSITION_DURATION_MS = 800;
-
-/**
- * Changes visibility of element with animated transition.
- * @param {Element} element Element which visibility should be changed.
- * @param {boolean} visible Whether element should be visible after transition.
- * @param {number=} opt_transitionDuration Time length of transition in
- * milliseconds. Default value is DEFAULT_TRANSITION_DURATION_MS.
- * @param {function()=} opt_onFinished Called after transition has finished.
- */
-function changeVisibility(
- element, visible, opt_transitionDuration, opt_onFinished) {
- var classes = element.classList;
- // If target visibility is the same as current element visibility.
- if (classes.contains('transparent') === !visible) {
- if (opt_onFinished)
- opt_onFinished();
- return;
- }
- var transitionDuration = (opt_transitionDuration === undefined) ?
- cr.FirstRun.getDefaultTransitionDuration() : opt_transitionDuration;
- var style = element.style;
- var oldDurationValue = style.getPropertyValue('transition-duration');
- style.setProperty('transition-duration', transitionDuration + 'ms');
- var transition = visible ? 'show-animated' : 'hide-animated';
- classes.add(transition);
- classes.toggle('transparent');
- element.addEventListener('webkitTransitionEnd', function f() {
- element.removeEventListener('webkitTransitionEnd', f);
- classes.remove(transition);
- if (oldDurationValue)
- style.setProperty('transition-duration', oldDurationValue);
- else
- style.removeProperty('transition-duration');
- if (opt_onFinished)
- opt_onFinished();
- });
- ensureTransitionEndEvent(element, transitionDuration);
-}
-
-cr.define('cr.FirstRun', function() {
- return {
- // Whether animated transitions are enabled.
- transitionsEnabled_: false,
-
- // SVG element representing UI background.
- background_: null,
-
- // Container for background.
- backgroundContainer_: null,
-
- // Mask element describing transparent "holes" in background.
- mask_: null,
-
- // Pattern used for creating rectangular holes.
- rectangularHolePattern_: null,
-
- // Pattern used for creating round holes.
- roundHolePattern_: null,
-
- // Dictionary keeping all available tutorial steps by their names.
- steps_: {},
-
- // Element representing step currently shown for user.
- currentStep_: null,
-
- /**
- * Initializes internal structures and preparing steps.
- */
- initialize: function() {
- disableTextSelectAndDrag();
- this.transitionsEnabled_ = loadTimeData.getBoolean('transitionsEnabled');
- this.background_ = $('background');
- this.backgroundContainer_ = $('background-container');
- this.mask_ = $('mask');
- this.rectangularHolePattern_ = $('rectangular-hole-pattern');
- this.rectangularHolePattern_.removeAttribute('id');
- this.roundHolePattern_ = $('round-hole-pattern');
- this.roundHolePattern_.removeAttribute('id');
- var stepElements = document.getElementsByClassName('step');
- for (var i = 0; i < stepElements.length; ++i) {
- var step = stepElements[i];
- cr.FirstRun.DecorateStep(step);
- this.steps_[step.getName()] = step;
- }
- this.setBackgroundVisible(true, function() {
- chrome.send('initialized');
- });
- },
-
- /**
- * Hides all elements and background.
- */
- finalize: function() {
- // At first we hide holes (job 1) and current step (job 2) simultaneously,
- // then background.
- var jobsLeft = 2;
- var onJobDone = function() {
- --jobsLeft;
- if (jobsLeft)
- return;
- this.setBackgroundVisible(false, function() {
- chrome.send('finalized');
- });
- }.bind(this);
- this.doHideCurrentStep_(function(name) {
- if (name)
- chrome.send('stepHidden', [name]);
- onJobDone();
- });
- this.removeHoles(onJobDone);
- },
-
- /**
- * Adds transparent rectangular hole to background.
- * @param {number} x X coordinate of top-left corner of hole.
- * @param {number} y Y coordinate of top-left corner of hole.
- * @param {number} widht Width of hole.
- * @param {number} height Height of hole.
- */
- addRectangularHole: function(x, y, width, height) {
- var hole = this.rectangularHolePattern_.cloneNode();
- hole.setAttribute('x', x);
- hole.setAttribute('y', y);
- hole.setAttribute('width', width);
- hole.setAttribute('height', height);
- this.mask_.appendChild(hole);
- setTimeout(function() {
- changeVisibility(hole, true);
- }, 0);
- },
-
- /**
- * Adds transparent round hole to background.
- * @param {number} x X coordinate of circle center.
- * @param {number} y Y coordinate of circle center.
- * @param {number} radius Radius of circle.
- */
- addRoundHole: function(x, y, radius) {
- var hole = this.roundHolePattern_.cloneNode();
- hole.setAttribute('cx', x);
- hole.setAttribute('cy', y);
- hole.setAttribute('r', radius);
- this.mask_.appendChild(hole);
- setTimeout(function() {
- changeVisibility(hole, true);
- }, 0);
- },
-
- /**
- * Removes all holes previously added by |addHole|.
- * @param {function=} opt_onHolesRemoved Called after all holes have been
- * hidden.
- */
- removeHoles: function(opt_onHolesRemoved) {
- var mask = this.mask_;
- var holes = Array.prototype.slice.call(
- mask.getElementsByClassName('hole'));
- var holesLeft = holes.length;
- if (!holesLeft) {
- if (opt_onHolesRemoved)
- opt_onHolesRemoved();
- return;
- }
- holes.forEach(function(hole) {
- changeVisibility(hole, false, this.getDefaultTransitionDuration(),
- function() {
- mask.removeChild(hole);
- --holesLeft;
- if (!holesLeft && opt_onHolesRemoved)
- opt_onHolesRemoved();
- });
- }.bind(this));
- },
-
- /**
- * Hides currently active step and notifies chrome after step has been
- * hidden.
- */
- hideCurrentStep: function() {
- assert(this.currentStep_);
- this.doHideCurrentStep_(function(name) {
- chrome.send('stepHidden', [name]);
- });
- },
-
- /**
- * Hides currently active step.
- * @param {function(string)=} opt_onStepHidden Called after step has been
- * hidden.
- */
- doHideCurrentStep_: function(opt_onStepHidden) {
- if (!this.currentStep_) {
- if (opt_onStepHidden)
- opt_onStepHidden();
- return;
- }
- var name = this.currentStep_.getName();
- this.currentStep_.hide(true, function() {
- this.currentStep_ = null;
- if (opt_onStepHidden)
- opt_onStepHidden(name);
- }.bind(this));
- },
-
- /**
- * Shows step with given name in given position.
- * @param {string} name Name of step.
- * @param {object} position Optional parameter with optional fields |top|,
- * |right|, |bottom|, |left| used for step positioning.
- * @param {Array} pointWithOffset Optional parameter for positioning
- * bubble. Contains [x, y, offset], where (x, y) - point to which bubble
- * points, offset - distance between arrow and point.
- */
- showStep: function(name, position, pointWithOffset) {
- assert(!this.currentStep_);
- if (!this.steps_.hasOwnProperty(name))
- throw Error('Step "' + name + '" not found.');
- var step = this.steps_[name];
- if (position)
- step.setPosition(position);
- if (pointWithOffset)
- step.setPointsTo(pointWithOffset.slice(0, 2), pointWithOffset[2]);
- step.show(true, function(step) {
- step.focusDefaultControl();
- this.currentStep_ = step;
- chrome.send('stepShown', [name]);
- }.bind(this));
- },
-
- /**
- * Sets visibility of the background.
- * @param {boolean} visibility Whether background should be visible.
- * @param {function()=} opt_onCompletion Called after visibility has
- * changed.
- */
- setBackgroundVisible: function(visible, opt_onCompletion) {
- changeVisibility(this.backgroundContainer_, visible,
- this.getBackgroundTransitionDuration(), opt_onCompletion);
- },
-
- /**
- * Returns default duration of animated transitions, in ms.
- */
- getDefaultTransitionDuration: function() {
- return this.transitionsEnabled_ ? DEFAULT_TRANSITION_DURATION_MS : 0;
- },
-
- /**
- * Returns duration of transitions of background shield, in ms.
- */
- getBackgroundTransitionDuration: function() {
- return this.transitionsEnabled_ ? BG_TRANSITION_DURATION_MS : 0;
- }
- };
-});
-
-/**
- * Initializes UI.
- */
-window.onload = function() {
- cr.FirstRun.initialize();
-};
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/help_step.html b/chromium/chrome/browser/resources/chromeos/first_run/help_step.html
deleted file mode 100644
index 0a9c513079e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/help_step.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<div id="help" class="step bubble transparent hidden">
- <div id="completion-image"></div>
- <h1 i18n-content="helpHeader"></h1>
- <p i18n-content="helpText1"></p>
- <p i18n-content="helpText2"></p>
- <div class="controls">
- <button i18n-content="helpKeepExploringButton"
- class="help-button custom-appearance blue-button"></button>
- <button i18n-content="helpFinishButton"
- class="next-button custom-appearance white-button"></button>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/preload.css b/chromium/chrome/browser/resources/chromeos/first_run/preload.css
deleted file mode 100644
index 03baa02837d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/preload.css
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * 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.
- */
-
-/**
- * Preloads images. Without preloading, background image starts loading in
- * the moment when CSS property is applied. Image loading has visible delay and
- * looks like defect.
- */
-
-@media all and (-webkit-max-device-pixel-ratio: 1.5) {
- body::after {
- content:
- url(chrome://resources/images/apps/button.png)
- url(chrome://resources/images/apps/button_hover.png)
- url(chrome://resources/images/apps/button_pressed.png)
- url(chrome://resources/images/apps/button_focused.png)
- url(chrome://resources/images/apps/button_focused_hover.png)
- url(chrome://resources/images/apps/button_focused_pressed.png)
- url(chrome://resources/images/apps/button_inactive.png)
- url(chrome://resources/images/apps/blue_button.png)
- url(chrome://resources/images/apps/blue_button_hover.png)
- url(chrome://resources/images/apps/blue_button_pressed.png)
- url(chrome://resources/images/apps/blue_button_focused.png)
- url(chrome://resources/images/apps/blue_button_focused_hover.png)
- url(chrome://resources/images/apps/blue_button_focused_pressed.png)
- url(chrome://resources/images/apps/blue_button_inactive.png);
- display: none;
- }
-}
-
-@media all and (-webkit-min-device-pixel-ratio: 1.5) {
- body::after {
- content:
- url(chrome://resources/images/2x/apps/button.png)
- url(chrome://resources/images/2x/apps/button_hover.png)
- url(chrome://resources/images/2x/apps/button_pressed.png)
- url(chrome://resources/images/2x/apps/button_focused.png)
- url(chrome://resources/images/2x/apps/button_focused_hover.png)
- url(chrome://resources/images/2x/apps/button_focused_pressed.png)
- url(chrome://resources/images/2x/apps/button_inactive.png)
- url(chrome://resources/images/2x/apps/blue_button.png)
- url(chrome://resources/images/2x/apps/blue_button_hover.png)
- url(chrome://resources/images/2x/apps/blue_button_pressed.png)
- url(chrome://resources/images/2x/apps/blue_button_focused.png)
- url(chrome://resources/images/2x/apps/blue_button_focused_hover.png)
- url(chrome://resources/images/2x/apps/blue_button_focused_pressed.png)
- url(chrome://resources/images/2x/apps/blue_button_inactive.png);
- display: none;
- }
-}
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/step.css b/chromium/chrome/browser/resources/chromeos/first_run/step.css
deleted file mode 100644
index 52e424eeb3e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/step.css
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.step {
- background: white;
- color: #8c8c8c;
- padding: 0;
-}
-
-.step h1 {
- color: #333;
- font-weight: normal;
-}
-
-.step p {
- line-height: 1.5;
-}
-
-.step button.blue-button {
- color: white;
-}
-
-.step button.white-button {
- color: black;
-}
-
-.step .controls button {
- margin: 0 3px;
-}
-
-.step .controls button:first-of-type {
- -webkit-margin-start: 0;
-}
-
-.step .controls button:last-of-type {
- -webkit-margin-end: 0;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/step.js b/chromium/chrome/browser/resources/chromeos/first_run/step.js
deleted file mode 100644
index 213ea27c02e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/step.js
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Prototype for first-run tutorial steps.
- */
-
-cr.define('cr.FirstRun', function() {
- var Step = cr.ui.define('div');
-
- Step.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- // Name of step.
- name_: null,
-
- // Button leading to next tutorial step.
- nextButton_: null,
-
- // Default control for this step.
- defaultControl_: null,
-
- decorate: function() {
- this.name_ = this.getAttribute('id');
- var controlsContainer = this.getElementsByClassName('controls')[0];
- if (!controlsContainer)
- throw Error('Controls not found.');
- this.nextButton_ =
- controlsContainer.getElementsByClassName('next-button')[0];
- if (!this.nextButton_)
- throw Error('Next button not found.');
- this.nextButton_.addEventListener('click', (function(e) {
- chrome.send('nextButtonClicked', [this.getName()]);
- e.stopPropagation();
- }).bind(this));
- this.defaultControl_ = controlsContainer.children[0];
- },
-
- /**
- * Returns name of the string.
- */
- getName: function() {
- return this.name_;
- },
-
- /**
- * Hides the step.
- * @param {boolean} animated Whether transition should be animated.
- * @param {function()=} opt_onHidden Called after step has been hidden.
- */
- hide: function(animated, opt_onHidden) {
- var transitionDuration =
- animated ? cr.FirstRun.getDefaultTransitionDuration() : 0;
- changeVisibility(this,
- false,
- transitionDuration,
- function() {
- this.classList.add('hidden');
- if (opt_onHidden)
- opt_onHidden();
- }.bind(this));
- },
-
- /**
- * Shows the step.
- * @param {boolean} animated Whether transition should be animated.
- * @param {function(Step)=} opt_onShown Called after step has been shown.
- */
- show: function(animated, opt_onShown) {
- var transitionDuration =
- animated ? cr.FirstRun.getDefaultTransitionDuration() : 0;
- this.classList.remove('hidden');
- changeVisibility(this,
- true,
- transitionDuration,
- function() {
- if (opt_onShown)
- opt_onShown(this);
- }.bind(this));
- },
-
- /**
- * Sets position of the step.
- * @param {object} position Parameter with optional fields |top|,
- * |right|, |bottom|, |left| holding corresponding offsets.
- */
- setPosition: function(position) {
- var style = this.style;
- ['top', 'right', 'bottom', 'left'].forEach(function(property) {
- if (position.hasOwnProperty(property))
- style.setProperty(property, position[property] + 'px');
- });
- },
-
- /**
- * Makes default control focused. Default control is a first control in
- * current implementation.
- */
- focusDefaultControl: function() {
- this.defaultControl_.focus();
- },
- };
-
- var Bubble = cr.ui.define('div');
-
- // List of rules declaring bubble's arrow position depending on text direction
- // and shelf alignment. Every rule has required field |position| with list
- // of classes that should be applied to arrow element if this rule choosen.
- // The rule is suitable if its |shelf| and |dir| fields are correspond
- // to current shelf alignment and text direction. Missing fields behaves like
- // '*' wildcard. The last suitable rule in list is choosen for arrow style.
- var ARROW_POSITION = {
- 'app-list': [
- {
- position: ['points-down', 'left']
- },
- {
- dir: 'rtl',
- position: ['points-down', 'right']
- },
- {
- shelf: 'left',
- position: ['points-left', 'top']
- },
- {
- shelf: 'right',
- position: ['points-right', 'top']
- }
- ],
- 'tray': [
- {
- position: ['points-right', 'top']
- },
- {
- dir: 'rtl',
- shelf: 'bottom',
- position: ['points-left', 'top']
- },
- {
- shelf: 'left',
- position: ['points-left', 'top']
- }
- ],
- 'help': [
- {
- position: ['points-right', 'bottom']
- },
- {
- dir: 'rtl',
- shelf: 'bottom',
- position: ['points-left', 'bottom']
- },
- {
- shelf: 'left',
- position: ['points-left', 'bottom']
- }
- ]
- };
-
- var DISTANCE_TO_POINTEE = 10;
- var MINIMAL_SCREEN_OFFSET = 10;
- var ARROW_LENGTH = 6; // Keep synced with .arrow border-width.
-
- Bubble.prototype = {
- __proto__: Step.prototype,
-
- // Element displaying arrow.
- arrow_: null,
-
- // Unit vector directed along the bubble arrow.
- direction_: null,
-
- /**
- * In addition to base class 'decorate' this method creates arrow and
- * sets some properties related to arrow.
- */
- decorate: function() {
- Step.prototype.decorate.call(this);
- this.arrow_ = document.createElement('div');
- this.arrow_.classList.add('arrow');
- this.appendChild(this.arrow_);
- var inputDirection = document.documentElement.getAttribute('dir');
- var shelfAlignment = document.documentElement.getAttribute('shelf');
- var isSuitable = function(rule) {
- var inputDirectionMatch = !rule.hasOwnProperty('dir') ||
- rule.dir === inputDirection;
- var shelfAlignmentMatch = !rule.hasOwnProperty('shelf') ||
- rule.shelf === shelfAlignment;
- return inputDirectionMatch && shelfAlignmentMatch;
- };
- var lastSuitableRule = null;
- var rules = ARROW_POSITION[this.getName()];
- rules.forEach(function(rule) {
- if (isSuitable(rule))
- lastSuitableRule = rule;
- });
- assert(lastSuitableRule);
- lastSuitableRule.position.forEach(function(cls) {
- this.arrow_.classList.add(cls);
- }.bind(this));
- var list = this.arrow_.classList;
- if (list.contains('points-up'))
- this.direction_ = [0, -1];
- else if (list.contains('points-right'))
- this.direction_ = [1, 0];
- else if (list.contains('points-down'))
- this.direction_ = [0, 1];
- else // list.contains('points-left')
- this.direction_ = [-1, 0];
- },
-
- /**
- * Sets position of bubble in such a maner that bubble's arrow points to
- * given point.
- * @param {Array} point Bubble arrow should point to this point after
- * positioning. |point| has format [x, y].
- * @param {offset} number Additional offset from |point|.
- */
- setPointsTo: function(point, offset) {
- var shouldShowBefore = this.hidden;
- // "Showing" bubble in order to make offset* methods work.
- if (shouldShowBefore) {
- this.style.setProperty('opacity', '0');
- this.show(false);
- }
- var arrow = [this.arrow_.offsetLeft + this.arrow_.offsetWidth / 2,
- this.arrow_.offsetTop + this.arrow_.offsetHeight / 2];
- var totalOffset = DISTANCE_TO_POINTEE + offset;
- var left = point[0] - totalOffset * this.direction_[0] - arrow[0];
- var top = point[1] - totalOffset * this.direction_[1] - arrow[1];
- // Force bubble to be inside screen.
- if (this.arrow_.classList.contains('points-up') ||
- this.arrow_.classList.contains('points-down')) {
- left = Math.max(left, MINIMAL_SCREEN_OFFSET);
- left = Math.min(left, document.body.offsetWidth - this.offsetWidth -
- MINIMAL_SCREEN_OFFSET);
- }
- if (this.arrow_.classList.contains('points-left') ||
- this.arrow_.classList.contains('points-right')) {
- top = Math.max(top, MINIMAL_SCREEN_OFFSET);
- top = Math.min(top, document.body.offsetHeight - this.offsetHeight -
- MINIMAL_SCREEN_OFFSET);
- }
- this.style.setProperty('left', left + 'px');
- this.style.setProperty('top', top + 'px');
- if (shouldShowBefore) {
- this.hide(false);
- this.style.removeProperty('opacity');
- }
- },
-
- /**
- * Sets position of bubble. Overrides Step.setPosition to adjust offsets
- * in case if its direction is the same as arrow's direction.
- * @param {object} position Parameter with optional fields |top|,
- * |right|, |bottom|, |left| holding corresponding offsets.
- */
- setPosition: function(position) {
- var arrow = this.arrow_;
- // Increasing offset if it's from side where bubble points to.
- [['top', 'points-up'],
- ['right', 'points-right'],
- ['bottom', 'points-down'],
- ['left', 'points-left']].forEach(function(mapping) {
- if (position.hasOwnProperty(mapping[0]) &&
- arrow.classList.contains(mapping[1])) {
- position[mapping[0]] += ARROW_LENGTH + DISTANCE_TO_POINTEE;
- }
- });
- Step.prototype.setPosition.call(this, position);
- },
- };
-
- var HelpStep = cr.ui.define('div');
-
- HelpStep.prototype = {
- __proto__: Bubble.prototype,
-
- decorate: function() {
- Bubble.prototype.decorate.call(this);
- var helpButton = this.getElementsByClassName('help-button')[0];
- helpButton.addEventListener('click', function(e) {
- chrome.send('helpButtonClicked');
- e.stopPropagation();
- });
- },
- };
-
- var DecorateStep = function(el) {
- if (el.id == 'help')
- HelpStep.decorate(el);
- else if (el.classList.contains('bubble'))
- Bubble.decorate(el);
- else
- Step.decorate(el);
- };
-
- return {DecorateStep: DecorateStep};
-});
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/step_bubble.css b/chromium/chrome/browser/resources/chromeos/first_run/step_bubble.css
deleted file mode 100644
index 202a2de24ac..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/step_bubble.css
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.step.bubble {
- border: 1px solid;
- border-radius: 3px;
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
- display: inline-block;
- position: absolute;
- width: 400px;
-}
-
-.step.bubble h1 {
- font-size: 18px;
- margin-bottom: 20px;
- margin-left: 20px;
- margin-right: 20px;
- margin-top: 20px;
-}
-
-.step.bubble p {
- font-size: 14px;
- margin-left: 20px;
- margin-right: 20px;
-}
-
-.step.bubble p + p {
- margin-top: 30px;
-}
-
-.step.bubble .controls {
- margin-bottom: 18px;
- margin-left: 18px;
- margin-right: 18px;
- margin-top: 18px;
- text-align: end;
-}
-
-.step.bubble .controls button {
- font-size: 12px;
- min-width: 0;
- padding: 0 15px;
- text-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
-}
-
-.step.bubble.hidden {
- visibility: hidden;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/first_run/tray_step.html b/chromium/chrome/browser/resources/chromeos/first_run/tray_step.html
deleted file mode 100644
index 2b7b9e73f3c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/first_run/tray_step.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<div id="tray" class="step bubble transparent hidden">
- <h1 i18n-content="trayHeader"></h1>
- <p i18n-content="trayText"><p>
- <div class="controls">
- <button i18n-content="nextButton"
- class="next-button custom-appearance blue-button"></button>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/genius_app/OWNERS b/chromium/chrome/browser/resources/chromeos/genius_app/OWNERS
deleted file mode 100644
index 3aa8a1c0597..00000000000
--- a/chromium/chrome/browser/resources/chromeos/genius_app/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-cnwan@chromium.org
-cylee@chromium.org
-davidyu@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/guest_session_tab.html b/chromium/chrome/browser/resources/chromeos/guest_session_tab.html
deleted file mode 100644
index 36d9e289b2c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/guest_session_tab.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<meta charset="utf-8">
-<title i18n-content="title"></title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<link rel="stylesheet" href="../ntp4/incognito_and_guest_tab.css">
-<link rel="stylesheet" href="login/enterprise_info.css">
-<script>
-// Until themes can clear the cache, force-reload the theme stylesheet.
-document.write('<link id="incognitothemecss" rel="stylesheet" ' +
- 'href="chrome://theme/css/incognito_new_tab_theme.css?' +
- Date.now() + '">');
-</script>
-</head>
-<body>
-<div id="enterprise-info" location="guest-tab"
- i18n-values="visible:enterpriseInfoVisible;">
- <img src="../../../../ui/webui/resources/images/business.svg">
- <span id="enterprise-info-message" i18n-content="enterpriseInfoMessage">
- </span>
- <a id="enterprise-info-hint-link" i18n-content="enterpriseLearnMore"
- i18n-values=".href:enterpriseInfoHintLink"></a>
-</div>
-<div class="content">
- <h1 i18n-content="guestTabHeading"></h1>
- <p>
- <span i18n-content="guestTabDescription"></span>
- <a i18n-content="learnMore" i18n-values=".href:learnMoreLink"></a>
- </p>
-</div>
-</body>
-<script>
-function themeChanged() {
- document.getElementById('incognitothemecss').href =
- 'chrome://theme/css/incognito_new_tab_theme.css?' + Date.now();
-}
-</script>
-</html>
-
diff --git a/chromium/chrome/browser/resources/chromeos/image_burner.html b/chromium/chrome/browser/resources/chromeos/image_burner.html
deleted file mode 100644
index 56377086367..00000000000
--- a/chromium/chrome/browser/resources/chromeos/image_burner.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!doctype html>
-<html>
-<head>
-<!-- TODO(crbug.com/427785): Remove this file after 2015-10-31. -->
-<meta http-equiv="refresh"
- content="0;url=http://google.com/chromeos/recovery">
-</head>
-<body></body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/images/new_charger_au.png b/chromium/chrome/browser/resources/chromeos/images/new_charger_au.png
deleted file mode 100644
index 2c84f95caa1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/images/new_charger_au.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/images/new_charger_uk.png b/chromium/chrome/browser/resources/chromeos/images/new_charger_uk.png
deleted file mode 100644
index d5b4c7dce26..00000000000
--- a/chromium/chrome/browser/resources/chromeos/images/new_charger_uk.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/images/new_charger_us.png b/chromium/chrome/browser/resources/chromeos/images/new_charger_us.png
deleted file mode 100644
index ba83eb19027..00000000000
--- a/chromium/chrome/browser/resources/chromeos/images/new_charger_us.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/images/original_charger_au.png b/chromium/chrome/browser/resources/chromeos/images/original_charger_au.png
deleted file mode 100644
index 20f977286d2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/images/original_charger_au.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/images/original_charger_uk.png b/chromium/chrome/browser/resources/chromeos/images/original_charger_uk.png
deleted file mode 100644
index a413391f86e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/images/original_charger_uk.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/images/original_charger_us.png b/chromium/chrome/browser/resources/chromeos/images/original_charger_us.png
deleted file mode 100644
index bf20388a8b7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/images/original_charger_us.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/images/safe-charger-checkmark.png b/chromium/chrome/browser/resources/chromeos/images/safe-charger-checkmark.png
deleted file mode 100644
index 57014503d02..00000000000
--- a/chromium/chrome/browser/resources/chromeos/images/safe-charger-checkmark.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/input_method/OWNERS b/chromium/chrome/browser/resources/chromeos/input_method/OWNERS
deleted file mode 100644
index 48de6e64885..00000000000
--- a/chromium/chrome/browser/resources/chromeos/input_method/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-shuchen@chromium.org
-fengyuan@chromium.org
-wuyingbing@chromium.org
-zhangchi@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json b/chromium/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json
index 8982bec8423..1b6c50484c4 100644
--- a/chromium/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json
+++ b/chromium/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json
@@ -17,6 +17,7 @@
"input",
"inputMethodPrivate",
"metricsPrivate",
+ "system.display",
"tabs",
"tts",
"unlimitedStorage",
@@ -100,6 +101,20 @@
"input_view": "inputview.html#id=quick&language=zh-TW&passwordLayout=quick&name=inputmethod_quick"
},
{
+ "name": "__MSG_inputmethod_cantonese__",
+ "type": "ime",
+ "id": "yue-hant-t-i0-und",
+ "indicator": "\u7CA4",
+ "description": "Cantonese",
+ "language": [
+ "zh-TW"
+ ],
+ "layouts": [
+ "us"
+ ],
+ "input_view": "inputview.html#id=us&language=zh-CN&passwordLayout=us&name=inputmethod_cantonese"
+ },
+ {
"name": "__MSG_inputmethod_wubi__",
"type": "ime",
"id": "zh-t-i0-wubi-1986",
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 8753d0f5202..425946ef29e 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
@@ -17,6 +17,7 @@
"input",
"inputMethodPrivate",
"metricsPrivate",
+ "system.display",
"tabs",
"tts",
"unlimitedStorage",
@@ -208,6 +209,38 @@
"options_page": "hmm_options.html?code=xkb:us:colemak:eng"
},
{
+ "name": "__MSG_keyboard_us_workman__",
+ "type": "ime",
+ "id": "xkb:us:workman:eng",
+ "indicator": "WM",
+ "description": "",
+ "language": [
+ "en",
+ "en-US"
+ ],
+ "layouts": [
+ "us(workman)"
+ ],
+ "input_view": "inputview.html#id=us-workman&language=en-US&passwordLayout=us-workman&name=keyboard_us_workman",
+ "options_page": "hmm_options.html?code=xkb:us:workman:eng"
+ },
+ {
+ "name": "__MSG_keyboard_us_workman_international__",
+ "type": "ime",
+ "id": "xkb:us:workman-intl:eng",
+ "indicator": "WMI",
+ "description": "",
+ "language": [
+ "en",
+ "en-US"
+ ],
+ "layouts": [
+ "us(workman-intl)"
+ ],
+ "input_view": "inputview.html#id=us-workman-intl&language=en-US&passwordLayout=us-workman-intl&name=keyboard_us_workman_international",
+ "options_page": "hmm_options.html?code=xkb:us:workman-intl:eng"
+ },
+ {
"name": "__MSG_keyboard_belgian__",
"type": "ime",
"id": "xkb:be::nld",
@@ -231,7 +264,7 @@
"fr-FR"
],
"layouts": [
- "fr"
+ "fr(oss)"
],
"input_view": "inputview.html#id=fr.compact.qwerty&language=fr&passwordLayout=fr.compact.qwerty&name=keyboard_french",
"options_page": "hmm_options.html?code=xkb:fr::fra"
@@ -847,7 +880,7 @@
"options_page": "hmm_options.html?code=xkb:se::swe"
},
{
- "name": "__MSG_keyboard_slovakian__",
+ "name": "__MSG_keyboard_slovak__",
"type": "ime",
"id": "xkb:sk::slo",
"description": "",
@@ -1027,6 +1060,20 @@
],
"input_view": "inputview.html#id=mk&language=mk&passwordLayout=us-ltr&name=keyboard_macedonian",
"options_page": "hmm_options.html?code=xkb:mk::mkd"
+ },
+ {
+ "name": "__MSG_keyboard_kazakh__",
+ "type": "ime",
+ "id": "xkb:kz::kaz",
+ "description": "",
+ "language": [
+ "kk"
+ ],
+ "layouts": [
+ "kz"
+ ],
+ "input_view": "inputview.html#id=kz&language=kk&passwordLayout=us-ltr&name=keyboard_kazakh",
+ "options_page": "hmm_options.html?code=xkb:kz::kaz"
}
],
"manifest_version": 2
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 bd05625efe9..4a24e1d8f08 100644
--- a/chromium/chrome/browser/resources/chromeos/input_method/xkb_manifest.json
+++ b/chromium/chrome/browser/resources/chromeos/input_method/xkb_manifest.json
@@ -176,6 +176,36 @@
"input_view": "inputview.html?id=us-colemak&language=en-US&passwordLayout=us-colemak&name=keyboard_us_colemak"
},
{
+ "name": "__MSG_keyboard_us_workman__",
+ "type": "ime",
+ "id": "xkb:us:workman:eng",
+ "indicator": "WM",
+ "description": "",
+ "language": [
+ "en",
+ "en-US"
+ ],
+ "layouts": [
+ "us(workman)"
+ ],
+ "input_view": "inputview.html?id=us-workman&language=en-US&passwordLayout=us-workman&name=keyboard_us_workman"
+ },
+ {
+ "name": "__MSG_keyboard_us_workman_international__",
+ "type": "ime",
+ "id": "xkb:us:workman-intl:eng",
+ "indicator": "WMI",
+ "description": "",
+ "language": [
+ "en",
+ "en-US"
+ ],
+ "layouts": [
+ "us(workman-intl)"
+ ],
+ "input_view": "inputview.html?id=us-workman-intl&language=en-US&passwordLayout=us-workman-intl&name=keyboard_us_workman_international"
+ },
+ {
"name": "__MSG_keyboard_belgian__",
"type": "ime",
"id": "xkb:be::nld",
@@ -718,7 +748,7 @@
"input_view": "inputview.html?id=se.compact.qwerty&language=sv&passwordLayout=se.compact.qwerty&name=keyboard_swedish"
},
{
- "name": "__MSG_keyboard_slovakian__",
+ "name": "__MSG_keyboard_slovak__",
"type": "ime",
"id": "xkb:sk::slo",
"description": "",
diff --git a/chromium/chrome/browser/resources/chromeos/insert.png b/chromium/chrome/browser/resources/chromeos/insert.png
deleted file mode 100644
index 829a595ea3a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/insert.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/keyboard/keyboard_utils.js b/chromium/chrome/browser/resources/chromeos/keyboard/keyboard_utils.js
deleted file mode 100644
index 2369197c3b4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/keyboard/keyboard_utils.js
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Namespace for keyboard utility functions.
- */
-var keyboard = {};
-
-/**
- * Swallows keypress and keyup events of arrow keys.
- * @param {Event} event Raised event.
- * @private
- */
-keyboard.onKeyIgnore_ = function(event) {
- event = /** @type {KeyboardEvent} */(event);
-
- if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey)
- return;
-
- if (event.keyIdentifier == 'Left' ||
- event.keyIdentifier == 'Right' ||
- event.keyIdentifier == 'Up' ||
- event.keyIdentifier == 'Down') {
- event.stopPropagation();
- event.preventDefault();
- }
-};
-
-/**
- * Converts arrow keys into tab/shift-tab key events.
- * @param {Event} event Raised event.
- * @private
- */
-keyboard.onKeyDown_ = function(event) {
- event = /** @type {KeyboardEvent} */(event);
-
- if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey)
- return;
-
- var needsUpDownKeys = event.target.classList.contains('needs-up-down-keys');
-
- if (event.keyIdentifier == 'Left' ||
- (!needsUpDownKeys && event.keyIdentifier == 'Up')) {
- keyboard.raiseKeyFocusPrevious(document.activeElement);
- event.stopPropagation();
- event.preventDefault();
- } else if (event.keyIdentifier == 'Right' ||
- (!needsUpDownKeys && event.keyIdentifier == 'Down')) {
- keyboard.raiseKeyFocusNext(document.activeElement);
- event.stopPropagation();
- event.preventDefault();
- }
-};
-
-/**
- * Raises tab/shift-tab keyboard events.
- * @param {HTMLElement} element Element that should receive the event.
- * @param {string} eventType Keyboard event type.
- * @param {boolean} shift True if shift should be on.
- * @private
- */
-keyboard.raiseTabKeyEvent_ = function(element, eventType, shift) {
- var event = document.createEvent('KeyboardEvent');
- event.initKeyboardEvent(
- eventType,
- true, // canBubble
- true, // cancelable
- window,
- 'U+0009',
- 0, // keyLocation
- false, // ctrl
- false, // alt
- shift, // shift
- false); // meta
- element.dispatchEvent(event);
-};
-
-/**
- * Raises shift+tab keyboard events to focus previous element.
- * @param {HTMLElement} element Element that should receive the event.
- */
-keyboard.raiseKeyFocusPrevious = function(element) {
- keyboard.raiseTabKeyEvent_(element, 'keydown', true);
- keyboard.raiseTabKeyEvent_(element, 'keypress', true);
- keyboard.raiseTabKeyEvent_(element, 'keyup', true);
-};
-
-/**
- * Raises tab keyboard events to focus next element.
- * @param {HTMLElement} element Element that should receive the event.
- */
-keyboard.raiseKeyFocusNext = function(element) {
- keyboard.raiseTabKeyEvent_(element, 'keydown', false);
- keyboard.raiseTabKeyEvent_(element, 'keypress', false);
- keyboard.raiseTabKeyEvent_(element, 'keyup', false);
-};
-
-/**
- * Initializes event handling for arrow keys driven focus flow.
- */
-keyboard.initializeKeyboardFlow = function() {
- document.addEventListener('keydown',
- keyboard.onKeyDown_, true);
- document.addEventListener('keypress',
- keyboard.onKeyIgnore_, true);
- document.addEventListener('keyup',
- keyboard.onKeyIgnore_, true);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/keyboard_overlay.css b/chromium/chrome/browser/resources/chromeos/keyboard_overlay.css
deleted file mode 100644
index 7b89b228301..00000000000
--- a/chromium/chrome/browser/resources/chromeos/keyboard_overlay.css
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-body {
- -webkit-user-select: none;
- background: #fff;
- font-size: 100%;
- margin: 0;
- overflow: hidden;
- padding: 0;
-}
-
-.keyboard-overlay-keyboard {
- background: -webkit-linear-gradient(#484848, #252525) no-repeat;
- background-color: #252525;
- border-radius: 6px;
-}
-
-.keyboard-overlay-instructions {
- -webkit-box-orient: vertical;
- background: -webkit-linear-gradient(rgb(51, 76, 126), rgb(13, 23, 43));
- border: 2px solid rgb(87, 108, 207);
- border-radius: 5px;
- color: #fff;
- display: -webkit-box;
- position: absolute;
- vertical-align: middle;
- z-index: 100;
-}
-
-.keyboard-overlay-instructions-text {
- -webkit-box-flex: 3;
- margin: 13px auto 0;
- max-width: 20em;
- text-align: center;
- vertical-align: middle;
-}
-
-.keyboard-overlay-instructions-hide-text {
- -webkit-box-flex: 2;
- font-weight: bold;
- text-align: center;
- vertical-align: middle;
-}
-
-.keyboard-overlay-learn-more-text {
- -webkit-box-flex: 1;
- font-size: 90%;
- margin: 0 auto 13px;
- text-align: center;
- text-decoration: underline;
- vertical-align: middle;
-}
-
-.keyboard-overlay-learn-more-text a {
- color: #fff;
-}
-
-.keyboard-overlay-key {
- -webkit-box-orient: vertical;
- background-color: rgba(24, 24, 24, 0.9);
- border: 2px solid #7f7f7f;
- border-radius: 4px;
- color: rgb(151, 151, 151);
- display: -webkit-box;
- font-size: 80%;
- font-weight: bold;
- position: absolute;
-}
-
-.keyboard-overlay-key.is-shortcut {
- background: -webkit-linear-gradient(rgba(61, 61, 61, 0.8),
- rgba(27, 27, 27, 0.8));
- border-color: #fafafa;
- color: #9e9e9e;
-}
-
-.keyboard-overlay-key.is-shortcut.modifier-shift {
- border-color: rgb(97, 186, 100);
-}
-
-.keyboard-overlay-key.is-shortcut.modifier-ctrl {
- border-color: rgb(93, 128, 199);
-}
-
-.keyboard-overlay-key.is-shortcut.modifier-alt {
- border-color: rgb(184, 84, 84);
-}
-
-.keyboard-overlay-key.is-shortcut.modifier-search {
- border-color: rgb(204, 204, 80);
-}
-
-.keyboard-overlay-key.is-shortcut.modifier-shift.modifier-ctrl {
- border-color: rgb(121, 172, 143);
-}
-
-.keyboard-overlay-key.is-shortcut.modifier-shift.modifier-alt {
- border-color: rgb(191, 189, 121);
-}
-
-.keyboard-overlay-key.is-shortcut.modifier-ctrl.modifier-alt {
- border-color: rgb(158, 84, 206);
-}
-
-.keyboard-overlay-key.is-shortcut.modifier-shift.modifier-ctrl.modifier-alt {
- border-color: #7f7f7f;
-}
-
-.keyboard-overlay-key.pressed {
- border-color: #fff;
- color: #fff;
-}
-
-.keyboard-overlay-key.pressed.is-shift {
- background: -webkit-linear-gradient(rgb(68, 161, 66), rgb(62, 95, 55));
-}
-
-.keyboard-overlay-key.pressed.is-shift.modifier-ctrl {
- background: -webkit-linear-gradient(rgb(66, 161, 67), rgb(46, 92, 83));
-}
-
-.keyboard-overlay-key.pressed.is-shift.modifier-alt {
- background: -webkit-linear-gradient(rgb(69, 163, 67), rgb(81, 81, 52));
-}
-
-.keyboard-overlay-key.pressed.is-shift.modifier-ctrl.modifier-alt {
- background: -webkit-linear-gradient(rgb(82, 161, 42), rgb(79, 77, 46));
-}
-
-.keyboard-overlay-key.pressed.is-ctrl {
- background: -webkit-linear-gradient(rgb(31, 55, 162), rgb(25, 38, 90));
-}
-
-.keyboard-overlay-key.pressed.is-ctrl.modifier-shift {
- background: -webkit-linear-gradient(rgb(67, 159, 165), rgb(30, 55, 96));
-}
-
-.keyboard-overlay-key.pressed.is-ctrl.modifier-alt {
- background: -webkit-linear-gradient(rgb(115, 54, 144), rgb(34, 37, 94));
-}
-
-.keyboard-overlay-key.pressed.is-ctrl.modifier-shift.modifier-alt {
- background: -webkit-linear-gradient(rgb(115, 54, 144), rgb(33, 37, 93));
-}
-
-.keyboard-overlay-key.pressed.is-alt {
- background: -webkit-linear-gradient(rgb(132, 44, 42), rgb(84, 30, 28));
-}
-
-.keyboard-overlay-key.pressed.is-alt.modifier-shift {
- background: -webkit-linear-gradient(top left, rgb(116, 94, 49),
- rgb(85, 36, 30));
-}
-
-.keyboard-overlay-key.pressed.is-alt.modifier-ctrl {
- background: -webkit-linear-gradient(rgb(118, 54, 143), rgb(82, 33, 40));
-}
-
-.keyboard-overlay-key.pressed.is-alt.modifier-shift.modifier-ctrl {
- background: -webkit-linear-gradient(top left, rgb(115, 95, 41),
- rgb(80, 36, 27));
-}
-
-.keyboard-overlay-key.pressed.is-search {
- background: -webkit-linear-gradient(rgb(242, 242, 126), rgb(186, 186, 52));
-}
-
-.keyboard-overlay-shortcut-text {
- -webkit-box-flex: 1;
- -webkit-box-ordinal-group: 1;
- color: #fff;
- padding: 1px 3px 0;
- text-align: center;
- text-shadow: #000 0 0 2px;
-}
-
-.keyboard-overlay-key-text {
- -webkit-box-ordinal-group: 2;
- padding: 0 3px 2px;
- text-align: center;
-}
-
-.keyboard-overlay-key.is-shortcut .keyboard-overlay-key-text {
- opacity: 0.25;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/keyboard_overlay.html b/chromium/chrome/browser/resources/chromeos/keyboard_overlay.html
deleted file mode 100644
index 104dcfa5033..00000000000
--- a/chromium/chrome/browser/resources/chromeos/keyboard_overlay.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!doctype html>
-<html i18n-values="lang:language">
-<head>
-<meta charset="utf-8" content="text/html">
-<title i18n-content="keyboardOverlayTitle"></title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<link rel="stylesheet" href="keyboard_overlay.css">
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="keyboard_overlay.js"></script>
-<body class="keyboard-overlay-keyboard"></body>
-<script src="strings.js"></script>
-<script src="chrome://resources/js/i18n_template.js"></script>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/keyboard_overlay.js b/chromium/chrome/browser/resources/chromeos/keyboard_overlay.js
deleted file mode 100644
index 3447f7dec98..00000000000
--- a/chromium/chrome/browser/resources/chromeos/keyboard_overlay.js
+++ /dev/null
@@ -1,804 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-<include src="keyboard_overlay_data.js">
-<include src="keyboard_overlay_accessibility_helper.js">
-
-var BASE_KEYBOARD = {
- top: 0,
- left: 0,
- width: 1237,
- height: 514
-};
-
-var BASE_INSTRUCTIONS = {
- top: 194,
- left: 370,
- width: 498,
- height: 142
-};
-
-var MODIFIER_TO_CLASS = {
- 'SHIFT': 'modifier-shift',
- 'CTRL': 'modifier-ctrl',
- 'ALT': 'modifier-alt',
- 'SEARCH': 'modifier-search'
-};
-
-var IDENTIFIER_TO_CLASS = {
- '2A': 'is-shift',
- '36': 'is-shift',
- '1D': 'is-ctrl',
- 'E0 1D': 'is-ctrl',
- '38': 'is-alt',
- 'E0 38': 'is-alt',
- 'E0 5B': 'is-search'
-};
-
-var LABEL_TO_IDENTIFIER = {
- 'search': 'E0 5B',
- 'ctrl': '1D',
- 'alt': '38',
- 'caps lock': '3A',
- 'esc': '01',
- 'disabled': 'DISABLED'
-};
-
-var KEYCODE_TO_LABEL = {
- 8: 'backspace',
- 9: 'tab',
- 13: 'enter',
- 27: 'esc',
- 32: 'space',
- 33: 'pageup',
- 34: 'pagedown',
- 35: 'end',
- 36: 'home',
- 37: 'left',
- 38: 'up',
- 39: 'right',
- 40: 'down',
- 46: 'delete',
- 91: 'search',
- 92: 'search',
- 96: '0',
- 97: '1',
- 98: '2',
- 99: '3',
- 100: '4',
- 101: '5',
- 102: '6',
- 103: '7',
- 104: '8',
- 105: '9',
- 106: '*',
- 107: '+',
- 109: '-',
- 110: '.',
- 111: '/',
- 112: 'back',
- 113: 'forward',
- 114: 'reload',
- 115: 'full screen',
- 116: 'switch window',
- 117: 'bright down',
- 118: 'bright up',
- 119: 'mute',
- 120: 'vol. down',
- 121: 'vol. up',
- 186: ';',
- 187: '+',
- 188: ',',
- 189: '-',
- 190: '.',
- 191: '/',
- 192: '`',
- 219: '[',
- 220: '\\',
- 221: ']',
- 222: '\'',
-};
-
-/**
- * Some key labels define actions (like for example 'vol. up' or 'mute').
- * These labels should be localized. (crbug.com/471025).
- */
-var LABEL_TO_LOCALIZED_LABEL_ID = {
- 'esc' : 'keyboardOverlayEscKeyLabel',
- 'back' : 'keyboardOverlayBackKeyLabel',
- 'forward' : 'keyboardOverlayForwardKeyLabel',
- 'reload' : 'keyboardOverlayReloadKeyLabel',
- 'full screen' : 'keyboardOverlayFullScreenKeyLabel',
- 'switch window' : 'keyboardOverlaySwitchWinKeyLabel',
- 'bright down' : 'keyboardOverlayBrightDownKeyLabel',
- 'bright up' : 'keyboardOverlayBrightUpKeyLabel',
- 'mute' : 'keyboardOverlayMuteKeyLabel',
- 'vol. down' : 'keyboardOverlayVolDownKeyLabel',
- 'vol. up' : 'keyboardOverlayVolUpKeyLabel',
- 'power' : 'keyboardOverlayPowerKeyLabel',
- 'backspace' : 'keyboardOverlayBackspaceKeyLabel',
- 'tab' : 'keyboardOverlayTabKeyLabel',
- 'search' : 'keyboardOverlaySearchKeyLabel',
- 'enter' : 'keyboardOverlayEnterKeyLabel',
- 'shift' : 'keyboardOverlayShiftKeyLabel',
- 'ctrl' : 'keyboardOverlayCtrlKeyLabel',
- 'alt' : 'keyboardOverlayAltKeyLabel',
- 'left' : 'keyboardOverlayLeftKeyLabel',
- 'right' : 'keyboardOverlayRightKeyLabel',
- 'up' : 'keyboardOverlayUpKeyLabel',
- 'down' : 'keyboardOverlayDownKeyLabel',
-};
-
-var IME_ID_PREFIX = '_comp_ime_';
-var EXTENSION_ID_LEN = 32;
-
-var keyboardOverlayId = 'en_US';
-var identifierMap = {};
-
-/**
- * True after at least one keydown event has been received.
- */
-var gotKeyDown = false;
-
-/**
- * Returns the layout name.
- * @return {string} layout name.
- */
-function getLayoutName() {
- return getKeyboardGlyphData().layoutName;
-}
-
-/**
- * Returns layout data.
- * @return {Array} Keyboard layout data.
- */
-function getLayout() {
- return keyboardOverlayData['layouts'][getLayoutName()];
-}
-
-// Cache the shortcut data after it is constructed.
-var shortcutDataCache;
-
-/**
- * Returns shortcut data.
- * @return {Object} Keyboard shortcut data.
- */
-function getShortcutData() {
- if (shortcutDataCache)
- return shortcutDataCache;
-
- shortcutDataCache = keyboardOverlayData['shortcut'];
-
- if (!isDisplayUIScalingEnabled()) {
- // Zoom screen in
- delete shortcutDataCache['+<>CTRL<>SHIFT'];
- // Zoom screen out
- delete shortcutDataCache['-<>CTRL<>SHIFT'];
- // Reset screen zoom
- delete shortcutDataCache['0<>CTRL<>SHIFT'];
- }
-
- return shortcutDataCache;
-}
-
-/**
- * Returns the keyboard overlay ID.
- * @return {string} Keyboard overlay ID.
- */
-function getKeyboardOverlayId() {
- return keyboardOverlayId;
-}
-
-/**
- * Returns keyboard glyph data.
- * @return {Object} Keyboard glyph data.
- */
-function getKeyboardGlyphData() {
- return keyboardOverlayData['keyboardGlyph'][getKeyboardOverlayId()];
-}
-
-/**
- * Converts a single hex number to a character.
- * @param {string} hex Hexadecimal string.
- * @return {string} Unicode values of hexadecimal string.
- */
-function hex2char(hex) {
- if (!hex) {
- return '';
- }
- var result = '';
- var n = parseInt(hex, 16);
- if (n <= 0xFFFF) {
- result += String.fromCharCode(n);
- } else if (n <= 0x10FFFF) {
- n -= 0x10000;
- result += (String.fromCharCode(0xD800 | (n >> 10)) +
- String.fromCharCode(0xDC00 | (n & 0x3FF)));
- } else {
- console.error('hex2Char error: Code point out of range :' + hex);
- }
- return result;
-}
-
-/**
- * Returns a list of modifiers normalized to ignore the distinction between
- * right or left keys.
- * @param {Array} modifiers List of modifiers with distinction between right
- * and left keys.
- * @return {Array} List of normalized modifiers ignoring the difference between
- * right or left keys.
- */
-function normalizeModifiers(modifiers) {
- var result = [];
- if (contains(modifiers, 'L_SHIFT') || contains(modifiers, 'R_SHIFT')) {
- result.push('SHIFT');
- }
- if (contains(modifiers, 'L_CTRL') || contains(modifiers, 'R_CTRL')) {
- result.push('CTRL');
- }
- if (contains(modifiers, 'L_ALT') || contains(modifiers, 'R_ALT')) {
- result.push('ALT');
- }
- if (contains(modifiers, 'SEARCH')) {
- result.push('SEARCH');
- }
- return result.sort();
-}
-
-/**
- * This table will contain the status of the modifiers.
- */
-var isPressed = {
- 'L_SHIFT': false,
- 'R_SHIFT': false,
- 'L_CTRL': false,
- 'R_CTRL': false,
- 'L_ALT': false,
- 'R_ALT': false,
- 'SEARCH': false,
-};
-
-/**
- * Returns a list of modifiers from the key event distinguishing right and left
- * keys.
- * @param {Event} e The key event.
- * @return {Array} List of modifiers based on key event.
- */
-function getModifiers(e) {
- if (!e)
- return [];
-
- var keyCodeToModifier = {
- 16: 'SHIFT',
- 17: 'CTRL',
- 18: 'ALT',
- 91: 'SEARCH',
- };
- var modifierWithKeyCode = keyCodeToModifier[e.keyCode];
- /** @const */ var DOM_KEY_LOCATION_LEFT = 1;
- var side = (e.location == DOM_KEY_LOCATION_LEFT) ? 'L_' : 'R_';
- var isKeyDown = (e.type == 'keydown');
-
- if (modifierWithKeyCode == 'SEARCH') {
- isPressed['SEARCH'] = isKeyDown;
- } else {
- isPressed[side + modifierWithKeyCode] = isKeyDown;
- }
-
- // make the result array
- return result = ['L_SHIFT', 'R_SHIFT', 'L_CTRL', 'R_CTRL', 'L_ALT', 'R_ALT',
- 'SEARCH'].filter(
- function(modifier) {
- return isPressed[modifier];
- }).sort();
-}
-
-/**
- * Returns an ID of the key.
- * @param {string} identifier Key identifier.
- * @param {number} i Key number.
- * @return {string} Key ID.
- */
-function keyId(identifier, i) {
- return identifier + '-key-' + i;
-}
-
-/**
- * Returns an ID of the text on the key.
- * @param {string} identifier Key identifier.
- * @param {number} i Key number.
- * @return {string} Key text ID.
- */
-function keyTextId(identifier, i) {
- return identifier + '-key-text-' + i;
-}
-
-/**
- * Returns an ID of the shortcut text.
- * @param {string} identifier Key identifier.
- * @param {number} i Key number.
- * @return {string} Key shortcut text ID.
- */
-function shortcutTextId(identifier, i) {
- return identifier + '-shortcut-text-' + i;
-}
-
-/**
- * Returns true if |list| contains |e|.
- * @param {Array} list Container list.
- * @param {string} e Element string.
- * @return {boolean} Returns true if the list contains the element.
- */
-function contains(list, e) {
- return list.indexOf(e) != -1;
-}
-
-/**
- * Returns a list of the class names corresponding to the identifier and
- * modifiers.
- * @param {string} identifier Key identifier.
- * @param {Array} modifiers List of key modifiers (with distinction between
- * right and left keys).
- * @param {Array} normalizedModifiers List of key modifiers (without distinction
- * between right or left keys).
- * @return {Array} List of class names corresponding to specified params.
- */
-function getKeyClasses(identifier, modifiers, normalizedModifiers) {
- var classes = ['keyboard-overlay-key'];
- for (var i = 0; i < normalizedModifiers.length; ++i) {
- classes.push(MODIFIER_TO_CLASS[normalizedModifiers[i]]);
- }
-
- if ((identifier == '2A' && contains(modifiers, 'L_SHIFT')) ||
- (identifier == '36' && contains(modifiers, 'R_SHIFT')) ||
- (identifier == '1D' && contains(modifiers, 'L_CTRL')) ||
- (identifier == 'E0 1D' && contains(modifiers, 'R_CTRL')) ||
- (identifier == '38' && contains(modifiers, 'L_ALT')) ||
- (identifier == 'E0 38' && contains(modifiers, 'R_ALT')) ||
- (identifier == 'E0 5B' && contains(modifiers, 'SEARCH'))) {
- classes.push('pressed');
- classes.push(IDENTIFIER_TO_CLASS[identifier]);
- }
- return classes;
-}
-
-/**
- * Returns true if a character is a ASCII character.
- * @param {string} c A character to be checked.
- * @return {boolean} True if the character is an ASCII character.
- */
-function isAscii(c) {
- var charCode = c.charCodeAt(0);
- return 0x00 <= charCode && charCode <= 0x7F;
-}
-
-/**
- * Returns a remapped identiifer based on the preference.
- * @param {string} identifier Key identifier.
- * @return {string} Remapped identifier.
- */
-function remapIdentifier(identifier) {
- return identifierMap[identifier] || identifier;
-}
-
-/**
- * Returns a label of the key.
- * @param {string} keyData Key glyph data.
- * @param {Array} modifiers Key Modifier list.
- * @return {string} Label of the key.
- */
-function getKeyLabel(keyData, modifiers) {
- if (!keyData) {
- return '';
- }
- if (keyData.label) {
- return keyData.label;
- }
- var keyLabel = '';
- for (var j = 1; j <= 9; j++) {
- var pos = keyData['p' + j];
- if (!pos) {
- continue;
- }
- keyLabel = hex2char(pos);
- if (!keyLabel) {
- continue;
- }
- if (isAscii(keyLabel) &&
- getShortcutData()[getAction(keyLabel, modifiers)]) {
- break;
- }
- }
- return keyLabel;
-}
-
-/**
- * Returns a normalized string used for a key of shortcutData.
- *
- * Examples:
- * keyCode: 'd', modifiers: ['CTRL', 'SHIFT'] => 'd<>CTRL<>SHIFT'
- * keyCode: 'alt', modifiers: ['ALT', 'SHIFT'] => 'ALT<>SHIFT'
- *
- * @param {string} keyCode Key code.
- * @param {Array} modifiers Key Modifier list.
- * @return {string} Normalized key shortcut data string.
- */
-function getAction(keyCode, modifiers) {
- /** @const */ var separatorStr = '<>';
- if (keyCode.toUpperCase() in MODIFIER_TO_CLASS) {
- keyCode = keyCode.toUpperCase();
- if (keyCode in modifiers) {
- return modifiers.join(separatorStr);
- } else {
- var action = [keyCode].concat(modifiers);
- action.sort();
- return action.join(separatorStr);
- }
- }
- return [keyCode].concat(modifiers).join(separatorStr);
-}
-
-/**
- * Returns a text which displayed on a key.
- * @param {string} keyData Key glyph data.
- * @return {string} Key text value.
- */
-function getKeyTextValue(keyData) {
- if (keyData.label) {
- // Do not show text on the space key.
- if (keyData.label == 'space') {
- return '';
- }
- // some key labels define actions such as 'mute' or 'vol. up'. Those actions
- // should be localized (crbug.com/471025).
- var localizedLabel = LABEL_TO_LOCALIZED_LABEL_ID[keyData.label];
- if (localizedLabel)
- return loadTimeData.getString(localizedLabel);
-
- return keyData.label;
- }
-
- var chars = [];
- for (var j = 1; j <= 9; ++j) {
- var pos = keyData['p' + j];
- if (pos && pos.length > 0) {
- chars.push(hex2char(pos));
- }
- }
- return chars.join(' ');
-}
-
-/**
- * Updates the whole keyboard.
- * @param {Array} modifiers Key Modifier list.
- * @param {Array} normModifiers Key Modifier list ignoring the distinction
- * between right and left keys.
- */
-function update(modifiers, normModifiers) {
- var instructions = $('instructions');
- if (modifiers.length == 0) {
- instructions.style.visibility = 'visible';
- } else {
- instructions.style.visibility = 'hidden';
- }
-
- var keyboardGlyphData = getKeyboardGlyphData();
- var shortcutData = getShortcutData();
- var layout = getLayout();
- for (var i = 0; i < layout.length; ++i) {
- var identifier = remapIdentifier(layout[i][0]);
- var keyData = keyboardGlyphData.keys[identifier];
- var classes = getKeyClasses(identifier, modifiers, normModifiers);
- var keyLabel = getKeyLabel(keyData, normModifiers);
- var shortcutId = shortcutData[getAction(keyLabel, normModifiers)];
- if (modifiers.length == 0 &&
- (identifier == '2A' || identifier == '36')) {
- // Either the right or left shift keys are used to disable the caps lock
- // if it was enabled. To fix crbug.com/453623.
- shortcutId = 'keyboardOverlayDisableCapsLock';
- }
- if (shortcutId) {
- classes.push('is-shortcut');
- }
-
- var key = $(keyId(identifier, i));
- key.className = classes.join(' ');
-
- if (!keyData) {
- continue;
- }
-
- var keyText = $(keyTextId(identifier, i));
- var keyTextValue = getKeyTextValue(keyData);
- if (keyTextValue) {
- keyText.style.visibility = 'visible';
- } else {
- keyText.style.visibility = 'hidden';
- }
- keyText.textContent = keyTextValue;
-
- var shortcutText = $(shortcutTextId(identifier, i));
- if (shortcutId) {
- shortcutText.style.visibility = 'visible';
- shortcutText.textContent = loadTimeData.getString(shortcutId);
- } else {
- shortcutText.style.visibility = 'hidden';
- }
-
- var format = keyboardGlyphData.keys[layout[i][0]].format;
- if (format) {
- if (format == 'left' || format == 'right') {
- shortcutText.style.textAlign = format;
- keyText.style.textAlign = format;
- }
- }
- }
-}
-
-/**
- * A callback function for onkeydown and onkeyup events.
- * @param {Event} e Key event.
- */
-function handleKeyEvent(e) {
- if (!getKeyboardOverlayId()) {
- return;
- }
-
- var modifiers = getModifiers(e);
-
- // To avoid flickering as the user releases the modifier keys that were held
- // to trigger the overlay, avoid updating in response to keyup events until at
- // least one keydown event has been received.
- if (!gotKeyDown) {
- if (e.type == 'keyup') {
- return;
- } else if (e.type == 'keydown') {
- gotKeyDown = true;
- }
- }
-
- var normModifiers = normalizeModifiers(modifiers);
- update(modifiers, normModifiers);
- KeyboardOverlayAccessibilityHelper.maybeSpeakAllShortcuts(normModifiers);
- e.preventDefault();
-}
-
-/**
- * Initializes the layout of the keys.
- */
-function initLayout() {
- // Add data for the caps lock key
- var keys = getKeyboardGlyphData().keys;
- if (!('3A' in keys)) {
- keys['3A'] = {label: 'caps lock', format: 'left'};
- }
- // Add data for the special key representing a disabled key
- keys['DISABLED'] = {label: 'disabled', format: 'left'};
-
- var layout = getLayout();
- var keyboard = document.body;
- var minX = window.innerWidth;
- var maxX = 0;
- var minY = window.innerHeight;
- var maxY = 0;
- var multiplier = 1.38 * window.innerWidth / BASE_KEYBOARD.width;
- var keyMargin = 7;
- var offsetX = 10;
- var offsetY = 7;
- for (var i = 0; i < layout.length; i++) {
- var array = layout[i];
- var identifier = remapIdentifier(array[0]);
- var x = Math.round((array[1] + offsetX) * multiplier);
- var y = Math.round((array[2] + offsetY) * multiplier);
- var w = Math.round((array[3] - keyMargin) * multiplier);
- var h = Math.round((array[4] - keyMargin) * multiplier);
-
- var key = document.createElement('div');
- key.id = keyId(identifier, i);
- key.className = 'keyboard-overlay-key';
- key.style.left = x + 'px';
- key.style.top = y + 'px';
- key.style.width = w + 'px';
- key.style.height = h + 'px';
-
- var keyText = document.createElement('div');
- keyText.id = keyTextId(identifier, i);
- keyText.className = 'keyboard-overlay-key-text';
- keyText.style.visibility = 'hidden';
- key.appendChild(keyText);
-
- var shortcutText = document.createElement('div');
- shortcutText.id = shortcutTextId(identifier, i);
- shortcutText.className = 'keyboard-overlay-shortcut-text';
- shortcutText.style.visilibity = 'hidden';
- key.appendChild(shortcutText);
- keyboard.appendChild(key);
-
- minX = Math.min(minX, x);
- maxX = Math.max(maxX, x + w);
- minY = Math.min(minY, y);
- maxY = Math.max(maxY, y + h);
- }
-
- var width = maxX - minX + 1;
- var height = maxY - minY + 1;
- keyboard.style.width = (width + 2 * (minX + 1)) + 'px';
- keyboard.style.height = (height + 2 * (minY + 1)) + 'px';
-
- var instructions = document.createElement('div');
- instructions.id = 'instructions';
- instructions.className = 'keyboard-overlay-instructions';
- instructions.style.left = ((BASE_INSTRUCTIONS.left - BASE_KEYBOARD.left) *
- width / BASE_KEYBOARD.width + minX) + 'px';
- instructions.style.top = ((BASE_INSTRUCTIONS.top - BASE_KEYBOARD.top) *
- height / BASE_KEYBOARD.height + minY) + 'px';
- instructions.style.width = (width * BASE_INSTRUCTIONS.width /
- BASE_KEYBOARD.width) + 'px';
- instructions.style.height = (height * BASE_INSTRUCTIONS.height /
- BASE_KEYBOARD.height) + 'px';
-
- var instructionsText = document.createElement('div');
- instructionsText.id = 'instructions-text';
- instructionsText.className = 'keyboard-overlay-instructions-text';
- instructionsText.innerHTML =
- loadTimeData.getString('keyboardOverlayInstructions');
- instructions.appendChild(instructionsText);
- var instructionsHideText = document.createElement('div');
- instructionsHideText.id = 'instructions-hide-text';
- instructionsHideText.className = 'keyboard-overlay-instructions-hide-text';
- instructionsHideText.innerHTML =
- loadTimeData.getString('keyboardOverlayInstructionsHide');
- instructions.appendChild(instructionsHideText);
- var learnMoreLinkText = document.createElement('div');
- learnMoreLinkText.id = 'learn-more-text';
- learnMoreLinkText.className = 'keyboard-overlay-learn-more-text';
- learnMoreLinkText.addEventListener('click', learnMoreClicked);
- var learnMoreLinkAnchor = document.createElement('a');
- learnMoreLinkAnchor.href =
- loadTimeData.getString('keyboardOverlayLearnMoreURL');
- learnMoreLinkAnchor.textContent =
- loadTimeData.getString('keyboardOverlayLearnMore');
- learnMoreLinkText.appendChild(learnMoreLinkAnchor);
- instructions.appendChild(learnMoreLinkText);
- keyboard.appendChild(instructions);
-}
-
-/**
- * Returns true if the device has a diamond key.
- * @return {boolean} Returns true if the device has a diamond key.
- */
-function hasDiamondKey() {
- return loadTimeData.getBoolean('keyboardOverlayHasChromeOSDiamondKey');
-}
-
-/**
- * Returns true if display scaling feature is enabled.
- * @return {boolean} True if display scaling feature is enabled.
- */
-function isDisplayUIScalingEnabled() {
- return loadTimeData.getBoolean('keyboardOverlayIsDisplayUIScalingEnabled');
-}
-
-/**
- * Initializes the layout and the key labels for the keyboard that has a diamond
- * key.
- */
-function initDiamondKey() {
- var newLayoutData = {
- '1D': [65.0, 287.0, 60.0, 60.0], // left Ctrl
- '38': [185.0, 287.0, 60.0, 60.0], // left Alt
- 'E0 5B': [125.0, 287.0, 60.0, 60.0], // search
- '3A': [5.0, 167.0, 105.0, 60.0], // caps lock
- '5B': [803.0, 6.0, 72.0, 35.0], // lock key
- '5D': [5.0, 287.0, 60.0, 60.0] // diamond key
- };
-
- var layout = getLayout();
- var powerKeyIndex = -1;
- var powerKeyId = '00';
- for (var i = 0; i < layout.length; i++) {
- var keyId = layout[i][0];
- if (keyId in newLayoutData) {
- layout[i] = [keyId].concat(newLayoutData[keyId]);
- delete newLayoutData[keyId];
- }
- if (keyId == powerKeyId)
- powerKeyIndex = i;
- }
- for (var keyId in newLayoutData)
- layout.push([keyId].concat(newLayoutData[keyId]));
-
- // Remove the power key.
- if (powerKeyIndex != -1)
- layout.splice(powerKeyIndex, 1);
-
- var keyData = getKeyboardGlyphData()['keys'];
- var newKeyData = {
- '3A': {'label': 'caps lock', 'format': 'left'},
- '5B': {'label': 'lock'},
- '5D': {'label': 'diamond', 'format': 'left'}
- };
- for (var keyId in newKeyData)
- keyData[keyId] = newKeyData[keyId];
-}
-
-/**
- * A callback function for the onload event of the body element.
- */
-function init() {
- document.addEventListener('keydown', handleKeyEvent);
- document.addEventListener('keyup', handleKeyEvent);
- chrome.send('getLabelMap');
-}
-
-/**
- * Initializes the global map for remapping identifiers of modifier keys based
- * on the preference.
- * Called after sending the 'getLabelMap' message.
- * @param {Object} remap Identifier map.
- */
-function initIdentifierMap(remap) {
- for (var key in remap) {
- var val = remap[key];
- if ((key in LABEL_TO_IDENTIFIER) &&
- (val in LABEL_TO_IDENTIFIER)) {
- identifierMap[LABEL_TO_IDENTIFIER[key]] =
- LABEL_TO_IDENTIFIER[val];
- } else {
- console.error('Invalid label map element: ' + key + ', ' + val);
- }
- }
- chrome.send('getInputMethodId');
-}
-
-/**
- * Initializes the global keyboad overlay ID and the layout of keys.
- * Called after sending the 'getInputMethodId' message.
- * @param {inputMethodId} inputMethodId Input Method Identifier.
- */
-function initKeyboardOverlayId(inputMethodId) {
- // Libcros returns an empty string when it cannot find the keyboard overlay ID
- // corresponding to the current input method.
- // In such a case, fallback to the default ID (en_US).
- var inputMethodIdToOverlayId =
- keyboardOverlayData['inputMethodIdToOverlayId'];
- if (inputMethodId) {
- if (inputMethodId.indexOf(IME_ID_PREFIX) == 0) {
- // If the input method is a component extension IME, remove the prefix:
- // _comp_ime_<ext_id>
- // The extension id is a hash value with 32 characters.
- inputMethodId = inputMethodId.slice(
- IME_ID_PREFIX.length + EXTENSION_ID_LEN);
- }
- keyboardOverlayId = inputMethodIdToOverlayId[inputMethodId];
- }
- if (!keyboardOverlayId) {
- console.error('No keyboard overlay ID for ' + inputMethodId);
- keyboardOverlayId = 'en_US';
- }
- while (document.body.firstChild) {
- document.body.removeChild(document.body.firstChild);
- }
- // We show Japanese layout as-is because the user has chosen the layout
- // that is quite diffrent from the physical layout that has a diamond key.
- if (hasDiamondKey() && getLayoutName() != 'J')
- initDiamondKey();
- initLayout();
- update([], []);
- window.webkitRequestAnimationFrame(function() {
- chrome.send('didPaint');
- });
-}
-
-/**
- * Handles click events of the learn more link.
- * @param {Event} e Mouse click event.
- */
-function learnMoreClicked(e) {
- chrome.send('openLearnMorePage');
- chrome.send('dialogClose');
- e.preventDefault();
-}
-
-document.addEventListener('DOMContentLoaded', init);
diff --git a/chromium/chrome/browser/resources/chromeos/keyboard_overlay_accessibility_helper.js b/chromium/chrome/browser/resources/chromeos/keyboard_overlay_accessibility_helper.js
deleted file mode 100644
index ff6c38673ab..00000000000
--- a/chromium/chrome/browser/resources/chromeos/keyboard_overlay_accessibility_helper.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2011 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.
-
-// An object to implement keyboard overlay accessibility.
-var KeyboardOverlayAccessibilityHelper = {
- // Returns true when ChromeVox is loaded and active, false otherwise.
- cvoxIsActive: function() {
- return window.cvox && window.cvox.Api.isChromeVoxActive();
- },
- // Speaks all the shortcut with the given modifiers.
- maybeSpeakAllShortcuts: function(modifiers) {
- if (!this.cvoxIsActive())
- return;
- cvox.Api.stop();
- var keyboardGlyphData = getKeyboardGlyphData();
- var shortcutData = getShortcutData();
- var layout = getLayouts()[keyboardGlyphData.layoutName];
- var keysToShortcutText = {};
- for (var i = 0; i < layout.length; ++i) {
- var identifier = remapIdentifier(layout[i][0]);
- var keyData = keyboardGlyphData.keys[identifier];
- var keyLabel = getKeyLabel(keyData, modifiers);
- var shortcutId = shortcutData[getAction(keyLabel, modifiers)];
- var shortcutText = templateData[shortcutId];
- var keysText = modifiers.concat(keyLabel).join(' + ');
- if (shortcutText)
- keysToShortcutText[keysText] = shortcutText;
- }
- for (var keysText in keysToShortcutText) {
- this.speakShortcut_(keysText, keysToShortcutText[keysText]);
- }
- },
- // Speaks given shortcut description.
- speakShortcut_: function(keysText, shortcutText) {
- keysText = keysText.toLowerCase(); // For correct pronunciation.
- cvox.Api.speak(keysText, 1, {});
- cvox.Api.speak(shortcutText, 1, {});
- },
-};
diff --git a/chromium/chrome/browser/resources/chromeos/keyboard_overlay_data.js b/chromium/chrome/browser/resources/chromeos/keyboard_overlay_data.js
deleted file mode 100644
index 4b056800243..00000000000
--- a/chromium/chrome/browser/resources/chromeos/keyboard_overlay_data.js
+++ /dev/null
@@ -1,15924 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is a generated file but may contain local modifications. See
-// src/tools/gen_keyboard_overlay_data/gen_keyboard_overlay_data.py --help
-
-var keyboardOverlayData = {
- 'inputMethodIdToOverlayId': {
- 'xkb:be::fra': 'fr',
- 'xkb:be::ger': 'de',
- 'xkb:be::nld': 'nl',
- 'xkb:bg::bul': 'bg',
- 'xkb:bg:phonetic:bul': 'bg',
- 'xkb:br::por': 'pt_BR',
- 'xkb:ca::fra': 'fr_CA',
- 'xkb:ca:eng:eng': 'ca',
- 'xkb:ch::ger': 'de',
- 'xkb:ch:fr:fra': 'fr',
- 'xkb:cz::cze': 'cs',
- 'xkb:de::ger': 'de',
- 'xkb:de:neo:ger': 'de_neo',
- 'xkb:dk::dan': 'da',
- 'xkb:ee::est': 'et',
- 'xkb:es::spa': 'es',
- 'xkb:es:cat:cat': 'ca',
- 'xkb:fi::fin': 'fi',
- 'xkb:fr::fra': 'fr',
- 'xkb:gb:dvorak:eng': 'en_GB_dvorak',
- 'xkb:gb:extd:eng': 'en_GB',
- 'xkb:gr::gre': 'el',
- 'xkb:hr::scr': 'hr',
- 'xkb:hu::hun': 'hu',
- 'xkb:il::heb': 'iw',
- 'xkb:it::ita': 'it',
- 'xkb:jp::jpn': 'ja',
- 'xkb:latam::spa': 'es_419',
- 'xkb:lt::lit': 'lt',
- 'xkb:lv:apostrophe:lav': 'lv',
- 'xkb:no::nob': 'no',
- 'xkb:pl::pol': 'pl',
- 'xkb:pt::por': 'pt_PT',
- 'xkb:ro::rum': 'ro',
- 'xkb:rs::srp': 'sr',
- 'xkb:ru::rus': 'ru',
- 'xkb:ru:phonetic:rus': 'ru',
- 'xkb:se::swe': 'sv',
- 'xkb:si::slv': 'sl',
- 'xkb:sk::slo': 'sk',
- 'xkb:tr::tur': 'tr',
- 'xkb:ua::ukr': 'uk',
- 'xkb:us::eng': 'en_US',
- 'xkb:us::ind': 'en_US',
- 'xkb:us::fil': 'en_US',
- 'xkb:us::msa': 'en_US',
- 'xkb:us:altgr-intl:eng': 'en_US_altgr_intl',
- 'xkb:us:colemak:eng': 'en_US_colemak',
- 'xkb:us:dvorak:eng': 'en_US_dvorak',
- 'xkb:us:intl:eng': 'en_US_intl',
- 'xkb:us:intl:nld': 'en_US_intl',
- 'xkb:us:intl:por': 'en_US_intl',
- 'vkd_ar': 'ar',
- 'vkd_fa': 'ar',
- 'vkd_deva_phone': 'hi',
- 'vkd_th': 'th',
- 'vkd_th_pattajoti': 'th',
- 'vkd_th_tis': 'th',
- 'vkd_vi_tcvn': 'vi',
- 'vkd_vi_telex': 'vi',
- 'vkd_vi_viqr': 'vi',
- 'vkd_vi_vni': 'vi',
- 'zh-hant-t-i0-cangjie-1987': 'zh_TW',
- 'zh-hant-t-i0-cangjie-1987-x-m0-simplified': 'zh_TW',
- 'zh-hant-t-i0-und': 'zh_TW',
- 'zh-t-i0-pinyin': 'zh_CN',
- 'hangul_2set': 'ko',
- 'hangul_3set390': 'ko',
- 'hangul_3setfinal': 'ko',
- 'hangul_3setnoshift': 'ko',
- 'hangul_romaja': 'ko',
- 'hangul_ahnmatae': 'ko',
- 'mozc-jp': 'ja',
- 'zinnia-japanese': 'ja'
- },
- 'keyboardGlyph': {
- 'ar': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31',
- 'p9': '661'
- },
- '03': {
- 'p1': '40',
- 'p7': '32',
- 'p9': '662'
- },
- '04': {
- 'p1': '23',
- 'p7': '33',
- 'p9': '663'
- },
- '05': {
- 'p1': '24',
- 'p7': '34',
- 'p9': '664'
- },
- '06': {
- 'p1': '66A',
- 'p7': '35',
- 'p9': '665'
- },
- '07': {
- 'p1': '5E',
- 'p7': '36',
- 'p9': '666'
- },
- '08': {
- 'p1': '26',
- 'p7': '37',
- 'p9': '667'
- },
- '09': {
- 'p1': '66D',
- 'p7': '38',
- 'p9': '668'
- },
- '0A': {
- 'p1': '28',
- 'p7': '39',
- 'p9': '669'
- },
- '0B': {
- 'p1': '29',
- 'p7': '30',
- 'p9': '660'
- },
- '0C': {
- 'p1': '5F',
- 'p7': '2D'
- },
- '0D': {
- 'p1': '2B',
- 'p7': '3D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p3': '064E',
- 'p7': '71',
- 'p9': 'FEBF'
- },
- '11': {
- 'p3': '064B',
- 'p7': '77',
- 'p9': 'FEBB'
- },
- '12': {
- 'p3': '064F',
- 'p7': '65',
- 'p9': 'FE9B'
- },
- '13': {
- 'p3': '064C',
- 'p7': '72',
- 'p9': 'FED7'
- },
- '14': {
- 'p3': 'FEF9',
- 'p7': '74',
- 'p9': 'FED3'
- },
- '15': {
- 'p3': 'FE87',
- 'p7': '79',
- 'p9': 'FECF'
- },
- '16': {
- 'p3': '60',
- 'p7': '75',
- 'p9': 'FECB'
- },
- '17': {
- 'p3': 'F7',
- 'p7': '69',
- 'p9': 'FEEB'
- },
- '18': {
- 'p3': 'D7',
- 'p7': '6F',
- 'p9': 'FEA7'
- },
- '19': {
- 'p3': '61B',
- 'p7': '70',
- 'p9': 'FEA3'
- },
- '1A': {
- 'p3': '3C',
- 'p9': 'FE9F'
- },
- '1B': {
- 'p3': '3E',
- 'p9': 'FEA9'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p3': '650',
- 'p7': '61',
- 'p9': 'FEB7'
- },
- '1F': {
- 'p3': '064D',
- 'p7': '73',
- 'p9': 'FEB3'
- },
- '20': {
- 'p3': '005B',
- 'p7': '64',
- 'p9': 'FEF3'
- },
- '21': {
- 'p3': '005D',
- 'p7': '66',
- 'p9': 'FE91'
- },
- '22': {
- 'p3': 'FEF7',
- 'p7': '67',
- 'p9': 'FEDF'
- },
- '23': {
- 'p3': 'FE83',
- 'p7': '68',
- 'p9': 'FE8D'
- },
- '24': {
- 'p3': '640',
- 'p7': '6A',
- 'p9': 'FE97'
- },
- '25': {
- 'p3': '060C',
- 'p7': '6B',
- 'p9': 'FEE7'
- },
- '26': {
- 'p3': '002F',
- 'p7': '6C',
- 'p9': 'FEE3'
- },
- '27': {
- 'p3': '003A',
- 'p9': 'FEDB'
- },
- '28': {
- 'p3': '22',
- 'p9': 'FEC3'
- },
- '29': {
- 'p1': '007E',
- 'p3': 'FE7C',
- 'p7': '60',
- 'p9': 'FEAB'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '007c',
- 'p7': '005c'
- },
- '2C': {
- 'p3': '007E',
- 'p7': '7A',
- 'p9': 'FE8B'
- },
- '2D': {
- 'p3': 'FE7E',
- 'p7': '78',
- 'p9': 'FE80'
- },
- '2E': {
- 'p3': '007B',
- 'p7': '63',
- 'p9': 'FE85'
- },
- '2F': {
- 'p3': '007D',
- 'p7': '76',
- 'p9': 'FEAD'
- },
- '30': {
- 'p3': 'FEF5',
- 'p7': '62',
- 'p9': 'FEFB'
- },
- '31': {
- 'p3': 'FE81',
- 'p7': '6E',
- 'p9': 'FEEF'
- },
- '32': {
- 'p3': '27',
- 'p7': '6D',
- 'p9': 'FE93'
- },
- '33': {
- 'p3': '002C',
- 'p9': 'FEED'
- },
- '34': {
- 'p3': '002E',
- 'p9': 'FEAF'
- },
- '35': {
- 'p3': '61F',
- 'p9': 'FEC7'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'bg': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31'
- },
- '03': {
- 'p1': '40',
- 'p3': '003f',
- 'p7': '32'
- },
- '04': {
- 'p1': '23',
- 'p3': '002b',
- 'p7': '33'
- },
- '05': {
- 'p1': '24',
- 'p3': '22',
- 'p7': '34'
- },
- '06': {
- 'p1': '25',
- 'p7': '35'
- },
- '07': {
- 'p1': '5e',
- 'p3': '003d',
- 'p7': '36'
- },
- '08': {
- 'p1': '26',
- 'p3': '003a',
- 'p7': '37'
- },
- '09': {
- 'p1': '2a',
- 'p3': '002f',
- 'p7': '38'
- },
- '0A': {
- 'p1': '28',
- 'p3': '005f',
- 'p7': '39'
- },
- '0B': {
- 'p1': '29',
- 'p3': '2116',
- 'p7': '30'
- },
- '0C': {
- 'p1': '5f',
- 'p3': '49',
- 'p7': '002d'
- },
- '0D': {
- 'p1': '2b',
- 'p3': '56',
- 'p7': '3d',
- 'p9': '002e'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p1': '71',
- 'p3': '44b',
- 'p9': '2c'
- },
- '11': {
- 'p1': '77',
- 'p9': '443'
- },
- '12': {
- 'p1': '65',
- 'p9': '435'
- },
- '13': {
- 'p1': '72',
- 'p9': '438'
- },
- '14': {
- 'p1': '74',
- 'p9': '448'
- },
- '15': {
- 'p1': '79',
- 'p9': '449'
- },
- '16': {
- 'p1': '75',
- 'p9': '43a'
- },
- '17': {
- 'p1': '69',
- 'p9': '441'
- },
- '18': {
- 'p1': '6f',
- 'p9': '434'
- },
- '19': {
- 'p1': '70',
- 'p9': '437'
- },
- '1A': {
- 'p1': '7b',
- 'p7': '5b',
- 'p9': '446'
- },
- '1B': {
- 'p1': '7d',
- 'p3': 'a7',
- 'p7': '5d',
- 'p9': '3b'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p1': '61',
- 'p9': '44c'
- },
- '1F': {
- 'p1': '73',
- 'p9': '44f'
- },
- '20': {
- 'p1': '64',
- 'p9': '430'
- },
- '21': {
- 'p1': '66',
- 'p9': '43e'
- },
- '22': {
- 'p1': '67',
- 'p9': '436'
- },
- '23': {
- 'p1': '68',
- 'p9': '433'
- },
- '24': {
- 'p1': '6a',
- 'p9': '442'
- },
- '25': {
- 'p1': '6b',
- 'p9': '43d'
- },
- '26': {
- 'p1': '6c',
- 'p9': '432'
- },
- '27': {
- 'p1': '3a',
- 'p7': '3b',
- 'p9': '43c'
- },
- '28': {
- 'p1': '201E',
- 'p7': '27',
- 'p9': '447'
- },
- '29': {
- 'p1': '007e',
- 'p7': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '7c',
- 'p3': '29',
- 'p7': '5c',
- 'p9': '28'
- },
- '2C': {
- 'p1': '7a',
- 'p9': '44e'
- },
- '2D': {
- 'p1': '78',
- 'p9': '439'
- },
- '2E': {
- 'p1': '63',
- 'p9': '44a'
- },
- '2F': {
- 'p1': '76',
- 'p9': '44d'
- },
- '30': {
- 'p1': '62',
- 'p9': '444'
- },
- '31': {
- 'p1': '6e',
- 'p9': '445'
- },
- '32': {
- 'p1': '6d',
- 'p9': '43f'
- },
- '33': {
- 'p1': '3c',
- 'p7': '2c',
- 'p9': '440'
- },
- '34': {
- 'p1': '3e',
- 'p7': '2e',
- 'p9': '43b'
- },
- '35': {
- 'p1': '3f',
- 'p7': '2f',
- 'p9': '431'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'ca': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31',
- 'p9': '007C'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '40'
- },
- '04': {
- 'p2': '00B7',
- 'p8': '33',
- 'p9': '23'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': '007E'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36',
- 'p9': '00AC'
- },
- '08': {
- 'p2': '002F',
- 'p8': '37'
- },
- '09': {
- 'p2': '28',
- 'p8': '38'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39'
- },
- '0B': {
- 'p2': '003D',
- 'p8': '30'
- },
- '0C': {
- 'p2': '003F',
- 'p8': '27'
- },
- '0D': {
- 'p2': '00BF',
- 'p8': '00A1'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '005E',
- 'p8': '60',
- 'p9': '005B'
- },
- '1B': {
- 'p2': '002A',
- 'p8': '002B',
- 'p9': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': '00F1'
- },
- '28': {
- 'p2': '00A8',
- 'p8': '00B4',
- 'p9': '007B'
- },
- '29': {
- 'p2': '00AA',
- 'p8': '00BA',
- 'p9': '005C'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '00C7',
- 'p8': 'E7',
- 'p9': '007D'
- },
- '2C': {
- 'p5': '007A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D'
- },
- '33': {
- 'p2': '003B',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003A',
- 'p8': '002E'
- },
- '35': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '003E',
- 'p8': '003C'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'cs': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p3': '31',
- 'p7': '31',
- 'p9': '002b'
- },
- '03': {
- 'p1': '40',
- 'p3': '32',
- 'p7': '32',
- 'p9': '011B'
- },
- '04': {
- 'p1': '23',
- 'p3': '33',
- 'p7': '33',
- 'p9': '161'
- },
- '05': {
- 'p1': '24',
- 'p3': '34',
- 'p7': '34',
- 'p9': '010d'
- },
- '06': {
- 'p1': '25',
- 'p3': '35',
- 'p7': '35',
- 'p9': '159'
- },
- '07': {
- 'p1': '5e',
- 'p3': '36',
- 'p7': '36',
- 'p9': '017e'
- },
- '08': {
- 'p1': '26',
- 'p3': '37',
- 'p7': '37',
- 'p9': 'fd'
- },
- '09': {
- 'p1': '2a',
- 'p3': '38',
- 'p7': '38',
- 'p9': 'e1'
- },
- '0A': {
- 'p1': '28',
- 'p3': '39',
- 'p7': '39',
- 'p9': 'ed'
- },
- '0B': {
- 'p1': '29',
- 'p3': '30',
- 'p7': '30',
- 'p9': 'e9'
- },
- '0C': {
- 'p1': '5f',
- 'p3': '25',
- 'p7': '2d',
- 'p9': '3d'
- },
- '0D': {
- 'p1': '2b',
- 'p3': '2c7',
- 'p7': '3d',
- 'p9': 'b4'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20ac'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '7A',
- 'p9': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p1': '7b',
- 'p3': '002f',
- 'p7': '5b',
- 'p9': 'fa'
- },
- '1B': {
- 'p1': '7d',
- 'p3': '28',
- 'p7': '5d',
- 'p9': '29'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p1': '3a',
- 'p3': '22',
- 'p7': '3b',
- 'p9': '16f'
- },
- '28': {
- 'p1': '22',
- 'p3': '21',
- 'p7': '27',
- 'p9': 'a7'
- },
- '29': {
- 'p1': '7e',
- 'p3': 'b0',
- 'p7': '60',
- 'p9': '3b'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '007c',
- 'p3': '27',
- 'p7': '5c',
- 'p9': 'a8'
- },
- '2C': {
- 'p5': '79',
- 'p9': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p1': '3c',
- 'p3': '3f',
- 'p7': '2c',
- 'p9': '2c'
- },
- '34': {
- 'p1': '3e',
- 'p3': '3a',
- 'p7': '2e',
- 'p9': '2e'
- },
- '35': {
- 'p1': '3f',
- 'p3': '5f',
- 'p7': '2f',
- 'p9': '2d'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p1': '7c',
- 'p3': '2a',
- 'p7': '5c',
- 'p9': '26'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'da': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31'
- },
- '03': {
- 'p1': '22',
- 'p7': '32',
- 'p9': '40'
- },
- '04': {
- 'p1': '23',
- 'p7': '33',
- 'p9': '00A3'
- },
- '05': {
- 'p1': '00A4',
- 'p7': '34',
- 'p9': '24'
- },
- '06': {
- 'p1': '25',
- 'p7': '35'
- },
- '07': {
- 'p1': '26',
- 'p7': '36'
- },
- '08': {
- 'p1': '002F',
- 'p7': '37',
- 'p9': '007B'
- },
- '09': {
- 'p1': '28',
- 'p7': '38',
- 'p9': '005B'
- },
- '0A': {
- 'p1': '29',
- 'p7': '39',
- 'p9': '005D'
- },
- '0B': {
- 'p1': '003D',
- 'p7': '30',
- 'p9': '007D'
- },
- '0C': {
- 'p1': '003F',
- 'p7': '002B'
- },
- '0D': {
- 'p1': '60',
- 'p7': '00B4',
- 'p9': '007C'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': 'E5'
- },
- '1B': {
- 'p1': '005E',
- 'p7': '00A8',
- 'p9': '007E'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': 'E6'
- },
- '28': {
- 'p5': '00F8'
- },
- '29': {
- 'p1': '00A7',
- 'p7': '00BD'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '002A',
- 'p7': '27'
- },
- '2C': {
- 'p5': '007A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D'
- },
- '33': {
- 'p1': '003B',
- 'p7': '002C'
- },
- '34': {
- 'p1': '003A',
- 'p7': '002E'
- },
- '35': {
- 'p1': '005F',
- 'p7': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p1': '003E',
- 'p7': '003C',
- 'p9': '005C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'de': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '00B2'
- },
- '04': {
- 'p2': '00A7',
- 'p8': '33',
- 'p9': '00B3'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36'
- },
- '08': {
- 'p2': '002F',
- 'p8': '37',
- 'p9': '007B'
- },
- '09': {
- 'p2': '28',
- 'p8': '38',
- 'p9': '005B'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39',
- 'p9': '005D'
- },
- '0B': {
- 'p2': '3D',
- 'p8': '30',
- 'p9': '7D'
- },
- '0C': {
- 'p2': '3F',
- 'p8': 'DF',
- 'p9': '5C'
- },
- '0D': {
- 'p2': '60',
- 'p8': 'B4'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '40'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '007A'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': '00FC'
- },
- '1B': {
- 'p2': '2A',
- 'p8': '2B',
- 'p9': '7E'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'strg'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': '00F6'
- },
- '28': {
- 'p5': 'E4'
- },
- '29': {
- 'p2': '00B0',
- 'p8': '005E'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '27',
- 'p8': '23'
- },
- '2C': {
- 'p5': '79'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D',
- 'p9': 'B5'
- },
- '33': {
- 'p2': '3B',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3A',
- 'p8': '2E'
- },
- '35': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '3E',
- 'p8': '3C',
- 'p9': '7C'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'strg'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'de_neo': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '00B0',
- 'p8': '31',
- 'p9': '00B9'
- },
- '03': {
- 'p2': '00A7',
- 'p8': '32',
- 'p9': '00B2'
- },
- '04': {
- 'p2': '2113',
- 'p8': '33',
- 'p9': '00B3'
- },
- '05': {
- 'p2': '00BB',
- 'p8': '34',
- 'p9': '203A'
- },
- '06': {
- 'p2': '00AB',
- 'p8': '35',
- 'p9': '2039'
- },
- '07': {
- 'p2': '24',
- 'p8': '36',
- 'p9': '00A2'
- },
- '08': {
- 'p2': '20AC',
- 'p8': '37',
- 'p9': '00A5'
- },
- '09': {
- 'p2': '201E',
- 'p8': '38',
- 'p9': '201A'
- },
- '0A': {
- 'p2': '201C',
- 'p8': '39',
- 'p9': '2018'
- },
- '0B': {
- 'p2': '201D',
- 'p8': '30',
- 'p9': '2019'
- },
- '0C': {
- 'p2': '2014',
- 'p8': '2D'
- },
- '0D': {
- 'p2': '00B8',
- 'p8': '02CB',
- 'p9': '02DA'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '78',
- 'p9': '2026'
- },
- '11': {
- 'p5': '76',
- 'p9': '005F'
- },
- '12': {
- 'p5': '6C',
- 'p9': '005B'
- },
- '13': {
- 'p5': '63',
- 'p9': '005D'
- },
- '14': {
- 'p5': '77',
- 'p9': '005E'
- },
- '15': {
- 'p5': '6B',
- 'p9': '21'
- },
- '16': {
- 'p5': '68',
- 'p9': '003C'
- },
- '17': {
- 'p5': '67',
- 'p9': '003E'
- },
- '18': {
- 'p5': '66',
- 'p9': '003D'
- },
- '19': {
- 'p5': '71',
- 'p9': '26'
- },
- '1A': {
- 'p5': 'DF',
- 'p9': '017F'
- },
- '1B': {
- 'p2': '02DC',
- 'p8': '02CA',
- 'p9': '002F'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'strg'
- },
- '1E': {
- 'p5': '75',
- 'p9': '005C'
- },
- '1F': {
- 'p5': '69',
- 'p9': '002F'
- },
- '20': {
- 'p5': '61',
- 'p9': '007B'
- },
- '21': {
- 'p5': '65',
- 'p9': '007D'
- },
- '22': {
- 'p5': '6F',
- 'p9': '002A'
- },
- '23': {
- 'p5': '73',
- 'p9': '003F'
- },
- '24': {
- 'p5': '6E',
- 'p9': '28'
- },
- '25': {
- 'p5': '72',
- 'p9': '29'
- },
- '26': {
- 'p5': '74',
- 'p9': '002D'
- },
- '27': {
- 'p5': '64',
- 'p9': '003A'
- },
- '28': {
- 'p5': '79',
- 'p9': '40'
- },
- '29': {
- 'p2': '02C7',
- 'p8': '02C6'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'label': 'mod3'
- },
- '2C': {
- 'p5': '00FC',
- 'p9': '23'
- },
- '2D': {
- 'p5': '00F6',
- 'p9': '24'
- },
- '2E': {
- 'p5': 'E4',
- 'p9': '007C'
- },
- '2F': {
- 'p5': '70',
- 'p9': '007E'
- },
- '30': {
- 'p5': '7a',
- 'p9': '60'
- },
- '31': {
- 'p5': '62',
- 'p9': '002B'
- },
- '32': {
- 'p5': '6D',
- 'p9': '25'
- },
- '33': {
- 'p2': '2013',
- 'p8': '2C',
- 'p9': '22'
- },
- '34': {
- 'p2': '2022',
- 'p8': '2E',
- 'p9': '27'
- },
- '35': {
- 'p5': '6A',
- 'p9': '003B'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'label': 'mod4'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'strg'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'mod4'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'mod3'
- }
- },
- 'layoutName': 'E'
- },
- 'el': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'Esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31'
- },
- '03': {
- 'p1': '40',
- 'p7': '32'
- },
- '04': {
- 'p1': '23',
- 'p7': '33'
- },
- '05': {
- 'p1': '24',
- 'p7': '34'
- },
- '06': {
- 'p1': '25',
- 'p7': '35'
- },
- '07': {
- 'p1': '005E',
- 'p7': '36'
- },
- '08': {
- 'p1': '26',
- 'p7': '37'
- },
- '09': {
- 'p1': '002A',
- 'p7': '38'
- },
- '0A': {
- 'p1': '28',
- 'p7': '39'
- },
- '0B': {
- 'p1': '29',
- 'p7': '30'
- },
- '0C': {
- 'p1': '005F',
- 'p7': '002D'
- },
- '0D': {
- 'p1': '002B',
- 'p7': '003D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p1': '51',
- 'p3': '3A',
- 'p9': '3B'
- },
- '11': {
- 'p1': '57',
- 'p9': '3C2'
- },
- '12': {
- 'p1': '45',
- 'p9': '20AC'
- },
- '13': {
- 'p1': '52',
- 'p9': '03A1'
- },
- '14': {
- 'p1': '54'
- },
- '15': {
- 'p1': '03A5'
- },
- '16': {
- 'p1': '55',
- 'p9': '398'
- },
- '17': {
- 'p1': '399'
- },
- '18': {
- 'p1': '039F'
- },
- '19': {
- 'p1': '50',
- 'p9': '03A0'
- },
- '1A': {
- 'p1': '007B',
- 'p7': '005B'
- },
- '1B': {
- 'p1': '007D',
- 'p7': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'Ctrl'
- },
- '1E': {
- 'p1': '391'
- },
- '1F': {
- 'p1': '53',
- 'p9': '03A3'
- },
- '20': {
- 'p1': '44',
- 'p9': '394'
- },
- '21': {
- 'p1': '46',
- 'p9': '3A6'
- },
- '22': {
- 'p1': '47',
- 'p9': '393'
- },
- '23': {
- 'p1': '397'
- },
- '24': {
- 'p1': '004A',
- 'p9': '039E'
- },
- '25': {
- 'p1': '039A'
- },
- '26': {
- 'p1': '004C',
- 'p9': '039B'
- },
- '27': {
- 'p1': '003A',
- 'p3': '00A8',
- 'p7': '003B',
- 'p9': '00B4'
- },
- '28': {
- 'p1': '22',
- 'p7': '27'
- },
- '29': {
- 'p1': '007E',
- 'p7': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '007C',
- 'p7': '005C'
- },
- '2C': {
- 'p1': '396'
- },
- '2D': {
- 'p1': '03A7'
- },
- '2E': {
- 'p1': '43',
- 'p9': '03A8'
- },
- '2F': {
- 'p1': '56',
- 'p9': '03A9'
- },
- '30': {
- 'p1': '392'
- },
- '31': {
- 'p1': '039D'
- },
- '32': {
- 'p1': '039C'
- },
- '33': {
- 'p1': '003C',
- 'p7': '002C'
- },
- '34': {
- 'p1': '003E',
- 'p7': '002E'
- },
- '35': {
- 'p1': '003F',
- 'p7': '002F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'Alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {},
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'Ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'Alt Gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'en_GB': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32'
- },
- '04': {
- 'p2': 'A3',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': '20AC'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '5E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '0D': {
- 'p2': '2B',
- 'p8': '3D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '7B',
- 'p8': '5B'
- },
- '1B': {
- 'p2': '7D',
- 'p8': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '28': {
- 'p2': '40',
- 'p8': '27'
- },
- '29': {
- 'p2': 'AC',
- 'p8': '60',
- 'p9': '00A6'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '007E',
- 'p8': '23'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '35': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '007C',
- 'p8': '005C'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'en_GB_dvorak': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32'
- },
- '04': {
- 'p2': 'A3',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': '20AC'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '5E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '7B',
- 'p8': '5B'
- },
- '0D': {
- 'p2': '7D',
- 'p8': '5D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p2': '40',
- 'p8': '27'
- },
- '11': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '12': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '13': {
- 'p5': '70'
- },
- '14': {
- 'p5': '79'
- },
- '15': {
- 'p5': '66'
- },
- '16': {
- 'p5': '67'
- },
- '17': {
- 'p5': '63'
- },
- '18': {
- 'p5': '72'
- },
- '19': {
- 'p5': '6C'
- },
- '1A': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '1B': {
- 'p2': '2B',
- 'p8': '3D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '6F'
- },
- '20': {
- 'p5': '65'
- },
- '21': {
- 'p5': '75'
- },
- '22': {
- 'p5': '69'
- },
- '23': {
- 'p5': '64'
- },
- '24': {
- 'p5': '68'
- },
- '25': {
- 'p5': '74'
- },
- '26': {
- 'p5': '6E'
- },
- '27': {
- 'p5': '73'
- },
- '28': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '29': {
- 'p2': 'AC',
- 'p8': '60',
- 'p9': '00A6'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '007E',
- 'p8': '23'
- },
- '2C': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '2D': {
- 'p5': '71'
- },
- '2E': {
- 'p5': '6A'
- },
- '2F': {
- 'p5': '6B'
- },
- '30': {
- 'p5': '78'
- },
- '31': {
- 'p5': '62'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p5': '77'
- },
- '34': {
- 'p5': '76'
- },
- '35': {
- 'p5': '7A'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '007C',
- 'p8': '005C'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'en_US': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '5E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '0D': {
- 'p2': '2B',
- 'p8': '3D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '7B',
- 'p8': '5B'
- },
- '1B': {
- 'p2': '7D',
- 'p8': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '7E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '7C',
- 'p8': '5C'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '35': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'en_US_altgr_intl': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '5E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '0D': {
- 'p2': '2B',
- 'p8': '3D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '7B',
- 'p8': '5B'
- },
- '1B': {
- 'p2': '7D',
- 'p8': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '7E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '7C',
- 'p8': '5C'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '35': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'en_US_colemak': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '5E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '0D': {
- 'p2': '2B',
- 'p8': '3D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '66'
- },
- '13': {
- 'p5': '70'
- },
- '14': {
- 'p5': '67'
- },
- '15': {
- 'p5': '6A'
- },
- '16': {
- 'p5': '6C'
- },
- '17': {
- 'p5': '75'
- },
- '18': {
- 'p5': '79'
- },
- '19': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '1A': {
- 'p2': '7B',
- 'p8': '5B'
- },
- '1B': {
- 'p2': '7D',
- 'p8': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '72'
- },
- '20': {
- 'p5': '73'
- },
- '21': {
- 'p5': '74'
- },
- '22': {
- 'p5': '64'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6E'
- },
- '25': {
- 'p5': '65'
- },
- '26': {
- 'p5': '69'
- },
- '27': {
- 'p5': '6F'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '7E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '7C',
- 'p8': '5C'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6B'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '35': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'backspace'
- }
- },
- 'layoutName': 'U'
- },
- 'en_US_dvorak': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '5E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '7B',
- 'p8': '5B'
- },
- '0D': {
- 'p2': '7D',
- 'p8': '5D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p2': '22',
- 'p8': '27'
- },
- '11': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '12': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '13': {
- 'p5': '70'
- },
- '14': {
- 'p5': '79'
- },
- '15': {
- 'p5': '66'
- },
- '16': {
- 'p5': '67'
- },
- '17': {
- 'p5': '63'
- },
- '18': {
- 'p5': '72'
- },
- '19': {
- 'p5': '6C'
- },
- '1A': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '1B': {
- 'p2': '2B',
- 'p8': '3D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '6F'
- },
- '20': {
- 'p5': '65'
- },
- '21': {
- 'p5': '75'
- },
- '22': {
- 'p5': '69'
- },
- '23': {
- 'p5': '64'
- },
- '24': {
- 'p5': '68'
- },
- '25': {
- 'p5': '74'
- },
- '26': {
- 'p5': '6E'
- },
- '27': {
- 'p5': '73'
- },
- '28': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '29': {
- 'p2': '7E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '7C',
- 'p8': '5C'
- },
- '2C': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '2D': {
- 'p5': '71'
- },
- '2E': {
- 'p5': '6A'
- },
- '2F': {
- 'p5': '6B'
- },
- '30': {
- 'p5': '78'
- },
- '31': {
- 'p5': '62'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p5': '77'
- },
- '34': {
- 'p5': '76'
- },
- '35': {
- 'p5': '7A'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'en_US_intl': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '5E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '0D': {
- 'p2': '2B',
- 'p8': '3D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '7B',
- 'p8': '5B'
- },
- '1B': {
- 'p2': '7D',
- 'p8': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '7E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '7C',
- 'p8': '5C'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '35': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'es': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31',
- 'p9': '007C'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '40'
- },
- '04': {
- 'p2': '00B7',
- 'p8': '33',
- 'p9': '23'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': '007E'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36',
- 'p9': '00AC'
- },
- '08': {
- 'p2': '002F',
- 'p8': '37'
- },
- '09': {
- 'p2': '28',
- 'p8': '38'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39'
- },
- '0B': {
- 'p2': '003D',
- 'p8': '30'
- },
- '0C': {
- 'p2': '003F',
- 'p8': '27'
- },
- '0D': {
- 'p2': '00BF',
- 'p8': '00A1'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '005E',
- 'p8': '60',
- 'p9': '005B'
- },
- '1B': {
- 'p2': '002A',
- 'p8': '002B',
- 'p9': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': '00F1'
- },
- '28': {
- 'p2': '00A8',
- 'p8': '00B4',
- 'p9': '007B'
- },
- '29': {
- 'p2': '00AA',
- 'p8': '00BA',
- 'p9': '005C'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '00C7',
- 'p8': 'E7',
- 'p9': '007D'
- },
- '2C': {
- 'p5': '007A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D'
- },
- '33': {
- 'p2': '003B',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003A',
- 'p8': '002E'
- },
- '35': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '003E',
- 'p8': '003C'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'es_419': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36'
- },
- '08': {
- 'p2': '002F',
- 'p8': '37'
- },
- '09': {
- 'p2': '28',
- 'p8': '38'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39'
- },
- '0B': {
- 'p2': '3d',
- 'p8': '30'
- },
- '0C': {
- 'p2': '3f',
- 'p8': '27',
- 'p9': '005C'
- },
- '0D': {
- 'p2': 'a1',
- 'p8': 'bf'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '40'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6f'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': 'A8',
- 'p8': 'B4'
- },
- '1B': {
- 'p2': '2a',
- 'p8': '2b',
- 'p9': '7e'
- },
- '1C': {
- 'format': 'right',
- 'label': 'intro'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6a'
- },
- '25': {
- 'p5': '6b'
- },
- '26': {
- 'p5': '6c'
- },
- '27': {
- 'p5': 'f1'
- },
- '28': {
- 'p2': '5B',
- 'p8': '7B',
- 'p9': '5E'
- },
- '29': {
- 'p2': '00B0',
- 'p8': '007C',
- 'p9': '00AC'
- },
- '2A': {
- 'format': 'left',
- 'label': 'may\u00fas'
- },
- '2B': {
- 'p2': '5D',
- 'p8': '7D',
- 'p9': '60'
- },
- '2C': {
- 'p5': '7a'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6e'
- },
- '32': {
- 'p5': '6d'
- },
- '33': {
- 'p2': '3b',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3a',
- 'p8': '2e'
- },
- '35': {
- 'p2': '5f',
- 'p8': '2d'
- },
- '36': {
- 'format': 'right',
- 'label': 'may\u00fas'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '3e',
- 'p8': '3c'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'et': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '40'
- },
- '04': {
- 'p2': '23',
- 'p8': '33',
- 'p9': 'A3'
- },
- '05': {
- 'p2': 'A4',
- 'p8': '34',
- 'p9': '24'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36'
- },
- '08': {
- 'p2': '2F',
- 'p8': '37',
- 'p9': '7B'
- },
- '09': {
- 'p2': '28',
- 'p8': '38',
- 'p9': '5B'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39',
- 'p9': '5D'
- },
- '0B': {
- 'p2': '3D',
- 'p8': '30',
- 'p9': '7D'
- },
- '0C': {
- 'p2': '3F',
- 'p8': '2B',
- 'p9': '5C'
- },
- '0D': {
- 'p2': '60',
- 'p8': 'B4'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': 'FC'
- },
- '1B': {
- 'p5': 'F5',
- 'p9': 'A7'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': '00F6'
- },
- '28': {
- 'p5': 'E4',
- 'p9': '5E'
- },
- '29': {
- 'p2': '7E',
- 'p8': '2C7'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '2A',
- 'p8': '27',
- 'p9': 'BD'
- },
- '2C': {
- 'p5': '007A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D'
- },
- '33': {
- 'p2': '3B',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3A',
- 'p8': '2E'
- },
- '35': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '3E',
- 'p8': '3C',
- 'p9': '7C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'fi': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '40'
- },
- '04': {
- 'p2': '23',
- 'p8': '33',
- 'p9': '00A3'
- },
- '05': {
- 'p2': '00A4',
- 'p8': '34',
- 'p9': '24'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36'
- },
- '08': {
- 'p2': '002F',
- 'p8': '37',
- 'p9': '007B'
- },
- '09': {
- 'p2': '28',
- 'p8': '38',
- 'p9': '005B'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39',
- 'p9': '005D'
- },
- '0B': {
- 'p2': '003D',
- 'p8': '30',
- 'p9': '007D'
- },
- '0C': {
- 'p2': '003F',
- 'p8': '002B',
- 'p9': '005C'
- },
- '0D': {
- 'p2': '60',
- 'p8': '00B4'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': 'E5'
- },
- '1B': {
- 'p2': '005E',
- 'p8': '00A8',
- 'p9': '007E'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': '00F6'
- },
- '28': {
- 'p5': 'E4'
- },
- '29': {
- 'p2': '00BD',
- 'p8': '00A7'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '002A',
- 'p8': '27'
- },
- '2C': {
- 'p5': '007A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D'
- },
- '33': {
- 'p2': '003B',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003A',
- 'p8': '002E'
- },
- '35': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '003E',
- 'p8': '003C',
- 'p9': '007C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'fr': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': '\u00e9chap'
- },
- '02': {
- 'p2': '31',
- 'p8': '26'
- },
- '03': {
- 'p2': '32',
- 'p8': 'E9',
- 'p9': '007E'
- },
- '04': {
- 'p2': '33',
- 'p8': '22',
- 'p9': '23'
- },
- '05': {
- 'p2': '34',
- 'p8': '27',
- 'p9': '007B'
- },
- '06': {
- 'p2': '35',
- 'p8': '28',
- 'p9': '005B'
- },
- '07': {
- 'p2': '36',
- 'p8': '2D',
- 'p9': '007C'
- },
- '08': {
- 'p2': '37',
- 'p8': 'E8',
- 'p9': '60'
- },
- '09': {
- 'p2': '38',
- 'p8': '5F',
- 'p9': '005C'
- },
- '0A': {
- 'p2': '39',
- 'p8': 'E7',
- 'p9': '005E'
- },
- '0B': {
- 'p2': '30',
- 'p8': 'E0',
- 'p9': '40'
- },
- '0C': {
- 'p2': '00B0',
- 'p8': '29',
- 'p9': '005D'
- },
- '0D': {
- 'p2': '002B',
- 'p8': '003D',
- 'p9': '007D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '61'
- },
- '11': {
- 'p5': '007A'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': 'A8',
- 'p8': '5E'
- },
- '1B': {
- 'p2': 'A3',
- 'p8': '24',
- 'p9': 'A4'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '71'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': '006D'
- },
- '28': {
- 'p2': '25',
- 'p8': 'F9'
- },
- '29': {
- 'p8': 'B2'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': 'B5',
- 'p8': '2A'
- },
- '2C': {
- 'p5': '77'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p2': '3F',
- 'p8': '2C'
- },
- '33': {
- 'p2': '2E',
- 'p8': '3B'
- },
- '34': {
- 'p2': '2F',
- 'p8': '3A'
- },
- '35': {
- 'p2': 'A7',
- 'p8': '21'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '3E',
- 'p8': '3C'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'fr_CA': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': '\u00e9chap'
- },
- '02': {
- 'p2': '21',
- 'p8': '31',
- 'p9': 'B1'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '40'
- },
- '04': {
- 'p2': '2F',
- 'p8': '33',
- 'p9': 'A3'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': 'A2'
- },
- '06': {
- 'p2': '25',
- 'p8': '35',
- 'p9': 'A4'
- },
- '07': {
- 'p2': '3F',
- 'p8': '36',
- 'p9': 'AC'
- },
- '08': {
- 'p2': '26',
- 'p8': '37',
- 'p9': 'A6'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38',
- 'p9': 'B2'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39',
- 'p9': 'B3'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30',
- 'p9': 'BC'
- },
- '0C': {
- 'p2': '5F',
- 'p8': '2D',
- 'p9': 'BD'
- },
- '0D': {
- 'p2': '2B',
- 'p8': '3D',
- 'p9': 'BE'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F',
- 'p9': '00A7'
- },
- '19': {
- 'p5': '70',
- 'p9': '00B6'
- },
- '1A': {
- 'p2': '5E',
- 'p8': '5E',
- 'p9': '5B'
- },
- '1B': {
- 'p2': 'A8',
- 'p8': 'B8',
- 'p9': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '3A',
- 'p8': '3B',
- 'p9': '7E'
- },
- '28': {
- 'p2': '60',
- 'p8': '60',
- 'p9': '7B'
- },
- '29': {
- 'p2': '7C',
- 'p8': '23',
- 'p9': '5C'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '3E',
- 'p8': '3C',
- 'p9': '7D'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D',
- 'p9': '00B5'
- },
- '33': {
- 'p2': '27',
- 'p8': '2C',
- 'p9': 'AF'
- },
- '34': {
- 'p2': '2E',
- 'p8': '2E',
- 'p9': 'AD'
- },
- '35': {
- 'p2': 'C9',
- 'p8': 'E9',
- 'p9': 'B4'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': 'BB',
- 'p8': 'AB',
- 'p9': 'B0'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'hi': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p3': '090D',
- 'p7': '31',
- 'p9': '967'
- },
- '03': {
- 'p1': '40',
- 'p3': '945',
- 'p7': '32',
- 'p9': '968'
- },
- '04': {
- 'p1': '23',
- 'p3': '094D0930',
- 'p7': '33',
- 'p9': '969'
- },
- '05': {
- 'p1': '24',
- 'p3': '0930094D',
- 'p7': '34',
- 'p9': '96A'
- },
- '06': {
- 'p1': '25',
- 'p3': '091C094D091E',
- 'p7': '35',
- 'p9': '96B'
- },
- '07': {
- 'p1': '5E',
- 'p3': '0924094D0930',
- 'p7': '36',
- 'p9': '96C'
- },
- '08': {
- 'p1': '26',
- 'p3': '0915094D0937',
- 'p7': '37',
- 'p9': '96D'
- },
- '09': {
- 'p1': '2A',
- 'p3': '0936094D0930',
- 'p7': '38',
- 'p9': '96E'
- },
- '0A': {
- 'p1': '28',
- 'p3': '28',
- 'p7': '39',
- 'p9': '96F'
- },
- '0B': {
- 'p1': '29',
- 'p3': '29',
- 'p7': '30',
- 'p9': '966'
- },
- '0C': {
- 'p1': '5F',
- 'p3': '903',
- 'p7': '2D'
- },
- '0D': {
- 'p1': '2B',
- 'p3': '090B',
- 'p7': '3D',
- 'p9': '943'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p3': '914',
- 'p7': '71',
- 'p9': '094C'
- },
- '11': {
- 'p3': '910',
- 'p7': '77',
- 'p9': '948'
- },
- '12': {
- 'p3': '906',
- 'p7': '65',
- 'p9': '093E'
- },
- '13': {
- 'p3': '908',
- 'p7': '72',
- 'p9': '940'
- },
- '14': {
- 'p3': '090A',
- 'p7': '74',
- 'p9': '942'
- },
- '15': {
- 'p3': '092D',
- 'p7': '79',
- 'p9': '092C'
- },
- '16': {
- 'p3': '919',
- 'p7': '75',
- 'p9': '939'
- },
- '17': {
- 'p3': '918',
- 'p7': '69',
- 'p9': '917'
- },
- '18': {
- 'p3': '927',
- 'p7': '6F',
- 'p9': '926'
- },
- '19': {
- 'p3': '091D',
- 'p7': '70',
- 'p9': '091C'
- },
- '1A': {
- 'p1': '7B',
- 'p3': '922',
- 'p7': '5B',
- 'p9': '921'
- },
- '1B': {
- 'p1': '7D',
- 'p3': '091E',
- 'p7': '5D',
- 'p9': '093C'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p3': '913',
- 'p7': '61',
- 'p9': '094B'
- },
- '1F': {
- 'p3': '090F',
- 'p7': '73',
- 'p9': '947'
- },
- '20': {
- 'p3': '905',
- 'p7': '64',
- 'p9': '094D'
- },
- '21': {
- 'p3': '907',
- 'p7': '66',
- 'p9': '093F'
- },
- '22': {
- 'p3': '909',
- 'p7': '67',
- 'p9': '941'
- },
- '23': {
- 'p3': '092B',
- 'p7': '68',
- 'p9': '092A'
- },
- '24': {
- 'p3': '931',
- 'p7': '6A',
- 'p9': '930'
- },
- '25': {
- 'p3': '916',
- 'p7': '6B',
- 'p9': '915'
- },
- '26': {
- 'p3': '925',
- 'p7': '6C',
- 'p9': '924'
- },
- '27': {
- 'p1': '3A',
- 'p3': '091B',
- 'p7': '3B',
- 'p9': '091A'
- },
- '28': {
- 'p1': '22',
- 'p3': '920',
- 'p7': '27',
- 'p9': '091F'
- },
- '29': {
- 'p1': '7E',
- 'p3': '912',
- 'p7': '60',
- 'p9': '094A'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '7C',
- 'p3': '911',
- 'p7': '5C',
- 'p9': '949'
- },
- '2C': {
- 'p3': '090E',
- 'p7': '7A',
- 'p9': '946'
- },
- '2D': {
- 'p3': '901',
- 'p7': '78',
- 'p9': '902'
- },
- '2E': {
- 'p3': '923',
- 'p7': '63',
- 'p9': '092E'
- },
- '2F': {
- 'p3': '929',
- 'p7': '76',
- 'p9': '928'
- },
- '30': {
- 'p3': '934',
- 'p7': '62',
- 'p9': '935'
- },
- '31': {
- 'p3': '933',
- 'p7': '6E',
- 'p9': '932'
- },
- '32': {
- 'p3': '936',
- 'p7': '6D',
- 'p9': '938'
- },
- '33': {
- 'p1': '3C',
- 'p3': '937',
- 'p7': '2C',
- 'p9': '002C'
- },
- '34': {
- 'p1': '3E',
- 'p3': '964',
- 'p7': '2E',
- 'p9': '002E'
- },
- '35': {
- 'p1': '3F',
- 'p3': '095F',
- 'p7': '2F',
- 'p9': '092F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'hr': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31',
- 'p9': '007E'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '02C7'
- },
- '04': {
- 'p2': '23',
- 'p8': '33',
- 'p9': '005E'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': '02D8'
- },
- '06': {
- 'p2': '25',
- 'p8': '35',
- 'p9': '02DA'
- },
- '07': {
- 'p2': '26',
- 'p8': '36',
- 'p9': '02DB'
- },
- '08': {
- 'p2': '002F',
- 'p8': '37',
- 'p9': '60'
- },
- '09': {
- 'p2': '28',
- 'p8': '38',
- 'p9': '02D9'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39',
- 'p9': '00B4'
- },
- '0B': {
- 'p2': '003D',
- 'p8': '30',
- 'p9': '02DD'
- },
- '0C': {
- 'p2': '003F',
- 'p8': '27',
- 'p9': '00A8'
- },
- '0D': {
- 'p2': '002A',
- 'p8': '002B',
- 'p9': '00B8'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '005C'
- },
- '11': {
- 'p5': '77',
- 'p9': '007C'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '007A'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': '161',
- 'p9': '00F7'
- },
- '1B': {
- 'p5': '111',
- 'p9': '00D7'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66',
- 'p9': '005B'
- },
- '22': {
- 'p5': '67',
- 'p9': '005D'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B',
- 'p9': '142'
- },
- '26': {
- 'p5': '006C',
- 'p9': '141'
- },
- '27': {
- 'p5': '10D'
- },
- '28': {
- 'p5': '107',
- 'p9': '00DF'
- },
- '29': {
- 'p2': '00A8',
- 'p8': '00B8'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p5': '17E',
- 'p9': '00A4'
- },
- '2C': {
- 'p5': '79'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76',
- 'p9': '40'
- },
- '30': {
- 'p5': '62',
- 'p9': '007B'
- },
- '31': {
- 'p5': '006E',
- 'p9': '007D'
- },
- '32': {
- 'p5': '006D',
- 'p9': '00A7'
- },
- '33': {
- 'p2': '003B',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003A',
- 'p8': '002E'
- },
- '35': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '003E',
- 'p8': '003C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'hu': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '27',
- 'p8': '31',
- 'p9': '7e'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '2c7'
- },
- '04': {
- 'p2': '2b',
- 'p8': '33',
- 'p9': '5e'
- },
- '05': {
- 'p2': '21',
- 'p8': '34',
- 'p9': '2d8'
- },
- '06': {
- 'p2': '25',
- 'p8': '35',
- 'p9': '2da'
- },
- '07': {
- 'p2': '2f',
- 'p8': '36',
- 'p9': '2db'
- },
- '08': {
- 'p2': '3d',
- 'p8': '37',
- 'p9': '60'
- },
- '09': {
- 'p2': '28',
- 'p8': '38',
- 'p9': '2d9'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39',
- 'p9': 'b4'
- },
- '0B': {
- 'p5': 'f6',
- 'p9': '2dd'
- },
- '0C': {
- 'p5': 'fc',
- 'p9': 'a8'
- },
- '0D': {
- 'p5': 'f3',
- 'p9': 'b8'
- },
- '0E': {
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '5c'
- },
- '11': {
- 'p5': '77',
- 'p9': '7c'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '7a'
- },
- '16': {
- 'p5': '75',
- 'p9': '20ac'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6f'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': '151',
- 'p9': 'f7'
- },
- '1B': {
- 'p5': 'fa',
- 'p9': 'd7'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73',
- 'p9': '111'
- },
- '20': {
- 'p5': '64',
- 'p9': '110'
- },
- '21': {
- 'p5': '66',
- 'p9': '5b'
- },
- '22': {
- 'p5': '67',
- 'p9': '5d'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6a'
- },
- '25': {
- 'p5': '6b',
- 'p9': '142'
- },
- '26': {
- 'p5': '6c',
- 'p9': '141'
- },
- '27': {
- 'p5': 'e9',
- 'p9': '24'
- },
- '28': {
- 'p5': 'e1',
- 'p9': 'df'
- },
- '29': {
- 'p2': 'a7',
- 'p8': '30'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p5': '171',
- 'p9': 'a4'
- },
- '2C': {
- 'p5': '79',
- 'p9': '3e'
- },
- '2D': {
- 'p5': '78',
- 'p9': '23'
- },
- '2E': {
- 'p5': '63',
- 'p9': '26'
- },
- '2F': {
- 'p5': '76',
- 'p9': '40'
- },
- '30': {
- 'p5': '62',
- 'p9': '7b'
- },
- '31': {
- 'p5': '6e',
- 'p9': '7d'
- },
- '32': {
- 'p5': '6d'
- },
- '33': {
- 'p2': '3f',
- 'p8': '2c',
- 'p9': '3b'
- },
- '34': {
- 'p2': '3a',
- 'p8': '2e'
- },
- '35': {
- 'p2': '5f',
- 'p8': '2d',
- 'p9': '2a'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p5': 'ed',
- 'p9': '3c'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller'
- },
- 'E0 38': {
- 'format': 'smaller'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'it': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32'
- },
- '04': {
- 'p2': 'A3',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36'
- },
- '08': {
- 'p2': '2F',
- 'p8': '37'
- },
- '09': {
- 'p2': '28',
- 'p8': '38'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39'
- },
- '0B': {
- 'p2': '3D',
- 'p8': '30'
- },
- '0C': {
- 'p2': '3F',
- 'p8': '27'
- },
- '0D': {
- 'p2': '5E',
- 'p8': 'EC'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': 'E9',
- 'p8': 'E8',
- 'p9': '5B'
- },
- '1B': {
- 'p2': '2A',
- 'p8': '2B',
- 'p9': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'invio'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': 'E7',
- 'p8': 'F2',
- 'p9': '40'
- },
- '28': {
- 'p2': 'B0',
- 'p8': 'E0',
- 'p9': '23'
- },
- '29': {
- 'p2': '7C',
- 'p8': '5C'
- },
- '2A': {
- 'format': 'left',
- 'label': 'maiusc'
- },
- '2B': {
- 'p2': 'A7',
- 'p8': 'F9',
- 'p9': '60'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '3B',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3A',
- 'p8': '2E'
- },
- '35': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '36': {
- 'format': 'right',
- 'label': 'maiusc'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '3E',
- 'p8': '3C'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'iw': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31'
- },
- '03': {
- 'p1': '40',
- 'p7': '32'
- },
- '04': {
- 'p1': '23',
- 'p7': '33'
- },
- '05': {
- 'p1': '24',
- 'p3': '20aa',
- 'p7': '34'
- },
- '06': {
- 'p1': '25',
- 'p7': '35'
- },
- '07': {
- 'p1': '5E',
- 'p7': '36'
- },
- '08': {
- 'p1': '26',
- 'p7': '37'
- },
- '09': {
- 'p1': '2A',
- 'p7': '38'
- },
- '0A': {
- 'p1': '28',
- 'p7': '39'
- },
- '0B': {
- 'p1': '29',
- 'p7': '30'
- },
- '0C': {
- 'p1': '5F',
- 'p7': '2D'
- },
- '0D': {
- 'p1': '2B',
- 'p7': '3D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '2F'
- },
- '11': {
- 'p5': '77',
- 'p9': '27'
- },
- '12': {
- 'p3': '20ac',
- 'p5': '65',
- 'p9': '5e7'
- },
- '13': {
- 'p5': '72',
- 'p9': '5e8'
- },
- '14': {
- 'p5': '74',
- 'p9': '5D0'
- },
- '15': {
- 'p5': '79',
- 'p9': '5D8'
- },
- '16': {
- 'p5': '75',
- 'p9': '5D5'
- },
- '17': {
- 'p5': '69',
- 'p9': '5Df'
- },
- '18': {
- 'p5': '6F',
- 'p9': '5dd'
- },
- '19': {
- 'p5': '70',
- 'p9': '5e4'
- },
- '1A': {
- 'p1': '7b',
- 'p7': '5B'
- },
- '1B': {
- 'p1': '7D',
- 'p7': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61',
- 'p9': '5e9'
- },
- '1F': {
- 'p5': '73',
- 'p9': '5d3'
- },
- '20': {
- 'p5': '64',
- 'p9': '5d2'
- },
- '21': {
- 'p5': '66',
- 'p9': '5db'
- },
- '22': {
- 'p5': '67',
- 'p9': '5e2'
- },
- '23': {
- 'p5': '68',
- 'p9': '5d9'
- },
- '24': {
- 'p5': '6A',
- 'p9': '5d7'
- },
- '25': {
- 'p5': '6B',
- 'p9': '5dc'
- },
- '26': {
- 'p5': '6C',
- 'p9': '5da'
- },
- '27': {
- 'p1': '3a',
- 'p7': '3b',
- 'p9': '5e3'
- },
- '28': {
- 'p1': '22',
- 'p7': 'b4'
- },
- '29': {
- 'p1': '7E',
- 'p7': '60',
- 'p9': '3b'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': 'A6',
- 'p7': '5C'
- },
- '2C': {
- 'p5': '7A',
- 'p9': '5d6'
- },
- '2D': {
- 'p5': '78',
- 'p9': '5e1'
- },
- '2E': {
- 'p5': '63',
- 'p9': '5d1'
- },
- '2F': {
- 'p5': '76',
- 'p9': '5d4'
- },
- '30': {
- 'p5': '62',
- 'p9': '5e0'
- },
- '31': {
- 'p5': '6E',
- 'p9': '5de'
- },
- '32': {
- 'p5': '6D',
- 'p9': '5e6'
- },
- '33': {
- 'p1': '3c',
- 'p7': 'b8',
- 'p9': '5ea'
- },
- '34': {
- 'p1': '3e',
- 'p7': '2e',
- 'p9': '5e5'
- },
- '35': {
- 'p1': '3f',
- 'p7': '2f',
- 'p9': '2e'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'ja': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31',
- 'p9': '306C'
- },
- '03': {
- 'p1': '22',
- 'p7': '32',
- 'p9': '3075'
- },
- '04': {
- 'p1': '23',
- 'p3': '3041',
- 'p7': '33',
- 'p9': '3042'
- },
- '05': {
- 'p1': '24',
- 'p3': '3045',
- 'p7': '34',
- 'p9': '3046'
- },
- '06': {
- 'p1': '25',
- 'p3': '3047',
- 'p7': '35',
- 'p9': '3048'
- },
- '07': {
- 'p1': '26',
- 'p3': '3049',
- 'p7': '36',
- 'p9': '304A'
- },
- '08': {
- 'p1': '27',
- 'p3': '3083',
- 'p7': '37',
- 'p9': '3084'
- },
- '09': {
- 'p1': '28',
- 'p3': '3085',
- 'p7': '38',
- 'p9': '3086'
- },
- '0A': {
- 'p1': '29',
- 'p3': '3087',
- 'p7': '39',
- 'p9': '3088'
- },
- '0B': {
- 'p3': '3092',
- 'p7': '30',
- 'p9': '308F'
- },
- '0C': {
- 'p1': '3D',
- 'p7': '2D',
- 'p9': '307B'
- },
- '0D': {
- 'p1': '7E',
- 'p7': '5E',
- 'p9': '3078'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p1': '71',
- 'p9': '305F'
- },
- '11': {
- 'p1': '77',
- 'p9': '3066'
- },
- '12': {
- 'p1': '65',
- 'p3': '3043',
- 'p9': '3044'
- },
- '13': {
- 'p1': '72',
- 'p9': '3059'
- },
- '14': {
- 'p1': '74',
- 'p9': '304B'
- },
- '15': {
- 'p1': '79',
- 'p9': '3093'
- },
- '16': {
- 'p1': '75',
- 'p9': '306A'
- },
- '17': {
- 'p1': '69',
- 'p9': '306B'
- },
- '18': {
- 'p1': '6F',
- 'p9': '3089'
- },
- '19': {
- 'p1': '70',
- 'p9': '305B'
- },
- '1A': {
- 'p1': '60',
- 'p7': '40',
- 'p9': '3099'
- },
- '1B': {
- 'p1': '7B',
- 'p3': '300C',
- 'p7': '5B',
- 'p9': '309A'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p1': '61',
- 'p9': '3061'
- },
- '1F': {
- 'p1': '73',
- 'p9': '3068'
- },
- '20': {
- 'p1': '64',
- 'p9': '3057'
- },
- '21': {
- 'p1': '66',
- 'p9': '306F'
- },
- '22': {
- 'p1': '67',
- 'p9': '304D'
- },
- '23': {
- 'p1': '68',
- 'p9': '304F'
- },
- '24': {
- 'p1': '6A',
- 'p9': '307E'
- },
- '25': {
- 'p1': '6B',
- 'p9': '306E'
- },
- '26': {
- 'p1': '6C',
- 'p9': '308A'
- },
- '27': {
- 'p1': '2B',
- 'p7': '3B',
- 'p9': '308C'
- },
- '28': {
- 'p1': '2A',
- 'p7': '3A',
- 'p9': '3051'
- },
- '29': {
- 'label': '\u304b\u306a / \u82f1\u6570'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '7D',
- 'p3': '300D',
- 'p7': '5D',
- 'p9': '3080'
- },
- '2C': {
- 'p1': '7A',
- 'p9': '3064'
- },
- '2D': {
- 'p1': '78',
- 'p9': '3055'
- },
- '2E': {
- 'p1': '63',
- 'p9': '305D'
- },
- '2F': {
- 'p1': '76',
- 'p9': '3072'
- },
- '30': {
- 'p1': '62',
- 'p9': '3053'
- },
- '31': {
- 'p1': '6E',
- 'p9': '307F'
- },
- '32': {
- 'p1': '6D',
- 'p9': '3082'
- },
- '33': {
- 'p1': '3C',
- 'p3': 'FF64',
- 'p7': '2C',
- 'p9': '306D'
- },
- '34': {
- 'p1': '3E',
- 'p3': 'FF61',
- 'p7': '2E',
- 'p9': '308B'
- },
- '35': {
- 'p1': '3F',
- 'p3': 'FF65',
- 'p7': '2F',
- 'p9': '3081'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {
- 'p1': '5F',
- 'p7': '5C',
- 'p9': '308D'
- },
- '79': {
- 'format': 'smaller',
- 'label': '\u304b\u306a'
- },
- '7B': {
- 'format': 'smaller',
- 'label': '\u82f1\u6570'
- },
- '7D': {
- 'p1': '7C',
- 'p7': 'A5',
- 'p9': '30FC'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'J'
- },
- 'ko': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '005E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '002A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '0D': {
- 'p2': '002B',
- 'p8': '003D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p1': '71',
- 'p3': '3143',
- 'p9': '3142'
- },
- '11': {
- 'p1': '77',
- 'p3': '3149',
- 'p9': '3148'
- },
- '12': {
- 'p1': '65',
- 'p3': '3138',
- 'p9': '3137'
- },
- '13': {
- 'p1': '72',
- 'p3': '3132',
- 'p9': '3131'
- },
- '14': {
- 'p1': '74',
- 'p3': '3146',
- 'p9': '3145'
- },
- '15': {
- 'p1': '79',
- 'p9': '315B'
- },
- '16': {
- 'p1': '75',
- 'p9': '3155'
- },
- '17': {
- 'p1': '69',
- 'p9': '3151'
- },
- '18': {
- 'p1': '6F',
- 'p3': '3152',
- 'p9': '3150'
- },
- '19': {
- 'p1': '70',
- 'p3': '3156',
- 'p9': '3154'
- },
- '1A': {
- 'p1': '007B',
- 'p7': '005B'
- },
- '1B': {
- 'p1': '007D',
- 'p7': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p1': '61',
- 'p9': '3141'
- },
- '1F': {
- 'p1': '73',
- 'p9': '3134'
- },
- '20': {
- 'p1': '64',
- 'p9': '3147'
- },
- '21': {
- 'p1': '66',
- 'p9': '3139'
- },
- '22': {
- 'p1': '67',
- 'p9': '314E'
- },
- '23': {
- 'p1': '68',
- 'p9': '3157'
- },
- '24': {
- 'p1': '6A',
- 'p9': '3153'
- },
- '25': {
- 'p1': '6B',
- 'p9': '314F'
- },
- '26': {
- 'p1': '6C',
- 'p9': '3163'
- },
- '27': {
- 'p1': '003A',
- 'p7': '003B'
- },
- '28': {
- 'p1': '22',
- 'p7': '27'
- },
- '29': {
- 'p2': '007E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '007C',
- 'p7': '005C',
- 'p9': '20A9'
- },
- '2C': {
- 'p1': '7A',
- 'p9': '314B'
- },
- '2D': {
- 'p1': '78',
- 'p9': '314C'
- },
- '2E': {
- 'p1': '63',
- 'p9': '314A'
- },
- '2F': {
- 'p1': '76',
- 'p9': '314D'
- },
- '30': {
- 'p1': '62',
- 'p9': '3160'
- },
- '31': {
- 'p1': '6E',
- 'p9': '315C'
- },
- '32': {
- 'p1': '6D',
- 'p9': '3161'
- },
- '33': {
- 'p1': '003C',
- 'p7': '002C'
- },
- '34': {
- 'p1': '003E',
- 'p7': '002E'
- },
- '35': {
- 'p1': '003F',
- 'p7': '002F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {
- 'format': 'smaller',
- 'label': '\ud55c/\uc601'
- },
- '7B': {
- 'format': 'smaller',
- 'label': '\ud55c\uc790'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': ' \ud55c\uc790'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': '\ud55c/\uc601'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'lt': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31',
- 'p9': '105'
- },
- '03': {
- 'p2': '40',
- 'p8': '32',
- 'p9': '10D'
- },
- '04': {
- 'p2': '23',
- 'p8': '33',
- 'p9': '119'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': '117'
- },
- '06': {
- 'p2': '25',
- 'p8': '35',
- 'p9': '12F'
- },
- '07': {
- 'p2': '005E',
- 'p8': '36',
- 'p9': '161'
- },
- '08': {
- 'p2': '26',
- 'p8': '37',
- 'p9': '173'
- },
- '09': {
- 'p2': '002A',
- 'p8': '38',
- 'p9': '016B'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '0D': {
- 'p2': '002B',
- 'p8': '003D',
- 'p9': '017E'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '007B',
- 'p8': '005B'
- },
- '1B': {
- 'p2': '007D',
- 'p8': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p2': '003A',
- 'p8': '003B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '007E',
- 'p8': '60',
- 'p9': '00B4'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '005C',
- 'p8': '007C'
- },
- '2C': {
- 'p5': '007A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D'
- },
- '33': {
- 'p2': '003C',
- 'p8': '002C',
- 'p9': '201E'
- },
- '34': {
- 'p2': '003E',
- 'p8': '002E',
- 'p9': '201C'
- },
- '35': {
- 'p2': '003F',
- 'p8': '002F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {},
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'lv': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '005E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '002A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '0D': {
- 'p2': '002B',
- 'p8': '003D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '007B',
- 'p8': '005B'
- },
- '1B': {
- 'p2': '007D',
- 'p8': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '003A',
- 'p8': '003B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '007E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '7C',
- 'p8': '005C'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '003C',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003E',
- 'p8': '002E'
- },
- '35': {
- 'p2': '003F',
- 'p8': '002F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '007C',
- 'p8': '005C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'nl': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35',
- 'p9': '20AC'
- },
- '07': {
- 'p2': '005E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '002A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '0D': {
- 'p2': '002B',
- 'p8': '003D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '007B',
- 'p8': '005B'
- },
- '1B': {
- 'p2': '007D',
- 'p8': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '003A',
- 'p8': '003B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '007E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '007C',
- 'p8': '005C'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '003C',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003E',
- 'p8': '002E'
- },
- '35': {
- 'p2': '003F',
- 'p8': '002F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'no': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31'
- },
- '03': {
- 'p1': '22',
- 'p7': '32',
- 'p9': '40'
- },
- '04': {
- 'p1': '23',
- 'p7': '33',
- 'p9': '00A3'
- },
- '05': {
- 'p1': '00A4',
- 'p7': '34',
- 'p9': '24'
- },
- '06': {
- 'p1': '25',
- 'p7': '35'
- },
- '07': {
- 'p1': '26',
- 'p7': '36'
- },
- '08': {
- 'p1': '002F',
- 'p7': '37',
- 'p9': '007B'
- },
- '09': {
- 'p1': '28',
- 'p7': '38',
- 'p9': '005B'
- },
- '0A': {
- 'p1': '29',
- 'p7': '39',
- 'p9': '005D'
- },
- '0B': {
- 'p1': '003D',
- 'p7': '30',
- 'p9': '007D'
- },
- '0C': {
- 'p1': '003F',
- 'p7': '002B'
- },
- '0D': {
- 'p1': '60',
- 'p7': '005C',
- 'p9': '00B4'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': 'E5'
- },
- '1B': {
- 'p1': '5e',
- 'p7': '00A8',
- 'p9': '7e'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': '00F8'
- },
- '28': {
- 'p5': 'E6'
- },
- '29': {
- 'p1': '00A7',
- 'p7': '007C'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '2a',
- 'p8': '27'
- },
- '2C': {
- 'p5': '007A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D',
- 'p9': '3bc'
- },
- '33': {
- 'p2': '003B',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003A',
- 'p8': '002E'
- },
- '35': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '3e',
- 'p8': '003C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'pl': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '5E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '2A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '0D': {
- 'p2': '2B',
- 'p8': '3D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'label': 'q',
- 'p1': '51'
- },
- '11': {
- 'label': 'w',
- 'p1': '57'
- },
- '12': {
- 'label': 'e',
- 'p1': '45'
- },
- '13': {
- 'label': 'r',
- 'p1': '52'
- },
- '14': {
- 'label': 't',
- 'p1': '54'
- },
- '15': {
- 'label': 'y',
- 'p1': '59'
- },
- '16': {
- 'label': 'u',
- 'p1': '55'
- },
- '17': {
- 'label': 'i',
- 'p1': '49'
- },
- '18': {
- 'label': 'o',
- 'p1': '4F'
- },
- '19': {
- 'label': 'p',
- 'p1': '50'
- },
- '1A': {
- 'p2': '7B',
- 'p8': '5B'
- },
- '1B': {
- 'p2': '7D',
- 'p8': '5D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'label': 'a',
- 'p1': '41'
- },
- '1F': {
- 'label': 's',
- 'p1': '53'
- },
- '20': {
- 'label': 'd',
- 'p1': '44'
- },
- '21': {
- 'label': 'f',
- 'p1': '46'
- },
- '22': {
- 'label': 'g',
- 'p1': '47'
- },
- '23': {
- 'label': 'h',
- 'p1': '48'
- },
- '24': {
- 'label': 'j',
- 'p1': '4A'
- },
- '25': {
- 'label': 'k',
- 'p1': '4B'
- },
- '26': {
- 'label': 'l',
- 'p1': '4C'
- },
- '27': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '7E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '7C',
- 'p8': '5C'
- },
- '2C': {
- 'label': 'z',
- 'p1': '5A'
- },
- '2D': {
- 'label': 'x',
- 'p1': '58'
- },
- '2E': {
- 'label': 'c',
- 'p1': '43'
- },
- '2F': {
- 'label': 'v',
- 'p1': '56'
- },
- '30': {
- 'label': 'b',
- 'p1': '42'
- },
- '31': {
- 'label': 'n',
- 'p1': '4E'
- },
- '32': {
- 'label': 'm',
- 'p1': '4D'
- },
- '33': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '35': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'pt_BR': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31',
- 'p9': 'B9'
- },
- '03': {
- 'p1': '40',
- 'p7': '32',
- 'p9': 'B2'
- },
- '04': {
- 'p1': '23',
- 'p7': '33',
- 'p9': 'B3'
- },
- '05': {
- 'p1': '24',
- 'p7': '34',
- 'p9': 'A3'
- },
- '06': {
- 'p1': '25',
- 'p7': '35',
- 'p9': 'A2'
- },
- '07': {
- 'p1': 'A8',
- 'p7': '36',
- 'p9': '00AC'
- },
- '08': {
- 'p1': '26',
- 'p7': '37'
- },
- '09': {
- 'p1': '2A',
- 'p7': '38'
- },
- '0A': {
- 'p1': '28',
- 'p7': '39'
- },
- '0B': {
- 'p1': '29',
- 'p7': '30'
- },
- '0C': {
- 'p1': '5F',
- 'p7': '2D'
- },
- '0D': {
- 'p1': '2B',
- 'p7': '3D',
- 'p9': 'A7'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '2F'
- },
- '11': {
- 'p5': '77',
- 'p9': '3F'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p1': '60',
- 'p7': 'B4'
- },
- '1B': {
- 'p1': '7B',
- 'p7': '5B',
- 'p9': 'AA0332'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p5': 'e7'
- },
- '28': {
- 'p1': '5E',
- 'p7': '7E'
- },
- '29': {
- 'p1': '22',
- 'p7': '27'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '7D',
- 'p7': '5D',
- 'p9': 'BA0332'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63',
- 'p9': '20A2'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p1': '3C',
- 'p7': '2C'
- },
- '34': {
- 'p1': '3E',
- 'p7': '2E'
- },
- '35': {
- 'p1': '3A',
- 'p7': '3B'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p1': '7C',
- 'p7': '5C'
- },
- '73': {
- 'p1': '3F',
- 'p7': '2f'
- },
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'B'
- },
- 'pt_PT': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '40'
- },
- '04': {
- 'p2': '23',
- 'p8': '33',
- 'p9': 'a3'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': 'a7'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36'
- },
- '08': {
- 'p2': '2f',
- 'p8': '37',
- 'p9': '7b'
- },
- '09': {
- 'p2': '28',
- 'p8': '38',
- 'p9': '5b'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39',
- 'p9': '5d'
- },
- '0B': {
- 'p2': '3d',
- 'p8': '30',
- 'p9': '7d'
- },
- '0C': {
- 'p2': '3f',
- 'p8': '27'
- },
- '0D': {
- 'p2': 'bb',
- 'p8': 'ab'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20ac'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '2a',
- 'p8': '2b',
- 'p9': 'a8'
- },
- '1B': {
- 'p2': '60',
- 'p8': 'b4'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p5': 'e7'
- },
- '28': {
- 'p2': 'aa0332',
- 'p8': 'ba0332'
- },
- '29': {
- 'p2': '7c',
- 'p8': '5c'
- },
- '2A': {
- 'format': 'glyph_shift',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '5e',
- 'p8': '7e'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '3b',
- 'p8': '2c'
- },
- '34': {
- 'p2': '3a',
- 'p8': '2e'
- },
- '35': {
- 'p2': '5f',
- 'p8': '2d'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '3e',
- 'p8': '3c'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'ro': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31',
- 'p9': '7E'
- },
- '03': {
- 'p1': '22',
- 'p7': '32',
- 'p9': '2C7'
- },
- '04': {
- 'p1': '23',
- 'p7': '33',
- 'p9': '5E'
- },
- '05': {
- 'p1': '24',
- 'p7': '34',
- 'p9': '2D8'
- },
- '06': {
- 'p1': '25',
- 'p7': '35',
- 'p9': '2DA'
- },
- '07': {
- 'p1': '26',
- 'p7': '36',
- 'p9': '2DB'
- },
- '08': {
- 'p1': '2F',
- 'p7': '37',
- 'p9': '60'
- },
- '09': {
- 'p1': '28',
- 'p7': '38',
- 'p9': '2D9'
- },
- '0A': {
- 'p1': '29',
- 'p7': '39',
- 'p9': 'B4'
- },
- '0B': {
- 'p1': '3D',
- 'p7': '30',
- 'p9': '2DD'
- },
- '0C': {
- 'p1': '3F',
- 'p7': '2B',
- 'p9': 'A8'
- },
- '0D': {
- 'p1': '2A',
- 'p7': '27',
- 'p9': 'B8'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '5c'
- },
- '11': {
- 'p5': '77',
- 'p9': 'A6'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72',
- 'p9': 'AE'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': '103',
- 'p9': '00F7'
- },
- '1B': {
- 'p5': '00EE',
- 'p9': '00D7'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61',
- 'p9': '201E'
- },
- '1F': {
- 'p5': '73',
- 'p9': '201D'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C',
- 'p9': 'A3'
- },
- '27': {
- 'p5': '219',
- 'p9': '40'
- },
- '28': {
- 'p5': '021b',
- 'p9': 'DF'
- },
- '29': {
- 'p1': '5B',
- 'p7': '5D'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p5': 'E2'
- },
- '2C': {
- 'p5': '7a'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63',
- 'p9': '00A9'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62',
- 'p9': '7b'
- },
- '31': {
- 'p5': '6E',
- 'p9': '7d'
- },
- '32': {
- 'p5': '6D',
- 'p9': 'a7'
- },
- '33': {
- 'p1': '3B',
- 'p7': '2C'
- },
- '34': {
- 'p1': '3A',
- 'p7': '2E'
- },
- '35': {
- 'p1': '5F',
- 'p7': '2D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p1': '3C',
- 'p7': '3E'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {
- 'p5': 'E2'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'ru': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31'
- },
- '03': {
- 'p1': '40',
- 'p3': '22',
- 'p7': '32'
- },
- '04': {
- 'p1': '23',
- 'p3': '2116',
- 'p7': '33'
- },
- '05': {
- 'p1': '24',
- 'p3': '3b',
- 'p7': '34'
- },
- '06': {
- 'p1': '25',
- 'p7': '35'
- },
- '07': {
- 'p1': '5e',
- 'p3': '3a',
- 'p7': '36'
- },
- '08': {
- 'p1': '26',
- 'p3': '3f',
- 'p7': '37'
- },
- '09': {
- 'p1': '2a',
- 'p7': '38'
- },
- '0A': {
- 'p1': '28',
- 'p7': '39'
- },
- '0B': {
- 'p1': '29',
- 'p7': '30'
- },
- '0C': {
- 'p1': '5f',
- 'p7': '2d'
- },
- '0D': {
- 'p1': '2b',
- 'p7': '3d'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p1': '71',
- 'p9': '439'
- },
- '11': {
- 'p1': '77',
- 'p9': '446'
- },
- '12': {
- 'p1': '65',
- 'p9': '443'
- },
- '13': {
- 'p1': '72',
- 'p9': '43a'
- },
- '14': {
- 'p1': '74',
- 'p9': '435'
- },
- '15': {
- 'p1': '79',
- 'p9': '43d'
- },
- '16': {
- 'p1': '75',
- 'p9': '433'
- },
- '17': {
- 'p1': '69',
- 'p9': '448'
- },
- '18': {
- 'p1': '6F',
- 'p9': '449'
- },
- '19': {
- 'p1': '70',
- 'p9': '437'
- },
- '1A': {
- 'p1': '7b',
- 'p7': '5b',
- 'p9': '445'
- },
- '1B': {
- 'p1': '7d',
- 'p7': '5d',
- 'p9': '44a'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p1': '61',
- 'p9': '444'
- },
- '1F': {
- 'p1': '73',
- 'p9': '44b'
- },
- '20': {
- 'p1': '64',
- 'p9': '432'
- },
- '21': {
- 'p1': '66',
- 'p9': '430'
- },
- '22': {
- 'p1': '67',
- 'p9': '43f'
- },
- '23': {
- 'p1': '68',
- 'p9': '440'
- },
- '24': {
- 'p1': '6A',
- 'p9': '43e'
- },
- '25': {
- 'p1': '6B',
- 'p9': '43b'
- },
- '26': {
- 'p1': '6C',
- 'p9': '434'
- },
- '27': {
- 'p1': '3a',
- 'p7': '3b',
- 'p9': '436'
- },
- '28': {
- 'p1': '22',
- 'p7': '27',
- 'p9': '44d'
- },
- '29': {
- 'p1': '7e',
- 'p7': '60',
- 'p9': '451'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '7c',
- 'p3': '2f',
- 'p7': '5c',
- 'p9': '5c'
- },
- '2C': {
- 'p1': '7A',
- 'p9': '44f'
- },
- '2D': {
- 'p1': '78',
- 'p9': '447'
- },
- '2E': {
- 'p1': '63',
- 'p9': '441'
- },
- '2F': {
- 'p1': '76',
- 'p9': '43c'
- },
- '30': {
- 'p1': '62',
- 'p9': '438'
- },
- '31': {
- 'p1': '6E',
- 'p9': '442'
- },
- '32': {
- 'p1': '6D',
- 'p9': '44c'
- },
- '33': {
- 'p1': '3c',
- 'p7': '2c',
- 'p9': '431'
- },
- '34': {
- 'p1': '3e',
- 'p7': '2e',
- 'p9': '44e'
- },
- '35': {
- 'p1': '3f',
- 'p3': '2c',
- 'p7': '2f',
- 'p9': '2e'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'sk': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p3': '31',
- 'p7': '31',
- 'p9': '002b'
- },
- '03': {
- 'p1': '40',
- 'p3': '32',
- 'p7': '32',
- 'p9': '013E'
- },
- '04': {
- 'p1': '23',
- 'p3': '33',
- 'p7': '33',
- 'p9': '161'
- },
- '05': {
- 'p1': '24',
- 'p3': '34',
- 'p7': '34',
- 'p9': '010d'
- },
- '06': {
- 'p1': '25',
- 'p3': '35',
- 'p7': '35',
- 'p9': '165'
- },
- '07': {
- 'p1': '5e',
- 'p3': '36',
- 'p7': '36',
- 'p9': '017e'
- },
- '08': {
- 'p1': '26',
- 'p3': '37',
- 'p7': '37',
- 'p9': 'fd'
- },
- '09': {
- 'p1': '2a',
- 'p3': '38',
- 'p7': '38',
- 'p9': 'e1'
- },
- '0A': {
- 'p1': '28',
- 'p3': '39',
- 'p7': '39',
- 'p9': 'ed'
- },
- '0B': {
- 'p1': '29',
- 'p3': '30',
- 'p7': '30',
- 'p9': 'e9'
- },
- '0C': {
- 'p1': '5f',
- 'p3': '25',
- 'p7': '2d',
- 'p9': '3d'
- },
- '0D': {
- 'p1': '2b',
- 'p3': '2c7',
- 'p7': '3d',
- 'p9': 'b4'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20ac'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6f'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p1': '7b',
- 'p3': 'b4',
- 'p7': '5b',
- 'p9': 'fa'
- },
- '1B': {
- 'p1': '7d',
- 'p3': '28',
- 'p7': '5d',
- 'p9': 'e4'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6a'
- },
- '25': {
- 'p5': '6b'
- },
- '26': {
- 'p5': '6c'
- },
- '27': {
- 'p1': '3a',
- 'p3': '22',
- 'p7': '3b',
- 'p9': 'f4'
- },
- '28': {
- 'p1': '22',
- 'p3': '21',
- 'p7': '27',
- 'p9': 'a7'
- },
- '29': {
- 'p1': '7e',
- 'p3': 'b0',
- 'p7': '60',
- 'p9': '3b'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '7c',
- 'p3': '29',
- 'p7': '5c',
- 'p9': '148'
- },
- '2C': {
- 'p5': '7a'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6e'
- },
- '32': {
- 'p5': '6d'
- },
- '33': {
- 'p1': '3c',
- 'p3': '3f',
- 'p7': '2c',
- 'p9': '2c'
- },
- '34': {
- 'p1': '3e',
- 'p3': '3a',
- 'p7': '2e',
- 'p9': '2e'
- },
- '35': {
- 'p1': '3f',
- 'p3': '5f',
- 'p7': '2f',
- 'p9': '2d'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p1': '2a',
- 'p3': '7c',
- 'p7': '26',
- 'p9': '5c'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'sl': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31',
- 'p9': '007E'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '02C7'
- },
- '04': {
- 'p2': '23',
- 'p8': '33',
- 'p9': '005E'
- },
- '05': {
- 'p2': '24',
- 'p8': '34',
- 'p9': '02D8'
- },
- '06': {
- 'p2': '25',
- 'p8': '35',
- 'p9': '02DA'
- },
- '07': {
- 'p2': '26',
- 'p8': '36',
- 'p9': '02DB'
- },
- '08': {
- 'p2': '002F',
- 'p8': '37',
- 'p9': '60'
- },
- '09': {
- 'p2': '28',
- 'p8': '38',
- 'p9': '02D9'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39',
- 'p9': '00B4'
- },
- '0B': {
- 'p2': '003D',
- 'p8': '30',
- 'p9': '02DD'
- },
- '0C': {
- 'p2': '003F',
- 'p8': '27',
- 'p9': '00A8'
- },
- '0D': {
- 'p2': '002A',
- 'p8': '002B',
- 'p9': '00B8'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '005C'
- },
- '11': {
- 'p5': '77',
- 'p9': '007C'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '7A'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': '161',
- 'p9': '00F7'
- },
- '1B': {
- 'p5': '111',
- 'p9': '00D7'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66',
- 'p9': '005B'
- },
- '22': {
- 'p5': '67',
- 'p9': '005D'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B',
- 'p9': '142'
- },
- '26': {
- 'p5': '6C',
- 'p9': '141'
- },
- '27': {
- 'p5': '10D'
- },
- '28': {
- 'p5': '107',
- 'p9': '00DF'
- },
- '29': {
- 'p2': '00A8',
- 'p8': '00B8'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p5': '17E',
- 'p9': '00A4'
- },
- '2C': {
- 'p5': '79'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76',
- 'p9': '40'
- },
- '30': {
- 'p5': '62',
- 'p9': '007B'
- },
- '31': {
- 'p5': '6E',
- 'p9': '007D'
- },
- '32': {
- 'p5': '6D',
- 'p9': '00A7'
- },
- '33': {
- 'p2': '003B',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003A',
- 'p8': '002E'
- },
- '35': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '003E',
- 'p8': '003C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'sr': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': '\u0438\u0437\u043b'
- },
- '02': {
- 'p2': '21',
- 'p8': '31',
- 'p9': '007E'
- },
- '03': {
- 'p2': '22',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33',
- 'p9': '005E'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36'
- },
- '08': {
- 'p2': '27',
- 'p8': '37',
- 'p9': '60'
- },
- '09': {
- 'p2': '28',
- 'p8': '38'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39'
- },
- '0B': {
- 'p2': '003D',
- 'p8': '30'
- },
- '0C': {
- 'p2': '003F',
- 'p8': '27'
- },
- '0D': {
- 'p2': '002A',
- 'p8': '002B'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p4': '71',
- 'p6': '459'
- },
- '11': {
- 'p4': '77',
- 'p6': '045A'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '7A'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p4': '161',
- 'p6': '448'
- },
- '1B': {
- 'p4': '111',
- 'p6': '442'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': '\u043a\u043d\u0442\u0440'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66',
- 'p9': '005B'
- },
- '22': {
- 'p5': '67',
- 'p9': '005D'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p4': '10D',
- 'p6': '447'
- },
- '28': {
- 'p4': '107',
- 'p6': '045B'
- },
- '29': {
- 'p2': '007C',
- 'p8': '005C'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p4': '17E',
- 'p6': '436'
- },
- '2C': {
- 'p5': '79'
- },
- '2D': {
- 'p4': '78',
- 'p6': '045F'
- },
- '2E': {
- 'p4': '63',
- 'p6': '446'
- },
- '2F': {
- 'p5': '76',
- 'p9': '40'
- },
- '30': {
- 'p5': '62',
- 'p9': '007B'
- },
- '31': {
- 'p5': '6E',
- 'p9': '007D'
- },
- '32': {
- 'p5': '6D',
- 'p9': '00A7'
- },
- '33': {
- 'p2': '003B',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003A',
- 'p8': '002E'
- },
- '35': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': '\u0430\u043b\u0442'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '003E',
- 'p8': '003C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': '\u043a\u043d\u0442\u0440'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': '\u0430\u043b\u0442'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'sv': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '22',
- 'p8': '32',
- 'p9': '40'
- },
- '04': {
- 'p2': '23',
- 'p8': '33',
- 'p9': '00A3'
- },
- '05': {
- 'p2': '00A4',
- 'p8': '34',
- 'p9': '24'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '26',
- 'p8': '36'
- },
- '08': {
- 'p2': '002F',
- 'p8': '37',
- 'p9': '007B'
- },
- '09': {
- 'p2': '28',
- 'p8': '38',
- 'p9': '005B'
- },
- '0A': {
- 'p2': '29',
- 'p8': '39',
- 'p9': '005D'
- },
- '0B': {
- 'p2': '003D',
- 'p8': '30',
- 'p9': '007D'
- },
- '0C': {
- 'p2': '003F',
- 'p8': '002B',
- 'p9': '005C'
- },
- '0D': {
- 'p2': '60',
- 'p8': '00B4'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20AC'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '006F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': 'E5'
- },
- '1B': {
- 'p2': '005E',
- 'p8': '00A8',
- 'p9': '007E'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '006A'
- },
- '25': {
- 'p5': '006B'
- },
- '26': {
- 'p5': '006C'
- },
- '27': {
- 'p5': '00F6'
- },
- '28': {
- 'p5': 'E4'
- },
- '29': {
- 'p2': '00BD',
- 'p8': '00A7'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '002A',
- 'p8': '27'
- },
- '2C': {
- 'p5': '007A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '006E'
- },
- '32': {
- 'p5': '006D'
- },
- '33': {
- 'p2': '003B',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003A',
- 'p8': '002E'
- },
- '35': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p2': '003E',
- 'p8': '003C',
- 'p9': '007C'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'th': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p3': '002B',
- 'p7': '31',
- 'p9': 'E45'
- },
- '03': {
- 'p1': '40',
- 'p3': 'E51',
- 'p7': '32',
- 'p9': '002F'
- },
- '04': {
- 'p1': '23',
- 'p3': 'E52',
- 'p7': '33',
- 'p9': '002D'
- },
- '05': {
- 'p1': '24',
- 'p3': 'E53',
- 'p7': '34',
- 'p9': 'E20'
- },
- '06': {
- 'p1': '25',
- 'p3': 'E54',
- 'p7': '35',
- 'p9': 'E16'
- },
- '07': {
- 'p1': '005E',
- 'p3': 'E39',
- 'p7': '36',
- 'p9': 'E38'
- },
- '08': {
- 'p1': '26',
- 'p3': '0E3F',
- 'p7': '37',
- 'p9': 'E36'
- },
- '09': {
- 'p1': '002A',
- 'p3': 'E55',
- 'p7': '38',
- 'p9': 'E04'
- },
- '0A': {
- 'p1': '28',
- 'p3': 'E56',
- 'p7': '39',
- 'p9': 'E15'
- },
- '0B': {
- 'p1': '29',
- 'p3': 'E57',
- 'p7': '30',
- 'p9': 'E08'
- },
- '0C': {
- 'p1': '005F',
- 'p3': 'E58',
- 'p7': '002D',
- 'p9': 'E02'
- },
- '0D': {
- 'p1': '002B',
- 'p3': 'E59',
- 'p7': '003D',
- 'p9': '0E0A'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p3': 'E50',
- 'p7': '71',
- 'p9': 'E46'
- },
- '11': {
- 'p3': '22',
- 'p7': '77',
- 'p9': 'E44'
- },
- '12': {
- 'p3': '0E0E',
- 'p7': '65',
- 'p9': 'E33'
- },
- '13': {
- 'p3': 'E11',
- 'p7': '72',
- 'p9': '0E1E'
- },
- '14': {
- 'p3': 'E18',
- 'p7': '74',
- 'p9': 'E30'
- },
- '15': {
- 'p3': '0E4D',
- 'p7': '79',
- 'p9': 'E31'
- },
- '16': {
- 'p3': '0E4A',
- 'p7': '75',
- 'p9': 'E35'
- },
- '17': {
- 'p3': 'E13',
- 'p7': '69',
- 'p9': 'E23'
- },
- '18': {
- 'p3': '0E2F',
- 'p7': '006F',
- 'p9': 'E19'
- },
- '19': {
- 'p3': '0E0D',
- 'p7': '70',
- 'p9': 'E22'
- },
- '1A': {
- 'p1': '007B',
- 'p3': 'E10',
- 'p7': '005B',
- 'p9': '0E1A'
- },
- '1B': {
- 'p1': '007D',
- 'p3': '002C',
- 'p7': '005D',
- 'p9': 'E25'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p3': 'E24',
- 'p7': '61',
- 'p9': '0E1F'
- },
- '1F': {
- 'p3': 'E06',
- 'p7': '73',
- 'p9': '0E2B'
- },
- '20': {
- 'p3': '0E0F',
- 'p7': '64',
- 'p9': 'E01'
- },
- '21': {
- 'p3': 'E42',
- 'p7': '66',
- 'p9': 'E14'
- },
- '22': {
- 'p3': '0E0C',
- 'p7': '67',
- 'p9': 'E40'
- },
- '23': {
- 'p3': 'E47',
- 'p7': '68',
- 'p9': 'E49'
- },
- '24': {
- 'p3': '0E4B',
- 'p7': '006A',
- 'p9': 'E48'
- },
- '25': {
- 'p3': 'E29',
- 'p7': '006B',
- 'p9': 'E32'
- },
- '26': {
- 'p3': 'E28',
- 'p7': '006C',
- 'p9': '0E2A'
- },
- '27': {
- 'p1': '003A',
- 'p3': '0E0B',
- 'p7': '003B',
- 'p9': 'E27'
- },
- '28': {
- 'p1': '22',
- 'p3': '002E',
- 'p7': '27',
- 'p9': 'E07'
- },
- '29': {
- 'p1': '007E',
- 'p3': '25',
- 'p7': '60',
- 'p9': '005F'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '00A6',
- 'p3': 'E05',
- 'p7': '005C',
- 'p9': 'E03'
- },
- '2C': {
- 'p3': '28',
- 'p7': '007A',
- 'p9': '0E1C'
- },
- '2D': {
- 'p3': '29',
- 'p7': '78',
- 'p9': '0E1B'
- },
- '2E': {
- 'p3': 'E09',
- 'p7': '63',
- 'p9': 'E41'
- },
- '2F': {
- 'p3': '0E2E',
- 'p7': '76',
- 'p9': '0E2D'
- },
- '30': {
- 'p3': '0E3A',
- 'p7': '62',
- 'p9': 'E34'
- },
- '31': {
- 'p3': '0E4C',
- 'p7': '006E',
- 'p9': 'E37'
- },
- '32': {
- 'p3': '003F',
- 'p7': '006D',
- 'p9': 'E17'
- },
- '33': {
- 'p1': '003C',
- 'p3': 'E12',
- 'p7': '002C',
- 'p9': 'E21'
- },
- '34': {
- 'p1': '003E',
- 'p3': '0E2C',
- 'p7': '002E',
- 'p9': 'E43'
- },
- '35': {
- 'p1': '003F',
- 'p3': 'E26',
- 'p7': '002D',
- 'p9': '0E1D'
- },
- '36': {
- 'format': 'right',
- 'label': 'shirt'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'tr': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p7': '31'
- },
- '03': {
- 'p1': '27',
- 'p7': '32'
- },
- '04': {
- 'p1': '5e',
- 'p7': '33',
- 'p9': '23'
- },
- '05': {
- 'p1': '2b',
- 'p7': '34',
- 'p9': '24'
- },
- '06': {
- 'p1': '25',
- 'p7': '35'
- },
- '07': {
- 'p1': '26',
- 'p7': '36'
- },
- '08': {
- 'p1': '2f',
- 'p7': '37',
- 'p9': '7b'
- },
- '09': {
- 'p1': '28',
- 'p7': '38',
- 'p9': '5b'
- },
- '0A': {
- 'p1': '29',
- 'p7': '39',
- 'p9': '5d'
- },
- '0B': {
- 'p1': '3d',
- 'p7': '30',
- 'p9': '7d'
- },
- '0C': {
- 'p1': '3f',
- 'p7': '2a',
- 'p9': '5c'
- },
- '0D': {
- 'p1': '5f',
- 'p7': '2d'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '40'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65',
- 'p9': '20ac'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': '11F',
- 'p9': 'A8'
- },
- '1B': {
- 'p5': '0FC',
- 'p9': '7e'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p5': '15f',
- 'p9': 'B4'
- },
- '28': {
- 'p5': '69'
- },
- '29': {
- 'p1': 'E9',
- 'p7': '22'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '3b',
- 'p7': '2c',
- 'p9': '60'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p5': '0F6'
- },
- '34': {
- 'p5': 'E7'
- },
- '35': {
- 'p1': '3a',
- 'p7': '2e'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '56': {
- 'p1': '3e',
- 'p7': '3c',
- 'p9': '7c'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'E'
- },
- 'uk': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31',
- 'p9': '2013'
- },
- '03': {
- 'p2': '40',
- 'p8': '32',
- 'p9': '22'
- },
- '04': {
- 'p2': '2116',
- 'p8': '33',
- 'p9': '20AC'
- },
- '05': {
- 'p2': '003B',
- 'p8': '34',
- 'p9': '24'
- },
- '06': {
- 'p2': '25',
- 'p8': '35',
- 'p9': '00BA'
- },
- '07': {
- 'p2': '003A',
- 'p8': '36'
- },
- '08': {
- 'p2': '003F',
- 'p8': '37'
- },
- '09': {
- 'p2': '002A',
- 'p8': '38',
- 'p9': '00A7'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '005F',
- 'p8': '002D',
- 'p9': '005B'
- },
- '0D': {
- 'p2': '002B',
- 'p8': '003D',
- 'p9': '005D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71',
- 'p9': '439'
- },
- '11': {
- 'p5': '77',
- 'p9': '446'
- },
- '12': {
- 'p5': '65',
- 'p9': '443'
- },
- '13': {
- 'p5': '72',
- 'p9': '043A'
- },
- '14': {
- 'p5': '74',
- 'p9': '435'
- },
- '15': {
- 'p5': '79',
- 'p9': '043D'
- },
- '16': {
- 'p5': '75',
- 'p9': '433'
- },
- '17': {
- 'p5': '69',
- 'p9': '448'
- },
- '18': {
- 'p5': '006F',
- 'p9': '449'
- },
- '19': {
- 'p5': '70',
- 'p9': '437'
- },
- '1A': {
- 'p2': '007B',
- 'p8': '445'
- },
- '1B': {
- 'p2': '007D',
- 'p8': '044A',
- 'p9': '457'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61',
- 'p9': '444'
- },
- '1F': {
- 'p2': '73',
- 'p8': '044B',
- 'p9': '456'
- },
- '20': {
- 'p5': '64',
- 'p9': '432'
- },
- '21': {
- 'p5': '66',
- 'p9': '430'
- },
- '22': {
- 'p5': '67',
- 'p9': '043F'
- },
- '23': {
- 'p5': '68',
- 'p9': '440'
- },
- '24': {
- 'p5': '006A',
- 'p9': '043E'
- },
- '25': {
- 'p5': '006B',
- 'p9': '043B'
- },
- '26': {
- 'p5': '006C',
- 'p9': '434'
- },
- '27': {
- 'p2': '003A',
- 'p8': '003B',
- 'p9': '436'
- },
- '28': {
- 'p1': '22',
- 'p3': '454',
- 'p7': '27',
- 'p9': '044D'
- },
- '29': {
- 'p2': '491',
- 'p8': '27',
- 'p9': '20B4'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '00BB',
- 'p3': '002F',
- 'p7': '00AB',
- 'p9': '005C'
- },
- '2C': {
- 'p5': '007A',
- 'p9': '044F'
- },
- '2D': {
- 'p5': '78',
- 'p9': '447'
- },
- '2E': {
- 'p5': '63',
- 'p9': '441'
- },
- '2F': {
- 'p5': '76',
- 'p9': '043C'
- },
- '30': {
- 'p5': '62',
- 'p9': '438'
- },
- '31': {
- 'p5': '006E',
- 'p9': '442'
- },
- '32': {
- 'p5': '006D',
- 'p9': '044C'
- },
- '33': {
- 'p2': '003C',
- 'p8': '002C',
- 'p9': '431'
- },
- '34': {
- 'p2': '003E',
- 'p8': '002E',
- 'p9': '044E'
- },
- '35': {
- 'p1': '003F',
- 'p3': '002C',
- 'p7': '002F',
- 'p9': '002E'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {},
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt gr'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'vi': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p5': '103'
- },
- '03': {
- 'p5': 'E2'
- },
- '04': {
- 'p5': 'EA'
- },
- '05': {
- 'p5': 'F4'
- },
- '06': {
- 'p2': '300'
- },
- '07': {
- 'p2': '309'
- },
- '08': {
- 'p2': '303'
- },
- '09': {
- 'p2': '301'
- },
- '0A': {
- 'p2': '323'
- },
- '0B': {
- 'p5': '111'
- },
- '0C': {
- 'p2': '5F',
- 'p8': '2D'
- },
- '0D': {
- 'p2': '2B',
- 'p8': '20AB'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p5': '1B0'
- },
- '1B': {
- 'p5': '1A1'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '3A',
- 'p8': '3B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '7E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {},
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '3C',
- 'p8': '2C'
- },
- '34': {
- 'p2': '3E',
- 'p8': '2E'
- },
- '35': {
- 'p2': '3F',
- 'p8': '2F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '37': {},
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- '73': {},
- '79': {
- 'format': 'smaller'
- },
- '7B': {
- 'format': 'smaller'
- },
- '7D': {
- 'p2': 'A6',
- 'p8': '5C'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'zh_CN': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p2': '21',
- 'p8': '31'
- },
- '03': {
- 'p2': '40',
- 'p8': '32'
- },
- '04': {
- 'p2': '23',
- 'p8': '33'
- },
- '05': {
- 'p2': '24',
- 'p8': '34'
- },
- '06': {
- 'p2': '25',
- 'p8': '35'
- },
- '07': {
- 'p2': '005E',
- 'p8': '36'
- },
- '08': {
- 'p2': '26',
- 'p8': '37'
- },
- '09': {
- 'p2': '002A',
- 'p8': '38'
- },
- '0A': {
- 'p2': '28',
- 'p8': '39'
- },
- '0B': {
- 'p2': '29',
- 'p8': '30'
- },
- '0C': {
- 'p2': '005F',
- 'p8': '002D'
- },
- '0D': {
- 'p2': '002B',
- 'p8': '003D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p5': '71'
- },
- '11': {
- 'p5': '77'
- },
- '12': {
- 'p5': '65'
- },
- '13': {
- 'p5': '72'
- },
- '14': {
- 'p5': '74'
- },
- '15': {
- 'p5': '79'
- },
- '16': {
- 'p5': '75'
- },
- '17': {
- 'p5': '69'
- },
- '18': {
- 'p5': '6F'
- },
- '19': {
- 'p5': '70'
- },
- '1A': {
- 'p2': '007B',
- 'p8': '005B'
- },
- '1B': {
- 'p2': '007D',
- 'p8': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p5': '61'
- },
- '1F': {
- 'p5': '73'
- },
- '20': {
- 'p5': '64'
- },
- '21': {
- 'p5': '66'
- },
- '22': {
- 'p5': '67'
- },
- '23': {
- 'p5': '68'
- },
- '24': {
- 'p5': '6A'
- },
- '25': {
- 'p5': '6B'
- },
- '26': {
- 'p5': '6C'
- },
- '27': {
- 'p2': '003A',
- 'p8': '003B'
- },
- '28': {
- 'p2': '22',
- 'p8': '27'
- },
- '29': {
- 'p2': '007E',
- 'p8': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p2': '007C',
- 'p8': '005C'
- },
- '2C': {
- 'p5': '7A'
- },
- '2D': {
- 'p5': '78'
- },
- '2E': {
- 'p5': '63'
- },
- '2F': {
- 'p5': '76'
- },
- '30': {
- 'p5': '62'
- },
- '31': {
- 'p5': '6E'
- },
- '32': {
- 'p5': '6D'
- },
- '33': {
- 'p2': '003C',
- 'p8': '002C'
- },
- '34': {
- 'p2': '003E',
- 'p8': '002E'
- },
- '35': {
- 'p2': '003F',
- 'p8': '002F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- },
- 'zh_TW': {
- 'keys': {
- '00': {
- 'label': 'power'
- },
- '01': {
- 'format': 'smaller',
- 'label': 'esc'
- },
- '02': {
- 'p1': '21',
- 'p3': '3105',
- 'p7': '31'
- },
- '03': {
- 'p1': '40',
- 'p3': '3109',
- 'p7': '32'
- },
- '04': {
- 'p1': '23',
- 'p3': '02C7',
- 'p7': '33'
- },
- '05': {
- 'p1': '24',
- 'p3': '02CB',
- 'p7': '34'
- },
- '06': {
- 'p1': '25',
- 'p3': '3113',
- 'p7': '35'
- },
- '07': {
- 'p1': '005E',
- 'p3': '02CA',
- 'p7': '36'
- },
- '08': {
- 'p1': '26',
- 'p3': '02D9',
- 'p7': '37'
- },
- '09': {
- 'p1': '002A',
- 'p3': '311A',
- 'p7': '38'
- },
- '0A': {
- 'p1': '28',
- 'p3': '311E',
- 'p7': '39'
- },
- '0B': {
- 'p1': '29',
- 'p3': '3122',
- 'p7': '30'
- },
- '0C': {
- 'p1': '005F',
- 'p3': '3126',
- 'p7': '002D'
- },
- '0D': {
- 'p1': '002B',
- 'p7': '003D'
- },
- '0E': {
- 'format': 'right',
- 'label': 'backspace'
- },
- '0F': {
- 'format': 'left',
- 'label': 'tab'
- },
- '10': {
- 'p1': '71',
- 'p3': '3106',
- 'p7': '624B'
- },
- '11': {
- 'p1': '77',
- 'p3': '310A',
- 'p7': '7530'
- },
- '12': {
- 'p1': '65',
- 'p3': '310D',
- 'p7': '6C34'
- },
- '13': {
- 'p1': '72',
- 'p3': '3110',
- 'p7': '53E3'
- },
- '14': {
- 'p1': '74',
- 'p3': '3114',
- 'p7': '5EFF'
- },
- '15': {
- 'p1': '79',
- 'p3': '3117',
- 'p7': '535C'
- },
- '16': {
- 'p1': '75',
- 'p3': '3127',
- 'p7': '5C71'
- },
- '17': {
- 'p1': '69',
- 'p3': '311B',
- 'p7': '6208'
- },
- '18': {
- 'p1': '6F',
- 'p3': '311F',
- 'p7': '4EBA'
- },
- '19': {
- 'p1': '70',
- 'p3': '3123',
- 'p7': '5FC3'
- },
- '1A': {
- 'p1': '007B',
- 'p7': '005B'
- },
- '1B': {
- 'p1': '007D',
- 'p7': '005D'
- },
- '1C': {
- 'format': 'right',
- 'label': 'enter'
- },
- '1D': {
- 'format': 'left',
- 'label': 'ctrl'
- },
- '1E': {
- 'p1': '61',
- 'p3': '3107',
- 'p7': '65E5'
- },
- '1F': {
- 'p1': '73',
- 'p3': '310B',
- 'p7': '5C38'
- },
- '20': {
- 'p1': '64',
- 'p3': '310E',
- 'p7': '6728'
- },
- '21': {
- 'p1': '66',
- 'p3': '3111',
- 'p7': '706B'
- },
- '22': {
- 'p1': '67',
- 'p3': '3115',
- 'p7': '571F'
- },
- '23': {
- 'p1': '68',
- 'p3': '3118',
- 'p7': '7AF9'
- },
- '24': {
- 'p1': '6A',
- 'p3': '3128',
- 'p7': '5341'
- },
- '25': {
- 'p1': '6B',
- 'p3': '311C',
- 'p7': '5927'
- },
- '26': {
- 'p1': '6C',
- 'p3': '3120',
- 'p7': '4E2D'
- },
- '27': {
- 'p1': '003A',
- 'p3': '3124',
- 'p7': '003B'
- },
- '28': {
- 'p1': '22',
- 'p7': '27'
- },
- '29': {
- 'p1': '007E',
- 'p7': '60'
- },
- '2A': {
- 'format': 'left',
- 'label': 'shift'
- },
- '2B': {
- 'p1': '007C',
- 'p7': '005C'
- },
- '2C': {
- 'p1': '7A',
- 'p3': '3108',
- 'p7': '91CD'
- },
- '2D': {
- 'p1': '78',
- 'p3': '310C',
- 'p7': '96E3'
- },
- '2E': {
- 'p1': '63',
- 'p3': '310F',
- 'p7': '91D1'
- },
- '2F': {
- 'p1': '76',
- 'p3': '3112',
- 'p7': '5973'
- },
- '30': {
- 'p1': '62',
- 'p3': '3116',
- 'p7': '6708'
- },
- '31': {
- 'p1': '6E',
- 'p3': '3119',
- 'p7': '5F13'
- },
- '32': {
- 'p1': '6D',
- 'p3': '3129',
- 'p7': '4E00'
- },
- '33': {
- 'p1': '003C',
- 'p3': '311D',
- 'p7': '002C'
- },
- '34': {
- 'p1': '003E',
- 'p3': '3121',
- 'p7': '002E'
- },
- '35': {
- 'p1': '003F',
- 'p3': '3125',
- 'p7': '002F'
- },
- '36': {
- 'format': 'right',
- 'label': 'shift'
- },
- '38': {
- 'format': 'left',
- 'label': 'alt'
- },
- '39': {
- 'label': 'space'
- },
- '3B': {
- 'label': 'back'
- },
- '3C': {
- 'label': 'forward'
- },
- '3D': {
- 'label': 'reload'
- },
- '3E': {
- 'label': 'full screen'
- },
- '3F': {
- 'label': 'switch window'
- },
- '40': {
- 'label': 'bright down'
- },
- '41': {
- 'label': 'bright up'
- },
- '42': {
- 'label': 'mute'
- },
- '43': {
- 'label': 'vol. down'
- },
- '44': {
- 'label': 'vol. up'
- },
- 'E0 1D': {
- 'format': 'smaller',
- 'label': 'ctrl'
- },
- 'E0 38': {
- 'format': 'smaller',
- 'label': 'alt'
- },
- 'E0 48': {
- 'label': 'up'
- },
- 'E0 4B': {
- 'label': 'left'
- },
- 'E0 4D': {
- 'label': 'right'
- },
- 'E0 50': {
- 'label': 'down'
- },
- 'E0 5B': {
- 'format': 'left',
- 'label': 'search'
- }
- },
- 'layoutName': 'U'
- }
- },
- 'layouts': {
- 'B': [
- [
- '43',
- 658.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '44',
- 730.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '42',
- 585.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '41',
- 513.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '40',
- 440.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3F',
- 368.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '3D',
- 223.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '3E',
- 295.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3C',
- 150.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3B',
- 77.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '00',
- 803.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '01',
- 5.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '',
- 815.0,
- 107.0,
- 30.0,
- 60.0
- ],
- [
- '73',
- 740.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '56',
- 80.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '39',
- 245.0,
- 287.0,
- 330.0,
- 60.0
- ],
- [
- '0E',
- 785.0,
- 47.0,
- 90.0,
- 60.0
- ],
- [
- '1C',
- 830.0,
- 107.0,
- 45.0,
- 120.0
- ],
- [
- '36',
- 800.0,
- 227.0,
- 75.0,
- 60.0
- ],
- [
- '0F',
- 5.0,
- 107.0,
- 90.0,
- 60.0
- ],
- [
- '2A',
- 5.0,
- 227.0,
- 75.0,
- 60.0
- ],
- [
- 'E0 50',
- 755.0,
- 318.0,
- 60.0,
- 29.0
- ],
- [
- 'E0 48',
- 755.0,
- 287.0,
- 60.0,
- 31.0
- ],
- [
- 'E0 4D',
- 815.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 4B',
- 695.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 5B',
- 5.0,
- 167.0,
- 105.0,
- 60.0
- ],
- [
- '38',
- 125.0,
- 287.0,
- 120.0,
- 60.0
- ],
- [
- '1D',
- 5.0,
- 287.0,
- 120.0,
- 60.0
- ],
- [
- 'E0 1D',
- 635.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 38',
- 575.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- '2B',
- 770.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '0D',
- 725.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0C',
- 665.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0B',
- 605.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0A',
- 545.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '09',
- 485.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '08',
- 425.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '07',
- 365.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '06',
- 305.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '05',
- 245.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '04',
- 185.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '03',
- 125.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '02',
- 65.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '29',
- 5.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '35',
- 680.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '34',
- 620.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '33',
- 560.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '32',
- 500.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '31',
- 440.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '30',
- 380.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2F',
- 320.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2E',
- 260.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2D',
- 200.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2C',
- 140.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '28',
- 710.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '27',
- 650.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '26',
- 590.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '25',
- 530.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '24',
- 470.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '23',
- 410.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '22',
- 350.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '21',
- 290.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '20',
- 230.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1F',
- 170.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1E',
- 110.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1B',
- 755.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '1A',
- 695.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '19',
- 635.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '18',
- 575.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '17',
- 515.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '16',
- 455.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '15',
- 395.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '14',
- 335.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '13',
- 275.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '12',
- 215.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '11',
- 155.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '10',
- 95.0,
- 107.0,
- 60.0,
- 60.0
- ]
- ],
- 'E': [
- [
- '43',
- 658.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '44',
- 730.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '42',
- 585.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '41',
- 513.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '40',
- 440.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3F',
- 368.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '3D',
- 223.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '3E',
- 295.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3C',
- 150.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3B',
- 77.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '00',
- 803.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '01',
- 5.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '',
- 815.0,
- 107.0,
- 30.0,
- 60.0
- ],
- [
- '56',
- 80.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '39',
- 245.0,
- 287.0,
- 330.0,
- 60.0
- ],
- [
- '0E',
- 785.0,
- 47.0,
- 90.0,
- 60.0
- ],
- [
- '1C',
- 830.0,
- 107.0,
- 45.0,
- 120.0
- ],
- [
- '36',
- 740.0,
- 227.0,
- 135.0,
- 60.0
- ],
- [
- '0F',
- 5.0,
- 107.0,
- 90.0,
- 60.0
- ],
- [
- '2A',
- 5.0,
- 227.0,
- 75.0,
- 60.0
- ],
- [
- 'E0 50',
- 755.0,
- 318.0,
- 60.0,
- 29.0
- ],
- [
- 'E0 48',
- 755.0,
- 287.0,
- 60.0,
- 31.0
- ],
- [
- 'E0 4D',
- 815.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 4B',
- 695.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 5B',
- 5.0,
- 167.0,
- 105.0,
- 60.0
- ],
- [
- '38',
- 125.0,
- 287.0,
- 120.0,
- 60.0
- ],
- [
- '1D',
- 5.0,
- 287.0,
- 120.0,
- 60.0
- ],
- [
- 'E0 1D',
- 635.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 38',
- 575.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- '2B',
- 770.5,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '0D',
- 725.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0C',
- 665.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0B',
- 605.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0A',
- 545.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '09',
- 485.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '08',
- 425.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '07',
- 365.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '06',
- 305.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '05',
- 245.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '04',
- 185.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '03',
- 125.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '02',
- 65.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '29',
- 5.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '35',
- 680.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '34',
- 620.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '33',
- 560.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '32',
- 500.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '31',
- 440.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '30',
- 380.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2F',
- 320.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2E',
- 260.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2D',
- 200.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2C',
- 140.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '28',
- 710.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '27',
- 650.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '26',
- 590.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '25',
- 530.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '24',
- 470.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '23',
- 410.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '22',
- 350.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '21',
- 290.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '20',
- 230.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1F',
- 170.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1E',
- 110.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1B',
- 755.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '1A',
- 695.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '19',
- 635.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '18',
- 575.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '17',
- 515.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '16',
- 455.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '15',
- 395.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '14',
- 335.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '13',
- 275.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '12',
- 215.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '11',
- 155.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '10',
- 95.0,
- 107.0,
- 60.0,
- 60.0
- ]
- ],
- 'J': [
- [
- '43',
- 658.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '44',
- 730.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '42',
- 585.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '41',
- 513.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '40',
- 440.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3F',
- 368.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '3D',
- 223.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '3E',
- 295.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3C',
- 150.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3B',
- 77.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '00',
- 803.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '01',
- 5.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '',
- 800.0,
- 107.0,
- 30.0,
- 60.0
- ],
- [
- '73',
- 725.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '39',
- 260.0,
- 287.0,
- 240.0,
- 60.0
- ],
- [
- '79',
- 500.0,
- 287.0,
- 75.0,
- 60.0
- ],
- [
- '7B',
- 185.0,
- 287.0,
- 75.0,
- 60.0
- ],
- [
- '7D',
- 759.0,
- 47.0,
- 56.0,
- 60.0
- ],
- [
- '0E',
- 815.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '1C',
- 815.0,
- 107.0,
- 60.0,
- 120.0
- ],
- [
- '36',
- 785.0,
- 227.0,
- 90.0,
- 60.0
- ],
- [
- '0F',
- 5.0,
- 107.0,
- 75.0,
- 60.0
- ],
- [
- '2A',
- 5.0,
- 227.0,
- 120.0,
- 60.0
- ],
- [
- 'E0 50',
- 755.0,
- 318.0,
- 60.0,
- 29.0
- ],
- [
- 'E0 48',
- 755.0,
- 287.0,
- 60.0,
- 31.0
- ],
- [
- 'E0 4D',
- 815.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 4B',
- 695.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 5B',
- 5.0,
- 167.0,
- 90.0,
- 60.0
- ],
- [
- '38',
- 95.0,
- 287.0,
- 90.0,
- 60.0
- ],
- [
- '1D',
- 5.0,
- 287.0,
- 90.0,
- 60.0
- ],
- [
- 'E0 1D',
- 635.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 38',
- 575.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- '2B',
- 755.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '0D',
- 701.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '0C',
- 643.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '0B',
- 585.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '0A',
- 527.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '09',
- 469.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '08',
- 411.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '07',
- 353.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '06',
- 295.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '05',
- 237.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '04',
- 179.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '03',
- 121.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '02',
- 63.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '29',
- 5.0,
- 47.0,
- 58.0,
- 60.0
- ],
- [
- '35',
- 665.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '34',
- 605.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '33',
- 545.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '32',
- 485.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '31',
- 425.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '30',
- 365.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2F',
- 305.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2E',
- 245.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2D',
- 185.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2C',
- 125.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '28',
- 695.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '27',
- 635.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '26',
- 575.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '25',
- 515.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '24',
- 455.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '23',
- 395.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '22',
- 335.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '21',
- 275.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '20',
- 215.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1F',
- 155.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1E',
- 95.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1B',
- 740.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '1A',
- 680.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '19',
- 620.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '18',
- 560.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '17',
- 500.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '16',
- 440.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '15',
- 380.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '14',
- 320.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '13',
- 260.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '12',
- 200.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '11',
- 140.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '10',
- 80.0,
- 107.0,
- 60.0,
- 60.0
- ]
- ],
- 'U': [
- [
- '39',
- 245.0,
- 287.0,
- 330.0,
- 60.0
- ],
- [
- '43',
- 658.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '44',
- 730.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '42',
- 585.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '41',
- 513.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '40',
- 440.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3F',
- 368.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '3D',
- 223.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '3E',
- 295.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3C',
- 150.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '3B',
- 77.0,
- 6.0,
- 73.0,
- 35.0
- ],
- [
- '00',
- 803.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '01',
- 5.0,
- 6.0,
- 72.0,
- 35.0
- ],
- [
- '0E',
- 785.0,
- 47.0,
- 90.0,
- 60.0
- ],
- [
- '1C',
- 770.0,
- 167.0,
- 105.0,
- 60.0
- ],
- [
- '36',
- 740.0,
- 227.0,
- 135.0,
- 60.0
- ],
- [
- '0F',
- 5.0,
- 107.0,
- 90.0,
- 60.0
- ],
- [
- '2A',
- 5.0,
- 227.0,
- 135.0,
- 60.0
- ],
- [
- 'E0 50',
- 755.0,
- 318.0,
- 60.0,
- 29.0
- ],
- [
- 'E0 48',
- 755.0,
- 287.0,
- 60.0,
- 31.0
- ],
- [
- 'E0 4D',
- 815.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 4B',
- 695.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 5B',
- 5.0,
- 167.0,
- 105.0,
- 60.0
- ],
- [
- '38',
- 125.0,
- 287.0,
- 120.0,
- 60.0
- ],
- [
- '1D',
- 5.0,
- 287.0,
- 120.0,
- 60.0
- ],
- [
- 'E0 1D',
- 635.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- 'E0 38',
- 575.0,
- 287.0,
- 60.0,
- 60.0
- ],
- [
- '2B',
- 815.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '0D',
- 725.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0C',
- 665.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0B',
- 605.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '0A',
- 545.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '09',
- 485.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '08',
- 425.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '07',
- 365.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '06',
- 305.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '05',
- 245.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '04',
- 185.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '03',
- 125.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '02',
- 65.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '29',
- 5.0,
- 47.0,
- 60.0,
- 60.0
- ],
- [
- '35',
- 680.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '34',
- 620.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '33',
- 560.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '32',
- 500.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '31',
- 440.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '30',
- 380.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2F',
- 320.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2E',
- 260.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2D',
- 200.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '2C',
- 140.0,
- 227.0,
- 60.0,
- 60.0
- ],
- [
- '28',
- 710.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '27',
- 650.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '26',
- 590.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '25',
- 530.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '24',
- 470.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '23',
- 410.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '22',
- 350.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '21',
- 290.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '20',
- 230.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1F',
- 170.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1E',
- 110.0,
- 167.0,
- 60.0,
- 60.0
- ],
- [
- '1B',
- 755.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '1A',
- 695.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '19',
- 635.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '18',
- 575.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '17',
- 515.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '16',
- 455.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '15',
- 395.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '14',
- 335.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '13',
- 275.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '12',
- 215.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '11',
- 155.0,
- 107.0,
- 60.0,
- 60.0
- ],
- [
- '10',
- 95.0,
- 107.0,
- 60.0,
- 60.0
- ]
- ]
- },
- 'shortcut': {
- '+<>ALT': 'keyboardOverlayMaximizeWindow',
- '+<>ALT<>SHIFT': 'keyboardOverlayCenterWindow',
- '+<>CTRL': 'keyboardOverlayZoomIn',
- '+<>CTRL<>SHIFT': 'keyboardOverlayZoomScreenIn',
- ',<>ALT<>CTRL': 'keyboardOverlayPreviousUser',
- '-<>ALT': 'keyboardOverlayMinimizeWindow',
- '-<>CTRL': 'keyboardOverlayZoomOut',
- '-<>CTRL<>SHIFT': 'keyboardOverlayZoomScreenOut',
- '-<>SEARCH': 'keyboardOverlayF11',
- '.<>ALT<>CTRL': 'keyboardOverlayNextUser',
- '.<>CTRL<>SHIFT': 'keyboardOverlayToggleSpeechInput',
- '.<>SEARCH': 'keyboardOverlayInsert',
- '/<>ALT<>CTRL': 'keyboardOverlayViewKeyboardOverlay',
- '/<>ALT<>CTRL<>SHIFT': 'keyboardOverlayViewKeyboardOverlay',
- '/<>CTRL': 'keyboardOverlayHelp',
- '/<>CTRL<>SHIFT': 'keyboardOverlayHelp',
- '0<>CTRL': 'keyboardOverlayResetZoom',
- '0<>CTRL<>SHIFT': 'keyboardOverlayResetScreenZoom',
- '0<>SEARCH': 'keyboardOverlayF10',
- '1<>ALT': 'keyboardOverlayActivateShelfItem1',
- '1<>CTRL': 'keyboardOverlayActivateTab1',
- '1<>SEARCH': 'keyboardOverlayF1',
- '2<>ALT': 'keyboardOverlayActivateShelfItem2',
- '2<>CTRL': 'keyboardOverlayActivateTab2',
- '2<>SEARCH': 'keyboardOverlayF2',
- '3<>ALT': 'keyboardOverlayActivateShelfItem3',
- '3<>CTRL': 'keyboardOverlayActivateTab3',
- '3<>SEARCH': 'keyboardOverlayF3',
- '4<>ALT': 'keyboardOverlayActivateShelfItem4',
- '4<>CTRL': 'keyboardOverlayActivateTab4',
- '4<>SEARCH': 'keyboardOverlayF4',
- '5<>ALT': 'keyboardOverlayActivateShelfItem5',
- '5<>CTRL': 'keyboardOverlayActivateTab5',
- '5<>SEARCH': 'keyboardOverlayF5',
- '6<>ALT': 'keyboardOverlayActivateShelfItem6',
- '6<>CTRL': 'keyboardOverlayActivateTab6',
- '6<>SEARCH': 'keyboardOverlayF6',
- '7<>ALT': 'keyboardOverlayActivateShelfItem7',
- '7<>CTRL': 'keyboardOverlayActivateTab7',
- '7<>SEARCH': 'keyboardOverlayF7',
- '8<>ALT': 'keyboardOverlayActivateShelfItem8',
- '8<>CTRL': 'keyboardOverlayActivateTab8',
- '8<>SEARCH': 'keyboardOverlayF8',
- '9<>ALT': 'keyboardOverlayActivateLastShelfItem',
- '9<>CTRL': 'keyboardOverlayActivateLastTab',
- '9<>SEARCH': 'keyboardOverlayF9',
- '=<>SEARCH': 'keyboardOverlayF12',
- 'ALT<>SEARCH': 'keyboardOverlayToggleCapsLock',
- 'ALT<>SHIFT': 'keyboardOverlayCycleThroughInputMethods',
- '[<>ALT': 'keyboardOverlayDockWindowLeft',
- ']<>ALT': 'keyboardOverlayDockWindowRight',
- 'a<>CTRL': 'keyboardOverlaySelectAll',
- 'arrowkeys<>CTRL': 'keyboardOverlayWordMove',
- 'b<>ALT<>SHIFT': 'keyboardOverlayFocusBookmarks',
- 'b<>CTRL<>SHIFT': 'keyboardOverlayToggleBookmarkBar',
- 'back<>CTRL': 'keyboardOverlayFocusPreviousPane',
- 'back<>SEARCH': 'keyboardOverlayF1',
- 'backspace': 'keyboardOverlayGoBack',
- 'backspace<>ALT': 'keyboardOverlayDelete',
- 'backspace<>CTRL': 'keyboardOverlayDeleteWord',
- 'backspace<>CTRL<>SHIFT': 'keyboardOverlayClearBrowsingDataDialog',
- 'backspace<>SEARCH': 'keyboardOverlayDelete',
- 'backspace<>SHIFT': 'keyboardOverlayGoForward',
- 'bright down<>ALT': 'keyboardOverlayDecreaseKeyBrightness',
- 'bright down<>ALT<>CTRL': 'keyboardOverlayMagnifierDecreaseZoom',
- 'bright down<>SEARCH': 'keyboardOverlayF6',
- 'bright up<>ALT': 'keyboardOverlayIncreaseKeyBrightness',
- 'bright up<>ALT<>CTRL': 'keyboardOverlayMagnifierIncreaseZoom',
- 'bright up<>SEARCH': 'keyboardOverlayF7',
- 'c<>CTRL': 'keyboardOverlayCopy',
- 'c<>CTRL<>SHIFT': 'keyboardOverlayDomInspector',
- 'd<>ALT': 'keyboardOverlayFocusAddressBar',
- 'd<>CTRL': 'keyboardOverlayBookmarkCurrentPage',
- 'd<>CTRL<>SHIFT': 'keyboardOverlayBookmarkAllTabs',
- 'down<>ALT': 'keyboardOverlayPageDown',
- 'down<>ALT<>CTRL': 'keyboardOverlayEnd',
- 'down<>SEARCH': 'keyboardOverlayPageDown',
- 'e<>ALT': 'keyboardOverlayShowWrenchMenu',
- 'e<>CTRL': 'keyboardOverlayFocusAddressBarInSearchMode',
- 'enter<>ALT': 'keyboardOverlayOpenAddressInNewTab',
- 'enter<>CTRL': 'keyboardOverlayAddWwwAndComAndOpenAddress',
- 'enter<>SHIFT': 'keyboardOverlayFindPreviousText',
- 'esc<>SEARCH': 'keyboardOverlayTaskManager',
- 'f<>ALT': 'keyboardOverlayShowWrenchMenu',
- 'f<>CTRL': 'keyboardOverlayFindText',
- 'forward<>CTRL': 'keyboardOverlayFocusNextPane',
- 'forward<>SEARCH': 'keyboardOverlayF2',
- 'full screen<>ALT': 'keyboardOverlaySwapPrimaryMonitor',
- 'full screen<>CTRL': 'keyboardOverlayMirrorMonitors',
- 'full screen<>SEARCH': 'keyboardOverlayF4',
- 'g<>CTRL': 'keyboardOverlayFindTextAgain',
- 'g<>CTRL<>SHIFT': 'keyboardOverlayFindPreviousText',
- 'h<>CTRL': 'keyboardOverlayHistory',
- 'i<>ALT<>SHIFT': 'keyboardOverlayReportIssue',
- 'i<>CTRL<>SHIFT': 'keyboardOverlayDeveloperTools',
- 'j<>CTRL': 'keyboardOverlayDownloads',
- 'j<>CTRL<>SHIFT': 'keyboardOverlayJavascriptConsole',
- 'k<>CTRL': 'keyboardOverlayFocusAddressBarInSearchMode',
- 'l<>ALT<>SHIFT': 'keyboardOverlayFocusShelf',
- 'l<>CTRL': 'keyboardOverlayFocusAddressBar',
- 'l<>SEARCH': 'keyboardOverlayLockScreen',
- 'left<>ALT': 'keyboardOverlayGoBack',
- 'left<>CTRL': 'keyboardOverlayPreviousWord',
- 'left<>CTRL<>SHIFT': 'keyboardOverlaySelectWordAtATime',
- 'left<>SEARCH': 'keyboardOverlayHome',
- 'm<>ALT<>SHIFT': 'keyboardOverlayOpenFileManager',
- 'mute<>SEARCH': 'keyboardOverlayF8',
- 'n<>ALT<>SHIFT': 'keyboardOverlayShowMessageCenter',
- 'n<>CTRL': 'keyboardOverlayNewWindow',
- 'n<>CTRL<>SHIFT': 'keyboardOverlayNewIncognitoWindow',
- 'o<>CTRL': 'keyboardOverlayOpen',
- 'o<>CTRL<>SHIFT': 'keyboardOverlayBookmarkManager',
- 'p<>ALT<>CTRL': 'keyboardOverlayToggleProjectionTouchHud',
- 'p<>CTRL': 'keyboardOverlayPrint',
- 'p<>CTRL<>SHIFT': 'keyboardOverlayOpenGoogleCloudPrint',
- 'power': 'keyboardOverlayLockScreenOrPowerOff',
- 'q<>CTRL<>SHIFT': 'keyboardOverlaySignOut',
- 'r<>CTRL': 'keyboardOverlayReloadCurrentPage',
- 'r<>CTRL<>SHIFT': 'keyboardOverlayReloadIgnoringCache',
- 'reload<>CTRL<>SHIFT': 'keyboardOverlayRotateScreen',
- 'reload<>SEARCH': 'keyboardOverlayF3',
- 'right<>ALT': 'keyboardOverlayGoForward',
- 'right<>CTRL': 'keyboardOverlayNextWord',
- 'right<>CTRL<>SHIFT': 'keyboardOverlaySelectWordAtATime',
- 'right<>SEARCH': 'keyboardOverlayEnd',
- 's<>ALT<>SHIFT': 'keyboardOverlayShowStatusMenu',
- 's<>CTRL': 'keyboardOverlaySave',
- 'space<>CTRL': 'keyboardOverlaySelectPreviousInputMethod',
- 'space<>SHIFT': 'keyboardOverlayScrollUpOnePage',
- 'switch window<>CTRL': 'keyboardOverlayTakeScreenshot',
- 'switch window<>CTRL<>SHIFT': 'keyboardOverlayScreenshotRegion',
- 'switch window<>SEARCH': 'keyboardOverlayF5',
- 't<>ALT<>CTRL': 'keyboardOverlayNewTerminal',
- 't<>ALT<>SHIFT': 'keyboardOverlayFocusToolbar',
- 't<>CTRL': 'keyboardOverlayNewTab',
- 't<>CTRL<>SHIFT': 'keyboardOverlayReopenLastClosedTab',
- 'tab<>ALT': 'keyboardOverlayNextWindow',
- 'tab<>ALT<>SHIFT': 'keyboardOverlayPreviousWindow',
- 'tab<>CTRL': 'keyboardOverlayActivateNextTab',
- 'tab<>CTRL<>SHIFT': 'keyboardOverlayActivatePreviousTab',
- 'u<>CTRL': 'keyboardOverlayViewSource',
- 'u<>CTRL<>SHIFT': 'keyboardOverlayInputUnicodeCharacters',
- 'up<>ALT': 'keyboardOverlayPageUp',
- 'up<>ALT<>CTRL': 'keyboardOverlayHome',
- 'up<>SEARCH': 'keyboardOverlayPageUp',
- 'v<>CTRL': 'keyboardOverlayPaste',
- 'v<>CTRL<>SHIFT': 'keyboardOverlayPasteAsPlainText',
- 'vol. down<>SEARCH': 'keyboardOverlayF9',
- 'vol. up<>SEARCH': 'keyboardOverlayF10',
- 'w<>CTRL': 'keyboardOverlayCloseTab',
- 'w<>CTRL<>SHIFT': 'keyboardOverlayCloseWindow',
- 'x<>CTRL': 'keyboardOverlayCut',
- 'z<>ALT<>CTRL': 'keyboardOverlayToggleChromevoxSpokenFeedback',
- 'z<>CTRL': 'keyboardOverlayUndo'
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/login/OWNERS b/chromium/chrome/browser/resources/chromeos/login/OWNERS
deleted file mode 100644
index 2ebdc1ec84f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-nkostylev@chromium.org
-antrim@chromium.org
-dzhioev@chromium.org
-achuith@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/login/accessibility_menu.css b/chromium/chrome/browser/resources/chromeos/login/accessibility_menu.css
deleted file mode 100644
index cb8350a18c8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/accessibility_menu.css
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#accessibility-menu {
- -webkit-padding-end: 80px;
- -webkit-padding-start: 25px;
- padding-bottom: 25px;
- padding-top: 15px;
-}
-
-.checkboxrow {
- display: -webkit-box;
- margin-top: 10px;
-}
-
-.checkboxlabel {
- -webkit-margin-start: 10px;
-}
-
-.close-button {
- background: url(chrome://theme/IDR_CLOSE_DIALOG) center no-repeat;
- height: 14px;
- position: absolute;
- right: 7px;
- top: 7px;
- width: 14px;
-}
-
-.close-button:hover {
- background-image: url(chrome://theme/IDR_CLOSE_DIALOG_H);
-}
-
-.close-button:active {
- background-image: url(chrome://theme/IDR_CLOSE_DIALOG_P);
-}
-
-html[dir=rtl] .close-button {
- left: 10px;
- right: auto;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/accessibility_menu.html b/chromium/chrome/browser/resources/chromeos/login/accessibility_menu.html
deleted file mode 100644
index 1a407925819..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/accessibility_menu.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<div id="accessibility-menu" class="bubble faded" hidden>
- <div class="checkboxrow">
- <input id="spoken-feedback" type="checkbox">
- <label for="spoken-feedback" class="checkboxlabel"
- i18n-content="spokenFeedbackOption">
- </label>
- </div>
- <div class="checkboxrow">
- <input id="large-cursor" type="checkbox">
- <label for="large-cursor" class="checkboxlabel"
- i18n-content="largeCursorOption">
- </label>
- </div>
- <div class="checkboxrow">
- <input id="high-contrast" type="checkbox">
- <label for="high-contrast" class="checkboxlabel"
- i18n-content="highContrastOption">
- </label>
- </div>
- <div class="checkboxrow">
- <input id="screen-magnifier" type="checkbox">
- <label for="screen-magnifier" class="checkboxlabel"
- i18n-content="screenMagnifierOption">
- </label>
- </div>
- <div class="checkboxrow">
- <input id="virtual-keyboard" type="checkbox">
- <label for="virtual-keyboard" class="checkboxlabel"
- i18n-content="virtualKeyboardOption">
- </label>
- </div>
- <div id="close-accessibility-menu" class="close-button"
- i18n-values="title:closeAccessibilityMenu" tabindex="0">
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/apps_menu.css b/chromium/chrome/browser/resources/chromeos/login/apps_menu.css
deleted file mode 100644
index 9068fabaa5d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/apps_menu.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.apps-menu-item {
- -webkit-padding-start: 24px;
- background: no-repeat 4px 50%;
- background-size: 16px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/apps_menu.js b/chromium/chrome/browser/resources/chromeos/login/apps_menu.js
deleted file mode 100644
index d60dce3dce4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/apps_menu.js
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Kiosk apps menu implementation.
- */
-
-cr.define('login', function() {
- 'use strict';
-
- var Menu = cr.ui.Menu;
- var MenuButton = cr.ui.MenuButton;
-
- /**
- * Creates apps menu button.
- * @constructor
- * @extends {cr.ui.MenuButton}
- */
- var AppsMenuButton = cr.ui.define('button');
-
- AppsMenuButton.prototype = {
- __proto__: MenuButton.prototype,
-
- /**
- * Flag of whether to rebuild the menu.
- * @type {boolean}
- * @private
- */
- needsRebuild_: true,
-
- /**
- * Array to hold apps info.
- * @type {Array}
- */
- data_: null,
- get data() {
- return this.data_;
- },
- set data(data) {
- this.data_ = data;
- this.needsRebuild_ = true;
- },
-
- /** @override */
- decorate: function() {
- MenuButton.prototype.decorate.call(this);
- this.menu = new Menu;
- cr.ui.decorate(this.menu, Menu);
- document.body.appendChild(this.menu);
-
- this.anchorType = cr.ui.AnchorType.ABOVE;
- chrome.send('initializeKioskApps');
- },
-
- /** @override */
- showMenu: function(shouldSetFocus) {
- if (this.needsRebuild_) {
- this.menu.textContent = '';
- this.data_.forEach(this.addItem_, this);
- this.needsRebuild_ = false;
- }
-
- if (this.data.length > 0)
- MenuButton.prototype.showMenu.apply(this, arguments);
- },
-
- /**
- * Invoked when apps menu becomes visible.
- */
- didShow: function() {
- window.setTimeout(function() {
- if (!$('apps-header-bar-item').hidden)
- chrome.send('checkKioskAppLaunchError');
- }, 500);
- },
-
- findAndRunAppForTesting: function(id, opt_diagnostic_mode) {
- this.showMenu(true);
- for (var i = 0; i < this.menu.menuItems.length; i++) {
- var menuNode = this.menu.menuItems[i];
- if (menuNode.appId == id) {
- var activationEvent = cr.doc.createEvent('Event');
- activationEvent.initEvent('activate', true, true);
-
- if (opt_diagnostic_mode) {
- var fakeCtrlEnterEvent = cr.doc.createEvent('KeyboardEvent');
- fakeCtrlEnterEvent.initKeyboardEvent('keypress', true, true, null,
- 'Enter', 0,
- true, false, false, false);
- activationEvent.originalEvent = fakeCtrlEnterEvent;
- }
-
- menuNode.dispatchEvent(activationEvent);
- break;
- }
- }
- },
-
- /**
- * Launch the app. If |diagnosticMode| is true, ask user to confirm.
- * @param {Object} app App data.
- * @param {boolean} diagnosticMode Whether to run the app in diagnostic
- * mode.
- */
- launchApp_: function(app, diagnosticMode) {
- if (!diagnosticMode) {
- chrome.send('launchKioskApp', [app.id, false]);
- return;
- }
-
- if (!this.confirmDiagnosticMode_) {
- this.confirmDiagnosticMode_ =
- new cr.ui.dialogs.ConfirmDialog(document.body);
- this.confirmDiagnosticMode_.setOkLabel(
- loadTimeData.getString('confirmKioskAppDiagnosticModeYes'));
- this.confirmDiagnosticMode_.setCancelLabel(
- loadTimeData.getString('confirmKioskAppDiagnosticModeNo'));
- }
-
- this.confirmDiagnosticMode_.show(
- loadTimeData.getStringF('confirmKioskAppDiagnosticModeFormat',
- app.label),
- function() {
- chrome.send('launchKioskApp', [app.id, true]);
- });
- },
-
- /**
- * Adds an app to the menu.
- * @param {Object} app An app info object.
- * @private
- */
- addItem_: function(app) {
- var menuItem = this.menu.addMenuItem(app);
- menuItem.classList.add('apps-menu-item');
- menuItem.appId = app.id;
- menuItem.addEventListener('activate', function(e) {
- var diagnosticMode = e.originalEvent && e.originalEvent.ctrlKey;
- this.launchApp_(app, diagnosticMode);
- }.bind(this));
- }
- };
-
- /**
- * Sets apps to be displayed in the apps menu.
- * @param {!Array<!Object>} apps An array of app info objects.
- */
- AppsMenuButton.setApps = function(apps) {
- $('show-apps-button').data = apps;
- $('login-header-bar').hasApps =
- apps.length > 0 || loadTimeData.getBoolean('kioskAppHasLaunchError');
- chrome.send('kioskAppsLoaded');
- };
-
- /**
- * Shows the given error message.
- * @param {!string} message Error message to show.
- */
- AppsMenuButton.showError = function(message) {
- /** @const */ var BUBBLE_OFFSET = 25;
- /** @const */ var BUBBLE_PADDING = 12;
- $('bubble').showTextForElement($('show-apps-button'),
- message,
- cr.ui.Bubble.Attachment.TOP,
- BUBBLE_OFFSET,
- BUBBLE_PADDING);
- };
-
-
- /**
- * Runs app with a given id from the list of loaded apps.
- * @param {!string} id of an app to run.
- * @param {boolean=} opt_diagnostic_mode Whether to run the app in diagnostic
- * mode. Default is false.
- */
- AppsMenuButton.runAppForTesting = function(id, opt_diagnostic_mode) {
- $('show-apps-button').findAndRunAppForTesting(id, opt_diagnostic_mode);
- };
-
- return {
- AppsMenuButton: AppsMenuButton
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/controller-pairing-screen.html b/chromium/chrome/browser/resources/chromeos/login/controller-pairing-screen.html
deleted file mode 100644
index a31686d188d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/controller-pairing-screen.html
+++ /dev/null
@@ -1,262 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-in-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-out-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/hero-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animated-pages.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-shared-element-animatable-behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-icon-item.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-material/paper-material.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
-List of devices.
-Published properties:
- * devices - array of strings, the model of the list.
- * selected - a name of the selected device ('null' if no devices are
- selected).
- * connecting - a binary attribute. If set, the list does not respond to the
- user actions and a spinner is shown near selected device.
--->
-<dom-module name="pairing-device-list">
- <link rel="stylesheet" href="pairing_device_list.css">
-
- <iron-iconset-svg name="pairing-device-list-icons">
- <svg><defs><g id="circle">
- <circle cx="12" cy="12" r="12"></circle>
- </g></defs></svg>
- </iron-iconset-svg>
-
- <template>
- <iron-selector selected="{{selected}}" attr-for-selected="name">
- <template is="dom-repeat" items="[[devices]]">
- <paper-icon-item name$="[[item]]" class="relative">
- <iron-icon icon="pairing-device-list-icons:circle" item-icon
- style$="[[getStyleForDeviceIcon_(item)]]">
- </iron-icon>
- <div><span>[[item]]</span></div>
- <div class="flex horizontal end-justified layout center">
- <div class="throbber"></div>
- </div>
- </paper-icon-item>
- </template>
- </iron-selector>
- </template>
-</dom-module>
-
-<!--
-Single page of the controller's out-of-box flow.
-The page consists of the top part and the bottom part.
-The top part contains a title of the page. Direct successors of the
-<controller-pairing-page> having 'title' class will be inserted there.
-The bottom part contains controls that are aligned right (all the successors
-that are <paper-button>s) and a content of the page (all the other successors).
-Special case is a help button (<paper-button> with 'help' class set) which
-is aligned left.
-There are several classes that can be used to change the page appearance:
- * split - if this class is set, top and bottom parts will have different
- colors.
- * big-font - if this class is set, slightly bigger font is used on page.
- * progress - if this class is set and 'split' is not, progress bar is shown
- instead of top and bottom parts separator.
-
-Also height of the top part can be specified in CSS as follows:
-
-controller-pairing-page::shadow #top {
- height: 100px;
-}
--->
-<dom-module name="controller-pairing-page">
- <link rel="stylesheet" href="controller_pairing_page.css">
-
- <template>
- <div class="vertical layout fit">
- <div id="top" class="relative vertical end-justified layout">
- <div id="title">
- <content select=".title"></content>
- </div>
- <div id="separator">
- <paper-progress indeterminate></paper-progress>
- </div>
- </div>
- <div id="bottom" class="flex vertical layout">
- <div class="flex vertical layout">
- <content select=":not(paper-button)"></content>
- </div>
- <div id="controls" class="horizontal layout center">
- <div class="flex">
- <content select="paper-button.help-button"></content>
- </div>
- <content select="paper-button"></content>
- </div>
- </div>
- </div>
- </template>
-</dom-module>
-
-<dom-module name="controller-pairing-screen">
- <link rel="stylesheet" href="oobe_screen_controller_pairing.css">
-
- <template>
- <paper-material class="fit">
- <neon-animated-pages id="pages" selected="{{C.page}}"
- attr-for-selected="name" class="fit">
- <controller-pairing-page name="devices-discovery" class="big-font">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_welcomeTitle">
- </div>
- <div i18n-content="login_ControllerPairingScreen_searching"></div>
- <paper-button class="help-button" on-tap="helpButtonClicked_"
- i18n-content="login_ControllerPairingScreen_helpBtn">
- </paper-button>
- </controller-pairing-page>
-
- <controller-pairing-page name="device-select" class="split">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_selectTitle">
- </div>
- <pairing-device-list devices="[[C.devices]]"
- selected="{{selectedDevice}}">
- </pairing-device-list>
- <paper-button class="help-button" on-tap="helpButtonClicked_"
- i18n-content="login_ControllerPairingScreen_helpBtn">
- </paper-button>
- <paper-button on-tap="userActed" action="chooseDevice"
- disabled$="[[C.controlsDisabled]]"
- i18n-content="login_ControllerPairingScreen_connectBtn">
- </paper-button>
- </controller-pairing-page>
-
- <controller-pairing-page name="device-not-found">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_troubleConnectingTitle">
- </div>
- <div i18n-content="login_ControllerPairingScreen_connectingAdvice">
- </div>
- <paper-button on-tap="userActed" action="repeatDiscovery"
- i18n-content="login_ControllerPairingScreen_adviceGotItBtn">
- </paper-button>
- </controller-pairing-page>
-
- <controller-pairing-page name="establishing-connection" class="split">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_selectTitle">
- </div>
- <pairing-device-list devices="[[C.devices]]"
- selected="{{selectedDevice}}" connecting>
- </pairing-device-list>
- <paper-button class="help-button" on-tap="helpButtonClicked_"
- i18n-content="login_ControllerPairingScreen_helpBtn">
- </paper-button>
- <paper-button disabled
- i18n-content="login_ControllerPairingScreen_connecting">
- </paper-button>
- </controller-pairing-page>
-
- <controller-pairing-page name="establishing-connection-error">
- <!-- TODO(dzhioev): Strings TBD. http://crbug.com/423740 -->
- <div class="title">
- Unable to connect to <span>[[selectedDevice]]<span>
- </div>
- <paper-button on-tap="userActed" action="repeatDiscovery">
- Repeat discovery
- </paper-button>
- </controller-pairing-page>
-
- <controller-pairing-page name="code-confirmation" class="split">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_confirmationTitle">
- </div>
- <div
- i18n-content="login_ControllerPairingScreen_confirmationQuestion">
- </div>
- <div id="code"><span>[[C.code]]</span></div>
- <paper-button on-tap="userActed" action="rejectCode"
- disabled$="[[C.controlsDisabled]"
- i18n-content="login_ControllerPairingScreen_rejectCodeBtn">
- </paper-button>
- <paper-button on-tap="userActed" action="acceptCode"
- disabled$="[[C.controlsDisabled]]"
- i18n-content="login_ControllerPairingScreen_acceptCodeBtn">
- </paper-button>
- </controller-pairing-page>
-
- <controller-pairing-page name="host-update" class="split">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_updateTitle">
- </div>
- <div i18n-content="login_ControllerPairingScreen_updateText"></div>
- <paper-progress indeterminate></paper-progress>
- </controller-pairing-page>
-
- <controller-pairing-page name="host-connection-lost" class="split">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_connectionLostTitle">
- </div>
- <div i18n-content="login_ControllerPairingScreen_connectionLostText">
- </div>
- <paper-progress indeterminate></paper-progress>
- </controller-pairing-page>
-
- <controller-pairing-page name="enrollment-introduction" class="split">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_enrollTitle">
- </div>
- <p i18n-content="login_ControllerPairingScreen_enrollText1"></p>
- <p>
- <strong i18n-content="login_ControllerPairingScreen_enrollText2">
- </strong>
- </p>
- <paper-button on-tap="userActed" action="proceedToAuthentication"
- disabled$="[[C.controlsDisabled]]"
- i18n-content="login_ControllerPairingScreen_continueBtn">
- </paper-button>
- </controller-pairing-page>
-
- <controller-pairing-page name="authentication" class="split">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_enrollTitle">
- </div>
- <div>Not implemented.</div>
- </controller-pairing-page>
-
- <controller-pairing-page name="host-enrollment" class="progress">
- <!-- This title contains <strong> tag inside. -->
- <html-echo class="title"
- content="[[getHostEnrollmentStepTitle_(C.enrollmentDomain)]]">
- </html-echo>
- </controller-pairing-page>
-
- <controller-pairing-page name="host-enrollment-error" class="progress">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_enrollmentErrorTitle">
- </div>
- <div
- i18n-content="login_ControllerPairingScreen_enrollmentErrorHostRestarts">
- </div>
- </controller-pairing-page>
-
- <controller-pairing-page name="pairing-done" class="big-font">
- <div class="title"
- i18n-content="login_ControllerPairingScreen_successTitle">
- </div>
- <div><span>[[getSuccessMessage_(selectedDevice)]]</div>
- <paper-button on-tap="userActed" action="startSession"
- disabled$="{{C.controlsDisabled}}"
- i18n-content="login_ControllerPairingScreen_continueToHangoutsBtn">
- </paper-button>
- </controller-pairing-page>
- </neon-animated-pages>
- </paper-material>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/controller-pairing-screen.js b/chromium/chrome/browser/resources/chromeos/login/controller-pairing-screen.js
deleted file mode 100644
index 70d39e1b616..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/controller-pairing-screen.js
+++ /dev/null
@@ -1,168 +0,0 @@
-// 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.
-
-Polymer((function() {
- /** @const */ var ICON_COLORS = ['#F0B9CB', '#F0ACC3', '#F098B6', '#F084A9',
- '#F06D99', '#F05287', '#F0467F', '#F03473',
- '#F01E65', '#F00051'];
- return {
- is: 'pairing-device-list',
-
- properties: {
- devices: Array,
-
- selected: {
- type: String,
- notify: true
- },
-
- connecting: {
- type: Boolean,
- reflectToAttribute: true
- }
- },
-
- getStyleForDeviceIcon_: function(deviceName) {
- return 'color: ' + this.colorByName_(deviceName);
- },
-
- /* Returns pseudo-random color depending of hash of the |name|. */
- colorByName_: function(name) {
- var hash = 0;
- for (var i = 0; i < name.length; ++i)
- hash = (name.charCodeAt(i) + 31 * hash) | 0;
- return ICON_COLORS[hash % ICON_COLORS.length];
- }
- };
-})());
-
-Polymer({
- is: 'controller-pairing-page',
-
- behaviors: [
- Polymer.NeonSharedElementAnimatableBehavior
- ],
-
- properties: {
- sharedElements: {
- value: function() {
- return {
- 'top-hero': this.$.top,
- 'bottom-hero': this.$.bottom
- };
- }
- },
-
- animationConfig: {
- value: function() {
- return {
- 'entry': [{
- name: 'hero-animation',
- id: 'top-hero',
- toPage: this
- }, {
- name: 'hero-animation',
- id: 'bottom-hero',
- toPage: this
- }, {
- name: 'fade-in-animation',
- node: this
- }],
-
- 'exit': [{
- name: 'hero-animation',
- id: 'top-hero',
- fromPage: this
- }, {
- name: 'hero-animation',
- id: 'bottom-hero',
- fromPage: this
- }, {
- name: 'fade-out-animation',
- node: this
- }]
- };
- }
- }
- }
-});
-
-Polymer((function() {
- 'use strict';
-
- // Keep these constants synced with corresponding constants defined in
- // controller_pairing_screen_actor.{h,cc}.
- /** @const */ var CONTEXT_KEY_CONTROLS_DISABLED = 'controlsDisabled';
- /** @const */ var CONTEXT_KEY_SELECTED_DEVICE = 'selectedDevice';
- /** @const */ var CONTEXT_KEY_ACCOUNT_ID = 'accountId';
-
- /** @const */ var ACTION_ENROLL = 'enroll';
-
- /** @const */ var PAGE_AUTHENTICATION = 'authentication';
-
- return {
- is: 'controller-pairing-screen',
-
- behaviors: [
- login.OobeScreenBehavior
- ],
-
- properties: {
- selectedDevice: {
- type: String,
- observer: 'selectedDeviceChanged_'
- }
- },
-
- observers: [
- 'deviceListChanged_(C.devices)'
- ],
-
- ready: function() {
- /**
- * Workaround for
- * https://github.com/PolymerElements/neon-animation/issues/32
- * TODO(dzhioev): Remove when fixed in Polymer.
- */
- var pages = this.$.pages;
- delete pages._squelchNextFinishEvent;
- Object.defineProperty(pages, '_squelchNextFinishEvent',
- { get: function() { return false; } });
- },
-
- /** @override */
- initialize: function() {
- ['code',
- 'controlsDisabled',
- 'devices',
- 'enrollmentDomain',
- 'page'].forEach(this.registerBoundContextField, this);
- this.context.set(CONTEXT_KEY_CONTROLS_DISABLED, true);
- this.commitContextChanges();
- },
-
- deviceListChanged_: function() {
- this.selectedDevice = this.context.get(CONTEXT_KEY_SELECTED_DEVICE, null);
- },
-
- selectedDeviceChanged_: function(selectedDevice) {
- this.context.set(CONTEXT_KEY_SELECTED_DEVICE,
- selectedDevice ? selectedDevice : '');
- this.commitContextChanges();
- },
-
- helpButtonClicked_: function() {
- console.error('Help is not implemented yet.');
- },
-
- getHostEnrollmentStepTitle_: function(domain) {
- return this.i18n(['enrollmentInProgress', domain]);
- },
-
- getSuccessMessage_: function(selectedDevice) {
- return this.i18n(['successText', selectedDevice]);
- }
- };
-})());
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/controller_pairing_page.css b/chromium/chrome/browser/resources/chromeos/login/controller_pairing_page.css
deleted file mode 100644
index 4882169b30a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/controller_pairing_page.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* 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.
- */
-
-:host {
- background-color: var(--google-green-500);
- color: white;
-}
-
-content::content strong {
- font-weight: 500;
-}
-
-/* Top part of a page. */
-
-#top {
- box-sizing: border-box;
- font-size: 23px;
- height: 266px;
- padding: 34px 48px 22px;
-}
-
-:host(.split) #top {
- padding-bottom: 33px;
-}
-
-:host(.big-font) #top {
- font-size: 33px;
-}
-
-/* Separator. */
-
-#separator {
- background-color: var(--google-green-100);
- bottom: 0;
- display: block;
- height: 1px;
- left: 48px;
- position: absolute;
- right: 0;
-}
-
-:host(.split) #separator {
- display: none;
-}
-
-#separator paper-progress {
- --paper-progress-active-color: white;
- --paper-progress-container-color: var(--google-green-100);
- display: none;
- width: 100%;
-}
-
-:host(.progress) #separator paper-progress {
- display: block;
-}
-
-:host(.progress) #separator {
- bottom: -2px;
- height: 4px;
-}
-
-/* Bottom part of a page. */
-
-#bottom {
- font-size: 16px;
- padding: 20px 48px 34px;
-}
-
-:host(.split) #bottom {
- background: white;
- color: black;
- padding-top: 35px;
-}
-
-:host(.big-font) #bottom {
- font-size: 24px;
-}
-
-/* Controls. */
-
-#controls {
- font-size: 14px;
- font-weight: 500;
- margin-bottom: calc(-0.5em - 6px);
-}
-
-#controls :first-child {
- margin-left: -0.5em;
-}
-
-#controls content[select='paper-button']::content :last-child {
- margin-right: -0.5em;
-}
-
-#controls content[select='paper-button']::content :not(:last-child) {
- margin-right: 1em;
-}
-
-:host(.split) #controls content[select='paper-button']::content :last-child {
- color: var(--google-green-500);
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/custom_elements_login.html b/chromium/chrome/browser/resources/chromeos/login/custom_elements_login.html
deleted file mode 100644
index a769e997f8f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/custom_elements_login.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<include src="gaia_buttons.html">
-<include src="gaia_card.html">
-<include src="gaia_header.html">
-<include src="gaia_input_form.html">
-<include src="gaia_input.html">
-<include src="gaia_password_changed.html">
-<include src="offline_gaia.html">
-<include src="saml_confirm_password.html">
-<include src="throbber_notice.html">
-
-<script src="chrome://oobe/custom_elements.js"></script>
diff --git a/chromium/chrome/browser/resources/chromeos/login/custom_elements_login.js b/chromium/chrome/browser/resources/chromeos/login/custom_elements_login.js
deleted file mode 100644
index f2fa09433b1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/custom_elements_login.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 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="gaia_buttons.js">
-<include src="gaia_card.js">
-<include src="gaia_header.js">
-<include src="gaia_input_form.js">
-<include src="gaia_input.js">
-<include src="gaia_password_changed.js">
-<include src="offline_gaia.js">
-<include src="saml_confirm_password.js">
-<include src="throbber_notice.js">
diff --git a/chromium/chrome/browser/resources/chromeos/login/custom_elements_oobe.html b/chromium/chrome/browser/resources/chromeos/login/custom_elements_oobe.html
deleted file mode 100644
index 92c1e5ea9c6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/custom_elements_oobe.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<include src="controller-pairing-screen.html">
-<include src="gaia_buttons.html">
-<include src="gaia_card.html">
-<include src="gaia_header.html">
-<include src="gaia_input_form.html">
-<include src="gaia_input.html">
-<include src="gaia_password_changed.html">
-<include src="host-pairing-screen.html">
-<include src="html-echo.html">
-<include src="notification_card.html">
-<include src="offline_gaia.html">
-<include src="oobe-screen.html">
-<include src="saml_confirm_password.html">
-<include src="throbber_notice.html">
-
-<script src="chrome://oobe/custom_elements.js"></script>
diff --git a/chromium/chrome/browser/resources/chromeos/login/custom_elements_oobe.js b/chromium/chrome/browser/resources/chromeos/login/custom_elements_oobe.js
deleted file mode 100644
index b875dd9c192..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/custom_elements_oobe.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 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.
-
-// This inclusion should go first, as <{controller,host}-paring-screen> depend
-// of it.
-<include src="oobe-screen.js">
-
-<include src="controller-pairing-screen.js">
-<include src="gaia_buttons.js">
-<include src="gaia_card.js">
-<include src="gaia_header.js">
-<include src="gaia_input_form.js">
-<include src="gaia_input.js">
-<include src="gaia_password_changed.js">
-<include src="host-pairing-screen.js">
-<include src="html-echo.js">
-<include src="notification_card.js">
-<include src="offline_gaia.js">
-<include src="saml_confirm_password.js">
-<include src="throbber_notice.js">
diff --git a/chromium/chrome/browser/resources/chromeos/login/demo_user_login.html b/chromium/chrome/browser/resources/chromeos/login/demo_user_login.html
deleted file mode 100644
index 96a722ac4f4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/demo_user_login.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<meta charset="utf-8">
-<link rel="stylesheet" href="chrome://resources/css/spinner.css">
-<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
-<link rel="stylesheet" href="demo_user_login.css">
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="chrome://oobe/strings.js"></script>
-<script src="chrome://oobe/demo_user_login.js"></script>
-</head>
-<body>
- <div id="page">
- <div id="logo-container">
- <div>
- <img id="logo" src="images/chrome_retail_login.png">
- </div>
- <div id="lower-container">
- <div id="demo-login-text" i18n-content="demoLoginMessage"></div>
- <div id="login-spinner" class="inline-spinner" hidden></div>
- </div>
- </div>
- </div>
- <script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/login/enterprise_info.css b/chromium/chrome/browser/resources/chromeos/login/enterprise_info.css
deleted file mode 100644
index 2b84175e106..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/enterprise_info.css
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * This is the stylesheet used for notifications in enterprise-enrolled devices.
- */
-
-#enterprise-info {
- background-color: rgb(250, 245, 202);
- border: 2px solid rgb(250, 245, 202);
- border-radius: 2px;
- margin-left: auto;
- margin-right: auto;
- padding: 3px 8px 7px;
-}
-
-#enterprise-info[location='guest-tab'] {
- box-sizing: border-box;
- margin-bottom: -43px;
- max-width: 640px;
-}
-
-#enterprise-info[visible='false'] {
- display: none;
-}
-
-#enterprise-info img {
- -webkit-margin-end: 4px;
- height: 18px;
- position: relative;
- top: 4px;
- width: 18px;
-}
-
-@media (max-height:480px) and (max-width:400px) {
- #enterprise-info[location='guest-tab'] {
- margin-bottom: 1em;
- }
-}
-
-@media (max-width:400px) {
- #enterprise-info[location='guest-tab'] {
- margin-top: -2em;
- }
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/enterprise_info.html b/chromium/chrome/browser/resources/chromeos/login/enterprise_info.html
deleted file mode 100644
index 569281e8a07..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/enterprise_info.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<div id="enterprise-info" hidden>
- <img src="../../../../../ui/webui/resources/images/business.svg">
- <span id="enterprise-info-message"></span>
- <a id="enterprise-info-hint-link" href="#" i18n-content="learnMore"></a>
-</div>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia.css b/chromium/chrome/browser/resources/chromeos/login/gaia.css
deleted file mode 100644
index c8602c703fd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia.css
+++ /dev/null
@@ -1,54 +0,0 @@
-/* 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.
- */
-
-.gaia-input {
- border: 1px solid #d9d9d9;
- border-radius: 1px;
- border-top: 1px solid #c0c0c0;
- font-size: 15px;
- height: 32px;
- margin: 0;
- padding: 0 8px;
- width: 100%;
-}
-
-.gaia-input:focus {
- border: 1px solid rgb(77, 144, 254);
- box-shadow: inset 0 1px 2px rgba(0,0,0,0.3);
- outline: none;
-}
-
-.blue-button {
- background-color: rgb(77, 144, 254);
- background-image: -webkit-linear-gradient(top,
- rgb(77, 144, 254),
- rgb(71, 135, 237));
- border: 1px solid rgb(48, 121, 237);
- border-radius: 2px;
- color: #fff;
- font-size: 13px;
- font-weight: bold;
- height: 32px;
- margin: 0 1.5em 1.2em 0;
- text-shadow: 0 1px rgba(0, 0, 0, 0.1);
-}
-
-.blue-button:hover {
- background-color: rgb(53, 122, 232);
- background-image: -webkit-linear-gradient(top,
- rgb(77, 144, 254),
- rgb(53, 122, 232));
- border: 1px solid rgb(47, 91, 183);
- text-shadow: 0 1px rgba(0, 0, 0, 0.3);
-}
-
-.blue-button:focus {
- box-shadow: inset 0 0 0 1px #fff;
-}
-
-.blue-button:focus:hover {
- box-shadow: inset 0 0 0 1px #fff, 0 1px 1px rgba(0, 0, 0, 0.1);
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_button.css b/chromium/chrome/browser/resources/chromeos/login/gaia_button.css
deleted file mode 100644
index 67f758ea424..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_button.css
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- display: inline-block;
-}
-
-paper-button {
- background-color: var(--google-blue-500);
- color: white;
- font-size: 14px;
- min-width: 90px;
-}
-
-:host([type='link']) paper-button,
-:host([type='dialog']) paper-button {
- background-color: transparent;
- color: var(--google-blue-500);
- margin: 0;
- min-width: 0;
-}
-
-:host([type='link']) paper-button[focused],
-:host([type='dialog']) paper-button[focused] {
- background-color: rgba(66, 133, 244, 0.12);
-}
-
-:host([type='link']) paper-button[disabled],
-:host([type='dialog']) paper-button[disabled] {
- color: rgb(168,168,168);
-}
-
-:host([type='link']) paper-button {
- border-radius: 0;
- margin-left: -0.57em;
- margin-right: -0.57em;
- text-transform: none;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_buttons.html b/chromium/chrome/browser/resources/chromeos/login/gaia_buttons.html
deleted file mode 100644
index 08a59c31fa4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_buttons.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- Material design buttons that mimic GAIA's buttons.
-
- Example:
- <gaia-button type="dialog"></gaia-button>
-
- Attributes:
- 'type' - there are three kinds of button: regular blue button (none type
- provided), dialog button (type="dialog") and a button that looks
- more like a link (type="link").
- 'disabled' - button is disabled when the attribute is set.
--->
-<dom-module id="gaia-button">
- <link rel="stylesheet" href="gaia_button.css">
-
- <template>
- <div on-click="onClick_" on-tap="onClick_">
- <paper-button id="button" disabled="[[disabled]]"
- on-focused-changed="focusedChanged_">
- <content></content>
- </paper-button>
- </div>
- </template>
-</dom-module>
-
-<!--
- Material desing icon button with a special styling.
-
- Example:
- <gaia-icon-button icon="close"></gaia-icon>
-
- Attributes:
- 'icon' - a name of icon from material design set to show on button.
- 'disabled' - button is disabled when the attribute is set.
- 'aria-label' - accessibility label.
--->
-<dom-module id="gaia-icon-button">
- <link rel="stylesheet" href="gaia_icon_button.css">
-
- <template>
- <div on-click="onClick_" on-tap="onClick_">
- <paper-icon-button id="iconButton" icon="[[icon]]" disabled="[[disabled]]"
- aria-label="[[ariaLabel]]">
- </paper-icon-button>
- </div>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_buttons.js b/chromium/chrome/browser/resources/chromeos/login/gaia_buttons.js
deleted file mode 100644
index 7ae8de3b320..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_buttons.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer({
- is: 'gaia-button',
-
- properties: {
- disabled: {
- type: Boolean,
- value: false,
- reflectToAttribute: true
- },
-
- type: {
- type: String,
- value: '',
- reflectToAttribute: true,
- observer: 'typeChanged_'
- }
- },
-
- focus: function() {
- this.$.button.focus();
- },
-
- focusedChanged_: function() {
- if (this.type == 'link' || this.type == 'dialog')
- return;
- this.$.button.raised = this.$.button.focused;
- },
-
- typeChanged_: function() {
- if (this.type == 'link')
- this.$.button.setAttribute('noink', '');
- else
- this.$.button.removeAttribute('noink');
- },
-
- onClick_: function(e) {
- if (this.disabled)
- e.stopPropagation();
- }
-});
-
-Polymer({
- is: 'gaia-icon-button',
-
- properties: {
- disabled: {
- type: Boolean,
- value: false,
- reflectToAttribute: true
- },
-
- icon: String,
-
- ariaLabel: String
- },
-
- focus: function() {
- this.$.iconButton.focus();
- },
-
- onClick_: function(e) {
- if (this.disabled)
- e.stopPropagation();
- }
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_card.css b/chromium/chrome/browser/resources/chromeos/login/gaia_card.css
deleted file mode 100644
index dda92a8f969..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_card.css
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- display: flex;
- flex-direction: column;
- position: relative;
-}
-
-.gaia-header {
- background-color: var(--google-blue-500);
- color: white;
- height: 198px;
-}
-
-:host(:not(.disabled)) .gaia-header {
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.17);
- /* z-index is needed to make shadow visible. */
- z-index: 1;
-}
-
-.gaia-footer {
- background-color: rgb(238, 238, 238);
-}
-
-.gaia-footer {
- position: relative;
-}
-
-.header-container {
- padding: 50px 40px 18px;
-}
-
-.footer-container {
- padding: 24px 40px 34px;
-}
-
-::content div.gaia-body-text {
- margin-bottom: 24px;
-}
-
-::content div.gaia-body-text p {
- color: rgba(0, 0, 0, 0.87);
- font-size: 14px;
- line-height: 20px;
- margin: 0;
-}
-
-::content p.enterprise-info {
- color: white;
- font-size: 15px;
- margin: 8px 0 0 0;
-}
-
-::content h1.welcome-message {
- color: white;
- font-size: 20px;
- font-weight: normal;
- margin-bottom: 0;
-}
-
-.overlay {
- background-color: rgba(0, 0, 0, 0.5);
- display: none;
- height: 100%;
- position: absolute;
- right: 0;
- top: 0;
- width: 100%;
- z-index: 11;
-}
-
-paper-progress#progress-bar {
- --paper-progress-active-color: var(--google-yellow-500);
- --paper-progress-container-color: var(--google-yellow-100);
- bottom: 0;
- display: none;
- height: 3px;
- position: absolute;
- width: 100%;
-}
-
-:host(.full-disabled) #full-overlay,
-:host(.disabled) #bottom-overlay,
-:host(.disabled) #progress-bar {
- display: block;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_card.html b/chromium/chrome/browser/resources/chromeos/login/gaia_card.html
deleted file mode 100644
index 21a3c5197b6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_card.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- Simple Gaia card which should be used for local UI elements that look like
- GAIA. It has blue header and grey footer.
-
- Example:
- <gaia-card>
- <div class="header" flex vertical layout end-justified start>
- ...
- </div>
- <gaia-input-form class="footer" ...>
- </gaia-input-form>
- </gaia-card>
-
- Add class |header| to all which you want to go inside blue header. Similar
- with class |footer|.
--->
-<dom-module name="gaia-card">
- <link rel="stylesheet" href="gaia_card.css">
-
- <template>
- <div class="gaia-header vertical layout relative">
- <div class="header-container flex vertical layout relative">
- <content select=".header"></content>
- </div>
- <paper-progress id="progress-bar" indeterminate></paper-progress>
- </div>
- <div class="gaia-footer flex vertical layout">
- <div class="footer-container flex vertical layout">
- <content select=".footer"></content>
- </div>
- <div id="bottom-overlay" class="overlay"></div>
- </div>
- <div id="full-overlay" class="overlay"></div>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_header.css b/chromium/chrome/browser/resources/chromeos/login/gaia_header.css
deleted file mode 100644
index ccb7c1337b4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_header.css
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-}
-
-#email {
- font-size: 20px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_header.html b/chromium/chrome/browser/resources/chromeos/login/gaia_header.html
deleted file mode 100644
index e75ad5b0904..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_header.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- Blue header for New Gaia UI, contains blue avatar logo and user email.
-
- Example:
- <gaia-header email="user@example.com">
- </gaia-header>
-
- Attributes:
- 'email' - displayed email.
--->
-<dom-module name="gaia-header">
- <link rel="stylesheet" href="gaia_header.css">
-
- <template>
- <img src="chrome://theme/IDR_LOGO_AVATAR_CIRCLE_BLUE_COLOR" alt
- class="self-start">
- <div id="email"><span>[[email]]<span></div>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_header.js b/chromium/chrome/browser/resources/chromeos/login/gaia_header.js
deleted file mode 100644
index 69898a4e223..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_header.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer({
- is: 'gaia-header',
-
- properties: {
- email: String
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_icon_button.css b/chromium/chrome/browser/resources/chromeos/login/gaia_icon_button.css
deleted file mode 100644
index 4cd46601eab..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_icon_button.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#iconButton {
- padding: 0;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_input.css b/chromium/chrome/browser/resources/chromeos/login/gaia_input.css
deleted file mode 100644
index f0427d6b82d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_input.css
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- display: block;
-}
-
-paper-input-container {
- --paper-input-container-color: rgb(212, 212, 212);
- --paper-input-container-focus-color: var(--google-blue-500);
- --paper-input-container-input {
- font-size: 15px;
- };
- --paper-input-container-input-color: rgba(0, 0, 0, 0.87);
- --paper-input-container-label: {
- color: rgba(0, 0, 0, 0.54);
- font-size: 15px;
- };
-}
-
-paper-input-container {
- padding: 0;
-}
-
-:host-context(html[dir=rtl]) input {
- flex-direction: row-reverse;
-}
-
-#domainLabel {
- color: rgba(0, 0, 0, 0.54);
- direction: ltr;
- width: auto;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_input.html b/chromium/chrome/browser/resources/chromeos/login/gaia_input.html
deleted file mode 100644
index 21884cb5845..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_input.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-input/iron-input.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input-container.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input-error.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- Material desing input field, that supports different input types and email
- validation and matches GAIA's visual style.
-
- Examples:
- <gaia-input value="Simple text input" required></gaia-input>
- <gaia-input type="email" domain="example.com"></gaia-input>
-
- Attributes:
- 'label' - same as <paper-input>'s 'label'.
- 'value' - same as <input>'s 'value'.
- 'type' - same as <input>'s 'type'.
- 'domain' - optional attribute for email input. The domain is displayed in
- the end of input field, if user is not provided any.
- 'error' - error message displayed in case if 'isInvalid' is true.
- 'isInvalid' - whether input data is invalid. Note: it is not changed
- automatically. Can be changed manually or with checkValidity()
- method.
- 'required' - whether empty field is invalid.
-
- Methods:
- 'focus' - focuses input field.
- 'checkValidity' - returns current validity state of the input form. Updates
- 'isInvalid' at the end.
--->
-<dom-module name="gaia-input">
- <link rel="stylesheet" href="gaia_input.css">
-
- <template>
- <paper-input-container id="decorator" on-tap="onTap"
- invalid="[[isInvalid]]" disabled$="[[disabled]]">
- <label><span>[[label]]</span></label>
- <div id="container" class="horizontal layout">
- <input id="input" is="iron-input" on-keydown="onKeyDown"
- bind-value="{{value}}" invalid="[[isInvalid]]"
- required$="[[required]]" disabled$="[[disabled]]" class="flex">
- <span id="domainLabel">[[domain]]</span>
- </div>
- <template is="dom-if" if="[[error]]">
- <paper-input-error>[[error]]</paper-input-error>
- </template>
- </paper-input-container>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_input.js b/chromium/chrome/browser/resources/chromeos/login/gaia_input.js
deleted file mode 100644
index b0bdd3ab9d8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_input.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer((function() {
- var INPUT_EMAIL_PATTERN = "^[a-zA-Z0-9.!#$%&'*+=?^_`{|}~-]+(@[^\\s@]+)?$";
-
- return {
- is: 'gaia-input',
-
- properties: {
- label: String,
- value: {
- notify: true,
- observer: 'updateDomainVisibility_',
- type: String
- },
-
- type: {
- observer: 'typeChanged_',
- type: String
- },
-
- domain: {
- observer: 'updateDomainVisibility_',
- type: String
- },
-
- disabled: Boolean,
-
- required: Boolean,
-
- error: String,
-
- isInvalid: Boolean
- },
-
- attached: function() {
- this.typeChanged_();
- },
-
- onKeyDown: function(e) {
- this.isInvalid = false;
- },
-
- updateDomainVisibility_: function() {
- this.$.domainLabel.hidden = (this.type !== 'email') || !this.domain ||
- (this.value && this.value.indexOf('@') !== -1);
- },
-
- onTap: function() {
- this.isInvalid = false;
- },
-
- focus: function() {
- this.$.input.focus();
- },
-
- checkValidity: function() {
- var valid = this.$.input.validate();
- this.isInvalid = !valid;
- return valid;
- },
-
- typeChanged_: function() {
- if (this.type == 'email') {
- this.$.input.pattern = INPUT_EMAIL_PATTERN;
- this.$.input.type = 'text';
- } else {
- this.$.input.removeAttribute('pattern');
- this.$.input.type = this.type;
- }
- this.updateDomainVisibility_();
- }
- };
-})());
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.css b/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.css
deleted file mode 100644
index 728f518659b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- display: block;
- font-size: 16px;
-}
-
-#inputs::content gaia-input {
- margin-bottom: 24px;
-}
-
-#inputs::content gaia-input:last-of-type {
- margin-bottom: 28px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.html b/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.html
deleted file mode 100644
index 2c75ba39bb7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- A simple input form with a button. Being used for typing email or password.
- User should put one or more <gaia-input>s inside.
-
- Example:
- <gaia-input-form button-text="Submit">
- <gaia-input label="Email" type="email"></gaia-input>
- <gaia-input label="Password" type="password"></gaia-input>
- <gaia-input label="OTP"></gaia-input>
- </gaia-input-form>
-
- Attributes:
- 'button-text' - text on the button.
-
- Events:
- 'submit' - fired on button click or "Enter" press inside input field.
-
--->
-<dom-module name="gaia-input-form">
- <link rel="stylesheet" href="gaia_input_form.css">
-
- <template>
- <div on-keydown="onKeyDown_">
- <content id="inputs" select="gaia-input"></content>
- <div class="horizontal-reverse justified layout center">
- <gaia-button id="button" on-tap="onButtonClicked_" class="self-end">
- <span>[[buttonText]]</span>
- </gaia-button>
- <content> </content>
- </div>
- </div>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.js b/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.js
deleted file mode 100644
index a49348b27cc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_input_form.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer({
- is: 'gaia-input-form',
-
- properties: {
- disabled: {
- type: Boolean,
- observer: 'onDisabledChanged_',
- },
-
- buttonText: String
- },
-
- onButtonClicked_: function() {
- this.fire('submit');
- },
-
- getInputs_: function() {
- return Polymer.dom(this.$.inputs).getDistributedNodes();
- },
-
- onKeyDown_: function(e) {
- if (e.keyCode != 13 || this.$.button.disabled)
- return;
- if (this.getInputs_().indexOf(e.target) == -1)
- return;
- this.onButtonClicked_();
- },
-
- getControls_: function() {
- var controls = this.getInputs_();
- controls.push(this.$.button);
- return controls.concat(Polymer.dom(this).querySelectorAll('gaia-button'));
- },
-
- onDisabledChanged_: function(disabled) {
- this.getControls_().forEach(function(control) {
- control.disabled = disabled;
- });
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.css b/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.css
deleted file mode 100644
index 37c6b5671c1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- display: block;
- position: relative;
-}
-
-iron-icon[icon='warning'] {
- color: var(--google-yellow-500);
- margin: 0 15px 0 0;
-}
-
-:host-context(html[dir=rtl]) iron-icon[icon='warning'] {
- margin: 0 0 0 15px;
-}
-
-#closeButton {
- color: white;
- position: absolute;
- right: 10px;
- top: 10px;
- z-index: 1;
-}
-
-:host-context(html[dir=rtl]) #closeButton {
- left: 10px;
- right: auto;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.html b/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.html
deleted file mode 100644
index d4d2d20e57f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.html
+++ /dev/null
@@ -1,101 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-in-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-out-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animated-pages.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- Password changed UI for the New Gaia flow.
- Contains two cards with a fade transition between them:
- 1. Old password input form.
- 2. Warning about data loss
- 3. Spinner with notice "Please wait";
-
- Example:
- <gaia-password-changed id="gaia-password-changed" hidden>
- </gaia-password-changed>
-
- Attributes:
- 'email' - displayed email in header.
-
- Events:
- 'passwordEnter' - fired when user enters password. Fires with an argument
- |password|.
- 'proceedAnyway' - fired when user decides to skip old password and
- lose all the data in cryptohome.
- 'cancel' - fired when user press X-button.
-
- Methods:
- 'invalidate' - mark password input as invalid.
- 'reset' - reset element, sets in on the first screen and enables
- buttons.
- 'focus' - if current card is the first one it focuses password input.
-
--->
-<dom-module name="gaia-password-changed">
- <link rel="stylesheet" href="gaia_password_changed.css">
-
- <template>
- <neon-animated-pages id="animatedPages" class="fit"
- entry-animation="fade-in-animation" exit-animation="fade-out-animation"
- on-neon-animation-finish="onAnimationFinish_" selected="0">
- <neon-animatable class="fit">
- <gaia-card id="oldPasswordCard" class="fit">
- <gaia-header class="header" email="[[email]]">
- </gaia-header>
- <div class="footer gaia-body-text" class="horizontal layout center">
- <p i18n-content="passwordChangedTitle">
- </p>
- </div>
- <gaia-input-form class="footer" id="oldPasswordInputForm"
- disabled="[[disabled]]" on-submit="onPasswordSubmitted_"
- i18n-values="button-text:nextButtonText">
- <gaia-input id="oldPasswordInput" type="password" required
- i18n-values="error:oldPasswordIncorrect;
- label:oldPasswordHint">
- </gaia-input>
- <gaia-button type="link" on-tap="onForgotPasswordClicked_"
- i18n-content="forgotOldPasswordButtonText">
- </gaia-button>
- </gaia-input-form>
- </gaia-card>
- </neon-animatable>
- <neon-animatable class="fit">
- <gaia-card class="fit">
- <gaia-header class="header" email="[[email]]">
- </gaia-header>
- <div class="footer">
- <div class="gaia-body-text horizontal layout center">
- <iron-icon icon="warning"></iron-icon>
- <p i18n-content="passwordChangedProceedAnywayTitle" class="flex">
- </p>
- </div>
- <div class="horizontal layout justified center">
- <gaia-button type="link" on-tap="onTryAgainClicked_"
- i18n-content="passwordChangedTryAgain">
- </gaia-button>
- <gaia-button id="proceedAnywayBtn" on-tap="onProceedClicked_"
- i18n-content="proceedAnywayButton">
- </gaia-button>
- </div>
- </div>
- </gaia-card>
- </neon-animatable>
- <neon-animatable class="fit">
- <throbber-notice class="fit" i18n-values="text:gaiaLoadingNewGaia">
- </throbber-notice>
- </neon-animatable>
- </neon-animated-pages>
- <gaia-icon-button id="closeButton" icon="close" on-tap="onClose_"
- disabled="[[disabled]]" i18n-values="aria-label:closeButton">
- </gaia-icon-button>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.js b/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.js
deleted file mode 100644
index 033ca4bafdf..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_password_changed.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer({
- is: 'gaia-password-changed',
-
- properties: {
- email: String,
-
- disabled: {
- type: Boolean,
- value: false
- }
- },
-
- ready: function() {
- /**
- * Workaround for
- * https://github.com/PolymerElements/neon-animation/issues/32
- * TODO(dzhioev): Remove when fixed in Polymer.
- */
- var pages = this.$.animatedPages;
- delete pages._squelchNextFinishEvent;
- Object.defineProperty(pages, '_squelchNextFinishEvent',
- { get: function() { return false; } });
- },
-
- invalidate: function() {
- this.$.oldPasswordInput.isInvalid = true;
- },
-
- reset: function() {
- this.$.animatedPages.selected = 0;
- this.clearPassword();
- this.$.oldPasswordInput.isInvalid = false;
- this.disabled = false;
- this.$.closeButton.hidden = false;
- this.$.oldPasswordCard.classList.remove('disabled');
- },
-
-
- focus: function() {
- if (this.$.animatedPages.selected == 0)
- this.$.oldPasswordInput.focus();
- },
-
- onPasswordSubmitted_: function() {
- if (!this.$.oldPasswordInput.checkValidity())
- return;
- this.$.oldPasswordCard.classList.add('disabled');
- this.disabled = true;
- this.fire('passwordEnter', {password: this.$.oldPasswordInput.value});
- },
-
- onForgotPasswordClicked_: function() {
- this.clearPassword();
- this.$.animatedPages.selected += 1;
- },
-
- onTryAgainClicked_: function() {
- this.$.oldPasswordInput.isInvalid = false;
- this.$.animatedPages.selected -= 1;
- },
-
- onAnimationFinish_: function() {
- this.focus();
- },
-
- clearPassword: function() {
- this.$.oldPasswordInput.value = '';
- },
-
- onProceedClicked_: function() {
- this.disabled = true;
- this.$.closeButton.hidden = true;
- this.$.animatedPages.selected = 2;
- this.fire('proceedAnyway');
- },
-
- onClose_: function() {
- this.fire('cancel');
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/header_bar.css b/chromium/chrome/browser/resources/chromeos/login/header_bar.css
deleted file mode 100644
index b3ea0d6a7db..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/header_bar.css
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#login-header-bar {
- -webkit-padding-start: 15px;
- border-bottom: 3px solid black;
- bottom: 0;
- left: 0;
- padding-bottom: 7px;
- position: absolute;
- right: 0;
-}
-
-#login-header-bar {
- /* Using copy of Ash launcher background with 0.8 opacity applied to it.
- Otherwise if opacity: 0.8 is set here it will affect button text as well.
- Have to position background differently so that opacity is not applied
- to child elements. */
- background-image: url(chrome://theme/IDR_LAUNCHER_BACKGROUND);
- padding-top: 7px;
-}
-
-html[screen=lock] .login-header-bar-hidden,
-html[screen=oobe] .login-header-bar-hidden {
- opacity: 0;
-}
-
-html[screen=lock] .login-header-bar-animate-fast,
-html[screen=oobe] .login-header-bar-animate-fast {
- -webkit-transition: opacity 200ms ease-out;
-}
-
-html[screen=lock] .login-header-bar-animate-slow,
-html[screen=oobe] .login-header-bar-animate-slow {
- -webkit-transition: opacity 2s ease-out;
-}
-
-#login-header-bar button,
-#login-header-bar button:active,
-#login-header-bar button:focus,
-#login-header-bar button:hover {
- background: transparent none;
- box-shadow: none;
- cursor: pointer;
- height: 34px;
- margin: 0;
- min-width: 0;
- opacity: 0.6;
- padding: 5px 8px;
- vertical-align: middle;
-}
-
-#login-header-bar button:not(.button-restricted),
-#login-header-bar button:active:not(.button-restricted),
-#login-header-bar button:focus:not(.button-restricted),
-#login-header-bar button:hover:not(.button-restricted) {
- color: white !important;
- opacity: 1 !important;
-}
-
-.header-bar-item {
- display: inline-block;
- height: 34px;
-}
-
-.add-supervised-user-menu {
- display: none;
-}
-
-#more-settings-header-bar-item.active button.add-supervised-user-menu {
- background-color: white;
- border: 1px solid lightgray;
- border-radius: 2px;
- bottom: 15px;
- color: black !important;
- display: block;
- font-size: 13px;
- height: auto;
- left: 15px;
- margin: 0 0 -10px -10px;
- min-height: 34px;
- position: absolute;
- text-align: center;
- width: 180px;
-}
-
-html[dir=rtl] #more-settings-header-bar-item.active
- button.add-supervised-user-menu {
- right: 0;
-}
-
-html[dir=rtl] .header-bar-item {
- background-position: right center;
-}
-
-#login-header-bar #shutdown-button,
-#login-header-bar #restart-button,
-#login-header-bar #add-user-button,
-#login-header-bar #guest-user-button,
-#login-header-bar #more-settings-button,
-#login-header-bar #cancel-multiple-sign-in-button {
- -webkit-padding-start: 24px;
- background-position: left center;
- background-repeat: no-repeat;
- background-size: 24px;
-}
-
-html[dir=rtl] #login-header-bar #shutdown-button,
-html[dir=rtl] #login-header-bar #restart-button,
-html[dir=rtl] #login-header-bar #add-user-button,
-html[dir=rtl] #login-header-bar #more-settings-button,
-html[dir=rtl] #login-header-bar #guest-user-button,
-html[dir=rtl] #login-header-bar #cancel-multiple-sign-in-button {
- background-position: right center;
-}
-
-#login-header-bar #more-settings-header-bar-item {
- position: relative;
-}
-
-#login-header-bar #shutdown-button {
- background-image: url(chrome://theme/IDR_ICON_POWER_WHITE);
-}
-
-#login-header-bar #restart-button {
- background-image: url(chrome://theme/IDR_ICON_POWER_WHITE);
-}
-
-#login-header-bar #add-user-button {
- background-image: url(chrome://theme/IDR_ICON_ADD_USER_WHITE);
-}
-
-#login-header-bar #more-settings-button {
- background-image: url(chrome://theme/IDR_ICON_MORE_VERT_WHITE);
-}
-
-#login-header-bar #guest-user-button {
- background-image: url(chrome://theme/IDR_ICON_GUEST_WHITE);
-}
-
-#login-header-bar #cancel-multiple-sign-in-button {
- /* TODO(dzhioev): replace with appropriate image when possible. */
- background-image: url(chrome://theme/IDR_PANEL_CLOSE);
-}
-
-.button-restricted {
- border: 1px solid transparent;
- color: white !important;
- opacity: 0.4 !important;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/header_bar.html b/chromium/chrome/browser/resources/chromeos/login/header_bar.html
deleted file mode 100644
index 1358dec7a68..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/header_bar.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<div id="login-header-bar" hidden class="login-header-bar-hidden">
- <div id="shutdown-header-bar-item" class="header-bar-item">
- <button id="shutdown-button" class="custom-appearance"
- i18n-content="shutDown"></button>
- </div>
- <div id="restart-header-bar-item" class="header-bar-item">
- <button id="restart-button" class="custom-appearance"
- i18n-content="restart"></button>
- </div>
- <div id="apps-header-bar-item" class="header-bar-item" hidden>
- <button id="show-apps-button" class="custom-appearance"
- i18n-content="showApps"></button>
- </div>
- <div id="guest-user-header-bar-item" class="header-bar-item" hidden>
- <button id="guest-user-button" class="custom-appearance"
- i18n-content="browseAsGuest"></button>
- </div>
- <div id="add-user-header-bar-item" class="header-bar-item" hidden>
- <button id="add-user-button" class="custom-appearance"
- i18n-content="addUser"></button>
- <button id="cancel-add-user-button" class="custom-appearance"
- i18n-content="cancel" hidden></button>
- </div>
- <div id="more-settings-header-bar-item" class="header-bar-item">
- <button id="more-settings-button" class="custom-appearance"
- i18n-values="aria-label:moreOptions"></button>
- <button class="add-supervised-user-menu custom-appearance"
- id="add-supervised-user-menu" tabindex="0"
- i18n-content="addSupervisedUser">
- </button>
- </div>
- <div id="sign-out-user-item" class="header-bar-item" hidden>
- <button id="sign-out-user-button" class="custom-appearance"
- i18n-content="signOutUser"></button>
- </div>
- <div id="cancel-multiple-sign-in-item" class="header-bar-item" hidden>
- <button id="cancel-multiple-sign-in-button" class="custom-appearance"
- i18n-content="cancel"></button>
- </div>
- <div id="cancel-consumer-management-enrollment" class="header-bar-item"
- hidden>
- <button id="cancel-consumer-management-enrollment-button"
- class="custom-appearance" i18n-content="cancel">
- </button>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/header_bar.js b/chromium/chrome/browser/resources/chromeos/login/header_bar.js
deleted file mode 100644
index 5a747c8ea7c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/header_bar.js
+++ /dev/null
@@ -1,451 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Login UI header bar implementation.
- */
-
-cr.define('login', function() {
- /**
- * Creates a header bar element.
- *
- * @constructor
- * @extends {HTMLDivElement}
- */
- var HeaderBar = cr.ui.define('div');
-
- HeaderBar.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- // Whether guest button should be shown when header bar is in normal mode.
- showGuest_: false,
-
- // Whether the reboot button should be shown the when header bar is in
- // normal mode.
- showReboot_: false,
-
- // Whether the shutdown button should be shown when the header bar is in
- // normal mode.
- showShutdown_: true,
-
- // Whether the create supervised user button should be shown when the header
- // bar is in normal mode. It will be shown in "More settings" menu.
- showCreateSupervised_: false,
-
- // Current UI state of the sign-in screen.
- signinUIState_: SIGNIN_UI_STATE.HIDDEN,
-
- // Whether to show kiosk apps menu.
- hasApps_: false,
-
- /** @override */
- decorate: function() {
- document.addEventListener('click', this.handleClick_.bind(this));
- $('shutdown-header-bar-item').addEventListener('click',
- this.handleShutdownClick_);
- $('shutdown-button').addEventListener('click',
- this.handleShutdownClick_);
- $('restart-header-bar-item').addEventListener('click',
- this.handleShutdownClick_);
- $('restart-button').addEventListener('click',
- this.handleShutdownClick_);
- $('add-user-button').addEventListener('click',
- this.handleAddUserClick_);
- $('more-settings-button').addEventListener('click',
- this.handleMoreSettingsClick_.bind(this));
- $('cancel-add-user-button').addEventListener('click',
- this.handleCancelAddUserClick_);
- $('guest-user-header-bar-item').addEventListener('click',
- this.handleGuestClick_);
- $('guest-user-button').addEventListener('click',
- this.handleGuestClick_);
- $('sign-out-user-button').addEventListener('click',
- this.handleSignoutClick_);
- $('cancel-multiple-sign-in-button').addEventListener('click',
- this.handleCancelMultipleSignInClick_);
- $('cancel-consumer-management-enrollment-button').addEventListener(
- 'click',
- this.handleCancelConsumerManagementEnrollmentClick_);
- this.addSupervisedUserMenu.addEventListener('click',
- this.handleAddSupervisedUserClick_.bind(this));
- if (Oobe.getInstance().displayType == DISPLAY_TYPE.LOGIN ||
- Oobe.getInstance().displayType == DISPLAY_TYPE.OOBE) {
- if (Oobe.getInstance().newKioskUI)
- chrome.send('initializeKioskApps');
- else
- login.AppsMenuButton.decorate($('show-apps-button'));
- }
- this.updateUI_();
- },
-
- /**
- * Tab index value for all button elements.
- *
- * @type {number}
- */
- set buttonsTabIndex(tabIndex) {
- var buttons = this.getElementsByTagName('button');
- for (var i = 0, button; button = buttons[i]; ++i) {
- button.tabIndex = tabIndex;
- }
- },
-
- /**
- * Disables the header bar and all of its elements.
- *
- * @type {boolean}
- */
- set disabled(value) {
- var buttons = this.getElementsByTagName('button');
- for (var i = 0, button; button = buttons[i]; ++i)
- if (!button.classList.contains('button-restricted'))
- button.disabled = value;
- },
-
- get getMoreSettingsMenu() {
- return $('more-settings-header-bar-item');
- },
-
- get addSupervisedUserMenu() {
- return this.querySelector('.add-supervised-user-menu');
- },
-
- /**
- * Whether action box button is in active state.
- * @type {boolean}
- */
- get isMoreSettingsActive() {
- return this.getMoreSettingsMenu.classList.contains('active');
- },
- set isMoreSettingsActive(active) {
- if (active == this.isMoreSettingsActive)
- return;
- if (active) {
- this.getMoreSettingsMenu.classList.add('active');
- } else {
- this.getMoreSettingsMenu.classList.remove('active');
- }
- },
-
-
- /**
- * Add user button click handler.
- *
- * @private
- */
- handleAddUserClick_: function(e) {
- Oobe.showSigninUI();
- // Prevent further propagation of click event. Otherwise, the click event
- // handler of document object will set wallpaper to user's wallpaper when
- // there is only one existing user. See http://crbug.com/166477
- e.stopPropagation();
- },
-
- handleMoreSettingsClick_: function(e) {
- this.isMoreSettingsActive = !this.isMoreSettingsActive;
- this.addSupervisedUserMenu.focus();
- e.stopPropagation();
- },
-
- handleClick_: function(e) {
- this.isMoreSettingsActive = false;
- },
-
- handleAddSupervisedUserClick_: function(e) {
- chrome.send('showSupervisedUserCreationScreen');
- e.preventDefault();
- },
-
- /**
- * Cancel add user button click handler.
- *
- * @private
- */
- handleCancelAddUserClick_: function(e) {
- // Let screen handle cancel itself if that is capable of doing so.
- if (Oobe.getInstance().currentScreen &&
- Oobe.getInstance().currentScreen.cancel) {
- Oobe.getInstance().currentScreen.cancel();
- return;
- }
-
- Oobe.showUserPods();
- },
-
- /**
- * Guest button click handler.
- *
- * @private
- */
- handleGuestClick_: function(e) {
- Oobe.disableSigninUI();
- chrome.send('launchIncognito');
- e.stopPropagation();
- },
-
- /**
- * Sign out button click handler.
- *
- * @private
- */
- handleSignoutClick_: function(e) {
- this.disabled = true;
- chrome.send('signOutUser');
- e.stopPropagation();
- },
-
- /**
- * Shutdown button click handler.
- *
- * @private
- */
- handleShutdownClick_: function(e) {
- chrome.send('shutdownSystem');
- e.stopPropagation();
- },
-
- /**
- * Cancel user adding button handler.
- *
- * @private
- */
- handleCancelMultipleSignInClick_: function(e) {
- chrome.send('cancelUserAdding');
- e.stopPropagation();
- },
-
- /**
- * Cancel consumer management enrollment button handler.
- *
- * @private
- */
- handleCancelConsumerManagementEnrollmentClick_: function(e) {
- chrome.send('cancelConsumerManagementEnrollment');
- e.stopPropagation();
- },
-
- /**
- * If true then "Browse as Guest" button is shown.
- *
- * @type {boolean}
- */
- set showGuestButton(value) {
- this.showGuest_ = value;
- this.updateUI_();
- },
-
- set showCreateSupervisedButton(value) {
- this.showCreateSupervised_ = value;
- this.updateUI_();
- },
-
- /**
- * If true the "Restart" button is shown.
- *
- * @type {boolean}
- */
- set showRebootButton(value) {
- this.showReboot_ = value;
- this.updateUI_();
- },
-
- /**
- * If true the "Shutdown" button is shown.
- *
- * @type {boolean}
- */
- set showShutdownButton(value) {
- this.showShutdown_ = value;
- this.updateUI_();
- },
-
- /**
- * Current header bar UI / sign in state.
- *
- * @type {number} state Current state of the sign-in screen (see
- * SIGNIN_UI_STATE).
- */
- get signinUIState() {
- return this.signinUIState_;
- },
- set signinUIState(state) {
- this.signinUIState_ = state;
- this.updateUI_();
- },
-
- /**
- * Whether the Cancel button is enabled during Gaia sign-in.
- *
- * @type {boolean}
- */
- set allowCancel(value) {
- this.allowCancel_ = value;
- this.updateUI_();
- },
-
- get allowCancel() {
- return !!this.allowCancel_;
- },
-
- /**
- * Update whether there are kiosk apps.
- *
- * @type {boolean}
- */
- set hasApps(value) {
- this.hasApps_ = value;
- this.updateUI_();
- },
-
- /**
- * Updates visibility state of action buttons.
- *
- * @private
- */
- updateUI_: function() {
- var gaiaIsActive = (this.signinUIState_ == SIGNIN_UI_STATE.GAIA_SIGNIN);
- var gaiaIsActiveWithBackButton =
- gaiaIsActive && !$('back-button-item').hidden;
- var enrollmentIsActive =
- (this.signinUIState_ == SIGNIN_UI_STATE.ENROLLMENT);
- var enrollmentIsActiveWithBackButton =
- enrollmentIsActive && !$('oauth-enroll-back-button').hidden;
- var accountPickerIsActive =
- (this.signinUIState_ == SIGNIN_UI_STATE.ACCOUNT_PICKER);
- var supervisedUserCreationDialogIsActive =
- (this.signinUIState_ ==
- SIGNIN_UI_STATE.SUPERVISED_USER_CREATION_FLOW);
- var wrongHWIDWarningIsActive =
- (this.signinUIState_ == SIGNIN_UI_STATE.WRONG_HWID_WARNING);
- var isSamlPasswordConfirm =
- (this.signinUIState_ == SIGNIN_UI_STATE.SAML_PASSWORD_CONFIRM);
- var isEnrollingConsumerManagement = (this.signinUIState_ ==
- SIGNIN_UI_STATE.CONSUMER_MANAGEMENT_ENROLLMENT);
- var isPasswordChangedUI =
- (this.signinUIState_ == SIGNIN_UI_STATE.PASSWORD_CHANGED);
- var isMultiProfilesUI =
- (Oobe.getInstance().displayType == DISPLAY_TYPE.USER_ADDING);
- var isLockScreen =
- (Oobe.getInstance().displayType == DISPLAY_TYPE.LOCK);
- var errorScreenIsActive =
- (this.signinUIState_ == SIGNIN_UI_STATE.ERROR);
-
- $('add-user-button').hidden =
- !accountPickerIsActive ||
- isMultiProfilesUI ||
- isLockScreen ||
- errorScreenIsActive;
- $('more-settings-header-bar-item').hidden =
- !this.showCreateSupervised_ ||
- gaiaIsActive ||
- isLockScreen ||
- errorScreenIsActive ||
- supervisedUserCreationDialogIsActive;
- $('cancel-add-user-button').hidden =
- !this.allowCancel_ ||
- gaiaIsActive ||
- isPasswordChangedUI ||
- isSamlPasswordConfirm ||
- errorScreenIsActive ||
- accountPickerIsActive ||
- wrongHWIDWarningIsActive ||
- isMultiProfilesUI ||
- supervisedUserCreationDialogIsActive;
- $('guest-user-header-bar-item').hidden =
- !this.showGuest_ ||
- isLockScreen ||
- supervisedUserCreationDialogIsActive ||
- wrongHWIDWarningIsActive ||
- isSamlPasswordConfirm ||
- isMultiProfilesUI ||
- (this.allowCancel_ && gaiaIsActive) ||
- enrollmentIsActiveWithBackButton ||
- gaiaIsActiveWithBackButton;
- $('restart-header-bar-item').hidden = !this.showReboot_;
- $('shutdown-header-bar-item').hidden = !this.showShutdown_;
- $('sign-out-user-item').hidden = !isLockScreen;
-
- $('add-user-header-bar-item').hidden =
- $('add-user-button').hidden && $('cancel-add-user-button').hidden;
- $('apps-header-bar-item').hidden = !this.hasApps_ ||
- (!gaiaIsActive && !accountPickerIsActive);
- $('cancel-multiple-sign-in-item').hidden = !isMultiProfilesUI;
- $('cancel-consumer-management-enrollment').hidden =
- !isEnrollingConsumerManagement;
-
- if (!Oobe.getInstance().newKioskUI) {
- if (!$('apps-header-bar-item').hidden)
- $('show-apps-button').didShow();
- }
- },
-
- /**
- * Animates Header bar to hide from the screen.
- *
- * @param {function()} callback will be called once animation is finished.
- */
- animateOut: function(callback) {
- var launcher = this;
- launcher.addEventListener(
- 'webkitTransitionEnd', function f(e) {
- launcher.removeEventListener('webkitTransitionEnd', f);
- callback();
- });
- // Guard timer for 2 seconds + 200 ms + epsilon.
- ensureTransitionEndEvent(launcher, 2250);
-
- this.classList.remove('login-header-bar-animate-slow');
- this.classList.add('login-header-bar-animate-fast');
- this.classList.add('login-header-bar-hidden');
- },
-
- /**
- * Animates Header bar to appear on the screen.
- *
- * @param {boolean} fast Whether the animation should complete quickly or
- * slowly.
- * @param {function()} callback will be called once animation is finished.
- */
- animateIn: function(fast, callback) {
- if (callback) {
- var launcher = this;
- launcher.addEventListener(
- 'webkitTransitionEnd', function f(e) {
- launcher.removeEventListener('webkitTransitionEnd', f);
- callback();
- });
- // Guard timer for 2 seconds + 200 ms + epsilon.
- ensureTransitionEndEvent(launcher, 2250);
- }
-
- if (fast) {
- this.classList.remove('login-header-bar-animate-slow');
- this.classList.add('login-header-bar-animate-fast');
- } else {
- this.classList.remove('login-header-bar-animate-fast');
- this.classList.add('login-header-bar-animate-slow');
- }
-
- this.classList.remove('login-header-bar-hidden');
- },
- };
-
- /**
- * Convenience wrapper of animateOut.
- */
- HeaderBar.animateOut = function(callback) {
- $('login-header-bar').animateOut(callback);
- };
-
- /**
- * Convenience wrapper of animateIn.
- */
- HeaderBar.animateIn = function(fast, callback) {
- $('login-header-bar').animateIn(fast, callback);
- };
-
- return {
- HeaderBar: HeaderBar
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/host-pairing-screen.html b/chromium/chrome/browser/resources/chromeos/login/host-pairing-screen.html
deleted file mode 100644
index ef6e82e5cc8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/host-pairing-screen.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-in-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-out-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable-behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animated-pages.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-icon-item.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<iron-iconset-svg name="host-pairing-icons" size="48">
- <svg>
- <defs>
- <g id="cast">
- <include src="../../../../app/theme/cast_icon.svg">
- </g>
- </defs>
- </svg>
-</iron-iconset-svg>
-
-<dom-module name="host-pairing-page">
-
- <link rel="stylesheet" href="oobe_screen_host_pairing_page.css">
-
- <template>
- <div id="title">
- <content select=".title"></content>
- </div>
- <div id="content">
- <content></content>
- </div>
- </template>
-</dom-module>
-
-<dom-module name="host-pairing-screen">
-
- <link rel="stylesheet" href="oobe_screen_host_pairing.css">
-
- <template>
- <neon-animated-pages attr-for-selected="name" selected="[[C.page]]"
- entry-animation="fade-in-animation" exit-animation="fade-out-animation">
- <host-pairing-page name="welcome">
- <div class="title" i18n-content="login_HostPairingScreen_welcomeTitle">
- </div>
- <div i18n-content="login_HostPairingScreen_welcomeText"></div>
- </host-pairing-page>
- <host-pairing-page name="code-confirmation">
- <div class="title"
- i18n-content="login_HostPairingScreen_confirmationTitle">
- </div>
- <div id="code">{{C.code}}</div>
- </host-pairing-page>
- <host-pairing-page name="update">
- <div class="title" i18n-content="login_HostPairingScreen_updatingTitle">
- </div>
- </host-pairing-page>
- <host-pairing-page name="enrollment-introduction">
- <div class="title" i18n-content="login_HostPairingScreen_enrollTitle">
- </div>
- </host-pairing-page>
- <host-pairing-page name="enrollment">
- <div class="title">
- <!-- 'enrollmentTitle' contains <strong> tag. We need to wrap it in
- 'html-echo' to prevent HTML escaping. -->
- <html-echo content="[[getEnrollmentStepTitle_(C.enrollmentDomain)]]">
- </html-echo>
- </div>
- </host-pairing-page>
- <host-pairing-page name="enrollment-error">
- <div class="title"
- i18n-content="login_HostPairingScreen_enrollmentErrorTitle">
- </div>
- <div i18n-content="login_HostPairingScreen_errorNeedsRestart"></div>
- </host-pairing-page>
- <host-pairing-page name="pairing-done">
- <div class="title" i18n-content="login_HostPairingScreen_doneTitle">
- </div>
- <div i18n-content="login_HostPairingScreen_doneText"></div>
- </host-pairing-page>
- </neon-animated-pages>
- <paper-icon-item id="device-indicator">
- <iron-icon icon="host-pairing-icons:cast" item-icon></iron-icon>
- <div id="device-label">{{C.deviceName}}</div>
- </paper-icon-item>
- <div id="illustration"></div>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/host-pairing-screen.js b/chromium/chrome/browser/resources/chromeos/login/host-pairing-screen.js
deleted file mode 100644
index 25baa321650..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/host-pairing-screen.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.
-
-Polymer({
- is: 'host-pairing-page',
-
- behaviors: [Polymer.NeonAnimatableBehavior]
-});
-
-Polymer((function() {
- 'use strict';
-
- /** @const */ var CALLBACK_CONTEXT_READY = 'contextReady';
-
- return {
- is: 'host-pairing-screen',
-
- behaviors: [login.OobeScreenBehavior],
-
- onBeforeShow: function() {
- Oobe.getInstance().headerHidden = true;
- },
-
- /** @override */
- initialize: function() {
- ['code',
- 'deviceName',
- 'enrollmentDomain',
- 'page'].forEach(this.registerBoundContextField, this);
- this.send(CALLBACK_CONTEXT_READY);
- },
-
- getEnrollmentStepTitle_: function(enrollmentDomain) {
- return this.i18n(['enrollingTitle', enrollmentDomain]);
- }
- };
-})());
diff --git a/chromium/chrome/browser/resources/chromeos/login/html-echo.html b/chromium/chrome/browser/resources/chromeos/login/html-echo.html
deleted file mode 100644
index f6aa348fe06..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/html-echo.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- The <html-echo> injects given |content| into its innerHTML, bypassing HTML
- escaping, which is always made by Polymer when we insert the result of an
- Polymer expression into element's body.
-
- Example:
-
- <html-echo content="<div>Hello</div>"></html-element>
-
- will be equivalent to:
-
- <span><div>Hello</div></span>
--->
-<dom-module name="html-echo"></dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/html-echo.js b/chromium/chrome/browser/resources/chromeos/login/html-echo.js
deleted file mode 100644
index 25821c86bb3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/html-echo.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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.
-
-Polymer({
- is: 'html-echo',
-
- properties: {
- content: {
- type: String,
- observer: 'contentChanged_'
- }
- },
-
- contentChanged_: function(content) {
- this.innerHTML = content;
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/images/chrome_retail_login.png b/chromium/chrome/browser/resources/chromeos/login/images/chrome_retail_login.png
deleted file mode 100644
index b155153e671..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/images/chrome_retail_login.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/login/login.html b/chromium/chrome/browser/resources/chromeos/login/login.html
deleted file mode 100644
index 8f5015f887b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/login.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;
- build:buildType;
- highlight:highlightStrength;
- lang:language">
-<head>
-<meta charset="utf-8">
-<meta name="google" value="notranslate">
-<title i18n-content="title"></title>
-<include src="login_resources.html">
-<include src="notification_card.html">
-<script src="chrome://oobe/login.js"></script>
-<script src="chrome://oobe/gaia_auth_host.js"></script>
-</head>
-<body i18n-values=".style.fontFamily:fontfamily;">
- <include src="screen_container.html">
- <script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/login/login.js b/chromium/chrome/browser/resources/chromeos/login/login.js
deleted file mode 100644
index ef3e6f071e2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/login.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Login UI based on a stripped down OOBE controller.
- */
-
-<include src="login_common.js">
-<include src="notification_card.js">
-
-cr.define('cr.ui.Oobe', function() {
- return {
- /**
- * Initializes the OOBE flow. This will cause all C++ handlers to
- * be invoked to do final setup.
- */
- initialize: function() {
- cr.ui.login.DisplayManager.initialize();
- login.WrongHWIDScreen.register();
- login.AccountPickerScreen.register();
- login.GaiaSigninScreen.register();
- login.UserImageScreen.register(/* lazyInit= */ true);
- login.ResetScreen.register();
- login.AutolaunchScreen.register();
- login.KioskEnableScreen.register();
- login.ErrorMessageScreen.register();
- login.TPMErrorMessageScreen.register();
- login.PasswordChangedScreen.register();
- login.SupervisedUserCreationScreen.register();
- login.TermsOfServiceScreen.register();
- login.AppLaunchSplashScreen.register();
- login.ConfirmPasswordScreen.register();
- login.FatalErrorScreen.register();
- login.DeviceDisabledScreen.register();
-
- cr.ui.Bubble.decorate($('bubble'));
- login.HeaderBar.decorate($('login-header-bar'));
-
- chrome.send('screenStateInitialize');
- },
-
- // Dummy Oobe functions not present with stripped login UI.
- initializeA11yMenu: function(e) {},
- handleAccessibilityLinkClick: function(e) {},
- handleSpokenFeedbackClick: function(e) {},
- handleHighContrastClick: function(e) {},
- handleScreenMagnifierClick: function(e) {},
- setUsageStats: function(checked) {},
- setOemEulaUrl: function(oemEulaUrl) {},
- setTpmPassword: function(password) {},
- refreshA11yInfo: function(data) {},
-
- /**
- * Reloads content of the page.
- * @param {!Object} data New dictionary with i18n values.
- */
- reloadContent: function(data) {
- loadTimeData.overrideValues(data);
- i18nTemplate.process(document, loadTimeData);
- Oobe.getInstance().updateLocalizedContent_();
- },
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/login_common.js b/chromium/chrome/browser/resources/chromeos/login/login_common.js
deleted file mode 100644
index dc9fa54e91e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/login_common.js
+++ /dev/null
@@ -1,430 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Common OOBE controller methods.
- */
-
-<include src="test_util.js">
-<include src="../../../../../ui/login/screen.js">
-<include src="screen_context.js">
-<include src="../user_images_grid.js">
-<include src="apps_menu.js">
-<include src="../../../../../ui/login/bubble.js">
-<include src="../../../../../ui/login/display_manager.js">
-<include src="header_bar.js">
-<include src="network_dropdown.js">
-<include src="oobe_screen_reset_confirmation_overlay.js">
-<include src="oobe_screen_reset.js">
-<include src="oobe_screen_autolaunch.js">
-<include src="oobe_screen_enable_kiosk.js">
-<include src="oobe_screen_terms_of_service.js">
-<include src="oobe_screen_user_image.js">
-<include src="../../../../../ui/login/account_picker/screen_account_picker.js">
-<include src="screen_app_launch_splash.js">
-<include src="screen_error_message.js">
-<include src="screen_gaia_signin.js">
-<include src="screen_password_changed.js">
-<include src="screen_supervised_user_creation.js">
-<include src="screen_tpm_error.js">
-<include src="screen_wrong_hwid.js">
-<include src="screen_confirm_password.js">
-<include src="screen_fatal_error.js">
-<include src="screen_device_disabled.js">
-<include src="../../../../../ui/login/login_ui_tools.js">
-<include src="../../../../../ui/login/account_picker/user_pod_row.js">
-<include src="../../../../../ui/login/resource_loader.js">
-
-cr.define('cr.ui', function() {
- var DisplayManager = cr.ui.login.DisplayManager;
-
- /**
- * Constructs an Out of box controller. It manages initialization of screens,
- * transitions, error messages display.
- * @extends {DisplayManager}
- * @constructor
- */
- function Oobe() {
- }
-
- /**
- * Delay in milliseconds between start of OOBE animation and start of
- * header bar animation.
- */
- var HEADER_BAR_DELAY_MS = 300;
-
- cr.addSingletonGetter(Oobe);
-
- Oobe.prototype = {
- __proto__: DisplayManager.prototype,
- };
-
- /**
- * Handle accelerators. These are passed from native code instead of a JS
- * event handler in order to make sure that embedded iframes cannot swallow
- * them.
- * @param {string} name Accelerator name.
- */
- Oobe.handleAccelerator = function(name) {
- Oobe.getInstance().handleAccelerator(name);
- };
-
- /**
- * Shows the given screen.
- * @param {Object} screen Screen params dict, e.g. {id: screenId, data: data}
- */
- Oobe.showScreen = function(screen) {
- Oobe.getInstance().showScreen(screen);
- };
-
- /**
- * Updates version label visibility.
- * @param {boolean} show True if version label should be visible.
- */
- Oobe.showVersion = function(show) {
- Oobe.getInstance().showVersion(show);
- };
-
- /**
- * Update body class to switch between OOBE UI and Login UI.
- */
- Oobe.showOobeUI = function(showOobe) {
- if (showOobe) {
- document.body.classList.add('oobe-display');
-
- // Callback to animate the header bar in.
- var showHeaderBar = function() {
- login.HeaderBar.animateIn(false, function() {
- chrome.send('headerBarVisible');
- });
- };
- // Start asynchronously so the OOBE network screen comes in first.
- window.setTimeout(showHeaderBar, HEADER_BAR_DELAY_MS);
- } else {
- document.body.classList.remove('oobe-display');
- Oobe.getInstance().prepareForLoginDisplay_();
- // Ensure header bar is visible when switching to Login UI from oobe.
- if (Oobe.getInstance().displayType == DISPLAY_TYPE.OOBE)
- login.HeaderBar.animateIn(true);
- }
-
- Oobe.getInstance().headerHidden = false;
- };
-
- /**
- * When |showShutdown| is set to "true", the shutdown button is shown and the
- * reboot button hidden. If set to "false", the reboot button is visible and
- * the shutdown button hidden.
- */
- Oobe.showShutdown = function(showShutdown) {
- $('login-header-bar').showShutdownButton = showShutdown;
- $('login-header-bar').showRebootButton = !showShutdown;
- };
-
- /**
- * Enables keyboard driven flow.
- */
- Oobe.enableKeyboardFlow = function(value) {
- // Don't show header bar for OOBE.
- Oobe.getInstance().forceKeyboardFlow = value;
- };
-
- /**
- * Disables signin UI.
- */
- Oobe.disableSigninUI = function() {
- DisplayManager.disableSigninUI();
- };
-
- /**
- * Shows signin UI.
- * @param {string} opt_email An optional email for signin UI.
- */
- Oobe.showSigninUI = function(opt_email) {
- DisplayManager.showSigninUI(opt_email);
- };
-
- /**
- * Resets sign-in input fields.
- * @param {boolean} forceOnline Whether online sign-in should be forced.
- * If |forceOnline| is false previously used sign-in type will be used.
- */
- Oobe.resetSigninUI = function(forceOnline) {
- DisplayManager.resetSigninUI(forceOnline);
- };
-
- /**
- * Shows sign-in error bubble.
- * @param {number} loginAttempts Number of login attemps tried.
- * @param {string} message Error message to show.
- * @param {string} link Text to use for help link.
- * @param {number} helpId Help topic Id associated with help link.
- */
- Oobe.showSignInError = function(loginAttempts, message, link, helpId) {
- DisplayManager.showSignInError(loginAttempts, message, link, helpId);
- };
-
- /**
- * Shows password changed screen that offers migration.
- * @param {boolean} showError Whether to show the incorrect password error.
- */
- Oobe.showPasswordChangedScreen = function(showError, email) {
- DisplayManager.showPasswordChangedScreen(showError, email);
- };
-
- /**
- * Shows dialog to create a supervised user.
- */
- Oobe.showSupervisedUserCreationScreen = function() {
- DisplayManager.showSupervisedUserCreationScreen();
- };
-
- /**
- * Shows TPM error screen.
- */
- Oobe.showTpmError = function() {
- DisplayManager.showTpmError();
- };
-
- /**
- * Show user-pods.
- */
- Oobe.showUserPods = function() {
- $('pod-row').loadLastWallpaper();
- Oobe.showScreen({id: SCREEN_ACCOUNT_PICKER});
- Oobe.resetSigninUI(true);
- };
-
- /**
- * Clears error bubble as well as optional menus that could be open.
- */
- Oobe.clearErrors = function() {
- var accessibilityMenu = $('accessibility-menu');
- if (accessibilityMenu)
- accessibilityMenu.hide();
- DisplayManager.clearErrors();
- };
-
- /**
- * Displays animations on successful authentication, that have to happen
- * before login UI is dismissed.
- */
- Oobe.animateAuthenticationSuccess = function() {
- login.HeaderBar.animateOut(function() {
- chrome.send('unlockOnLoginSuccess');
- });
- };
-
- /**
- * Displays animations that have to happen once login UI is fully displayed.
- */
- Oobe.animateOnceFullyDisplayed = function() {
- login.HeaderBar.animateIn(true, function() {
- chrome.send('headerBarVisible');
- });
- };
-
- /**
- * Sets text content for a div with |labelId|.
- * @param {string} labelId Id of the label div.
- * @param {string} labelText Text for the label.
- */
- Oobe.setLabelText = function(labelId, labelText) {
- DisplayManager.setLabelText(labelId, labelText);
- };
-
- /**
- * Sets the text content of the enterprise info message.
- * If the text is empty, the entire notification will be hidden.
- * @param {string} messageText The message text.
- */
- Oobe.setEnterpriseInfo = function(messageText, assetId) {
- DisplayManager.setEnterpriseInfo(messageText, assetId);
- };
-
- /**
- * Updates the device requisition string shown in the requisition prompt.
- * @param {string} requisition The device requisition.
- */
- Oobe.updateDeviceRequisition = function(requisition) {
- Oobe.getInstance().updateDeviceRequisition(requisition);
- };
-
- /**
- * Enforces focus on user pod of locked user.
- */
- Oobe.forceLockedUserPodFocus = function() {
- login.AccountPickerScreen.forceLockedUserPodFocus();
- };
-
- /**
- * Clears password field in user-pod.
- */
- Oobe.clearUserPodPassword = function() {
- DisplayManager.clearUserPodPassword();
- };
-
- /**
- * Restores input focus to currently selected pod.
- */
- Oobe.refocusCurrentPod = function() {
- DisplayManager.refocusCurrentPod();
- };
-
- /**
- * Skip to login screen for telemetry.
- */
- Oobe.skipToLoginForTesting = function() {
- Oobe.disableSigninUI();
- chrome.send('skipToLoginForTesting');
- };
-
- /**
- * Login for telemetry.
- * @param {string} username Login username.
- * @param {string} password Login password.
- */
- Oobe.loginForTesting = function(username, password, gaia_id) {
- Oobe.disableSigninUI();
- chrome.send('skipToLoginForTesting', [username]);
- if (!gaia_id) {
- /* TODO (alemate): Remove this backward compatibility hack when
- as soon as all telemetry tests will pass gaia_id directly.
- */
- gaia_id = '12345';
- }
- chrome.send('completeLogin', [gaia_id, username, password, false]);
- };
-
- /**
- * Guest login for telemetry.
- */
- Oobe.guestLoginForTesting = function() {
- Oobe.skipToLoginForTesting();
- chrome.send('launchIncognito');
- };
-
- /**
- * Authenticate for telemetry - used for screenlocker.
- * @param {string} username Login username.
- * @param {string} password Login password.
- */
- Oobe.authenticateForTesting = function(username, password) {
- Oobe.disableSigninUI();
- chrome.send('authenticateUser', [username, password]);
- };
-
- /**
- * Gaia login screen for telemetry.
- */
- Oobe.addUserForTesting = function() {
- Oobe.skipToLoginForTesting();
- chrome.send('addUser');
- };
-
- /**
- * Shows the add user dialog. Used in browser tests.
- */
- Oobe.showAddUserForTesting = function() {
- chrome.send('showAddUser');
- };
-
- /**
- * Hotrod requisition for telemetry.
- */
- Oobe.remoraRequisitionForTesting = function() {
- chrome.send('setDeviceRequisition', ['remora']);
- };
-
- /**
- * Begin enterprise enrollment for telemetry.
- */
- Oobe.switchToEnterpriseEnrollmentForTesting = function() {
- chrome.send('toggleEnrollmentScreen');
- };
-
- /**
- * Finish enterprise enrollment for telemetry.
- */
- Oobe.enterpriseEnrollmentDone = function() {
- chrome.send('oauthEnrollClose', ['done']);
- };
-
- /**
- * Returns true if enrollment was successful. Dismisses the enrollment
- * attribute screen if it's present.
- */
- Oobe.isEnrollmentSuccessfulForTest = function() {
- if (document.querySelector('.oauth-enroll-state-attribute-prompt'))
- chrome.send('oauthEnrollAttributes', ['', '']);
-
- return $('oauth-enrollment').classList.contains(
- 'oauth-enroll-state-success');
- };
-
- /**
- * Shows/hides login UI control bar with buttons like [Shut down].
- */
- Oobe.showControlBar = function(show) {
- Oobe.getInstance().headerHidden = !show;
- };
-
- /**
- * Sets the current size of the client area (display size).
- * @param {number} width client area width
- * @param {number} height client area height
- */
- Oobe.setClientAreaSize = function(width, height) {
- Oobe.getInstance().setClientAreaSize(width, height);
- };
-
- /**
- * Checks whether the New Gaia flow is active.
- */
- Oobe.isNewGaiaFlow = function() {
- return document.querySelector('.new-gaia-flow') != undefined;
- };
-
- // Export
- return {
- Oobe: Oobe
- };
-});
-
-var Oobe = cr.ui.Oobe;
-
-// Allow selection events on components with editable text (password field)
-// bug (http://code.google.com/p/chromium/issues/detail?id=125863)
-disableTextSelectAndDrag(function(e) {
- var src = e.target;
- return src instanceof HTMLTextAreaElement ||
- src instanceof HTMLInputElement &&
- /text|password|search/.test(src.type);
-});
-
-// Register assets for async loading.
-[{
- id: SCREEN_OOBE_ENROLLMENT,
- html: [{ url: 'chrome://oobe/enrollment.html', targetID: 'inner-container' }],
- css: ['chrome://oobe/enrollment.css'],
- js: ['chrome://oobe/enrollment.js']
-}].forEach(cr.ui.login.ResourceLoader.registerAssets);
-
-(function() {
- 'use strict';
-
- document.addEventListener('DOMContentLoaded', function() {
- // Immediately load async assets.
- // TODO(dconnelly): remove this at some point and only load as needed.
- // See crbug.com/236426
- cr.ui.login.ResourceLoader.loadAssets(SCREEN_OOBE_ENROLLMENT, function() {
- // This screen is async-loaded so we manually trigger i18n processing.
- i18nTemplate.process($('oauth-enrollment'), loadTimeData);
- // Delayed binding since this isn't defined yet.
- login.OAuthEnrollmentScreen.register();
- });
-
- cr.ui.Oobe.initialize();
- });
-})();
diff --git a/chromium/chrome/browser/resources/chromeos/login/login_resources.html b/chromium/chrome/browser/resources/chromeos/login/login_resources.html
deleted file mode 100644
index d2d81fc40a5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/login_resources.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<link rel="stylesheet" href="chrome://resources/css/butter_bar.css">
-<link rel="stylesheet" href="chrome://resources/css/dialogs.css">
-<link rel="stylesheet" href="chrome://resources/css/list.css">
-<link rel="stylesheet" href="chrome://resources/css/menu_button.css">
-<link rel="stylesheet" href="chrome://resources/css/menu.css">
-<link rel="stylesheet" href="chrome://resources/css/spinner.css">
-<link rel="stylesheet" href="chrome://resources/css/throbber.css">
-<link rel="stylesheet" href="chrome://resources/css/widgets.css">
-<link rel="stylesheet" href="apps_menu.css">
-<link rel="stylesheet" href="../../../../../ui/login/bubble.css">
-<link rel="stylesheet" href="enterprise_info.css">
-<link rel="stylesheet" href="header_bar.css">
-<link rel="stylesheet" href="network_dropdown.css">
-<link rel="stylesheet" href="../../../../../ui/login/oobe.css">
-<link rel="stylesheet" href="oobe_popup_overlay.css">
-<link rel="stylesheet" href="oobe_screen.css">
-<link rel="stylesheet" href="oobe_screen_enable_debugging.css">
-<link rel="stylesheet" href="oobe_screen_eula.css">
-<link rel="stylesheet" href="oobe_screen_eula_installation_settings_overlay.css">
-<link rel="stylesheet" href="oobe_screen_network.css">
-<link rel="stylesheet" href="oobe_screen_reset.css">
-<link rel="stylesheet" href="oobe_screen_reset_confirmation_overlay.css">
-<link rel="stylesheet" href="oobe_screen_hid_detection.css">
-<link rel="stylesheet" href="oobe_screen_autolaunch.css">
-<link rel="stylesheet" href="oobe_screen_enable_kiosk.css">
-<link rel="stylesheet" href="oobe_screen_terms_of_service.css">
-<link rel="stylesheet" href="oobe_screen_update.css">
-<link rel="stylesheet" href="oobe_screen_auto_enrollment_check.css">
-<link rel="stylesheet" href="oobe_screen_user_image.css">
-<link rel="stylesheet" href="screen_app_launch_splash.css">
-<link rel="stylesheet" href="../../../../../ui/login/screen_container.css">
-<link rel="stylesheet" href="../../../../../ui/login/account_picker/screen_account_picker.css">
-<link rel="stylesheet" href="screen_gaia_signin.css">
-<link rel="stylesheet" href="screen_error_message.css">
-<link rel="stylesheet" href="screen_tpm_error.css">
-<link rel="stylesheet" href="screen_password_changed.css">
-<link rel="stylesheet" href="screen_wrong_hwid.css">
-<link rel="stylesheet" href="screen_supervised_user_creation.css">
-<link rel="stylesheet" href="screen_confirm_password.css">
-<link rel="stylesheet" href="screen_fatal_error.css">
-<link rel="stylesheet" href="screen_device_disabled.css">
-<link rel="stylesheet" href="../../../../../ui/login/account_picker/user_pod_row.css">
-<link rel="stylesheet" href="../../options/chromeos/bluetooth.css">
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/event_tracker.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/cr/ui.js"></script>
-<script src="chrome://resources/js/cr/ui/touch_handler.js"></script>
-<script src="chrome://resources/js/cr/ui/array_data_model.js"></script>
-<script src="chrome://resources/js/cr/ui/dialogs.js"></script>
-<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script>
-<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_item.js"></script>
-<script src="chrome://resources/js/cr/ui/list.js"></script>
-<script src="chrome://resources/js/cr/ui/grid.js"></script>
-<script src="chrome://resources/js/cr/ui/position_util.js"></script>
-<script src="chrome://resources/js/cr/ui/menu_item.js"></script>
-<script src="chrome://resources/js/cr/ui/menu.js"></script>
-<script src="chrome://resources/js/cr/ui/menu_button.js"></script>
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="chrome://oobe/strings.js"></script>
-<script src="chrome://oobe/keyboard_utils.js"></script>
-<script src="chrome://resources/js/polymer_config.js"></script>
diff --git a/chromium/chrome/browser/resources/chromeos/login/login_screens.html b/chromium/chrome/browser/resources/chromeos/login/login_screens.html
deleted file mode 100644
index 676c8f80faa..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/login_screens.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<include src="oobe_screen_reset.html">
-<include src="oobe_screen_autolaunch.html">
-<include src="oobe_screen_enable_kiosk.html">
-<include src="oobe_screen_terms_of_service.html">
-<include src="oobe_screen_user_image.html">
-<include src="../../../../../ui/login/account_picker/screen_account_picker.html">
-<include src="screen_error_message.html">
-<include src="screen_gaia_signin.html">
-<include src="screen_supervised_user_creation.html">
-<include src="screen_password_changed.html">
-<include src="screen_tpm_error.html">
-<include src="screen_wrong_hwid.html">
-<include src="screen_app_launch_splash.html">
-<include src="screen_confirm_password.html">
-<include src="screen_fatal_error.html">
-<include src="screen_device_disabled.html">
diff --git a/chromium/chrome/browser/resources/chromeos/login/network_dropdown.css b/chromium/chrome/browser/resources/chromeos/login/network_dropdown.css
deleted file mode 100644
index b15dcda3073..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/network_dropdown.css
+++ /dev/null
@@ -1,146 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * This is the stylesheet used by the network drop-down control.
- */
-
-.dropdown-title {
- -webkit-appearance: none;
- -webkit-box-align: start;
- -webkit-padding-end: 20px;
- -webkit-padding-start: 1px;
- -webkit-user-select: none;
- background-image: url(../../../../../ui/webui/resources/images/select.png),
- linear-gradient(to bottom,
- rgb(237, 237, 237),
- rgb(237, 237, 237) 38%,
- rgb(222, 222, 222));
- background-position: center right;
- background-repeat: no-repeat;
- border: 1px solid rgba(0, 0, 0, 0.25);
- border-radius: 2px;
- box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08),
- inset 0 1px 2px rgba(255, 255, 255, 0.75);
- color: #444;
- display: -webkit-box;
- font-size: inherit;
- height: 22px;
- margin: 0;
- overflow: hidden;
- padding-bottom: 2px;
- padding-top: 2px;
- text-align: left;
- text-indent: 4px;
- text-overflow: ellipsis;
- text-shadow: 0 1px 0 rgb(240, 240, 240);
- white-space: nowrap;
- z-index: 10;
-}
-
-html[dir=rtl] .dropdown-title {
- background-position: center left;
-}
-
-.dropdown-title:enabled:hover {
- background-image: url(../../../../../ui/webui/resources/images/select.png),
- linear-gradient(to bottom,
- rgb(237, 237, 237),
- rgb(237, 237, 237) 38%,
- rgb(222, 222, 222));
- border-color: rgba(0, 0, 0, 0.3);
- box-shadow: 0 1px 0 rgba(0, 0, 0, 0.12),
- inset 0 1px 2px rgba(255, 255, 255, 0.95);
- color: black;
-}
-
-.dropdown-title:enabled:active {
- background-image: url(../../../../../ui/webui/resources/images/select.png),
- linear-gradient(to bottom,
- rgb(231, 231, 231),
- rgb(231, 231, 231) 38%,
- rgb(215, 215, 215));
- box-shadow: none;
- text-shadow: none;
-}
-
-.dropdown-title:focus {
- -webkit-transition: border-color 200ms;
- border-color: rgb(77, 144, 254);
- outline: none;
-}
-
-html[highlight=strong] .dropdown-title:focus {
- box-shadow: 0 0 23px rgb(77, 144, 254);
-}
-
-.dropdown-title img {
- margin-top: -1px;
-}
-
-.dropdown-title div {
- -webkit-box-flex: 1;
- margin-top: 1px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.dropdown-container {
- background: #f7f7f7;
- border: 1px solid rgb(124, 145, 191);
- max-height: 234px;
- overflow-x: hidden;
- overflow-y: auto;
- padding-bottom: 2px;
- padding-top: 2px;
- position: absolute;
- top: 100%;
- width: 99.5%;
- z-index: 10;
-}
-
-.dropdown-item-container {
- -webkit-padding-start: 5px;
- display: -webkit-box;
- height: 24px;
-}
-
-.dropdown-item-container.hover {
- background: rgb(220, 228, 250);
-}
-
-.dropdown-image {
- width: 25px;
-}
-
-.dropdown-item {
- -webkit-box-flex: 1;
- color: #555;
- cursor: default;
- overflow: hidden;
- padding-top: 4px;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.dropdown-divider {
- height: 3px;
-}
-
-.dropdown-divider hr {
- margin-bottom: 2px;
- margin-top: 2px;
-}
-
-.dropdown-item.disabled-item {
- color: graytext;
-}
-
-.dropdown-overlay {
- bottom: 0;
- left: 0;
- position: fixed;
- right: 0;
- top: 0;
- z-index: 5;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/network_dropdown.js b/chromium/chrome/browser/resources/chromeos/login/network_dropdown.js
deleted file mode 100644
index 846183d13ff..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/network_dropdown.js
+++ /dev/null
@@ -1,443 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Network drop-down implementation.
- */
-
-cr.define('cr.ui', function() {
- /**
- * Whether keyboard flow is in use. When setting to true, up/down arrow key
- * will be used to move focus instead of opening the drop down.
- */
- var useKeyboardFlow = false;
-
- /**
- * Creates a new container for the drop down menu items.
- * @constructor
- * @extends {HTMLDivElement}
- */
- var DropDownContainer = cr.ui.define('div');
-
- DropDownContainer.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- /** @override */
- decorate: function() {
- this.classList.add('dropdown-container');
- // Selected item in the menu list.
- this.selectedItem = null;
- // First item which could be selected.
- this.firstItem = null;
- this.setAttribute('role', 'menu');
- // Whether scroll has just happened.
- this.scrollJustHappened = false;
- },
-
- /**
- * Gets scroll action to be done for the item.
- * @param {!Object} item Menu item.
- * @return {integer} -1 for scroll up; 0 for no action; 1 for scroll down.
- */
- scrollAction: function(item) {
- var thisTop = this.scrollTop;
- var thisBottom = thisTop + this.offsetHeight;
- var itemTop = item.offsetTop;
- var itemBottom = itemTop + item.offsetHeight;
- if (itemTop <= thisTop) return -1;
- if (itemBottom >= thisBottom) return 1;
- return 0;
- },
-
- /**
- * Selects new item.
- * @param {!Object} selectedItem Item to be selected.
- * @param {boolean} mouseOver Is mouseover event triggered?
- */
- selectItem: function(selectedItem, mouseOver) {
- if (mouseOver && this.scrollJustHappened) {
- this.scrollJustHappened = false;
- return;
- }
- if (this.selectedItem)
- this.selectedItem.classList.remove('hover');
- selectedItem.classList.add('hover');
- this.selectedItem = selectedItem;
- if (!this.hidden) {
- this.previousSibling.setAttribute(
- 'aria-activedescendant', selectedItem.id);
- }
- var action = this.scrollAction(selectedItem);
- if (action != 0) {
- selectedItem.scrollIntoView(action < 0);
- this.scrollJustHappened = true;
- }
- }
- };
-
- /**
- * Creates a new DropDown div.
- * @constructor
- * @extends {HTMLDivElement}
- */
- var DropDown = cr.ui.define('div');
-
- DropDown.ITEM_DIVIDER_ID = -2;
-
- DropDown.KEYCODE_DOWN = 40;
- DropDown.KEYCODE_ENTER = 13;
- DropDown.KEYCODE_ESC = 27;
- DropDown.KEYCODE_SPACE = 32;
- DropDown.KEYCODE_TAB = 9;
- DropDown.KEYCODE_UP = 38;
-
- DropDown.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- /** @override */
- decorate: function() {
- this.appendChild(this.createOverlay_());
- this.appendChild(this.title_ = this.createTitle_());
- var container = new DropDownContainer();
- container.id = this.id + '-dropdown-container';
- this.appendChild(container);
-
- this.addEventListener('keydown', this.keyDownHandler_);
-
- this.title_.id = this.id + '-dropdown';
- this.title_.setAttribute('role', 'button');
- this.title_.setAttribute('aria-haspopup', 'true');
- this.title_.setAttribute('aria-owns', container.id);
- },
-
- /**
- * Returns true if dropdown menu is shown.
- * @type {bool} Whether menu element is shown.
- */
- get isShown() {
- return !this.container.hidden;
- },
-
- /**
- * Sets dropdown menu visibility.
- * @param {bool} show New visibility state for dropdown menu.
- */
- set isShown(show) {
- this.firstElementChild.hidden = !show;
- this.container.hidden = !show;
- if (show) {
- this.container.selectItem(this.container.firstItem, false);
- } else {
- this.title_.removeAttribute('aria-activedescendant');
- }
-
- // Flag for keyboard flow util to forward the up/down keys.
- this.title_.classList.toggle('needs-up-down-keys', show);
- },
-
- /**
- * Returns container of the menu items.
- */
- get container() {
- return this.lastElementChild;
- },
-
- /**
- * Sets title and icon.
- * @param {string} title Text on dropdown.
- * @param {string} icon Icon in dataURL format.
- */
- setTitle: function(title, icon) {
- this.title_.firstElementChild.src = icon;
- this.title_.lastElementChild.textContent = title;
- },
-
- /**
- * Sets dropdown items.
- * @param {Array} items Dropdown items array.
- */
- setItems: function(items) {
- this.container.innerHTML = '';
- this.container.firstItem = null;
- this.container.selectedItem = null;
- for (var i = 0; i < items.length; ++i) {
- var item = items[i];
- if ('sub' in item) {
- // Workaround for submenus, add items on top level.
- // TODO(altimofeev): support submenus.
- for (var j = 0; j < item.sub.length; ++j)
- this.createItem_(this.container, item.sub[j]);
- continue;
- }
- this.createItem_(this.container, item);
- }
- this.container.selectItem(this.container.firstItem, false);
-
- var maxHeight = cr.ui.LoginUITools.getMaxHeightBeforeShelfOverlapping(
- this.container);
- if (maxHeight < this.container.offsetHeight)
- this.container.style.maxHeight = maxHeight + 'px';
- },
-
- /**
- * Id of the active drop-down element.
- * @private
- */
- activeElementId_: '',
-
- /**
- * Creates dropdown item element and adds into container.
- * @param {HTMLElement} container Container where item is added.
- * @param {!Object} item Item to be added.
- * @private
- */
- createItem_: function(container, item) {
- var itemContentElement;
- var className = 'dropdown-item';
- if (item.id == DropDown.ITEM_DIVIDER_ID) {
- className = 'dropdown-divider';
- itemContentElement = this.ownerDocument.createElement('hr');
- } else {
- var span = this.ownerDocument.createElement('span');
- itemContentElement = span;
- span.textContent = item.label;
- if ('bold' in item && item.bold)
- span.classList.add('bold');
- var image = this.ownerDocument.createElement('img');
- image.alt = '';
- image.classList.add('dropdown-image');
- if (item.icon)
- image.src = item.icon;
- }
-
- var itemElement = this.ownerDocument.createElement('div');
- itemElement.classList.add(className);
- itemElement.appendChild(itemContentElement);
- itemElement.iid = item.id;
- itemElement.controller = this;
- var enabled = 'enabled' in item && item.enabled;
- if (!enabled)
- itemElement.classList.add('disabled-item');
-
- if (item.id > 0) {
- var wrapperDiv = this.ownerDocument.createElement('div');
- wrapperDiv.setAttribute('role', 'menuitem');
- wrapperDiv.id = this.id + item.id;
- if (!enabled)
- wrapperDiv.setAttribute('aria-disabled', 'true');
- wrapperDiv.classList.add('dropdown-item-container');
- var imageDiv = this.ownerDocument.createElement('div');
- imageDiv.appendChild(image);
- wrapperDiv.appendChild(imageDiv);
- wrapperDiv.appendChild(itemElement);
- wrapperDiv.addEventListener('click', function f(e) {
- var item = this.lastElementChild;
- if (item.iid < -1 || item.classList.contains('disabled-item'))
- return;
- item.controller.isShown = false;
- if (item.iid >= 0)
- chrome.send('networkItemChosen', [item.iid]);
- this.parentNode.parentNode.title_.focus();
- });
- wrapperDiv.addEventListener('mouseover', function f(e) {
- this.parentNode.selectItem(this, true);
- });
- itemElement = wrapperDiv;
- }
- container.appendChild(itemElement);
- if (!container.firstItem && item.id >= 0) {
- container.firstItem = itemElement;
- }
- },
-
- /**
- * Creates dropdown overlay element, which catches outside clicks.
- * @type {HTMLElement}
- * @private
- */
- createOverlay_: function() {
- var overlay = this.ownerDocument.createElement('div');
- overlay.classList.add('dropdown-overlay');
- overlay.addEventListener('click', function() {
- this.parentNode.title_.focus();
- this.parentNode.isShown = false;
- });
- return overlay;
- },
-
- /**
- * Creates dropdown title element.
- * @type {HTMLElement}
- * @private
- */
- createTitle_: function() {
- var image = this.ownerDocument.createElement('img');
- image.alt = '';
- image.classList.add('dropdown-image');
- var text = this.ownerDocument.createElement('div');
-
- var el = this.ownerDocument.createElement('div');
- el.appendChild(image);
- el.appendChild(text);
-
- el.tabIndex = 0;
- el.classList.add('dropdown-title');
- el.iid = -1;
- el.controller = this;
- el.inFocus = false;
- el.opening = false;
-
- el.addEventListener('click', function f(e) {
- this.controller.isShown = !this.controller.isShown;
- });
-
- el.addEventListener('focus', function(e) {
- this.inFocus = true;
- });
-
- el.addEventListener('blur', function(e) {
- this.inFocus = false;
- });
-
- el.addEventListener('keydown', function f(e) {
- if (this.inFocus && !this.controller.isShown &&
- (e.keyCode == DropDown.KEYCODE_ENTER ||
- e.keyCode == DropDown.KEYCODE_SPACE ||
- (!useKeyboardFlow && (e.keyCode == DropDown.KEYCODE_UP ||
- e.keyCode == DropDown.KEYCODE_DOWN)))) {
- this.opening = true;
- this.controller.isShown = true;
- e.stopPropagation();
- e.preventDefault();
- }
- });
- return el;
- },
-
- /**
- * Handles keydown event from the keyboard.
- * @private
- * @param {!Event} e Keydown event.
- */
- keyDownHandler_: function(e) {
- if (!this.isShown)
- return;
- var selected = this.container.selectedItem;
- var handled = false;
- switch (e.keyCode) {
- case DropDown.KEYCODE_UP: {
- do {
- selected = selected.previousSibling;
- if (!selected)
- selected = this.container.lastElementChild;
- } while (selected.iid < 0);
- this.container.selectItem(selected, false);
- handled = true;
- break;
- }
- case DropDown.KEYCODE_DOWN: {
- do {
- selected = selected.nextSibling;
- if (!selected)
- selected = this.container.firstItem;
- } while (selected.iid < 0);
- this.container.selectItem(selected, false);
- handled = true;
- break;
- }
- case DropDown.KEYCODE_ESC: {
- this.isShown = false;
- handled = true;
- break;
- }
- case DropDown.KEYCODE_TAB: {
- this.isShown = false;
- handled = true;
- break;
- }
- case DropDown.KEYCODE_ENTER: {
- if (!this.title_.opening) {
- this.title_.focus();
- this.isShown = false;
- var item =
- this.title_.controller.container.selectedItem.lastElementChild;
- if (item.iid >= 0 && !item.classList.contains('disabled-item'))
- chrome.send('networkItemChosen', [item.iid]);
- }
- handled = true;
- break;
- }
- }
- if (handled) {
- e.stopPropagation();
- e.preventDefault();
- }
- this.title_.opening = false;
- }
- };
-
- /**
- * Updates networks list with the new data.
- * @param {!Object} data Networks list.
- */
- DropDown.updateNetworks = function(data) {
- if (DropDown.activeElementId_)
- $(DropDown.activeElementId_).setItems(data);
- };
-
- /**
- * Updates network title, which is shown by the drop-down.
- * @param {string} title Title to be displayed.
- * @param {!Object} icon Icon to be displayed.
- */
- DropDown.updateNetworkTitle = function(title, icon) {
- if (DropDown.activeElementId_)
- $(DropDown.activeElementId_).setTitle(title, icon);
- };
-
- /**
- * Activates network drop-down. Only one network drop-down
- * can be active at the same time. So activating new drop-down deactivates
- * the previous one.
- * @param {string} elementId Id of network drop-down element.
- * @param {boolean} isOobe Whether drop-down is used by an Oobe screen.
- */
- DropDown.show = function(elementId, isOobe) {
- $(elementId).isShown = false;
- if (DropDown.activeElementId_ != elementId) {
- DropDown.activeElementId_ = elementId;
- chrome.send('networkDropdownShow', [elementId, isOobe]);
- }
- };
-
- /**
- * Deactivates network drop-down. Deactivating inactive drop-down does
- * nothing.
- * @param {string} elementId Id of network drop-down element.
- */
- DropDown.hide = function(elementId) {
- if (DropDown.activeElementId_ == elementId) {
- DropDown.activeElementId_ = '';
- chrome.send('networkDropdownHide');
- }
- };
-
- /**
- * Refreshes network drop-down. Should be called on language change.
- */
- DropDown.refresh = function() {
- chrome.send('networkDropdownRefresh');
- };
-
- /**
- * Sets the keyboard flow flag.
- */
- DropDown.enableKeyboardFlow = function() {
- useKeyboardFlow = true;
- };
-
- return {
- DropDown: DropDown
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/notification_card.css b/chromium/chrome/browser/resources/chromeos/login/notification_card.css
deleted file mode 100644
index 2be458dd11d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/notification_card.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#container {
- padding: 40px;
-}
-
-#icon-container {
- margin-bottom: 14px;
-}
-
-:host iron-icon {
- height: 28px;
- width: 28px;
-}
-
-iron-icon[icon=warning] {
- color: var(--google-yellow-500);
-}
-
-iron-icon[icon=done] {
- color: var(--google-green-500);
-}
-
-#text-container {
- color: grey;
- line-height: 130%;
- max-width: 240px;
- text-align: center;
-}
-
-a {
- color: var(--google-blue-500);
- text-decoration: none;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/notification_card.html b/chromium/chrome/browser/resources/chromeos/login/notification_card.html
deleted file mode 100644
index 641766b1922..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/notification_card.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- A simple notification card with a button, link (optional) and icon (optional).
- Example:
- <notification-card button-label="OK" link-label="What?" type="success">
- Great success!
- </notification-card>
-
- Atributes:
- 'button-label' - label displayed on the button. If empty or not set, the
- button is hidden.
- 'link-label' - text of the link. If empty or not set, the link is hidden.
- 'type' - icon type. Can be either 'success' or 'fail'. If not set, no icon
- is displayed.
-
- Events:
- 'buttonclick' - fired on button click.
- 'linkclick' - fired on link click.
-
--->
-<dom-module name="notification-card">
- <link rel="stylesheet" href="notification_card.css">
-
- <template>
- <div id="container" class="vertical layout center fit">
- <div class="flex vertical layout center center-justified">
- <template is="dom-if" if="[[type]]">
- <div id="icon-container" class="vertical layout center">
- <iron-icon icon$="[[iconNameByType_(type)]]">
- </iron-icon>
- </div>
- </template>
- <div id="text-container">
- <content></content>
- </div>
- </div>
- <div class="self-stretch horizontal-reverse layout justified center">
- <gaia-button id="submitButton" on-tap="buttonClicked_"
- hidden$="[[!buttonLabel]]">
- <span>[[buttonLabel]]</span>
- </gaia-button>
- <a href="#" on-click="linkClicked_" hidden$="{{!linkLabel}}">
- <span>[[linkLabel]]</span>
- </a>
- </div>
- </div>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/notification_card.js b/chromium/chrome/browser/resources/chromeos/login/notification_card.js
deleted file mode 100644
index 880ded8bf84..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/notification_card.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer({
- is: 'notification-card',
-
- properties: {
- buttonLabel: {
- type: String,
- value: ''
- },
-
- linkLabel: {
- type: String,
- value: ''
- },
-
- type: {
- type: String,
- value: ''
- }
- },
-
- iconNameByType_: function(type) {
- if (type == 'fail')
- return 'warning';
- if (type == 'success')
- return 'done';
- console.error('Unknown type "' + type + '".');
- return '';
- },
-
- buttonClicked_: function() {
- this.fire('buttonclick');
- },
-
- linkClicked_: function(e) {
- this.fire('linkclick');
- e.preventDefault();
- },
-
- get submitButton() {
- return this.$.submitButton;
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/offline_gaia.css b/chromium/chrome/browser/resources/chromeos/login/offline_gaia.css
deleted file mode 100644
index f8c4dd5b1d7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/offline_gaia.css
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- display: flex;
- flex-direction: column;
- font-size: 18px;
- overflow: hidden;
- position: relative;
-}
-
-#backButton {
- color: white;
- left: 10px;
- position: absolute;
- top: 10px;
- z-index: 1;
-}
-
-:host-context(html[dir=rtl]) #backButton {
- left: auto;
- right: 10px;
- transform: scaleX(-1);
-}
-
-paper-dialog {
- --paper-dialog-title: {
- font-size: 15px;
- };
-
- width: 384px;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/offline_gaia.html b/chromium/chrome/browser/resources/chromeos/login/offline_gaia.html
deleted file mode 100644
index 32a262c687a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/offline_gaia.html
+++ /dev/null
@@ -1,110 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/slide-from-left-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/slide-from-right-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/slide-left-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/slide-right-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animated-pages.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- Offline UI for the New Gaia flow.
- Contains two cards with a slide transition between them:
- 1. Email input form.
- 2. Password input form.
-
- Example:
- <offline-gaia></offline-gaia>
-
- Attributes:
- 'enterpriseInfo' - Information about device management.
- 'emailDomain' - autocomplete domain for the email input.
-
- Events:
- 'authCompleted' - fired when user enters login and password. Fires with an
- argument |credentials| which contains.
- |credentials| = { 'useOffline': true,
- 'email': <email>,
- 'password': <typed password> }
- If user did not type domain |email| will be added by
- "@gmail.com" or by 'emailDomain' if it is set.
- Methods:
- 'focus' - focuses current screen (email input or password input);
- 'setEmail' - accepts an argument |email|. If |email| is empty it sets
- current screen to the email input, otherwise it sets current
- screen to password input and shows error that previously
- entered password is incorrect.
--->
-<dom-module name="offline-gaia">
- <link rel="stylesheet" href="offline_gaia.css">
-
- <template>
- <neon-animated-pages id="animatedPages" class="fit" attr-for-selected="id"
- entry-animation="slide-from-right-animation"
- exit-animation="slide-to-left-animation"
- on-neon-animation-finish="onAnimationFinish_" selected="emailSection">
-
- <neon-animatable id="emailSection" class="fit">
- <gaia-card class="fit">
- <div class="header flex vertical layout end-justified start">
- <h1 class="welcome-message" i18n-content="offlineLoginWelcome"></h1>
- <p class="enterprise-info" hidden$="[[!enterpriseInfo]]">
- <span>[[enterpriseInfo]]</span>
- </p>
- </div>
- <div class="footer flex vertical layout justified">
- <gaia-input-form on-submit="onEmailSubmitted_"
- disabled="[[disabled]]"
- i18n-values="button-text:offlineLoginNextBtn">
- <gaia-input id="emailInput" type="email" required
- domain="[[emailDomain]]"
- i18n-values="error:offlineLoginInvalidEmail;
- label:offlineLoginEmail">
- </gaia-input>
- </gaia-input-form>
- <img src="chrome://theme/IDR_LOGO_GOOGLE_COLOR_90"
- class="self-center" alt="">
- </div>
- </gaia-card>
- </neon-animatable>
-
- <neon-animatable id="passwordSection" class="fit">
- <gaia-card id="passwordCard" class="fit">
- <gaia-header class="header flex" id="passwordHeader">
- </gaia-header>
- <gaia-input-form class="footer" disabled="[[disabled]]"
- on-submit="onPasswordSubmitted_"
- i18n-values="button-text:offlineLoginNextBtn">
- <gaia-input id="passwordInput" type="password" required
- i18n-values="error:offlineLoginInvalidPassword;
- label:offlineLoginPassword">
- </gaia-input>
- <gaia-button type="link" on-tap="onForgotPasswordClicked_"
- i18n-content="offlineLoginForgotPasswordBtn">
- </gaia-button>
- </gaia-input-form>
- </gaia-card>
- </neon-animatable>
- </neon-animated-pages>
-
- <gaia-icon-button id="backButton" icon="arrow-back" disabled="[[disabled]]"
- on-tap="onBack_" hidden>
- </gaia-icon-button>
-
- <paper-dialog id="forgotPasswordDlg" no-cancel-on-outside-click
- on-iron-overlay-closed="onDialogOverlayClosed_">
- <p i18n-content="offlineLoginForgotPasswordDlg"></p>
- <div class="buttons">
- <gaia-button type="dialog" dialog-confirm autofocus
- i18n-content="offlineLoginCloseBtn">
- </gaia-button>
- </div>
- </paper-dialog>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/offline_gaia.js b/chromium/chrome/browser/resources/chromeos/login/offline_gaia.js
deleted file mode 100644
index 25a258defd6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/offline_gaia.js
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer((function() {
- var DEFAULT_EMAIL_DOMAIN = '@gmail.com';
-
- return {
- is: 'offline-gaia',
-
- properties: {
- disabled: {
- type: Boolean,
- value: false
- },
-
- enterpriseInfo: String,
-
- emailDomain: String
- },
-
- ready: function() {
- /**
- * Workaround for
- * https://github.com/PolymerElements/neon-animation/issues/32
- * TODO(dzhioev): Remove when fixed in Polymer.
- */
- var pages = this.$.animatedPages;
- delete pages._squelchNextFinishEvent;
- Object.defineProperty(pages, '_squelchNextFinishEvent',
- { get: function() { return false; } });
- },
-
- onAnimationFinish_: function() {
- this.$.backButton.hidden = this.isEmailSectionActive_();
- this.focus();
- },
-
- focus: function() {
- if (this.isEmailSectionActive_())
- this.$.emailInput.focus();
- else
- this.$.passwordInput.focus();
- },
-
- onForgotPasswordClicked_: function() {
- this.$.forgotPasswordDlg.fitInto = this;
- this.disabled = true;
- this.$.forgotPasswordDlg.open();
- this.$.passwordCard.classList.add('full-disabled');
- this.$.forgotPasswordDlg.focus();
- },
-
- onDialogOverlayClosed_: function() {
- this.disabled = false;
- this.$.passwordCard.classList.remove('full-disabled');
- },
-
- setEmail: function(email) {
- if (email) {
- if (this.emailDomain)
- email = email.replace(this.emailDomain, '');
- this.switchToPasswordCard(email);
- this.$.passwordInput.isInvalid = true;
- } else {
- this.$.emailInput.value = '';
- this.switchToEmailCard();
- }
- },
-
- onBack_: function() {
- this.$.backButton.hidden = true;
- this.switchToEmailCard();
- },
-
- isRTL_: function() {
- return !!document.querySelector('html[dir=rtl]');
- },
-
- isEmailSectionActive_: function() {
- return this.$.animatedPages.selected == 'emailSection';
- },
-
- switchToEmailCard() {
- this.$.passwordInput.value = '';
- this.$.passwordInput.isInvalid = false;
- this.$.emailInput.isInvalid = false;
- if (this.isEmailSectionActive_())
- return;
- this.$.animatedPages.entryAnimation =
- 'slide-from-' + (this.isRTL_() ? 'right' : 'left') + '-animation';
- this.$.animatedPages.exitAnimation =
- 'slide-' + (this.isRTL_() ? 'left' : 'right') + '-animation';
- this.$.animatedPages.selected = 'emailSection';
- },
-
- switchToPasswordCard(email) {
- this.$.emailInput.value = email;
- if (email.indexOf('@') === -1) {
- if (this.emailDomain)
- email = email + this.emailDomain;
- else
- email = email + DEFAULT_EMAIL_DOMAIN;
- }
- this.$.passwordHeader.email = email;
- if (!this.isEmailSectionActive_())
- return;
- this.$.animatedPages.entryAnimation =
- 'slide-from-' + (this.isRTL_() ? 'left' : 'right') + '-animation';
- this.$.animatedPages.exitAnimation =
- 'slide-' + (this.isRTL_() ? 'right' : 'left') + '-animation';
- this.$.animatedPages.selected = 'passwordSection';
- },
-
- onEmailSubmitted_: function() {
- if (this.$.emailInput.checkValidity())
- this.switchToPasswordCard(this.$.emailInput.value);
- else
- this.$.emailInput.focus();
- },
-
- onPasswordSubmitted_: function() {
- if (!this.$.passwordInput.checkValidity())
- return;
- var msg = {
- 'useOffline': true,
- 'email': this.$.passwordHeader.email,
- 'password': this.$.passwordInput.value
- };
- this.$.passwordInput.value = '';
- this.fire('authCompleted', msg);
- }
- };
-})());
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe-screen.html b/chromium/chrome/browser/resources/chromeos/login/oobe-screen.html
deleted file mode 100644
index aba00ff36e7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe-screen.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe-screen.js b/chromium/chrome/browser/resources/chromeos/login/oobe-screen.js
deleted file mode 100644
index b79784d145b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe-screen.js
+++ /dev/null
@@ -1,234 +0,0 @@
-// 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('login', function() {
- /** @const */ var CALLBACK_USER_ACTED = 'userActed';
-
- var OobeScreenBehavior = {
- properties: {
- /**
- * Internal storage of |this.context|. Short name has been choosen for
- * reason: such name doesn't take much space in HTML data bindings, which
- * are used very often.
- * C binded to the native part of the context, that means that all the
- * changes in the native part appear in C automatically. Reverse is not
- * true, you should use:
- * this.context.set(...);
- * this.context.commitContextChanges();
- * to send updates to the native part.
- * TODO(dzhioev): make binding two-way.
- */
- C: Object,
-
- name: String
- },
-
- /**
- * The login.Screen which is hosting |this|.
- */
- screen_: null,
-
- /**
- * Dictionary of context observers that are methods of |this| bound to
- * |this|.
- */
- contextObservers_: null,
-
- /**
- * login.ScreenContext used for sharing data with native backend.
- */
- context: null,
-
- /**
- * Called when the screen is being registered.
- */
- initialize: function() {},
-
- ready: function() {
- if (this.decorate_) {
- this.initialize();
- } else {
- this.ready_ = true;
- }
- },
-
- userActed: function(e) {
- this.send(CALLBACK_USER_ACTED,
- e.detail.sourceEvent.target.getAttribute('action'));
- },
-
- i18n: function(args) {
- if (!(args instanceof Array))
- args = [args];
- args[0] = 'login_' + this.name + '_' + args[0];
- return loadTimeData.getStringF.apply(loadTimeData, args);
- },
-
- /**
- * Called by login.Screen when the screen is beeing registered.
- */
- decorate: function(screen) {
- this.screen_ = screen;
- this.context = screen.screenContext_;
- this.C = this.context.storage_;
- this.contextObservers_ = {};
- var self = this;
- if (this.ready_) {
- this.initialize();
- } else {
- this.decorate_ = true;
- }
- },
-
- /**
- * Should be called for every context field which is used in Polymer
- * declarative data bindings (e.g. {{C.fieldName}}).
- */
- registerBoundContextField: function(fieldName) {
- this.addContextObserver(fieldName, this.onContextFieldChanged_);
- },
-
- onContextFieldChanged_: function(_, _, fieldName) {
- this.notifyPath('C.' + fieldName, this.C[fieldName]);
- },
-
- /**
- * @final
- */
- send: function() {
- return this.sendImpl_.apply(this, arguments);
- },
-
- /**
- * @final
- */
- addContextObserver: function() {
- return this.addContextObserverImpl_.apply(this, arguments);
- },
-
- /**
- * @final
- */
- removeContextObserver: function() {
- return this.removeContextObserverImpl_.apply(this, arguments);
- },
-
- /**
- * @final
- */
- commitContextChanges: function() {
- return this.commitContextChangesImpl_.apply(this, arguments);
- },
-
- /**
- * @override
- * @final
- */
- querySelector: function() {
- return this.querySelectorImpl_.apply(this, arguments);
- },
-
- /**
- * @override
- * @final
- */
- querySelectorAll: function() {
- return this.querySelectorAllImpl_.apply(this, arguments);
- },
-
- /**
- * See login.Screen.send.
- * @private
- */
- sendImpl_: function() {
- return this.screen_.send.apply(this.screen_, arguments);
- },
-
- /**
- * Starts observation of property with |key| of the context attached to
- * current screen. This method differs from "login.ScreenContext" in that
- * it automatically detects if observer is method of |this| and make
- * all needed actions to make it work correctly. So it's no need for client
- * to bind methods to |this| and keep resulting callback for
- * |removeObserver| call:
- *
- * this.addContextObserver('key', this.onKeyChanged_);
- * ...
- * this.removeContextObserver('key', this.onKeyChanged_);
- * @private
- */
- addContextObserverImpl_: function(key, observer) {
- var realObserver = observer;
- var propertyName = this.getPropertyNameOf_(observer);
- if (propertyName) {
- if (!this.contextObservers_.hasOwnProperty(propertyName))
- this.contextObservers_[propertyName] = observer.bind(this);
- realObserver = this.contextObservers_[propertyName];
- }
- this.context.addObserver(key, realObserver);
- },
-
- /**
- * Removes |observer| from the list of context observers. Supports not only
- * regular functions but also screen methods (see comment to
- * |addContextObserver|).
- * @private
- */
- removeContextObserverImpl_: function(observer) {
- var realObserver = observer;
- var propertyName = this.getPropertyNameOf_(observer);
- if (propertyName) {
- if (!this.contextObservers_.hasOwnProperty(propertyName))
- return;
- realObserver = this.contextObservers_[propertyName];
- delete this.contextObservers_[propertyName];
- }
- this.context.removeObserver(realObserver);
- },
-
- /**
- * See login.Screen.commitContextChanges.
- * @private
- */
- commitContextChangesImpl_: function() {
- return this.screen_.commitContextChanges.apply(this.screen_, arguments);
- },
-
- /**
- * Calls |querySelector| method of the shadow dom and returns the result.
- * @private
- */
- querySelectorImpl_: function(selector) {
- return this.shadowRoot.querySelector(selector);
- },
-
-
- /**
- * Calls standart |querySelectorAll| method of the shadow dom and returns
- * the result converted to Array.
- * @private
- */
- querySelectorAllImpl_: function(selector) {
- var list = this.shadowRoot.querySelectorAll(selector);
- return Array.prototype.slice.call(list);
- },
-
- /**
- * If |value| is the value of some property of |this| returns property's
- * name. Otherwise returns empty string.
- * @private
- */
- getPropertyNameOf_: function(value) {
- for (var key in this)
- if (this[key] === value)
- return key;
- return '';
- }
- };
-
- return {
- OobeScreenBehavior: OobeScreenBehavior
- };
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe.html b/chromium/chrome/browser/resources/chromeos/login/oobe.html
deleted file mode 100644
index f84f6aea02c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;
- build:buildType;
- highlight:highlightStrength;
- lang:language">
-<head>
-<meta charset="utf-8">
-<meta name="google" value="notranslate">
-<title i18n-content="title"></title>
-<include src="login_resources.html">
-<link rel="import" href="chrome://oobe/custom_elements.html">
-<link rel="stylesheet" href="roboto_font.css">
-<link rel="stylesheet" href="accessibility_menu.css">
-<script src="chrome://oobe/oobe.js"></script>
-<script src="chrome://oobe/gaia_auth_host.js"></script>
-</head>
-<body class="oobe-display" i18n-values=".style.fontFamily:fontfamily;">
- <include src="screen_container.html">
- <include src="accessibility_menu.html">
- <div id="popup-overlay" class="popup-overlay" hidden>
- <include src="oobe_screen_eula_installation_settings_overlay.html">
- </div>
- <script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe.js b/chromium/chrome/browser/resources/chromeos/login/oobe.js
deleted file mode 100644
index 15dbacfb1f1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe.js
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Out of the box experience flow (OOBE).
- * This is the main code for the OOBE WebUI implementation.
- */
-
-<include src="login_common.js">
-<include src="oobe_screen_auto_enrollment_check.js">
-<include src="oobe_screen_controller_pairing.js">
-<include src="oobe_screen_enable_debugging.js">
-<include src="oobe_screen_eula.js">
-<include src="oobe_screen_hid_detection.js">
-<include src="oobe_screen_host_pairing.js">
-<include src="oobe_screen_network.js">
-<include src="oobe_screen_update.js">
-
-cr.define('cr.ui.Oobe', function() {
- return {
- /**
- * Setups given "select" element using the list and adds callback.
- * Creates option groups if needed.
- * @param {!Element} select Select object to be updated.
- * @param {!Object} list List of the options to be added.
- * Elements with optionGroupName are considered option group.
- * @param {string} callback Callback name which should be send to Chrome or
- * an empty string if the event listener shouldn't be added.
- */
- setupSelect: function(select, list, callback) {
- select.innerHTML = '';
- var optgroup = select;
- for (var i = 0; i < list.length; ++i) {
- var item = list[i];
- if (item.optionGroupName) {
- optgroup = document.createElement('optgroup');
- optgroup.label = item.optionGroupName;
- select.appendChild(optgroup);
- } else {
- var option =
- new Option(item.title, item.value, item.selected, item.selected);
- optgroup.appendChild(option);
- }
- }
- if (callback) {
- var runCallback = function() {
- callback(select.options[select.selectedIndex].value);
- };
- select.addEventListener('blur', runCallback);
- select.addEventListener('click', runCallback);
- select.addEventListener('keyup', function(event) {
- var keycodeInterested = [
- 9, // Tab
- 13, // Enter
- 27, // Escape
- ];
- if (keycodeInterested.indexOf(event.keyCode) >= 0)
- runCallback();
- });
- }
- },
-
- /**
- * Initializes the OOBE flow. This will cause all C++ handlers to
- * be invoked to do final setup.
- */
- initialize: function() {
- cr.ui.login.DisplayManager.initialize();
- login.HIDDetectionScreen.register();
- login.WrongHWIDScreen.register();
- login.NetworkScreen.register();
- login.EulaScreen.register();
- login.UpdateScreen.register();
- login.AutoEnrollmentCheckScreen.register();
- login.EnableDebuggingScreen.register();
- login.ResetScreen.register();
- login.AutolaunchScreen.register();
- login.KioskEnableScreen.register();
- login.AccountPickerScreen.register();
- login.GaiaSigninScreen.register();
- login.UserImageScreen.register(/* lazyInit= */ false);
- login.ErrorMessageScreen.register();
- login.TPMErrorMessageScreen.register();
- login.PasswordChangedScreen.register();
- login.SupervisedUserCreationScreen.register();
- login.TermsOfServiceScreen.register();
- login.AppLaunchSplashScreen.register();
- login.ConfirmPasswordScreen.register();
- login.FatalErrorScreen.register();
- login.ControllerPairingScreen.register();
- login.HostPairingScreen.register();
- login.DeviceDisabledScreen.register();
-
- cr.ui.Bubble.decorate($('bubble'));
- login.HeaderBar.decorate($('login-header-bar'));
-
- Oobe.initializeA11yMenu();
-
- chrome.send('screenStateInitialize');
- },
-
- /**
- * Initializes OOBE accessibility menu.
- */
- initializeA11yMenu: function() {
- cr.ui.Bubble.decorate($('accessibility-menu'));
- $('connect-accessibility-link').addEventListener(
- 'click', Oobe.handleAccessibilityLinkClick);
- $('eula-accessibility-link').addEventListener(
- 'click', Oobe.handleAccessibilityLinkClick);
- $('update-accessibility-link').addEventListener(
- 'click', Oobe.handleAccessibilityLinkClick);
- // Same behaviour on hitting spacebar. See crbug.com/342991.
- function reactOnSpace(event) {
- if (event.keyCode == 32)
- Oobe.handleAccessibilityLinkClick(event);
- }
- $('connect-accessibility-link').addEventListener(
- 'keyup', reactOnSpace);
- $('eula-accessibility-link').addEventListener(
- 'keyup', reactOnSpace);
- $('update-accessibility-link').addEventListener(
- 'keyup', reactOnSpace);
-
- $('high-contrast').addEventListener('click',
- Oobe.handleHighContrastClick);
- $('large-cursor').addEventListener('click',
- Oobe.handleLargeCursorClick);
- $('spoken-feedback').addEventListener('click',
- Oobe.handleSpokenFeedbackClick);
- $('screen-magnifier').addEventListener('click',
- Oobe.handleScreenMagnifierClick);
- $('virtual-keyboard').addEventListener('click',
- Oobe.handleVirtualKeyboardClick);
-
- // A11y menu should be accessible i.e. disable autohide on any
- // keydown or click inside menu.
- $('accessibility-menu').hideOnKeyPress = false;
- $('accessibility-menu').hideOnSelfClick = false;
- },
-
- /**
- * Accessibility link handler.
- */
- handleAccessibilityLinkClick: function(e) {
- /** @const */ var BUBBLE_OFFSET = 5;
- /** @const */ var BUBBLE_PADDING = 10;
- $('accessibility-menu').showForElement(e.target,
- cr.ui.Bubble.Attachment.BOTTOM,
- BUBBLE_OFFSET, BUBBLE_PADDING);
-
- var maxHeight = cr.ui.LoginUITools.getMaxHeightBeforeShelfOverlapping(
- $('accessibility-menu'));
- if (maxHeight < $('accessibility-menu').offsetHeight) {
- $('accessibility-menu').showForElement(e.target,
- cr.ui.Bubble.Attachment.TOP,
- BUBBLE_OFFSET, BUBBLE_PADDING);
- }
-
- $('accessibility-menu').firstBubbleElement = $('spoken-feedback');
- $('accessibility-menu').lastBubbleElement = $('close-accessibility-menu');
- if (Oobe.getInstance().currentScreen &&
- Oobe.getInstance().currentScreen.defaultControl) {
- $('accessibility-menu').elementToFocusOnHide =
- Oobe.getInstance().currentScreen.defaultControl;
- } else {
- // Update screen falls into this category. Since it doesn't have any
- // controls other than a11y link we don't want that link to receive
- // focus when screen is shown i.e. defaultControl is not defined.
- // Focus a11y link instead.
- $('accessibility-menu').elementToFocusOnHide = e.target;
- }
- e.stopPropagation();
- },
-
- /**
- * Spoken feedback checkbox handler.
- */
- handleSpokenFeedbackClick: function(e) {
- chrome.send('enableSpokenFeedback', [$('spoken-feedback').checked]);
- e.stopPropagation();
- },
-
- /**
- * Large cursor checkbox handler.
- */
- handleLargeCursorClick: function(e) {
- chrome.send('enableLargeCursor', [$('large-cursor').checked]);
- e.stopPropagation();
- },
-
- /**
- * High contrast mode checkbox handler.
- */
- handleHighContrastClick: function(e) {
- chrome.send('enableHighContrast', [$('high-contrast').checked]);
- e.stopPropagation();
- },
-
- /**
- * Screen magnifier checkbox handler.
- */
- handleScreenMagnifierClick: function(e) {
- chrome.send('enableScreenMagnifier', [$('screen-magnifier').checked]);
- e.stopPropagation();
- },
-
- /**
- * On-screen keyboard checkbox handler.
- */
- handleVirtualKeyboardClick: function(e) {
- chrome.send('enableVirtualKeyboard', [$('virtual-keyboard').checked]);
- e.stopPropagation();
- },
-
- /**
- * Sets usage statistics checkbox.
- * @param {boolean} checked Is the checkbox checked?
- */
- setUsageStats: function(checked) {
- $('usage-stats').checked = checked;
- },
-
- /**
- * Set OEM EULA URL.
- * @param {text} oemEulaUrl OEM EULA URL.
- */
- setOemEulaUrl: function(oemEulaUrl) {
- if (oemEulaUrl) {
- $('oem-eula-frame').src = oemEulaUrl;
- $('eulas').classList.remove('one-column');
- } else {
- $('eulas').classList.add('one-column');
- }
- },
-
- /**
- * Sets TPM password.
- * @param {text} password TPM password to be shown.
- */
- setTpmPassword: function(password) {
- $('tpm-busy').hidden = true;
-
- if (password.length) {
- $('tpm-password').textContent = password;
- $('tpm-password').hidden = false;
- } else {
- $('tpm-desc').hidden = true;
- $('tpm-desc-powerwash').hidden = false;
- }
- },
-
- /**
- * Refreshes a11y menu state.
- * @param {!Object} data New dictionary with a11y features state.
- */
- refreshA11yInfo: function(data) {
- $('high-contrast').checked = data.highContrastEnabled;
- $('spoken-feedback').checked = data.spokenFeedbackEnabled;
- $('screen-magnifier').checked = data.screenMagnifierEnabled;
- $('large-cursor').checked = data.largeCursorEnabled;
- $('virtual-keyboard').checked = data.virtualKeyboardEnabled;
- },
-
- /**
- * Reloads content of the page (localized strings, options of the select
- * controls).
- * @param {!Object} data New dictionary with i18n values.
- */
- reloadContent: function(data) {
- // Reload global local strings, process DOM tree again.
- loadTimeData.overrideValues(data);
- i18nTemplate.process(document, loadTimeData);
-
- // Update language and input method menu lists.
- Oobe.setupSelect($('language-select'), data.languageList);
- Oobe.setupSelect($('keyboard-select'), data.inputMethodsList);
- Oobe.setupSelect($('timezone-select'), data.timezoneList);
-
- // Update localized content of the screens.
- Oobe.updateLocalizedContent();
- },
-
- /**
- * Updates localized content of the screens.
- * Should be executed on language change.
- */
- updateLocalizedContent: function() {
- // Buttons, headers and links.
- Oobe.getInstance().updateLocalizedContent_();
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_popup_overlay.css b/chromium/chrome/browser/resources/chromeos/login/oobe_popup_overlay.css
deleted file mode 100644
index 57a6bf4daad..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_popup_overlay.css
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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.
- */
-
-.popup-overlay {
- -webkit-transition: 250ms opacity;
- align-items: center;
- background: rgba(255, 255, 255, .75);
- bottom: 0;
- display: flex;
- justify-content: center;
- left: 0;
- padding: 20px;
- position: fixed;
- right: 0;
- top: 0;
- z-index: 5;
-}
-
-.oobe-popup {
- background: white;
- border: 1px solid rgb(188, 193, 208);
- border-radius: 2px;
- box-shadow: 0 5px 80px #505050;
- min-height: 250px;
- position: relative;
- width: 460px;
- z-index: 10;
-}
-
-.oobe-popup h1 {
- -webkit-padding-end: 24px;
- -webkit-user-select: none;
- background: linear-gradient(white, #F8F8F8);
- color: rgb(83, 99, 125);
- font-size: 105%;
- font-weight: bold;
- margin: 0;
- padding: 10px 15px 8px 15px;
- text-shadow: white 0 1px 2px;
-}
-
-.popup-content-area {
- padding: 20px 20px 60px 20px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen.css
deleted file mode 100644
index 86b1209ee07..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen.css
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * This contains common styling for all the OOBE screens.
- */
-
-.step {
- box-sizing: border-box;
- position: absolute;
-}
-
-.step.animated:not(.faded) {
- -webkit-transition: -webkit-transform 200ms ease-in-out,
- opacity 200ms ease-in-out,
- visibility 200ms ease-in-out;
-}
-
-.step.hidden {
- visibility: hidden;
-}
-
-.faded,
-.left,
-.right {
- opacity: 0;
-}
-
-.step.right {
- -webkit-transform: translateX(50px);
-}
-
-.step.left {
- -webkit-transform: translateX(-50px)
-}
-
-.step.fullscreen {
- height: 100%;
- left: 0;
- right: 0;
- top: 0;
- width: 100%;
-}
-
-.step-controls {
- bottom: 21px;
- box-sizing: border-box;
- display: flex;
- height: 28px;
- justify-content: flex-end;
- padding-right: 34px; /* Double the padding of .step */
- position: absolute;
- width: 100%;
-}
-
-html[dir=rtl] .step-controls {
- /* Hack as -webkit-padding-end doesn't catch direction. crbug.com/363836 */
- padding-left: 34px;
-}
-
-.animation .step-controls button {
- /* Don't grey out disabled buttons during animation. */
- color: buttontext !important;
-}
-
-.step.loading .step-contents,
-.step.loading .step-controls,
-.step.loading .step-extra-controls {
- visibility: hidden;
-}
-
-.step:not(.loading) #user-images-loading {
- visibility: hidden;
-}
-
-.step:not(.loading) #eula-busy {
- visibility: hidden;
-}
-
-.step-loading {
- align-items: center;
- bottom: 0;
- display: flex;
- justify-content: center;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-/* Fixes perfomance problem caused by http://crbug.com/229405 . */
-.step.hidden .throbber,
-.step.hidden .spinner,
-.step.hidden .inline-spinner {
- display: none;
-}
-
-#security-info a,
-#eula a,
-.step-extra-controls a {
- color: rgb(49, 106, 197); /* same as 'Learn more' link */
- font-size: 12px;
- text-decoration: none;
-}
-
-.step-extra-controls {
- bottom: 26px;
- left: 49px;
- position: absolute;
-}
-
-/* EULA screen extra controls have 2 elements
- so they require different alignment. */
-#eula-extra-controls {
- bottom: 17px;
-}
-
-#security-info a:focus,
-#eula a:focus,
-.step-extra-controls a:focus {
- -webkit-transition: outline-color 200ms;
- /* Note: May use 1px solid here. */
- outline-color: rgb(77, 144, 254);
-}
-
-.step-extra-controls > *:not(:first-child) {
- margin-top: 7px;
-}
-
-html[dir=rtl] .step-extra-controls {
- left: auto;
- right: 49px;
-}
-
-#oobe.autolaunch #autolaunch-confirm-button,
-#oobe.autolaunch #autolaunch-cancel-button,
-#oobe.connect #continue-button,
-#oobe.eula #accept-button,
-#oobe.eula #back-button,
-#oobe.kiosk-enable #kiosk-cancel-button,
-#oobe.kiosk-enable #kiosk-enable-button,
-#oobe.user-image #ok-button {
- display: block;
-}
-
-#autolaunch-confirm-button,
-#back-button,
-#kiosk-enable-button,
-#reset-button,
-#password-changed-back-button,
-#tos-back-button {
- -webkit-margin-end: 8px;
-}
-
-.menu-area {
- margin: 5px;
-}
-
-.menu-control {
- color: #444;
- font-family: inherit;
- line-height: 20px;
- position: relative;
- width: 250px;
-}
-
-html[highlight=strong] #security-info a:focus,
-html[highlight=strong] #eula a:focus,
-html[highlight=strong] .step-extra-controls a:focus,
-html[highlight=strong] .menu-control:focus,
-html[highlight=strong] input[type='button']:focus,
-html[highlight=strong] button:focus {
- box-shadow: 0 0 23px rgb(77, 144, 254) !important;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.css
deleted file mode 100644
index b0735e475d8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.css
+++ /dev/null
@@ -1,16 +0,0 @@
-/* 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.
- */
-
-#auto-enrollment-check {
- min-height: 395px;
- padding: 70px 17px 21px;
-}
-
-#auto-enrollment-check #auto-enrollment-check-progress {
- color: #9c9c9c;
- display: flex;
- justify-content: center;
- margin-top: 130px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.html
deleted file mode 100644
index c66fd77af32..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<div class="step right hidden animated" id="auto-enrollment-check" role="group"
- i18n-values="aria-label:autoEnrollmentCheckScreenHeader" hidden>
- <div class="step-contents">
- <div id="auto-enrollment-check-progress" aria-live="polite">
- <div class="throbber"></div>
- <div i18n-content="autoEnrollmentCheckMessage"></div>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.js
deleted file mode 100644
index 5a90efb8eac..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Oobe Auto-enrollment check screen implementation.
- */
-
-login.createScreen('AutoEnrollmentCheckScreen',
- 'auto-enrollment-check',
- function() {
- return {
- EXTERNAL_API: []
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.css
deleted file mode 100644
index 9a0f0502527..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.css
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#autolaunch {
- min-height: 423px;
- padding: 40px 17px 80px;
- text-align: center;
- width: 722px;
-}
-
-#autolaunch-controls {
- bottom: 80px;
- justify-content: center;
-}
-
-#autolaunch-warning-title {
- color: #606060;
- font-size: 22px;
- padding: 5px 45px 30px;
-}
-
-#autolaunch-warning {
- color: #606060;
- font-size: 16px;
- padding: 35px 40px 10px;
-}
-
-#autolaunch-app {
- padding-bottom: 40px;
-}
-
-#autolaunch-app-container {
- -webkit-align-items: center;
- -webkit-justify-content: center;
- display: -webkit-flex;
-}
-
-#autolaunch-app-name {
- color: #404040;
- font-size: 22px;
- padding-left: 10px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.html
deleted file mode 100644
index 94cd4747036..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<div class="step hidden no-logo" id="autolaunch" hidden>
- <div class="step-contents">
- <div id="autolaunch-warning-title" i18n-content="autolaunchTitle"></div>
- <div id="autolaunch-app-container">
- <img id="autolaunch-app-icon" alt="">
- <div id="autolaunch-app-name"></div>
- </div>
- <div id="autolaunch-warning" i18n-content="autolaunchWarning"></div>
- </div>
- <div id="autolaunch-controls" class="step-controls"></div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.js
deleted file mode 100644
index ed9fe639e25..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.js
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe reset screen implementation.
- */
-
-login.createScreen('AutolaunchScreen', 'autolaunch', function() {
- return {
- EXTERNAL_API: ['updateApp', 'confirmAutoLaunchForTesting'],
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('autolaunchTitle');
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
-
- var confirmButton = this.ownerDocument.createElement('button');
- confirmButton.id = 'autolaunch-confirm-button';
- confirmButton.textContent =
- loadTimeData.getString('autolaunchConfirmButton');
- confirmButton.addEventListener('click', function(e) {
- chrome.send('autolaunchOnConfirm');
- e.stopPropagation();
- });
- buttons.push(confirmButton);
-
- var cancelButton = this.ownerDocument.createElement('button');
- cancelButton.id = 'autolaunch-cancel-button';
- cancelButton.textContent =
- loadTimeData.getString('autolaunchCancelButton');
- cancelButton.addEventListener('click', function(e) {
- chrome.send('autolaunchOnCancel');
- e.stopPropagation();
- });
- buttons.push(cancelButton);
- return buttons;
- },
-
- /**
- * Event handler invoked when the page is shown and ready.
- */
- onBeforeShow: function() {
- chrome.send('autolaunchVisible');
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- return $('autolaunch-cancel-button');
- },
-
- /**
- * Cancels the reset and drops the user back to the login screen.
- */
- cancel: function() {
- chrome.send('autolaunchOnCancel');
- },
-
- /**
- * Sets app to be displayed in the auto-launch warning.
- * @param {!Object} app An dictionary with app info.
- */
- updateApp: function(app) {
- if (app.appIconUrl && app.appIconUrl.length)
- $('autolaunch-app-icon').src = app.appIconUrl;
-
- $('autolaunch-app-name').innerText = app.appName;
- },
-
- /**
- * Initiates confirm/cancel response for testing.
- * @param {boolean} confirm True if the screen should confirm auto-launch.
- */
- confirmAutoLaunchForTesting: function(confirm) {
- var button = confirm ? $('autolaunch-confirm-button') :
- $('autolaunch-cancel-button');
- var clickEvent = cr.doc.createEvent('Event');
- clickEvent.initEvent('click', true, true);
- button.dispatchEvent(clickEvent);
- }
- };
-});
-
-
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.css
deleted file mode 100644
index 76b222aa96e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.css
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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.
- */
-
-/* TODO(dzhioev): support RTL. http://crbug.com/423354 */
-/* TODO(xdai): Remove the hard-coded font-family for 'Roboto'. */
-
-:host {
- -webkit-user-select: none;
- background: white;
- display: block;
- font-family: 'Roboto';
- height: 600px;
- position: relative;
- width: 720px;
-}
-
-controller-pairing-page[name='device-select']::shadow #top,
-controller-pairing-page[name='establishing-connection']::shadow #top {
- height: 200px;
-}
-
-controller-pairing-page[name='code-confirmation']::shadow #top,
-controller-pairing-page[name='host-update']::shadow #top,
-controller-pairing-page[name='host-connection-lost']::shadow #top,
-controller-pairing-page[name='enrollment-introduction']::shadow #top {
- height: 300px;
-}
-
-controller-pairing-page[name='authentication']::shadow #top {
- height: 100px;
-}
-
-paper-progress {
- --paper-progress-active-color: var(--google-green-500);
- --paper-progress-container-color: var(--google-green-100);
- margin-bottom: 28px;
- margin-top: 28px;
- width: 100%;
-}
-
-#code {
- color: #757575;
- font-size: 55px;
- font-weight: 300;
-}
-
-pairing-device-list {
- height: 252px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.html
deleted file mode 100644
index 4f02eb82d68..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<div class="step hidden no-logo" id="controller-pairing" hidden>
- <controller-pairing-screen name="ControllerPairingScreen">
- </controller-pairing-screen>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.js
deleted file mode 100644
index cc50c3c554e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-/**
- * @fileoverview controller pairing screen implementation.
- */
-
-login.createScreen('ControllerPairingScreen', 'controller-pairing', function() {
- return {
- decorate: function() {
- this.children[0].decorate(this);
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.css
deleted file mode 100644
index 9c23f20e6ea..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.css
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#debugging {
- display: flex;
- flex-flow: column;
- font-size: 16px;
- min-height: 423px;
- text-align: center;
- width: 722px;
-}
-
-#debugging .step-contents {
- margin: 80px 100px;
-}
-
-#debugging.setup-view .step-contents {
- margin-bottom: 40px;
- margin-top: 40px;
-}
-
-#debugging.done-view .step-contents,
-#debugging.error-view .step-contents {
- margin: 80px;
-}
-
-#debugging #debugging-controls {
- height: auto;
- justify-content: center;
- margin-top: auto;
- padding-bottom: 80px;
- padding-right: 0;
- position: static;
-}
-
-#debugging.setup-view #debugging-controls {
- padding-bottom: 40px;
-}
-
-#debugging-controls button {
- margin: 0 10px;
-}
-
-#enable-debugging-icon {
- background-position: center;
- background-repeat: no-repeat;
- width: 100%;
-}
-
-.remove-protection-view #enable-debugging-icon,
-.setup-view #enable-debugging-icon,
-.wait-view #enable-debugging-icon {
- background-image: url(chrome://theme/IDR_RESET_WARNING);
- background-size: 39px 72px;
- height: 72px;
-}
-
-.done-view #enable-debugging-icon {
- background-image: url(chrome://theme/IDR_ENABLE_DEBUGGING_SUCCESS);
- background-size: 86px 66px;
- height: 66px;
-}
-
-.error-view #enable-debugging-icon {
- background-image: url(chrome://theme/IDR_ENABLE_DEBUGGING_FAILURE);
- background-size: 66px;
- height: 66px;
-}
-
-/** Preload icons */
-#enable-debugging-icon::after {
- content:
- url(chrome://theme/IDR_RESET_WARNING)
- url(chrome://theme/IDR_ENABLE_DEBUGGING_SUCCESS)
- url(chrome://theme/IDR_ENABLE_DEBUGGING_FAILURE);
- display: none;
-}
-
-.enable-debugging-title {
- color: #464646;
- font-size: 24px;
- font-weight: bold;
- padding: 30px 45px;
-}
-
-.enable-debugging-text {
- color: #606060;
-}
-
-#debugging #debugging-warning-details,
-#debugging #debugging-done-msg {
- padding: 20px 40px 0;
-}
-
-#debugging #enable-debugging-wait-msg {
- display: inline-block;
- padding: 25px 0;
- vertical-align: middle;
-}
-
-#enable-debugging-passwords {
- font-style: italic;
- margin-bottom: 10px;
- margin-top: 20px;
-}
-
-#enable-debugging-password-note {
- color: #c6c6c6;
- font-size: 12px;
-}
-
-.enable-debugging-password-input {
- align-items: center;
- display: flex;
- flex-direction: column;
- margin: 10px 0;
-}
-
-.enable-debugging-password-input input[type=password] {
- margin: 5px 0;
- width: 300px;
-}
-
-.enable-debugging-password-input
- input[type=password]::-webkit-input-placeholder {
- font-size: 14px;
- font-style: normal;
-}
-
-.done-specific,
-.error-specific,
-.remove-protection-specific,
-.setup-specific,
-.wait-specific {
- display: none;
-}
-
-.error-view .error-specific,
-.done-view .done-specific,
-.remove-protection-view .remove-protection-specific,
-.setup-view .setup-specific,
-.wait-view .wait-specific {
- display: block;
-}
-
-#debugging-remove-protection-button,
-#debugging-enable-button,
-#debugging-cancel-button,
-#debugging-ok-button {
- display: none;
-}
-
-.remove-protection-view #debugging-remove-protection-button,
-.remove-protection-view #debugging-cancel-button,
-.setup-view #debugging-enable-button,
-.setup-view #debugging-cancel-button,
-.done-view #debugging-ok-button,
-.error-view #debugging-ok-button {
- display: inline-block;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.html
deleted file mode 100644
index c3f878b7b24..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<div class="step faded hidden no-logo" id="debugging" role="group" hidden
- i18n-values="aria-label:enableDebuggingScreenAccessibleTitle">
- <div class="step-contents" aria-live="polite" aria-atomic="true">
- <div id="enable-debugging-icon"></div>
- <div i18n-content="enableDebuggingScreenTitle"
- class="enable-debugging-title remove-protection-specific setup-specific
- done-specific wait-specific">
- </div>
- <div i18n-content="enableDebuggingErrorTitle"
- class="enable-debugging-title error-specific">
- </div>
- <div id="enable-debugging-info"
- class="enable-debugging-text
- remove-protection-specific setup-specific state-specific
- error-specific done-specific">
- <div id="enable-debugging-remove-protection-details"
- class="remove-protection-specific">
- <span i18n-content="enableDebuggingRemveRootfsMessage"></span>
- <a id="enable-debugging-help-link" href="#"
- i18n-content="enableDebuggingLearnMore"></a>
- </div>
- <div id="enable-debugging-setup-details"
- i18n-content="enableDebuggingSetupMessage"
- class="setup-specific">
- </div>
- <div id="enable-debugging-passwords" class="setup-specific">
- <div class="enable-debugging-password-input">
- <input id="enable-debugging-password" type="password">
- <input id="enable-debugging-password2" type="password">
- </div>
- <div id="enable-debugging-password-note"
- i18n-content="enableDebuggingPasswordLengthNote">
- </div>
- </div>
- <div class="enable-debugging-completed-details done-specific"
- i18n-content="enableDebuggingDoneMessage">
- </div>
- <div class="enable-debugging-error-details error-specific"
- i18n-content="enableDebuggingErrorMessage">
- </div>
- </div>
- <div id="revert-promise" class="enable-debugging-text wait-specific">
- <div id="enable-debugging-wait-msg"
- i18n-content="enableDebuggingWaitMessage">
- </div>
- </div>
- </div>
- <div id="debugging-controls" class="step-controls"></div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.js
deleted file mode 100644
index a1b70bb1803..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.js
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (c) 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.
-
-/**
- * @fileoverview Enable developer features screen implementation.
- */
-
-login.createScreen('EnableDebuggingScreen', 'debugging', function() {
- return {
-
- /* Possible UI states of the enable debugging screen. */
- UI_STATE: {
- ERROR: -1,
- NONE: 0,
- REMOVE_PROTECTION: 1,
- SETUP: 2,
- WAIT: 3,
- DONE: 4
- },
-
- EXTERNAL_API: [
- 'updateState'
- ],
-
- /** @override */
- decorate: function() {
- $('enable-debugging-help-link').addEventListener('click',
- function(event) {
- chrome.send('enableDebuggingOnLearnMore');
- });
-
- var password = $('enable-debugging-password');
- var password2 = $('enable-debugging-password2');
- password.addEventListener('input', this.onPasswordChanged_.bind(this));
- password2.addEventListener('input', this.onPasswordChanged_.bind(this));
- password.placeholder =
- loadTimeData.getString('enableDebuggingPasswordLabel');
- password2.placeholder =
- loadTimeData.getString('enableDebuggingConfirmPasswordLabel');
- },
-
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('enableDebuggingScreenTitle');
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
- var rootfsRemoveButton = this.ownerDocument.createElement('button');
- rootfsRemoveButton.id = 'debugging-remove-protection-button';
- rootfsRemoveButton.textContent =
- loadTimeData.getString('enableDebuggingRemoveButton');
- rootfsRemoveButton.addEventListener('click', function(e) {
- chrome.send('enableDebuggingOnRemoveRootFSProtection');
- e.stopPropagation();
- });
- buttons.push(rootfsRemoveButton);
-
- var enableButton = this.ownerDocument.createElement('button');
- enableButton.id = 'debugging-enable-button';
- enableButton.textContent =
- loadTimeData.getString('enableDebuggingEnableButton');
- enableButton.addEventListener('click', function(e) {
- chrome.send('enableDebuggingOnSetup',
- [$('enable-debugging-password').value]);
- e.stopPropagation();
- });
- buttons.push(enableButton);
-
- var cancelButton = this.ownerDocument.createElement('button');
- cancelButton.id = 'debugging-cancel-button';
- cancelButton.textContent =
- loadTimeData.getString('enableDebuggingCancelButton');
- cancelButton.addEventListener('click', function(e) {
- chrome.send('enableDebuggingOnCancel');
- e.stopPropagation();
- });
- buttons.push(cancelButton);
-
- var okButton = this.ownerDocument.createElement('button');
- okButton.id = 'debugging-ok-button';
- okButton.textContent =
- loadTimeData.getString('enableDebuggingOKButton');
- okButton.addEventListener('click', function(e) {
- chrome.send('enableDebuggingOnDone');
- e.stopPropagation();
- });
- buttons.push(okButton);
-
- return buttons;
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- if (this.state_ == this.UI_STATE.REMOVE_PROTECTION)
- return $('debugging-remove-protection-button');
- else if (this.state_ == this.UI_STATE.SETUP)
- return $('enable-debugging-password');
- else if (this.state_ == this.UI_STATE.DONE ||
- this.state_ == this.UI_STATE.ERROR) {
- return $('debugging-ok-button');
- }
-
- return $('debugging-cancel-button');
- },
-
- /**
- * Cancels the enable debugging screen and drops the user back to the
- * network settings.
- */
- cancel: function() {
- chrome.send('enableDebuggingOnCancel');
- },
-
- /**
- * Event handler that is invoked just before the screen in shown.
- * @param {Object} data Screen init payload.
- */
- onBeforeShow: function(data) {
- this.setDialogView_(this.UI_STATE.NONE);
- },
-
- onPasswordChanged_: function() {
- var enableButton = $('debugging-enable-button');
- var password = $('enable-debugging-password');
- var password2 = $('enable-debugging-password2');
- var pwd = password.value;
- var pwd2 = password2.value;
- enableButton.disabled = !((pwd.length == 0 && pwd2.length == 0) ||
- (pwd == pwd2 && pwd.length >= 4));
- },
-
- /**
- * Sets css style for corresponding state of the screen.
- * @param {number} state.
- * @private
- */
- setDialogView_: function(state) {
- this.state_ = state;
- this.classList.toggle('remove-protection-view',
- state == this.UI_STATE.REMOVE_PROTECTION);
- this.classList.toggle('setup-view', state == this.UI_STATE.SETUP);
- this.classList.toggle('wait-view', state == this.UI_STATE.WAIT);
- this.classList.toggle('done-view', state == this.UI_STATE.DONE);
- this.classList.toggle('error-view', state == this.UI_STATE.ERROR);
- this.defaultControl.focus();
-
- if (Oobe.getInstance().currentScreen === this)
- Oobe.getInstance().updateScreenSize(this);
- },
-
- updateState: function(state) {
- this.setDialogView_(state);
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.css
deleted file mode 100644
index ba4ab3896dd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#kiosk-enable {
- min-height: 423px;
- padding: 40px 17px 80px;
- text-align: center;
- width: 722px;
-}
-
-#kiosk-enable-controls {
- bottom: 80px;
- justify-content: center;
-}
-
-#kiosk-enable-msg {
- color: #606060;
- font-size: 22px;
- padding: 5px 45px 30px;
-}
-
-#kiosk-enable-details {
- color: #606060;
- font-size: 16px;
- padding: 35px 40px 80px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.html
deleted file mode 100644
index 9a7c9969a6b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<div class="step hidden no-logo" id="kiosk-enable" hidden>
- <div class="step-contents">
- <div id="kiosk-enable-msg" i18n-content="kioskEnableWarningText"></div>
- <img id="kiosk-enable-icon" src="chrome://theme/IDR_RESET_WARNING" alt="">
- <div id="kiosk-enable-details"
- i18n-content="kioskEnableWarningDetails"></div>
- </div>
- <div id="kiosk-enable-controls" class="step-controls"></div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.js
deleted file mode 100644
index 8bb2bb43bc5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.js
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe reset screen implementation.
- */
-
-login.createScreen('KioskEnableScreen', 'kiosk-enable', function() {
- return {
- EXTERNAL_API: ['enableKioskForTesting',
- 'onCompleted'],
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('kioskEnableTitle');
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
-
- var confirmButton = this.ownerDocument.createElement('button');
- confirmButton.id = 'kiosk-enable-button';
- confirmButton.textContent =
- loadTimeData.getString('kioskEnableButton');
- confirmButton.addEventListener('click', function(e) {
- chrome.send('kioskOnEnable');
- e.stopPropagation();
- });
- buttons.push(confirmButton);
-
- var cancelButton = this.ownerDocument.createElement('button');
- cancelButton.id = 'kiosk-cancel-button';
- cancelButton.textContent =
- loadTimeData.getString('kioskCancelButton');
- cancelButton.addEventListener('click', function(e) {
- chrome.send('kioskOnClose');
- e.stopPropagation();
- });
- buttons.push(cancelButton);
-
- var okButton = this.ownerDocument.createElement('button');
- okButton.id = 'kiosk-ok-button';
- okButton.hidden = true;
- okButton.textContent =
- loadTimeData.getString('kioskOKButton');
- okButton.addEventListener('click', function(e) {
- chrome.send('kioskOnClose');
- e.stopPropagation();
- });
- buttons.push(okButton);
- return buttons;
- },
-
- /**
- * Event handler invoked when the page is shown and ready.
- */
- onBeforeShow: function() {
- $('kiosk-enable-button').hidden = false;
- $('kiosk-cancel-button').hidden = false;
- $('kiosk-ok-button').hidden = true;
- $('kiosk-enable-details').textContent =
- loadTimeData.getString('kioskEnableWarningDetails');
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- return $('kiosk-cancel-button');
- },
-
- /**
- * Cancels the reset and drops the user back to the login screen.
- */
- cancel: function() {
- chrome.send('kioskOnClose');
- },
-
- /**
- * Initiates enable/cancel response for testing.
- * @param {boolean} confirm True if the screen should confirm auto-launch.
- */
- enableKioskForTesting: function(confirm) {
- var button = confirm ? $('kiosk-enable-button') :
- $('kiosk-cancel-button');
- var clickEvent = cr.doc.createEvent('Event');
- clickEvent.initEvent('click', true, true);
- button.dispatchEvent(clickEvent);
- },
-
- /**
- * Updates completion message on the screen.
- * @param {boolean} success True if consumer kiosk was successfully enabled.
- */
- onCompleted: function(success) {
- $('kiosk-enable-button').hidden = true;
- $('kiosk-cancel-button').hidden = true;
- $('kiosk-ok-button').hidden = false;
- $('kiosk-enable-details').textContent =
- loadTimeData.getString(success ? 'kioskEnableSuccessMsg' :
- 'kioskEnableErrorMsg');
- }
- };
-});
-
-
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.css
deleted file mode 100644
index accb4a3de38..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.css
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#eula {
- min-height: 395px;
- padding: 70px 17px 21px;
-}
-
-#cros-eula,
-#oem-eula {
- border: 1px solid #d9d9d9;
- height: 222px;
-}
-
-.eula-frame {
- height: 222px;
-}
-
-#logging {
- clear: both;
- font-size: small;
- margin-top: 20px;
- width: 620px;
-}
-
-#logging div {
- display: table-cell;
- vertical-align: middle;
-}
-
-#usage-stats {
- -webkit-margin-end: 10px;
-}
-
-.eula-columns {
- display: -webkit-box;
- width: 630px;
-}
-
-.eula-frame {
- border: none;
- padding: 0 0 0 5px;
-}
-
-#cros-eula {
- width: 314px;
-}
-
-#cros-eula-frame {
- width: 309px;
-}
-
-#oem-eula {
- border-left: none;
- width: 313px;
-}
-
-#oem-eula-frame {
- width: 308px;
-}
-
-#eulas.one-column #cros-eula {
- width: 628px;
-}
-
-#eulas.one-column #cros-eula-frame {
- width: 623px;
-}
-
-#eulas.one-column #oem-eula {
- display: none;
-}
-
-#eula #stats-help-link {
- color: rgb(49, 106, 197);
-}
-
-#eula .step-contents {
- -webkit-margin-start: 32px;
- margin-bottom: 30px;
-}
-
-#eula .credits {
- clear: both;
- font-size: small;
-}
-
-#cros-eula-loading {
- -webkit-align-items: center;
- -webkit-flex-direction: column;
- -webkit-justify-content: center;
- display: none;
- height: 100%;
- width: 100%;
-}
-
-.step.eula-loading #cros-eula-frame {
- display: none;
-}
-
-.step.eula-loading #cros-eula-loading {
- display: -webkit-flex;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.html
deleted file mode 100644
index 590886c0220..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<div class="step right hidden animated eula-loading" id="eula" role="group"
- i18n-values="aria-label:eulaScreenAccessibleTitle" hidden>
- <div class="step-contents">
- <div id="eulas" class="eula-columns one-column">
- <div id="cros-eula" tabindex="0">
- <iframe id="cros-eula-frame" name="cros-eula-frame" class="eula-frame"
- src="about:blank"></iframe>
- <div id="cros-eula-loading">
- <div>
- <p i18n-content="termsOfServiceLoading"></p>
- </div>
- </div>
- </div>
- <div id="oem-eula">
- <iframe id="oem-eula-frame" name="oem-eula-frame" class="eula-frame"></iframe>
- </div>
- </div>
- <div id="logging">
- <div>
- <input id="usage-stats" type="checkbox">
- </div>
- <div>
- <label for="usage-stats" i18n-content="checkboxLogging"></label>
- <a id="stats-help-link" href="#" i18n-content="learnMore"></a>
- </div>
- </div>
- </div>
- <div id="eula-controls" class="step-controls"></div>
- <div id="eula-extra-controls" class="step-extra-controls">
- <div id="installation-settings">
- <a id="installation-settings-link" href="#"
- i18n-content="eulaSystemInstallationSettings">
- </a>
- </div>
- <div id="eula-accessibility">
- <a id="eula-accessibility-link" href="#" role="button"
- i18n-content="accessibilityLink"></a>
- </div>
- <div id="eula-chrome-credits"
- class="credits"><a id="eula-chrome-credits-link" href="#" role="button"
- i18n-content="chromeCreditsLink"></a></div>
- <div id="eula-chromeos-credits"
- class="credits"><a id="eula-chromeos-credits-link" href="#" role="button"
- i18n-content="chromeosCreditsLink"></a></div>
- </div>
- <div id="eula-busy" class="step-loading">
- <div class="throbber"></div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.js
deleted file mode 100644
index f6c85cc2cdf..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula.js
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe eula screen implementation.
- */
-
-login.createScreen('EulaScreen', 'eula', function() {
- var CONTEXT_KEY_USAGE_STATS_ENABLED = 'usageStatsEnabled';
-
- return {
- /** @override */
- decorate: function() {
- $('eula-chrome-credits-link').hidden = true;
- $('eula-chromeos-credits-link').hidden = true;
- $('stats-help-link').addEventListener('click', function(event) {
- chrome.send('eulaOnLearnMore');
- });
- $('installation-settings-link').addEventListener(
- 'click', function(event) {
- chrome.send('eulaOnInstallationSettingsPopupOpened');
- $('popup-overlay').hidden = false;
- $('installation-settings-ok-button').focus();
- });
- $('installation-settings-ok-button').addEventListener(
- 'click', function(event) {
- $('popup-overlay').hidden = true;
- });
- // Do not allow focus leaving the overlay.
- $('popup-overlay').addEventListener('focusout', function(event) {
- // WebKit does not allow immediate focus return.
- window.setTimeout(function() {
- // TODO(ivankr): focus cycling.
- $('installation-settings-ok-button').focus();
- }, 0);
- event.preventDefault();
- });
-
- var self = this;
- $('usage-stats').addEventListener('click', function(event) {
- self.context.set(CONTEXT_KEY_USAGE_STATS_ENABLED,
- $('usage-stats').checked);
- self.commitContextChanges();
- event.stopPropagation();
- });
- },
-
- /**
- * Event handler that is invoked when 'chrome://terms' is loaded.
- */
- onFrameLoad: function() {
- $('accept-button').disabled = false;
- $('eula').classList.remove('eula-loading');
- // Initially, the back button is focused and the accept button is
- // disabled.
- // Move the focus to the accept button now but only if the user has not
- // moved the focus anywhere in the meantime.
- if (!$('back-button').blurred)
- $('accept-button').focus();
- },
-
- /**
- * Event handler that is invoked just before the screen is shown.
- * @param {object} data Screen init payload.
- */
- onBeforeShow: function() {
- $('eula').classList.add('eula-loading');
- $('cros-eula-frame').onload = this.onFrameLoad;
- $('accept-button').disabled = true;
- $('cros-eula-frame').src = 'chrome://terms';
- },
-
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('eulaScreenTitle');
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {Array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
-
- var backButton = this.declareButton('back-button');
- backButton.textContent = loadTimeData.getString('back');
- buttons.push(backButton);
-
- var acceptButton = this.declareButton('accept-button');
- acceptButton.disabled = true;
- acceptButton.classList.add('preserve-disabled-state');
- acceptButton.textContent = loadTimeData.getString('acceptAgreement');
- acceptButton.addEventListener('click', function(e) {
- $('eula').classList.add('loading'); // Mark EULA screen busy.
- Oobe.clearErrors();
- e.stopPropagation();
- });
- buttons.push(acceptButton);
-
- return buttons;
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- return $('accept-button').disabled ? $('back-button') :
- $('accept-button');
- },
-
- enableKeyboardFlow: function() {
- $('eula-chrome-credits-link').hidden = false;
- $('eula-chromeos-credits-link').hidden = false;
- $('eula-chrome-credits-link').addEventListener('click',
- function(event) {
- chrome.send('eulaOnChromeCredits');
- });
- $('eula-chromeos-credits-link').addEventListener('click',
- function(event) {
- chrome.send('eulaOnChromeOSCredits');
- });
- },
-
- /**
- * Updates localized content of the screen that is not updated via template.
- */
- updateLocalizedContent: function() {
- // Force iframes to refresh. It's only available method because we have
- // no access to iframe.contentWindow.
- if ($('cros-eula-frame').src) {
- $('cros-eula-frame').src = $('cros-eula-frame').src;
- }
- if ($('oem-eula-frame').src) {
- $('oem-eula-frame').src = $('oem-eula-frame').src;
- }
- }
- };
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula_installation_settings_overlay.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula_installation_settings_overlay.css
deleted file mode 100644
index 2d4fc888dce..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula_installation_settings_overlay.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 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. */
-
-#tpm-busy {
- text-align: center;
-}
-
-#tpm-password {
- font-weight: bold;
- text-align: center;
-}
-
-#installation-settings-popup button {
- bottom: 20px;
- position: absolute;
- right: 20px;
-} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula_installation_settings_overlay.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula_installation_settings_overlay.html
deleted file mode 100644
index 15358d043bb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_eula_installation_settings_overlay.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<div id="installation-settings-popup" class="oobe-popup">
- <h1 i18n-content="eulaSystemInstallationSettings"></h1>
- <div class="popup-content-area">
- <div id="tpm-settings">
- <p i18n-content="eulaTpmDesc"></p>
- <p id="tpm-desc" i18n-content="eulaTpmKeyDesc"></p>
- <p id="tpm-desc-powerwash" i18n-content="eulaTpmDescPowerwash" hidden>
- </p>
- <div id="tpm-busy">
- <div id="spinner" class="inline-spinner"></div>
- <span i18n-content="eulaTpmBusy"></span>
- </div>
- <p id="tpm-password"></p>
- </div>
- </div>
- <button id="installation-settings-ok-button"
- i18n-content="eulaSystemInstallationSettingsOkButton">
- </button>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css
deleted file mode 100644
index f1f2162f78e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css
+++ /dev/null
@@ -1,95 +0,0 @@
-/* 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.
- */
-
-#hid-detection {
- min-height: 395px;
- padding: 70px 17px 21px;
- width: 622px;
-}
-
-#hid-detection .step-contents {
- margin: 33px auto 82px;
- width: 475px;
-}
-
-#hid-detection #hid-invitation-text {
- font-size: 16px;
-}
-
-#hid-detection #hid-prerequisite-msg {
- padding: 10px 0 20px;
-}
-
-#hid-keyboard-block,
-#hid-mouse-block {
- padding: 10px 0;
-}
-
-#hid-keyboard-block {
- padding-bottom: 30px;
-}
-
-#hid-keyboard-icon,
-#hid-mouse-icon {
- bottom: -15px;
- height: 40px;
- position: relative;
- width: 40px;
-}
-
-#hid-mouse-icon-block,
-#hid-keyboard-icon-block {
- display: inline;
-}
-
-#hid-mouse-label,
-#hid-keyboard-label {
- -webkit-padding-start: 10px;
- display: inline;
-}
-
-#hid-detection .label {
- display: none;
-}
-
-#hid-keyboard-tick,
-#hid-mouse-tick {
- -webkit-margin-start: -28px;
- bottom: -20px;
- position: relative;
- visibility: hidden;
-}
-
-.searching {
- opacity: 0.6
-}
-
-#hid-detection #hid-keyboard-pincode {
- -webkit-padding-start: 60px;
- padding-bottom: 15px;
- padding-top: 15px;
-}
-
-.searching #hid-keyboard-label-searching,
-.searching #hid-mouse-label-searching,
-.connected #hid-keyboard-label-connected,
-.connected #hid-mouse-label-connected,
-.paired #hid-keyboard-label-paired,
-.paired #hid-mouse-label-paired,
-.pairing #hid-keyboard-label-pairing,
-.connected #hid-keyboard-tick,
-.connected #hid-mouse-tick,
-.paired #hid-keyboard-tick,
-.paired #hid-mouse-tick {
- display: inline;
-}
-
-.connected #hid-keyboard-tick,
-.connected #hid-mouse-tick,
-.paired #hid-keyboard-tick,
-.paired #hid-mouse-tick {
- visibility: visible;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.html
deleted file mode 100644
index 11cbd6ff502..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<div class="step hidden" id="hid-detection" hidden role="group"
- i18n-values="aria-label:hidDetectionInvitation">
- <div class="step-contents">
- <div id="hid-invitation-text" i18n-content="hidDetectionInvitation"></div>
- <div id="hid-prerequisite-msg" i18n-content="hidDetectionPrerequisites">
- </div>
- <div id="hid-mouse-block">
- <div id="hid-mouse-icon-block">
- <img id="hid-mouse-icon" src="chrome://theme/IDR_BLUETOOTH_MOUSE"
- alt="">
- <img id="hid-mouse-tick" src="chrome://theme/IDR_BLUETOOTH_PAIRING_TICK"
- alt="">
- </div>
- <div id="hid-mouse-label">
- <span id="hid-mouse-label-searching" aria-live="polite"
- i18n-content="hidDetectionMouseSearching" class="label">
- </span>
- <span id="hid-mouse-label-connected" aria-live="polite"
- i18n-content="hidDetectionUSBMouseConnected" class="label">
- </span>
- <span id="hid-mouse-label-paired" aria-live="polite"
- i18n-content="hidDetectionBTMousePaired" class="label">
- </span>
- </div>
- </div>
- <div id="hid-keyboard-block" class="searching">
- <div id="hid-keyboard-icon-block">
- <img id="hid-keyboard-icon" src="chrome://theme/IDR_BLUETOOTH_KEYBOARD"
- alt="">
- <img id="hid-keyboard-tick"
- src="chrome://theme/IDR_BLUETOOTH_PAIRING_TICK" alt="">
- </div>
- <div id="hid-keyboard-label">
- <span id="hid-keyboard-label-searching" aria-live="polite"
- i18n-content="hidDetectionKeyboardSearching" class="label">
- </span>
- <span id="hid-keyboard-label-connected" aria-live="polite"
- i18n-content="hidDetectionUSBKeyboardConnected" class="label">
- </span>
- <span id="hid-keyboard-label-paired" class="label" aria-live="polite">
- </span>
- <span id="hid-keyboard-label-pairing" class="label"></span>
- </div>
- <div id="hid-keyboard-pincode" hidden>
- <div id="hid-keyboard-pincode-sym-1" class="bluetooth-keyboard-button">
- </div>
- <div id="hid-keyboard-pincode-sym-2" class="bluetooth-keyboard-button">
- </div>
- <div id="hid-keyboard-pincode-sym-3" class="bluetooth-keyboard-button">
- </div>
- <div id="hid-keyboard-pincode-sym-4" class="bluetooth-keyboard-button">
- </div>
- <div id="hid-keyboard-pincode-sym-5" class="bluetooth-keyboard-button">
- </div>
- <div id="hid-keyboard-pincode-sym-6" class="bluetooth-keyboard-button">
- </div>
- <div id="hid-keyboard-pincode-sym-7"
- i18n-content="hidDetectionBTEnterKey"
- class="bluetooth-keyboard-button">
- </div>
- </div>
- </div>
- </div>
- <div id="hid-detection-controls" class="step-controls"></div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.js
deleted file mode 100644
index ed60538fa33..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.js
+++ /dev/null
@@ -1,210 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Oobe HID detection screen implementation.
- */
-
-login.createScreen('HIDDetectionScreen', 'hid-detection', function() {
- var CONTEXT_KEY_KEYBOARD_STATE = 'keyboard-state';
- var CONTEXT_KEY_MOUSE_STATE = 'mouse-state';
- var CONTEXT_KEY_KEYBOARD_PINCODE = 'keyboard-pincode';
- var CONTEXT_KEY_KEYBOARD_ENTERED_PART_EXPECTED = 'num-keys-entered-expected';
- var CONTEXT_KEY_KEYBOARD_ENTERED_PART_PINCODE = 'num-keys-entered-pincode';
- var CONTEXT_KEY_MOUSE_DEVICE_NAME = 'mouse-device-name';
- var CONTEXT_KEY_KEYBOARD_DEVICE_NAME = 'keyboard-device-name';
- var CONTEXT_KEY_KEYBOARD_LABEL = 'keyboard-device-label';
- var CONTEXT_KEY_CONTINUE_BUTTON_ENABLED = 'continue-button-enabled';
-
- var PINCODE_LENGTH = 6;
-
- return {
-
- /**
- * Enumeration of possible states during pairing. The value associated with
- * each state maps to a localized string in the global variable
- * |loadTimeData|.
- * @enum {string}
- */
- PAIRING: {
- STARTUP: 'bluetoothStartConnecting',
- REMOTE_PIN_CODE: 'bluetoothRemotePinCode',
- CONNECT_FAILED: 'bluetoothConnectFailed',
- CANCELED: 'bluetoothPairingCanceled',
- // Pairing dismissed (succeeded or canceled).
- DISMISSED: 'bluetoothPairingDismissed'
- },
-
- // Enumeration of possible connection states of a device.
- CONNECTION: {
- SEARCHING: 'searching',
- CONNECTED: 'connected',
- PAIRING: 'pairing',
- PAIRED: 'paired',
- // Special info state.
- UPDATE: 'update'
- },
-
- // Possible ids of device blocks.
- BLOCK: {
- MOUSE: 'hid-mouse-block',
- KEYBOARD: 'hid-keyboard-block'
- },
-
- /**
- * Button to move to usual OOBE flow after detection.
- * @private
- */
- continueButton_: null,
-
- /** @override */
- decorate: function() {
- var self = this;
-
- this.context.addObserver(
- CONTEXT_KEY_MOUSE_STATE,
- function(stateId) {
- if (stateId === undefined)
- return;
- self.setDeviceBlockState_('hid-mouse-block', stateId);
- }
- );
- this.context.addObserver(
- CONTEXT_KEY_KEYBOARD_STATE,
- function(stateId) {
- self.updatePincodeKeysState_();
- if (stateId === undefined)
- return;
- self.setDeviceBlockState_('hid-keyboard-block', stateId);
- if (stateId == self.CONNECTION.PAIRED) {
- $('hid-keyboard-label-paired').textContent = self.context.get(
- CONTEXT_KEY_KEYBOARD_LABEL, '');
- } else if (stateId == self.CONNECTION.PAIRING) {
- $('hid-keyboard-label-pairing').textContent = self.context.get(
- CONTEXT_KEY_KEYBOARD_LABEL, '');
- }
- }
- );
- this.context.addObserver(
- CONTEXT_KEY_KEYBOARD_PINCODE,
- this.updatePincodeKeysState_.bind(this));
- this.context.addObserver(
- CONTEXT_KEY_KEYBOARD_ENTERED_PART_EXPECTED,
- this.updatePincodeKeysState_.bind(this));
- this.context.addObserver(
- CONTEXT_KEY_KEYBOARD_ENTERED_PART_PINCODE,
- this.updatePincodeKeysState_.bind(this));
- this.context.addObserver(
- CONTEXT_KEY_CONTINUE_BUTTON_ENABLED,
- function(enabled) {
- $('hid-continue-button').disabled = !enabled;
- }
- );
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
- var continueButton = this.ownerDocument.createElement('button');
- continueButton.id = 'hid-continue-button';
- continueButton.textContent = loadTimeData.getString(
- 'hidDetectionContinue');
- continueButton.addEventListener('click', function(e) {
- chrome.send('HIDDetectionOnContinue');
- e.stopPropagation();
- });
- buttons.push(continueButton);
-
- return buttons;
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- return $('hid-continue-button');
- },
-
- /**
- * Sets a device-block css class to reflect device state of searching,
- * connected, pairing or paired (for BT devices).
- * @param {blockId} id one of keys of this.BLOCK dict.
- * @param {state} one of keys of this.CONNECTION dict.
- * @private
- */
- setDeviceBlockState_: function(blockId, state) {
- if (state == 'update')
- return;
- var deviceBlock = $(blockId);
- for (var key in this.CONNECTION) {
- var stateCase = this.CONNECTION[key];
- deviceBlock.classList.toggle(stateCase, stateCase == state);
- }
- },
-
- /**
- * Sets state for mouse-block.
- * @param {state} one of keys of this.CONNECTION dict.
- */
- setPointingDeviceState: function(state) {
- if (state === undefined)
- return;
- this.setDeviceBlockState_(this.BLOCK.MOUSE, state);
- },
-
- /**
- * Updates state for pincode key elements based on context state.
- */
- updatePincodeKeysState_: function() {
- var pincodeKeys = $('hid-keyboard-pincode');
- var pincode = this.context.get(CONTEXT_KEY_KEYBOARD_PINCODE, '');
- var state = this.context.get(CONTEXT_KEY_KEYBOARD_STATE, '');
-
- if (!pincode || state !== this.CONNECTION.PAIRING) {
- pincodeKeys.hidden = true;
- return;
- }
-
- if (pincodeKeys.hidden) {
- pincodeKeys.hidden = false;
- announceAccessibleMessage(
- this.context.get(CONTEXT_KEY_KEYBOARD_LABEL, '') + ' ' + pincode +
- ' ' + loadTimeData.getString('hidDetectionBTEnterKey'));
- }
-
- var entered = this.context.get(
- CONTEXT_KEY_KEYBOARD_ENTERED_PART_PINCODE, 0);
-
- // whether the functionality of getting num of entered keys is available.
- var expected = this.context.get(
- CONTEXT_KEY_KEYBOARD_ENTERED_PART_EXPECTED, false);
-
- if (pincode.length != PINCODE_LENGTH)
- console.error('Wrong pincode length');
-
- // Pincode keys plus Enter key.
- for (var i = 0; i < (PINCODE_LENGTH + 1); i++) {
- var pincodeSymbol = $('hid-keyboard-pincode-sym-' + (i + 1));
- pincodeSymbol.classList.toggle('key-typed', i < entered && expected);
- pincodeSymbol.classList.toggle('key-untyped', i > entered && expected);
- pincodeSymbol.classList.toggle('key-next', i == entered && expected);
- if (i < PINCODE_LENGTH)
- pincodeSymbol.textContent = pincode[i] ? pincode[i] : '';
- }
- },
-
- /*
- * Event handler that is invoked just before the screen in shown.
- * @param {Object} data Screen init payload.
- */
- onBeforeShow: function(data) {
- this.setDeviceBlockState_('hid-mouse-block', this.CONNECTION.SEARCHING);
- this.setDeviceBlockState_('hid-keyboard-block',
- this.CONNECTION.SEARCHING);
- },
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.css
deleted file mode 100644
index a5a9a1a8eb4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.css
+++ /dev/null
@@ -1,56 +0,0 @@
-/* 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.
- */
-
-/* TODO(dzhioev): support RTL. http://crbug.com/423354 */
-
-:host {
- -webkit-user-select: none;
- background-color: var(--google-yellow-500);
- color: white;
- display: block;
- font-family: 'Roboto';
- font-weight: 300;
- height: 100%;
-}
-
-neon-animated-pages {
- left: 114px;
- position: absolute;
- right: 0;
- top: 100px;
-}
-
-#illustration {
- background-image: url(chrome://theme/IDR_BUILDINGS_ILLUSTRATION);
- bottom: 95px;
- height: 368px;
- position: absolute;
- right: 95px;
- width: 503px;
-}
-
-#device-indicator {
- bottom: 74px;
- font-size: 33px;
- font-weight: bolder;
- left: 130px;
- position: absolute;
-}
-
-#device-label {
- margin-left: 0.4em;
-}
-
-#code {
- font-family: 'Roboto';
- font-size: 120px;
- font-weight: lighter;
-}
-
-iron-icon {
- height: 48px;
- width: 48px;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.html
deleted file mode 100644
index 0bee2ba7320..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<div class="step hidden no-logo fullscreen" id="host-pairing" hidden>
- <host-pairing-screen name="HostPairingScreen"></host-pairing-screen>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.js
deleted file mode 100644
index 9b62a88e162..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.
-
-/**
- * @fileoverview host pairing screen implementation.
- */
-
-login.createScreen('HostPairingScreen', 'host-pairing', function() {
- /**
- * We can't pass Polymer screen directly to login.createScreen, because it
- * changes object's prototype chain.
- */
- return {
- polymerScreen_: null,
-
- decorate: function() {
- polymerScreen_ = this.children[0];
- polymerScreen_.decorate(this);
- },
-
- onBeforeShow: function() {
- polymerScreen_.onBeforeShow();
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing_page.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing_page.css
deleted file mode 100644
index 70e4e9aa6d9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing_page.css
+++ /dev/null
@@ -1,20 +0,0 @@
-/* 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.
- */
-
-:host {
- display: block;
-}
-
-#title {
- border-bottom: 2px solid rgba(255, 255, 255, 0.2);
- font-size: 45px;
- padding-bottom: 18px;
-}
-
-#content {
- font-size: 24px;
- padding-top: 25px;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.css
deleted file mode 100644
index d68d22646b8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.css
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#connect {
- min-height: 395px;
- padding: 70px 17px 21px;
-}
-
-#connect table {
- margin: 7em auto;
-}
-
-.control-with-label {
- -webkit-box-align: start;
- display: -webkit-box;
- margin: 10px 0;
-}
-
-#welcome-message {
- color: #444;
- font-size: 16px;
- margin-bottom: 30px;
-}
-
-#connect .step-contents {
- margin: 33px auto 82px;
- width: 435px;
-}
-
-.connect-debugging-specific {
- display: none;
-}
-
-.connect-debugging-view .connect-debugging-specific {
- display: block;
-}
-
-html:not([highlight=strong]) #network-timezone-setting {
- display: none;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.html
deleted file mode 100644
index ffa420c28d2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<div class="step hidden animated" id="connect" role="group" hidden>
- <div class="step-contents">
- <div id="welcome-message" i18n-content="networkScreenGreeting">
- </div>
- <div class="control-with-label">
- <label for="language-select" i18n-content="selectLanguage"
- class="label"></label>
- <div class="menu-area">
- <select id="language-select" class="menu-control"></select>
- </div>
- </div>
- <div class="control-with-label">
- <label for="keyboard-select" i18n-content="selectKeyboard"
- class="label"></label>
- <div class="menu-area">
- <select id="keyboard-select" class="menu-control"></select>
- </div>
- </div>
- <div class="control-with-label" id="network-timezone-setting">
- <label for="timezone-select" i18n-content="selectTimezone"
- class="label"></label>
- <div class="menu-area">
- <select id="timezone-select" class="menu-control"></select>
- </div>
- </div>
- <div class="control-with-label">
- <label for="networks-list-dropdown" i18n-content="selectNetwork"
- class="label"></label>
- <div class="menu-area">
- <div id="networks-list" class="menu-control"></div>
- </div>
- </div>
- </div>
- <div id="connect-controls" class="step-controls"></div>
- <div id="connect-extra-controls" class="step-extra-controls">
- <div id="connect-accessibility">
- <a id="connect-accessibility-link" href="#" role="button"
- i18n-content="accessibilityLink"></a>
- </div>
- <div class="connect-debugging-specific">
- <a id="connect-debugging-features-link" href="#" role="button"
- i18n-content="debuggingFeaturesLink"></a>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.js
deleted file mode 100644
index bba9c388247..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_network.js
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe network screen implementation.
- */
-
-login.createScreen('NetworkScreen', 'connect', function() {
- var USER_ACTION_CONTINUE_BUTTON_CLICKED = 'continue';
- var USER_ACTION_CONNECT_DEBUGGING_FEATURES_CLICKED =
- 'connect-debugging-features';
- var CONTEXT_KEY_LOCALE = 'locale';
- var CONTEXT_KEY_INPUT_METHOD = 'input-method';
- var CONTEXT_KEY_TIMEZONE = 'timezone';
- var CONTEXT_KEY_CONTINUE_BUTTON_ENABLED = 'continue-button-enabled';
-
- return {
- EXTERNAL_API: [
- 'showError'
- ],
-
- /**
- * Dropdown element for networks selection.
- */
- dropdown_: null,
-
- /** @override */
- decorate: function() {
- var self = this;
-
- Oobe.setupSelect($('language-select'),
- loadTimeData.getValue('languageList'),
- function(languageId) {
- self.context.set(CONTEXT_KEY_LOCALE, languageId);
- self.commitContextChanges();
- });
- Oobe.setupSelect($('keyboard-select'),
- loadTimeData.getValue('inputMethodsList'),
- function(inputMethodId) {
- self.context.set(CONTEXT_KEY_INPUT_METHOD,
- inputMethodId);
- self.commitContextChanges();
- });
- Oobe.setupSelect($('timezone-select'),
- loadTimeData.getValue('timezoneList'),
- function(timezoneId) {
- self.context.set(CONTEXT_KEY_TIMEZONE, timezoneId);
- self.commitContextChanges();
- });
-
- this.dropdown_ = $('networks-list');
- cr.ui.DropDown.decorate(this.dropdown_);
-
- this.declareUserAction(
- $('connect-debugging-features-link'),
- { action_id: USER_ACTION_CONNECT_DEBUGGING_FEATURES_CLICKED,
- event: 'click'
- });
- this.declareUserAction(
- $('connect-debugging-features-link'),
- { action_id: USER_ACTION_CONNECT_DEBUGGING_FEATURES_CLICKED,
- condition: function(event) { return event.keyCode == 32; },
- event: 'keyup'
- });
-
- this.context.addObserver(
- CONTEXT_KEY_INPUT_METHOD,
- function(inputMethodId) {
- option = $('keyboard-select').querySelector(
- 'option[value="' + inputMethodId + '"]');
- if (option)
- option.selected = true;
- });
- this.context.addObserver(CONTEXT_KEY_TIMEZONE, function(timezoneId) {
- $('timezone-select').value = timezoneId;
- });
- this.context.addObserver(CONTEXT_KEY_CONTINUE_BUTTON_ENABLED,
- function(enabled) {
- $('continue-button').disabled = !enabled;
- });
- },
-
- onBeforeShow: function(data) {
- cr.ui.DropDown.show('networks-list', true, -1);
- this.classList.toggle('connect-debugging-view',
- data && 'isDeveloperMode' in data && data['isDeveloperMode']);
- },
-
- onBeforeHide: function() {
- cr.ui.DropDown.hide('networks-list');
- },
-
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('networkScreenTitle');
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
-
- var continueButton = this.declareButton(
- 'continue-button',
- USER_ACTION_CONTINUE_BUTTON_CLICKED);
- continueButton.disabled = !this.context.get(
- CONTEXT_KEY_CONTINUE_BUTTON_ENABLED, false /* default */);
- continueButton.textContent = loadTimeData.getString('continueButton');
- continueButton.classList.add('preserve-disabled-state');
- buttons.push(continueButton);
-
- return buttons;
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- return $('language-select');
- },
-
- /**
- * Shows the network error message.
- * @param {string} message Message to be shown.
- */
- showError: function(message) {
- var error = document.createElement('div');
- var messageDiv = document.createElement('div');
- messageDiv.className = 'error-message-bubble';
- messageDiv.textContent = message;
- error.appendChild(messageDiv);
- error.setAttribute('role', 'alert');
-
- $('bubble').showContentForElement($('networks-list'),
- cr.ui.Bubble.Attachment.BOTTOM,
- error);
- }
- };
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css
deleted file mode 100644
index 57cd66a8596..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css
+++ /dev/null
@@ -1,180 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#oauth-enrollment {
- height: 528px;
- padding: 0;
- width: 448px;
-}
-
-#oauth-enrollment.saml {
- padding-top: 47px;
- width: 562px;
-}
-
-#oauth-enroll-step-contents {
- color: #666;
- height: 100%;
- width: 100%;
-}
-
-#oauth-enroll-step-contents > div {
- display: none;
-}
-
-.oauth-enroll-state-error #oauth-enroll-step-error,
-.oauth-enroll-state-success #oauth-enroll-step-success {
- display: table;
- height: 480px;
- margin: 0 auto;
-}
-
-.oauth-enroll-state-working #oauth-enroll-step-signin,
-.oauth-enroll-state-attribute-prompt-error
- #oauth-enroll-step-attribute-prompt-error,
-.oauth-enroll-state-signin #oauth-enroll-step-signin,
-.oauth-enroll-state-attribute-prompt
- #oauth-enroll-step-attribute-prompt {
- display: block;
- height: 100%;
- width: 100%;
-}
-
-#oauth-enroll-auth-view-container,
-#oauth-enroll-auth-view {
- display: block;
- height: 100%;
- overflow: hidden;
- padding: 0;
- width: 100%;
-}
-
-#oauth-enrollment.mode-manual #oauth-enroll-learn-more-link,
-#oauth-enrollment.mode-forced #oauth-enroll-learn-more-link,
-#oauth-enrollment.mode-recovery #oauth-enroll-learn-more-link {
- display: inline;
-}
-
-.oauth-enroll-step-content {
- display: table-cell;
- vertical-align: middle;
-}
-
-.oauth-enroll-step-message {
- display: inline-block;
- max-width: 400px;
- text-align: left;
- vertical-align: top;
-}
-
-.oauth-enroll-link {
- color: rgb(17, 85, 204);
- cursor: pointer;
- text-decoration: none;
-}
-
-.oauth-enroll-button {
- display: none;
-}
-
-#oauth-enroll-back-button,
-#oauth-enrollment.saml #oauth-enroll-back-button {
- display: none;
-}
-
-.oauth-enroll-state-signin #oauth-enroll-back-button {
- display: inline;
-}
-
-.oauth-enroll-state-signin.mode-manual #oauth-enroll-cancel-button,
-.oauth-enroll-state-signin.mode-forced #oauth-enroll-refresh-button,
-.oauth-enroll-state-signin.mode-recovery #oauth-enroll-refresh-button,
-.oauth-enroll-state-working.mode-manual #oauth-enroll-cancel-button,
-.oauth-enroll-state-working.mode-forced #oauth-enroll-refresh-button,
-.oauth-enroll-state-working.mode-recovery #oauth-enroll-refresh-button,
-.oauth-enroll-state-error.mode-manual #oauth-enroll-cancel-button,
-.oauth-enroll-state-error.mode-manual #oauth-enroll-done-button,
-.oauth-enroll-state-success #oauth-enroll-done-button {
- display: inline;
-}
-
-#oobe.oauth-enrollment #header-oauth-enrollment {
- display: block;
-}
-
-#oauth-saml-notice-container {
- -webkit-margin-start: 19px;
- left: 0;
- position: absolute;
- right: 0;
- text-align: start;
- top: 15px;
-}
-
-#oauth-enrollment.saml #oauth-enrollment-controls,
-#oauth-enrollment.saml #oauth-enroll-signin-link-container {
- -webkit-padding-end: 17px;
-}
-
-#oauth-enrollment:not(.saml) #oauth-saml-notice-container {
- display: none;
-}
-
-#oauth-saml-notice-message {
- color: rgb(106, 106, 106);
- font-size: 13px;
- margin: 0 auto;
-}
-
-#oauth-enroll-cancel-button,
-#oauth-enroll-back-button,
-#oauth-enroll-refresh-button {
- position: absolute;
- top: 10px;
- z-index: 1;
-}
-
-#oauth-enroll-cancel-button,
-#oauth-enroll-refresh-button {
- color: rgba(0, 0, 0, .54);
- right: 10px;
-}
-
-html[dir=rtl] #oauth-enroll-cancel-button,
-html[dir=rtl] #oauth-enroll-refresh-button {
- left: 10px;
- right: auto;
-}
-
-#oauth-enrollment.saml #oauth-enroll-cancel-button,
-#oauth-enrollment.saml #oauth-enroll-refresh-button {
- color: rgba(0, 0, 0, .54);
-}
-
-.oauth-enroll-state-signin #oauth-enroll-cancel-button,
-.oauth-enroll-state-working #oauth-enroll-cancel-button,
-.oauth-enroll-state-signin #oauth-enroll-refresh-button,
-.oauth-enroll-state-working #oauth-enroll-refresh-button {
- color: white;
-}
-
-#oauth-enroll-back-button {
- color: white;
- left: 10px;
-}
-
-html[dir=rtl] #oauth-enroll-back-button {
- -webkit-transform: scaleX(-1);
- left: auto;
- right: 10px;
-}
-
-#oauth-enroll-attribute-prompt-message {
- color: black;
-}
-
-#oauth-enroll-attribute-input {
- padding-top: 24px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html
deleted file mode 100644
index 9b4d8aabb8c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-
-<div id="oauth-enrollment" class="step no-logo hidden" hidden>
- <div id="oauth-enroll-step-contents">
- <div id="oauth-enroll-step-signin">
- <div id="oauth-enroll-auth-view-container"></div>
- </div>
- <div id="oauth-enroll-step-error" role="alert">
- <notification-card id="oauth-enroll-error-card" type="fail"
- i18n-values="button-label:oauthEnrollRetry">
- </notification-card>
- </div>
- <div id="oauth-enroll-step-success" role="alert">
- <notification-card id="oauth-enroll-success-card" type="success"
- i18n-values="button-label:oauthEnrollDone"
- i18n-content="oauthEnrollSuccess">
- </notification-card>
- </div>
- <div id="oauth-enroll-step-attribute-prompt">
- <gaia-card id="oauth-enroll-attribute-prompt-card" class="fit">
- <div class="header flex vertical layout end-justified">
- <h1 class="welcome-message" style="text-transform:capitalize"
- i18n-content="oauthEnrollScreenTitle"></h1>
- <p class="enterprise-info"
- i18n-content="oauthEnrollDeviceInformation"></p>
- </div>
- <div class="footer flex vertical layout justified">
- <div class="oauth-enroll-step-message">
- <span id="oauth-enroll-attribute-prompt-message"
- i18n-content="oauthEnrollAttributeExplanation"></span>
- <a href="#" id="oauth-enroll-learn-more-link"
- class="oauth-enroll-link"
- i18n-content="oauthEnrollExplaneAttributeLink"></a>
- <gaia-input-form id="oauth-enroll-attribute-input"
- i18n-values="button-text:oauthEnrollNextBtn">
- <gaia-input id="oauth-enroll-asset-id" type="text"
- i18n-values="label:oauthEnrollAssetIdLabel">
- </gaia-input>
- <gaia-input id="oauth-enroll-location" type="text"
- i18n-values="label:oauthEnrollLocationLabel">
- </gaia-input>
- <gaia-button type="link" id="oauth-enroll-skip-button"
- i18n-content="oauthEnrollSkip">
- </gaia-button>
- </gaia-input-form>
- </div>
- </div>
- </gaia-card>
- </div>
- <div id="oauth-enroll-step-attribute-prompt-error">
- <notification-card id="oauth-enroll-attribute-prompt-error-card"
- type="fail" i18n-values="button-label:oauthEnrollDone">
- </notification-card>
- </div>
- </div>
- <div id="oauth-saml-notice-container">
- <span id="oauth-saml-notice-message"></span>
- </div>
- <div id="oauth-enrollment-controls" class="step-controls"></div>
- <gaia-icon-button id="oauth-enroll-back-button" icon="arrow-back" hidden
- i18n-values="aria-label:backButton">
- </gaia-icon-button>
- <gaia-icon-button id="oauth-enroll-cancel-button" icon="close"
- class="oauth-enroll-button" i18n-values="aria-label:closeButton">
- </gaia-icon-button>
- <gaia-icon-button id="oauth-enroll-refresh-button" icon="refresh"
- class="oauth-enroll-button" i18n-values="aria-label:closeButton">
- </gaia-icon-button>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
deleted file mode 100644
index 8b33b6cb6a3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-login.createScreen('OAuthEnrollmentScreen', 'oauth-enrollment', function() {
- /** @const */ var STEP_SIGNIN = 'signin';
- /** @const */ var STEP_WORKING = 'working';
- /** @const */ var STEP_ATTRIBUTE_PROMPT = 'attribute-prompt';
- /** @const */ var STEP_ERROR = 'error';
- /** @const */ var STEP_SUCCESS = 'success';
-
- /* TODO(dzhioev): define this step on C++ side.
- /** @const */ var STEP_ATTRIBUTE_PROMPT_ERROR = 'attribute-prompt-error';
-
- /** @const */ var HELP_TOPIC_ENROLLMENT = 4631259;
-
- return {
- EXTERNAL_API: [
- 'showStep',
- 'showError',
- 'doReload',
- 'showAttributePromptStep',
- ],
-
- /**
- * Authenticator object that wraps GAIA webview.
- */
- authenticator_: null,
-
- /**
- * The current step. This is the last value passed to showStep().
- */
- currentStep_: null,
-
- /**
- * We block esc, back button and cancel button until gaia is loaded to
- * prevent multiple cancel events.
- */
- isCancelDisabled_: null,
-
- get isCancelDisabled() { return this.isCancelDisabled_ },
- set isCancelDisabled(disabled) {
- if (disabled == this.isCancelDisabled)
- return;
- this.isCancelDisabled_ = disabled;
- },
-
- /** @override */
- decorate: function() {
- var webview = document.createElement('webview');
- webview.id = webview.name = 'oauth-enroll-auth-view';
- $('oauth-enroll-auth-view-container').appendChild(webview);
- this.authenticator_ = new cr.login.Authenticator(webview);
-
- this.authenticator_.addEventListener('ready',
- (function() {
- if (this.currentStep_ != STEP_SIGNIN)
- return;
- this.isCancelDisabled = false;
- chrome.send('frameLoadingCompleted', [0]);
- }).bind(this));
-
- this.authenticator_.addEventListener('authCompleted',
- (function(e) {
- var detail = e.detail;
- if (!detail.email || !detail.authCode) {
- this.showError(
- loadTimeData.getString('fatalEnrollmentError'),
- false);
- return;
- }
- chrome.send('oauthEnrollCompleteLogin', [detail.email,
- detail.authCode]);
- }).bind(this));
-
- this.authenticator_.addEventListener('authFlowChange',
- (function(e) {
- var isSAML = this.authenticator_.authFlow ==
- cr.login.Authenticator.AuthFlow.SAML;
- if (isSAML) {
- $('oauth-saml-notice-message').textContent =
- loadTimeData.getStringF('samlNotice',
- this.authenticator_.authDomain);
- }
- this.classList.toggle('saml', isSAML);
- if (Oobe.getInstance().currentScreen == this)
- Oobe.getInstance().updateScreenSize(this);
- }).bind(this));
-
- this.authenticator_.addEventListener('backButton',
- (function(e) {
- $('oauth-enroll-back-button').hidden = !e.detail;
- $('oauth-enroll-auth-view').focus();
- $('login-header-bar').updateUI_();
- }).bind(this));
-
- this.authenticator_.insecureContentBlockedCallback =
- (function(url) {
- this.showError(
- loadTimeData.getStringF('insecureURLEnrollmentError', url),
- false);
- }).bind(this);
-
- this.authenticator_.missingGaiaInfoCallback =
- (function() {
- this.showError(
- loadTimeData.getString('fatalEnrollmentError'),
- false);
- }).bind(this);
-
- $('oauth-enroll-error-card').addEventListener('buttonclick',
- this.doRetry_.bind(this));
- function doneCallback() {
- chrome.send('oauthEnrollClose', ['done']);
- };
-
- $('oauth-enroll-attribute-prompt-error-card').addEventListener(
- 'buttonclick', doneCallback);
- $('oauth-enroll-success-card').addEventListener(
- 'buttonclick', doneCallback);
-
- $('oauth-enroll-cancel-button').addEventListener('click',
- this.cancel.bind(this));
- $('oauth-enroll-refresh-button').addEventListener('click',
- this.cancel.bind(this));
-
- $('oauth-enroll-back-button').addEventListener('click',
- (function(e) {
- $('oauth-enroll-back-button').hidden = true;
- $('oauth-enroll-auth-view').back();
- e.preventDefault();
- }).bind(this));
-
- $('oauth-enroll-attribute-prompt-card').addEventListener('submit',
- this.onAttributesSubmitted.bind(this));
-
- $('oauth-enroll-learn-more-link').addEventListener('click',
- function(event) {
- chrome.send('oauthEnrollOnLearnMore');
- });
-
- $('oauth-enroll-skip-button').addEventListener('click',
- this.onSkipButtonClicked.bind(this));
- },
-
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('oauthEnrollScreenTitle');
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
- var ownerDocument = this.ownerDocument;
-
- function makeButton(id, classes, label, handler) {
- var button = ownerDocument.createElement('button');
- button.id = id;
- button.classList.add('oauth-enroll-button');
- button.classList.add.apply(button.classList, classes);
- button.textContent = label;
- button.addEventListener('click', handler);
- buttons.push(button);
- }
-
- return buttons;
- },
-
- /**
- * Event handler that is invoked just before the frame is shown.
- * @param {Object} data Screen init payload, contains the signin frame
- * URL.
- */
- onBeforeShow: function(data) {
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.ENROLLMENT;
- $('inner-container').classList.add('new-gaia-flow');
- var gaiaParams = {};
- gaiaParams.gaiaUrl = data.gaiaUrl;
- gaiaParams.clientId = data.clientId;
- gaiaParams.gaiaPath = 'embedded/setup/chromeos';
- gaiaParams.isNewGaiaFlowChromeOS = true;
- gaiaParams.needPassword = false;
- if (data.management_domain) {
- gaiaParams.enterpriseDomain = data.management_domain;
- gaiaParams.emailDomain = data.management_domain;
- }
- gaiaParams.flow = data.flow;
- this.authenticator_.load(cr.login.Authenticator.AuthMode.DEFAULT,
- gaiaParams);
-
- var modes = ['manual', 'forced', 'recovery'];
- for (var i = 0; i < modes.length; ++i) {
- this.classList.toggle('mode-' + modes[i],
- data.enrollment_mode == modes[i]);
- }
- this.isCancelDisabled = true;
- this.showStep(STEP_SIGNIN);
- },
-
- onBeforeHide: function() {
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
- },
-
- /**
- * Shows attribute-prompt step with pre-filled asset ID and
- * location.
- */
- showAttributePromptStep: function(annotated_asset_id, annotated_location) {
- $('oauth-enroll-asset-id').value = annotated_asset_id;
- $('oauth-enroll-location').value = annotated_location;
- $('oauth-enroll-back-button').hidden = true;
-
- this.showStep(STEP_ATTRIBUTE_PROMPT);
- },
-
- /**
- * Cancels enrollment and drops the user back to the login screen.
- */
- cancel: function() {
- if (this.isCancelDisabled)
- return;
- this.isCancelDisabled = true;
- chrome.send('oauthEnrollClose', ['cancel']);
- },
-
- /**
- * Switches between the different steps in the enrollment flow.
- * @param {string} step the steps to show, one of "signin", "working",
- * "attribute-prompt", "error", "success".
- */
- showStep: function(step) {
- this.classList.toggle('oauth-enroll-state-' + this.currentStep_, false);
- this.classList.toggle('oauth-enroll-state-' + step, true);
-
- if (step == STEP_SIGNIN) {
- $('oauth-enroll-auth-view').focus();
- } else if (step == STEP_ERROR) {
- $('oauth-enroll-error-card').submitButton.focus();
- } else if (step == STEP_SUCCESS) {
- $('oauth-enroll-success-card').submitButton.focus();
- } else if (step == STEP_ATTRIBUTE_PROMPT) {
- $('oauth-enroll-asset-id').focus();
- } else if (step == STEP_ATTRIBUTE_PROMPT_ERROR) {
- $('oauth-enroll-attribute-prompt-error-card').submitButton.focus();
- }
- this.currentStep_ = step;
- },
-
- /**
- * Sets an error message and switches to the error screen.
- * @param {string} message the error message.
- * @param {boolean} retry whether the retry link should be shown.
- */
- showError: function(message, retry) {
- if (this.currentStep_ == STEP_ATTRIBUTE_PROMPT) {
- $('oauth-enroll-attribute-prompt-error-card').textContent = message;
- this.showStep(STEP_ATTRIBUTE_PROMPT_ERROR);
- return;
- }
- $('oauth-enroll-error-card').textContent = message;
- $('oauth-enroll-error-card').buttonLabel =
- retry ? loadTimeData.getString('oauthEnrollRetry') : '';
- this.showStep(STEP_ERROR);
- },
-
- doReload: function() {
- this.authenticator_.reload();
- },
-
- /**
- * Retries the enrollment process after an error occurred in a previous
- * attempt. This goes to the C++ side through |chrome| first to clean up the
- * profile, so that the next attempt is performed with a clean state.
- */
- doRetry_: function() {
- chrome.send('oauthEnrollRetry');
- },
-
- /**
- * Skips the device attribute update,
- * shows the successful enrollment step.
- */
- onSkipButtonClicked: function() {
- this.showStep(STEP_SUCCESS);
- },
-
- /**
- * Uploads the device attributes to server. This goes to C++ side through
- * |chrome| and launches the device attribute update negotiation.
- */
- onAttributesSubmitted: function() {
- chrome.send('oauthEnrollAttributes',
- [$('oauth-enroll-asset-id').value,
- $('oauth-enroll-location').value]);
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.css
deleted file mode 100644
index abe034b9c84..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.css
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#reset {
- display: flex;
- flex-flow: column;
- font-size: 16px;
- min-height: 423px;
- padding: 40px 17px 80px;
- text-align: center;
- width: 722px;
-}
-
-#reset #reset-controls {
- bottom: 40px;
- justify-content: center;
- margin-top: auto;
-}
-
-#reset-controls button {
- margin: 0 10px;
-}
-
-#reset #reset-warning-icon {
- height: 112px;
-}
-
-#reset #reset-warning-msg,
-#reset #powerwash-warning-msg,
-#reset #powerwash-and-rollback-warning-msg {
- color: #606060;
- font-size: 22px;
- padding: 5px 45px 30px;
-}
-
-.reset-text {
- color: #606060;
-}
-
-#reset #reset-warning-details,
-#reset #reset-revert-promise-msg {
- padding: 20px 40px 0;
-}
-
-#reset #reset-warning-restart {
- padding: 30px 40px 0;
-}
-
-#reset #rollback {
- padding: 30px 40px 10px;
-}
-
-#reset #reset-revert-spinner-message {
- display: inline-block;
- padding: 25px 0;
- vertical-align: middle;
-}
-
-#reset #reset-revert-spinner {
- margin-top: 0;
- vertical-align: middle;
-}
-
-.powerwash-proposal-specific,
-.rollback-proposal-specific,
-.revert-promise-specific,
-.restart-required-specific {
- display: none;
-}
-
-.powerwash-proposal-view .powerwash-proposal-specific,
-.rollback-proposal-view .rollback-proposal-specific,
-.restart-required-view .restart-required-specific,
-.revert-promise-view .revert-promise-specific {
- display: block;
-}
-
-#reset-restart-button,
-#reset-button,
-#reset-toconfirm-button,
-#reset-cancel-button,
-.revert-promise-view #reset-controls {
- display: none;
-}
-
-.restart-required-view #reset-restart-button,
-.powerwash-proposal-view #reset-toconfirm-button,
-.rollback-proposal-view #reset-toconfirm-button,
-.restart-required-view #reset-cancel-button,
-.powerwash-proposal-view #reset-cancel-button,
-.rollback-proposal-view #reset-cancel-button {
- display: inline-block;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.html
deleted file mode 100644
index 52666c554e5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<div class="step faded hidden no-logo" id="reset" role="group" hidden
- i18n-values="aria-label:resetScreenAccessibleTitle">
- <div class="step-contents">
- <div id="reset-warning-msg" i18n-content="resetWarningTitle"
- class="revert-promise-specific restart-required-specific
- powerwash-proposal-specific rollback-proposal-specific">
- </div>
- <img id="reset-warning-icon" src="chrome://theme/IDR_RESET_WARNING"
- i18n-values="alt:resetScreenIconTitle">
- <div id="reset-info"
- class="reset-text powerwash-proposal-specific rollback-proposal-specific
- restart-required-specific">
- <div id="powerwash-warning-details"
- i18n-content="resetPowerwashWarningDetails"
- class="powerwash-proposal-specific">
- </div>
- <div id="rollback-warning-details"
- i18n-content="resetPowerwashRollbackWarningDetails"
- class="rollback-proposal-specific">
- </div>
- <div id="reset-warning-data-details"
- class="reset-text powerwash-proposal-specific
- rollback-proposal-specific"
- i18n-content="resetWarningDataDetails">
- </div>
- <div id="reset-warning-restart" i18n-content="resetRestartMessage"
- class="reset-text restart-required-specific">
- </div>
- <a id="powerwash-help-link" href="#" i18n-content="learnMore"></a>
- </div>
- <div id="revert-promise" class="revert-promise-specific">
- <div id="reset-revert-promise-msg" i18n-content="resetRevertPromise">
- </div>
- <div id="reset-revert-spinner" class="throbber">
- </div>
- <div id="reset-revert-spinner-message" class="reset-text"
- i18n-content="resetRevertSpinnerMessage">
- </div>
- </div>
- </div>
- <div id="reset-controls" class="step-controls"></div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.js
deleted file mode 100644
index 874f8e3165f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset.js
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Device reset screen implementation.
- */
-
-login.createScreen('ResetScreen', 'reset', function() {
- var USER_ACTION_CANCEL_RESET = 'cancel-reset';
- var USER_ACTION_RESTART_PRESSED = 'restart-pressed';
- var USER_ACTION_LEARN_MORE_PRESSED = 'learn-more-link';
- var USER_ACTION_SHOW_CONFIRMATION = 'show-confirmation';
- var USER_ACTION_POWERWASH_PRESSED = 'powerwash-pressed';
- var USER_ACTION_RESET_CONFIRM_DISMISSED = 'reset-confirm-dismissed';
- var CONTEXT_KEY_ROLLBACK_AVAILABLE = 'rollback-available';
- var CONTEXT_KEY_ROLLBACK_CHECKED = 'rollback-checked';
- var CONTEXT_KEY_IS_OFFICIAL_BUILD = 'is-official-build';
- var CONTEXT_KEY_IS_CONFIRMATIONAL_VIEW = 'is-confirmational-view';
- var CONTEXT_KEY_SCREEN_STATE = 'screen-state';
-
- return {
-
- /* Possible UI states of the reset screen. */
- RESET_SCREEN_UI_STATE: {
- REVERT_PROMISE: 'ui-state-revert-promise',
- RESTART_REQUIRED: 'ui-state-restart-required',
- POWERWASH_PROPOSAL: 'ui-state-powerwash-proposal',
- ROLLBACK_PROPOSAL: 'ui-state-rollback-proposal',
- ERROR: 'ui-state-error',
- },
-
- RESET_SCREEN_STATE: {
- RESTART_REQUIRED: 0,
- REVERT_PROMISE: 1,
- POWERWASH_PROPOSAL: 2, // supports 2 ui-states
- ERROR: 3,
- },
-
-
- /** @override */
- decorate: function() {
- var self = this;
-
- this.declareUserAction($('powerwash-help-link'),
- { action_id: USER_ACTION_LEARN_MORE_PRESSED,
- event: 'click'
- });
- this.declareUserAction($('reset-confirm-dismiss'),
- { action_id: USER_ACTION_RESET_CONFIRM_DISMISSED,
- event: 'click'
- });
- this.declareUserAction($('reset-confirm-commit'),
- { action_id: USER_ACTION_POWERWASH_PRESSED,
- event: 'click'
- });
-
- this.context.addObserver(
- CONTEXT_KEY_SCREEN_STATE,
- function(state) {
- if (state == self.RESET_SCREEN_STATE.RESTART_REQUIRED)
- self.ui_state = self.RESET_SCREEN_UI_STATE.RESTART_REQUIRED;
- if (state == self.RESET_SCREEN_STATE.REVERT_PROMISE)
- self.ui_state = self.RESET_SCREEN_UI_STATE.REVERT_PROMISE;
- else if (state == self.RESET_SCREEN_STATE.POWERWASH_PROPOSAL)
- self.ui_state = self.RESET_SCREEN_UI_STATE.POWERWASH_PROPOSAL;
- self.setDialogView_();
- if (state == self.RESET_SCREEN_STATE.REVERT_PROMISE) {
- announceAccessibleMessage(
- loadTimeData.getString('resetRevertSpinnerMessage'));
- }
- }
- );
-
- this.context.addObserver(
- CONTEXT_KEY_IS_OFFICIAL_BUILD,
- function(isOfficial) {
- $('powerwash-help-link').setAttribute('hidden', !isOfficial);
- }
- );
- this.context.addObserver(
- CONTEXT_KEY_ROLLBACK_CHECKED,
- function(rollbackChecked) {
- self.setRollbackOptionView();
- }
- );
- this.context.addObserver(
- CONTEXT_KEY_ROLLBACK_AVAILABLE,
- function(rollbackAvailable) {
- self.setRollbackOptionView();
- }
- );
- this.context.addObserver(
- CONTEXT_KEY_IS_CONFIRMATIONAL_VIEW,
- function(is_confirmational) {
- if (is_confirmational) {
- console.log(self.context.get(CONTEXT_KEY_SCREEN_STATE, 0));
- if (self.context.get(CONTEXT_KEY_SCREEN_STATE, 0) !=
- self.RESET_SCREEN_STATE.POWERWASH_PROPOSAL)
- return;
- console.log(self);
- reset.ConfirmResetOverlay.getInstance().initializePage();
- } else {
- $('overlay-reset').setAttribute('hidden', true);
- }
- }
- );
- },
-
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('resetScreenTitle');
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
- var restartButton = this.ownerDocument.createElement('button');
- restartButton.id = 'reset-restart-button';
- restartButton.textContent = loadTimeData.getString('resetButtonRestart');
- this.declareUserAction(restartButton,
- { action_id: USER_ACTION_RESTART_PRESSED,
- event: 'click'
- });
- buttons.push(restartButton);
-
- // Button that leads to confirmation pop-up dialog.
- var toConfirmButton = this.ownerDocument.createElement('button');
- toConfirmButton.id = 'reset-toconfirm-button';
- toConfirmButton.textContent =
- loadTimeData.getString('resetButtonPowerwash');
- this.declareUserAction(toConfirmButton,
- { action_id: USER_ACTION_SHOW_CONFIRMATION,
- event: 'click'
- });
- buttons.push(toConfirmButton);
-
- var cancelButton = this.ownerDocument.createElement('button');
- cancelButton.id = 'reset-cancel-button';
- cancelButton.textContent = loadTimeData.getString('cancelButton');
- this.declareUserAction(cancelButton,
- { action_id: USER_ACTION_CANCEL_RESET,
- event: 'click'
- });
- buttons.push(cancelButton);
-
- return buttons;
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- // choose
- if (this.context.get(CONTEXT_KEY_SCREEN_STATE,
- this.RESET_SCREEN_STATE.RESTART_REQUIRED) ==
- this.RESET_SCREEN_STATE.RESTART_REQUIRED)
- return $('reset-restart-button');
- if (this.context.get(CONTEXT_KEY_IS_CONFIRMATIONAL_VIEW, false))
- return $('reset-confirm-commit');
- return $('reset-toconfirm-button');
- },
-
- /**
- * Cancels the reset and drops the user back to the login screen.
- */
- cancel: function() {
- if (this.context.get(CONTEXT_KEY_IS_CONFIRMATIONAL_VIEW, false)) {
- $('reset').send(login.Screen.CALLBACK_USER_ACTED,
- USER_ACTION_RESET_CONFIRM_DISMISSED);
- return;
- }
- this.send(login.Screen.CALLBACK_USER_ACTED, USER_ACTION_CANCEL_RESET);
- },
-
- /**
- * Event handler that is invoked just before the screen in shown.
- * @param {Object} data Screen init payload.
- */
- onBeforeShow: function(data) {
- },
-
- /**
- * Sets css style for corresponding state of the screen.
- * @private
- */
- setDialogView_: function(state) {
- state = this.ui_state;
- var resetOverlay = $('reset-confirm-overlay');
- this.classList.toggle(
- 'revert-promise-view',
- state == this.RESET_SCREEN_UI_STATE.REVERT_PROMISE);
- this.classList.toggle(
- 'restart-required-view',
- state == this.RESET_SCREEN_UI_STATE.RESTART_REQUIRED);
- this.classList.toggle(
- 'powerwash-proposal-view',
- state == this.RESET_SCREEN_UI_STATE.POWERWASH_PROPOSAL);
- resetOverlay.classList.toggle(
- 'powerwash-proposal-view',
- state == this.RESET_SCREEN_UI_STATE.POWERWASH_PROPOSAL);
- this.classList.toggle(
- 'rollback-proposal-view',
- state == this.RESET_SCREEN_UI_STATE.ROLLBACK_PROPOSAL);
- resetOverlay.classList.toggle(
- 'rollback-proposal-view',
- state == this.RESET_SCREEN_UI_STATE.ROLLBACK_PROPOSAL);
- },
-
- setRollbackOptionView: function() {
- if (this.context.get(CONTEXT_KEY_IS_CONFIRMATIONAL_VIEW, false))
- return;
- if (this.context.get(CONTEXT_KEY_SCREEN_STATE) !=
- this.RESET_SCREEN_STATE.POWERWASH_PROPOSAL)
- return;
-
- if (this.context.get(CONTEXT_KEY_ROLLBACK_AVAILABLE, false) &&
- this.context.get(CONTEXT_KEY_ROLLBACK_CHECKED, false)) {
- // show rollback option
- $('reset-toconfirm-button').textContent = loadTimeData.getString(
- 'resetButtonPowerwashAndRollback');
- this.ui_state = this.RESET_SCREEN_UI_STATE.ROLLBACK_PROPOSAL;
- } else {
- // hide rollback option
- $('reset-toconfirm-button').textContent = loadTimeData.getString(
- 'resetButtonPowerwash');
- this.ui_state = this.RESET_SCREEN_UI_STATE.POWERWASH_PROPOSAL;
- }
- this.setDialogView_();
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.css
deleted file mode 100644
index af8e05aa8d4..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/* 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. */
-
-#reset-confirm-overlay {
- font-size: 16px;
- margin: auto;
- min-height: 250px;
- width: 400px;
-}
-
-#reset-confirm-overlay .button-strip {
- display: flex;
- justify-content: center;
- padding-bottom: 20px;
-}
-
-#reset-confirm-overlay .button-strip button {
- /*-webkit-margin-start: 9px;*/
- margin: 0 10px;
-} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.html
deleted file mode 100644
index 956b6288c70..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<div id="overlay-reset" class="popup-overlay" hidden>
-<div id="reset-confirm-overlay" class="oobe-popup not-resizable">
- <h1 i18n-content="confirmPowerwashTitle" class="powerwash-proposal-specific">
- </h1>
- <h1 i18n-content="confirmRollbackTitle" class="rollback-proposal-specific">
- </h1>
- <div class="popup-content-area">
- <div id="reset-confirm-info"
- class="content-area reset-text">
- <div id="powerwash-confirm-message"
- i18n-content="confirmPowerwashMessage"
- class="powerwash-proposal-specific">
- </div>
- <div id="rollback-confirm-message"
- i18n-content="confirmRollbackMessage"
- class="rollback-proposal-specific">
- </div>
- </div>
- </div>
- <div id="reset-buttons" class="button-strip">
- <button id="reset-confirm-commit" i18n-content="confirmResetButton">
- </button>
- <button id="reset-confirm-dismiss" i18n-content="cancel"></button>
- </div>
-</div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.js
deleted file mode 100644
index b1f3288d2ec..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_reset_confirmation_overlay.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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('reset', function() {
-
- var USER_ACTION_RESET_CONFIRM_DISMISSED = 'reset-confirm-dismissed';
- /**
- * ResetScreenConfirmationOverlay class
- * Encapsulated handling of the 'Confirm reset device' overlay OOBE page.
- * @class
- */
- function ConfirmResetOverlay() {
- }
-
- cr.addSingletonGetter(ConfirmResetOverlay);
-
- ConfirmResetOverlay.prototype = {
- /**
- * Initialize the page.
- */
- initializePage: function() {
- var overlay = $('reset-confirm-overlay');
- overlay.addEventListener('cancelOverlay', function(e) {
- $('reset').send(login.Screen.CALLBACK_USER_ACTED,
- USER_ACTION_RESET_CONFIRM_DISMISSED);
- e.stopPropagation();
- });
- $('overlay-reset').removeAttribute('hidden');
- },
- };
-
- // Export
- return {
- ConfirmResetOverlay: ConfirmResetOverlay
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.css
deleted file mode 100644
index 82017d7cae7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.css
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#terms-of-service {
- padding: 70px 17px 21px;
-}
-
-#tos-container {
- border: 1px solid #d9d9d9;
- height: 222px;
-}
-
-#terms-of-service .step-contents {
- -webkit-margin-start: 32px;
- margin-bottom: 49px;
-}
-
-#terms-of-service h1 {
- font-size: 100%;
- font-weight: normal;
- margin: 0 0 8px 0;
- width: 630px;
-}
-
-#tos-subheading {
- color: rgb(100, 100, 100);
- font-size: 11px;
- margin: 0 0 27px 0;
- width: 630px;
-}
-
-#tos-container {
- -webkit-margin-end: -2px;
- overflow: auto;
- width: 630px;
-}
-
-#tos-content {
- padding: 8px 13px;
-}
-
-#terms-of-service h2 {
- font-size: 100%;
- margin: 0 0 13px 0;
-}
-
-#tos-content-main {
- white-space: pre-wrap;
-}
-
-#tos-loading,
-#tos-error {
- -webkit-align-items: center;
- -webkit-flex-direction: column;
- -webkit-justify-content: center;
- display: none;
- height: 100%;
- width: 100%;
-}
-
-#terms-of-service p {
- color: rgb(100, 100, 100);
- font-size: 12px;
- margin: 0;
- text-align: center;
-}
-
-#terms-of-service p + p {
- margin-top: 4px;
-}
-
-.step.tos-loading #tos-content {
- display: none;
-}
-
-.step.tos-loading #tos-loading {
- display: -webkit-flex;
-}
-
-.step.error #tos-content,
-.step.error #tos-accept-button {
- display: none;
-}
-
-.step.error #tos-error {
- display: -webkit-flex;
-}
-
-#terms-of-service.error #tos-back-button {
- -webkit-margin-end: 1px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.html
deleted file mode 100644
index 8a314e11cfd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<div class="step right hidden tos-loading" id="terms-of-service" hidden>
- <div class="step-contents">
- <h1 id="tos-heading"></h1>
- <div id="tos-subheading"></div>
- <div id="tos-container">
- <div id="tos-content">
- <h2 id="tos-content-heading"></h2>
- <span id="tos-content-main"></span>
- </div>
- <div id="tos-loading">
- <div>
- <p i18n-content="termsOfServiceLoading"></p>
- </div>
- </div>
- <div id="tos-error">
- <div>
- <p i18n-content="termsOfServiceError"></p>
- <p i18n-content="termsOfServiceTryAgain"></p>
- </div>
- </div>
- </div>
- </div>
- <div id="terms-of-service-controls" class="step-controls"></div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.js
deleted file mode 100644
index 3e11a158578..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.js
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe Terms of Service screen implementation.
- */
-
-login.createScreen('TermsOfServiceScreen', 'terms-of-service',
- function() { return {
- EXTERNAL_API: [
- 'setDomain',
- 'setTermsOfServiceLoadError',
- 'setTermsOfService'
- ],
-
- /**
- * Updates headings on the screen to indicate that the Terms of Service
- * being shown belong to |domain|.
- * @param {string} domain The domain whose Terms of Service are being shown.
- */
- setDomain: function(domain) {
- $('tos-heading').textContent =
- loadTimeData.getStringF('termsOfServiceScreenHeading', domain);
- $('tos-subheading').textContent =
- loadTimeData.getStringF('termsOfServiceScreenSubheading', domain);
- $('tos-content-heading').textContent =
- loadTimeData.getStringF('termsOfServiceContentHeading', domain);
- },
-
- /**
- * Displays an error message on the Terms of Service screen. Called when the
- * download of the Terms of Service has failed.
- */
- setTermsOfServiceLoadError: function() {
- this.classList.remove('tos-loading');
- this.classList.add('error');
- },
-
- /**
- * Displays the given |termsOfService|, enables the accept button and moves
- * the focus to it.
- * @param {string} termsOfService The terms of service, as plain text.
- */
- setTermsOfService: function(termsOfService) {
- this.classList.remove('tos-loading');
- $('tos-content-main').textContent = termsOfService;
- $('tos-accept-button').disabled = false;
- // Initially, the back button is focused and the accept button is
- // disabled.
- // Move the focus to the accept button now but only if the user has not
- // moved the focus anywhere in the meantime.
- if (!$('tos-back-button').blurred)
- $('tos-accept-button').focus();
- },
-
- /**
- * Buttons in Oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
-
- var backButton = this.ownerDocument.createElement('button');
- backButton.id = 'tos-back-button';
- backButton.textContent =
- loadTimeData.getString('termsOfServiceBackButton');
- backButton.addEventListener('click', function(event) {
- $('tos-back-button').disabled = true;
- $('tos-accept-button').disabled = true;
- chrome.send('termsOfServiceBack');
- });
- backButton.addEventListener('blur', function(event) {
- this.blurred = true;
- });
- buttons.push(backButton);
-
- var acceptButton = this.ownerDocument.createElement('button');
- acceptButton.id = 'tos-accept-button';
- acceptButton.disabled = this.classList.contains('tos-loading');
- acceptButton.classList.add('preserve-disabled-state');
- acceptButton.textContent =
- loadTimeData.getString('termsOfServiceAcceptButton');
- acceptButton.addEventListener('click', function(event) {
- $('tos-back-button').disabled = true;
- $('tos-accept-button').disabled = true;
- chrome.send('termsOfServiceAccept');
- });
- buttons.push(acceptButton);
-
- return buttons;
- },
-
- /**
- * Returns the control which should receive initial focus.
- */
- get defaultControl() {
- return $('tos-accept-button').disabled ? $('tos-back-button') :
- $('tos-accept-button');
- },
-
- /**
- * Event handler that is invoked just before the screen is shown.
- * @param {object} data Screen init payload.
- */
- onBeforeShow: function(data) {
- Oobe.getInstance().headerHidden = true;
- }
- };
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.css
deleted file mode 100644
index f5223478a70..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.css
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#update {
- min-height: 423px;
- padding: 70px 17px 69px; /* Screen has no controls. */
-}
-
-#update #update-screen-curtain {
- -webkit-box-align: start;
- -webkit-box-pack: center;
-}
-
-#update #update-checking-progress {
- -webkit-box-align: start;
- -webkit-box-pack: center;
- color: #9c9c9c;
- display: -webkit-box;
-}
-
-#update #update-screen-curtain {
- margin: 45px 35px;
-}
-
-#update-screen-main {
- margin: 45px 35px;
- min-height: 114px;
- text-align: center;
-}
-
-#update #update-cancel-hint {
- -webkit-margin-start: 45px;
- color: rgb(170, 0, 0);
- margin-top: 30px;
- position: absolute;
-}
-
-#update #update-upper-label {
- margin-bottom: 4px;
-}
-
-#update #checking-updates-label {
- margin-bottom: 90px;
-}
-
-#update #update-bottom-label {
- margin-bottom: 4px;
- margin-top: 4px;
- text-align: left;
-}
-
-#update progress {
- border: solid 1px #bbb;
- height: 15px;
- margin-bottom: 4px;
- margin-top: 34px;
- padding: 1px;
- width: 300px;
-}
-
-#update progress::-webkit-progress-bar {
- background: white;
-}
-
-#update progress::-webkit-progress-value {
- background: #bbb;
-}
-
-#update .progress-message {
- color: #a3a3a3;
- font-size: 13px;
- margin-top: 4px;
- text-align: center;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.html
deleted file mode 100644
index 5c784949c64..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<div class="step right hidden animated" id="update" role="group"
- i18n-values="aria-label:updateScreenAccessibleTitle" hidden>
- <div class="step-contents">
- <div id="update-cancel-hint" hidden>
- <p i18n-content="cancelUpdateHint"></p>
- </div>
- <div id="update-screen-curtain">
- <div id="checking-updates-label" i18n-content="checkingForUpdatesMsg">
- </div>
- <div id="update-checking-progress" aria-live="polite">
- <div class="throbber"></div>
- <div i18n-content="checkingForUpdates"></div>
- </div>
- </div>
- <div id="update-screen-main" hidden>
- <p id="update-upper-label"></p>
- <p id="update-bottom-label" i18n-content="installingUpdateDesc"></p>
- <progress id="update-progress-bar" max="100" value="0"></progress>
- <p id="estimated-time-left" class="progress-message" hidden></p>
- <p id="progress-message" class="progress-message" hidden></p>
- </div>
- </div>
- <div id="update-extra-controls" class="step-extra-controls">
- <div id="update-accessibility">
- <a id="update-accessibility-link" href="#" role="button"
- i18n-content="accessibilityLink"></a>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.js
deleted file mode 100644
index 1fa14c9797c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_update.js
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe update screen implementation.
- */
-
-login.createScreen('UpdateScreen', 'update', function() {
- var USER_ACTION_CANCEL_UPDATE_SHORTCUT = 'cancel-update';
- var CONTEXT_KEY_TIME_LEFT_SEC = 'time-left-sec';
- var CONTEXT_KEY_SHOW_TIME_LEFT = 'show-time-left';
- var CONTEXT_KEY_UPDATE_MESSAGE = 'update-msg';
- var CONTEXT_KEY_SHOW_CURTAIN = 'show-curtain';
- var CONTEXT_KEY_SHOW_PROGRESS_MESSAGE = 'show-progress-msg';
- var CONTEXT_KEY_PROGRESS = 'progress';
- var CONTEXT_KEY_PROGRESS_MESSAGE = 'progress-msg';
- var CONTEXT_KEY_CANCEL_UPDATE_SHORTCUT_ENABLED = 'cancel-update-enabled';
-
- return {
- EXTERNAL_API: [],
-
- /** @override */
- decorate: function() {
- var self = this;
-
- this.context.addObserver(CONTEXT_KEY_TIME_LEFT_SEC,
- function(time_left_sec) {
- self.setEstimatedTimeLeft(time_left_sec);
- });
- this.context.addObserver(CONTEXT_KEY_SHOW_TIME_LEFT,
- function(show_time_left) {
- self.showEstimatedTimeLeft(show_time_left);
- });
- this.context.addObserver(CONTEXT_KEY_UPDATE_MESSAGE,
- function(update_msg) {
- self.setUpdateMessage(update_msg);
- });
- this.context.addObserver(CONTEXT_KEY_SHOW_CURTAIN,
- function(show_curtain) {
- self.showUpdateCurtain(show_curtain);
- });
- this.context.addObserver(CONTEXT_KEY_SHOW_PROGRESS_MESSAGE,
- function(show_progress_msg) {
- self.showProgressMessage(show_progress_msg);
- });
- this.context.addObserver(CONTEXT_KEY_PROGRESS,
- function(progress) {
- self.setUpdateProgress(progress);
- });
- this.context.addObserver(CONTEXT_KEY_PROGRESS_MESSAGE,
- function(progress_msg) {
- self.setProgressMessage(progress_msg);
- });
- this.context.addObserver(CONTEXT_KEY_CANCEL_UPDATE_SHORTCUT_ENABLED,
- function(enabled) {
- $('update-cancel-hint').hidden = !enabled;
- });
- },
-
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('updateScreenTitle');
- },
-
- /**
- * Cancels the screen.
- */
- cancel: function() {
- // It's safe to act on the accelerator even if it's disabled on official
- // builds, since Chrome will just ignore this user action in that case.
- var updateCancelHint = $('update-cancel-hint').firstElementChild;
- updateCancelHint.textContent =
- loadTimeData.getString('cancelledUpdateMessage');
- this.send(login.Screen.CALLBACK_USER_ACTED,
- USER_ACTION_CANCEL_UPDATE_SHORTCUT);
- },
-
- /**
- * Sets update's progress bar value.
- * @param {number} progress Percentage of the progress bar.
- */
- setUpdateProgress: function(progress) {
- $('update-progress-bar').value = progress;
- },
-
- /**
- * Shows or hides downloading ETA message.
- * @param {boolean} visible Are ETA message visible?
- */
- showEstimatedTimeLeft: function(visible) {
- $('progress-message').hidden = visible;
- $('estimated-time-left').hidden = !visible;
- },
-
- /**
- * Sets estimated time left until download will complete.
- * @param {number} seconds Time left in seconds.
- */
- setEstimatedTimeLeft: function(seconds) {
- var minutes = Math.ceil(seconds / 60);
- var message = '';
- if (minutes > 60) {
- message = loadTimeData.getString('downloadingTimeLeftLong');
- } else if (minutes > 55) {
- message = loadTimeData.getString('downloadingTimeLeftStatusOneHour');
- } else if (minutes > 20) {
- message = loadTimeData.getStringF('downloadingTimeLeftStatusMinutes',
- Math.ceil(minutes / 5) * 5);
- } else if (minutes > 1) {
- message = loadTimeData.getStringF('downloadingTimeLeftStatusMinutes',
- minutes);
- } else {
- message = loadTimeData.getString('downloadingTimeLeftSmall');
- }
- $('estimated-time-left').textContent =
- loadTimeData.getStringF('downloading', message);
- },
-
- /**
- * Shows or hides info message below progress bar.
- * @param {boolean} visible Are message visible?
- */
- showProgressMessage: function(visible) {
- $('estimated-time-left').hidden = visible;
- $('progress-message').hidden = !visible;
- },
-
- /**
- * Sets message below progress bar.
- * @param {string} message Message that should be shown.
- */
- setProgressMessage: function(message) {
- $('progress-message').innerText = message;
- },
-
- /**
- * Sets update message, which is shown above the progress bar.
- * @param {text} message Message which is shown by the label.
- */
- setUpdateMessage: function(message) {
- $('update-upper-label').textContent = message;
- },
-
- /**
- * Shows or hides update curtain.
- * @param {boolean} visible Are curtains visible?
- */
- showUpdateCurtain: function(visible) {
- $('update-screen-curtain').hidden = !visible;
- $('update-screen-main').hidden = visible;
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css
deleted file mode 100644
index 75c3bfad5af..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#user-image {
- min-height: 443px;
- padding: 70px 17px 21px;
- width: 702px;
-}
-
-#user-image.loading {
- min-height: 609px; /* Should be the same as #gaia-signin height. */
- width: 722px; /* Should be the same as #gaia-signin width. */
-}
-
-#user-image-screen-curtain {
- -webkit-margin-start: 8px;
-}
-
-#user-image-screen-description {
- margin-top: 0;
-}
-
-#user-image-grid {
- -webkit-user-drag: none;
- -webkit-user-select: none;
- display: inline-block;
- height: 264px;
- margin: 0;
- outline: none;
- overflow: hidden;
- padding: 0;
- width: 400px;
-}
-
-#user-image-grid img {
- background-color: white;
- height: 50px;
- vertical-align: middle;
- width: 50px;
-}
-
-#user-image-grid > li {
- border: 1px solid rgba(0, 0, 0, 0.15);
- border-radius: 4px;
- display: inline-block;
- margin: 4px;
- padding: 3px;
-}
-
-#user-image-grid [selected] {
- border: 2px solid rgb(0, 102, 204);
- padding: 2px;
-}
-
-/**
- * #user-image-preview can have the following classes:
- * .default-image: one of the default images is selected (including the grey
- * silhouette);
- * .profile-image: profile image is selected;
- * .profile-image-loading: profile image is being loaded;
- * .online: camera is streaming video;
- * .camera: camera (live or photo) is selected;
- * .live: camera is in live mode (no photo taken yet/last photo removed).
- */
-#user-image-preview {
- float: right;
- margin: 4px;
- max-width: 220px;
- position: relative;
-}
-
-#profile-image {
- position: relative;
-}
-
-/* White background for spinner styled like user image */
-#profile-image .spinner-bg {
- background-color: white;
- display: none;
- height: 50px;
- left: 3px;
- position: absolute;
- top: 3px;
- width: 50px;
-}
-
-.profile-image-loading #profile-image .spinner-bg {
- display: block;
-}
-
-#profile-image .spinner {
- left: 14px;
- position: absolute;
- top: 14px;
-}
-
-.image-loading.user-image .new-gaia-flow #user-image {
- height: 528px; /* Should be the same as #gaia-signin height. */
- padding: 0 0 0;
- width: 448px; /* Should be the same as #gaia-signin width. */
-}
-
-.new-gaia-flow #user-image.loading {
- min-height: 528px; /* Should be the same as #gaia-signin height. */
- width: 448px; /* Should be the same as #gaia-signin width. */
-}
-
-.new-gaia-flow #old-flow-throbber {
- display: none;
-}
-
-.image-loading.user-image .new-gaia-flow #step-logo {
- display: none;
-}
-
-html[dir=rtl] #user-image-preview {
- float: left;
-}
-
-#user-image-preview-img {
- display: block;
- max-height: 220px;
- max-width: 220px;
-}
-
-#user-image-preview-img.animated-transform {
- -webkit-transition: -webkit-transform 200ms linear;
-}
-
-.camera.live #user-image-preview-img {
- display: none;
-}
-
-.camera.flip-x #user-image-preview-img {
- -webkit-transform: rotateY(180deg);
-}
-
-.default-image #user-image-preview-img {
- background: white;
- border: solid 1px #cacaca;
- border-radius: 4px;
- padding: 2px;
-}
-
-.user-image-stream-area {
- display: none;
- padding: 0;
- position: relative;
-}
-
-.camera.live .user-image-stream-area {
- display: block;
-}
-
-#user-image-stream-crop {
- -webkit-transition: -webkit-transform 200ms linear;
- height: 220px;
- overflow: hidden;
- position: relative;
- width: 220px;
-}
-
-.flip-x #user-image-stream-crop {
- -webkit-transform: rotateY(180deg);
-}
-
-/* TODO(ivankr): specify dimensions from real capture size. */
-.user-image-stream {
- border: solid 1px #cacaca;
- height: 220px;
- /* Center image for 4:3 aspect ratio. */
- left: -16.6%;
- position: absolute;
- visibility: hidden;
-}
-
-.online .user-image-stream {
- visibility: visible;
-}
-
-#user-image-preview-caption {
- color: dimGray;
- font-size: smaller;
- margin: 8px 4px;
-}
-
-.camera #user-image-preview-caption {
- display: none;
-}
-
-#flip-photo {
- -webkit-transition: opacity 75ms linear;
- background: url(chrome://theme/IDR_MIRROR_FLIP) no-repeat;
- border: none;
- bottom: 44px; /* 8px + image bottom. */
- display: block;
- height: 32px;
- opacity: 0;
- position: absolute;
- right: 8px;
- width: 32px;
- z-index: 1;
-}
-
-/* TODO(merkulova): remove when webkit crbug.com/126479 is fixed. */
-.flip-trick {
- -webkit-transform: translateZ(1px);
-}
-
-html[dir=rtl] #flip-photo {
- left: 8px;
- right: auto;
-}
-
-/* "Flip photo" button is hidden during flip animation. */
-.camera.online:not(.animation) #flip-photo,
-.camera.phototaken:not(.animation) #flip-photo {
- opacity: 0.75;
-}
-
-#discard-photo,
-#take-photo {
- display: none;
- height: 25px;
- margin: 4px 1px;
- padding: 0;
- width: 220px;
-}
-
-.camera:not(.live) #discard-photo {
- background: url(chrome://theme/IDR_USER_IMAGE_RECYCLE)
- no-repeat center center;
- display: block;
-}
-
-.camera.live.online #take-photo {
- background: url(chrome://theme/IDR_USER_IMAGE_CAPTURE)
- no-repeat center -1px;
- display: block;
-}
-
-#user-image-preview .perspective-box {
- -webkit-perspective: 600px;
- border: solid 1px #cacaca;
- border-radius: 4px;
- padding: 2px;
- width: 220px;
-}
-
-#user-image-attribution {
- /* Turned off for now. */
- display: none;
-}
-
-#user-image .step-contents {
- -webkit-margin-start: 31px;
- margin-bottom: 30px;
-}
-
-.user-image-stream-area .spinner {
- display: none;
- height: 44px;
- left: 50%;
- margin-left: -22px;
- margin-top: -22px;
- position: absolute;
- top: 50%;
- width: 44px;
-}
-
-.camera.live:not(.online) .user-image-stream-area .spinner {
- display: block;
-}
-
-#user-images-loading {
- color: #9c9c9c;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.html
deleted file mode 100644
index b6e1b33f55b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<div class="step right hidden loading" id="user-image" hidden>
- <div class="step-contents">
- <div id="user-image-screen-curtain">
- <p id="user-image-screen-description"
- i18n-content="userImageScreenDescription"></p>
- </div>
- <div id="user-image-screen-main">
- <grid id="user-image-grid" tabindex="1"
- aria-labelledby="user-image-screen-description">
- </grid>
- <div id="user-image-preview">
- <img id="user-image-preview-img" class="animated-transform" alt="">
- <div class="user-image-stream-area">
- <div class="perspective-box">
- <div id="user-image-stream-crop">
- <video class="user-image-stream" autoplay></video>
- </div>
- </div>
- <div class="spinner"></div>
- </div>
- <p id="user-image-preview-caption"></p>
- <button id="discard-photo" i18n-values="title:discardPhoto"
- tabindex="2"></button>
- <button id="take-photo" i18n-values="title:takePhoto" tabindex="2">
- </button>
- <button id="flip-photo" class="custom-appearance"
- i18n-values="title:flipPhoto" tabindex="1"></button>
- </div>
- <div id="user-image-attribution">
- <span i18n-content="authorCredit"></span>
- <strong id="user-image-author-name"></strong>
- <a id="user-image-author-website" target="_blank"></a>
- </div>
- </div>
- </div>
- <div id="user-image-controls" class="step-controls"></div>
- <div id="user-images-loading" class="step-loading">
- <div id="old-flow-throbber" class="step-loading">
- <div class="throbber"></div>
- <div i18n-content="syncingPreferences"></div>
- </div>
- <throbber-notice i18n-values="text:syncingPreferencesNewGaia" class="fit">
- </throbber-notice>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js b/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js
deleted file mode 100644
index 0628c6a7bbd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screen_user_image.js
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe user image screen implementation.
- */
-
-login.createScreen('UserImageScreen', 'user-image', function() {
- var CONTEXT_KEY_IS_CAMERA_PRESENT = 'isCameraPresent';
- var CONTEXT_KEY_SELECTED_IMAGE_URL = 'selectedImageURL';
- var CONTEXT_KEY_PROFILE_PICTURE_DATA_URL = 'profilePictureDataURL';
-
- var UserImagesGrid = options.UserImagesGrid;
- var ButtonImages = UserImagesGrid.ButtonImages;
-
- return {
- EXTERNAL_API: [
- 'setDefaultImages',
- 'hideCurtain'
- ],
-
- /** @override */
- decorate: function(element) {
- var imageGrid = $('user-image-grid');
- UserImagesGrid.decorate(imageGrid);
-
- // Preview image will track the selected item's URL.
- var previewElement = $('user-image-preview');
- previewElement.oncontextmenu = function(e) { e.preventDefault(); };
-
- imageGrid.previewElement = previewElement;
- imageGrid.selectionType = 'default';
- imageGrid.flipPhotoElement = $('flip-photo');
-
- imageGrid.addEventListener('select',
- this.handleSelect_.bind(this));
- imageGrid.addEventListener('activate',
- this.handleImageActivated_.bind(this));
- imageGrid.addEventListener('phototaken',
- this.handlePhotoTaken_.bind(this));
- imageGrid.addEventListener('photoupdated',
- this.handlePhotoUpdated_.bind(this));
-
- // Set the title for camera item in the grid.
- imageGrid.setCameraTitles(
- loadTimeData.getString('takePhoto'),
- loadTimeData.getString('photoFromCamera'));
-
- this.profileImageLoading = true;
-
- // Profile image data (if present).
- this.profileImage_ = imageGrid.addItem(
- ButtonImages.PROFILE_PICTURE, // Image URL.
- loadTimeData.getString('profilePhoto'), // Title.
- undefined, // Click handler.
- 0, // Position.
- function(el) {
- // Custom decorator for Profile image element.
- var spinner = el.ownerDocument.createElement('div');
- spinner.className = 'spinner';
- var spinnerBg = el.ownerDocument.createElement('div');
- spinnerBg.className = 'spinner-bg';
- spinnerBg.appendChild(spinner);
- el.appendChild(spinnerBg);
- el.id = 'profile-image';
- });
- this.profileImage_.type = 'profile';
-
- $('take-photo').addEventListener(
- 'click', this.handleTakePhoto_.bind(this));
- $('discard-photo').addEventListener(
- 'click', this.handleDiscardPhoto_.bind(this));
-
- // Toggle 'animation' class for the duration of WebKit transition.
- $('flip-photo').addEventListener(
- 'click', this.handleFlipPhoto_.bind(this));
- $('user-image-stream-crop').addEventListener(
- 'webkitTransitionEnd', function(e) {
- previewElement.classList.remove('animation');
- });
- $('user-image-preview-img').addEventListener(
- 'webkitTransitionEnd', function(e) {
- previewElement.classList.remove('animation');
- });
-
- var self = this;
- this.context.addObserver(CONTEXT_KEY_IS_CAMERA_PRESENT,
- function(present) {
- $('user-image-grid').cameraPresent = present;
- });
- this.context.addObserver(CONTEXT_KEY_SELECTED_IMAGE_URL,
- this.setSelectedImage_);
- this.context.addObserver(CONTEXT_KEY_PROFILE_PICTURE_DATA_URL,
- function(url) {
- self.profileImageLoading = false;
- if (url) {
- self.profileImage_ =
- $('user-image-grid').updateItem(self.profileImage_, url);
- }
- });
-
- this.updateLocalizedContent();
-
- chrome.send('getImages');
- },
-
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('userImageScreenTitle');
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var okButton = this.ownerDocument.createElement('button');
- okButton.id = 'ok-button';
- okButton.textContent = loadTimeData.getString('okButtonText');
- okButton.addEventListener('click', this.acceptImage_.bind(this));
- return [okButton];
- },
-
- /**
- * The caption to use for the Profile image preview.
- * @type {string}
- */
- get profileImageCaption() {
- return this.profileImageCaption_;
- },
- set profileImageCaption(value) {
- this.profileImageCaption_ = value;
- this.updateCaption_();
- },
-
- /**
- * True if the Profile image is being loaded.
- * @type {boolean}
- */
- get profileImageLoading() {
- return this.profileImageLoading_;
- },
- set profileImageLoading(value) {
- this.profileImageLoading_ = value;
- $('user-image-screen-main').classList.toggle('profile-image-loading',
- value);
- if (value)
- announceAccessibleMessage(loadTimeData.getString('syncingPreferences'));
- this.updateProfileImageCaption_();
- },
-
- /**
- * Handles image activation (by pressing Enter).
- * @private
- */
- handleImageActivated_: function() {
- switch ($('user-image-grid').selectedItemUrl) {
- case ButtonImages.TAKE_PHOTO:
- this.handleTakePhoto_();
- break;
- default:
- this.acceptImage_();
- break;
- }
- },
-
- /**
- * Handles selection change.
- * @param {Event} e Selection change event.
- * @private
- */
- handleSelect_: function(e) {
- var imageGrid = $('user-image-grid');
- $('ok-button').disabled = false;
-
- // Camera selection
- if (imageGrid.selectionType == 'camera') {
- $('flip-photo').tabIndex = 1;
- // No current image selected.
- if (imageGrid.cameraLive) {
- imageGrid.previewElement.classList.remove('phototaken');
- $('ok-button').disabled = true;
- } else {
- imageGrid.previewElement.classList.add('phototaken');
- this.notifyImageSelected_();
- }
- } else {
- imageGrid.previewElement.classList.remove('phototaken');
- $('flip-photo').tabIndex = -1;
- this.notifyImageSelected_();
- }
- // Start/stop camera on (de)selection.
- if (!imageGrid.inProgramSelection &&
- imageGrid.selectionType != e.oldSelectionType) {
- if (imageGrid.selectionType == 'camera') {
- // Programmatic selection of camera item is done in
- // startCamera callback where streaming is started by itself.
- imageGrid.startCamera(
- function() {
- // Start capture if camera is still the selected item.
- $('user-image-preview-img').classList.toggle(
- 'animated-transform', true);
- return imageGrid.selectedItem == imageGrid.cameraImage;
- });
- } else {
- $('user-image-preview-img').classList.toggle('animated-transform',
- false);
- imageGrid.stopCamera();
- }
- }
- this.updateCaption_();
- // Update image attribution text.
- var image = imageGrid.selectedItem;
- $('user-image-author-name').textContent = image.author;
- $('user-image-author-website').textContent = image.website;
- $('user-image-author-website').href = image.website;
- $('user-image-attribution').style.visibility =
- (image.author || image.website) ? 'visible' : 'hidden';
- },
-
- /**
- * Handle camera-photo flip.
- */
- handleFlipPhoto_: function() {
- var imageGrid = $('user-image-grid');
- imageGrid.previewElement.classList.add('animation');
- imageGrid.flipPhoto = !imageGrid.flipPhoto;
- var flipMessageId = imageGrid.flipPhoto ?
- 'photoFlippedAccessibleText' : 'photoFlippedBackAccessibleText';
- announceAccessibleMessage(loadTimeData.getString(flipMessageId));
- },
-
- /**
- * Handle photo capture from the live camera stream.
- */
- handleTakePhoto_: function(e) {
- $('user-image-grid').takePhoto();
- chrome.send('takePhoto');
- },
-
- /**
- * Handle photo captured event.
- * @param {Event} e Event with 'dataURL' property containing a data URL.
- */
- handlePhotoTaken_: function(e) {
- chrome.send('photoTaken', [e.dataURL]);
- announceAccessibleMessage(
- loadTimeData.getString('photoCaptureAccessibleText'));
- },
-
- /**
- * Handle photo updated event.
- * @param {Event} e Event with 'dataURL' property containing a data URL.
- */
- handlePhotoUpdated_: function(e) {
- chrome.send('photoTaken', [e.dataURL]);
- },
-
- /**
- * Handle discarding the captured photo.
- */
- handleDiscardPhoto_: function(e) {
- var imageGrid = $('user-image-grid');
- imageGrid.discardPhoto();
- chrome.send('discardPhoto');
- announceAccessibleMessage(
- loadTimeData.getString('photoDiscardAccessibleText'));
- },
-
- /**
- * Event handler that is invoked just before the screen is shown.
- * @param {object} data Screen init payload.
- */
- onBeforeShow: function(data) {
- Oobe.getInstance().headerHidden = true;
- this.loading = true;
- var imageGrid = $('user-image-grid');
- imageGrid.updateAndFocus();
- chrome.send('onUserImageScreenShown');
- },
-
- /**
- * Event handler that is invoked just before the screen is hidden.
- */
- onBeforeHide: function() {
- $('user-image-grid').stopCamera();
- this.loading = false;
- },
-
- /**
- * Accepts currently selected image, if possible.
- * @private
- */
- acceptImage_: function() {
- var okButton = $('ok-button');
- if (!okButton.disabled) {
- // This ensures that #ok-button won't be re-enabled again.
- $('user-image-grid').disabled = true;
- okButton.disabled = true;
- chrome.send('onUserImageAccepted');
- this.loading = true;
- }
- },
-
- /**
- * Appends default images to the image grid. Should only be called once.
- * @param {Array<{url: string, author: string, website: string}>} images
- * An array of default images data, including URL, author and website.
- */
- setDefaultImages: function(imagesData) {
- $('user-image-grid').setDefaultImages(imagesData);
- this.setSelectedImage_(
- this.context.get(CONTEXT_KEY_SELECTED_IMAGE_URL, ''));
- chrome.send('screenReady');
- },
-
- /**
- * Selects user image with the given URL.
- * @param {string} url URL of the image to select.
- * @private
- */
- setSelectedImage_: function(url) {
- if (!url)
- return;
- var imageGrid = $('user-image-grid');
- imageGrid.selectedItemUrl = url;
- imageGrid.focus();
- },
-
- get loading() {
- return this.classList.contains('loading');
- },
-
- set loading(value) {
- this.classList.toggle('loading', value);
- $('oobe').classList.toggle('image-loading', value);
- Oobe.getInstance().updateScreenSize(this);
- },
-
- /**
- * Hides curtain with spinner.
- */
- hideCurtain: function() {
- this.loading = false;
- },
-
- /**
- * Updates the image preview caption.
- * @private
- */
- updateCaption_: function() {
- $('user-image-preview-caption').textContent =
- $('user-image-grid').selectionType == 'profile' ?
- this.profileImageCaption : '';
- },
-
- /**
- * Updates localized content of the screen that is not updated via template.
- */
- updateLocalizedContent: function() {
- this.updateProfileImageCaption_();
- },
-
- /**
- * Updates profile image caption.
- * @private
- */
- updateProfileImageCaption_: function() {
- this.profileImageCaption = loadTimeData.getString(
- this.profileImageLoading_ ? 'profilePhotoLoading' : 'profilePhoto');
- },
-
- /**
- * Notifies chrome about image selection.
- * @private
- */
- notifyImageSelected_: function() {
- var imageGrid = $('user-image-grid');
- chrome.send('selectImage',
- [imageGrid.selectedItemUrl,
- imageGrid.selectionType,
- !imageGrid.inProgramSelection]);
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/oobe_screens.html b/chromium/chrome/browser/resources/chromeos/login/oobe_screens.html
deleted file mode 100644
index 508eea33264..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/oobe_screens.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<include src="oobe_screen_eula.html">
-<include src="oobe_screen_network.html">
-<include src="oobe_screen_enable_debugging.html">
-<include src="oobe_screen_reset.html">
-<include src="oobe_screen_autolaunch.html">
-<include src="oobe_screen_enable_kiosk.html">
-<include src="oobe_screen_terms_of_service.html">
-<include src="oobe_screen_update.html">
-<include src="oobe_screen_controller_pairing.html">
-<include src="oobe_screen_host_pairing.html">
-<include src="oobe_screen_auto_enrollment_check.html">
-<include src="oobe_screen_user_image.html">
-<include src="oobe_screen_hid_detection.html">
-<include src="../../../../../ui/login/account_picker/screen_account_picker.html">
-<include src="screen_error_message.html">
-<include src="screen_gaia_signin.html">
-<include src="screen_supervised_user_creation.html">
-<include src="screen_password_changed.html">
-<include src="screen_tpm_error.html">
-<include src="screen_wrong_hwid.html">
-<include src="screen_app_launch_splash.html">
-<include src="screen_confirm_password.html">
-<include src="screen_fatal_error.html">
-<include src="screen_device_disabled.html">
diff --git a/chromium/chrome/browser/resources/chromeos/login/pairing_device_list.css b/chromium/chrome/browser/resources/chromeos/login/pairing_device_list.css
deleted file mode 100644
index eb2c72573d6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/pairing_device_list.css
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 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.
- */
-
-/* TODO(dzhioev): support RTL. http://crbug.com/423354 */
-
-:host {
- display: block;
- overflow: auto;
-}
-
-core-selector {
- display: block;
-}
-
-:host([connecting]) {
- pointer-events: none;
-}
-
-paper-icon-item {
- padding-bottom: 18px;
- padding-top: 18px;
-}
-
-/* Items separator. */
-paper-icon-item:not(:last-of-type)::after {
- background-color: rgba(0, 0, 0, 0.1);
- bottom: 0;
- content: '';
- display: block;
- height: 1px;
- left: calc(40px + 1em);
- position: absolute;
- right: 0;
-}
-
-iron-icon {
- height: 40px;
- margin-right: 1em;
- width: 40px;
-}
-
-.throbber {
- display: none;
-}
-
-.iron-selected {
- font-weight: bold;
-}
-
-:host([connecting]) .iron-selected .throbber {
- background: url(chrome://resources/images/throbber_small.svg) no-repeat;
- background-size: cover;
- display: inline-block;
- height: 25px;
- margin-right: 10px;
- width: 25px;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/roboto_font.css b/chromium/chrome/browser/resources/chromeos/login/roboto_font.css
deleted file mode 100644
index 357cf379651..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/roboto_font.css
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 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.
- */
-
-/* TODO(dzhioev): get rid of this file, when we have Roboto among system fonts.
- * http://crbug.com/409047
- */
-
-@font-face {
- font-family: 'Roboto';
- font-style: normal;
- font-weight: 100;
- src: url(Roboto-Thin.ttf) format('truetype');
-}
-
-@font-face {
- font-family: 'Roboto';
- font-style: normal;
- font-weight: 300;
- src: url(Roboto-Light.ttf) format('truetype');
-}
-
-@font-face {
- font-family: 'Roboto';
- font-style: normal;
- font-weight: 400;
- src: url(Roboto-Regular.ttf) format('truetype');
-}
-
-@font-face {
- font-family: 'Roboto';
- font-style: normal;
- font-weight: 500;
- src: url(Roboto-Medium.ttf) format('truetype');
-}
-
-@font-face {
- font-family: 'Roboto';
- font-style: normal;
- font-weight: 700;
- src: url(Roboto-Bold.ttf) format('truetype');
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.css b/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.css
deleted file mode 100644
index 93df538e535..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.css
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- display: block;
- position: relative;
-}
-
-#closeButton {
- color: white;
- position: absolute;
- right: 10px;
- top: 10px;
- z-index: 1;
-}
-
-:host-context(html[dir=rtl]) #closeButton {
- left: 10px;
- right: auto;
-}
-
-paper-dialog {
- --paper-dialog-title: {
- font-size: 15px;
- };
-
- width: 384px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.html b/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.html
deleted file mode 100644
index f10e848b230..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-in-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-out-animation.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animated-pages.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<!--
- SAML password confirmation UI for the New Gaia flow.
- Contains two cards with a fade transition between them:
- 1. Password input form.
- 2. Spinner with notice "Please wait";
-
- Example:
- <saml-confirm-password id="saml-confirm-password" hidden>
- </saml-confirm-password>
-
- Attributes:
- 'email' - Displayed email in header.
-
- Events:
- 'passwordEnter' - Fired when user enters password. Fires with an argument
- |password|.
- 'cancel' - Fired when user presses the X-button and then presses YES
- in the cancel confirmation dialog.
-
- Methods:
- 'invalidate' - Mark password input as invalid.
- 'reset' - Reset element, switches to the first screen, closes
- the confirm dialog, displays the close button,
- empties password field and enables buttons.
- 'focus' - If the current card is the first one, focuses password input.
--->
-<dom-module name="saml-confirm-password">
- <link rel="stylesheet" href="saml_confirm_password.css">
-
- <template>
- <neon-animated-pages id="animatedPages" class="fit"
- entry-animation="fade-in-animation" exit-animation="fade-out-animation"
- on-neon-animation-finish="onAnimationFinish_" selected="0">
- <neon-animatable class="fit">
- <gaia-card id="confirmPasswordCard" class="fit">
- <gaia-header class="header flex" email="[[email]]">
- </gaia-header>
- <div class="footer gaia-body-text horizontal layout center">
- <p i18n-content="confirmPasswordTitle">
- </p>
- </div>
- <gaia-input-form id="inputForm" class="footer"
- on-submit="onPasswordSubmitted_" disabled="[[disabled]]"
- i18n-values="button-text:nextButtonText">
- <gaia-input id="passwordInput" type="password" required
- i18n-values="error:confirmPasswordIncorrectPassword;
- label:confirmPasswordLabel;">
- </gaia-input>
- </gaia-input-form>
- </gaia-card>
- </neon-animatable>
- <neon-animatable class="fit">
- <throbber-notice i18n-values="text:gaiaLoadingNewGaia" class="fit">
- </throbber-notice>
- </neon-animatable>
- </neon-animated-pages>
-
- <gaia-icon-button id="closeButton" icon="close" on-tap="onClose_"
- disabled="[[disabled]]" i18n-values="aria-label:closeButton">
- </gaia-icon-button>
-
- <paper-dialog id="cancelConfirmDlg" no-cancel-on-outside-click
- on-iron-overlay-closed="onDialogOverlayClosed_">
- <h2 i18n-content="accountSetupCancelDialogTitle"></h2>
- <div class="buttons">
- <gaia-button type="dialog" dialog-dismiss autofocus
- i18n-content="accountSetupCancelDialogNo">
- </gaia-button>
- <gaia-button type="dialog" dialog-confirm on-tap="onConfirmCancel_"
- i18n-content="accountSetupCancelDialogYes">
- </gaia-button>
- </div>
- </paper-dialog>
-
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.js b/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.js
deleted file mode 100644
index 5acc6252beb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/saml_confirm_password.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer({
- is: 'saml-confirm-password',
-
- properties: {
- email: String,
-
- disabled: {
- type: Boolean,
- value: false,
- observer: 'disabledChanged_'
- }
- },
-
- ready: function() {
- /**
- * Workaround for
- * https://github.com/PolymerElements/neon-animation/issues/32
- * TODO(dzhioev): Remove when fixed in Polymer.
- */
- var pages = this.$.animatedPages;
- delete pages._squelchNextFinishEvent;
- Object.defineProperty(pages, '_squelchNextFinishEvent',
- { get: function() { return false; } });
- },
-
- reset: function() {
- this.$.cancelConfirmDlg.close();
- this.disabled = false;
- this.$.closeButton.hidden = false;
- if (this.$.animatedPages.selected != 0)
- this.$.animatedPages.selected = 0;
- this.$.passwordInput.value = '';
- },
-
- invalidate: function() {
- this.$.passwordInput.isInvalid = true;
- },
-
- focus: function() {
- if (this.$.animatedPages.selected == 0)
- this.$.passwordInput.focus();
- },
-
- onClose_: function() {
- this.disabled = true;
- this.$.cancelConfirmDlg.fitInto = this;
- this.$.cancelConfirmDlg.open();
- },
-
- onConfirmCancel_: function() {
- this.fire('cancel');
- },
-
- onPasswordSubmitted_: function() {
- if (!this.$.passwordInput.checkValidity())
- return;
- this.$.animatedPages.selected = 1;
- this.$.closeButton.hidden = true;
- this.fire('passwordEnter', {password: this.$.passwordInput.value});
- },
-
- onDialogOverlayClosed_: function() {
- this.disabled = false;
- },
-
- disabledChanged_: function(disabled) {
- this.$.confirmPasswordCard.classList.toggle('full-disabled', disabled);
- },
-
- onAnimationFinish_: function() {
- if (this.$.animatedPages.selected == 1)
- this.$.passwordInput.value = '';
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.css b/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.css
deleted file mode 100644
index 0a97b02f35a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.css
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#app-launch-splash {
- -webkit-box-align: center;
- -webkit-box-pack: center;
- background: white;
- display: -webkit-box;
-}
-
-#splash-content {
- -webkit-box-align: center;
- -webkit-box-orient: vertical;
- -webkit-box-pack: center;
- display: -webkit-box;
- position: relative;
-}
-
-#splash-header {
- -webkit-padding-start: 108px;
- background: left center no-repeat;
- background-size: 96px;
- color: #666;
- display: -webkit-box;
- font-size: 48px;
- height: 96px;
- line-height: 96px;
-}
-
-#splash-launch-text {
- color: #666;
- font-size: 18px;
- padding-top: 50px;
-}
-
-#splash-spinner {
- height: 32px;
- width: 32px;
-}
-
-#splash-config-network-container {
- -webkit-transition: 1s opacity;
- height : 30px;
- opacity: 1;
- padding-bottom: 20px;
-}
-
-#splash-config-network-container.faded {
- opacity: 0;
-}
-
-#splash-config-network {
- font-size: 10px;
- font-weight: bold;
- margin: 0;
- padding: 0;
- text-decoration: none;
-}
-
-#splash-config-network:hover {
- color: rgb(202, 67, 100)
-}
-
-#splash-shortcut-info {
- bottom: 50px;
- color: gray;
- left: 0;
- position: absolute;
- right: 0;
- text-align: center;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.html b/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.html
deleted file mode 100644
index a3ef95a852f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<div id="app-launch-splash" class="step hidden no-logo fullscreen" hidden>
- <div id="splash-content">
- <div id="splash-header" i18n-content="productName"></div>
- <div id="splash-launch-text" i18n-content="appStartMessage"></div>
- <div id="splash-config-network-container" class="faded">
- <a id="splash-config-network" i18n-content="configureNetwork" href="javascript:void(0)"></a>
- </div>
- <div id="splash-spinner" class="spinner"></div>
- </div>
- <p id="splash-shortcut-info" i18n-content="shortcutInfo"></p>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.js b/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.js
deleted file mode 100644
index 6d01722e43d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_app_launch_splash.js
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview App install/launch splash screen implementation.
- */
-
-login.createScreen('AppLaunchSplashScreen', 'app-launch-splash', function() {
- return {
- EXTERNAL_API: [
- 'toggleNetworkConfig',
- 'updateApp',
- 'updateMessage',
- ],
-
- /** @override */
- decorate: function() {
- $('splash-config-network').addEventListener('click', function(e) {
- chrome.send('configureNetwork');
- });
-
- var networkContainer = $('splash-config-network-container');
- networkContainer.addEventListener(
- 'webkitTransitionEnd',
- function(e) {
- if (this.classList.contains('faded'))
- $('splash-config-network').hidden = true;
- }.bind(networkContainer)
- );
-
- // Ensure the webkitTransitionEnd event gets called after a wait time.
- // The wait time should be inline with the transition duration time
- // defined in css file. The current value in css is 1000ms. To avoid
- // the emulated webkitTransitionEnd firing before real one, a 1050ms
- // delay is used.
- ensureTransitionEndEvent(networkContainer, 1050);
- },
-
- /**
- * Event handler that is invoked just before the frame is shown.
- * @param {string} data Screen init payload.
- */
- onBeforeShow: function(data) {
- $('splash-config-network').hidden = true;
- this.toggleNetworkConfig(false);
- this.updateApp(data['appInfo']);
-
- $('splash-shortcut-info').hidden = !data['shortcutEnabled'];
-
- Oobe.getInstance().headerHidden = true;
- Oobe.getInstance().solidBackground = true;
- },
-
- /**
- * Event handler that is invoked just before the frame is hidden.
- */
- onBeforeHide: function() {
- },
-
- /**
- * Toggles visibility of the network configuration option.
- * @param {boolean} visible Whether to show the option.
- */
- toggleNetworkConfig: function(visible) {
- var container = $('splash-config-network-container');
- var currVisible = !container.classList.contains('faded');
- if (currVisible == visible)
- return;
-
- if (visible) {
- $('splash-config-network').hidden = false;
- container.classList.remove('faded');
- } else {
- container.classList.add('faded');
- }
- },
-
- /**
- * Updates the app name and icon.
- * @param {Object} app Details of app being launched.
- */
- updateApp: function(app) {
- $('splash-header').textContent = app.name;
- $('splash-header').style.backgroundImage = 'url(' + app.iconURL + ')';
- },
-
- /**
- * Updates the message for the current launch state.
- * @param {string} message Description for current launch state.
- */
- updateMessage: function(message) {
- $('splash-launch-text').textContent = message;
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.css b/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.css
deleted file mode 100644
index 0b29e02f93a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.css
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#confirm-password {
- height: 609px; /* Should be the same as #gaia-signin. */
- padding: 70px;
- width: 722px; /* Should be the same as #gaia-signin. */
-}
-
-#confirm-password .step-contents {
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
-}
-
-#confirm-password-main {
- height: 100%;
- width: 310px;
-}
-
-#confirm-password-title {
- font-weight: bold;
-}
-
-#confirm-password-input-container {
- margin-bottom: 1em;
-}
-
-#confirm-password-error {
- color: rgb(221, 75, 57);
- margin-top: .5em;
-}
-
-#confirm-password:not(.error) #confirm-password-error {
- display: none;
-}
-
-#confirm-password-divider {
- margin-left: 44px;
- margin-right: 30px;
-}
-
-#confirm-password-right {
- -webkit-box-flex: 1;
- margin-top: 1em;
-}
-
-.confirm-password .new-gaia-flow #step-logo {
- display: none;
-}
-
-.new-gaia-flow #saml-confirm-password,
-.new-gaia-flow #confirm-password {
- height: 528px;
- padding: 0;
- width: 448px;
-}
-
-<include src="gaia.css">
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.html b/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.html
deleted file mode 100644
index 51b6841d45a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<link rel="import" href="chrome://oobe/custom_elements.html">
-<div id="confirm-password" class="step hidden" hidden>
- <div id="saml-confirm-password-contents" class="step-contents">
- <div id="confirm-password-main">
- <p id="confirm-password-title" i18n-content="confirmPasswordTitle"></p>
- <div id="confirm-password-input-container">
- <label>
- <p i18n-content="confirmPasswordLabel"></p>
- <input id="confirm-password-input" class="gaia-input" type="password">
- </label>
- </div>
- <p id="confirm-password-error"
- i18n-content="confirmPasswordErrorText"></p>
- <button id="confirm-password-confirm-button"
- class="custom-appearance button-fancy blue-button"
- i18n-content="confirmPasswordConfirmButton"></button>
- </div>
- <div id="confirm-password-divider" class="signin-divider"></div>
- <div id="confirm-password-right">
- <p class="signin-text" i18n-content="confirmPasswordText"></p>
- </div>
- </div>
- <saml-confirm-password id="saml-confirm-password" hidden>
- </saml-confirm-password>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.js b/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.js
deleted file mode 100644
index 2c287408a5e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_confirm_password.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Password confirmation screen implementation.
- */
-
-login.createScreen('ConfirmPasswordScreen', 'confirm-password', function() {
- return {
- EXTERNAL_API: [
- 'show'
- ],
-
- /**
- * Callback to run when the screen is dismissed.
- * @type {function(string)}
- */
- callback_: null,
-
- /** @override */
- decorate: function() {
- $('confirm-password-input').addEventListener(
- 'keydown', this.onPasswordFieldKeyDown_.bind(this));
- $('confirm-password-confirm-button').addEventListener(
- 'click', this.onConfirmPassword_.bind(this));
-
- $('saml-confirm-password').addEventListener('cancel', function(e) {
- Oobe.showScreen({id: SCREEN_ACCOUNT_PICKER});
- Oobe.resetSigninUI(true);
- });
- $('saml-confirm-password').addEventListener('passwordEnter', function(e) {
- this.callback_(e.detail.password);
- }.bind(this));
- },
-
- get defaultControl() {
- return $('confirm-password-input');
- },
-
- /** @override */
- onBeforeShow: function(data) {
- $('login-header-bar').signinUIState =
- SIGNIN_UI_STATE.SAML_PASSWORD_CONFIRM;
- },
-
- /** @override */
- onAfterShow: function(data) {
- if (Oobe.isNewGaiaFlow())
- $('saml-confirm-password').focus();
- },
-
- /** @override */
- onBeforeHide: function() {
- if (Oobe.isNewGaiaFlow())
- $('saml-confirm-password').reset();
- },
-
- /**
- * Handle 'keydown' event on password input field.
- */
- onPasswordFieldKeyDown_: function(e) {
- if (e.keyIdentifier == 'Enter')
- this.onConfirmPassword_();
- },
-
- /**
- * Invoked when user clicks on the 'confirm' button.
- */
- onConfirmPassword_: function() {
- this.callback_($('confirm-password-input').value);
- },
-
- /**
- * Shows the confirm password screen.
- * @param {string} email The authenticated user's e-mail.
- * @param {number} attemptCount Number of attempts tried, starting at 0.
- * @param {function(string)} callback The callback to be invoked when the
- * screen is dismissed.
- */
- show: function(email, attemptCount, callback) {
- this.callback_ = callback;
- this.classList.toggle('error', attemptCount > 0);
- if (Oobe.isNewGaiaFlow()) {
- $('saml-confirm-password-contents').hidden = true;
- var samlConfirmPassword = $('saml-confirm-password');
- samlConfirmPassword.reset();
- samlConfirmPassword.hidden = false;
- samlConfirmPassword.email = email;
- if (attemptCount > 0)
- samlConfirmPassword.invalidate();
- } else {
- $('confirm-password-input').value = '';
- }
- Oobe.showScreen({id: SCREEN_CONFIRM_PASSWORD});
- $('progress-dots').hidden = true;
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_container.html b/chromium/chrome/browser/resources/chromeos/login/screen_container.html
deleted file mode 100644
index d350000fb19..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_container.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<div id="background" class="background-initial"></div>
-<include src="version.html">
-<div id="scroll-container">
- <div id="outer-container" class="down">
- <div id="oobe" class="faded">
- <div id="inner-container" class="down">
- <div id="step-logo" hidden>
- <img src="chrome://theme/IDR_PRODUCT_LOGO" alt>
- <div id="header-sections">
- </div>
- </div>
- <include src="[OOBE]_screens.html">
- </div>
- <div id="progress-dots" class="down"></div>
- </div>
- </div>
-</div>
-<div id="bubble" class="bubble faded" hidden></div>
-<include src="header_bar.html">
-<include src="../../../../../ui/login/account_picker/user_pod_template.html">
-<include src="oobe_screen_reset_confirmation_overlay.html">
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_context.js b/chromium/chrome/browser/resources/chromeos/login/screen_context.js
deleted file mode 100644
index fe1758cb40c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_context.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Implementation of ScreenContext class: key-value storage for
- * values that are shared between C++ and JS sides.
- */
-cr.define('login', function() {
- 'use strict';
-
- function require(condition, message) {
- if (!condition) {
- throw Error(message);
- }
- }
-
- function checkKeyIsValid(key) {
- var keyType = typeof key;
- require(keyType === 'string', 'Invalid type of key: "' + keyType + '".');
- }
-
- function checkValueIsValid(value) {
- var valueType = typeof value;
- require((['string', 'boolean', 'number'].indexOf(valueType) != -1 ||
- Array.isArray(value)),
- 'Invalid type of value: "' + valueType + '".');
- }
-
- function ScreenContext() {
- this.storage_ = {};
- this.changes_ = {};
- this.observers_ = {};
- }
-
- ScreenContext.prototype = {
- /**
- * Returns stored value for |key| or |defaultValue| if key not found in
- * storage. Throws Error if key not found and |defaultValue| omitted.
- */
- get: function(key, defaultValue) {
- checkKeyIsValid(key);
- if (this.hasKey(key)) {
- return this.storage_[key];
- } else if (typeof defaultValue !== 'undefined') {
- return defaultValue;
- } else {
- throw Error('Key "' + key + '" not found.');
- }
- },
-
- /**
- * Sets |value| for |key|. Returns true if call changes state of context,
- * false otherwise.
- */
- set: function(key, value) {
- checkKeyIsValid(key);
- checkValueIsValid(value);
- if (this.hasKey(key) && this.storage_[key] === value)
- return false;
- this.changes_[key] = value;
- this.storage_[key] = value;
- return true;
- },
-
- hasKey: function(key) {
- checkKeyIsValid(key);
- return this.storage_.hasOwnProperty(key);
- },
-
- hasChanges: function() {
- return Object.keys(this.changes_).length > 0;
- },
-
- /**
- * Applies |changes| to context. Returns Array of changed keys' names.
- */
- applyChanges: function(changes) {
- require(!this.hasChanges(), 'Context has changes.');
- var oldValues = {};
- for (var key in changes) {
- checkKeyIsValid(key);
- checkValueIsValid(changes[key]);
- oldValues[key] = this.storage_[key];
- this.storage_[key] = changes[key];
- }
- var observers = this.cloneObservers_();
- for (var key in changes) {
- if (observers.hasOwnProperty(key)) {
- var keyObservers = observers[key];
- for (var observerIndex in keyObservers)
- keyObservers[observerIndex](changes[key], oldValues[key], key);
- }
- }
- return Object.keys(changes);
- },
-
- /**
- * Returns changes made on context since previous call.
- */
- getChangesAndReset: function() {
- var result = this.changes_;
- this.changes_ = {};
- return result;
- },
-
- addObserver: function(key, observer) {
- if (!this.observers_.hasOwnProperty(key))
- this.observers_[key] = [];
- if (this.observers_[key].indexOf(observer) !== -1) {
- console.warn('Observer already registered.');
- return;
- }
- this.observers_[key].push(observer);
- },
-
- removeObserver: function(observer) {
- for (var key in this.observers_) {
- var observerIndex = this.observers_[key].indexOf(observer);
- if (observerIndex != -1)
- this.observers_[key].splice(observerIndex, 1);
- }
- },
-
- /**
- * Creates deep copy of observers lists.
- * @private
- */
- cloneObservers_: function() {
- var result = {};
- for (var key in this.observers_)
- result[key] = this.observers_[key].slice();
- return result;
- }
- };
-
- return {
- ScreenContext: ScreenContext
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_context_test.html b/chromium/chrome/browser/resources/chromeos/login/screen_context_test.html
deleted file mode 100644
index bc77e4bb158..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_context_test.html
+++ /dev/null
@@ -1,207 +0,0 @@
-<!doctype html>
-<title></title>
-<script src="https://cdn.rawgit.com/google/closure-library/master/closure/goog/base.js"></script>
-<script src="../../../../../ui/webui/resources/js/cr.js"></script>
-<script src="screen_context.js"></script>
-<script>
-
-goog.require('goog.testing.jsunit');
-
-</script>
-<body>
-<script>
-
-function callSuccessful(f) {
- try {
- f();
- } catch (e) {
- return false;
- }
- return true;
-}
-
-function checkThrows(f) {
- assertFalse(callSuccessful(f));
-}
-
-function checkNotThrows(f) {
- assertTrue(callSuccessful(f));
-}
-
-function testSimple() {
- var context = new login.ScreenContext;
- assertFalse(context.hasChanges());
-
- assertFalse(context.hasKey('key0'));
-
- var rv = context.set('key0', true);
- assertTrue(rv);
- assertTrue(context.hasKey('key0'));
- assertTrue(context.get('key0'));
- assertTrue(context.get('key0', false));
- assertTrue(context.hasChanges());
-
- rv = context.set('key0', true);
- assertFalse(rv);
-
- rv = context.set('key0', false);
- assertTrue(rv);
- assertTrue(context.hasKey('key0'));
- assertFalse(context.get('key0'));
- assertFalse(context.get('key0', true));
- assertTrue(context.hasChanges());
-
- assertFalse(context.hasKey('key1'));
-
- assertEquals(1, context.get('key1', 1));
- rv = context.set('key1', 2);
- assertTrue(rv);
- assertTrue(context.hasKey('key1'));
- assertEquals(2, context.get('key1'));
- assertEquals(2, context.get('key1', 1));
-}
-
-function testChanges() {
- var context = new login.ScreenContext;
- assertFalse(context.hasChanges());
-
- var rv = context.set('key0', 2);
- assertTrue(rv);
- assertEquals(2, context.get('key0'));
- assertTrue(context.hasChanges());
-
- var changes = context.getChangesAndReset();
- assertFalse(context.hasChanges());
-
- assertEquals(1, Object.keys(changes).length);
-
- assertEquals(2, changes['key0']);
-
- rv = context.set('key0', 3);
- assertTrue(rv);
- assertEquals(3, context.get('key0', 3));
- assertTrue(context.hasChanges());
-
- rv = context.set('key0', 2);
- assertTrue(rv);
- assertTrue(context.hasChanges());
-}
-
-function testComplexChanges() {
- var context = new login.ScreenContext;
- assertFalse(context.hasChanges());
-
- context.set('key0', 'value0');
- context.set('key1', true);
- context.set('key2', 3.14159);
- assertTrue(context.hasChanges());
-
- // Get all changes and verify them.
- var changes = context.getChangesAndReset();
- assertFalse(context.hasChanges());
- assertEquals(3, Object.keys(changes).length);
-
- assertEquals('value0', changes['key0']);
- assertEquals(true, changes['key1']);
- assertEquals(3.14159, changes['key2']);
-
- context.set('key0', 'value1');
- assertTrue(context.hasChanges());
-
- context.set('key0', 'value0');
- assertTrue(context.hasChanges());
-
- changes = context.getChangesAndReset();
- assertFalse(context.hasChanges());
- assertEquals(1, Object.keys(changes).length);
- assertEquals('value0', changes['key0']);
-}
-
-function testApplyChanges() {
- var context = new login.ScreenContext;
- assertFalse(context.hasChanges());
-
- var changes = {
- key0: 'value0',
- key1: 1,
- key2: true
- };
-
- var keys = context.applyChanges(changes);
-
- assertEquals(3, keys.length);
- keys.sort();
- assertEquals('key0', keys[0]);
- assertEquals('key1', keys[1]);
- assertEquals('key2', keys[2]);
-
- assertFalse(context.hasChanges());
- assertEquals('value0', context.get('key0'));
- assertEquals(1, context.get('key1'));
- assertTrue(context.get('key2'));
-}
-
-function testErrorHandling() {
- function createContext() {
- return new login.ScreenContext;
- }
-
- /* Invalid keys. */
- checkThrows(function() {
- createContext().set(true, 10);
- });
- checkThrows(function() {
- createContext().set(new Object, 10);
- });
- checkThrows(function() {
- createContext().set(10, 10);
- });
- checkNotThrows(function() {
- createContext().set('key0', 10);
- });
- checkThrows(function() {
- var c = createContext();
- c.set('10', 10);
- c.get(10);
- });
- checkNotThrows(function() {
- var c = createContext();
- c.set('10', 10);
- c.get('10');
- });
- checkThrows(function() {
- createContext().hasKey(20);
- });
-
- /* Missing key. */
- checkThrows(function() {
- createContext().get('key');
- });
- checkNotThrows(function() {
- createContext().get('key', 10);
- });
-
- /* Invalid values. */
- checkThrows(function() {
- createContext().set('key0', new Object());
- });
- checkThrows(function() {
- createContext().set('key0', new Boolean(true));
- });
-
- /* Applying diff to context with changes. */
- checkThrows(function() {
- var c = createContext();
- c.set('key', 'value');
- c.applyChanges({'key1': 'value1'});
- });
- checkNotThrows(function() {
- var c = createContext();
- c.set('key', 'value');
- c.getChangesAndReset();
- c.applyChanges({'key1': 'value1'});
- });
-}
-
-</script>
-</body>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.css b/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.css
deleted file mode 100644
index 52e9b9095c5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.css
+++ /dev/null
@@ -1,58 +0,0 @@
-/* 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.
- */
-
-#device-disabled,
-#device-disabled-top-container,
-#device-disabled-bottom-container {
- display: flex;
- flex-direction: column;
-}
-
-#device-disabled {
- font-size: 12px;
- line-height: 18px;
- width: 330px;
-}
-
-#device-disabled-top-container {
- background-color: rgb(213, 0, 0);
- color: white;
- padding: 25px 20px;
- text-align: center;
-}
-
-#device-disabled-symbol {
- align-self: center;
- background-image: url(chrome://theme/IDR_DEVICE_DISABLED);
- height: 24px;
- width: 24px;
-}
-
-#device-disabled-heading {
- font-size: 15px;
- line-height: 15px;
- margin-top: 8px;
-}
-
-#device-disabled-explanation {
- font-weight: bold;
- margin: 25px 0 -5px;
- max-height: 54px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#device-disabled-bottom-container {
- background-color: white;
- padding: 25px 20px;
-}
-
-#device-disabled-message {
- margin: -3px 0 -5px;
- max-height: 400px;
- overflow: auto;
- text-overflow: ellipsis;
- white-space: pre-wrap;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.html b/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.html
deleted file mode 100644
index 3b3e088dab0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<div id="device-disabled" class="step hidden no-logo" role="group" hidden>
- <div id="device-disabled-top-container">
- <div id="device-disabled-symbol"></div>
- <div id="device-disabled-heading" i18n-content="deviceDisabledHeading">
- </div>
- <div id="device-disabled-explanation"></div>
- </div>
- <div id="device-disabled-bottom-container">
- <div id="device-disabled-message"></div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.js b/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.js
deleted file mode 100644
index baaf9c3fd09..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_device_disabled.js
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Device disabled screen implementation.
- */
-
-login.createScreen('DeviceDisabledScreen', 'device-disabled', function() {
- return {
- EXTERNAL_API: [
- 'setEnrollmentDomain',
- 'setMessage'
- ],
-
- /**
- * Ignore any accelerators the user presses on this screen.
- */
- ignoreAccelerators: true,
-
- /** @override */
- decorate: function() {
- this.setEnrollmentDomain(null);
- },
-
- /**
- * The visibility of the cancel button in the header bar is controlled by a
- * global. Although the device disabling screen hides the button, a
- * notification intended for an earlier screen (e.g animation finished)
- * could re-show the button. If this happens, the current screen's cancel()
- * method will be shown when the user actually clicks the button. Make sure
- * that this is a no-op.
- */
- cancel: function() {
- },
-
- /**
- * Event handler that is invoked just before the screen in shown.
- */
- onBeforeShow: function() {
- $('progress-dots').hidden = true;
- var headerBar = $('login-header-bar');
- headerBar.allowCancel = false;
- headerBar.showGuestButton = false;
- headerBar.signinUIState = SIGNIN_UI_STATE.HIDDEN;
- },
-
- /**
- * Updates the explanation shown to the user. The explanation will indicate
- * that the device is owned by |enrollment_domain|. If |enrollment_domain|
- * is null or empty, a generic explanation will be used instead that does
- * not reference any domain.
- * @param {string} enrollment_domain The domain that owns the device.
- */
- setEnrollmentDomain: function(enrollment_domain) {
- if (enrollment_domain) {
- // The contents of |enrollment_domain| is untrusted. Set the resulting
- // string as |textContent| so that it gets treated as plain text and
- // cannot be used to inject JS or HTML.
- $('device-disabled-explanation').textContent = loadTimeData.getStringF(
- 'deviceDisabledExplanationWithDomain',
- enrollment_domain);
- } else {
- $('device-disabled-explanation').textContent = loadTimeData.getString(
- 'deviceDisabledExplanationWithoutDomain');
- }
- },
-
-
- /**
- * Sets the message to show to the user.
- * @param {string} message The message to show to the user.
- */
- setMessage: function(message) {
- // The contents of |message| is untrusted. Set it as |textContent| so that
- // it gets treated as plain text and cannot be used to inject JS or HTML.
- $('device-disabled-message').textContent = message;
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_error_message.css b/chromium/chrome/browser/resources/chromeos/login/screen_error_message.css
deleted file mode 100644
index 459b76a545a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_error_message.css
+++ /dev/null
@@ -1,154 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#error-message {
- width: 650px;
-}
-
-.show-with-ui-state-update,
-.show-with-ui-state-signin,
-.show-with-ui-state-supervised,
-.show-with-ui-state-kiosk-mode,
-.show-with-ui-state-local-state-error,
-.show-with-ui-state-auto-enrollment-error,
-.show-with-ui-state-rollback-error,
-.show-with-error-state-portal,
-.show-with-error-state-offline,
-.show-with-error-state-proxy,
-.show-with-error-state-auth-ext-timeout,
-.show-with-error-state-kiosk-online,
-.guest-signin,
-.offline-login,
-.connecting-indicator {
- display: none;
-}
-
-.ui-state-update .show-with-ui-state-update,
-.ui-state-signin .show-with-ui-state-signin,
-.ui-state-supervised .show-with-ui-state-supervised,
-.ui-state-kiosk-mode .show-with-ui-state-kiosk-mode,
-.ui-state-local-state-error .show-with-ui-state-local-state-error,
-.ui-state-auto-enrollment-error .show-with-ui-state-auto-enrollment-error,
-.ui-state-rollback-error .show-with-ui-state-rollback-error,
-.error-state-portal .show-with-error-state-portal,
-.error-state-offline .show-with-error-state-offline,
-.error-state-proxy .show-with-error-state-proxy,
-.error-state-auth-ext-timeout .show-with-error-state-auth-ext-timeout,
-.error-state-kiosk-online .show-with-error-state-kiosk-online,
-.allow-guest-signin .guest-signin,
-.allow-offline-login .offline-login,
-.show-connecting-indicator .connecting-indicator {
- display: block;
-}
-
-#oobe.error-message #step-logo {
- z-index: 1;
-}
-
-.error-header {
- /* A hack used to prevent aliasing on High-DPI displays. */
- -webkit-transform: scale3d(1,1,1);
- background-clip: padding-box;
- background-color: white;
- border-bottom: 1px solid rgb(238,238,238);
- padding: 71px 20px 50px;
- text-align: center;
-}
-
-.error-icon {
- height: 64px;
- margin-bottom: 40px;
-}
-
-.error-title {
- color: #606060;
- font-size: 15px;
-}
-
-.error-body {
- background-color: rgb(249,249,249);
- padding: 20px 20px 20px;
-}
-
-.error-controls {
- background-color: rgb(249,249,249);
- padding: 20px 20px 20px;
-}
-
-.error-message-paragraph {
- font-size: 12px;
- line-height: 18px;
-}
-
-.error-message-paragraph {
- margin-top: 20px;
-}
-
-.error-message-paragraph a {
- color: rgb(17,85,204);
- text-decoration: none;
-}
-
-#offline-network-control {
- -webkit-align-items: center;
- display: -webkit-flex;
-}
-
-.offline-network-list-label {
- -webkit-margin-end: 10px;
-}
-
-.button-spacer {
- -webkit-box-flex: 1;
-}
-
-.ui-state-auto-enrollment-error .error-guest-signin {
- display: none;
-}
-
-.ui-state-auto-enrollment-error.allow-guest-signin
- .error-guest-signin-fix-network {
- display: block;
-}
-
-@-webkit-keyframes connecting-indicator-ellipsis {
- 0% {
- opacity: 0;
- }
- 10% {
- opacity: 1;
- }
- 50% {
- opacity: .8;
- }
- 100% {
- opacity: 0;
- }
-}
-
-#connecting-indicator-ellipsis-1 {
- -webkit-animation: connecting-indicator-ellipsis 3s 0 infinite;
-}
-
-#connecting-indicator-ellipsis-2 {
- -webkit-animation: connecting-indicator-ellipsis 3s 500ms infinite;
-}
-
-#connecting-indicator-ellipsis-3 {
- -webkit-animation: connecting-indicator-ellipsis 3s 1s infinite;
-}
-
-#error-close-button {
- color: rgba(0, 0, 0, .54);
- position: absolute;
- right: 10px;
- top: 10px;
- z-index: 1;
-}
-
-html[dir=rtl] #error-close-button {
- left: 10px;
- right: auto;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_error_message.html b/chromium/chrome/browser/resources/chromeos/login/screen_error_message.html
deleted file mode 100644
index 827798e8aed..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_error_message.html
+++ /dev/null
@@ -1,145 +0,0 @@
-<link rel="import" href="chrome://oobe/custom_elements.html">
-
-<div id="error-message" class="step hidden show-offline-error" hidden>
- <div class="step-contents">
- <div class="error-header" aria-live="assertive">
- <img alt class="error-icon" src="chrome://theme/IDR_ERROR_NETWORK_OFFLINE">
- <div id="captive-portal-title" i18n-content="captivePortalTitle"
- class="error-title
- show-with-error-state-portal
- show-with-error-state-offline"></div>
- <div id="login-error-title" i18n-content="loginErrorTitle"
- class="error-title
- show-with-error-state-proxy
- show-with-error-state-auth-ext-timeout
- show-with-ui-state-local-state-error">
- </div>
- <div id="kiosk-online-title" i18n-content="kioskOnlineTitle"
- class="error-title
- show-with-error-state-kiosk-online">
- </div>
- <div id="rollback-error-title" i18n-content="rollbackErrorTitle"
- class="error-title
- show-with-ui-state-rollback-error">
- </div>
- </div>
- <div class="error-body" aria-live="assertive">
- <div id="kiosk-online-message-body"
- class="error-message-paragraph
- show-with-error-state-kiosk-online">
- <span i18n-content="kioskOnlineMessageBody"
- class="show-with-error-state-kiosk-online"></span>
- </div>
- <div id="offline-message-body"
- class="error-message-paragraph
- show-with-error-state-offline
- show-with-error-state-auth-ext-timeout">
- <span id="update-offline-message-text"
- i18n-content="updateOfflineMessageBody"
- class="show-with-ui-state-update"></span>
- <span id="signin-offline-message-text"
- i18n-content="signinOfflineMessageBody"
- class="show-with-ui-state-signin
- show-with-ui-state-supervised"></span>
- <span id="kiosk-offline-message-text"
- i18n-content="kioskOfflineMessageBody"
- class="show-with-ui-state-kiosk-mode"></span>
- <span id="auto-enrollment-offline-message-text"
- class="show-with-ui-state-auto-enrollment-error"></span>
- </div>
- <div id="captive-portal-message-body"
- class="error-message-paragraph
- show-with-error-state-portal">
- <span id="captive-portal-message-text"
- class="show-with-ui-state-update
- show-with-ui-state-signin
- show-with-ui-state-supervised
- show-with-ui-state-kiosk-mode
- show-with-ui-state-auto-enrollment-error"></span>
- </div>
- <div id="captive-portal-proxy-message-body"
- class="error-message-paragraph
- show-with-error-state-portal
- show-with-error-state-auth-ext-timeout">
- <span id="captive-portal-proxy-message-text"
- class="show-with-ui-state-update
- show-with-ui-state-signin
- show-with-ui-state-supervised
- show-with-ui-state-kiosk-mode
- show-with-ui-state-auto-enrollment-error"></span>
- </div>
- <div id="proxy-message-body"
- class="error-message-paragraph
- show-with-error-state-proxy">
- <span id="update-proxy-message-text"
- class="show-with-ui-state-update
- show-with-ui-state-auto-enrollment-error"></span>
- <span id="signin-proxy-message-text"
- class="show-with-ui-state-signin
- show-with-ui-state-supervised
- show-with-ui-state-kiosk-mode"></span>
- </div>
- <div id="offline-network-control-body"
- class="show-with-ui-state-update
- show-with-ui-state-signin
- show-with-ui-state-supervised
- show-with-ui-state-kiosk-mode
- show-with-ui-state-auto-enrollment-error">
- <div id="offline-network-control" class="error-message-paragraph">
- <label for="offline-networks-list-dropdown"
- i18n-content="selectNetwork"
- class="offline-network-list-label
- show-with-error-state-offline
- show-with-error-state-proxy
- show-with-error-state-auth-timeout
- show-with-error-state-kiosk-online"></label>
- <label for="offline-networks-list-dropdown"
- i18n-content="selectAnotherNetwork"
- class="offline-network-list-label
- show-with-error-state-portal">
- </label>
- <div class="menu-area">
- <div id="offline-networks-list" class="menu-control"></div>
- </div>
- </div>
- </div>
- <div id="local-state-error-body"
- class="show-with-ui-state-local-state-error">
- <div i18n-content="localStateErrorText0"
- class="error-message-paragraph">
- </div>
- <div i18n-content="localStateErrorText1"
- class="error-message-paragraph">
- </div>
- </div>
- <div id="rollback-error-message-body"
- class="error-message-paragraph
- show-with-ui-state-rollback-error">
- <span i18n-content="rollbackErrorMessageBody"
- class="show-with-ui-state-rollback-error"></span>
- </div>
- <div class="show-with-ui-state-update
- show-with-ui-state-signin
- show-with-ui-state-supervised
- show-with-ui-state-kiosk-mode
- show-with-ui-local-state-error">
- <span id="error-guest-signin"
- class="error-message-paragraph guest-signin"></span>
- </div>
- <div class="show-with-ui-state-auto-enrollment-error">
- <span id="error-guest-signin-fix-network"
- class="error-message-paragraph guest-signin"></span>
- </div>
- <div id="error-offline-login"
- class="error-message-paragraph offline-login"></div>
- <div id="connecting-indicator"
- class="connecting-indicator error-message-paragraph"></div>
- </div>
- </div>
- <div class="error-controls">
- <div id="error-message-controls" class="step-controls"></div>
- </div>
- <gaia-icon-button id="error-close-button" icon="close"
- i18n-values="aria-label:closeButton">
- </gaia-icon-button>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_error_message.js b/chromium/chrome/browser/resources/chromeos/login/screen_error_message.js
deleted file mode 100644
index 5efe9d6b357..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_error_message.js
+++ /dev/null
@@ -1,431 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Offline message screen implementation.
- */
-
-login.createScreen('ErrorMessageScreen', 'error-message', function() {
- var CONTEXT_KEY_ERROR_STATE_CODE = 'error-state-code';
- var CONTEXT_KEY_ERROR_STATE_NETWORK = 'error-state-network';
- var CONTEXT_KEY_GUEST_SIGNIN_ALLOWED = 'guest-signin-allowed';
- var CONTEXT_KEY_OFFLINE_SIGNIN_ALLOWED = 'offline-signin-allowed';
- var CONTEXT_KEY_SHOW_CONNECTING_INDICATOR = 'show-connecting-indicator';
- var CONTEXT_KEY_UI_STATE = 'ui-state';
-
- var USER_ACTION_CONFIGURE_CERTS = 'configure-certs';
- var USER_ACTION_DIAGNOSE = 'diagnose';
- var USER_ACTION_LAUNCH_OOBE_GUEST = 'launch-oobe-guest';
- var USER_ACTION_LOCAL_STATE_POWERWASH = 'local-state-error-powerwash';
- var USER_ACTION_REBOOT = 'reboot';
- var USER_ACTION_SHOW_CAPTIVE_PORTAL = 'show-captive-portal';
-
- // Link which starts guest session for captive portal fixing.
- /** @const */ var FIX_CAPTIVE_PORTAL_ID = 'captive-portal-fix-link';
-
- /** @const */ var FIX_PROXY_SETTINGS_ID = 'proxy-settings-fix-link';
-
- // Class of the elements which hold current network name.
- /** @const */ var CURRENT_NETWORK_NAME_CLASS =
- 'portal-network-name';
-
- // Link which triggers frame reload.
- /** @const */ var RELOAD_PAGE_ID = 'proxy-error-signin-retry-link';
-
- // Array of the possible UI states of the screen. Must be in the
- // same order as ErrorScreen::UIState enum values.
- /** @const */ var UI_STATES = [
- ERROR_SCREEN_UI_STATE.UNKNOWN,
- ERROR_SCREEN_UI_STATE.UPDATE,
- ERROR_SCREEN_UI_STATE.SIGNIN,
- ERROR_SCREEN_UI_STATE.SUPERVISED_USER_CREATION_FLOW,
- ERROR_SCREEN_UI_STATE.KIOSK_MODE,
- ERROR_SCREEN_UI_STATE.LOCAL_STATE_ERROR,
- ERROR_SCREEN_UI_STATE.AUTO_ENROLLMENT_ERROR,
- ERROR_SCREEN_UI_STATE.ROLLBACK_ERROR,
- ];
-
- // The help topic linked from the auto enrollment error message.
- /** @const */ var HELP_TOPIC_AUTO_ENROLLMENT = 4632009;
-
- // Possible error states of the screen.
- /** @const */ var ERROR_STATE = {
- UNKNOWN: 'error-state-unknown',
- PORTAL: 'error-state-portal',
- OFFLINE: 'error-state-offline',
- PROXY: 'error-state-proxy',
- AUTH_EXT_TIMEOUT: 'error-state-auth-ext-timeout',
- KIOSK_ONLINE: 'error-state-kiosk-online'
- };
-
- // Possible error states of the screen. Must be in the same order as
- // ErrorScreen::ErrorState enum values.
- /** @const */ var ERROR_STATES = [
- ERROR_STATE.UNKNOWN,
- ERROR_STATE.PORTAL,
- ERROR_STATE.OFFLINE,
- ERROR_STATE.PROXY,
- ERROR_STATE.AUTH_EXT_TIMEOUT,
- ERROR_STATE.NONE,
- ERROR_STATE.KIOSK_ONLINE,
- ];
-
- return {
- EXTERNAL_API: [
- 'updateLocalizedContent',
- 'onBeforeShow',
- 'onBeforeHide',
- 'allowGuestSignin',
- 'allowOfflineLogin',
- 'setUIState',
- 'setErrorState',
- 'showConnectingIndicator'
- ],
-
- // Error screen initial UI state.
- ui_state_: ERROR_SCREEN_UI_STATE.UNKNOWN,
-
- // Error screen initial error state.
- error_state_: ERROR_STATE.UNKNOWN,
-
- /** @override */
- decorate: function() {
- cr.ui.DropDown.decorate($('offline-networks-list'));
- this.updateLocalizedContent();
-
- var self = this;
- this.context.addObserver(CONTEXT_KEY_ERROR_STATE_CODE,
- function(error_state) {
- self.setErrorState(error_state);
- });
- this.context.addObserver(CONTEXT_KEY_ERROR_STATE_NETWORK,
- function(network) {
- self.setNetwork_(network);
- });
- this.context.addObserver(CONTEXT_KEY_GUEST_SIGNIN_ALLOWED,
- function(allowed) {
- self.allowGuestSignin(allowed);
- });
- this.context.addObserver(CONTEXT_KEY_OFFLINE_SIGNIN_ALLOWED,
- function(allowed) {
- self.allowOfflineLogin(allowed);
- });
- this.context.addObserver(CONTEXT_KEY_SHOW_CONNECTING_INDICATOR,
- function(show) {
- self.showConnectingIndicator(show);
- });
- this.context.addObserver(CONTEXT_KEY_UI_STATE, function(ui_state) {
- self.setUIState(ui_state);
- });
- $('error-close-button').addEventListener('click', this.cancel.bind(this));
- },
-
- /**
- * Updates localized content of the screen that is not updated via template.
- */
- updateLocalizedContent: function() {
- var self = this;
- $('auto-enrollment-offline-message-text').innerHTML =
- loadTimeData.getStringF(
- 'autoEnrollmentOfflineMessageBody',
- loadTimeData.getString('deviceType'),
- '<b class="' + CURRENT_NETWORK_NAME_CLASS + '"></b>',
- '<a id="auto-enrollment-learn-more" class="signin-link" ' +
- '"href="#">',
- '</a>');
- $('auto-enrollment-learn-more').onclick = function() {
- chrome.send('launchHelpApp', [HELP_TOPIC_AUTO_ENROLLMENT]);
- };
-
- $('captive-portal-message-text').innerHTML = loadTimeData.getStringF(
- 'captivePortalMessage',
- '<b class="' + CURRENT_NETWORK_NAME_CLASS + '"></b>',
- '<a id="' + FIX_CAPTIVE_PORTAL_ID + '" class="signin-link" href="#">',
- '</a>');
- $(FIX_CAPTIVE_PORTAL_ID).onclick = function() {
- self.send(login.Screen.CALLBACK_USER_ACTED,
- USER_ACTION_SHOW_CAPTIVE_PORTAL);
- };
-
- $('captive-portal-proxy-message-text').innerHTML =
- loadTimeData.getStringF(
- 'captivePortalProxyMessage',
- '<a id="' + FIX_PROXY_SETTINGS_ID + '" class="signin-link" href="#">',
- '</a>');
- $(FIX_PROXY_SETTINGS_ID).onclick = function() {
- chrome.send('openProxySettings');
- };
- $('update-proxy-message-text').innerHTML = loadTimeData.getStringF(
- 'updateProxyMessageText',
- '<a id="update-proxy-error-fix-proxy" class="signin-link" href="#">',
- '</a>');
- $('update-proxy-error-fix-proxy').onclick = function() {
- chrome.send('openProxySettings');
- };
- $('signin-proxy-message-text').innerHTML = loadTimeData.getStringF(
- 'signinProxyMessageText',
- '<a id="' + RELOAD_PAGE_ID + '" class="signin-link" href="#">',
- '</a>',
- '<a id="signin-proxy-error-fix-proxy" class="signin-link" href="#">',
- '</a>');
- $(RELOAD_PAGE_ID).onclick = function() {
- var gaiaScreen = $(SCREEN_GAIA_SIGNIN);
- // Schedules an immediate retry.
- gaiaScreen.doReload();
- };
- $('signin-proxy-error-fix-proxy').onclick = function() {
- chrome.send('openProxySettings');
- };
-
- $('error-guest-signin').innerHTML = loadTimeData.getStringF(
- 'guestSignin',
- '<a id="error-guest-signin-link" class="signin-link" href="#">',
- '</a>');
- $('error-guest-signin-link').addEventListener(
- 'click',
- this.launchGuestSession_.bind(this));
-
- $('error-guest-signin-fix-network').innerHTML = loadTimeData.getStringF(
- 'guestSigninFixNetwork',
- '<a id="error-guest-fix-network-signin-link" class="signin-link" ' +
- 'href="#">',
- '</a>');
- $('error-guest-fix-network-signin-link').addEventListener(
- 'click',
- this.launchGuestSession_.bind(this));
-
- $('error-offline-login').innerHTML = loadTimeData.getStringF(
- 'offlineLogin',
- '<a id="error-offline-login-link" class="signin-link" href="#">',
- '</a>');
- $('error-offline-login-link').onclick = function() {
- chrome.send('offlineLogin');
- };
-
- var ellipsis = '';
- for (var i = 1; i <= 3; ++i) {
- ellipsis +=
- '<span id="connecting-indicator-ellipsis-' + i + '"></span>';
- }
- $('connecting-indicator').innerHTML =
- loadTimeData.getStringF('connectingIndicatorText', ellipsis);
-
- this.onContentChange_();
- },
-
- /**
- * Event handler that is invoked just before the screen in shown.
- * @param {Object} data Screen init payload.
- */
- onBeforeShow: function(data) {
- cr.ui.Oobe.clearErrors();
- cr.ui.DropDown.show('offline-networks-list', false);
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.ERROR;
- $('error-close-button').hidden =
- !(Oobe.isNewGaiaFlow() && $('login-header-bar').allowCancel);
- },
-
- /**
- * Event handler that is invoked just before the screen is hidden.
- */
- onBeforeHide: function() {
- cr.ui.DropDown.hide('offline-networks-list');
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
- },
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
- var self = this;
-
- var rebootButton = this.ownerDocument.createElement('button');
- rebootButton.textContent = loadTimeData.getString('rebootButton');
- rebootButton.classList.add('show-with-ui-state-kiosk-mode');
- rebootButton.addEventListener('click', function(e) {
- self.send(login.Screen.CALLBACK_USER_ACTED, USER_ACTION_REBOOT);
- e.stopPropagation();
- });
- buttons.push(rebootButton);
-
- var diagnoseButton = this.ownerDocument.createElement('button');
- diagnoseButton.textContent = loadTimeData.getString('diagnoseButton');
- diagnoseButton.classList.add('show-with-ui-state-kiosk-mode');
- diagnoseButton.addEventListener('click', function(e) {
- self.send(login.Screen.CALLBACK_USER_ACTED, USER_ACTION_DIAGNOSE);
- e.stopPropagation();
- });
- buttons.push(diagnoseButton);
-
- var certsButton = this.ownerDocument.createElement('button');
- certsButton.textContent = loadTimeData.getString('configureCertsButton');
- certsButton.classList.add('show-with-ui-state-kiosk-mode');
- certsButton.addEventListener('click', function(e) {
- self.send(login.Screen.CALLBACK_USER_ACTED,
- USER_ACTION_CONFIGURE_CERTS);
- e.stopPropagation();
- });
- buttons.push(certsButton);
-
- var continueButton = this.ownerDocument.createElement('button');
- continueButton.id = 'continue-network-config-btn';
- continueButton.textContent = loadTimeData.getString('continueButton');
- continueButton.classList.add('show-with-error-state-kiosk-online');
- continueButton.addEventListener('click', function(e) {
- chrome.send('continueAppLaunch');
- e.stopPropagation();
- });
- buttons.push(continueButton);
-
- var okButton = this.ownerDocument.createElement('button');
- okButton.id = 'ok-error-screen-btn';
- okButton.textContent = loadTimeData.getString('okButton');
- okButton.classList.add('show-with-ui-state-rollback-error');
- okButton.addEventListener('click', function(e) {
- chrome.send('cancelOnReset');
- e.stopPropagation();
- });
- buttons.push(okButton);
-
- var spacer = this.ownerDocument.createElement('div');
- spacer.classList.add('button-spacer');
- spacer.classList.add('show-with-ui-state-kiosk-mode');
- buttons.push(spacer);
-
- var powerwashButton = this.ownerDocument.createElement('button');
- powerwashButton.id = 'error-message-restart-and-powerwash-button';
- powerwashButton.textContent =
- loadTimeData.getString('localStateErrorPowerwashButton');
- powerwashButton.classList.add('show-with-ui-state-local-state-error');
- powerwashButton.addEventListener('click', function(e) {
- self.send(login.Screen.CALLBACK_USER_ACTED,
- USER_ACTION_LOCAL_STATE_POWERWASH);
- e.stopPropagation();
- });
- buttons.push(powerwashButton);
-
- return buttons;
- },
-
- /**
- * Sets current UI state of the screen.
- * @param {string} ui_state New UI state of the screen.
- * @private
- */
- setUIState_: function(ui_state) {
- this.classList.remove(this.ui_state);
- this.ui_state = ui_state;
- this.classList.add(this.ui_state);
-
- if (ui_state == ERROR_SCREEN_UI_STATE.LOCAL_STATE_ERROR) {
- // Hide header bar and progress dots, because there are no way
- // from the error screen about broken local state.
- Oobe.getInstance().headerHidden = true;
- $('progress-dots').hidden = true;
- }
- this.onContentChange_();
- },
-
- /**
- * Sets current error state of the screen.
- * @param {string} error_state New error state of the screen.
- * @private
- */
- setErrorState_: function(error_state) {
- this.classList.remove(this.error_state);
- this.error_state = error_state;
- this.classList.add(this.error_state);
- this.onContentChange_();
- },
-
- /**
- * Sets network.
- * @param {string} network Name of the current network
- * @private
- */
- setNetwork_: function(network) {
- var networkNameElems =
- document.getElementsByClassName(CURRENT_NETWORK_NAME_CLASS);
- for (var i = 0; i < networkNameElems.length; ++i)
- networkNameElems[i].textContent = network;
- this.onContentChange_();
- },
-
- /* Method called after content of the screen changed.
- * @private
- */
- onContentChange_: function() {
- if (Oobe.getInstance().currentScreen === this)
- Oobe.getInstance().updateScreenSize(this);
- },
-
- /**
- * Event handler for guest session launch.
- * @private
- */
- launchGuestSession_: function() {
- if (Oobe.getInstance().isOobeUI()) {
- this.send(login.Screen.CALLBACK_USER_ACTED,
- USER_ACTION_LAUNCH_OOBE_GUEST);
- } else {
- chrome.send('launchIncognito');
- }
- },
-
- /**
- * Prepares error screen to show guest signin link.
- * @private
- */
- allowGuestSignin: function(allowed) {
- this.classList.toggle('allow-guest-signin', allowed);
- this.onContentChange_();
- },
-
- /**
- * Prepares error screen to show offline login link.
- * @private
- */
- allowOfflineLogin: function(allowed) {
- this.classList.toggle('allow-offline-login', allowed);
- this.onContentChange_();
- },
-
- /**
- * Sets current UI state of the screen.
- * @param {number} ui_state New UI state of the screen.
- * @private
- */
- setUIState: function(ui_state) {
- this.setUIState_(UI_STATES[ui_state]);
- },
-
- /**
- * Sets current error state of the screen.
- * @param {number} error_state New error state of the screen.
- * @private
- */
- setErrorState: function(error_state) {
- this.setErrorState_(ERROR_STATES[error_state]);
- },
-
- /**
- * Updates visibility of the label indicating we're reconnecting.
- * @param {boolean} show Whether the label should be shown.
- */
- showConnectingIndicator: function(show) {
- this.classList.toggle('show-connecting-indicator', show);
- this.onContentChange_();
- },
-
- /**
- * Cancels error screen and drops to user pods.
- */
- cancel: function() {
- if ($('login-header-bar').allowCancel)
- Oobe.showUserPods();
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.css b/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.css
deleted file mode 100644
index 73084668e27..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.css
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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.
- */
-
-#fatal-error {
- padding: 50px 17px 17px;
- width: 722px; /* Should be the same as #gaia-signin. */
-}
-
-/* Size is set explicitly to make <img> consume the space before the image is
- loaded. This ensures correct screen's size calculation in
- DisplayManager.updateScreenSize. */
-#fatal-error-message-container img {
- height: 85px;
- width: 112px;
-}
-
-#fatal-error-message-container {
- text-align: center;
- width: 100%;
-}
-
-#fatal-error-button-strip {
- display: -webkit-box;
-}
-
-#fatal-error-button-strip-space-filler {
- -webkit-box-flex: 1;
-}
-
-.new-gaia-flow #fatal-error {
- height: 528px;
- width: 448px;
-}
-
-.new-gaia-flow #fatal-error-message-container,
-.new-gaia-flow #fatal-error-button-strip,
-.fatal-error .new-gaia-flow #step-logo,
-#fatal-error-card {
- display: none;
-}
-
-.new-gaia-flow #fatal-error-card {
- bottom: 0;
- display: block;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.html b/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.html
deleted file mode 100644
index 4bd8f973044..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<link rel="import" href="chrome://oobe/custom_elements.html">
-
-<div id="fatal-error" class="step hidden" hidden>
- <div class="step-contents">
- <div id="fatal-error-message-container">
- <div><img src="chrome://theme/IDR_FATAL_ERROR" alt></div>
- <p>
- <span id="fatal-error-message"></span>
- </p>
- </div>
- <div id="fatal-error-button-strip">
- <div id="fatal-error-button-strip-space-filler"></div>
- <button id="fatal-error-dismiss-button"
- i18n-content="fatalErrorDismissButton"></button>
- </div>
- </div>
- <notification-card id="fatal-error-card" type="fail">
- </notification-card>
-</div>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.js b/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.js
deleted file mode 100644
index c1c3ecbfca1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_fatal_error.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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.
-
-/**
- * @fileoverview A simple message box screen implementation.
- */
-
-login.createScreen('FatalErrorScreen', 'fatal-error', function() { return {
- EXTERNAL_API: [
- 'show'
- ],
-
- /**
- * Callback to run when the screen is dismissed.
- * @type {function()}
- */
- callback_: null,
-
- /**
- * Saved UI states to restore when this screen hides.
- * @type {Object}
- */
- savedUIStates_: {},
-
- /** @override */
- decorate: function() {
- $('fatal-error-dismiss-button').addEventListener(
- 'click', this.onDismiss_.bind(this));
- $('fatal-error-card').addEventListener(
- 'buttonclick', this.onDismiss_.bind(this));
- },
-
- /** @override */
- get defaultControl() {
- if (Oobe.isNewGaiaFlow()) {
- return $('fatal-error-card').submitButton;
- } else {
- return $('fatal-error-dismiss-button');
- }
- },
-
- /** @override */
- onBeforeShow: function() {
- this.savedUIStates_.progressDotHidden = $('progress-dots').hidden;
- $('progress-dots').hidden = true;
-
- this.savedUIStates_.headerHidden = Oobe.getInstance().headerHidden;
- Oobe.getInstance().headerHidden = true;
- },
-
- /** @override */
- onBeforeHide: function() {
- $('progress-dots').hidden = this.savedUIStates_.progressDotHidden;
- Oobe.getInstance().headerHidden = this.savedUIStates_.headerHidden;
- },
-
- /**
- * Invoked when user clicks on the ok button.
- */
- onDismiss_: function() {
- this.callback_();
- },
-
- /**
- * Shows the fatal error string screen.
- * @param {string} message The error message to show.
- * @param {function()} callback The callback to be invoked when the
- * screen is dismissed.
- */
- show: function(message, buttonLabel, callback) {
- if (Oobe.isNewGaiaFlow()) {
- $('fatal-error-card').textContent = message;
- $('fatal-error-card').buttonLabel = buttonLabel;
- } else {
- $('fatal-error-message').textContent = message;
- }
- this.callback_ = callback;
- Oobe.showScreen({id: SCREEN_FATAL_ERROR});
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.css b/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
deleted file mode 100644
index 8c4654b55b9..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
+++ /dev/null
@@ -1,286 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#gaia-signin {
- height: 609px; /* Should be the same as #user-image.loading min-heigth. */
- padding: 70px 17px 69px; /* Screen has no controls. */
- width: 722px; /* Should be the same as #user-image.loading width. */
-}
-
-#gaia-signin:not(.full-width).no-right-panel {
- width: 522px;
-}
-
-.new-gaia-flow #gaia-signin {
- height: 528px;
- padding: 0 0 0;
- width: 448px;
-}
-
-.new-gaia-flow .throbber {
- display: none;
-}
-
-#inner-container:not(.new-gaia-flow) throbber-notice {
- display: none;
-}
-
-#gaia-signin.full-width {
- padding: 75px 0 0;
-}
-
-.new-gaia-flow #gaia-signin.full-width {
- padding-top: 47px;
- width: 562px;
-}
-
-#signin-right {
- -webkit-margin-start: 30px;
- margin-top: 80px;
- top: 60px;
- width: 200px;
-}
-
-#signin-right,
-#enterprise-info-container,
-#saml-info-container {
- font-size: 12px;
-}
-
-/* For touch-optimized UI, make the links bigger. */
-@media (pointer:coarse) {
- #signin-right {
- font-size: 14px;
- }
-}
-
-.new-gaia-flow #signin-right,
-.no-right-panel #signin-right {
- display: none;
-}
-
-#close-button-item,
-#back-button-item {
- color: white;
- position: absolute;
- top: 10px;
- z-index: 1;
-}
-
-#close-button-item[disabled],
-#back-button-item[disabled] {
- color: rgb(127, 127, 127);
-}
-
-#close-button-item {
- right: 10px;
-}
-
-#back-button-item {
- left: 10px;
-}
-
-html[dir=rtl] #close-button-item {
- left: 10px;
- right: auto;
-}
-
-html[dir=rtl] #back-button-item {
- -webkit-transform: scaleX(-1);
- left: auto;
- right: 10px;
-}
-
-.loading #close-button-item,
-.new-gaia-flow .full-width #close-button-item {
- color: rgba(0, 0, 0, .54);
-}
-
-.new-gaia-flow .full-width #back-button-item {
- display: none;
-}
-
-.loading.auth-completed #close-button-item {
- display: none;
-}
-
-.signin-text {
- color: #666;
- margin-top: 20px;
-}
-
-.signin-link {
- color: rgb(37, 79, 155);
- cursor: pointer;
- text-decoration: none;
-}
-
-.signin-link:focus {
- -webkit-transition: outline-color 200ms;
- /* Note: May use 1px solid here. */
- outline-color: rgb(77, 144, 254);
-}
-
-#gaia-signin-form-container,
-#signin-frame {
- height: 100%;
-}
-
-.new-gaia-flow #gaia-signin-form-container {
- width: 100%;
-}
-
-.full-width #signin-frame,
-.full-width #gaia-signin-form-container {
- width: 100%;
-}
-
-.signin-divider {
- background: linear-gradient(
- to bottom,
- #e3e3e3,
- #cacaca 50%,
- #e3e3e3);
- border: none;
- width: 1px;
-}
-
-.gaia-signin .new-gaia-flow #step-logo,
-.gaia-signin .new-gaia-flow #gaia-signin-divider,
-.no-right-panel #gaia-signin-divider {
- display: none;
-}
-
-#signin-frame {
- background-color: transparent;
- margin-left: -44px;
- vertical-align: top;
- width: 400px;
-}
-
-webview#signin-frame {
- -webkit-transition: opacity 500ms ease-in;
- display: block;
- margin-left: 0;
- opacity: 0;
- overflow: hidden;
- padding: 0;
- width: 448px;
-}
-
-webview#signin-frame.show {
- -webkit-transition: opacity 500ms ease-out;
- opacity: 1;
-}
-
-/* Simpler alignment if no right panel. */
-.no-right-panel #signin-frame {
- margin-left: 0;
-}
-
-/* Position to be aligned with the login box in iframe */
-#login-box {
- height: 31px;
- position: absolute;
- top: 77px;
- visibility: hidden;
- z-index: -1;
-}
-
-#enterprise-info-container {
- bottom: 10px;
- left: 0;
- position: absolute;
- right: 0;
- text-align: center;
-}
-
-.new-gaia-flow #enterprise-info-container {
- display: none;
-}
-
-#enterprise-info-container #enterprise-info {
- display: inline-block;
-}
-
-#gaia-signin .step-contents {
- -webkit-box-pack: center;
- display: -webkit-box;
- height: 100%;
-}
-
-#createSupervisedUserSeparator {
- background-color: rgba(128, 128, 128, 0.3);
- height: 1px;
- width: 200px;
-}
-
-#createSupervisedUserLogo {
- font-weight: bold;
- margin-top: 16px;
-}
-
-#createSupervisedUserLogo img {
- vertical-align: text-bottom;
-}
-
-#createSupervisedUserLogo span {
- vertical-align: -10%;
-}
-
-#createSupervisedUserLinkPlaceholder,
-#createSupervisedUserNoManagerText {
- margin-top: 10px;
-}
-
-#saml-notice-container {
- left: 0;
- position: absolute;
- right: 0;
- text-align: center;
- top: 50px;
-}
-
-.new-gaia-flow #saml-notice-container {
- -webkit-margin-start: 19px;
- text-align: start;
- top: 15px;
-}
-
-#saml-notice-message {
- margin: 0 auto;
-}
-
-.new-gaia-flow #saml-notice-message {
- color: rgb(106, 106, 106);
- font-size: 13px;
-}
-
-#gaia-whitelist-error {
- bottom: 0;
- display: none;
- left: 0;
- position: absolute;
- right: 0;
- top: 0;
-}
-
-.new-gaia-flow #gaia-whitelist-error {
- display: block;
- visibility: hidden;
-}
-
-.new-gaia-flow .whitelist-error #gaia-whitelist-error {
- visibility: visible;
-}
-
-.new-gaia-flow #gaia-signin.whitelist-error .step-contents {
- visibility: hidden;
-}
-
-.new-gaia-flow #gaia-signin.whitelist-error .step-loading {
- visibility: hidden;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.html b/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.html
deleted file mode 100644
index 481dd5174dc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<link rel="import" href="chrome://oobe/custom_elements.html">
-
-<div class="step right hidden" id="gaia-signin" role="group"
- aria-live="polite" hidden>
- <div class="step-contents">
- <div id="gaia-signin-form-container">
- <div id="login-box"><!-- Aligned with the login box in iframe --></div>
- <iframe id="signin-frame" name="signin-frame" hidden
- src="about:blank"
- marginwidth="0"
- marginheight="0"
- frameborder="0"
- scrolling="no"></iframe>
- <offline-gaia id="offline-gaia" class="fit" hidden></offline-gaia>
- </div>
- <div id="gaia-signin-divider" class="signin-divider" hidden></div>
- <div id="signin-right" hidden>
- <div id="createAccount" class="signin-text"></div>
- <div id="guestSignin" class="signin-text"></div>
- <div id="createSupervisedUserPane" class="signin-text">
- <div id="createSupervisedUserSeparator"></div>
- <div id="createSupervisedUserLogo">
- <img src="chrome://theme/IDR_LEGACY_SUPERVISED_USER_ICON">
- <span i18n-content="createSupervisedUserFeatureName"></span>
- </div>
- <div id="createSupervisedUserLinkPlaceholder"></div>
- <div id="createSupervisedUserNoManagerText" hidden></div>
- </div>
- <div id="consumerManagementEnrollment" class="signin-text"></div>
- </div>
- </div>
- <div id="gaia-loading" class="step-loading">
- <div class="throbber"></div>
- <throbber-notice i18n-values="text:gaiaLoadingNewGaia"></throbber-notice>
- </div>
- <notification-card id="gaia-whitelist-error" type="fail"
- i18n-values="button-label:tryAgainButton;
- link-label:learnMoreButton">
- </notification-card>
- <div id="enterprise-info-container" hidden>
- <include src="enterprise_info.html">
- </div>
- <div id="saml-notice-container" hidden>
- <span id="saml-notice-message"></span>
- </div>
- <gaia-icon-button id="back-button-item" icon="arrow-back" hidden
- i18n-values="aria-label:backButton">
- </gaia-icon-button>
- <gaia-icon-button id="close-button-item" icon="close" hidden
- i18n-values="aria-label:closeButton">
- </gaia-icon-button>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
deleted file mode 100644
index 59af59ec07f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
+++ /dev/null
@@ -1,1040 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe signin screen implementation.
- */
-
-login.createScreen('GaiaSigninScreen', 'gaia-signin', function() {
- // GAIA animation guard timer. Started when GAIA page is loaded
- // (Authenticator 'ready' event) and is intended to guard against edge cases
- // when 'showView' message is not generated/received.
- /** @const */ var GAIA_ANIMATION_GUARD_MILLISEC = 300;
-
- // Maximum Gaia loading time in seconds.
- /** @const */ var MAX_GAIA_LOADING_TIME_SEC = 60;
-
- /** @const */ var HELP_TOPIC_ENTERPRISE_REPORTING = 2535613;
-
- // The help topic regarding user not being in the whitelist.
- /** @const */ var HELP_CANT_ACCESS_ACCOUNT = 188036;
-
- // Amount of time the user has to be idle for before showing the online login
- // page.
- /** @const */ var IDLE_TIME_UNTIL_EXIT_OFFLINE_IN_MILLISECONDS = 180 * 1000;
-
- // Approximate amount of time between checks to see if we should go to the
- // online login page when we're in the offline login page and the device is
- // online.
- /** @const */ var IDLE_TIME_CHECK_FREQUENCY = 5 * 1000;
-
- return {
- EXTERNAL_API: [
- 'loadAuthExtension',
- 'doReload',
- 'monitorOfflineIdle',
- 'onWebviewError',
- 'onFrameError',
- 'updateCancelButtonState',
- 'showWhitelistCheckFailedError',
- ],
-
- /**
- * Frame loading error code (0 - no error).
- * @type {number}
- * @private
- */
- error_: 0,
-
- /**
- * Saved gaia auth host load params.
- * @type {?string}
- * @private
- */
- gaiaAuthParams_: null,
-
- /**
- * Whether local version of Gaia page is used.
- * @type {boolean}
- * @private
- */
- isLocal_: false,
-
- /**
- * Whether new Gaia flow is active.
- * @type {boolean}
- */
- isNewGaiaFlow: false,
-
- /**
- * Email of the user, which is logging in using offline mode.
- * @type {string}
- */
- email: '',
-
- /**
- * Whether consumer management enrollment is in progress.
- * @type {boolean}
- * @private
- */
- isEnrollingConsumerManagement_: false,
-
- /**
- * Timer id of pending load.
- * @type {number}
- * @private
- */
- loadingTimer_: undefined,
-
- /**
- * Timer id of a guard timer that is fired in case 'showView' message
- * is not received from GAIA.
- * @type {number}
- * @private
- */
- loadAnimationGuardTimer_: undefined,
-
- /**
- * Whether we've processed 'showView' message - either from GAIA or from
- * guard timer.
- * @type {boolean}
- * @private
- */
- showViewProcessed_: undefined,
-
- /**
- * Whether user can cancel Gaia screen.
- * @type {boolean}
- * @private
- */
- cancelAllowed_: undefined,
-
- /**
- * Whether we should show user pods on the login screen.
- * @type {boolean}
- * @private
- */
- isShowUsers_: undefined,
-
- /**
- * SAML password confirmation attempt count.
- * @type {number}
- */
- samlPasswordConfirmAttempt_: 0,
-
- /**
- * Do we currently have a setTimeout task running that tries to bring us
- * back to the online login page after the user has idled for awhile? If so,
- * then this id will be non-negative.
- */
- tryToGoToOnlineLoginPageCallbackId_: -1,
-
- /**
- * The most recent period of time that the user has interacted. This is
- * only updated when the offline page is active and the device is online.
- */
- mostRecentUserActivity_: Date.now(),
-
- /**
- * Whether we should show webview based signin.
- * @type {boolean}
- * @private
- */
- isWebviewSignin: false,
-
- /** @override */
- decorate: function() {
- this.isWebviewSignin = loadTimeData.getValue('isWebviewSignin');
- if (this.isWebviewSignin) {
- // Replace iframe with webview.
- var webview = this.ownerDocument.createElement('webview');
- webview.id = 'signin-frame';
- webview.name = 'signin-frame';
- webview.hidden = true;
- $('signin-frame').parentNode.replaceChild(webview, $('signin-frame'));
- this.gaiaAuthHost_ = new cr.login.GaiaAuthHost(webview);
-
- $('offline-gaia').addEventListener('authCompleted',
- this.onAuthCompletedMessage_.bind(this));
- } else {
- this.gaiaAuthHost_ = new cr.login.GaiaAuthHost($('signin-frame'));
- }
- this.gaiaAuthHost_.addEventListener(
- 'ready', this.onAuthReady_.bind(this));
- this.gaiaAuthHost_.addEventListener(
- 'dialogShown', this.onDialogShown_.bind(this));
- this.gaiaAuthHost_.addEventListener(
- 'dialogHidden', this.onDialogHidden_.bind(this));
- this.gaiaAuthHost_.addEventListener(
- 'backButton', this.onBackButton_.bind(this));
- this.gaiaAuthHost_.addEventListener(
- 'showView', this.onShowView_.bind(this));
- this.gaiaAuthHost_.confirmPasswordCallback =
- this.onAuthConfirmPassword_.bind(this);
- this.gaiaAuthHost_.noPasswordCallback =
- this.onAuthNoPassword_.bind(this);
- this.gaiaAuthHost_.insecureContentBlockedCallback =
- this.onInsecureContentBlocked_.bind(this);
- this.gaiaAuthHost_.missingGaiaInfoCallback =
- this.missingGaiaInfo_.bind(this);
- this.gaiaAuthHost_.samlApiUsedCallback =
- this.samlApiUsed_.bind(this);
- this.gaiaAuthHost_.addEventListener('authDomainChange',
- this.onAuthDomainChange_.bind(this));
- this.gaiaAuthHost_.addEventListener('authFlowChange',
- this.onAuthFlowChange_.bind(this));
- this.gaiaAuthHost_.addEventListener('authCompleted',
- this.onAuthCompletedMessage_.bind(this));
- this.gaiaAuthHost_.addEventListener('loadAbort',
- this.onLoadAbortMessage_.bind(this));
- this.gaiaAuthHost_.addEventListener(
- 'identifierEntered', this.onIdentifierEnteredMessage_.bind(this));
-
- $('enterprise-info-hint-link').addEventListener('click', function(e) {
- chrome.send('launchHelpApp', [HELP_TOPIC_ENTERPRISE_REPORTING]);
- e.preventDefault();
- });
-
- $('back-button-item').addEventListener('click', function(e) {
- $('back-button-item').hidden = true;
- $('signin-frame').back();
- e.preventDefault();
- });
-
- $('close-button-item').addEventListener('click', function(e) {
- this.cancel();
- e.preventDefault();
- }.bind(this));
-
- $('gaia-whitelist-error').addEventListener('buttonclick', function() {
- this.showWhitelistCheckFailedError(false);
- }.bind(this));
-
- $('gaia-whitelist-error').addEventListener('linkclick', function() {
- chrome.send('launchHelpApp', [HELP_CANT_ACCESS_ACCOUNT]);
- });
-
- this.updateLocalizedContent();
- },
-
- /**
- * Header text of the screen.
- * @type {string}
- */
- get header() {
- return loadTimeData.getString('signinScreenTitle');
- },
-
- /**
- * Returns true if local version of Gaia is used.
- * @type {boolean}
- */
- get isLocal() {
- return this.isLocal_;
- },
-
- /**
- * Sets whether local version of Gaia is used.
- * @param {boolean} value Whether local version of Gaia is used.
- */
- set isLocal(value) {
- this.isLocal_ = value;
- if (this.isNewGaiaFlow) {
- $('signin-frame').hidden = this.isLocal_;
- $('offline-gaia').hidden = !this.isLocal_;
- }
- chrome.send('updateOfflineLogin', [value]);
- },
-
- /**
- * This enables or disables trying to go back to the online login page
- * after the user is idle for a few minutes, assuming that we're currently
- * in the offline one. This is only applicable when the offline page is
- * currently active. It is intended that when the device goes online, this
- * gets called with true; when it goes offline, this gets called with
- * false.
- */
- monitorOfflineIdle: function(shouldMonitor) {
- var ACTIVITY_EVENTS = ['click', 'mousemove', 'keypress'];
- var self = this;
-
- // updateActivityTime_ is used as a callback for addEventListener, so we
- // need the exact reference for removeEventListener. Because the callback
- // needs to access the |this| as scoped inside of this function, we create
- // a closure that uses the appropriate |this|.
- //
- // Unfourtantely, we cannot define this function inside of the JSON object
- // as then we have to no way to create to capture the correct |this|
- // reference. We define it here instead.
- if (!self.updateActivityTime_) {
- self.updateActivityTime_ = function() {
- self.mostRecentUserActivity_ = Date.now();
- };
- }
-
- // Begin monitoring.
- if (shouldMonitor) {
- // If we're not using the offline login page or we're already
- // monitoring, then we don't need to do anything.
- if (self.isLocal === false ||
- self.tryToGoToOnlineLoginPageCallbackId_ !== -1)
- return;
-
- self.mostRecentUserActivity_ = Date.now();
- ACTIVITY_EVENTS.forEach(function(event) {
- document.addEventListener(event, self.updateActivityTime_);
- });
-
- self.tryToGoToOnlineLoginPageCallbackId_ = setInterval(function() {
- // If we're not in the offline page or the signin page, then we want
- // to terminate monitoring.
- if (self.isLocal === false ||
- Oobe.getInstance().currentScreen.id != 'gaia-signin') {
- self.monitorOfflineIdle(false);
- return;
- }
-
- var idleDuration = Date.now() - self.mostRecentUserActivity_;
- if (idleDuration > IDLE_TIME_UNTIL_EXIT_OFFLINE_IN_MILLISECONDS) {
- self.isLocal = false;
- self.monitorOfflineIdle(false);
- }
- }, IDLE_TIME_CHECK_FREQUENCY);
- }
-
- // Stop monitoring.
- else {
- // We're not monitoring, so we don't need to do anything.
- if (self.tryToGoToOnlineLoginPageCallbackId_ === -1)
- return;
-
- ACTIVITY_EVENTS.forEach(function(event) {
- document.removeEventListener(event, self.updateActivityTime_);
- });
- clearInterval(self.tryToGoToOnlineLoginPageCallbackId_);
- self.tryToGoToOnlineLoginPageCallbackId_ = -1;
- }
- },
-
- /**
- * Shows/hides loading UI.
- * @param {boolean} show True to show loading UI.
- * @private
- */
- showLoadingUI_: function(show) {
- $('gaia-loading').hidden = !show;
- if (this.isNewGaiaFlow && this.isLocal) {
- $('offline-gaia').hidden = show;
- } else {
- $('signin-frame').hidden = show;
- }
- $('signin-right').hidden = show;
- $('enterprise-info-container').hidden = show;
- $('gaia-signin-divider').hidden = show;
- this.classList.toggle('loading', show);
- $('signin-frame').classList.remove('show');
- if (!show)
- this.classList.remove('auth-completed');
- },
-
- /**
- * Handler for Gaia loading timeout.
- * @private
- */
- onLoadingTimeOut_: function() {
- if (this != Oobe.getInstance().currentScreen)
- return;
- this.loadingTimer_ = undefined;
- chrome.send('showLoadingTimeoutError');
- },
-
- /**
- * Clears loading timer.
- * @private
- */
- clearLoadingTimer_: function() {
- if (this.loadingTimer_) {
- clearTimeout(this.loadingTimer_);
- this.loadingTimer_ = undefined;
- }
- },
-
- /**
- * Sets up loading timer.
- * @private
- */
- startLoadingTimer_: function() {
- this.clearLoadingTimer_();
- this.loadingTimer_ = setTimeout(this.onLoadingTimeOut_.bind(this),
- MAX_GAIA_LOADING_TIME_SEC * 1000);
- },
-
- /**
- * Handler for GAIA animation guard timer.
- * @private
- */
- onLoadAnimationGuardTimer_: function() {
- this.loadAnimationGuardTimer_ = undefined;
- this.onShowView_();
- },
-
- /**
- * Clears GAIA animation guard timer.
- * @private
- */
- clearLoadAnimationGuardTimer_: function() {
- if (this.loadAnimationGuardTimer_) {
- clearTimeout(this.loadAnimationGuardTimer_);
- this.loadAnimationGuardTimer_ = undefined;
- }
- },
-
- /**
- * Sets up GAIA animation guard timer.
- * @private
- */
- startLoadAnimationGuardTimer_: function() {
- this.clearLoadAnimationGuardTimer_();
- this.loadAnimationGuardTimer_ = setTimeout(
- this.onLoadAnimationGuardTimer_.bind(this),
- GAIA_ANIMATION_GUARD_MILLISEC);
- },
-
- /**
- * Whether Gaia is loading.
- * @type {boolean}
- */
- get loading() {
- return !$('gaia-loading').hidden;
- },
- set loading(loading) {
- if (loading == this.loading)
- return;
-
- this.showLoadingUI_(loading);
- },
-
- /**
- * Event handler that is invoked just before the frame is shown.
- * @param {string} data Screen init payload. Url of auth extension start
- * page.
- */
- onBeforeShow: function(data) {
- chrome.send('loginUIStateChanged', ['gaia-signin', true]);
- $('login-header-bar').signinUIState =
- this.isEnrollingConsumerManagement_ ?
- SIGNIN_UI_STATE.CONSUMER_MANAGEMENT_ENROLLMENT :
- SIGNIN_UI_STATE.GAIA_SIGNIN;
-
- // Ensure that GAIA signin (or loading UI) is actually visible.
- window.requestAnimationFrame(function() {
- chrome.send('loginVisible', ['gaia-loading']);
- });
- $('back-button-item').disabled = false;
- $('back-button-item').hidden = true;
- $('close-button-item').disabled = false;
- this.classList.toggle('loading', this.loading);
-
- // Button header is always visible when sign in is presented.
- // Header is hidden once GAIA reports on successful sign in.
- Oobe.getInstance().headerHidden = false;
- },
-
- onAfterShow: function(data) {
- if (!this.loading && this.isWebviewSignin) {
- if (this.isLocal)
- $('offline-gaia').focus();
- else
- $('signin-frame').focus();
- }
- },
-
- /**
- * Event handler that is invoked just before the screen is hidden.
- */
- onBeforeHide: function() {
- chrome.send('loginUIStateChanged', ['gaia-signin', false]);
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
- },
-
- /**
- * Loads the authentication extension into the iframe.
- * @param {Object} data Extension parameters bag.
- * @private
- */
- loadAuthExtension: function(data) {
- this.isNewGaiaFlow = data.useNewGaiaFlow;
- this.isLocal = data.isLocal;
- this.email = '';
-
- // Reset SAML
- this.classList.toggle('full-width', false);
- this.samlPasswordConfirmAttempt_ = 0;
-
- this.updateAuthExtension_(data);
-
- var params = {};
- for (var i in cr.login.GaiaAuthHost.SUPPORTED_PARAMS) {
- var name = cr.login.GaiaAuthHost.SUPPORTED_PARAMS[i];
- if (data[name])
- params[name] = data[name];
- }
-
- if (data.localizedStrings)
- params.localizedStrings = data.localizedStrings;
-
- if (this.isNewGaiaFlow) {
- $('inner-container').classList.add('new-gaia-flow');
- params.chromeType = data.chromeType;
- params.isNewGaiaFlowChromeOS = true;
- }
-
- if (data.gaiaEndpoint)
- params.gaiaPath = data.gaiaEndpoint;
-
- $('login-header-bar').newGaiaFlow = this.isNewGaiaFlow;
-
- // Screen size could have been changed because of 'new-gaia-flow' or
- // 'full-width' classes.
- if (Oobe.getInstance().currentScreen === this)
- Oobe.getInstance().updateScreenSize(this);
-
- if (data.forceReload ||
- JSON.stringify(this.gaiaAuthParams_) != JSON.stringify(params)) {
- this.error_ = 0;
-
- var authMode = cr.login.GaiaAuthHost.AuthMode.DEFAULT;
- if (data.useOffline)
- authMode = cr.login.GaiaAuthHost.AuthMode.OFFLINE;
-
- this.gaiaAuthParams_ = params;
- this.loading = true;
- this.startLoadingTimer_();
-
- if (this.isLocal && this.isNewGaiaFlow) {
- this.loadOffline(params);
- this.onAuthReady_();
- } else {
- this.gaiaAuthHost_.load(authMode,
- params,
- this.onAuthCompleted_.bind(this));
- }
- } else if (this.loading && this.error_) {
- // An error has occurred, so trying to reload.
- this.doReload();
- }
- },
-
- /**
- * Updates the authentication extension with new parameters, if needed.
- * @param {Object} data New extension parameters bag.
- * @private
- */
- updateAuthExtension_: function(data) {
- if (this.isNewGaiaFlow) {
- $('login-header-bar').showCreateSupervisedButton =
- data.supervisedUsersEnabled && data.supervisedUsersCanCreate;
- $('login-header-bar').showGuestButton = data.guestSignin;
- } else {
- $('createAccount').hidden = !data.createAccount;
- $('guestSignin').hidden = !data.guestSignin;
- $('createSupervisedUserPane').hidden = !data.supervisedUsersEnabled;
-
- $('createSupervisedUserLinkPlaceholder').hidden =
- !data.supervisedUsersCanCreate;
- $('createSupervisedUserNoManagerText').hidden =
- data.supervisedUsersCanCreate;
- $('createSupervisedUserNoManagerText').textContent =
- data.supervisedUsersRestrictionReason;
- }
-
- var isEnrollingConsumerManagement = data.isEnrollingConsumerManagement;
- $('consumerManagementEnrollment').hidden = !isEnrollingConsumerManagement;
-
- this.isShowUsers_ = data.isShowUsers;
- this.updateCancelButtonState();
-
- this.isEnrollingConsumerManagement_ = isEnrollingConsumerManagement;
-
- // Sign-in right panel is hidden if all of its items are hidden.
- var noRightPanel = $('createAccount').hidden &&
- $('guestSignin').hidden &&
- $('createSupervisedUserPane').hidden &&
- $('consumerManagementEnrollment').hidden;
- this.classList.toggle('no-right-panel', noRightPanel);
- this.classList.toggle('full-width', false);
- if (Oobe.getInstance().currentScreen === this)
- Oobe.getInstance().updateScreenSize(this);
- },
-
- /**
- * Updates [Cancel] button state. Allow cancellation of screen only when
- * user pods can be displayed.
- */
- updateCancelButtonState: function() {
- this.cancelAllowed_ = this.isLocal ||
- (this.isShowUsers_ && $('pod-row').pods.length);
- $('login-header-bar').allowCancel = this.cancelAllowed_;
- if (this.isNewGaiaFlow)
- $('close-button-item').hidden = !this.cancelAllowed_;
- },
-
- /**
- * Whether the current auth flow is SAML.
- */
- isSAML: function() {
- return this.gaiaAuthHost_.authFlow ==
- cr.login.GaiaAuthHost.AuthFlow.SAML;
- },
-
- /**
- * Invoked when the authDomain property is changed on the GAIA host.
- */
- onAuthDomainChange_: function() {
- $('saml-notice-message').textContent = loadTimeData.getStringF(
- 'samlNotice',
- this.gaiaAuthHost_.authDomain);
- },
-
- /**
- * Invoked when the authFlow property is changed on the GAIA host.
- * @param {Event} e Property change event.
- */
- onAuthFlowChange_: function(e) {
- var isSAML = this.isSAML();
-
- this.classList.toggle('no-right-panel', isSAML);
- this.classList.toggle('full-width', isSAML);
- $('saml-notice-container').hidden = !isSAML;
-
- if (Oobe.getInstance().currentScreen === this) {
- Oobe.getInstance().updateScreenSize(this);
- $('login-header-bar').allowCancel = isSAML || this.cancelAllowed_;
- if (this.isNewGaiaFlow)
- $('close-button-item').hidden = !(isSAML || this.cancelAllowed_);
- }
- },
-
- /**
- * Invoked when the auth host emits 'ready' event.
- * @private
- */
- onAuthReady_: function() {
- showViewProcessed_ = false;
- if (this.isNewGaiaFlow)
- this.startLoadAnimationGuardTimer_();
-
- this.clearLoadingTimer_();
- this.loading = false;
-
- if (!this.isNewGaiaFlow)
- this.onLoginUIVisible_();
-
- // Warm up the user images screen.
- Oobe.getInstance().preloadScreen({id: SCREEN_USER_IMAGE_PICKER});
- },
-
- /**
- * Invoked when the auth host emits 'dialogShown' event.
- * @private
- */
- onDialogShown_: function() {
- $('back-button-item').disabled = true;
- $('close-button-item').disabled = true;
- },
-
- /**
- * Invoked when the auth host emits 'dialogHidden' event.
- * @private
- */
- onDialogHidden_: function() {
- $('back-button-item').disabled = false;
- $('close-button-item').disabled = false;
- },
-
- /**
- * Invoked when the auth host emits 'backButton' event.
- * @private
- */
- onBackButton_: function(e) {
- $('back-button-item').hidden = !e.detail;
- $('login-header-bar').updateUI_();
- $('signin-frame').focus();
- },
-
- /**
- * Invoked when the auth host emits 'showView' event or when corresponding
- * guard time fires.
- * @private
- */
- onShowView_: function(e) {
- if (showViewProcessed_)
- return;
-
- showViewProcessed_ = true;
- this.clearLoadAnimationGuardTimer_();
- $('signin-frame').classList.add('show');
- this.onLoginUIVisible_();
- },
-
- /**
- * Called when UI is shown.
- * @private
- */
- onLoginUIVisible_: function() {
- // Show deferred error bubble.
- if (this.errorBubble_) {
- this.showErrorBubble(this.errorBubble_[0], this.errorBubble_[1]);
- this.errorBubble_ = undefined;
- }
-
- chrome.send('loginWebuiReady');
- chrome.send('loginVisible', ['gaia-signin']);
- },
-
- /**
- * Invoked when the user has successfully authenticated via SAML, the
- * principals API was not used and the auth host needs the user to confirm
- * the scraped password.
- * @param {string} email The authenticated user's e-mail.
- * @param {number} passwordCount The number of passwords that were scraped.
- * @private
- */
- onAuthConfirmPassword_: function(email, passwordCount) {
- this.loading = true;
- Oobe.getInstance().headerHidden = false;
-
- if (this.samlPasswordConfirmAttempt_ == 0)
- chrome.send('scrapedPasswordCount', [passwordCount]);
-
- if (this.samlPasswordConfirmAttempt_ < 2) {
- login.ConfirmPasswordScreen.show(
- email,
- this.samlPasswordConfirmAttempt_,
- this.onConfirmPasswordCollected_.bind(this));
- } else {
- chrome.send('scrapedPasswordVerificationFailed');
- this.showFatalAuthError(
- loadTimeData.getString('fatalErrorMessageVerificationFailed'),
- loadTimeData.getString('fatalErrorTryAgainButton'));
- }
- if (this.isNewGaiaFlow) {
- this.classList.toggle('no-right-panel', false);
- this.classList.toggle('full-width', false);
- }
- },
-
- /**
- * Invoked when the confirm password screen is dismissed.
- * @private
- */
- onConfirmPasswordCollected_: function(password) {
- this.samlPasswordConfirmAttempt_++;
- this.gaiaAuthHost_.verifyConfirmedPassword(password);
-
- // Shows signin UI again without changing states.
- Oobe.showScreen({id: SCREEN_GAIA_SIGNIN});
- },
-
- /**
- * Inovked when the user has successfully authenticated via SAML, the
- * principals API was not used and no passwords could be scraped.
- * @param {string} email The authenticated user's e-mail.
- */
- onAuthNoPassword_: function(email) {
- this.showFatalAuthError(
- loadTimeData.getString('fatalErrorMessageNoPassword'),
- loadTimeData.getString('fatalErrorTryAgainButton'));
- chrome.send('scrapedPasswordCount', [0]);
- },
-
- /**
- * Invoked when the authentication flow had to be aborted because content
- * served over an unencrypted connection was detected. Shows a fatal error.
- * This method is only called on Chrome OS, where the entire authentication
- * flow is required to be encrypted.
- * @param {string} url The URL that was blocked.
- */
- onInsecureContentBlocked_: function(url) {
- this.showFatalAuthError(
- loadTimeData.getStringF('fatalErrorMessageInsecureURL', url),
- loadTimeData.getString('fatalErrorDoneButton'));
- },
-
- /**
- * Shows the fatal auth error.
- * @param {string} message The error message to show.
- * @param {string} buttonLabel The label to display on dismiss button.
- */
- showFatalAuthError: function(message, buttonLabel) {
- login.FatalErrorScreen.show(message, buttonLabel, Oobe.showSigninUI);
- },
-
- /**
- * Show fatal auth error when information is missing from GAIA.
- */
- missingGaiaInfo_: function() {
- this.showFatalAuthError(
- loadTimeData.getString('fatalErrorMessageNoAccountDetails'),
- loadTimeData.getString('fatalErrorTryAgainButton'));
- },
-
- /**
- * Record that SAML API was used during sign-in.
- */
- samlApiUsed_: function() {
- chrome.send('usingSAMLAPI');
- },
-
- /**
- * Invoked when auth is completed successfully.
- * @param {!Object} credentials Credentials of the completed authentication.
- * @private
- */
- onAuthCompleted_: function(credentials) {
- if (credentials.useOffline) {
- this.email = credentials.email;
- chrome.send('authenticateUser',
- [credentials.email,
- credentials.password]);
- } else if (credentials.authCode) {
- if (credentials.hasOwnProperty('authCodeOnly') &&
- credentials.authCodeOnly) {
- chrome.send('completeAuthenticationAuthCodeOnly',
- [credentials.authCode]);
- } else {
- chrome.send('completeAuthentication', [
- credentials.gaiaId,
- credentials.email,
- credentials.password,
- credentials.authCode,
- credentials.usingSAML,
- credentials.gapsCookie
- ]);
- }
- } else {
- chrome.send('completeLogin',
- [credentials.gaiaId,
- credentials.email,
- credentials.password,
- credentials.usingSAML]);
- }
-
- this.loading = true;
- this.classList.add('auth-completed');
- // Now that we're in logged in state header should be hidden.
- Oobe.getInstance().headerHidden = true;
- // Clear any error messages that were shown before login.
- Oobe.clearErrors();
- },
-
- /**
- * Invoked when onAuthCompleted message received.
- * @param {!Object} e Payload of the received HTML5 message.
- * @private
- */
- onAuthCompletedMessage_: function(e) {
- this.onAuthCompleted_(e.detail);
- },
-
- /**
- * Invoked when onLoadAbort message received.
- * @param {!Object} e Payload of the received HTML5 message.
- * @private
- */
- onLoadAbortMessage_: function(e) {
- this.onWebviewError(e.detail);
- },
-
- /**
- * Invoked when identifierEntered message received.
- * @param {!Object} e Payload of the received HTML5 message.
- * @private
- */
- onIdentifierEnteredMessage_: function(e) {
- this.onIdentifierEntered(e.detail);
- },
-
- /**
- * Clears input fields and switches to input mode.
- * @param {boolean} takeFocus True to take focus.
- * @param {boolean} forceOnline Whether online sign-in should be forced.
- * If |forceOnline| is false previously used sign-in type will be used.
- */
- reset: function(takeFocus, forceOnline) {
- // Reload and show the sign-in UI if needed.
- if (takeFocus) {
- if (!forceOnline && this.isLocal) {
- // Show 'Cancel' button to allow user to return to the main screen
- // (e.g. this makes sense when connection is back).
- Oobe.getInstance().headerHidden = false;
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.GAIA_SIGNIN;
- // Do nothing, since offline version is reloaded after an error comes.
- } else {
- Oobe.showSigninUI();
- }
- }
- },
-
- /**
- * Reloads extension frame.
- */
- doReload: function() {
- if (this.isLocal)
- return;
- this.error_ = 0;
- this.gaiaAuthHost_.reload();
- this.loading = true;
- this.startLoadingTimer_();
- },
-
- /**
- * Updates localized content of the screen that is not updated via template.
- */
- updateLocalizedContent: function() {
- $('createAccount').innerHTML = loadTimeData.getStringF(
- 'createAccount',
- '<a id="createAccountLink" class="signin-link" href="#">',
- '</a>');
- $('guestSignin').innerHTML = loadTimeData.getStringF(
- 'guestSignin',
- '<a id="guestSigninLink" class="signin-link" href="#">',
- '</a>');
- $('createSupervisedUserLinkPlaceholder').innerHTML =
- loadTimeData.getStringF(
- 'createSupervisedUser',
- '<a id="createSupervisedUserLink" class="signin-link" href="#">',
- '</a>');
- $('consumerManagementEnrollment').innerHTML = loadTimeData.getString(
- 'consumerManagementEnrollmentSigninMessage');
- $('createAccountLink').addEventListener('click', function(e) {
- chrome.send('createAccount');
- e.preventDefault();
- });
- $('guestSigninLink').addEventListener('click', function(e) {
- chrome.send('launchIncognito');
- e.preventDefault();
- });
- $('createSupervisedUserLink').addEventListener('click', function(e) {
- chrome.send('showSupervisedUserCreationScreen');
- e.preventDefault();
- });
- },
-
- /**
- * Shows sign-in error bubble.
- * @param {number} loginAttempts Number of login attemps tried.
- * @param {HTMLElement} content Content to show in bubble.
- */
- showErrorBubble: function(loginAttempts, error) {
- if (this.isLocal) {
- $('add-user-button').hidden = true;
- $('cancel-add-user-button').hidden = false;
- // Reload offline version of the sign-in extension, which will show
- // error itself.
- chrome.send('offlineLogin', [this.email]);
- } else if (!this.loading) {
- // We want to show bubble near "Email" field, but we can't calculate
- // it's position because it is located inside iframe. So we only
- // can hardcode some constants.
- /** @const */ var ERROR_BUBBLE_OFFSET = 84;
- /** @const */ var ERROR_BUBBLE_PADDING = 0;
- $('bubble').showContentForElement($('login-box'),
- cr.ui.Bubble.Attachment.LEFT,
- error,
- ERROR_BUBBLE_OFFSET,
- ERROR_BUBBLE_PADDING);
- } else {
- // Defer the bubble until the frame has been loaded.
- this.errorBubble_ = [loginAttempts, error];
- }
- },
-
- /**
- * Called when user canceled signin.
- */
- cancel: function() {
- if (!this.cancelAllowed_) {
- // In OOBE signin screen, cancel is not allowed because there is
- // no other screen to show. If user is in middle of a saml flow,
- // reset signin screen to get out of the saml flow.
- if (this.isSAML())
- Oobe.resetSigninUI(true);
-
- return;
- }
-
- $('offline-gaia').switchToEmailCard();
-
- this.classList.remove('whitelist-error');
- Oobe.showUserPods();
- },
-
- /**
- * Handler for iframe's error notification coming from the outside.
- * For more info see C++ class 'WebUILoginView' which calls this method.
- * @param {number} error Error code.
- * @param {string} url The URL that failed to load.
- */
- onFrameError: function(error, url) {
- this.error_ = error;
- chrome.send('frameLoadingCompleted', [this.error_]);
- },
-
- /**
- * Handler for webview error handling.
- * @param {!Object} data Additional information about error event like:
- * {string} error Error code such as "ERR_INTERNET_DISCONNECTED".
- * {string} url The URL that failed to load.
- */
- onWebviewError: function(data) {
- chrome.send('webviewLoadAborted', [data.error]);
- },
-
- /**
- * Handler for identifierEntered event.
- * @param {!Object} data The identifier entered by user:
- * {string} accountIdentifier User identifier.
- */
- onIdentifierEntered: function(data) {
- chrome.send('identifierEntered', [data.accountIdentifier]);
- },
-
- /**
- * Sets welcome and enterpriseinfo strings for offline gaia.
- * Also sets callback and sends message whether we already have email and
- * should switch to the password screen with error.
- */
- loadOffline: function(params) {
- var offlineLogin = $('offline-gaia');
- var strings = params.localizedStrings;
- if ('stringEnterpriseInfo' in strings)
- offlineLogin.enterpriseInfo = strings['stringEnterpriseInfo'];
- if ('emailDomain' in params)
- offlineLogin.emailDomain = '@' + params['emailDomain'];
- offlineLogin.setEmail(params.email);
- },
-
- /**
- * Show/Hide error when user is not in whitelist. When UI is hidden
- * GAIA is reloaded.
- * @param {boolean} show Show/hide error UI.
- * @param {!Object} opt_data Optional additional information.
- */
- showWhitelistCheckFailedError: function(show, opt_data) {
- if (show) {
- var isManaged = opt_data && opt_data.enterpriseManaged;
- $('gaia-whitelist-error').textContent =
- loadTimeData.getValue(isManaged ? 'whitelistErrorEnterprise' :
- 'whitelistErrorConsumer');
- }
-
- this.classList.toggle('whitelist-error', show);
- this.loading = !show;
-
- if (!show)
- Oobe.showSigninUI();
- }
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.css b/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.css
deleted file mode 100644
index ca97922024d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.css
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#password-changed {
- height: 570px;
- /* Screen has no controls but has padding at the last text message */
- padding: 70px 17px 50px;
- width: 485px;
-}
-
-#password-changed-contents {
- color: #606060;
- margin: 20px 60px;
-}
-
-#oobe.password-changed .step-controls {
- -webkit-margin-start: 60px;
- justify-content: flex-start;
-}
-
-#password-changed-title {
- font-weight: bold;
-}
-
-#password-changed-description,
-#password-changed-more-info {
- margin-top: 25px;
-}
-
-#old-password-block {
- margin-top: 45px;
-}
-
-#old-password {
- padding: 4px 6px;
-}
-
-#password-changed-link-block {
- margin-top: 10px;
-}
-
-#password-changed-contents a {
- color: rgb(49, 106, 197);
- font-size: 12px;
- text-decoration: none;
-}
-
-#password-changed-contents a.disabled {
- color: gray;
-}
-
-#password-changed-contents a:focus {
- -webkit-transition: outline-color 200ms;
- /* Note: May use 1px solid here. */
- outline-color: rgb(77, 144, 254);
-}
-
-#password-changed input[type='password']:disabled {
- outline-color: rgb(77, 144, 254);
-}
-
-#password-changed-proceed-anyway-warning {
- -webkit-padding-start: 30px;
- background: url(chrome://theme/IDR_WARNING) left top /24px no-repeat;
- margin-top: 50px;
-}
-
-#password-changed.migrate #password-changed-proceed-anyway-warning,
-#password-changed.migrate #password-changed-proceed-button {
- display: none;
-}
-
-#password-changed.resync #old-password-block,
-#password-changed.resync #password-changed-link-block,
-#password-changed.resync #password-changed-ok-button {
- display: none;
-}
-
-#old-password-error {
- color: red;
- display: none;
- font-size: 12px;
- margin-top: 10px;
-}
-
-#password-changed.migrate.password-error #old-password-error {
- display: block;
-}
-
-.password-changed .new-gaia-flow #step-logo {
- display: none;
-}
-
-.new-gaia-flow #gaia-password-changed,
-.new-gaia-flow #password-changed {
- height: 528px;
- padding: 0;
- width: 448px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.html b/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.html
deleted file mode 100644
index 9f72357b81a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<link rel="import" href="chrome://oobe/custom_elements.html">
-<div id="password-changed" class="step faded hidden migrate" hidden>
- <div id="password-changed-contents" class="step-contents">
- <div id="password-changed-title" i18n-content="passwordChangedTitle">
- </div>
- <div id="password-changed-description" i18n-content="passwordChangedDesc">
- </div>
- <div id="password-changed-more-info"
- i18n-content="passwordChangedMoreInfo"></div>
- <div id="old-password-block">
- <input id="old-password" type="password" class="password"
- i18n-values="placeholder:oldPasswordHint">
- </div>
- <div id="old-password-error" i18n-content="oldPasswordIncorrect"></div>
- <div id="password-changed-link-block">
- <a id="password-changed-cant-remember-link" href="#"
- i18n-content="passwordChangedCantRemember"></a>
- </div>
- <div id="password-changed-proceed-anyway-warning"
- i18n-content="passwordChangedProceedAnyway"></div>
- </div>
- <div id="password-changed-controls" class="step-controls"></div>
- <gaia-password-changed id="gaia-password-changed" hidden>
- </gaia-password-changed>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.js b/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.js
deleted file mode 100644
index 8001a670d23..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_password_changed.js
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Password changed screen implementation.
- */
-
-login.createScreen('PasswordChangedScreen', 'password-changed', function() {
- return {
- EXTERNAL_API: [
- 'show'
- ],
-
- /** @override */
- decorate: function() {
- $('old-password').addEventListener(
- 'keydown', function(e) {
- $('password-changed').classList.remove('password-error');
- if (e.keyIdentifier == 'Enter') {
- $('password-changed').migrate();
- e.stopPropagation();
- }
- });
- $('old-password').addEventListener(
- 'keyup', function(e) {
- if ($('password-changed').disabled)
- return;
- $('password-changed-ok-button').disabled = this.value.length == 0;
- });
- $('password-changed-cant-remember-link').addEventListener(
- 'click', function(e) {
- if (this.classList.contains('disabled'))
- return;
- var screen = $('password-changed');
- if (screen.classList.contains('migrate')) {
- screen.classList.remove('migrate');
- screen.classList.add('resync');
- $('password-changed-proceed-button').focus();
- $('password-changed').classList.remove('password-error');
- $('old-password').value = '';
- $('password-changed-ok-button').disabled = true;
- }
- });
-
- var gaiaPasswordChanged = $('gaia-password-changed');
- gaiaPasswordChanged.addEventListener('cancel', function(e) {
- chrome.send('cancelPasswordChangedFlow',
- [$('gaia-password-changed').email]);
- gaiaPasswordChanged.reset();
- });
-
- gaiaPasswordChanged.addEventListener('passwordEnter', function(e) {
- chrome.send('migrateUserData', [e.detail.password]);
- });
-
- gaiaPasswordChanged.addEventListener('proceedAnyway', function() {
- chrome.send('resyncUserData');
- });
- },
-
- /**
- * Screen controls.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var buttons = [];
-
- var backButton = this.ownerDocument.createElement('button');
- backButton.id = 'password-changed-back-button';
- backButton.textContent =
- loadTimeData.getString('passwordChangedBackButton');
- backButton.addEventListener('click', function(e) {
- var screen = $('password-changed');
- if (screen.classList.contains('migrate')) {
- screen.cancel();
- } else {
- // Resync all data UI step.
- screen.classList.remove('resync');
- screen.classList.add('migrate');
- $('old-password').focus();
- }
- e.stopPropagation();
- });
- buttons.push(backButton);
-
- var okButton = this.ownerDocument.createElement('button');
- okButton.id = 'password-changed-ok-button';
- okButton.textContent = loadTimeData.getString('passwordChangedsOkButton');
- okButton.addEventListener('click', function(e) {
- $('password-changed').migrate();
- e.stopPropagation();
- });
- buttons.push(okButton);
-
- var proceedAnywayButton = this.ownerDocument.createElement('button');
- proceedAnywayButton.id = 'password-changed-proceed-button';
- proceedAnywayButton.textContent =
- loadTimeData.getString('proceedAnywayButton');
- proceedAnywayButton.addEventListener('click', function(e) {
- var screen = $('password-changed');
- if (screen.classList.contains('resync'))
- $('password-changed').resync();
- e.stopPropagation();
- });
- buttons.push(proceedAnywayButton);
-
- return buttons;
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- return $('old-password');
- },
-
- /**
- * True if the the screen is disabled (handles no user interaction).
- * @type {boolean}
- */
- disabled_: false,
- get disabled() {
- return this.disabled_;
- },
- set disabled(value) {
- this.disabled_ = value;
- var controls = this.querySelectorAll('button,input');
- for (var i = 0, control; control = controls[i]; ++i) {
- control.disabled = value;
- }
- $('login-header-bar').disabled = value;
- $('password-changed-cant-remember-link').classList[
- value ? 'add' : 'remove']('disabled');
- },
-
- /**
- * Cancels password migration and drops the user back to the login screen.
- */
- cancel: function() {
- this.disabled = true;
- chrome.send('cancelPasswordChangedFlow', ['']);
- },
-
- /**
- * Starts migration process using old password that user provided.
- */
- migrate: function() {
- if (!$('old-password').value) {
- $('old-password').focus();
- return;
- }
- this.disabled = true;
- chrome.send('migrateUserData', [$('old-password').value]);
- },
-
- onAfterShow: function(data) {
- if (Oobe.isNewGaiaFlow())
- $('gaia-password-changed').focus();
- },
-
- /**
- * Event handler that is invoked just before the screen is hidden.
- */
- onBeforeHide: function() {
- $('login-header-bar').disabled = false;
- },
-
- /**
- * Starts migration process by removing old cryptohome and re-syncing data.
- */
- resync: function() {
- this.disabled = true;
- chrome.send('resyncUserData');
- },
-
- /**
- * Show password changed screen.
- * @param {boolean} showError Whether to show the incorrect password error.
- */
- show: function(showError, email) {
- if (Oobe.isNewGaiaFlow()) {
- $('password-changed-contents').hidden = true;
- $('password-changed-controls').hidden = true;
- var gaiaPasswordChanged = $('gaia-password-changed');
- gaiaPasswordChanged.reset();
- gaiaPasswordChanged.hidden = false;
- if (showError)
- gaiaPasswordChanged.invalidate();
- if (email)
- gaiaPasswordChanged.email = email;
- } else {
- var screen = $('password-changed');
- screen.classList.toggle('password-error', showError);
- screen.classList.add('migrate');
- screen.classList.remove('resync');
- $('old-password').value = '';
- $('password-changed').disabled = false;
- }
- // We'll get here after the successful online authentication.
- // It assumes session is about to start so hides login screen controls.
- Oobe.getInstance().headerHidden = false;
- Oobe.showScreen({id: SCREEN_PASSWORD_CHANGED});
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.PASSWORD_CHANGED;
- if (!Oobe.isNewGaiaFlow())
- $('password-changed-ok-button').disabled = true;
- }
- };
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css b/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
deleted file mode 100644
index 30416a668c7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
+++ /dev/null
@@ -1,564 +0,0 @@
-/* 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.
- *
- * This is the stylesheet used by the Locally managed user creation flow screen.
- */
-
-#supervised-user-creation {
- height: 609px; /* Same size as GAIA sign in screen.*/
- padding: 0 0; /* Some screens have elements right next to borders. */
- width: 722px;
-}
-
-#supervised-user-creation .step-contents {
- height: 100%;
-}
-
-#supervised-user-creation .nofocus:focus {
- outline: none;
-}
-
-#supervised-user-creation .step-controls {
- -webkit-padding-end: 20px;
- align-items: center;
- bottom: 20px;
- display: flex;
- justify-content: flex-end;
-}
-
-#supervised-user-creation .controls-links {
- align-items: center;
- display: flex;
- justify-content: flex-start;
-}
-
-#supervised-user-creation .controls-buttons {
- align-items: center;
- display: flex;
- justify-content: flex-end;
-}
-
-#supervised-user-creation .logo-padded-text {
- padding: 0 17px 0;
-}
-
-#supervised-user-creation .marketing {
- background-color: green;
- height: 344px;
-}
-
-#supervised-user-creation .below-marketing {
- font-size: 12px;
- line-height: 18px;
- max-height: 184px;
- overflow-x: auto;
-}
-
-#supervised-user-creation .button-link {
- font-size: small;
- padding: 0 20px;
-}
-
-.below-marketing::-webkit-scrollbar {
- width: 8px;
-}
-
-.below-marketing::-webkit-scrollbar-track-piece {
- background: #eee;
-}
-
-.below-marketing::-webkit-scrollbar-thumb {
- background: #888;
-}
-
-#supervised-user-creation .page-no-marketing {
- height: 470px;
- padding: 70px 17px 0;
-}
-
-#supervised-user-creation .page-title {
- color: #000;
- font-size: 15px;
- line-height: 24px;
-}
-
-.below-marketing strong {
- color: #000;
- font-weight: bold;
-}
-
-#supervised-user-creation .page-title-explanation {
- color: rgb(150, 150, 150);
- font-size: 12px;
-}
-
-#supervised-user-creation .page-title.inline {
- -webkit-margin-end: 1ex;
- display: inline-block;
-}
-
-#supervised-user-creation .page-title-explanation.inline {
- display: inline;
-}
-
-#supervised-user-creation .page-title.centred {
- text-align: center;
-}
-
-#supervised-user-creation .page-title-explanation.centred {
- text-align: center;
-}
-
-#supervised-user-creation-intro-title {
- font-size: x-large;
- text-align: center;
-}
-
-#supervised-user-creation-intro-placeholder {
- background-color: gray;
- font-size: x-large;
- height: 150px;
- text-align: center;
-}
-
-#supervised-user-creation-intro .below-marketing {
- margin: 20px 21px 2px 40px;
-}
-
-#supervised-user-creation-intro-alternate-text {
- margin-bottom: 12px;
- margin-top: 12px;
-}
-
-#supervised-user-creation-intro-text-3 {
- margin-top: 12px;
-}
-
-#supervised-user-creation-created .below-marketing {
- margin: 20px 40px 0;
-}
-
-#supervised-user-creation-created-text-1 {
- max-width: 600px;
- word-wrap: break-word;
-}
-
-#supervised-user-creation-created-text-2 {
- margin-top: 20px;
- max-width: 600px;
- word-wrap: break-word;
-}
-
-#supervised-user-creation-created-text-3 {
- margin-top: 20px;
-}
-
-#supervised-user-creation-password-block,
-#supervised-user-creation-password-title {
- margin-top: 10px;
-}
-
-#supervised-user-creation-name-block {
- margin-bottom: 20px;
- margin-top: 10px;
-}
-
-input.supervised-user-creation-manager-password,
-#supervised-user-creation-name,
-#supervised-user-creation-password {
- padding: 4px 6px;
-}
-#supervised-user-creation-password-confirm {
- margin-top: 12px;
- padding: 4px 6px;
-}
-
-#supervised-user-creation-name-error {
- visibility: hidden;
-}
-
-#supervised-user-creation-name-error.error {
- color: rgb(207, 93, 70);
- padding-left: 28px;
- visibility: visible;
-}
-
-#supervised-user-creation-managers-block {
- display: flex;
- flex-direction: column;
- height: 100%;
-}
-
-#supervised-user-creation-managers-pane {
- border: 1px solid #c8c8c8;
- height: 100%;
- margin-top: 20px;
- overflow-x: hidden;
- overflow-y: auto;
-}
-
-/* This class will be set for elements with hide-on-import class by JS when
- * page is used in 'import' mode
- */
-#supervised-user-creation .hidden-on-import {
- display: none;
-}
-
-#supervised-user-creation-error {
- padding: 175px 120px 0;
- text-align: center;
-}
-
-#supervised-user-creation-error .error-icon {
- margin-bottom: 50px;
-}
-
-#supervised-user-creation-error .error-message-paragraph {
- margin-bottom: 40px;
- margin-top: 30px;
-}
-
-.screen-control-button {
- margin-left: 10px !important;
-}
-
-.import-pod {
- height: 32px;
- opacity: 0.8;
- padding: 20px;
- width: 646px;
-}
-
-.import-pod .import-pod-name {
- color: #000;
- display: inline-block;
- height: 32px;
- max-height: 32px;
- padding-top: 6px;
- vertical-align: top;
-}
-
-.import-pod.imported .import-pod-name {
- color: rgb(141, 141, 141);
-}
-
-.import-pod .import-pod-image {
- border: 1px solid gray;
- display: inline;
- height: 30px;
- width: 30px;
-}
-
-.manager-pod {
- height: 32px;
- opacity: 0.8;
- padding: 20px;
- width: 646px;
-}
-
-.manager-pod .supervised-user-creation-manager-info-block {
- float: left;
- min-height: 32px;
-}
-
-.manager-pod .supervised-user-creation-manager-image {
- border: 1px solid gray;
- display: inline-block;
- height: 30px;
- width: 30px;
-}
-
-.manager-pod .supervised-user-creation-manager-info {
- display: inline-block;
- margin: 0 8px;
- min-height: 32px;
-}
-
-.manager-pod .supervised-user-creation-manager-info-text {
- display: inline-block;
- min-height: 32px;
- vertical-align: top;
-}
-
-.manager-pod .password-block {
- float: right;
-}
-
-.manager-pod .supervised-user-creation-manager-email {
- color: #666;
- font-size: small;
- max-height: 16px;
-}
-
-.manager-pod .supervised-user-creation-manager-name {
- color: #000;
- font-size: small;
- max-height: 16px;
-}
-
-#supervised-user-creation-status {
- margin: 4px 10px;
-}
-
-#supervised-user-creation-status .error {
- color: rgb(207, 93, 70);
-}
-
-#supervised-user-creation-status .spinner-wrapper {
- -webkit-margin-start: 3px;
- display: inline-flex;
- margin-top: 3px;
- vertical-align: top;
-}
-
-#supervised-user-creation-status .id-text {
- display: inline-flex;
- margin-top: 1px;
- max-width: 480px;
- vertical-align: baseline;
-}
-
-.manager-pod.focused {
- background-color: rgb(66, 129, 244);
- opacity: 1;
-}
-
-.import-pod.imported.focused {
- background-color: rgb(238, 238, 238);
- opacity: 1;
-}
-
-.import-pod.focused {
- background-color: rgb(66, 129, 244);
- opacity: 1;
-}
-
-.manager-pod.focused .supervised-user-creation-manager-email {
- color: #fff;
-}
-
-.manager-pod.focused .supervised-user-creation-manager-name {
- color: #fff;
-}
-
-#supervised-user-creation-import-pane {
- border: 1px solid #c8c8c8;
- height: 400px;
- overflow-x: hidden;
- overflow-y: auto;
-}
-
-#supervised-user-creation-import .page-title-explanation {
- padding-bottom: 10px;
- padding-top: 6px;
-}
-
-.manager-pod .password-error,
-#supervised-user-creation .password-error,
-#supervised-user-creation .duplicate-name {
- border: 1px solid red !important;
-}
-
-#supervised-user-creation-image-picker {
- margin-top: 16px;
-}
-
-#supervised-user-creation-image-grid {
- -webkit-user-drag: none;
- -webkit-user-select: none;
- display: inline-block;
- height: 264px;
- margin: 0;
- outline: none;
- overflow: hidden;
- padding: 0;
- width: 400px;
-}
-
-#supervised-user-creation-image-grid img {
- background-color: white;
- height: 50px;
- vertical-align: middle;
- width: 50px;
-}
-
-#supervised-user-creation-image-grid > li {
- border: 1px solid rgba(0, 0, 0, 0.15);
- border-radius: 4px;
- display: inline-block;
- margin: 4px;
- padding: 3px;
-}
-
-#supervised-user-creation-image-grid [selected] {
- border: 2px solid rgb(0, 102, 204);
- padding: 2px;
-}
-
-#supervised-user-creation-image-preview {
- float: right;
- margin: 4px;
- max-width: 220px;
- position: relative;
-}
-
-html[dir=rtl] #supervised-user-creation-image-preview {
- float: left;
-}
-
-#supervised-user-creation-image-preview-img {
- display: block;
- max-height: 220px;
- max-width: 220px;
-}
-
-#supervised-user-creation-image-preview-img.animated-transform {
- -webkit-transition: -webkit-transform 200ms linear;
-}
-
-.camera.live #supervised-user-creation-image-preview-img {
- display: none;
-}
-
-.camera.flip-x #supervised-user-creation-image-preview-img {
- -webkit-transform: rotateY(180deg);
-}
-
-.default-image #supervised-user-creation-image-preview-img {
- background: white;
- border: solid 1px #cacaca;
- border-radius: 4px;
- padding: 2px;
-}
-
-.supervised-user-creation-image-stream-area {
- display: none;
- padding: 0;
- position: relative;
-}
-
-.camera.live .supervised-user-creation-image-stream-area {
- display: block;
-}
-
-#supervised-user-creation-image-stream-crop {
- -webkit-transition: -webkit-transform 200ms linear;
- height: 220px;
- overflow: hidden;
- position: relative;
- width: 220px;
-}
-
-.flip-x #supervised-user-creation-image-stream-crop {
- -webkit-transform: rotateY(180deg);
-}
-
-.supervised-user-creation-image-stream {
- border: solid 1px #cacaca;
- height: 220px;
- /* Center image for 4:3 aspect ratio. */
- left: -16.6%;
- position: absolute;
- visibility: hidden;
-}
-
-.online .supervised-user-creation-image-stream {
- visibility: visible;
-}
-
-#supervised-user-creation-image-preview-caption {
- color: dimGray;
- font-size: smaller;
- margin: 8px 4px;
-}
-
-.camera #supervised-user-creation-image-preview-caption {
- display: none;
-}
-
-#supervised-user-creation-flip-photo {
- -webkit-transition: opacity 75ms linear;
- background: url(chrome://theme/IDR_MIRROR_FLIP) no-repeat;
- border: none;
- bottom: 44px; /* 8px + image bottom. */
- display: block;
- height: 32px;
- opacity: 0;
- position: absolute;
- right: 8px;
- width: 32px;
-}
-
-/* TODO(merkulova): remove when webkit crbug.com/126479 is fixed. */
-.flip-trick {
- -webkit-transform: translateZ(1px);
-}
-
-html[dir=rtl] #supervised-user-creation-flip-photo {
- left: 8px;
- right: auto;
-}
-
-/* "Flip photo" button is hidden during flip animation. */
-.camera.online:not(.animation) #supervised-user-creation-flip-photo,
-.camera.phototaken:not(.animation) #supervised-user-creation-flip-photo {
- opacity: 0.75;
-}
-
-#supervised-user-creation-discard-photo,
-#supervised-user-creation-take-photo {
- display: none;
- height: 25px;
- margin: 4px 1px;
- padding: 0;
- width: 220px;
-}
-
-.camera:not(.live) #supervised-user-creation-discard-photo {
- background: url(chrome://theme/IDR_USER_IMAGE_RECYCLE)
- no-repeat center center;
- display: block;
-}
-
-.camera.live.online #supervised-user-creation-take-photo {
- background: url(chrome://theme/IDR_USER_IMAGE_CAPTURE)
- no-repeat center -1px;
- display: block;
-}
-
-#supervised-user-creation-image-preview .perspective-box {
- -webkit-perspective: 600px;
- border: solid 1px #cacaca;
- border-radius: 4px;
- padding: 2px;
- width: 220px;
-}
-
-.supervised-user-creation-image-stream-area .spinner {
- display: none;
- height: 44px;
- left: 50%;
- margin-left: -22px;
- margin-top: -22px;
- position: absolute;
- top: 50%;
- width: 44px;
-}
-
-.camera.live:not(.online) .supervised-user-creation-image-stream-area .spinner {
- display: block;
-}
-
-#supervised-user-creation-close-button-item {
- color: rgba(0, 0, 0, .54);
- position: absolute;
- right: 10px;
- top: 10px;
- z-index: 1;
-}
-
-html[dir=rtl] #supervised-user-creation-close-button-item {
- left: 10px;
- right: auto;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.html b/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.html
deleted file mode 100644
index bfa6ee72bbd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.html
+++ /dev/null
@@ -1,164 +0,0 @@
-<link rel="import" href="chrome://oobe/custom_elements.html">
-<div class="step hidden" id="supervised-user-creation" hidden>
- <div class="step-contents">
- <div id="supervised-user-creation-intro" class="step-no-logo">
- <div id="supervised-user-creation-marketing-intro"
- class="marketing">
- <img src="chrome://theme/IDR_SUPERVISED_ILLUSTRATION_START" alt="">
- </div>
- <div class="below-marketing">
- <div class="page-title"
- i18n-content="createSupervisedUserIntroTextTitle">
- </div>
- <div id="supervised-user-creation-intro-alternate-text"></div>
- <div i18n-content="createSupervisedUserIntroText2"></div>
- <div id="supervised-user-creation-intro-text-3"
- i18n-content="createSupervisedUserIntroText3"></div>
- </div>
- </div>
- <div id="supervised-user-creation-manager" class="page-no-marketing" hidden>
- <div id="supervised-user-creation-managers-block" hidden>
- <div class="logo-padded-text">
- <div class="page-title"
- i18n-content="createSupervisedUserPickManagerTitle"></div>
- <div class="page-title-explanation"
- i18n-content="createSupervisedUserPickManagerTitleExplanation">
- </div>
- </div>
- <div id="supervised-user-creation-managers-pane"></div>
- </div>
- </div>
- <div id="supervised-user-creation-username" class="page-no-marketing"
- role="group"
- i18n-values="aria-label:createSupervisedUserNameAccessibleTitle" hidden>
- <div class="logo-padded-text">
- <div class="hide-on-import">
- <div class="page-title inline"
- i18n-content="createSupervisedUserNameTitle"></div>
- <div id="supervised-user-creation-name-explanation"
- class="page-title-explanation inline"></div>
- </div>
- <div id="supervised-user-creation-name-block" class="hide-on-import">
- <input id="supervised-user-creation-name" type="text" maxlength="50"
- i18n-values="placeholder:createSupervisedUserNameHint" />
- <span id="supervised-user-creation-name-error" class="no-error">
- </span>
- </div>
- <div>
- <div class="page-title inline"
- i18n-content="createSupervisedUserPasswordTitle"></div>
- <div class="page-title-explanation inline"
- i18n-content="createSupervisedUserPasswordExplanation"></div>
- </div>
- <div id="supervised-user-creation-password-block">
- <div>
- <input id="supervised-user-creation-password" type="password"
- i18n-values="placeholder:createSupervisedUserPasswordHint" />
- </div>
- <div>
- <input id="supervised-user-creation-password-confirm"
- type="password"
- i18n-values="
- placeholder:createSupervisedUserPasswordConfirmHint" />
- </div>
- </div>
- </div>
- <div id="supervised-user-creation-image-picker" class="logo-padded-text">
- <grid id="supervised-user-creation-image-grid">
- </grid>
- <div id="supervised-user-creation-image-preview">
- <img id="supervised-user-creation-image-preview-img" alt="">
- <div class="supervised-user-creation-image-stream-area">
- <div class="perspective-box">
- <div id="supervised-user-creation-image-stream-crop">
- <video class="supervised-user-creation-image-stream" autoplay>
- </video>
- </div>
- </div>
- <div class="spinner"></div>
- </div>
- <p id="supervised-user-creation-image-preview-caption"></p>
- <button id="supervised-user-creation-flip-photo"
- class="custom-appearance"
- i18n-values="title:flipPhoto"></button>
- <button id="supervised-user-creation-discard-photo"
- i18n-values="title:discardPhoto"></button>
- <button id="supervised-user-creation-take-photo"
- i18n-values="title:takePhoto"></button>
- </div>
- </div>
- </div>
-
- <div id="supervised-user-creation-import" class="page-no-marketing" hidden>
- <div class="logo-padded-text">
- <div>
- <div class="page-title"
- i18n-content="importExistingSupervisedUserTitle"></div>
- <div class="page-title-explanation"
- i18n-content="importExistingSupervisedUserText"></div>
- </div>
- </div>
- <div id="supervised-user-creation-import-pane"></div>
- </div>
-
- <div id="supervised-user-creation-created" class="step-no-logo" hidden>
- <div class="marketing">
- <img src="chrome://theme/IDR_SUPERVISED_ILLUSTRATION_DONE" alt="">
- </div>
- <div class="below-marketing">
- <div>
- <div id="supervised-user-creation-created-text-1"
- class="page-title"></div>
- <div id="supervised-user-creation-created-text-2"></div>
- <div id="supervised-user-creation-created-text-3"></div>
- </div>
- </div>
- </div>
- <div id="supervised-user-creation-error" hidden>
- <img alt class="error-icon" src="chrome://theme/IDR_TECHNICAL_ERROR">
- <div id="supervised-user-creation-error-title" class="error-title"></div>
- <div id="supervised-user-creation-error-text"
- class="error-message-paragraph"></div>
- <div>
- <button id="supervised-user-creation-error-button"
- class="custom-appearance button-fancy button-blue">
- </button>
- </div>
- </div>
- </div>
- <div id="supervised-user-creation-controls" class="step-controls">
- </div>
- <div class="template-import-supervised-user-link button-link" hidden>
- <a href="#" class="signin-link" i18n-content="importSupervisedUserLink"></a>
- </div>
- <div class="template-create-supervised-user-link button-link" hidden>
- <a href="#" class="signin-link" i18n-content="createSupervisedUserLink"></a>
- </div>
- <div class="template-status-container status-container" hidden>
- <span class="id-text"></span>
- <div class="spinner-wrapper">
- <div class="id-spinner inline-spinner"></div>
- </div>
- </div>
- <div id="supervised-user-creation-manager-template" hidden
- class="manager-pod">
- <div class="supervised-user-creation-manager-info-block">
- <img class="supervised-user-creation-manager-image" alt="">
- <div class="supervised-user-creation-manager-info-text">
- <div class="supervised-user-creation-manager-name"></div>
- <div class="supervised-user-creation-manager-email"></div>
- </div>
- </div>
- <div class="password-block" hidden>
- <input class="supervised-user-creation-manager-password" type="password"
- i18n-values="placeholder:createSupervisedUserManagerPasswordHint" />
- </div>
- </div>
- <div id="supervised-user-creation-import-template" hidden class="import-pod">
- <img class="import-pod-image"></img>
- <div class="import-pod-name"></div>
- </div>
- <gaia-icon-button id="supervised-user-creation-close-button-item"
- icon="close" i18n-values="aria-label:closeButton">
- </gaia-icon-button>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js b/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
deleted file mode 100644
index cc0bc952e8e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
+++ /dev/null
@@ -1,1601 +0,0 @@
-// 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.
-
-/**
- * @fileoverview Legacy supervised user creation flow screen.
- */
-
-login.createScreen('SupervisedUserCreationScreen',
- 'supervised-user-creation', function() {
- var MAX_NAME_LENGTH = 50;
- var UserImagesGrid = options.UserImagesGrid;
- var ButtonImages = UserImagesGrid.ButtonImages;
-
- var ManagerPod = cr.ui.define(function() {
- var node = $('supervised-user-creation-manager-template').cloneNode(true);
- node.removeAttribute('id');
- node.removeAttribute('hidden');
- return node;
- });
-
- ManagerPod.userImageSalt_ = {};
-
- /**
- * UI element for displaying single account in list of possible managers for
- * new supervised user.
- * @type {Object}
- */
- ManagerPod.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- /** @override */
- decorate: function() {
- // Mousedown has to be used instead of click to be able to prevent 'focus'
- // event later.
- this.addEventListener('mousedown',
- this.handleMouseDown_.bind(this));
- var screen = $('supervised-user-creation');
- var managerPod = this;
- var managerPodList = screen.managerList_;
- var hideManagerPasswordError = function(element) {
- managerPod.passwordElement.classList.remove('password-error');
- $('bubble').hide();
- };
-
- screen.configureTextInput(
- this.passwordElement,
- screen.updateNextButtonForManager_.bind(screen),
- screen.validIfNotEmpty_.bind(screen),
- function(element) {
- screen.getScreenButton('next').focus();
- },
- hideManagerPasswordError);
-
- this.passwordElement.addEventListener('keydown', function(e) {
- switch (e.keyIdentifier) {
- case 'Up':
- managerPodList.selectNextPod(-1);
- e.stopPropagation();
- break;
- case 'Down':
- managerPodList.selectNextPod(+1);
- e.stopPropagation();
- break;
- }
- });
- },
-
- /**
- * Updates UI elements from user data.
- */
- update: function() {
- this.imageElement.src = 'chrome://userimage/' + this.user.username +
- '?id=' + ManagerPod.userImageSalt_[this.user.username];
-
- this.nameElement.textContent = this.user.displayName;
- this.emailElement.textContent = this.user.emailAddress;
- },
-
- showPasswordError: function() {
- this.passwordElement.classList.add('password-error');
- $('bubble').showTextForElement(
- this.passwordElement,
- loadTimeData.getString(
- 'createSupervisedUserWrongManagerPasswordText'),
- cr.ui.Bubble.Attachment.BOTTOM,
- 24, 4);
- },
-
- /**
- * Brings focus to password field.
- */
- focusInput: function() {
- this.passwordElement.focus();
- },
-
- /**
- * Gets image element.
- * @type {!HTMLImageElement}
- */
- get imageElement() {
- return this.querySelector('.supervised-user-creation-manager-image');
- },
-
- /**
- * Gets name element.
- * @type {!HTMLDivElement}
- */
- get nameElement() {
- return this.querySelector('.supervised-user-creation-manager-name');
- },
-
- /**
- * Gets e-mail element.
- * @type {!HTMLDivElement}
- */
- get emailElement() {
- return this.querySelector('.supervised-user-creation-manager-email');
- },
-
- /**
- * Gets password element.
- * @type {!HTMLDivElement}
- */
- get passwordElement() {
- return this.querySelector('.supervised-user-creation-manager-password');
- },
-
- /**
- * Gets password enclosing block.
- * @type {!HTMLDivElement}
- */
- get passwordBlock() {
- return this.querySelector('.password-block');
- },
-
- /** @override */
- handleMouseDown_: function(e) {
- this.parentNode.selectPod(this);
- // Prevent default so that we don't trigger 'focus' event.
- e.preventDefault();
- },
-
- /**
- * The user that this pod represents.
- * @type {!Object}
- */
- user_: undefined,
- get user() {
- return this.user_;
- },
- set user(userDict) {
- this.user_ = userDict;
- this.update();
- },
- };
-
- var ManagerPodList = cr.ui.define('div');
-
- /**
- * UI element for selecting manager account for new supervised user.
- * @type {Object}
- */
- ManagerPodList.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- selectedPod_: null,
-
- /** @override */
- decorate: function() {
- },
-
- /**
- * Returns all the pods in this pod list.
- * @type {NodeList}
- */
- get pods() {
- return this.children;
- },
-
- addPod: function(manager) {
- var managerPod = new ManagerPod({user: manager});
- this.appendChild(managerPod);
- managerPod.update();
- },
-
- clearPods: function() {
- this.innerHTML = '';
- this.selectedPod_ = null;
- },
-
- selectPod: function(podToSelect) {
- if ((this.selectedPod_ == podToSelect) && !!podToSelect) {
- podToSelect.focusInput();
- return;
- }
- this.selectedPod_ = podToSelect;
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
- if (pod != podToSelect) {
- pod.classList.remove('focused');
- pod.passwordElement.value = '';
- pod.passwordBlock.hidden = true;
- }
- }
- if (!podToSelect)
- return;
- podToSelect.classList.add('focused');
- podToSelect.passwordBlock.hidden = false;
- podToSelect.passwordElement.value = '';
- podToSelect.focusInput();
- chrome.send('managerSelectedOnSupervisedUserCreationFlow',
- [podToSelect.user.username]);
- },
-
- /**
- * Select pod next to currently selected one in given |direction|.
- * @param {integer} direction - +1 for selecting pod below current, -1 for
- * selecting pod above current.
- * @type {boolean} returns if selected pod has changed.
- */
- selectNextPod: function(direction) {
- if (!this.selectedPod_)
- return false;
- var index = -1;
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
- if (pod == this.selectedPod_) {
- index = i;
- break;
- }
- }
- if (-1 == index)
- return false;
- index = index + direction;
- if (index < 0 || index >= this.pods.length)
- return false;
- this.selectPod(this.pods[index]);
- return true;
- }
- };
-
- var ImportPod = cr.ui.define(function() {
- var node = $('supervised-user-creation-import-template').cloneNode(true);
- node.removeAttribute('id');
- node.removeAttribute('hidden');
- return node;
- });
-
- /**
- * UI element for displaying single supervised user in list of possible users
- * for importing existing users.
- * @type {Object}
- */
- ImportPod.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- /** @override */
- decorate: function() {
- // Mousedown has to be used instead of click to be able to prevent 'focus'
- // event later.
- this.addEventListener('mousedown', this.handleMouseDown_.bind(this));
- var screen = $('supervised-user-creation');
- var importList = screen.importList_;
- },
-
- /**
- * Updates UI elements from user data.
- */
- update: function() {
- this.imageElement.src = this.user.avatarurl;
- this.nameElement.textContent = this.user.name;
- if (this.user.exists) {
- if (this.user.conflict == 'imported') {
- this.nameElement.textContent =
- loadTimeData.getStringF('importUserExists', this.user.name);
- } else {
- this.nameElement.textContent =
- loadTimeData.getStringF('importUsernameExists', this.user.name);
- }
- }
- this.classList.toggle('imported', this.user.exists);
- },
-
- /**
- * Gets image element.
- * @type {!HTMLImageElement}
- */
- get imageElement() {
- return this.querySelector('.import-pod-image');
- },
-
- /**
- * Gets name element.
- * @type {!HTMLDivElement}
- */
- get nameElement() {
- return this.querySelector('.import-pod-name');
- },
-
- /** @override */
- handleMouseDown_: function(e) {
- this.parentNode.selectPod(this);
- // Prevent default so that we don't trigger 'focus' event.
- e.preventDefault();
- },
-
- /**
- * The user that this pod represents.
- * @type {Object}
- */
- user_: undefined,
-
- get user() {
- return this.user_;
- },
-
- set user(userDict) {
- this.user_ = userDict;
- this.update();
- },
- };
-
- var ImportPodList = cr.ui.define('div');
-
- /**
- * UI element for selecting existing supervised user for import.
- * @type {Object}
- */
- ImportPodList.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- selectedPod_: null,
-
- /** @override */
- decorate: function() {
- this.setAttribute('tabIndex', 0);
- this.classList.add('nofocus');
- var importList = this;
- var screen = $('supervised-user-creation');
-
- this.addEventListener('focus', function(e) {
- if (importList.selectedPod_ == null) {
- if (importList.pods.length > 0)
- importList.selectPod(importList.pods[0]);
- }
- });
-
- this.addEventListener('keydown', function(e) {
- switch (e.keyIdentifier) {
- case 'Up':
- importList.selectNextPod(-1);
- e.stopPropagation();
- break;
- case 'Enter':
- if (importList.selectedPod_ != null)
- screen.importSupervisedUser_();
- e.stopPropagation();
- break;
- case 'Down':
- importList.selectNextPod(+1);
- e.stopPropagation();
- break;
- }
- });
- },
-
- /**
- * Returns all the pods in this pod list.
- * @type {NodeList}
- */
- get pods() {
- return this.children;
- },
-
- /**
- * Returns selected pod.
- * @type {Node}
- */
- get selectedPod() {
- return this.selectedPod_;
- },
-
- addPod: function(user) {
- var importPod = new ImportPod({user: user});
- this.appendChild(importPod);
- importPod.update();
- },
-
- clearPods: function() {
- this.innerHTML = '';
- this.selectedPod_ = null;
- },
-
- scrollIntoView: function(pod) {
- scroller = this.parentNode;
- var itemHeight = pod.getBoundingClientRect().height;
- var scrollTop = scroller.scrollTop;
- var top = pod.offsetTop - scroller.offsetTop;
- var clientHeight = scroller.clientHeight;
-
- var self = scroller;
-
- // Function to adjust the tops of viewport and row.
- function scrollToAdjustTop() {
- self.scrollTop = top;
- return true;
- };
- // Function to adjust the bottoms of viewport and row.
- function scrollToAdjustBottom() {
- var cs = getComputedStyle(self);
- var paddingY = parseInt(cs.paddingTop, 10) +
- parseInt(cs.paddingBottom, 10);
-
- if (top + itemHeight > scrollTop + clientHeight - paddingY) {
- self.scrollTop = top + itemHeight - clientHeight + paddingY;
- return true;
- }
- return false;
- };
-
- // Check if the entire of given indexed row can be shown in the viewport.
- if (itemHeight <= clientHeight) {
- if (top < scrollTop)
- return scrollToAdjustTop();
- if (scrollTop + clientHeight < top + itemHeight)
- return scrollToAdjustBottom();
- } else {
- if (scrollTop < top)
- return scrollToAdjustTop();
- if (top + itemHeight < scrollTop + clientHeight)
- return scrollToAdjustBottom();
- }
- return false;
- },
-
- /**
- * @param {Element} podToSelect - pod to select, can be null.
- */
- selectPod: function(podToSelect) {
- if ((this.selectedPod_ == podToSelect) && !!podToSelect) {
- return;
- }
- this.selectedPod_ = podToSelect;
- for (var i = 0; i < this.pods.length; i++) {
- var pod = this.pods[i];
- if (pod != podToSelect)
- pod.classList.remove('focused');
- }
- if (!podToSelect)
- return;
- podToSelect.classList.add('focused');
- podToSelect.focus();
- var screen = $('supervised-user-creation');
- if (!this.selectedPod_) {
- screen.getScreenButton('import').disabled = true;
- } else {
- screen.getScreenButton('import').disabled =
- this.selectedPod_.user.exists;
- if (!this.selectedPod_.user.exists) {
- chrome.send('userSelectedForImportInSupervisedUserCreationFlow',
- [podToSelect.user.id]);
- }
- }
- },
-
- selectNextPod: function(direction) {
- if (!this.selectedPod_)
- return false;
- var index = -1;
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
- if (pod == this.selectedPod_) {
- index = i;
- break;
- }
- }
- if (-1 == index)
- return false;
- index = index + direction;
- if (index < 0 || index >= this.pods.length)
- return false;
- this.selectPod(this.pods[index]);
- return true;
- },
-
- selectUser: function(user_id) {
- for (var i = 0, pod; pod = this.pods[i]; ++i) {
- if (pod.user.id == user_id) {
- this.selectPod(pod);
- this.scrollIntoView(pod);
- break;
- }
- }
- },
- };
-
- return {
- EXTERNAL_API: [
- 'loadManagers',
- 'setCameraPresent',
- 'setDefaultImages',
- 'setExistingSupervisedUsers',
- 'showErrorPage',
- 'showIntroPage',
- 'showManagerPage',
- 'showManagerPasswordError',
- 'showPage',
- 'showPasswordError',
- 'showProgress',
- 'showStatusError',
- 'showTutorialPage',
- 'showUsernamePage',
- 'supervisedUserNameError',
- 'supervisedUserNameOk',
- 'supervisedUserSuggestImport',
- ],
-
- lastVerifiedName_: null,
- lastIncorrectUserName_: null,
- managerList_: null,
- importList_: null,
-
- currentPage_: null,
- imagesRequested_: false,
-
- // Contains data that can be auto-shared with handler.
- context_: {},
-
- /** @override */
- decorate: function() {
- this.managerList_ = new ManagerPodList();
- $('supervised-user-creation-managers-pane').appendChild(
- this.managerList_);
-
- this.importList_ = new ImportPodList();
- $('supervised-user-creation-import-pane').appendChild(this.importList_);
-
- var userNameField = $('supervised-user-creation-name');
- var passwordField = $('supervised-user-creation-password');
- var password2Field = $('supervised-user-creation-password-confirm');
-
- var creationScreen = this;
-
- var hideUserPasswordError = function(element) {
- $('bubble').hide();
- $('supervised-user-creation-password').classList.remove(
- 'password-error');
- };
-
- this.configureTextInput(userNameField,
- this.checkUserName_.bind(this),
- this.validIfNotEmpty_.bind(this),
- function(element) {
- passwordField.focus();
- },
- this.clearUserNameError_.bind(this));
- this.configureTextInput(passwordField,
- this.updateNextButtonForUser_.bind(this),
- this.validIfNotEmpty_.bind(this),
- function(element) {
- password2Field.focus();
- },
- hideUserPasswordError);
- this.configureTextInput(password2Field,
- this.updateNextButtonForUser_.bind(this),
- this.validIfNotEmpty_.bind(this),
- function(element) {
- creationScreen.getScreenButton('next').focus();
- },
- hideUserPasswordError);
-
- this.getScreenButton('error').addEventListener('click', function(e) {
- creationScreen.handleErrorButtonPressed_();
- e.stopPropagation();
- });
-
- /*
- TODO(antrim) : this is an explicit code duplications with UserImageScreen.
- It should be removed by issue 251179.
- */
- var imageGrid = this.getScreenElement('image-grid');
- UserImagesGrid.decorate(imageGrid);
-
- // Preview image will track the selected item's URL.
- var previewElement = this.getScreenElement('image-preview');
- previewElement.oncontextmenu = function(e) { e.preventDefault(); };
-
- imageGrid.previewElement = previewElement;
- imageGrid.selectionType = 'default';
- imageGrid.flipPhotoElement = this.getScreenElement('flip-photo');
-
- imageGrid.addEventListener('activate',
- this.handleActivate_.bind(this));
- imageGrid.addEventListener('select',
- this.handleSelect_.bind(this));
- imageGrid.addEventListener('phototaken',
- this.handlePhotoTaken_.bind(this));
- imageGrid.addEventListener('photoupdated',
- this.handlePhotoUpdated_.bind(this));
- // Set the title for camera item in the grid.
- imageGrid.setCameraTitles(
- loadTimeData.getString('takePhoto'),
- loadTimeData.getString('photoFromCamera'));
-
- this.getScreenElement('take-photo').addEventListener(
- 'click', this.handleTakePhoto_.bind(this));
- this.getScreenElement('discard-photo').addEventListener(
- 'click', this.handleDiscardPhoto_.bind(this));
-
- // Toggle 'animation' class for the duration of WebKit transition.
- this.getScreenElement('flip-photo').addEventListener(
- 'click', this.handleFlipPhoto_.bind(this));
- this.getScreenElement('image-stream-crop').addEventListener(
- 'webkitTransitionEnd', function(e) {
- previewElement.classList.remove('animation');
- });
- this.getScreenElement('image-preview-img').addEventListener(
- 'webkitTransitionEnd', function(e) {
- previewElement.classList.remove('animation');
- });
-
- $('supervised-user-creation-close-button-item').addEventListener(
- 'click', function(e) {
- this.cancel();
- e.preventDefault();
- }.bind(this));
- },
-
- buttonIds: [],
-
- /**
- * Creates button for adding to controls.
- * @param {string} buttonId -- id for button, have to be unique within
- * screen. Actual id will be prefixed with screen name and appended with
- * '-button'. Use getScreenButton(buttonId) to find it later.
- * @param {string} i18nPrefix -- screen prefix for i18n values.
- * @param {function} callback -- will be called on button press with
- * buttonId parameter.
- * @param {array} pages -- list of pages where this button should be
- * displayed.
- * @param {array} classes -- list of additional CSS classes for button.
- */
- makeButton: function(buttonId, i18nPrefix, callback, pages, classes) {
- var capitalizedId = buttonId.charAt(0).toUpperCase() + buttonId.slice(1);
- this.buttonIds.push(buttonId);
- var result = this.ownerDocument.createElement('button');
- result.id = this.name() + '-' + buttonId + '-button';
- result.classList.add('screen-control-button');
- for (var i = 0; i < classes.length; i++) {
- result.classList.add(classes[i]);
- }
- result.textContent = loadTimeData.
- getString(i18nPrefix + capitalizedId + 'ButtonTitle');
- result.addEventListener('click', function(e) {
- callback(buttonId);
- e.stopPropagation();
- });
- result.pages = pages;
- return result;
- },
-
- /**
- * Simple validator for |configureTextInput|.
- * Element is considered valid if it has any text.
- * @param {Element} element - element to be validated.
- * @return {boolean} - true, if element has any text.
- */
- validIfNotEmpty_: function(element) {
- return (element.value.length > 0);
- },
-
- /**
- * Configure text-input |element|.
- * @param {Element} element - element to be configured.
- * @param {function(element)} inputChangeListener - function that will be
- * called upon any button press/release.
- * @param {function(element)} validator - function that will be called when
- * Enter is pressed. If it returns |true| then advance to next element.
- * @param {function(element)} moveFocus - function that will determine next
- * element and move focus to it.
- * @param {function(element)} errorHider - function that is called upon
- * every button press, so that any associated error can be hidden.
- */
- configureTextInput: function(element,
- inputChangeListener,
- validator,
- moveFocus,
- errorHider) {
- element.addEventListener('keydown', function(e) {
- if (e.keyIdentifier == 'Enter') {
- var dataValid = true;
- if (validator)
- dataValid = validator(element);
- if (!dataValid) {
- element.focus();
- } else {
- if (moveFocus)
- moveFocus(element);
- }
- e.stopPropagation();
- return;
- }
- if (errorHider)
- errorHider(element);
- if (inputChangeListener)
- inputChangeListener(element);
- });
- element.addEventListener('keyup', function(e) {
- if (inputChangeListener)
- inputChangeListener(element);
- });
- },
-
- /**
- * Makes element from template.
- * @param {string} templateId -- template will be looked up within screen
- * by class with name "template-<templateId>".
- * @param {string} elementId -- id for result, uinque within screen. Actual
- * id will be prefixed with screen name. Use getScreenElement(id) to find
- * it later.
- */
- makeFromTemplate: function(templateId, elementId) {
- var templateClassName = 'template-' + templateId;
- var templateNode = this.querySelector('.' + templateClassName);
- var screenPrefix = this.name() + '-';
- var result = templateNode.cloneNode(true);
- result.classList.remove(templateClassName);
- result.id = screenPrefix + elementId;
- return result;
- },
-
- /**
- * @param {string} buttonId -- id of button to be found,
- * @return {Element} button created by makeButton with given buttonId.
- */
- getScreenButton: function(buttonId) {
- var fullId = this.name() + '-' + buttonId + '-button';
- return this.getScreenElement(buttonId + '-button');
- },
-
- /**
- * @param {string} elementId -- id of element to be found,
- * @return {Element} button created by makeFromTemplate with elementId.
- */
- getScreenElement: function(elementId) {
- var fullId = this.name() + '-' + elementId;
- return $(fullId);
- },
-
- /**
- * Screen controls.
- * @type {!Array} Array of Buttons.
- */
- get buttons() {
- var links = this.ownerDocument.createElement('div');
- var buttons = this.ownerDocument.createElement('div');
- links.classList.add('controls-links');
- buttons.classList.add('controls-buttons');
-
- var importLink = this.makeFromTemplate('import-supervised-user-link',
- 'import-link');
- importLink.hidden = true;
- links.appendChild(importLink);
-
- var linkElement = importLink.querySelector('.signin-link');
- linkElement.addEventListener('click',
- this.importLinkPressed_.bind(this));
-
- var createLink = this.makeFromTemplate('create-supervised-user-link',
- 'create-link');
- createLink.hidden = true;
- links.appendChild(createLink);
-
- var status = this.makeFromTemplate('status-container', 'status');
- buttons.appendChild(status);
-
- linkElement = createLink.querySelector('.signin-link');
- linkElement.addEventListener('click',
- this.createLinkPressed_.bind(this));
-
- buttons.appendChild(this.makeButton(
- 'start',
- 'supervisedUserCreationFlow',
- this.startButtonPressed_.bind(this),
- ['intro'],
- ['custom-appearance', 'button-fancy', 'button-blue']));
-
- buttons.appendChild(this.makeButton(
- 'prev',
- 'supervisedUserCreationFlow',
- this.prevButtonPressed_.bind(this),
- ['manager'],
- []));
-
- buttons.appendChild(this.makeButton(
- 'next',
- 'supervisedUserCreationFlow',
- this.nextButtonPressed_.bind(this),
- ['manager', 'username'],
- []));
-
- buttons.appendChild(this.makeButton(
- 'import',
- 'supervisedUserCreationFlow',
- this.importButtonPressed_.bind(this),
- ['import', 'import-password'],
- []));
-
- buttons.appendChild(this.makeButton(
- 'gotit',
- 'supervisedUserCreationFlow',
- this.gotItButtonPressed_.bind(this),
- ['created'],
- ['custom-appearance', 'button-fancy', 'button-blue']));
- return [links, buttons];
- },
-
- /**
- * Does sanity check and calls backend with current user name/password pair
- * to authenticate manager. May result in showManagerPasswordError.
- * @private
- */
- validateAndLogInAsManager_: function() {
- var selectedPod = this.managerList_.selectedPod_;
- if (null == selectedPod)
- return;
-
- var managerId = selectedPod.user.username;
- var managerDisplayId = selectedPod.user.emailAddress;
- var managerPassword = selectedPod.passwordElement.value;
- if (managerPassword.length == 0)
- return;
- if (this.disabled)
- return;
- this.disabled = true;
- this.context_.managerId = managerId;
- this.context_.managerDisplayId = managerDisplayId;
- this.context_.managerName = selectedPod.user.displayName;
- chrome.send('authenticateManagerInSupervisedUserCreationFlow',
- [managerId, managerPassword]);
- },
-
- /**
- * Does sanity check and calls backend with user display name/password pair
- * to create a user.
- * @private
- */
- validateAndCreateSupervisedUser_: function() {
- var firstPassword = $('supervised-user-creation-password').value;
- var secondPassword =
- $('supervised-user-creation-password-confirm').value;
- var userName = $('supervised-user-creation-name').value;
- if (firstPassword != secondPassword) {
- this.showPasswordError(loadTimeData.getString(
- 'createSupervisedUserPasswordMismatchError'));
- return;
- }
- if (this.disabled)
- return;
- this.disabled = true;
-
- this.context_.supervisedName = userName;
- chrome.send('specifySupervisedUserCreationFlowUserData',
- [userName, firstPassword]);
- },
-
- /**
- * Does sanity check and calls backend with selected existing supervised
- * user id to import user.
- * @private
- */
- importSupervisedUser_: function() {
- if (this.disabled)
- return;
- if (this.currentPage_ == 'import-password') {
- var firstPassword = this.getScreenElement('password').value;
- var secondPassword = this.getScreenElement('password-confirm').value;
- if (firstPassword != secondPassword) {
- this.showPasswordError(loadTimeData.getString(
- 'createSupervisedUserPasswordMismatchError'));
- return;
- }
- var userId = this.context_.importUserId;
- this.disabled = true;
- chrome.send('importSupervisedUserWithPassword',
- [userId, firstPassword]);
- return;
- } else {
- var selectedPod = this.importList_.selectedPod_;
- if (!selectedPod)
- return;
- var user = selectedPod.user;
- var userId = user.id;
-
- this.context_.importUserId = userId;
- this.context_.supervisedName = user.name;
- this.context_.selectedImageUrl = user.avatarurl;
- if (!user.needPassword) {
- this.disabled = true;
- chrome.send('importSupervisedUser', [userId]);
- } else {
- this.setVisiblePage_('import-password');
- }
- }
- },
-
- /**
- * Calls backend part to check if current user name is valid/not taken.
- * Results in a call to either supervisedUserNameOk or
- * supervisedUserNameError.
- * @private
- */
- checkUserName_: function() {
- var userName = this.getScreenElement('name').value;
-
- // Avoid flickering
- if (userName == this.lastIncorrectUserName_ ||
- userName == this.lastVerifiedName_) {
- return;
- }
- if (userName.length > 0) {
- chrome.send('checkSupervisedUserName', [userName]);
- } else {
- this.nameErrorVisible = false;
- this.lastVerifiedName_ = null;
- this.lastIncorrectUserName_ = null;
- this.updateNextButtonForUser_();
- }
- },
-
- /**
- * Called by backend part in case of successful name validation.
- * @param {string} name - name that was validated.
- */
- supervisedUserNameOk: function(name) {
- this.lastVerifiedName_ = name;
- this.lastIncorrectUserName_ = null;
- if ($('supervised-user-creation-name').value == name)
- this.clearUserNameError_();
- this.updateNextButtonForUser_();
- },
-
- /**
- * Called by backend part in case of name validation failure.
- * @param {string} name - name that was validated.
- * @param {string} errorText - reason why this name is invalid.
- */
- supervisedUserNameError: function(name, errorText) {
- this.disabled = false;
- this.lastIncorrectUserName_ = name;
- this.lastVerifiedName_ = null;
-
- var userNameField = $('supervised-user-creation-name');
- if (userNameField.value == this.lastIncorrectUserName_) {
- this.nameErrorVisible = true;
- $('bubble').showTextForElement(
- $('supervised-user-creation-name'),
- errorText,
- cr.ui.Bubble.Attachment.RIGHT,
- 12, 4);
- this.setButtonDisabledStatus('next', true);
- }
- },
-
- supervisedUserSuggestImport: function(name, user_id) {
- this.disabled = false;
- this.lastIncorrectUserName_ = name;
- this.lastVerifiedName_ = null;
-
- var userNameField = $('supervised-user-creation-name');
- var creationScreen = this;
-
- if (userNameField.value == this.lastIncorrectUserName_) {
- this.nameErrorVisible = true;
- var link = this.ownerDocument.createElement('div');
- link.innerHTML = loadTimeData.getStringF(
- 'importBubbleText',
- '<a class="signin-link" href="#">',
- name,
- '</a>');
- link.querySelector('.signin-link').addEventListener('click',
- function(e) {
- creationScreen.handleSuggestImport_(user_id);
- e.stopPropagation();
- });
- $('bubble').showContentForElement(
- $('supervised-user-creation-name'),
- cr.ui.Bubble.Attachment.RIGHT,
- link,
- 12, 4);
- this.setButtonDisabledStatus('next', true);
- }
- },
-
- /**
- * Clears user name error, if name is no more guaranteed to be invalid.
- * @private
- */
- clearUserNameError_: function() {
- // Avoid flickering
- if ($('supervised-user-creation-name').value ==
- this.lastIncorrectUserName_) {
- return;
- }
- this.nameErrorVisible = false;
- },
-
- /**
- * Called by backend part in case of password validation failure.
- * @param {string} errorText - reason why this password is invalid.
- */
- showPasswordError: function(errorText) {
- $('bubble').showTextForElement(
- $('supervised-user-creation-password'),
- errorText,
- cr.ui.Bubble.Attachment.RIGHT,
- 12, 4);
- $('supervised-user-creation-password').classList.add('password-error');
- $('supervised-user-creation-password').focus();
- this.disabled = false;
- this.setButtonDisabledStatus('next', true);
- },
-
- /**
- * True if user name error should be displayed.
- * @type {boolean}
- */
- set nameErrorVisible(value) {
- $('supervised-user-creation-name').
- classList.toggle('duplicate-name', value);
- if (!value)
- $('bubble').hide();
- },
-
- /**
- * Updates state of Continue button after minimal checks.
- * @return {boolean} true, if form seems to be valid.
- * @private
- */
- updateNextButtonForManager_: function() {
- var selectedPod = this.managerList_.selectedPod_;
- canProceed = null != selectedPod &&
- selectedPod.passwordElement.value.length > 0;
-
- this.setButtonDisabledStatus('next', !canProceed);
- return canProceed;
- },
-
- /**
- * Updates state of Continue button after minimal checks.
- * @return {boolean} true, if form seems to be valid.
- * @private
- */
- updateNextButtonForUser_: function() {
- var firstPassword = this.getScreenElement('password').value;
- var secondPassword = this.getScreenElement('password-confirm').value;
- var userName = this.getScreenElement('name').value;
-
- var passwordOk = (firstPassword.length > 0) &&
- (firstPassword.length == secondPassword.length);
-
- if (this.currentPage_ == 'import-password') {
- this.setButtonDisabledStatus('import', !passwordOk);
- return passwordOk;
- }
- var imageGrid = this.getScreenElement('image-grid');
- var imageChosen = !(imageGrid.selectionType == 'camera' &&
- imageGrid.cameraLive);
- var canProceed =
- passwordOk &&
- (userName.length > 0) &&
- this.lastVerifiedName_ &&
- (userName == this.lastVerifiedName_) &&
- imageChosen;
-
- this.setButtonDisabledStatus('next', !canProceed);
- return canProceed;
- },
-
- showSelectedManagerPasswordError_: function() {
- var selectedPod = this.managerList_.selectedPod_;
- selectedPod.showPasswordError();
- selectedPod.passwordElement.value = '';
- selectedPod.focusInput();
- this.updateNextButtonForManager_();
- },
-
- /**
- * Enables one particular subpage and hides the rest.
- * @param {string} visiblePage - name of subpage.
- * @private
- */
- setVisiblePage_: function(visiblePage) {
- this.disabled = false;
- this.updateText_();
- $('bubble').hide();
- if (!this.imagesRequested_) {
- chrome.send('supervisedUserGetImages');
- this.imagesRequested_ = true;
- }
- var pageNames = ['intro',
- 'manager',
- 'username',
- 'import',
- 'error',
- 'created'];
- var pageButtons = {'intro' : 'start',
- 'error' : 'error',
- 'import' : 'import',
- 'import-password' : 'import',
- 'created' : 'gotit'};
- this.hideStatus_();
- var pageToDisplay = visiblePage;
- if (visiblePage == 'import-password')
- pageToDisplay = 'username';
-
- for (i in pageNames) {
- var pageName = pageNames[i];
- var page = $('supervised-user-creation-' + pageName);
- page.hidden = (pageName != pageToDisplay);
- if (pageName == pageToDisplay)
- $('step-logo').hidden = page.classList.contains('step-no-logo');
- }
-
- for (i in this.buttonIds) {
- var button = this.getScreenButton(this.buttonIds[i]);
- button.hidden = button.pages.indexOf(visiblePage) < 0;
- button.disabled = false;
- }
-
- var pagesWithCancel = ['intro', 'manager', 'username', 'import-password',
- 'error', 'import'];
- $('login-header-bar').allowCancel =
- pagesWithCancel.indexOf(visiblePage) > -1;
- $('cancel-add-user-button').disabled = false;
-
- this.getScreenElement('import-link').hidden = true;
- this.getScreenElement('create-link').hidden = true;
-
- if (pageButtons[visiblePage])
- this.getScreenButton(pageButtons[visiblePage]).focus();
-
- this.currentPage_ = visiblePage;
-
- if (visiblePage == 'manager' || visiblePage == 'intro') {
- $('supervised-user-creation-password').classList.remove(
- 'password-error');
- if (this.managerList_.pods.length > 0)
- this.managerList_.selectPod(this.managerList_.pods[0]);
- $('login-header-bar').updateUI_();
- }
-
- if (visiblePage == 'username' || visiblePage == 'import-password') {
- var elements = this.getScreenElement(pageToDisplay).
- querySelectorAll('.hide-on-import');
- for (var i = 0; i < elements.length; i++) {
- elements[i].classList.toggle('hidden-on-import',
- visiblePage == 'import-password');
- }
- }
- if (visiblePage == 'username') {
- var imageGrid = this.getScreenElement('image-grid');
- // select some image.
- var selected = this.imagesData_[
- Math.floor(Math.random() * this.imagesData_.length)];
- this.context_.selectedImageUrl = selected.url;
- imageGrid.selectedItemUrl = selected.url;
- chrome.send('supervisedUserSelectImage',
- [selected.url, 'default']);
- this.getScreenElement('image-grid').redraw();
- this.checkUserName_();
- this.updateNextButtonForUser_();
- this.getScreenElement('name').focus();
- this.getScreenElement('import-link').hidden =
- this.importList_.pods.length == 0;
- } else if (visiblePage == 'import-password') {
- var imageGrid = this.getScreenElement('image-grid');
- var selected;
- if ('selectedImageUrl' in this.context_) {
- selected = this.context_.selectedImageUrl;
- } else {
- // select some image.
- selected = this.imagesData_[
- Math.floor(Math.random() * this.imagesData_.length)].url;
- chrome.send('supervisedUserSelectImage',
- [selected, 'default']);
- }
- imageGrid.selectedItemUrl = selected;
- this.getScreenElement('image-grid').redraw();
-
- this.updateNextButtonForUser_();
-
- this.getScreenElement('password').focus();
- this.getScreenElement('import-link').hidden = true;
- } else {
- this.getScreenElement('image-grid').stopCamera();
- }
- if (visiblePage == 'import') {
- this.getScreenElement('create-link').hidden = false;
- this.getScreenButton('import').disabled =
- !this.importList_.selectedPod_ ||
- this.importList_.selectedPod_.user.exists;
- }
- $('supervised-user-creation-close-button-item').hidden =
- (visiblePage == 'created');
-
- chrome.send('currentSupervisedUserPage', [this.currentPage_]);
- },
-
- setButtonDisabledStatus: function(buttonName, status) {
- var button = $('supervised-user-creation-' + buttonName + '-button');
- button.disabled = status;
- },
-
- gotItButtonPressed_: function() {
- chrome.send('finishLocalSupervisedUserCreation');
- },
-
- handleErrorButtonPressed_: function() {
- chrome.send('abortLocalSupervisedUserCreation');
- },
-
- startButtonPressed_: function() {
- this.setVisiblePage_('manager');
- this.setButtonDisabledStatus('next', true);
- },
-
- nextButtonPressed_: function() {
- if (this.currentPage_ == 'manager') {
- this.validateAndLogInAsManager_();
- return;
- }
- if (this.currentPage_ == 'username') {
- this.validateAndCreateSupervisedUser_();
- }
- },
-
- importButtonPressed_: function() {
- this.importSupervisedUser_();
- },
-
- importLinkPressed_: function() {
- this.setVisiblePage_('import');
- },
-
- handleSuggestImport_: function(user_id) {
- this.setVisiblePage_('import');
- this.importList_.selectUser(user_id);
- },
-
- createLinkPressed_: function() {
- this.setVisiblePage_('username');
- this.lastIncorrectUserName_ = null;
- this.lastVerifiedName_ = null;
- this.checkUserName_();
- },
-
- prevButtonPressed_: function() {
- this.setVisiblePage_('intro');
- },
-
- showProgress: function(text) {
- var status = this.getScreenElement('status');
- var statusText = status.querySelector('.id-text');
- statusText.textContent = text;
- statusText.classList.remove('error');
- status.querySelector('.id-spinner').hidden = false;
- status.hidden = false;
- this.getScreenElement('import-link').hidden = true;
- this.getScreenElement('create-link').hidden = true;
- },
-
- showStatusError: function(text) {
- var status = this.getScreenElement('status');
- var statusText = status.querySelector('.id-text');
- statusText.textContent = text;
- statusText.classList.add('error');
- status.querySelector('.id-spinner').hidden = true;
- status.hidden = false;
- this.getScreenElement('import-link').hidden = true;
- this.getScreenElement('create-link').hidden = true;
- },
-
- hideStatus_: function() {
- var status = this.getScreenElement('status');
- status.hidden = true;
- },
-
- /**
- * Updates state of login header so that necessary buttons are displayed.
- */
- onBeforeShow: function(data) {
- $('login-header-bar').signinUIState =
- SIGNIN_UI_STATE.SUPERVISED_USER_CREATION_FLOW;
- if (data['managers']) {
- this.loadManagers(data['managers']);
- }
- var imageGrid = this.getScreenElement('image-grid');
- imageGrid.updateAndFocus();
- },
-
- /**
- * Update state of login header so that necessary buttons are displayed.
- */
- onBeforeHide: function() {
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
- this.getScreenElement('image-grid').stopCamera();
- },
-
- /**
- * Returns a control which should receive an initial focus.
- */
- get defaultControl() {
- return $('supervised-user-creation-name');
- },
-
- /**
- * True if the the screen is disabled (handles no user interaction).
- * @type {boolean}
- */
- disabled_: false,
-
- get disabled() {
- return this.disabled_;
- },
-
- set disabled(value) {
- this.disabled_ = value;
- var controls = this.querySelectorAll('button,input');
- for (var i = 0, control; control = controls[i]; ++i) {
- control.disabled = value;
- }
- $('login-header-bar').disabled = value;
- $('cancel-add-user-button').disabled = false;
- },
-
- /**
- * Called by backend part to propagate list of possible managers.
- * @param {Array} userList - list of users that can be managers.
- */
- loadManagers: function(userList) {
- $('supervised-user-creation-managers-block').hidden = false;
- this.managerList_.clearPods();
- for (var i = 0; i < userList.length; ++i)
- this.managerList_.addPod(userList[i]);
- if (userList.length > 0)
- this.managerList_.selectPod(this.managerList_.pods[0]);
- },
-
- /**
- * Cancels user creation and drops to user screen (either sign).
- */
- cancel: function() {
- var notSignedInPages = ['intro', 'manager'];
- var postCreationPages = ['created'];
- if (notSignedInPages.indexOf(this.currentPage_) >= 0) {
- chrome.send('hideLocalSupervisedUserCreation');
-
- // Make sure no manager password is kept:
- this.managerList_.clearPods();
-
- Oobe.showUserPods();
- return;
- }
- if (postCreationPages.indexOf(this.currentPage_) >= 0) {
- chrome.send('finishLocalSupervisedUserCreation');
- return;
- }
- chrome.send('abortLocalSupervisedUserCreation');
- },
-
- updateText_: function() {
- var managerDisplayId = this.context_.managerDisplayId;
- this.updateElementText_('intro-alternate-text',
- 'createSupervisedUserIntroAlternateText');
- this.updateElementText_('created-text-1',
- 'createSupervisedUserCreatedText1',
- this.context_.supervisedName);
- // TODO(antrim): Move wrapping with strong in grd file, and eliminate this
- //call.
- this.updateElementText_('created-text-2',
- 'createSupervisedUserCreatedText2',
- this.wrapStrong(
- loadTimeData.getString('managementURL')),
- this.context_.supervisedName);
- this.updateElementText_('created-text-3',
- 'createSupervisedUserCreatedText3',
- managerDisplayId);
- this.updateElementText_('name-explanation',
- 'createSupervisedUserNameExplanation',
- managerDisplayId);
- },
-
- wrapStrong: function(original) {
- if (original == undefined)
- return original;
- return '<strong>' + original + '</strong>';
- },
-
- updateElementText_: function(localId, templateName) {
- var args = Array.prototype.slice.call(arguments);
- args.shift();
- this.getScreenElement(localId).innerHTML =
- loadTimeData.getStringF.apply(loadTimeData, args);
- },
-
- showIntroPage: function() {
- $('supervised-user-creation-password').value = '';
- $('supervised-user-creation-password-confirm').value = '';
- $('supervised-user-creation-name').value = '';
-
- this.lastVerifiedName_ = null;
- this.lastIncorrectUserName_ = null;
- this.passwordErrorVisible = false;
- $('supervised-user-creation-password').classList.remove('password-error');
- this.nameErrorVisible = false;
-
- this.setVisiblePage_('intro');
- },
-
- showManagerPage: function() {
- this.setVisiblePage_('manager');
- },
-
- showUsernamePage: function() {
- this.setVisiblePage_('username');
- },
-
- showTutorialPage: function() {
- this.setVisiblePage_('created');
- },
-
- showPage: function(page) {
- this.setVisiblePage_(page);
- },
-
- showErrorPage: function(errorTitle, errorText, errorButtonText) {
- this.disabled = false;
- $('supervised-user-creation-error-title').innerHTML = errorTitle;
- $('supervised-user-creation-error-text').innerHTML = errorText;
- $('supervised-user-creation-error-button').textContent = errorButtonText;
- this.setVisiblePage_('error');
- },
-
- showManagerPasswordError: function() {
- this.disabled = false;
- this.showSelectedManagerPasswordError_();
- },
-
- /*
- TODO(antrim) : this is an explicit code duplications with UserImageScreen.
- It should be removed by issue 251179.
- */
- /**
- * Currently selected user image index (take photo button is with zero
- * index).
- * @type {number}
- */
- selectedUserImage_: -1,
- imagesData: [],
-
- setDefaultImages: function(imagesData) {
- var imageGrid = this.getScreenElement('image-grid');
- imageGrid.setDefaultImages(imagesData);
- this.imagesData_ = imagesData;
- },
-
-
- handleActivate_: function() {
- var imageGrid = this.getScreenElement('image-grid');
- if (imageGrid.selectedItemUrl == ButtonImages.TAKE_PHOTO) {
- this.handleTakePhoto_();
- return;
- }
- this.nextButtonPressed_();
- },
-
- /**
- * Handles selection change.
- * @param {Event} e Selection change event.
- * @private
- */
- handleSelect_: function(e) {
- var imageGrid = this.getScreenElement('image-grid');
- this.updateNextButtonForUser_();
-
- $('supervised-user-creation-flip-photo').tabIndex =
- (imageGrid.selectionType == 'camera') ? 0 : -1;
- if (imageGrid.cameraLive || imageGrid.selectionType != 'camera')
- imageGrid.previewElement.classList.remove('phototaken');
- else
- imageGrid.previewElement.classList.add('phototaken');
-
- if (!imageGrid.cameraLive || imageGrid.selectionType != 'camera') {
- this.context_.selectedImageUrl = imageGrid.selectedItemUrl;
- chrome.send('supervisedUserSelectImage',
- [imageGrid.selectedItemUrl, imageGrid.selectionType]);
- }
- // Start/stop camera on (de)selection.
- if (!imageGrid.inProgramSelection &&
- imageGrid.selectionType != e.oldSelectionType) {
- if (imageGrid.selectionType == 'camera') {
- // Programmatic selection of camera item is done in
- // startCamera callback where streaming is started by itself.
- imageGrid.startCamera(
- function() {
- // Start capture if camera is still the selected item.
- $('supervised-user-creation-image-preview-img').classList.
- toggle('animated-transform', true);
- return imageGrid.selectedItem == imageGrid.cameraImage;
- });
- } else {
- $('supervised-user-creation-image-preview-img').classList.toggle(
- 'animated-transform', false);
- imageGrid.stopCamera();
- }
- }
- },
-
- /**
- * Handle camera-photo flip.
- */
- handleFlipPhoto_: function() {
- var imageGrid = this.getScreenElement('image-grid');
- imageGrid.previewElement.classList.add('animation');
- imageGrid.flipPhoto = !imageGrid.flipPhoto;
- var flipMessageId = imageGrid.flipPhoto ?
- 'photoFlippedAccessibleText' : 'photoFlippedBackAccessibleText';
- announceAccessibleMessage(loadTimeData.getString(flipMessageId));
- },
-
- /**
- * Handle photo capture from the live camera stream.
- */
- handleTakePhoto_: function(e) {
- this.getScreenElement('image-grid').takePhoto();
- chrome.send('supervisedUserTakePhoto');
- },
-
- handlePhotoTaken_: function(e) {
- chrome.send('supervisedUserPhotoTaken', [e.dataURL]);
- announceAccessibleMessage(
- loadTimeData.getString('photoCaptureAccessibleText'));
- },
-
- /**
- * Handle photo updated event.
- * @param {Event} e Event with 'dataURL' property containing a data URL.
- */
- handlePhotoUpdated_: function(e) {
- chrome.send('supervisedUserPhotoTaken', [e.dataURL]);
- },
-
- /**
- * Handle discarding the captured photo.
- */
- handleDiscardPhoto_: function(e) {
- var imageGrid = this.getScreenElement('image-grid');
- imageGrid.discardPhoto();
- chrome.send('supervisedUserDiscardPhoto');
- announceAccessibleMessage(
- loadTimeData.getString('photoDiscardAccessibleText'));
- },
-
- setCameraPresent: function(present) {
- this.getScreenElement('image-grid').cameraPresent = present;
- },
-
- setExistingSupervisedUsers: function(users) {
- var selectedUser = null;
- // Store selected user
- if (this.importList_.selectedPod)
- selectedUser = this.importList_.selectedPod.user.id;
-
- var userList = users;
- userList.sort(function(a, b) {
- // Put existing users last.
- if (a.exists != b.exists)
- return a.exists ? 1 : -1;
- // Sort rest by name.
- return a.name.localeCompare(b.name, [], {sensitivity: 'base'});
- });
-
- this.importList_.clearPods();
- var selectedIndex = -1;
- for (var i = 0; i < userList.length; ++i) {
- this.importList_.addPod(userList[i]);
- if (selectedUser == userList[i].id)
- selectedIndex = i;
- }
-
- if (userList.length == 1)
- this.importList_.selectPod(this.importList_.pods[0]);
-
- if (selectedIndex >= 0)
- this.importList_.selectPod(this.importList_.pods[selectedIndex]);
-
- if (this.currentPage_ == 'username')
- this.getScreenElement('import-link').hidden = (userList.length == 0);
- },
- };
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.css b/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.css
deleted file mode 100644
index 62340abd9cd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#tpm-error-message {
- min-width: 650px;
-}
-
-#oobe.tpm-error-message #step-logo {
- z-index: 1;
-}
-
-#tpm-error-message-controls {
- text-align: end;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.html b/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.html
deleted file mode 100644
index 26fc939892e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<div id="tpm-error-message" class="step faded hidden" hidden>
- <div class="step-contents">
- <div class="error-header">
- <img alt class="error-icon" src="chrome://theme/IDR_FATAL_ERROR">
- <div id="tpm-error-title" class="error-title"
- i18n-content="errorTpmFailureTitle"></div>
- </div>
- <div class="error-body">
- <div id="tmp-error-reboot-text" class="error-message-paragraph"
- i18n-content="errorTpmFailureReboot"></div>
- <div id="tpm-error-message-controls"
- class="error-message-paragraph"></div>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.js b/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.js
deleted file mode 100644
index ff5359a6a2c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_tpm_error.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Offline message screen implementation.
- */
-
-login.createScreen('TPMErrorMessageScreen', 'tpm-error-message', function() {
- return {
- EXTERNAL_API: [
- 'show'
- ],
-
- /**
- * Buttons in oobe wizard's button strip.
- * @type {array} Array of Buttons.
- */
- get buttons() {
- var rebootButton = this.ownerDocument.createElement('button');
- rebootButton.id = 'reboot-button';
- rebootButton.textContent =
- loadTimeData.getString('errorTpmFailureRebootButton');
- rebootButton.addEventListener('click', function() {
- chrome.send('rebootSystem');
- });
- return [rebootButton];
- },
-
- /**
- * Show TPM screen.
- */
- show: function() {
- Oobe.showScreen({id: SCREEN_TPM_ERROR});
- }
- };
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.css b/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.css
deleted file mode 100644
index 0955d3c6cc0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * This is the stylesheet used by the wrong HWID screen.
- */
-
-#wrong-hwid {
- padding: 40px 17px 30px;
- text-align: center;
- width: 722px;
-}
-
-#wrong-hwid #wrong-hwid-message-header {
- color: #606060;
- font-size: 22px;
- padding: 5px 40px 30px;
-}
-
-#wrong-hwid #wrong-hwid-icon {
- height: 112px;
-}
-
-#wrong-hwid #wrong-hwid-message-content {
- color: #606060;
- font-size: 16px;
- padding: 20px 40px 40px;
-}
-
-#skip-hwid-warning {
- justify-content: center;
-}
-
-#skip-hwid-warning-link {
- color: #8c8c8c;
- font-size: 18px;
- text-decoration: none;
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.html b/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.html
deleted file mode 100644
index 4136fdd2bde..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<div class="step hidden no-logo" id="wrong-hwid" hidden>
- <div class="step-contents">
- <div id="wrong-hwid-message">
- <div id="wrong-hwid-message-header" i18n-content="wrongHWIDScreenHeader">
- </div>
- <img id="wrong-hwid-icon" src="chrome://theme/IDR_RESET_WARNING"/>
- <div id="wrong-hwid-message-content"></div>
- </div>
- <div id="skip-hwid-warning" class="step-controls">
- <a id="skip-hwid-warning-link" href="#"
- i18n-content="wrongHWIDScreenSkipLink"></a>
- </div>
- </div>
-</div>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.js b/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.js
deleted file mode 100644
index 202c494275b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/screen_wrong_hwid.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview wrong HWID screen implementation.
- */
-
-login.createScreen('WrongHWIDScreen', 'wrong-hwid', function() {
- return {
- /** @override */
- decorate: function() {
- $('skip-hwid-warning-link').addEventListener('click', function(event) {
- chrome.send('wrongHWIDOnSkip');
- });
- this.updateLocalizedContent();
- },
-
- /**
- * Updates state of login header so that necessary buttons are displayed.
- **/
- onBeforeShow: function(data) {
- $('login-header-bar').signinUIState = SIGNIN_UI_STATE.WRONG_HWID_WARNING;
- },
-
- /**
- * Updates localized content of the screen that is not updated via template.
- */
- updateLocalizedContent: function() {
- $('wrong-hwid-message-content').innerHTML =
- '<p>' +
- loadTimeData.getStringF('wrongHWIDMessageFirstPart',
- '<strong>', '</strong>') +
- '</p><p>' +
- loadTimeData.getString('wrongHWIDMessageSecondPart') +
- '</p>';
- }
- };
-});
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/test_util.js b/chromium/chrome/browser/resources/chromeos/login/test_util.js
deleted file mode 100644
index 5a0399ef236..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/test_util.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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', function() {
- function ErrorStore() {
- var self = this;
- window.addEventListener('error', function(e) {
- self.store_.push(e);
- });
- }
-
- cr.addSingletonGetter(ErrorStore);
-
- ErrorStore.prototype = {
- store_: [],
-
- get length() {
- return this.store_.length;
- },
- };
-
- return {
- ErrorStore: ErrorStore,
- };
-});
-
-cr.ErrorStore.getInstance();
diff --git a/chromium/chrome/browser/resources/chromeos/login/throbber_notice.css b/chromium/chrome/browser/resources/chromeos/login/throbber_notice.css
deleted file mode 100644
index 8ca67e30023..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/throbber_notice.css
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
- align-items: center;
- display: flex;
- flex-direction: column;
- justify-content: center;
-}
-
-paper-spinner {
- --paper-spinner-layer-1-color: var(--google-blue-500);
- --paper-spinner-layer-2-color: var(--google-blue-500);
- --paper-spinner-layer-3-color: var(--google-blue-500);
- --paper-spinner-layer-4-color: var(--google-blue-500);
-}
-
-paper-spinner {
- height: 38px;
- margin-bottom: 28px;
- width: 38px;
-}
-
-#spinner-comment {
- color: #747474;
- font-size: 13px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/login/throbber_notice.html b/chromium/chrome/browser/resources/chromeos/login/throbber_notice.html
deleted file mode 100644
index 397f4cd8d3f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/throbber_notice.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file. -->
-
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<dom-module name="throbber-notice">
- <link rel="stylesheet" href="throbber_notice.css">
- <template>
- <paper-spinner dir="ltr" active></paper-spinner>
- <div id="spinner-comment"><span>[[text]]</span></div>
- </template>
-</dom-module>
-
diff --git a/chromium/chrome/browser/resources/chromeos/login/throbber_notice.js b/chromium/chrome/browser/resources/chromeos/login/throbber_notice.js
deleted file mode 100644
index 2b56e0bf024..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/throbber_notice.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Polymer({
- is: 'throbber-notice',
-
- properties: {
- text: String
- }
-});
diff --git a/chromium/chrome/browser/resources/chromeos/login/version.html b/chromium/chrome/browser/resources/chromeos/login/version.html
deleted file mode 100644
index 5078d7a7b79..00000000000
--- a/chromium/chrome/browser/resources/chromeos/login/version.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<div id="version-labels" hidden>
- <div id="version"></div>
- <div id="asset-id"></div>
-</div>
diff --git a/chromium/chrome/browser/resources/chromeos/merge_session_load.html b/chromium/chrome/browser/resources/chromeos/merge_session_load.html
deleted file mode 100644
index b2b308977c7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/merge_session_load.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<title i18n-content="title">
-</title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<style>
-html {
- height: 100%;
-}
-body {
- -webkit-user-select: none;
- background: white;
- color: #000;
- display: -webkit-box;
- height: 100%;
- margin: 0;
- padding: 0;
- visibility: hidden;
- width: 100%;
-}
-
-.header {
- padding: 3px;
- width: 80%;
-}
-</style>
-
-<script>
-
-function sendCommand(cmd) {
- window.domAutomationController.setAutomationId(1);
- window.domAutomationController.send(cmd);
-}
-
-// Show the interstitial page.
-function showPage() {
- document.body.style.visibility = 'visible';
-}
-
-// Show the interstitial page.
-function forceLoad() {
- sendCommand('proceed');
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- var showDelayTime = loadTimeData.getString('show_delay_time');
- var totalWaitTime = loadTimeData.getString('total_wait_time');
- window.setTimeout(showPage, showDelayTime);
- window.setTimeout(forceLoad, totalWaitTime);
-});
-</script>
-
-<body oncontextmenu="return false;">
- <div class="header" i18n-content="heading" id="mgs">
- </div>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/mobile_dialogs.css b/chromium/chrome/browser/resources/chromeos/mobile_dialogs.css
deleted file mode 100644
index 9c96e68feff..00000000000
--- a/chromium/chrome/browser/resources/chromeos/mobile_dialogs.css
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-body {
- cursor: default;
- font-size: 13px;
-}
-
-.container {
- -webkit-box-align: center;
- -webkit-box-pack: center;
- bottom: 0;
- display: -webkit-box;
- left: 0;
- position: fixed;
- right: 0;
- top: 0;
-}
-
-.dialog {
- background: white;
- min-height: 225px;
- min-width: 350px;
- padding: 0;
- position: relative;
-}
-
-.dialog h1 {
- background: -webkit-linear-gradient(white, #F8F8F8);
- border-bottom: 1px solid rgba(188, 193, 208, .5);
- color: rgb(83, 99, 125);
- font-size: 105%;
- font-weight: bold;
- margin: 0;
- padding: 10px 15px 8px 15px;
- text-shadow: white 0 1px 2px;
- width: 320px;
-}
-
-.content-area {
- padding: 10px 15px 5px 15px;
- width: 320px;
-}
-
-.action-area {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: end;
- display: -webkit-box;
- padding: 12px;
-}
-
-html[dir='rtl'] .action-area {
- left: 0;
-}
-
-.action-area-right {
- display: -webkit-box;
-}
-
-.button-strip {
- -webkit-box-orient: horizontal;
- display: -webkit-box;
-}
-
-.button-strip > button {
- -webkit-margin-start: 10px;
- display: block;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/mobile_setup.css b/chromium/chrome/browser/resources/chromeos/mobile_setup.css
deleted file mode 100644
index 2ce8a8ed302..00000000000
--- a/chromium/chrome/browser/resources/chromeos/mobile_setup.css
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-html,
-body {
- -webkit-user-select: none;
- height: 100%;
- margin: 0;
- overflow: hidden;
- padding: 0;
- width: 100%;
-}
-
-iframe {
- overflow-x: scroll;
- overflow-y: scroll;
-}
-
-.dialog-body {
- border: 1px #aaa solid;
- height: 100%;
- margin-top: 0;
- overflow: hidden;
- width: 100%;
-}
-
-.overlay {
- bottom: 0;
- left: 0;
- padding: 100px;
- position: absolute;
- right: 0;
- top: 0;
- z-index: 10;
-}
-
-.opaque-overlay {
- background: white;
-}
-
-.translucent-black-overlay {
- background: rgba(0, 0, 0, 0.1);
-}
-
-.overlay > div {
- background: white;
- border: 1px solid #bdbdbd;
- border-radius: 5px;
- box-shadow: 1px 1px 12px rgba(0, 0, 0, 0.15);
- padding: 15px;
-}
-
-.startup {
- left: 50%;
- margin-left: -266px;
- margin-top: -250px;
- position: absolute;
- top: 50%;
- width: 500px;
-}
-
-.logo {
- background:
- url(chrome-extension://iadeocfgjdjdmpenejdbfeaocpbikmab/carrier_logo.png)
- no-repeat;
- background-position: 85% 50%;
- height: 58px;
- margin-bottom: 20px;
- margin-top: 20px;
-}
-
-.splitter {
- border-bottom: 1px solid #EEE;
- height: 1px;
- margin-top: 10px;
-}
-
-.hidden {
- display: none;
-}
-
-.header-cell {
- -webkit-padding-start: 10px;
-}
-
-.canvas-cell {
- line-height: 0;
- vertical-align: middle;
-}
-
-#paymentForm,
-#portalFrame {
- height: 100%;
- width: 100%;
-}
-
-#carrierPage {
- height: 380px;
- overflow: hidden;
- padding-top: 10px;
- width: 500px;
-}
-
-#banner {
- -webkit-padding-end: 5px;
- -webkit-padding-start: 70px;
- background-color: rgb(252, 246, 224);
- border: 1px solid #ccc;
- box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.2);
- display: -webkit-box;
- margin-left: -22px;
- padding-bottom: 5px;
- padding-top: 5px;
- width: 467px;
-}
-
-#statusHeader {
- font-size: 16px;
- font-weight: bold;
-}
-
-#auxHeader {
- font-size: 16px;
-}
-
-#finalMessage {
- padding-bottom: 50px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/mobile_setup.html b/chromium/chrome/browser/resources/chromeos/mobile_setup.html
deleted file mode 100644
index cfdd6c1e7ff..00000000000
--- a/chromium/chrome/browser/resources/chromeos/mobile_setup.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype html>
-<html i18n-values="lang:language">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<title i18n-content="title"></title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<link rel="stylesheet" href="chrome://resources/css/dialogs.css"></link>
-<link rel="stylesheet" href="mobile_setup.css"></link>
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="chrome://resources/js/cr/ui/dialogs.js"></script>
-<script src="mobile_setup.js"></script>
-</head>
-<body>
- <div id="mainDiv" class="dialog-body">
- <iframe class="hidden" id="paymentForm" name="paymentForm" frameborder="0"></iframe>
- <div id="systemStatus" class="overlay opaque-overlay hidden">
- <div class="startup">
- <div id="banner">
- <table border="0">
- <tbody><tr>
- <td class="canvas-cell"><canvas id="canvas" width="56"
- height="56"></canvas></td>
- <td class="header-cell">
- <div id="statusHeader"></div>
- <div id="auxHeader"></div>
- </td>
- </tr>
- </tbody></table>
- </div>
- <iframe id="carrierPage" name="carrierPage" frameborder="0"></iframe>
- </div>
- </div>
- <div id="finalStatus" class="overlay translucent-black-overlay hidden">
- <div class="startup">
- <div class="header"><h3 id="finalHeader"></h3></div>
- <div id="finalMessage"></div>
- <div class="splitter"></div>
- <div class="logo"></div>
- <div class="button-strip">
- <button id="closeButton"
- i18n-content="close_button" class="hidden"></button>
- </div>
- </div>
- </div>
- </div>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/mobile_setup.js b/chromium/chrome/browser/resources/chromeos/mobile_setup.js
deleted file mode 100644
index f1b8e25aa66..00000000000
--- a/chromium/chrome/browser/resources/chromeos/mobile_setup.js
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-cr.define('mobile', function() {
-
- function MobileSetup() {
- }
-
- cr.addSingletonGetter(MobileSetup);
-
- MobileSetup.PLAN_ACTIVATION_UNKNOWN = -2;
- MobileSetup.PLAN_ACTIVATION_PAGE_LOADING = -1;
- MobileSetup.PLAN_ACTIVATION_START = 0;
- MobileSetup.PLAN_ACTIVATION_TRYING_OTASP = 1;
- MobileSetup.PLAN_ACTIVATION_INITIATING_ACTIVATION = 3;
- MobileSetup.PLAN_ACTIVATION_RECONNECTING = 4;
- MobileSetup.PLAN_ACTIVATION_WAITING_FOR_CONNECTION = 5;
- MobileSetup.PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING = 6;
- MobileSetup.PLAN_ACTIVATION_SHOWING_PAYMENT = 7;
- MobileSetup.PLAN_ACTIVATION_RECONNECTING_PAYMENT = 8;
- MobileSetup.PLAN_ACTIVATION_DELAY_OTASP = 9;
- MobileSetup.PLAN_ACTIVATION_START_OTASP = 10;
- MobileSetup.PLAN_ACTIVATION_OTASP = 11;
- MobileSetup.PLAN_ACTIVATION_DONE = 12;
- MobileSetup.PLAN_ACTIVATION_ERROR = 0xFF;
-
- MobileSetup.EXTENSION_PAGE_URL =
- 'chrome-extension://iadeocfgjdjdmpenejdbfeaocpbikmab';
- MobileSetup.ACTIVATION_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
- '/activation.html';
- MobileSetup.PORTAL_OFFLINE_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
- '/portal_offline.html';
- MobileSetup.REDIRECT_POST_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
- '/redirect.html';
-
- MobileSetup.prototype = {
- // Mobile device information.
- deviceInfo_: null,
- frameName_: '',
- initialized_: false,
- fakedTransaction_: false,
- paymentShown_: false,
- frameLoadError_: 0,
- frameLoadIgnored_: true,
- carrierPageUrl_: null,
- spinnerInt_: -1,
- // UI states.
- state_: MobileSetup.PLAN_ACTIVATION_UNKNOWN,
- STATE_UNKNOWN_: 'unknown',
- STATE_CONNECTING_: 'connecting',
- STATE_ERROR_: 'error',
- STATE_PAYMENT_: 'payment',
- STATE_ACTIVATING_: 'activating',
- STATE_CONNECTED_: 'connected',
-
- initialize: function(frame_name, carrierPage) {
- if (this.initialized_) {
- console.log('calling initialize() again?');
- return;
- }
- this.initialized_ = true;
- self = this;
- this.frameName_ = frame_name;
-
- cr.ui.dialogs.BaseDialog.OK_LABEL =
- loadTimeData.getString('ok_button');
- cr.ui.dialogs.BaseDialog.CANCEL_LABEL =
- loadTimeData.getString('cancel_button');
- this.confirm_ = new cr.ui.dialogs.ConfirmDialog(document.body);
-
- window.addEventListener('message', function(e) {
- self.onMessageReceived_(e);
- });
-
- $('closeButton').addEventListener('click', function(e) {
- $('finalStatus').classList.add('hidden');
- });
-
- // Kick off activation process.
- chrome.send('startActivation');
- },
-
- startSpinner_: function() {
- this.stopSpinner_();
- this.spinnerInt_ = setInterval(mobile.MobileSetup.drawProgress, 100);
- },
-
- stopSpinner_: function() {
- if (this.spinnerInt_ != -1) {
- clearInterval(this.spinnerInt_);
- this.spinnerInt_ = -1;
- }
- },
-
- onFrameLoaded_: function(success) {
- chrome.send('paymentPortalLoad', [success ? 'ok' : 'failed']);
- },
-
- loadPaymentFrame_: function(deviceInfo) {
- if (deviceInfo) {
- this.frameLoadError_ = 0;
- this.deviceInfo_ = deviceInfo;
- if (deviceInfo.post_data && deviceInfo.post_data.length) {
- this.frameLoadIgnored_ = true;
- $(this.frameName_).contentWindow.location.href =
- MobileSetup.REDIRECT_POST_PAGE_URL +
- '?post_data=' + escape(deviceInfo.post_data) +
- '&formUrl=' + escape(deviceInfo.payment_url);
- } else {
- this.frameLoadIgnored_ = false;
- $(this.frameName_).contentWindow.location.href =
- deviceInfo.payment_url;
- }
- }
- },
-
- onMessageReceived_: function(e) {
- if (e.origin !=
- this.deviceInfo_.payment_url.substring(0, e.origin.length) &&
- e.origin != MobileSetup.EXTENSION_PAGE_URL)
- return;
-
- if (e.data.type == 'requestDeviceInfoMsg') {
- this.sendDeviceInfo_();
- } else if (e.data.type == 'framePostReady') {
- this.frameLoadIgnored_ = false;
- this.sendPostFrame_(e.origin);
- } else if (e.data.type == 'reportTransactionStatusMsg') {
- console.log('calling setTransactionStatus from onMessageReceived_');
- chrome.send('setTransactionStatus', [e.data.status]);
- }
- },
-
- changeState_: function(deviceInfo) {
- var newState = deviceInfo.state;
- if (this.state_ == newState)
- return;
-
- // The mobile setup is already in its final state.
- if (this.state_ == MobileSetup.PLAN_ACTIVATION_DONE ||
- this.state_ == MobileSetup.PLAN_ACTIVATION_ERROR) {
- return;
- }
-
- // Map handler state to UX.
- var simpleActivationFlow =
- (deviceInfo.activation_type == 'NonCellular' ||
- deviceInfo.activation_type == 'OTA');
- switch (newState) {
- case MobileSetup.PLAN_ACTIVATION_PAGE_LOADING:
- case MobileSetup.PLAN_ACTIVATION_START:
- case MobileSetup.PLAN_ACTIVATION_DELAY_OTASP:
- case MobileSetup.PLAN_ACTIVATION_START_OTASP:
- case MobileSetup.PLAN_ACTIVATION_RECONNECTING:
- case MobileSetup.PLAN_ACTIVATION_RECONNECTING_PAYMENT:
- // Activation page should not be shown for the simple activation flow.
- if (simpleActivationFlow)
- break;
-
- $('statusHeader').textContent =
- loadTimeData.getString('connecting_header');
- $('auxHeader').textContent =
- loadTimeData.getString('please_wait');
- $('paymentForm').classList.add('hidden');
- $('finalStatus').classList.add('hidden');
- this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
- $('systemStatus').classList.remove('hidden');
- $('canvas').classList.remove('hidden');
- this.startSpinner_();
- break;
- case MobileSetup.PLAN_ACTIVATION_TRYING_OTASP:
- case MobileSetup.PLAN_ACTIVATION_INITIATING_ACTIVATION:
- case MobileSetup.PLAN_ACTIVATION_OTASP:
- // Activation page should not be shown for the simple activation flow.
- if (simpleActivationFlow)
- break;
-
- $('statusHeader').textContent =
- loadTimeData.getString('activating_header');
- $('auxHeader').textContent =
- loadTimeData.getString('please_wait');
- $('paymentForm').classList.add('hidden');
- $('finalStatus').classList.add('hidden');
- this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
- $('systemStatus').classList.remove('hidden');
- $('canvas').classList.remove('hidden');
- this.startSpinner_();
- break;
- case MobileSetup.PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
- // Activation page should not be shown for the simple activation flow.
- if (!simpleActivationFlow) {
- $('statusHeader').textContent =
- loadTimeData.getString('connecting_header');
- $('auxHeader').textContent = '';
- $('paymentForm').classList.add('hidden');
- $('finalStatus').classList.add('hidden');
- this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
- $('systemStatus').classList.remove('hidden');
- $('canvas').classList.remove('hidden');
- }
- this.loadPaymentFrame_(deviceInfo);
- break;
- case MobileSetup.PLAN_ACTIVATION_WAITING_FOR_CONNECTION:
- var statusHeaderText;
- var carrierPage;
- if (deviceInfo.activation_type == 'NonCellular') {
- statusHeaderText = loadTimeData.getString(
- 'portal_unreachable_header');
- carrierPage = MobileSetup.PORTAL_OFFLINE_PAGE_URL;
- } else if (deviceInfo.activation_type == 'OTA') {
- statusHeaderText =
- loadTimeData.getString('connecting_header');
- carrierPage = MobileSetup.ACTIVATION_PAGE_URL;
- }
- $('statusHeader').textContent = statusHeaderText;
- $('auxHeader').textContent = '';
- $('auxHeader').classList.add('hidden');
- $('paymentForm').classList.add('hidden');
- $('finalStatus').classList.add('hidden');
- $('systemStatus').classList.remove('hidden');
- this.setCarrierPage_(carrierPage);
- $('canvas').classList.remove('hidden');
- this.startSpinner_();
- break;
- case MobileSetup.PLAN_ACTIVATION_SHOWING_PAYMENT:
- $('statusHeader').textContent = '';
- $('auxHeader').textContent = '';
- $('finalStatus').classList.add('hidden');
- $('systemStatus').classList.add('hidden');
- $('paymentForm').classList.remove('hidden');
- $('canvas').classList.add('hidden');
- this.stopSpinner_();
- this.paymentShown_ = true;
- break;
- case MobileSetup.PLAN_ACTIVATION_DONE:
- $('statusHeader').textContent = '';
- $('auxHeader').textContent = '';
- $('finalHeader').textContent =
- loadTimeData.getString('completed_header');
- $('finalMessage').textContent =
- loadTimeData.getString('completed_text');
- $('systemStatus').classList.add('hidden');
- $('closeButton').classList.remove('hidden');
- $('finalStatus').classList.remove('hidden');
- $('canvas').classList.add('hidden');
- $('closeButton').classList.toggle('hidden', !this.paymentShown_);
- $('paymentForm').classList.toggle('hidden', !this.paymentShown_);
- this.stopSpinner_();
- break;
- case MobileSetup.PLAN_ACTIVATION_ERROR:
- $('statusHeader').textContent = '';
- $('auxHeader').textContent = '';
- $('finalHeader').textContent =
- loadTimeData.getString('error_header');
- $('finalMessage').textContent = deviceInfo.error;
- $('systemStatus').classList.add('hidden');
- $('canvas').classList.add('hidden');
- $('closeButton').classList.toggle('hidden', !this.paymentShown_);
- $('paymentForm').classList.toggle('hidden', !this.paymentShown_);
- $('finalStatus').classList.remove('hidden');
- this.stopSpinner_();
- break;
- }
- this.state_ = newState;
- },
-
- setCarrierPage_: function(url) {
- if (this.carrierPageUrl_ == url)
- return;
- this.carrierPageUrl_ = url;
- $('carrierPage').contentWindow.location.href = url;
- },
-
- updateDeviceStatus_: function(deviceInfo) {
- this.changeState_(deviceInfo);
- },
-
- portalFrameLoadError_: function(errorCode) {
- if (this.frameLoadIgnored_)
- return;
- console.log('Portal frame load error detected: ', errorCode);
- this.frameLoadError_ = errorCode;
- },
-
- portalFrameLoadCompleted_: function() {
- if (this.frameLoadIgnored_)
- return;
- console.log('Portal frame load completed!');
- this.onFrameLoaded_(this.frameLoadError_ == 0);
- },
-
- sendPostFrame_: function(frameUrl) {
- var msg = { type: 'postFrame' };
- $(this.frameName_).contentWindow.postMessage(msg, frameUrl);
- },
-
- sendDeviceInfo_: function() {
- var msg = {
- type: 'deviceInfoMsg',
- domain: document.location,
- payload: {
- 'carrier': this.deviceInfo_.carrier,
- 'MEID': this.deviceInfo_.MEID,
- 'IMEI': this.deviceInfo_.IMEI,
- 'MDN': this.deviceInfo_.MDN
- }
- };
- $(this.frameName_).contentWindow.postMessage(msg,
- this.deviceInfo_.payment_url);
- }
-
- };
-
- MobileSetup.drawProgress = function() {
- var ctx = canvas.getContext('2d');
- ctx.clearRect(0, 0, canvas.width, canvas.height);
-
- var segmentCount = Math.min(12, canvas.width / 1.6); // Number of segments
- var rotation = 0.75; // Counterclockwise rotation
-
- // Rotate canvas over time
- ctx.translate(canvas.width / 2, canvas.height / 2);
- ctx.rotate(Math.PI * 2 / (segmentCount + rotation));
- ctx.translate(-canvas.width / 2, -canvas.height / 2);
-
- var gap = canvas.width / 24; // Gap between segments
- var oRadius = canvas.width / 2; // Outer radius
- var iRadius = oRadius * 0.618; // Inner radius
- var oCircumference = Math.PI * 2 * oRadius; // Outer circumference
- var iCircumference = Math.PI * 2 * iRadius; // Inner circumference
- var oGap = gap / oCircumference; // Gap size as fraction of outer ring
- var iGap = gap / iCircumference; // Gap size as fraction of inner ring
- var oArc = Math.PI * 2 * (1 / segmentCount - oGap); // Angle of outer arcs
- var iArc = Math.PI * 2 * (1 / segmentCount - iGap); // Angle of inner arcs
-
- for (i = 0; i < segmentCount; i++) { // Draw each segment
- var opacity = Math.pow(1.0 - i / segmentCount, 3.0);
- opacity = (0.15 + opacity * 0.8); // Vary from 0.15 to 0.95
- var angle = - Math.PI * 2 * i / segmentCount;
-
- ctx.beginPath();
- ctx.arc(canvas.width / 2, canvas.height / 2, oRadius,
- angle - oArc / 2, angle + oArc / 2, false);
- ctx.arc(canvas.width / 2, canvas.height / 2, iRadius,
- angle + iArc / 2, angle - iArc / 2, true);
- ctx.closePath();
- ctx.fillStyle = 'rgba(240, 30, 29, ' + opacity + ')';
- ctx.fill();
- }
- };
-
- MobileSetup.deviceStateChanged = function(deviceInfo) {
- MobileSetup.getInstance().updateDeviceStatus_(deviceInfo);
- };
-
- MobileSetup.portalFrameLoadError = function(errorCode) {
- MobileSetup.getInstance().portalFrameLoadError_(errorCode);
- };
-
- MobileSetup.portalFrameLoadCompleted = function() {
- MobileSetup.getInstance().portalFrameLoadCompleted_();
- };
-
- MobileSetup.loadPage = function() {
- mobile.MobileSetup.getInstance().initialize('paymentForm',
- mobile.MobileSetup.ACTIVATION_PAGE_URL);
- };
-
- // Export
- return {
- MobileSetup: MobileSetup
- };
-});
-
-document.addEventListener('DOMContentLoaded', mobile.MobileSetup.loadPage);
diff --git a/chromium/chrome/browser/resources/chromeos/mobile_setup_portal.html b/chromium/chrome/browser/resources/chromeos/mobile_setup_portal.html
deleted file mode 100644
index 8840c5674e0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/mobile_setup_portal.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!doctype html>
-<html i18n-values="lang:language">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<title i18n-content="title"></title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<link rel="stylesheet" href="mobile_setup.css"></link>
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="mobile_setup_portal.js"></script>
-</head>
-<body>
- <div id="mainDiv" class="dialog-body">
- <iframe id="portalFrame" name="portalFrame" frameborder="0" hidden></iframe>
- <div id="systemStatus" class="overlay opaque-overlay" hidden>
- <div class="startup">
- <div id="banner">
- <table border="0">
- <tbody>
- <tr>
- <td class="canvas-cell">
- <canvas id="canvas" width="56" height="56"></canvas></td>
- <td class="header-cell">
- <div id="statusHeader"></div>
- <div id="auxHeader"></div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <iframe id="carrierPage" name="carrierPage" frameborder="0"></iframe>
- </div>
- </div>
- </div>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/mobile_setup_portal.js b/chromium/chrome/browser/resources/chromeos/mobile_setup_portal.js
deleted file mode 100644
index 53808d1a197..00000000000
--- a/chromium/chrome/browser/resources/chromeos/mobile_setup_portal.js
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('mobile', function() {
-
- // TODO(tbarzic): Share code with mobile_setup.js.
- var EXTENSION_BASE_URL =
- 'chrome-extension://iadeocfgjdjdmpenejdbfeaocpbikmab/';
- var REDIRECT_POST_PAGE_URL = EXTENSION_BASE_URL + 'redirect.html?autoPost=1';
- var PORTAL_OFFLINE_PAGE_URL = EXTENSION_BASE_URL + 'portal_offline.html';
- var INVALID_DEVICE_INFO_PAGE_URL =
- EXTENSION_BASE_URL + 'invalid_device_info.html';
-
- var NetworkState = {
- UNKNOWN: 0,
- PORTAL_REACHABLE: 1,
- PORTAL_UNREACHABLE: 2
- };
-
- var CarrierPageType = {
- NOT_SET: 0,
- PORTAL_OFFLINE: 1,
- INVALID_DEVICE_INFO: 2
- };
-
- function PortalImpl() {
- // Mobile device information.
- this.deviceInfo_ = null;
- this.spinnerInt_ = -1;
- this.networkState_ = NetworkState.UNKNOWN;
- this.portalFrameSet_ = false;
- this.carrierPageType_ = CarrierPageType.NOT_SET;
- }
-
- cr.addSingletonGetter(PortalImpl);
-
- PortalImpl.prototype = {
- initialize: function() {
- // Get network device info for which portal should be opened.
- // For LTE networks, this will also start observing network connection
- // state and raise |updatePortalReachability| messages when the portal
- // reachability changes.
- chrome.send('getDeviceInfo');
- },
-
- updateDeviceInfo: function(deviceInfo) {
- this.deviceInfo_ = deviceInfo;
- this.updateState_();
- },
-
- updateNetworkState: function(networkState) {
- if (this.networkState_ == networkState)
- return;
- this.networkState_ = networkState;
-
- // If the device info is not yet set, the state will be updated on the
- // device info update.
- if (this.deviceInfo_)
- this.updateState_();
- },
-
- updateState_: function() {
- if (!this.deviceInfo_ || this.networkState_ == NetworkState.UNKNOWN)
- return;
-
- if (!this.isDeviceInfoValid_()) {
- // If the device info is not valid, hide portalFrame and show system
- // status displaying 'invalid device info' page.
- this.setCarrierPage_(CarrierPageType.INVALID_DEVICE_INFO);
- $('portalFrame').hidden = true;
- $('systemStatus').hidden = false;
- } else if (this.networkState_ != NetworkState.PORTAL_REACHABLE) {
- // If the portal is not reachable, hide portalFrame and show system
- // status displaying 'offline portal' page.
- this.setCarrierPage_(CarrierPageType.PORTAL_OFFLINE);
- $('portalFrame').hidden = true;
- $('systemStatus').hidden = false;
- } else {
- // If the portal is reachable and device info is valid, set and show
- // portalFrame; and hide system status displaying 'offline portal' page.
- this.setPortalFrameIfNeeded_(this.deviceInfo_);
- $('portalFrame').hidden = false;
- $('systemStatus').hidden = true;
- this.stopSpinner_();
- }
- },
-
- setCarrierPage_: function(type) {
- // The page is already set, nothing to do.
- if (type == this.carrierPageType_)
- return;
-
- switch (type) {
- case CarrierPageType.PORTAL_OFFLINE:
- $('carrierPage').contentWindow.location.href =
- PORTAL_OFFLINE_PAGE_URL;
- $('statusHeader').textContent =
- loadTimeData.getString('portal_unreachable_header');
- this.startSpinner_();
- break;
- case CarrierPageType.INVALID_DEVICE_INFO:
- $('carrierPage').contentWindow.location.href =
- INVALID_DEVICE_INFO_PAGE_URL;
- $('statusHeader').textContent =
- loadTimeData.getString('invalid_device_info_header');
- this.stopSpinner_();
- break;
- case CarrierPageType.NOT_SET:
- $('carrierPage').contentWindow.location.href = 'about:blank';
- $('statusHeader').textContent = '';
- this.stopSpinner_();
- break;
- default:
- break;
- }
-
- this.carrierPageType_ = type;
- },
-
- setPortalFrameIfNeeded_: function(deviceInfo) {
- // The portal should be set only once.
- if (this.portalFrameSet_)
- return;
-
- var postData = '';
- if (deviceInfo.post_data && deviceInfo.post_data.length)
- postData = '&post_data=' + encodeURIComponent(deviceInfo.post_data);
-
- $('portalFrame').contentWindow.location.href = REDIRECT_POST_PAGE_URL +
- postData + '&formUrl=' + encodeURIComponent(deviceInfo.payment_url);
-
- this.portalFrameSet_ = true;
- },
-
- isDeviceInfoValid_: function() {
- // Device info is valid if it has mdn which doesn't contain only '0's.
- return this.deviceInfo_ && this.deviceInfo_.MDN &&
- this.deviceInfo_.MDN.match('[^0]');
- },
-
- startSpinner_: function() {
- this.stopSpinner_();
- this.spinnerInt_ = setInterval(this.drawProgress_.bind(this), 100);
- },
-
- stopSpinner_: function() {
- if (this.spinnerInt_ != -1) {
- clearInterval(this.spinnerInt_);
- this.spinnerInt_ = -1;
- }
- // Clear the spinner canvas.
- var ctx = canvas.getContext('2d');
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- },
-
- drawProgress_: function() {
- var ctx = canvas.getContext('2d');
- ctx.clearRect(0, 0, canvas.width, canvas.height);
-
- var segmentCount = Math.min(12, canvas.width / 1.6); // Number of segments
- var rotation = 0.75; // Counterclockwise rotation
-
- // Rotate canvas over time
- ctx.translate(canvas.width / 2, canvas.height / 2);
- ctx.rotate(Math.PI * 2 / (segmentCount + rotation));
- ctx.translate(-canvas.width / 2, -canvas.height / 2);
-
- var gap = canvas.width / 24; // Gap between segments
- var oRadius = canvas.width / 2; // Outer radius
- var iRadius = oRadius * 0.618; // Inner radius
- var oCircumference = Math.PI * 2 * oRadius; // Outer circumference
- var iCircumference = Math.PI * 2 * iRadius; // Inner circumference
- var oGap = gap / oCircumference; // Gap size as fraction of outer ring
- var iGap = gap / iCircumference; // Gap size as fraction of inner ring
- var oArc = Math.PI * 2 * (1 / segmentCount - oGap); // Angle of outer arcs
- var iArc = Math.PI * 2 * (1 / segmentCount - iGap); // Angle of inner arcs
-
- for (i = 0; i < segmentCount; i++) { // Draw each segment
- var opacity = Math.pow(1.0 - i / segmentCount, 3.0);
- opacity = (0.15 + opacity * 0.8); // Vary from 0.15 to 0.95
- var angle = - Math.PI * 2 * i / segmentCount;
-
- ctx.beginPath();
- ctx.arc(canvas.width / 2, canvas.height / 2, oRadius,
- angle - oArc / 2, angle + oArc / 2, false);
- ctx.arc(canvas.width / 2, canvas.height / 2, iRadius,
- angle + iArc / 2, angle - iArc / 2, true);
- ctx.closePath();
- ctx.fillStyle = 'rgba(240, 30, 29, ' + opacity + ')';
- ctx.fill();
- }
- }
- };
-
- function MobileSetupPortal() {}
-
- MobileSetupPortal.loadPage = function() {
- PortalImpl.getInstance().initialize();
- };
-
- MobileSetupPortal.onGotDeviceInfo = function(deviceInfo) {
- PortalImpl.getInstance().updateDeviceInfo(deviceInfo);
- };
-
- MobileSetupPortal.onConnectivityChanged = function(portalReachable) {
- PortalImpl.getInstance().updateNetworkState(
- portalReachable ? NetworkState.PORTAL_REACHABLE :
- NetworkState.PORTAL_UNREACHABLE);
- };
-
- // Export
- return {
- MobileSetupPortal: MobileSetupPortal
- };
-});
-
-document.addEventListener('DOMContentLoaded',
- mobile.MobileSetupPortal.loadPage);
diff --git a/chromium/chrome/browser/resources/chromeos/neterror.css b/chromium/chrome/browser/resources/chromeos/neterror.css
deleted file mode 100644
index 234c7cc1bcb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/neterror.css
+++ /dev/null
@@ -1,213 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Don't use the main frame div when the error is in a subframe. */
-html[subframe] #main-frame-error {
- display: none;
-}
-
-/* Don't use the subframe error div when the error is in a main frame. */
-html:not([subframe]) #sub-frame-error {
- display: none;
-}
-
-#diagnose-button {
- -webkit-margin-start: 0;
- margin-bottom: 10px;
- margin-top: 20px;
-}
-
-h1 {
- color: #666;
- font-size: 1.5em;
- font-weight: normal;
- margin: 10px 0 25px 0;
-}
-
-a {
- color: rgb(17, 85, 204);
- text-decoration: none;
-}
-
-.icon {
- -webkit-user-select: none;
-}
-
-.icon-generic {
- /**
- * Can't access chrome://theme/IDR_ERROR_NETWORK_GENERIC from an untrusted
- * renderer process, so embed the resource manually.
- */
- content: -webkit-image-set(
- url(../../../renderer/resources/default_100_percent/common/error_network_generic.png) 1x,
- url(../../../renderer/resources/default_200_percent/common/error_network_generic.png) 2x);
-}
-
-.icon-offline {
- content: -webkit-image-set(
- url(../../../renderer/resources/default_100_percent/offline/100-error-offline.png) 1x,
- url(../../../renderer/resources/default_200_percent/offline/200-error-offline.png) 2x);
-}
-
-#help-box-outer {
- -webkit-transition: height ease-in 218ms;
- overflow: hidden;
-}
-
-#help-box-inner {
- background-color: #f9f9f9;
- border-top: 1px solid #EEE;
- color: #444;
- padding: 25px 20px;
- text-align: start;
-}
-
-#suggestions {
- margin-top: 15px;
-}
-
-#sub-frame-error-details {
- color: #8F8F8F;
- text-shadow: 0 1px 0 rgba(255,255,255,0.3);
-}
-
-[jscontent=failedUrl] {
- overflow-wrap: break-word;
-}
-
-.hidden {
- display: none;
-}
-
-.suggestions {
- margin-top: 18px;
-}
-
-.suggestion-header {
- font-weight: bold;
- margin-bottom: 4px;
-}
-
-.suggestion-body {
- color: #777;
-}
-
-.error-code {
- color: #A0A0A0;
- margin-top: 15px;
-}
-
-/* Increase line height at higher resolutions. */
-@media (min-width: 641px) and (min-height: 641px) {
- #help-box-inner {
- line-height: 18px;
- }
-}
-
-/* Decrease padding at low sizes. */
-@media (max-width: 640px),
- (max-height: 640px) {
- body {
- margin: 15px;
- }
- h1 {
- margin: 10px 0 15px 0;
- }
- #help-box-inner {
- padding: 20px;
- }
- .suggestions {
- margin-top: 10px;
- }
- .suggestion-header {
- margin-bottom: 0;
- }
- .error-code {
- margin-top: 10px;
- }
-}
-
-/* Don't allow overflow when in a subframe. */
-html[subframe] body {
- overflow: hidden;
-}
-
-#sub-frame-error {
- -webkit-align-items: center;
- -webkit-flex-flow: column;
- -webkit-justify-content: center;
- background-color: #DDD;
- display: -webkit-flex;
- height: 100%;
- left: 0;
- position: absolute;
- top: 0;
- width: 100%;
-}
-
-#sub-frame-error:hover {
- background-color: #EEE;
-}
-
-#sub-frame-error-details {
- margin: 0 10px;
- visibility: hidden;
-}
-
-/* Show details only when hovering. */
-#sub-frame-error:hover #sub-frame-error-details {
- visibility: visible;
-}
-
-/* If the iframe is too small, always hide the error code. */
-/* TODO(mmenke): See if overflow: no-display works better, once supported. */
-@media (max-width: 200px),
- (max-height: 95px) {
- #sub-frame-error-details {
- display: none;
- }
-}
-
-/* Offline page */
-.offline .interstitial-wrapper {
- color: #2b2b2b;
- font-size: 1em;
- line-height: 1.55;
- margin: 100px auto 0;
- max-width: 600px;
- width: 100%;
-}
-
-.offline .runner-container {
- height: 150px;
- max-width: 600px;
- overflow: hidden;
- position: absolute;
- top: 10px;
- width: 44px;
- z-index: 2;
-}
-
-.offline .runner-canvas {
- height: 150px;
- max-width: 600px;
- opacity: 1;
- overflow: hidden;
- position: absolute;
- top: 0;
-}
-
-.offline .controller {
- background: rgba(247,247,247, .1);
- height: 100vh;
- left: 0;
- position: absolute;
- top: 0;
- width: 100vw;
- z-index: 1;
-}
-
-#offline-resources {
- display: none;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/neterror.js b/chromium/chrome/browser/resources/chromeos/neterror.js
deleted file mode 100644
index 2dad8fa7c21..00000000000
--- a/chromium/chrome/browser/resources/chromeos/neterror.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-function toggleHelpBox() {
- var helpBoxOuter = $('details');
- helpBoxOuter.classList.toggle('hidden');
- var detailsButton = $('details-button');
- if (helpBoxOuter.classList.contains('hidden')) {
- detailsButton.innerText = detailsButton.detailsText;
- } else {
- detailsButton.innerText = detailsButton.hideDetailsText;
- }
-}
-
-function diagnoseErrors() {
- window.domAutomationController.setAutomationId(1);
- window.domAutomationController.send('open_connectivity_diagnostics');
-}
-
-// Subframes use a different layout but the same html file. This is to make it
-// easier to support platforms that load the error page via different
-// mechanisms (Currently just iOS).
-if (window.top.location != window.location)
- document.documentElement.setAttribute('subframe', '');
-
-// Re-renders the error page using |strings| as the dictionary of values.
-// Used by NetErrorTabHelper to update DNS error pages with probe results.
-function updateForDnsProbe(strings) {
- var context = new JsEvalContext(strings);
- jstProcess(context, $('t'));
-}
-
-// Given the classList property of an element, adds an icon class to the list
-// and removes the previously-
-function updateIconClass(classList, newClass) {
- var oldClass;
-
- if (classList.hasOwnProperty('last_icon_class')) {
- oldClass = classList['last_icon_class'];
- if (oldClass == newClass)
- return;
- }
-
- classList.add(newClass);
- if (oldClass !== undefined)
- classList.remove(oldClass);
-
- classList['last_icon_class'] = newClass;
-
- if (newClass == 'icon-offline') {
- document.body.classList.add('offline');
- new Runner('.interstitial-wrapper');
- }
-}
diff --git a/chromium/chrome/browser/resources/chromeos/network_ui/OWNERS b/chromium/chrome/browser/resources/chromeos/network_ui/OWNERS
deleted file mode 100644
index aa215c7d505..00000000000
--- a/chromium/chrome/browser/resources/chromeos/network_ui/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-stevenjb@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/network_ui/compiled_resources.gyp b/chromium/chrome/browser/resources/chromeos/network_ui/compiled_resources.gyp
index 3de7f6a08f8..586004e055c 100644
--- a/chromium/chrome/browser/resources/chromeos/network_ui/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/chromeos/network_ui/compiled_resources.gyp
@@ -8,12 +8,12 @@
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:util',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_network_icon_externs.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_network_icon_externs.js',
'../../../../../third_party/closure_compiler/externs/networking_private.js'
],
},
diff --git a/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.css b/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.css
deleted file mode 100644
index 958293cc60d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.css
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-paper-button[raised].colored {
- background: rgb(66, 133, 244);
- color: white;
-}
-
-#header {
- margin: 5px;
-}
-
-#header a {
- padding: 0 4px;
-}
-
-#header cr-network-icon {
- height: 40px;
- width: 40px;
-}
-
-cr-network-select {
- padding: 5px;
- width: 500px;
-}
-
-#refresh {
- margin-top: 10px;
- padding: 5px;
-}
-
-.state-table {
- border-collapse: collapse;
-}
-
-.state-table tr td {
- border: 1px solid rgb(220, 220, 220);
- font-size: 13px;
-}
-
-.state-table-header {
- font-weight: bold;
-}
-
-.state-table-expand-button-cell {
- text-align: center;
-}
-
-.state-table-expand-button {
- background-color: #fff;
- border: none;
- height: 20px;
- margin: 0;
- outline: none;
- padding: 0;
- width: 20px;
-}
-
-.state-table-expanded-cell {
- white-space: pre-wrap;
-}
-
-.state-table cr-network-icon {
- height: 25px;
- width: 25px;
-}
-
-#advanced-options {
- margin-top: 10px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.html b/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.html
deleted file mode 100644
index 094b95a93f8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-
-<head>
- <meta charset="utf-8">
- <title id="network" i18n-content="titleText"></title>
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" href="chrome://network/network_ui.css">
- <link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_network_icon.html">
- <link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_network_select.html">
- <link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="chrome://network/strings.js"></script>
- <script src="chrome://network/network_ui.js"></script>
-</head>
-
-<body>
- <div id="header">
- <p i18n-content="autoRefreshText"></p>
- <span i18n-values=".innerHTML:deviceLogLinkText"></span>
- <div id="advanced-options">
- <span i18n-content="clickToExpandText"></span>
- <span i18n-content="propertyFormatText"></span>
- <select id="get-property-format">
- <option value="normal" i18n-content="normalFormatOption"></option>
- <option value="managed" i18n-content="managedFormatOption"></option>
- <option value="state" i18n-content="stateFormatOption"></option>
- <option value="shill" i18n-content="shillFormatOption"></option>
- </select>
- </div>
-
- <cr-network-select expandable show-active max-height="100">
- </cr-network-select>
-
- <div>
- <paper-button raised class="colored" id="refresh"
- i18n-content="networkRefreshText">
- </paper-button>
- </div>
- </div>
-
- <h3 i18n-content="visibleNetworksLabel"></h3>
- <table id="network-state-table" class="state-table">
- <tr class="state-table-header">
- <td></td>
- <td></td>
- <td>GUID</td>
- <td>Path</td>
- <td>Name</td>
- <td>Type</td>
- <td>State</td>
- <td>Connect?</td>
- <td>Error</td>
- <td>Security</td>
- <td>Tech</td>
- <td>Activation</td>
- <td>Roam</td>
- <td>Strength</td>
- </tr>
- </table>
-
- <h3 i18n-content="favoriteNetworksLabel"></h3>
- <table id="favorite-state-table" class="state-table">
- <tr class="state-table-header">
- <td></td>
- <td></td>
- <td>GUID</td>
- <td>Path</td>
- <td>Name</td>
- <td>Type</td>
- <td>Profile</td>
- <td>Visible</td>
- <td>ONC Source</td>
- </tr>
- </table>
-
- <script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.js b/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.js
deleted file mode 100644
index 1e997b6212f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/network_ui/network_ui.js
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var NetworkUI = (function() {
- 'use strict';
-
- // Properties to display in the network state table. Each entry can be either
- // a single state field or an array of state fields. If more than one is
- // specified then the first non empty value is used.
- var NETWORK_STATE_FIELDS = [
- 'GUID',
- 'service_path',
- 'Name',
- 'Type',
- 'ConnectionState',
- 'connectable',
- 'ErrorState',
- 'WiFi.Security',
- ['Cellular.NetworkTechnology',
- 'EAP.EAP'],
- 'Cellular.ActivationState',
- 'Cellular.RoamingState',
- 'WiFi.SignalStrength'
- ];
-
- var FAVORITE_STATE_FIELDS = [
- 'GUID',
- 'service_path',
- 'Name',
- 'Type',
- 'profile_path',
- 'visible',
- 'Source'
- ];
-
- /**
- * Creates and returns a typed HTMLTableCellElement.
- *
- * @return {!HTMLTableCellElement} A new td element.
- */
- var createTableCellElement = function() {
- return /** @type {!HTMLTableCellElement} */(document.createElement('td'));
- };
-
- /**
- * Creates and returns a typed HTMLTableRowElement.
- *
- * @return {!HTMLTableRowElement} A new tr element.
- */
- var createTableRowElement = function() {
- return /** @type {!HTMLTableRowElement} */(document.createElement('tr'));
- };
-
- /**
- * Returns the ONC data property for networkState associated with a key. Used
- * to access properties in the networkState by |key| which may may refer to a
- * nested property, e.g. 'WiFi.Security'. If any part of a nested key is
- * missing, this will return undefined.
- *
- * @param {!chrome.networkingPrivate.NetworkStateProperties} networkState The
- * network state property dictionary.
- * @param {string} key The ONC key for the property.
- * @return {*} The value associated with the property or undefined if the
- * key (any part of it) is not defined.
- */
- var getOncProperty = function(networkState, key) {
- var dict = /** @type {!Object} */(networkState);
- var keys = key.split('.');
- while (keys.length > 1) {
- var k = keys.shift();
- dict = dict[k];
- if (!dict || typeof dict != 'object')
- return undefined;
- }
- return dict[keys.shift()];
- };
-
- /**
- * Creates a cell with a button for expanding a network state table row.
- *
- * @param {string} guid The GUID identifying the network.
- * @return {!HTMLTableCellElement} The created td element that displays the
- * given value.
- */
- var createStateTableExpandButton = function(guid) {
- var cell = createTableCellElement();
- cell.className = 'state-table-expand-button-cell';
- var button = document.createElement('button');
- button.addEventListener('click', function(event) {
- toggleExpandRow(/** @type {!HTMLElement} */(event.target), guid);
- });
- button.className = 'state-table-expand-button';
- button.textContent = '+';
- cell.appendChild(button);
- return cell;
- };
-
- /**
- * Creates a cell with an icon representing the network state.
- *
- * @param {!chrome.networkingPrivate.NetworkStateProperties} networkState The
- * network state properties.
- * @return {!HTMLTableCellElement} The created td element that displays the
- * icon.
- */
- var createStateTableIcon = function(networkState) {
- var cell = createTableCellElement();
- cell.className = 'state-table-icon-cell';
- var icon = /** @type {!CrNetworkIconElement} */(
- document.createElement('cr-network-icon'));
- icon.isListItem = true;
- icon.networkState = networkState;
- cell.appendChild(icon);
- return cell;
- };
-
- /**
- * Creates a cell in the network state table.
- *
- * @param {*} value Content in the cell.
- * @return {!HTMLTableCellElement} The created td element that displays the
- * given value.
- */
- var createStateTableCell = function(value) {
- var cell = createTableCellElement();
- cell.textContent = value || '';
- return cell;
- };
-
- /**
- * Creates a row in the network state table.
- *
- * @param {Array} stateFields The state fields to use for the row.
- * @param {!chrome.networkingPrivate.NetworkStateProperties} networkState The
- * network state properties.
- * @return {!HTMLTableRowElement} The created tr element that contains the
- * network state information.
- */
- var createStateTableRow = function(stateFields, networkState) {
- var row = createTableRowElement();
- row.className = 'state-table-row';
- var guid = networkState.GUID;
- row.appendChild(createStateTableExpandButton(guid));
- row.appendChild(createStateTableIcon(networkState));
- for (var i = 0; i < stateFields.length; ++i) {
- var field = stateFields[i];
- var value;
- if (typeof field == 'string') {
- value = getOncProperty(networkState, field);
- } else {
- for (var j = 0; j < field.length; ++j) {
- value = getOncProperty(networkState, field[j]);
- if (value != undefined)
- break;
- }
- }
- if (field == 'GUID')
- value = value.slice(0, 8);
- row.appendChild(createStateTableCell(value));
- }
- return row;
- };
-
- /**
- * Creates a table for networks or favorites.
- *
- * @param {string} tablename The name of the table to be created.
- * @param {!Array<string>} stateFields The list of fields for the table.
- * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
- * An array of network or favorite states.
- */
- var createStateTable = function(tablename, stateFields, states) {
- var table = $(tablename);
- var oldRows = table.querySelectorAll('.state-table-row');
- for (var i = 0; i < oldRows.length; ++i)
- table.removeChild(oldRows[i]);
- states.forEach(function(state) {
- table.appendChild(createStateTableRow(stateFields, state));
- });
- };
-
- /**
- * Returns a valid HTMLElement id from |guid|.
- *
- * @param {string} guid A GUID which may start with a digit.
- * @return {string} A valid HTMLElement id.
- */
- var idFromGuid = function(guid) {
- return '_' + guid.replace(/[{}]/g, '');
- };
-
- /**
- * This callback function is triggered when visible networks are received.
- *
- * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
- * A list of network state information for each visible network.
- */
- var onVisibleNetworksReceived = function(states) {
- createStateTable('network-state-table', NETWORK_STATE_FIELDS, states);
- };
-
- /**
- * This callback function is triggered when favorite networks are received.
- *
- * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>} states
- * A list of network state information for each favorite network.
- */
- var onFavoriteNetworksReceived = function(states) {
- createStateTable('favorite-state-table', FAVORITE_STATE_FIELDS, states);
- };
-
- /**
- * Toggles the button state and add or remove a row displaying the complete
- * state information for a row.
- *
- * @param {!HTMLElement} btn The button that was clicked.
- * @param {string} guid GUID identifying the network.
- */
- var toggleExpandRow = function(btn, guid) {
- var cell = btn.parentNode;
- var row = /** @type {!HTMLTableRowElement} */(cell.parentNode);
- if (btn.textContent == '-') {
- btn.textContent = '+';
- row.parentNode.removeChild(row.nextSibling);
- } else {
- btn.textContent = '-';
- var expandedRow = createExpandedRow(guid, row);
- row.parentNode.insertBefore(expandedRow, row.nextSibling);
- }
- };
-
- /**
- * Creates the expanded row for displaying the complete state as JSON.
- *
- * @param {string} guid The GUID identifying the network.
- * @param {!HTMLTableRowElement} baseRow The unexpanded row associated with
- * the new row.
- * @return {!HTMLTableRowElement} The created tr element for the expanded row.
- */
- var createExpandedRow = function(guid, baseRow) {
- var expandedRow = createTableRowElement();
- expandedRow.className = 'state-table-row';
- var emptyCell = createTableCellElement();
- emptyCell.style.border = 'none';
- expandedRow.appendChild(emptyCell);
- var detailCell = createTableCellElement();
- detailCell.id = idFromGuid(guid);
- detailCell.className = 'state-table-expanded-cell';
- detailCell.colSpan = baseRow.childNodes.length - 1;
- expandedRow.appendChild(detailCell);
- var showDetail = function(state, error) {
- if (error && error.message)
- detailCell.textContent = error.message;
- else
- detailCell.textContent = JSON.stringify(state, null, '\t');
- };
- var selected = $('get-property-format').selectedIndex;
- var selectedId = $('get-property-format').options[selected].value;
- if (selectedId == 'shill') {
- chrome.send('getShillProperties', [guid]);
- } else if (selectedId == 'state') {
- chrome.networkingPrivate.getState(guid, function(properties) {
- showDetail(properties, chrome.runtime.lastError); });
- } else if (selectedId == 'managed') {
- chrome.networkingPrivate.getManagedProperties(guid, function(properties) {
- showDetail(properties, chrome.runtime.lastError); });
- } else {
- chrome.networkingPrivate.getProperties(guid, function(properties) {
- showDetail(properties, chrome.runtime.lastError); });
- }
- return expandedRow;
- };
-
- /**
- * Callback invoked by Chrome after a getShillProperties call.
- *
- * @param {Array} args The requested Shill properties. Will contain
- * just the 'GUID' and 'ShillError' properties if the call failed.
- */
- var getShillPropertiesResult = function(args) {
- var properties = args.shift();
- var guid = properties['GUID'];
- if (!guid) {
- console.error('No GUID in getShillPropertiesResult');
- return;
- }
-
- var detailCell = document.querySelector('td#' + idFromGuid(guid));
- if (!detailCell) {
- console.error('No cell for GUID: ' + guid);
- return;
- }
-
- if (properties['ShillError'])
- detailCell.textContent = properties['ShillError'];
- else
- detailCell.textContent = JSON.stringify(properties, null, '\t');
-
- };
-
- /**
- * Requests an update of all network info.
- */
- var requestNetworks = function() {
- chrome.networkingPrivate.getNetworks(
- {'networkType': chrome.networkingPrivate.NetworkType.ALL,
- 'visible': true},
- onVisibleNetworksReceived);
- chrome.networkingPrivate.getNetworks(
- {'networkType': chrome.networkingPrivate.NetworkType.ALL,
- 'configured': true},
- onFavoriteNetworksReceived);
- };
-
- /**
- * Sets refresh rate if the interval is found in the url.
- */
- var setRefresh = function() {
- var interval = parseQueryParams(window.location)['refresh'];
- if (interval && interval != '')
- setInterval(requestNetworks, parseInt(interval, 10) * 1000);
- };
-
- /**
- * Gets network information from WebUI.
- */
- document.addEventListener('DOMContentLoaded', function() {
- $('refresh').onclick = requestNetworks;
- setRefresh();
- requestNetworks();
- });
-
- return {
- getShillPropertiesResult: getShillPropertiesResult
- };
-})();
diff --git a/chromium/chrome/browser/resources/chromeos/nfc_debug.css b/chromium/chrome/browser/resources/chromeos/nfc_debug.css
deleted file mode 100644
index 9ffa968f66a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/nfc_debug.css
+++ /dev/null
@@ -1,84 +0,0 @@
-/* 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.
- */
-
-body {
- margin: 0
-}
-
-p {
- white-space: pre-wrap;
-}
-
-label {
- display: block;
-}
-
-h1 {
- margin: 1%;
-}
-
-div.entity-div {
- box-shadow: 0 0 20px 2px #aaa;
- display: inline-block;
- margin: 10px 5px;
- overflow: hidden;
- padding: 10px;
- vertical-align: top;
-}
-
-#nfc-adapter-info {
- width: 165px;
-}
-
-#ndef-record-form {
- width: 300px;
-}
-
-#nfc-tag-info,
-#nfc-peer-info {
- width: 270px;
- word-wrap: break-word;
-}
-
-#ndef-record-form input {
- width: 99%;
-}
-
-.parameters-table td {
- padding: 0 10px 10px 0;
-}
-
-.transition-in {
- -webkit-transition: opacity 250ms ease-in-out;
- opacity: 1;
- transition: opacity 250ms ease-in-out;
-}
-
-.transition-out {
- -webkit-transition: opacity 250ms ease-in-out;
- opacity: 0.25;
- transition: opacity 250ms ease-in-out;
-}
-
-hr {
- background: #888;
- border: 0;
- border-bottom: 1px dashed #ccc;
-}
-
-div.record-key-value-div {
- margin-bottom: 10px;
-}
-
-span.record-key-span,
-div.record-key-div {
- font-style: italic;
- font-weight: bold;
- margin-right: 10px;
-}
-
-.record-value-div > * {
- margin: 10px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/nfc_debug.html b/chromium/chrome/browser/resources/chromeos/nfc_debug.html
deleted file mode 100644
index 6e5563e929d..00000000000
--- a/chromium/chrome/browser/resources/chromeos/nfc_debug.html
+++ /dev/null
@@ -1,131 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
- <meta charset="utf-8">
- <title i18n-content="titleText"></title>
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" type="text/css" href="nfc_debug.css">
- <script src="chrome://resources/js/cr.js"></script>
- <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="nfc_debug.js"></script>
-</head>
-<body>
- <h1 i18n-content="titleText"></h1>
- <p id="nfc-not-supported" i18n-content="notSupportedText"></p>
- <div id="wrapper">
- <div id="nfc-adapter-info" class="entity-div">
- <h3 i18n-content="adapterHeaderText"></h3>
- <div id="adapter-parameters"></div>
- <div id="adapter-toggles">
- <button id="power-toggle"></button>
- <button id="poll-toggle"></button>
- </div>
- </div>
- <div id="ndef-record-form" class="entity-div">
- <h3 i18n-content="ndefFormHeaderText"></h3>
- <select id="record-type-menu">
- <option i18n-content="ndefFormTypeTextText" value="text"></option>
- <option i18n-content="ndefFormTypeUriText" value="uri"></option>
- <option i18n-content="ndefFormTypeSmartPosterText" value="smart-poster">
- </option>
- </select>
- <div id="text-form" class="record-form">
- <div>
- <label for="text-form-text" class="required"
- i18n-content="ndefFormFieldTextText">
- </label>
- <input type="text" id="text-form-text">
- </div>
- <div>
- <label for="text-form-encoding" class="required"
- i18n-content="ndefFormFieldEncodingText">
- </label>
- <input type="text" id="text-form-encoding">
- </div>
- <div>
- <label for="text-form-language-code" class="required"
- i18n-content="ndefFormFieldLanguageCodeText">
- </label>
- <input type="text" id="text-form-language-code">
- </div>
- </div>
- <div id="uri-form" class="record-form">
- <div>
- <label for="uri-form-uri" class="required"
- i18n-content="ndefFormFieldUriText"></label>
- <input type="text" id="uri-form-uri">
- </div>
- <div>
- <label for="uri-form-mime-type"
- i18n-content="ndefFormFieldMimeTypeText"></label>
- <input type="text" id="uri-form-mime-type">
- </div>
- <div>
- <label for="uri-form-target-size"
- i18n-content="ndefFormFieldTargetSizeText"></label>
- <input type="text" id="uri-form-target-size">
- </div>
- </div>
- <div id="smart-poster-form" class="record-form">
- <div>
- <label for="smart-poster-form-uri"
- i18n-content="ndefFormFieldUriText"></label>
- <input type="text" id="smart-poster-form-uri">
- </div>
- <div>
- <label for="smart-poster-form-mime-type"
- i18n-content="ndefFormFieldMimeTypeText"></label>
- <input type="text" id="smart-poster-form-mime-type">
- </div>
- <div>
- <label for="smart-poster-form-target-size"
- i18n-content="ndefFormFieldTargetSizeText"></label>
- <input type="text" id="smart-poster-form-target-size">
- </div>
- <div>
- <label for="smart-poster-form-title-text"
- i18n-content="ndefFormFieldTitleTextText">
- </label>
- <input type="text" id="smart-poster-form-title-text">
- </div>
- <div>
- <label for="smart-poster-form-title-encoding"
- i18n-content="ndefFormFieldTitleEncodingText">
- </label>
- <input type="text" id="smart-poster-form-title-encoding">
- </div>
- <div>
- <label for="smart-poster-form-title-language-code"
- i18n-content="ndefFormFieldTitleLanguageCodeText">
- </label>
- <input type="text" id="smart-poster-form-title-language-code">
- </div>
- </div>
- <button id="record-form-submit-button"></button>
- </div>
- <div id="nfc-peer-info" class="entity-div">
- <h3 i18n-content="nfcPeerHeaderText"></h3>
- <div id="peer-parameters"></div>
- <div id="peer-records-entry" class="records-entry">
- <h3 i18n-content="recordsHeaderText"></h3>
- <hr/>
- <div id="peer-records-container"></div>
- <hr/>
- </div>
- </div>
- <div id="nfc-tag-info" class="entity-div">
- <h3 i18n-content="nfcTagHeaderText"></h3>
- <div id="tag-parameters"></div>
- <div id="tag-records-entry" class="records-entry">
- <h3 i18n-content="recordsHeaderText"></h3>
- <hr/>
- <div id="tag-records-container"></div>
- <hr/>
- </div>
- </div>
- </div>
- <script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/nfc_debug.js b/chromium/chrome/browser/resources/chromeos/nfc_debug.js
deleted file mode 100644
index 02ccf517977..00000000000
--- a/chromium/chrome/browser/resources/chromeos/nfc_debug.js
+++ /dev/null
@@ -1,375 +0,0 @@
-// 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('nfcDebug', function() {
- 'use strict';
-
- function NfcDebugUI() {
- this.adapterData_ = {};
- this.peerData_ = {};
- this.tagData_ = {};
- }
-
- NfcDebugUI.prototype = {
- setAdapterData: function(data) {
- this.adapterData_ = data;
- },
-
- setPeerData: function(data) {
- this.peerData_ = data;
- },
-
- setTagData: function(data) {
- this.tagData_ = data;
- },
-
- /**
- * Powers the NFC adapter ON or OFF.
- */
- toggleAdapterPower: function() {
- chrome.send('setAdapterPower', [!this.adapterData_.powered]);
- },
-
- /**
- * Tells the NFC adapter to start or stop polling.
- */
- toggleAdapterPolling: function() {
- chrome.send('setAdapterPolling', [!this.adapterData_.polling]);
- },
-
- /**
- * Notifies the UI that the user made an NDEF type selection and the
- * appropriate form should be displayed.
- */
- recordTypeChanged: function() {
- this.updateRecordFormContents();
- },
-
- /**
- * Creates a table element and populates it for each record contained
- * in the given list of records and adds them as a child of the given
- * DOMElement. This method will replace the contents of the given element
- * with the tables.
- *
- * @param {DOMElement} div The container that the records should be rendered
- * to.
- * @param {Array} records List of NDEF record data.
- */
- renderRecords: function(div, records) {
- div.textContent = '';
- if (records.length == 0) {
- return;
- }
- var self = this;
- records.forEach(function(record) {
- var recordDiv = document.createElement('div');
- recordDiv.setAttribute('class', 'record-div');
- for (var key in record) {
- if (!record.hasOwnProperty(key))
- continue;
-
- var rowDiv = document.createElement('div');
- rowDiv.setAttribute('class', 'record-key-value-div');
-
- var keyElement, valueElement;
- if (key == 'titles') {
- keyElement = document.createElement('div');
- keyElement.setAttribute('class', 'record-key-div');
- keyElement.appendChild(document.createTextNode(key));
- valueElement = document.createElement('div');
- valueElement.setAttribute('class', 'record-value-div');
- self.renderRecords(valueElement, record[key]);
- } else {
- keyElement = document.createElement('span');
- keyElement.setAttribute('class', 'record-key-span');
- keyElement.appendChild(document.createTextNode(key));
- valueElement = document.createElement('span');
- valueElement.setAttribute('class', 'record-value-span');
- valueElement.appendChild(document.createTextNode(record[key]));
- }
- rowDiv.appendChild(keyElement);
- rowDiv.appendChild(valueElement);
- recordDiv.appendChild(rowDiv);
- }
- div.appendChild(recordDiv);
- if (records[records.length - 1] !== record)
- div.appendChild(document.createElement('hr'));
- });
- },
-
- /**
- * Updates which record type form is displayed based on the currently
- * selected type.
- */
- updateRecordFormContents: function() {
- var recordTypeMenu = $('record-type-menu');
- var selectedType =
- recordTypeMenu.options[recordTypeMenu.selectedIndex].value;
- this.updateRecordFormContentsFromType(selectedType);
- },
-
- /**
- * Updates which record type form is displayed based on the passed in
- * type string.
- *
- * @param {string} type The record type.
- */
- updateRecordFormContentsFromType: function(type) {
- $('text-form').hidden = (type != 'text');
- $('uri-form').hidden = (type != 'uri');
- $('smart-poster-form').hidden = (type != 'smart-poster');
- },
-
- /**
- * Tries to push or write the record to the remote tag or device based on
- * the contents of the record form fields.
- */
- submitRecordForm: function() {
- var recordTypeMenu = $('record-type-menu');
- var selectedType =
- recordTypeMenu.options[recordTypeMenu.selectedIndex].value;
- var recordData = {};
- if (selectedType == 'text') {
- recordData.type = 'TEXT';
- if ($('text-form-text').value)
- recordData.text = $('text-form-text').value;
- if ($('text-form-encoding').value)
- recordData.encoding = $('text-form-encoding').value;
- if ($('text-form-language-code').value)
- recordData.languageCode = $('text-form-language-code').value;
- } else if (selectedType == 'uri') {
- recordData.type = 'URI';
- if ($('uri-form-uri').value)
- recordData.uri = $('uri-form-uri').value;
- if ($('uri-form-mime-type').value)
- recordData.mimeType = $('uri-form-mime-type').value;
- if ($('uri-form-target-size').value) {
- var targetSize = $('uri-form-target-size').value;
- targetSize = parseFloat(targetSize);
- recordData.targetSize = isNaN(targetSize) ? 0.0 : targetSize;
- }
- } else if (selectedType == 'smart-poster') {
- recordData.type = 'SMART_POSTER';
- if ($('smart-poster-form-uri').value)
- recordData.uri = $('smart-poster-form-uri').value;
- if ($('smart-poster-form-mime-type').value)
- recordData.mimeType = $('smart-poster-form-mime-type').value;
- if ($('smart-poster-form-target-size').value) {
- var targetSize = $('smart-poster-form-target-size').value;
- targetSize = parseFloat(targetSize);
- recordData.targetSize = isNaN(targetSize) ? 0.0 : targetSize;
- }
- var title = {};
- if ($('smart-poster-form-title-text').value)
- title.text = $('smart-poster-form-title-text').value;
- if ($('smart-poster-form-title-encoding').value)
- title.encoding = $('smart-poster-form-title-encoding').value;
- if ($('smart-poster-form-title-language-code').value)
- title.languageCode =
- $('smart-poster-form-title-language-code').value;
- if (Object.keys(title).length != 0)
- recordData.titles = [title];
- }
- chrome.send('submitRecordForm', [recordData]);
- },
-
- /**
- * Given a dictionary |data|, builds a table where each row contains the
- * a key and its value. The resulting table is then added as the sole child
- * of |div|. |data| contains information about an adapter, tag, or peer and
- * this method creates a table for display, thus the value of some keys
- * will be processed.
- *
- * @param {DOMElement} div The container that the table should be rendered
- * to.
- * @param {dictionary} data Data to generate the table from.
- */
- createTableFromData: function(div, data) {
- div.textContent = '';
- var table = document.createElement('table');
- table.classList.add('parameters-table');
- for (var key in data) {
- var row = document.createElement('tr');
- var col = document.createElement('td');
- col.textContent = key;
- row.appendChild(col);
-
- col = document.createElement('td');
- var value = data[key];
- if (key == 'records')
- value = value.length;
- else if (key == 'supportedTechnologies')
- value = value.join(', ');
- col.textContent = value;
- row.appendChild(col);
- table.appendChild(row);
- }
- div.appendChild(table);
- },
- };
-
- cr.addSingletonGetter(NfcDebugUI);
-
- /**
- * Initializes the page after the content has loaded.
- */
- NfcDebugUI.initialize = function() {
- $('nfc-adapter-info').hidden = true;
- $('adapter-toggles').hidden = true;
- $('nfc-adapter-info').classList.add('transition-out');
- $('ndef-record-form').classList.add('transition-out');
- $('nfc-peer-info').classList.add('transition-out');
- $('nfc-tag-info').classList.add('transition-out');
- $('power-toggle').onclick = function() {
- NfcDebugUI.getInstance().toggleAdapterPower();
- };
- $('poll-toggle').onclick = function() {
- NfcDebugUI.getInstance().toggleAdapterPolling();
- };
- $('record-type-menu').onchange = function() {
- NfcDebugUI.getInstance().recordTypeChanged();
- };
- $('record-form-submit-button').onclick = function() {
- NfcDebugUI.getInstance().submitRecordForm();
- };
- $('record-form-submit-button').hidden = true;
- NfcDebugUI.getInstance().updateRecordFormContents();
- chrome.send('initialize');
- };
-
- /**
- * Updates the UI based on the NFC availability on the current platform.
- *
- * @param {bool} available If true, NFC is supported on the current platform.
- */
- NfcDebugUI.onNfcAvailabilityDetermined = function(available) {
- $('nfc-not-supported').hidden = available;
- };
-
- /**
- * Notifies the UI that information about the NFC adapter has been received.
- *
- * @param {dictionary} data Properties of the NFC adapter.
- */
- NfcDebugUI.onNfcAdapterInfoChanged = function(data) {
- NfcDebugUI.getInstance().setAdapterData(data);
-
- $('nfc-adapter-info').hidden = false;
- NfcDebugUI.getInstance().createTableFromData($('adapter-parameters'), data);
-
- $('nfc-adapter-info').classList.toggle('transition-out', !data.present);
- $('nfc-adapter-info').classList.toggle('transition-in', data.present);
- $('ndef-record-form').classList.toggle('transition-out', !data.present);
- $('ndef-record-form').classList.toggle('transition-in', data.present);
-
- $('adapter-toggles').hidden = !data.present;
- $('ndef-record-form').hidden = !data.present;
-
- $('power-toggle').textContent = loadTimeData.getString(
- data.powered ? 'adapterPowerOffText' : 'adapterPowerOnText');
- $('poll-toggle').textContent = loadTimeData.getString(
- data.polling ? 'adapterStopPollText' : 'adapterStartPollText');
- };
-
- /**
- * Notifies the UI that information about an NFC peer has been received.
- *
- * @param {dictionary} data Properties of the NFC peer device.
- */
- NfcDebugUI.onNfcPeerDeviceInfoChanged = function(data) {
- NfcDebugUI.getInstance().setPeerData(data);
-
- if (Object.keys(data).length == 0) {
- $('nfc-peer-info').classList.add('transition-out');
- $('nfc-peer-info').classList.remove('transition-in');
- $('record-form-submit-button').hidden = true;
- return;
- }
-
- $('nfc-peer-info').classList.remove('transition-out');
- $('nfc-peer-info').classList.add('transition-in');
-
- NfcDebugUI.getInstance().createTableFromData($('peer-parameters'), data);
-
- $('record-form-submit-button').hidden = false;
- $('record-form-submit-button').textContent =
- loadTimeData.getString('ndefFormPushButtonText');
-
- if (data.records.length == 0) {
- $('peer-records-entry').hidden = true;
- return;
- }
-
- $('peer-records-entry').hidden = false;
- NfcDebugUI.getInstance().renderRecords($('peer-records-container'),
- data.records);
- };
-
- /**
- * Notifies the UI that information about an NFC tag has been received.
- *
- * @param {dictionary} data Properties of the NFC tag.
- */
- NfcDebugUI.onNfcTagInfoChanged = function(data) {
- NfcDebugUI.getInstance().setTagData(data);
-
- if (Object.keys(data).length == 0) {
- $('nfc-tag-info').classList.add('transition-out');
- $('nfc-tag-info').classList.remove('transition-in');
- $('record-form-submit-button').hidden = true;
- return;
- }
-
- $('nfc-tag-info').classList.remove('transition-out');
- $('nfc-tag-info').classList.add('transition-in');
-
- NfcDebugUI.getInstance().createTableFromData($('tag-parameters'), data);
-
- $('record-form-submit-button').hidden = false;
- $('record-form-submit-button').textContent =
- loadTimeData.getString('ndefFormWriteButtonText');
-
- if (data.records.length == 0) {
- $('tag-records-entry').hidden = true;
- return;
- }
-
- $('tag-records-entry').hidden = false;
- NfcDebugUI.getInstance().renderRecords($('tag-records-container'),
- data.records);
- };
-
- /**
- * Notifies the UI that a call to "setAdapterPower" failed. Displays an
- * alert.
- */
- NfcDebugUI.onSetAdapterPowerFailed = function() {
- alert(loadTimeData.getString('errorFailedToSetPowerText'));
- };
-
- /**
- * Notifies the UI that a call to "setAdapterPolling" failed. Displays an
- * alert.
- */
- NfcDebugUI.onSetAdapterPollingFailed = function() {
- alert(loadTimeData.getString('errorFailedToSetPollingText'));
- };
-
- /**
- * Notifies the UI that an error occurred while submitting an NDEF record
- * form.
- * @param {string} errorMessage An error message, describing the failure.
- */
- NfcDebugUI.onSubmitRecordFormFailed = function(errorMessage) {
- alert(loadTimeData.getString('errorFailedToSubmitPrefixText') +
- ' ' + errorMessage);
- };
-
- // Export
- return {
- NfcDebugUI: NfcDebugUI
- };
-});
-
-document.addEventListener('DOMContentLoaded', nfcDebug.NfcDebugUI.initialize);
diff --git a/chromium/chrome/browser/resources/chromeos/power.css b/chromium/chrome/browser/resources/chromeos/power.css
deleted file mode 100644
index a675d894e15..00000000000
--- a/chromium/chrome/browser/resources/chromeos/power.css
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.
- */
-
-#main-table {
- border-collapse: collapse;
- border-width: 0;
- margin-left: auto;
- margin-right: auto;
- table-layout: fixed;
- width: 1000px;
-}
-
-tr.section-row {
- border-bottom-width: 2px;
- border-color: #000;
- border-left-width: 0;
- border-right-width: 0;
- border-style: solid;
- border-top-width: 2px;
- width: 100%;
-}
-
-td.title-cell {
- border-width: 0;
- text-align: right;
- vertical-align: top;
- width: 15%;
-}
-
-p.title-text {
- font-weight: bold;
- margin-right: 10px;
-}
-
-td.show-button-cell {
- border-bottom-width: 0;
- border-color: #aaa;
- border-left-width: 1px;
- border-right-width: 1px;
- border-style: solid;
- border-top-width: 0;
- text-align: center;
- vertical-align: top;
- width: 10%;
-}
-
-td.plots-cell {
- border-width: 0;
- padding: 10px;
- text-align: left;
- width: 75%;
-}
-
-div.section-div {
- width: 100%;
-}
-
-div.plots-div {
- width: 100%;
-}
-
-button.show-button {
- margin: 10px;
-}
-
-button.reload-button {
- margin-bottom: 10px;
- margin-top: 10px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/power.html b/chromium/chrome/browser/resources/chromeos/power.html
deleted file mode 100644
index cfe7e627c44..00000000000
--- a/chromium/chrome/browser/resources/chromeos/power.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!doctype html>
-<html i18n-values="lang:language">
-<head>
- <meta charset="utf-8">
- <title i18n-content="titleText"></title>
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" href="chrome://power/power.css">
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="chrome://power/strings.js"></script>
- <script src="chrome://power/power.js"></script>
-</head>
-<body>
- <table id="main-table">
- <tr class="section-row">
- <td class="title-cell">
- <p i18n-content="batteryChargeSectionTitle" class="title-text"></p>
- </td>
- <td class="show-button-cell">
- <button id="battery-charge-show-button" class="show-button"
- i18n-content="showButton">
- </button>
- </td>
- <td id="battery-charge-cell" class="plots-cell">
- <div id="battery-charge-section" class="section-div">
- <div class="plots-div" id="battery-charge-plots-div"></div>
- <form>
- <label>
- <span i18n-content="averageOverText"></span>
- <input id="sample-count-input" type="number" min="1" max="150"
- value="10">
- </label>
- <span i18n-content="samplesText"></span>
- </form>
- <button id="battery-charge-reload-button" class="reload-button"
- i18n-content="reloadButton">
- </button>
- </div>
- </td>
- </tr>
-
- <tr class="section-row">
- <td class="title-cell">
- <p i18n-content="cpuIdleSectionTitle" class="title-text"></p>
- </td>
- <td class="show-button-cell">
- <button id="cpu-idle-show-button" class="show-button"
- i18n-content="showButton">
- </button>
- </td>
- <td id="cpu-idle-cell" class="plots-cell">
- <div id="cpu-idle-section" class="section-div">
- <div class="plots-div" id="cpu-idle-plots-div"></div>
- <button id="cpu-idle-reload-button" class="reload-button"
- i18n-content="reloadButton">
- </button>
- </div>
- </td>
- </tr>
-
- <tr class="section-row">
- <td class="title-cell">
- <p i18n-content="cpuFreqSectionTitle" class="title-text"></p>
- </td>
- <td class="show-button-cell">
- <button id="cpu-freq-show-button" class="show-button"
- i18n-content="showButton">
- </button>
- </td>
- <td id="cpu-freq-cell" class="plots-cell">
- <div id="cpu-freq-section" class="section-div">
- <div class="plots-div" id="cpu-freq-plots-div"></div>
- <button id="cpu-freq-reload-button" class="reload-button"
- i18n-content="reloadButton">
- </button>
- </div>
- </td>
- </tr>
- </table>
- <script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/power.js b/chromium/chrome/browser/resources/chromeos/power.js
deleted file mode 100644
index 98c38de54c0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/power.js
+++ /dev/null
@@ -1,866 +0,0 @@
-// 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.
-
-/**
- * Plot a line graph of data versus time on a HTML canvas element.
- *
- * @param {HTMLCanvasElement} plotCanvas The canvas on which the line graph is
- * drawn.
- * @param {HTMLCanvasElement} legendCanvas The canvas on which the legend for
- * the line graph is drawn.
- * @param {Array<number>} tData The time (in seconds) in the past when the
- * corresponding data in plots was sampled.
- * @param {Array<{data: Array<number>, color: string}>} plots An
- * array of plots to plot on the canvas. The field 'data' of a plot is an
- * array of samples to be plotted as a line graph with color speficied by
- * the field 'color'. The elements in the 'data' array are ordered
- * corresponding to their sampling time in the argument 'tData'. Also, the
- * number of elements in the 'data' array should be the same as in the time
- * array 'tData' above.
- * @param {number} yMin Minimum bound of y-axis
- * @param {number} yMax Maximum bound of y-axis.
- * @param {integer} yPrecision An integer value representing the number of
- * digits of precision the y-axis data should be printed with.
- */
-function plotLineGraph(
- plotCanvas, legendCanvas, tData, plots, yMin, yMax, yPrecision) {
- var textFont = 12 * devicePixelRatio + 'px Arial';
- var textHeight = 12 * devicePixelRatio;
- var padding = 5 * devicePixelRatio; // Pixels
- var errorOffsetPixels = 15 * devicePixelRatio;
- var gridColor = '#ccc';
- var plotCtx = plotCanvas.getContext('2d');
- var size = tData.length;
-
- function drawText(ctx, text, x, y) {
- ctx.font = textFont;
- ctx.fillStyle = '#000';
- ctx.fillText(text, x, y);
- }
-
- function printErrorText(ctx, text) {
- ctx.clearRect(0, 0, plotCanvas.width, plotCanvas.height);
- drawText(ctx, text, errorOffsetPixels, errorOffsetPixels);
- }
-
- if (size < 2) {
- printErrorText(plotCtx,
- loadTimeData.getString('notEnoughDataAvailableYet'));
- return;
- }
-
- for (var count = 0; count < plots.length; count++) {
- if (plots[count].data.length != size) {
- throw new Error('Mismatch in time and plot data.');
- }
- }
-
- function valueToString(value) {
- if (Math.abs(value) < 1) {
- return Number(value).toFixed(yPrecision - 1);
- } else {
- return Number(value).toPrecision(yPrecision);
- }
- }
-
- function getTextWidth(ctx, text) {
- ctx.font = textFont;
- // For now, all text is drawn to the left of vertical lines, or centered.
- // Add a 2 pixel padding so that there is some spacing between the text
- // and the vertical line.
- return Math.round(ctx.measureText(text).width) + 2 * devicePixelRatio;
- }
-
- function getLegend(text) {
- return ' ' + text + ' ';
- }
-
- function drawHighlightText(ctx, text, x, y, color) {
- ctx.strokeStyle = '#000';
- ctx.strokeRect(x, y - textHeight, getTextWidth(ctx, text), textHeight);
- ctx.fillStyle = color;
- ctx.fillRect(x, y - textHeight, getTextWidth(ctx, text), textHeight);
- ctx.fillStyle = '#fff';
- ctx.fillText(text, x, y);
- }
-
- function drawLine(ctx, x1, y1, x2, y2, color) {
- ctx.save();
- ctx.beginPath();
- ctx.moveTo(x1, y1);
- ctx.lineTo(x2, y2);
- ctx.strokeStyle = color;
- ctx.lineWidth = 1 * devicePixelRatio;
- ctx.stroke();
- ctx.restore();
- }
-
- // The strokeRect method of the 2d context of a plotCanvas draws a bounding
- // rectangle with an offset origin and greater dimensions. Hence, use this
- // function to draw a rect at the desired location with desired dimensions.
- function drawRect(ctx, x, y, width, height, color) {
- var offset = 1 * devicePixelRatio;
- drawLine(ctx, x, y, x + width - offset, y, color);
- drawLine(ctx, x, y, x, y + height - offset, color);
- drawLine(ctx, x, y + height - offset, x + width - offset,
- y + height - offset, color);
- drawLine(ctx, x + width - offset, y, x + width - offset,
- y + height - offset, color);
- }
-
- function drawLegend() {
- // Show a legend only if at least one individual plot has a name.
- var valid = false;
- for (var i = 0; i < plots.length; i++) {
- if (plots[i].name != null) {
- valid = true;
- break;
- }
- }
- if (!valid) {
- legendCanvas.hidden = true;
- return;
- }
-
-
- var padding = 2 * devicePixelRatio;
- var legendSquareSide = 12 * devicePixelRatio;
- var legendCtx = legendCanvas.getContext('2d');
- var xLoc = padding;
- var yLoc = padding;
- // Adjust the height of the canvas before drawing on it.
- for (var i = 0; i < plots.length; i++) {
- if (plots[i].name == null) {
- continue;
- }
- var legendText = getLegend(plots[i].name);
- xLoc += legendSquareSide + getTextWidth(legendCtx, legendText) +
- 2 * padding;
- if (i < plots.length - 1) {
- var xLocNext = xLoc +
- getTextWidth(legendCtx, getLegend(plots[i + 1].name)) +
- legendSquareSide;
- if (xLocNext >= legendCanvas.width) {
- xLoc = padding;
- yLoc = yLoc + 2 * padding + textHeight;
- }
- }
- }
-
- legendCanvas.height = yLoc + textHeight + padding;
- legendCanvas.style.height =
- legendCanvas.height / devicePixelRatio + 'px';
-
- xLoc = padding;
- yLoc = padding;
- // Go over the plots again, this time drawing the legends.
- for (var i = 0; i < plots.length; i++) {
- legendCtx.fillStyle = plots[i].color;
- legendCtx.fillRect(xLoc, yLoc, legendSquareSide, legendSquareSide);
- xLoc += legendSquareSide;
-
- var legendText = getLegend(plots[i].name);
- drawText(legendCtx, legendText, xLoc, yLoc + textHeight - 1);
- xLoc += getTextWidth(legendCtx, legendText) + 2 * padding;
-
- if (i < plots.length - 1) {
- var xLocNext = xLoc +
- getTextWidth(legendCtx, getLegend(plots[i + 1].name)) +
- legendSquareSide;
- if (xLocNext >= legendCanvas.width) {
- xLoc = padding;
- yLoc = yLoc + 2 * padding + textHeight;
- }
- }
- }
- }
-
- var yMinStr = valueToString(yMin);
- var yMaxStr = valueToString(yMax);
- var yHalfStr = valueToString((yMax + yMin) / 2);
- var yMinWidth = getTextWidth(plotCtx, yMinStr);
- var yMaxWidth = getTextWidth(plotCtx, yMaxStr);
- var yHalfWidth = getTextWidth(plotCtx, yHalfStr);
-
- var xMinStr = tData[0];
- var xMaxStr = tData[size - 1];
- var xMinWidth = getTextWidth(plotCtx, xMinStr);
- var xMaxWidth = getTextWidth(plotCtx, xMaxStr);
-
- var xOrigin = padding + Math.max(yMinWidth,
- yMaxWidth,
- Math.round(xMinWidth / 2));
- var yOrigin = padding + textHeight;
- var width = plotCanvas.width - xOrigin - Math.floor(xMaxWidth / 2) - padding;
- if (width < size) {
- plotCanvas.width += size - width;
- width = size;
- }
- var height = plotCanvas.height - yOrigin - textHeight - padding;
- var linePlotEndMarkerWidth = 3;
-
- function drawPlots() {
- // Start fresh.
- plotCtx.clearRect(0, 0, plotCanvas.width, plotCanvas.height);
-
- // Draw the bounding rectangle.
- drawRect(plotCtx, xOrigin, yOrigin, width, height, gridColor);
-
- // Draw the x and y bound values.
- drawText(plotCtx, yMaxStr, xOrigin - yMaxWidth, yOrigin + textHeight);
- drawText(plotCtx, yMinStr, xOrigin - yMinWidth, yOrigin + height);
- drawText(plotCtx,
- xMinStr,
- xOrigin - xMinWidth / 2,
- yOrigin + height + textHeight);
- drawText(plotCtx,
- xMaxStr,
- xOrigin + width - xMaxWidth / 2,
- yOrigin + height + textHeight);
-
- // Draw y-level (horizontal) lines.
- drawLine(plotCtx,
- xOrigin + 1, yOrigin + height / 4,
- xOrigin + width - 2, yOrigin + height / 4,
- gridColor);
- drawLine(plotCtx,
- xOrigin + 1, yOrigin + height / 2,
- xOrigin + width - 2, yOrigin + height / 2, gridColor);
- drawLine(plotCtx,
- xOrigin + 1, yOrigin + 3 * height / 4,
- xOrigin + width - 2, yOrigin + 3 * height / 4,
- gridColor);
-
- // Draw half-level value.
- drawText(plotCtx,
- yHalfStr,
- xOrigin - yHalfWidth,
- yOrigin + height / 2 + textHeight / 2);
-
- // Draw the plots.
- var yValRange = yMax - yMin;
- for (var count = 0; count < plots.length; count++) {
- var plot = plots[count];
- var yData = plot.data;
- plotCtx.strokeStyle = plot.color;
- plotCtx.lineWidth = 2;
- plotCtx.beginPath();
- var beginPath = true;
- for (var i = 0; i < size; i++) {
- var val = yData[i];
- if (typeof val === 'string') {
- // Stroke the plot drawn so far and begin a fresh plot.
- plotCtx.stroke();
- plotCtx.beginPath();
- beginPath = true;
- continue;
- }
- var xPos = xOrigin + Math.floor(i / (size - 1) * (width - 1));
- var yPos = yOrigin + height - 1 -
- Math.round((val - yMin) / yValRange * (height - 1));
- if (beginPath) {
- plotCtx.moveTo(xPos, yPos);
- // A simple move to does not print anything. Hence, draw a little
- // square here to mark a beginning.
- plotCtx.fillStyle = '#000';
- plotCtx.fillRect(xPos - linePlotEndMarkerWidth,
- yPos - linePlotEndMarkerWidth,
- linePlotEndMarkerWidth * devicePixelRatio,
- linePlotEndMarkerWidth * devicePixelRatio);
- beginPath = false;
- } else {
- plotCtx.lineTo(xPos, yPos);
- if (i === size - 1 || typeof yData[i + 1] === 'string') {
- // Draw a little square to mark an end to go with the start
- // markers from above.
- plotCtx.fillStyle = '#000';
- plotCtx.fillRect(xPos - linePlotEndMarkerWidth,
- yPos - linePlotEndMarkerWidth,
- linePlotEndMarkerWidth * devicePixelRatio,
- linePlotEndMarkerWidth * devicePixelRatio);
- }
- }
- }
- plotCtx.stroke();
- }
-
- // Paint the missing time intervals with |gridColor|.
- // Pick one of the plots to look for missing time intervals.
- function drawMissingRect(start, end) {
- var xLeft = xOrigin + Math.floor(start / (size - 1) * (width - 1));
- var xRight = xOrigin + Math.floor(end / (size - 1) * (width - 1));
- plotCtx.fillStyle = gridColor;
- // The x offsets below are present so that the blank space starts
- // and ends between two valid samples.
- plotCtx.fillRect(xLeft + 1, yOrigin, xRight - xLeft - 2, height - 1);
- }
- var inMissingInterval = false;
- var intervalStart;
- for (var i = 0; i < size; i++) {
- if (typeof plots[0].data[i] === 'string') {
- if (!inMissingInterval) {
- inMissingInterval = true;
- // The missing interval should actually start from the previous
- // sample.
- intervalStart = Math.max(i - 1, 0);
- }
-
- if (i == size - 1) {
- // If this is the last sample, just draw missing rect.
- drawMissingRect(intervalStart, i);
- }
- } else if (inMissingInterval) {
- inMissingInterval = false;
- drawMissingRect(intervalStart, i);
- }
- }
- }
-
- function drawTimeGuide(tDataIndex) {
- var x = xOrigin + tDataIndex / (size - 1) * (width - 1);
- drawLine(plotCtx, x, yOrigin, x, yOrigin + height - 1, '#000');
- drawText(plotCtx,
- tData[tDataIndex],
- x - getTextWidth(plotCtx, tData[tDataIndex]) / 2,
- yOrigin - 2);
-
- for (var count = 0; count < plots.length; count++) {
- var yData = plots[count].data;
-
- // Draw small black square on the plot where the time guide intersects
- // it.
- var val = yData[tDataIndex];
- var yPos, valStr;
- if (typeof val === 'string') {
- yPos = yOrigin + Math.round(height / 2);
- valStr = val;
- } else {
- yPos = yOrigin + height - 1 -
- Math.round((val - yMin) / (yMax - yMin) * (height - 1));
- valStr = valueToString(val);
- }
- plotCtx.fillStyle = '#000';
- plotCtx.fillRect(x - 2, yPos - 2, 4, 4);
-
- // Draw the val to right of the intersection.
- var yLoc;
- if (yPos - textHeight / 2 < yOrigin) {
- yLoc = yOrigin + textHeight;
- } else if (yPos + textHeight / 2 >= yPos + height) {
- yLoc = yOrigin + height - 1;
- } else {
- yLoc = yPos + textHeight / 2;
- }
- drawHighlightText(plotCtx, valStr, x + 5, yLoc, plots[count].color);
- }
- }
-
- function onMouseOverOrMove(event) {
- drawPlots();
-
- var boundingRect = plotCanvas.getBoundingClientRect();
- var x = Math.round((event.clientX - boundingRect.left) * devicePixelRatio);
- var y = Math.round((event.clientY - boundingRect.top) * devicePixelRatio);
- if (x < xOrigin || x >= xOrigin + width ||
- y < yOrigin || y >= yOrigin + height) {
- return;
- }
-
- if (width == size) {
- drawTimeGuide(x - xOrigin);
- } else {
- drawTimeGuide(Math.round((x - xOrigin) / (width - 1) * (size - 1)));
- }
- }
-
- function onMouseOut(event) {
- drawPlots();
- }
-
- drawLegend();
- drawPlots();
- plotCanvas.addEventListener('mouseover', onMouseOverOrMove);
- plotCanvas.addEventListener('mousemove', onMouseOverOrMove);
- plotCanvas.addEventListener('mouseout', onMouseOut);
-}
-
-var sleepSampleInterval = 30 * 1000; // in milliseconds.
-var sleepText = loadTimeData.getString('systemSuspended');
-var invalidDataText = loadTimeData.getString('invalidData');
-var offlineText = loadTimeData.getString('offlineText');
-
-var plotColors = ['Red', 'Blue', 'Green', 'Gold', 'CadetBlue', 'LightCoral',
- 'LightSlateGray', 'Peru', 'DarkRed', 'LawnGreen', 'Tan'];
-
-/**
- * Add canvases for plotting to |plotsDiv|. For every header in |headerArray|,
- * one canvas for the plot and one for its legend are added.
- *
- * @param {Array<string>} headerArray Headers for the different plots to be
- * added to |plotsDiv|.
- * @param {HTMLDivElement} plotsDiv The div element into which the canvases
- * are added.
- * @return {<string>: {plotCanvas: <HTMLCanvasElement>,
- * legendCanvas: <HTMLCanvasElement>} Returns an object
- * with the headers as 'keys'. Each element is an object containing the
- * legend canvas and the plot canvas that have been added to |plotsDiv|.
- */
-function addCanvases(headerArray, plotsDiv) {
- // Remove the contents before adding new ones.
- while (plotsDiv.firstChild != null) {
- plotsDiv.removeChild(plotsDiv.firstChild);
- }
- var width = Math.floor(plotsDiv.getBoundingClientRect().width);
- var canvases = {};
- for (var i = 0; i < headerArray.length; i++) {
- var header = document.createElement('h4');
- header.textContent = headerArray[i];
- plotsDiv.appendChild(header);
-
- var legendCanvas = document.createElement('canvas');
- legendCanvas.width = width * devicePixelRatio;
- legendCanvas.style.width = width + 'px';
- plotsDiv.appendChild(legendCanvas);
-
- var plotCanvasDiv = document.createElement('div');
- plotCanvasDiv.style.overflow = 'auto';
- plotsDiv.appendChild(plotCanvasDiv);
-
- plotCanvas = document.createElement('canvas');
- plotCanvas.width = width * devicePixelRatio;
- plotCanvas.height = 200 * devicePixelRatio;
- plotCanvas.style.height = '200px';
- plotCanvasDiv.appendChild(plotCanvas);
-
- canvases[headerArray[i]] = {plot: plotCanvas, legend: legendCanvas};
- }
- return canvases;
-}
-
-/**
- * Add samples in |sampleArray| to individual plots in |plots|. If the system
- * resumed from a sleep/suspend, then "suspended" sleep samples are added to
- * the plot for the sleep duration.
- *
- * @param {Array<{data: Array<number>, color: string}>} plots An
- * array of plots to plot on the canvas. The field 'data' of a plot is an
- * array of samples to be plotted as a line graph with color speficied by
- * the field 'color'. The elements in the 'data' array are ordered
- * corresponding to their sampling time in the argument 'tData'. Also, the
- * number of elements in the 'data' array should be the same as in the time
- * array 'tData' below.
- * @param {Array<number>} tData The time (in seconds) in the past when the
- * corresponding data in plots was sampled.
- * @param {Array<number>} absTime
- * @param {Array<number>} sampleArray The array of samples wherein each
- * element corresponds to the individual plot in |plots|.
- * @param {number} sampleTime Time in milliseconds since the epoch when the
- * samples in |sampleArray| were captured.
- * @param {number} previousSampleTime Time in milliseconds since the epoch
- * when the sample prior to the current sample was captured.
- * @param {Array<{time: number, sleepDuration: number}>} systemResumedArray An
- * array objects corresponding to system resume events. The 'time' field is
- * for the time in milliseconds since the epoch when the system resumed. The
- * 'sleepDuration' field is for the time in milliseconds the system spent
- * in sleep/suspend state.
- */
-function addTimeDataSample(plots, tData, absTime, sampleArray,
- sampleTime, previousSampleTime,
- systemResumedArray) {
- for (var i = 0; i < plots.length; i++) {
- if (plots[i].data.length != tData.length) {
- throw new Error('Mismatch in time and plot data.');
- }
- }
-
- var time;
- if (tData.length == 0) {
- time = new Date(sampleTime);
- absTime[0] = sampleTime;
- tData[0] = time.toLocaleTimeString();
- for (var i = 0; i < plots.length; i++) {
- plots[i].data[0] = sampleArray[i];
- }
- return;
- }
-
- for (var i = 0; i < systemResumedArray.length; i++) {
- var resumeTime = systemResumedArray[i].time;
- var sleepDuration = systemResumedArray[i].sleepDuration;
- var sleepStartTime = resumeTime - sleepDuration;
- if (resumeTime < sampleTime) {
- if (sleepStartTime < previousSampleTime) {
- // This can happen if pending callbacks were handled before actually
- // suspending.
- sleepStartTime = previousSampleTime + 1000;
- }
- // Add sleep samples for every |sleepSampleInterval|.
- var sleepSampleTime = sleepStartTime;
- while (sleepSampleTime < resumeTime) {
- time = new Date(sleepSampleTime);
- absTime.push(sleepSampleTime);
- tData.push(time.toLocaleTimeString());
- for (var j = 0; j < plots.length; j++) {
- plots[j].data.push(sleepText);
- }
- sleepSampleTime += sleepSampleInterval;
- }
- }
- }
-
- time = new Date(sampleTime);
- absTime.push(sampleTime);
- tData.push(time.toLocaleTimeString());
- for (var i = 0; i < plots.length; i++) {
- plots[i].data.push(sampleArray[i]);
- }
-}
-
-/**
- * Display the battery charge vs time on a line graph.
- *
- * @param {Array<{time: number,
- * batteryPercent: number,
- * batteryDischargeRate: number,
- * externalPower: number}>} powerSupplyArray An array of objects
- * with fields representing the battery charge, time when the charge
- * measurement was taken, and whether there was external power connected at
- * that time.
- * @param {Array<{time: ?, sleepDuration: ?}>} systemResumedArray An array
- * objects with fields 'time' and 'sleepDuration'. Each object corresponds
- * to a system resume event. The 'time' field is for the time in
- * milliseconds since the epoch when the system resumed. The 'sleepDuration'
- * field is for the time in milliseconds the system spent in sleep/suspend
- * state.
- */
-function showBatteryChargeData(powerSupplyArray, systemResumedArray) {
- var chargeTimeData = [];
- var chargeAbsTime = [];
- var chargePlot = [
- {
- name: loadTimeData.getString('batteryChargePercentageHeader'),
- color: 'Blue',
- data: []
- }
- ];
- var dischargeRateTimeData = [];
- var dischargeRateAbsTime = [];
- var dischargeRatePlot = [
- {
- name: loadTimeData.getString('dischargeRateLegendText'),
- color: 'Red',
- data: []
- },
- {
- name: loadTimeData.getString('movingAverageLegendText'),
- color: 'Green',
- data: []
- },
- {
- name: loadTimeData.getString('binnedAverageLegendText'),
- color: 'Blue',
- data: []
- }
- ];
- var minDischargeRate = 1000; // A high unrealistic number to begin with.
- var maxDischargeRate = -1000; // A low unrealistic number to begin with.
- for (var i = 0; i < powerSupplyArray.length; i++) {
- var j = Math.max(i - 1, 0);
-
- addTimeDataSample(chargePlot,
- chargeTimeData,
- chargeAbsTime,
- [powerSupplyArray[i].batteryPercent],
- powerSupplyArray[i].time,
- powerSupplyArray[j].time,
- systemResumedArray);
-
- var dischargeRate = powerSupplyArray[i].batteryDischargeRate;
- var inputSampleCount = $('sample-count-input').value;
-
- var movingAverage = 0;
- var k = 0;
- for (k = 0; k < inputSampleCount && i - k >= 0; k++) {
- movingAverage += powerSupplyArray[i - k].batteryDischargeRate;
- }
- // |k| will be atleast 1 because the 'min' value of the input field is 1.
- movingAverage /= k;
-
- var binnedAverage = 0;
- for (k = 0; k < inputSampleCount; k++) {
- var currentSampleIndex = i - i % inputSampleCount + k;
- if (currentSampleIndex >= powerSupplyArray.length) {
- break;
- }
-
- binnedAverage +=
- powerSupplyArray[currentSampleIndex].batteryDischargeRate;
- }
- binnedAverage /= k;
-
- minDischargeRate = Math.min(dischargeRate, minDischargeRate);
- maxDischargeRate = Math.max(dischargeRate, maxDischargeRate);
- addTimeDataSample(dischargeRatePlot,
- dischargeRateTimeData,
- dischargeRateAbsTime,
- [dischargeRate, movingAverage, binnedAverage],
- powerSupplyArray[i].time,
- powerSupplyArray[j].time,
- systemResumedArray);
- }
- if (minDischargeRate == maxDischargeRate) {
- // This means that all the samples had the same value. Hence, offset the
- // extremes by a bit so that the plot looks good.
- minDischargeRate -= 1;
- maxDischargeRate += 1;
- }
-
- plotsDiv = $('battery-charge-plots-div');
-
- canvases = addCanvases(
- [loadTimeData.getString('batteryChargePercentageHeader'),
- loadTimeData.getString('batteryDischargeRateHeader')],
- plotsDiv);
-
- batteryChargeCanvases = canvases[
- loadTimeData.getString('batteryChargePercentageHeader')];
- plotLineGraph(
- batteryChargeCanvases['plot'],
- batteryChargeCanvases['legend'],
- chargeTimeData,
- chargePlot,
- 0.00,
- 100.00,
- 3);
-
- dischargeRateCanvases = canvases[
- loadTimeData.getString('batteryDischargeRateHeader')];
- plotLineGraph(
- dischargeRateCanvases['plot'],
- dischargeRateCanvases['legend'],
- dischargeRateTimeData,
- dischargeRatePlot,
- minDischargeRate,
- maxDischargeRate,
- 3);
-}
-
-/**
- * Shows state occupancy data (CPU idle or CPU freq state occupancy) on a set of
- * plots on the about:power UI.
- *
- * @param {Array<Array<{
- * time: number,
- * cpuOnline: boolean,
- * timeInState: Object<number>}>} timeInStateData Array of arrays
- * where each array corresponds to a CPU on the system. The elements of the
- * individual arrays contain state occupancy samples.
- * @param {Array<{time: ?, sleepDuration: ?}>} systemResumedArray An array
- * objects with fields 'time' and 'sleepDuration'. Each object corresponds
- * to a system resume event. The 'time' field is for the time in
- * milliseconds since the epoch when the system resumed. The 'sleepDuration'
- * field is for the time in milliseconds the system spent in sleep/suspend
- * state.
- * @param {string} i18nHeaderString The header string to be displayed with each
- * plot. For example, CPU idle data will have its own header format, and CPU
- * freq data will have its header format.
- * @param {string} unitString This is the string capturing the unit, if any,
- * for the different states. Note that this is not the unit of the data
- * being plotted.
- * @param {HTMLDivElement} plotsDivId The div element in which the plots should
- * be added.
- */
-function showStateOccupancyData(timeInStateData,
- systemResumedArray,
- i18nHeaderString,
- unitString,
- plotsDivId) {
- var cpuPlots = [];
- for (var cpu = 0; cpu < timeInStateData.length; cpu++) {
- var cpuData = timeInStateData[cpu];
- if (cpuData.length == 0) {
- cpuPlots[cpu] = {plots: [], tData: []};
- continue;
- }
- tData = [];
- absTime = [];
- // Each element of |plots| is an array of samples, one for each of the CPU
- // states. The number of states is dicovered by looking at the first
- // sample for which the CPU is online.
- var plots = [];
- var stateIndexMap = [];
- var stateCount = 0;
- for (var i = 0; i < cpuData.length; i++) {
- if (cpuData[i].cpuOnline) {
- for (var state in cpuData[i].timeInState) {
- var stateName = state;
- if (unitString != null) {
- stateName += ' ' + unitString;
- }
- plots.push({
- name: stateName,
- data: [],
- color: plotColors[stateCount]
- });
- stateIndexMap.push(state);
- stateCount += 1;
- }
- break;
- }
- }
- // If stateCount is 0, then it means the CPU has been offline
- // throughout. Just add a single plot for such a case.
- if (stateCount == 0) {
- plots.push({
- name: null,
- data: [],
- color: null
- });
- stateCount = 1; // Some invalid state!
- }
-
- // Pass the samples through the function addTimeDataSample to add 'sleep'
- // samples.
- for (var i = 0; i < cpuData.length; i++) {
- var sample = cpuData[i];
- var valArray = [];
- for (var j = 0; j < stateCount; j++) {
- if (sample.cpuOnline) {
- valArray[j] = sample.timeInState[stateIndexMap[j]];
- } else {
- valArray[j] = offlineText;
- }
- }
-
- var k = Math.max(i - 1, 0);
- addTimeDataSample(plots,
- tData,
- absTime,
- valArray,
- sample.time,
- cpuData[k].time,
- systemResumedArray);
- }
-
- // Calculate the percentage occupancy of each state. A valid number is
- // possible only if two consecutive samples are valid/numbers.
- for (var k = 0; k < stateCount; k++) {
- var stateData = plots[k].data;
- // Skip the first sample as there is no previous sample.
- for (var i = stateData.length - 1; i > 0; i--) {
- if (typeof stateData[i] === 'number') {
- if (typeof stateData[i - 1] === 'number') {
- stateData[i] = (stateData[i] - stateData[i - 1]) /
- (absTime[i] - absTime[i - 1]) * 100;
- } else {
- stateData[i] = invalidDataText;
- }
- }
- }
- }
-
- // Remove the first sample from the time and data arrays.
- tData.shift();
- for (var k = 0; k < stateCount; k++) {
- plots[k].data.shift();
- }
- cpuPlots[cpu] = {plots: plots, tData: tData};
- }
-
- headers = [];
- for (var cpu = 0; cpu < timeInStateData.length; cpu++) {
- headers[cpu] =
- 'CPU ' + cpu + ' ' + loadTimeData.getString(i18nHeaderString);
- }
-
- canvases = addCanvases(headers, $(plotsDivId));
- for (var cpu = 0; cpu < timeInStateData.length; cpu++) {
- cpuCanvases = canvases[headers[cpu]];
- plotLineGraph(cpuCanvases['plot'],
- cpuCanvases['legend'],
- cpuPlots[cpu]['tData'],
- cpuPlots[cpu]['plots'],
- 0,
- 100,
- 3);
- }
-}
-
-function showCpuIdleData(idleStateData, systemResumedArray) {
- showStateOccupancyData(idleStateData,
- systemResumedArray,
- 'idleStateOccupancyPercentageHeader',
- null,
- 'cpu-idle-plots-div');
-}
-
-function showCpuFreqData(freqStateData, systemResumedArray) {
- showStateOccupancyData(freqStateData,
- systemResumedArray,
- 'frequencyStateOccupancyPercentageHeader',
- 'MHz',
- 'cpu-freq-plots-div');
-}
-
-function requestBatteryChargeData() {
- chrome.send('requestBatteryChargeData');
-}
-
-function requestCpuIdleData() {
- chrome.send('requestCpuIdleData');
-}
-
-function requestCpuFreqData() {
- chrome.send('requestCpuFreqData');
-}
-
-/**
- * Return a callback for the 'Show'/'Hide' buttons for each section of the
- * about:power page.
- *
- * @param {string} sectionId The ID of the section which is to be shown or
- * hidden.
- * @param {string} buttonId The ID of the 'Show'/'Hide' button.
- * @param {function} requestFunction The function which should be invoked on
- * 'Show' to request for data from chrome.
- * @return {function} The button callback function.
- */
-function showHideCallback(sectionId, buttonId, requestFunction) {
- return function() {
- if ($(sectionId).hidden) {
- $(sectionId).hidden = false;
- $(buttonId).textContent = loadTimeData.getString('hideButton');
- requestFunction();
- } else {
- $(sectionId).hidden = true;
- $(buttonId).textContent = loadTimeData.getString('showButton');
- }
- }
-}
-
-var powerUI = {
- showBatteryChargeData: showBatteryChargeData,
- showCpuIdleData: showCpuIdleData,
- showCpuFreqData: showCpuFreqData
-};
-
-document.addEventListener('DOMContentLoaded', function() {
- $('battery-charge-section').hidden = true;
- $('battery-charge-show-button').onclick = showHideCallback(
- 'battery-charge-section',
- 'battery-charge-show-button',
- requestBatteryChargeData);
- $('battery-charge-reload-button').onclick = requestBatteryChargeData;
- $('sample-count-input').onclick = requestBatteryChargeData;
-
- $('cpu-idle-section').hidden = true;
- $('cpu-idle-show-button').onclick = showHideCallback(
- 'cpu-idle-section', 'cpu-idle-show-button', requestCpuIdleData);
- $('cpu-idle-reload-button').onclick = requestCpuIdleData;
-
- $('cpu-freq-section').hidden = true;
- $('cpu-freq-show-button').onclick = showHideCallback(
- 'cpu-freq-section', 'cpu-freq-show-button', requestCpuFreqData);
- $('cpu-freq-reload-button').onclick = requestCpuFreqData;
-});
diff --git a/chromium/chrome/browser/resources/chromeos/proxy_settings.css b/chromium/chrome/browser/resources/chromeos/proxy_settings.css
deleted file mode 100644
index d08633155fa..00000000000
--- a/chromium/chrome/browser/resources/chromeos/proxy_settings.css
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* These additional styles constrain the size of the proxy page to the height of
- the dialog containing them. */
-html {
- height: 100%;
-}
-
-body {
- -webkit-box-sizing: border-box;
- height: 100%;
- margin: 0;
- padding: 8px;
-}
-
-#proxyPage {
- height: 100%;
-}
-
-#proxy-page-title {
- /* We have a title on the window, so the title in domui should be hidden. */
- display: none;
-}
-
-#internet-details-content-area > .subpages-tab-contents {
- height: 100% !important;
-}
-
-#advanced-config {
- padding-top: 10px;
-}
-
-html[highlight=strong] input[type='button']:focus,
-html[highlight=strong] input[type='checkbox']:focus,
-html[highlight=strong] input[type='radio']:focus,
-html[highlight=strong] input[type='text']:focus,
-html[highlight=strong] input[type='url']:focus,
-html[highlight=strong] button:focus,
-html[highlight=strong] list:focus {
- box-shadow: 0 0 23px rgb(77, 144, 254) !important;
-}
-
-html[highlight=strong] #network-proxy-tab {
- padding: 10px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/proxy_settings.html b/chromium/chrome/browser/resources/chromeos/proxy_settings.html
deleted file mode 100644
index 061eaf803ee..00000000000
--- a/chromium/chrome/browser/resources/chromeos/proxy_settings.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;highlight:highlightStrength;lang:language">
-<head>
-<meta charset="utf-8">
-<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
-<link rel="stylesheet" href="chrome://resources/css/list.css">
-<link rel="stylesheet" href="chrome://resources/css/widgets.css">
-
-<link rel="stylesheet" href="../options/options_page.css">
-<link rel="stylesheet" href="../options/chromeos/internet_detail.css">
-<link rel="stylesheet" href="proxy_settings.css">
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/event_tracker.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/cr/ui.js"></script>
-<script src="chrome://resources/js/cr/ui/touch_handler.js"></script>
-<script src="chrome://resources/js/cr/ui/array_data_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script>
-<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"></script>
-<script src="chrome://resources/js/cr/ui/list_item.js"></script>
-<script src="chrome://resources/js/cr/ui/list.js"></script>
-<script src="chrome://resources/js/cr/ui/page_manager/page_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/page_manager/page.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-
-<script src="../options/preferences.js"></script>
-<script src="../options/pref_ui.js"></script>
-<script src="../options/options_page.js"></script>
-<script src="../options/chromeos/onc_data.js"></script>
-<script src="../options/chromeos/internet_detail.js"></script>
-<script src="../options/chromeos/proxy_rules_list.js"></script>
-<script src="keyboard/keyboard_utils.js"></script>
-
-<script src="proxy_settings.js"></script>
-</head>
-
-<body>
-<include src="../options/chromeos/internet_detail.html">
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/proxy_settings.js b/chromium/chrome/browser/resources/chromeos/proxy_settings.js
deleted file mode 100644
index 45bf609faff..00000000000
--- a/chromium/chrome/browser/resources/chromeos/proxy_settings.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var Preferences = options.Preferences;
-var DetailsInternetPage = options.internet.DetailsInternetPage;
-
-/**
- * DOMContentLoaded handler, sets up the page.
- */
-function load() {
- if (cr.isChromeOS)
- document.documentElement.setAttribute('os', 'chromeos');
-
- // Decorate the existing elements in the document.
- cr.ui.decorate('input[pref][type=checkbox]', options.PrefCheckbox);
- cr.ui.decorate('input[pref][type=number]', options.PrefNumber);
- cr.ui.decorate('input[pref][type=radio]', options.PrefRadio);
- cr.ui.decorate('input[pref][type=range]', options.PrefRange);
- cr.ui.decorate('select[pref]', options.PrefSelect);
- cr.ui.decorate('input[pref][type=text]', options.PrefTextField);
- cr.ui.decorate('input[pref][type=url]', options.PrefTextField);
-
- DetailsInternetPage.initializeProxySettings();
-
- // TODO(ivankr): remove when http://crosbug.com/20660 is resolved.
- var inputs = document.querySelectorAll('input[pref]');
- for (var i = 0, el; el = inputs[i]; i++) {
- el.addEventListener('keyup', function(e) {
- cr.dispatchSimpleEvent(this, 'change');
- });
- }
-
- Preferences.getInstance().initialize();
- chrome.send('coreOptionsInitialize');
-
- var params = parseQueryParams(window.location);
- var network = params.network;
- if (!network) {
- console.error('Error: No network argument provided!');
- network = '';
- }
- chrome.send('selectNetwork', [network]);
-
- DetailsInternetPage.showProxySettings();
-}
-
-disableTextSelectAndDrag(function(e) {
- var src = e.target;
- return src instanceof HTMLTextAreaElement ||
- src instanceof HTMLInputElement &&
- /text|url/.test(src.type);
-});
-
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chromium/chrome/browser/resources/chromeos/salsa.css b/chromium/chrome/browser/resources/chromeos/salsa.css
deleted file mode 100644
index b4a2b3eee29..00000000000
--- a/chromium/chrome/browser/resources/chromeos/salsa.css
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#entry-list {
- list-style-type: none;
- width: 900px;
-}
-
-.entry {
- width: 100%;
-}
-
-.entry-key,
-.entry-value {
- font-size: small;
-}
-
-p,
-span {
- font-weight: bold;
-}
-
-#treatment-header {
- display: table-cell;
- padding-right: 20px;
- vertical-align: middle;
-}
-
-.treatment {
- display: table-cell;
- height: 40px;
- text-align: center;
- vertical-align: middle;
- width: 40px;
-}
-
-.selected {
- border: 2px solid black;
- border-radius: 20px;
-}
-
-#bounding-box {
- border: 1px solid black;
- border-radius: 10px;
- margin: 50px;
- padding: 15px;
- text-align: center;
- width: 600px;
-}
-
-#instructions {
- text-align: left;
-}
-
-#treatment-list {
- display: inline-block;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/salsa.html b/chromium/chrome/browser/resources/chromeos/salsa.html
deleted file mode 100644
index 50d6775f452..00000000000
--- a/chromium/chrome/browser/resources/chromeos/salsa.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>Salsa</title>
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" href="salsa.css">
- <script src="salsa.js"></script>
-</head>
-
-<body>
-<div id="bounding-box">
- <h1 class="title">Salsa</h1>
-
- <div id="invalid-treatment-info" hidden>
- I'm afraid there has been some problem determining which treatments to use
- for your experiment. Please try to copy/paste the URL again and refresh
- this page. If the problem persists please contact the person running the
- experiment.
- </div>
-
- <div id="valid-treatment-info">
- <div id="treatment-list">
- <div id="treatment-header">Available Treatments:</div>
- <div id="treatment-template" class="treatment" hidden></div>
- </div>
-
- <p>Instructions</p>
-
- <ul id="instructions">
- <li> <span>Click</span> or use your <span>arrow keys</span> to change the
- selected treatment.
-
- <li> Treatments are ordered randomly, so there is no special significance
- to their labels.
-
- <li> When you navigate away from this page your settings will be returned
- to normal. If the browser crashes, and/or you experience unusual behavior
- after this experiment, you can manually reset your settings to their
- default values at <a href="chrome://gesture">chrome://gesture</a>.
- </ul>
-
- <p>Thank you for your participation!</p>
- </div>
-</div>
-
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/salsa.js b/chromium/chrome/browser/resources/chromeos/salsa.js
deleted file mode 100644
index ef036928ec8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/salsa.js
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Redefine '$' here rather than including 'cr.js', since this is
-// the only function needed. This allows this file to be loaded
-// in a browser directly for layout and some testing purposes.
-var $ = function(id) { return document.getElementById(id); };
-
-var currentTreatment = 0;
-var treatments = [];
-
-/**
- * Take a string of hex like '74657374' and return the ascii version 'test'.
- * @param {string} str The string of hex characters to convert to ascii
- * @return {string} The ASCII values of those hex encoded characters
- */
-function hexToChars(str) {
- var decoded = '';
- if (str.length % 2 == 0) {
- for (var pos = str.length; pos > 0; pos = pos - 2) {
- var c = String.fromCharCode(parseInt(str.substring(pos - 2, pos), 16));
- decoded = c + decoded;
- }
- }
- return decoded;
-}
-
-/**
- * Extract the experiment information out of the encoded URL string.
- * The format is as follows:
- * chrome://salsa/#HEX_ENCODED_EXPERIMENT
- * Experiments are encoded as:
- * treatment1+treatment2+...+treatmentn
- * Each treatment is of the form:
- * preference1,preference2,...,preferencen
- * Each preference is of the form:
- * name:value
- * This function returns an object storing all the parsed data.
- * @param {string} url The URL to parse the experiment from
- * @return {list} a list of objects, each representing a single treatment
- * and consisting of a set of preference name -> value pairs
- */
-function parseURL(url) {
- var match = url.match('#([0-9ABCDEFabcdef]*)');
- var experimentString = match ? match[1] : '';
- experimentString = hexToChars(experimentString);
-
- var treatmentsFound = [];
- if (experimentString == '')
- return treatmentsFound;
-
- var treatmentStrings = experimentString.split('+');
- for (var i = 0; i < treatmentStrings.length; i++) {
- var prefStrings = treatmentStrings[i].split(',');
- treatment = [];
- for (var j = 0; j < prefStrings.length; j++) {
- var key = prefStrings[j].split(':')[0];
- var value = prefStrings[j].split(':')[1];
- treatment.push({'key': key, 'value': value});
- }
- treatmentsFound.push(treatment);
- }
-
- return treatmentsFound;
-}
-
-function setPreferenceValue(key, value) {
- chrome.send('salsaSetPreferenceValue', [key, parseFloat(value)]);
-}
-
-function backupPreferenceValue(key) {
- chrome.send('salsaBackupPreferenceValue', [key]);
-}
-
-function handleKeyPress(e) {
- e = e || window.event;
- var selectedTreatment = currentTreatment;
-
- if (e.keyCode == '37' || e.keyCode == '38') {
- selectedTreatment = currentTreatment - 1;
- if (selectedTreatment < 0)
- selectedTreatment = 0;
- } else if (e.keyCode == '39' || e.keyCode == '40') {
- selectedTreatment = currentTreatment + 1;
- if (selectedTreatment >= treatments.length)
- selectedTreatment = treatments.length - 1;
- }
-
- if (selectedTreatment != currentTreatment)
- applyTreatment(selectedTreatment);
-}
-
-function applyTreatment(treatmentNumber) {
- if (treatmentNumber < 0)
- treatmentNumber = 0;
- if (treatmentNumber >= treatments.length)
- treatmentNumber = treatments.length;
-
- $('treatment' + currentTreatment).className = 'treatment';
- currentTreatment = treatmentNumber;
- $('treatment' + currentTreatment).className = 'selected treatment';
-
- for (var i = 0; i < treatments[treatmentNumber].length; i++) {
- var key = treatments[treatmentNumber][i].key;
- var value = treatments[treatmentNumber][i].value;
- setPreferenceValue(key, value);
- }
-}
-
-function initialize() {
- // Parse the experiment string in the URL.
- treatments = parseURL(document.URL);
-
- // Update the available treatments list.
- for (var i = 0; i < treatments.length; i++) {
- var newTreatment = $('treatment-template').cloneNode(true);
- newTreatment.id = 'treatment' + i.toString();
- newTreatment.removeAttribute('hidden');
- newTreatment.onclick = function() {
- applyTreatment(parseInt(this.textContent));
- };
- newTreatment.textContent = i.toString();
- $('treatment-list').appendChild(newTreatment);
- }
-
- if (treatments.length > 0) {
- // Store a copy of the settings right now so you can reset them afterwards.
- for (var i = 0; i < treatments[0].length; i++)
- backupPreferenceValue(treatments[0][i].key);
-
- // Select Treatment 0 to start
- applyTreatment(0);
- } else {
- // Make the error message visible and hide everything else
- $('invalid-treatment-info').hidden = false;
- var div = $('valid-treatment-info');
- div.parentNode.removeChild(div);
- }
-}
-
-/**
- * A key handler so the user can use the arrow keys to select their treatments.
- * This should fire any time they press a key
- */
-document.onkeydown = handleKeyPress;
-document.addEventListener('DOMContentLoaded', initialize);
diff --git a/chromium/chrome/browser/resources/chromeos/set_time.css b/chromium/chrome/browser/resources/chromeos/set_time.css
deleted file mode 100644
index fcc2e4f89db..00000000000
--- a/chromium/chrome/browser/resources/chromeos/set_time.css
+++ /dev/null
@@ -1,45 +0,0 @@
-/* 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. */
-
-body {
- overflow: hidden; /* Hide scrollbars for accurate size calculation. */
- padding: 8px 20px;
-}
-
-h2 {
- margin-bottom: 20px;
-}
-
-.button-strip {
- display: flex;
- justify-content: flex-end;
- margin-top: 25px;
-}
-
-.row {
- align-items: center;
- display: flex;
- margin: 0.65em 0;
-}
-
-input[type='date'],
-input[type='time'] {
- font-family: inherit;
- font-size: 16px;
- letter-spacing: 1px;
- margin-bottom: 4px;
-}
-
-input[type='date']::-webkit-clear-button,
-input[type='time']::-webkit-clear-button {
- display: none;
-}
-
-label {
- -webkit-margin-end: 5px;
-}
-
-#timezone-select {
- flex: 1;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/set_time.html b/chromium/chrome/browser/resources/chromeos/set_time.html
deleted file mode 100644
index 05013522c45..00000000000
--- a/chromium/chrome/browser/resources/chromeos/set_time.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<meta charset="utf-8">
-<title i18n-content="setTimeTitle"></title>
-
-<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
-<link rel="stylesheet" href="set_time.css">
-</head>
-
-<body>
-<form id="set-time">
- <h2 i18n-content="setTimeTitle"></h2>
- <p id="prompt" i18n-content="prompt" class="row"></p>
-
- <div class="timeControl">
- <input id="date" type="date" i18n-values="title:dateLabel">
- <input id="time" type="time" i18n-values="title:timeLabel">
- </div>
-
- <div id="timezone" class="row" hidden>
- <label id="timezone-label" for="timezone-select" i18n-content="timezone">
- </label>
- <select id="timezone-select" i18n-options="timezoneList"></select>
- </div>
-
- <div class="button-strip">
- <button id="done" type="submit" i18n-content="doneButton"></button>
- </div>
-</form>
-
-<script src="chrome://resources/js/cr.js"></script>
-<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="set_time.js"></script>
-<script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/set_time.js b/chromium/chrome/browser/resources/chromeos/set_time.js
deleted file mode 100644
index 9ff4d8b2d59..00000000000
--- a/chromium/chrome/browser/resources/chromeos/set_time.js
+++ /dev/null
@@ -1,200 +0,0 @@
-// 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('settime', function() {
- /**
- * TimeSetter handles a dialog to check and set system time. It can also
- * include a timezone dropdown if timezoneId is provided.
- *
- * TimeSetter uses the system time to populate the controls initially and
- * update them as the system time or timezone changes, and notifies Chrome
- * when the user changes the time or timezone.
- * @constructor
- */
- function TimeSetter() {}
-
- cr.addSingletonGetter(TimeSetter);
-
- /** @const */ var BODY_PADDING_PX = 20;
- /** @const */ var LABEL_PADDING_PX = 5;
-
- TimeSetter.prototype = {
- /**
- * Performs initial setup.
- */
- initialize: function() {
- // Store values for reverting inputs when the user's date/time is invalid.
- this.prevValues_ = {};
-
- // The build time doesn't include a timezone, so subtract 1 day to get a
- // safe minimum date.
- this.minDate_ = new Date(loadTimeData.getValue('buildTime'));
- this.minDate_.setDate(this.minDate_.getDate() - 1);
-
- // Set the max date to the min date plus 20 years.
- this.maxDate_ = new Date(this.minDate_);
- this.maxDate_.setYear(this.minDate_.getFullYear() + 20);
-
- // Make sure the ostensible date is within this range.
- var now = new Date();
- if (now > this.maxDate_)
- this.maxDate_ = now;
- else if (now < this.minDate_)
- this.minDate_ = now;
-
- $('date').setAttribute('min', this.toHtmlValues_(this.minDate_).date);
- $('date').setAttribute('max', this.toHtmlValues_(this.maxDate_).date);
-
- this.updateTime_();
-
- // Show the timezone select if we have a timezone ID.
- var currentTimezoneId = loadTimeData.getValue('currentTimezoneId');
- if (currentTimezoneId) {
- this.setTimezone_(currentTimezoneId);
- $('timezone-select').addEventListener(
- 'change', this.onTimezoneChange_.bind(this), false);
- $('timezone').hidden = false;
- }
-
- this.sizeToFit_();
-
- $('time').addEventListener('blur', this.onTimeBlur_.bind(this), false);
- $('date').addEventListener('blur', this.onTimeBlur_.bind(this), false);
-
- $('set-time').addEventListener(
- 'submit', this.onSubmit_.bind(this), false);
- },
-
- /**
- * Sets the current timezone.
- * @param {string} timezoneId The timezone ID to select.
- * @private
- */
- setTimezone_: function(timezoneId) {
- $('timezone-select').value = timezoneId;
- this.updateTime_();
- },
-
- /**
- * Updates the date/time controls to the current local time.
- * Called initially, then called again once a minute.
- * @private
- */
- updateTime_: function() {
- var now = new Date();
-
- // Only update time controls if neither is focused.
- if (document.activeElement.id != 'date' &&
- document.activeElement.id != 'time') {
- var htmlValues = this.toHtmlValues_(now);
- this.prevValues_.date = $('date').value = htmlValues.date;
- this.prevValues_.time = $('time').value = htmlValues.time;
- }
-
- window.clearTimeout(this.timeTimeout_);
-
- // Start timer to update these inputs every minute.
- var secondsRemaining = 60 - now.getSeconds();
- this.timeTimeout_ = window.setTimeout(this.updateTime_.bind(this),
- secondsRemaining * 1000);
- },
-
- /**
- * Sets the system time from the UI.
- * @private
- */
- applyTime_: function() {
- var date = $('date').valueAsDate;
- date.setMilliseconds(date.getMilliseconds() + $('time').valueAsNumber);
-
- // Add timezone offset to get real time.
- date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
-
- var seconds = Math.floor(date / 1000);
- chrome.send('setTimeInSeconds', [seconds]);
- },
-
- /**
- * Called when focus is lost on date/time controls.
- * @param {Event} e The blur event.
- * @private
- */
- onTimeBlur_: function(e) {
- if (e.target.validity.valid && e.target.value) {
- // Make this the new fallback time in case of future invalid input.
- this.prevValues_[e.target.id] = e.target.value;
- this.applyTime_();
- } else {
- // Restore previous value.
- e.target.value = this.prevValues_[e.target.id];
- }
- },
-
- /**
- * @param {Event} e The change event.
- * @private
- */
- onTimezoneChange_: function(e) {
- chrome.send('setTimezone', [e.currentTarget.value]);
- },
-
- /**
- * Closes the dialog window.
- * @param {Event} e The submit event.
- * @private
- */
- onSubmit_: function(e) {
- e.preventDefault();
- chrome.send('dialogClose');
- },
-
- /**
- * Resizes the window if necessary to show the entire contents.
- * @private
- */
- sizeToFit_: function() {
- // Because of l10n, we should check that the vertical content can fit
- // within the window.
- if (window.innerHeight < document.body.scrollHeight) {
- // Resize window to fit scrollHeight and the title bar.
- var newHeight = document.body.scrollHeight +
- window.outerHeight - window.innerHeight;
- window.resizeTo(window.outerWidth, newHeight);
- }
- },
-
- /**
- * Builds date and time strings suitable for the values of HTML date and
- * time elements.
- * @param {Date} date The date object to represent.
- * @return {{date: string, time: string}} Date is an RFC 3339 formatted date
- * and time is an HH:MM formatted time.
- * @private
- */
- toHtmlValues_: function(date) {
- // Get the current time and subtract the timezone offset, so the
- // JSON string is in local time.
- var localDate = new Date(date);
- localDate.setMinutes(date.getMinutes() - date.getTimezoneOffset());
- return {date: localDate.toISOString().slice(0, 10),
- time: localDate.toISOString().slice(11, 16)};
- },
- };
-
- TimeSetter.setTimezone = function(timezoneId) {
- TimeSetter.getInstance().setTimezone_(timezoneId);
- };
-
- TimeSetter.updateTime = function() {
- TimeSetter.getInstance().updateTime_();
- };
-
- return {
- TimeSetter: TimeSetter
- };
-});
-
-document.addEventListener('DOMContentLoaded', function() {
- settime.TimeSetter.getInstance().initialize();
-});
diff --git a/chromium/chrome/browser/resources/chromeos/sim_unlock.css b/chromium/chrome/browser/resources/chromeos/sim_unlock.css
deleted file mode 100644
index 9e9d588f419..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sim_unlock.css
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.error {
- color: red;
-}
-
-#pin-error-msg {
- height: 25px;
- margin: 5px auto 5px auto;
-}
-
-.content-area {
- max-height: 125px;
- overflow: auto;
-}
-
-.change-pin-content-area {
- height: 156px;
- overflow: auto;
- padding: 10px 15px 5px 15px;
- width: 320px;
-}
-
-.choose-pin-content-area {
- max-height: 125px;
- min-height: 120px;
- overflow: auto;
- padding: 10px 15px 5px 15px;
- width: 320px;
-}
-
-.input-area {
- margin: 10px auto 25px auto;
- width: 125px;
-}
-
-#pin-input-area {
- margin-top: 30px;
-}
-
-#puk-input-area {
- margin-bottom: 0;
-}
-
-#puk-content-area {
- max-height: 163px;
-}
-
-.code-input {
- border: 1px solid #aaa;
- border-radius: 2px;
- font-size: inherit;
- padding: 3px;
-}
-
-#locked-puk-action-area {
- -webkit-box-pack: center;
-}
-
-#disabled-sim-action-area {
- -webkit-box-pack: center;
-}
-
-#puk-warning-msg {
- padding-bottom: 6px;
-}
-
-#puk-enter-msg {
- padding-top: 6px;
-}
-
-#choose-pin-msg {
- padding-bottom: 6px;
-}
-
-#choose-pin-error {
- padding-top: 6px;
-}
-
-.label {
- margin: 5px 5px 5px 0;
- padding: 5px 5px 5px 0;
- width: 150px;
-}
-
-.input-with-label {
- display: -webkit-box;
-}
-
-.choose-pin-input-area {
- margin: 5px 5px 5px 5px;
- width: 125px;
-}
-
-#choose-pin-action-area {
- padding: 6px;
-}
diff --git a/chromium/chrome/browser/resources/chromeos/sim_unlock.html b/chromium/chrome/browser/resources/chromeos/sim_unlock.html
deleted file mode 100644
index c6c2d368814..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sim_unlock.html
+++ /dev/null
@@ -1,143 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<meta charset="utf-8">
-<title i18n-content="title"></title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<link rel="stylesheet" href="chrome://resources/css/widgets.css">
-<link rel="stylesheet" href="mobile_dialogs.css">
-<link rel="stylesheet" href="sim_unlock.css">
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="sim_unlock.js"></script>
-<script>
-var SimUnlock = mobile.SimUnlock;
-
-function load() {
- SimUnlock.initialize();
-}
-
-document.addEventListener('DOMContentLoaded', load);
-</script>
-</head>
-<body>
- <div id="container" class="container">
- <div id="locked-pin-overlay" class="dialog" hidden>
- <h1 i18n-content="enterPinTitle"></h1>
- <div id="pin-content-area" class="content-area">
- <div id="pin-error-msg"></div>
- <div id="pin-input-area" class="input-area">
- <input id="pin-input" class="code-input" type="password"
- maxlength="8" size="14">
- </div>
- </div>
- <div class="action-area">
- <div class="action-area-right">
- <div class="button-strip">
- <button id="enter-pin-confirm" i18n-content="ok"></button>
- <button id="enter-pin-dismiss" i18n-content="cancel"></button>
- </div>
- </div>
- </div>
- </div>
- <div id="locked-pin-no-tries-overlay" class="dialog" hidden>
- <h1 i18n-content="incorrectPinTitle"></h1>
- <div id="pin-no-tries-content-area" class="content-area">
- <!-- TODO(nkostylev): Add warning icon. -->
- <div id="pin-no-tries-error-msg" i18n-content="noPinTriesLeft"></div>
- </div>
- <div class="action-area">
- <div class="action-area-right">
- <div class="button-strip">
- <button id="pin-no-tries-proceed" i18n-content="enterPukButton">
- </button>
- <button id="pin-no-tries-dismiss" i18n-content="cancel"></button>
- </div>
- </div>
- </div>
- </div>
- <div id="locked-puk-overlay" class="dialog" hidden>
- <h1 i18n-content="enterPukTitle"></h1>
- <div id="puk-content-area" class="content-area">
- <div id="puk-warning-msg" i18n-content="enterPukWarning" class="error">
- </div>
- <div id="puk-enter-msg" i18n-content="enterPukMessage"></div>
- <div id="puk-input-area" class="input-area">
- <input id="puk-input" class="code-input" type="password"
- maxlength="8" size="14">
- </div>
- </div>
- <div class="action-area">
- <div class="action-area-right">
- <div class="button-strip">
- <button id="enter-puk-confirm" i18n-content="ok"></button>
- <button id="enter-puk-dismiss" i18n-content="cancel"></button>
- </div>
- </div>
- </div>
- </div>
- <div id="choose-pin-overlay" class="dialog" hidden>
- <h1 id="choose-pin-title" i18n-content="choosePinTitle"></h1>
- <div id="choose-pin-content-area" class="choose-pin-content-area">
- <div id="choose-pin-msg" i18n-content="choosePinMessage"></div>
- <div class="input-with-label">
- <div id="old-pin-label" i18n-content="oldPin" class="label" hidden>
- </div>
- <div id="old-pin-input-area" class="choose-pin-input-area" hidden>
- <input id="old-pin-input" class="code-input" type="password"
- maxlength="8" size="14">
- </div>
- </div>
- <div class="input-with-label">
- <div id="new-pin-label" i18n-content="newPin" class="label"></div>
- <div id="new-pin-input-area" class="choose-pin-input-area">
- <input id="new-pin-input" class="code-input" type="password"
- maxlength="8" size="14">
- </div>
- </div>
- <div class="input-with-label">
- <div id="retype-new-pin-label" i18n-content="retypeNewPin"
- class="label"></div>
- <div id="retype-new-pin-input-area" class="choose-pin-input-area">
- <input id="retype-new-pin-input" class="code-input" type="password"
- maxlength="8" size="14">
- </div>
- </div>
- <div id="choose-pin-error" class="error"
- i18n-content="pinsDontMatchMessage" hidden></div>
- </div>
- <div id="choose-pin-action-area" class="action-area">
- <div class="action-area-right">
- <div class="button-strip">
- <button id="choose-pin-confirm" i18n-content="ok"></button>
- <button id="choose-pin-dismiss" i18n-content="cancel"></button>
- </div>
- </div>
- </div>
- </div>
- <div id="locked-puk-no-tries-overlay" class="dialog" hidden>
- <h1 i18n-content="enterPukTitle"></h1>
- <div id="puk-no-tries-content-area" class="content-area">
- <div id="puk-no-tries-msg" i18n-content="noPukTriesLeft"></div>
- </div>
- <div id="locked-puk-action-area" class="action-area">
- <div class="button-strip">
- <button id="puk-no-tries-confirm" i18n-content="ok"></button>
- </div>
- </div>
- </div>
- <div id="sim-disabled-overlay" class="dialog" hidden>
- <h1 i18n-content="simDisabledTitle"></h1>
- <div id="sim-disabled-content-area" class="content-area">
- <div id="sim-disabled-msg" i18n-content="simDisabledMessage"></div>
- </div>
- <div id="disabled-sim-action-area" class="action-area">
- <div class="button-strip">
- <button id="sim-disabled-confirm" i18n-content="ok"></button>
- </div>
- </div>
- </div>
- </div>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/sim_unlock.js b/chromium/chrome/browser/resources/chromeos/sim_unlock.js
deleted file mode 100644
index 64aedb0d547..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sim_unlock.js
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('mobile', function() {
-
- function SimUnlock() {
- }
-
- cr.addSingletonGetter(SimUnlock);
-
- // State of the dialog.
- SimUnlock.SIM_UNLOCK_LOADING = -1;
- SimUnlock.SIM_ABSENT_NOT_LOCKED = 0,
- SimUnlock.SIM_NOT_LOCKED_ASK_PIN = 1;
- SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN = 2;
- SimUnlock.SIM_LOCKED_PIN = 3;
- SimUnlock.SIM_LOCKED_NO_PIN_TRIES_LEFT = 4;
- SimUnlock.SIM_LOCKED_PUK = 5;
- SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT = 6;
- SimUnlock.SIM_DISABLED = 7;
-
- // Mode of the dialog.
- SimUnlock.SIM_DIALOG_UNLOCK = 0;
- SimUnlock.SIM_DIALOG_CHANGE_PIN = 1;
- SimUnlock.SIM_DIALOG_SET_LOCK_ON = 2;
- SimUnlock.SIM_DIALOG_SET_LOCK_OFF = 3;
-
- // Error codes.
- SimUnlock.ERROR_PIN = 'incorrectPin';
- SimUnlock.ERROR_PUK = 'incorrectPuk';
- SimUnlock.ERROR_OK = 'ok';
-
- // Misc constants.
- SimUnlock.PIN_MIN_LENGTH = 4;
- SimUnlock.PUK_LENGTH = 8;
-
- SimUnlock.prototype = {
- initialized_: false,
- mode_: SimUnlock.SIM_DIALOG_UNLOCK,
- pukValue_: '',
- defaultDialogSize_: {
- 'width': window.innerWidth,
- 'height': window.innerHeight
- },
- state_: SimUnlock.SIM_UNLOCK_LOADING,
-
- changeState_: function(simInfo) {
- var newState = simInfo.state;
- var error = simInfo.error;
- var tries = simInfo.tries;
- var pinMessage;
- this.hideAll_();
- switch (newState) {
- case SimUnlock.SIM_UNLOCK_LOADING:
- break;
- case SimUnlock.SIM_ABSENT_NOT_LOCKED:
- SimUnlock.close();
- break;
- case SimUnlock.SIM_LOCKED_PIN:
- if (error == SimUnlock.ERROR_OK) {
- pinMessage = loadTimeData.getStringF('enterPinTriesMessage', tries);
- $('pin-error-msg').classList.remove('error');
- } else if (error == SimUnlock.ERROR_PIN) {
- pinMessage = loadTimeData.getStringF(
- 'incorrectPinTriesMessage', tries);
- $('pin-error-msg').classList.add('error');
- }
- $('pin-error-msg').textContent = pinMessage;
- $('pin-input').value = '';
- SimUnlock.enablePinDialog(true);
- $('locked-pin-overlay').hidden = false;
- $('pin-input').focus();
- break;
- case SimUnlock.SIM_NOT_LOCKED_ASK_PIN:
- if (error == SimUnlock.ERROR_OK) {
- pinMessage = loadTimeData.getString('enterPinMessage');
- $('pin-error-msg').classList.remove('error');
- } else if (error == SimUnlock.ERROR_PIN) {
- pinMessage = loadTimeData.getStringF(
- 'incorrectPinTriesMessage', tries);
- $('pin-error-msg').classList.add('error');
- }
- $('pin-error-msg').textContent = pinMessage;
- $('pin-input').value = '';
- SimUnlock.enablePinDialog(true);
- $('locked-pin-overlay').hidden = false;
- $('pin-input').focus();
- break;
- case SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN:
- SimUnlock.prepareChoosePinDialog(true);
- if (error == SimUnlock.ERROR_OK) {
- pinMessage = loadTimeData.getString('changePinMessage');
- $('choose-pin-msg').classList.remove('error');
- } else if (error == SimUnlock.ERROR_PIN) {
- pinMessage = loadTimeData.getStringF(
- 'incorrectPinTriesMessage', tries);
- $('choose-pin-msg').classList.add('error');
- }
- $('choose-pin-msg').textContent = pinMessage;
- $('old-pin-input').value = '';
- $('new-pin-input').value = '';
- $('retype-new-pin-input').value = '';
- $('choose-pin-overlay').hidden = false;
- SimUnlock.enableChoosePinDialog(true);
- $('old-pin-input').focus();
- break;
- case SimUnlock.SIM_LOCKED_NO_PIN_TRIES_LEFT:
- $('locked-pin-no-tries-overlay').hidden = false;
- break;
- case SimUnlock.SIM_LOCKED_PUK:
- $('puk-input').value = '';
- if (tries && tries >= 0) {
- var pukMessage = loadTimeData.getStringF('enterPukWarning', tries);
- $('puk-warning-msg').textContent = pukMessage;
- }
- $('enter-puk-confirm').disabled = true;
- $('locked-puk-overlay').hidden = false;
- $('puk-input').focus();
-
- // Resize the dialog to accomodate the PUK contents.
- this.updateDialogSize_(0, 45);
- break;
- case SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT:
- $('locked-puk-no-tries-overlay').hidden = false;
- break;
- case SimUnlock.SIM_DISABLED:
- $('sim-disabled-overlay').hidden = false;
- break;
- }
- this.state_ = newState;
- },
-
- /**
- * Returns current state of the dialog.
- * @type {number} value of the state.
- */
- get state() {
- return this.state_;
- },
-
- updateDialogSize_: function(deltaX, deltaY) {
- window.resizeTo(this.defaultDialogSize_.width + deltaX,
- this.defaultDialogSize_.height + deltaY);
- },
-
- hideAll_: function() {
- $('locked-pin-overlay').hidden = true;
- $('locked-pin-no-tries-overlay').hidden = true;
- $('locked-puk-overlay').hidden = true;
- $('choose-pin-overlay').hidden = true;
- $('locked-puk-no-tries-overlay').hidden = true;
- $('sim-disabled-overlay').hidden = true;
- },
-
- newPinEntered_: function(newPin, newPin2) {
- var changePinMode = this.state_ == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
- if (newPin.length < SimUnlock.PIN_MIN_LENGTH ||
- newPin2.length < SimUnlock.PIN_MIN_LENGTH ||
- (changePinMode &&
- $('old-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH)) {
- return;
- }
- if (newPin != newPin2) {
- $('choose-pin-error').hidden = false;
- $('old-pin-input').value = '';
- $('new-pin-input').value = '';
- $('retype-new-pin-input').value = '';
- if (changePinMode)
- $('old-pin-input').focus();
- else
- $('new-pin-input').focus();
- } else {
- $('choose-pin-error').hidden = true;
- SimUnlock.enableChoosePinDialog(false);
- if (changePinMode) {
- var oldPin = $('old-pin-input').value;
- chrome.send('changePinCode', [oldPin, newPin]);
- } else {
- chrome.send('enterPukCode', [this.pukValue_, newPin]);
- this.pukValue_ = '';
- }
- }
- },
-
- pukEntered_: function(pukValue) {
- if (pukValue.length < SimUnlock.PUK_LENGTH)
- return;
- this.pukValue_ = pukValue;
- this.hideAll_();
- SimUnlock.prepareChoosePinDialog(false);
- SimUnlock.enableChoosePinDialog(true);
- $('new-pin-input').value = '';
- $('retype-new-pin-input').value = '';
- $('choose-pin-overlay').hidden = false;
- $('new-pin-input').focus();
- this.updateDialogSize_(0, 18);
- },
-
- updateSimStatus_: function(simInfo) {
- this.changeState_(simInfo);
- },
- };
-
- SimUnlock.cancel = function() {
- SimUnlock.close();
- };
-
- SimUnlock.close = function() {
- window.close();
- };
-
- SimUnlock.initialize = function() {
- this.initialized_ = true;
-
- var modePattern = /(^\?|&)mode=([^&#]*)/;
- var results = modePattern.exec(window.location.search);
- if (results == null) {
- this.mode_ = SimUnlock.SIM_DIALOG_UNLOCK;
- } else {
- var mode = results[2];
- if (mode == 'change-pin')
- this.mode_ = SimUnlock.SIM_DIALOG_CHANGE_PIN;
- else if (mode == 'set-lock-on')
- this.mode_ = SimUnlock.SIM_DIALOG_SET_LOCK_ON;
- else if (mode == 'set-lock-off')
- this.mode_ = SimUnlock.SIM_DIALOG_SET_LOCK_OFF;
- }
-
- // PIN input screen.
- $('pin-input').addEventListener('keydown', function(event) {
- if (event.keyIdentifier == 'Enter') {
- SimUnlock.submitPin();
- return;
- }
- });
- $('pin-input').addEventListener('keyup', function(event) {
- $('enter-pin-confirm').disabled =
- $('enter-pin-dismiss').disabled ||
- this.value.length < SimUnlock.PIN_MIN_LENGTH;
- });
- $('pin-input').addEventListener('textInput',
- SimUnlock.processInput.bind(this));
- $('enter-pin-confirm').addEventListener('click', function(event) {
- SimUnlock.submitPin();
- });
- $('enter-pin-dismiss').addEventListener('click', function(event) {
- SimUnlock.cancel();
- });
-
- // No PIN retries left screen.
- $('pin-no-tries-proceed').addEventListener('click', function(event) {
- chrome.send('proceedToPukInput');
- });
- $('pin-no-tries-dismiss').addEventListener('click', function(event) {
- SimUnlock.cancel();
- });
-
- // PUK input screen.
- $('puk-input').addEventListener('keydown', function(event) {
- if (event.keyIdentifier == 'Enter') {
- SimUnlock.pukEntered($('puk-input').value);
- return;
- }
- });
- $('puk-input').addEventListener('keyup', function(event) {
- $('enter-puk-confirm').disabled =
- $('enter-puk-dismiss').disabled ||
- this.value.length < SimUnlock.PUK_LENGTH;
- });
- $('puk-input').addEventListener('textInput',
- SimUnlock.processInput.bind(this));
- $('enter-puk-confirm').addEventListener('click', function(event) {
- SimUnlock.pukEntered($('puk-input').value);
- });
- $('enter-puk-dismiss').addEventListener('click', function(event) {
- SimUnlock.cancel();
- });
-
- // Change PIN / new PIN screen.
- $('old-pin-input').addEventListener('keydown', function(event) {
- if (event.keyIdentifier == 'Enter') {
- if (this.value.length >= SimUnlock.PIN_MIN_LENGTH)
- $('new-pin-input').focus();
- return;
- }
- });
- $('old-pin-input').addEventListener('keyup', function(event) {
- $('choose-pin-confirm').disabled =
- $('choose-pin-dismiss').disabled ||
- this.value.length < SimUnlock.PIN_MIN_LENGTH ||
- $('new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
- $('retype-new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH;
- });
- $('old-pin-input').addEventListener('textInput',
- SimUnlock.processInput.bind(this));
- $('new-pin-input').addEventListener('keydown', function(event) {
- if (event.keyIdentifier == 'Enter') {
- if (this.value.length >= SimUnlock.PIN_MIN_LENGTH)
- $('retype-new-pin-input').focus();
- return;
- }
- });
- $('new-pin-input').addEventListener('keyup', function(event) {
- var changePinMode =
- SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
- var oldPinLengthOk =
- $('old-pin-input').value.length >= SimUnlock.PIN_MIN_LENGTH;
- var oldPinOk = !changePinMode || oldPinLengthOk;
- $('choose-pin-confirm').disabled =
- $('choose-pin-dismiss').disabled ||
- this.value.length < SimUnlock.PIN_MIN_LENGTH ||
- $('retype-new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
- !oldPinOk;
- });
- $('new-pin-input').addEventListener('textInput',
- SimUnlock.processInput.bind(this));
- $('retype-new-pin-input').addEventListener('keyup', function(event) {
- var changePinMode =
- SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
- var oldPinLengthOk =
- $('old-pin-input').value.length >= SimUnlock.PIN_MIN_LENGTH;
- var oldPinOk = !changePinMode || oldPinLengthOk;
- $('choose-pin-confirm').disabled =
- $('choose-pin-dismiss').disabled ||
- this.value.length < SimUnlock.PIN_MIN_LENGTH ||
- $('new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
- !oldPinOk;
- });
- $('retype-new-pin-input').addEventListener('keydown', function(event) {
- if (event.keyIdentifier == 'Enter') {
- SimUnlock.newPinEntered($('new-pin-input').value,
- $('retype-new-pin-input').value);
- return;
- }
- });
- $('retype-new-pin-input').addEventListener('textInput',
- SimUnlock.processInput.bind(this));
- $('choose-pin-confirm').addEventListener('click', function(event) {
- SimUnlock.newPinEntered($('new-pin-input').value,
- $('retype-new-pin-input').value);
- });
- $('choose-pin-dismiss').addEventListener('click', function(event) {
- SimUnlock.cancel();
- });
-
- // SIM blocked screens.
- $('puk-no-tries-confirm').addEventListener('click', function(event) {
- SimUnlock.close();
- });
- $('sim-disabled-confirm').addEventListener('click', function(event) {
- SimUnlock.close();
- });
- chrome.send('simStatusInitialize', [this.mode_]);
- };
-
- SimUnlock.enablePinDialog = function(enabled) {
- $('pin-input').disabled = !enabled;
- // Ok button is initially disabled.
- $('enter-pin-confirm').disabled = true;
- $('enter-pin-dismiss').disabled = !enabled;
- };
-
- SimUnlock.enableChoosePinDialog = function(enabled) {
- $('old-pin-input').disabled = !enabled;
- $('new-pin-input').disabled = !enabled;
- $('retype-new-pin-input').disabled = !enabled;
- // Ok button is initially disabled.
- $('choose-pin-confirm').disabled = true;
- $('choose-pin-dismiss').disabled = !enabled;
- };
-
- SimUnlock.submitPin = function() {
- var pin = $('pin-input').value;
- if (pin.length < SimUnlock.PIN_MIN_LENGTH)
- return;
- SimUnlock.enablePinDialog(false);
- chrome.send('enterPinCode', [pin]);
- };
-
- SimUnlock.prepareChoosePinDialog = function(changePin) {
- // Our dialog has different height than choose-pin step of the
- // unlock process which we're reusing.
- if (changePin) {
- $('choose-pin-content-area').classList.remove('choose-pin-content-area');
- $('choose-pin-content-area').classList.add('change-pin-content-area');
- var title = loadTimeData.getString('changePinTitle');
- $('choose-pin-title').textContent = title;
- } else {
- $('choose-pin-content-area').classList.remove('change-pin-content-area');
- $('choose-pin-content-area').classList.add('choose-pin-content-area');
- var pinMessage = loadTimeData.getString('choosePinMessage');
- $('choose-pin-msg').classList.remove('error');
- $('choose-pin-msg').textContent = pinMessage;
- var title = loadTimeData.getString('choosePinTitle');
- $('choose-pin-title').textContent = title;
- }
- $('old-pin-label').hidden = !changePin;
- $('old-pin-input-area').hidden = !changePin;
- };
-
- SimUnlock.newPinEntered = function(newPin, newPin2) {
- SimUnlock.getInstance().newPinEntered_(newPin, newPin2);
- };
-
- SimUnlock.pukEntered = function(pukValue) {
- SimUnlock.getInstance().pukEntered_(pukValue);
- };
-
- /**
- * Processes PIN/PUK fields input, restricting it to 0..9.
- */
- SimUnlock.processInput = function(event) {
- if (/[^0-9]+/gi.test(event.data))
- event.preventDefault();
- };
-
- SimUnlock.simStateChanged = function(simInfo) {
- SimUnlock.getInstance().updateSimStatus_(simInfo);
- };
-
- // Export
- return {
- SimUnlock: SimUnlock
- };
-
-});
-
-disableTextSelectAndDrag();
diff --git a/chromium/chrome/browser/resources/chromeos/slow.css b/chromium/chrome/browser/resources/chromeos/slow.css
deleted file mode 100644
index ceca2c3a468..00000000000
--- a/chromium/chrome/browser/resources/chromeos/slow.css
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-body {
- background-color: #E6E6E6;
- font-size: 12pt;
- margin: 50px 40px 20px 40px;
- text-align: center;
-}
-
-#container {
- background-color: #fbfbfb;
- border: 1px solid #AAA;
- border-bottom: 1px solid #888;
- border-radius: 3px;
- box-shadow: 0 2px 2px #AAA;
- color: #666;
- margin: auto;
- max-width: 540px;
- min-height: 29px;
- min-width: 200px;
- padding: 20px 60px;
- text-align: start;
-}
-
-#container-inner {
- background-color: #fbfbfb;
- margin-top: 25px;
- text-align: center;
-}
-
-button {
- -webkit-user-select: none;
- background-image: -webkit-linear-gradient(#ededed, #ededed 38%, #dedede);
- border: 1px solid rgba(0, 0, 0, 0.25);
- border-radius: 2px;
- box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08),
- inset 0 1px 2px rgba(255, 255, 255, 0.75);
- margin-top: 10px;
- min-height: 29px;
- min-width: 65px;
- padding: 8px 13px;
- text-shadow: 0 1px 0 rgb(240, 240, 240);
-}
-
diff --git a/chromium/chrome/browser/resources/chromeos/slow.html b/chromium/chrome/browser/resources/chromeos/slow.html
deleted file mode 100644
index 8ed682e44d0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/slow.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<meta charset="utf-8">
-<meta name="viewport" content="width=device-width, initial-scale=1.0,
- maximum-scale=1.0, user-scalable=no">
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-<link rel="stylesheet" href="chrome://resources/css/widgets.css">
-<link rel="stylesheet" href="slow.css">
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="chrome://slow/slow.js"></script>
-<script src="chrome://slow/strings.js"></script>
-</head>
-<body>
- <div id="container" class="container">
- <div i18n-content="slowDescription"></div>
- <br>
- <div i18n-values=".innerHTML:slowWarning"></div>
- <div id="container-inner" width=100% class="container-inner">
- <button id="slow-disable" i18n-content="slowDisable" hidden></button>
- <button id="slow-enable" i18n-content="slowEnable" hidden></button>
- </div>
- </div>
-<script src="chrome://resources/js/i18n_template.js"></script>
-<script src="chrome://resources/js/jstemplate_compiled.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/chromeos/slow.js b/chromium/chrome/browser/resources/chromeos/slow.js
deleted file mode 100644
index 14a5e82cec5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/slow.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- function Slow() {
- }
- cr.addSingletonGetter(Slow);
-
- Slow.prototype = {
- initialized_: false
- };
-
- Slow.initialize = function() {
- $('slow-disable').addEventListener('click', function(event) {
- Slow.disableTracing();
- });
- $('slow-enable').addEventListener('click', function(event) {
- Slow.enableTracing();
- });
- this.initialized_ = true;
- };
-
- Slow.disableTracing = function() {
- chrome.send('disableTracing');
- };
-
- Slow.enableTracing = function() {
- chrome.send('enableTracing');
- };
-
- Slow.tracingPrefChanged = function(enabled) {
- $('slow-disable').hidden = !enabled;
- $('slow-enable').hidden = enabled;
- };
-
- // Export
- return {
- Slow: Slow
- };
-});
-
-function load() {
- options.Slow.initialize();
- chrome.send('loadComplete');
-}
-
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/camera_snap.wav b/chromium/chrome/browser/resources/chromeos/sounds/camera_snap.wav
deleted file mode 100644
index 35ae4c3e490..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/camera_snap.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/earcons/enter_screen.wav b/chromium/chrome/browser/resources/chromeos/sounds/earcons/enter_screen.wav
deleted file mode 100644
index 670b88a447b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/earcons/enter_screen.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/earcons/exit_screen.wav b/chromium/chrome/browser/resources/chromeos/sounds/earcons/exit_screen.wav
deleted file mode 100644
index bea36c1d657..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/earcons/exit_screen.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/earcons/passthrough.wav b/chromium/chrome/browser/resources/chromeos/sounds/earcons/passthrough.wav
deleted file mode 100644
index d499759fbdc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/earcons/passthrough.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/lock.wav b/chromium/chrome/browser/resources/chromeos/sounds/lock.wav
deleted file mode 100644
index e9ee817dc69..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/lock.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/object_delete.wav b/chromium/chrome/browser/resources/chromeos/sounds/object_delete.wav
deleted file mode 100644
index 21b5490e051..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/object_delete.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/shutdown.wav b/chromium/chrome/browser/resources/chromeos/sounds/shutdown.wav
deleted file mode 100644
index 08c3c5196b2..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/shutdown.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/spoken_feedback_disabled.wav b/chromium/chrome/browser/resources/chromeos/sounds/spoken_feedback_disabled.wav
deleted file mode 100644
index 0255fe3a304..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/spoken_feedback_disabled.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/spoken_feedback_enabled.wav b/chromium/chrome/browser/resources/chromeos/sounds/spoken_feedback_enabled.wav
deleted file mode 100644
index 45627fe5cdf..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/spoken_feedback_enabled.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/startup.wav b/chromium/chrome/browser/resources/chromeos/sounds/startup.wav
deleted file mode 100644
index 135be0ce757..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/startup.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/startup2.wav b/chromium/chrome/browser/resources/chromeos/sounds/startup2.wav
deleted file mode 100644
index c42fc124c61..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/startup2.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/unlock.wav b/chromium/chrome/browser/resources/chromeos/sounds/unlock.wav
deleted file mode 100644
index cd1b8413729..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/unlock.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/sounds/volume_adjust.wav b/chromium/chrome/browser/resources/chromeos/sounds/volume_adjust.wav
deleted file mode 100644
index 3176f4cb20a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/sounds/volume_adjust.wav
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/user_images_grid.js b/chromium/chrome/browser/resources/chromeos/user_images_grid.js
deleted file mode 100644
index 9f17b992deb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/user_images_grid.js
+++ /dev/null
@@ -1,680 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
- /** @const */ var Grid = cr.ui.Grid;
- /** @const */ var GridItem = cr.ui.GridItem;
- /** @const */ var GridSelectionController = cr.ui.GridSelectionController;
- /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
-
- /**
- * Dimensions for camera capture.
- * @const
- */
- var CAPTURE_SIZE = {
- height: 480,
- width: 480
- };
-
- /**
- * Path for internal URLs.
- * @const
- */
- var CHROME_THEME_PATH = 'chrome://theme';
-
- /**
- * Creates a new user images grid item.
- * @param {{url: string, title: (string|undefined),
- * decorateFn: (!Function|undefined),
- * clickHandler: (!Function|undefined)}} imageInfo User image URL,
- * optional title, decorator callback and click handler.
- * @constructor
- * @extends {cr.ui.GridItem}
- */
- function UserImagesGridItem(imageInfo) {
- var el = new GridItem(imageInfo);
- el.__proto__ = UserImagesGridItem.prototype;
- return el;
- }
-
- UserImagesGridItem.prototype = {
- __proto__: GridItem.prototype,
-
- /** @override */
- decorate: function() {
- GridItem.prototype.decorate.call(this);
- var imageEl = cr.doc.createElement('img');
- // Force 1x scale for chrome://theme URLs. Grid elements are much smaller
- // than actual images so there is no need in full scale on HDPI.
- var url = this.dataItem.url;
- if (url.slice(0, CHROME_THEME_PATH.length) == CHROME_THEME_PATH)
- imageEl.src = this.dataItem.url + '@1x';
- else
- imageEl.src = this.dataItem.url;
- imageEl.title = this.dataItem.title || '';
- imageEl.alt = imageEl.title;
- if (typeof this.dataItem.clickHandler == 'function')
- imageEl.addEventListener('mousedown', this.dataItem.clickHandler);
- // Remove any garbage added by GridItem and ListItem decorators.
- this.textContent = '';
- this.appendChild(imageEl);
- if (typeof this.dataItem.decorateFn == 'function')
- this.dataItem.decorateFn(this);
- this.setAttribute('role', 'option');
- this.oncontextmenu = function(e) { e.preventDefault(); };
- }
- };
-
- /**
- * Creates a selection controller that wraps selection on grid ends
- * and translates Enter presses into 'activate' events.
- * @param {cr.ui.ListSelectionModel} selectionModel The selection model to
- * interact with.
- * @param {cr.ui.Grid} grid The grid to interact with.
- * @constructor
- * @extends {cr.ui.GridSelectionController}
- */
- function UserImagesGridSelectionController(selectionModel, grid) {
- GridSelectionController.call(this, selectionModel, grid);
- }
-
- UserImagesGridSelectionController.prototype = {
- __proto__: GridSelectionController.prototype,
-
- /** @override */
- getIndexBefore: function(index) {
- var result =
- GridSelectionController.prototype.getIndexBefore.call(this, index);
- return result == -1 ? this.getLastIndex() : result;
- },
-
- /** @override */
- getIndexAfter: function(index) {
- var result =
- GridSelectionController.prototype.getIndexAfter.call(this, index);
- return result == -1 ? this.getFirstIndex() : result;
- },
-
- /** @override */
- handleKeyDown: function(e) {
- if (e.keyIdentifier == 'Enter')
- cr.dispatchSimpleEvent(this.grid_, 'activate');
- else
- GridSelectionController.prototype.handleKeyDown.call(this, e);
- }
- };
-
- /**
- * Creates a new user images grid element.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {cr.ui.Grid}
- */
- var UserImagesGrid = cr.ui.define('grid');
-
- UserImagesGrid.prototype = {
- __proto__: Grid.prototype,
-
- /** @override */
- createSelectionController: function(sm) {
- return new UserImagesGridSelectionController(sm, this);
- },
-
- /** @override */
- decorate: function() {
- Grid.prototype.decorate.call(this);
- this.dataModel = new ArrayDataModel([]);
- this.itemConstructor = /** @type {function(new:cr.ui.ListItem, *)} */(
- UserImagesGridItem);
- this.selectionModel = new ListSingleSelectionModel();
- this.inProgramSelection_ = false;
- this.addEventListener('dblclick', this.handleDblClick_.bind(this));
- this.addEventListener('change', this.handleChange_.bind(this));
- this.setAttribute('role', 'listbox');
- this.autoExpands = true;
- },
-
- /**
- * Handles double click on the image grid.
- * @param {Event} e Double click Event.
- * @private
- */
- handleDblClick_: function(e) {
- // If a child element is double-clicked and not the grid itself, handle
- // this as 'Enter' keypress.
- if (e.target != this)
- cr.dispatchSimpleEvent(this, 'activate');
- },
-
- /**
- * Handles selection change.
- * @param {Event} e Double click Event.
- * @private
- */
- handleChange_: function(e) {
- if (this.selectedItem === null)
- return;
-
- var oldSelectionType = this.selectionType;
-
- // Update current selection type.
- this.selectionType = this.selectedItem.type;
-
- // Show grey silhouette with the same border as stock images.
- if (/^chrome:\/\/theme\//.test(this.selectedItemUrl))
- this.previewElement.classList.add('default-image');
-
- this.updatePreview_();
-
- var e = new Event('select');
- e.oldSelectionType = oldSelectionType;
- this.dispatchEvent(e);
- },
-
- /**
- * Updates the preview image, if present.
- * @private
- */
- updatePreview_: function() {
- var url = this.selectedItemUrl;
- if (url && this.previewImage_) {
- if (url.slice(0, CHROME_THEME_PATH.length) == CHROME_THEME_PATH)
- this.previewImage_.src = url + '@' + window.devicePixelRatio + 'x';
- else
- this.previewImage_.src = url;
- }
- },
-
- /**
- * Whether a camera is present or not.
- * @type {boolean}
- */
- get cameraPresent() {
- return this.cameraPresent_;
- },
- set cameraPresent(value) {
- this.cameraPresent_ = value;
- if (this.cameraLive)
- this.cameraImage = null;
- },
-
- /**
- * Whether camera is actually streaming video. May be |false| even when
- * camera is present and shown but still initializing.
- * @type {boolean}
- */
- get cameraOnline() {
- return this.previewElement.classList.contains('online');
- },
- set cameraOnline(value) {
- this.previewElement.classList.toggle('online', value);
- },
-
- /**
- * Tries to starts camera stream capture.
- * @param {function(): boolean} onAvailable Callback that is called if
- * camera is available. If it returns |true|, capture is started
- * immediately.
- */
- startCamera: function(onAvailable, onAbsent) {
- this.stopCamera();
- this.cameraStartInProgress_ = true;
- navigator.webkitGetUserMedia(
- {video: true},
- this.handleCameraAvailable_.bind(this, onAvailable),
- this.handleCameraAbsent_.bind(this));
- },
-
- /**
- * Stops camera capture, if it's currently active.
- */
- stopCamera: function() {
- this.cameraOnline = false;
- if (this.cameraVideo_)
- this.cameraVideo_.src = '';
- if (this.cameraStream_)
- this.stopVideoTracks_(this.cameraStream_);
- // Cancel any pending getUserMedia() checks.
- this.cameraStartInProgress_ = false;
- },
-
- /**
- * Stops all video tracks associated with a MediaStream object.
- * @param {MediaStream} stream
- */
- stopVideoTracks_: function(stream) {
- var tracks = stream.getVideoTracks();
- for (var t of tracks)
- t.stop();
- },
-
- /**
- * Handles successful camera check.
- * @param {function(): boolean} onAvailable Callback to call. If it returns
- * |true|, capture is started immediately.
- * @param {!MediaStream} stream Stream object as returned by getUserMedia.
- * @private
- * @suppress {deprecated}
- */
- handleCameraAvailable_: function(onAvailable, stream) {
- if (this.cameraStartInProgress_ && onAvailable()) {
- this.cameraVideo_.src = URL.createObjectURL(stream);
- this.cameraStream_ = stream;
- } else {
- this.stopVideoTracks_(stream);
- }
- this.cameraStartInProgress_ = false;
- },
-
- /**
- * Handles camera check failure.
- * @param {NavigatorUserMediaError=} err Error object.
- * @private
- */
- handleCameraAbsent_: function(err) {
- this.cameraPresent = false;
- this.cameraOnline = false;
- this.cameraStartInProgress_ = false;
- },
-
- /**
- * Handles successful camera capture start.
- * @private
- */
- handleVideoStarted_: function() {
- this.cameraOnline = true;
- this.handleVideoUpdate_();
- },
-
- /**
- * Handles camera stream update. Called regularly (at rate no greater then
- * 4/sec) while camera stream is live.
- * @private
- */
- handleVideoUpdate_: function() {
- this.lastFrameTime_ = new Date().getTime();
- },
-
- /**
- * Type of the selected image (one of 'default', 'profile', 'camera').
- * Setting it will update class list of |previewElement|.
- * @type {string}
- */
- get selectionType() {
- return this.selectionType_;
- },
- set selectionType(value) {
- this.selectionType_ = value;
- var previewClassList = this.previewElement.classList;
- previewClassList[value == 'default' ? 'add' : 'remove']('default-image');
- previewClassList[value == 'profile' ? 'add' : 'remove']('profile-image');
- previewClassList[value == 'camera' ? 'add' : 'remove']('camera');
-
- var setFocusIfLost = function() {
- // Set focus to the grid, if focus is not on UI.
- if (!document.activeElement ||
- document.activeElement.tagName == 'BODY') {
- $('user-image-grid').focus();
- }
- };
- // Timeout guarantees processing AFTER style changes display attribute.
- setTimeout(setFocusIfLost, 0);
- },
-
- /**
- * Current image captured from camera as data URL. Setting to null will
- * return to the live camera stream.
- * @type {(string|undefined)}
- */
- get cameraImage() {
- return this.cameraImage_;
- },
- set cameraImage(imageUrl) {
- this.cameraLive = !imageUrl;
- if (this.cameraPresent && !imageUrl)
- imageUrl = UserImagesGrid.ButtonImages.TAKE_PHOTO;
- if (imageUrl) {
- this.cameraImage_ = this.cameraImage_ ?
- this.updateItem(this.cameraImage_, imageUrl, this.cameraTitle_) :
- this.addItem(imageUrl, this.cameraTitle_, undefined, 0);
- this.cameraImage_.type = 'camera';
- } else {
- this.removeItem(this.cameraImage_);
- this.cameraImage_ = null;
- }
- },
-
- /**
- * Updates the titles for the camera element.
- * @param {string} placeholderTitle Title when showing a placeholder.
- * @param {string} capturedImageTitle Title when showing a captured photo.
- */
- setCameraTitles: function(placeholderTitle, capturedImageTitle) {
- this.placeholderTitle_ = placeholderTitle;
- this.capturedImageTitle_ = capturedImageTitle;
- this.cameraTitle_ = this.placeholderTitle_;
- },
-
- /**
- * True when camera is in live mode (i.e. no still photo selected).
- * @type {boolean}
- */
- get cameraLive() {
- return this.cameraLive_;
- },
- set cameraLive(value) {
- this.cameraLive_ = value;
- this.previewElement.classList[value ? 'add' : 'remove']('live');
- },
-
- /**
- * Should only be queried from the 'change' event listener, true if the
- * change event was triggered by a programmatical selection change.
- * @type {boolean}
- */
- get inProgramSelection() {
- return this.inProgramSelection_;
- },
-
- /**
- * URL of the image selected.
- * @type {string?}
- */
- get selectedItemUrl() {
- var selectedItem = this.selectedItem;
- return selectedItem ? selectedItem.url : null;
- },
- set selectedItemUrl(url) {
- for (var i = 0, el; el = this.dataModel.item(i); i++) {
- if (el.url === url)
- this.selectedItemIndex = i;
- }
- },
-
- /**
- * Set index to the image selected.
- * @type {number} index The index of selected image.
- */
- set selectedItemIndex(index) {
- this.inProgramSelection_ = true;
- this.selectionModel.selectedIndex = index;
- this.inProgramSelection_ = false;
- },
-
- /** @override */
- get selectedItem() {
- var index = this.selectionModel.selectedIndex;
- return index != -1 ? this.dataModel.item(index) : null;
- },
- set selectedItem(selectedItem) {
- var index = this.indexOf(selectedItem);
- this.inProgramSelection_ = true;
- this.selectionModel.selectedIndex = index;
- this.selectionModel.leadIndex = index;
- this.inProgramSelection_ = false;
- },
-
- /**
- * Element containing the preview image (the first IMG element) and the
- * camera live stream (the first VIDEO element).
- * @type {HTMLElement}
- */
- get previewElement() {
- // TODO(ivankr): temporary hack for non-HTML5 version.
- return this.previewElement_ || this;
- },
- set previewElement(value) {
- this.previewElement_ = value;
- this.previewImage_ = value.querySelector('img');
- this.cameraVideo_ = value.querySelector('video');
- this.cameraVideo_.addEventListener('canplay',
- this.handleVideoStarted_.bind(this));
- this.cameraVideo_.addEventListener('timeupdate',
- this.handleVideoUpdate_.bind(this));
- this.updatePreview_();
- // Initialize camera state and check for its presence.
- this.cameraLive = true;
- this.cameraPresent = false;
- },
-
- /**
- * Whether the camera live stream and photo should be flipped horizontally.
- * If setting this property results in photo update, 'photoupdated' event
- * will be fired with 'dataURL' property containing the photo encoded as
- * a data URL
- * @type {boolean}
- */
- get flipPhoto() {
- return this.flipPhoto_ || false;
- },
- set flipPhoto(value) {
- if (this.flipPhoto_ == value)
- return;
- this.flipPhoto_ = value;
- this.previewElement.classList.toggle('flip-x', value);
- /* TODO(merkulova): remove when webkit crbug.com/126479 is fixed. */
- this.flipPhotoElement.classList.toggle('flip-trick', value);
- if (!this.cameraLive) {
- // Flip current still photo.
- var e = new Event('photoupdated');
- e.dataURL = this.flipPhoto ?
- this.flipFrame_(this.previewImage_) : this.previewImage_.src;
- this.dispatchEvent(e);
- }
- },
-
- /**
- * Performs photo capture from the live camera stream. 'phototaken' event
- * will be fired as soon as captured photo is available, with 'dataURL'
- * property containing the photo encoded as a data URL.
- * @return {boolean} Whether photo capture was successful.
- */
- takePhoto: function() {
- if (!this.cameraOnline)
- return false;
- var canvas = /** @type {HTMLCanvasElement} */(
- document.createElement('canvas'));
- canvas.width = CAPTURE_SIZE.width;
- canvas.height = CAPTURE_SIZE.height;
- this.captureFrame_(
- this.cameraVideo_,
- /** @type {CanvasRenderingContext2D} */(canvas.getContext('2d')),
- CAPTURE_SIZE);
- // Preload image before displaying it.
- var previewImg = new Image();
- previewImg.addEventListener('load', function(e) {
- this.cameraTitle_ = this.capturedImageTitle_;
- this.cameraImage = previewImg.src;
- }.bind(this));
- previewImg.src = canvas.toDataURL('image/png');
- var e = new Event('phototaken');
- e.dataURL = this.flipPhoto ? this.flipFrame_(canvas) : previewImg.src;
- this.dispatchEvent(e);
- return true;
- },
-
- /**
- * Discard current photo and return to the live camera stream.
- */
- discardPhoto: function() {
- this.cameraTitle_ = this.placeholderTitle_;
- this.cameraImage = null;
- },
-
- /**
- * Capture a single still frame from a <video> element, placing it at the
- * current drawing origin of a canvas context.
- * @param {HTMLVideoElement} video Video element to capture from.
- * @param {CanvasRenderingContext2D} ctx Canvas context to draw onto.
- * @param {{width: number, height: number}} destSize Capture size.
- * @private
- */
- captureFrame_: function(video, ctx, destSize) {
- var width = video.videoWidth;
- var height = video.videoHeight;
- if (width < destSize.width || height < destSize.height) {
- console.error('Video capture size too small: ' +
- width + 'x' + height + '!');
- }
- var src = {};
- if (width / destSize.width > height / destSize.height) {
- // Full height, crop left/right.
- src.height = height;
- src.width = height * destSize.width / destSize.height;
- } else {
- // Full width, crop top/bottom.
- src.width = width;
- src.height = width * destSize.height / destSize.width;
- }
- src.x = (width - src.width) / 2;
- src.y = (height - src.height) / 2;
- ctx.drawImage(video, src.x, src.y, src.width, src.height,
- 0, 0, destSize.width, destSize.height);
- },
-
- /**
- * Flips frame horizontally.
- * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} source
- * Frame to flip.
- * @return {string} Flipped frame as data URL.
- */
- flipFrame_: function(source) {
- var canvas = document.createElement('canvas');
- canvas.width = CAPTURE_SIZE.width;
- canvas.height = CAPTURE_SIZE.height;
- var ctx = canvas.getContext('2d');
- ctx.translate(CAPTURE_SIZE.width, 0);
- ctx.scale(-1.0, 1.0);
- ctx.drawImage(source, 0, 0);
- return canvas.toDataURL('image/png');
- },
-
- /**
- * Adds new image to the user image grid.
- * @param {string} url Image URL.
- * @param {string=} opt_title Image tooltip.
- * @param {Function=} opt_clickHandler Image click handler.
- * @param {number=} opt_position If given, inserts new image into
- * that position (0-based) in image list.
- * @param {Function=} opt_decorateFn Function called with the list element
- * as argument to do any final decoration.
- * @return {!Object} Image data inserted into the data model.
- */
- // TODO(ivankr): this function needs some argument list refactoring.
- addItem: function(url, opt_title, opt_clickHandler, opt_position,
- opt_decorateFn) {
- var imageInfo = {
- url: url,
- title: opt_title,
- clickHandler: opt_clickHandler,
- decorateFn: opt_decorateFn
- };
- this.inProgramSelection_ = true;
- if (opt_position !== undefined)
- this.dataModel.splice(opt_position, 0, imageInfo);
- else
- this.dataModel.push(imageInfo);
- this.inProgramSelection_ = false;
- return imageInfo;
- },
-
- /**
- * Returns index of an image in grid.
- * @param {Object} imageInfo Image data returned from addItem() call.
- * @return {number} Image index (0-based) or -1 if image was not found.
- */
- indexOf: function(imageInfo) {
- return this.dataModel.indexOf(imageInfo);
- },
-
- /**
- * Replaces an image in the grid.
- * @param {Object} imageInfo Image data returned from addItem() call.
- * @param {string} imageUrl New image URL.
- * @param {string=} opt_title New image tooltip (if undefined, tooltip
- * is left unchanged).
- * @return {!Object} Image data of the added or updated image.
- */
- updateItem: function(imageInfo, imageUrl, opt_title) {
- var imageIndex = this.indexOf(imageInfo);
- var wasSelected = this.selectionModel.selectedIndex == imageIndex;
- this.removeItem(imageInfo);
- var newInfo = this.addItem(
- imageUrl,
- opt_title === undefined ? imageInfo.title : opt_title,
- imageInfo.clickHandler,
- imageIndex,
- imageInfo.decorateFn);
- // Update image data with the reset of the keys from the old data.
- for (var k in imageInfo) {
- if (!(k in newInfo))
- newInfo[k] = imageInfo[k];
- }
- if (wasSelected)
- this.selectedItem = newInfo;
- return newInfo;
- },
-
- /**
- * Removes previously added image from the grid.
- * @param {Object} imageInfo Image data returned from the addItem() call.
- */
- removeItem: function(imageInfo) {
- var index = this.indexOf(imageInfo);
- if (index != -1) {
- var wasSelected = this.selectionModel.selectedIndex == index;
- this.inProgramSelection_ = true;
- this.dataModel.splice(index, 1);
- if (wasSelected) {
- // If item removed was selected, select the item next to it.
- this.selectedItem = this.dataModel.item(
- Math.min(this.dataModel.length - 1, index));
- }
- this.inProgramSelection_ = false;
- }
- },
-
- /**
- * Forces re-display, size re-calculation and focuses grid.
- */
- updateAndFocus: function() {
- // Recalculate the measured item size.
- this.measured_ = null;
- this.columns = 0;
- this.redraw();
- this.focus();
- },
-
- /**
- * Appends default images to the image grid. Should only be called once.
- * @param {Array<{url: string, author: string,
- * website: string, title: string}>} imagesData
- * An array of default images data, including URL, author, title and
- * website.
- */
- setDefaultImages: function(imagesData) {
- for (var i = 0, data; data = imagesData[i]; i++) {
- var item = this.addItem(data.url, data.title);
- item.type = 'default';
- item.author = data.author || '';
- item.website = data.website || '';
- }
- }
- };
-
- /**
- * URLs of special button images.
- * @enum {string}
- */
- UserImagesGrid.ButtonImages = {
- TAKE_PHOTO: 'chrome://theme/IDR_BUTTON_USER_IMAGE_TAKE_PHOTO',
- CHOOSE_FILE: 'chrome://theme/IDR_BUTTON_USER_IMAGE_CHOOSE_FILE',
- PROFILE_PICTURE: 'chrome://theme/IDR_PROFILE_PICTURE_LOADING'
- };
-
- return {
- UserImagesGrid: UserImagesGrid
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/OWNERS b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/OWNERS
deleted file mode 100644
index e88b945697a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-bshe@chromium.org
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
deleted file mode 100644
index 391ea71d2ca..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
+++ /dev/null
@@ -1,378 +0,0 @@
-/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-html {
- height: 100%;
-}
-
-body {
- -webkit-app-region: drag;
- background-color: rgba(20, 20, 20, 0.93);
- color: #999;
- font-size: 80%;
- height: 100%;
- margin: 0;
- padding: 0;
-}
-
-/* Click events are not received in draggable area. Making all clickable areas
- * not draggable to receive click events.
- * TODO(bshe): Remove this when http://crbug.com/142275 fixed.
- */
-.dialog-topbar #navstrip,
-.dialog-topbar #window-close-button,
-.overlay-container .page,
-#author-website,
-/* TODO(bshe): Once http://crbug.com/369651 fixed, use .image-picker instead of
- * #category-container.
- */
-#category-container,
-#surprise-me {
- -webkit-app-region: no-drag;
-}
-
-.dialog-container {
- display: flex;
- flex-direction: column;
- height: 100%;
- overflow: hidden;
-}
-
-.dialog-topbar {
- -webkit-box-align: center;
- display: -webkit-box;
- height: 54px;
- overflow: hidden;
- padding: 0 15px;
- position: relative;
-}
-
-.dialog-topbar .spacer {
- -webkit-box-flex: 1;
-}
-
-#categories-list {
- -webkit-box-orient: horizontal;
- display: -webkit-box;
- height: 54px;
- outline: none;
- width: 100%;
-}
-
-#categories-list > li {
- -webkit-box-align: center;
- -webkit-transition: border-top 130ms ease;
- -webkit-user-select: none;
- border-top: 4px solid transparent;
- color: #777;
- display: -webkit-box;
- height: 50px;
-}
-
-#categories-list:not([disabled]) > li:hover {
- border-top-color: rgba(255, 255, 255, 0.4);
- cursor: pointer;
-}
-
-#categories-list > li[selected] {
- color: rgb(70, 78, 90);
- cursor: default;
-}
-
-#categories-list > li > div {
- line-height: 34px;
- padding: 0 10px;
-}
-
-#categories-list > li[selected] > div {
- color: #eee;
-}
-
-.close {
- background-position: center;
- background-repeat: no-repeat;
- height: 14px;
- padding: 10px;
- position: absolute;
- right: 0;
- top: 0;
- width: 14px;
-}
-
-#window-close-button {
- background-image: url(../images/ui/close-white.png);
-}
-
-#window-close-button:hover {
- background-image: url(../images/ui/close-white-hover.png);
-}
-
-#bar {
- -webkit-transition: left 130ms ease-in-out;
- background-color: #eee;
- height: 4px;
- position: absolute;
- top: 0;
-}
-
-.dialog-main {
- display: flex;
- flex: 1;
-}
-
-#category-container {
- flex: 1;
- position: relative;
-}
-
-#spinner-container {
- -webkit-box-align: center;
- -webkit-box-pack: center;
- background: url(chrome://resources/images/throbber_medium.svg) center/32px
- no-repeat;
- display: -webkit-box;
- height: 287px;
- padding-bottom: 15px;
- padding-top: 5px;
- position: absolute;
- top: 0;
- width: 100%;
-}
-
-#wallpaper-set-by-message {
- -webkit-padding-end: 5px;
- -webkit-padding-start: 15px;
- height: 17px;
-}
-
-#wallpaper-set-by-message:empty {
- display: none;
-}
-
-.image-picker {
- -webkit-padding-end: 5px;
- -webkit-padding-start: 15px;
- display: block;
- /* Set font size to 0 to remove the extra vertical margin between two rows of
- * thumbnails.
- * TODO(bshe): Find the root cause of the margin.
- */
- font-size: 0;
- height: 287px;
- outline: none;
- overflow-y: auto;
- padding-bottom: 15px;
- padding-top: 5px;
-}
-
-.image-picker .spacer {
- display: block;
-}
-
-.image-picker > * {
- display: inline-block;
- margin: 0;
- overflow: hidden;
- padding: 0;
-}
-
-.image-picker [role=listitem] {
- -webkit-margin-end: 1px;
- height: 68px;
- margin-bottom: 1px;
- position: relative;
- width: 108px;
-}
-
-.image-picker:not([disabled]) [role=listitem]:hover {
- outline: 3px solid #f1f1f1;
- z-index: 1;
-}
-
-.image-picker .check {
- background-image: url(../images/ui/check.png);
- height: 32px;
- left: 38px;
- position: absolute;
- top: 18px;
- width: 32px;
- z-index: 2;
-}
-
-::-webkit-scrollbar {
- width: 6px;
-}
-
-::-webkit-scrollbar-thumb {
- background: #aaa;
-}
-
-::-webkit-scrollbar-thumb:hover {
- background: #888;
-}
-
-/* The width and height of img tag need to be set here. Otherwise, an incorrect
- * image size may be used during layout. Some images may be misaligned as a
- * result. See http://code.google.com/p/chromium/issues/detail?id=148480 for
- * screen shot.
- */
-.image-picker img {
- height: 68px;
- width: 108px;
-}
-
-.image-picker[disabled]~.bottom-bar #online-wallpaper-attribute,
-.image-picker[disabled] .check {
- visibility: hidden;
-}
-
-.image-picker[disabled],
-.image-picker-offline img:not([offline]) {
- -webkit-filter: grayscale(1);
-}
-
-#wallpaper-attribute {
- -webkit-box-orient: vertical;
- display: -webkit-box;
-}
-
-.bottom-bar {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: end;
- display: -webkit-box;
- height: 40px;
- padding: 11px 15px 8px 15px;
-}
-
-.bottom-bar > .spacer {
- -webkit-box-flex: 1;
-}
-
-#online-wallpaper-attribute {
- display: -webkit-box;
-}
-
-#attribute-image {
- -webkit-margin-end: 10px;
- height: 34px;
- width: 54px;
-}
-
-#author-website {
- color: #999;
- overflow: hidden;
- white-space: nowrap;
- width: 240px;
-}
-
-/* [hidden] does display:none, but its priority is too low. */
-[hidden],
-body[custom] [visibleif]:not([visibleif~='custom']),
-body:not([custom]) [visibleif~='custom'] {
- display: none !important;
-}
-
-body[surprise-me-disabled] [visibleif]:not([visibleif~='surprise-me-disabled']),
-body:not([surprise-me-disabled]) [visibleif~='surprise-me-disabled'] {
- display: none !important;
-}
-
-.progress-bar {
- background-color: rgba(255, 255, 255, 0.7);
- height: 6px;
- position: absolute;
- top: 62px;
- width: 100%;
-}
-
-.progress-track {
- -webkit-transition: width 1ms linear;
- background-color: rgb(66, 129, 244);
- height: 100%;
- width: 0;
-}
-
-.overlay-container {
- -webkit-box-align: center;
- -webkit-box-orient: vertical;
- -webkit-box-pack: center;
- background-color: rgba(25, 25, 25, 0.25);
- bottom: 0;
- display: -webkit-box;
- left: 0;
- overflow: auto;
- position: fixed;
- right: 0;
- top: 0;
- z-index: 4;
-}
-
-.overlay-container .page {
- -webkit-box-orient: vertical;
- background: rgb(255, 255, 255);
- border-radius: 3px;
- box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.15);
- color: #333;
- display: -webkit-box;
- padding: 20px;
- position: relative;
- width: 302px;
-}
-
-#error-container {
- z-index: 5;
-}
-
-.overlay-container .close {
- background-image: url(../images/ui/close-overlay.png);
-}
-
-.overlay-container .close:hover {
- background-image: url(../images/ui/close-overlay-hover.png);
-}
-
-/* Custom wallpaper thumbnail container. */
-#add-new img {
- content: url(../images/ui/add-wallpaper-thumbnail.png);
-}
-
-.image-picker:not([disabled]) #add-new:hover img {
- content: url(../images/ui/add-wallpaper-thumbnail-hover.png);
-}
-
-#wallpaper-selection-container #content div {
- margin: 20px 0 5px 0;
-}
-
-#wallpaper-selection-container #warning span {
- line-height: 17px;
-}
-
-#wallpaper-selection-container select {
- height: 30px;
-}
-
-#wallpaper-selection-container input[type='file']::-webkit-file-upload-button {
- height: 30px;
-}
-
-#wallpaper-selection-container .remember-icon {
- content: url(../images/ui/remember.png);
-}
-
-#surprise-me #checkbox {
- background-image: url(../images/ui/checkbox_unchecked.png);
- display: inline-block;
- height: 17px;
- margin-right: 4px;
- opacity: 0.7;
- position: relative;
- top: 4px;
- width: 17px;
-}
-
-#surprise-me #checkbox.checked {
- background-image: url(../images/ui/checkbox_checked.png);
-}
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon128.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon128.png
deleted file mode 100644
index fcc60622a14..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon128.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon16.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon16.png
deleted file mode 100644
index 39b8b7e02e8..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon16.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon256.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon256.png
deleted file mode 100644
index 2ac138b4bcc..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon256.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon32.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon32.png
deleted file mode 100644
index f74ee64eb2b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon32.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon48.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon48.png
deleted file mode 100644
index 2e5d9ab2bcb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon48.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon64.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon64.png
deleted file mode 100644
index 4249d367cb3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon64.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon96.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon96.png
deleted file mode 100644
index 4cd46999488..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/icon96.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/add-wallpaper-thumbnail-hover.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/add-wallpaper-thumbnail-hover.png
deleted file mode 100644
index 3cbf6aa6d9c..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/add-wallpaper-thumbnail-hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/add-wallpaper-thumbnail.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/add-wallpaper-thumbnail.png
deleted file mode 100644
index 710a95977cb..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/add-wallpaper-thumbnail.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/check.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/check.png
deleted file mode 100644
index f11047e8226..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/check.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-overlay-hover.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-overlay-hover.png
deleted file mode 100644
index c49f5639a83..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-overlay-hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-overlay.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-overlay.png
deleted file mode 100644
index efb23e7136f..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-overlay.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-white-hover.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-white-hover.png
deleted file mode 100644
index 548fdf488a1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-white-hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-white.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-white.png
deleted file mode 100644
index 566efa90cc7..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close-white.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close_bar.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close_bar.png
deleted file mode 100644
index 142adb8b647..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close_bar.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/add-wallpaper-thumbnail-hover.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/add-wallpaper-thumbnail-hover.png
deleted file mode 100644
index 3e8bba9b42b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/add-wallpaper-thumbnail-hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/add-wallpaper-thumbnail.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/add-wallpaper-thumbnail.png
deleted file mode 100644
index 148861f9b32..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/add-wallpaper-thumbnail.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/check.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/check.png
deleted file mode 100644
index d0bb12d2f28..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/check.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/checkbox_checked.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/checkbox_checked.png
deleted file mode 100644
index 238ce2f34bd..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/checkbox_checked.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/checkbox_unchecked.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/checkbox_unchecked.png
deleted file mode 100644
index 45c25da4254..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/checkbox_unchecked.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-overlay-hover.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-overlay-hover.png
deleted file mode 100644
index c3ce1dc3a55..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-overlay-hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-overlay.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-overlay.png
deleted file mode 100644
index 02e1f91ee0b..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-overlay.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-white-hover.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-white-hover.png
deleted file mode 100644
index e90252b6fe1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-white-hover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-white.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-white.png
deleted file mode 100644
index 4ac41b2d8b5..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close-white.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close_bar.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close_bar.png
deleted file mode 100644
index e70e5b6a991..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close_bar.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/remember.png b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/remember.png
deleted file mode 100644
index 130b6d4f2b6..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/remember.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/constants.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/constants.js
deleted file mode 100644
index 8001c1621ee..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/constants.js
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-/** @const */ var Constants = {
- /**
- * Key to access wallpaper rss in chrome.storage.local.
- */
- AccessLocalRssKey: 'wallpaper-picker-surprise-rss-key',
-
- /**
- * Key to access wallpaper manifest in chrome.storage.local.
- */
- AccessLocalManifestKey: 'wallpaper-picker-manifest-key',
-
- /**
- * Key to access user wallpaper info in chrome.storage.local.
- */
- AccessLocalWallpaperInfoKey: 'wallpaper-local-info-key',
-
- /**
- * Key to access user wallpaper info in chrome.storage.sync.
- */
- AccessSyncWallpaperInfoKey: 'wallpaper-sync-info-key',
-
- /**
- * Key to access last changed date of a surprise wallpaper in
- * chrome.storage.local or chrome.storage.sync.
- */
- AccessLastSurpriseWallpaperChangedDate: 'wallpaper-last-changed-date-key',
-
- /**
- * Key to access if surprise me feature is enabled or not in
- * chrome.storage.local.
- */
- AccessLocalSurpriseMeEnabledKey: 'surprise-me-enabled-key',
-
- /**
- * Key to access if surprise me feature is enabled or not in
- * chrome.storage.sync.
- */
- AccessSyncSurpriseMeEnabledKey: 'sync-surprise-me-enabled-key',
-
- /**
- * Suffix to append to baseURL if requesting high resoultion wallpaper.
- */
- HighResolutionSuffix: '_high_resolution.jpg',
-
- /**
- * URL to get latest wallpaper RSS feed.
- */
- WallpaperRssURL: 'https://storage.googleapis.com/' +
- 'chromeos-wallpaper-public/wallpaper.rss',
-
- /**
- * cros-wallpaper namespace URI.
- */
- WallpaperNameSpaceURI: 'http://commondatastorage.googleapis.com/' +
- 'chromeos-wallpaper-public/cros-wallpaper-uri',
-
- /**
- * Wallpaper sources enum.
- */
- WallpaperSourceEnum: {
- Online: 'ONLINE',
- OEM: 'OEM',
- Custom: 'CUSTOM',
- AddNew: 'ADDNEW',
- Default: 'DEFAULT'
- },
-
- /**
- * Local storage.
- */
- WallpaperLocalStorage: chrome.storage.local,
-
- /**
- * Sync storage.
- */
- WallpaperSyncStorage: chrome.storage.sync,
-
- /**
- * Suffix to append to file name if it is a thumbnail.
- */
- CustomWallpaperThumbnailSuffix: '_thumbnail',
-
- /**
- * Wallpaper directory enum.
- */
- WallpaperDirNameEnum: {
- ORIGINAL: 'original',
- THUMBNAIL: 'thumbnail'
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
deleted file mode 100644
index eba94a343e0..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var WALLPAPER_PICKER_WIDTH = 574;
-var WALLPAPER_PICKER_HEIGHT = 420;
-
-var wallpaperPickerWindow;
-
-var surpriseWallpaper = null;
-
-function SurpriseWallpaper() {
-}
-
-/**
- * Gets SurpriseWallpaper instance. In case it hasn't been initialized, a new
- * instance is created.
- * @return {SurpriseWallpaper} A SurpriseWallpaper instance.
- */
-SurpriseWallpaper.getInstance = function() {
- if (!surpriseWallpaper)
- surpriseWallpaper = new SurpriseWallpaper();
- return surpriseWallpaper;
-};
-
-/**
- * Tries to change wallpaper to a new one in the background. May fail due to a
- * network issue.
- */
-SurpriseWallpaper.prototype.tryChangeWallpaper = function() {
- var self = this;
- var onFailure = function(status) {
- if (status != 404)
- self.fallbackToLocalRss_();
- else
- self.updateRandomWallpaper_();
- };
- // Try to fetch newest rss as document from server first. If the requested
- // URL is not found (404 error), set a random wallpaper displayed in the
- // wallpaper picker. If any other error occurs, proceed with local copy of
- // rss.
- WallpaperUtil.fetchURL(Constants.WallpaperRssURL, 'document', function(xhr) {
- WallpaperUtil.saveToLocalStorage(Constants.AccessLocalRssKey,
- new XMLSerializer().serializeToString(xhr.responseXML));
- self.updateSurpriseWallpaper(xhr.responseXML);
- }, onFailure);
-};
-
-/**
- * Retries changing the wallpaper 1 hour later. This is called when fetching the
- * rss or wallpaper from server fails.
- * @private
- */
-SurpriseWallpaper.prototype.retryLater_ = function() {
- chrome.alarms.create('RetryAlarm', {delayInMinutes: 60});
-};
-
-/**
- * Fetches the cached rss feed from local storage in the event of being unable
- * to download the online feed.
- * @private
- */
-SurpriseWallpaper.prototype.fallbackToLocalRss_ = function() {
- var self = this;
- Constants.WallpaperLocalStorage.get(Constants.AccessLocalRssKey,
- function(items) {
- var rssString = items[Constants.AccessLocalRssKey];
- if (rssString) {
- self.updateSurpriseWallpaper(new DOMParser().parseFromString(rssString,
- 'text/xml'));
- } else {
- self.updateSurpriseWallpaper();
- }
- });
-};
-
-/**
- * Starts to change wallpaper. Called after rss is fetched.
- * @param {Document=} opt_rss The fetched rss document. If opt_rss is null, uses
- * a random wallpaper.
- */
-SurpriseWallpaper.prototype.updateSurpriseWallpaper = function(opt_rss) {
- if (opt_rss) {
- var items = opt_rss.querySelectorAll('item');
- var date = new Date(new Date().toDateString()).getTime();
- for (var i = 0; i < items.length; i++) {
- item = items[i];
- var disableDate = new Date(item.getElementsByTagNameNS(
- Constants.WallpaperNameSpaceURI, 'disableDate')[0].textContent).
- getTime();
- var enableDate = new Date(item.getElementsByTagNameNS(
- Constants.WallpaperNameSpaceURI, 'enableDate')[0].textContent).
- getTime();
- var regionsString = item.getElementsByTagNameNS(
- Constants.WallpaperNameSpaceURI, 'regions')[0].textContent;
- var regions = regionsString.split(', ');
- if (enableDate <= date && disableDate > date &&
- regions.indexOf(navigator.language) != -1) {
- var self = this;
- this.setWallpaperFromRssItem_(item,
- function() {},
- function(status) {
- if (status != 404)
- self.retryLater_();
- else
- self.updateRandomWallpaper_();
- });
- return;
- }
- }
- }
- // No surprise wallpaper for today at current locale or fetching rss feed
- // fails. Fallback to use a random one from wallpaper server.
- this.updateRandomWallpaper_();
-};
-
-/**
- * Sets a new random wallpaper if one has not already been set today.
- * @private
- */
-SurpriseWallpaper.prototype.updateRandomWallpaper_ = function() {
- var self = this;
- var onSuccess = function(items) {
- var dateString = new Date().toDateString();
- // At most one random wallpaper per day.
- if (items[Constants.AccessLastSurpriseWallpaperChangedDate] != dateString) {
- self.setRandomWallpaper_(dateString);
- }
- };
- WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
- if (syncEnabled) {
- Constants.WallpaperSyncStorage.get(
- Constants.AccessLastSurpriseWallpaperChangedDate, onSuccess);
- } else {
- Constants.WallpaperLocalStorage.get(
- Constants.AccessLastSurpriseWallpaperChangedDate, onSuccess);
- }
- });
-};
-
-/**
- * Sets wallpaper to one of the wallpapers displayed in wallpaper picker. If
- * the wallpaper download fails, retry one hour later. Wallpapers that are
- * disabled for surprise me are excluded.
- * @param {string} dateString String representation of current local date.
- * @private
- */
-SurpriseWallpaper.prototype.setRandomWallpaper_ = function(dateString) {
- var self = this;
- Constants.WallpaperLocalStorage.get(Constants.AccessLocalManifestKey,
- function(items) {
- var manifest = items[Constants.AccessLocalManifestKey];
- if (manifest && manifest.wallpaper_list) {
- var filtered = manifest.wallpaper_list.filter(function(element) {
- // Older version manifest do not have available_for_surprise_me field.
- // In this case, no wallpaper should be filtered out.
- return element.available_for_surprise_me ||
- element.available_for_surprise_me == undefined;
- });
- var index = Math.floor(Math.random() * filtered.length);
- var wallpaper = filtered[index];
- var wallpaperURL = wallpaper.base_url + Constants.HighResolutionSuffix;
- var onSuccess = function() {
- WallpaperUtil.saveWallpaperInfo(wallpaperURL, wallpaper.default_layout,
- Constants.WallpaperSourceEnum.Online);
- WallpaperUtil.saveToLocalStorage(
- Constants.AccessLastSurpriseWallpaperChangedDate,
- dateString, function() {
- WallpaperUtil.saveToSyncStorage(
- Constants.AccessLastSurpriseWallpaperChangedDate,
- dateString);
- });
- };
- WallpaperUtil.setOnlineWallpaper(wallpaperURL, wallpaper.default_layout,
- onSuccess, self.retryLater_.bind(self));
- }
- });
-};
-
-/**
- * Sets wallpaper to the wallpaper specified by item from rss. If downloading
- * the wallpaper fails, retry one hour later.
- * @param {Element} item The wallpaper rss item element.
- * @param {function} onSuccess Success callback.
- * @param {function} onFailure Failure callback.
- * @private
- */
-SurpriseWallpaper.prototype.setWallpaperFromRssItem_ = function(item,
- onSuccess,
- onFailure) {
- var url = item.querySelector('link').textContent;
- var layout = item.getElementsByTagNameNS(
- Constants.WallpaperNameSpaceURI, 'layout')[0].textContent;
- var self = this;
- WallpaperUtil.fetchURL(url, 'arraybuffer', function(xhr) {
- if (xhr.response != null) {
- chrome.wallpaperPrivate.setCustomWallpaper(xhr.response, layout, false,
- 'surprise_wallpaper',
- onSuccess);
- WallpaperUtil.saveWallpaperInfo(url, layout,
- Constants.WallpaperSourceEnum.Online);
- var dateString = new Date().toDateString();
- WallpaperUtil.saveToLocalStorage(
- Constants.AccessLastSurpriseWallpaperChangedDate,
- dateString, function() {
- WallpaperUtil.saveToSyncStorage(
- Constants.AccessLastSurpriseWallpaperChangedDate, dataString);
- });
- } else {
- self.updateRandomWallpaper_();
- }
- }, onFailure);
-};
-
-/**
- * Disables the wallpaper surprise me feature. Clear all alarms and states.
- */
-SurpriseWallpaper.prototype.disable = function() {
- chrome.alarms.clearAll();
- // Makes last changed date invalid.
- WallpaperUtil.saveToLocalStorage(
- Constants.AccessLastSurpriseWallpaperChangedDate, '', function() {
- WallpaperUtil.saveToSyncStorage(
- Constants.AccessLastSurpriseWallpaperChangedDate, '');
- });
-};
-
-/**
- * Changes current wallpaper and sets up an alarm to schedule next change around
- * midnight.
- */
-SurpriseWallpaper.prototype.next = function() {
- var nextUpdate = this.nextUpdateTime(new Date());
- chrome.alarms.create({when: nextUpdate});
- this.tryChangeWallpaper();
-};
-
-/**
- * Calculates when the next wallpaper change should be triggered.
- * @param {Date} now Current time.
- * @return {number} The time when next wallpaper change should happen.
- */
-SurpriseWallpaper.prototype.nextUpdateTime = function(now) {
- var nextUpdate = new Date(now.setDate(now.getDate() + 1)).toDateString();
- return new Date(nextUpdate).getTime();
-};
-
-chrome.app.runtime.onLaunched.addListener(function() {
- if (wallpaperPickerWindow && !wallpaperPickerWindow.contentWindow.closed) {
- wallpaperPickerWindow.focus();
- chrome.wallpaperPrivate.minimizeInactiveWindows();
- return;
- }
-
- chrome.app.window.create('main.html', {
- frame: 'none',
- width: WALLPAPER_PICKER_WIDTH,
- height: WALLPAPER_PICKER_HEIGHT,
- resizable: false,
- alphaEnabled: true
- }, function(w) {
- wallpaperPickerWindow = w;
- chrome.wallpaperPrivate.minimizeInactiveWindows();
- w.onClosed.addListener(function() {
- chrome.wallpaperPrivate.restoreMinimizedWindows();
- });
- WallpaperUtil.testSendMessage('wallpaper-window-created');
- });
-});
-
-chrome.syncFileSystem.onFileStatusChanged.addListener(function(detail) {
- WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
- if (!syncEnabled)
- return;
- if (detail.status == 'synced') {
- if (detail.direction == 'remote_to_local') {
- if (detail.action == 'added') {
- Constants.WallpaperLocalStorage.get(
- Constants.AccessLocalWallpaperInfoKey,
- function(items) {
- var localData = items[Constants.AccessLocalWallpaperInfoKey];
- if (localData && localData.url == detail.fileEntry.name &&
- localData.source == Constants.WallpaperSourceEnum.Custom) {
- WallpaperUtil.setCustomWallpaperFromSyncFS(localData.url,
- localData.layout);
- } else if (!localData || localData.url !=
- detail.fileEntry.name.replace(
- Constants.CustomWallpaperThumbnailSuffix, '')) {
- // localData might be null on a powerwashed device.
- WallpaperUtil.storeWallpaperFromSyncFSToLocalFS(
- detail.fileEntry);
- }
- });
- } else if (detail.action == 'deleted') {
- var fileName = detail.fileEntry.name.replace(
- Constants.CustomWallpaperThumbnailSuffix, '');
- WallpaperUtil.deleteWallpaperFromLocalFS(fileName);
- }
- } else { // detail.direction == 'local_to_remote'
- if (detail.action == 'deleted') {
- WallpaperUtil.deleteWallpaperFromSyncFS(detail.fileEntry.name);
- WallpaperUtil.deleteWallpaperFromLocalFS(detail.fileEntry.name);
- }
- }
- }
- });
-});
-
-chrome.storage.onChanged.addListener(function(changes, namespace) {
- WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
- if (syncEnabled) {
- // If sync theme is enabled, use values from chrome.storage.sync to sync
- // wallpaper changes.
- WallpaperUtil.requestSyncFS(function() {});
- if (changes[Constants.AccessSyncSurpriseMeEnabledKey]) {
- if (changes[Constants.AccessSyncSurpriseMeEnabledKey].newValue) {
- SurpriseWallpaper.getInstance().next();
- } else {
- SurpriseWallpaper.getInstance().disable();
- }
- }
-
- if (changes[Constants.AccessSyncWallpaperInfoKey]) {
- var syncInfo = changes[Constants.AccessSyncWallpaperInfoKey].newValue;
-
- Constants.WallpaperSyncStorage.get(
- Constants.AccessSyncSurpriseMeEnabledKey, function(enabledItems) {
- var syncSurpriseMeEnabled =
- enabledItems[Constants.AccessSyncSurpriseMeEnabledKey];
-
- Constants.WallpaperSyncStorage.get(
- Constants.AccessLastSurpriseWallpaperChangedDate,
- function(items) {
- var syncLastSurpriseMeChangedDate =
- items[Constants.AccessLastSurpriseWallpaperChangedDate];
-
- var today = new Date().toDateString();
- // If SurpriseMe is enabled and surprise wallpaper hasn't been
- // changed today, we should not sync the change, instead onAlarm()
- // will be triggered to update a surprise me wallpaper.
- if (!syncSurpriseMeEnabled ||
- (syncSurpriseMeEnabled &&
- syncLastSurpriseMeChangedDate == today)) {
- Constants.WallpaperLocalStorage.get(
- Constants.AccessLocalWallpaperInfoKey, function(infoItems) {
- var localInfo =
- infoItems[Constants.AccessLocalWallpaperInfoKey];
- // Normally, the wallpaper info saved in local storage and sync
- // storage are the same. If the synced value changed by sync
- // service, they may different. In that case, change wallpaper
- // to the one saved in sync storage and update the local value.
- if (localInfo == undefined ||
- localInfo.url != syncInfo.url ||
- localInfo.layout != syncInfo.layout ||
- localInfo.source != syncInfo.source) {
- if (syncInfo.source == Constants.WallpaperSourceEnum.Online) {
- // TODO(bshe): Consider schedule an alarm to set online
- // wallpaper later when failed. Note that we need to cancel
- // the retry if user set another wallpaper before retry
- // alarm invoked.
- WallpaperUtil.setOnlineWallpaper(syncInfo.url,
- syncInfo.layout, function() {}, function() {});
- } else if (syncInfo.source ==
- Constants.WallpaperSourceEnum.Custom) {
- WallpaperUtil.setCustomWallpaperFromSyncFS(syncInfo.url,
- syncInfo.layout);
- } else if (syncInfo.source ==
- Constants.WallpaperSourceEnum.Default) {
- chrome.wallpaperPrivate.resetWallpaper();
- }
- WallpaperUtil.saveToLocalStorage(
- Constants.AccessLocalWallpaperInfoKey, syncInfo);
- }
- });
- }
- });
- });
- }
- } else {
- // If sync theme is disabled, use values from chrome.storage.local to
- // track wallpaper changes.
- if (changes[Constants.AccessLocalSurpriseMeEnabledKey]) {
- if (changes[Constants.AccessLocalSurpriseMeEnabledKey].newValue) {
- SurpriseWallpaper.getInstance().next();
- } else {
- SurpriseWallpaper.getInstance().disable();
- }
- }
- }
- });
-});
-
-chrome.alarms.onAlarm.addListener(function() {
- SurpriseWallpaper.getInstance().next();
-});
-
-chrome.wallpaperPrivate.onWallpaperChangedBy3rdParty.addListener(function() {
- WallpaperUtil.saveToLocalStorage(
- Constants.AccessLocalSurpriseMeEnabledKey, false, function() {
- WallpaperUtil.saveToSyncStorage(Constants.AccessSyncSurpriseMeEnabledKey,
- false);
- });
- SurpriseWallpaper.getInstance().disable();
-});
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/main.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/main.js
deleted file mode 100644
index adf044a8845..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/main.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Global wallpaperManager reference useful for poking at from the console.
-*/
-var wallpaperManager;
-
-function init() {
- WallpaperManager.initStrings(function() {
- wallpaperManager = new WallpaperManager(document.body);
- });
-}
-
-document.addEventListener('DOMContentLoaded', init);
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/main_scripts.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/main_scripts.js
deleted file mode 100644
index 57de792b0cf..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/main_scripts.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//<include src="../../../../../../ui/webui/resources/js/cr.js">
-//<include src="../../../../../../ui/webui/resources/js/event_tracker.js">
-//<include src="../../../../../../ui/webui/resources/js/load_time_data.js">
-//<include src="../../../../../../ui/webui/resources/js/i18n_template_no_process.js">
-//<include src="../../../../../../ui/webui/resources/js/util.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/event_target.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/touch_handler.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/array_data_model.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list_item.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list_selection_model.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list_single_selection_model.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list_selection_controller.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/list.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/grid.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/command.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/position_util.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/menu_item.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/menu.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/menu_button.js">
-//<include src="../../../../../../ui/webui/resources/js/cr/ui/context_menu_handler.js">
-//<include src="constants.js">
-//<include src="util.js">
-//<include src="progress_manager.js">
-//<include src="wallpaper_directories.js">
-//<include src="wallpaper_categories_list.js">
-//<include src="wallpaper_images_grid.js">
-//<include src="wallpaper_manager.js">
-//<include src="main.js">
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/progress_manager.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/progress_manager.js
deleted file mode 100644
index 7e472aca409..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/progress_manager.js
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Monitor the downloading progress of a XMLHttpRequest |xhr_| and shows the
- * progress on |progressBar_|.
- * @constructor
- */
-function ProgressManager() {
- this.xhr_ = null;
- this.progressBar_ = document.querySelector('.progress-bar');
- this.selectedGridItem_ = null;
-}
-
-/**
- * Sets the XMLHttpRequest |xhr| to monitor, and the wallpaper thumbnail grid
- * item |selectedGridItem| to show a progress bar for. Cancels previous xhr and
- * hides/removes previous progress bar if any.
- * Note: this must be called before xhr.send() function. Otherwise, we wont get
- * loadstart event.
- * @param {XMLHttpRequest} xhr The XMLHttpRequest.
- * @param {WallpaperThumbnailsGridItem} selectedGridItem The wallpaper thumbnail
- * grid item. It extends from cr.ui.ListItem.
- */
-ProgressManager.prototype.reset = function(xhr, selectedGridItem) {
- if (this.xhr_)
- this.removeEventListeners_();
- this.hideProgressBar(this.selectedGridItem_);
- this.xhr_ = xhr;
- this.selectedGridItem_ = selectedGridItem;
- this.xhrListeners_ = {
- 'loadstart': this.onDownloadStart_.bind(this),
- 'progress': this.onDownloadProgress_.bind(this),
- 'abort': this.onDownloadErrorOrAbort_.bind(this),
- 'error': this.onDownloadErrorOrAbort_.bind(this),
- 'load': this.onDownloadComplete_.bind(this)
- };
- for (var eventType in this.xhrListeners_)
- this.xhr_.addEventListener(eventType, this.xhrListeners_[eventType]);
-};
-
-/**
- * Removes all event listeners progress manager currently registered.
- * @private
- */
-ProgressManager.prototype.removeEventListeners_ = function() {
- for (var eventType in this.xhrListeners_)
- this.xhr_.removeEventListener(eventType, this.xhrListeners_[eventType]);
-};
-
-/**
- * Removes the progress bar in |selectedGridItem| if any. May be called
- * asynchronously.
- * @param {WallpaperThumbnailsGridItem} selectedGridItem The wallpaper thumbnail
- grid item. It extends from cr.ui.ListItem.
- */
-ProgressManager.prototype.hideProgressBar = function(selectedGridItem) {
- if (selectedGridItem && selectedGridItem.querySelector('.progress-bar')) {
- this.progressBar_.hidden = true;
- selectedGridItem.removeChild(this.progressBar_);
- }
-};
-
-/**
- * Calculates and updates the width of progress track.
- * @private
- * @param {float} percentComplete The percent of loaded content.
- */
-ProgressManager.prototype.setProgress_ = function(percentComplete) {
- this.progressBar_.querySelector('.progress-track').style.width =
- (percentComplete * 100) + '%';
-};
-
-/**
- * Shows a 0% progress bar to indicate downloading starts.
- * @private
- * @param {Event} e A loadstart ProgressEvent from XMLHttpRequest.
- */
-ProgressManager.prototype.onDownloadStart_ = function(e) {
- this.setProgress_(0);
- this.selectedGridItem_.appendChild(this.progressBar_);
- this.progressBar_.hidden = false;
-};
-
-/**
- * Hides progress bar when progression is terminated.
- * @private
- * @param {Event} e An error/abort ProgressEvent from XMLHttpRequest.
- */
-ProgressManager.prototype.onDownloadErrorOrAbort_ = function(e) {
- this.removeEventListeners_();
- this.xhr_ = null;
- this.hideProgressBar(this.selectedGridItem_);
-};
-
-/**
- * Download completed successfully. Shows a 100% progress bar and clears |xhr_|.
- * @private
- * @param {Event} e A load ProgressEvent from XMLHttpRequest.
- */
-ProgressManager.prototype.onDownloadComplete_ = function(e) {
- this.setProgress_(1);
- this.removeEventListeners_();
- this.xhr_ = null;
-};
-
-/**
- * Calculates downloading percentage and shows downloading progress.
- * @private
- * @param {Event} e A progress ProgressEvent from XMLHttpRequest.
- */
-ProgressManager.prototype.onDownloadProgress_ = function(e) {
- if (e.lengthComputable)
- this.setProgress_(e.loaded / e.total);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js
deleted file mode 100644
index de8c5187886..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var WallpaperUtil = {
- strings: null, // Object that contains all the flags
- syncFs: null, // syncFileSystem handler
- webkitFs: null // webkitFileSystem handler
-};
-
-/**
- * Deletes |wallpaperFileName| and its associated thumbnail from local FS.
- * @param {string} wallpaperFilename Name of the file that will be deleted
- */
-WallpaperUtil.deleteWallpaperFromLocalFS = function(wallpaperFilename) {
- WallpaperUtil.requestLocalFS(function(fs) {
- var originalPath = Constants.WallpaperDirNameEnum.ORIGINAL + '/' +
- wallpaperFilename;
- var thumbnailPath = Constants.WallpaperDirNameEnum.THUMBNAIL + '/' +
- wallpaperFilename;
- fs.root.getFile(originalPath,
- {create: false},
- function(fe) {
- fe.remove(function() {}, null);
- },
- // NotFoundError is expected. After we receive a delete
- // event from either original wallpaper or wallpaper
- // thumbnail, we delete both of them in local FS to achieve
- // a faster synchronization. So each file is expected to be
- // deleted twice and the second attempt is a noop.
- function(e) {
- if (e.name != 'NotFoundError')
- WallpaperUtil.onFileSystemError(e);
- });
- fs.root.getFile(thumbnailPath,
- {create: false},
- function(fe) {
- fe.remove(function() {}, null);
- },
- function(e) {
- if (e.name != 'NotFoundError')
- WallpaperUtil.onFileSystemError(e);
- });
- });
-};
-
-/**
- * Loads a wallpaper from sync file system and saves it and its thumbnail to
- * local file system.
- * @param {string} wallpaperFileEntry File name of wallpaper image.
- */
-WallpaperUtil.storeWallpaperFromSyncFSToLocalFS = function(wallpaperFileEntry) {
- var filenName = wallpaperFileEntry.name;
- var storeDir = Constants.WallpaperDirNameEnum.ORIGINAL;
- if (filenName.indexOf(Constants.CustomWallpaperThumbnailSuffix) != -1)
- storeDir = Constants.WallpaperDirNameEnum.THUMBNAIL;
- filenName = filenName.replace(Constants.CustomWallpaperThumbnailSuffix, '');
- wallpaperFileEntry.file(function(file) {
- var reader = new FileReader();
- reader.onloadend = function() {
- WallpaperUtil.storeWallpaperToLocalFS(filenName, reader.result, storeDir);
- };
- reader.readAsArrayBuffer(file);
- }, WallpaperUtil.onFileSystemError);
-};
-
-/**
- * Deletes |wallpaperFileName| and its associated thumbnail from syncFileSystem.
- * @param {string} wallpaperFilename Name of the file that will be deleted.
- */
-WallpaperUtil.deleteWallpaperFromSyncFS = function(wallpaperFilename) {
- var thumbnailFilename = wallpaperFilename +
- Constants.CustomWallpaperThumbnailSuffix;
- var success = function(fs) {
- fs.root.getFile(wallpaperFilename,
- {create: false},
- function(fe) {
- fe.remove(function() {}, null);
- },
- WallpaperUtil.onFileSystemError);
- fs.root.getFile(thumbnailFilename,
- {create: false},
- function(fe) {
- fe.remove(function() {}, null);
- },
- WallpaperUtil.onFileSystemError);
- };
- WallpaperUtil.requestSyncFS(success);
-};
-
-/**
- * Executes callback after requesting the sync settings.
- * @param {function} callback The callback will be executed.
- */
-WallpaperUtil.enabledSyncThemesCallback = function(callback) {
- chrome.wallpaperPrivate.getSyncSetting(function(setting) {
- callback(setting.syncThemes);
- });
-};
-
-/**
- * Request a syncFileSystem handle and run callback on it.
- * @param {function} callback The callback to execute after syncFileSystem
- * handler is available.
- */
-WallpaperUtil.requestSyncFS = function(callback) {
- WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
- if (!syncEnabled)
- return;
- if (WallpaperUtil.syncFs) {
- callback(WallpaperUtil.syncFs);
- } else {
- chrome.syncFileSystem.requestFileSystem(function(fs) {
- WallpaperUtil.syncFs = fs;
- callback(WallpaperUtil.syncFs);
- });
- }
- });
-};
-
-/**
- * Request a Local Fs handle and run callback on it.
- * @param {function} callback The callback to execute after Local handler is
- * available.
- */
-WallpaperUtil.requestLocalFS = function(callback) {
- if (WallpaperUtil.webkitFs) {
- callback(WallpaperUtil.webkitFs);
- } else {
- window.webkitRequestFileSystem(window.PERSISTENT, 1024 * 1024 * 100,
- function(fs) {
- WallpaperUtil.webkitFs = fs;
- callback(fs);
- });
- }
-};
-
-/**
- * Print error to console.error.
- * @param {Event} e The error will be printed to console.error.
- */
-// TODO(ranj): Handle different errors differently.
-WallpaperUtil.onFileSystemError = function(e) {
- console.error(e);
-};
-
-/**
- * Write jpeg/png file data into file entry.
- * @param {FileEntry} fileEntry The file entry that going to be writen.
- * @param {ArrayBuffer} wallpaperData Data for image file.
- * @param {function=} writeCallback The callback that will be executed after
- * writing data.
- */
-WallpaperUtil.writeFile = function(fileEntry, wallpaperData, writeCallback) {
- fileEntry.createWriter(function(fileWriter) {
- var blob = new Blob([new Int8Array(wallpaperData)]);
- fileWriter.write(blob);
- if (writeCallback)
- writeCallback();
- }, WallpaperUtil.onFileSystemError);
-};
-
-/**
- * Write jpeg/png file data into syncFileSystem.
- * @param {string} wallpaperFilename The filename that going to be writen.
- * @param {ArrayBuffer} wallpaperData Data for image file.
- */
-WallpaperUtil.storeWallpaperToSyncFS = function(wallpaperFilename,
- wallpaperData) {
- var callback = function(fs) {
- fs.root.getFile(wallpaperFilename,
- {create: false},
- function() {}, // already exists
- function(e) { // not exists, create
- fs.root.getFile(wallpaperFilename, {create: true},
- function(fe) {
- WallpaperUtil.writeFile(
- fe, wallpaperData);
- },
- WallpaperUtil.onFileSystemError);
- });
- };
- WallpaperUtil.requestSyncFS(callback);
-};
-
-/**
- * Stores jpeg/png wallpaper into |localDir| in local file system.
- * @param {string} wallpaperFilename File name of wallpaper image.
- * @param {ArrayBuffer} wallpaperData The wallpaper data.
- * @param {string} saveDir The path to store wallpaper in local file system.
- */
-WallpaperUtil.storeWallpaperToLocalFS = function(wallpaperFilename,
- wallpaperData, saveDir) {
- if (!wallpaperData) {
- console.error('wallpaperData is null');
- return;
- }
- var getDirSuccess = function(dirEntry) {
- dirEntry.getFile(wallpaperFilename,
- {create: false},
- function() {}, // already exists
- function(e) { // not exists, create
- dirEntry.getFile(wallpaperFilename, {create: true},
- function(fe) {
- WallpaperUtil.writeFile(fe,
- wallpaperData);
- },
- WallpaperUtil.onFileSystemError);
- });
- };
- WallpaperUtil.requestLocalFS(function(fs) {
- fs.root.getDirectory(saveDir, {create: true}, getDirSuccess,
- WallpaperUtil.onFileSystemError);
- });
-};
-
-/**
- * Sets wallpaper from synced file system.
- * @param {string} wallpaperFilename File name used to set wallpaper.
- * @param {string} wallpaperLayout Layout used to set wallpaper.
- * @param {function=} onSuccess Callback if set successfully.
- */
-WallpaperUtil.setCustomWallpaperFromSyncFS = function(
- wallpaperFilename, wallpaperLayout, onSuccess) {
- var setWallpaperFromSyncCallback = function(fs) {
- if (!wallpaperFilename) {
- console.error('wallpaperFilename is not provided.');
- return;
- }
- if (!wallpaperLayout)
- wallpaperLayout = 'CENTER_CROPPED';
- fs.root.getFile(wallpaperFilename, {create: false}, function(fileEntry) {
- fileEntry.file(function(file) {
- var reader = new FileReader();
- reader.onloadend = function() {
- chrome.wallpaperPrivate.setCustomWallpaper(
- reader.result,
- wallpaperLayout,
- true,
- wallpaperFilename,
- function(thumbnailData) {
- // TODO(ranj): Ignore 'canceledWallpaper' error.
- if (chrome.runtime.lastError) {
- console.error(chrome.runtime.lastError.message);
- return;
- }
- WallpaperUtil.storeWallpaperToLocalFS(wallpaperFilename,
- reader.result, Constants.WallpaperDirNameEnum.ORIGINAL);
- WallpaperUtil.storeWallpaperToLocalFS(wallpaperFilename,
- reader.result, Constants.WallpaperDirNameEnum.THUMBNAIL);
- if (onSuccess)
- onSuccess();
- });
- };
- reader.readAsArrayBuffer(file);
- }, WallpaperUtil.onFileSystemError);
- }, function(e) {} // fail to read file, expected due to download delay
- );
- };
- WallpaperUtil.requestSyncFS(setWallpaperFromSyncCallback);
-};
-
-/**
- * Saves value to local storage that associates with key.
- * @param {string} key The key that associates with value.
- * @param {string} value The value to save to local storage.
- * @param {function=} opt_callback The callback on success.
- */
-WallpaperUtil.saveToLocalStorage = function(key, value, opt_callback) {
- var items = {};
- items[key] = value;
- Constants.WallpaperLocalStorage.set(items, opt_callback);
-};
-
-/**
- * Saves value to sync storage that associates with key if sync theme is
- * enabled.
- * @param {string} key The key that associates with value.
- * @param {string} value The value to save to sync storage.
- * @param {function=} opt_callback The callback on success.
- */
-WallpaperUtil.saveToSyncStorage = function(key, value, opt_callback) {
- var items = {};
- items[key] = value;
- WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
- if (syncEnabled)
- Constants.WallpaperSyncStorage.set(items, opt_callback);
- });
-};
-
-/**
- * Saves user's wallpaper infomation to local and sync storage. Note that local
- * value should be saved first.
- * @param {string} url The url address of wallpaper. For custom wallpaper, it is
- * the file name.
- * @param {string} layout The wallpaper layout.
- * @param {string} source The wallpaper source.
- */
-WallpaperUtil.saveWallpaperInfo = function(url, layout, source) {
- var wallpaperInfo = {
- url: url,
- layout: layout,
- source: source
- };
- WallpaperUtil.saveToLocalStorage(Constants.AccessLocalWallpaperInfoKey,
- wallpaperInfo, function() {
- WallpaperUtil.saveToSyncStorage(Constants.AccessSyncWallpaperInfoKey,
- wallpaperInfo);
- });
-};
-
-/**
- * Downloads resources from url. Calls onSuccess and opt_onFailure accordingly.
- * @param {string} url The url address where we should fetch resources.
- * @param {string} type The response type of XMLHttprequest.
- * @param {function} onSuccess The success callback. It must be called with
- * current XMLHttprequest object.
- * @param {function} onFailure The failure callback.
- * @param {XMLHttpRequest=} opt_xhr The XMLHttpRequest object.
- */
-WallpaperUtil.fetchURL = function(url, type, onSuccess, onFailure, opt_xhr) {
- var xhr;
- if (opt_xhr)
- xhr = opt_xhr;
- else
- xhr = new XMLHttpRequest();
-
- try {
- // Do not use loadend here to handle both success and failure case. It gets
- // complicated with abortion. Unexpected error message may show up. See
- // http://crbug.com/242581.
- xhr.addEventListener('load', function(e) {
- if (this.status == 200) {
- onSuccess(this);
- } else {
- onFailure(this.status);
- }
- });
- xhr.addEventListener('error', onFailure);
- xhr.open('GET', url, true);
- xhr.responseType = type;
- xhr.send(null);
- } catch (e) {
- onFailure();
- }
-};
-
-/**
- * Sets wallpaper to online wallpaper specified by url and layout
- * @param {string} url The url address where we should fetch resources.
- * @param {string} layout The layout of online wallpaper.
- * @param {function} onSuccess The success callback.
- * @param {function} onFailure The failure callback.
- */
-WallpaperUtil.setOnlineWallpaper = function(url, layout, onSuccess, onFailure) {
- var self = this;
- chrome.wallpaperPrivate.setWallpaperIfExists(url, layout, function(exists) {
- if (exists) {
- onSuccess();
- return;
- }
-
- self.fetchURL(url, 'arraybuffer', function(xhr) {
- if (xhr.response != null) {
- chrome.wallpaperPrivate.setWallpaper(xhr.response, layout, url,
- onSuccess);
- self.saveWallpaperInfo(url, layout,
- Constants.WallpaperSourceEnum.Online);
- } else {
- onFailure();
- }
- }, onFailure);
- });
-};
-
-/**
- * Runs chrome.test.sendMessage in test environment. Does nothing if running
- * in production environment.
- *
- * @param {string} message Test message to send.
- */
-WallpaperUtil.testSendMessage = function(message) {
- var test = chrome.test || window.top.chrome.test;
- if (test)
- test.sendMessage(message);
-};
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_categories_list.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_categories_list.js
deleted file mode 100644
index fa064a04cd3..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_categories_list.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 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.
-
-cr.define('wallpapers', function() {
- /** @const */ var List = cr.ui.List;
- /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
- /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
- /** @const */ var ListSelectionController = cr.ui.ListSelectionController;
-
- /**
- * Create a selection controller for the wallpaper categories list.
- * @param {cr.ui.ListSelectionModel} selectionModel
- * @constructor
- * @extends {cr.ui.ListSelectionController}
- */
- function WallpaperCategoriesListSelectionController(selectionModel) {
- ListSelectionController.call(this, selectionModel);
- }
-
- WallpaperCategoriesListSelectionController.prototype = {
- __proto__: ListSelectionController.prototype,
-
- /**
- * @override
- */
- getIndexBefore: function(index) {
- return this.getIndexAbove(index);
- },
-
- /**
- * @override
- */
- getIndexAfter: function(index) {
- return this.getIndexBelow(index);
- },
- };
-
- /**
- * Create a new wallpaper categories list (horizontal list).
- * @constructor
- * @extends {cr.ui.List}
- */
- var WallpaperCategoriesList = cr.ui.define('list');
-
- WallpaperCategoriesList.prototype = {
- __proto__: List.prototype,
-
- /**
- * @override
- */
- decorate: function() {
- List.prototype.decorate.call(this);
- this.selectionModel = new ListSingleSelectionModel();
- this.dataModel = new ArrayDataModel([]);
-
- // cr.ui.list calculates items in view port based on client height and
- // item height. However, categories list is displayed horizontally. So we
- // should not calculate visible items here. Sets autoExpands to true to
- // show every item in the list.
- this.autoExpands = true;
-
- var self = this;
- this.itemConstructor = function(entry) {
- var li = self.ownerDocument.createElement('li');
- cr.defineProperty(li, 'custom', cr.PropertyKind.BOOL_ATTR);
- li.custom = (entry == loadTimeData.getString('customCategoryLabel'));
- cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR);
- cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR);
- var div = self.ownerDocument.createElement('div');
- div.textContent = entry;
- li.appendChild(div);
- return li;
- };
- },
-
- /**
- * @override
- */
- createSelectionController: function(sm) {
- return new WallpaperCategoriesListSelectionController(assert(sm));
- },
- };
-
- return {
- WallpaperCategoriesList: WallpaperCategoriesList
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_directories.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_directories.js
deleted file mode 100644
index dfb9158ad1a..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_directories.js
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Wallpaper file system quota.
- */
-/** @const */ var WallpaperQuota = 1024 * 1024 * 100;
-
-var wallpaperDirectories = null;
-
-/**
- * Manages custom wallpaper related directories in wallpaper's sandboxed
- * FileSystem.
- * @constructor
- */
-function WallpaperDirectories() {
- this.wallpaperDirs_ = {};
- this.wallpaperDirs_[Constants.WallpaperDirNameEnum.ORIGINAL] = null;
- this.wallpaperDirs_[Constants.WallpaperDirNameEnum.THUMBNAIL] = null;
-}
-
-/**
- * Gets WallpaperDirectories instance. In case is hasn't been initialized, a new
- * instance is created.
- * @return {WallpaperDirectories} A WallpaperDirectories instance.
- */
-WallpaperDirectories.getInstance = function() {
- if (wallpaperDirectories === null)
- wallpaperDirectories = new WallpaperDirectories();
- return wallpaperDirectories;
-};
-
-WallpaperDirectories.prototype = {
- /**
- * Returns all custom wallpaper related directory entries.
- */
- get wallpaperDirs() {
- return this.wallpaperDirs_;
- },
-
- /**
- * If dirName is not requested, gets the directory entry of dirName and cache
- * the result. Calls success callback if success.
- * @param {string} dirName The directory name of requested directory entry.
- * @param {function(DirectoryEntry):void} success Call success with requested
- * DirectoryEntry.
- * @param {function(e):void} failure Call failure when failed to get the
- * requested directory.
- */
- requestDir: function(dirName, success, failure) {
- if (dirName != Constants.WallpaperDirNameEnum.ORIGINAL &&
- dirName != Constants.WallpaperDirNameEnum.THUMBNAIL) {
- console.error('Error: Unknow directory name.');
- var e = new Error();
- e.code = FileError.NOT_FOUND_ERR;
- failure(e);
- return;
- }
- var self = this;
- window.webkitRequestFileSystem(window.PERSISTENT, WallpaperQuota,
- function(fs) {
- fs.root.getDirectory(dirName, {create: true}, function(dirEntry) {
- self.wallpaperDirs_[dirName] = dirEntry;
- success(dirEntry);
- }, failure);
- }, failure);
- },
-
- /**
- * Gets DirectoryEntry associated with dirName from cache. If not in cache try
- * to request it from FileSystem.
- * @param {string} dirName The directory name of requested directory entry.
- * @param {function(DirectoryEntry):void} success Call success with requested
- * DirectoryEntry.
- * @param {function(e):void} failure Call failure when failed to get the
- * requested directory.
- */
- getDirectory: function(dirName, success, failure) {
- if (this.wallpaperDirs[dirName])
- success(this.wallpaperDirs[dirName]);
- else
- this.requestDir(dirName, success, failure);
- }
-};
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_images_grid.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_images_grid.js
deleted file mode 100644
index 8b5926842c1..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_images_grid.js
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('wallpapers', function() {
- /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
- /** @const */ var Grid = cr.ui.Grid;
- /** @const */ var GridItem = cr.ui.GridItem;
- /** @const */ var GridSelectionController = cr.ui.GridSelectionController;
- /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
- /** @const */ var ThumbnailSuffix = '_thumbnail.png';
- /** @const */ var ShowSpinnerDelayMs = 500;
-
- /**
- * Creates a new wallpaper thumbnails grid item.
- * @param {{wallpaperId: number, baseURL: string, layout: string,
- * source: string, availableOffline: boolean,
- * opt_dynamicURL: string, opt_author: string,
- * opt_authorWebsite: string}}
- * wallpaperInfo Wallpaper data item in WallpaperThumbnailsGrid's data
- * model.
- * @param {number} dataModelId A unique ID that this item associated to.
- * @param {object} thumbnail The thumbnail image Object associated with this
- * grid item.
- * @param {function} callback The callback function when decoration finished.
- * @constructor
- * @extends {cr.ui.GridItem}
- */
- function WallpaperThumbnailsGridItem(wallpaperInfo,
- dataModelId,
- thumbnail,
- callback) {
- var el = new GridItem(wallpaperInfo);
- el.__proto__ = WallpaperThumbnailsGridItem.prototype;
- el.dataModelId_ = dataModelId;
- el.thumbnail_ = thumbnail;
- el.callback_ = callback;
- return el;
- }
-
- WallpaperThumbnailsGridItem.prototype = {
- __proto__: GridItem.prototype,
-
- /**
- * The unique ID this thumbnail grid associated to.
- * @type {number}
- */
- dataModelId_: null,
-
- /**
- * The thumbnail image associated with the current grid item.
- */
- thumbnail_: null,
-
- /**
- * Called when the WallpaperThumbnailsGridItem is decorated or failed to
- * decorate. If the decoration contains image, the callback function should
- * be called after image loaded.
- * @type {function}
- */
- callback_: null,
-
- /** @override */
- decorate: function() {
- GridItem.prototype.decorate.call(this);
- // Removes garbage created by GridItem.
- this.innerText = '';
-
- if (this.thumbnail_) {
- this.appendChild(this.thumbnail_);
- this.callback_(this.dataModelId_);
- return;
- }
-
- var imageEl = cr.doc.createElement('img');
- imageEl.classList.add('thumbnail');
- cr.defineProperty(imageEl, 'offline', cr.PropertyKind.BOOL_ATTR);
- imageEl.offline = this.dataItem.availableOffline;
- this.appendChild(imageEl);
- var self = this;
-
- switch (this.dataItem.source) {
- case Constants.WallpaperSourceEnum.AddNew:
- this.id = 'add-new';
- this.addEventListener('click', function(e) {
- var checkbox = $('surprise-me').querySelector('#checkbox');
- if (!checkbox.classList.contains('checked'))
- $('wallpaper-selection-container').hidden = false;
- });
- // Delay dispatching the completion callback until all items have
- // begun loading and are tracked.
- window.setTimeout(this.callback_.bind(this, this.dataModelId_), 0);
- break;
- case Constants.WallpaperSourceEnum.Custom:
- var errorHandler = function(e) {
- self.callback_(self.dataModelId_);
- console.error('Can not access file system.');
- };
- var wallpaperDirectories = WallpaperDirectories.getInstance();
- var getThumbnail = function(fileName) {
- var setURL = function(fileEntry) {
- imageEl.src = fileEntry.toURL();
- self.callback_(self.dataModelId_,
- self.dataItem.wallpaperId,
- imageEl);
- };
- var fallback = function() {
- wallpaperDirectories.getDirectory(
- Constants.WallpaperDirNameEnum.ORIGINAL, function(dirEntry) {
- dirEntry.getFile(fileName, {create: false}, setURL,
- errorHandler);
- }, errorHandler);
- };
- var success = function(dirEntry) {
- dirEntry.getFile(fileName, {create: false}, setURL, fallback);
- };
- wallpaperDirectories.getDirectory(
- Constants.WallpaperDirNameEnum.THUMBNAIL, success, errorHandler);
- };
- getThumbnail(self.dataItem.baseURL);
- break;
- case Constants.WallpaperSourceEnum.OEM:
- case Constants.WallpaperSourceEnum.Online:
- chrome.wallpaperPrivate.getThumbnail(this.dataItem.baseURL,
- this.dataItem.source,
- function(data) {
- if (data) {
- var blob = new Blob([new Int8Array(data)],
- {'type': 'image\/png'});
- imageEl.src = window.URL.createObjectURL(blob);
- imageEl.addEventListener('load', function(e) {
- self.callback_(self.dataModelId_,
- self.dataItem.wallpaperId,
- imageEl);
- window.URL.revokeObjectURL(this.src);
- });
- } else if (self.dataItem.source ==
- Constants.WallpaperSourceEnum.Online) {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', self.dataItem.baseURL + ThumbnailSuffix, true);
- xhr.responseType = 'arraybuffer';
- xhr.send(null);
- xhr.addEventListener('load', function(e) {
- if (xhr.status === 200) {
- chrome.wallpaperPrivate.saveThumbnail(self.dataItem.baseURL,
- xhr.response);
- var blob = new Blob([new Int8Array(xhr.response)],
- {'type' : 'image\/png'});
- imageEl.src = window.URL.createObjectURL(blob);
- // TODO(bshe): We currently use empty div to reserve space for
- // thumbnail. Use a placeholder like "loading" image may
- // better.
- imageEl.addEventListener('load', function(e) {
- self.callback_(self.dataModelId_,
- self.dataItem.wallpaperId,
- this);
- window.URL.revokeObjectURL(this.src);
- });
- } else {
- self.callback_(self.dataModelId_);
- }
- });
- }
- });
- break;
- default:
- console.error('Unsupported image source.');
- // Delay dispatching the completion callback until all items have
- // begun loading and are tracked.
- window.setTimeout(this.callback_.bind(this, this.dataModelId_), 0);
- }
- },
- };
-
- /**
- * Creates a selection controller that wraps selection on grid ends
- * and translates Enter presses into 'activate' events.
- * @param {cr.ui.ListSelectionModel} selectionModel The selection model to
- * interact with.
- * @param {cr.ui.Grid} grid The grid to interact with.
- * @constructor
- * @extends {cr.ui.GridSelectionController}
- */
- function WallpaperThumbnailsGridSelectionController(selectionModel, grid) {
- GridSelectionController.call(this, selectionModel, grid);
- }
-
- WallpaperThumbnailsGridSelectionController.prototype = {
- __proto__: GridSelectionController.prototype,
-
- /** @override */
- getIndexBefore: function(index) {
- var result =
- GridSelectionController.prototype.getIndexBefore.call(this, index);
- return result == -1 ? this.getLastIndex() : result;
- },
-
- /** @override */
- getIndexAfter: function(index) {
- var result =
- GridSelectionController.prototype.getIndexAfter.call(this, index);
- return result == -1 ? this.getFirstIndex() : result;
- },
-
- /** @override */
- handleKeyDown: function(e) {
- if (e.keyIdentifier == 'Enter')
- cr.dispatchSimpleEvent(this.grid_, 'activate');
- else
- GridSelectionController.prototype.handleKeyDown.call(this, e);
- },
- };
-
- /**
- * Creates a new user images grid element.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {cr.ui.Grid}
- */
- var WallpaperThumbnailsGrid = cr.ui.define('grid');
-
- WallpaperThumbnailsGrid.prototype = {
- __proto__: Grid.prototype,
-
- /**
- * The checkbox element.
- */
- checkmark_: undefined,
-
- /**
- * ID of spinner delay timer.
- * @private
- */
- spinnerTimeout_: 0,
-
- /**
- * The item in data model which should have a checkmark.
- * @type {{baseURL: string, dynamicURL: string, layout: string,
- * author: string, authorWebsite: string,
- * availableOffline: boolean}}
- * wallpaperInfo The information of the wallpaper to be set active.
- */
- activeItem_: undefined,
- set activeItem(activeItem) {
- if (this.activeItem_ != activeItem) {
- this.activeItem_ = activeItem;
- this.updateActiveThumb_();
- }
- },
-
- get activeItem() {
- return this.activeItem_;
- },
-
- /**
- * A unique ID that assigned to each set dataModel operation. Note that this
- * id wont increase if the new dataModel is null or empty.
- */
- dataModelId_: 0,
-
- /**
- * The number of items that need to be generated after a new dataModel is
- * set.
- */
- pendingItems_: 0,
-
- /**
- * Maintains all grid items' thumbnail images for quickly switching between
- * different categories.
- */
- thumbnailList_: undefined,
-
- /** @override */
- set dataModel(dataModel) {
- if (this.dataModel_ == dataModel)
- return;
-
- if (dataModel && dataModel.length != 0) {
- this.dataModelId_++;
- // Clears old pending items. The new pending items will be counted when
- // item is constructed in function itemConstructor below.
- this.pendingItems_ = 0;
-
- this.style.visibility = 'hidden';
- // If spinner is hidden, schedule to show the spinner after
- // ShowSpinnerDelayMs delay. Otherwise, keep it spinning.
- if ($('spinner-container').hidden) {
- this.spinnerTimeout_ = window.setTimeout(function() {
- $('spinner-container').hidden = false;
- }, ShowSpinnerDelayMs);
- }
- } else {
- // Sets dataModel to null should hide spinner immediately.
- $('spinner-container').hidden = true;
- }
-
- var parentSetter = cr.ui.Grid.prototype.__lookupSetter__('dataModel');
- parentSetter.call(this, dataModel);
- },
-
- get dataModel() {
- return this.dataModel_;
- },
-
- /** @override */
- createSelectionController: function(sm) {
- return new WallpaperThumbnailsGridSelectionController(sm, this);
- },
-
- /**
- * Check if new thumbnail grid finished loading. This reduces the count of
- * remaining items to be loaded and when 0, shows the thumbnail grid. Note
- * it does not reduce the count on a previous |dataModelId|.
- * @param {number} dataModelId A unique ID that a thumbnail item is
- * associated to.
- * @param {number} opt_wallpaperId The unique wallpaper ID that associated
- * with this thumbnail gird item.
- * @param {object} opt_thumbnail The thumbnail image that associated with
- * the opt_wallpaperId.
- */
- pendingItemComplete: function(dataModelId,
- opt_wallpaperId,
- opt_thumbnail) {
- if (dataModelId != this.dataModelId_)
- return;
- this.pendingItems_--;
- if (opt_wallpaperId != null)
- this.thumbnailList_[opt_wallpaperId] = opt_thumbnail;
- if (this.pendingItems_ == 0) {
- this.style.visibility = 'visible';
- window.clearTimeout(this.spinnerTimeout_);
- this.spinnerTimeout_ = 0;
- $('spinner-container').hidden = true;
- }
- },
-
- /** @override */
- decorate: function() {
- Grid.prototype.decorate.call(this);
- // checkmark_ needs to be initialized before set data model. Otherwise, we
- // may try to access checkmark before initialization in
- // updateActiveThumb_().
- this.checkmark_ = cr.doc.createElement('div');
- this.checkmark_.classList.add('check');
- this.dataModel = new ArrayDataModel([]);
- this.thumbnailList_ = new ArrayDataModel([]);
- var self = this;
- this.itemConstructor = function(value) {
- var dataModelId = self.dataModelId_;
- self.pendingItems_++;
- return WallpaperThumbnailsGridItem(value, dataModelId,
- (value.wallpaperId == null) ?
- null : self.thumbnailList_[value.wallpaperId],
- self.pendingItemComplete.bind(self));
- };
- this.selectionModel = new ListSingleSelectionModel();
- this.inProgramSelection_ = false;
- },
-
- /**
- * Should only be queried from the 'change' event listener, true if the
- * change event was triggered by a programmatical selection change.
- * @type {boolean}
- */
- get inProgramSelection() {
- return this.inProgramSelection_;
- },
-
- /**
- * Set index to the image selected.
- * @type {number} index The index of selected image.
- */
- set selectedItemIndex(index) {
- this.inProgramSelection_ = true;
- this.selectionModel.selectedIndex = index;
- this.inProgramSelection_ = false;
- },
-
- /**
- * The selected item.
- * @type {!Object} Wallpaper information inserted into the data model.
- */
- get selectedItem() {
- var index = this.selectionModel.selectedIndex;
- return index != -1 ? this.dataModel.item(index) : null;
- },
- set selectedItem(selectedItem) {
- var index = this.dataModel.indexOf(selectedItem);
- this.inProgramSelection_ = true;
- this.selectionModel.leadIndex = index;
- this.selectionModel.selectedIndex = index;
- this.inProgramSelection_ = false;
- },
-
- /**
- * Forces re-display, size re-calculation and focuses grid.
- */
- updateAndFocus: function() {
- // Recalculate the measured item size.
- this.measured_ = null;
- this.columns = 0;
- this.redraw();
- this.focus();
- },
-
- /**
- * Shows a checkmark on the active thumbnail and clears previous active one
- * if any. Note if wallpaper was not set successfully, checkmark should not
- * show on that thumbnail.
- */
- updateActiveThumb_: function() {
- var selectedGridItem = this.getListItem(this.activeItem_);
- if (this.checkmark_.parentNode &&
- this.checkmark_.parentNode == selectedGridItem) {
- return;
- }
-
- // Clears previous checkmark.
- if (this.checkmark_.parentNode)
- this.checkmark_.parentNode.removeChild(this.checkmark_);
-
- if (!selectedGridItem)
- return;
- selectedGridItem.appendChild(this.checkmark_);
- },
-
- /**
- * Redraws the viewport.
- */
- redraw: function() {
- Grid.prototype.redraw.call(this);
- // The active thumbnail maybe deleted in the above redraw(). Sets it again
- // to make sure checkmark shows correctly.
- this.updateActiveThumb_();
- }
- };
-
- return {
- WallpaperThumbnailsGrid: WallpaperThumbnailsGrid
- };
-});
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
deleted file mode 100644
index 759b33b7095..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
+++ /dev/null
@@ -1,1130 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * WallpaperManager constructor.
- *
- * WallpaperManager objects encapsulate the functionality of the wallpaper
- * manager extension.
- *
- * @constructor
- * @param {HTMLElement} dialogDom The DOM node containing the prototypical
- * extension UI.
- */
-
-function WallpaperManager(dialogDom) {
- this.dialogDom_ = dialogDom;
- this.document_ = dialogDom.ownerDocument;
- this.enableOnlineWallpaper_ = loadTimeData.valueExists('manifestBaseURL');
- this.selectedItem_ = null;
- this.progressManager_ = new ProgressManager();
- this.customWallpaperData_ = null;
- this.currentWallpaper_ = null;
- this.wallpaperRequest_ = null;
- this.wallpaperDirs_ = WallpaperDirectories.getInstance();
- this.preManifestDomInit_();
- this.fetchManifest_();
-}
-
-// Anonymous 'namespace'.
-// TODO(bshe): Get rid of anonymous namespace.
-(function() {
-
- /**
- * URL of the learn more page for wallpaper picker.
- */
- /** @const */ var LearnMoreURL =
- 'https://support.google.com/chromebook/?p=wallpaper_fileerror&hl=' +
- navigator.language;
-
- /**
- * Index of the All category. It is the first category in wallpaper picker.
- */
- /** @const */ var AllCategoryIndex = 0;
-
- /**
- * Index offset of categories parsed from manifest. The All category is added
- * before them. So the offset is 1.
- */
- /** @const */ var OnlineCategoriesOffset = 1;
-
- /**
- * Returns a translated string.
- *
- * Wrapper function to make dealing with translated strings more concise.
- *
- * @param {string} id The id of the string to return.
- * @return {string} The translated string.
- */
- function str(id) {
- return loadTimeData.getString(id);
- }
-
- /**
- * Returns the base name for |file_path|.
- * @param {string} file_path The path of the file.
- * @return {string} The base name of the file.
- */
- function getBaseName(file_path) {
- return file_path.substring(file_path.lastIndexOf('/') + 1);
- }
-
- /**
- * Retruns the current selected layout.
- * @return {string} The selected layout.
- */
- function getSelectedLayout() {
- var setWallpaperLayout = $('set-wallpaper-layout');
- return setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value;
- }
-
- /**
- * Loads translated strings.
- */
- WallpaperManager.initStrings = function(callback) {
- chrome.wallpaperPrivate.getStrings(function(strings) {
- loadTimeData.data = strings;
- if (callback)
- callback();
- });
- };
-
- /**
- * Requests wallpaper manifest file from server.
- */
- WallpaperManager.prototype.fetchManifest_ = function() {
- var locale = navigator.language;
- if (!this.enableOnlineWallpaper_) {
- this.postManifestDomInit_();
- return;
- }
-
- var urls = [
- str('manifestBaseURL') + locale + '.json',
- // Fallback url. Use 'en' locale by default.
- str('manifestBaseURL') + 'en.json'];
-
- var asyncFetchManifestFromUrls = function(urls, func, successCallback,
- failureCallback) {
- var index = 0;
- var loop = {
- next: function() {
- if (index < urls.length) {
- func(loop, urls[index]);
- index++;
- } else {
- failureCallback();
- }
- },
-
- success: function(response) {
- successCallback(response);
- },
-
- failure: function() {
- failureCallback();
- }
- };
- loop.next();
- };
-
- var fetchManifestAsync = function(loop, url) {
- var xhr = new XMLHttpRequest();
- try {
- xhr.addEventListener('loadend', function(e) {
- if (this.status == 200 && this.responseText != null) {
- try {
- var manifest = JSON.parse(this.responseText);
- loop.success(manifest);
- } catch (e) {
- loop.failure();
- }
- } else {
- loop.next();
- }
- });
- xhr.open('GET', url, true);
- xhr.send(null);
- } catch (e) {
- loop.failure();
- }
- };
-
- if (navigator.onLine) {
- asyncFetchManifestFromUrls(urls, fetchManifestAsync,
- this.onLoadManifestSuccess_.bind(this),
- this.onLoadManifestFailed_.bind(this));
- } else {
- // If device is offline, fetches manifest from local storage.
- // TODO(bshe): Always loading the offline manifest first and replacing
- // with the online one when available.
- this.onLoadManifestFailed_();
- }
- };
-
- /**
- * Shows error message in a centered dialog.
- * @private
- * @param {string} errroMessage The string to show in the error dialog.
- */
- WallpaperManager.prototype.showError_ = function(errorMessage) {
- document.querySelector('.error-message').textContent = errorMessage;
- $('error-container').hidden = false;
- };
-
- /**
- * Sets manifest loaded from server. Called after manifest is successfully
- * loaded.
- * @param {object} manifest The parsed manifest file.
- */
- WallpaperManager.prototype.onLoadManifestSuccess_ = function(manifest) {
- this.manifest_ = manifest;
- WallpaperUtil.saveToLocalStorage(Constants.AccessLocalManifestKey,
- manifest);
- this.postManifestDomInit_();
- };
-
- // Sets manifest to previously saved object if any and shows connection error.
- // Called after manifest failed to load.
- WallpaperManager.prototype.onLoadManifestFailed_ = function() {
- var accessManifestKey = Constants.AccessLocalManifestKey;
- var self = this;
- Constants.WallpaperLocalStorage.get(accessManifestKey, function(items) {
- self.manifest_ = items[accessManifestKey] ?
- items[accessManifestKey] : null;
- self.showError_(str('connectionFailed'));
- self.postManifestDomInit_();
- $('wallpaper-grid').classList.add('image-picker-offline');
- });
- };
-
- /**
- * Toggle surprise me feature of wallpaper picker. It fires an storage
- * onChanged event. Event handler for that event is in event_page.js.
- * @private
- */
- WallpaperManager.prototype.toggleSurpriseMe_ = function() {
- var self = this;
- var checkbox = $('surprise-me').querySelector('#checkbox');
- var shouldEnable = !checkbox.classList.contains('checked');
- var onSuccess = function() {
- if (chrome.runtime.lastError == null) {
- if (shouldEnable) {
- self.document_.body.removeAttribute('surprise-me-disabled');
- checkbox.classList.add('checked');
- // Hides the wallpaper set by message if there is any.
- $('wallpaper-set-by-message').textContent = '';
- } else {
- // Unchecking the "Surprise me" checkbox falls back to the previous
- // wallpaper before "Surprise me" was turned on.
- if (self.wallpaperGrid_.activeItem) {
- self.setSelectedWallpaper_(self.wallpaperGrid_.activeItem);
- self.onWallpaperChanged_(self.wallpaperGrid_.activeItem,
- self.currentWallpaper_);
- }
- checkbox.classList.remove('checked');
- self.document_.body.setAttribute('surprise-me-disabled', '');
- }
- $('categories-list').disabled = shouldEnable;
- $('wallpaper-grid').disabled = shouldEnable;
- } else {
- // TODO(bshe): show error message to user.
- console.error('Failed to save surprise me option to chrome storage.');
- }
- };
-
- // To prevent the onChanged event being fired twice, we only save the value
- // to sync storage if the sync theme is enabled, otherwise save it to local
- // storage.
- WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
- if (syncEnabled)
- WallpaperUtil.saveToSyncStorage(
- Constants.AccessSyncSurpriseMeEnabledKey, shouldEnable, onSuccess);
- else
- WallpaperUtil.saveToLocalStorage(
- Constants.AccessLocalSurpriseMeEnabledKey, shouldEnable, onSuccess);
- });
- };
-
- /**
- * One-time initialization of various DOM nodes. Fetching manifest may take a
- * long time due to slow connection. Dom nodes that do not depend on manifest
- * should be initialized here to unblock from manifest fetching.
- */
- WallpaperManager.prototype.preManifestDomInit_ = function() {
- $('window-close-button').addEventListener('click', function() {
- window.close();
- });
- this.document_.defaultView.addEventListener(
- 'resize', this.onResize_.bind(this));
- this.document_.defaultView.addEventListener(
- 'keydown', this.onKeyDown_.bind(this));
- $('learn-more').href = LearnMoreURL;
- $('close-error').addEventListener('click', function() {
- $('error-container').hidden = true;
- });
- $('close-wallpaper-selection').addEventListener('click', function() {
- $('wallpaper-selection-container').hidden = true;
- $('set-wallpaper-layout').disabled = true;
- });
- };
-
- /**
- * One-time initialization of various DOM nodes. Dom nodes that do depend on
- * manifest should be initialized here.
- */
- WallpaperManager.prototype.postManifestDomInit_ = function() {
- i18nTemplate.process(this.document_, loadTimeData);
- this.initCategoriesList_();
- this.initThumbnailsGrid_();
- this.presetCategory_();
-
- $('file-selector').addEventListener(
- 'change', this.onFileSelectorChanged_.bind(this));
- $('set-wallpaper-layout').addEventListener(
- 'change', this.onWallpaperLayoutChanged_.bind(this));
-
- if (loadTimeData.valueExists('wallpaperAppName')) {
- $('wallpaper-set-by-message').textContent = loadTimeData.getStringF(
- 'currentWallpaperSetByMessage', str('wallpaperAppName'));
- }
-
- if (this.enableOnlineWallpaper_) {
- var self = this;
- self.document_.body.setAttribute('surprise-me-disabled', '');
- $('surprise-me').hidden = false;
- $('surprise-me').addEventListener('click',
- this.toggleSurpriseMe_.bind(this));
- var onSurpriseMeEnabled = function() {
- $('surprise-me').querySelector('#checkbox').classList.add('checked');
- $('categories-list').disabled = true;
- $('wallpaper-grid').disabled = true;
- self.document_.body.removeAttribute('surprise-me-disabled');
- };
-
- WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
- // Surprise me has been moved from local to sync storage, prefer
- // values from sync, but if unset check local and update synced pref
- // if applicable.
- if (syncEnabled) {
- Constants.WallpaperSyncStorage.get(
- Constants.AccessSyncSurpriseMeEnabledKey, function(items) {
- if (items.hasOwnProperty(
- Constants.AccessSyncSurpriseMeEnabledKey)) {
- if (items[Constants.AccessSyncSurpriseMeEnabledKey]) {
- onSurpriseMeEnabled();
- }
- } else {
- Constants.WallpaperLocalStorage.get(
- Constants.AccessLocalSurpriseMeEnabledKey, function(items) {
- if (items.hasOwnProperty(
- Constants.AccessLocalSurpriseMeEnabledKey)) {
- WallpaperUtil.saveToSyncStorage(
- Constants.AccessSyncSurpriseMeEnabledKey,
- items[Constants.AccessLocalSurpriseMeEnabledKey]);
- if (items[Constants.AccessLocalSurpriseMeEnabledKey]) {
- onSurpriseMeEnabled();
- }
- }
- });
- }
- });
- } else {
- Constants.WallpaperLocalStorage.get(
- Constants.AccessLocalSurpriseMeEnabledKey, function(items) {
- if (items.hasOwnProperty(
- Constants.AccessLocalSurpriseMeEnabledKey)) {
- if (items[Constants.AccessLocalSurpriseMeEnabledKey]) {
- onSurpriseMeEnabled();
- }
- }
- });
- }
- });
-
- window.addEventListener('offline', function() {
- chrome.wallpaperPrivate.getOfflineWallpaperList(function(lists) {
- if (!self.downloadedListMap_)
- self.downloadedListMap_ = {};
- for (var i = 0; i < lists.length; i++) {
- self.downloadedListMap_[lists[i]] = true;
- }
- var thumbnails = self.document_.querySelectorAll('.thumbnail');
- for (var i = 0; i < thumbnails.length; i++) {
- var thumbnail = thumbnails[i];
- var url = self.wallpaperGrid_.dataModel.item(i).baseURL;
- var fileName = getBaseName(url) + Constants.HighResolutionSuffix;
- if (self.downloadedListMap_ &&
- self.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) {
- thumbnail.offline = true;
- }
- }
- });
- $('wallpaper-grid').classList.add('image-picker-offline');
- });
- window.addEventListener('online', function() {
- self.downloadedListMap_ = null;
- $('wallpaper-grid').classList.remove('image-picker-offline');
- });
- }
-
- this.onResize_();
- this.initContextMenuAndCommand_();
- WallpaperUtil.testSendMessage('launched');
- };
-
- /**
- * One-time initialization of context menu and command.
- */
- WallpaperManager.prototype.initContextMenuAndCommand_ = function() {
- this.wallpaperContextMenu_ = $('wallpaper-context-menu');
- cr.ui.Menu.decorate(this.wallpaperContextMenu_);
- cr.ui.contextMenuHandler.setContextMenu(this.wallpaperGrid_,
- this.wallpaperContextMenu_);
- var commands = this.dialogDom_.querySelectorAll('command');
- for (var i = 0; i < commands.length; i++)
- cr.ui.Command.decorate(commands[i]);
-
- var doc = this.document_;
- doc.addEventListener('command', this.onCommand_.bind(this));
- doc.addEventListener('canExecute', this.onCommandCanExecute_.bind(this));
- };
-
- /**
- * Handles a command being executed.
- * @param {Event} event A command event.
- */
- WallpaperManager.prototype.onCommand_ = function(event) {
- if (event.command.id == 'delete') {
- var wallpaperGrid = this.wallpaperGrid_;
- var selectedIndex = wallpaperGrid.selectionModel.selectedIndex;
- var item = wallpaperGrid.dataModel.item(selectedIndex);
- if (!item || item.source != Constants.WallpaperSourceEnum.Custom)
- return;
- this.removeCustomWallpaper(item.baseURL);
- wallpaperGrid.dataModel.splice(selectedIndex, 1);
- // Calculate the number of remaining custom wallpapers. The add new button
- // in data model needs to be excluded.
- var customWallpaperCount = wallpaperGrid.dataModel.length - 1;
- if (customWallpaperCount == 0) {
- // Active custom wallpaper is also copied in chronos data dir. It needs
- // to be deleted.
- chrome.wallpaperPrivate.resetWallpaper();
- this.onWallpaperChanged_(null, null);
- WallpaperUtil.saveWallpaperInfo('', '',
- Constants.WallpaperSourceEnum.Default);
- } else {
- selectedIndex = Math.min(selectedIndex, customWallpaperCount - 1);
- wallpaperGrid.selectionModel.selectedIndex = selectedIndex;
- }
- event.cancelBubble = true;
- }
- };
-
- /**
- * Decides if a command can be executed on current target.
- * @param {Event} event A command event.
- */
- WallpaperManager.prototype.onCommandCanExecute_ = function(event) {
- switch (event.command.id) {
- case 'delete':
- var wallpaperGrid = this.wallpaperGrid_;
- var selectedIndex = wallpaperGrid.selectionModel.selectedIndex;
- var item = wallpaperGrid.dataModel.item(selectedIndex);
- if (selectedIndex != this.wallpaperGrid_.dataModel.length - 1 &&
- item && item.source == Constants.WallpaperSourceEnum.Custom) {
- event.canExecute = true;
- break;
- }
- default:
- event.canExecute = false;
- }
- };
-
- /**
- * Preset to the category which contains current wallpaper.
- */
- WallpaperManager.prototype.presetCategory_ = function() {
- this.currentWallpaper_ = str('currentWallpaper');
- // The currentWallpaper_ is either a url contains HightResolutionSuffix or a
- // custom wallpaper file name converted from an integer value represent
- // time (e.g., 13006377367586070).
- if (!this.enableOnlineWallpaper_ || (this.currentWallpaper_ &&
- this.currentWallpaper_.indexOf(Constants.HighResolutionSuffix) == -1)) {
- // Custom is the last one in the categories list.
- this.categoriesList_.selectionModel.selectedIndex =
- this.categoriesList_.dataModel.length - 1;
- return;
- }
- var self = this;
- var presetCategoryInner_ = function() {
- // Selects the first category in the categories list of current
- // wallpaper as the default selected category when showing wallpaper
- // picker UI.
- var presetCategory = AllCategoryIndex;
- if (self.currentWallpaper_) {
- for (var key in self.manifest_.wallpaper_list) {
- var url = self.manifest_.wallpaper_list[key].base_url +
- Constants.HighResolutionSuffix;
- if (url.indexOf(self.currentWallpaper_) != -1 &&
- self.manifest_.wallpaper_list[key].categories.length > 0) {
- presetCategory = self.manifest_.wallpaper_list[key].categories[0] +
- OnlineCategoriesOffset;
- break;
- }
- }
- }
- self.categoriesList_.selectionModel.selectedIndex = presetCategory;
- };
- if (navigator.onLine) {
- presetCategoryInner_();
- } else {
- // If device is offline, gets the available offline wallpaper list first.
- // Wallpapers which are not in the list will display a grayscaled
- // thumbnail.
- chrome.wallpaperPrivate.getOfflineWallpaperList(function(lists) {
- if (!self.downloadedListMap_)
- self.downloadedListMap_ = {};
- for (var i = 0; i < lists.length; i++)
- self.downloadedListMap_[lists[i]] = true;
- presetCategoryInner_();
- });
- }
- };
-
- /**
- * Constructs the thumbnails grid.
- */
- WallpaperManager.prototype.initThumbnailsGrid_ = function() {
- this.wallpaperGrid_ = $('wallpaper-grid');
- wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_);
-
- this.wallpaperGrid_.addEventListener('change', this.onChange_.bind(this));
- this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this));
- };
-
- /**
- * Handles change event dispatched by wallpaper grid.
- */
- WallpaperManager.prototype.onChange_ = function() {
- // splice may dispatch a change event because the position of selected
- // element changing. But the actual selected element may not change after
- // splice. Check if the new selected element equals to the previous selected
- // element before continuing. Otherwise, wallpaper may reset to previous one
- // as described in http://crbug.com/229036.
- if (this.selectedItem_ == this.wallpaperGrid_.selectedItem)
- return;
- this.selectedItem_ = this.wallpaperGrid_.selectedItem;
- this.onSelectedItemChanged_();
- };
-
- /**
- * Closes window if no pending wallpaper request.
- */
- WallpaperManager.prototype.onClose_ = function() {
- if (this.wallpaperRequest_) {
- this.wallpaperRequest_.addEventListener('loadend', function() {
- // Close window on wallpaper loading finished.
- window.close();
- });
- } else {
- window.close();
- }
- };
-
- /**
- * Moves the check mark to |activeItem| and hides the wallpaper set by third
- * party message if any. Called when wallpaper changed successfully.
- * @param {?Object} activeItem The active item in WallpaperThumbnailsGrid's
- * data model.
- * @param {?string} currentWallpaperURL The URL or filename of current
- * wallpaper.
- */
- WallpaperManager.prototype.onWallpaperChanged_ = function(
- activeItem, currentWallpaperURL) {
- this.wallpaperGrid_.activeItem = activeItem;
- this.currentWallpaper_ = currentWallpaperURL;
- // Hides the wallpaper set by message.
- $('wallpaper-set-by-message').textContent = '';
- };
-
- /**
- * Sets wallpaper to the corresponding wallpaper of selected thumbnail.
- * @param {{baseURL: string, layout: string, source: string,
- * availableOffline: boolean, opt_dynamicURL: string,
- * opt_author: string, opt_authorWebsite: string}}
- * selectedItem the selected item in WallpaperThumbnailsGrid's data
- * model.
- */
- WallpaperManager.prototype.setSelectedWallpaper_ = function(selectedItem) {
- var self = this;
- switch (selectedItem.source) {
- case Constants.WallpaperSourceEnum.Custom:
- var errorHandler = this.onFileSystemError_.bind(this);
- var success = function(dirEntry) {
- dirEntry.getFile(selectedItem.baseURL, {create: false},
- function(fileEntry) {
- fileEntry.file(function(file) {
- var reader = new FileReader();
- reader.readAsArrayBuffer(file);
- reader.addEventListener('error', errorHandler);
- reader.addEventListener('load', function(e) {
- self.setCustomWallpaper(e.target.result, selectedItem.layout,
- false, selectedItem.baseURL,
- function(thumbnailData) {
- self.onWallpaperChanged_(selectedItem,
- selectedItem.baseURL, thumbnailData);
- WallpaperUtil.storeWallpaperToSyncFS(
- selectedItem.baseURL, e.target.result);
- WallpaperUtil.storeWallpaperToSyncFS(
- selectedItem.baseURL +
- Constants.CustomWallpaperThumbnailSuffix,
- thumbnailData);
- },
- errorHandler);
- });
- }, errorHandler);
- }, errorHandler);
- };
- this.wallpaperDirs_.getDirectory(
- Constants.WallpaperDirNameEnum.ORIGINAL, success, errorHandler);
- break;
- case Constants.WallpaperSourceEnum.OEM:
- // Resets back to default wallpaper.
- chrome.wallpaperPrivate.resetWallpaper();
- this.onWallpaperChanged_(selectedItem, selectedItem.baseURL);
- WallpaperUtil.saveWallpaperInfo(wallpaperURL, selectedItem.layout,
- selectedItem.source);
- break;
- case Constants.WallpaperSourceEnum.Online:
- var wallpaperURL = selectedItem.baseURL +
- Constants.HighResolutionSuffix;
- var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem);
-
- chrome.wallpaperPrivate.setWallpaperIfExists(wallpaperURL,
- selectedItem.layout,
- function(exists) {
- if (exists) {
- self.onWallpaperChanged_(selectedItem, wallpaperURL);
- WallpaperUtil.saveWallpaperInfo(wallpaperURL, selectedItem.layout,
- selectedItem.source);
- return;
- }
-
- // Falls back to request wallpaper from server.
- if (self.wallpaperRequest_)
- self.wallpaperRequest_.abort();
-
- self.wallpaperRequest_ = new XMLHttpRequest();
- self.progressManager_.reset(self.wallpaperRequest_, selectedGridItem);
-
- var onSuccess = function(xhr) {
- var image = xhr.response;
- chrome.wallpaperPrivate.setWallpaper(image, selectedItem.layout,
- wallpaperURL,
- function() {
- self.progressManager_.hideProgressBar(selectedGridItem);
-
- if (chrome.runtime.lastError != undefined &&
- chrome.runtime.lastError.message !=
- str('canceledWallpaper')) {
- self.showError_(chrome.runtime.lastError.message);
- } else {
- self.onWallpaperChanged_(selectedItem, wallpaperURL);
- }
- });
- WallpaperUtil.saveWallpaperInfo(wallpaperURL, selectedItem.layout,
- selectedItem.source);
- self.wallpaperRequest_ = null;
- };
- var onFailure = function(status) {
- self.progressManager_.hideProgressBar(selectedGridItem);
- self.showError_(str('downloadFailed'));
- self.wallpaperRequest_ = null;
- };
- WallpaperUtil.fetchURL(wallpaperURL, 'arraybuffer', onSuccess,
- onFailure, self.wallpaperRequest_);
- });
- break;
- default:
- console.error('Unsupported wallpaper source.');
- }
- };
-
- /*
- * Removes the oldest custom wallpaper. If the oldest one is set as current
- * wallpaper, removes the second oldest one to free some space. This should
- * only be called when exceeding wallpaper quota.
- */
- WallpaperManager.prototype.removeOldestWallpaper_ = function() {
- // Custom wallpapers should already sorted when put to the data model. The
- // last element is the add new button, need to exclude it as well.
- var oldestIndex = this.wallpaperGrid_.dataModel.length - 2;
- var item = this.wallpaperGrid_.dataModel.item(oldestIndex);
- if (!item || item.source != Constants.WallpaperSourceEnum.Custom)
- return;
- if (item.baseURL == this.currentWallpaper_)
- item = this.wallpaperGrid_.dataModel.item(--oldestIndex);
- if (item) {
- this.removeCustomWallpaper(item.baseURL);
- this.wallpaperGrid_.dataModel.splice(oldestIndex, 1);
- }
- };
-
- /*
- * Shows an error message to user and log the failed reason in console.
- */
- WallpaperManager.prototype.onFileSystemError_ = function(e) {
- var msg = '';
- switch (e.code) {
- case FileError.QUOTA_EXCEEDED_ERR:
- msg = 'QUOTA_EXCEEDED_ERR';
- // Instead of simply remove oldest wallpaper, we should consider a
- // better way to handle this situation. See crbug.com/180890.
- this.removeOldestWallpaper_();
- break;
- case FileError.NOT_FOUND_ERR:
- msg = 'NOT_FOUND_ERR';
- break;
- case FileError.SECURITY_ERR:
- msg = 'SECURITY_ERR';
- break;
- case FileError.INVALID_MODIFICATION_ERR:
- msg = 'INVALID_MODIFICATION_ERR';
- break;
- case FileError.INVALID_STATE_ERR:
- msg = 'INVALID_STATE_ERR';
- break;
- default:
- msg = 'Unknown Error';
- break;
- }
- console.error('Error: ' + msg);
- this.showError_(str('accessFileFailure'));
- };
-
- /**
- * Handles changing of selectedItem in wallpaper manager.
- */
- WallpaperManager.prototype.onSelectedItemChanged_ = function() {
- this.setWallpaperAttribution_(this.selectedItem_);
-
- if (!this.selectedItem_ || this.selectedItem_.source == 'ADDNEW')
- return;
-
- if (this.selectedItem_.baseURL && !this.wallpaperGrid_.inProgramSelection) {
- if (this.selectedItem_.source == Constants.WallpaperSourceEnum.Custom) {
- var items = {};
- var key = this.selectedItem_.baseURL;
- var self = this;
- Constants.WallpaperLocalStorage.get(key, function(items) {
- self.selectedItem_.layout =
- items[key] ? items[key] : 'CENTER_CROPPED';
- self.setSelectedWallpaper_(self.selectedItem_);
- });
- } else {
- this.setSelectedWallpaper_(this.selectedItem_);
- }
- }
- };
-
- /**
- * Set attributions of wallpaper with given URL. If URL is not valid, clear
- * the attributions.
- * @param {{baseURL: string, dynamicURL: string, layout: string,
- * author: string, authorWebsite: string, availableOffline: boolean}}
- * selectedItem selected wallpaper item in grid.
- * @private
- */
- WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) {
- // Only online wallpapers have author and website attributes. All other type
- // of wallpapers should not show attributions.
- if (selectedItem &&
- selectedItem.source == Constants.WallpaperSourceEnum.Online) {
- $('author-name').textContent = selectedItem.author;
- $('author-website').textContent = $('author-website').href =
- selectedItem.authorWebsite;
- chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL,
- selectedItem.source,
- function(data) {
- var img = $('attribute-image');
- if (data) {
- var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'});
- img.src = window.URL.createObjectURL(blob);
- img.addEventListener('load', function(e) {
- window.URL.revokeObjectURL(this.src);
- });
- } else {
- img.src = '';
- }
- });
- $('wallpaper-attribute').hidden = false;
- $('attribute-image').hidden = false;
- return;
- }
- $('wallpaper-attribute').hidden = true;
- $('attribute-image').hidden = true;
- $('author-name').textContent = '';
- $('author-website').textContent = $('author-website').href = '';
- $('attribute-image').src = '';
- };
-
- /**
- * Resize thumbnails grid and categories list to fit the new window size.
- */
- WallpaperManager.prototype.onResize_ = function() {
- this.wallpaperGrid_.redraw();
- this.categoriesList_.redraw();
- };
-
- /**
- * Close the last opened overlay or app window on pressing the Escape key.
- * @param {Event} event A keydown event.
- */
- WallpaperManager.prototype.onKeyDown_ = function(event) {
- if (event.keyCode == 27) {
- // The last opened overlay coincides with the first match of querySelector
- // because the Error Container is declared in the DOM before the Wallpaper
- // Selection Container.
- // TODO(bshe): Make the overlay selection not dependent on the DOM.
- var closeButtonSelector = '.overlay-container:not([hidden]) .close';
- var closeButton = this.document_.querySelector(closeButtonSelector);
- if (closeButton) {
- closeButton.click();
- event.preventDefault();
- } else {
- this.onClose_();
- }
- }
- };
-
- /**
- * Constructs the categories list.
- */
- WallpaperManager.prototype.initCategoriesList_ = function() {
- this.categoriesList_ = $('categories-list');
- wallpapers.WallpaperCategoriesList.decorate(this.categoriesList_);
-
- this.categoriesList_.selectionModel.addEventListener(
- 'change', this.onCategoriesChange_.bind(this));
-
- if (this.enableOnlineWallpaper_ && this.manifest_) {
- // Adds all category as first category.
- this.categoriesList_.dataModel.push(str('allCategoryLabel'));
- for (var key in this.manifest_.categories) {
- this.categoriesList_.dataModel.push(this.manifest_.categories[key]);
- }
- }
- // Adds custom category as last category.
- this.categoriesList_.dataModel.push(str('customCategoryLabel'));
- };
-
- /**
- * Handles the custom wallpaper which user selected from file manager. Called
- * when users select a file.
- */
- WallpaperManager.prototype.onFileSelectorChanged_ = function() {
- var files = $('file-selector').files;
- if (files.length != 1)
- console.error('More than one files are selected or no file selected');
- if (!files[0].type.match('image/jpeg') &&
- !files[0].type.match('image/png')) {
- this.showError_(str('invalidWallpaper'));
- return;
- }
- var layout = getSelectedLayout();
- var self = this;
- var errorHandler = this.onFileSystemError_.bind(this);
- var setSelectedFile = function(file, layout, fileName) {
- var saveThumbnail = function(thumbnail) {
- var success = function(dirEntry) {
- dirEntry.getFile(fileName, {create: true}, function(fileEntry) {
- fileEntry.createWriter(function(fileWriter) {
- fileWriter.onwriteend = function(e) {
- $('set-wallpaper-layout').disabled = false;
- var wallpaperInfo = {
- baseURL: fileName,
- layout: layout,
- source: Constants.WallpaperSourceEnum.Custom,
- availableOffline: true
- };
- self.wallpaperGrid_.dataModel.splice(0, 0, wallpaperInfo);
- self.wallpaperGrid_.selectedItem = wallpaperInfo;
- self.onWallpaperChanged_(wallpaperInfo, fileName);
- WallpaperUtil.saveToLocalStorage(self.currentWallpaper_,
- layout);
- };
-
- fileWriter.onerror = errorHandler;
-
- var blob = new Blob([new Int8Array(thumbnail)],
- {'type' : 'image\/jpeg'});
- fileWriter.write(blob);
- }, errorHandler);
- }, errorHandler);
- };
- self.wallpaperDirs_.getDirectory(
- Constants.WallpaperDirNameEnum.THUMBNAIL, success, errorHandler);
- };
- var onCustomWallpaperSuccess = function(thumbnailData, wallpaperData) {
- WallpaperUtil.storeWallpaperToSyncFS(fileName, wallpaperData);
- WallpaperUtil.storeWallpaperToSyncFS(
- fileName + Constants.CustomWallpaperThumbnailSuffix,
- thumbnailData);
- saveThumbnail(thumbnailData);
- };
- var success = function(dirEntry) {
- dirEntry.getFile(fileName, {create: true}, function(fileEntry) {
- fileEntry.createWriter(function(fileWriter) {
- fileWriter.addEventListener('writeend', function(e) {
- var reader = new FileReader();
- reader.readAsArrayBuffer(file);
- reader.addEventListener('error', errorHandler);
- reader.addEventListener('load', function(e) {
- self.setCustomWallpaper(e.target.result, layout, true, fileName,
- function(thumbnail) {
- onCustomWallpaperSuccess(thumbnail, e.target.result);
- },
- function() {
- self.removeCustomWallpaper(fileName);
- errorHandler();
- });
- });
- });
- fileWriter.addEventListener('error', errorHandler);
- fileWriter.write(file);
- }, errorHandler);
- }, errorHandler);
- };
- self.wallpaperDirs_.getDirectory(Constants.WallpaperDirNameEnum.ORIGINAL,
- success,
- errorHandler);
- };
- setSelectedFile(files[0], layout, new Date().getTime().toString());
- };
-
- /**
- * Removes wallpaper and thumbnail with fileName from FileSystem.
- * @param {string} fileName The file name of wallpaper and thumbnail to be
- * removed.
- */
- WallpaperManager.prototype.removeCustomWallpaper = function(fileName) {
- var errorHandler = this.onFileSystemError_.bind(this);
- var self = this;
- var removeFile = function(fileName) {
- var success = function(dirEntry) {
- dirEntry.getFile(fileName, {create: false}, function(fileEntry) {
- fileEntry.remove(function() {
- WallpaperUtil.deleteWallpaperFromSyncFS(fileName);
- }, errorHandler);
- }, errorHandler);
- };
-
- // Removes copy of original.
- self.wallpaperDirs_.getDirectory(Constants.WallpaperDirNameEnum.ORIGINAL,
- success,
- errorHandler);
-
- // Removes generated thumbnail.
- self.wallpaperDirs_.getDirectory(Constants.WallpaperDirNameEnum.THUMBNAIL,
- success,
- errorHandler);
- };
- removeFile(fileName);
- };
-
- /**
- * Sets current wallpaper and generate thumbnail if generateThumbnail is true.
- * @param {ArrayBuffer} wallpaper The binary representation of wallpaper.
- * @param {string} layout The user selected wallpaper layout.
- * @param {boolean} generateThumbnail True if need to generate thumbnail.
- * @param {string} fileName The unique file name of wallpaper.
- * @param {function(thumbnail):void} success Success callback. If
- * generateThumbnail is true, the callback parameter should have the
- * generated thumbnail.
- * @param {function(e):void} failure Failure callback. Called when there is an
- * error from FileSystem.
- */
- WallpaperManager.prototype.setCustomWallpaper = function(wallpaper,
- layout,
- generateThumbnail,
- fileName,
- success,
- failure) {
- var self = this;
- var onFinished = function(opt_thumbnail) {
- if (chrome.runtime.lastError != undefined &&
- chrome.runtime.lastError.message != str('canceledWallpaper')) {
- self.showError_(chrome.runtime.lastError.message);
- $('set-wallpaper-layout').disabled = true;
- failure();
- } else {
- success(opt_thumbnail);
- // Custom wallpapers are not synced yet. If login on a different
- // computer after set a custom wallpaper, wallpaper wont change by sync.
- WallpaperUtil.saveWallpaperInfo(fileName, layout,
- Constants.WallpaperSourceEnum.Custom);
- }
- };
-
- chrome.wallpaperPrivate.setCustomWallpaper(wallpaper, layout,
- generateThumbnail,
- fileName, onFinished);
- };
-
- /**
- * Handles the layout setting change of custom wallpaper.
- */
- WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() {
- var layout = getSelectedLayout();
- var self = this;
- chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, function() {
- if (chrome.runtime.lastError != undefined &&
- chrome.runtime.lastError.message != str('canceledWallpaper')) {
- self.showError_(chrome.runtime.lastError.message);
- self.removeCustomWallpaper(fileName);
- $('set-wallpaper-layout').disabled = true;
- } else {
- WallpaperUtil.saveToLocalStorage(self.currentWallpaper_, layout);
- self.onWallpaperChanged_(self.wallpaperGrid_.activeItem,
- self.currentWallpaper_);
- }
- });
- };
-
- /**
- * Handles user clicking on a different category.
- */
- WallpaperManager.prototype.onCategoriesChange_ = function() {
- var categoriesList = this.categoriesList_;
- var selectedIndex = categoriesList.selectionModel.selectedIndex;
- if (selectedIndex == -1)
- return;
- var selectedListItem = categoriesList.getListItemByIndex(selectedIndex);
- var bar = $('bar');
- bar.style.left = selectedListItem.offsetLeft + 'px';
- bar.style.width = selectedListItem.offsetWidth + 'px';
-
- var wallpapersDataModel = new cr.ui.ArrayDataModel([]);
- var selectedItem = null;
- if (selectedListItem.custom) {
- this.document_.body.setAttribute('custom', '');
- var errorHandler = this.onFileSystemError_.bind(this);
- var toArray = function(list) {
- return Array.prototype.slice.call(list || [], 0);
- };
-
- var self = this;
- var processResults = function(entries) {
- for (var i = 0; i < entries.length; i++) {
- var entry = entries[i];
- var wallpaperInfo = {
- // Set wallpaperId to null to avoid duplicate thumbnail images,
- // see crbug.com/506135 for details.
- wallpaperId: null,
- baseURL: entry.name,
- // The layout will be replaced by the actual value saved in
- // local storage when requested later. Layout is not important
- // for constructing thumbnails grid, we use CENTER_CROPPED here
- // to speed up the process of constructing. So we do not need to
- // wait for fetching correct layout.
- layout: 'CENTER_CROPPED',
- source: Constants.WallpaperSourceEnum.Custom,
- availableOffline: true
- };
- wallpapersDataModel.push(wallpaperInfo);
- }
- if (loadTimeData.getBoolean('isOEMDefaultWallpaper')) {
- var oemDefaultWallpaperElement = {
- wallpaperId: null,
- baseURL: 'OemDefaultWallpaper',
- layout: 'CENTER_CROPPED',
- source: Constants.WallpaperSourceEnum.OEM,
- availableOffline: true
- };
- wallpapersDataModel.push(oemDefaultWallpaperElement);
- }
- for (var i = 0; i < wallpapersDataModel.length; i++) {
- // For custom wallpapers, the file name of |currentWallpaper_|
- // includes the first directory level (corresponding to user id hash).
- if (getBaseName(self.currentWallpaper_) ==
- wallpapersDataModel.item(i).baseURL) {
- selectedItem = wallpapersDataModel.item(i);
- }
- }
- var lastElement = {
- baseURL: '',
- layout: '',
- source: Constants.WallpaperSourceEnum.AddNew,
- availableOffline: true
- };
- wallpapersDataModel.push(lastElement);
- self.wallpaperGrid_.dataModel = wallpapersDataModel;
- if (selectedItem) {
- self.wallpaperGrid_.selectedItem = selectedItem;
- self.wallpaperGrid_.activeItem = selectedItem;
- }
- };
-
- var success = function(dirEntry) {
- var dirReader = dirEntry.createReader();
- var entries = [];
- // All of a directory's entries are not guaranteed to return in a single
- // call.
- var readEntries = function() {
- dirReader.readEntries(function(results) {
- if (!results.length) {
- processResults(entries.sort());
- } else {
- entries = entries.concat(toArray(results));
- readEntries();
- }
- }, errorHandler);
- };
- readEntries(); // Start reading dirs.
- };
- this.wallpaperDirs_.getDirectory(Constants.WallpaperDirNameEnum.ORIGINAL,
- success, errorHandler);
- } else {
- this.document_.body.removeAttribute('custom');
- // Need this check for test purpose.
- var numOnlineWallpaper = (this.enableOnlineWallpaper_ && this.manifest_) ?
- this.manifest_.wallpaper_list.length : 0;
- for (var i = 0; i < numOnlineWallpaper; i++) {
- if (selectedIndex == AllCategoryIndex ||
- this.manifest_.wallpaper_list[i].categories.indexOf(
- selectedIndex - OnlineCategoriesOffset) != -1) {
- var wallpaperInfo = {
- wallpaperId: i,
- baseURL: this.manifest_.wallpaper_list[i].base_url,
- layout: this.manifest_.wallpaper_list[i].default_layout,
- source: Constants.WallpaperSourceEnum.Online,
- availableOffline: false,
- author: this.manifest_.wallpaper_list[i].author,
- authorWebsite: this.manifest_.wallpaper_list[i].author_website,
- dynamicURL: this.manifest_.wallpaper_list[i].dynamic_url
- };
- var fileName = getBaseName(wallpaperInfo.baseURL) +
- Constants.HighResolutionSuffix;
- if (this.downloadedListMap_ &&
- this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) {
- wallpaperInfo.availableOffline = true;
- }
- wallpapersDataModel.push(wallpaperInfo);
- var url = this.manifest_.wallpaper_list[i].base_url +
- Constants.HighResolutionSuffix;
- if (url == this.currentWallpaper_) {
- selectedItem = wallpaperInfo;
- }
- }
- }
- this.wallpaperGrid_.dataModel = wallpapersDataModel;
- if (selectedItem) {
- this.wallpaperGrid_.selectedItem = selectedItem;
- this.wallpaperGrid_.activeItem = selectedItem;
- }
- }
- };
-
-})();
diff --git a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/main.html b/chromium/chrome/browser/resources/chromeos/wallpaper_manager/main.html
deleted file mode 100644
index 5888d9a166e..00000000000
--- a/chromium/chrome/browser/resources/chromeos/wallpaper_manager/main.html
+++ /dev/null
@@ -1,132 +0,0 @@
-<!doctype html>
-<!--
-------
-Copyright (c) 2013 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<html i18n-values="dir:textdirection;lang:language">
-<head>
- <meta charset="utf-8">
- <title>Wallpaper Picker</title>
- <link rel="stylesheet" href="../../../../../ui/webui/resources/css/text_defaults.css">
- <link rel="stylesheet" href="../../../../../ui/webui/resources/css/widgets.css">
- <link rel="stylesheet" href="../../../../../ui/webui/resources/css/menu.css"></link>
-
- <link rel="stylesheet" href="css/wallpaper_manager.css">
- <script src="js/main_scripts.js"></script>
- <if expr="False">
- <!-- This file has not been flattened, load individual scripts.
- Keep the list in sync with js/main_scripts.js. -->
- <script src="../../../../../ui/webui/resources/js/cr.js"></script>
- <script src="../../../../../ui/webui/resources/js/event_tracker.js"></script>
- <script src="../../../../../ui/webui/resources/js/load_time_data.js"></script>
- <script src="../../../../../ui/webui/resources/js/i18n_template_no_process.js"></script>
- <script src="../../../../../ui/webui/resources/js/util.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/touch_handler.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/list_item.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/list_selection_model.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/list_single_selection_model.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/list_selection_controller.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/list.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/grid.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/command.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/position_util.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/menu_item.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/menu.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/menu_button.js"></script>
- <script src="../../../../../ui/webui/resources/js/cr/ui/context_menu_handler.js"></script>
-
- <script src="js/constants.js"></script>
- <script src="js/util.js"></script>
- <script src="js/progress_manager.js"></script>
- <script src="js/wallpaper_directories.js"></script>
- <script src="js/wallpaper_categories_list.js"></script>
- <script src="js/wallpaper_images_grid.js"></script>
- <script src="js/wallpaper_manager.js"></script>
- <script src="js/main.js"></script>
- </if>
-</head>
-<body>
- <commands>
- <command id="delete" i18n-values="label:deleteCommandLabel"
- shortcut="U+007F"></command>
- </commands>
-
- <cr-menu id="wallpaper-context-menu" class="chrome-menu"
- visibleif="custom surprise-me-disabled">
- <cr-menu-item command="#delete"></cr-menu-item>
- </cr-menu>
-
- <div id="error-container" class="overlay-container" hidden>
- <div class="page">
- <div id="close-error" class="close"></div>
- <span class="error-message"></span>
- <a id="learn-more" i18n-content="learnMore" target="_blank"></a>
- </div>
- </div>
- <div id="wallpaper-selection-container" class="overlay-container" hidden>
- <div class="page">
- <div id="close-wallpaper-selection" class="close"></div>
- <div id="content">
- <input id="file-selector" type="file" size="80"
- accept="image/jpeg, image/png">
- <div i18n-content="positionLabel"></div>
- <select id="set-wallpaper-layout" disabled>
- <option value="CENTER" i18n-content="centerLayout"></option>
- <option selected="selected" value="CENTER_CROPPED"
- i18n-content="centerCroppedLayout"></option>
- <option value="STRETCH" i18n-content="stretchLayout"></option>
- </select>
- <div id="warning">
- <img class="remember-icon">
- <span i18n-content="customWallpaperWarning"></span>
- </div>
- </div>
- </div>
- </div>
- <div class="dialog-container">
- <div class="dialog-topbar">
- <div id="navstrip">
- <list id="categories-list"></list>
- <div id="bar"></div>
- </div>
- <div class="spacer"></div>
- <div id="window-close-button" class="close"></div>
- </div>
- <div class="dialog-main">
- <div id="category-container">
- <div id="wallpaper-set-by-message"></div>
- <grid id="wallpaper-grid" class="image-picker"></grid>
- <div id="spinner-container" hidden></div>
- <div class="progress-bar" hidden>
- <div class="progress-track"></div>
- </div>
- <div class="bottom-bar">
- <div id="online-wallpaper-attribute">
- <img id="attribute-image" hidden>
- <div id="wallpaper-attribute" hidden>
- <div>
- <label>
- <span id="author-name"></span>
- </label>
- </div>
- <div>
- <a id="author-website" target="_blank"></a>
- </div>
- </div>
- </div>
- <div class="spacer"></div>
- <div id="surprise-me" hidden>
- <div id="checkbox"></div>
- <span i18n-content="surpriseMeLabel"></span>
- </div>
- </div>
- </div>
- </div>
- </div>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/component_extension_resources.grd b/chromium/chrome/browser/resources/component_extension_resources.grd
index d07c2631411..80e80afc8cd 100644
--- a/chromium/chrome/browser/resources/component_extension_resources.grd
+++ b/chromium/chrome/browser/resources/component_extension_resources.grd
@@ -101,8 +101,10 @@
</if>
<if expr="not is_android">
<include name="IDR_FEEDBACK_DEFAULT_HTML" file="feedback/html/default.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+ <include name="IDR_FEEDBACK_SYSINFO_HTML" file="feedback/html/sys_info.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_FEEDBACK_EVENT_HANDLER_JS" file="feedback/js/event_handler.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_FEEDBACK_FEEDBACK_JS" file="feedback/js/feedback.js" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_FEEDBACK_SYSINFO_JS" file="feedback/js/sys_info.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_FEEDBACK_TAKE_SCREENSHOT_JS" file="feedback/js/take_screenshot.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_FEEDBACK_TOPBAR_HANDLER_JS" file="feedback/js/topbar_handlers.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_FEEDBACK_FEEDBACK_CSS" file="feedback/css/feedback.css" type="BINDATA" />
@@ -149,8 +151,6 @@
<if expr="enable_plugins">
<include name="IDR_PDF_INDEX_CSS" file="pdf/index.css" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PDF_INDEX_HTML" file="pdf/index.html" allowexternalscript="true" type="BINDATA" />
- <include name="IDR_PDF_INDEX_MATERIAL_CSS" file="pdf/index-material.css" allowexternalscript="true" type="BINDATA" />
- <include name="IDR_PDF_INDEX_MATERIAL_HTML" file="pdf/index-material.html" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PDF_MAIN_JS" file="pdf/main.js" type="BINDATA" />
<include name="IDR_PDF_PDF_JS" file="pdf/pdf.js" type="BINDATA" />
<include name="IDR_PDF_UI_MANAGER_JS" file="pdf/toolbar_manager.js" type="BINDATA" />
@@ -169,15 +169,9 @@
<include name="IDR_PDF_VIEWER_BOOKMARK_JS" file="pdf/elements/viewer-bookmark/viewer-bookmark.js" type="BINDATA" />
<include name="IDR_PDF_VIEWER_BOOKMARKS_CONTENT_HTML" file="pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html" type="BINDATA" />
<include name="IDR_PDF_VIEWER_BOOKMARKS_CONTENT_JS" file="pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_BUTTON_CSS" file="pdf/elements/viewer-button/viewer-button.css" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_BUTTON_HTML" file="pdf/elements/viewer-button/viewer-button.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_BUTTON_JS" file="pdf/elements/viewer-button/viewer-button.js" type="BINDATA" />
<include name="IDR_PDF_VIEWER_ERROR_SCREEN_CSS" file="pdf/elements/viewer-error-screen/viewer-error-screen.css" 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_ERROR_SCREEN_LEGACY_CSS" file="pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.css" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_ERROR_SCREEN_LEGACY_HTML" file="pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_ERROR_SCREEN_LEGACY_JS" file="pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js" type="BINDATA" />
<include name="IDR_PDF_VIEWER_PAGE_INDICATOR_CSS" file="pdf/elements/viewer-page-indicator/viewer-page-indicator.css" type="BINDATA" />
<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" />
@@ -186,18 +180,9 @@
<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_PASSWORD_SCREEN_LEGACY_CSS" file="pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.css" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PASSWORD_SCREEN_LEGACY_HTML" file="pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PASSWORD_SCREEN_LEGACY_JS" file="pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.js" type="BINDATA" />
<include name="IDR_PDF_VIEWER_PDF_TOOLBAR_CSS" file="pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css" type="BINDATA" />
<include name="IDR_PDF_VIEWER_PDF_TOOLBAR_HTML" file="pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html" type="BINDATA" />
<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_PROGRESS_BAR_CSS" file="pdf/elements/viewer-progress-bar/viewer-progress-bar.css" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PROGRESS_BAR_HTML" file="pdf/elements/viewer-progress-bar/viewer-progress-bar.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PROGRESS_BAR_JS" file="pdf/elements/viewer-progress-bar/viewer-progress-bar.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_TOOLBAR_CSS" file="pdf/elements/viewer-toolbar/viewer-toolbar.css" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_TOOLBAR_HTML" file="pdf/elements/viewer-toolbar/viewer-toolbar.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_TOOLBAR_JS" file="pdf/elements/viewer-toolbar/viewer-toolbar.js" type="BINDATA" />
<include name="IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_CSS" file="pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css" 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" />
@@ -207,20 +192,6 @@
<include name="IDR_PDF_VIEWER_ZOOM_SELECTOR_CSS" file="pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css" 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" />
-
- <!-- Button images. -->
- <include name="IDR_PDF_BUTTON_LOW_1" file="pdf/elements/viewer-button/img/lowDPI/button_fit_page.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_LOW_2" file="pdf/elements/viewer-button/img/lowDPI/button_fit_width.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_LOW_3" file="pdf/elements/viewer-button/img/lowDPI/button_zoom_out.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_LOW_4" file="pdf/elements/viewer-button/img/lowDPI/button_zoom_in.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_LOW_5" file="pdf/elements/viewer-button/img/lowDPI/button_save.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_LOW_6" file="pdf/elements/viewer-button/img/lowDPI/button_print.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_HIGH_1" file="pdf/elements/viewer-button/img/hiDPI/button_fit_page.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_HIGH_2" file="pdf/elements/viewer-button/img/hiDPI/button_fit_width.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_HIGH_3" file="pdf/elements/viewer-button/img/hiDPI/button_zoom_out.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_HIGH_4" file="pdf/elements/viewer-button/img/hiDPI/button_zoom_in.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_HIGH_5" file="pdf/elements/viewer-button/img/hiDPI/button_save.png" type="BINDATA" />
- <include name="IDR_PDF_BUTTON_HIGH_6" file="pdf/elements/viewer-button/img/hiDPI/button_print.png" 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/crashes.css b/chromium/chrome/browser/resources/crashes.css
deleted file mode 100644
index 1d7ab78f679..00000000000
--- a/chromium/chrome/browser/resources/crashes.css
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-body {
- margin: 20px;
-}
-
-h1 {
- -webkit-padding-start: 75px;
- background-image: url(../../app/theme/common/sadtab.svg);
- background-position: left;
- background-repeat: no-repeat;
- font-size: 156%;
- font-weight: bold;
- margin: 0;
- padding-bottom: 20px;
- padding-top: 20px;
-}
-
-html[dir=rtl] h1 {
- background-position: right;
-}
-
-#countBanner {
- background-color: rgb(235, 239, 250);
- border: 1px solid #bbb;
- border-radius: 2px;
- font-size: 100%;
- padding: 4px;
-}
-
-#crashList h3 {
- font-size: 100%;
-}
-
-#crashList > div > * {
- margin: 0.75em 0;
-}
-
-#crashList a:visited {
- color: #666;
-}
-
-#crashList > div:not(:last-child) {
- border-bottom: 1px solid #bbb;
-}
-
-#disabledMode h2 {
- color: rgb(141, 51, 42);
- font-size: 125%;
-}
diff --git a/chromium/chrome/browser/resources/crashes.html b/chromium/chrome/browser/resources/crashes.html
deleted file mode 100644
index b848e68e59d..00000000000
--- a/chromium/chrome/browser/resources/crashes.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
- <meta charset="utf-8">
- <title i18n-content="crashesTitle"></title>
- <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" href="chrome://resources/css/widgets.css">
- <link rel="stylesheet" href="crashes.css">
- <script src="chrome://resources/js/action_link.js"></script>
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="chrome://crashes/strings.js"></script>
- <script src="chrome://crashes/crashes.js"></script>
-</head>
-<body>
- <header><h1 i18n-content="crashesTitle"></h1></header>
- <div id="crashUploadStatus" hidden>
- <a is="action-link" role="button" id="uploadCrashes"
- i18n-content="uploadCrashesLinkText"></a>
- </div>
- <div id="enabledMode">
- <h2 id="countBanner"></h2>
- <div id="crashList"></div>
- <p id="noCrashes" i18n-content="noCrashesMessage" hidden></p>
- </div>
- <div id="disabledMode" hidden>
- <h2 i18n-content="disabledHeader"></h2>
- <p i18n-values=".innerHTML:disabledMessage"></p>
- </div>
- <script src="chrome://resources/js/i18n_template.js"></script>
- <script src="chrome://resources/js/jstemplate_compiled.js"></script>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/crashes.js b/chromium/chrome/browser/resources/crashes.js
deleted file mode 100644
index e385dd57e9b..00000000000
--- a/chromium/chrome/browser/resources/crashes.js
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/* Id for tracking automatic refresh of crash list. */
-var refreshCrashListId = undefined;
-
-/**
- * Requests the list of crashes from the backend.
- */
-function requestCrashes() {
- chrome.send('requestCrashList');
-}
-
-/**
- * Callback from backend with the list of crashes. Builds the UI.
- * @param {boolean} enabled Whether or not crash reporting is enabled.
- * @param {boolean} dynamicBackend Whether the crash backend is dynamic.
- * @param {array} crashes The list of crashes.
- * @param {string} version The browser version.
- */
-function updateCrashList(enabled, dynamicBackend, crashes, version) {
- $('countBanner').textContent = loadTimeData.getStringF('crashCountFormat',
- crashes.length);
-
- var crashSection = $('crashList');
-
- $('enabledMode').hidden = !enabled;
- $('disabledMode').hidden = enabled;
- $('crashUploadStatus').hidden = !enabled || !dynamicBackend;
-
- if (!enabled)
- return;
-
- // Clear any previous list.
- crashSection.textContent = '';
-
- var productName = loadTimeData.getString('shortProductName');
-
- for (var i = 0; i < crashes.length; i++) {
- var crash = crashes[i];
- if (crash['local_id'] == '')
- crash['local_id'] = productName;
-
- var crashBlock = document.createElement('div');
- var title = document.createElement('h3');
- title.textContent = loadTimeData.getStringF('crashHeaderFormat',
- crash['id'],
- crash['local_id']);
- crashBlock.appendChild(title);
- var date = document.createElement('p');
- date.textContent = loadTimeData.getStringF('crashTimeFormat',
- crash['time']);
- crashBlock.appendChild(date);
- var linkBlock = document.createElement('p');
- var link = document.createElement('a');
- var commentLines = [
- 'Chrome Version: ' + version,
- // TODO(tbreisacher): fill in the OS automatically?
- 'Operating System: e.g., "Windows 7", "Mac OSX 10.6"',
- '',
- 'URL (if applicable) where crash occurred:',
- '',
- 'Can you reproduce this crash?',
- '',
- 'What steps will reproduce this crash? (or if it\'s not ' +
- 'reproducible, what were you doing just before the crash)?',
- '',
- '1.', '2.', '3.',
- '',
- '*Please note that issues filed with no information filled in ' +
- 'above will be marked as WontFix*',
- '',
- '****DO NOT CHANGE BELOW THIS LINE****',
- 'report_id:' + crash.id
- ];
- var params = {
- template: 'Crash Report',
- comment: commentLines.join('\n'),
- };
- var href = 'http://code.google.com/p/chromium/issues/entry';
- for (var param in params) {
- href = appendParam(href, param, params[param]);
- }
- link.href = href;
- link.target = '_blank';
- link.textContent = loadTimeData.getString('bugLinkText');
- linkBlock.appendChild(link);
- crashBlock.appendChild(linkBlock);
- crashSection.appendChild(crashBlock);
- }
-
- $('noCrashes').hidden = crashes.length != 0;
-}
-
-/**
- * Request crashes get uploaded in the background.
- */
-function requestCrashUpload() {
- // Don't need locking with this call because the system crash reporter
- // has locking built into itself.
- chrome.send('requestCrashUpload');
-
- // Trigger a refresh in 5 seconds. Clear any previous requests.
- clearTimeout(refreshCrashListId);
- refreshCrashListId = setTimeout(requestCrashes, 5000);
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- $('uploadCrashes').onclick = requestCrashUpload;
- requestCrashes();
-});
diff --git a/chromium/chrome/browser/resources/downloads/OWNERS b/chromium/chrome/browser/resources/downloads/OWNERS
index ba74b648a51..cd46f8deb58 100644
--- a/chromium/chrome/browser/resources/downloads/OWNERS
+++ b/chromium/chrome/browser/resources/downloads/OWNERS
@@ -1,3 +1,2 @@
asanka@chromium.org
-benjhayden@chromium.org
dbeam@chromium.org
diff --git a/chromium/chrome/browser/resources/downloads/compiled_resources.gyp b/chromium/chrome/browser/resources/downloads/compiled_resources.gyp
index 23d94325487..25184bdbd81 100644
--- a/chromium/chrome/browser/resources/downloads/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/downloads/compiled_resources.gyp
@@ -17,8 +17,8 @@
'../../../../ui/webui/resources/js/cr/ui/focus_row.js',
'../../../../ui/webui/resources/js/event_tracker.js',
'../../../../ui/webui/resources/js/util.js',
- '../md_downloads/constants.js',
- '../md_downloads/throttled_icon_loader.js',
+ 'constants.js',
+ 'throttled_icon_loader.js',
'item_view.js',
'focus_row.js',
],
diff --git a/chromium/chrome/browser/resources/downloads/compiled_resources2.gyp b/chromium/chrome/browser/resources/downloads/compiled_resources2.gyp
index f5793ee3ea7..4777352a9ff 100644
--- a/chromium/chrome/browser/resources/downloads/compiled_resources2.gyp
+++ b/chromium/chrome/browser/resources/downloads/compiled_resources2.gyp
@@ -4,6 +4,11 @@
{
'targets': [
{
+ 'target_name': 'constants',
+ 'dependencies': ['<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr'],
+ 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+ },
+ {
'target_name': 'externs',
'includes': ['../../../../third_party/closure_compiler/externs_js.gypi'],
},
@@ -13,8 +18,8 @@
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
- '../md_downloads/compiled_resources2.gyp:constants',
- '../md_downloads/compiled_resources2.gyp:throttled_icon_loader',
+ 'constants',
+ 'throttled_icon_loader',
'externs',
],
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
@@ -40,8 +45,8 @@
'<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui',
'<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:command',
'<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_grid',
- '../md_downloads/copmiled_resources2.gyp:constants',
- '../md_downloads/compiled_resources2.gyp:throttled_icon_loader',
+ 'constants',
+ 'throttled_icon_loader',
'item_view',
'focus_row',
'<(EXTERNS_GYP):chrome_send',
@@ -49,5 +54,10 @@
],
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
+ {
+ 'target_name': 'throttled_icon_loader',
+ 'dependencies': ['<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr'],
+ 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+ },
],
}
diff --git a/chromium/chrome/browser/resources/downloads/constants.html b/chromium/chrome/browser/resources/downloads/constants.html
new file mode 100644
index 00000000000..0ac6c26b9e5
--- /dev/null
+++ b/chromium/chrome/browser/resources/downloads/constants.html
@@ -0,0 +1,2 @@
+<link rel="import" href="chrome://resources/html/cr.html">
+<script src="chrome://downloads/constants.js"></script>
diff --git a/chromium/chrome/browser/resources/downloads/constants.js b/chromium/chrome/browser/resources/downloads/constants.js
new file mode 100644
index 00000000000..b123be03919
--- /dev/null
+++ b/chromium/chrome/browser/resources/downloads/constants.js
@@ -0,0 +1,38 @@
+// 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.
+
+cr.define('downloads', function() {
+ /**
+ * Explains why a download is in DANGEROUS state.
+ * @enum {string}
+ */
+ var DangerType = {
+ NOT_DANGEROUS: 'NOT_DANGEROUS',
+ DANGEROUS_FILE: 'DANGEROUS_FILE',
+ DANGEROUS_URL: 'DANGEROUS_URL',
+ DANGEROUS_CONTENT: 'DANGEROUS_CONTENT',
+ UNCOMMON_CONTENT: 'UNCOMMON_CONTENT',
+ DANGEROUS_HOST: 'DANGEROUS_HOST',
+ POTENTIALLY_UNWANTED: 'POTENTIALLY_UNWANTED',
+ };
+
+ /**
+ * The states a download can be in. These correspond to states defined in
+ * DownloadsDOMHandler::CreateDownloadItemValue
+ * @enum {string}
+ */
+ var States = {
+ IN_PROGRESS: 'IN_PROGRESS',
+ CANCELLED: 'CANCELLED',
+ COMPLETE: 'COMPLETE',
+ PAUSED: 'PAUSED',
+ DANGEROUS: 'DANGEROUS',
+ INTERRUPTED: 'INTERRUPTED',
+ };
+
+ return {
+ DangerType: DangerType,
+ States: States,
+ };
+});
diff --git a/chromium/chrome/browser/resources/md_downloads/throttled_icon_loader.html b/chromium/chrome/browser/resources/downloads/throttled_icon_loader.html
index 4cbd4ebfebd..4cbd4ebfebd 100644
--- a/chromium/chrome/browser/resources/md_downloads/throttled_icon_loader.html
+++ b/chromium/chrome/browser/resources/downloads/throttled_icon_loader.html
diff --git a/chromium/chrome/browser/resources/md_downloads/throttled_icon_loader.js b/chromium/chrome/browser/resources/downloads/throttled_icon_loader.js
index 5a10024e480..5a10024e480 100644
--- a/chromium/chrome/browser/resources/md_downloads/throttled_icon_loader.js
+++ b/chromium/chrome/browser/resources/downloads/throttled_icon_loader.js
diff --git a/chromium/chrome/browser/resources/engagement/engagement_table.css b/chromium/chrome/browser/resources/engagement/engagement_table.css
index 55318c35756..cb6a00889fc 100644
--- a/chromium/chrome/browser/resources/engagement/engagement_table.css
+++ b/chromium/chrome/browser/resources/engagement/engagement_table.css
@@ -13,8 +13,24 @@ table th {
table th {
background: rgb(224, 236, 255);
+ cursor: pointer;
+ padding-bottom: 4px;
+ padding-top: 4px;
+ white-space: nowrap;
}
.origin-cell {
min-width: 500px;
}
+
+table tr:hover {
+ background: rgb(255, 255, 187);
+}
+
+.sort-column::after {
+ content: '▲';
+}
+
+:host([sort-reverse]) .sort-column::after {
+ content: '▼';
+}
diff --git a/chromium/chrome/browser/resources/engagement/engagement_table.html b/chromium/chrome/browser/resources/engagement/engagement_table.html
index 434ee3d53db..3b667e8f6e8 100644
--- a/chromium/chrome/browser/resources/engagement/engagement_table.html
+++ b/chromium/chrome/browser/resources/engagement/engagement_table.html
@@ -6,12 +6,18 @@
<table>
<thead>
<tr>
- <th>Origin</th>
- <th>Points</th>
+ <th on-tap="handleSortColumnTap" sort-key="origin">
+ Origin
+ </th>
+ <th on-tap="handleSortColumnTap" sort-key="score" class="sort-column">
+ Points
+ </th>
</tr>
</thead>
<tbody>
- <template is="dom-repeat" items="{{engagementInfo}}" as="info">
+ <template id="engagement-table-items" is="dom-repeat"
+ items="{{engagementInfo}}" as="info"
+ sort="[[getTableSortFunction_(sortKey_, sortReverse)]]">
<tr>
<td class="origin-cell">{{info.origin}}</td>
<td>{{info.score}}</td>
diff --git a/chromium/chrome/browser/resources/engagement/engagement_table.js b/chromium/chrome/browser/resources/engagement/engagement_table.js
index efd259e8dd0..976fbe975f0 100644
--- a/chromium/chrome/browser/resources/engagement/engagement_table.js
+++ b/chromium/chrome/browser/resources/engagement/engagement_table.js
@@ -4,6 +4,15 @@
'use strict';
+/**
+ * Strips a scheme from an origin.
+ * @param {string} origin
+ * @return {string} The host of the given origin.
+ */
+function stripScheme(origin) {
+ return new URL(origin).host;
+}
+
Polymer({
is: 'engagement-table',
properties: {
@@ -11,10 +20,88 @@ Polymer({
* A list of engagement info objects.
* @type !Array<!SiteEngagementInfo>
*/
- engagementInfo: {
- type: Array,
- value: () => []
- },
+ engagementInfo: {type: Array, value: function() { return []; } },
+
+ /**
+ * The table's current sort key.
+ * @type {string}
+ * @private
+ */
+ sortKey_: {type: String, value: 'score'},
+
+ /**
+ * Whether the table is in reverse sorting order.
+ * @type {boolean}
+ * @private
+ */
+ sortReverse: {type: Boolean, value: true, reflectToAttribute: true},
+ },
+
+ /**
+ * @param {Event} e
+ */
+ handleSortColumnTap: function(e) {
+ this.sortTable_(e.currentTarget);
+ e.preventDefault();
+ },
+
+ /**
+ * Sorts the engagement table based on the provided sort column header. Sort
+ * columns have a 'sort-key' attribute that is a property name of a
+ * SiteEngagementInfo.
+ * @param {HTMLElement} th The column to sort by.
+ * @private
+ */
+ sortTable_: function(th) {
+ // Remove the old sort indicator column.
+ var sortColumn = this.$$('.sort-column');
+ if (sortColumn)
+ sortColumn.className = '';
+
+ // Updating these properties recomputes the template sort function.
+ var newSortKey = th.getAttribute('sort-key');
+ if (this.sortKey_)
+ this.sortReverse = (newSortKey == this.sortKey_) && !this.sortReverse;
+
+ this.sortKey_ = newSortKey;
+
+ // Specify the new sort indicator column.
+ th.className = 'sort-column';
+ },
+
+ /**
+ * Returns a sorting function for SiteEngagementInfo objects that sorts based
+ * on sortKey.
+ * @param {string} sortKey The name of the property to sort by.
+ * @param {boolean} reverse Whether the sort should be in reverse order.
+ * @return {function} A comparator for SiteEngagementInfos.
+ * @private
+ */
+ getTableSortFunction_: function(sortKey, reverse) {
+ return function(a, b) {
+ return (reverse ? -1 : 1) *
+ this.compareTableItem_(sortKey, a, b);
+ }.bind(this);
},
+ /**
+ * Compares two SiteEngagementInfo objects based on the sortKey.
+ * @param {string} sortKey The name of the property to sort by.
+ * @return {number} A negative number if |a| should be ordered before |b|, a
+ * positive number otherwise.
+ * @private
+ */
+ compareTableItem_: function(sortKey, a, b) {
+ var val1 = a[sortKey];
+ var val2 = b[sortKey];
+
+ if (sortKey == 'origin')
+ return stripScheme(val1) > stripScheme(val2) ? 1 : -1;
+
+ if (sortKey == 'score')
+ return val1 - val2;
+
+ assertNotReached('Unsupported sort key: ' + sortKey);
+ return 0;
+ },
});
diff --git a/chromium/chrome/browser/resources/engagement/site_engagement.js b/chromium/chrome/browser/resources/engagement/site_engagement.js
index 911bbe59432..38451293f51 100644
--- a/chromium/chrome/browser/resources/engagement/site_engagement.js
+++ b/chromium/chrome/browser/resources/engagement/site_engagement.js
@@ -9,16 +9,24 @@ define('main', [
'chrome/browser/ui/webui/engagement/site_engagement.mojom',
'content/public/renderer/service_provider',
], function(connection, siteEngagementMojom, serviceProvider) {
-
return function() {
var uiHandler = connection.bindHandleToProxy(
serviceProvider.connectToService(
siteEngagementMojom.SiteEngagementUIHandler.name),
siteEngagementMojom.SiteEngagementUIHandler);
- // Populate engagement table.
- uiHandler.getSiteEngagementInfo().then(response => {
- $('engagement-table').engagementInfo = response.info;
- });
+ var updateEngagementTable = function() {
+ // Populate engagement table.
+ uiHandler.getSiteEngagementInfo().then(function(response) {
+ // Round each score to 2 decimal places.
+ response.info.forEach(function(x) {
+ x.score = Number(Math.round(x.score * 100) / 100);
+ });
+ $('engagement-table').engagementInfo = response.info;
+ });
+
+ setTimeout(updateEngagementTable, 2000);
+ };
+ updateEngagementTable();
};
});
diff --git a/chromium/chrome/browser/resources/extensions/OWNERS b/chromium/chrome/browser/resources/extensions/OWNERS
index 9fb4aea29dc..ccdcd27a2b2 100644
--- a/chromium/chrome/browser/resources/extensions/OWNERS
+++ b/chromium/chrome/browser/resources/extensions/OWNERS
@@ -1,4 +1,3 @@
dbeam@chromium.org
finnur@chromium.org
-kalman@chromium.org
rdevlin.cronin@chromium.org
diff --git a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.html b/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.html
deleted file mode 100644
index 4ec504af79c..00000000000
--- a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<div id="kiosk-disable-bailout-confirm-overlay" class="page">
- <div class="close-button"></div>
- <div class="content-area">
- <p id="kiosk-disable-bailout-warning-bold"
- i18n-content='kioskDisableBailoutShortcutWarningBold'></p>
- <p i18n-content='kioskDisableBailoutShortcutWarning'></p>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="kiosk-disable-bailout-cancel-button"
- i18n-content="kioskDisableBailoutShortcutCancel"></button>
- <button id="kiosk-disable-bailout-confirm-button"
- i18n-content="kioskDisableBailoutShortcutConfirm"></button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.js b/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.js
deleted file mode 100644
index 89c628b3dc1..00000000000
--- a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_disable_bailout_confirm.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('extensions', function() {
- /**
- * A confirmation overlay for disabling kiosk app bailout shortcut.
- * @constructor
- */
- function KioskDisableBailoutConfirm() {
- }
-
- cr.addSingletonGetter(KioskDisableBailoutConfirm);
-
- KioskDisableBailoutConfirm.prototype = {
- /**
- * Initialize the page.
- */
- initialize: function() {
- var overlay = $('kiosk-disable-bailout-confirm-overlay');
- cr.ui.overlay.setupOverlay(overlay);
- cr.ui.overlay.globalInitialization();
- overlay.addEventListener('cancelOverlay', this.handleCancel);
-
- var el = $('kiosk-disable-bailout-shortcut');
- el.addEventListener('change', this.handleDisableBailoutShortcutChange_);
-
- $('kiosk-disable-bailout-confirm-button').onclick = function(e) {
- extensions.ExtensionSettings.showOverlay($('kiosk-apps-page'));
- chrome.send('setDisableBailoutShortcut', [true]);
- };
- $('kiosk-disable-bailout-cancel-button').onclick = this.handleCancel;
- },
-
- /** Handles overlay being canceled. */
- handleCancel: function() {
- extensions.ExtensionSettings.showOverlay($('kiosk-apps-page'));
- $('kiosk-disable-bailout-shortcut').checked = false;
- },
-
- /**
- * Custom change handler for the disable bailout shortcut checkbox.
- * It blocks the underlying pref being changed and brings up confirmation
- * alert to user.
- * @private
- */
- handleDisableBailoutShortcutChange_: function() {
- // Just set the pref if user un-checks the box.
- if (!$('kiosk-disable-bailout-shortcut').checked) {
- chrome.send('setDisableBailoutShortcut', [false]);
- return false;
- }
-
- // Otherwise, show the confirmation overlay.
- extensions.ExtensionSettings.showOverlay($(
- 'kiosk-disable-bailout-confirm-overlay'));
- return true;
- }
- };
-
- // Export
- return {
- KioskDisableBailoutConfirm: KioskDisableBailoutConfirm
- };
-});
-
diff --git a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_list.js b/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_list.js
deleted file mode 100644
index d92784097d7..00000000000
--- a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_app_list.js
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * The type of the app data object. The definition is based on
- * chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc:
- * PopulateAppDict()
- * @typedef {{id: string,
- * name: string,
- * iconURL: string,
- * autoLaunch: boolean,
- * isLoading: boolean}}
- */
-var AppDict;
-
-cr.define('extensions', function() {
- /** @const */ var List = cr.ui.List;
- /** @const */ var ListItem = cr.ui.ListItem;
- /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
-
- /**
- * Creates a list for showing kiosk apps.
- * @constructor
- * @extends {cr.ui.List}
- */
- var KioskAppList = cr.ui.define('list');
-
- KioskAppList.prototype = {
- __proto__: List.prototype,
-
- /**
- * True if auto launch feature can be configured.
- * @type {?boolean}
- */
- autoLaunchEnabled_: false,
-
- /** @override */
- createItem: function(app) {
- var item = new KioskAppListItem();
- item.data = app;
- item.autoLaunchEnabled = this.autoLaunchEnabled_;
- return item;
- },
-
- /**
- * Sets auto launch enabled flag.
- * @param {boolean} enabled True if auto launch should be enabled.
- */
- setAutoLaunchEnabled: function(enabled) {
- this.autoLaunchEnabled_ = enabled;
- },
-
- /**
- * Loads the given list of apps.
- * @param {!Array<!Object>} apps An array of app info objects.
- */
- setApps: function(apps) {
- this.dataModel = new ArrayDataModel(apps);
- },
-
- /**
- * Updates the given app.
- * @param {!AppDict} app An app info object.
- */
- updateApp: function(app) {
- for (var i = 0; i < this.items.length; ++i) {
- if (this.items[i].data.id == app.id) {
- this.items[i].data = app;
- break;
- }
- }
- }
- };
-
- /**
- * Creates a list item for a kiosk app.
- * @constructor
- * @extends {cr.ui.ListItem}
- */
- var KioskAppListItem = cr.ui.define(function() {
- var el = $('kiosk-app-list-item-template').cloneNode(true);
- el.removeAttribute('id');
- el.hidden = false;
- return el;
- });
-
- KioskAppListItem.prototype = {
- __proto__: ListItem.prototype,
-
- /**
- * Data object to hold app info.
- * @type {Object}
- * @private
- */
- data_: null,
-
- get data() {
- assert(this.data_);
- return this.data_;
- },
-
- set data(data) {
- this.data_ = data;
- this.redraw();
- },
-
- set autoLaunchEnabled(enabled) {
- this.querySelector('.enable-auto-launch-button').hidden = !enabled;
- this.querySelector('.disable-auto-launch-button').hidden = !enabled;
- },
-
- /**
- * Getter for the icon element.
- * @type {Element}
- */
- get icon() {
- return this.querySelector('.kiosk-app-icon');
- },
-
- /**
- * Getter for the name element.
- * @type {Element}
- */
- get name() {
- return this.querySelector('.kiosk-app-name');
- },
-
- /**
- * Getter for the status text element.
- * @type {Element}
- */
- get status() {
- return this.querySelector('.kiosk-app-status');
- },
-
- /** @override */
- decorate: function() {
- ListItem.prototype.decorate.call(this);
-
- var sendMessageWithId = function(msg) {
- return function() {
- chrome.send(msg, [this.data.id]);
- }.bind(this);
- }.bind(this);
-
- this.querySelector('.enable-auto-launch-button').onclick =
- sendMessageWithId('enableKioskAutoLaunch');
- this.querySelector('.disable-auto-launch-button').onclick =
- sendMessageWithId('disableKioskAutoLaunch');
- this.querySelector('.row-delete-button').onclick =
- sendMessageWithId('removeKioskApp');
- },
-
- /**
- * Updates UI from app info data.
- */
- redraw: function() {
- this.icon.classList.toggle('spinner', this.data.isLoading);
- this.icon.style.backgroundImage = 'url(' + this.data.iconURL + ')';
-
- this.name.textContent = this.data.name || this.data.id;
- this.status.textContent = this.data.autoLaunch ?
- loadTimeData.getString('autoLaunch') : '';
-
- this.autoLaunch = this.data.autoLaunch;
- }
- };
-
- /**
- * True if the app represented by this item will auto launch.
- */
- cr.defineProperty(KioskAppListItem, 'autoLaunch', cr.PropertyKind.BOOL_ATTR);
-
- // Export
- return {
- KioskAppList: KioskAppList
- };
-});
diff --git a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.css b/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.css
deleted file mode 100644
index 6040b4620bf..00000000000
--- a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.css
+++ /dev/null
@@ -1,156 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#kiosk-apps-page .checkbox {
- display: block;
-}
-
-#kiosk-app-list {
- border: 1px solid lightgrey;
- height: 200px;
- margin-bottom: 5px;
-}
-
-#kiosk-app-list > * {
- -webkit-box-align: center;
- box-sizing: border-box;
- display: -webkit-box;
- height: 32px;
-}
-
-/* TODO(xiyuan): The .row-delete-button rules probably should live somewhere
- * else and be shared with options.css */
-list .row-delete-button {
- -webkit-transition: 150ms opacity;
- background-color: transparent;
- /* TODO(stuartmorgan): Replace with real images once they are available. */
- background-image: -webkit-image-set(
- url(../../../../../ui/resources/default_100_percent/close_2.png) 1x,
- url(../../../../../ui/resources/default_200_percent/close_2.png) 2x);
- border: none;
- display: block;
- height: 16px;
- opacity: 1;
- width: 16px;
-}
-
-list > *:not(:hover):not([selected]):not([lead]) .row-delete-button,
-list:not([has-element-focus]) > *:not(:hover):not([selected])
- .row-delete-button,
-list[disabled] .row-delete-button,
-list .row-delete-button[disabled] {
- opacity: 0;
- pointer-events: none;
-}
-
-list .row-delete-button:hover {
- background-image: -webkit-image-set(
- url(../../../../../ui/resources/default_100_percent/close_2_hover.png)
- 1x,
- url(../../../../../ui/resources/default_200_percent/close_2_hover.png)
- 2x);
-}
-
-list .row-delete-button:active {
- background-image: -webkit-image-set(
- url(../../../../../ui/resources/default_100_percent/close_2_pressed.png)
- 1x,
- url(../../../../../ui/resources/default_200_percent/close_2_pressed.png)
- 2x);
-}
-
-.controlled-setting-with-label > input:disabled + span label {
- color: #999;
-}
-
-#kiosk-app-id-edit-row {
- -webkit-justify-content: space-between;
- display: -webkit-flex;
- width: 510px;
-}
-
-#kiosk-app-id-edit,
-#kiosk-app-add {
- display: block;
-}
-
-#kiosk-app-id-edit {
- -webkit-flex-grow: 1;
- -webkit-margin-end: 10px;
-}
-
-#kiosk-apps-error-banner {
- -webkit-transition: opacity 150ms;
- background-color: rgb(223, 165, 165);
- margin: 2px 0;
- opacity: 0;
- padding: 5px;
- visibility: hidden;
- white-space: nowrap;
- width: 100%;
-}
-
-#kiosk-apps-error-banner.visible {
- opacity: 1;
- visibility: visible;
-}
-
-.kiosk-app-list-item {
- white-space: nowrap;
-}
-
-.kiosk-app-list-item .space-filler {
- -webkit-box-flex: 1;
-}
-
-.kiosk-app-icon,
-.kiosk-app-name,
-.kiosk-app-status {
- display: inline-block;
- vertical-align: middle;
-}
-
-.kiosk-app-icon {
- background-size: 100%;
- height: 16px;
- width: 16px;
-}
-
-.kiosk-app-icon.spinner {
- background-image: url(chrome://resources/images/throbber_small.svg)
- !important;
-}
-
-.kiosk-app-name,
-.kiosk-app-status {
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.kiosk-app-name {
- max-width: 250px;
-}
-
-.kiosk-app-status {
- -webkit-margin-start: 8px;
- max-width: 120px;
-}
-
-.disable-auto-launch-button,
-.enable-auto-launch-button {
- display: none;
-}
-
-.kiosk-app-list-item[auto-launch]:hover .disable-auto-launch-button,
-.kiosk-app-list-item:not([auto-launch]):hover .enable-auto-launch-button {
- display: inline-block;
-}
-
-#kiosk-disable-bailout-confirm-overlay {
- width: 250px
-}
-
-#kiosk-disable-bailout-warning-bold {
- font-weight: bold;
-}
diff --git a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.html b/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.html
deleted file mode 100644
index dd0a50614e0..00000000000
--- a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<div id="kiosk-apps-page" class="page">
- <div class="close-button"></div>
- <h1 i18n-content="kioskOverlayTitle"></h1>
- <div class="content-area">
- <div class="option">
- <list id="kiosk-app-list"></list>
- <div id="kiosk-apps-error-banner">
- <span class="kiosk-app-name"></span>
- <span class="kiosk-app-status" i18n-content="invalidApp"></span>
- </div>
- <label for="kiosk-app-id-edit">
- <span i18n-content="addKioskApp"></span>
- </label>
- <div id="kiosk-app-id-edit-row">
- <input id="kiosk-app-id-edit" type="text"
- i18n-values="placeholder:kioskAppIdEditHint">
- <button id="kiosk-app-add" i18n-content="add"></button>
- </div>
- <div class="checkbox">
- <span class="controlled-setting-with-label">
- <input id="kiosk-disable-bailout-shortcut" type="checkbox">
- <span>
- <label for="kiosk-disable-bailout-shortcut"
- i18n-content="kioskDiableBailoutShortcutLabel">
- </label>
- </span>
- </span>
- </div>
- </div>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="kiosk-options-overlay-confirm" i18n-content="done">
- </button>
- </div>
- </div>
-
- <div id="kiosk-app-list-item-template" class="kiosk-app-list-item" hidden>
- <div class="content">
- <span class="kiosk-app-icon"></span>
- <span class="kiosk-app-name"></span>
- <span class="kiosk-app-status"></span>
- </div>
- <div class="space-filler"></div>
- <button class="enable-auto-launch-button"
- i18n-content="enableAutoLaunchButton">
- </button>
- <button class="disable-auto-launch-button"
- i18n-content="disableAutoLaunchButton">
- </button>
- <button class="raw-button custom-appearance row-delete-button">
- </button>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.js b/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.js
deleted file mode 100644
index 4697bcaef6e..00000000000
--- a/chromium/chrome/browser/resources/extensions/chromeos/kiosk_apps.js
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('extensions', function() {
- /**
- * Encapsulated handling of ChromeOS kiosk apps options page.
- * @constructor
- */
- function KioskAppsOverlay() {
- }
-
- cr.addSingletonGetter(KioskAppsOverlay);
-
- KioskAppsOverlay.prototype = {
- /**
- * Clear error timer id.
- * @type {?number}
- */
- clearErrorTimer_: null,
-
- /**
- * Initialize the page.
- */
- initialize: function() {
- chrome.send('initializeKioskAppSettings');
- extensions.KioskAppList.decorate($('kiosk-app-list'));
-
- var overlay = $('kiosk-apps-page');
- cr.ui.overlay.setupOverlay(overlay);
- cr.ui.overlay.globalInitialization();
- overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this));
-
- $('kiosk-options-overlay-confirm').onclick =
- this.handleDismiss_.bind(this);
- $('kiosk-app-id-edit').addEventListener('keypress',
- this.handleAppIdInputKeyPressed_.bind(this));
- $('kiosk-app-add').onclick = this.handleAddButtonClick_.bind(this);
- },
-
- /*
- * Invoked when the page is shown.
- */
- didShowPage: function() {
- chrome.send('getKioskAppSettings');
- $('kiosk-app-id-edit').focus();
- },
-
- /**
- * Shows error for given app name/id and schedules it to cleared.
- * @param {!string} appName App name/id to show in error banner.
- */
- showError: function(appName) {
- var errorBanner = $('kiosk-apps-error-banner');
- var appNameElement = errorBanner.querySelector('.kiosk-app-name');
- appNameElement.textContent = appName;
- errorBanner.classList.add('visible');
-
- if (this.clearErrorTimer_)
- window.clearTimeout(this.clearErrorTimer_);
-
- // Sets a timer to clear out error banner after 5 seconds.
- this.clearErrorTimer_ = window.setTimeout(function() {
- errorBanner.classList.remove('visible');
- this.clearErrorTimer_ = null;
- }.bind(this), 5000);
- },
-
- /**
- * Handles keypressed event in the app id input element.
- * @private
- */
- handleAppIdInputKeyPressed_: function(e) {
- if (e.keyIdentifier == 'Enter' && e.target.value)
- this.handleAddButtonClick_();
- },
-
- /**
- * Handles click event on the add button.
- * @private
- */
- handleAddButtonClick_: function() {
- var appId = $('kiosk-app-id-edit').value;
- if (!appId)
- return;
-
- chrome.send('addKioskApp', [appId]);
- $('kiosk-app-id-edit').value = '';
- },
-
- /**
- * Handles the overlay being dismissed.
- * @private
- */
- handleDismiss_: function() {
- this.handleAddButtonClick_();
- extensions.ExtensionSettings.showOverlay(null);
- }
- };
-
- /**
- * Sets apps to be displayed in kiosk-app-list.
- * @param {!Object<{apps: !Array<AppDict>, disableBailout: boolean,
- * hasAutoLaunchApp: boolean}>} settings An object containing an array of
- * app info objects and disable bailout shortcut flag.
- */
- KioskAppsOverlay.setSettings = function(settings) {
- $('kiosk-app-list').setApps(settings.apps);
- $('kiosk-disable-bailout-shortcut').checked = settings.disableBailout;
- $('kiosk-disable-bailout-shortcut').disabled = !settings.hasAutoLaunchApp;
- };
-
- /**
- * Update an app in kiosk-app-list.
- * @param {!Object} app App info to be updated.
- */
- KioskAppsOverlay.updateApp = function(app) {
- $('kiosk-app-list').updateApp(app);
- };
-
- /**
- * Shows error for given app name/id.
- * @param {!string} appName App name/id to show in error banner.
- */
- KioskAppsOverlay.showError = function(appName) {
- KioskAppsOverlay.getInstance().showError(appName);
- };
-
- /**
- * Enables consumer kiosk.
- * @param {!{kioskEnabled: boolean, autoLaunchEnabled: boolean}} params
- */
- KioskAppsOverlay.enableKiosk = function(params) {
- $('add-kiosk-app').hidden = !params.kioskEnabled;
- $('kiosk-disable-bailout-shortcut').parentNode.hidden =
- !params.autoLaunchEnabled;
- $('kiosk-app-list').setAutoLaunchEnabled(params.autoLaunchEnabled);
- };
-
- // Export
- return {
- KioskAppsOverlay: KioskAppsOverlay
- };
-});
-
-<include src="kiosk_app_list.js">
-<include src="kiosk_app_disable_bailout_confirm.js">
diff --git a/chromium/chrome/browser/resources/extensions/compiled_resources.gyp b/chromium/chrome/browser/resources/extensions/compiled_resources.gyp
index a40ae066330..7779b4e4666 100644
--- a/chromium/chrome/browser/resources/extensions/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/extensions/compiled_resources.gyp
@@ -32,9 +32,9 @@
'focus_row.js',
],
'externs': [
- '<(EXTERNS_DIR)/chrome_extensions.js',
'<(EXTERNS_DIR)/chrome_send.js',
'<(EXTERNS_DIR)/developer_private.js',
+ '<(EXTERNS_DIR)/management.js',
],
},
'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chromium/chrome/browser/resources/extensions/extension_command_list.js b/chromium/chrome/browser/resources/extensions/extension_command_list.js
index 9974fb72da9..49e05301268 100644
--- a/chromium/chrome/browser/resources/extensions/extension_command_list.js
+++ b/chromium/chrome/browser/resources/extensions/extension_command_list.js
@@ -2,16 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-/** @typedef {{active: boolean,
- * command_name: string,
- * description: string,
- * extension_action: boolean,
- * extension_id: string,
- * global: boolean,
- * keybinding: string}}
- */
-var ExtensionCommand;
-
cr.define('options', function() {
'use strict';
@@ -217,10 +207,11 @@ cr.define('options', function() {
/**
* Updates the extensions data for the overlay.
- * @param {!Array<ExtensionInfo>} data The extension data.
+ * @param {!Array<chrome.developerPrivate.ExtensionInfo>} data The extension
+ * data.
*/
setData: function(data) {
- /** @private {!Array<ExtensionInfo>} */
+ /** @private {!Array<chrome.developerPrivate.ExtensionInfo>} */
this.data_ = data;
this.textContent = '';
@@ -232,7 +223,8 @@ cr.define('options', function() {
/**
* Synthesizes and initializes an HTML element for the extension command
* metadata given in |extension|.
- * @param {ExtensionInfo} extension A dictionary of extension metadata.
+ * @param {chrome.developerPrivate.ExtensionInfo} extension A dictionary of
+ * extension metadata.
* @private
*/
createNodeForExtension_: function(extension) {
@@ -259,7 +251,8 @@ cr.define('options', function() {
* Synthesizes and initializes an HTML element for the extension command
* metadata given in |command|.
* @param {string} extensionId The associated extension's id.
- * @param {Command} command A dictionary of extension command metadata.
+ * @param {chrome.developerPrivate.Command} command A dictionary of
+ * extension command metadata.
* @private
*/
createNodeForCommand_: function(extensionId, command) {
diff --git a/chromium/chrome/browser/resources/extensions/extension_commands_overlay.js b/chromium/chrome/browser/resources/extensions/extension_commands_overlay.js
index 9b51f341f90..6e0e43a5dc2 100644
--- a/chromium/chrome/browser/resources/extensions/extension_commands_overlay.js
+++ b/chromium/chrome/browser/resources/extensions/extension_commands_overlay.js
@@ -54,7 +54,7 @@ cr.define('extensions', function() {
/**
* Called by the dom_ui_ to re-populate the page with data representing
* the current state of extension commands.
- * @param {!Array<ExtensionInfo>} extensionsData
+ * @param {!Array<chrome.developerPrivate.ExtensionInfo>} extensionsData
*/
ExtensionCommandsOverlay.updateExtensionsData = function(extensionsData) {
var overlay = ExtensionCommandsOverlay.getInstance();
diff --git a/chromium/chrome/browser/resources/extensions/extension_error.js b/chromium/chrome/browser/resources/extensions/extension_error.js
index 9ad71e8d753..7853a157dd5 100644
--- a/chromium/chrome/browser/resources/extensions/extension_error.js
+++ b/chromium/chrome/browser/resources/extensions/extension_error.js
@@ -67,18 +67,21 @@ cr.define('extensions', function() {
* @type {(ManifestError|RuntimeError)}
*/
this.error = error;
+ var iconAltTextKey = 'extensionLogLevelWarn';
// Add an additional class for the severity level.
if (error.type == chrome.developerPrivate.ErrorType.RUNTIME) {
switch (error.severity) {
case chrome.developerPrivate.ErrorLevel.LOG:
this.classList.add('extension-error-severity-info');
+ iconAltTextKey = 'extensionLogLevelInfo';
break;
case chrome.developerPrivate.ErrorLevel.WARN:
this.classList.add('extension-error-severity-warning');
break;
case chrome.developerPrivate.ErrorLevel.ERROR:
this.classList.add('extension-error-severity-fatal');
+ iconAltTextKey = 'extensionLogLevelError';
break;
default:
assertNotReached();
@@ -90,9 +93,7 @@ cr.define('extensions', function() {
var iconNode = document.createElement('img');
iconNode.className = 'extension-error-icon';
- // TODO(hcarmona): Populate alt text with a proper description since this
- // icon conveys the severity of the error. (info, warning, fatal).
- iconNode.alt = '';
+ iconNode.alt = loadTimeData.getString(iconAltTextKey);
this.insertBefore(iconNode, this.firstChild);
var messageSpan = this.querySelector('.extension-error-message');
@@ -195,7 +196,7 @@ cr.define('extensions', function() {
/**
* The callback for the extension changed event.
- * @private {function(EventData):void}
+ * @private {function(chrome.developerPrivate.EventData):void}
*/
this.onItemStateChangedListener_ = function(data) {
var type = chrome.developerPrivate.EventType;
diff --git a/chromium/chrome/browser/resources/extensions/extension_error_overlay.js b/chromium/chrome/browser/resources/extensions/extension_error_overlay.js
index 1f7975e6605..3acfef97b6d 100644
--- a/chromium/chrome/browser/resources/extensions/extension_error_overlay.js
+++ b/chromium/chrome/browser/resources/extensions/extension_error_overlay.js
@@ -2,6 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
+/** @typedef {chrome.developerPrivate.RuntimeError} */
+var RuntimeError;
+/** @typedef {chrome.developerPrivate.ManifestError} */
+var ManifestError;
+
cr.define('extensions', function() {
'use strict';
@@ -465,7 +471,8 @@ cr.define('extensions', function() {
/**
* Requests a file's source.
- * @param {RequestFileSourceProperties} args The arguments for the call.
+ * @param {chrome.developerPrivate.RequestFileSourceProperties} args The
+ * arguments for the call.
*/
requestFileSource: function(args) {
chrome.developerPrivate.requestFileSource(
@@ -475,10 +482,10 @@ cr.define('extensions', function() {
/**
* Set the code to be displayed in the code portion of the overlay.
* @see ExtensionErrorOverlay.requestFileSourceResponse().
- * @param {?RequestFileSourceResponse} response The response from the
- * request file source call, which will be shown as code. If |response|
- * is null, then a "Could not display code" message will be displayed
- * instead.
+ * @param {?chrome.developerPrivate.RequestFileSourceResponse} response The
+ * response from the request file source call, which will be shown as
+ * code. If |response| is null, then a "Could not display code" message
+ * will be displayed instead.
*/
onFileSourceResponse_: function(response) {
this.codeDiv_.populate(
diff --git a/chromium/chrome/browser/resources/extensions/extension_list.js b/chromium/chrome/browser/resources/extensions/extension_list.js
index 2bbed63d122..c59e3857daa 100644
--- a/chromium/chrome/browser/resources/extensions/extension_list.js
+++ b/chromium/chrome/browser/resources/extensions/extension_list.js
@@ -66,8 +66,8 @@ cr.define('extensions', function() {
/**
* Compares two extensions for the order they should appear in the list.
- * @param {ExtensionInfo} a The first extension.
- * @param {ExtensionInfo} b The second extension.
+ * @param {chrome.developerPrivate.ExtensionInfo} a The first extension.
+ * @param {chrome.developerPrivate.ExtensionInfo} b The second extension.
* returns {number} -1 if A comes before B, 1 if A comes after B, 0 if equal.
*/
function compareExtensions(a, b) {
@@ -163,7 +163,7 @@ cr.define('extensions', function() {
* @param {!extensions.ExtensionListDelegate} delegate
*/
initialize: function(delegate) {
- /** @private {!Array<ExtensionInfo>} */
+ /** @private {!Array<chrome.developerPrivate.ExtensionInfo>} */
this.extensions_ = [];
/** @private {!extensions.ExtensionListDelegate} */
@@ -408,7 +408,8 @@ cr.define('extensions', function() {
/**
* Synthesizes and initializes an HTML element for the extension metadata
* given in |extension|.
- * @param {!ExtensionInfo} extension A dictionary of extension metadata.
+ * @param {!chrome.developerPrivate.ExtensionInfo} extension A dictionary
+ * of extension metadata.
* @param {?Element} nextWrapper The newly created wrapper will be inserted
* before |nextWrapper| if non-null (else it will be appended to the
* wrapper list).
@@ -602,7 +603,8 @@ cr.define('extensions', function() {
/**
* Updates an HTML element for the extension metadata given in |extension|.
- * @param {!ExtensionInfo} extension A dictionary of extension metadata.
+ * @param {!chrome.developerPrivate.ExtensionInfo} extension A dictionary of
+ * extension metadata.
* @param {!Element} wrapper The extension wrapper element to update.
* @private
*/
@@ -1047,8 +1049,8 @@ cr.define('extensions', function() {
/**
* Updates or creates a wrapper for |extension|.
- * @param {!ExtensionInfo} extension The information about the extension to
- * update.
+ * @param {!chrome.developerPrivate.ExtensionInfo} extension The information
+ * about the extension to update.
* @private
*/
updateOrCreateWrapper_: function(extension) {
diff --git a/chromium/chrome/browser/resources/extensions/extensions.js b/chromium/chrome/browser/resources/extensions/extensions.js
index e957033c9c8..ceeea64b256 100644
--- a/chromium/chrome/browser/resources/extensions/extensions.js
+++ b/chromium/chrome/browser/resources/extensions/extensions.js
@@ -243,7 +243,7 @@ cr.define('extensions', function() {
/**
* [Re]-Populates the page with data representing the current state of
* installed extensions.
- * @param {ProfileInfo} profileInfo
+ * @param {chrome.developerPrivate.ProfileInfo} profileInfo
* @private
*/
update_: function(profileInfo) {
diff --git a/chromium/chrome/browser/resources/extensions/pack_extension_overlay.js b/chromium/chrome/browser/resources/extensions/pack_extension_overlay.js
index 05d23d1f2f9..63b20a4d2de 100644
--- a/chromium/chrome/browser/resources/extensions/pack_extension_overlay.js
+++ b/chromium/chrome/browser/resources/extensions/pack_extension_overlay.js
@@ -97,7 +97,8 @@ cr.define('extensions', function() {
/**
* Handles a response from a packDirectory call.
- * @param {PackDirectoryResponse} response The response of the pack call.
+ * @param {chrome.developerPrivate.PackDirectoryResponse} response The
+ * response of the pack call.
* @private
*/
onPackResponse_: function(response) {
diff --git a/chromium/chrome/browser/resources/feedback/html/sys_info.html b/chromium/chrome/browser/resources/feedback/html/sys_info.html
new file mode 100644
index 00000000000..30fd6a5a767
--- /dev/null
+++ b/chromium/chrome/browser/resources/feedback/html/sys_info.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html i18n-values="dir:textdirection;lang:language">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title i18n-content="sysinfoPageTitle"></title>
+ <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
+ <link rel="stylesheet" href="../../about_sys/about_sys.css">
+ <script src="chrome://resources/js/util.js"></script>
+ <script src="chrome://resources/js/i18n_template_no_process.js"></script>
+ <script src="chrome://resources/js/jstemplate_compiled.js"></script>
+ <script src="../js/sys_info.js"></script>
+ <style>
+ html, body {
+ overflow: visible;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="header">
+ <h1 id="title" i18n-content="sysinfoPageTitle"></h1>
+ <p id="description" i18n-content="sysinfoPageDescription"></p>
+ </div>
+ <div id="content">
+ <h2 id="tableTitle" i18n-content="sysinfoPageTableTitle"></h2>
+ <div id="anchor"></div>
+ <button id="expandAllBtn" class="global-button" i18n-content="sysinfoPageExpandAllBtn"></button>
+ <button id="collapseAllBtn" class="global-button" i18n-content="sysinfoPageCollapseAllBtn"></button>
+ <p id="status" i18n-content="sysinfoPageStatusLoading"></p>
+ <table class="list" id="detailsTable"></table>
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/feedback/js/event_handler.js b/chromium/chrome/browser/resources/feedback/js/event_handler.js
index 1e9d4aae021..315be255a64 100644
--- a/chromium/chrome/browser/resources/feedback/js/event_handler.js
+++ b/chromium/chrome/browser/resources/feedback/js/event_handler.js
@@ -70,6 +70,9 @@ var whitelistedExtensionIds = [
'B206D8716769728278D2D300349C6CB7D7DE2EF9', // http://crbug.com/510270
'EFCF5358672FEE04789FD2EC3638A67ADEDB6C8C', // http://crbug.com/514696
'FAD85BC419FE00995D196312F53448265EFA86F1', // http://crbug.com/516527
+ 'F33B037DEDA65F226B7409C2ADB0CF3F8565AB03', // http://crbug.com/541769
+ '969C788BCBC82FBBE04A17360CA165C23A419257', // http://crbug.com/541769
+ '3BC3740BFC58F06088B300274B4CFBEA20136342', // http://crbug.com/541769
];
diff --git a/chromium/chrome/browser/resources/feedback/js/feedback.js b/chromium/chrome/browser/resources/feedback/js/feedback.js
index e0775f5bc04..b903be5eef6 100644
--- a/chromium/chrome/browser/resources/feedback/js/feedback.js
+++ b/chromium/chrome/browser/resources/feedback/js/feedback.js
@@ -49,6 +49,9 @@ var lastReader = null;
var feedbackInfo = null;
var systemInfo = null;
+var isSystemInfoReady = false;
+var onSystemInfoReadyCallback = null;
+
/**
* Reads the selected file when the user selects a file.
* @param {Event} fileSelectedEvent The onChanged event for the file input box.
@@ -233,6 +236,17 @@ function resizeAppWindow() {
}
/**
+ * @return {Object} the full anonymized system information we got from the
+ * system as well as the extra-app added data.
+ */
+function getFullSystemInformation() {
+ var sysInfo = feedbackInfo.systemInformation;
+ if (systemInfo != null)
+ sysInfo = sysInfo.concat(systemInfo);
+ return sysInfo;
+}
+
+/**
* Initializes our page.
* Flow:
* .) DOMContent Loaded -> . Request feedbackInfo object
@@ -273,6 +287,9 @@ function initialize() {
chrome.feedbackPrivate.getSystemInformation(function(sysInfo) {
systemInfo = sysInfo;
+ isSystemInfoReady = true;
+ if (onSystemInfoReadyCallback != null)
+ onSystemInfoReadyCallback(getFullSystemInformation());
});
// An extension called us with an attached file.
@@ -298,9 +315,38 @@ function initialize() {
i18nTemplate.process(document, loadTimeData);
if ($('sys-info-url')) {
- // Opens a new window showing the current system info.
- $('sys-info-url').onclick =
- windowOpener(SYSINFO_WINDOW_ID, 'chrome://system');
+ // Opens a new window showing the full anonymized system+app
+ // information.
+ $('sys-info-url').onclick = function() {
+ var win = chrome.app.window.get('sys-info-window');
+ if (win) {
+ win.show();
+ return;
+ }
+ chrome.app.window.create(
+ '/html/sys_info.html', {
+ frame: 'chrome',
+ id: 'sys-info-window',
+ width: 600,
+ height: 400,
+ hidden: false,
+ resizable: true
+ }, function(appWindow) {
+ // Define two functions for the newly created window so that it
+ // can retrieve its needed data.
+ appWindow.contentWindow.getFullSystemInfo =
+ function(onSysInfoReady) {
+ if (isSystemInfoReady) {
+ onSysInfoReady(getFullSystemInformation());
+ return;
+ }
+ onSystemInfoReadyCallback = onSysInfoReady;
+ };
+ appWindow.contentWindow.getLoadTimeData = function() {
+ return loadTimeData;
+ };
+ });
+ };
}
if ($('histograms-url')) {
// Opens a new window showing the histogram metrics.
diff --git a/chromium/chrome/browser/resources/feedback/js/sys_info.js b/chromium/chrome/browser/resources/feedback/js/sys_info.js
new file mode 100644
index 00000000000..fcbd37c9ed0
--- /dev/null
+++ b/chromium/chrome/browser/resources/feedback/js/sys_info.js
@@ -0,0 +1,156 @@
+// 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.
+
+/**
+ * The global load time data that contains the localized strings that we will
+ * get from the main page when this page first loads.
+ */
+var loadTimeData = null;
+
+function getValueDivForButton(button) {
+ return $(button.id.substr(0, button.id.length - 4));
+}
+
+function getButtonForValueDiv(valueDiv) {
+ return $(valueDiv.id + '-btn');
+}
+
+/**
+ * Toggles whether an item is collapsed or expanded.
+ */
+function changeCollapsedStatus() {
+ var valueDiv = getValueDivForButton(this);
+ if (valueDiv.parentNode.className == 'number-collapsed') {
+ valueDiv.parentNode.className = 'number-expanded';
+ this.textContent = loadTimeData.getString('sysinfoPageCollapseBtn');
+ } else {
+ valueDiv.parentNode.className = 'number-collapsed';
+ this.textContent = loadTimeData.getString('sysinfoPageExpandBtn');
+ }
+}
+
+/**
+ * Collapses all log items.
+ */
+function collapseAll() {
+ var valueDivs = document.getElementsByClassName('stat-value');
+ for (var i = 0; i < valueDivs.length; i++) {
+ var button = getButtonForValueDiv(valueDivs[i]);
+ if (button && button.className != 'button-hidden') {
+ button.textContent = loadTimeData.getString('sysinfoPageExpandBtn');
+ valueDivs[i].parentNode.className = 'number-collapsed';
+ }
+ }
+}
+
+/**
+ * Expands all log items.
+ */
+function expandAll() {
+ var valueDivs = document.getElementsByClassName('stat-value');
+ for (var i = 0; i < valueDivs.length; i++) {
+ var button = getButtonForValueDiv(valueDivs[i]);
+ if (button && button.className != 'button-hidden') {
+ button.textContent = loadTimeData.getString('sysinfoPageCollapseBtn');
+ valueDivs[i].parentNode.className = 'number-expanded';
+ }
+ }
+}
+
+/**
+ * Collapse only those log items with multi-line values.
+ */
+function collapseMultiLineStrings() {
+ var valueDivs = document.getElementsByClassName('stat-value');
+ var nameDivs = document.getElementsByClassName('stat-name');
+ for (var i = 0; i < valueDivs.length; i++) {
+ var button = getButtonForValueDiv(valueDivs[i]);
+ button.onclick = changeCollapsedStatus;
+ if (valueDivs[i].scrollHeight > (nameDivs[i].scrollHeight * 2)) {
+ button.className = '';
+ button.textContent = loadTimeData.getString('sysinfoPageExpandBtn');
+ valueDivs[i].parentNode.className = 'number-collapsed';
+ } else {
+ button.className = 'button-hidden';
+ valueDivs[i].parentNode.className = 'number';
+ }
+ }
+}
+
+function createNameCell(key) {
+ var nameCell = document.createElement('td');
+ nameCell.setAttribute('class', 'name');
+ var nameDiv = document.createElement('div');
+ nameDiv.setAttribute('class', 'stat-name');
+ nameDiv.appendChild(document.createTextNode(key));
+ nameCell.appendChild(nameDiv);
+ return nameCell;
+}
+
+function createButtonCell(key) {
+ var buttonCell = document.createElement('td');
+ buttonCell.setAttribute('class', 'button-cell');
+ var button = document.createElement('button');
+ button.setAttribute('id', '' + key + '-value-btn');
+ buttonCell.appendChild(button);
+ return buttonCell;
+}
+
+function createValueCell(key, value) {
+ var valueCell = document.createElement('td');
+ var valueDiv = document.createElement('div');
+ valueDiv.setAttribute('class', 'stat-value');
+ valueDiv.setAttribute('id', '' + key + '-value');
+ valueDiv.appendChild(document.createTextNode(value));
+ valueCell.appendChild(valueDiv);
+ return valueCell;
+}
+
+function createTableRow(key, value) {
+ var row = document.createElement('tr');
+ row.appendChild(createNameCell(key));
+ row.appendChild(createButtonCell(key));
+ row.appendChild(createValueCell(key, value));
+ return row;
+}
+
+/**
+ * Builds the system information table row by row.
+ * @param {Element} table The DOM table element to which the newly created rows
+ * will be appended.
+ * @param {Object} systemInfo The system information that will be used to fill
+ * the table.
+ */
+function createTable(table, systemInfo) {
+ for (var key in systemInfo) {
+ var item = systemInfo[key];
+ table.appendChild(createTableRow(item['key'], item['value']));
+ }
+}
+
+/**
+ * The callback which will be invoked by the parent window, when the system
+ * information is ready.
+ * @param {Object} systemInfo The system information that will be used to fill
+ * the table.
+ */
+function onSysInfoReady(systemInfo) {
+ createTable($('detailsTable'), systemInfo);
+
+ $('collapseAllBtn').onclick = collapseAll;
+ $('expandAllBtn').onclick = expandAll;
+
+ collapseMultiLineStrings();
+
+ $('status').textContent = '';
+}
+
+/**
+ * Initializes the page when the window is loaded.
+ */
+window.onload = function() {
+ loadTimeData = getLoadTimeData();
+ i18nTemplate.process(document, loadTimeData);
+ getFullSystemInfo(onSysInfoReady);
+};
diff --git a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
index 64627402bb7..2407ffa3582 100644
--- a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
+++ b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -68,7 +68,6 @@ cr.define('cr.login', function() {
'gaiaUrl', // Gaia url to use.
'gaiaPath', // Gaia path to use without a leading slash.
'hl', // Language code for the user interface.
- 'email', // Pre-fill the email field in Gaia UI.
'service', // Name of Gaia service.
'continueUrl', // Continue url to use.
'frameUrl', // Initial frame URL to use. If empty defaults to
@@ -85,11 +84,30 @@ cr.define('cr.login', function() {
'enterpriseDomain', // Domain in which hosting device is (or should be)
// enrolled.
'emailDomain', // Value used to prefill domain for email.
+ 'chromeType', // Type of Chrome OS device, e.g. "chromebox".
'clientVersion', // Version of the Chrome build.
'platformVersion', // Version of the OS build.
'releaseChannel', // Installation channel.
'endpointGen', // Current endpoint generation.
'gapsCookie', // GAPS cookie
+
+ // The email fields allow for the following possibilities:
+ //
+ // 1/ If 'email' is not supplied, then the email text field is blank and the
+ // user must type an email to proceed.
+ //
+ // 2/ If 'email' is supplied, and 'readOnlyEmail' is truthy, then the email
+ // is hardcoded and the user cannot change it. The user is asked for
+ // password. This is useful for re-auth scenarios, where chrome needs the
+ // user to authenticate for a specific account and only that account.
+ //
+ // 3/ If 'email' is supplied, and 'readOnlyEmail' is falsy, gaia will
+ // prefill the email text field using the given email address, but the user
+ // can still change it and then proceed. This is used on desktop when the
+ // user disconnects their profile then reconnects, to encourage them to use
+ // the same account.
+ 'email',
+ 'readOnlyEmail',
];
/**
@@ -202,7 +220,7 @@ cr.define('cr.login', function() {
this.continueUrl_.substring(0, this.continueUrl_.indexOf('?')) ||
this.continueUrl_;
this.isConstrainedWindow_ = data.constrained == '1';
- this.isNewGaiaFlowChromeOS = data.isNewGaiaFlowChromeOS;
+ this.isNewGaiaFlow = data.isNewGaiaFlow;
this.useEafe_ = data.useEafe || false;
this.clientId_ = data.clientId;
this.gapsCookie_ = data.gapsCookie;
@@ -218,7 +236,7 @@ cr.define('cr.login', function() {
this.idpOrigin_.indexOf('https://') == 0;
this.needPassword = !('needPassword' in data) || data.needPassword;
- if (this.isNewGaiaFlowChromeOS) {
+ if (this.isNewGaiaFlow) {
this.webview_.contextMenus.onShow.addListener(function(e) {
e.preventDefault();
});
@@ -247,13 +265,13 @@ cr.define('cr.login', function() {
Authenticator.prototype.constructInitialFrameUrl_ = function(data) {
var path = data.gaiaPath;
- if (!path && this.isNewGaiaFlowChromeOS)
+ if (!path && this.isNewGaiaFlow)
path = EMBEDDED_SETUP_CHROMEOS_ENDPOINT;
if (!path)
path = IDP_PATH;
var url = this.idpOrigin_ + path;
- if (this.isNewGaiaFlowChromeOS) {
+ if (this.isNewGaiaFlow) {
if (data.chromeType)
url = appendParam(url, 'chrometype', data.chromeType);
if (data.clientId)
@@ -276,8 +294,13 @@ cr.define('cr.login', function() {
url = appendParam(url, 'hl', data.hl);
if (data.gaiaId)
url = appendParam(url, 'user_id', data.gaiaId);
- if (data.email)
- url = appendParam(url, 'Email', data.email);
+ if (data.email) {
+ if (data.readOnlyEmail) {
+ url = appendParam(url, 'Email', data.email);
+ } else {
+ url = appendParam(url, 'email_hint', data.email);
+ }
+ }
if (this.isConstrainedWindow_)
url = appendParam(url, 'source', CONSTRAINED_FLOW_SOURCE);
if (data.flow)
@@ -294,7 +317,8 @@ cr.define('cr.login', function() {
Authenticator.prototype.onRequestCompleted_ = function(details) {
var currentUrl = details.url;
- if (currentUrl.lastIndexOf(this.continueUrlWithoutParams_, 0) == 0) {
+ if (!this.isNewGaiaFlow &&
+ currentUrl.lastIndexOf(this.continueUrlWithoutParams_, 0) == 0) {
if (currentUrl.indexOf('ntp=1') >= 0)
this.skipForNow_ = true;
@@ -397,7 +421,7 @@ cr.define('cr.login', function() {
var location = decodeURIComponent(header.value);
this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/);
} else if (
- this.isNewGaiaFlowChromeOS && headerName == SET_COOKIE_HEADER) {
+ this.isNewGaiaFlow && headerName == SET_COOKIE_HEADER) {
var headerValue = header.value;
if (headerValue.indexOf(OAUTH_CODE_COOKIE + '=', 0) == 0) {
this.oauthCode_ =
@@ -444,7 +468,7 @@ cr.define('cr.login', function() {
Authenticator.prototype.onBeforeSendHeaders_ = function(details) {
// We should re-send cookie if first request was unsuccessful (i.e. no new
// GAPS cookie was received).
- if (this.isNewGaiaFlowChromeOS && this.gapsCookie_ &&
+ if (this.isNewGaiaFlow && this.gapsCookie_ &&
(!this.gapsCookieSent_ || !this.newGapsCookie_)) {
var headers = details.requestHeaders;
var found = false;
@@ -742,10 +766,8 @@ cr.define('cr.login', function() {
* @private
*/
Authenticator.prototype.onLoadCommit_ = function(e) {
- if (this.oauthCode_) {
- this.skipForNow_ = true;
+ if (this.oauthCode_)
this.maybeCompleteAuth_();
- }
};
/**
diff --git a/chromium/chrome/browser/resources/gesture_config.css b/chromium/chrome/browser/resources/gesture_config.css
deleted file mode 100644
index 71030769fd3..00000000000
--- a/chromium/chrome/browser/resources/gesture_config.css
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-body {
- font-size: 12px;
-}
-
-form {
- display: table;
- margin: 8px;
-}
-
-h2 {
- border-bottom: 1px solid rgb(238, 238, 238);
- color: rgb(48, 57, 66);
-}
-
-.buttons-pane {
- display: inline-block;
- width: 100%;
-}
-
-#reset-all-button {
- float: right;
- min-width: 15em;
-}
-
-html[dir=rtl] #reset-all-button {
- float: left;
-}
-
-.input {
- text-align: right;
- width: 110px;
-}
-
-html[dir=rtl] .input {
- text-align: left;
-}
-
-.row {
- display: table-row;
-}
-
-.row-label {
- display: table-cell;
- font-size: 16px;
- text-align: right;
- width: 370px;
-}
-
-html[dir=rtl] .row-label {
- text-align: left;
-}
-
-.row-input {
- display: table-cell;
-}
-
-.row-units {
- display: table-cell;
- text-align: left;
- width: 100px;
-}
-
-html[dir=rtl] .row-units {
- text-align: right;
-}
-
-.row-reset {
- display: table-cell;
- font-size: 12px;
- width: 100%;
-}
-
-.section-properties {
- border-spacing: 8px;
- display: table;
-}
-
-#section-row-template,
-#section-template {
- display: none;
-}
diff --git a/chromium/chrome/browser/resources/gesture_config.html b/chromium/chrome/browser/resources/gesture_config.html
deleted file mode 100644
index 4a2d575a0f9..00000000000
--- a/chromium/chrome/browser/resources/gesture_config.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <meta charset="utf-8">
- <title>Gesture Preferences</title>
- <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
- <link rel="stylesheet" href="chrome://resources/css/widgets.css">
- <link rel="stylesheet" href="gesture_config.css">
- <script src="gesture_config.js"></script>
-</head>
-<body>
-<form>
- <div class="buttons-pane">
- <button id="reset-all-button">Reset All</button>
- </div>
- <div id="gesture-form"></div>
-</form>
-<div id="section-template">
- <h2 class="section-title"></h2>
- <div class="section-properties">
- <!-- Section rows are inserted here. -->
- </div>
-</div>
-<div id="section-row-template" class="row">
- <label class="row-label"></label>
- <div class="row-input">
- <input class="input" type="number" size="20">
- </div>
- <div class="row-units"></div>
- <button class="row-reset">Reset</button>
-</div>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/gesture_config.js b/chromium/chrome/browser/resources/gesture_config.js
deleted file mode 100644
index 2e5ac484fff..00000000000
--- a/chromium/chrome/browser/resources/gesture_config.js
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Redefine '$' here rather than including 'cr.js', since this is
-// the only function needed. This allows this file to be loaded
-// in a browser directly for layout and some testing purposes.
-var $ = function(id) { return document.getElementById(id); };
-
-/**
- * A generic WebUI for configuring preference values used by Chrome's gesture
- * recognition systems.
- * @param {string} title The user-visible title to display for the configuration
- * section.
- * @param {string} prefix The prefix for the configuration fields.
- * @param {!Object} fields An array of fields that contain the name of the pref
- * and user-visible labels.
- */
-function GeneralConfig(title, prefix, fields) {
- this.title = title;
- this.prefix = prefix;
- this.fields = fields;
-}
-
-GeneralConfig.prototype = {
- /**
- * Sets up the form for configuring all the preference values.
- */
- buildAll: function() {
- this.buildForm();
- this.loadForm();
- this.initForm();
- },
-
- /**
- * Dynamically builds web-form based on the list of preferences.
- */
- buildForm: function() {
- var buf = [];
-
- var section = $('section-template').cloneNode(true);
- section.removeAttribute('id');
- var title = section.querySelector('.section-title');
- title.textContent = this.title;
-
- for (var i = 0; i < this.fields.length; i++) {
- var field = this.fields[i];
-
- var row = $('section-row-template').cloneNode(true);
- row.removeAttribute('id');
-
- var label = row.querySelector('.row-label');
- var input = row.querySelector('.input');
- var units = row.querySelector('.row-units');
- var reset = row.querySelector('.row-reset');
-
- label.setAttribute('for', field.key);
- label.innerHTML = field.label;
- input.id = field.key;
- input.min = field.min || 0;
-
- if (field.max)
- input.max = field.max;
-
- input.step = field.step || 'any';
-
- if (field.units)
- units.innerHTML = field.units;
-
- reset.id = field.key + '-reset';
- gesture_config.updateResetButton(reset, true);
-
- section.querySelector('.section-properties').appendChild(row);
- }
- $('gesture-form').appendChild(section);
- },
-
- /**
- * Initializes the form by adding appropriate event listeners to elements.
- */
- initForm: function() {
- for (var i = 0; i < this.fields.length; i++) {
- var field = this.fields[i];
- var config = this;
- $(field.key).onchange = (function(key) {
- config.setPreferenceValue(key, $(key).value);
- gesture_config.updateResetButton($(key + '-reset'), false);
- gesture_config.updateResetAllButton(false);
- }).bind(null, field.key);
- $(field.key + '-reset').onclick = (function(key) {
- config.resetPreferenceValue(key);
- }).bind(null, field.key);
- }
- },
-
- /**
- * Requests preference values for all the relevant fields.
- */
- loadForm: function() {
- for (var i = 0; i < this.fields.length; i++)
- this.updatePreferenceValue(this.fields[i].key);
- },
-
- /**
- * Handles processing of "Reset All" button.
- * Causes all form values to be updated based on current preference values.
- * @return {boolean} Returns false.
- */
- onReset: function() {
- for (var i = 0; i < this.fields.length; i++) {
- var field = this.fields[i];
- this.resetPreferenceValue(field.key);
- }
- return false;
- },
-
- /**
- * Requests a preference setting's value.
- * This method is asynchronous; the result is provided by a call to
- * updatePreferenceValueResult.
- * @param {string} prefName The name of the preference value being requested.
- */
- updatePreferenceValue: function(prefName) {
- chrome.send('updatePreferenceValue', [this.prefix + prefName]);
- },
-
- /**
- * Sets a preference setting's value.
- * @param {string} prefName The name of the preference value being set.
- * @param {value} value The value to be associated with prefName.
- */
- setPreferenceValue: function(prefName, value) {
- chrome.send('setPreferenceValue',
- [this.prefix + prefName, parseFloat(value)]);
- },
-
- /**
- * Resets a preference to its default value and get that callback
- * to updatePreferenceValueResult with the new value of the preference.
- * @param {string} prefName The name of the requested preference.
- */
- resetPreferenceValue: function(prefName) {
- chrome.send('resetPreferenceValue', [this.prefix + prefName]);
- }
-};
-
-/**
- * Returns a GeneralConfig for configuring gestures.* preferences.
- * @return {object} A GeneralConfig object.
- */
-function GestureConfig() {
- /** The title of the section for the gesture preferences. **/
- /** @const */ var GESTURE_TITLE = 'Gesture Configuration';
-
- /** Common prefix of gesture preferences. **/
- /** @const */ var GESTURE_PREFIX = 'gesture.';
-
- /** List of fields used to dynamically build form. **/
- var GESTURE_FIELDS = [
- {
- key: 'fling_max_cancel_to_down_time_in_ms',
- label: 'Maximum Cancel to Down Time for Tap Suppression',
- units: 'milliseconds',
- },
- {
- key: 'fling_max_tap_gap_time_in_ms',
- label: 'Maximum Tap Gap Time for Tap Suppression',
- units: 'milliseconds',
- },
- {
- key: 'semi_long_press_time_in_ms',
- label: 'Semi Long Press Time',
- units: 'milliseconds',
- },
- {
- key: 'max_separation_for_gesture_touches_in_pixels',
- label: 'Maximum Separation for Gesture Touches',
- units: 'pixels'
- },
- {
- key: 'tab_scrub_activation_delay_in_ms',
- label: 'Tab scrub auto activation delay, (-1 for never)',
- units: 'milliseconds'
- }
- ];
-
- return new GeneralConfig(GESTURE_TITLE, GESTURE_PREFIX, GESTURE_FIELDS);
-}
-
-/**
- * Returns a GeneralConfig for configuring overscroll.* preferences.
- * @return {object} A GeneralConfig object.
- */
-function OverscrollConfig() {
- /** @const */ var OVERSCROLL_TITLE = 'Overscroll Configuration';
-
- /** @const */ var OVERSCROLL_PREFIX = 'overscroll.';
-
- var OVERSCROLL_FIELDS = [
- {
- key: 'horizontal_threshold_complete',
- label: 'Complete when overscrolled (horizontal)',
- units: '%'
- },
- {
- key: 'vertical_threshold_complete',
- label: 'Complete when overscrolled (vertical)',
- units: '%'
- },
- {
- key: 'minimum_threshold_start_touchpad',
- label: 'Start overscroll gesture (horizontal; touchpad)',
- units: 'pixels'
- },
- {
- key: 'minimum_threshold_start',
- label: 'Start overscroll gesture (horizontal; touchscreen)',
- units: 'pixels'
- },
- {
- key: 'vertical_threshold_start',
- label: 'Start overscroll gesture (vertical)',
- units: 'pixels'
- },
- {
- key: 'horizontal_resist_threshold',
- label: 'Start resisting overscroll after (horizontal)',
- units: 'pixels'
- },
- {
- key: 'vertical_resist_threshold',
- label: 'Start resisting overscroll after (vertical)',
- units: 'pixels'
- },
- ];
-
- return new GeneralConfig(OVERSCROLL_TITLE,
- OVERSCROLL_PREFIX,
- OVERSCROLL_FIELDS);
-}
-
-/**
- * WebUI instance for configuring preference values related to gesture input.
- */
-window.gesture_config = {
- /**
- * Build and initialize the gesture configuration form.
- */
- initialize: function() {
- var g = GestureConfig();
- g.buildAll();
-
- var o = OverscrollConfig();
- o.buildAll();
-
- $('reset-all-button').onclick = function() {
- g.onReset();
- o.onReset();
- };
- },
-
- /**
- * Checks if all gesture preferences are set to default by checking the status
- * of the reset button associated with each preference.
- * @return {boolean} True if all gesture preferences are set to default.
- */
- areAllPrefsSetToDefault: function() {
- var resets = $('gesture-form').querySelectorAll('.row-reset');
- for (var i = 0; i < resets.length; i++) {
- if (!resets[i].disabled)
- return false;
- }
- return true;
- },
-
- /**
- * Updates the status and label of a preference reset button.
- * @param {HTMLInputElement} resetButton Reset button for the preference.
- * @param {boolean} isDefault Whether the preference is set to the default
- * value.
- */
- updateResetButton: function(resetButton, isDefault) {
- /** @const */ var TITLE_DEFAULT = 'Default';
-
- /** @const */ var TITLE_NOT_DEFAULT = 'Reset';
-
- resetButton.innerHTML = isDefault ? TITLE_DEFAULT : TITLE_NOT_DEFAULT;
- resetButton.disabled = isDefault;
- },
-
- /**
- * Updates the status and label of "Reset All" button.
- * @param {boolean} isDefault Whether all preference are set to their default
- * values.
- */
- updateResetAllButton: function(isDefault) {
- /** @const */ var TITLE_DEFAULT = 'Everything is set to default';
-
- /** @const */ var TITLE_NOT_DEFAULT = 'Reset All To Default';
-
- var button = $('reset-all-button');
- button.innerHTML = isDefault ? TITLE_DEFAULT : TITLE_NOT_DEFAULT;
- button.disabled = isDefault;
- },
-
- /**
- * Handle callback from call to updatePreferenceValue.
- * @param {string} prefName The name of the requested preference value.
- * @param {value} value The current value associated with prefName.
- * @param {boolean} isDefault Whether the value is the default value.
- */
- updatePreferenceValueResult: function(prefName, value, isDefault) {
- prefName = prefName.substring(prefName.indexOf('.') + 1);
- $(prefName).value = value;
- this.updateResetButton($(prefName + '-reset'), isDefault);
- this.updateResetAllButton(this.areAllPrefsSetToDefault());
- },
-};
-
-document.addEventListener('DOMContentLoaded', gesture_config.initialize);
diff --git a/chromium/chrome/browser/resources/hangout_services/manifest.json b/chromium/chrome/browser/resources/hangout_services/manifest.json
index 211426e16f2..92255eb9237 100644
--- a/chromium/chrome/browser/resources/hangout_services/manifest.json
+++ b/chromium/chrome/browser/resources/hangout_services/manifest.json
@@ -5,7 +5,7 @@
"name": "Google Hangouts",
// Note: Always update the version number when this file is updated. Chrome
// triggers extension preferences update on the version increase.
- "version": "1.1.2",
+ "version": "1.2.0",
"manifest_version": 2,
"externally_connectable": {
"matches": [
diff --git a/chromium/chrome/browser/resources/hangout_services/thunk.js b/chromium/chrome/browser/resources/hangout_services/thunk.js
index d03a8318240..db150069907 100644
--- a/chromium/chrome/browser/resources/hangout_services/thunk.js
+++ b/chromium/chrome/browser/resources/hangout_services/thunk.js
@@ -41,10 +41,6 @@ chrome.runtime.onMessageExternal.addListener(
requestInfo['guestProcessId'] = sender.guestProcessId;
}
- if (sender.guestRenderFrameRoutingId) {
- requestInfo['guestRenderFrameId'] = sender.guestRenderFrameRoutingId;
- }
-
var method = message['method'];
var origin = getHost(sender.url);
if (method == 'cpu.getInfo') {
@@ -167,6 +163,15 @@ chrome.runtime.onMessageExternal.addListener(
chrome.webrtcLoggingPrivate.stopRtpDump(
requestInfo, origin, incoming, outgoing, doSendResponse);
return true;
+ } else if (method == 'logging.startAudioDebugRecordings') {
+ var seconds = message['seconds'] || 0;
+ chrome.webrtcLoggingPrivate.startAudioDebugRecordings(
+ requestInfo, origin, seconds, doSendResponse);
+ return true;
+ } else if (method == 'logging.stopAudioDebugRecordings') {
+ chrome.webrtcLoggingPrivate.stopAudioDebugRecordings(
+ requestInfo, origin, doSendResponse);
+ return true;
}
throw new Error('Unknown method: ' + method);
} catch (e) {
diff --git a/chromium/chrome/browser/resources/help/help_content.css b/chromium/chrome/browser/resources/help/help_content.css
index fb367d15a3a..4f09ff20131 100644
--- a/chromium/chrome/browser/resources/help/help_content.css
+++ b/chromium/chrome/browser/resources/help/help_content.css
@@ -86,6 +86,11 @@
background-size: 18px;
}
+#update-status-icon.disabled-by-admin {
+ background-image: url(../../../../ui/webui/resources/images/business.svg);
+ background-size: 18px;
+}
+
#update-status-message-container {
display: inline-block;
vertical-align: middle;
diff --git a/chromium/chrome/browser/resources/help/help_content.html b/chromium/chrome/browser/resources/help/help_content.html
index 158c755fbba..0e032aa4e0e 100644
--- a/chromium/chrome/browser/resources/help/help_content.html
+++ b/chromium/chrome/browser/resources/help/help_content.html
@@ -30,7 +30,7 @@
<div id="update-status-message-container">
<div id="update-status-message" i18n-content="updateCheckStarted">
</div>
-<if expr="is_macosx">
+<if expr="is_macosx or is_win">
<div id="update-obsolete-system-container" hidden>
<span id="update-obsolete-system"
i18n-content="updateObsoleteSystem"></span>
diff --git a/chromium/chrome/browser/resources/help/help_page.js b/chromium/chrome/browser/resources/help/help_page.js
index d3d53dc50c5..4269098fc15 100644
--- a/chromium/chrome/browser/resources/help/help_page.js
+++ b/chromium/chrome/browser/resources/help/help_page.js
@@ -165,7 +165,9 @@ cr.define('help', function() {
var logo = $('product-logo');
logo.onclick = function(e) {
logo.classList.remove('spin');
- setTimeout(function() { logo.classList.add('spin'); }, 0);
+ // Force a style recalc that cancels the animation specified by "spin".
+ getComputedStyle(logo).getPropertyValue('animation-name');
+ logo.classList.add('spin');
};
// Attempt to update.
@@ -330,6 +332,9 @@ cr.define('help', function() {
} else if (status == 'failed') {
this.setUpdateImage_('failed');
$('update-status-message').innerHTML = message;
+ } else if (status == 'disabled_by_admin') {
+ this.setUpdateImage_('disabled-by-admin');
+ $('update-status-message').innerHTML = message;
}
if (cr.isChromeOS) {
@@ -427,7 +432,7 @@ cr.define('help', function() {
* @private
*/
setObsoleteSystem_: function(obsolete) {
- if (cr.isMac && $('update-obsolete-system-container')) {
+ if ($('update-obsolete-system-container')) {
$('update-obsolete-system-container').hidden = !obsolete;
}
},
@@ -438,8 +443,7 @@ cr.define('help', function() {
* @private
*/
setObsoleteSystemEndOfTheLine_: function(endOfTheLine) {
- if (cr.isMac &&
- $('update-obsolete-system-container') &&
+ if ($('update-obsolete-system-container') &&
!$('update-obsolete-system-container').hidden &&
$('update-status-message')) {
$('update-status-message').hidden = endOfTheLine;
diff --git a/chromium/chrome/browser/resources/history/history.js b/chromium/chrome/browser/resources/history/history.js
index 40a336123f9..3ea486d1f9a 100644
--- a/chromium/chrome/browser/resources/history/history.js
+++ b/chromium/chrome/browser/resources/history/history.js
@@ -1966,6 +1966,16 @@ function load() {
window.addEventListener(
'resize', historyView.updateClearBrowsingDataButton_);
+<if expr="is_ios">
+ // Trigger window resize event when search field is focused to force update
+ // of the clear browsing button, which should disappear when search field
+ // is active. The window is not resized when the virtual keyboard is shown
+ // on iOS.
+ searchField.addEventListener('focus', function() {
+ cr.dispatchSimpleEvent(window, 'resize');
+ });
+</if> /* is_ios */
+
// When the search field loses focus, add a delay before updating the
// visibility, otherwise the button will flash on the screen before the
// keyboard animates away.
diff --git a/chromium/chrome/browser/resources/history/other_devices.js b/chromium/chrome/browser/resources/history/other_devices.js
index 15d7d47a48c..8f46192d61f 100644
--- a/chromium/chrome/browser/resources/history/other_devices.js
+++ b/chromium/chrome/browser/resources/history/other_devices.js
@@ -24,7 +24,8 @@
COLLAPSE_SESSION: 6,
EXPAND_SESSION: 7,
OPEN_ALL: 8,
- LIMIT: 9 // Should always be the last one.
+ HAS_FOREIGN_DATA: 9,
+ LIMIT: 10 // Should always be the last one.
};
/**
@@ -353,6 +354,7 @@ function DevicesView() {
this.rowHeights_ = [NB_ENTRIES_FIRST_ROW_COLUMN];
this.focusGrids_ = [];
this.updateSignInState(loadTimeData.getBoolean('isUserSignedIn'));
+ this.hasSeenForeignData_ = false;
recordUmaEvent_(HISTOGRAM_EVENT.INITIALIZED);
}
@@ -379,6 +381,14 @@ DevicesView.prototype.setSessionList = function(sessionList) {
for (var i = 0; i < sessionList.length; i++)
this.devices_.push(new Device(sessionList[i], this));
this.displayResults_();
+
+ // This metric should only be emitted if we see foreign data, and it should
+ // only be emitted once per page refresh. Flip flag to remember because this
+ // method is called upon any update.
+ if (!this.hasSeenForeignData_ && sessionList.length > 0) {
+ this.hasSeenForeignData_ = true;
+ recordUmaEvent_(HISTOGRAM_EVENT.HAS_FOREIGN_DATA);
+ }
};
diff --git a/chromium/chrome/browser/resources/inline_login/inline_login.js b/chromium/chrome/browser/resources/inline_login/inline_login.js
index 684216a9b2b..80398495e6b 100644
--- a/chromium/chrome/browser/resources/inline_login/inline_login.js
+++ b/chromium/chrome/browser/resources/inline_login/inline_login.js
@@ -27,6 +27,7 @@ cr.define('inline.login', function() {
function onAuthReady(e) {
$('contents').classList.toggle('loading', false);
authReadyFired = true;
+ chrome.send('metricsHandler:recordAction', ['Signin_SigninPage_Shown']);
}
function onDropLink(e) {
diff --git a/chromium/chrome/browser/resources/inspect/inspect.css b/chromium/chrome/browser/resources/inspect/inspect.css
index b173b1afdf9..cf72748f660 100644
--- a/chromium/chrome/browser/resources/inspect/inspect.css
+++ b/chromium/chrome/browser/resources/inspect/inspect.css
@@ -350,6 +350,7 @@ img {
border: 1px solid transparent;
line-height: 20px;
margin: 4px;
+ min-width: 0;
padding: 0 3px;
}
diff --git a/chromium/chrome/browser/resources/inspect/inspect.js b/chromium/chrome/browser/resources/inspect/inspect.js
index bfaa219b2d7..b8747ff040a 100644
--- a/chromium/chrome/browser/resources/inspect/inspect.js
+++ b/chromium/chrome/browser/resources/inspect/inspect.js
@@ -748,6 +748,7 @@ function createConfigLine(port, location) {
var newSelection = line.nextElementSibling;
line.parentNode.removeChild(line);
selectLine(newSelection);
+ commitPortForwardingConfig(false);
});
line.appendChild(lineDelete);
diff --git a/chromium/chrome/browser/resources/local_discovery/local_discovery.js b/chromium/chrome/browser/resources/local_discovery/local_discovery.js
index 9d437aa7217..3e2fb1b8ad5 100644
--- a/chromium/chrome/browser/resources/local_discovery/local_discovery.js
+++ b/chromium/chrome/browser/resources/local_discovery/local_discovery.js
@@ -416,6 +416,13 @@ cr.define('local_discovery', function() {
$('register-login-promo').hidden = isUserLoggedIn ||
isUserSupervisedOrOffTheRecord;
}
+ if (!($('register-login-promo').hidden) ||
+ !($('cloud-devices-login-promo').hidden) ||
+ !($('register-overlay-login-promo').hidden)) {
+ chrome.send(
+ 'metricsHandler:recordAction',
+ ['Signin_Impression_FromDevicesPage']);
+ }
}
/**
diff --git a/chromium/chrome/browser/resources/local_ntp/OWNERS b/chromium/chrome/browser/resources/local_ntp/OWNERS
index a7215af69ac..6d4196126a1 100644
--- a/chromium/chrome/browser/resources/local_ntp/OWNERS
+++ b/chromium/chrome/browser/resources/local_ntp/OWNERS
@@ -2,4 +2,5 @@ jered@chromium.org
jeremycho@chromium.org
samarth@chromium.org
mathp@chromium.org
+fserb@chromium.org
huangs@chromium.org
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.css b/chromium/chrome/browser/resources/local_ntp/local_ntp.css
index 4f80b30a79d..184560e9cc3 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.css
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.css
@@ -6,7 +6,6 @@
* body tag. */
body {
background-attachment: fixed !important;
- background-color: white;
cursor: default;
font-family: arial, sans-serif;
font-size: small;
@@ -39,17 +38,17 @@ body.fakebox-disable #fakebox > input {
}
#logo {
- background-image: url(images/google_logo.png@2x);
+ background-image: url(../../../../ui/webui/resources/images/google_logo.svg);
background-repeat: no-repeat;
- background-size: 269px 95px;
- height: 95px;
+ height: 92px;
margin-bottom: 24px;
margin-top: 157px;
- width: 269px;
+ width: 272px;
}
body.alternate-logo #logo {
- -webkit-mask-image: url(images/google_logo.png@2x);
+ -webkit-mask-image:
+ url(../../../../ui/webui/resources/images/google_logo.svg);
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 100%;
background: #eee;
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.html b/chromium/chrome/browser/resources/local_ntp/local_ntp.html
index 2b3e1e4f7a3..8db7c1d6756 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.html
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.html
@@ -4,9 +4,10 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<head>
+ <link rel="stylesheet" href="chrome-search://local-ntp/theme.css"></link>
+ <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp.css"></link>
<script src="chrome-search://local-ntp/config.js"></script>
<script src="chrome-search://local-ntp/local-ntp.js"></script>
- <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp.css"></link>
<meta charset="utf-8">
<meta name="google" value="notranslate">
</head>
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.js b/chromium/chrome/browser/resources/local_ntp/local_ntp.js
index 9d3ce86c972..dcb64601c80 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.js
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.js
@@ -77,7 +77,7 @@ var NTP_DESIGN = {
showFavicon: true,
thumbnailTextColor: [50, 50, 50, 255],
thumbnailFallback: 'dot', // Draw single dot.
- tileWidth: 154,
+ tileWidth: 156,
tileMargin: 16,
titleColor: [50, 50, 50, 255],
titleColorAgainstDark: [210, 210, 210, 255],
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 d2d356f9f7d..66f286a85ae 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.css
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.css
@@ -81,7 +81,7 @@ a:visited {
height: calc(130px - 2px);
line-height: 100%;
margin: 0 8px;
- width: calc(156px - 2px);
+ width: 156px;
}
.icon-ntp .mv-tile,
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 6c51584b543..98ebea550ab 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
@@ -300,10 +300,8 @@ var addTile = function(args) {
window.devicePixelRatio + 'x/' + data.renderViewId + '/' + data.tid;
}
tiles.appendChild(renderTile(data));
- logEvent(LOG_TYPE.NTP_CLIENT_SIDE_SUGGESTION);
} else if (args.id) {
tiles.appendChild(renderTile(args));
- logEvent(LOG_TYPE.NTP_SERVER_SIDE_SUGGESTION);
} else {
tiles.appendChild(renderTile(null));
}
diff --git a/chromium/chrome/browser/resources/md_downloads/action_service.html b/chromium/chrome/browser/resources/md_downloads/action_service.html
index 1adb058eb5c..0dce3440a71 100644
--- a/chromium/chrome/browser/resources/md_downloads/action_service.html
+++ b/chromium/chrome/browser/resources/md_downloads/action_service.html
@@ -1,4 +1,4 @@
<link rel="import" href="chrome://resources/html/assert.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://downloads/i18n_setup.html">
<script src="chrome://downloads/action_service.js"></script>
diff --git a/chromium/chrome/browser/resources/md_downloads/action_service.js b/chromium/chrome/browser/resources/md_downloads/action_service.js
index f984fe5a146..e065ee9d97f 100644
--- a/chromium/chrome/browser/resources/md_downloads/action_service.js
+++ b/chromium/chrome/browser/resources/md_downloads/action_service.js
@@ -12,7 +12,31 @@ cr.define('downloads', function() {
}
/** @constructor */
- function ActionService() {}
+ function ActionService() {
+ /** @private {Array<string>} */
+ this.searchTerms_ = [];
+ }
+
+ /**
+ * @param {string} s
+ * @return {string} |s| without whitespace at the beginning or end.
+ */
+ function trim(s) { return s.trim(); }
+
+ /**
+ * @param {string|undefined} value
+ * @return {boolean} Whether |value| is truthy.
+ */
+ function truthy(value) { return !!value; }
+
+ /**
+ * @param {string} searchText Input typed by the user into a search box.
+ * @return {Array<string>} A list of terms extracted from |searchText|.
+ */
+ ActionService.splitTerms = function(searchText) {
+ // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']).
+ return searchText.split(/"([^"]*)"/).map(trim).filter(truthy);
+ };
ActionService.prototype = {
/** @param {string} id ID of the download to cancel. */
@@ -40,12 +64,17 @@ cr.define('downloads', function() {
/** @param {string} id ID of the download that the user started dragging. */
drag: chromeSendWithId('drag'),
+ /** Loads more downloads with the current search terms. */
+ loadMore: function() {
+ chrome.send('getDownloads', this.searchTerms_);
+ },
+
/**
* @return {boolean} Whether the user is currently searching for downloads
* (i.e. has a non-empty search term).
*/
isSearching: function() {
- return this.searchText_.length > 0;
+ return this.searchTerms_.length > 0;
},
/** Opens the current local destination for downloads. */
@@ -73,14 +102,19 @@ cr.define('downloads', function() {
/** @param {string} searchText What to search for. */
search: function(searchText) {
- if (this.searchText_ == searchText)
- return;
+ var searchTerms = ActionService.splitTerms(searchText);
+ var sameTerms = searchTerms.length == this.searchTerms_.length;
+
+ for (var i = 0; sameTerms && i < searchTerms.length; ++i) {
+ if (searchTerms[i] != this.searchTerms_[i])
+ sameTerms = false;
+ }
- this.searchText_ = searchText;
+ if (sameTerms)
+ return;
- // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']).
- function trim(s) { return s.trim(); }
- chrome.send('getDownloads', searchText.split(/"([^"]*)"/).map(trim));
+ this.searchTerms_ = searchTerms;
+ this.loadMore();
},
/**
diff --git a/chromium/chrome/browser/resources/md_downloads/action_service_unittest.gtestjs b/chromium/chrome/browser/resources/md_downloads/action_service_unittest.gtestjs
new file mode 100644
index 00000000000..9f850352f75
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_downloads/action_service_unittest.gtestjs
@@ -0,0 +1,39 @@
+// 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.
+
+/**
+ * @param {!Array<string>} list
+ * @return {string}
+ */
+function str(list) {
+ return JSON.stringify(list);
+}
+
+/**
+ * @extends {testing.Test}
+ * @constructor
+ */
+function ActionServiceUnitTest() {}
+
+ActionServiceUnitTest.prototype = {
+ __proto__: testing.Test.prototype,
+
+ /** @override */
+ extraLibraries: [
+ '../../../../ui/webui/resources/js/cr.js',
+ 'action_service.js',
+ ],
+};
+
+TEST_F('ActionServiceUnitTest', 'splitTerms', function() {
+ var ActionService = downloads.ActionService;
+ assertEquals(str([]), str(ActionService.splitTerms('')));
+ assertEquals(str([]), str(ActionService.splitTerms(' ')));
+ assertEquals(str(['a']), str(ActionService.splitTerms('a')));
+ assertEquals(str(['a b']), str(ActionService.splitTerms('a b')));
+ assertEquals(str(['a', 'b']), str(ActionService.splitTerms('a "b"')));
+ assertEquals(str(['a', 'b', 'c']), str(ActionService.splitTerms('a "b" c')));
+ assertEquals(str(['a', 'b b', 'c']),
+ str(ActionService.splitTerms('a "b b" c')));
+});
diff --git a/chromium/chrome/browser/resources/md_downloads/compiled_resources.gyp b/chromium/chrome/browser/resources/md_downloads/compiled_resources.gyp
index 33835847ece..89a982f5363 100644
--- a/chromium/chrome/browser/resources/md_downloads/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/md_downloads/compiled_resources.gyp
@@ -7,7 +7,7 @@
'target_name': 'manager',
'variables': {
'depends': [
- '../../../../ui/webui/resources/cr_elements/v1_0/cr_search_field/cr_search_field.js',
+ '../../../../ui/webui/resources/cr_elements/cr_search_field/cr_search_field.js',
'../../../../ui/webui/resources/js/action_link.js',
'../../../../ui/webui/resources/js/assert.js',
'../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
@@ -15,19 +15,23 @@
'../../../../ui/webui/resources/js/event_tracker.js',
'../../../../ui/webui/resources/js/cr/ui.js',
'../../../../ui/webui/resources/js/cr/ui/command.js',
- '../../../../ui/webui/resources/js/cr/ui/focus_row.js',
- '../../../../ui/webui/resources/js/cr/ui/focus_grid.js',
'../../../../ui/webui/resources/js/util.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-ripple-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js',
'action_service.js',
'constants.js',
- 'throttled_icon_loader.js',
- 'focus_row.js',
'item.js',
'toolbar.js',
],
'externs': [
'<(EXTERNS_DIR)/chrome_send.js',
- '../downloads/externs.js',
+ 'externs.js',
],
},
'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chromium/chrome/browser/resources/md_downloads/compiled_resources2.gyp b/chromium/chrome/browser/resources/md_downloads/compiled_resources2.gyp
index 78f2cbc3a1b..bc280d8fe32 100644
--- a/chromium/chrome/browser/resources/md_downloads/compiled_resources2.gyp
+++ b/chromium/chrome/browser/resources/md_downloads/compiled_resources2.gyp
@@ -18,22 +18,18 @@
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
- 'target_name': 'focus_row',
- 'dependencies': [
- '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
- '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_row',
- ],
- 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+ 'target_name': 'externs',
+ 'includes': ['../../../../third_party/closure_compiler/externs_js.gypi'],
},
{
'target_name': 'item',
'dependencies': [
+ # TODO(dbeam): create compiled_resources2.gyp files for Polymer.
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
- '../downloads/compiled_resources2.gyp:constants',
- '../downloads/compiled_resources2.gyp:throttled_icon_loader',
- '../downloads/compiled_resources2.gyp:externs',
+ 'constants',
'action_service',
+ 'externs',
],
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
@@ -45,9 +41,7 @@
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
'<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui',
'<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:command',
- '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_grid',
'action_service',
- 'focus_row',
'item',
'toolbar',
'<(EXTERNS_GYP):chrome_send',
@@ -56,14 +50,11 @@
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
- 'target_name': 'throttled_icon_loader',
- 'dependencies': ['<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr'],
- 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
- },
- {
'target_name': 'toolbar',
'dependencies': [
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
+ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
+ '<(DEPTH)/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp:cr_search_field',
'action_service',
],
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
diff --git a/chromium/chrome/browser/resources/md_downloads/crisper.js b/chromium/chrome/browser/resources/md_downloads/crisper.js
new file mode 100644
index 00000000000..4741e55d1f7
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_downloads/crisper.js
@@ -0,0 +1,17142 @@
+// 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.
+
+if (typeof Polymer == 'undefined')
+ Polymer = {dom: 'shadow'};
+else
+ console.error('Polymer is already defined.');
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * The global object.
+ * @type {!Object}
+ * @const
+ */
+var global = this;
+
+/** Platform, package, object property, and Event support. **/
+var cr = function() {
+ 'use strict';
+
+ /**
+ * Builds an object structure for the provided namespace path,
+ * ensuring that names that already exist are not overwritten. For
+ * example:
+ * "a.b.c" -> a = {};a.b={};a.b.c={};
+ * @param {string} name Name of the object that this file defines.
+ * @param {*=} opt_object The object to expose at the end of the path.
+ * @param {Object=} opt_objectToExportTo The object to add the path to;
+ * default is {@code global}.
+ * @private
+ */
+ function exportPath(name, opt_object, opt_objectToExportTo) {
+ var parts = name.split('.');
+ var cur = opt_objectToExportTo || global;
+
+ for (var part; parts.length && (part = parts.shift());) {
+ if (!parts.length && opt_object !== undefined) {
+ // last part and we have an object; use it
+ cur[part] = opt_object;
+ } else if (part in cur) {
+ cur = cur[part];
+ } else {
+ cur = cur[part] = {};
+ }
+ }
+ return cur;
+ };
+
+ /**
+ * Fires a property change event on the target.
+ * @param {EventTarget} target The target to dispatch the event on.
+ * @param {string} propertyName The name of the property that changed.
+ * @param {*} newValue The new value for the property.
+ * @param {*} oldValue The old value for the property.
+ */
+ function dispatchPropertyChange(target, propertyName, newValue, oldValue) {
+ var e = new Event(propertyName + 'Change');
+ e.propertyName = propertyName;
+ e.newValue = newValue;
+ e.oldValue = oldValue;
+ target.dispatchEvent(e);
+ }
+
+ /**
+ * Converts a camelCase javascript property name to a hyphenated-lower-case
+ * attribute name.
+ * @param {string} jsName The javascript camelCase property name.
+ * @return {string} The equivalent hyphenated-lower-case attribute name.
+ */
+ function getAttributeName(jsName) {
+ return jsName.replace(/([A-Z])/g, '-$1').toLowerCase();
+ }
+
+ /**
+ * The kind of property to define in {@code defineProperty}.
+ * @enum {string}
+ * @const
+ */
+ var PropertyKind = {
+ /**
+ * Plain old JS property where the backing data is stored as a "private"
+ * field on the object.
+ * Use for properties of any type. Type will not be checked.
+ */
+ JS: 'js',
+
+ /**
+ * The property backing data is stored as an attribute on an element.
+ * Use only for properties of type {string}.
+ */
+ ATTR: 'attr',
+
+ /**
+ * The property backing data is stored as an attribute on an element. If the
+ * element has the attribute then the value is true.
+ * Use only for properties of type {boolean}.
+ */
+ BOOL_ATTR: 'boolAttr'
+ };
+
+ /**
+ * Helper function for defineProperty that returns the getter to use for the
+ * property.
+ * @param {string} name The name of the property.
+ * @param {PropertyKind} kind The kind of the property.
+ * @return {function():*} The getter for the property.
+ */
+ function getGetter(name, kind) {
+ switch (kind) {
+ case PropertyKind.JS:
+ var privateName = name + '_';
+ return function() {
+ return this[privateName];
+ };
+ case PropertyKind.ATTR:
+ var attributeName = getAttributeName(name);
+ return function() {
+ return this.getAttribute(attributeName);
+ };
+ case PropertyKind.BOOL_ATTR:
+ var attributeName = getAttributeName(name);
+ return function() {
+ return this.hasAttribute(attributeName);
+ };
+ }
+
+ // TODO(dbeam): replace with assertNotReached() in assert.js when I can coax
+ // the browser/unit tests to preprocess this file through grit.
+ throw 'not reached';
+ }
+
+ /**
+ * Helper function for defineProperty that returns the setter of the right
+ * kind.
+ * @param {string} name The name of the property we are defining the setter
+ * for.
+ * @param {PropertyKind} kind The kind of property we are getting the
+ * setter for.
+ * @param {function(*, *):void=} opt_setHook A function to run after the
+ * property is set, but before the propertyChange event is fired.
+ * @return {function(*):void} The function to use as a setter.
+ */
+ function getSetter(name, kind, opt_setHook) {
+ switch (kind) {
+ case PropertyKind.JS:
+ var privateName = name + '_';
+ return function(value) {
+ var oldValue = this[name];
+ if (value !== oldValue) {
+ this[privateName] = value;
+ if (opt_setHook)
+ opt_setHook.call(this, value, oldValue);
+ dispatchPropertyChange(this, name, value, oldValue);
+ }
+ };
+
+ case PropertyKind.ATTR:
+ var attributeName = getAttributeName(name);
+ return function(value) {
+ var oldValue = this[name];
+ if (value !== oldValue) {
+ if (value == undefined)
+ this.removeAttribute(attributeName);
+ else
+ this.setAttribute(attributeName, value);
+ if (opt_setHook)
+ opt_setHook.call(this, value, oldValue);
+ dispatchPropertyChange(this, name, value, oldValue);
+ }
+ };
+
+ case PropertyKind.BOOL_ATTR:
+ var attributeName = getAttributeName(name);
+ return function(value) {
+ var oldValue = this[name];
+ if (value !== oldValue) {
+ if (value)
+ this.setAttribute(attributeName, name);
+ else
+ this.removeAttribute(attributeName);
+ if (opt_setHook)
+ opt_setHook.call(this, value, oldValue);
+ dispatchPropertyChange(this, name, value, oldValue);
+ }
+ };
+ }
+
+ // TODO(dbeam): replace with assertNotReached() in assert.js when I can coax
+ // the browser/unit tests to preprocess this file through grit.
+ throw 'not reached';
+ }
+
+ /**
+ * Defines a property on an object. When the setter changes the value a
+ * property change event with the type {@code name + 'Change'} is fired.
+ * @param {!Object} obj The object to define the property for.
+ * @param {string} name The name of the property.
+ * @param {PropertyKind=} opt_kind What kind of underlying storage to use.
+ * @param {function(*, *):void=} opt_setHook A function to run after the
+ * property is set, but before the propertyChange event is fired.
+ */
+ function defineProperty(obj, name, opt_kind, opt_setHook) {
+ if (typeof obj == 'function')
+ obj = obj.prototype;
+
+ var kind = /** @type {PropertyKind} */ (opt_kind || PropertyKind.JS);
+
+ if (!obj.__lookupGetter__(name))
+ obj.__defineGetter__(name, getGetter(name, kind));
+
+ if (!obj.__lookupSetter__(name))
+ obj.__defineSetter__(name, getSetter(name, kind, opt_setHook));
+ }
+
+ /**
+ * Counter for use with createUid
+ */
+ var uidCounter = 1;
+
+ /**
+ * @return {number} A new unique ID.
+ */
+ function createUid() {
+ return uidCounter++;
+ }
+
+ /**
+ * Returns a unique ID for the item. This mutates the item so it needs to be
+ * an object
+ * @param {!Object} item The item to get the unique ID for.
+ * @return {number} The unique ID for the item.
+ */
+ function getUid(item) {
+ if (item.hasOwnProperty('uid'))
+ return item.uid;
+ return item.uid = createUid();
+ }
+
+ /**
+ * Dispatches a simple event on an event target.
+ * @param {!EventTarget} target The event target to dispatch the event on.
+ * @param {string} type The type of the event.
+ * @param {boolean=} opt_bubbles Whether the event bubbles or not.
+ * @param {boolean=} opt_cancelable Whether the default action of the event
+ * can be prevented. Default is true.
+ * @return {boolean} If any of the listeners called {@code preventDefault}
+ * during the dispatch this will return false.
+ */
+ function dispatchSimpleEvent(target, type, opt_bubbles, opt_cancelable) {
+ var e = new Event(type, {
+ bubbles: opt_bubbles,
+ cancelable: opt_cancelable === undefined || opt_cancelable
+ });
+ return target.dispatchEvent(e);
+ }
+
+ /**
+ * Calls |fun| and adds all the fields of the returned object to the object
+ * named by |name|. For example, cr.define('cr.ui', function() {
+ * function List() {
+ * ...
+ * }
+ * function ListItem() {
+ * ...
+ * }
+ * return {
+ * List: List,
+ * ListItem: ListItem,
+ * };
+ * });
+ * defines the functions cr.ui.List and cr.ui.ListItem.
+ * @param {string} name The name of the object that we are adding fields to.
+ * @param {!Function} fun The function that will return an object containing
+ * the names and values of the new fields.
+ */
+ function define(name, fun) {
+ var obj = exportPath(name);
+ var exports = fun();
+ for (var propertyName in exports) {
+ // Maybe we should check the prototype chain here? The current usage
+ // pattern is always using an object literal so we only care about own
+ // properties.
+ var propertyDescriptor = Object.getOwnPropertyDescriptor(exports,
+ propertyName);
+ if (propertyDescriptor)
+ Object.defineProperty(obj, propertyName, propertyDescriptor);
+ }
+ }
+
+ /**
+ * Adds a {@code getInstance} static method that always return the same
+ * instance object.
+ * @param {!Function} ctor The constructor for the class to add the static
+ * method to.
+ */
+ function addSingletonGetter(ctor) {
+ ctor.getInstance = function() {
+ return ctor.instance_ || (ctor.instance_ = new ctor());
+ };
+ }
+
+ /**
+ * Forwards public APIs to private implementations.
+ * @param {Function} ctor Constructor that have private implementations in its
+ * prototype.
+ * @param {Array<string>} methods List of public method names that have their
+ * underscored counterparts in constructor's prototype.
+ * @param {string=} opt_target Selector for target node.
+ */
+ function makePublic(ctor, methods, opt_target) {
+ methods.forEach(function(method) {
+ ctor[method] = function() {
+ var target = opt_target ? document.getElementById(opt_target) :
+ ctor.getInstance();
+ return target[method + '_'].apply(target, arguments);
+ };
+ });
+ }
+
+ /**
+ * The mapping used by the sendWithCallback mechanism to tie the callback
+ * supplied to an invocation of sendWithCallback with the WebUI response
+ * sent by the browser in response to the chrome.send call. The mapping is
+ * from ID to callback function; the ID is generated by sendWithCallback and
+ * is unique across all invocations of said method.
+ * @type {!Object<Function>}
+ */
+ var chromeSendCallbackMap = Object.create(null);
+
+ /**
+ * The named method the WebUI handler calls directly in response to a
+ * chrome.send call that expects a callback. The handler requires no knowledge
+ * of the specific name of this method, as the name is passed to the handler
+ * as the first argument in the arguments list of chrome.send. The handler
+ * must pass the ID, also sent via the chrome.send arguments list, as the
+ * first argument of the JS invocation; additionally, the handler may
+ * supply any number of other arguments that will be forwarded to the
+ * callback.
+ * @param {string} id The unique ID identifying the callback method this
+ * response is tied to.
+ */
+ function webUIResponse(id) {
+ chromeSendCallbackMap[id].apply(
+ null, Array.prototype.slice.call(arguments, 1));
+ delete chromeSendCallbackMap[id];
+ }
+
+ /**
+ * A variation of chrome.send which allows the client to receive a direct
+ * callback without requiring the handler to have specific knowledge of any
+ * JS internal method names or state. The callback will be removed from the
+ * mapping once it has fired.
+ * @param {string} methodName The name of the WebUI handler API.
+ * @param {Array|undefined} args Arguments for the method call sent to the
+ * WebUI handler. Pass undefined if no args should be sent to the handler.
+ * @param {Function} callback A callback function which is called (indirectly)
+ * by the WebUI handler.
+ */
+ function sendWithCallback(methodName, args, callback) {
+ var id = methodName + createUid();
+ chromeSendCallbackMap[id] = callback;
+ chrome.send(methodName, ['cr.webUIResponse', id].concat(args || []));
+ }
+
+ /**
+ * A registry of callbacks keyed by event name. Used by addWebUIListener to
+ * register listeners.
+ * @type {!Object<Array<Function>>}
+ */
+ var webUIListenerMap = Object.create(null);
+
+ /**
+ * The named method the WebUI handler calls directly when an event occurs.
+ * The WebUI handler must supply the name of the event as the first argument
+ * of the JS invocation; additionally, the handler may supply any number of
+ * other arguments that will be forwarded to the listener callbacks.
+ * @param {string} event The name of the event that has occurred.
+ */
+ function webUIListenerCallback(event) {
+ var listenerCallbacks = webUIListenerMap[event];
+ for (var i = 0; i < listenerCallbacks.length; i++) {
+ var callback = listenerCallbacks[i];
+ callback.apply(null, Array.prototype.slice.call(arguments, 1));
+ }
+ }
+
+ /**
+ * Registers a listener for an event fired from WebUI handlers. Any number of
+ * listeners may register for a single event.
+ * @param {string} event The event to listen to.
+ * @param {Function} callback The callback run when the event is fired.
+ */
+ function addWebUIListener(event, callback) {
+ if (event in webUIListenerMap)
+ webUIListenerMap[event].push(callback);
+ else
+ webUIListenerMap[event] = [callback];
+ }
+
+ return {
+ addSingletonGetter: addSingletonGetter,
+ createUid: createUid,
+ define: define,
+ defineProperty: defineProperty,
+ dispatchPropertyChange: dispatchPropertyChange,
+ dispatchSimpleEvent: dispatchSimpleEvent,
+ exportPath: exportPath,
+ getUid: getUid,
+ makePublic: makePublic,
+ webUIResponse: webUIResponse,
+ sendWithCallback: sendWithCallback,
+ webUIListenerCallback: webUIListenerCallback,
+ addWebUIListener: addWebUIListener,
+ PropertyKind: PropertyKind,
+
+ get doc() {
+ return document;
+ },
+
+ /** Whether we are using a Mac or not. */
+ get isMac() {
+ return /Mac/.test(navigator.platform);
+ },
+
+ /** Whether this is on the Windows platform or not. */
+ get isWindows() {
+ return /Win/.test(navigator.platform);
+ },
+
+ /** Whether this is on chromeOS or not. */
+ get isChromeOS() {
+ return /CrOS/.test(navigator.userAgent);
+ },
+
+ /** Whether this is on vanilla Linux (not chromeOS). */
+ get isLinux() {
+ return /Linux/.test(navigator.userAgent);
+ },
+ };
+}();
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('cr.ui', function() {
+
+ /**
+ * Decorates elements as an instance of a class.
+ * @param {string|!Element} source The way to find the element(s) to decorate.
+ * If this is a string then {@code querySeletorAll} is used to find the
+ * elements to decorate.
+ * @param {!Function} constr The constructor to decorate with. The constr
+ * needs to have a {@code decorate} function.
+ */
+ function decorate(source, constr) {
+ var elements;
+ if (typeof source == 'string')
+ elements = cr.doc.querySelectorAll(source);
+ else
+ elements = [source];
+
+ for (var i = 0, el; el = elements[i]; i++) {
+ if (!(el instanceof constr))
+ constr.decorate(el);
+ }
+ }
+
+ /**
+ * Helper function for creating new element for define.
+ */
+ function createElementHelper(tagName, opt_bag) {
+ // Allow passing in ownerDocument to create in a different document.
+ var doc;
+ if (opt_bag && opt_bag.ownerDocument)
+ doc = opt_bag.ownerDocument;
+ else
+ doc = cr.doc;
+ return doc.createElement(tagName);
+ }
+
+ /**
+ * Creates the constructor for a UI element class.
+ *
+ * Usage:
+ * <pre>
+ * var List = cr.ui.define('list');
+ * List.prototype = {
+ * __proto__: HTMLUListElement.prototype,
+ * decorate: function() {
+ * ...
+ * },
+ * ...
+ * };
+ * </pre>
+ *
+ * @param {string|Function} tagNameOrFunction The tagName or
+ * function to use for newly created elements. If this is a function it
+ * needs to return a new element when called.
+ * @return {function(Object=):Element} The constructor function which takes
+ * an optional property bag. The function also has a static
+ * {@code decorate} method added to it.
+ */
+ function define(tagNameOrFunction) {
+ var createFunction, tagName;
+ if (typeof tagNameOrFunction == 'function') {
+ createFunction = tagNameOrFunction;
+ tagName = '';
+ } else {
+ createFunction = createElementHelper;
+ tagName = tagNameOrFunction;
+ }
+
+ /**
+ * Creates a new UI element constructor.
+ * @param {Object=} opt_propertyBag Optional bag of properties to set on the
+ * object after created. The property {@code ownerDocument} is special
+ * cased and it allows you to create the element in a different
+ * document than the default.
+ * @constructor
+ */
+ function f(opt_propertyBag) {
+ var el = createFunction(tagName, opt_propertyBag);
+ f.decorate(el);
+ for (var propertyName in opt_propertyBag) {
+ el[propertyName] = opt_propertyBag[propertyName];
+ }
+ return el;
+ }
+
+ /**
+ * Decorates an element as a UI element class.
+ * @param {!Element} el The element to decorate.
+ */
+ f.decorate = function(el) {
+ el.__proto__ = f.prototype;
+ el.decorate();
+ };
+
+ return f;
+ }
+
+ /**
+ * Input elements do not grow and shrink with their content. This is a simple
+ * (and not very efficient) way of handling shrinking to content with support
+ * for min width and limited by the width of the parent element.
+ * @param {!HTMLElement} el The element to limit the width for.
+ * @param {!HTMLElement} parentEl The parent element that should limit the
+ * size.
+ * @param {number} min The minimum width.
+ * @param {number=} opt_scale Optional scale factor to apply to the width.
+ */
+ function limitInputWidth(el, parentEl, min, opt_scale) {
+ // Needs a size larger than borders
+ el.style.width = '10px';
+ var doc = el.ownerDocument;
+ var win = doc.defaultView;
+ var computedStyle = win.getComputedStyle(el);
+ var parentComputedStyle = win.getComputedStyle(parentEl);
+ var rtl = computedStyle.direction == 'rtl';
+
+ // To get the max width we get the width of the treeItem minus the position
+ // of the input.
+ var inputRect = el.getBoundingClientRect(); // box-sizing
+ var parentRect = parentEl.getBoundingClientRect();
+ var startPos = rtl ? parentRect.right - inputRect.right :
+ inputRect.left - parentRect.left;
+
+ // Add up border and padding of the input.
+ var inner = parseInt(computedStyle.borderLeftWidth, 10) +
+ parseInt(computedStyle.paddingLeft, 10) +
+ parseInt(computedStyle.paddingRight, 10) +
+ parseInt(computedStyle.borderRightWidth, 10);
+
+ // We also need to subtract the padding of parent to prevent it to overflow.
+ var parentPadding = rtl ? parseInt(parentComputedStyle.paddingLeft, 10) :
+ parseInt(parentComputedStyle.paddingRight, 10);
+
+ var max = parentEl.clientWidth - startPos - inner - parentPadding;
+ if (opt_scale)
+ max *= opt_scale;
+
+ function limit() {
+ if (el.scrollWidth > max) {
+ el.style.width = max + 'px';
+ } else {
+ el.style.width = 0;
+ var sw = el.scrollWidth;
+ if (sw < min) {
+ el.style.width = min + 'px';
+ } else {
+ el.style.width = sw + 'px';
+ }
+ }
+ }
+
+ el.addEventListener('input', limit);
+ limit();
+ }
+
+ /**
+ * Takes a number and spits out a value CSS will be happy with. To avoid
+ * subpixel layout issues, the value is rounded to the nearest integral value.
+ * @param {number} pixels The number of pixels.
+ * @return {string} e.g. '16px'.
+ */
+ function toCssPx(pixels) {
+ if (!window.isFinite(pixels))
+ console.error('Pixel value is not a number: ' + pixels);
+ return Math.round(pixels) + 'px';
+ }
+
+ /**
+ * Users complain they occasionaly use doubleclicks instead of clicks
+ * (http://crbug.com/140364). To fix it we freeze click handling for
+ * the doubleclick time interval.
+ * @param {MouseEvent} e Initial click event.
+ */
+ function swallowDoubleClick(e) {
+ var doc = e.target.ownerDocument;
+ var counter = Math.min(1, e.detail);
+ function swallow(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ function onclick(e) {
+ if (e.detail > counter) {
+ counter = e.detail;
+ // Swallow the click since it's a click inside the doubleclick timeout.
+ swallow(e);
+ } else {
+ // Stop tracking clicks and let regular handling.
+ doc.removeEventListener('dblclick', swallow, true);
+ doc.removeEventListener('click', onclick, true);
+ }
+ }
+ // The following 'click' event (if e.type == 'mouseup') mustn't be taken
+ // into account (it mustn't stop tracking clicks). Start event listening
+ // after zero timeout.
+ setTimeout(function() {
+ doc.addEventListener('click', onclick, true);
+ doc.addEventListener('dblclick', swallow, true);
+ }, 0);
+ }
+
+ return {
+ decorate: decorate,
+ define: define,
+ limitInputWidth: limitInputWidth,
+ toCssPx: toCssPx,
+ swallowDoubleClick: swallowDoubleClick
+ };
+});
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview A command is an abstraction of an action a user can do in the
+ * UI.
+ *
+ * When the focus changes in the document for each command a canExecute event
+ * is dispatched on the active element. By listening to this event you can
+ * enable and disable the command by setting the event.canExecute property.
+ *
+ * When a command is executed a command event is dispatched on the active
+ * element. Note that you should stop the propagation after you have handled the
+ * command if there might be other command listeners higher up in the DOM tree.
+ */
+
+cr.define('cr.ui', function() {
+
+ /**
+ * This is used to identify keyboard shortcuts.
+ * @param {string} shortcut The text used to describe the keys for this
+ * keyboard shortcut.
+ * @constructor
+ */
+ function KeyboardShortcut(shortcut) {
+ var mods = {};
+ var ident = '';
+ shortcut.split('-').forEach(function(part) {
+ var partLc = part.toLowerCase();
+ switch (partLc) {
+ case 'alt':
+ case 'ctrl':
+ case 'meta':
+ case 'shift':
+ mods[partLc + 'Key'] = true;
+ break;
+ default:
+ if (ident)
+ throw Error('Invalid shortcut');
+ ident = part;
+ }
+ });
+
+ this.ident_ = ident;
+ this.mods_ = mods;
+ }
+
+ KeyboardShortcut.prototype = {
+ /**
+ * Whether the keyboard shortcut object matches a keyboard event.
+ * @param {!Event} e The keyboard event object.
+ * @return {boolean} Whether we found a match or not.
+ */
+ matchesEvent: function(e) {
+ if (e.keyIdentifier == this.ident_) {
+ // All keyboard modifiers needs to match.
+ var mods = this.mods_;
+ return ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].every(function(k) {
+ return e[k] == !!mods[k];
+ });
+ }
+ return false;
+ }
+ };
+
+ /**
+ * Creates a new command element.
+ * @constructor
+ * @extends {HTMLElement}
+ */
+ var Command = cr.ui.define('command');
+
+ Command.prototype = {
+ __proto__: HTMLElement.prototype,
+
+ /**
+ * Initializes the command.
+ */
+ decorate: function() {
+ CommandManager.init(assert(this.ownerDocument));
+
+ if (this.hasAttribute('shortcut'))
+ this.shortcut = this.getAttribute('shortcut');
+ },
+
+ /**
+ * Executes the command by dispatching a command event on the given element.
+ * If |element| isn't given, the active element is used instead.
+ * If the command is {@code disabled} this does nothing.
+ * @param {HTMLElement=} opt_element Optional element to dispatch event on.
+ */
+ execute: function(opt_element) {
+ if (this.disabled)
+ return;
+ var doc = this.ownerDocument;
+ if (doc.activeElement) {
+ var e = new Event('command', {bubbles: true});
+ e.command = this;
+
+ (opt_element || doc.activeElement).dispatchEvent(e);
+ }
+ },
+
+ /**
+ * Call this when there have been changes that might change whether the
+ * command can be executed or not.
+ * @param {Node=} opt_node Node for which to actuate command state.
+ */
+ canExecuteChange: function(opt_node) {
+ dispatchCanExecuteEvent(this,
+ opt_node || this.ownerDocument.activeElement);
+ },
+
+ /**
+ * The keyboard shortcut that triggers the command. This is a string
+ * consisting of a keyIdentifier (as reported by WebKit in keydown) as
+ * well as optional key modifiers joinded with a '-'.
+ *
+ * Multiple keyboard shortcuts can be provided by separating them by
+ * whitespace.
+ *
+ * For example:
+ * "F1"
+ * "U+0008-Meta" for Apple command backspace.
+ * "U+0041-Ctrl" for Control A
+ * "U+007F U+0008-Meta" for Delete and Command Backspace
+ *
+ * @type {string}
+ */
+ shortcut_: '',
+ get shortcut() {
+ return this.shortcut_;
+ },
+ set shortcut(shortcut) {
+ var oldShortcut = this.shortcut_;
+ if (shortcut !== oldShortcut) {
+ this.keyboardShortcuts_ = shortcut.split(/\s+/).map(function(shortcut) {
+ return new KeyboardShortcut(shortcut);
+ });
+
+ // Set this after the keyboardShortcuts_ since that might throw.
+ this.shortcut_ = shortcut;
+ cr.dispatchPropertyChange(this, 'shortcut', this.shortcut_,
+ oldShortcut);
+ }
+ },
+
+ /**
+ * Whether the event object matches the shortcut for this command.
+ * @param {!Event} e The key event object.
+ * @return {boolean} Whether it matched or not.
+ */
+ matchesEvent: function(e) {
+ if (!this.keyboardShortcuts_)
+ return false;
+
+ return this.keyboardShortcuts_.some(function(keyboardShortcut) {
+ return keyboardShortcut.matchesEvent(e);
+ });
+ },
+ };
+
+ /**
+ * The label of the command.
+ */
+ cr.defineProperty(Command, 'label', cr.PropertyKind.ATTR);
+
+ /**
+ * Whether the command is disabled or not.
+ */
+ cr.defineProperty(Command, 'disabled', cr.PropertyKind.BOOL_ATTR);
+
+ /**
+ * Whether the command is hidden or not.
+ */
+ cr.defineProperty(Command, 'hidden', cr.PropertyKind.BOOL_ATTR);
+
+ /**
+ * Whether the command is checked or not.
+ */
+ cr.defineProperty(Command, 'checked', cr.PropertyKind.BOOL_ATTR);
+
+ /**
+ * The flag that prevents the shortcut text from being displayed on menu.
+ *
+ * If false, the keyboard shortcut text (eg. "Ctrl+X" for the cut command)
+ * is displayed in menu when the command is assosiated with a menu item.
+ * Otherwise, no text is displayed.
+ */
+ cr.defineProperty(Command, 'hideShortcutText', cr.PropertyKind.BOOL_ATTR);
+
+ /**
+ * Dispatches a canExecute event on the target.
+ * @param {!cr.ui.Command} command The command that we are testing for.
+ * @param {EventTarget} target The target element to dispatch the event on.
+ */
+ function dispatchCanExecuteEvent(command, target) {
+ var e = new CanExecuteEvent(command);
+ target.dispatchEvent(e);
+ command.disabled = !e.canExecute;
+ }
+
+ /**
+ * The command managers for different documents.
+ */
+ var commandManagers = {};
+
+ /**
+ * Keeps track of the focused element and updates the commands when the focus
+ * changes.
+ * @param {!Document} doc The document that we are managing the commands for.
+ * @constructor
+ */
+ function CommandManager(doc) {
+ doc.addEventListener('focus', this.handleFocus_.bind(this), true);
+ // Make sure we add the listener to the bubbling phase so that elements can
+ // prevent the command.
+ doc.addEventListener('keydown', this.handleKeyDown_.bind(this), false);
+ }
+
+ /**
+ * Initializes a command manager for the document as needed.
+ * @param {!Document} doc The document to manage the commands for.
+ */
+ CommandManager.init = function(doc) {
+ var uid = cr.getUid(doc);
+ if (!(uid in commandManagers)) {
+ commandManagers[uid] = new CommandManager(doc);
+ }
+ };
+
+ CommandManager.prototype = {
+
+ /**
+ * Handles focus changes on the document.
+ * @param {Event} e The focus event object.
+ * @private
+ * @suppress {checkTypes}
+ * TODO(vitalyp): remove the suppression.
+ */
+ handleFocus_: function(e) {
+ var target = e.target;
+
+ // Ignore focus on a menu button or command item.
+ if (target.menu || target.command)
+ return;
+
+ var commands = Array.prototype.slice.call(
+ target.ownerDocument.querySelectorAll('command'));
+
+ commands.forEach(function(command) {
+ dispatchCanExecuteEvent(command, target);
+ });
+ },
+
+ /**
+ * Handles the keydown event and routes it to the right command.
+ * @param {!Event} e The keydown event.
+ */
+ handleKeyDown_: function(e) {
+ var target = e.target;
+ var commands = Array.prototype.slice.call(
+ target.ownerDocument.querySelectorAll('command'));
+
+ for (var i = 0, command; command = commands[i]; i++) {
+ if (command.matchesEvent(e)) {
+ // When invoking a command via a shortcut, we have to manually check
+ // if it can be executed, since focus might not have been changed
+ // what would have updated the command's state.
+ command.canExecuteChange();
+
+ if (!command.disabled) {
+ e.preventDefault();
+ // We do not want any other element to handle this.
+ e.stopPropagation();
+ command.execute();
+ return;
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * The event type used for canExecute events.
+ * @param {!cr.ui.Command} command The command that we are evaluating.
+ * @extends {Event}
+ * @constructor
+ * @class
+ */
+ function CanExecuteEvent(command) {
+ var e = new Event('canExecute', {bubbles: true, cancelable: true});
+ e.__proto__ = CanExecuteEvent.prototype;
+ e.command = command;
+ return e;
+ }
+
+ CanExecuteEvent.prototype = {
+ __proto__: Event.prototype,
+
+ /**
+ * The current command
+ * @type {cr.ui.Command}
+ */
+ command: null,
+
+ /**
+ * Whether the target can execute the command. Setting this also stops the
+ * propagation and prevents the default. Callers can tell if an event has
+ * been handled via |this.defaultPrevented|.
+ * @type {boolean}
+ */
+ canExecute_: false,
+ get canExecute() {
+ return this.canExecute_;
+ },
+ set canExecute(canExecute) {
+ this.canExecute_ = !!canExecute;
+ this.stopPropagation();
+ this.preventDefault();
+ }
+ };
+
+ // Export
+ return {
+ Command: Command,
+ CanExecuteEvent: CanExecuteEvent
+ };
+});
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// <include src="../../../../ui/webui/resources/js/assert.js">
+
+/**
+ * Alias for document.getElementById.
+ * @param {string} id The ID of the element to find.
+ * @return {HTMLElement} The found element or null if not found.
+ */
+function $(id) {
+ return document.getElementById(id);
+}
+
+/**
+ * Add an accessible message to the page that will be announced to
+ * users who have spoken feedback on, but will be invisible to all
+ * other users. It's removed right away so it doesn't clutter the DOM.
+ * @param {string} msg The text to be pronounced.
+ */
+function announceAccessibleMessage(msg) {
+ var element = document.createElement('div');
+ element.setAttribute('aria-live', 'polite');
+ element.style.position = 'relative';
+ element.style.left = '-9999px';
+ element.style.height = '0px';
+ element.innerText = msg;
+ document.body.appendChild(element);
+ window.setTimeout(function() {
+ document.body.removeChild(element);
+ }, 0);
+}
+
+/**
+ * Calls chrome.send with a callback and restores the original afterwards.
+ * @param {string} name The name of the message to send.
+ * @param {!Array} params The parameters to send.
+ * @param {string} callbackName The name of the function that the backend calls.
+ * @param {!Function} callback The function to call.
+ */
+function chromeSend(name, params, callbackName, callback) {
+ var old = global[callbackName];
+ global[callbackName] = function() {
+ // restore
+ global[callbackName] = old;
+
+ var args = Array.prototype.slice.call(arguments);
+ return callback.apply(global, args);
+ };
+ chrome.send(name, params);
+}
+
+/**
+ * Returns the scale factors supported by this platform for webui
+ * resources.
+ * @return {Array} The supported scale factors.
+ */
+function getSupportedScaleFactors() {
+ var supportedScaleFactors = [];
+ if (cr.isMac || cr.isChromeOS || cr.isWindows || cr.isLinux) {
+ // All desktop platforms support zooming which also updates the
+ // renderer's device scale factors (a.k.a devicePixelRatio), and
+ // these platforms has high DPI assets for 2.0x. Use 1x and 2x in
+ // image-set on these platforms so that the renderer can pick the
+ // closest image for the current device scale factor.
+ supportedScaleFactors.push(1);
+ supportedScaleFactors.push(2);
+ } else {
+ // For other platforms that use fixed device scale factor, use
+ // the window's device pixel ratio.
+ // TODO(oshima): Investigate if Android/iOS need to use image-set.
+ supportedScaleFactors.push(window.devicePixelRatio);
+ }
+ return supportedScaleFactors;
+}
+
+/**
+ * Generates a CSS url string.
+ * @param {string} s The URL to generate the CSS url for.
+ * @return {string} The CSS url string.
+ */
+function url(s) {
+ // http://www.w3.org/TR/css3-values/#uris
+ // Parentheses, commas, whitespace characters, single quotes (') and double
+ // quotes (") appearing in a URI must be escaped with a backslash
+ var s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1');
+ // WebKit has a bug when it comes to URLs that end with \
+ // https://bugs.webkit.org/show_bug.cgi?id=28885
+ if (/\\\\$/.test(s2)) {
+ // Add a space to work around the WebKit bug.
+ s2 += ' ';
+ }
+ return 'url("' + s2 + '")';
+}
+
+/**
+ * Returns the URL of the image, or an image set of URLs for the profile avatar.
+ * Default avatars have resources available for multiple scalefactors, whereas
+ * the GAIA profile image only comes in one size.
+ *
+ * @param {string} path The path of the image.
+ * @return {string} The url, or an image set of URLs of the avatar image.
+ */
+function getProfileAvatarIcon(path) {
+ var chromeThemePath = 'chrome://theme';
+ var isDefaultAvatar =
+ (path.slice(0, chromeThemePath.length) == chromeThemePath);
+ return isDefaultAvatar ? imageset(path + '@scalefactorx'): url(path);
+}
+
+/**
+ * Generates a CSS -webkit-image-set for a chrome:// url.
+ * An entry in the image set is added for each of getSupportedScaleFactors().
+ * The scale-factor-specific url is generated by replacing the first instance of
+ * 'scalefactor' in |path| with the numeric scale factor.
+ * @param {string} path The URL to generate an image set for.
+ * 'scalefactor' should be a substring of |path|.
+ * @return {string} The CSS -webkit-image-set.
+ */
+function imageset(path) {
+ var supportedScaleFactors = getSupportedScaleFactors();
+
+ var replaceStartIndex = path.indexOf('scalefactor');
+ if (replaceStartIndex < 0)
+ return url(path);
+
+ var s = '';
+ for (var i = 0; i < supportedScaleFactors.length; ++i) {
+ var scaleFactor = supportedScaleFactors[i];
+ var pathWithScaleFactor = path.substr(0, replaceStartIndex) + scaleFactor +
+ path.substr(replaceStartIndex + 'scalefactor'.length);
+
+ s += url(pathWithScaleFactor) + ' ' + scaleFactor + 'x';
+
+ if (i != supportedScaleFactors.length - 1)
+ s += ', ';
+ }
+ return '-webkit-image-set(' + s + ')';
+}
+
+/**
+ * Parses query parameters from Location.
+ * @param {Location} location The URL to generate the CSS url for.
+ * @return {Object} Dictionary containing name value pairs for URL
+ */
+function parseQueryParams(location) {
+ var params = {};
+ var query = unescape(location.search.substring(1));
+ var vars = query.split('&');
+ for (var i = 0; i < vars.length; i++) {
+ var pair = vars[i].split('=');
+ params[pair[0]] = pair[1];
+ }
+ return params;
+}
+
+/**
+ * Creates a new URL by appending or replacing the given query key and value.
+ * Not supporting URL with username and password.
+ * @param {Location} location The original URL.
+ * @param {string} key The query parameter name.
+ * @param {string} value The query parameter value.
+ * @return {string} The constructed new URL.
+ */
+function setQueryParam(location, key, value) {
+ var query = parseQueryParams(location);
+ query[encodeURIComponent(key)] = encodeURIComponent(value);
+
+ var newQuery = '';
+ for (var q in query) {
+ newQuery += (newQuery ? '&' : '?') + q + '=' + query[q];
+ }
+
+ return location.origin + location.pathname + newQuery + location.hash;
+}
+
+/**
+ * @param {Node} el A node to search for ancestors with |className|.
+ * @param {string} className A class to search for.
+ * @return {Element} A node with class of |className| or null if none is found.
+ */
+function findAncestorByClass(el, className) {
+ return /** @type {Element} */(findAncestor(el, function(el) {
+ return el.classList && el.classList.contains(className);
+ }));
+}
+
+/**
+ * Return the first ancestor for which the {@code predicate} returns true.
+ * @param {Node} node The node to check.
+ * @param {function(Node):boolean} predicate The function that tests the
+ * nodes.
+ * @return {Node} The found ancestor or null if not found.
+ */
+function findAncestor(node, predicate) {
+ var last = false;
+ while (node != null && !(last = predicate(node))) {
+ node = node.parentNode;
+ }
+ return last ? node : null;
+}
+
+function swapDomNodes(a, b) {
+ var afterA = a.nextSibling;
+ if (afterA == b) {
+ swapDomNodes(b, a);
+ return;
+ }
+ var aParent = a.parentNode;
+ b.parentNode.replaceChild(a, b);
+ aParent.insertBefore(b, afterA);
+}
+
+/**
+ * Disables text selection and dragging, with optional whitelist callbacks.
+ * @param {function(Event):boolean=} opt_allowSelectStart Unless this function
+ * is defined and returns true, the onselectionstart event will be
+ * surpressed.
+ * @param {function(Event):boolean=} opt_allowDragStart Unless this function
+ * is defined and returns true, the ondragstart event will be surpressed.
+ */
+function disableTextSelectAndDrag(opt_allowSelectStart, opt_allowDragStart) {
+ // Disable text selection.
+ document.onselectstart = function(e) {
+ if (!(opt_allowSelectStart && opt_allowSelectStart.call(this, e)))
+ e.preventDefault();
+ };
+
+ // Disable dragging.
+ document.ondragstart = function(e) {
+ if (!(opt_allowDragStart && opt_allowDragStart.call(this, e)))
+ e.preventDefault();
+ };
+}
+
+/**
+ * TODO(dbeam): DO NOT USE. THIS IS DEPRECATED. Use an action-link instead.
+ * Call this to stop clicks on <a href="#"> links from scrolling to the top of
+ * the page (and possibly showing a # in the link).
+ */
+function preventDefaultOnPoundLinkClicks() {
+ document.addEventListener('click', function(e) {
+ var anchor = findAncestor(/** @type {Node} */(e.target), function(el) {
+ return el.tagName == 'A';
+ });
+ // Use getAttribute() to prevent URL normalization.
+ if (anchor && anchor.getAttribute('href') == '#')
+ e.preventDefault();
+ });
+}
+
+/**
+ * Check the directionality of the page.
+ * @return {boolean} True if Chrome is running an RTL UI.
+ */
+function isRTL() {
+ return document.documentElement.dir == 'rtl';
+}
+
+/**
+ * Get an element that's known to exist by its ID. We use this instead of just
+ * calling getElementById and not checking the result because this lets us
+ * satisfy the JSCompiler type system.
+ * @param {string} id The identifier name.
+ * @return {!HTMLElement} the Element.
+ */
+function getRequiredElement(id) {
+ return assertInstanceof($(id), HTMLElement,
+ 'Missing required element: ' + id);
+}
+
+/**
+ * Query an element that's known to exist by a selector. We use this instead of
+ * just calling querySelector and not checking the result because this lets us
+ * satisfy the JSCompiler type system.
+ * @param {string} selectors CSS selectors to query the element.
+ * @param {(!Document|!DocumentFragment|!Element)=} opt_context An optional
+ * context object for querySelector.
+ * @return {!HTMLElement} the Element.
+ */
+function queryRequiredElement(selectors, opt_context) {
+ var element = (opt_context || document).querySelector(selectors);
+ return assertInstanceof(element, HTMLElement,
+ 'Missing required element: ' + selectors);
+}
+
+// Handle click on a link. If the link points to a chrome: or file: url, then
+// call into the browser to do the navigation.
+document.addEventListener('click', function(e) {
+ if (e.defaultPrevented)
+ return;
+
+ var el = e.target;
+ if (el.nodeType == Node.ELEMENT_NODE &&
+ el.webkitMatchesSelector('A, A *')) {
+ while (el.tagName != 'A') {
+ el = el.parentElement;
+ }
+
+ if ((el.protocol == 'file:' || el.protocol == 'about:') &&
+ (e.button == 0 || e.button == 1)) {
+ chrome.send('navigateToUrl', [
+ el.href,
+ el.target,
+ e.button,
+ e.altKey,
+ e.ctrlKey,
+ e.metaKey,
+ e.shiftKey
+ ]);
+ e.preventDefault();
+ }
+ }
+});
+
+/**
+ * Creates a new URL which is the old URL with a GET param of key=value.
+ * @param {string} url The base URL. There is not sanity checking on the URL so
+ * it must be passed in a proper format.
+ * @param {string} key The key of the param.
+ * @param {string} value The value of the param.
+ * @return {string} The new URL.
+ */
+function appendParam(url, key, value) {
+ var param = encodeURIComponent(key) + '=' + encodeURIComponent(value);
+
+ if (url.indexOf('?') == -1)
+ return url + '?' + param;
+ return url + '&' + param;
+}
+
+/**
+ * Creates a CSS -webkit-image-set for a favicon request.
+ * @param {string} url The url for the favicon.
+ * @param {number=} opt_size Optional preferred size of the favicon.
+ * @param {string=} opt_type Optional type of favicon to request. Valid values
+ * are 'favicon' and 'touch-icon'. Default is 'favicon'.
+ * @return {string} -webkit-image-set for the favicon.
+ */
+function getFaviconImageSet(url, opt_size, opt_type) {
+ var size = opt_size || 16;
+ var type = opt_type || 'favicon';
+ return imageset(
+ 'chrome://' + type + '/size/' + size + '@scalefactorx/' + url);
+}
+
+/**
+ * Creates a new URL for a favicon request for the current device pixel ratio.
+ * The URL must be updated when the user moves the browser to a screen with a
+ * different device pixel ratio. Use getFaviconImageSet() for the updating to
+ * occur automatically.
+ * @param {string} url The url for the favicon.
+ * @param {number=} opt_size Optional preferred size of the favicon.
+ * @param {string=} opt_type Optional type of favicon to request. Valid values
+ * are 'favicon' and 'touch-icon'. Default is 'favicon'.
+ * @return {string} Updated URL for the favicon.
+ */
+function getFaviconUrlForCurrentDevicePixelRatio(url, opt_size, opt_type) {
+ var size = opt_size || 16;
+ var type = opt_type || 'favicon';
+ return 'chrome://' + type + '/size/' + size + '@' +
+ window.devicePixelRatio + 'x/' + url;
+}
+
+/**
+ * Creates an element of a specified type with a specified class name.
+ * @param {string} type The node type.
+ * @param {string} className The class name to use.
+ * @return {Element} The created element.
+ */
+function createElementWithClassName(type, className) {
+ var elm = document.createElement(type);
+ elm.className = className;
+ return elm;
+}
+
+/**
+ * webkitTransitionEnd does not always fire (e.g. when animation is aborted
+ * or when no paint happens during the animation). This function sets up
+ * a timer and emulate the event if it is not fired when the timer expires.
+ * @param {!HTMLElement} el The element to watch for webkitTransitionEnd.
+ * @param {number} timeOut The maximum wait time in milliseconds for the
+ * webkitTransitionEnd to happen.
+ */
+function ensureTransitionEndEvent(el, timeOut) {
+ var fired = false;
+ el.addEventListener('webkitTransitionEnd', function f(e) {
+ el.removeEventListener('webkitTransitionEnd', f);
+ fired = true;
+ });
+ window.setTimeout(function() {
+ if (!fired)
+ cr.dispatchSimpleEvent(el, 'webkitTransitionEnd', true);
+ }, timeOut);
+}
+
+/**
+ * Alias for document.scrollTop getter.
+ * @param {!HTMLDocument} doc The document node where information will be
+ * queried from.
+ * @return {number} The Y document scroll offset.
+ */
+function scrollTopForDocument(doc) {
+ return doc.documentElement.scrollTop || doc.body.scrollTop;
+}
+
+/**
+ * Alias for document.scrollTop setter.
+ * @param {!HTMLDocument} doc The document node where information will be
+ * queried from.
+ * @param {number} value The target Y scroll offset.
+ */
+function setScrollTopForDocument(doc, value) {
+ doc.documentElement.scrollTop = doc.body.scrollTop = value;
+}
+
+/**
+ * Alias for document.scrollLeft getter.
+ * @param {!HTMLDocument} doc The document node where information will be
+ * queried from.
+ * @return {number} The X document scroll offset.
+ */
+function scrollLeftForDocument(doc) {
+ return doc.documentElement.scrollLeft || doc.body.scrollLeft;
+}
+
+/**
+ * Alias for document.scrollLeft setter.
+ * @param {!HTMLDocument} doc The document node where information will be
+ * queried from.
+ * @param {number} value The target X scroll offset.
+ */
+function setScrollLeftForDocument(doc, value) {
+ doc.documentElement.scrollLeft = doc.body.scrollLeft = value;
+}
+
+/**
+ * Replaces '&', '<', '>', '"', and ''' characters with their HTML encoding.
+ * @param {string} original The original string.
+ * @return {string} The string with all the characters mentioned above replaced.
+ */
+function HTMLEscape(original) {
+ return original.replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;')
+ .replace(/'/g, '&#39;');
+}
+
+/**
+ * Shortens the provided string (if necessary) to a string of length at most
+ * |maxLength|.
+ * @param {string} original The original string.
+ * @param {number} maxLength The maximum length allowed for the string.
+ * @return {string} The original string if its length does not exceed
+ * |maxLength|. Otherwise the first |maxLength| - 1 characters with '...'
+ * appended.
+ */
+function elide(original, maxLength) {
+ if (original.length <= maxLength)
+ return original;
+ return original.substring(0, maxLength - 1) + '\u2026';
+};
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Assertion support.
+ */
+
+/**
+ * Verify |condition| is truthy and return |condition| if so.
+ * @template T
+ * @param {T} condition A condition to check for truthiness. Note that this
+ * may be used to test whether a value is defined or not, and we don't want
+ * to force a cast to Boolean.
+ * @param {string=} opt_message A message to show on failure.
+ * @return {T} A non-null |condition|.
+ */
+function assert(condition, opt_message) {
+ if (!condition) {
+ var message = 'Assertion failed';
+ if (opt_message)
+ message = message + ': ' + opt_message;
+ var error = new Error(message);
+ var global = function() { return this; }();
+ if (global.traceAssertionsForTesting)
+ console.warn(error.stack);
+ throw error;
+ }
+ return condition;
+}
+
+/**
+ * Call this from places in the code that should never be reached.
+ *
+ * For example, handling all the values of enum with a switch() like this:
+ *
+ * function getValueFromEnum(enum) {
+ * switch (enum) {
+ * case ENUM_FIRST_OF_TWO:
+ * return first
+ * case ENUM_LAST_OF_TWO:
+ * return last;
+ * }
+ * assertNotReached();
+ * return document;
+ * }
+ *
+ * This code should only be hit in the case of serious programmer error or
+ * unexpected input.
+ *
+ * @param {string=} opt_message A message to show when this is hit.
+ */
+function assertNotReached(opt_message) {
+ assert(false, opt_message || 'Unreachable code hit');
+}
+
+/**
+ * @param {*} value The value to check.
+ * @param {function(new: T, ...)} type A user-defined constructor.
+ * @param {string=} opt_message A message to show when this is hit.
+ * @return {T}
+ * @template T
+ */
+function assertInstanceof(value, type, opt_message) {
+ assert(value instanceof type,
+ opt_message || value + ' is not a[n] ' + (type.name || typeof type));
+ return value;
+};
+// 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.
+
+cr.define('downloads', function() {
+ /**
+ * @param {string} chromeSendName
+ * @return {function(string):void} A chrome.send() callback with curried name.
+ */
+ function chromeSendWithId(chromeSendName) {
+ return function(id) { chrome.send(chromeSendName, [id]); };
+ }
+
+ /** @constructor */
+ function ActionService() {
+ /** @private {Array<string>} */
+ this.searchTerms_ = [];
+ }
+
+ /**
+ * @param {string} s
+ * @return {string} |s| without whitespace at the beginning or end.
+ */
+ function trim(s) { return s.trim(); }
+
+ /**
+ * @param {string|undefined} value
+ * @return {boolean} Whether |value| is truthy.
+ */
+ function truthy(value) { return !!value; }
+
+ /**
+ * @param {string} searchText Input typed by the user into a search box.
+ * @return {Array<string>} A list of terms extracted from |searchText|.
+ */
+ ActionService.splitTerms = function(searchText) {
+ // Split quoted terms (e.g., 'The "lazy" dog' => ['The', 'lazy', 'dog']).
+ return searchText.split(/"([^"]*)"/).map(trim).filter(truthy);
+ };
+
+ ActionService.prototype = {
+ /** @param {string} id ID of the download to cancel. */
+ cancel: chromeSendWithId('cancel'),
+
+ /** Instructs the browser to clear all finished downloads. */
+ clearAll: function() {
+ if (loadTimeData.getBoolean('allowDeletingHistory')) {
+ chrome.send('clearAll');
+ this.search('');
+ }
+ },
+
+ /** @param {string} id ID of the dangerous download to discard. */
+ discardDangerous: chromeSendWithId('discardDangerous'),
+
+ /** @param {string} url URL of a file to download. */
+ download: function(url) {
+ var a = document.createElement('a');
+ a.href = url;
+ a.setAttribute('download', '');
+ a.click();
+ },
+
+ /** @param {string} id ID of the download that the user started dragging. */
+ drag: chromeSendWithId('drag'),
+
+ /** Loads more downloads with the current search terms. */
+ loadMore: function() {
+ chrome.send('getDownloads', this.searchTerms_);
+ },
+
+ /**
+ * @return {boolean} Whether the user is currently searching for downloads
+ * (i.e. has a non-empty search term).
+ */
+ isSearching: function() {
+ return this.searchTerms_.length > 0;
+ },
+
+ /** Opens the current local destination for downloads. */
+ openDownloadsFolder: chrome.send.bind(chrome, 'openDownloadsFolder'),
+
+ /**
+ * @param {string} id ID of the download to run locally on the user's box.
+ */
+ openFile: chromeSendWithId('openFile'),
+
+ /** @param {string} id ID the of the progressing download to pause. */
+ pause: chromeSendWithId('pause'),
+
+ /** @param {string} id ID of the finished download to remove. */
+ remove: chromeSendWithId('remove'),
+
+ /** @param {string} id ID of the paused download to resume. */
+ resume: chromeSendWithId('resume'),
+
+ /**
+ * @param {string} id ID of the dangerous download to save despite
+ * warnings.
+ */
+ saveDangerous: chromeSendWithId('saveDangerous'),
+
+ /** @param {string} searchText What to search for. */
+ search: function(searchText) {
+ var searchTerms = ActionService.splitTerms(searchText);
+ var sameTerms = searchTerms.length == this.searchTerms_.length;
+
+ for (var i = 0; sameTerms && i < searchTerms.length; ++i) {
+ if (searchTerms[i] != this.searchTerms_[i])
+ sameTerms = false;
+ }
+
+ if (sameTerms)
+ return;
+
+ this.searchTerms_ = searchTerms;
+ this.loadMore();
+ },
+
+ /**
+ * Shows the local folder a finished download resides in.
+ * @param {string} id ID of the download to show.
+ */
+ show: chromeSendWithId('show'),
+
+ /** Undo download removal. */
+ undo: chrome.send.bind(chrome, 'undo'),
+ };
+
+ cr.addSingletonGetter(ActionService);
+
+ return {ActionService: ActionService};
+});
+// 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.
+
+cr.define('downloads', function() {
+ /**
+ * Explains why a download is in DANGEROUS state.
+ * @enum {string}
+ */
+ var DangerType = {
+ NOT_DANGEROUS: 'NOT_DANGEROUS',
+ DANGEROUS_FILE: 'DANGEROUS_FILE',
+ DANGEROUS_URL: 'DANGEROUS_URL',
+ DANGEROUS_CONTENT: 'DANGEROUS_CONTENT',
+ UNCOMMON_CONTENT: 'UNCOMMON_CONTENT',
+ DANGEROUS_HOST: 'DANGEROUS_HOST',
+ POTENTIALLY_UNWANTED: 'POTENTIALLY_UNWANTED',
+ };
+
+ /**
+ * The states a download can be in. These correspond to states defined in
+ * DownloadsDOMHandler::CreateDownloadItemValue
+ * @enum {string}
+ */
+ var States = {
+ IN_PROGRESS: 'IN_PROGRESS',
+ CANCELLED: 'CANCELLED',
+ COMPLETE: 'COMPLETE',
+ PAUSED: 'PAUSED',
+ DANGEROUS: 'DANGEROUS',
+ INTERRUPTED: 'INTERRUPTED',
+ };
+
+ return {
+ DangerType: DangerType,
+ States: States,
+ };
+});
+// 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.
+
+// Action links are elements that are used to perform an in-page navigation or
+// action (e.g. showing a dialog).
+//
+// They look like normal anchor (<a>) tags as their text color is blue. However,
+// they're subtly different as they're not initially underlined (giving users a
+// clue that underlined links navigate while action links don't).
+//
+// Action links look very similar to normal links when hovered (hand cursor,
+// underlined). This gives the user an idea that clicking this link will do
+// something similar to navigation but in the same page.
+//
+// They can be created in JavaScript like this:
+//
+// var link = document.createElement('a', 'action-link'); // Note second arg.
+//
+// or with a constructor like this:
+//
+// var link = new ActionLink();
+//
+// They can be used easily from HTML as well, like so:
+//
+// <a is="action-link">Click me!</a>
+//
+// NOTE: <action-link> and document.createElement('action-link') don't work.
+
+/**
+ * @constructor
+ * @extends {HTMLAnchorElement}
+ */
+var ActionLink = document.registerElement('action-link', {
+ prototype: {
+ __proto__: HTMLAnchorElement.prototype,
+
+ /** @this {ActionLink} */
+ createdCallback: function() {
+ // Action links can start disabled (e.g. <a is="action-link" disabled>).
+ this.tabIndex = this.disabled ? -1 : 0;
+
+ if (!this.hasAttribute('role'))
+ this.setAttribute('role', 'link');
+
+ this.addEventListener('keydown', function(e) {
+ if (!this.disabled && e.keyIdentifier == 'Enter') {
+ // Schedule a click asynchronously because other 'keydown' handlers
+ // may still run later (e.g. document.addEventListener('keydown')).
+ // Specifically options dialogs break when this timeout isn't here.
+ // NOTE: this affects the "trusted" state of the ensuing click. I
+ // haven't found anything that breaks because of this (yet).
+ window.setTimeout(this.click.bind(this), 0);
+ }
+ });
+
+ function preventDefault(e) {
+ e.preventDefault();
+ }
+
+ function removePreventDefault() {
+ document.removeEventListener('selectstart', preventDefault);
+ document.removeEventListener('mouseup', removePreventDefault);
+ }
+
+ this.addEventListener('mousedown', function() {
+ // This handlers strives to match the behavior of <a href="...">.
+
+ // While the mouse is down, prevent text selection from dragging.
+ document.addEventListener('selectstart', preventDefault);
+ document.addEventListener('mouseup', removePreventDefault);
+
+ // If focus started via mouse press, don't show an outline.
+ if (document.activeElement != this)
+ this.classList.add('no-outline');
+ });
+
+ this.addEventListener('blur', function() {
+ this.classList.remove('no-outline');
+ });
+ },
+
+ /** @type {boolean} */
+ set disabled(disabled) {
+ if (disabled)
+ HTMLAnchorElement.prototype.setAttribute.call(this, 'disabled', '');
+ else
+ HTMLAnchorElement.prototype.removeAttribute.call(this, 'disabled');
+ this.tabIndex = disabled ? -1 : 0;
+ },
+ get disabled() {
+ return this.hasAttribute('disabled');
+ },
+
+ /** @override */
+ setAttribute: function(attr, val) {
+ if (attr.toLowerCase() == 'disabled')
+ this.disabled = true;
+ else
+ HTMLAnchorElement.prototype.setAttribute.apply(this, arguments);
+ },
+
+ /** @override */
+ removeAttribute: function(attr) {
+ if (attr.toLowerCase() == 'disabled')
+ this.disabled = false;
+ else
+ HTMLAnchorElement.prototype.removeAttribute.apply(this, arguments);
+ },
+ },
+
+ extends: 'a',
+});
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+!function(a,b){b["true"]=a;var c={},d={},e={},f=null;!function(a){function b(a){if("number"==typeof a)return a;var b={};for(var c in a)b[c]=a[c];return b}function c(){this._delay=0,this._endDelay=0,this._fill="none",this._iterationStart=0,this._iterations=1,this._duration=0,this._playbackRate=1,this._direction="normal",this._easing="linear"}function d(b,d){var e=new c;return d&&(e.fill="both",e.duration="auto"),"number"!=typeof b||isNaN(b)?void 0!==b&&Object.getOwnPropertyNames(b).forEach(function(c){if("auto"!=b[c]){if(("number"==typeof e[c]||"duration"==c)&&("number"!=typeof b[c]||isNaN(b[c])))return;if("fill"==c&&-1==s.indexOf(b[c]))return;if("direction"==c&&-1==t.indexOf(b[c]))return;if("playbackRate"==c&&1!==b[c]&&a.isDeprecated("AnimationEffectTiming.playbackRate","2014-11-28","Use Animation.playbackRate instead."))return;e[c]=b[c]}}):e.duration=b,e}function e(a){return"number"==typeof a&&(a=isNaN(a)?{duration:0}:{duration:a}),a}function f(b,c){b=a.numericTimingToObject(b);var e=d(b,c);return e._easing=i(e.easing),e}function g(a,b,c,d){return 0>a||a>1||0>c||c>1?B:function(e){function f(a,b,c){return 3*a*(1-c)*(1-c)*c+3*b*(1-c)*c*c+c*c*c}if(0==e||1==e)return e;for(var g=0,h=1;;){var i=(g+h)/2,j=f(a,c,i);if(Math.abs(e-j)<.001)return f(b,d,i);e>j?g=i:h=i}}}function h(a,b){return function(c){if(c>=1)return 1;var d=1/a;return c+=b*d,c-c%d}}function i(a){var b=z.exec(a);if(b)return g.apply(this,b.slice(1).map(Number));var c=A.exec(a);if(c)return h(Number(c[1]),{start:u,middle:v,end:w}[c[2]]);var d=x[a];return d?d:B}function j(a){return Math.abs(k(a)/a.playbackRate)}function k(a){return a.duration*a.iterations}function l(a,b,c){return null==b?C:b<c.delay?D:b>=c.delay+a?E:F}function m(a,b,c,d,e){switch(d){case D:return"backwards"==b||"both"==b?0:null;case F:return c-e;case E:return"forwards"==b||"both"==b?a:null;case C:return null}}function n(a,b,c,d){return(d.playbackRate<0?b-a:b)*d.playbackRate+c}function o(a,b,c,d,e){return 1/0===c||c===-1/0||c-d==b&&e.iterations&&(e.iterations+e.iterationStart)%1==0?a:c%a}function p(a,b,c,d){return 0===c?0:b==a?d.iterationStart+d.iterations-1:Math.floor(c/a)}function q(a,b,c,d){var e=a%2>=1,f="normal"==d.direction||d.direction==(e?"alternate-reverse":"alternate"),g=f?c:b-c,h=g/b;return b*d.easing(h)}function r(a,b,c){var d=l(a,b,c),e=m(a,c.fill,b,d,c.delay);if(null===e)return null;if(0===a)return d===D?0:1;var f=c.iterationStart*c.duration,g=n(a,e,f,c),h=o(c.duration,k(c),g,f,c),i=p(c.duration,h,g,c);return q(i,c.duration,h,c)/c.duration}var s="backwards|forwards|both|none".split("|"),t="reverse|alternate|alternate-reverse".split("|");c.prototype={_setMember:function(b,c){this["_"+b]=c,this._effect&&(this._effect._timingInput[b]=c,this._effect._timing=a.normalizeTimingInput(a.normalizeTimingInput(this._effect._timingInput)),this._effect.activeDuration=a.calculateActiveDuration(this._effect._timing),this._effect._animation&&this._effect._animation._rebuildUnderlyingAnimation())},get playbackRate(){return this._playbackRate},set delay(a){this._setMember("delay",a)},get delay(){return this._delay},set endDelay(a){this._setMember("endDelay",a)},get endDelay(){return this._endDelay},set fill(a){this._setMember("fill",a)},get fill(){return this._fill},set iterationStart(a){this._setMember("iterationStart",a)},get iterationStart(){return this._iterationStart},set duration(a){this._setMember("duration",a)},get duration(){return this._duration},set direction(a){this._setMember("direction",a)},get direction(){return this._direction},set easing(a){this._setMember("easing",a)},get easing(){return this._easing},set iterations(a){this._setMember("iterations",a)},get iterations(){return this._iterations}};var u=1,v=.5,w=0,x={ease:g(.25,.1,.25,1),"ease-in":g(.42,0,1,1),"ease-out":g(0,0,.58,1),"ease-in-out":g(.42,0,.58,1),"step-start":h(1,u),"step-middle":h(1,v),"step-end":h(1,w)},y="\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*",z=new RegExp("cubic-bezier\\("+y+","+y+","+y+","+y+"\\)"),A=/steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/,B=function(a){return a},C=0,D=1,E=2,F=3;a.cloneTimingInput=b,a.makeTiming=d,a.numericTimingToObject=e,a.normalizeTimingInput=f,a.calculateActiveDuration=j,a.calculateTimeFraction=r,a.calculatePhase=l,a.toTimingFunction=i}(c,f),function(a){function b(a,b){return a in h?h[a][b]||b:b}function c(a,c,d){var g=e[a];if(g){f.style[a]=c;for(var h in g){var i=g[h],j=f.style[i];d[i]=b(i,j)}}else d[a]=b(a,c)}function d(b){function d(){var a=e.length;null==e[a-1].offset&&(e[a-1].offset=1),a>1&&null==e[0].offset&&(e[0].offset=0);for(var b=0,c=e[0].offset,d=1;a>d;d++){var f=e[d].offset;if(null!=f){for(var g=1;d-b>g;g++)e[b+g].offset=c+(f-c)*g/(d-b);b=d,c=f}}}if(!Array.isArray(b)&&null!==b)throw new TypeError("Keyframes must be null or an array of keyframes");if(null==b)return[];for(var e=b.map(function(b){var d={};for(var e in b){var f=b[e];if("offset"==e){if(null!=f&&(f=Number(f),!isFinite(f)))throw new TypeError("keyframe offsets must be numbers.")}else{if("composite"==e)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"add compositing is not supported"};f="easing"==e?a.toTimingFunction(f):""+f}c(e,f,d)}return void 0==d.offset&&(d.offset=null),void 0==d.easing&&(d.easing=a.toTimingFunction("linear")),d}),f=!0,g=-1/0,h=0;h<e.length;h++){var i=e[h].offset;if(null!=i){if(g>i)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:"InvalidModificationError",message:"Keyframes are not loosely sorted by offset. Sort or specify offsets."};g=i}else f=!1}return e=e.filter(function(a){return a.offset>=0&&a.offset<=1}),f||d(),e}var e={background:["backgroundImage","backgroundPosition","backgroundSize","backgroundRepeat","backgroundAttachment","backgroundOrigin","backgroundClip","backgroundColor"],border:["borderTopColor","borderTopStyle","borderTopWidth","borderRightColor","borderRightStyle","borderRightWidth","borderBottomColor","borderBottomStyle","borderBottomWidth","borderLeftColor","borderLeftStyle","borderLeftWidth"],borderBottom:["borderBottomWidth","borderBottomStyle","borderBottomColor"],borderColor:["borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],borderLeft:["borderLeftWidth","borderLeftStyle","borderLeftColor"],borderRadius:["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],borderRight:["borderRightWidth","borderRightStyle","borderRightColor"],borderTop:["borderTopWidth","borderTopStyle","borderTopColor"],borderWidth:["borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],flex:["flexGrow","flexShrink","flexBasis"],font:["fontFamily","fontSize","fontStyle","fontVariant","fontWeight","lineHeight"],margin:["marginTop","marginRight","marginBottom","marginLeft"],outline:["outlineColor","outlineStyle","outlineWidth"],padding:["paddingTop","paddingRight","paddingBottom","paddingLeft"]},f=document.createElementNS("http://www.w3.org/1999/xhtml","div"),g={thin:"1px",medium:"3px",thick:"5px"},h={borderBottomWidth:g,borderLeftWidth:g,borderRightWidth:g,borderTopWidth:g,fontSize:{"xx-small":"60%","x-small":"75%",small:"89%",medium:"100%",large:"120%","x-large":"150%","xx-large":"200%"},fontWeight:{normal:"400",bold:"700"},outlineWidth:g,textShadow:{none:"0px 0px 0px transparent"},boxShadow:{none:"0px 0px 0px 0px transparent"}};a.normalizeKeyframes=d}(c,f),function(a){var b={};a.isDeprecated=function(a,c,d,e){var f=e?"are":"is",g=new Date,h=new Date(c);return h.setMonth(h.getMonth()+3),h>g?(a in b||console.warn("Web Animations: "+a+" "+f+" deprecated and will stop working on "+h.toDateString()+". "+d),b[a]=!0,!1):!0},a.deprecated=function(b,c,d,e){var f=e?"are":"is";if(a.isDeprecated(b,c,d,e))throw new Error(b+" "+f+" no longer supported. "+d)}}(c),function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,"play|currentTime|pause|reverse|playbackRate|cancel|finish|startTime|playState".split("|").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}!function(a,b){function c(a){for(var b={},c=0;c<a.length;c++)for(var d in a[c])if("offset"!=d&&"easing"!=d&&"composite"!=d){var e={offset:a[c].offset,easing:a[c].easing,value:a[c][d]};b[d]=b[d]||[],b[d].push(e)}for(var f in b){var g=b[f];if(0!=g[0].offset||1!=g[g.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"Partial keyframes are not supported"}}return b}function d(a){var c=[];for(var d in a)for(var e=a[d],f=0;f<e.length-1;f++){var g=e[f].offset,h=e[f+1].offset,i=e[f].value,j=e[f+1].value;g==h&&(1==h?i=j:j=i),c.push({startTime:g,endTime:h,easing:e[f].easing,property:d,interpolation:b.propertyInterpolation(d,i,j)})}return c.sort(function(a,b){return a.startTime-b.startTime}),c}b.convertEffectInput=function(e){var f=a.normalizeKeyframes(e),g=c(f),h=d(g);return function(a,c){if(null!=c)h.filter(function(a){return 0>=c&&0==a.startTime||c>=1&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(d){var e=c-d.startTime,f=d.endTime-d.startTime,g=0==f?0:d.easing(e/f);b.apply(a,d.property,d.interpolation(g))});else for(var d in g)"offset"!=d&&"easing"!=d&&"composite"!=d&&b.clear(a,d)}}}(c,d,f),function(a){function b(a,b,c){e[c]=e[c]||[],e[c].push([a,b])}function c(a,c,d){for(var e=0;e<d.length;e++){var f=d[e];b(a,c,f),/-/.test(f)&&b(a,c,f.replace(/-(.)/g,function(a,b){return b.toUpperCase()}))}}function d(b,c,d){if("initial"==c||"initial"==d){var g=b.replace(/-(.)/g,function(a,b){return b.toUpperCase()});"initial"==c&&(c=f[g]),"initial"==d&&(d=f[g])}for(var h=c==d?[]:e[b],i=0;h&&i<h.length;i++){var j=h[i][0](c),k=h[i][0](d);if(void 0!==j&&void 0!==k){var l=h[i][1](j,k);if(l){var m=a.Interpolation.apply(null,l);return function(a){return 0==a?c:1==a?d:m(a)}}}}return a.Interpolation(!1,!0,function(a){return a?d:c})}var e={};a.addPropertiesHandler=c;var f={backgroundColor:"transparent",backgroundPosition:"0% 0%",borderBottomColor:"currentColor",borderBottomLeftRadius:"0px",borderBottomRightRadius:"0px",borderBottomWidth:"3px",borderLeftColor:"currentColor",borderLeftWidth:"3px",borderRightColor:"currentColor",borderRightWidth:"3px",borderSpacing:"2px",borderTopColor:"currentColor",borderTopLeftRadius:"0px",borderTopRightRadius:"0px",borderTopWidth:"3px",bottom:"auto",clip:"rect(0px, 0px, 0px, 0px)",color:"black",fontSize:"100%",fontWeight:"400",height:"auto",left:"auto",letterSpacing:"normal",lineHeight:"120%",marginBottom:"0px",marginLeft:"0px",marginRight:"0px",marginTop:"0px",maxHeight:"none",maxWidth:"none",minHeight:"0px",minWidth:"0px",opacity:"1.0",outlineColor:"invert",outlineOffset:"0px",outlineWidth:"3px",paddingBottom:"0px",paddingLeft:"0px",paddingRight:"0px",paddingTop:"0px",right:"auto",textIndent:"0px",textShadow:"0px 0px 0px transparent",top:"auto",transform:"",verticalAlign:"0px",visibility:"visible",width:"auto",wordSpacing:"normal",zIndex:"auto"};a.propertyInterpolation=d}(d,f),function(a,b){function c(b){var c=a.calculateActiveDuration(b),d=function(d){return a.calculateTimeFraction(c,d,b)};return d._totalDuration=b.delay+c+b.endDelay,d._isCurrent=function(d){var e=a.calculatePhase(c,d,b);return e===PhaseActive||e===PhaseBefore},d}b.KeyframeEffect=function(d,e,f){var g,h=c(a.normalizeTimingInput(f)),i=b.convertEffectInput(e),j=function(){i(d,g)};return j._update=function(a){return g=h(a),null!==g},j._clear=function(){i(d,null)},j._hasSameTarget=function(a){return d===a},j._isCurrent=h._isCurrent,j._totalDuration=h._totalDuration,j},b.NullEffect=function(a){var b=function(){a&&(a(),a=null)};return b._update=function(){return null},b._totalDuration=0,b._isCurrent=function(){return!1},b._hasSameTarget=function(){return!1},b}}(c,d,f),function(a){a.apply=function(b,c,d){b.style[a.propertyName(c)]=d},a.clear=function(b,c){b.style[a.propertyName(c)]=""}}(d,f),function(a){window.Element.prototype.animate=function(b,c){return a.timeline._play(a.KeyframeEffect(this,b,c))}}(d),function(a){function b(a,c,d){if("number"==typeof a&&"number"==typeof c)return a*(1-d)+c*d;if("boolean"==typeof a&&"boolean"==typeof c)return.5>d?a:c;if(a.length==c.length){for(var e=[],f=0;f<a.length;f++)e.push(b(a[f],c[f],d));return e}throw"Mismatched interpolation arguments "+a+":"+c}a.Interpolation=function(a,c,d){return function(e){return d(b(a,c,e))}}}(d,f),function(a,b){a.sequenceNumber=0;var c=function(a,b,c){this.target=a,this.currentTime=b,this.timelineTime=c,this.type="finish",this.bubbles=!1,this.cancelable=!1,this.currentTarget=a,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()};b.Animation=function(b){this._sequenceNumber=a.sequenceNumber++,this._currentTime=0,this._startTime=null,this._paused=!1,this._playbackRate=1,this._inTimeline=!0,this._finishedFlag=!1,this.onfinish=null,this._finishHandlers=[],this._effect=b,this._inEffect=this._effect._update(0),this._idle=!0,this._currentTimePending=!1},b.Animation.prototype={_ensureAlive:function(){this._inEffect=this._effect._update(this.playbackRate<0&&0===this.currentTime?-1:this.currentTime),this._inTimeline||!this._inEffect&&this._finishedFlag||(this._inTimeline=!0,b.timeline._animations.push(this))},_tickCurrentTime:function(a,b){a!=this._currentTime&&(this._currentTime=a,this._isFinished&&!b&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this._ensureAlive())},get currentTime(){return this._idle||this._currentTimePending?null:this._currentTime},set currentTime(a){a=+a,isNaN(a)||(b.restart(),this._paused||null==this._startTime||(this._startTime=this._timeline.currentTime-a/this._playbackRate),this._currentTimePending=!1,this._currentTime!=a&&(this._tickCurrentTime(a,!0),b.invalidateEffects()))},get startTime(){return this._startTime},set startTime(a){a=+a,isNaN(a)||this._paused||this._idle||(this._startTime=a,this._tickCurrentTime((this._timeline.currentTime-this._startTime)*this.playbackRate),b.invalidateEffects())},get playbackRate(){return this._playbackRate},set playbackRate(a){if(a!=this._playbackRate){var b=this.currentTime;this._playbackRate=a,this._startTime=null,"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!=b&&(this.currentTime=b)}},get _isFinished(){return!this._idle&&(this._playbackRate>0&&this._currentTime>=this._totalDuration||this._playbackRate<0&&this._currentTime<=0)},get _totalDuration(){return this._effect._totalDuration},get playState(){return this._idle?"idle":null==this._startTime&&!this._paused&&0!=this.playbackRate||this._currentTimePending?"pending":this._paused?"paused":this._isFinished?"finished":"running"},play:function(){this._paused=!1,(this._isFinished||this._idle)&&(this._currentTime=this._playbackRate>0?0:this._totalDuration,this._startTime=null,b.invalidateEffects()),this._finishedFlag=!1,b.restart(),this._idle=!1,this._ensureAlive()},pause:function(){this._isFinished||this._paused||this._idle||(this._currentTimePending=!0),this._startTime=null,this._paused=!0},finish:function(){this._idle||(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this._currentTimePending=!1)},cancel:function(){this._inEffect&&(this._inEffect=!1,this._idle=!0,this.currentTime=0,this._startTime=null,this._effect._update(null),b.invalidateEffects(),b.restart())},reverse:function(){this.playbackRate*=-1,this.play()},addEventListener:function(a,b){"function"==typeof b&&"finish"==a&&this._finishHandlers.push(b)},removeEventListener:function(a,b){if("finish"==a){var c=this._finishHandlers.indexOf(b);c>=0&&this._finishHandlers.splice(c,1)}},_fireEvents:function(a){var b=this._isFinished;if((b||this._idle)&&!this._finishedFlag){var d=new c(this,this._currentTime,a),e=this._finishHandlers.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){e.forEach(function(a){a.call(d.target,d)})},0)}this._finishedFlag=b},_tick:function(a){return this._idle||this._paused||(null==this._startTime?this.startTime=a-this._currentTime/this.playbackRate:this._isFinished||this._tickCurrentTime((a-this._startTime)*this.playbackRate)),this._currentTimePending=!1,this._fireEvents(a),!this._idle&&(this._inEffect||!this._finishedFlag)}}}(c,d,f),function(a,b){function c(a){var b=i;i=[],a<s.currentTime&&(a=s.currentTime),g(a),b.forEach(function(b){b[1](a)}),o&&g(a),f(),l=void 0}function d(a,b){return a._sequenceNumber-b._sequenceNumber}function e(){this._animations=[],this.currentTime=window.performance&&performance.now?performance.now():0}function f(){p.forEach(function(a){a()}),p.length=0}function g(a){n=!1;var c=b.timeline;c.currentTime=a,c._animations.sort(d),m=!1;var e=c._animations;c._animations=[];var f=[],g=[];e=e.filter(function(b){return b._inTimeline=b._tick(a),b._inEffect?g.push(b._effect):f.push(b._effect),b._isFinished||b._paused||b._idle||(m=!0),b._inTimeline}),p.push.apply(p,f),p.push.apply(p,g),c._animations.push.apply(c._animations,e),o=!1,m&&requestAnimationFrame(function(){})}var h=window.requestAnimationFrame,i=[],j=0;window.requestAnimationFrame=function(a){var b=j++;return 0==i.length&&h(c),i.push([b,a]),b},window.cancelAnimationFrame=function(a){i.forEach(function(b){b[0]==a&&(b[1]=function(){})})},e.prototype={_play:function(c){c._timing=a.normalizeTimingInput(c.timing);var d=new b.Animation(c);return d._idle=!1,d._timeline=this,this._animations.push(d),b.restart(),b.invalidateEffects(),d}};var k,l=void 0,k=function(){return void 0==l&&(l=performance.now()),l},m=!1,n=!1;b.restart=function(){return m||(m=!0,requestAnimationFrame(function(){}),n=!0),n};var o=!1;b.invalidateEffects=function(){o=!0};var p=[],q=1e3/60,r=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){if(o){var a=k();a-s.currentTime>0&&(s.currentTime+=q*(Math.floor((a-s.currentTime)/q)+1)),g(s.currentTime)}return f(),r.apply(this,arguments)}});var s=new e;b.timeline=s}(c,d,f),function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\s*/,"");var c=a(b);return c?[c[0],c[1].replace(/^\s*/,"")]:void 0}function d(a,d,e){a=c.bind(null,a);for(var f=[];;){var g=a(e);if(!g)return[f,e];if(f.push(g[0]),e=g[1],g=b(d,e),!g||""==g[1])return[f,e];e=g[1]}}function e(a,b){for(var c=0,d=0;d<b.length&&(!/\s|,/.test(b[d])||0!=c);d++)if("("==b[d])c++;else if(")"==b[d]&&(c--,0==c&&d++,0>=c))break;var e=a(b.substr(0,d));return void 0==e?void 0:[e,b.substr(d)]}function f(a,b){for(var c=a,d=b;c&&d;)c>d?c%=d:d%=c;return c=a*b/(c+d)}function g(a){return function(b){var c=a(b);return c&&(c[0]=void 0),c}}function h(a,b){return function(c){var d=a(c);return d?d:[b,c]}}function i(b,c){for(var d=[],e=0;e<b.length;e++){var f=a.consumeTrimmed(b[e],c);if(!f||""==f[0])return;void 0!==f[0]&&d.push(f[0]),c=f[1]}return""==c?d:void 0}function j(a,b,c,d,e){for(var g=[],h=[],i=[],j=f(d.length,e.length),k=0;j>k;k++){var l=b(d[k%d.length],e[k%e.length]);if(!l)return;g.push(l[0]),h.push(l[1]),i.push(l[2])}return[g,h,function(b){var d=b.map(function(a,b){return i[b](a)}).join(c);return a?a(d):d}]}function k(a,b,c){for(var d=[],e=[],f=[],g=0,h=0;h<c.length;h++)if("function"==typeof c[h]){var i=c[h](a[g],b[g++]);d.push(i[0]),e.push(i[1]),f.push(i[2])}else!function(a){d.push(!1),e.push(!1),f.push(function(){return c[a]})}(h);return[d,e,function(a){for(var b="",c=0;c<a.length;c++)b+=f[c](a[c]);return b}]}a.consumeToken=b,a.consumeTrimmed=c,a.consumeRepeated=d,a.consumeParenthesised=e,a.ignore=g,a.optional=h,a.consumeList=i,a.mergeNestedRepeated=j.bind(null,null),a.mergeWrappedNestedRepeated=j,a.mergeList=k}(d),function(a){function b(b){function c(b){var c=a.consumeToken(/^inset/i,b);if(c)return d.inset=!0,c;var c=a.consumeLengthOrPercent(b);if(c)return d.lengths.push(c[0]),c;var c=a.consumeColor(b);return c?(d.color=c[0],c):void 0}var d={inset:!1,lengths:[],color:null},e=a.consumeRepeated(c,/^/,b);return e&&e[0].length?[d,e[1]]:void 0}function c(c){var d=a.consumeRepeated(b,/^,/,c);return d&&""==d[1]?d[0]:void 0}function d(b,c){for(;b.lengths.length<Math.max(b.lengths.length,c.lengths.length);)b.lengths.push({px:0});for(;c.lengths.length<Math.max(b.lengths.length,c.lengths.length);)c.lengths.push({px:0});if(b.inset==c.inset&&!!b.color==!!c.color){for(var d,e=[],f=[[],0],g=[[],0],h=0;h<b.lengths.length;h++){var i=a.mergeDimensions(b.lengths[h],c.lengths[h],2==h);f[0].push(i[0]),g[0].push(i[1]),e.push(i[2])}if(b.color&&c.color){var j=a.mergeColors(b.color,c.color);f[1]=j[0],g[1]=j[1],d=j[2]}return[f,g,function(a){for(var c=b.inset?"inset ":" ",f=0;f<e.length;f++)c+=e[f](a[0][f])+" ";return d&&(c+=d(a[1])),c}]}}function e(b,c,d,e){function f(a){return{inset:a,color:[0,0,0,0],lengths:[{px:0},{px:0},{px:0},{px:0}]}}for(var g=[],h=[],i=0;i<d.length||i<e.length;i++){var j=d[i]||f(e[i].inset),k=e[i]||f(d[i].inset);g.push(j),h.push(k)}return a.mergeNestedRepeated(b,c,g,h)}var f=e.bind(null,d,", ");a.addPropertiesHandler(c,f,["box-shadow","text-shadow"])}(d),function(a){function b(a){return a.toFixed(3).replace(".000","")}function c(a,b,c){return Math.min(b,Math.max(a,c))}function d(a){return/^\s*[-+]?(\d*\.)?\d+\s*$/.test(a)?Number(a):void 0}function e(a,c){return[a,c,b]}function f(a,b){return 0!=a?h(0,1/0)(a,b):void 0}function g(a,b){return[a,b,function(a){return Math.round(c(1,1/0,a))}]}function h(a,d){return function(e,f){return[e,f,function(e){return b(c(a,d,e))}]}}function i(a,b){return[a,b,Math.round]}a.clamp=c,a.addPropertiesHandler(d,h(0,1/0),["border-image-width","line-height"]),a.addPropertiesHandler(d,h(0,1),["opacity","shape-image-threshold"]),a.addPropertiesHandler(d,f,["flex-grow","flex-shrink"]),a.addPropertiesHandler(d,g,["orphans","widows"]),a.addPropertiesHandler(d,i,["z-index"]),a.parseNumber=d,a.mergeNumbers=e,a.numberToString=b}(d,f),function(a){function b(a,b){return"visible"==a||"visible"==b?[0,1,function(c){return 0>=c?a:c>=1?b:"visible"}]:void 0}a.addPropertiesHandler(String,b,["visibility"])}(d),function(a){function b(a){a=a.trim(),e.fillStyle="#000",e.fillStyle=a;var b=e.fillStyle;if(e.fillStyle="#fff",e.fillStyle=a,b==e.fillStyle){e.fillRect(0,0,1,1);var c=e.getImageData(0,0,1,1).data;e.clearRect(0,0,1,1);var d=c[3]/255;return[c[0]*d,c[1]*d,c[2]*d,d]}}function c(b,c){return[b,c,function(b){function c(a){return Math.max(0,Math.min(255,a))}if(b[3])for(var d=0;3>d;d++)b[d]=Math.round(c(b[d]/b[3]));return b[3]=a.numberToString(a.clamp(0,1,b[3])),"rgba("+b.join(",")+")"}]}var d=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");d.width=d.height=1;var e=d.getContext("2d");a.addPropertiesHandler(b,c,["background-color","border-bottom-color","border-left-color","border-right-color","border-top-color","color","outline-color","text-decoration-color"]),a.consumeColor=a.consumeParenthesised.bind(null,b),a.mergeColors=c}(d,f),function(a,b){function c(a,b){if(b=b.trim().toLowerCase(),"0"==b&&"px".search(a)>=0)return{px:0};if(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\(/g,"(");var c={};b=b.replace(a,function(a){return c[a]=null,"U"+a});for(var d="U("+a.source+")",e=b.replace(/[-+]?(\d*\.)?\d+/g,"N").replace(new RegExp("N"+d,"g"),"D").replace(/\s[+-]\s/g,"O").replace(/\s/g,""),f=[/N\*(D)/g,/(N|D)[*/]N/g,/(N|D)O\1/g,/\((N|D)\)/g],g=0;g<f.length;)f[g].test(e)?(e=e.replace(f[g],"$1"),g=0):g++;if("D"==e){for(var h in c){var i=eval(b.replace(new RegExp("U"+h,"g"),"").replace(new RegExp(d,"g"),"*0"));if(!isFinite(i))return;c[h]=i}return c}}}function d(a,b){return e(a,b,!0)}function e(b,c,d){var e,f=[];for(e in b)f.push(e);for(e in c)f.indexOf(e)<0&&f.push(e);return b=f.map(function(a){return b[a]||0}),c=f.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,e){return 1==b.length&&d&&(c=Math.max(c,0)),a.numberToString(c)+f[e]}).join(" + ");return b.length>1?"calc("+c+")":c}]}var f="px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc",g=c.bind(null,new RegExp(f,"g")),h=c.bind(null,new RegExp(f+"|%","g")),i=c.bind(null,/deg|rad|grad|turn/g);a.parseLength=g,a.parseLengthOrPercent=h,a.consumeLengthOrPercent=a.consumeParenthesised.bind(null,h),a.parseAngle=i,a.mergeDimensions=e;var j=a.consumeParenthesised.bind(null,g),k=a.consumeRepeated.bind(void 0,j,/^/),l=a.consumeRepeated.bind(void 0,k,/^,/);a.consumeSizePairList=l;var m=function(a){var b=l(a);return b&&""==b[1]?b[0]:void 0},n=a.mergeNestedRepeated.bind(void 0,d," "),o=a.mergeNestedRepeated.bind(void 0,n,",");a.mergeNonNegativeSizePair=n,a.addPropertiesHandler(m,o,["background-size"]),a.addPropertiesHandler(h,d,["border-bottom-width","border-image-width","border-left-width","border-right-width","border-top-width","flex-basis","font-size","height","line-height","max-height","max-width","outline-width","width"]),a.addPropertiesHandler(h,e,["border-bottom-left-radius","border-bottom-right-radius","border-top-left-radius","border-top-right-radius","bottom","left","letter-spacing","margin-bottom","margin-left","margin-right","margin-top","min-height","min-width","outline-offset","padding-bottom","padding-left","padding-right","padding-top","perspective","right","shape-margin","text-indent","top","vertical-align","word-spacing"])}(d,f),function(a){function b(b){return a.consumeLengthOrPercent(b)||a.consumeToken(/^auto/,b)}function c(c){var d=a.consumeList([a.ignore(a.consumeToken.bind(null,/^rect/)),a.ignore(a.consumeToken.bind(null,/^\(/)),a.consumeRepeated.bind(null,b,/^,/),a.ignore(a.consumeToken.bind(null,/^\)/))],c);return d&&4==d[0].length?d[0]:void 0}function d(b,c){return"auto"==b||"auto"==c?[!0,!1,function(d){var e=d?b:c;if("auto"==e)return"auto";var f=a.mergeDimensions(e,e);return f[2](f[0])}]:a.mergeDimensions(b,c)}function e(a){return"rect("+a+")"}var f=a.mergeWrappedNestedRepeated.bind(null,e,d,", ");a.parseBox=c,a.mergeBoxes=f,a.addPropertiesHandler(c,f,["clip"])}(d,f),function(a){function b(a){return function(b){var c=0;return a.map(function(a){return a===j?b[c++]:a})}}function c(a){return a}function d(b){if(b=b.toLowerCase().trim(),"none"==b)return[];for(var c,d=/\s*(\w+)\(([^)]*)\)/g,e=[],f=0;c=d.exec(b);){if(c.index!=f)return;f=c.index+c[0].length;var g=c[1],h=m[g];if(!h)return;var i=c[2].split(","),j=h[0];if(j.length<i.length)return;for(var n=[],o=0;o<j.length;o++){var p,q=i[o],r=j[o];if(p=q?{A:function(b){return"0"==b.trim()?l:a.parseAngle(b)},N:a.parseNumber,T:a.parseLengthOrPercent,L:a.parseLength}[r.toUpperCase()](q):{a:l,n:n[0],t:k}[r],void 0===p)return;n.push(p)}if(e.push({t:g,d:n}),d.lastIndex==b.length)return e}}function e(a){return a.toFixed(6).replace(".000000","")}function f(b,c){if(b.decompositionPair!==c){b.decompositionPair=c;var d=a.makeMatrixDecomposition(b)}if(c.decompositionPair!==b){c.decompositionPair=b;var f=a.makeMatrixDecomposition(c)}return null==d[0]||null==f[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(d[0].push(0),f[0].push(1),[d,f,function(b){var c=a.quat(d[0][3],f[0][3],b[5]),g=a.composeMatrix(b[0],b[1],b[2],c,b[4]),h=g.map(e).join(",");return h}])}function g(a){return a.replace(/[xy]/,"")}function h(a){return a.replace(/(x|y|z|3d)?$/,"3d")}function i(b,c){var d=a.makeMatrixDecomposition&&!0,e=!1;if(!b.length||!c.length){b.length||(e=!0,b=c,c=[]);for(var i=0;i<b.length;i++){var j=b[i].t,k=b[i].d,l="scale"==j.substr(0,5)?1:0;c.push({t:j,d:k.map(function(a){if("number"==typeof a)return l;var b={};for(var c in a)b[c]=l;return b})})}}var n=function(a,b){return"perspective"==a&&"perspective"==b||("matrix"==a||"matrix3d"==a)&&("matrix"==b||"matrix3d"==b)},o=[],p=[],q=[];if(b.length!=c.length){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]]}else for(var i=0;i<b.length;i++){var j,s=b[i].t,t=c[i].t,u=b[i].d,v=c[i].d,w=m[s],x=m[t];if(n(s,t)){if(!d)return;var r=f([b[i]],[c[i]]);o.push(r[0]),p.push(r[1]),q.push(["matrix",[r[2]]])}else{if(s==t)j=s;else if(w[2]&&x[2]&&g(s)==g(t))j=g(s),u=w[2](u),v=x[2](v);else{if(!w[1]||!x[1]||h(s)!=h(t)){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]];break}j=h(s),u=w[1](u),v=x[1](v)}for(var y=[],z=[],A=[],B=0;B<u.length;B++){var C="number"==typeof u[B]?a.mergeNumbers:a.mergeDimensions,r=C(u[B],v[B]);y[B]=r[0],z[B]=r[1],A.push(r[2])}o.push(y),p.push(z),q.push([j,A])}}if(e){var D=o;o=p,p=D}return[o,p,function(a){return a.map(function(a,b){var c=a.map(function(a,c){return q[b][1][c](a)}).join(",");return"matrix"==q[b][0]&&16==c.split(",").length&&(q[b][0]="matrix3d"),q[b][0]+"("+c+")"}).join(" ")}]}var j=null,k={px:0},l={deg:0},m={matrix:["NNNNNN",[j,j,0,0,j,j,0,0,0,0,1,0,j,j,0,1],c],matrix3d:["NNNNNNNNNNNNNNNN",c],rotate:["A"],rotatex:["A"],rotatey:["A"],rotatez:["A"],rotate3d:["NNNA"],perspective:["L"],scale:["Nn",b([j,j,1]),c],scalex:["N",b([j,1,1]),b([j,1])],scaley:["N",b([1,j,1]),b([1,j])],scalez:["N",b([1,1,j])],scale3d:["NNN",c],skew:["Aa",null,c],skewx:["A",null,b([j,l])],skewy:["A",null,b([l,j])],translate:["Tt",b([j,j,k]),c],translatex:["T",b([j,k,k]),b([j,k])],translatey:["T",b([k,j,k]),b([k,j])],translatez:["L",b([k,k,j])],translate3d:["TTL",c]};a.addPropertiesHandler(d,i,["transform"])}(d,f),function(a){function b(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(c[a]=b)})}var c={};b("transform",["webkitTransform","msTransform"]),b("transformOrigin",["webkitTransformOrigin"]),b("perspective",["webkitPerspective"]),b("perspectiveOrigin",["webkitPerspectiveOrigin"]),a.propertyName=function(a){return c[a]||a}}(d,f)}(),!function(a,b){function c(a){var b=window.document.timeline;b.currentTime=a,b._discardAnimations(),0==b._animations.length?e=!1:requestAnimationFrame(c)}var d=window.requestAnimationFrame;window.requestAnimationFrame=function(a){return d(function(b){window.document.timeline._updateAnimationsPromises(),a(b),window.document.timeline._updateAnimationsPromises()})},b.AnimationTimeline=function(){this._animations=[],this.currentTime=void 0},b.AnimationTimeline.prototype={getAnimations:function(){return this._discardAnimations(),this._animations.slice()},_updateAnimationsPromises:function(){b.animationsWithPromises=b.animationsWithPromises.filter(function(a){return a._updatePromises()})},_discardAnimations:function(){this._updateAnimationsPromises(),this._animations=this._animations.filter(function(a){return"finished"!=a.playState&&"idle"!=a.playState})},_play:function(a){var c=new b.Animation(a,this);return this._animations.push(c),b.restartWebAnimationsNextTick(),c._updatePromises(),c._animation.play(),c._updatePromises(),c},play:function(a){return a&&a.remove(),this._play(a)}};var e=!1;b.restartWebAnimationsNextTick=function(){e||(e=!0,requestAnimationFrame(c))};var f=new b.AnimationTimeline;b.timeline=f;try{Object.defineProperty(window.document,"timeline",{configurable:!0,get:function(){return f}})}catch(g){}try{window.document.timeline=f}catch(g){}}(c,e,f),function(a,b){b.animationsWithPromises=[],b.Animation=function(b,c){if(this.effect=b,b&&(b._animation=this),!c)throw new Error("Animation with null timeline is not supported");this._timeline=c,this._sequenceNumber=a.sequenceNumber++,this._holdTime=0,this._paused=!1,this._isGroup=!1,this._animation=null,this._childAnimations=[],this._callback=null,this._oldPlayState="idle",this._rebuildUnderlyingAnimation(),this._animation.cancel(),this._updatePromises()},b.Animation.prototype={_updatePromises:function(){var a=this._oldPlayState,b=this.playState;return this._readyPromise&&b!==a&&("idle"==b?(this._rejectReadyPromise(),this._readyPromise=void 0):"pending"==a?this._resolveReadyPromise():"pending"==b&&(this._readyPromise=void 0)),this._finishedPromise&&b!==a&&("idle"==b?(this._rejectFinishedPromise(),this._finishedPromise=void 0):"finished"==b?this._resolveFinishedPromise():"finished"==a&&(this._finishedPromise=void 0)),this._oldPlayState=this.playState,this._readyPromise||this._finishedPromise},_rebuildUnderlyingAnimation:function(){this._updatePromises();var a,c,d,e,f=this._animation?!0:!1;f&&(a=this.playbackRate,c=this._paused,d=this.startTime,e=this.currentTime,this._animation.cancel(),this._animation._wrapper=null,this._animation=null),(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this._animation=b.newUnderlyingAnimationForKeyframeEffect(this.effect),b.bindAnimationForKeyframeEffect(this)),(this.effect instanceof window.SequenceEffect||this.effect instanceof window.GroupEffect)&&(this._animation=b.newUnderlyingAnimationForGroup(this.effect),b.bindAnimationForGroup(this)),this.effect&&this.effect._onsample&&b.bindAnimationForCustomEffect(this),f&&(1!=a&&(this.playbackRate=a),null!==d?this.startTime=d:null!==e?this.currentTime=e:null!==this._holdTime&&(this.currentTime=this._holdTime),c&&this.pause()),this._updatePromises()
+},_updateChildren:function(){if(this.effect&&"idle"!=this.playState){var a=this.effect._timing.delay;this._childAnimations.forEach(function(c){this._arrangeChildren(c,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c.effect))}.bind(this))}},_setExternalAnimation:function(a){if(this.effect&&this._isGroup)for(var b=0;b<this.effect.children.length;b++)this.effect.children[b]._animation=a,this._childAnimations[b]._setExternalAnimation(a)},_constructChildAnimations:function(){if(this.effect&&this._isGroup){var a=this.effect._timing.delay;this._removeChildAnimations(),this.effect.children.forEach(function(c){var d=window.document.timeline._play(c);this._childAnimations.push(d),d.playbackRate=this.playbackRate,this._paused&&d.pause(),c._animation=this.effect._animation,this._arrangeChildren(d,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c))}.bind(this))}},_arrangeChildren:function(a,b){null===this.startTime?a.currentTime=this.currentTime-b/this.playbackRate:a.startTime!==this.startTime+b/this.playbackRate&&(a.startTime=this.startTime+b/this.playbackRate)},get timeline(){return this._timeline},get playState(){return this._animation?this._animation.playState:"idle"},get finished(){return window.Promise?(this._finishedPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._finishedPromise=new Promise(function(a,b){this._resolveFinishedPromise=function(){a(this)},this._rejectFinishedPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"finished"==this.playState&&this._resolveFinishedPromise()),this._finishedPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get ready(){return window.Promise?(this._readyPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._readyPromise=new Promise(function(a,b){this._resolveReadyPromise=function(){a(this)},this._rejectReadyPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"pending"!==this.playState&&this._resolveReadyPromise()),this._readyPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get onfinish(){return this._onfinish},set onfinish(a){"function"==typeof a?(this._onfinish=a,this._animation.onfinish=function(b){b.target=this,a.call(this,b)}.bind(this)):(this._animation.onfinish=a,this.onfinish=this._animation.onfinish)},get currentTime(){this._updatePromises();var a=this._animation.currentTime;return this._updatePromises(),a},set currentTime(a){this._updatePromises(),this._animation.currentTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.currentTime=a-c}),this._updatePromises()},get startTime(){return this._animation.startTime},set startTime(a){this._updatePromises(),this._animation.startTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.startTime=a+c}),this._updatePromises()},get playbackRate(){return this._animation.playbackRate},set playbackRate(a){this._updatePromises();var b=this.currentTime;this._animation.playbackRate=a,this._forEachChild(function(b){b.playbackRate=a}),"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!==b&&(this.currentTime=b),this._updatePromises()},play:function(){this._updatePromises(),this._paused=!1,this._animation.play(),-1==this._timeline._animations.indexOf(this)&&this._timeline._animations.push(this),this._register(),b.awaitStartTime(this),this._forEachChild(function(a){var b=a.currentTime;a.play(),a.currentTime=b}),this._updatePromises()},pause:function(){this._updatePromises(),this.currentTime&&(this._holdTime=this.currentTime),this._animation.pause(),this._register(),this._forEachChild(function(a){a.pause()}),this._paused=!0,this._updatePromises()},finish:function(){this._updatePromises(),this._animation.finish(),this._register(),this._updatePromises()},cancel:function(){this._updatePromises(),this._animation.cancel(),this._register(),this._removeChildAnimations(),this._updatePromises()},reverse:function(){this._updatePromises();var a=this.currentTime;this._animation.reverse(),this._forEachChild(function(a){a.reverse()}),null!==a&&(this.currentTime=a),this._updatePromises()},addEventListener:function(a,b){var c=b;"function"==typeof b&&(c=function(a){a.target=this,b.call(this,a)}.bind(this),b._wrapper=c),this._animation.addEventListener(a,c)},removeEventListener:function(a,b){this._animation.removeEventListener(a,b&&b._wrapper||b)},_removeChildAnimations:function(){for(;this._childAnimations.length;)this._childAnimations.pop().cancel()},_forEachChild:function(b){var c=0;if(this.effect.children&&this._childAnimations.length<this.effect.children.length&&this._constructChildAnimations(),this._childAnimations.forEach(function(a){b.call(this,a,c),this.effect instanceof window.SequenceEffect&&(c+=a.effect.activeDuration)}.bind(this)),"pending"!=this.playState){var d=this.effect._timing,e=this.currentTime;null!==e&&(e=a.calculateTimeFraction(a.calculateActiveDuration(d),e,d)),(null==e||isNaN(e))&&this._removeChildAnimations()}}},window.Animation=b.Animation}(c,e,f),function(a,b){function c(b){this._frames=a.normalizeKeyframes(b)}function d(){for(var a=!1;h.length;){var b=h.shift();b._updateChildren(),a=!0}return a}var e=function(a){if(a._animation=void 0,a instanceof window.SequenceEffect||a instanceof window.GroupEffect)for(var b=0;b<a.children.length;b++)e(a.children[b])};b.removeMulti=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d._parent?(-1==b.indexOf(d._parent)&&b.push(d._parent),d._parent.children.splice(d._parent.children.indexOf(d),1),d._parent=null,e(d)):d._animation&&d._animation.effect==d&&(d._animation.cancel(),d._animation.effect=new KeyframeEffect(null,[]),d._animation._callback&&(d._animation._callback._animation=null),d._animation._rebuildUnderlyingAnimation(),e(d))}for(c=0;c<b.length;c++)b[c]._rebuild()},b.KeyframeEffect=function(b,d,e){return this.target=b,this._parent=null,e=a.numericTimingToObject(e),this._timingInput=a.cloneTimingInput(e),this._timing=a.normalizeTimingInput(e),this.timing=a.makeTiming(e,!1,this),this.timing._effect=this,"function"==typeof d?(a.deprecated("Custom KeyframeEffect","2015-06-22","Use KeyframeEffect.onsample instead."),this._normalizedKeyframes=d):this._normalizedKeyframes=new c(d),this._keyframes=d,this.activeDuration=a.calculateActiveDuration(this._timing),this},b.KeyframeEffect.prototype={getFrames:function(){return"function"==typeof this._normalizedKeyframes?this._normalizedKeyframes:this._normalizedKeyframes._frames},set onsample(a){if("function"==typeof this.getFrames())throw new Error("Setting onsample on custom effect KeyframeEffect is not supported.");this._onsample=a,this._animation&&this._animation._rebuildUnderlyingAnimation()},get parent(){return this._parent},clone:function(){if("function"==typeof this.getFrames())throw new Error("Cloning custom effects is not supported.");var b=new KeyframeEffect(this.target,[],a.cloneTimingInput(this._timingInput));return b._normalizedKeyframes=this._normalizedKeyframes,b._keyframes=this._keyframes,b},remove:function(){b.removeMulti([this])}};var f=Element.prototype.animate;Element.prototype.animate=function(a,c){return b.timeline._play(new b.KeyframeEffect(this,a,c))};var g=document.createElementNS("http://www.w3.org/1999/xhtml","div");b.newUnderlyingAnimationForKeyframeEffect=function(a){if(a){var b=a.target||g,c=a._keyframes;"function"==typeof c&&(c=[]);var d=a._timingInput}else var b=g,c=[],d=0;return f.apply(b,[c,d])},b.bindAnimationForKeyframeEffect=function(a){a.effect&&"function"==typeof a.effect._normalizedKeyframes&&b.bindAnimationForCustomEffect(a)};var h=[];b.awaitStartTime=function(a){null===a.startTime&&a._isGroup&&(0==h.length&&requestAnimationFrame(d),h.push(a))};var i=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){window.document.timeline._updateAnimationsPromises();var a=i.apply(this,arguments);return d()&&(a=i.apply(this,arguments)),window.document.timeline._updateAnimationsPromises(),a}}),window.KeyframeEffect=b.KeyframeEffect,window.Element.prototype.getAnimations=function(){return document.timeline.getAnimations().filter(function(a){return null!==a.effect&&a.effect.target==this}.bind(this))}}(c,e,f),function(a,b){function c(a){a._registered||(a._registered=!0,f.push(a),g||(g=!0,requestAnimationFrame(d)))}function d(){var a=f;f=[],a.sort(function(a,b){return a._sequenceNumber-b._sequenceNumber}),a=a.filter(function(a){a();var b=a._animation?a._animation.playState:"idle";return"running"!=b&&"pending"!=b&&(a._registered=!1),a._registered}),f.push.apply(f,a),f.length?(g=!0,requestAnimationFrame(d)):g=!1}var e=(document.createElementNS("http://www.w3.org/1999/xhtml","div"),0);b.bindAnimationForCustomEffect=function(b){var d,f=b.effect.target,g="function"==typeof b.effect.getFrames();d=g?b.effect.getFrames():b.effect._onsample;var h=b.effect.timing,i=null;h=a.normalizeTimingInput(h);var j=function(){var c=j._animation?j._animation.currentTime:null;null!==c&&(c=a.calculateTimeFraction(a.calculateActiveDuration(h),c,h),isNaN(c)&&(c=null)),c!==i&&(g?d(c,f,b.effect):d(c,b.effect,b.effect._animation)),i=c};j._animation=b,j._registered=!1,j._sequenceNumber=e++,b._callback=j,c(j)};var f=[],g=!1;b.Animation.prototype._register=function(){this._callback&&c(this._callback)}}(c,e,f),function(a,b){function c(a){return a._timing.delay+a.activeDuration+a._timing.endDelay}function d(b,c){this._parent=null,this.children=b||[],this._reparent(this.children),c=a.numericTimingToObject(c),this._timingInput=a.cloneTimingInput(c),this._timing=a.normalizeTimingInput(c,!0),this.timing=a.makeTiming(c,!0,this),this.timing._effect=this,"auto"===this._timing.duration&&(this._timing.duration=this.activeDuration)}window.SequenceEffect=function(){d.apply(this,arguments)},window.GroupEffect=function(){d.apply(this,arguments)},d.prototype={_isAncestor:function(a){for(var b=this;null!==b;){if(b==a)return!0;b=b._parent}return!1},_rebuild:function(){for(var a=this;a;)"auto"===a.timing.duration&&(a._timing.duration=a.activeDuration),a=a._parent;this._animation&&this._animation._rebuildUnderlyingAnimation()},_reparent:function(a){b.removeMulti(a);for(var c=0;c<a.length;c++)a[c]._parent=this},_putChild:function(a,b){for(var c=b?"Cannot append an ancestor or self":"Cannot prepend an ancestor or self",d=0;d<a.length;d++)if(this._isAncestor(a[d]))throw{type:DOMException.HIERARCHY_REQUEST_ERR,name:"HierarchyRequestError",message:c};for(var d=0;d<a.length;d++)b?this.children.push(a[d]):this.children.unshift(a[d]);this._reparent(a),this._rebuild()},append:function(){this._putChild(arguments,!0)},prepend:function(){this._putChild(arguments,!1)},get parent(){return this._parent},get firstChild(){return this.children.length?this.children[0]:null},get lastChild(){return this.children.length?this.children[this.children.length-1]:null},clone:function(){for(var b=a.cloneTimingInput(this._timingInput),c=[],d=0;d<this.children.length;d++)c.push(this.children[d].clone());return this instanceof GroupEffect?new GroupEffect(c,b):new SequenceEffect(c,b)},remove:function(){b.removeMulti([this])}},window.SequenceEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.SequenceEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a+=c(b)}),Math.max(a,0)}}),window.GroupEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.GroupEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a=Math.max(a,c(b))}),a}}),b.newUnderlyingAnimationForGroup=function(c){var d,e=null,f=function(b){var c=d._wrapper;return c&&"pending"!=c.playState&&c.effect?null==b?void c._removeChildAnimations():0==b&&c.playbackRate<0&&(e||(e=a.normalizeTimingInput(c.effect.timing)),b=a.calculateTimeFraction(a.calculateActiveDuration(e),-1,e),isNaN(b)||null==b)?(c._forEachChild(function(a){a.currentTime=-1}),void c._removeChildAnimations()):void 0:void 0},g=new KeyframeEffect(null,[],c._timing);return g.onsample=f,d=b.timeline._play(g)},b.bindAnimationForGroup=function(a){a._animation._wrapper=a,a._isGroup=!0,b.awaitStartTime(a),a._constructChildAnimations(),a._setExternalAnimation(a)},b.groupChildDuration=c}(c,e,f)}({},function(){return this}());
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// <include src="../../../../ui/webui/resources/js/i18n_template_no_process.js">
+
+i18nTemplate.process(document, loadTimeData);
+(function () {
+function resolve() {
+document.body.removeAttribute('unresolved');
+}
+if (window.WebComponents) {
+addEventListener('WebComponentsReady', resolve);
+} else {
+if (document.readyState === 'interactive' || document.readyState === 'complete') {
+resolve();
+} else {
+addEventListener('DOMContentLoaded', resolve);
+}
+}
+}());
+window.Polymer = {
+Settings: function () {
+var user = window.Polymer || {};
+var parts = location.search.slice(1).split('&');
+for (var i = 0, o; i < parts.length && (o = parts[i]); i++) {
+o = o.split('=');
+o[0] && (user[o[0]] = o[1] || true);
+}
+var wantShadow = user.dom === 'shadow';
+var hasShadow = Boolean(Element.prototype.createShadowRoot);
+var nativeShadow = hasShadow && !window.ShadowDOMPolyfill;
+var useShadow = wantShadow && hasShadow;
+var hasNativeImports = Boolean('import' in document.createElement('link'));
+var useNativeImports = hasNativeImports;
+var useNativeCustomElements = !window.CustomElements || window.CustomElements.useNative;
+return {
+wantShadow: wantShadow,
+hasShadow: hasShadow,
+nativeShadow: nativeShadow,
+useShadow: useShadow,
+useNativeShadow: useShadow && nativeShadow,
+useNativeImports: useNativeImports,
+useNativeCustomElements: useNativeCustomElements
+};
+}()
+};
+(function () {
+var userPolymer = window.Polymer;
+window.Polymer = function (prototype) {
+if (typeof prototype === 'function') {
+prototype = prototype.prototype;
+}
+if (!prototype) {
+prototype = {};
+}
+var factory = desugar(prototype);
+prototype = factory.prototype;
+var options = { prototype: prototype };
+if (prototype.extends) {
+options.extends = prototype.extends;
+}
+Polymer.telemetry._registrate(prototype);
+document.registerElement(prototype.is, options);
+return factory;
+};
+var desugar = function (prototype) {
+var base = Polymer.Base;
+if (prototype.extends) {
+base = Polymer.Base._getExtendedPrototype(prototype.extends);
+}
+prototype = Polymer.Base.chainObject(prototype, base);
+prototype.registerCallback();
+return prototype.constructor;
+};
+window.Polymer = Polymer;
+if (userPolymer) {
+for (var i in userPolymer) {
+Polymer[i] = userPolymer[i];
+}
+}
+Polymer.Class = desugar;
+}());
+Polymer.telemetry = {
+registrations: [],
+_regLog: function (prototype) {
+console.log('[' + prototype.is + ']: registered');
+},
+_registrate: function (prototype) {
+this.registrations.push(prototype);
+Polymer.log && this._regLog(prototype);
+},
+dumpRegistrations: function () {
+this.registrations.forEach(this._regLog);
+}
+};
+Object.defineProperty(window, 'currentImport', {
+enumerable: true,
+configurable: true,
+get: function () {
+return (document._currentScript || document.currentScript).ownerDocument;
+}
+});
+Polymer.RenderStatus = {
+_ready: false,
+_callbacks: [],
+whenReady: function (cb) {
+if (this._ready) {
+cb();
+} else {
+this._callbacks.push(cb);
+}
+},
+_makeReady: function () {
+this._ready = true;
+for (var i = 0; i < this._callbacks.length; i++) {
+this._callbacks[i]();
+}
+this._callbacks = [];
+},
+_catchFirstRender: function () {
+requestAnimationFrame(function () {
+Polymer.RenderStatus._makeReady();
+});
+},
+_afterNextRenderQueue: [],
+_waitingNextRender: false,
+afterNextRender: function (element, fn, args) {
+this._watchNextRender();
+this._afterNextRenderQueue.push([
+element,
+fn,
+args
+]);
+},
+_watchNextRender: function () {
+if (!this._waitingNextRender) {
+this._waitingNextRender = true;
+var fn = function () {
+Polymer.RenderStatus._flushNextRender();
+};
+if (!this._ready) {
+this.whenReady(fn);
+} else {
+requestAnimationFrame(fn);
+}
+}
+},
+_flushNextRender: function () {
+var self = this;
+setTimeout(function () {
+self._flushRenderCallbacks(self._afterNextRenderQueue);
+self._afterNextRenderQueue = [];
+self._waitingNextRender = false;
+});
+},
+_flushRenderCallbacks: function (callbacks) {
+for (var i = 0, h; i < callbacks.length; i++) {
+h = callbacks[i];
+h[1].apply(h[0], h[2] || Polymer.nar);
+}
+;
+}
+};
+if (window.HTMLImports) {
+HTMLImports.whenReady(function () {
+Polymer.RenderStatus._catchFirstRender();
+});
+} else {
+Polymer.RenderStatus._catchFirstRender();
+}
+Polymer.ImportStatus = Polymer.RenderStatus;
+Polymer.ImportStatus.whenLoaded = Polymer.ImportStatus.whenReady;
+Polymer.Base = {
+__isPolymerInstance__: true,
+_addFeature: function (feature) {
+this.extend(this, feature);
+},
+registerCallback: function () {
+this._desugarBehaviors();
+this._doBehavior('beforeRegister');
+this._registerFeatures();
+this._doBehavior('registered');
+},
+createdCallback: function () {
+Polymer.telemetry.instanceCount++;
+this.root = this;
+this._doBehavior('created');
+this._initFeatures();
+},
+attachedCallback: function () {
+var self = this;
+Polymer.RenderStatus.whenReady(function () {
+self.isAttached = true;
+self._doBehavior('attached');
+});
+},
+detachedCallback: function () {
+this.isAttached = false;
+this._doBehavior('detached');
+},
+attributeChangedCallback: function (name, oldValue, newValue) {
+this._attributeChangedImpl(name);
+this._doBehavior('attributeChanged', [
+name,
+oldValue,
+newValue
+]);
+},
+_attributeChangedImpl: function (name) {
+this._setAttributeToProperty(this, name);
+},
+extend: function (prototype, api) {
+if (prototype && api) {
+var n$ = Object.getOwnPropertyNames(api);
+for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
+this.copyOwnProperty(n, api, prototype);
+}
+}
+return prototype || api;
+},
+mixin: function (target, source) {
+for (var i in source) {
+target[i] = source[i];
+}
+return target;
+},
+copyOwnProperty: function (name, source, target) {
+var pd = Object.getOwnPropertyDescriptor(source, name);
+if (pd) {
+Object.defineProperty(target, name, pd);
+}
+},
+_log: console.log.apply.bind(console.log, console),
+_warn: console.warn.apply.bind(console.warn, console),
+_error: console.error.apply.bind(console.error, console),
+_logf: function () {
+return this._logPrefix.concat([this.is]).concat(Array.prototype.slice.call(arguments, 0));
+}
+};
+Polymer.Base._logPrefix = function () {
+var color = window.chrome || /firefox/i.test(navigator.userAgent);
+return color ? [
+'%c[%s::%s]:',
+'font-weight: bold; background-color:#EEEE00;'
+] : ['[%s::%s]:'];
+}();
+Polymer.Base.chainObject = function (object, inherited) {
+if (object && inherited && object !== inherited) {
+if (!Object.__proto__) {
+object = Polymer.Base.extend(Object.create(inherited), object);
+}
+object.__proto__ = inherited;
+}
+return object;
+};
+Polymer.Base = Polymer.Base.chainObject(Polymer.Base, HTMLElement.prototype);
+if (window.CustomElements) {
+Polymer.instanceof = CustomElements.instanceof;
+} else {
+Polymer.instanceof = function (obj, ctor) {
+return obj instanceof ctor;
+};
+}
+Polymer.isInstance = function (obj) {
+return Boolean(obj && obj.__isPolymerInstance__);
+};
+Polymer.telemetry.instanceCount = 0;
+(function () {
+var modules = {};
+var lcModules = {};
+var findModule = function (id) {
+return modules[id] || lcModules[id.toLowerCase()];
+};
+var DomModule = function () {
+return document.createElement('dom-module');
+};
+DomModule.prototype = Object.create(HTMLElement.prototype);
+Polymer.Base.extend(DomModule.prototype, {
+constructor: DomModule,
+createdCallback: function () {
+this.register();
+},
+register: function (id) {
+var id = id || this.id || this.getAttribute('name') || this.getAttribute('is');
+if (id) {
+this.id = id;
+modules[id] = this;
+lcModules[id.toLowerCase()] = this;
+}
+},
+import: function (id, selector) {
+if (id) {
+var m = findModule(id);
+if (!m) {
+forceDomModulesUpgrade();
+m = findModule(id);
+}
+if (m && selector) {
+m = m.querySelector(selector);
+}
+return m;
+}
+}
+});
+var cePolyfill = window.CustomElements && !CustomElements.useNative;
+document.registerElement('dom-module', DomModule);
+function forceDomModulesUpgrade() {
+if (cePolyfill) {
+var script = document._currentScript || document.currentScript;
+var doc = script && script.ownerDocument || document;
+var modules = doc.querySelectorAll('dom-module');
+for (var i = modules.length - 1, m; i >= 0 && (m = modules[i]); i--) {
+if (m.__upgraded__) {
+return;
+} else {
+CustomElements.upgrade(m);
+}
+}
+}
+}
+}());
+Polymer.Base._addFeature({
+_prepIs: function () {
+if (!this.is) {
+var module = (document._currentScript || document.currentScript).parentNode;
+if (module.localName === 'dom-module') {
+var id = module.id || module.getAttribute('name') || module.getAttribute('is');
+this.is = id;
+}
+}
+if (this.is) {
+this.is = this.is.toLowerCase();
+}
+}
+});
+Polymer.Base._addFeature({
+behaviors: [],
+_desugarBehaviors: function () {
+if (this.behaviors.length) {
+this.behaviors = this._desugarSomeBehaviors(this.behaviors);
+}
+},
+_desugarSomeBehaviors: function (behaviors) {
+behaviors = this._flattenBehaviorsList(behaviors);
+for (var i = behaviors.length - 1; i >= 0; i--) {
+this._mixinBehavior(behaviors[i]);
+}
+return behaviors;
+},
+_flattenBehaviorsList: function (behaviors) {
+var flat = [];
+for (var i = 0; i < behaviors.length; i++) {
+var b = behaviors[i];
+if (b instanceof Array) {
+flat = flat.concat(this._flattenBehaviorsList(b));
+} else if (b) {
+flat.push(b);
+} else {
+this._warn(this._logf('_flattenBehaviorsList', 'behavior is null, check for missing or 404 import'));
+}
+}
+return flat;
+},
+_mixinBehavior: function (b) {
+var n$ = Object.getOwnPropertyNames(b);
+for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
+if (!Polymer.Base._behaviorProperties[n] && !this.hasOwnProperty(n)) {
+this.copyOwnProperty(n, b, this);
+}
+}
+},
+_prepBehaviors: function () {
+this._prepFlattenedBehaviors(this.behaviors);
+},
+_prepFlattenedBehaviors: function (behaviors) {
+for (var i = 0, l = behaviors.length; i < l; i++) {
+this._prepBehavior(behaviors[i]);
+}
+this._prepBehavior(this);
+},
+_doBehavior: function (name, args) {
+for (var i = 0; i < this.behaviors.length; i++) {
+this._invokeBehavior(this.behaviors[i], name, args);
+}
+this._invokeBehavior(this, name, args);
+},
+_invokeBehavior: function (b, name, args) {
+var fn = b[name];
+if (fn) {
+fn.apply(this, args || Polymer.nar);
+}
+},
+_marshalBehaviors: function () {
+for (var i = 0; i < this.behaviors.length; i++) {
+this._marshalBehavior(this.behaviors[i]);
+}
+this._marshalBehavior(this);
+}
+});
+Polymer.Base._behaviorProperties = {
+hostAttributes: true,
+registered: true,
+properties: true,
+observers: true,
+listeners: true,
+created: true,
+attached: true,
+detached: true,
+attributeChanged: true,
+ready: true
+};
+Polymer.Base._addFeature({
+_getExtendedPrototype: function (tag) {
+return this._getExtendedNativePrototype(tag);
+},
+_nativePrototypes: {},
+_getExtendedNativePrototype: function (tag) {
+var p = this._nativePrototypes[tag];
+if (!p) {
+var np = this.getNativePrototype(tag);
+p = this.extend(Object.create(np), Polymer.Base);
+this._nativePrototypes[tag] = p;
+}
+return p;
+},
+getNativePrototype: function (tag) {
+return Object.getPrototypeOf(document.createElement(tag));
+}
+});
+Polymer.Base._addFeature({
+_prepConstructor: function () {
+this._factoryArgs = this.extends ? [
+this.extends,
+this.is
+] : [this.is];
+var ctor = function () {
+return this._factory(arguments);
+};
+if (this.hasOwnProperty('extends')) {
+ctor.extends = this.extends;
+}
+Object.defineProperty(this, 'constructor', {
+value: ctor,
+writable: true,
+configurable: true
+});
+ctor.prototype = this;
+},
+_factory: function (args) {
+var elt = document.createElement.apply(document, this._factoryArgs);
+if (this.factoryImpl) {
+this.factoryImpl.apply(elt, args);
+}
+return elt;
+}
+});
+Polymer.nob = Object.create(null);
+Polymer.Base._addFeature({
+properties: {},
+getPropertyInfo: function (property) {
+var info = this._getPropertyInfo(property, this.properties);
+if (!info) {
+for (var i = 0; i < this.behaviors.length; i++) {
+info = this._getPropertyInfo(property, this.behaviors[i].properties);
+if (info) {
+return info;
+}
+}
+;
+}
+return info || Polymer.nob;
+},
+_getPropertyInfo: function (property, properties) {
+var p = properties && properties[property];
+if (typeof p === 'function') {
+p = properties[property] = { type: p };
+}
+if (p) {
+p.defined = true;
+}
+return p;
+},
+_prepPropertyInfo: function () {
+this._propertyInfo = {};
+for (var i = 0, p; i < this.behaviors.length; i++) {
+this._addPropertyInfo(this._propertyInfo, this.behaviors[i].properties);
+}
+this._addPropertyInfo(this._propertyInfo, this.properties);
+this._addPropertyInfo(this._propertyInfo, this._propertyEffects);
+},
+_addPropertyInfo: function (target, source) {
+if (source) {
+var t, s;
+for (var i in source) {
+t = target[i];
+s = source[i];
+if (i[0] === '_' && !s.readOnly) {
+continue;
+}
+if (!target[i]) {
+target[i] = {
+type: typeof s === 'function' ? s : s.type,
+readOnly: s.readOnly,
+attribute: Polymer.CaseMap.camelToDashCase(i)
+};
+} else {
+if (!t.type) {
+t.type = s.type;
+}
+if (!t.readOnly) {
+t.readOnly = s.readOnly;
+}
+}
+}
+}
+}
+});
+Polymer.CaseMap = {
+_caseMap: {},
+dashToCamelCase: function (dash) {
+var mapped = Polymer.CaseMap._caseMap[dash];
+if (mapped) {
+return mapped;
+}
+if (dash.indexOf('-') < 0) {
+return Polymer.CaseMap._caseMap[dash] = dash;
+}
+return Polymer.CaseMap._caseMap[dash] = dash.replace(/-([a-z])/g, function (m) {
+return m[1].toUpperCase();
+});
+},
+camelToDashCase: function (camel) {
+var mapped = Polymer.CaseMap._caseMap[camel];
+if (mapped) {
+return mapped;
+}
+return Polymer.CaseMap._caseMap[camel] = camel.replace(/([a-z][A-Z])/g, function (g) {
+return g[0] + '-' + g[1].toLowerCase();
+});
+}
+};
+Polymer.Base._addFeature({
+_addHostAttributes: function (attributes) {
+if (!this._aggregatedAttributes) {
+this._aggregatedAttributes = {};
+}
+if (attributes) {
+this.mixin(this._aggregatedAttributes, attributes);
+}
+},
+_marshalHostAttributes: function () {
+if (this._aggregatedAttributes) {
+this._applyAttributes(this, this._aggregatedAttributes);
+}
+},
+_applyAttributes: function (node, attr$) {
+for (var n in attr$) {
+if (!this.hasAttribute(n) && n !== 'class') {
+var v = attr$[n];
+this.serializeValueToAttribute(v, n, this);
+}
+}
+},
+_marshalAttributes: function () {
+this._takeAttributesToModel(this);
+},
+_takeAttributesToModel: function (model) {
+if (this.hasAttributes()) {
+for (var i in this._propertyInfo) {
+var info = this._propertyInfo[i];
+if (this.hasAttribute(info.attribute)) {
+this._setAttributeToProperty(model, info.attribute, i, info);
+}
+}
+}
+},
+_setAttributeToProperty: function (model, attribute, property, info) {
+if (!this._serializing) {
+var property = property || Polymer.CaseMap.dashToCamelCase(attribute);
+info = info || this._propertyInfo && this._propertyInfo[property];
+if (info && !info.readOnly) {
+var v = this.getAttribute(attribute);
+model[property] = this.deserialize(v, info.type);
+}
+}
+},
+_serializing: false,
+reflectPropertyToAttribute: function (property, attribute, value) {
+this._serializing = true;
+value = value === undefined ? this[property] : value;
+this.serializeValueToAttribute(value, attribute || Polymer.CaseMap.camelToDashCase(property));
+this._serializing = false;
+},
+serializeValueToAttribute: function (value, attribute, node) {
+var str = this.serialize(value);
+node = node || this;
+if (str === undefined) {
+node.removeAttribute(attribute);
+} else {
+node.setAttribute(attribute, str);
+}
+},
+deserialize: function (value, type) {
+switch (type) {
+case Number:
+value = Number(value);
+break;
+case Boolean:
+value = value !== null;
+break;
+case Object:
+try {
+value = JSON.parse(value);
+} catch (x) {
+}
+break;
+case Array:
+try {
+value = JSON.parse(value);
+} catch (x) {
+value = null;
+console.warn('Polymer::Attributes: couldn`t decode Array as JSON');
+}
+break;
+case Date:
+value = new Date(value);
+break;
+case String:
+default:
+break;
+}
+return value;
+},
+serialize: function (value) {
+switch (typeof value) {
+case 'boolean':
+return value ? '' : undefined;
+case 'object':
+if (value instanceof Date) {
+return value;
+} else if (value) {
+try {
+return JSON.stringify(value);
+} catch (x) {
+return '';
+}
+}
+default:
+return value != null ? value : undefined;
+}
+}
+});
+Polymer.Base._addFeature({
+_setupDebouncers: function () {
+this._debouncers = {};
+},
+debounce: function (jobName, callback, wait) {
+return this._debouncers[jobName] = Polymer.Debounce.call(this, this._debouncers[jobName], callback, wait);
+},
+isDebouncerActive: function (jobName) {
+var debouncer = this._debouncers[jobName];
+return debouncer && debouncer.finish;
+},
+flushDebouncer: function (jobName) {
+var debouncer = this._debouncers[jobName];
+if (debouncer) {
+debouncer.complete();
+}
+},
+cancelDebouncer: function (jobName) {
+var debouncer = this._debouncers[jobName];
+if (debouncer) {
+debouncer.stop();
+}
+}
+});
+Polymer.version = '1.2.3';
+Polymer.Base._addFeature({
+_registerFeatures: function () {
+this._prepIs();
+this._prepBehaviors();
+this._prepConstructor();
+this._prepPropertyInfo();
+},
+_prepBehavior: function (b) {
+this._addHostAttributes(b.hostAttributes);
+},
+_marshalBehavior: function (b) {
+},
+_initFeatures: function () {
+this._marshalHostAttributes();
+this._setupDebouncers();
+this._marshalBehaviors();
+}
+});
+Polymer.Base._addFeature({
+_prepTemplate: function () {
+if (this._template === undefined) {
+this._template = Polymer.DomModule.import(this.is, 'template');
+}
+if (this._template && this._template.hasAttribute('is')) {
+this._warn(this._logf('_prepTemplate', 'top-level Polymer template ' + 'must not be a type-extension, found', this._template, 'Move inside simple <template>.'));
+}
+if (this._template && !this._template.content && window.HTMLTemplateElement && HTMLTemplateElement.decorate) {
+HTMLTemplateElement.decorate(this._template);
+}
+},
+_stampTemplate: function () {
+if (this._template) {
+this.root = this.instanceTemplate(this._template);
+}
+},
+instanceTemplate: function (template) {
+var dom = document.importNode(template._content || template.content, true);
+return dom;
+}
+});
+(function () {
+var baseAttachedCallback = Polymer.Base.attachedCallback;
+Polymer.Base._addFeature({
+_hostStack: [],
+ready: function () {
+},
+_registerHost: function (host) {
+this.dataHost = host = host || Polymer.Base._hostStack[Polymer.Base._hostStack.length - 1];
+if (host && host._clients) {
+host._clients.push(this);
+}
+},
+_beginHosting: function () {
+Polymer.Base._hostStack.push(this);
+if (!this._clients) {
+this._clients = [];
+}
+},
+_endHosting: function () {
+Polymer.Base._hostStack.pop();
+},
+_tryReady: function () {
+if (this._canReady()) {
+this._ready();
+}
+},
+_canReady: function () {
+return !this.dataHost || this.dataHost._clientsReadied;
+},
+_ready: function () {
+this._beforeClientsReady();
+if (this._template) {
+this._setupRoot();
+this._readyClients();
+}
+this._clientsReadied = true;
+this._clients = null;
+this._afterClientsReady();
+this._readySelf();
+},
+_readyClients: function () {
+this._beginDistribute();
+var c$ = this._clients;
+if (c$) {
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+c._ready();
+}
+}
+this._finishDistribute();
+},
+_readySelf: function () {
+this._doBehavior('ready');
+this._readied = true;
+if (this._attachedPending) {
+this._attachedPending = false;
+this.attachedCallback();
+}
+},
+_beforeClientsReady: function () {
+},
+_afterClientsReady: function () {
+},
+_beforeAttached: function () {
+},
+attachedCallback: function () {
+if (this._readied) {
+this._beforeAttached();
+baseAttachedCallback.call(this);
+} else {
+this._attachedPending = true;
+}
+}
+});
+}());
+Polymer.ArraySplice = function () {
+function newSplice(index, removed, addedCount) {
+return {
+index: index,
+removed: removed,
+addedCount: addedCount
+};
+}
+var EDIT_LEAVE = 0;
+var EDIT_UPDATE = 1;
+var EDIT_ADD = 2;
+var EDIT_DELETE = 3;
+function ArraySplice() {
+}
+ArraySplice.prototype = {
+calcEditDistances: function (current, currentStart, currentEnd, old, oldStart, oldEnd) {
+var rowCount = oldEnd - oldStart + 1;
+var columnCount = currentEnd - currentStart + 1;
+var distances = new Array(rowCount);
+for (var i = 0; i < rowCount; i++) {
+distances[i] = new Array(columnCount);
+distances[i][0] = i;
+}
+for (var j = 0; j < columnCount; j++)
+distances[0][j] = j;
+for (var i = 1; i < rowCount; i++) {
+for (var j = 1; j < columnCount; j++) {
+if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))
+distances[i][j] = distances[i - 1][j - 1];
+else {
+var north = distances[i - 1][j] + 1;
+var west = distances[i][j - 1] + 1;
+distances[i][j] = north < west ? north : west;
+}
+}
+}
+return distances;
+},
+spliceOperationsFromEditDistances: function (distances) {
+var i = distances.length - 1;
+var j = distances[0].length - 1;
+var current = distances[i][j];
+var edits = [];
+while (i > 0 || j > 0) {
+if (i == 0) {
+edits.push(EDIT_ADD);
+j--;
+continue;
+}
+if (j == 0) {
+edits.push(EDIT_DELETE);
+i--;
+continue;
+}
+var northWest = distances[i - 1][j - 1];
+var west = distances[i - 1][j];
+var north = distances[i][j - 1];
+var min;
+if (west < north)
+min = west < northWest ? west : northWest;
+else
+min = north < northWest ? north : northWest;
+if (min == northWest) {
+if (northWest == current) {
+edits.push(EDIT_LEAVE);
+} else {
+edits.push(EDIT_UPDATE);
+current = northWest;
+}
+i--;
+j--;
+} else if (min == west) {
+edits.push(EDIT_DELETE);
+i--;
+current = west;
+} else {
+edits.push(EDIT_ADD);
+j--;
+current = north;
+}
+}
+edits.reverse();
+return edits;
+},
+calcSplices: function (current, currentStart, currentEnd, old, oldStart, oldEnd) {
+var prefixCount = 0;
+var suffixCount = 0;
+var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
+if (currentStart == 0 && oldStart == 0)
+prefixCount = this.sharedPrefix(current, old, minLength);
+if (currentEnd == current.length && oldEnd == old.length)
+suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
+currentStart += prefixCount;
+oldStart += prefixCount;
+currentEnd -= suffixCount;
+oldEnd -= suffixCount;
+if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)
+return [];
+if (currentStart == currentEnd) {
+var splice = newSplice(currentStart, [], 0);
+while (oldStart < oldEnd)
+splice.removed.push(old[oldStart++]);
+return [splice];
+} else if (oldStart == oldEnd)
+return [newSplice(currentStart, [], currentEnd - currentStart)];
+var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
+var splice = undefined;
+var splices = [];
+var index = currentStart;
+var oldIndex = oldStart;
+for (var i = 0; i < ops.length; i++) {
+switch (ops[i]) {
+case EDIT_LEAVE:
+if (splice) {
+splices.push(splice);
+splice = undefined;
+}
+index++;
+oldIndex++;
+break;
+case EDIT_UPDATE:
+if (!splice)
+splice = newSplice(index, [], 0);
+splice.addedCount++;
+index++;
+splice.removed.push(old[oldIndex]);
+oldIndex++;
+break;
+case EDIT_ADD:
+if (!splice)
+splice = newSplice(index, [], 0);
+splice.addedCount++;
+index++;
+break;
+case EDIT_DELETE:
+if (!splice)
+splice = newSplice(index, [], 0);
+splice.removed.push(old[oldIndex]);
+oldIndex++;
+break;
+}
+}
+if (splice) {
+splices.push(splice);
+}
+return splices;
+},
+sharedPrefix: function (current, old, searchLength) {
+for (var i = 0; i < searchLength; i++)
+if (!this.equals(current[i], old[i]))
+return i;
+return searchLength;
+},
+sharedSuffix: function (current, old, searchLength) {
+var index1 = current.length;
+var index2 = old.length;
+var count = 0;
+while (count < searchLength && this.equals(current[--index1], old[--index2]))
+count++;
+return count;
+},
+calculateSplices: function (current, previous) {
+return this.calcSplices(current, 0, current.length, previous, 0, previous.length);
+},
+equals: function (currentValue, previousValue) {
+return currentValue === previousValue;
+}
+};
+return new ArraySplice();
+}();
+Polymer.domInnerHTML = function () {
+var escapeAttrRegExp = /[&\u00A0"]/g;
+var escapeDataRegExp = /[&\u00A0<>]/g;
+function escapeReplace(c) {
+switch (c) {
+case '&':
+return '&amp;';
+case '<':
+return '&lt;';
+case '>':
+return '&gt;';
+case '"':
+return '&quot;';
+case '\xA0':
+return '&nbsp;';
+}
+}
+function escapeAttr(s) {
+return s.replace(escapeAttrRegExp, escapeReplace);
+}
+function escapeData(s) {
+return s.replace(escapeDataRegExp, escapeReplace);
+}
+function makeSet(arr) {
+var set = {};
+for (var i = 0; i < arr.length; i++) {
+set[arr[i]] = true;
+}
+return set;
+}
+var voidElements = makeSet([
+'area',
+'base',
+'br',
+'col',
+'command',
+'embed',
+'hr',
+'img',
+'input',
+'keygen',
+'link',
+'meta',
+'param',
+'source',
+'track',
+'wbr'
+]);
+var plaintextParents = makeSet([
+'style',
+'script',
+'xmp',
+'iframe',
+'noembed',
+'noframes',
+'plaintext',
+'noscript'
+]);
+function getOuterHTML(node, parentNode, composed) {
+switch (node.nodeType) {
+case Node.ELEMENT_NODE:
+var tagName = node.localName;
+var s = '<' + tagName;
+var attrs = node.attributes;
+for (var i = 0, attr; attr = attrs[i]; i++) {
+s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
+}
+s += '>';
+if (voidElements[tagName]) {
+return s;
+}
+return s + getInnerHTML(node, composed) + '</' + tagName + '>';
+case Node.TEXT_NODE:
+var data = node.data;
+if (parentNode && plaintextParents[parentNode.localName]) {
+return data;
+}
+return escapeData(data);
+case Node.COMMENT_NODE:
+return '<!--' + node.data + '-->';
+default:
+console.error(node);
+throw new Error('not implemented');
+}
+}
+function getInnerHTML(node, composed) {
+if (node instanceof HTMLTemplateElement)
+node = node.content;
+var s = '';
+var c$ = Polymer.dom(node).childNodes;
+c$ = composed ? node._composedChildren : c$;
+for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) {
+s += getOuterHTML(child, node, composed);
+}
+return s;
+}
+return { getInnerHTML: getInnerHTML };
+}();
+Polymer.DomApi = function () {
+'use strict';
+var Settings = Polymer.Settings;
+var getInnerHTML = Polymer.domInnerHTML.getInnerHTML;
+var nativeInsertBefore = Element.prototype.insertBefore;
+var nativeRemoveChild = Element.prototype.removeChild;
+var nativeAppendChild = Element.prototype.appendChild;
+var nativeCloneNode = Element.prototype.cloneNode;
+var nativeImportNode = Document.prototype.importNode;
+var needsToWrap = Settings.hasShadow && !Settings.nativeShadow;
+var wrap = window.wrap ? window.wrap : function (node) {
+return node;
+};
+var DomApi = function (node) {
+this.node = needsToWrap ? wrap(node) : node;
+if (this.patch) {
+this.patch();
+}
+};
+DomApi.prototype = {
+flush: function () {
+Polymer.dom.flush();
+},
+deepContains: function (node) {
+if (this.node.contains(node)) {
+return true;
+}
+var n = node;
+var wrappedDocument = wrap(document);
+while (n && n !== wrappedDocument && n !== this.node) {
+n = Polymer.dom(n).parentNode || n.host;
+}
+return n === this.node;
+},
+_lazyDistribute: function (host) {
+if (host.shadyRoot && host.shadyRoot._distributionClean) {
+host.shadyRoot._distributionClean = false;
+Polymer.dom.addDebouncer(host.debounce('_distribute', host._distributeContent));
+}
+},
+appendChild: function (node) {
+return this._addNode(node);
+},
+insertBefore: function (node, ref_node) {
+return this._addNode(node, ref_node);
+},
+_addNode: function (node, ref_node) {
+this._removeNodeFromParent(node);
+var addedInsertionPoint;
+var root = this.getOwnerRoot();
+if (root) {
+addedInsertionPoint = this._maybeAddInsertionPoint(node, this.node);
+}
+if (this._nodeHasLogicalChildren(this.node)) {
+if (ref_node) {
+var children = this.childNodes;
+var index = children.indexOf(ref_node);
+if (index < 0) {
+throw Error('The ref_node to be inserted before is not a child ' + 'of this node');
+}
+}
+this._addLogicalInfo(node, this.node, index);
+}
+this._addNodeToHost(node);
+if (!this._maybeDistribute(node, this.node) && !this._tryRemoveUndistributedNode(node)) {
+if (ref_node) {
+ref_node = ref_node.localName === CONTENT ? this._firstComposedNode(ref_node) : ref_node;
+}
+var container = this.node._isShadyRoot ? this.node.host : this.node;
+addToComposedParent(container, node, ref_node);
+if (ref_node) {
+nativeInsertBefore.call(container, node, ref_node);
+} else {
+nativeAppendChild.call(container, node);
+}
+}
+if (addedInsertionPoint) {
+this._updateInsertionPoints(root.host);
+}
+this.notifyObserver();
+return node;
+},
+removeChild: function (node) {
+if (factory(node).parentNode !== this.node) {
+console.warn('The node to be removed is not a child of this node', node);
+}
+this._removeNodeFromHost(node);
+if (!this._maybeDistribute(node, this.node)) {
+var container = this.node._isShadyRoot ? this.node.host : this.node;
+if (container === node.parentNode) {
+removeFromComposedParent(container, node);
+nativeRemoveChild.call(container, node);
+}
+}
+this.notifyObserver();
+return node;
+},
+replaceChild: function (node, ref_node) {
+this.insertBefore(node, ref_node);
+this.removeChild(ref_node);
+return node;
+},
+_hasCachedOwnerRoot: function (node) {
+return Boolean(node._ownerShadyRoot !== undefined);
+},
+getOwnerRoot: function () {
+return this._ownerShadyRootForNode(this.node);
+},
+_ownerShadyRootForNode: function (node) {
+if (!node) {
+return;
+}
+if (node._ownerShadyRoot === undefined) {
+var root;
+if (node._isShadyRoot) {
+root = node;
+} else {
+var parent = Polymer.dom(node).parentNode;
+if (parent) {
+root = parent._isShadyRoot ? parent : this._ownerShadyRootForNode(parent);
+} else {
+root = null;
+}
+}
+node._ownerShadyRoot = root;
+}
+return node._ownerShadyRoot;
+},
+_maybeDistribute: function (node, parent) {
+var fragContent = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent && Polymer.dom(node).querySelector(CONTENT);
+var wrappedContent = fragContent && Polymer.dom(fragContent).parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE;
+var hasContent = fragContent || node.localName === CONTENT;
+if (hasContent) {
+var root = this._ownerShadyRootForNode(parent);
+if (root) {
+var host = root.host;
+this._lazyDistribute(host);
+}
+}
+var parentNeedsDist = this._parentNeedsDistribution(parent);
+if (parentNeedsDist) {
+this._lazyDistribute(parent);
+}
+return parentNeedsDist || hasContent && !wrappedContent;
+},
+_maybeAddInsertionPoint: function (node, parent) {
+var added;
+if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent) {
+var c$ = factory(node).querySelectorAll(CONTENT);
+for (var i = 0, n, np, na; i < c$.length && (n = c$[i]); i++) {
+np = factory(n).parentNode;
+if (np === node) {
+np = parent;
+}
+na = this._maybeAddInsertionPoint(n, np);
+added = added || na;
+}
+} else if (node.localName === CONTENT) {
+saveLightChildrenIfNeeded(parent);
+saveLightChildrenIfNeeded(node);
+added = true;
+}
+return added;
+},
+_tryRemoveUndistributedNode: function (node) {
+if (this.node.shadyRoot) {
+var parent = getComposedParent(node);
+if (parent) {
+nativeRemoveChild.call(parent, node);
+}
+return true;
+}
+},
+_updateInsertionPoints: function (host) {
+var i$ = host.shadyRoot._insertionPoints = factory(host.shadyRoot).querySelectorAll(CONTENT);
+for (var i = 0, c; i < i$.length; i++) {
+c = i$[i];
+saveLightChildrenIfNeeded(c);
+saveLightChildrenIfNeeded(factory(c).parentNode);
+}
+},
+_nodeHasLogicalChildren: function (node) {
+return Boolean(node._lightChildren !== undefined);
+},
+_parentNeedsDistribution: function (parent) {
+return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);
+},
+_removeNodeFromParent: function (node) {
+var parent = node._lightParent || node.parentNode;
+if (parent && hasDomApi(parent)) {
+factory(parent).notifyObserver();
+}
+this._removeNodeFromHost(node, true);
+},
+_removeNodeFromHost: function (node, ensureComposedRemoval) {
+var hostNeedsDist;
+var root;
+var parent = node._lightParent;
+if (parent) {
+factory(node)._distributeParent();
+root = this._ownerShadyRootForNode(node);
+if (root) {
+root.host._elementRemove(node);
+hostNeedsDist = this._removeDistributedChildren(root, node);
+}
+this._removeLogicalInfo(node, parent);
+}
+this._removeOwnerShadyRoot(node);
+if (root && hostNeedsDist) {
+this._updateInsertionPoints(root.host);
+this._lazyDistribute(root.host);
+} else if (ensureComposedRemoval) {
+removeFromComposedParent(getComposedParent(node), node);
+}
+},
+_removeDistributedChildren: function (root, container) {
+var hostNeedsDist;
+var ip$ = root._insertionPoints;
+for (var i = 0; i < ip$.length; i++) {
+var content = ip$[i];
+if (this._contains(container, content)) {
+var dc$ = factory(content).getDistributedNodes();
+for (var j = 0; j < dc$.length; j++) {
+hostNeedsDist = true;
+var node = dc$[j];
+var parent = node.parentNode;
+if (parent) {
+removeFromComposedParent(parent, node);
+nativeRemoveChild.call(parent, node);
+}
+}
+}
+}
+return hostNeedsDist;
+},
+_contains: function (container, node) {
+while (node) {
+if (node == container) {
+return true;
+}
+node = factory(node).parentNode;
+}
+},
+_addNodeToHost: function (node) {
+var root = this.getOwnerRoot();
+if (root) {
+root.host._elementAdd(node);
+}
+},
+_addLogicalInfo: function (node, container, index) {
+var children = factory(container).childNodes;
+index = index === undefined ? children.length : index;
+if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+var c$ = arrayCopyChildNodes(node);
+for (var i = 0, n; i < c$.length && (n = c$[i]); i++) {
+children.splice(index++, 0, n);
+n._lightParent = container;
+}
+} else {
+children.splice(index, 0, node);
+node._lightParent = container;
+}
+},
+_removeLogicalInfo: function (node, container) {
+var children = factory(container).childNodes;
+var index = children.indexOf(node);
+if (index < 0 || container !== node._lightParent) {
+throw Error('The node to be removed is not a child of this node');
+}
+children.splice(index, 1);
+node._lightParent = null;
+},
+_removeOwnerShadyRoot: function (node) {
+if (this._hasCachedOwnerRoot(node)) {
+var c$ = factory(node).childNodes;
+for (var i = 0, l = c$.length, n; i < l && (n = c$[i]); i++) {
+this._removeOwnerShadyRoot(n);
+}
+}
+node._ownerShadyRoot = undefined;
+},
+_firstComposedNode: function (content) {
+var n$ = factory(content).getDistributedNodes();
+for (var i = 0, l = n$.length, n, p$; i < l && (n = n$[i]); i++) {
+p$ = factory(n).getDestinationInsertionPoints();
+if (p$[p$.length - 1] === content) {
+return n;
+}
+}
+},
+querySelector: function (selector) {
+return this.querySelectorAll(selector)[0];
+},
+querySelectorAll: function (selector) {
+return this._query(function (n) {
+return matchesSelector.call(n, selector);
+}, this.node);
+},
+_query: function (matcher, node) {
+node = node || this.node;
+var list = [];
+this._queryElements(factory(node).childNodes, matcher, list);
+return list;
+},
+_queryElements: function (elements, matcher, list) {
+for (var i = 0, l = elements.length, c; i < l && (c = elements[i]); i++) {
+if (c.nodeType === Node.ELEMENT_NODE) {
+this._queryElement(c, matcher, list);
+}
+}
+},
+_queryElement: function (node, matcher, list) {
+if (matcher(node)) {
+list.push(node);
+}
+this._queryElements(factory(node).childNodes, matcher, list);
+},
+getDestinationInsertionPoints: function () {
+return this.node._destinationInsertionPoints || [];
+},
+getDistributedNodes: function () {
+return this.node._distributedNodes || [];
+},
+queryDistributedElements: function (selector) {
+var c$ = this.getEffectiveChildNodes();
+var list = [];
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+if (c.nodeType === Node.ELEMENT_NODE && matchesSelector.call(c, selector)) {
+list.push(c);
+}
+}
+return list;
+},
+getEffectiveChildNodes: function () {
+var list = [];
+var c$ = this.childNodes;
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+if (c.localName === CONTENT) {
+var d$ = factory(c).getDistributedNodes();
+for (var j = 0; j < d$.length; j++) {
+list.push(d$[j]);
+}
+} else {
+list.push(c);
+}
+}
+return list;
+},
+_clear: function () {
+while (this.childNodes.length) {
+this.removeChild(this.childNodes[0]);
+}
+},
+setAttribute: function (name, value) {
+this.node.setAttribute(name, value);
+this._distributeParent();
+},
+removeAttribute: function (name) {
+this.node.removeAttribute(name);
+this._distributeParent();
+},
+_distributeParent: function () {
+if (this._parentNeedsDistribution(this.parentNode)) {
+this._lazyDistribute(this.parentNode);
+}
+},
+cloneNode: function (deep) {
+var n = nativeCloneNode.call(this.node, false);
+if (deep) {
+var c$ = this.childNodes;
+var d = factory(n);
+for (var i = 0, nc; i < c$.length; i++) {
+nc = factory(c$[i]).cloneNode(true);
+d.appendChild(nc);
+}
+}
+return n;
+},
+importNode: function (externalNode, deep) {
+var doc = this.node instanceof Document ? this.node : this.node.ownerDocument;
+var n = nativeImportNode.call(doc, externalNode, false);
+if (deep) {
+var c$ = factory(externalNode).childNodes;
+var d = factory(n);
+for (var i = 0, nc; i < c$.length; i++) {
+nc = factory(doc).importNode(c$[i], true);
+d.appendChild(nc);
+}
+}
+return n;
+},
+observeNodes: function (callback) {
+if (callback) {
+if (!this.observer) {
+this.observer = this.node.localName === CONTENT ? new DomApi.DistributedNodesObserver(this) : new DomApi.EffectiveNodesObserver(this);
+}
+return this.observer.addListener(callback);
+}
+},
+unobserveNodes: function (handle) {
+if (this.observer) {
+this.observer.removeListener(handle);
+}
+},
+notifyObserver: function () {
+if (this.observer) {
+this.observer.notify();
+}
+}
+};
+if (!Settings.useShadow) {
+Object.defineProperties(DomApi.prototype, {
+childNodes: {
+get: function () {
+var c$ = getLightChildren(this.node);
+return Array.isArray(c$) ? c$ : arrayCopyChildNodes(this.node);
+},
+configurable: true
+},
+children: {
+get: function () {
+return Array.prototype.filter.call(this.childNodes, function (n) {
+return n.nodeType === Node.ELEMENT_NODE;
+});
+},
+configurable: true
+},
+parentNode: {
+get: function () {
+return this.node._lightParent || getComposedParent(this.node);
+},
+configurable: true
+},
+firstChild: {
+get: function () {
+return this.childNodes[0];
+},
+configurable: true
+},
+lastChild: {
+get: function () {
+var c$ = this.childNodes;
+return c$[c$.length - 1];
+},
+configurable: true
+},
+nextSibling: {
+get: function () {
+var c$ = this.parentNode && factory(this.parentNode).childNodes;
+if (c$) {
+return c$[Array.prototype.indexOf.call(c$, this.node) + 1];
+}
+},
+configurable: true
+},
+previousSibling: {
+get: function () {
+var c$ = this.parentNode && factory(this.parentNode).childNodes;
+if (c$) {
+return c$[Array.prototype.indexOf.call(c$, this.node) - 1];
+}
+},
+configurable: true
+},
+firstElementChild: {
+get: function () {
+return this.children[0];
+},
+configurable: true
+},
+lastElementChild: {
+get: function () {
+var c$ = this.children;
+return c$[c$.length - 1];
+},
+configurable: true
+},
+nextElementSibling: {
+get: function () {
+var c$ = this.parentNode && factory(this.parentNode).children;
+if (c$) {
+return c$[Array.prototype.indexOf.call(c$, this.node) + 1];
+}
+},
+configurable: true
+},
+previousElementSibling: {
+get: function () {
+var c$ = this.parentNode && factory(this.parentNode).children;
+if (c$) {
+return c$[Array.prototype.indexOf.call(c$, this.node) - 1];
+}
+},
+configurable: true
+},
+textContent: {
+get: function () {
+var nt = this.node.nodeType;
+if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {
+return this.node.textContent;
+} else {
+var tc = [];
+for (var i = 0, cn = this.childNodes, c; c = cn[i]; i++) {
+if (c.nodeType !== Node.COMMENT_NODE) {
+tc.push(c.textContent);
+}
+}
+return tc.join('');
+}
+},
+set: function (text) {
+var nt = this.node.nodeType;
+if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {
+this.node.textContent = text;
+} else {
+this._clear();
+if (text) {
+this.appendChild(document.createTextNode(text));
+}
+}
+},
+configurable: true
+},
+innerHTML: {
+get: function () {
+var nt = this.node.nodeType;
+if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {
+return null;
+} else {
+return getInnerHTML(this.node);
+}
+},
+set: function (text) {
+var nt = this.node.nodeType;
+if (nt !== Node.TEXT_NODE || nt !== Node.COMMENT_NODE) {
+this._clear();
+var d = document.createElement('div');
+d.innerHTML = text;
+var c$ = arrayCopyChildNodes(d);
+for (var i = 0; i < c$.length; i++) {
+this.appendChild(c$[i]);
+}
+}
+},
+configurable: true
+}
+});
+DomApi.prototype._getComposedInnerHTML = function () {
+return getInnerHTML(this.node, true);
+};
+} else {
+var forwardMethods = function (m$) {
+for (var i = 0; i < m$.length; i++) {
+forwardMethod(m$[i]);
+}
+};
+var forwardMethod = function (method) {
+DomApi.prototype[method] = function () {
+return this.node[method].apply(this.node, arguments);
+};
+};
+forwardMethods([
+'cloneNode',
+'appendChild',
+'insertBefore',
+'removeChild',
+'replaceChild'
+]);
+DomApi.prototype.querySelectorAll = function (selector) {
+return arrayCopy(this.node.querySelectorAll(selector));
+};
+DomApi.prototype.getOwnerRoot = function () {
+var n = this.node;
+while (n) {
+if (n.nodeType === Node.DOCUMENT_FRAGMENT_NODE && n.host) {
+return n;
+}
+n = n.parentNode;
+}
+};
+DomApi.prototype.importNode = function (externalNode, deep) {
+var doc = this.node instanceof Document ? this.node : this.node.ownerDocument;
+return doc.importNode(externalNode, deep);
+};
+DomApi.prototype.getDestinationInsertionPoints = function () {
+var n$ = this.node.getDestinationInsertionPoints && this.node.getDestinationInsertionPoints();
+return n$ ? arrayCopy(n$) : [];
+};
+DomApi.prototype.getDistributedNodes = function () {
+var n$ = this.node.getDistributedNodes && this.node.getDistributedNodes();
+return n$ ? arrayCopy(n$) : [];
+};
+DomApi.prototype._distributeParent = function () {
+};
+Object.defineProperties(DomApi.prototype, {
+childNodes: {
+get: function () {
+return arrayCopyChildNodes(this.node);
+},
+configurable: true
+},
+children: {
+get: function () {
+return arrayCopyChildren(this.node);
+},
+configurable: true
+},
+textContent: {
+get: function () {
+return this.node.textContent;
+},
+set: function (value) {
+return this.node.textContent = value;
+},
+configurable: true
+},
+innerHTML: {
+get: function () {
+return this.node.innerHTML;
+},
+set: function (value) {
+return this.node.innerHTML = value;
+},
+configurable: true
+}
+});
+var forwardProperties = function (f$) {
+for (var i = 0; i < f$.length; i++) {
+forwardProperty(f$[i]);
+}
+};
+var forwardProperty = function (name) {
+Object.defineProperty(DomApi.prototype, name, {
+get: function () {
+return this.node[name];
+},
+configurable: true
+});
+};
+forwardProperties([
+'parentNode',
+'firstChild',
+'lastChild',
+'nextSibling',
+'previousSibling',
+'firstElementChild',
+'lastElementChild',
+'nextElementSibling',
+'previousElementSibling'
+]);
+}
+var CONTENT = 'content';
+function factory(node, patch) {
+node = node || document;
+if (!node.__domApi) {
+node.__domApi = new DomApi(node, patch);
+}
+return node.__domApi;
+}
+;
+function hasDomApi(node) {
+return Boolean(node.__domApi);
+}
+;
+Polymer.dom = function (obj, patch) {
+if (obj instanceof Event) {
+return Polymer.EventApi.factory(obj);
+} else {
+return factory(obj, patch);
+}
+};
+function getLightChildren(node) {
+var children = node._lightChildren;
+return children ? children : node.childNodes;
+}
+function getComposedChildren(node) {
+if (!node._composedChildren) {
+node._composedChildren = arrayCopyChildNodes(node);
+}
+return node._composedChildren;
+}
+function addToComposedParent(parent, node, ref_node) {
+var children = getComposedChildren(parent);
+var i = ref_node ? children.indexOf(ref_node) : -1;
+if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+var fragChildren = getComposedChildren(node);
+for (var j = 0; j < fragChildren.length; j++) {
+addNodeToComposedChildren(fragChildren[j], parent, children, i + j);
+}
+node._composedChildren = null;
+} else {
+addNodeToComposedChildren(node, parent, children, i);
+}
+}
+function getComposedParent(node) {
+return node.__patched ? node._composedParent : node.parentNode;
+}
+function addNodeToComposedChildren(node, parent, children, i) {
+node._composedParent = parent;
+children.splice(i >= 0 ? i : children.length, 0, node);
+}
+function removeFromComposedParent(parent, node) {
+node._composedParent = null;
+if (parent) {
+var children = getComposedChildren(parent);
+var i = children.indexOf(node);
+if (i >= 0) {
+children.splice(i, 1);
+}
+}
+}
+function saveLightChildrenIfNeeded(node) {
+if (!node._lightChildren) {
+var c$ = arrayCopyChildNodes(node);
+for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) {
+child._lightParent = child._lightParent || node;
+}
+node._lightChildren = c$;
+}
+}
+function arrayCopyChildNodes(parent) {
+var copy = [], i = 0;
+for (var n = parent.firstChild; n; n = n.nextSibling) {
+copy[i++] = n;
+}
+return copy;
+}
+function arrayCopyChildren(parent) {
+var copy = [], i = 0;
+for (var n = parent.firstElementChild; n; n = n.nextElementSibling) {
+copy[i++] = n;
+}
+return copy;
+}
+function arrayCopy(a$) {
+var l = a$.length;
+var copy = new Array(l);
+for (var i = 0; i < l; i++) {
+copy[i] = a$[i];
+}
+return copy;
+}
+function hasInsertionPoint(root) {
+return Boolean(root && root._insertionPoints.length);
+}
+var p = Element.prototype;
+var matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector;
+return {
+getLightChildren: getLightChildren,
+getComposedParent: getComposedParent,
+getComposedChildren: getComposedChildren,
+removeFromComposedParent: removeFromComposedParent,
+saveLightChildrenIfNeeded: saveLightChildrenIfNeeded,
+matchesSelector: matchesSelector,
+hasInsertionPoint: hasInsertionPoint,
+ctor: DomApi,
+factory: factory,
+hasDomApi: hasDomApi,
+arrayCopy: arrayCopy,
+arrayCopyChildNodes: arrayCopyChildNodes,
+arrayCopyChildren: arrayCopyChildren,
+wrap: wrap
+};
+}();
+Polymer.Base.extend(Polymer.dom, {
+_flushGuard: 0,
+_FLUSH_MAX: 100,
+_needsTakeRecords: !Polymer.Settings.useNativeCustomElements,
+_debouncers: [],
+_staticFlushList: [],
+_finishDebouncer: null,
+flush: function () {
+this._flushGuard = 0;
+this._prepareFlush();
+while (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {
+for (var i = 0; i < this._debouncers.length; i++) {
+this._debouncers[i].complete();
+}
+if (this._finishDebouncer) {
+this._finishDebouncer.complete();
+}
+this._prepareFlush();
+this._flushGuard++;
+}
+if (this._flushGuard >= this._FLUSH_MAX) {
+console.warn('Polymer.dom.flush aborted. Flush may not be complete.');
+}
+},
+_prepareFlush: function () {
+if (this._needsTakeRecords) {
+CustomElements.takeRecords();
+}
+for (var i = 0; i < this._staticFlushList.length; i++) {
+this._staticFlushList[i]();
+}
+},
+addStaticFlush: function (fn) {
+this._staticFlushList.push(fn);
+},
+removeStaticFlush: function (fn) {
+var i = this._staticFlushList.indexOf(fn);
+if (i >= 0) {
+this._staticFlushList.splice(i, 1);
+}
+},
+addDebouncer: function (debouncer) {
+this._debouncers.push(debouncer);
+this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlush);
+},
+_finishFlush: function () {
+Polymer.dom._debouncers = [];
+}
+});
+Polymer.EventApi = function () {
+'use strict';
+var DomApi = Polymer.DomApi.ctor;
+var Settings = Polymer.Settings;
+DomApi.Event = function (event) {
+this.event = event;
+};
+if (Settings.useShadow) {
+DomApi.Event.prototype = {
+get rootTarget() {
+return this.event.path[0];
+},
+get localTarget() {
+return this.event.target;
+},
+get path() {
+return this.event.path;
+}
+};
+} else {
+DomApi.Event.prototype = {
+get rootTarget() {
+return this.event.target;
+},
+get localTarget() {
+var current = this.event.currentTarget;
+var currentRoot = current && Polymer.dom(current).getOwnerRoot();
+var p$ = this.path;
+for (var i = 0; i < p$.length; i++) {
+if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {
+return p$[i];
+}
+}
+},
+get path() {
+if (!this.event._path) {
+var path = [];
+var o = this.rootTarget;
+while (o) {
+path.push(o);
+o = Polymer.dom(o).parentNode || o.host;
+}
+path.push(window);
+this.event._path = path;
+}
+return this.event._path;
+}
+};
+}
+var factory = function (event) {
+if (!event.__eventApi) {
+event.__eventApi = new DomApi.Event(event);
+}
+return event.__eventApi;
+};
+return { factory: factory };
+}();
+(function () {
+'use strict';
+var DomApi = Polymer.DomApi.ctor;
+Object.defineProperty(DomApi.prototype, 'classList', {
+get: function () {
+if (!this._classList) {
+this._classList = new DomApi.ClassList(this);
+}
+return this._classList;
+},
+configurable: true
+});
+DomApi.ClassList = function (host) {
+this.domApi = host;
+this.node = host.node;
+};
+DomApi.ClassList.prototype = {
+add: function () {
+this.node.classList.add.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+},
+remove: function () {
+this.node.classList.remove.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+},
+toggle: function () {
+this.node.classList.toggle.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+},
+contains: function () {
+return this.node.classList.contains.apply(this.node.classList, arguments);
+}
+};
+}());
+(function () {
+'use strict';
+var DomApi = Polymer.DomApi.ctor;
+var Settings = Polymer.Settings;
+var hasDomApi = Polymer.DomApi.hasDomApi;
+DomApi.EffectiveNodesObserver = function (domApi) {
+this.domApi = domApi;
+this.node = this.domApi.node;
+this._listeners = [];
+};
+DomApi.EffectiveNodesObserver.prototype = {
+addListener: function (callback) {
+if (!this._isSetup) {
+this._setup();
+this._isSetup = true;
+}
+var listener = {
+fn: callback,
+_nodes: []
+};
+this._listeners.push(listener);
+this._scheduleNotify();
+return listener;
+},
+removeListener: function (handle) {
+var i = this._listeners.indexOf(handle);
+if (i >= 0) {
+this._listeners.splice(i, 1);
+handle._nodes = [];
+}
+if (!this._hasListeners()) {
+this._cleanup();
+this._isSetup = false;
+}
+},
+_setup: function () {
+this._observeContentElements(this.domApi.childNodes);
+},
+_cleanup: function () {
+this._unobserveContentElements(this.domApi.childNodes);
+},
+_hasListeners: function () {
+return Boolean(this._listeners.length);
+},
+_scheduleNotify: function () {
+if (this._debouncer) {
+this._debouncer.stop();
+}
+this._debouncer = Polymer.Debounce(this._debouncer, this._notify);
+this._debouncer.context = this;
+Polymer.dom.addDebouncer(this._debouncer);
+},
+notify: function () {
+if (this._hasListeners()) {
+this._scheduleNotify();
+}
+},
+_notify: function (mxns) {
+this._beforeCallListeners();
+this._callListeners();
+},
+_beforeCallListeners: function () {
+this._updateContentElements();
+},
+_updateContentElements: function () {
+this._observeContentElements(this.domApi.childNodes);
+},
+_observeContentElements: function (elements) {
+for (var i = 0, n; i < elements.length && (n = elements[i]); i++) {
+if (this._isContent(n)) {
+n.__observeNodesMap = n.__observeNodesMap || new WeakMap();
+if (!n.__observeNodesMap.has(this)) {
+n.__observeNodesMap.set(this, this._observeContent(n));
+}
+}
+}
+},
+_observeContent: function (content) {
+var self = this;
+var h = Polymer.dom(content).observeNodes(function () {
+self._scheduleNotify();
+});
+h._avoidChangeCalculation = true;
+return h;
+},
+_unobserveContentElements: function (elements) {
+for (var i = 0, n, h; i < elements.length && (n = elements[i]); i++) {
+if (this._isContent(n)) {
+h = n.__observeNodesMap.get(this);
+if (h) {
+Polymer.dom(n).unobserveNodes(h);
+n.__observeNodesMap.delete(this);
+}
+}
+}
+},
+_isContent: function (node) {
+return node.localName === 'content';
+},
+_callListeners: function () {
+var o$ = this._listeners;
+var nodes = this._getEffectiveNodes();
+for (var i = 0, o; i < o$.length && (o = o$[i]); i++) {
+var info = this._generateListenerInfo(o, nodes);
+if (info || o._alwaysNotify) {
+this._callListener(o, info);
+}
+}
+},
+_getEffectiveNodes: function () {
+return this.domApi.getEffectiveChildNodes();
+},
+_generateListenerInfo: function (listener, newNodes) {
+if (listener._avoidChangeCalculation) {
+return true;
+}
+var oldNodes = listener._nodes;
+var info = {
+target: this.node,
+addedNodes: [],
+removedNodes: []
+};
+var splices = Polymer.ArraySplice.calculateSplices(newNodes, oldNodes);
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {
+info.removedNodes.push(n);
+}
+}
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = s.index; j < s.index + s.addedCount; j++) {
+info.addedNodes.push(newNodes[j]);
+}
+}
+listener._nodes = newNodes;
+if (info.addedNodes.length || info.removedNodes.length) {
+return info;
+}
+},
+_callListener: function (listener, info) {
+return listener.fn.call(this.node, info);
+},
+enableShadowAttributeTracking: function () {
+}
+};
+if (Settings.useShadow) {
+var baseSetup = DomApi.EffectiveNodesObserver.prototype._setup;
+var baseCleanup = DomApi.EffectiveNodesObserver.prototype._cleanup;
+var beforeCallListeners = DomApi.EffectiveNodesObserver.prototype._beforeCallListeners;
+Polymer.Base.extend(DomApi.EffectiveNodesObserver.prototype, {
+_setup: function () {
+if (!this._observer) {
+var self = this;
+this._mutationHandler = function (mxns) {
+if (mxns && mxns.length) {
+self._scheduleNotify();
+}
+};
+this._observer = new MutationObserver(this._mutationHandler);
+this._boundFlush = function () {
+self._flush();
+};
+Polymer.dom.addStaticFlush(this._boundFlush);
+this._observer.observe(this.node, { childList: true });
+}
+baseSetup.call(this);
+},
+_cleanup: function () {
+this._observer.disconnect();
+this._observer = null;
+this._mutationHandler = null;
+Polymer.dom.removeStaticFlush(this._boundFlush);
+baseCleanup.call(this);
+},
+_flush: function () {
+if (this._observer) {
+this._mutationHandler(this._observer.takeRecords());
+}
+},
+enableShadowAttributeTracking: function () {
+if (this._observer) {
+this._makeContentListenersAlwaysNotify();
+this._observer.disconnect();
+this._observer.observe(this.node, {
+childList: true,
+attributes: true,
+subtree: true
+});
+var root = this.domApi.getOwnerRoot();
+var host = root && root.host;
+if (host && Polymer.dom(host).observer) {
+Polymer.dom(host).observer.enableShadowAttributeTracking();
+}
+}
+},
+_makeContentListenersAlwaysNotify: function () {
+for (var i = 0, h; i < this._listeners.length; i++) {
+h = this._listeners[i];
+h._alwaysNotify = h._isContentListener;
+}
+}
+});
+}
+}());
+(function () {
+'use strict';
+var DomApi = Polymer.DomApi.ctor;
+var Settings = Polymer.Settings;
+DomApi.DistributedNodesObserver = function (domApi) {
+DomApi.EffectiveNodesObserver.call(this, domApi);
+};
+DomApi.DistributedNodesObserver.prototype = Object.create(DomApi.EffectiveNodesObserver.prototype);
+Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, {
+_setup: function () {
+},
+_cleanup: function () {
+},
+_beforeCallListeners: function () {
+},
+_getEffectiveNodes: function () {
+return this.domApi.getDistributedNodes();
+}
+});
+if (Settings.useShadow) {
+Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, {
+_setup: function () {
+if (!this._observer) {
+var root = this.domApi.getOwnerRoot();
+var host = root && root.host;
+if (host) {
+var self = this;
+this._observer = Polymer.dom(host).observeNodes(function () {
+self._scheduleNotify();
+});
+this._observer._isContentListener = true;
+if (this._hasAttrSelect()) {
+Polymer.dom(host).observer.enableShadowAttributeTracking();
+}
+}
+}
+},
+_hasAttrSelect: function () {
+var select = this.node.getAttribute('select');
+return select && select.match(/[[.]+/);
+},
+_cleanup: function () {
+var root = this.domApi.getOwnerRoot();
+var host = root && root.host;
+if (host) {
+Polymer.dom(host).unobserveNodes(this._observer);
+}
+this._observer = null;
+}
+});
+}
+}());
+(function () {
+var hasDomApi = Polymer.DomApi.hasDomApi;
+Polymer.Base._addFeature({
+_prepShady: function () {
+this._useContent = this._useContent || Boolean(this._template);
+},
+_poolContent: function () {
+if (this._useContent) {
+saveLightChildrenIfNeeded(this);
+}
+},
+_setupRoot: function () {
+if (this._useContent) {
+this._createLocalRoot();
+if (!this.dataHost) {
+upgradeLightChildren(this._lightChildren);
+}
+}
+},
+_createLocalRoot: function () {
+this.shadyRoot = this.root;
+this.shadyRoot._distributionClean = false;
+this.shadyRoot._hasDistributed = false;
+this.shadyRoot._isShadyRoot = true;
+this.shadyRoot._dirtyRoots = [];
+var i$ = this.shadyRoot._insertionPoints = !this._notes || this._notes._hasContent ? this.shadyRoot.querySelectorAll('content') : [];
+saveLightChildrenIfNeeded(this.shadyRoot);
+for (var i = 0, c; i < i$.length; i++) {
+c = i$[i];
+saveLightChildrenIfNeeded(c);
+saveLightChildrenIfNeeded(c.parentNode);
+}
+this.shadyRoot.host = this;
+},
+get domHost() {
+var root = Polymer.dom(this).getOwnerRoot();
+return root && root.host;
+},
+distributeContent: function (updateInsertionPoints) {
+if (this.shadyRoot) {
+var dom = Polymer.dom(this);
+if (updateInsertionPoints) {
+dom._updateInsertionPoints(this);
+}
+var host = getTopDistributingHost(this);
+dom._lazyDistribute(host);
+}
+},
+_distributeContent: function () {
+if (this._useContent && !this.shadyRoot._distributionClean) {
+this._beginDistribute();
+this._distributeDirtyRoots();
+this._finishDistribute();
+}
+},
+_beginDistribute: function () {
+if (this._useContent && hasInsertionPoint(this.shadyRoot)) {
+this._resetDistribution();
+this._distributePool(this.shadyRoot, this._collectPool());
+}
+},
+_distributeDirtyRoots: function () {
+var c$ = this.shadyRoot._dirtyRoots;
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+c._distributeContent();
+}
+this.shadyRoot._dirtyRoots = [];
+},
+_finishDistribute: function () {
+if (this._useContent) {
+this.shadyRoot._distributionClean = true;
+if (hasInsertionPoint(this.shadyRoot)) {
+this._composeTree();
+notifyContentObservers(this.shadyRoot);
+} else {
+if (!this.shadyRoot._hasDistributed) {
+this.textContent = '';
+this._composedChildren = null;
+this.appendChild(this.shadyRoot);
+} else {
+var children = this._composeNode(this);
+this._updateChildNodes(this, children);
+}
+}
+if (!this.shadyRoot._hasDistributed) {
+notifyInitialDistribution(this);
+}
+this.shadyRoot._hasDistributed = true;
+}
+},
+elementMatches: function (selector, node) {
+node = node || this;
+return matchesSelector.call(node, selector);
+},
+_resetDistribution: function () {
+var children = getLightChildren(this);
+for (var i = 0; i < children.length; i++) {
+var child = children[i];
+if (child._destinationInsertionPoints) {
+child._destinationInsertionPoints = undefined;
+}
+if (isInsertionPoint(child)) {
+clearDistributedDestinationInsertionPoints(child);
+}
+}
+var root = this.shadyRoot;
+var p$ = root._insertionPoints;
+for (var j = 0; j < p$.length; j++) {
+p$[j]._distributedNodes = [];
+}
+},
+_collectPool: function () {
+var pool = [];
+var children = getLightChildren(this);
+for (var i = 0; i < children.length; i++) {
+var child = children[i];
+if (isInsertionPoint(child)) {
+pool.push.apply(pool, child._distributedNodes);
+} else {
+pool.push(child);
+}
+}
+return pool;
+},
+_distributePool: function (node, pool) {
+var p$ = node._insertionPoints;
+for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {
+this._distributeInsertionPoint(p, pool);
+maybeRedistributeParent(p, this);
+}
+},
+_distributeInsertionPoint: function (content, pool) {
+var anyDistributed = false;
+for (var i = 0, l = pool.length, node; i < l; i++) {
+node = pool[i];
+if (!node) {
+continue;
+}
+if (this._matchesContentSelect(node, content)) {
+distributeNodeInto(node, content);
+pool[i] = undefined;
+anyDistributed = true;
+}
+}
+if (!anyDistributed) {
+var children = getLightChildren(content);
+for (var j = 0; j < children.length; j++) {
+distributeNodeInto(children[j], content);
+}
+}
+},
+_composeTree: function () {
+this._updateChildNodes(this, this._composeNode(this));
+var p$ = this.shadyRoot._insertionPoints;
+for (var i = 0, l = p$.length, p, parent; i < l && (p = p$[i]); i++) {
+parent = p._lightParent || p.parentNode;
+if (!parent._useContent && parent !== this && parent !== this.shadyRoot) {
+this._updateChildNodes(parent, this._composeNode(parent));
+}
+}
+},
+_composeNode: function (node) {
+var children = [];
+var c$ = getLightChildren(node.shadyRoot || node);
+for (var i = 0; i < c$.length; i++) {
+var child = c$[i];
+if (isInsertionPoint(child)) {
+var distributedNodes = child._distributedNodes;
+for (var j = 0; j < distributedNodes.length; j++) {
+var distributedNode = distributedNodes[j];
+if (isFinalDestination(child, distributedNode)) {
+children.push(distributedNode);
+}
+}
+} else {
+children.push(child);
+}
+}
+return children;
+},
+_updateChildNodes: function (container, children) {
+var composed = getComposedChildren(container);
+var splices = Polymer.ArraySplice.calculateSplices(children, composed);
+for (var i = 0, d = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {
+if (getComposedParent(n) === container) {
+remove(n);
+}
+composed.splice(s.index + d, 1);
+}
+d -= s.addedCount;
+}
+for (var i = 0, s, next; i < splices.length && (s = splices[i]); i++) {
+next = composed[s.index];
+for (var j = s.index, n; j < s.index + s.addedCount; j++) {
+n = children[j];
+insertBefore(container, n, next);
+composed.splice(j, 0, n);
+}
+}
+ensureComposedParent(container, children);
+},
+_matchesContentSelect: function (node, contentElement) {
+var select = contentElement.getAttribute('select');
+if (!select) {
+return true;
+}
+select = select.trim();
+if (!select) {
+return true;
+}
+if (!(node instanceof Element)) {
+return false;
+}
+var validSelectors = /^(:not\()?[*.#[a-zA-Z_|]/;
+if (!validSelectors.test(select)) {
+return false;
+}
+return this.elementMatches(select, node);
+},
+_elementAdd: function () {
+},
+_elementRemove: function () {
+}
+});
+var saveLightChildrenIfNeeded = Polymer.DomApi.saveLightChildrenIfNeeded;
+var getLightChildren = Polymer.DomApi.getLightChildren;
+var matchesSelector = Polymer.DomApi.matchesSelector;
+var hasInsertionPoint = Polymer.DomApi.hasInsertionPoint;
+var getComposedChildren = Polymer.DomApi.getComposedChildren;
+var getComposedParent = Polymer.DomApi.getComposedParent;
+var removeFromComposedParent = Polymer.DomApi.removeFromComposedParent;
+function distributeNodeInto(child, insertionPoint) {
+insertionPoint._distributedNodes.push(child);
+var points = child._destinationInsertionPoints;
+if (!points) {
+child._destinationInsertionPoints = [insertionPoint];
+} else {
+points.push(insertionPoint);
+}
+}
+function clearDistributedDestinationInsertionPoints(content) {
+var e$ = content._distributedNodes;
+if (e$) {
+for (var i = 0; i < e$.length; i++) {
+var d = e$[i]._destinationInsertionPoints;
+if (d) {
+d.splice(d.indexOf(content) + 1, d.length);
+}
+}
+}
+}
+function maybeRedistributeParent(content, host) {
+var parent = content._lightParent;
+if (parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot) && parent.shadyRoot._distributionClean) {
+parent.shadyRoot._distributionClean = false;
+host.shadyRoot._dirtyRoots.push(parent);
+}
+}
+function isFinalDestination(insertionPoint, node) {
+var points = node._destinationInsertionPoints;
+return points && points[points.length - 1] === insertionPoint;
+}
+function isInsertionPoint(node) {
+return node.localName == 'content';
+}
+var nativeInsertBefore = Element.prototype.insertBefore;
+var nativeRemoveChild = Element.prototype.removeChild;
+function insertBefore(parentNode, newChild, refChild) {
+var newChildParent = getComposedParent(newChild);
+if (newChildParent !== parentNode) {
+removeFromComposedParent(newChildParent, newChild);
+}
+remove(newChild);
+nativeInsertBefore.call(parentNode, newChild, refChild || null);
+newChild._composedParent = parentNode;
+}
+function remove(node) {
+var parentNode = getComposedParent(node);
+if (parentNode) {
+node._composedParent = null;
+nativeRemoveChild.call(parentNode, node);
+}
+}
+function ensureComposedParent(parent, children) {
+for (var i = 0, n; i < children.length; i++) {
+children[i]._composedParent = parent;
+}
+}
+function getTopDistributingHost(host) {
+while (host && hostNeedsRedistribution(host)) {
+host = host.domHost;
+}
+return host;
+}
+function hostNeedsRedistribution(host) {
+var c$ = Polymer.dom(host).children;
+for (var i = 0, c; i < c$.length; i++) {
+c = c$[i];
+if (c.localName === 'content') {
+return host.domHost;
+}
+}
+}
+function notifyContentObservers(root) {
+for (var i = 0, c; i < root._insertionPoints.length; i++) {
+c = root._insertionPoints[i];
+if (hasDomApi(c)) {
+Polymer.dom(c).notifyObserver();
+}
+}
+}
+function notifyInitialDistribution(host) {
+if (hasDomApi(host)) {
+Polymer.dom(host).notifyObserver();
+}
+}
+var needsUpgrade = window.CustomElements && !CustomElements.useNative;
+function upgradeLightChildren(children) {
+if (needsUpgrade && children) {
+for (var i = 0; i < children.length; i++) {
+CustomElements.upgrade(children[i]);
+}
+}
+}
+}());
+if (Polymer.Settings.useShadow) {
+Polymer.Base._addFeature({
+_poolContent: function () {
+},
+_beginDistribute: function () {
+},
+distributeContent: function () {
+},
+_distributeContent: function () {
+},
+_finishDistribute: function () {
+},
+_createLocalRoot: function () {
+this.createShadowRoot();
+this.shadowRoot.appendChild(this.root);
+this.root = this.shadowRoot;
+}
+});
+}
+Polymer.DomModule = document.createElement('dom-module');
+Polymer.Base._addFeature({
+_registerFeatures: function () {
+this._prepIs();
+this._prepBehaviors();
+this._prepConstructor();
+this._prepTemplate();
+this._prepShady();
+this._prepPropertyInfo();
+},
+_prepBehavior: function (b) {
+this._addHostAttributes(b.hostAttributes);
+},
+_initFeatures: function () {
+this._registerHost();
+if (this._template) {
+this._poolContent();
+this._beginHosting();
+this._stampTemplate();
+this._endHosting();
+}
+this._marshalHostAttributes();
+this._setupDebouncers();
+this._marshalBehaviors();
+this._tryReady();
+},
+_marshalBehavior: function (b) {
+}
+});
+Polymer.nar = [];
+Polymer.Annotations = {
+parseAnnotations: function (template) {
+var list = [];
+var content = template._content || template.content;
+this._parseNodeAnnotations(content, list, template.hasAttribute('strip-whitespace'));
+return list;
+},
+_parseNodeAnnotations: function (node, list, stripWhiteSpace) {
+return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, list) : this._parseElementAnnotations(node, list, stripWhiteSpace);
+},
+_bindingRegex: /([^{[]*)(\{\{|\[\[)(?!\}\}|\]\])(.+?)(?:\]\]|\}\})/g,
+_parseBindings: function (text) {
+var re = this._bindingRegex;
+var parts = [];
+var m, lastIndex;
+while ((m = re.exec(text)) !== null) {
+if (m[1]) {
+parts.push({ literal: m[1] });
+}
+var mode = m[2][0];
+var value = m[3].trim();
+var negate = false;
+if (value[0] == '!') {
+negate = true;
+value = value.substring(1).trim();
+}
+var customEvent, notifyEvent, colon;
+if (mode == '{' && (colon = value.indexOf('::')) > 0) {
+notifyEvent = value.substring(colon + 2);
+value = value.substring(0, colon);
+customEvent = true;
+}
+parts.push({
+compoundIndex: parts.length,
+value: value,
+mode: mode,
+negate: negate,
+event: notifyEvent,
+customEvent: customEvent
+});
+lastIndex = re.lastIndex;
+}
+if (lastIndex && lastIndex < text.length) {
+var literal = text.substring(lastIndex);
+if (literal) {
+parts.push({ literal: literal });
+}
+}
+if (parts.length) {
+return parts;
+}
+},
+_literalFromParts: function (parts) {
+var s = '';
+for (var i = 0; i < parts.length; i++) {
+var literal = parts[i].literal;
+s += literal || '';
+}
+return s;
+},
+_parseTextNodeAnnotation: function (node, list) {
+var parts = this._parseBindings(node.textContent);
+if (parts) {
+node.textContent = this._literalFromParts(parts) || ' ';
+var annote = {
+bindings: [{
+kind: 'text',
+name: 'textContent',
+parts: parts,
+isCompound: parts.length !== 1
+}]
+};
+list.push(annote);
+return annote;
+}
+},
+_parseElementAnnotations: function (element, list, stripWhiteSpace) {
+var annote = {
+bindings: [],
+events: []
+};
+if (element.localName === 'content') {
+list._hasContent = true;
+}
+this._parseChildNodesAnnotations(element, annote, list, stripWhiteSpace);
+if (element.attributes) {
+this._parseNodeAttributeAnnotations(element, annote, list);
+if (this.prepElement) {
+this.prepElement(element);
+}
+}
+if (annote.bindings.length || annote.events.length || annote.id) {
+list.push(annote);
+}
+return annote;
+},
+_parseChildNodesAnnotations: function (root, annote, list, stripWhiteSpace) {
+if (root.firstChild) {
+var node = root.firstChild;
+var i = 0;
+while (node) {
+var next = node.nextSibling;
+if (node.localName === 'template' && !node.hasAttribute('preserve-content')) {
+this._parseTemplate(node, i, list, annote);
+}
+if (node.nodeType === Node.TEXT_NODE) {
+var n = next;
+while (n && n.nodeType === Node.TEXT_NODE) {
+node.textContent += n.textContent;
+next = n.nextSibling;
+root.removeChild(n);
+n = next;
+}
+if (stripWhiteSpace && !node.textContent.trim()) {
+root.removeChild(node);
+i--;
+}
+}
+if (node.parentNode) {
+var childAnnotation = this._parseNodeAnnotations(node, list, stripWhiteSpace);
+if (childAnnotation) {
+childAnnotation.parent = annote;
+childAnnotation.index = i;
+}
+}
+node = next;
+i++;
+}
+}
+},
+_parseTemplate: function (node, index, list, parent) {
+var content = document.createDocumentFragment();
+content._notes = this.parseAnnotations(node);
+content.appendChild(node.content);
+list.push({
+bindings: Polymer.nar,
+events: Polymer.nar,
+templateContent: content,
+parent: parent,
+index: index
+});
+},
+_parseNodeAttributeAnnotations: function (node, annotation) {
+var attrs = Array.prototype.slice.call(node.attributes);
+for (var i = attrs.length - 1, a; a = attrs[i]; i--) {
+var n = a.name;
+var v = a.value;
+var b;
+if (n.slice(0, 3) === 'on-') {
+node.removeAttribute(n);
+annotation.events.push({
+name: n.slice(3),
+value: v
+});
+} else if (b = this._parseNodeAttributeAnnotation(node, n, v)) {
+annotation.bindings.push(b);
+} else if (n === 'id') {
+annotation.id = v;
+}
+}
+},
+_parseNodeAttributeAnnotation: function (node, name, value) {
+var parts = this._parseBindings(value);
+if (parts) {
+var origName = name;
+var kind = 'property';
+if (name[name.length - 1] == '$') {
+name = name.slice(0, -1);
+kind = 'attribute';
+}
+var literal = this._literalFromParts(parts);
+if (literal && kind == 'attribute') {
+node.setAttribute(name, literal);
+}
+if (node.localName == 'input' && name == 'value') {
+node.setAttribute(origName, '');
+}
+node.removeAttribute(origName);
+if (kind === 'property') {
+name = Polymer.CaseMap.dashToCamelCase(name);
+}
+return {
+kind: kind,
+name: name,
+parts: parts,
+literal: literal,
+isCompound: parts.length !== 1
+};
+}
+},
+_localSubTree: function (node, host) {
+return node === host ? node.childNodes : node._lightChildren || node.childNodes;
+},
+findAnnotatedNode: function (root, annote) {
+var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote.parent);
+return !parent ? root : Polymer.Annotations._localSubTree(parent, root)[annote.index];
+}
+};
+(function () {
+function resolveCss(cssText, ownerDocument) {
+return cssText.replace(CSS_URL_RX, function (m, pre, url, post) {
+return pre + '\'' + resolve(url.replace(/["']/g, ''), ownerDocument) + '\'' + post;
+});
+}
+function resolveAttrs(element, ownerDocument) {
+for (var name in URL_ATTRS) {
+var a$ = URL_ATTRS[name];
+for (var i = 0, l = a$.length, a, at, v; i < l && (a = a$[i]); i++) {
+if (name === '*' || element.localName === name) {
+at = element.attributes[a];
+v = at && at.value;
+if (v && v.search(BINDING_RX) < 0) {
+at.value = a === 'style' ? resolveCss(v, ownerDocument) : resolve(v, ownerDocument);
+}
+}
+}
+}
+}
+function resolve(url, ownerDocument) {
+if (url && url[0] === '#') {
+return url;
+}
+var resolver = getUrlResolver(ownerDocument);
+resolver.href = url;
+return resolver.href || url;
+}
+var tempDoc;
+var tempDocBase;
+function resolveUrl(url, baseUri) {
+if (!tempDoc) {
+tempDoc = document.implementation.createHTMLDocument('temp');
+tempDocBase = tempDoc.createElement('base');
+tempDoc.head.appendChild(tempDocBase);
+}
+tempDocBase.href = baseUri;
+return resolve(url, tempDoc);
+}
+function getUrlResolver(ownerDocument) {
+return ownerDocument.__urlResolver || (ownerDocument.__urlResolver = ownerDocument.createElement('a'));
+}
+var CSS_URL_RX = /(url\()([^)]*)(\))/g;
+var URL_ATTRS = {
+'*': [
+'href',
+'src',
+'style',
+'url'
+],
+form: ['action']
+};
+var BINDING_RX = /\{\{|\[\[/;
+Polymer.ResolveUrl = {
+resolveCss: resolveCss,
+resolveAttrs: resolveAttrs,
+resolveUrl: resolveUrl
+};
+}());
+Polymer.Base._addFeature({
+_prepAnnotations: function () {
+if (!this._template) {
+this._notes = [];
+} else {
+var self = this;
+Polymer.Annotations.prepElement = function (element) {
+self._prepElement(element);
+};
+if (this._template._content && this._template._content._notes) {
+this._notes = this._template._content._notes;
+} else {
+this._notes = Polymer.Annotations.parseAnnotations(this._template);
+}
+this._processAnnotations(this._notes);
+Polymer.Annotations.prepElement = null;
+}
+},
+_processAnnotations: function (notes) {
+for (var i = 0; i < notes.length; i++) {
+var note = notes[i];
+for (var j = 0; j < note.bindings.length; j++) {
+var b = note.bindings[j];
+for (var k = 0; k < b.parts.length; k++) {
+var p = b.parts[k];
+if (!p.literal) {
+p.signature = this._parseMethod(p.value);
+if (!p.signature) {
+p.model = this._modelForPath(p.value);
+}
+}
+}
+}
+if (note.templateContent) {
+this._processAnnotations(note.templateContent._notes);
+var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(note.templateContent._notes);
+var bindings = [];
+for (var prop in pp) {
+bindings.push({
+index: note.index,
+kind: 'property',
+name: '_parent_' + prop,
+parts: [{
+mode: '{',
+model: prop,
+value: prop
+}]
+});
+}
+note.bindings = note.bindings.concat(bindings);
+}
+}
+},
+_discoverTemplateParentProps: function (notes) {
+var pp = {};
+for (var i = 0, n; i < notes.length && (n = notes[i]); i++) {
+for (var j = 0, b$ = n.bindings, b; j < b$.length && (b = b$[j]); j++) {
+for (var k = 0, p$ = b.parts, p; k < p$.length && (p = p$[k]); k++) {
+if (p.signature) {
+var args = p.signature.args;
+for (var kk = 0; kk < args.length; kk++) {
+pp[args[kk].model] = true;
+}
+} else {
+pp[p.model] = true;
+}
+}
+}
+if (n.templateContent) {
+var tpp = n.templateContent._parentProps;
+Polymer.Base.mixin(pp, tpp);
+}
+}
+return pp;
+},
+_prepElement: function (element) {
+Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument);
+},
+_findAnnotatedNode: Polymer.Annotations.findAnnotatedNode,
+_marshalAnnotationReferences: function () {
+if (this._template) {
+this._marshalIdNodes();
+this._marshalAnnotatedNodes();
+this._marshalAnnotatedListeners();
+}
+},
+_configureAnnotationReferences: function (config) {
+var notes = this._notes;
+var nodes = this._nodes;
+for (var i = 0; i < notes.length; i++) {
+var note = notes[i];
+var node = nodes[i];
+this._configureTemplateContent(note, node);
+this._configureCompoundBindings(note, node);
+}
+},
+_configureTemplateContent: function (note, node) {
+if (note.templateContent) {
+node._content = note.templateContent;
+}
+},
+_configureCompoundBindings: function (note, node) {
+var bindings = note.bindings;
+for (var i = 0; i < bindings.length; i++) {
+var binding = bindings[i];
+if (binding.isCompound) {
+var storage = node.__compoundStorage__ || (node.__compoundStorage__ = {});
+var parts = binding.parts;
+var literals = new Array(parts.length);
+for (var j = 0; j < parts.length; j++) {
+literals[j] = parts[j].literal;
+}
+var name = binding.name;
+storage[name] = literals;
+if (binding.literal && binding.kind == 'property') {
+if (node._configValue) {
+node._configValue(name, binding.literal);
+} else {
+node[name] = binding.literal;
+}
+}
+}
+}
+},
+_marshalIdNodes: function () {
+this.$ = {};
+for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) {
+if (a.id) {
+this.$[a.id] = this._findAnnotatedNode(this.root, a);
+}
+}
+},
+_marshalAnnotatedNodes: function () {
+if (this._notes && this._notes.length) {
+var r = new Array(this._notes.length);
+for (var i = 0; i < this._notes.length; i++) {
+r[i] = this._findAnnotatedNode(this.root, this._notes[i]);
+}
+this._nodes = r;
+}
+},
+_marshalAnnotatedListeners: function () {
+for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) {
+if (a.events && a.events.length) {
+var node = this._findAnnotatedNode(this.root, a);
+for (var j = 0, e$ = a.events, e; j < e$.length && (e = e$[j]); j++) {
+this.listen(node, e.name, e.value);
+}
+}
+}
+}
+});
+Polymer.Base._addFeature({
+listeners: {},
+_listenListeners: function (listeners) {
+var node, name, eventName;
+for (eventName in listeners) {
+if (eventName.indexOf('.') < 0) {
+node = this;
+name = eventName;
+} else {
+name = eventName.split('.');
+node = this.$[name[0]];
+name = name[1];
+}
+this.listen(node, name, listeners[eventName]);
+}
+},
+listen: function (node, eventName, methodName) {
+var handler = this._recallEventHandler(this, eventName, node, methodName);
+if (!handler) {
+handler = this._createEventHandler(node, eventName, methodName);
+}
+if (handler._listening) {
+return;
+}
+this._listen(node, eventName, handler);
+handler._listening = true;
+},
+_boundListenerKey: function (eventName, methodName) {
+return eventName + ':' + methodName;
+},
+_recordEventHandler: function (host, eventName, target, methodName, handler) {
+var hbl = host.__boundListeners;
+if (!hbl) {
+hbl = host.__boundListeners = new WeakMap();
+}
+var bl = hbl.get(target);
+if (!bl) {
+bl = {};
+hbl.set(target, bl);
+}
+var key = this._boundListenerKey(eventName, methodName);
+bl[key] = handler;
+},
+_recallEventHandler: function (host, eventName, target, methodName) {
+var hbl = host.__boundListeners;
+if (!hbl) {
+return;
+}
+var bl = hbl.get(target);
+if (!bl) {
+return;
+}
+var key = this._boundListenerKey(eventName, methodName);
+return bl[key];
+},
+_createEventHandler: function (node, eventName, methodName) {
+var host = this;
+var handler = function (e) {
+if (host[methodName]) {
+host[methodName](e, e.detail);
+} else {
+host._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined'));
+}
+};
+handler._listening = false;
+this._recordEventHandler(host, eventName, node, methodName, handler);
+return handler;
+},
+unlisten: function (node, eventName, methodName) {
+var handler = this._recallEventHandler(this, eventName, node, methodName);
+if (handler) {
+this._unlisten(node, eventName, handler);
+handler._listening = false;
+}
+},
+_listen: function (node, eventName, handler) {
+node.addEventListener(eventName, handler);
+},
+_unlisten: function (node, eventName, handler) {
+node.removeEventListener(eventName, handler);
+}
+});
+(function () {
+'use strict';
+var wrap = Polymer.DomApi.wrap;
+var HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
+var GESTURE_KEY = '__polymerGestures';
+var HANDLED_OBJ = '__polymerGesturesHandled';
+var TOUCH_ACTION = '__polymerGesturesTouchAction';
+var TAP_DISTANCE = 25;
+var TRACK_DISTANCE = 5;
+var TRACK_LENGTH = 2;
+var MOUSE_TIMEOUT = 2500;
+var MOUSE_EVENTS = [
+'mousedown',
+'mousemove',
+'mouseup',
+'click'
+];
+var MOUSE_WHICH_TO_BUTTONS = [
+0,
+1,
+4,
+2
+];
+var MOUSE_HAS_BUTTONS = function () {
+try {
+return new MouseEvent('test', { buttons: 1 }).buttons === 1;
+} catch (e) {
+return false;
+}
+}();
+var IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
+var mouseCanceller = function (mouseEvent) {
+mouseEvent[HANDLED_OBJ] = { skip: true };
+if (mouseEvent.type === 'click') {
+var path = Polymer.dom(mouseEvent).path;
+for (var i = 0; i < path.length; i++) {
+if (path[i] === POINTERSTATE.mouse.target) {
+return;
+}
+}
+mouseEvent.preventDefault();
+mouseEvent.stopPropagation();
+}
+};
+function setupTeardownMouseCanceller(setup) {
+for (var i = 0, en; i < MOUSE_EVENTS.length; i++) {
+en = MOUSE_EVENTS[i];
+if (setup) {
+document.addEventListener(en, mouseCanceller, true);
+} else {
+document.removeEventListener(en, mouseCanceller, true);
+}
+}
+}
+function ignoreMouse() {
+if (IS_TOUCH_ONLY) {
+return;
+}
+if (!POINTERSTATE.mouse.mouseIgnoreJob) {
+setupTeardownMouseCanceller(true);
+}
+var unset = function () {
+setupTeardownMouseCanceller();
+POINTERSTATE.mouse.target = null;
+POINTERSTATE.mouse.mouseIgnoreJob = null;
+};
+POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob, unset, MOUSE_TIMEOUT);
+}
+function hasLeftMouseButton(ev) {
+var type = ev.type;
+if (MOUSE_EVENTS.indexOf(type) === -1) {
+return false;
+}
+if (type === 'mousemove') {
+var buttons = ev.buttons === undefined ? 1 : ev.buttons;
+if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
+buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
+}
+return Boolean(buttons & 1);
+} else {
+var button = ev.button === undefined ? 0 : ev.button;
+return button === 0;
+}
+}
+function isSyntheticClick(ev) {
+if (ev.type === 'click') {
+if (ev.detail === 0) {
+return true;
+}
+var t = Gestures.findOriginalTarget(ev);
+var bcr = t.getBoundingClientRect();
+var x = ev.pageX, y = ev.pageY;
+return !(x >= bcr.left && x <= bcr.right && (y >= bcr.top && y <= bcr.bottom));
+}
+return false;
+}
+var POINTERSTATE = {
+mouse: {
+target: null,
+mouseIgnoreJob: null
+},
+touch: {
+x: 0,
+y: 0,
+id: -1,
+scrollDecided: false
+}
+};
+function firstTouchAction(ev) {
+var path = Polymer.dom(ev).path;
+var ta = 'auto';
+for (var i = 0, n; i < path.length; i++) {
+n = path[i];
+if (n[TOUCH_ACTION]) {
+ta = n[TOUCH_ACTION];
+break;
+}
+}
+return ta;
+}
+function trackDocument(stateObj, movefn, upfn) {
+stateObj.movefn = movefn;
+stateObj.upfn = upfn;
+document.addEventListener('mousemove', movefn);
+document.addEventListener('mouseup', upfn);
+}
+function untrackDocument(stateObj) {
+document.removeEventListener('mousemove', stateObj.movefn);
+document.removeEventListener('mouseup', stateObj.upfn);
+}
+var Gestures = {
+gestures: {},
+recognizers: [],
+deepTargetFind: function (x, y) {
+var node = document.elementFromPoint(x, y);
+var next = node;
+while (next && next.shadowRoot) {
+next = next.shadowRoot.elementFromPoint(x, y);
+if (next) {
+node = next;
+}
+}
+return node;
+},
+findOriginalTarget: function (ev) {
+if (ev.path) {
+return ev.path[0];
+}
+return ev.target;
+},
+handleNative: function (ev) {
+var handled;
+var type = ev.type;
+var node = wrap(ev.currentTarget);
+var gobj = node[GESTURE_KEY];
+if (!gobj) {
+return;
+}
+var gs = gobj[type];
+if (!gs) {
+return;
+}
+if (!ev[HANDLED_OBJ]) {
+ev[HANDLED_OBJ] = {};
+if (type.slice(0, 5) === 'touch') {
+var t = ev.changedTouches[0];
+if (type === 'touchstart') {
+if (ev.touches.length === 1) {
+POINTERSTATE.touch.id = t.identifier;
+}
+}
+if (POINTERSTATE.touch.id !== t.identifier) {
+return;
+}
+if (!HAS_NATIVE_TA) {
+if (type === 'touchstart' || type === 'touchmove') {
+Gestures.handleTouchAction(ev);
+}
+}
+if (type === 'touchend') {
+POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget;
+ignoreMouse(true);
+}
+}
+}
+handled = ev[HANDLED_OBJ];
+if (handled.skip) {
+return;
+}
+var recognizers = Gestures.recognizers;
+for (var i = 0, r; i < recognizers.length; i++) {
+r = recognizers[i];
+if (gs[r.name] && !handled[r.name]) {
+if (r.flow && r.flow.start.indexOf(ev.type) > -1) {
+if (r.reset) {
+r.reset();
+}
+}
+}
+}
+for (var i = 0, r; i < recognizers.length; i++) {
+r = recognizers[i];
+if (gs[r.name] && !handled[r.name]) {
+handled[r.name] = true;
+r[type](ev);
+}
+}
+},
+handleTouchAction: function (ev) {
+var t = ev.changedTouches[0];
+var type = ev.type;
+if (type === 'touchstart') {
+POINTERSTATE.touch.x = t.clientX;
+POINTERSTATE.touch.y = t.clientY;
+POINTERSTATE.touch.scrollDecided = false;
+} else if (type === 'touchmove') {
+if (POINTERSTATE.touch.scrollDecided) {
+return;
+}
+POINTERSTATE.touch.scrollDecided = true;
+var ta = firstTouchAction(ev);
+var prevent = false;
+var dx = Math.abs(POINTERSTATE.touch.x - t.clientX);
+var dy = Math.abs(POINTERSTATE.touch.y - t.clientY);
+if (!ev.cancelable) {
+} else if (ta === 'none') {
+prevent = true;
+} else if (ta === 'pan-x') {
+prevent = dy > dx;
+} else if (ta === 'pan-y') {
+prevent = dx > dy;
+}
+if (prevent) {
+ev.preventDefault();
+} else {
+Gestures.prevent('track');
+}
+}
+},
+add: function (node, evType, handler) {
+node = wrap(node);
+var recognizer = this.gestures[evType];
+var deps = recognizer.deps;
+var name = recognizer.name;
+var gobj = node[GESTURE_KEY];
+if (!gobj) {
+node[GESTURE_KEY] = gobj = {};
+}
+for (var i = 0, dep, gd; i < deps.length; i++) {
+dep = deps[i];
+if (IS_TOUCH_ONLY && MOUSE_EVENTS.indexOf(dep) > -1) {
+continue;
+}
+gd = gobj[dep];
+if (!gd) {
+gobj[dep] = gd = { _count: 0 };
+}
+if (gd._count === 0) {
+node.addEventListener(dep, this.handleNative);
+}
+gd[name] = (gd[name] || 0) + 1;
+gd._count = (gd._count || 0) + 1;
+}
+node.addEventListener(evType, handler);
+if (recognizer.touchAction) {
+this.setTouchAction(node, recognizer.touchAction);
+}
+},
+remove: function (node, evType, handler) {
+node = wrap(node);
+var recognizer = this.gestures[evType];
+var deps = recognizer.deps;
+var name = recognizer.name;
+var gobj = node[GESTURE_KEY];
+if (gobj) {
+for (var i = 0, dep, gd; i < deps.length; i++) {
+dep = deps[i];
+gd = gobj[dep];
+if (gd && gd[name]) {
+gd[name] = (gd[name] || 1) - 1;
+gd._count = (gd._count || 1) - 1;
+if (gd._count === 0) {
+node.removeEventListener(dep, this.handleNative);
+}
+}
+}
+}
+node.removeEventListener(evType, handler);
+},
+register: function (recog) {
+this.recognizers.push(recog);
+for (var i = 0; i < recog.emits.length; i++) {
+this.gestures[recog.emits[i]] = recog;
+}
+},
+findRecognizerByEvent: function (evName) {
+for (var i = 0, r; i < this.recognizers.length; i++) {
+r = this.recognizers[i];
+for (var j = 0, n; j < r.emits.length; j++) {
+n = r.emits[j];
+if (n === evName) {
+return r;
+}
+}
+}
+return null;
+},
+setTouchAction: function (node, value) {
+if (HAS_NATIVE_TA) {
+node.style.touchAction = value;
+}
+node[TOUCH_ACTION] = value;
+},
+fire: function (target, type, detail) {
+var ev = Polymer.Base.fire(type, detail, {
+node: target,
+bubbles: true,
+cancelable: true
+});
+if (ev.defaultPrevented) {
+var se = detail.sourceEvent;
+if (se && se.preventDefault) {
+se.preventDefault();
+}
+}
+},
+prevent: function (evName) {
+var recognizer = this.findRecognizerByEvent(evName);
+if (recognizer.info) {
+recognizer.info.prevent = true;
+}
+}
+};
+Gestures.register({
+name: 'downup',
+deps: [
+'mousedown',
+'touchstart',
+'touchend'
+],
+flow: {
+start: [
+'mousedown',
+'touchstart'
+],
+end: [
+'mouseup',
+'touchend'
+]
+},
+emits: [
+'down',
+'up'
+],
+info: {
+movefn: function () {
+},
+upfn: function () {
+}
+},
+reset: function () {
+untrackDocument(this.info);
+},
+mousedown: function (e) {
+if (!hasLeftMouseButton(e)) {
+return;
+}
+var t = Gestures.findOriginalTarget(e);
+var self = this;
+var movefn = function movefn(e) {
+if (!hasLeftMouseButton(e)) {
+self.fire('up', t, e);
+untrackDocument(self.info);
+}
+};
+var upfn = function upfn(e) {
+if (hasLeftMouseButton(e)) {
+self.fire('up', t, e);
+}
+untrackDocument(self.info);
+};
+trackDocument(this.info, movefn, upfn);
+this.fire('down', t, e);
+},
+touchstart: function (e) {
+this.fire('down', Gestures.findOriginalTarget(e), e.changedTouches[0]);
+},
+touchend: function (e) {
+this.fire('up', Gestures.findOriginalTarget(e), e.changedTouches[0]);
+},
+fire: function (type, target, event) {
+var self = this;
+Gestures.fire(target, type, {
+x: event.clientX,
+y: event.clientY,
+sourceEvent: event,
+prevent: function (e) {
+return Gestures.prevent(e);
+}
+});
+}
+});
+Gestures.register({
+name: 'track',
+touchAction: 'none',
+deps: [
+'mousedown',
+'touchstart',
+'touchmove',
+'touchend'
+],
+flow: {
+start: [
+'mousedown',
+'touchstart'
+],
+end: [
+'mouseup',
+'touchend'
+]
+},
+emits: ['track'],
+info: {
+x: 0,
+y: 0,
+state: 'start',
+started: false,
+moves: [],
+addMove: function (move) {
+if (this.moves.length > TRACK_LENGTH) {
+this.moves.shift();
+}
+this.moves.push(move);
+},
+movefn: function () {
+},
+upfn: function () {
+},
+prevent: false
+},
+reset: function () {
+this.info.state = 'start';
+this.info.started = false;
+this.info.moves = [];
+this.info.x = 0;
+this.info.y = 0;
+this.info.prevent = false;
+untrackDocument(this.info);
+},
+hasMovedEnough: function (x, y) {
+if (this.info.prevent) {
+return false;
+}
+if (this.info.started) {
+return true;
+}
+var dx = Math.abs(this.info.x - x);
+var dy = Math.abs(this.info.y - y);
+return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE;
+},
+mousedown: function (e) {
+if (!hasLeftMouseButton(e)) {
+return;
+}
+var t = Gestures.findOriginalTarget(e);
+var self = this;
+var movefn = function movefn(e) {
+var x = e.clientX, y = e.clientY;
+if (self.hasMovedEnough(x, y)) {
+self.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : 'start';
+self.info.addMove({
+x: x,
+y: y
+});
+if (!hasLeftMouseButton(e)) {
+self.info.state = 'end';
+untrackDocument(self.info);
+}
+self.fire(t, e);
+self.info.started = true;
+}
+};
+var upfn = function upfn(e) {
+if (self.info.started) {
+Gestures.prevent('tap');
+movefn(e);
+}
+untrackDocument(self.info);
+};
+trackDocument(this.info, movefn, upfn);
+this.info.x = e.clientX;
+this.info.y = e.clientY;
+},
+touchstart: function (e) {
+var ct = e.changedTouches[0];
+this.info.x = ct.clientX;
+this.info.y = ct.clientY;
+},
+touchmove: function (e) {
+var t = Gestures.findOriginalTarget(e);
+var ct = e.changedTouches[0];
+var x = ct.clientX, y = ct.clientY;
+if (this.hasMovedEnough(x, y)) {
+this.info.addMove({
+x: x,
+y: y
+});
+this.fire(t, ct);
+this.info.state = 'track';
+this.info.started = true;
+}
+},
+touchend: function (e) {
+var t = Gestures.findOriginalTarget(e);
+var ct = e.changedTouches[0];
+if (this.info.started) {
+Gestures.prevent('tap');
+this.info.state = 'end';
+this.info.addMove({
+x: ct.clientX,
+y: ct.clientY
+});
+this.fire(t, ct);
+}
+},
+fire: function (target, touch) {
+var secondlast = this.info.moves[this.info.moves.length - 2];
+var lastmove = this.info.moves[this.info.moves.length - 1];
+var dx = lastmove.x - this.info.x;
+var dy = lastmove.y - this.info.y;
+var ddx, ddy = 0;
+if (secondlast) {
+ddx = lastmove.x - secondlast.x;
+ddy = lastmove.y - secondlast.y;
+}
+return Gestures.fire(target, 'track', {
+state: this.info.state,
+x: touch.clientX,
+y: touch.clientY,
+dx: dx,
+dy: dy,
+ddx: ddx,
+ddy: ddy,
+sourceEvent: touch,
+hover: function () {
+return Gestures.deepTargetFind(touch.clientX, touch.clientY);
+}
+});
+}
+});
+Gestures.register({
+name: 'tap',
+deps: [
+'mousedown',
+'click',
+'touchstart',
+'touchend'
+],
+flow: {
+start: [
+'mousedown',
+'touchstart'
+],
+end: [
+'click',
+'touchend'
+]
+},
+emits: ['tap'],
+info: {
+x: NaN,
+y: NaN,
+prevent: false
+},
+reset: function () {
+this.info.x = NaN;
+this.info.y = NaN;
+this.info.prevent = false;
+},
+save: function (e) {
+this.info.x = e.clientX;
+this.info.y = e.clientY;
+},
+mousedown: function (e) {
+if (hasLeftMouseButton(e)) {
+this.save(e);
+}
+},
+click: function (e) {
+if (hasLeftMouseButton(e)) {
+this.forward(e);
+}
+},
+touchstart: function (e) {
+this.save(e.changedTouches[0]);
+},
+touchend: function (e) {
+this.forward(e.changedTouches[0]);
+},
+forward: function (e) {
+var dx = Math.abs(e.clientX - this.info.x);
+var dy = Math.abs(e.clientY - this.info.y);
+var t = Gestures.findOriginalTarget(e);
+if (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE || isSyntheticClick(e)) {
+if (!this.info.prevent) {
+Gestures.fire(t, 'tap', {
+x: e.clientX,
+y: e.clientY,
+sourceEvent: e
+});
+}
+}
+}
+});
+var DIRECTION_MAP = {
+x: 'pan-x',
+y: 'pan-y',
+none: 'none',
+all: 'auto'
+};
+Polymer.Base._addFeature({
+_listen: function (node, eventName, handler) {
+if (Gestures.gestures[eventName]) {
+Gestures.add(node, eventName, handler);
+} else {
+node.addEventListener(eventName, handler);
+}
+},
+_unlisten: function (node, eventName, handler) {
+if (Gestures.gestures[eventName]) {
+Gestures.remove(node, eventName, handler);
+} else {
+node.removeEventListener(eventName, handler);
+}
+},
+setScrollDirection: function (direction, node) {
+node = node || this;
+Gestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto');
+}
+});
+Polymer.Gestures = Gestures;
+}());
+Polymer.Async = {
+_currVal: 0,
+_lastVal: 0,
+_callbacks: [],
+_twiddleContent: 0,
+_twiddle: document.createTextNode(''),
+run: function (callback, waitTime) {
+if (waitTime > 0) {
+return ~setTimeout(callback, waitTime);
+} else {
+this._twiddle.textContent = this._twiddleContent++;
+this._callbacks.push(callback);
+return this._currVal++;
+}
+},
+cancel: function (handle) {
+if (handle < 0) {
+clearTimeout(~handle);
+} else {
+var idx = handle - this._lastVal;
+if (idx >= 0) {
+if (!this._callbacks[idx]) {
+throw 'invalid async handle: ' + handle;
+}
+this._callbacks[idx] = null;
+}
+}
+},
+_atEndOfMicrotask: function () {
+var len = this._callbacks.length;
+for (var i = 0; i < len; i++) {
+var cb = this._callbacks[i];
+if (cb) {
+try {
+cb();
+} catch (e) {
+i++;
+this._callbacks.splice(0, i);
+this._lastVal += i;
+this._twiddle.textContent = this._twiddleContent++;
+throw e;
+}
+}
+}
+this._callbacks.splice(0, len);
+this._lastVal += len;
+}
+};
+new window.MutationObserver(function () {
+Polymer.Async._atEndOfMicrotask();
+}).observe(Polymer.Async._twiddle, { characterData: true });
+Polymer.Debounce = function () {
+var Async = Polymer.Async;
+var Debouncer = function (context) {
+this.context = context;
+var self = this;
+this.boundComplete = function () {
+self.complete();
+};
+};
+Debouncer.prototype = {
+go: function (callback, wait) {
+var h;
+this.finish = function () {
+Async.cancel(h);
+};
+h = Async.run(this.boundComplete, wait);
+this.callback = callback;
+},
+stop: function () {
+if (this.finish) {
+this.finish();
+this.finish = null;
+}
+},
+complete: function () {
+if (this.finish) {
+this.stop();
+this.callback.call(this.context);
+}
+}
+};
+function debounce(debouncer, callback, wait) {
+if (debouncer) {
+debouncer.stop();
+} else {
+debouncer = new Debouncer(this);
+}
+debouncer.go(callback, wait);
+return debouncer;
+}
+return debounce;
+}();
+Polymer.Base._addFeature({
+$$: function (slctr) {
+return Polymer.dom(this.root).querySelector(slctr);
+},
+toggleClass: function (name, bool, node) {
+node = node || this;
+if (arguments.length == 1) {
+bool = !node.classList.contains(name);
+}
+if (bool) {
+Polymer.dom(node).classList.add(name);
+} else {
+Polymer.dom(node).classList.remove(name);
+}
+},
+toggleAttribute: function (name, bool, node) {
+node = node || this;
+if (arguments.length == 1) {
+bool = !node.hasAttribute(name);
+}
+if (bool) {
+Polymer.dom(node).setAttribute(name, '');
+} else {
+Polymer.dom(node).removeAttribute(name);
+}
+},
+classFollows: function (name, toElement, fromElement) {
+if (fromElement) {
+Polymer.dom(fromElement).classList.remove(name);
+}
+if (toElement) {
+Polymer.dom(toElement).classList.add(name);
+}
+},
+attributeFollows: function (name, toElement, fromElement) {
+if (fromElement) {
+Polymer.dom(fromElement).removeAttribute(name);
+}
+if (toElement) {
+Polymer.dom(toElement).setAttribute(name, '');
+}
+},
+getEffectiveChildNodes: function () {
+return Polymer.dom(this).getEffectiveChildNodes();
+},
+getEffectiveChildren: function () {
+var list = Polymer.dom(this).getEffectiveChildNodes();
+return list.filter(function (n) {
+return n.nodeType === Node.ELEMENT_NODE;
+});
+},
+getEffectiveTextContent: function () {
+var cn = this.getEffectiveChildNodes();
+var tc = [];
+for (var i = 0, c; c = cn[i]; i++) {
+if (c.nodeType !== Node.COMMENT_NODE) {
+tc.push(Polymer.dom(c).textContent);
+}
+}
+return tc.join('');
+},
+queryEffectiveChildren: function (slctr) {
+var e$ = Polymer.dom(this).queryDistributedElements(slctr);
+return e$ && e$[0];
+},
+queryAllEffectiveChildren: function (slctr) {
+return Polymer.dom(this).queryDistributedElements(slctr);
+},
+getContentChildNodes: function (slctr) {
+var content = Polymer.dom(this.root).querySelector(slctr || 'content');
+return content ? Polymer.dom(content).getDistributedNodes() : [];
+},
+getContentChildren: function (slctr) {
+return this.getContentChildNodes(slctr).filter(function (n) {
+return n.nodeType === Node.ELEMENT_NODE;
+});
+},
+fire: function (type, detail, options) {
+options = options || Polymer.nob;
+var node = options.node || this;
+var detail = detail === null || detail === undefined ? {} : detail;
+var bubbles = options.bubbles === undefined ? true : options.bubbles;
+var cancelable = Boolean(options.cancelable);
+var useCache = options._useCache;
+var event = this._getEvent(type, bubbles, cancelable, useCache);
+event.detail = detail;
+if (useCache) {
+this.__eventCache[type] = null;
+}
+node.dispatchEvent(event);
+if (useCache) {
+this.__eventCache[type] = event;
+}
+return event;
+},
+__eventCache: {},
+_getEvent: function (type, bubbles, cancelable, useCache) {
+var event = useCache && this.__eventCache[type];
+if (!event || (event.bubbles != bubbles || event.cancelable != cancelable)) {
+event = new Event(type, {
+bubbles: Boolean(bubbles),
+cancelable: cancelable
+});
+}
+return event;
+},
+async: function (callback, waitTime) {
+var self = this;
+return Polymer.Async.run(function () {
+callback.call(self);
+}, waitTime);
+},
+cancelAsync: function (handle) {
+Polymer.Async.cancel(handle);
+},
+arrayDelete: function (path, item) {
+var index;
+if (Array.isArray(path)) {
+index = path.indexOf(item);
+if (index >= 0) {
+return path.splice(index, 1);
+}
+} else {
+var arr = this._get(path);
+index = arr.indexOf(item);
+if (index >= 0) {
+return this.splice(path, index, 1);
+}
+}
+},
+transform: function (transform, node) {
+node = node || this;
+node.style.webkitTransform = transform;
+node.style.transform = transform;
+},
+translate3d: function (x, y, z, node) {
+node = node || this;
+this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node);
+},
+importHref: function (href, onload, onerror) {
+var l = document.createElement('link');
+l.rel = 'import';
+l.href = href;
+var self = this;
+if (onload) {
+l.onload = function (e) {
+return onload.call(self, e);
+};
+}
+if (onerror) {
+l.onerror = function (e) {
+return onerror.call(self, e);
+};
+}
+document.head.appendChild(l);
+return l;
+},
+create: function (tag, props) {
+var elt = document.createElement(tag);
+if (props) {
+for (var n in props) {
+elt[n] = props[n];
+}
+}
+return elt;
+},
+isLightDescendant: function (node) {
+return this !== node && this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot();
+},
+isLocalDescendant: function (node) {
+return this.root === Polymer.dom(node).getOwnerRoot();
+}
+});
+Polymer.Bind = {
+_dataEventCache: {},
+prepareModel: function (model) {
+Polymer.Base.mixin(model, this._modelApi);
+},
+_modelApi: {
+_notifyChange: function (source, event, value) {
+value = value === undefined ? this[source] : value;
+event = event || Polymer.CaseMap.camelToDashCase(source) + '-changed';
+this.fire(event, { value: value }, {
+bubbles: false,
+cancelable: false,
+_useCache: true
+});
+},
+_propertySetter: function (property, value, effects, fromAbove) {
+var old = this.__data__[property];
+if (old !== value && (old === old || value === value)) {
+this.__data__[property] = value;
+if (typeof value == 'object') {
+this._clearPath(property);
+}
+if (this._propertyChanged) {
+this._propertyChanged(property, value, old);
+}
+if (effects) {
+this._effectEffects(property, value, effects, old, fromAbove);
+}
+}
+return old;
+},
+__setProperty: function (property, value, quiet, node) {
+node = node || this;
+var effects = node._propertyEffects && node._propertyEffects[property];
+if (effects) {
+node._propertySetter(property, value, effects, quiet);
+} else {
+node[property] = value;
+}
+},
+_effectEffects: function (property, value, effects, old, fromAbove) {
+for (var i = 0, l = effects.length, fx; i < l && (fx = effects[i]); i++) {
+fx.fn.call(this, property, value, fx.effect, old, fromAbove);
+}
+},
+_clearPath: function (path) {
+for (var prop in this.__data__) {
+if (prop.indexOf(path + '.') === 0) {
+this.__data__[prop] = undefined;
+}
+}
+}
+},
+ensurePropertyEffects: function (model, property) {
+if (!model._propertyEffects) {
+model._propertyEffects = {};
+}
+var fx = model._propertyEffects[property];
+if (!fx) {
+fx = model._propertyEffects[property] = [];
+}
+return fx;
+},
+addPropertyEffect: function (model, property, kind, effect) {
+var fx = this.ensurePropertyEffects(model, property);
+var propEffect = {
+kind: kind,
+effect: effect,
+fn: Polymer.Bind['_' + kind + 'Effect']
+};
+fx.push(propEffect);
+return propEffect;
+},
+createBindings: function (model) {
+var fx$ = model._propertyEffects;
+if (fx$) {
+for (var n in fx$) {
+var fx = fx$[n];
+fx.sort(this._sortPropertyEffects);
+this._createAccessors(model, n, fx);
+}
+}
+},
+_sortPropertyEffects: function () {
+var EFFECT_ORDER = {
+'compute': 0,
+'annotation': 1,
+'computedAnnotation': 2,
+'reflect': 3,
+'notify': 4,
+'observer': 5,
+'complexObserver': 6,
+'function': 7
+};
+return function (a, b) {
+return EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind];
+};
+}(),
+_createAccessors: function (model, property, effects) {
+var defun = {
+get: function () {
+return this.__data__[property];
+}
+};
+var setter = function (value) {
+this._propertySetter(property, value, effects);
+};
+var info = model.getPropertyInfo && model.getPropertyInfo(property);
+if (info && info.readOnly) {
+if (!info.computed) {
+model['_set' + this.upper(property)] = setter;
+}
+} else {
+defun.set = setter;
+}
+Object.defineProperty(model, property, defun);
+},
+upper: function (name) {
+return name[0].toUpperCase() + name.substring(1);
+},
+_addAnnotatedListener: function (model, index, property, path, event) {
+if (!model._bindListeners) {
+model._bindListeners = [];
+}
+var fn = this._notedListenerFactory(property, path, this._isStructured(path));
+var eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed';
+model._bindListeners.push({
+index: index,
+property: property,
+path: path,
+changedFn: fn,
+event: eventName
+});
+},
+_isStructured: function (path) {
+return path.indexOf('.') > 0;
+},
+_isEventBogus: function (e, target) {
+return e.path && e.path[0] !== target;
+},
+_notedListenerFactory: function (property, path, isStructured) {
+return function (target, value, targetPath) {
+if (targetPath) {
+this._notifyPath(this._fixPath(path, property, targetPath), value);
+} else {
+value = target[property];
+if (!isStructured) {
+this[path] = value;
+} else {
+if (this.__data__[path] != value) {
+this.set(path, value);
+}
+}
+}
+};
+},
+prepareInstance: function (inst) {
+inst.__data__ = Object.create(null);
+},
+setupBindListeners: function (inst) {
+var b$ = inst._bindListeners;
+for (var i = 0, l = b$.length, info; i < l && (info = b$[i]); i++) {
+var node = inst._nodes[info.index];
+this._addNotifyListener(node, inst, info.event, info.changedFn);
+}
+;
+},
+_addNotifyListener: function (element, context, event, changedFn) {
+element.addEventListener(event, function (e) {
+return context._notifyListener(changedFn, e);
+});
+}
+};
+Polymer.Base.extend(Polymer.Bind, {
+_shouldAddListener: function (effect) {
+return effect.name && effect.kind != 'attribute' && effect.kind != 'text' && !effect.isCompound && effect.parts[0].mode === '{' && !effect.parts[0].negate;
+},
+_annotationEffect: function (source, value, effect) {
+if (source != effect.value) {
+value = this._get(effect.value);
+this.__data__[effect.value] = value;
+}
+var calc = effect.negate ? !value : value;
+if (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) {
+return this._applyEffectValue(effect, calc);
+}
+},
+_reflectEffect: function (source, value, effect) {
+this.reflectPropertyToAttribute(source, effect.attribute, value);
+},
+_notifyEffect: function (source, value, effect, old, fromAbove) {
+if (!fromAbove) {
+this._notifyChange(source, effect.event, value);
+}
+},
+_functionEffect: function (source, value, fn, old, fromAbove) {
+fn.call(this, source, value, old, fromAbove);
+},
+_observerEffect: function (source, value, effect, old) {
+var fn = this[effect.method];
+if (fn) {
+fn.call(this, value, old);
+} else {
+this._warn(this._logf('_observerEffect', 'observer method `' + effect.method + '` not defined'));
+}
+},
+_complexObserverEffect: function (source, value, effect) {
+var fn = this[effect.method];
+if (fn) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+fn.apply(this, args);
+}
+} else {
+this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.method + '` not defined'));
+}
+},
+_computeEffect: function (source, value, effect) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+var fn = this[effect.method];
+if (fn) {
+this.__setProperty(effect.name, fn.apply(this, args));
+} else {
+this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined'));
+}
+}
+},
+_annotatedComputationEffect: function (source, value, effect) {
+var computedHost = this._rootDataHost || this;
+var fn = computedHost[effect.method];
+if (fn) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+var computedvalue = fn.apply(computedHost, args);
+if (effect.negate) {
+computedvalue = !computedvalue;
+}
+this._applyEffectValue(effect, computedvalue);
+}
+} else {
+computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined'));
+}
+},
+_marshalArgs: function (model, effect, path, value) {
+var values = [];
+var args = effect.args;
+for (var i = 0, l = args.length; i < l; i++) {
+var arg = args[i];
+var name = arg.name;
+var v;
+if (arg.literal) {
+v = arg.value;
+} else if (arg.structured) {
+v = Polymer.Base._get(name, model);
+} else {
+v = model[name];
+}
+if (args.length > 1 && v === undefined) {
+return;
+}
+if (arg.wildcard) {
+var baseChanged = name.indexOf(path + '.') === 0;
+var matches = effect.trigger.name.indexOf(name) === 0 && !baseChanged;
+values[i] = {
+path: matches ? path : name,
+value: matches ? value : v,
+base: v
+};
+} else {
+values[i] = v;
+}
+}
+return values;
+}
+});
+Polymer.Base._addFeature({
+_addPropertyEffect: function (property, kind, effect) {
+var prop = Polymer.Bind.addPropertyEffect(this, property, kind, effect);
+prop.pathFn = this['_' + prop.kind + 'PathEffect'];
+},
+_prepEffects: function () {
+Polymer.Bind.prepareModel(this);
+this._addAnnotationEffects(this._notes);
+},
+_prepBindings: function () {
+Polymer.Bind.createBindings(this);
+},
+_addPropertyEffects: function (properties) {
+if (properties) {
+for (var p in properties) {
+var prop = properties[p];
+if (prop.observer) {
+this._addObserverEffect(p, prop.observer);
+}
+if (prop.computed) {
+prop.readOnly = true;
+this._addComputedEffect(p, prop.computed);
+}
+if (prop.notify) {
+this._addPropertyEffect(p, 'notify', { event: Polymer.CaseMap.camelToDashCase(p) + '-changed' });
+}
+if (prop.reflectToAttribute) {
+this._addPropertyEffect(p, 'reflect', { attribute: Polymer.CaseMap.camelToDashCase(p) });
+}
+if (prop.readOnly) {
+Polymer.Bind.ensurePropertyEffects(this, p);
+}
+}
+}
+},
+_addComputedEffect: function (name, expression) {
+var sig = this._parseMethod(expression);
+for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
+this._addPropertyEffect(arg.model, 'compute', {
+method: sig.method,
+args: sig.args,
+trigger: arg,
+name: name
+});
+}
+},
+_addObserverEffect: function (property, observer) {
+this._addPropertyEffect(property, 'observer', {
+method: observer,
+property: property
+});
+},
+_addComplexObserverEffects: function (observers) {
+if (observers) {
+for (var i = 0, o; i < observers.length && (o = observers[i]); i++) {
+this._addComplexObserverEffect(o);
+}
+}
+},
+_addComplexObserverEffect: function (observer) {
+var sig = this._parseMethod(observer);
+for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
+this._addPropertyEffect(arg.model, 'complexObserver', {
+method: sig.method,
+args: sig.args,
+trigger: arg
+});
+}
+},
+_addAnnotationEffects: function (notes) {
+for (var i = 0, note; i < notes.length && (note = notes[i]); i++) {
+var b$ = note.bindings;
+for (var j = 0, binding; j < b$.length && (binding = b$[j]); j++) {
+this._addAnnotationEffect(binding, i);
+}
+}
+},
+_addAnnotationEffect: function (note, index) {
+if (Polymer.Bind._shouldAddListener(note)) {
+Polymer.Bind._addAnnotatedListener(this, index, note.name, note.parts[0].value, note.parts[0].event);
+}
+for (var i = 0; i < note.parts.length; i++) {
+var part = note.parts[i];
+if (part.signature) {
+this._addAnnotatedComputationEffect(note, part, index);
+} else if (!part.literal) {
+this._addPropertyEffect(part.model, 'annotation', {
+kind: note.kind,
+index: index,
+name: note.name,
+value: part.value,
+isCompound: note.isCompound,
+compoundIndex: part.compoundIndex,
+event: part.event,
+customEvent: part.customEvent,
+negate: part.negate
+});
+}
+}
+},
+_addAnnotatedComputationEffect: function (note, part, index) {
+var sig = part.signature;
+if (sig.static) {
+this.__addAnnotatedComputationEffect('__static__', index, note, part, null);
+} else {
+for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
+if (!arg.literal) {
+this.__addAnnotatedComputationEffect(arg.model, index, note, part, arg);
+}
+}
+}
+},
+__addAnnotatedComputationEffect: function (property, index, note, part, trigger) {
+this._addPropertyEffect(property, 'annotatedComputation', {
+index: index,
+isCompound: note.isCompound,
+compoundIndex: part.compoundIndex,
+kind: note.kind,
+name: note.name,
+negate: part.negate,
+method: part.signature.method,
+args: part.signature.args,
+trigger: trigger
+});
+},
+_parseMethod: function (expression) {
+var m = expression.match(/([^\s]+)\((.*)\)/);
+if (m) {
+var sig = {
+method: m[1],
+static: true
+};
+if (m[2].trim()) {
+var args = m[2].replace(/\\,/g, '&comma;').split(',');
+return this._parseArgs(args, sig);
+} else {
+sig.args = Polymer.nar;
+return sig;
+}
+}
+},
+_parseArgs: function (argList, sig) {
+sig.args = argList.map(function (rawArg) {
+var arg = this._parseArg(rawArg);
+if (!arg.literal) {
+sig.static = false;
+}
+return arg;
+}, this);
+return sig;
+},
+_parseArg: function (rawArg) {
+var arg = rawArg.trim().replace(/&comma;/g, ',').replace(/\\(.)/g, '$1');
+var a = {
+name: arg,
+model: this._modelForPath(arg)
+};
+var fc = arg[0];
+if (fc === '-') {
+fc = arg[1];
+}
+if (fc >= '0' && fc <= '9') {
+fc = '#';
+}
+switch (fc) {
+case '\'':
+case '"':
+a.value = arg.slice(1, -1);
+a.literal = true;
+break;
+case '#':
+a.value = Number(arg);
+a.literal = true;
+break;
+}
+if (!a.literal) {
+a.structured = arg.indexOf('.') > 0;
+if (a.structured) {
+a.wildcard = arg.slice(-2) == '.*';
+if (a.wildcard) {
+a.name = arg.slice(0, -2);
+}
+}
+}
+return a;
+},
+_marshalInstanceEffects: function () {
+Polymer.Bind.prepareInstance(this);
+if (this._bindListeners) {
+Polymer.Bind.setupBindListeners(this);
+}
+},
+_applyEffectValue: function (info, value) {
+var node = this._nodes[info.index];
+var property = info.name;
+if (info.isCompound) {
+var storage = node.__compoundStorage__[property];
+storage[info.compoundIndex] = value;
+value = storage.join('');
+}
+if (info.kind == 'attribute') {
+this.serializeValueToAttribute(value, property, node);
+} else {
+if (property === 'className') {
+value = this._scopeElementClass(node, value);
+}
+if (property === 'textContent' || node.localName == 'input' && property == 'value') {
+value = value == undefined ? '' : value;
+}
+var pinfo;
+if (!node._propertyInfo || !(pinfo = node._propertyInfo[property]) || !pinfo.readOnly) {
+this.__setProperty(property, value, true, node);
+}
+}
+},
+_executeStaticEffects: function () {
+if (this._propertyEffects && this._propertyEffects.__static__) {
+this._effectEffects('__static__', null, this._propertyEffects.__static__);
+}
+}
+});
+Polymer.Base._addFeature({
+_setupConfigure: function (initialConfig) {
+this._config = {};
+this._handlers = [];
+if (initialConfig) {
+for (var i in initialConfig) {
+if (initialConfig[i] !== undefined) {
+this._config[i] = initialConfig[i];
+}
+}
+}
+},
+_marshalAttributes: function () {
+this._takeAttributesToModel(this._config);
+},
+_attributeChangedImpl: function (name) {
+var model = this._clientsReadied ? this : this._config;
+this._setAttributeToProperty(model, name);
+},
+_configValue: function (name, value) {
+var info = this._propertyInfo[name];
+if (!info || !info.readOnly) {
+this._config[name] = value;
+}
+},
+_beforeClientsReady: function () {
+this._configure();
+},
+_configure: function () {
+this._configureAnnotationReferences();
+this._aboveConfig = this.mixin({}, this._config);
+var config = {};
+for (var i = 0; i < this.behaviors.length; i++) {
+this._configureProperties(this.behaviors[i].properties, config);
+}
+this._configureProperties(this.properties, config);
+this.mixin(config, this._aboveConfig);
+this._config = config;
+if (this._clients && this._clients.length) {
+this._distributeConfig(this._config);
+}
+},
+_configureProperties: function (properties, config) {
+for (var i in properties) {
+var c = properties[i];
+if (c.value !== undefined) {
+var value = c.value;
+if (typeof value == 'function') {
+value = value.call(this, this._config);
+}
+config[i] = value;
+}
+}
+},
+_distributeConfig: function (config) {
+var fx$ = this._propertyEffects;
+if (fx$) {
+for (var p in config) {
+var fx = fx$[p];
+if (fx) {
+for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) {
+if (x.kind === 'annotation' && !x.isCompound) {
+var node = this._nodes[x.effect.index];
+if (node._configValue) {
+var value = p === x.effect.value ? config[p] : this._get(x.effect.value, config);
+node._configValue(x.effect.name, value);
+}
+}
+}
+}
+}
+}
+},
+_afterClientsReady: function () {
+this._executeStaticEffects();
+this._applyConfig(this._config, this._aboveConfig);
+this._flushHandlers();
+},
+_applyConfig: function (config, aboveConfig) {
+for (var n in config) {
+if (this[n] === undefined) {
+this.__setProperty(n, config[n], n in aboveConfig);
+}
+}
+},
+_notifyListener: function (fn, e) {
+if (!Polymer.Bind._isEventBogus(e, e.target)) {
+var value, path;
+if (e.detail) {
+value = e.detail.value;
+path = e.detail.path;
+}
+if (!this._clientsReadied) {
+this._queueHandler([
+fn,
+e.target,
+value,
+path
+]);
+} else {
+return fn.call(this, e.target, value, path);
+}
+}
+},
+_queueHandler: function (args) {
+this._handlers.push(args);
+},
+_flushHandlers: function () {
+var h$ = this._handlers;
+for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) {
+h[0].call(this, h[1], h[2], h[3]);
+}
+this._handlers = [];
+}
+});
+(function () {
+'use strict';
+Polymer.Base._addFeature({
+notifyPath: function (path, value, fromAbove) {
+var info = {};
+this._get(path, this, info);
+this._notifyPath(info.path, value, fromAbove);
+},
+_notifyPath: function (path, value, fromAbove) {
+var old = this._propertySetter(path, value);
+if (old !== value && (old === old || value === value)) {
+this._pathEffector(path, value);
+if (!fromAbove) {
+this._notifyPathUp(path, value);
+}
+return true;
+}
+},
+_getPathParts: function (path) {
+if (Array.isArray(path)) {
+var parts = [];
+for (var i = 0; i < path.length; i++) {
+var args = path[i].toString().split('.');
+for (var j = 0; j < args.length; j++) {
+parts.push(args[j]);
+}
+}
+return parts;
+} else {
+return path.toString().split('.');
+}
+},
+set: function (path, value, root) {
+var prop = root || this;
+var parts = this._getPathParts(path);
+var array;
+var last = parts[parts.length - 1];
+if (parts.length > 1) {
+for (var i = 0; i < parts.length - 1; i++) {
+var part = parts[i];
+if (array && part[0] == '#') {
+prop = Polymer.Collection.get(array).getItem(part);
+} else {
+prop = prop[part];
+if (array && parseInt(part, 10) == part) {
+parts[i] = Polymer.Collection.get(array).getKey(prop);
+}
+}
+if (!prop) {
+return;
+}
+array = Array.isArray(prop) ? prop : null;
+}
+if (array) {
+var coll = Polymer.Collection.get(array);
+if (last[0] == '#') {
+var key = last;
+var old = coll.getItem(key);
+last = array.indexOf(old);
+coll.setItem(key, value);
+} else if (parseInt(last, 10) == last) {
+var old = prop[last];
+var key = coll.getKey(old);
+parts[i] = key;
+coll.setItem(key, value);
+}
+}
+prop[last] = value;
+if (!root) {
+this._notifyPath(parts.join('.'), value);
+}
+} else {
+prop[path] = value;
+}
+},
+get: function (path, root) {
+return this._get(path, root);
+},
+_get: function (path, root, info) {
+var prop = root || this;
+var parts = this._getPathParts(path);
+var array;
+for (var i = 0; i < parts.length; i++) {
+if (!prop) {
+return;
+}
+var part = parts[i];
+if (array && part[0] == '#') {
+prop = Polymer.Collection.get(array).getItem(part);
+} else {
+prop = prop[part];
+if (info && array && parseInt(part, 10) == part) {
+parts[i] = Polymer.Collection.get(array).getKey(prop);
+}
+}
+array = Array.isArray(prop) ? prop : null;
+}
+if (info) {
+info.path = parts.join('.');
+}
+return prop;
+},
+_pathEffector: function (path, value) {
+var model = this._modelForPath(path);
+var fx$ = this._propertyEffects && this._propertyEffects[model];
+if (fx$) {
+for (var i = 0, fx; i < fx$.length && (fx = fx$[i]); i++) {
+var fxFn = fx.pathFn;
+if (fxFn) {
+fxFn.call(this, path, value, fx.effect);
+}
+}
+}
+if (this._boundPaths) {
+this._notifyBoundPaths(path, value);
+}
+},
+_annotationPathEffect: function (path, value, effect) {
+if (effect.value === path || effect.value.indexOf(path + '.') === 0) {
+Polymer.Bind._annotationEffect.call(this, path, value, effect);
+} else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) {
+var node = this._nodes[effect.index];
+if (node && node._notifyPath) {
+var p = this._fixPath(effect.name, effect.value, path);
+node._notifyPath(p, value, true);
+}
+}
+},
+_complexObserverPathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._complexObserverEffect.call(this, path, value, effect);
+}
+},
+_computePathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._computeEffect.call(this, path, value, effect);
+}
+},
+_annotatedComputationPathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._annotatedComputationEffect.call(this, path, value, effect);
+}
+},
+_pathMatchesEffect: function (path, effect) {
+var effectArg = effect.trigger.name;
+return effectArg == path || effectArg.indexOf(path + '.') === 0 || effect.trigger.wildcard && path.indexOf(effectArg) === 0;
+},
+linkPaths: function (to, from) {
+this._boundPaths = this._boundPaths || {};
+if (from) {
+this._boundPaths[to] = from;
+} else {
+this.unlinkPaths(to);
+}
+},
+unlinkPaths: function (path) {
+if (this._boundPaths) {
+delete this._boundPaths[path];
+}
+},
+_notifyBoundPaths: function (path, value) {
+for (var a in this._boundPaths) {
+var b = this._boundPaths[a];
+if (path.indexOf(a + '.') == 0) {
+this._notifyPath(this._fixPath(b, a, path), value);
+} else if (path.indexOf(b + '.') == 0) {
+this._notifyPath(this._fixPath(a, b, path), value);
+}
+}
+},
+_fixPath: function (property, root, path) {
+return property + path.slice(root.length);
+},
+_notifyPathUp: function (path, value) {
+var rootName = this._modelForPath(path);
+var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);
+var eventName = dashCaseName + this._EVENT_CHANGED;
+this.fire(eventName, {
+path: path,
+value: value
+}, {
+bubbles: false,
+_useCache: true
+});
+},
+_modelForPath: function (path) {
+var dot = path.indexOf('.');
+return dot < 0 ? path : path.slice(0, dot);
+},
+_EVENT_CHANGED: '-changed',
+notifySplices: function (path, splices) {
+var info = {};
+var array = this._get(path, this, info);
+this._notifySplices(array, info.path, splices);
+},
+_notifySplices: function (array, path, splices) {
+var change = {
+keySplices: Polymer.Collection.applySplices(array, splices),
+indexSplices: splices
+};
+if (!array.hasOwnProperty('splices')) {
+Object.defineProperty(array, 'splices', {
+configurable: true,
+writable: true
+});
+}
+array.splices = change;
+this._notifyPath(path + '.splices', change);
+this._notifyPath(path + '.length', array.length);
+change.keySplices = null;
+change.indexSplices = null;
+},
+_notifySplice: function (array, path, index, added, removed) {
+this._notifySplices(array, path, [{
+index: index,
+addedCount: added,
+removed: removed,
+object: array,
+type: 'splice'
+}]);
+},
+push: function (path) {
+var info = {};
+var array = this._get(path, this, info);
+var args = Array.prototype.slice.call(arguments, 1);
+var len = array.length;
+var ret = array.push.apply(array, args);
+if (args.length) {
+this._notifySplice(array, info.path, len, args.length, []);
+}
+return ret;
+},
+pop: function (path) {
+var info = {};
+var array = this._get(path, this, info);
+var hadLength = Boolean(array.length);
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.pop.apply(array, args);
+if (hadLength) {
+this._notifySplice(array, info.path, array.length, 0, [ret]);
+}
+return ret;
+},
+splice: function (path, start, deleteCount) {
+var info = {};
+var array = this._get(path, this, info);
+if (start < 0) {
+start = array.length - Math.floor(-start);
+} else {
+start = Math.floor(start);
+}
+if (!start) {
+start = 0;
+}
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.splice.apply(array, args);
+var addedCount = Math.max(args.length - 2, 0);
+if (addedCount || ret.length) {
+this._notifySplice(array, info.path, start, addedCount, ret);
+}
+return ret;
+},
+shift: function (path) {
+var info = {};
+var array = this._get(path, this, info);
+var hadLength = Boolean(array.length);
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.shift.apply(array, args);
+if (hadLength) {
+this._notifySplice(array, info.path, 0, 0, [ret]);
+}
+return ret;
+},
+unshift: function (path) {
+var info = {};
+var array = this._get(path, this, info);
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.unshift.apply(array, args);
+if (args.length) {
+this._notifySplice(array, info.path, 0, args.length, []);
+}
+return ret;
+},
+prepareModelNotifyPath: function (model) {
+this.mixin(model, {
+fire: Polymer.Base.fire,
+_getEvent: Polymer.Base._getEvent,
+__eventCache: Polymer.Base.__eventCache,
+notifyPath: Polymer.Base.notifyPath,
+_get: Polymer.Base._get,
+_EVENT_CHANGED: Polymer.Base._EVENT_CHANGED,
+_notifyPath: Polymer.Base._notifyPath,
+_notifyPathUp: Polymer.Base._notifyPathUp,
+_pathEffector: Polymer.Base._pathEffector,
+_annotationPathEffect: Polymer.Base._annotationPathEffect,
+_complexObserverPathEffect: Polymer.Base._complexObserverPathEffect,
+_annotatedComputationPathEffect: Polymer.Base._annotatedComputationPathEffect,
+_computePathEffect: Polymer.Base._computePathEffect,
+_modelForPath: Polymer.Base._modelForPath,
+_pathMatchesEffect: Polymer.Base._pathMatchesEffect,
+_notifyBoundPaths: Polymer.Base._notifyBoundPaths,
+_getPathParts: Polymer.Base._getPathParts
+});
+}
+});
+}());
+Polymer.Base._addFeature({
+resolveUrl: function (url) {
+var module = Polymer.DomModule.import(this.is);
+var root = '';
+if (module) {
+var assetPath = module.getAttribute('assetpath') || '';
+root = Polymer.ResolveUrl.resolveUrl(assetPath, module.ownerDocument.baseURI);
+}
+return Polymer.ResolveUrl.resolveUrl(url, root);
+}
+});
+Polymer.CssParse = function () {
+var api = {
+parse: function (text) {
+text = this._clean(text);
+return this._parseCss(this._lex(text), text);
+},
+_clean: function (cssText) {
+return cssText.replace(this._rx.comments, '').replace(this._rx.port, '');
+},
+_lex: function (text) {
+var root = {
+start: 0,
+end: text.length
+};
+var n = root;
+for (var i = 0, s = 0, l = text.length; i < l; i++) {
+switch (text[i]) {
+case this.OPEN_BRACE:
+if (!n.rules) {
+n.rules = [];
+}
+var p = n;
+var previous = p.rules[p.rules.length - 1];
+n = {
+start: i + 1,
+parent: p,
+previous: previous
+};
+p.rules.push(n);
+break;
+case this.CLOSE_BRACE:
+n.end = i + 1;
+n = n.parent || root;
+break;
+}
+}
+return root;
+},
+_parseCss: function (node, text) {
+var t = text.substring(node.start, node.end - 1);
+node.parsedCssText = node.cssText = t.trim();
+if (node.parent) {
+var ss = node.previous ? node.previous.end : node.parent.start;
+t = text.substring(ss, node.start - 1);
+t = this._expandUnicodeEscapes(t);
+t = t.replace(this._rx.multipleSpaces, ' ');
+t = t.substring(t.lastIndexOf(';') + 1);
+var s = node.parsedSelector = node.selector = t.trim();
+node.atRule = s.indexOf(this.AT_START) === 0;
+if (node.atRule) {
+if (s.indexOf(this.MEDIA_START) === 0) {
+node.type = this.types.MEDIA_RULE;
+} else if (s.match(this._rx.keyframesRule)) {
+node.type = this.types.KEYFRAMES_RULE;
+}
+} else {
+if (s.indexOf(this.VAR_START) === 0) {
+node.type = this.types.MIXIN_RULE;
+} else {
+node.type = this.types.STYLE_RULE;
+}
+}
+}
+var r$ = node.rules;
+if (r$) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+this._parseCss(r, text);
+}
+}
+return node;
+},
+_expandUnicodeEscapes: function (s) {
+return s.replace(/\\([0-9a-f]{1,6})\s/gi, function () {
+var code = arguments[1], repeat = 6 - code.length;
+while (repeat--) {
+code = '0' + code;
+}
+return '\\' + code;
+});
+},
+stringify: function (node, preserveProperties, text) {
+text = text || '';
+var cssText = '';
+if (node.cssText || node.rules) {
+var r$ = node.rules;
+if (r$ && (preserveProperties || !this._hasMixinRules(r$))) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+cssText = this.stringify(r, preserveProperties, cssText);
+}
+} else {
+cssText = preserveProperties ? node.cssText : this.removeCustomProps(node.cssText);
+cssText = cssText.trim();
+if (cssText) {
+cssText = ' ' + cssText + '\n';
+}
+}
+}
+if (cssText) {
+if (node.selector) {
+text += node.selector + ' ' + this.OPEN_BRACE + '\n';
+}
+text += cssText;
+if (node.selector) {
+text += this.CLOSE_BRACE + '\n\n';
+}
+}
+return text;
+},
+_hasMixinRules: function (rules) {
+return rules[0].selector.indexOf(this.VAR_START) === 0;
+},
+removeCustomProps: function (cssText) {
+return cssText;
+},
+removeCustomPropAssignment: function (cssText) {
+return cssText.replace(this._rx.customProp, '').replace(this._rx.mixinProp, '');
+},
+removeCustomPropApply: function (cssText) {
+return cssText.replace(this._rx.mixinApply, '').replace(this._rx.varApply, '');
+},
+types: {
+STYLE_RULE: 1,
+KEYFRAMES_RULE: 7,
+MEDIA_RULE: 4,
+MIXIN_RULE: 1000
+},
+OPEN_BRACE: '{',
+CLOSE_BRACE: '}',
+_rx: {
+comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim,
+port: /@import[^;]*;/gim,
+customProp: /(?:^|[\s;])--[^;{]*?:[^{};]*?(?:[;\n]|$)/gim,
+mixinProp: /(?:^|[\s;])?--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\n]|$)?/gim,
+mixinApply: /@apply[\s]*\([^)]*?\)[\s]*(?:[;\n]|$)?/gim,
+varApply: /[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,
+keyframesRule: /^@[^\s]*keyframes/,
+multipleSpaces: /\s+/g
+},
+VAR_START: '--',
+MEDIA_START: '@media',
+AT_START: '@'
+};
+return api;
+}();
+Polymer.StyleUtil = function () {
+return {
+MODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css], template',
+INCLUDE_ATTR: 'include',
+toCssText: function (rules, callback, preserveProperties) {
+if (typeof rules === 'string') {
+rules = this.parser.parse(rules);
+}
+if (callback) {
+this.forEachStyleRule(rules, callback);
+}
+return this.parser.stringify(rules, preserveProperties);
+},
+forRulesInStyles: function (styles, callback) {
+if (styles) {
+for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
+this.forEachStyleRule(this.rulesForStyle(s), callback);
+}
+}
+},
+rulesForStyle: function (style) {
+if (!style.__cssRules && style.textContent) {
+style.__cssRules = this.parser.parse(style.textContent);
+}
+return style.__cssRules;
+},
+clearStyleRules: function (style) {
+style.__cssRules = null;
+},
+forEachStyleRule: function (node, callback) {
+if (!node) {
+return;
+}
+var s = node.parsedSelector;
+var skipRules = false;
+if (node.type === this.ruleTypes.STYLE_RULE) {
+callback(node);
+} else if (node.type === this.ruleTypes.KEYFRAMES_RULE || node.type === this.ruleTypes.MIXIN_RULE) {
+skipRules = true;
+}
+var r$ = node.rules;
+if (r$ && !skipRules) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+this.forEachStyleRule(r, callback);
+}
+}
+},
+applyCss: function (cssText, moniker, target, afterNode) {
+var style = document.createElement('style');
+if (moniker) {
+style.setAttribute('scope', moniker);
+}
+style.textContent = cssText;
+target = target || document.head;
+if (!afterNode) {
+var n$ = target.querySelectorAll('style[scope]');
+afterNode = n$[n$.length - 1];
+}
+target.insertBefore(style, afterNode && afterNode.nextSibling || target.firstChild);
+return style;
+},
+cssFromModules: function (moduleIds, warnIfNotFound) {
+var modules = moduleIds.trim().split(' ');
+var cssText = '';
+for (var i = 0; i < modules.length; i++) {
+cssText += this.cssFromModule(modules[i], warnIfNotFound);
+}
+return cssText;
+},
+cssFromModule: function (moduleId, warnIfNotFound) {
+var m = Polymer.DomModule.import(moduleId);
+if (m && !m._cssText) {
+m._cssText = this.cssFromElement(m);
+}
+if (!m && warnIfNotFound) {
+console.warn('Could not find style data in module named', moduleId);
+}
+return m && m._cssText || '';
+},
+cssFromElement: function (element) {
+var cssText = '';
+var content = element.content || element;
+var e$ = Polymer.DomApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));
+for (var i = 0, e; i < e$.length; i++) {
+e = e$[i];
+if (e.localName === 'template') {
+cssText += this.cssFromElement(e);
+} else {
+if (e.localName === 'style') {
+var include = e.getAttribute(this.INCLUDE_ATTR);
+if (include) {
+cssText += this.cssFromModules(include, true);
+}
+e = e.__appliedElement || e;
+e.parentNode.removeChild(e);
+cssText += this.resolveCss(e.textContent, element.ownerDocument);
+} else if (e.import && e.import.body) {
+cssText += this.resolveCss(e.import.body.textContent, e.import);
+}
+}
+}
+return cssText;
+},
+resolveCss: Polymer.ResolveUrl.resolveCss,
+parser: Polymer.CssParse,
+ruleTypes: Polymer.CssParse.types
+};
+}();
+Polymer.StyleTransformer = function () {
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var styleUtil = Polymer.StyleUtil;
+var api = {
+dom: function (node, scope, useAttr, shouldRemoveScope) {
+this._transformDom(node, scope || '', useAttr, shouldRemoveScope);
+},
+_transformDom: function (node, selector, useAttr, shouldRemoveScope) {
+if (node.setAttribute) {
+this.element(node, selector, useAttr, shouldRemoveScope);
+}
+var c$ = Polymer.dom(node).childNodes;
+for (var i = 0; i < c$.length; i++) {
+this._transformDom(c$[i], selector, useAttr, shouldRemoveScope);
+}
+},
+element: function (element, scope, useAttr, shouldRemoveScope) {
+if (useAttr) {
+if (shouldRemoveScope) {
+element.removeAttribute(SCOPE_NAME);
+} else {
+element.setAttribute(SCOPE_NAME, scope);
+}
+} else {
+if (scope) {
+if (element.classList) {
+if (shouldRemoveScope) {
+element.classList.remove(SCOPE_NAME);
+element.classList.remove(scope);
+} else {
+element.classList.add(SCOPE_NAME);
+element.classList.add(scope);
+}
+} else if (element.getAttribute) {
+var c = element.getAttribute(CLASS);
+if (shouldRemoveScope) {
+if (c) {
+element.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, ''));
+}
+} else {
+element.setAttribute(CLASS, c + (c ? ' ' : '') + SCOPE_NAME + ' ' + scope);
+}
+}
+}
+}
+},
+elementStyles: function (element, callback) {
+var styles = element._styles;
+var cssText = '';
+for (var i = 0, l = styles.length, s, text; i < l && (s = styles[i]); i++) {
+var rules = styleUtil.rulesForStyle(s);
+cssText += nativeShadow ? styleUtil.toCssText(rules, callback) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\n\n';
+}
+return cssText.trim();
+},
+css: function (rules, scope, ext, callback, useAttr) {
+var hostScope = this._calcHostScope(scope, ext);
+scope = this._calcElementScope(scope, useAttr);
+var self = this;
+return styleUtil.toCssText(rules, function (rule) {
+if (!rule.isScoped) {
+self.rule(rule, scope, hostScope);
+rule.isScoped = true;
+}
+if (callback) {
+callback(rule, scope, hostScope);
+}
+});
+},
+_calcElementScope: function (scope, useAttr) {
+if (scope) {
+return useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope;
+} else {
+return '';
+}
+},
+_calcHostScope: function (scope, ext) {
+return ext ? '[is=' + scope + ']' : scope;
+},
+rule: function (rule, scope, hostScope) {
+this._transformRule(rule, this._transformComplexSelector, scope, hostScope);
+},
+_transformRule: function (rule, transformer, scope, hostScope) {
+var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
+for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {
+p$[i] = transformer.call(this, p, scope, hostScope);
+}
+rule.selector = rule.transformedSelector = p$.join(COMPLEX_SELECTOR_SEP);
+},
+_transformComplexSelector: function (selector, scope, hostScope) {
+var stop = false;
+var hostContext = false;
+var self = this;
+selector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) {
+if (!stop) {
+var info = self._transformCompoundSelector(s, c, scope, hostScope);
+stop = stop || info.stop;
+hostContext = hostContext || info.hostContext;
+c = info.combinator;
+s = info.value;
+} else {
+s = s.replace(SCOPE_JUMP, ' ');
+}
+return c + s;
+});
+if (hostContext) {
+selector = selector.replace(HOST_CONTEXT_PAREN, function (m, pre, paren, post) {
+return pre + paren + ' ' + hostScope + post + COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post;
+});
+}
+return selector;
+},
+_transformCompoundSelector: function (selector, combinator, scope, hostScope) {
+var jumpIndex = selector.search(SCOPE_JUMP);
+var hostContext = false;
+if (selector.indexOf(HOST_CONTEXT) >= 0) {
+hostContext = true;
+} else if (selector.indexOf(HOST) >= 0) {
+selector = selector.replace(HOST_PAREN, function (m, host, paren) {
+return hostScope + paren;
+});
+selector = selector.replace(HOST, hostScope);
+} else if (jumpIndex !== 0) {
+selector = scope ? this._transformSimpleSelector(selector, scope) : selector;
+}
+if (selector.indexOf(CONTENT) >= 0) {
+combinator = '';
+}
+var stop;
+if (jumpIndex >= 0) {
+selector = selector.replace(SCOPE_JUMP, ' ');
+stop = true;
+}
+return {
+value: selector,
+combinator: combinator,
+stop: stop,
+hostContext: hostContext
+};
+},
+_transformSimpleSelector: function (selector, scope) {
+var p$ = selector.split(PSEUDO_PREFIX);
+p$[0] += scope;
+return p$.join(PSEUDO_PREFIX);
+},
+documentRule: function (rule) {
+rule.selector = rule.parsedSelector;
+this.normalizeRootSelector(rule);
+if (!nativeShadow) {
+this._transformRule(rule, this._transformDocumentSelector);
+}
+},
+normalizeRootSelector: function (rule) {
+if (rule.selector === ROOT) {
+rule.selector = 'body';
+}
+},
+_transformDocumentSelector: function (selector) {
+return selector.match(SCOPE_JUMP) ? this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR) : this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR);
+},
+SCOPE_NAME: 'style-scope'
+};
+var SCOPE_NAME = api.SCOPE_NAME;
+var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')';
+var COMPLEX_SELECTOR_SEP = ',';
+var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)([^\s>+~]+)/g;
+var HOST = ':host';
+var ROOT = ':root';
+var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
+var HOST_CONTEXT = ':host-context';
+var HOST_CONTEXT_PAREN = /(.*)(?:\:host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;
+var CONTENT = '::content';
+var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//;
+var CSS_CLASS_PREFIX = '.';
+var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
+var CSS_ATTR_SUFFIX = ']';
+var PSEUDO_PREFIX = ':';
+var CLASS = 'class';
+return api;
+}();
+Polymer.StyleExtends = function () {
+var styleUtil = Polymer.StyleUtil;
+return {
+hasExtends: function (cssText) {
+return Boolean(cssText.match(this.rx.EXTEND));
+},
+transform: function (style) {
+var rules = styleUtil.rulesForStyle(style);
+var self = this;
+styleUtil.forEachStyleRule(rules, function (rule) {
+var map = self._mapRule(rule);
+if (rule.parent) {
+var m;
+while (m = self.rx.EXTEND.exec(rule.cssText)) {
+var extend = m[1];
+var extendor = self._findExtendor(extend, rule);
+if (extendor) {
+self._extendRule(rule, extendor);
+}
+}
+}
+rule.cssText = rule.cssText.replace(self.rx.EXTEND, '');
+});
+return styleUtil.toCssText(rules, function (rule) {
+if (rule.selector.match(self.rx.STRIP)) {
+rule.cssText = '';
+}
+}, true);
+},
+_mapRule: function (rule) {
+if (rule.parent) {
+var map = rule.parent.map || (rule.parent.map = {});
+var parts = rule.selector.split(',');
+for (var i = 0, p; i < parts.length; i++) {
+p = parts[i];
+map[p.trim()] = rule;
+}
+return map;
+}
+},
+_findExtendor: function (extend, rule) {
+return rule.parent && rule.parent.map && rule.parent.map[extend] || this._findExtendor(extend, rule.parent);
+},
+_extendRule: function (target, source) {
+if (target.parent !== source.parent) {
+this._cloneAndAddRuleToParent(source, target.parent);
+}
+target.extends = target.extends || [];
+target.extends.push(source);
+source.selector = source.selector.replace(this.rx.STRIP, '');
+source.selector = (source.selector && source.selector + ',\n') + target.selector;
+if (source.extends) {
+source.extends.forEach(function (e) {
+this._extendRule(target, e);
+}, this);
+}
+},
+_cloneAndAddRuleToParent: function (rule, parent) {
+rule = Object.create(rule);
+rule.parent = parent;
+if (rule.extends) {
+rule.extends = rule.extends.slice();
+}
+parent.rules.push(rule);
+},
+rx: {
+EXTEND: /@extends\(([^)]*)\)\s*?;/gim,
+STRIP: /%[^,]*$/
+}
+};
+}();
+(function () {
+var prepElement = Polymer.Base._prepElement;
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var styleUtil = Polymer.StyleUtil;
+var styleTransformer = Polymer.StyleTransformer;
+var styleExtends = Polymer.StyleExtends;
+Polymer.Base._addFeature({
+_prepElement: function (element) {
+if (this._encapsulateStyle) {
+styleTransformer.element(element, this.is, this._scopeCssViaAttr);
+}
+prepElement.call(this, element);
+},
+_prepStyles: function () {
+if (this._encapsulateStyle === undefined) {
+this._encapsulateStyle = !nativeShadow && Boolean(this._template);
+}
+if (this._template) {
+this._styles = this._collectStyles();
+var cssText = styleTransformer.elementStyles(this);
+if (cssText) {
+var style = styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.content : null);
+if (!nativeShadow) {
+this._scopeStyle = style;
+}
+}
+} else {
+this._styles = [];
+}
+},
+_collectStyles: function () {
+var styles = [];
+var cssText = '', m$ = this.styleModules;
+if (m$) {
+for (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) {
+cssText += styleUtil.cssFromModule(m);
+}
+}
+cssText += styleUtil.cssFromModule(this.is);
+var p = this._template && this._template.parentNode;
+if (this._template && (!p || p.id.toLowerCase() !== this.is)) {
+cssText += styleUtil.cssFromElement(this._template);
+}
+if (cssText) {
+var style = document.createElement('style');
+style.textContent = cssText;
+if (styleExtends.hasExtends(style.textContent)) {
+cssText = styleExtends.transform(style);
+}
+styles.push(style);
+}
+return styles;
+},
+_elementAdd: function (node) {
+if (this._encapsulateStyle) {
+if (node.__styleScoped) {
+node.__styleScoped = false;
+} else {
+styleTransformer.dom(node, this.is, this._scopeCssViaAttr);
+}
+}
+},
+_elementRemove: function (node) {
+if (this._encapsulateStyle) {
+styleTransformer.dom(node, this.is, this._scopeCssViaAttr, true);
+}
+},
+scopeSubtree: function (container, shouldObserve) {
+if (nativeShadow) {
+return;
+}
+var self = this;
+var scopify = function (node) {
+if (node.nodeType === Node.ELEMENT_NODE) {
+node.className = self._scopeElementClass(node, node.className);
+var n$ = node.querySelectorAll('*');
+for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
+n.className = self._scopeElementClass(n, n.className);
+}
+}
+};
+scopify(container);
+if (shouldObserve) {
+var mo = new MutationObserver(function (mxns) {
+for (var i = 0, m; i < mxns.length && (m = mxns[i]); i++) {
+if (m.addedNodes) {
+for (var j = 0; j < m.addedNodes.length; j++) {
+scopify(m.addedNodes[j]);
+}
+}
+}
+});
+mo.observe(container, {
+childList: true,
+subtree: true
+});
+return mo;
+}
+}
+});
+}());
+Polymer.StyleProperties = function () {
+'use strict';
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var matchesSelector = Polymer.DomApi.matchesSelector;
+var styleUtil = Polymer.StyleUtil;
+var styleTransformer = Polymer.StyleTransformer;
+return {
+decorateStyles: function (styles) {
+var self = this, props = {};
+styleUtil.forRulesInStyles(styles, function (rule) {
+self.decorateRule(rule);
+self.collectPropertiesInCssText(rule.propertyInfo.cssText, props);
+});
+var names = [];
+for (var i in props) {
+names.push(i);
+}
+return names;
+},
+decorateRule: function (rule) {
+if (rule.propertyInfo) {
+return rule.propertyInfo;
+}
+var info = {}, properties = {};
+var hasProperties = this.collectProperties(rule, properties);
+if (hasProperties) {
+info.properties = properties;
+rule.rules = null;
+}
+info.cssText = this.collectCssText(rule);
+rule.propertyInfo = info;
+return info;
+},
+collectProperties: function (rule, properties) {
+var info = rule.propertyInfo;
+if (info) {
+if (info.properties) {
+Polymer.Base.mixin(properties, info.properties);
+return true;
+}
+} else {
+var m, rx = this.rx.VAR_ASSIGN;
+var cssText = rule.parsedCssText;
+var any;
+while (m = rx.exec(cssText)) {
+properties[m[1]] = (m[2] || m[3]).trim();
+any = true;
+}
+return any;
+}
+},
+collectCssText: function (rule) {
+var customCssText = '';
+var cssText = rule.parsedCssText;
+cssText = cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, '');
+var parts = cssText.split(';');
+for (var i = 0, p; i < parts.length; i++) {
+p = parts[i];
+if (p.match(this.rx.MIXIN_MATCH) || p.match(this.rx.VAR_MATCH)) {
+customCssText += p + ';\n';
+}
+}
+return customCssText;
+},
+collectPropertiesInCssText: function (cssText, props) {
+var m;
+while (m = this.rx.VAR_CAPTURE.exec(cssText)) {
+props[m[1]] = true;
+var def = m[2];
+if (def && def.match(this.rx.IS_VAR)) {
+props[def] = true;
+}
+}
+},
+reify: function (props) {
+var names = Object.getOwnPropertyNames(props);
+for (var i = 0, n; i < names.length; i++) {
+n = names[i];
+props[n] = this.valueForProperty(props[n], props);
+}
+},
+valueForProperty: function (property, props) {
+if (property) {
+if (property.indexOf(';') >= 0) {
+property = this.valueForProperties(property, props);
+} else {
+var self = this;
+var fn = function (all, prefix, value, fallback) {
+var propertyValue = self.valueForProperty(props[value], props) || (props[fallback] ? self.valueForProperty(props[fallback], props) : fallback);
+return prefix + (propertyValue || '');
+};
+property = property.replace(this.rx.VAR_MATCH, fn);
+}
+}
+return property && property.trim() || '';
+},
+valueForProperties: function (property, props) {
+var parts = property.split(';');
+for (var i = 0, p, m; i < parts.length; i++) {
+if (p = parts[i]) {
+m = p.match(this.rx.MIXIN_MATCH);
+if (m) {
+p = this.valueForProperty(props[m[1]], props);
+} else {
+var pp = p.split(':');
+if (pp[1]) {
+pp[1] = pp[1].trim();
+pp[1] = this.valueForProperty(pp[1], props) || pp[1];
+}
+p = pp.join(':');
+}
+parts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || '';
+}
+}
+return parts.filter(function (v) {
+return v;
+}).join(';');
+},
+applyProperties: function (rule, props) {
+var output = '';
+if (!rule.propertyInfo) {
+this.decorateRule(rule);
+}
+if (rule.propertyInfo.cssText) {
+output = this.valueForProperties(rule.propertyInfo.cssText, props);
+}
+rule.cssText = output;
+},
+propertyDataFromStyles: function (styles, element) {
+var props = {}, self = this;
+var o = [], i = 0;
+styleUtil.forRulesInStyles(styles, function (rule) {
+if (!rule.propertyInfo) {
+self.decorateRule(rule);
+}
+if (element && rule.propertyInfo.properties && matchesSelector.call(element, rule.transformedSelector || rule.parsedSelector)) {
+self.collectProperties(rule, props);
+addToBitMask(i, o);
+}
+i++;
+});
+return {
+properties: props,
+key: o
+};
+},
+scopePropertiesFromStyles: function (styles) {
+if (!styles._scopeStyleProperties) {
+styles._scopeStyleProperties = this.selectedPropertiesFromStyles(styles, this.SCOPE_SELECTORS);
+}
+return styles._scopeStyleProperties;
+},
+hostPropertiesFromStyles: function (styles) {
+if (!styles._hostStyleProperties) {
+styles._hostStyleProperties = this.selectedPropertiesFromStyles(styles, this.HOST_SELECTORS);
+}
+return styles._hostStyleProperties;
+},
+selectedPropertiesFromStyles: function (styles, selectors) {
+var props = {}, self = this;
+styleUtil.forRulesInStyles(styles, function (rule) {
+if (!rule.propertyInfo) {
+self.decorateRule(rule);
+}
+for (var i = 0; i < selectors.length; i++) {
+if (rule.parsedSelector === selectors[i]) {
+self.collectProperties(rule, props);
+return;
+}
+}
+});
+return props;
+},
+transformStyles: function (element, properties, scopeSelector) {
+var self = this;
+var hostSelector = styleTransformer._calcHostScope(element.is, element.extends);
+var rxHostSelector = element.extends ? '\\' + hostSelector.slice(0, -1) + '\\]' : hostSelector;
+var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFFIX);
+return styleTransformer.elementStyles(element, function (rule) {
+self.applyProperties(rule, properties);
+if (rule.cssText && !nativeShadow) {
+self._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeSelector);
+}
+});
+},
+_scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) {
+rule.transformedSelector = rule.transformedSelector || rule.selector;
+var selector = rule.transformedSelector;
+var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' + scopeId + ']' : '.' + scopeId;
+var parts = selector.split(',');
+for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
+parts[i] = p.match(hostRx) ? p.replace(hostSelector, hostSelector + scope) : scope + ' ' + p;
+}
+rule.selector = parts.join(',');
+},
+applyElementScopeSelector: function (element, selector, old, viaAttr) {
+var c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.className;
+var v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector;
+if (c !== v) {
+if (viaAttr) {
+element.setAttribute(styleTransformer.SCOPE_NAME, v);
+} else {
+element.className = v;
+}
+}
+},
+applyElementStyle: function (element, properties, selector, style) {
+var cssText = style ? style.textContent || '' : this.transformStyles(element, properties, selector);
+var s = element._customStyle;
+if (s && !nativeShadow && s !== style) {
+s._useCount--;
+if (s._useCount <= 0 && s.parentNode) {
+s.parentNode.removeChild(s);
+}
+}
+if (nativeShadow || (!style || !style.parentNode)) {
+if (nativeShadow && element._customStyle) {
+element._customStyle.textContent = cssText;
+style = element._customStyle;
+} else if (cssText) {
+style = styleUtil.applyCss(cssText, selector, nativeShadow ? element.root : null, element._scopeStyle);
+}
+}
+if (style) {
+style._useCount = style._useCount || 0;
+if (element._customStyle != style) {
+style._useCount++;
+}
+element._customStyle = style;
+}
+return style;
+},
+mixinCustomStyle: function (props, customStyle) {
+var v;
+for (var i in customStyle) {
+v = customStyle[i];
+if (v || v === 0) {
+props[i] = v;
+}
+}
+},
+rx: {
+VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi,
+MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\)/i,
+VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)))[\s]*?\)/gi,
+VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi,
+IS_VAR: /^--/,
+BRACKETED: /\{[^}]*\}/g,
+HOST_PREFIX: '(?:^|[^.#[:])',
+HOST_SUFFIX: '($|[.:[\\s>+~])'
+},
+HOST_SELECTORS: [':host'],
+SCOPE_SELECTORS: [':root'],
+XSCOPE_NAME: 'x-scope'
+};
+function addToBitMask(n, bits) {
+var o = parseInt(n / 32);
+var v = 1 << n % 32;
+bits[o] = (bits[o] || 0) | v;
+}
+}();
+(function () {
+Polymer.StyleCache = function () {
+this.cache = {};
+};
+Polymer.StyleCache.prototype = {
+MAX: 100,
+store: function (is, data, keyValues, keyStyles) {
+data.keyValues = keyValues;
+data.styles = keyStyles;
+var s$ = this.cache[is] = this.cache[is] || [];
+s$.push(data);
+if (s$.length > this.MAX) {
+s$.shift();
+}
+},
+retrieve: function (is, keyValues, keyStyles) {
+var cache = this.cache[is];
+if (cache) {
+for (var i = cache.length - 1, data; i >= 0; i--) {
+data = cache[i];
+if (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) {
+return data;
+}
+}
+}
+},
+clear: function () {
+this.cache = {};
+},
+_objectsEqual: function (target, source) {
+var t, s;
+for (var i in target) {
+t = target[i], s = source[i];
+if (!(typeof t === 'object' && t ? this._objectsStrictlyEqual(t, s) : t === s)) {
+return false;
+}
+}
+if (Array.isArray(target)) {
+return target.length === source.length;
+}
+return true;
+},
+_objectsStrictlyEqual: function (target, source) {
+return this._objectsEqual(target, source) && this._objectsEqual(source, target);
+}
+};
+}());
+Polymer.StyleDefaults = function () {
+var styleProperties = Polymer.StyleProperties;
+var styleUtil = Polymer.StyleUtil;
+var StyleCache = Polymer.StyleCache;
+var api = {
+_styles: [],
+_properties: null,
+customStyle: {},
+_styleCache: new StyleCache(),
+addStyle: function (style) {
+this._styles.push(style);
+this._properties = null;
+},
+get _styleProperties() {
+if (!this._properties) {
+styleProperties.decorateStyles(this._styles);
+this._styles._scopeStyleProperties = null;
+this._properties = styleProperties.scopePropertiesFromStyles(this._styles);
+styleProperties.mixinCustomStyle(this._properties, this.customStyle);
+styleProperties.reify(this._properties);
+}
+return this._properties;
+},
+_needsStyleProperties: function () {
+},
+_computeStyleProperties: function () {
+return this._styleProperties;
+},
+updateStyles: function (properties) {
+this._properties = null;
+if (properties) {
+Polymer.Base.mixin(this.customStyle, properties);
+}
+this._styleCache.clear();
+for (var i = 0, s; i < this._styles.length; i++) {
+s = this._styles[i];
+s = s.__importElement || s;
+s._apply();
+}
+}
+};
+return api;
+}();
+(function () {
+'use strict';
+var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute;
+var propertyUtils = Polymer.StyleProperties;
+var styleTransformer = Polymer.StyleTransformer;
+var styleUtil = Polymer.StyleUtil;
+var styleDefaults = Polymer.StyleDefaults;
+var nativeShadow = Polymer.Settings.useNativeShadow;
+Polymer.Base._addFeature({
+_prepStyleProperties: function () {
+this._ownStylePropertyNames = this._styles ? propertyUtils.decorateStyles(this._styles) : null;
+},
+customStyle: null,
+getComputedStyleValue: function (property) {
+return this._styleProperties && this._styleProperties[property] || getComputedStyle(this).getPropertyValue(property);
+},
+_setupStyleProperties: function () {
+this.customStyle = {};
+},
+_needsStyleProperties: function () {
+return Boolean(this._ownStylePropertyNames && this._ownStylePropertyNames.length);
+},
+_beforeAttached: function () {
+if (!this._scopeSelector && this._needsStyleProperties()) {
+this._updateStyleProperties();
+}
+},
+_findStyleHost: function () {
+var e = this, root;
+while (root = Polymer.dom(e).getOwnerRoot()) {
+if (Polymer.isInstance(root.host)) {
+return root.host;
+}
+e = root.host;
+}
+return styleDefaults;
+},
+_updateStyleProperties: function () {
+var info, scope = this._findStyleHost();
+if (!scope._styleCache) {
+scope._styleCache = new Polymer.StyleCache();
+}
+var scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this);
+scopeData.key.customStyle = this.customStyle;
+info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles);
+var scopeCached = Boolean(info);
+if (scopeCached) {
+this._styleProperties = info._styleProperties;
+} else {
+this._computeStyleProperties(scopeData.properties);
+}
+this._computeOwnStyleProperties();
+if (!scopeCached) {
+info = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles);
+}
+var globalCached = Boolean(info) && !scopeCached;
+var style = this._applyStyleProperties(info);
+if (!scopeCached) {
+style = style && nativeShadow ? style.cloneNode(true) : style;
+info = {
+style: style,
+_scopeSelector: this._scopeSelector,
+_styleProperties: this._styleProperties
+};
+scopeData.key.customStyle = {};
+this.mixin(scopeData.key.customStyle, this.customStyle);
+scope._styleCache.store(this.is, info, scopeData.key, this._styles);
+if (!globalCached) {
+styleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._styles);
+}
+}
+},
+_computeStyleProperties: function (scopeProps) {
+var scope = this._findStyleHost();
+if (!scope._styleProperties) {
+scope._computeStyleProperties();
+}
+var props = Object.create(scope._styleProperties);
+this.mixin(props, propertyUtils.hostPropertiesFromStyles(this._styles));
+scopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, this).properties;
+this.mixin(props, scopeProps);
+this.mixin(props, propertyUtils.scopePropertiesFromStyles(this._styles));
+propertyUtils.mixinCustomStyle(props, this.customStyle);
+propertyUtils.reify(props);
+this._styleProperties = props;
+},
+_computeOwnStyleProperties: function () {
+var props = {};
+for (var i = 0, n; i < this._ownStylePropertyNames.length; i++) {
+n = this._ownStylePropertyNames[i];
+props[n] = this._styleProperties[n];
+}
+this._ownStyleProperties = props;
+},
+_scopeCount: 0,
+_applyStyleProperties: function (info) {
+var oldScopeSelector = this._scopeSelector;
+this._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto__._scopeCount++;
+var style = propertyUtils.applyElementStyle(this, this._styleProperties, this._scopeSelector, info && info.style);
+if (!nativeShadow) {
+propertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelector, this._scopeCssViaAttr);
+}
+return style;
+},
+serializeValueToAttribute: function (value, attribute, node) {
+node = node || this;
+if (attribute === 'class' && !nativeShadow) {
+var host = node === this ? this.domHost || this.dataHost : this;
+if (host) {
+value = host._scopeElementClass(node, value);
+}
+}
+node = this.shadyRoot && this.shadyRoot._hasDistributed ? Polymer.dom(node) : node;
+serializeValueToAttribute.call(this, value, attribute, node);
+},
+_scopeElementClass: function (element, selector) {
+if (!nativeShadow && !this._scopeCssViaAttr) {
+selector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is + (element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : '');
+}
+return selector;
+},
+updateStyles: function (properties) {
+if (this.isAttached) {
+if (properties) {
+this.mixin(this.customStyle, properties);
+}
+if (this._needsStyleProperties()) {
+this._updateStyleProperties();
+} else {
+this._styleProperties = null;
+}
+if (this._styleCache) {
+this._styleCache.clear();
+}
+this._updateRootStyles();
+}
+},
+_updateRootStyles: function (root) {
+root = root || this.root;
+var c$ = Polymer.dom(root)._query(function (e) {
+return e.shadyRoot || e.shadowRoot;
+});
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+if (c.updateStyles) {
+c.updateStyles();
+}
+}
+}
+});
+Polymer.updateStyles = function (properties) {
+styleDefaults.updateStyles(properties);
+Polymer.Base._updateRootStyles(document);
+};
+var styleCache = new Polymer.StyleCache();
+Polymer.customStyleCache = styleCache;
+var SCOPE_NAME = styleTransformer.SCOPE_NAME;
+var XSCOPE_NAME = propertyUtils.XSCOPE_NAME;
+}());
+Polymer.Base._addFeature({
+_registerFeatures: function () {
+this._prepIs();
+this._prepConstructor();
+this._prepTemplate();
+this._prepStyles();
+this._prepStyleProperties();
+this._prepAnnotations();
+this._prepEffects();
+this._prepBehaviors();
+this._prepPropertyInfo();
+this._prepBindings();
+this._prepShady();
+},
+_prepBehavior: function (b) {
+this._addPropertyEffects(b.properties);
+this._addComplexObserverEffects(b.observers);
+this._addHostAttributes(b.hostAttributes);
+},
+_initFeatures: function () {
+this._setupConfigure();
+this._setupStyleProperties();
+this._setupDebouncers();
+this._registerHost();
+if (this._template) {
+this._poolContent();
+this._beginHosting();
+this._stampTemplate();
+this._endHosting();
+this._marshalAnnotationReferences();
+}
+this._marshalInstanceEffects();
+this._marshalBehaviors();
+this._marshalHostAttributes();
+this._marshalAttributes();
+this._tryReady();
+},
+_marshalBehavior: function (b) {
+if (b.listeners) {
+this._listenListeners(b.listeners);
+}
+}
+});
+(function () {
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var propertyUtils = Polymer.StyleProperties;
+var styleUtil = Polymer.StyleUtil;
+var cssParse = Polymer.CssParse;
+var styleDefaults = Polymer.StyleDefaults;
+var styleTransformer = Polymer.StyleTransformer;
+Polymer({
+is: 'custom-style',
+extends: 'style',
+_template: null,
+properties: { include: String },
+ready: function () {
+this._tryApply();
+},
+attached: function () {
+this._tryApply();
+},
+_tryApply: function () {
+if (!this._appliesToDocument) {
+if (this.parentNode && this.parentNode.localName !== 'dom-module') {
+this._appliesToDocument = true;
+var e = this.__appliedElement || this;
+styleDefaults.addStyle(e);
+if (e.textContent || this.include) {
+this._apply(true);
+} else {
+var self = this;
+var observer = new MutationObserver(function () {
+observer.disconnect();
+self._apply(true);
+});
+observer.observe(e, { childList: true });
+}
+}
+}
+},
+_apply: function (deferProperties) {
+var e = this.__appliedElement || this;
+if (this.include) {
+e.textContent = styleUtil.cssFromModules(this.include, true) + e.textContent;
+}
+if (e.textContent) {
+styleUtil.forEachStyleRule(styleUtil.rulesForStyle(e), function (rule) {
+styleTransformer.documentRule(rule);
+});
+var self = this;
+function fn() {
+self._applyCustomProperties(e);
+}
+if (this._pendingApplyProperties) {
+cancelAnimationFrame(this._pendingApplyProperties);
+this._pendingApplyProperties = null;
+}
+if (deferProperties) {
+this._pendingApplyProperties = requestAnimationFrame(fn);
+} else {
+fn();
+}
+}
+},
+_applyCustomProperties: function (element) {
+this._computeStyleProperties();
+var props = this._styleProperties;
+var rules = styleUtil.rulesForStyle(element);
+element.textContent = styleUtil.toCssText(rules, function (rule) {
+var css = rule.cssText = rule.parsedCssText;
+if (rule.propertyInfo && rule.propertyInfo.cssText) {
+css = cssParse.removeCustomPropAssignment(css);
+rule.cssText = propertyUtils.valueForProperties(css, props);
+}
+});
+}
+});
+}());
+Polymer.Templatizer = {
+properties: { __hideTemplateChildren__: { observer: '_showHideChildren' } },
+_instanceProps: Polymer.nob,
+_parentPropPrefix: '_parent_',
+templatize: function (template) {
+this._templatized = template;
+if (!template._content) {
+template._content = template.content;
+}
+if (template._content._ctor) {
+this.ctor = template._content._ctor;
+this._prepParentProperties(this.ctor.prototype, template);
+return;
+}
+var archetype = Object.create(Polymer.Base);
+this._customPrepAnnotations(archetype, template);
+this._prepParentProperties(archetype, template);
+archetype._prepEffects();
+this._customPrepEffects(archetype);
+archetype._prepBehaviors();
+archetype._prepPropertyInfo();
+archetype._prepBindings();
+archetype._notifyPathUp = this._notifyPathUpImpl;
+archetype._scopeElementClass = this._scopeElementClassImpl;
+archetype.listen = this._listenImpl;
+archetype._showHideChildren = this._showHideChildrenImpl;
+var _constructor = this._constructorImpl;
+var ctor = function TemplateInstance(model, host) {
+_constructor.call(this, model, host);
+};
+ctor.prototype = archetype;
+archetype.constructor = ctor;
+template._content._ctor = ctor;
+this.ctor = ctor;
+},
+_getRootDataHost: function () {
+return this.dataHost && this.dataHost._rootDataHost || this.dataHost;
+},
+_showHideChildrenImpl: function (hide) {
+var c = this._children;
+for (var i = 0; i < c.length; i++) {
+var n = c[i];
+if (Boolean(hide) != Boolean(n.__hideTemplateChildren__)) {
+if (n.nodeType === Node.TEXT_NODE) {
+if (hide) {
+n.__polymerTextContent__ = n.textContent;
+n.textContent = '';
+} else {
+n.textContent = n.__polymerTextContent__;
+}
+} else if (n.style) {
+if (hide) {
+n.__polymerDisplay__ = n.style.display;
+n.style.display = 'none';
+} else {
+n.style.display = n.__polymerDisplay__;
+}
+}
+}
+n.__hideTemplateChildren__ = hide;
+}
+},
+_debounceTemplate: function (fn) {
+Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', fn));
+},
+_flushTemplates: function (debouncerExpired) {
+Polymer.dom.flush();
+},
+_customPrepEffects: function (archetype) {
+var parentProps = archetype._parentProps;
+for (var prop in parentProps) {
+archetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop));
+}
+for (var prop in this._instanceProps) {
+archetype._addPropertyEffect(prop, 'function', this._createInstancePropEffector(prop));
+}
+},
+_customPrepAnnotations: function (archetype, template) {
+archetype._template = template;
+var c = template._content;
+if (!c._notes) {
+var rootDataHost = archetype._rootDataHost;
+if (rootDataHost) {
+Polymer.Annotations.prepElement = function () {
+rootDataHost._prepElement();
+};
+}
+c._notes = Polymer.Annotations.parseAnnotations(template);
+Polymer.Annotations.prepElement = null;
+this._processAnnotations(c._notes);
+}
+archetype._notes = c._notes;
+archetype._parentProps = c._parentProps;
+},
+_prepParentProperties: function (archetype, template) {
+var parentProps = this._parentProps = archetype._parentProps;
+if (this._forwardParentProp && parentProps) {
+var proto = archetype._parentPropProto;
+var prop;
+if (!proto) {
+for (prop in this._instanceProps) {
+delete parentProps[prop];
+}
+proto = archetype._parentPropProto = Object.create(null);
+if (template != this) {
+Polymer.Bind.prepareModel(proto);
+Polymer.Base.prepareModelNotifyPath(proto);
+}
+for (prop in parentProps) {
+var parentProp = this._parentPropPrefix + prop;
+var effects = [
+{
+kind: 'function',
+effect: this._createForwardPropEffector(prop),
+fn: Polymer.Bind._functionEffect
+},
+{
+kind: 'notify',
+fn: Polymer.Bind._notifyEffect,
+effect: { event: Polymer.CaseMap.camelToDashCase(parentProp) + '-changed' }
+}
+];
+Polymer.Bind._createAccessors(proto, parentProp, effects);
+}
+}
+var self = this;
+if (template != this) {
+Polymer.Bind.prepareInstance(template);
+template._forwardParentProp = function (source, value) {
+self._forwardParentProp(source, value);
+};
+}
+this._extendTemplate(template, proto);
+template._pathEffector = function (path, value, fromAbove) {
+return self._pathEffectorImpl(path, value, fromAbove);
+};
+}
+},
+_createForwardPropEffector: function (prop) {
+return function (source, value) {
+this._forwardParentProp(prop, value);
+};
+},
+_createHostPropEffector: function (prop) {
+var prefix = this._parentPropPrefix;
+return function (source, value) {
+this.dataHost._templatized[prefix + prop] = value;
+};
+},
+_createInstancePropEffector: function (prop) {
+return function (source, value, old, fromAbove) {
+if (!fromAbove) {
+this.dataHost._forwardInstanceProp(this, prop, value);
+}
+};
+},
+_extendTemplate: function (template, proto) {
+var n$ = Object.getOwnPropertyNames(proto);
+for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
+var val = template[n];
+var pd = Object.getOwnPropertyDescriptor(proto, n);
+Object.defineProperty(template, n, pd);
+if (val !== undefined) {
+template._propertySetter(n, val);
+}
+}
+},
+_showHideChildren: function (hidden) {
+},
+_forwardInstancePath: function (inst, path, value) {
+},
+_forwardInstanceProp: function (inst, prop, value) {
+},
+_notifyPathUpImpl: function (path, value) {
+var dataHost = this.dataHost;
+var dot = path.indexOf('.');
+var root = dot < 0 ? path : path.slice(0, dot);
+dataHost._forwardInstancePath.call(dataHost, this, path, value);
+if (root in dataHost._parentProps) {
+dataHost._templatized.notifyPath(dataHost._parentPropPrefix + path, value);
+}
+},
+_pathEffectorImpl: function (path, value, fromAbove) {
+if (this._forwardParentPath) {
+if (path.indexOf(this._parentPropPrefix) === 0) {
+var subPath = path.substring(this._parentPropPrefix.length);
+var model = this._modelForPath(subPath);
+if (model in this._parentProps) {
+this._forwardParentPath(subPath, value);
+}
+}
+}
+Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove);
+},
+_constructorImpl: function (model, host) {
+this._rootDataHost = host._getRootDataHost();
+this._setupConfigure(model);
+this._registerHost(host);
+this._beginHosting();
+this.root = this.instanceTemplate(this._template);
+this.root.__noContent = !this._notes._hasContent;
+this.root.__styleScoped = true;
+this._endHosting();
+this._marshalAnnotatedNodes();
+this._marshalInstanceEffects();
+this._marshalAnnotatedListeners();
+var children = [];
+for (var n = this.root.firstChild; n; n = n.nextSibling) {
+children.push(n);
+n._templateInstance = this;
+}
+this._children = children;
+if (host.__hideTemplateChildren__) {
+this._showHideChildren(true);
+}
+this._tryReady();
+},
+_listenImpl: function (node, eventName, methodName) {
+var model = this;
+var host = this._rootDataHost;
+var handler = host._createEventHandler(node, eventName, methodName);
+var decorated = function (e) {
+e.model = model;
+handler(e);
+};
+host._listen(node, eventName, decorated);
+},
+_scopeElementClassImpl: function (node, value) {
+var host = this._rootDataHost;
+if (host) {
+return host._scopeElementClass(node, value);
+}
+},
+stamp: function (model) {
+model = model || {};
+if (this._parentProps) {
+var templatized = this._templatized;
+for (var prop in this._parentProps) {
+model[prop] = templatized[this._parentPropPrefix + prop];
+}
+}
+return new this.ctor(model, this);
+},
+modelForElement: function (el) {
+var model;
+while (el) {
+if (model = el._templateInstance) {
+if (model.dataHost != this) {
+el = model.dataHost;
+} else {
+return model;
+}
+} else {
+el = el.parentNode;
+}
+}
+}
+};
+Polymer({
+is: 'dom-template',
+extends: 'template',
+_template: null,
+behaviors: [Polymer.Templatizer],
+ready: function () {
+this.templatize(this);
+}
+});
+Polymer._collections = new WeakMap();
+Polymer.Collection = function (userArray) {
+Polymer._collections.set(userArray, this);
+this.userArray = userArray;
+this.store = userArray.slice();
+this.initMap();
+};
+Polymer.Collection.prototype = {
+constructor: Polymer.Collection,
+initMap: function () {
+var omap = this.omap = new WeakMap();
+var pmap = this.pmap = {};
+var s = this.store;
+for (var i = 0; i < s.length; i++) {
+var item = s[i];
+if (item && typeof item == 'object') {
+omap.set(item, i);
+} else {
+pmap[item] = i;
+}
+}
+},
+add: function (item) {
+var key = this.store.push(item) - 1;
+if (item && typeof item == 'object') {
+this.omap.set(item, key);
+} else {
+this.pmap[item] = key;
+}
+return '#' + key;
+},
+removeKey: function (key) {
+key = this._parseKey(key);
+this._removeFromMap(this.store[key]);
+delete this.store[key];
+},
+_removeFromMap: function (item) {
+if (item && typeof item == 'object') {
+this.omap.delete(item);
+} else {
+delete this.pmap[item];
+}
+},
+remove: function (item) {
+var key = this.getKey(item);
+this.removeKey(key);
+return key;
+},
+getKey: function (item) {
+var key;
+if (item && typeof item == 'object') {
+key = this.omap.get(item);
+} else {
+key = this.pmap[item];
+}
+if (key != undefined) {
+return '#' + key;
+}
+},
+getKeys: function () {
+return Object.keys(this.store).map(function (key) {
+return '#' + key;
+});
+},
+_parseKey: function (key) {
+if (key[0] == '#') {
+return key.slice(1);
+}
+throw new Error('unexpected key ' + key);
+},
+setItem: function (key, item) {
+key = this._parseKey(key);
+var old = this.store[key];
+if (old) {
+this._removeFromMap(old);
+}
+if (item && typeof item == 'object') {
+this.omap.set(item, key);
+} else {
+this.pmap[item] = key;
+}
+this.store[key] = item;
+},
+getItem: function (key) {
+key = this._parseKey(key);
+return this.store[key];
+},
+getItems: function () {
+var items = [], store = this.store;
+for (var key in store) {
+items.push(store[key]);
+}
+return items;
+},
+_applySplices: function (splices) {
+var keyMap = {}, key;
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+s.addedKeys = [];
+for (var j = 0; j < s.removed.length; j++) {
+key = this.getKey(s.removed[j]);
+keyMap[key] = keyMap[key] ? null : -1;
+}
+for (var j = 0; j < s.addedCount; j++) {
+var item = this.userArray[s.index + j];
+key = this.getKey(item);
+key = key === undefined ? this.add(item) : key;
+keyMap[key] = keyMap[key] ? null : 1;
+s.addedKeys.push(key);
+}
+}
+var removed = [];
+var added = [];
+for (var key in keyMap) {
+if (keyMap[key] < 0) {
+this.removeKey(key);
+removed.push(key);
+}
+if (keyMap[key] > 0) {
+added.push(key);
+}
+}
+return [{
+removed: removed,
+added: added
+}];
+}
+};
+Polymer.Collection.get = function (userArray) {
+return Polymer._collections.get(userArray) || new Polymer.Collection(userArray);
+};
+Polymer.Collection.applySplices = function (userArray, splices) {
+var coll = Polymer._collections.get(userArray);
+return coll ? coll._applySplices(splices) : null;
+};
+Polymer({
+is: 'dom-repeat',
+extends: 'template',
+_template: null,
+properties: {
+items: { type: Array },
+as: {
+type: String,
+value: 'item'
+},
+indexAs: {
+type: String,
+value: 'index'
+},
+sort: {
+type: Function,
+observer: '_sortChanged'
+},
+filter: {
+type: Function,
+observer: '_filterChanged'
+},
+observe: {
+type: String,
+observer: '_observeChanged'
+},
+delay: Number,
+initialCount: {
+type: Number,
+observer: '_initializeChunking'
+},
+targetFramerate: {
+type: Number,
+value: 20
+},
+_targetFrameTime: { computed: '_computeFrameTime(targetFramerate)' }
+},
+behaviors: [Polymer.Templatizer],
+observers: ['_itemsChanged(items.*)'],
+created: function () {
+this._instances = [];
+this._pool = [];
+this._limit = Infinity;
+var self = this;
+this._boundRenderChunk = function () {
+self._renderChunk();
+};
+},
+detached: function () {
+for (var i = 0; i < this._instances.length; i++) {
+this._detachInstance(i);
+}
+},
+attached: function () {
+var parent = Polymer.dom(Polymer.dom(this).parentNode);
+for (var i = 0; i < this._instances.length; i++) {
+this._attachInstance(i, parent);
+}
+},
+ready: function () {
+this._instanceProps = { __key__: true };
+this._instanceProps[this.as] = true;
+this._instanceProps[this.indexAs] = true;
+if (!this.ctor) {
+this.templatize(this);
+}
+},
+_sortChanged: function (sort) {
+var dataHost = this._getRootDataHost();
+this._sortFn = sort && (typeof sort == 'function' ? sort : function () {
+return dataHost[sort].apply(dataHost, arguments);
+});
+this._needFullRefresh = true;
+if (this.items) {
+this._debounceTemplate(this._render);
+}
+},
+_filterChanged: function (filter) {
+var dataHost = this._getRootDataHost();
+this._filterFn = filter && (typeof filter == 'function' ? filter : function () {
+return dataHost[filter].apply(dataHost, arguments);
+});
+this._needFullRefresh = true;
+if (this.items) {
+this._debounceTemplate(this._render);
+}
+},
+_computeFrameTime: function (rate) {
+return Math.ceil(1000 / rate);
+},
+_initializeChunking: function () {
+if (this.initialCount) {
+this._limit = this.initialCount;
+this._chunkCount = this.initialCount;
+this._lastChunkTime = performance.now();
+}
+},
+_tryRenderChunk: function () {
+if (this.items && this._limit < this.items.length) {
+this.debounce('renderChunk', this._requestRenderChunk);
+}
+},
+_requestRenderChunk: function () {
+requestAnimationFrame(this._boundRenderChunk);
+},
+_renderChunk: function () {
+var currChunkTime = performance.now();
+var ratio = this._targetFrameTime / (currChunkTime - this._lastChunkTime);
+this._chunkCount = Math.round(this._chunkCount * ratio) || 1;
+this._limit += this._chunkCount;
+this._lastChunkTime = currChunkTime;
+this._debounceTemplate(this._render);
+},
+_observeChanged: function () {
+this._observePaths = this.observe && this.observe.replace('.*', '.').split(' ');
+},
+_itemsChanged: function (change) {
+if (change.path == 'items') {
+if (Array.isArray(this.items)) {
+this.collection = Polymer.Collection.get(this.items);
+} else if (!this.items) {
+this.collection = null;
+} else {
+this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', this.items));
+}
+this._keySplices = [];
+this._indexSplices = [];
+this._needFullRefresh = true;
+this._initializeChunking();
+this._debounceTemplate(this._render);
+} else if (change.path == 'items.splices') {
+this._keySplices = this._keySplices.concat(change.value.keySplices);
+this._indexSplices = this._indexSplices.concat(change.value.indexSplices);
+this._debounceTemplate(this._render);
+} else {
+var subpath = change.path.slice(6);
+this._forwardItemPath(subpath, change.value);
+this._checkObservedPaths(subpath);
+}
+},
+_checkObservedPaths: function (path) {
+if (this._observePaths) {
+path = path.substring(path.indexOf('.') + 1);
+var paths = this._observePaths;
+for (var i = 0; i < paths.length; i++) {
+if (path.indexOf(paths[i]) === 0) {
+this._needFullRefresh = true;
+if (this.delay) {
+this.debounce('render', this._render, this.delay);
+} else {
+this._debounceTemplate(this._render);
+}
+return;
+}
+}
+}
+},
+render: function () {
+this._needFullRefresh = true;
+this._debounceTemplate(this._render);
+this._flushTemplates();
+},
+_render: function () {
+var c = this.collection;
+if (this._needFullRefresh) {
+this._applyFullRefresh();
+this._needFullRefresh = false;
+} else if (this._keySplices.length) {
+if (this._sortFn) {
+this._applySplicesUserSort(this._keySplices);
+} else {
+if (this._filterFn) {
+this._applyFullRefresh();
+} else {
+this._applySplicesArrayOrder(this._indexSplices);
+}
+}
+} else {
+}
+this._keySplices = [];
+this._indexSplices = [];
+var keyToIdx = this._keyToInstIdx = {};
+for (var i = this._instances.length - 1; i >= 0; i--) {
+var inst = this._instances[i];
+if (inst.isPlaceholder && i < this._limit) {
+inst = this._insertInstance(i, inst.__key__);
+} else if (!inst.isPlaceholder && i >= this._limit) {
+inst = this._downgradeInstance(i, inst.__key__);
+}
+keyToIdx[inst.__key__] = i;
+if (!inst.isPlaceholder) {
+inst.__setProperty(this.indexAs, i, true);
+}
+}
+this._pool.length = 0;
+this.fire('dom-change');
+this._tryRenderChunk();
+},
+_applyFullRefresh: function () {
+var c = this.collection;
+var keys;
+if (this._sortFn) {
+keys = c ? c.getKeys() : [];
+} else {
+keys = [];
+var items = this.items;
+if (items) {
+for (var i = 0; i < items.length; i++) {
+keys.push(c.getKey(items[i]));
+}
+}
+}
+var self = this;
+if (this._filterFn) {
+keys = keys.filter(function (a) {
+return self._filterFn(c.getItem(a));
+});
+}
+if (this._sortFn) {
+keys.sort(function (a, b) {
+return self._sortFn(c.getItem(a), c.getItem(b));
+});
+}
+for (var i = 0; i < keys.length; i++) {
+var key = keys[i];
+var inst = this._instances[i];
+if (inst) {
+inst.__key__ = key;
+if (!inst.isPlaceholder && i < this._limit) {
+inst.__setProperty(this.as, c.getItem(key), true);
+}
+} else if (i < this._limit) {
+this._insertInstance(i, key);
+} else {
+this._insertPlaceholder(i, key);
+}
+}
+for (var j = this._instances.length - 1; j >= i; j--) {
+this._detachAndRemoveInstance(j);
+}
+},
+_numericSort: function (a, b) {
+return a - b;
+},
+_applySplicesUserSort: function (splices) {
+var c = this.collection;
+var instances = this._instances;
+var keyMap = {};
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = 0; j < s.removed.length; j++) {
+var key = s.removed[j];
+keyMap[key] = keyMap[key] ? null : -1;
+}
+for (var j = 0; j < s.added.length; j++) {
+var key = s.added[j];
+keyMap[key] = keyMap[key] ? null : 1;
+}
+}
+var removedIdxs = [];
+var addedKeys = [];
+for (var key in keyMap) {
+if (keyMap[key] === -1) {
+removedIdxs.push(this._keyToInstIdx[key]);
+}
+if (keyMap[key] === 1) {
+addedKeys.push(key);
+}
+}
+if (removedIdxs.length) {
+removedIdxs.sort(this._numericSort);
+for (var i = removedIdxs.length - 1; i >= 0; i--) {
+var idx = removedIdxs[i];
+if (idx !== undefined) {
+this._detachAndRemoveInstance(idx);
+}
+}
+}
+var self = this;
+if (addedKeys.length) {
+if (this._filterFn) {
+addedKeys = addedKeys.filter(function (a) {
+return self._filterFn(c.getItem(a));
+});
+}
+addedKeys.sort(function (a, b) {
+return self._sortFn(c.getItem(a), c.getItem(b));
+});
+var start = 0;
+for (var i = 0; i < addedKeys.length; i++) {
+start = this._insertRowUserSort(start, addedKeys[i]);
+}
+}
+},
+_insertRowUserSort: function (start, key) {
+var c = this.collection;
+var item = c.getItem(key);
+var end = this._instances.length - 1;
+var idx = -1;
+while (start <= end) {
+var mid = start + end >> 1;
+var midKey = this._instances[mid].__key__;
+var cmp = this._sortFn(c.getItem(midKey), item);
+if (cmp < 0) {
+start = mid + 1;
+} else if (cmp > 0) {
+end = mid - 1;
+} else {
+idx = mid;
+break;
+}
+}
+if (idx < 0) {
+idx = end + 1;
+}
+this._insertPlaceholder(idx, key);
+return idx;
+},
+_applySplicesArrayOrder: function (splices) {
+var c = this.collection;
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = 0; j < s.removed.length; j++) {
+this._detachAndRemoveInstance(s.index);
+}
+for (var j = 0; j < s.addedKeys.length; j++) {
+this._insertPlaceholder(s.index + j, s.addedKeys[j]);
+}
+}
+},
+_detachInstance: function (idx) {
+var inst = this._instances[idx];
+if (!inst.isPlaceholder) {
+for (var i = 0; i < inst._children.length; i++) {
+var el = inst._children[i];
+Polymer.dom(inst.root).appendChild(el);
+}
+return inst;
+}
+},
+_attachInstance: function (idx, parent) {
+var inst = this._instances[idx];
+if (!inst.isPlaceholder) {
+parent.insertBefore(inst.root, this);
+}
+},
+_detachAndRemoveInstance: function (idx) {
+var inst = this._detachInstance(idx);
+if (inst) {
+this._pool.push(inst);
+}
+this._instances.splice(idx, 1);
+},
+_insertPlaceholder: function (idx, key) {
+this._instances.splice(idx, 0, {
+isPlaceholder: true,
+__key__: key
+});
+},
+_stampInstance: function (idx, key) {
+var model = { __key__: key };
+model[this.as] = this.collection.getItem(key);
+model[this.indexAs] = idx;
+return this.stamp(model);
+},
+_insertInstance: function (idx, key) {
+var inst = this._pool.pop();
+if (inst) {
+inst.__setProperty(this.as, this.collection.getItem(key), true);
+inst.__setProperty('__key__', key, true);
+} else {
+inst = this._stampInstance(idx, key);
+}
+var beforeRow = this._instances[idx + 1];
+var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this;
+var parentNode = Polymer.dom(this).parentNode;
+Polymer.dom(parentNode).insertBefore(inst.root, beforeNode);
+this._instances[idx] = inst;
+return inst;
+},
+_downgradeInstance: function (idx, key) {
+var inst = this._detachInstance(idx);
+if (inst) {
+this._pool.push(inst);
+}
+inst = {
+isPlaceholder: true,
+__key__: key
+};
+this._instances[idx] = inst;
+return inst;
+},
+_showHideChildren: function (hidden) {
+for (var i = 0; i < this._instances.length; i++) {
+this._instances[i]._showHideChildren(hidden);
+}
+},
+_forwardInstanceProp: function (inst, prop, value) {
+if (prop == this.as) {
+var idx;
+if (this._sortFn || this._filterFn) {
+idx = this.items.indexOf(this.collection.getItem(inst.__key__));
+} else {
+idx = inst[this.indexAs];
+}
+this.set('items.' + idx, value);
+}
+},
+_forwardInstancePath: function (inst, path, value) {
+if (path.indexOf(this.as + '.') === 0) {
+this._notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value);
+}
+},
+_forwardParentProp: function (prop, value) {
+var i$ = this._instances;
+for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) {
+if (!inst.isPlaceholder) {
+inst.__setProperty(prop, value, true);
+}
+}
+},
+_forwardParentPath: function (path, value) {
+var i$ = this._instances;
+for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) {
+if (!inst.isPlaceholder) {
+inst._notifyPath(path, value, true);
+}
+}
+},
+_forwardItemPath: function (path, value) {
+if (this._keyToInstIdx) {
+var dot = path.indexOf('.');
+var key = path.substring(0, dot < 0 ? path.length : dot);
+var idx = this._keyToInstIdx[key];
+var inst = this._instances[idx];
+if (inst && !inst.isPlaceholder) {
+if (dot >= 0) {
+path = this.as + '.' + path.substring(dot + 1);
+inst._notifyPath(path, value, true);
+} else {
+inst.__setProperty(this.as, value, true);
+}
+}
+}
+},
+itemForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance[this.as];
+},
+keyForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance.__key__;
+},
+indexForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance[this.indexAs];
+}
+});
+Polymer({
+is: 'array-selector',
+_template: null,
+properties: {
+items: {
+type: Array,
+observer: 'clearSelection'
+},
+multi: {
+type: Boolean,
+value: false,
+observer: 'clearSelection'
+},
+selected: {
+type: Object,
+notify: true
+},
+selectedItem: {
+type: Object,
+notify: true
+},
+toggle: {
+type: Boolean,
+value: false
+}
+},
+clearSelection: function () {
+if (Array.isArray(this.selected)) {
+for (var i = 0; i < this.selected.length; i++) {
+this.unlinkPaths('selected.' + i);
+}
+} else {
+this.unlinkPaths('selected');
+this.unlinkPaths('selectedItem');
+}
+if (this.multi) {
+if (!this.selected || this.selected.length) {
+this.selected = [];
+this._selectedColl = Polymer.Collection.get(this.selected);
+}
+} else {
+this.selected = null;
+this._selectedColl = null;
+}
+this.selectedItem = null;
+},
+isSelected: function (item) {
+if (this.multi) {
+return this._selectedColl.getKey(item) !== undefined;
+} else {
+return this.selected == item;
+}
+},
+deselect: function (item) {
+if (this.multi) {
+if (this.isSelected(item)) {
+var skey = this._selectedColl.getKey(item);
+this.arrayDelete('selected', item);
+this.unlinkPaths('selected.' + skey);
+}
+} else {
+this.selected = null;
+this.selectedItem = null;
+this.unlinkPaths('selected');
+this.unlinkPaths('selectedItem');
+}
+},
+select: function (item) {
+var icol = Polymer.Collection.get(this.items);
+var key = icol.getKey(item);
+if (this.multi) {
+if (this.isSelected(item)) {
+if (this.toggle) {
+this.deselect(item);
+}
+} else {
+this.push('selected', item);
+var skey = this._selectedColl.getKey(item);
+this.linkPaths('selected.' + skey, 'items.' + key);
+}
+} else {
+if (this.toggle && item == this.selected) {
+this.deselect();
+} else {
+this.selected = item;
+this.selectedItem = item;
+this.linkPaths('selected', 'items.' + key);
+this.linkPaths('selectedItem', 'items.' + key);
+}
+}
+}
+});
+Polymer({
+is: 'dom-if',
+extends: 'template',
+_template: null,
+properties: {
+'if': {
+type: Boolean,
+value: false,
+observer: '_queueRender'
+},
+restamp: {
+type: Boolean,
+value: false,
+observer: '_queueRender'
+}
+},
+behaviors: [Polymer.Templatizer],
+_queueRender: function () {
+this._debounceTemplate(this._render);
+},
+detached: function () {
+this._teardownInstance();
+},
+attached: function () {
+if (this.if && this.ctor) {
+this.async(this._ensureInstance);
+}
+},
+render: function () {
+this._flushTemplates();
+},
+_render: function () {
+if (this.if) {
+if (!this.ctor) {
+this.templatize(this);
+}
+this._ensureInstance();
+this._showHideChildren();
+} else if (this.restamp) {
+this._teardownInstance();
+}
+if (!this.restamp && this._instance) {
+this._showHideChildren();
+}
+if (this.if != this._lastIf) {
+this.fire('dom-change');
+this._lastIf = this.if;
+}
+},
+_ensureInstance: function () {
+if (!this._instance) {
+var parentNode = Polymer.dom(this).parentNode;
+if (parentNode) {
+var parent = Polymer.dom(parentNode);
+this._instance = this.stamp();
+var root = this._instance.root;
+parent.insertBefore(root, this);
+}
+}
+},
+_teardownInstance: function () {
+if (this._instance) {
+var c$ = this._instance._children;
+if (c$) {
+var parent = Polymer.dom(Polymer.dom(c$[0]).parentNode);
+for (var i = 0, n; i < c$.length && (n = c$[i]); i++) {
+parent.removeChild(n);
+}
+}
+this._instance = null;
+}
+},
+_showHideChildren: function () {
+var hidden = this.__hideTemplateChildren__ || !this.if;
+if (this._instance) {
+this._instance._showHideChildren(hidden);
+}
+},
+_forwardParentProp: function (prop, value) {
+if (this._instance) {
+this._instance[prop] = value;
+}
+},
+_forwardParentPath: function (path, value) {
+if (this._instance) {
+this._instance._notifyPath(path, value, true);
+}
+}
+});
+Polymer({
+is: 'dom-bind',
+extends: 'template',
+_template: null,
+created: function () {
+var self = this;
+Polymer.RenderStatus.whenReady(function () {
+self._markImportsReady();
+});
+},
+_ensureReady: function () {
+if (!this._readied) {
+this._readySelf();
+}
+},
+_markImportsReady: function () {
+this._importsReady = true;
+this._ensureReady();
+},
+_registerFeatures: function () {
+this._prepConstructor();
+},
+_insertChildren: function () {
+var parentDom = Polymer.dom(Polymer.dom(this).parentNode);
+parentDom.insertBefore(this.root, this);
+},
+_removeChildren: function () {
+if (this._children) {
+for (var i = 0; i < this._children.length; i++) {
+this.root.appendChild(this._children[i]);
+}
+}
+},
+_initFeatures: function () {
+},
+_scopeElementClass: function (element, selector) {
+if (this.dataHost) {
+return this.dataHost._scopeElementClass(element, selector);
+} else {
+return selector;
+}
+},
+_prepConfigure: function () {
+var config = {};
+for (var prop in this._propertyEffects) {
+config[prop] = this[prop];
+}
+var setupConfigure = this._setupConfigure;
+this._setupConfigure = function () {
+setupConfigure.call(this, config);
+};
+},
+attached: function () {
+if (this._importsReady) {
+this.render();
+}
+},
+detached: function () {
+this._removeChildren();
+},
+render: function () {
+this._ensureReady();
+if (!this._children) {
+this._template = this;
+this._prepAnnotations();
+this._prepEffects();
+this._prepBehaviors();
+this._prepConfigure();
+this._prepBindings();
+this._prepPropertyInfo();
+Polymer.Base._initFeatures.call(this);
+this._children = Polymer.DomApi.arrayCopyChildNodes(this.root);
+}
+this._insertChildren();
+this.fire('dom-change');
+}
+});
+/**
+ * `IronResizableBehavior` is a behavior that can be used in Polymer elements to
+ * coordinate the flow of resize events between "resizers" (elements that control the
+ * size or hidden state of their children) and "resizables" (elements that need to be
+ * notified when they are resized or un-hidden by their parents in order to take
+ * action on their new measurements).
+ * Elements that perform measurement should add the `IronResizableBehavior` behavior to
+ * their element definition and listen for the `iron-resize` event on themselves.
+ * This event will be fired when they become showing after having been hidden,
+ * when they are resized explicitly by another resizable, or when the window has been
+ * resized.
+ * Note, the `iron-resize` event is non-bubbling.
+ *
+ * @polymerBehavior Polymer.IronResizableBehavior
+ * @demo demo/index.html
+ **/
+ Polymer.IronResizableBehavior = {
+ properties: {
+ /**
+ * The closest ancestor element that implements `IronResizableBehavior`.
+ */
+ _parentResizable: {
+ type: Object,
+ observer: '_parentResizableChanged'
+ },
+
+ /**
+ * True if this element is currently notifying its descedant elements of
+ * resize.
+ */
+ _notifyingDescendant: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ listeners: {
+ 'iron-request-resize-notifications': '_onIronRequestResizeNotifications'
+ },
+
+ created: function() {
+ // We don't really need property effects on these, and also we want them
+ // to be created before the `_parentResizable` observer fires:
+ this._interestedResizables = [];
+ this._boundNotifyResize = this.notifyResize.bind(this);
+ },
+
+ attached: function() {
+ this.fire('iron-request-resize-notifications', null, {
+ node: this,
+ bubbles: true,
+ cancelable: true
+ });
+
+ if (!this._parentResizable) {
+ window.addEventListener('resize', this._boundNotifyResize);
+ this.notifyResize();
+ }
+ },
+
+ detached: function() {
+ if (this._parentResizable) {
+ this._parentResizable.stopResizeNotificationsFor(this);
+ } else {
+ window.removeEventListener('resize', this._boundNotifyResize);
+ }
+
+ this._parentResizable = null;
+ },
+
+ /**
+ * Can be called to manually notify a resizable and its descendant
+ * resizables of a resize change.
+ */
+ notifyResize: function() {
+ if (!this.isAttached) {
+ return;
+ }
+
+ this._interestedResizables.forEach(function(resizable) {
+ if (this.resizerShouldNotify(resizable)) {
+ this._notifyDescendant(resizable);
+ }
+ }, this);
+
+ this._fireResize();
+ },
+
+ /**
+ * Used to assign the closest resizable ancestor to this resizable
+ * if the ancestor detects a request for notifications.
+ */
+ assignParentResizable: function(parentResizable) {
+ this._parentResizable = parentResizable;
+ },
+
+ /**
+ * Used to remove a resizable descendant from the list of descendants
+ * that should be notified of a resize change.
+ */
+ stopResizeNotificationsFor: function(target) {
+ var index = this._interestedResizables.indexOf(target);
+
+ if (index > -1) {
+ this._interestedResizables.splice(index, 1);
+ this.unlisten(target, 'iron-resize', '_onDescendantIronResize');
+ }
+ },
+
+ /**
+ * This method can be overridden to filter nested elements that should or
+ * should not be notified by the current element. Return true if an element
+ * should be notified, or false if it should not be notified.
+ *
+ * @param {HTMLElement} element A candidate descendant element that
+ * implements `IronResizableBehavior`.
+ * @return {boolean} True if the `element` should be notified of resize.
+ */
+ resizerShouldNotify: function(element) { return true; },
+
+ _onDescendantIronResize: function(event) {
+ if (this._notifyingDescendant) {
+ event.stopPropagation();
+ return;
+ }
+
+ // NOTE(cdata): In ShadowDOM, event retargetting makes echoing of the
+ // otherwise non-bubbling event "just work." We do it manually here for
+ // the case where Polymer is not using shadow roots for whatever reason:
+ if (!Polymer.Settings.useShadow) {
+ this._fireResize();
+ }
+ },
+
+ _fireResize: function() {
+ this.fire('iron-resize', null, {
+ node: this,
+ bubbles: false
+ });
+ },
+
+ _onIronRequestResizeNotifications: function(event) {
+ var target = event.path ? event.path[0] : event.target;
+
+ if (target === this) {
+ return;
+ }
+
+ if (this._interestedResizables.indexOf(target) === -1) {
+ this._interestedResizables.push(target);
+ this.listen(target, 'iron-resize', '_onDescendantIronResize');
+ }
+
+ target.assignParentResizable(this);
+ this._notifyDescendant(target);
+
+ event.stopPropagation();
+ },
+
+ _parentResizableChanged: function(parentResizable) {
+ if (parentResizable) {
+ window.removeEventListener('resize', this._boundNotifyResize);
+ }
+ },
+
+ _notifyDescendant: function(descendant) {
+ // NOTE(cdata): In IE10, attached is fired on children first, so it's
+ // important not to notify them if the parent is not attached yet (or
+ // else they will get redundantly notified when the parent attaches).
+ if (!this.isAttached) {
+ return;
+ }
+
+ this._notifyingDescendant = true;
+ descendant.notifyResize();
+ this._notifyingDescendant = false;
+ }
+ };
+(function() {
+
+ var IOS = navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/);
+ var IOS_TOUCH_SCROLLING = IOS && IOS[1] >= 8;
+ var DEFAULT_PHYSICAL_COUNT = 3;
+ var MAX_PHYSICAL_COUNT = 500;
+
+ Polymer({
+
+ is: 'iron-list',
+
+ properties: {
+
+ /**
+ * An array containing items determining how many instances of the template
+ * to stamp and that that each template instance should bind to.
+ */
+ items: {
+ type: Array
+ },
+
+ /**
+ * The name of the variable to add to the binding scope for the array
+ * element associated with a given template instance.
+ */
+ as: {
+ type: String,
+ value: 'item'
+ },
+
+ /**
+ * The name of the variable to add to the binding scope with the index
+ * for the row.
+ */
+ indexAs: {
+ type: String,
+ value: 'index'
+ },
+
+ /**
+ * The name of the variable to add to the binding scope to indicate
+ * if the row is selected.
+ */
+ selectedAs: {
+ type: String,
+ value: 'selected'
+ },
+
+ /**
+ * When true, tapping a row will select the item, placing its data model
+ * in the set of selected items retrievable via the selection property.
+ *
+ * Note that tapping focusable elements within the list item will not
+ * result in selection, since they are presumed to have their * own action.
+ */
+ selectionEnabled: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * When `multiSelection` is false, this is the currently selected item, or `null`
+ * if no item is selected.
+ */
+ selectedItem: {
+ type: Object,
+ notify: true
+ },
+
+ /**
+ * When `multiSelection` is true, this is an array that contains the selected items.
+ */
+ selectedItems: {
+ type: Object,
+ notify: true
+ },
+
+ /**
+ * When `true`, multiple items may be selected at once (in this case,
+ * `selected` is an array of currently selected items). When `false`,
+ * only one item may be selected at a time.
+ */
+ multiSelection: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ observers: [
+ '_itemsChanged(items.*)',
+ '_selectionEnabledChanged(selectionEnabled)',
+ '_multiSelectionChanged(multiSelection)'
+ ],
+
+ behaviors: [
+ Polymer.Templatizer,
+ Polymer.IronResizableBehavior
+ ],
+
+ listeners: {
+ 'iron-resize': '_resizeHandler'
+ },
+
+ /**
+ * The ratio of hidden tiles that should remain in the scroll direction.
+ * Recommended value ~0.5, so it will distribute tiles evely in both directions.
+ */
+ _ratio: 0.5,
+
+ /**
+ * The element that controls the scroll
+ * @type {?Element}
+ */
+ _scroller: null,
+
+ /**
+ * The padding-top value of the `scroller` element
+ */
+ _scrollerPaddingTop: 0,
+
+ /**
+ * This value is the same as `scrollTop`.
+ */
+ _scrollPosition: 0,
+
+ /**
+ * The number of tiles in the DOM.
+ */
+ _physicalCount: 0,
+
+ /**
+ * The k-th tile that is at the top of the scrolling list.
+ */
+ _physicalStart: 0,
+
+ /**
+ * The k-th tile that is at the bottom of the scrolling list.
+ */
+ _physicalEnd: 0,
+
+ /**
+ * The sum of the heights of all the tiles in the DOM.
+ */
+ _physicalSize: 0,
+
+ /**
+ * The average `offsetHeight` of the tiles observed till now.
+ */
+ _physicalAverage: 0,
+
+ /**
+ * The number of tiles which `offsetHeight` > 0 observed until now.
+ */
+ _physicalAverageCount: 0,
+
+ /**
+ * The Y position of the item rendered in the `_physicalStart`
+ * tile relative to the scrolling list.
+ */
+ _physicalTop: 0,
+
+ /**
+ * The number of items in the list.
+ */
+ _virtualCount: 0,
+
+ /**
+ * The n-th item rendered in the `_physicalStart` tile.
+ */
+ _virtualStartVal: 0,
+
+ /**
+ * A map between an item key and its physical item index
+ */
+ _physicalIndexForKey: null,
+
+ /**
+ * The estimated scroll height based on `_physicalAverage`
+ */
+ _estScrollHeight: 0,
+
+ /**
+ * The scroll height of the dom node
+ */
+ _scrollHeight: 0,
+
+ /**
+ * The height of the list. This is referred as the viewport in the context of list.
+ */
+ _viewportSize: 0,
+
+ /**
+ * An array of DOM nodes that are currently in the tree
+ * @type {?Array<!TemplatizerNode>}
+ */
+ _physicalItems: null,
+
+ /**
+ * An array of heights for each item in `_physicalItems`
+ * @type {?Array<number>}
+ */
+ _physicalSizes: null,
+
+ /**
+ * A cached value for the visible index.
+ * See `firstVisibleIndex`
+ * @type {?number}
+ */
+ _firstVisibleIndexVal: null,
+
+ /**
+ * A Polymer collection for the items.
+ * @type {?Polymer.Collection}
+ */
+ _collection: null,
+
+ /**
+ * True if the current item list was rendered for the first time
+ * after attached.
+ */
+ _itemsRendered: false,
+
+ /**
+ * The page that is currently rendered.
+ */
+ _lastPage: null,
+
+ /**
+ * The max number of pages to render. One page is equivalent to the height of the list.
+ */
+ _maxPages: 3,
+
+ /**
+ * The bottom of the physical content.
+ */
+ get _physicalBottom() {
+ return this._physicalTop + this._physicalSize;
+ },
+
+ /**
+ * The bottom of the scroll.
+ */
+ get _scrollBottom() {
+ return this._scrollPosition + this._viewportSize;
+ },
+
+ /**
+ * The n-th item rendered in the last physical item.
+ */
+ get _virtualEnd() {
+ return this._virtualStartVal + this._physicalCount - 1;
+ },
+
+ /**
+ * The lowest n-th value for an item such that it can be rendered in `_physicalStart`.
+ */
+ _minVirtualStart: 0,
+
+ /**
+ * The largest n-th value for an item such that it can be rendered in `_physicalStart`.
+ */
+ get _maxVirtualStart() {
+ return Math.max(0, this._virtualCount - this._physicalCount);
+ },
+
+ /**
+ * The height of the physical content that isn't on the screen.
+ */
+ get _hiddenContentSize() {
+ return this._physicalSize - this._viewportSize;
+ },
+
+ /**
+ * The maximum scroll top value.
+ */
+ get _maxScrollTop() {
+ return this._estScrollHeight - this._viewportSize;
+ },
+
+ /**
+ * Sets the n-th item rendered in `_physicalStart`
+ */
+ set _virtualStart(val) {
+ // clamp the value so that _minVirtualStart <= val <= _maxVirtualStart
+ this._virtualStartVal = Math.min(this._maxVirtualStart, Math.max(this._minVirtualStart, val));
+ this._physicalStart = this._virtualStartVal % this._physicalCount;
+ this._physicalEnd = (this._physicalStart + this._physicalCount - 1) % this._physicalCount;
+ },
+
+ /**
+ * Gets the n-th item rendered in `_physicalStart`
+ */
+ get _virtualStart() {
+ return this._virtualStartVal;
+ },
+
+ /**
+ * An optimal physical size such that we will have enough physical items
+ * to fill up the viewport and recycle when the user scrolls.
+ *
+ * This default value assumes that we will at least have the equivalent
+ * to a viewport of physical items above and below the user's viewport.
+ */
+ get _optPhysicalSize() {
+ return this._viewportSize * this._maxPages;
+ },
+
+ /**
+ * True if the current list is visible.
+ */
+ get _isVisible() {
+ return this._scroller && Boolean(this._scroller.offsetWidth || this._scroller.offsetHeight);
+ },
+
+ /**
+ * Gets the index of the first visible item in the viewport.
+ *
+ * @type {number}
+ */
+ get firstVisibleIndex() {
+ var physicalOffset;
+
+ if (this._firstVisibleIndexVal === null) {
+ physicalOffset = this._physicalTop;
+
+ this._firstVisibleIndexVal = this._iterateItems(
+ function(pidx, vidx) {
+ physicalOffset += this._physicalSizes[pidx];
+
+ if (physicalOffset > this._scrollPosition) {
+ return vidx;
+ }
+ }) || 0;
+ }
+
+ return this._firstVisibleIndexVal;
+ },
+
+ ready: function() {
+ if (IOS_TOUCH_SCROLLING) {
+ this._scrollListener = function() {
+ requestAnimationFrame(this._scrollHandler.bind(this));
+ }.bind(this);
+ } else {
+ this._scrollListener = this._scrollHandler.bind(this);
+ }
+ },
+
+ /**
+ * When the element has been attached to the DOM tree.
+ */
+ attached: function() {
+ // delegate to the parent's scroller
+ // e.g. paper-scroll-header-panel
+ var el = Polymer.dom(this);
+
+ var parentNode = /** @type {?{scroller: ?Element}} */ (el.parentNode);
+ if (parentNode && parentNode.scroller) {
+ this._scroller = parentNode.scroller;
+ } else {
+ this._scroller = this;
+ this.classList.add('has-scroller');
+ }
+
+ if (IOS_TOUCH_SCROLLING) {
+ this._scroller.style.webkitOverflowScrolling = 'touch';
+ }
+
+ this._scroller.addEventListener('scroll', this._scrollListener);
+
+ this.updateViewportBoundaries();
+ this._render();
+ },
+
+ /**
+ * When the element has been removed from the DOM tree.
+ */
+ detached: function() {
+ this._itemsRendered = false;
+ if (this._scroller) {
+ this._scroller.removeEventListener('scroll', this._scrollListener);
+ }
+ },
+
+ /**
+ * Invoke this method if you dynamically update the viewport's
+ * size or CSS padding.
+ *
+ * @method updateViewportBoundaries
+ */
+ updateViewportBoundaries: function() {
+ var scrollerStyle = window.getComputedStyle(this._scroller);
+ this._scrollerPaddingTop = parseInt(scrollerStyle['padding-top'], 10);
+ this._viewportSize = this._scroller.offsetHeight;
+ },
+
+ /**
+ * Update the models, the position of the
+ * items in the viewport and recycle tiles as needed.
+ */
+ _refresh: function() {
+ // clamp the `scrollTop` value
+ // IE 10|11 scrollTop may go above `_maxScrollTop`
+ // iOS `scrollTop` may go below 0 and above `_maxScrollTop`
+ var scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scroller.scrollTop));
+ var tileHeight, tileTop, kth, recycledTileSet, scrollBottom, physicalBottom;
+ var ratio = this._ratio;
+ var delta = scrollTop - this._scrollPosition;
+ var recycledTiles = 0;
+ var hiddenContentSize = this._hiddenContentSize;
+ var currentRatio = ratio;
+ var movingUp = [];
+
+ // track the last `scrollTop`
+ this._scrollPosition = scrollTop;
+
+ // clear cached visible index
+ this._firstVisibleIndexVal = null;
+
+ scrollBottom = this._scrollBottom;
+ physicalBottom = this._physicalBottom;
+
+ // random access
+ if (Math.abs(delta) > this._physicalSize) {
+ this._physicalTop += delta;
+ recycledTiles = Math.round(delta / this._physicalAverage);
+ }
+ // scroll up
+ else if (delta < 0) {
+ var topSpace = scrollTop - this._physicalTop;
+ var virtualStart = this._virtualStart;
+
+ recycledTileSet = [];
+
+ kth = this._physicalEnd;
+ currentRatio = topSpace / hiddenContentSize;
+
+ // move tiles from bottom to top
+ while (
+ // approximate `currentRatio` to `ratio`
+ currentRatio < ratio &&
+ // recycle less physical items than the total
+ recycledTiles < this._physicalCount &&
+ // ensure that these recycled tiles are needed
+ virtualStart - recycledTiles > 0 &&
+ // ensure that the tile is not visible
+ physicalBottom - this._physicalSizes[kth] > scrollBottom
+ ) {
+
+ tileHeight = this._physicalSizes[kth];
+ currentRatio += tileHeight / hiddenContentSize;
+ physicalBottom -= tileHeight;
+ recycledTileSet.push(kth);
+ recycledTiles++;
+ kth = (kth === 0) ? this._physicalCount - 1 : kth - 1;
+ }
+
+ movingUp = recycledTileSet;
+ recycledTiles = -recycledTiles;
+ }
+ // scroll down
+ else if (delta > 0) {
+ var bottomSpace = physicalBottom - scrollBottom;
+ var virtualEnd = this._virtualEnd;
+ var lastVirtualItemIndex = this._virtualCount-1;
+
+ recycledTileSet = [];
+
+ kth = this._physicalStart;
+ currentRatio = bottomSpace / hiddenContentSize;
+
+ // move tiles from top to bottom
+ while (
+ // approximate `currentRatio` to `ratio`
+ currentRatio < ratio &&
+ // recycle less physical items than the total
+ recycledTiles < this._physicalCount &&
+ // ensure that these recycled tiles are needed
+ virtualEnd + recycledTiles < lastVirtualItemIndex &&
+ // ensure that the tile is not visible
+ this._physicalTop + this._physicalSizes[kth] < scrollTop
+ ) {
+
+ tileHeight = this._physicalSizes[kth];
+ currentRatio += tileHeight / hiddenContentSize;
+
+ this._physicalTop += tileHeight;
+ recycledTileSet.push(kth);
+ recycledTiles++;
+ kth = (kth + 1) % this._physicalCount;
+ }
+ }
+
+ if (recycledTiles === 0) {
+ // If the list ever reach this case, the physical average is not significant enough
+ // to create all the items needed to cover the entire viewport.
+ // e.g. A few items have a height that differs from the average by serveral order of magnitude.
+ if (physicalBottom < scrollBottom || this._physicalTop > scrollTop) {
+ this.async(this._increasePool.bind(this, 1));
+ }
+ } else {
+ this._virtualStart = this._virtualStart + recycledTiles;
+ this._update(recycledTileSet, movingUp);
+ }
+ },
+
+ /**
+ * Update the list of items, starting from the `_virtualStartVal` item.
+ * @param {!Array<number>=} itemSet
+ * @param {!Array<number>=} movingUp
+ */
+ _update: function(itemSet, movingUp) {
+ // update models
+ this._assignModels(itemSet);
+
+ // measure heights
+ this._updateMetrics(itemSet);
+
+ // adjust offset after measuring
+ if (movingUp) {
+ while (movingUp.length) {
+ this._physicalTop -= this._physicalSizes[movingUp.pop()];
+ }
+ }
+ // update the position of the items
+ this._positionItems();
+
+ // set the scroller size
+ this._updateScrollerSize();
+
+ // increase the pool of physical items
+ this._increasePoolIfNeeded();
+ },
+
+ /**
+ * Creates a pool of DOM elements and attaches them to the local dom.
+ */
+ _createPool: function(size) {
+ var physicalItems = new Array(size);
+
+ this._ensureTemplatized();
+
+ for (var i = 0; i < size; i++) {
+ var inst = this.stamp(null);
+ // First element child is item; Safari doesn't support children[0]
+ // on a doc fragment
+ physicalItems[i] = inst.root.querySelector('*');
+ Polymer.dom(this).appendChild(inst.root);
+ }
+
+ return physicalItems;
+ },
+
+ /**
+ * Increases the pool of physical items only if needed.
+ * This function will allocate additional physical items
+ * if the physical size is shorter than `_optPhysicalSize`
+ */
+ _increasePoolIfNeeded: function() {
+ if (this._viewportSize !== 0 && this._physicalSize < this._optPhysicalSize) {
+ // 0 <= `currentPage` <= `_maxPages`
+ var currentPage = Math.floor(this._physicalSize / this._viewportSize);
+
+ if (currentPage === 0) {
+ // fill the first page
+ this.async(this._increasePool.bind(this, Math.round(this._physicalCount * 0.5)));
+ } else if (this._lastPage !== currentPage) {
+ // once a page is filled up, paint it and defer the next increase
+ requestAnimationFrame(this._increasePool.bind(this, 1));
+ } else {
+ // fill the rest of the pages
+ this.async(this._increasePool.bind(this, 1));
+ }
+ this._lastPage = currentPage;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Increases the pool size.
+ */
+ _increasePool: function(missingItems) {
+ // limit the size
+ var nextPhysicalCount = Math.min(
+ this._physicalCount + missingItems,
+ this._virtualCount,
+ MAX_PHYSICAL_COUNT
+ );
+ var prevPhysicalCount = this._physicalCount;
+ var delta = nextPhysicalCount - prevPhysicalCount;
+
+ if (delta > 0) {
+ [].push.apply(this._physicalItems, this._createPool(delta));
+ [].push.apply(this._physicalSizes, new Array(delta));
+
+ this._physicalCount = prevPhysicalCount + delta;
+ // tail call
+ return this._update();
+ }
+ },
+
+ /**
+ * Render a new list of items. This method does exactly the same as `update`,
+ * but it also ensures that only one `update` cycle is created.
+ */
+ _render: function() {
+ var requiresUpdate = this._virtualCount > 0 || this._physicalCount > 0;
+
+ if (this.isAttached && !this._itemsRendered && this._isVisible && requiresUpdate) {
+ this._lastPage = 0;
+ this._update();
+ this._itemsRendered = true;
+ }
+ },
+
+ /**
+ * Templetizes the user template.
+ */
+ _ensureTemplatized: function() {
+ if (!this.ctor) {
+ // Template instance props that should be excluded from forwarding
+ var props = {};
+
+ props.__key__ = true;
+ props[this.as] = true;
+ props[this.indexAs] = true;
+ props[this.selectedAs] = true;
+
+ this._instanceProps = props;
+ this._userTemplate = Polymer.dom(this).querySelector('template');
+
+ if (this._userTemplate) {
+ this.templatize(this._userTemplate);
+ } else {
+ console.warn('iron-list requires a template to be provided in light-dom');
+ }
+ }
+ },
+
+ /**
+ * Implements extension point from Templatizer mixin.
+ */
+ _getStampedChildren: function() {
+ return this._physicalItems;
+ },
+
+ /**
+ * Implements extension point from Templatizer
+ * Called as a side effect of a template instance path change, responsible
+ * for notifying items.<key-for-instance>.<path> change up to host.
+ */
+ _forwardInstancePath: function(inst, path, value) {
+ if (path.indexOf(this.as + '.') === 0) {
+ this.notifyPath('items.' + inst.__key__ + '.' +
+ path.slice(this.as.length + 1), value);
+ }
+ },
+
+ /**
+ * Implements extension point from Templatizer mixin
+ * Called as side-effect of a host property change, responsible for
+ * notifying parent path change on each row.
+ */
+ _forwardParentProp: function(prop, value) {
+ if (this._physicalItems) {
+ this._physicalItems.forEach(function(item) {
+ item._templateInstance[prop] = value;
+ }, this);
+ }
+ },
+
+ /**
+ * Implements extension point from Templatizer
+ * Called as side-effect of a host path change, responsible for
+ * notifying parent.<path> path change on each row.
+ */
+ _forwardParentPath: function(path, value) {
+ if (this._physicalItems) {
+ this._physicalItems.forEach(function(item) {
+ item._templateInstance.notifyPath(path, value, true);
+ }, this);
+ }
+ },
+
+ /**
+ * Called as a side effect of a host items.<key>.<path> path change,
+ * responsible for notifying item.<path> changes to row for key.
+ */
+ _forwardItemPath: function(path, value) {
+ if (this._physicalIndexForKey) {
+ var dot = path.indexOf('.');
+ var key = path.substring(0, dot < 0 ? path.length : dot);
+ var idx = this._physicalIndexForKey[key];
+ var row = this._physicalItems[idx];
+ if (row) {
+ var inst = row._templateInstance;
+ if (dot >= 0) {
+ path = this.as + '.' + path.substring(dot+1);
+ inst.notifyPath(path, value, true);
+ } else {
+ inst[this.as] = value;
+ }
+ }
+ }
+ },
+
+ /**
+ * Called when the items have changed. That is, ressignments
+ * to `items`, splices or updates to a single item.
+ */
+ _itemsChanged: function(change) {
+ if (change.path === 'items') {
+ // render the new set
+ this._itemsRendered = false;
+
+ // update the whole set
+ this._virtualStartVal = 0;
+ this._physicalTop = 0;
+ this._virtualCount = this.items ? this.items.length : 0;
+ this._collection = this.items ? Polymer.Collection.get(this.items) : null;
+ this._physicalIndexForKey = {};
+
+ // scroll to the top
+ this._resetScrollPosition(0);
+
+ // create the initial physical items
+ if (!this._physicalItems) {
+ this._physicalCount = Math.max(1, Math.min(DEFAULT_PHYSICAL_COUNT, this._virtualCount));
+ this._physicalItems = this._createPool(this._physicalCount);
+ this._physicalSizes = new Array(this._physicalCount);
+ }
+
+ this.debounce('refresh', this._render);
+
+ } else if (change.path === 'items.splices') {
+ // render the new set
+ this._itemsRendered = false;
+
+ this._adjustVirtualIndex(change.value.indexSplices);
+ this._virtualCount = this.items ? this.items.length : 0;
+
+ this.debounce('refresh', this._render);
+
+ } else {
+ // update a single item
+ this._forwardItemPath(change.path.split('.').slice(1).join('.'), change.value);
+ }
+ },
+
+ /**
+ * @param {!Array<!PolymerSplice>} splices
+ */
+ _adjustVirtualIndex: function(splices) {
+ var i, splice, idx;
+
+ for (i = 0; i < splices.length; i++) {
+ splice = splices[i];
+
+ // deselect removed items
+ splice.removed.forEach(this.$.selector.deselect, this.$.selector);
+
+ idx = splice.index;
+ // We only need to care about changes happening above the current position
+ if (idx >= this._virtualStartVal) {
+ break;
+ }
+
+ this._virtualStart = this._virtualStart +
+ Math.max(splice.addedCount - splice.removed.length, idx - this._virtualStartVal);
+ }
+ },
+
+ _scrollHandler: function() {
+ this._refresh();
+ },
+
+ /**
+ * Executes a provided function per every physical index in `itemSet`
+ * `itemSet` default value is equivalent to the entire set of physical indexes.
+ *
+ * @param {!function(number, number)} fn
+ * @param {!Array<number>=} itemSet
+ */
+ _iterateItems: function(fn, itemSet) {
+ var pidx, vidx, rtn, i;
+
+ if (arguments.length === 2 && itemSet) {
+ for (i = 0; i < itemSet.length; i++) {
+ pidx = itemSet[i];
+ if (pidx >= this._physicalStart) {
+ vidx = this._virtualStartVal + (pidx - this._physicalStart);
+ } else {
+ vidx = this._virtualStartVal + (this._physicalCount - this._physicalStart) + pidx;
+ }
+ if ((rtn = fn.call(this, pidx, vidx)) != null) {
+ return rtn;
+ }
+ }
+ } else {
+ pidx = this._physicalStart;
+ vidx = this._virtualStartVal;
+
+ for (; pidx < this._physicalCount; pidx++, vidx++) {
+ if ((rtn = fn.call(this, pidx, vidx)) != null) {
+ return rtn;
+ }
+ }
+
+ pidx = 0;
+
+ for (; pidx < this._physicalStart; pidx++, vidx++) {
+ if ((rtn = fn.call(this, pidx, vidx)) != null) {
+ return rtn;
+ }
+ }
+ }
+ },
+
+ /**
+ * Assigns the data models to a given set of items.
+ * @param {!Array<number>=} itemSet
+ */
+ _assignModels: function(itemSet) {
+ this._iterateItems(function(pidx, vidx) {
+ var el = this._physicalItems[pidx];
+ var inst = el._templateInstance;
+ var item = this.items && this.items[vidx];
+
+ if (item) {
+ inst[this.as] = item;
+ inst.__key__ = this._collection.getKey(item);
+ inst[this.selectedAs] =
+ /** @type {!ArraySelectorElement} */ (this.$.selector).isSelected(item);
+ inst[this.indexAs] = vidx;
+ el.removeAttribute('hidden');
+ this._physicalIndexForKey[inst.__key__] = pidx;
+ } else {
+ inst.__key__ = null;
+ el.setAttribute('hidden', '');
+ }
+
+ }, itemSet);
+ },
+
+ /**
+ * Updates the height for a given set of items.
+ *
+ * @param {!Array<number>=} itemSet
+ */
+ _updateMetrics: function(itemSet) {
+ var newPhysicalSize = 0;
+ var oldPhysicalSize = 0;
+ var prevAvgCount = this._physicalAverageCount;
+ var prevPhysicalAvg = this._physicalAverage;
+ // Make sure we distributed all the physical items
+ // so we can measure them
+ Polymer.dom.flush();
+
+ this._iterateItems(function(pidx, vidx) {
+ oldPhysicalSize += this._physicalSizes[pidx] || 0;
+ this._physicalSizes[pidx] = this._physicalItems[pidx].offsetHeight;
+ newPhysicalSize += this._physicalSizes[pidx];
+ this._physicalAverageCount += this._physicalSizes[pidx] ? 1 : 0;
+ }, itemSet);
+
+ this._physicalSize = this._physicalSize + newPhysicalSize - oldPhysicalSize;
+ this._viewportSize = this._scroller.offsetHeight;
+
+ // update the average if we measured something
+ if (this._physicalAverageCount !== prevAvgCount) {
+ this._physicalAverage = Math.round(
+ ((prevPhysicalAvg * prevAvgCount) + newPhysicalSize) /
+ this._physicalAverageCount);
+ }
+ },
+
+ /**
+ * Updates the position of the physical items.
+ */
+ _positionItems: function() {
+ this._adjustScrollPosition();
+
+ var y = this._physicalTop;
+
+ this._iterateItems(function(pidx) {
+
+ this.transform('translate3d(0, ' + y + 'px, 0)', this._physicalItems[pidx]);
+ y += this._physicalSizes[pidx];
+
+ });
+ },
+
+ /**
+ * Adjusts the scroll position when it was overestimated.
+ */
+ _adjustScrollPosition: function() {
+ var deltaHeight = this._virtualStartVal === 0 ? this._physicalTop :
+ Math.min(this._scrollPosition + this._physicalTop, 0);
+
+ if (deltaHeight) {
+ this._physicalTop = this._physicalTop - deltaHeight;
+
+ // juking scroll position during interial scrolling on iOS is no bueno
+ if (!IOS_TOUCH_SCROLLING) {
+ this._resetScrollPosition(this._scroller.scrollTop - deltaHeight);
+ }
+ }
+ },
+
+ /**
+ * Sets the position of the scroll.
+ */
+ _resetScrollPosition: function(pos) {
+ if (this._scroller) {
+ this._scroller.scrollTop = pos;
+ this._scrollPosition = this._scroller.scrollTop;
+ }
+ },
+
+ /**
+ * Sets the scroll height, that's the height of the content,
+ *
+ * @param {boolean=} forceUpdate If true, updates the height no matter what.
+ */
+ _updateScrollerSize: function(forceUpdate) {
+ this._estScrollHeight = (this._physicalBottom +
+ Math.max(this._virtualCount - this._physicalCount - this._virtualStartVal, 0) * this._physicalAverage);
+
+ forceUpdate = forceUpdate || this._scrollHeight === 0;
+ forceUpdate = forceUpdate || this._scrollPosition >= this._estScrollHeight - this._physicalSize;
+
+ // amortize height adjustment, so it won't trigger repaints very often
+ if (forceUpdate || Math.abs(this._estScrollHeight - this._scrollHeight) >= this._optPhysicalSize) {
+ this.$.items.style.height = this._estScrollHeight + 'px';
+ this._scrollHeight = this._estScrollHeight;
+ }
+ },
+
+ /**
+ * Scroll to a specific item in the virtual list regardless
+ * of the physical items in the DOM tree.
+ *
+ * @method scrollToIndex
+ * @param {number} idx The index of the item
+ */
+ scrollToIndex: function(idx) {
+ if (typeof idx !== 'number') {
+ return;
+ }
+
+ var firstVisible = this.firstVisibleIndex;
+
+ idx = Math.min(Math.max(idx, 0), this._virtualCount-1);
+
+ // start at the previous virtual item
+ // so we have a item above the first visible item
+ this._virtualStart = idx - 1;
+
+ // assign new models
+ this._assignModels();
+
+ // measure the new sizes
+ this._updateMetrics();
+
+ // estimate new physical offset
+ this._physicalTop = this._virtualStart * this._physicalAverage;
+
+ var currentTopItem = this._physicalStart;
+ var currentVirtualItem = this._virtualStart;
+ var targetOffsetTop = 0;
+ var hiddenContentSize = this._hiddenContentSize;
+
+ // scroll to the item as much as we can
+ while (currentVirtualItem < idx && targetOffsetTop < hiddenContentSize) {
+ targetOffsetTop = targetOffsetTop + this._physicalSizes[currentTopItem];
+ currentTopItem = (currentTopItem + 1) % this._physicalCount;
+ currentVirtualItem++;
+ }
+
+ // update the scroller size
+ this._updateScrollerSize(true);
+
+ // update the position of the items
+ this._positionItems();
+
+ // set the new scroll position
+ this._resetScrollPosition(this._physicalTop + targetOffsetTop + 1);
+
+ // increase the pool of physical items if needed
+ this._increasePoolIfNeeded();
+
+ // clear cached visible index
+ this._firstVisibleIndexVal = null;
+ },
+
+ /**
+ * Reset the physical average and the average count.
+ */
+ _resetAverage: function() {
+ this._physicalAverage = 0;
+ this._physicalAverageCount = 0;
+ },
+
+ /**
+ * A handler for the `iron-resize` event triggered by `IronResizableBehavior`
+ * when the element is resized.
+ */
+ _resizeHandler: function() {
+ this.debounce('resize', function() {
+ this._render();
+ if (this._itemsRendered && this._physicalItems && this._isVisible) {
+ this._resetAverage();
+ this.updateViewportBoundaries();
+ this.scrollToIndex(this.firstVisibleIndex);
+ }
+ });
+ },
+
+ _getModelFromItem: function(item) {
+ var key = this._collection.getKey(item);
+ var pidx = this._physicalIndexForKey[key];
+
+ if (pidx !== undefined) {
+ return this._physicalItems[pidx]._templateInstance;
+ }
+ return null;
+ },
+
+ /**
+ * Gets a valid item instance from its index or the object value.
+ *
+ * @param {(Object|number)} item The item object or its index
+ */
+ _getNormalizedItem: function(item) {
+ if (typeof item === 'number') {
+ item = this.items[item];
+ if (!item) {
+ throw new RangeError('<item> not found');
+ }
+ } else if (this._collection.getKey(item) === undefined) {
+ throw new TypeError('<item> should be a valid item');
+ }
+ return item;
+ },
+
+ /**
+ * Select the list item at the given index.
+ *
+ * @method selectItem
+ * @param {(Object|number)} item The item object or its index
+ */
+ selectItem: function(item) {
+ item = this._getNormalizedItem(item);
+ var model = this._getModelFromItem(item);
+
+ if (!this.multiSelection && this.selectedItem) {
+ this.deselectItem(this.selectedItem);
+ }
+ if (model) {
+ model[this.selectedAs] = true;
+ }
+ this.$.selector.select(item);
+ },
+
+ /**
+ * Deselects the given item list if it is already selected.
+ *
+
+ * @method deselect
+ * @param {(Object|number)} item The item object or its index
+ */
+ deselectItem: function(item) {
+ item = this._getNormalizedItem(item);
+ var model = this._getModelFromItem(item);
+
+ if (model) {
+ model[this.selectedAs] = false;
+ }
+ this.$.selector.deselect(item);
+ },
+
+ /**
+ * Select or deselect a given item depending on whether the item
+ * has already been selected.
+ *
+ * @method toggleSelectionForItem
+ * @param {(Object|number)} item The item object or its index
+ */
+ toggleSelectionForItem: function(item) {
+ item = this._getNormalizedItem(item);
+ if (/** @type {!ArraySelectorElement} */ (this.$.selector).isSelected(item)) {
+ this.deselectItem(item);
+ } else {
+ this.selectItem(item);
+ }
+ },
+
+ /**
+ * Clears the current selection state of the list.
+ *
+ * @method clearSelection
+ */
+ clearSelection: function() {
+ function unselect(item) {
+ var model = this._getModelFromItem(item);
+ if (model) {
+ model[this.selectedAs] = false;
+ }
+ }
+
+ if (Array.isArray(this.selectedItems)) {
+ this.selectedItems.forEach(unselect, this);
+ } else if (this.selectedItem) {
+ unselect.call(this, this.selectedItem);
+ }
+
+ /** @type {!ArraySelectorElement} */ (this.$.selector).clearSelection();
+ },
+
+ /**
+ * Add an event listener to `tap` if `selectionEnabled` is true,
+ * it will remove the listener otherwise.
+ */
+ _selectionEnabledChanged: function(selectionEnabled) {
+ if (selectionEnabled) {
+ this.listen(this, 'tap', '_selectionHandler');
+ this.listen(this, 'keypress', '_selectionHandler');
+ } else {
+ this.unlisten(this, 'tap', '_selectionHandler');
+ this.unlisten(this, 'keypress', '_selectionHandler');
+ }
+ },
+
+ /**
+ * Select an item from an event object.
+ */
+ _selectionHandler: function(e) {
+ if (e.type !== 'keypress' || e.keyCode === 13) {
+ var model = this.modelForElement(e.target);
+ if (model) {
+ this.toggleSelectionForItem(model[this.as]);
+ }
+ }
+ },
+
+ _multiSelectionChanged: function(multiSelection) {
+ this.clearSelection();
+ this.$.selector.multi = multiSelection;
+ },
+
+ /**
+ * Updates the size of an item.
+ *
+ * @method updateSizeForItem
+ * @param {(Object|number)} item The item object or its index
+ */
+ updateSizeForItem: function(item) {
+ item = this._getNormalizedItem(item);
+ var key = this._collection.getKey(item);
+ var pidx = this._physicalIndexForKey[key];
+
+ if (pidx !== undefined) {
+ this._updateMetrics([pidx]);
+ this._positionItems();
+ }
+ }
+ });
+
+})();
+(function() {
+
+ // monostate data
+ var metaDatas = {};
+ var metaArrays = {};
+ var singleton = null;
+
+ Polymer.IronMeta = Polymer({
+
+ is: 'iron-meta',
+
+ properties: {
+
+ /**
+ * The type of meta-data. All meta-data of the same type is stored
+ * together.
+ */
+ type: {
+ type: String,
+ value: 'default',
+ observer: '_typeChanged'
+ },
+
+ /**
+ * The key used to store `value` under the `type` namespace.
+ */
+ key: {
+ type: String,
+ observer: '_keyChanged'
+ },
+
+ /**
+ * The meta-data to store or retrieve.
+ */
+ value: {
+ type: Object,
+ notify: true,
+ observer: '_valueChanged'
+ },
+
+ /**
+ * If true, `value` is set to the iron-meta instance itself.
+ */
+ self: {
+ type: Boolean,
+ observer: '_selfChanged'
+ },
+
+ /**
+ * Array of all meta-data values for the given type.
+ */
+ list: {
+ type: Array,
+ notify: true
+ }
+
+ },
+
+ hostAttributes: {
+ hidden: true
+ },
+
+ /**
+ * Only runs if someone invokes the factory/constructor directly
+ * e.g. `new Polymer.IronMeta()`
+ *
+ * @param {{type: (string|undefined), key: (string|undefined), value}=} config
+ */
+ factoryImpl: function(config) {
+ if (config) {
+ for (var n in config) {
+ switch(n) {
+ case 'type':
+ case 'key':
+ case 'value':
+ this[n] = config[n];
+ break;
+ }
+ }
+ }
+ },
+
+ created: function() {
+ // TODO(sjmiles): good for debugging?
+ this._metaDatas = metaDatas;
+ this._metaArrays = metaArrays;
+ },
+
+ _keyChanged: function(key, old) {
+ this._resetRegistration(old);
+ },
+
+ _valueChanged: function(value) {
+ this._resetRegistration(this.key);
+ },
+
+ _selfChanged: function(self) {
+ if (self) {
+ this.value = this;
+ }
+ },
+
+ _typeChanged: function(type) {
+ this._unregisterKey(this.key);
+ if (!metaDatas[type]) {
+ metaDatas[type] = {};
+ }
+ this._metaData = metaDatas[type];
+ if (!metaArrays[type]) {
+ metaArrays[type] = [];
+ }
+ this.list = metaArrays[type];
+ this._registerKeyValue(this.key, this.value);
+ },
+
+ /**
+ * Retrieves meta data value by key.
+ *
+ * @method byKey
+ * @param {string} key The key of the meta-data to be returned.
+ * @return {*}
+ */
+ byKey: function(key) {
+ return this._metaData && this._metaData[key];
+ },
+
+ _resetRegistration: function(oldKey) {
+ this._unregisterKey(oldKey);
+ this._registerKeyValue(this.key, this.value);
+ },
+
+ _unregisterKey: function(key) {
+ this._unregister(key, this._metaData, this.list);
+ },
+
+ _registerKeyValue: function(key, value) {
+ this._register(key, value, this._metaData, this.list);
+ },
+
+ _register: function(key, value, data, list) {
+ if (key && data && value !== undefined) {
+ data[key] = value;
+ list.push(value);
+ }
+ },
+
+ _unregister: function(key, data, list) {
+ if (key && data) {
+ if (key in data) {
+ var value = data[key];
+ delete data[key];
+ this.arrayDelete(list, value);
+ }
+ }
+ }
+
+ });
+
+ Polymer.IronMeta.getIronMeta = function getIronMeta() {
+ if (singleton === null) {
+ singleton = new Polymer.IronMeta();
+ }
+ return singleton;
+ };
+
+ /**
+ `iron-meta-query` can be used to access infomation stored in `iron-meta`.
+
+ Examples:
+
+ If I create an instance like this:
+
+ <iron-meta key="info" value="foo/bar"></iron-meta>
+
+ Note that value="foo/bar" is the metadata I've defined. I could define more
+ attributes or use child nodes to define additional metadata.
+
+ Now I can access that element (and it's metadata) from any `iron-meta-query` instance:
+
+ var value = new Polymer.IronMetaQuery({key: 'info'}).value;
+
+ @group Polymer Iron Elements
+ @element iron-meta-query
+ */
+ Polymer.IronMetaQuery = Polymer({
+
+ is: 'iron-meta-query',
+
+ properties: {
+
+ /**
+ * The type of meta-data. All meta-data of the same type is stored
+ * together.
+ */
+ type: {
+ type: String,
+ value: 'default',
+ observer: '_typeChanged'
+ },
+
+ /**
+ * Specifies a key to use for retrieving `value` from the `type`
+ * namespace.
+ */
+ key: {
+ type: String,
+ observer: '_keyChanged'
+ },
+
+ /**
+ * The meta-data to store or retrieve.
+ */
+ value: {
+ type: Object,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * Array of all meta-data values for the given type.
+ */
+ list: {
+ type: Array,
+ notify: true
+ }
+
+ },
+
+ /**
+ * Actually a factory method, not a true constructor. Only runs if
+ * someone invokes it directly (via `new Polymer.IronMeta()`);
+ *
+ * @param {{type: (string|undefined), key: (string|undefined)}=} config
+ */
+ factoryImpl: function(config) {
+ if (config) {
+ for (var n in config) {
+ switch(n) {
+ case 'type':
+ case 'key':
+ this[n] = config[n];
+ break;
+ }
+ }
+ }
+ },
+
+ created: function() {
+ // TODO(sjmiles): good for debugging?
+ this._metaDatas = metaDatas;
+ this._metaArrays = metaArrays;
+ },
+
+ _keyChanged: function(key) {
+ this._setValue(this._metaData && this._metaData[key]);
+ },
+
+ _typeChanged: function(type) {
+ this._metaData = metaDatas[type];
+ this.list = metaArrays[type];
+ if (this.key) {
+ this._keyChanged(this.key);
+ }
+ },
+
+ /**
+ * Retrieves meta data value by key.
+ * @param {string} key The key of the meta-data to be returned.
+ * @return {*}
+ */
+ byKey: function(key) {
+ return this._metaData && this._metaData[key];
+ }
+
+ });
+
+ })();
+Polymer({
+
+ is: 'iron-icon',
+
+ properties: {
+
+ /**
+ * The name of the icon to use. The name should be of the form:
+ * `iconset_name:icon_name`.
+ */
+ icon: {
+ type: String,
+ observer: '_iconChanged'
+ },
+
+ /**
+ * The name of the theme to used, if one is specified by the
+ * iconset.
+ */
+ theme: {
+ type: String,
+ observer: '_updateIcon'
+ },
+
+ /**
+ * If using iron-icon without an iconset, you can set the src to be
+ * the URL of an individual icon image file. Note that this will take
+ * precedence over a given icon attribute.
+ */
+ src: {
+ type: String,
+ observer: '_srcChanged'
+ },
+
+ /**
+ * @type {!Polymer.IronMeta}
+ */
+ _meta: {
+ value: Polymer.Base.create('iron-meta', {type: 'iconset'})
+ }
+
+ },
+
+ _DEFAULT_ICONSET: 'icons',
+
+ _iconChanged: function(icon) {
+ var parts = (icon || '').split(':');
+ this._iconName = parts.pop();
+ this._iconsetName = parts.pop() || this._DEFAULT_ICONSET;
+ this._updateIcon();
+ },
+
+ _srcChanged: function(src) {
+ this._updateIcon();
+ },
+
+ _usesIconset: function() {
+ return this.icon || !this.src;
+ },
+
+ /** @suppress {visibility} */
+ _updateIcon: function() {
+ if (this._usesIconset()) {
+ if (this._iconsetName) {
+ this._iconset = /** @type {?Polymer.Iconset} */ (
+ this._meta.byKey(this._iconsetName));
+ if (this._iconset) {
+ this._iconset.applyIcon(this, this._iconName, this.theme);
+ this.unlisten(window, 'iron-iconset-added', '_updateIcon');
+ } else {
+ this.listen(window, 'iron-iconset-added', '_updateIcon');
+ }
+ }
+ } else {
+ if (!this._img) {
+ this._img = document.createElement('img');
+ this._img.style.width = '100%';
+ this._img.style.height = '100%';
+ this._img.draggable = false;
+ }
+ this._img.src = this.src;
+ Polymer.dom(this.root).appendChild(this._img);
+ }
+ }
+
+ });
+/**
+ * The `iron-iconset-svg` element allows users to define their own icon sets
+ * that contain svg icons. The svg icon elements should be children of the
+ * `iron-iconset-svg` element. Multiple icons should be given distinct id's.
+ *
+ * Using svg elements to create icons has a few advantages over traditional
+ * bitmap graphics like jpg or png. Icons that use svg are vector based so
+ * they are resolution independent and should look good on any device. They
+ * are stylable via css. Icons can be themed, colorized, and even animated.
+ *
+ * Example:
+ *
+ * <iron-iconset-svg name="my-svg-icons" size="24">
+ * <svg>
+ * <defs>
+ * <g id="shape">
+ * <rect x="12" y="0" width="12" height="24" />
+ * <circle cx="12" cy="12" r="12" />
+ * </g>
+ * </defs>
+ * </svg>
+ * </iron-iconset-svg>
+ *
+ * This will automatically register the icon set "my-svg-icons" to the iconset
+ * database. To use these icons from within another element, make a
+ * `iron-iconset` element and call the `byId` method
+ * to retrieve a given iconset. To apply a particular icon inside an
+ * element use the `applyIcon` method. For example:
+ *
+ * iconset.applyIcon(iconNode, 'car');
+ *
+ * @element iron-iconset-svg
+ * @demo demo/index.html
+ * @implements {Polymer.Iconset}
+ */
+ Polymer({
+ is: 'iron-iconset-svg',
+
+ properties: {
+
+ /**
+ * The name of the iconset.
+ */
+ name: {
+ type: String,
+ observer: '_nameChanged'
+ },
+
+ /**
+ * The size of an individual icon. Note that icons must be square.
+ */
+ size: {
+ type: Number,
+ value: 24
+ }
+
+ },
+
+ attached: function() {
+ this.style.display = 'none';
+ },
+
+ /**
+ * Construct an array of all icon names in this iconset.
+ *
+ * @return {!Array} Array of icon names.
+ */
+ getIconNames: function() {
+ this._icons = this._createIconMap();
+ return Object.keys(this._icons).map(function(n) {
+ return this.name + ':' + n;
+ }, this);
+ },
+
+ /**
+ * Applies an icon to the given element.
+ *
+ * An svg icon is prepended to the element's shadowRoot if it exists,
+ * otherwise to the element itself.
+ *
+ * @method applyIcon
+ * @param {Element} element Element to which the icon is applied.
+ * @param {string} iconName Name of the icon to apply.
+ * @return {?Element} The svg element which renders the icon.
+ */
+ applyIcon: function(element, iconName) {
+ // insert svg element into shadow root, if it exists
+ element = element.root || element;
+ // Remove old svg element
+ this.removeIcon(element);
+ // install new svg element
+ var svg = this._cloneIcon(iconName);
+ if (svg) {
+ var pde = Polymer.dom(element);
+ pde.insertBefore(svg, pde.childNodes[0]);
+ return element._svgIcon = svg;
+ }
+ return null;
+ },
+
+ /**
+ * Remove an icon from the given element by undoing the changes effected
+ * by `applyIcon`.
+ *
+ * @param {Element} element The element from which the icon is removed.
+ */
+ removeIcon: function(element) {
+ // Remove old svg element
+ if (element._svgIcon) {
+ Polymer.dom(element).removeChild(element._svgIcon);
+ element._svgIcon = null;
+ }
+ },
+
+ /**
+ *
+ * When name is changed, register iconset metadata
+ *
+ */
+ _nameChanged: function() {
+ new Polymer.IronMeta({type: 'iconset', key: this.name, value: this});
+ this.async(function() {
+ this.fire('iron-iconset-added', this, {node: window});
+ });
+ },
+
+ /**
+ * Create a map of child SVG elements by id.
+ *
+ * @return {!Object} Map of id's to SVG elements.
+ */
+ _createIconMap: function() {
+ // Objects chained to Object.prototype (`{}`) have members. Specifically,
+ // on FF there is a `watch` method that confuses the icon map, so we
+ // need to use a null-based object here.
+ var icons = Object.create(null);
+ Polymer.dom(this).querySelectorAll('[id]')
+ .forEach(function(icon) {
+ icons[icon.id] = icon;
+ });
+ return icons;
+ },
+
+ /**
+ * Produce installable clone of the SVG element matching `id` in this
+ * iconset, or `undefined` if there is no matching element.
+ *
+ * @return {Element} Returns an installable clone of the SVG element
+ * matching `id`.
+ */
+ _cloneIcon: function(id) {
+ // create the icon map on-demand, since the iconset itself has no discrete
+ // signal to know when it's children are fully parsed
+ this._icons = this._icons || this._createIconMap();
+ return this._prepareSvgClone(this._icons[id], this.size);
+ },
+
+ /**
+ * @param {Element} sourceSvg
+ * @param {number} size
+ * @return {Element}
+ */
+ _prepareSvgClone: function(sourceSvg, size) {
+ if (sourceSvg) {
+ var content = sourceSvg.cloneNode(true),
+ svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
+ viewBox = content.getAttribute('viewBox') || '0 0 ' + size + ' ' + size;
+ svg.setAttribute('viewBox', viewBox);
+ svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
+ // TODO(dfreedm): `pointer-events: none` works around https://crbug.com/370136
+ // TODO(sjmiles): inline style may not be ideal, but avoids requiring a shadow-root
+ svg.style.cssText = 'pointer-events: none; display: block; width: 100%; height: 100%;';
+ svg.appendChild(content).removeAttribute('id');
+ return svg;
+ }
+ return null;
+ }
+
+ });
+(function() {
+ 'use strict';
+
+ /**
+ * Chrome uses an older version of DOM Level 3 Keyboard Events
+ *
+ * Most keys are labeled as text, but some are Unicode codepoints.
+ * Values taken from: http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/keyset.html#KeySet-Set
+ */
+ var KEY_IDENTIFIER = {
+ 'U+0008': 'backspace',
+ 'U+0009': 'tab',
+ 'U+001B': 'esc',
+ 'U+0020': 'space',
+ 'U+007F': 'del'
+ };
+
+ /**
+ * Special table for KeyboardEvent.keyCode.
+ * KeyboardEvent.keyIdentifier is better, and KeyBoardEvent.key is even better
+ * than that.
+ *
+ * Values from: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.keyCode#Value_of_keyCode
+ */
+ var KEY_CODE = {
+ 8: 'backspace',
+ 9: 'tab',
+ 13: 'enter',
+ 27: 'esc',
+ 33: 'pageup',
+ 34: 'pagedown',
+ 35: 'end',
+ 36: 'home',
+ 32: 'space',
+ 37: 'left',
+ 38: 'up',
+ 39: 'right',
+ 40: 'down',
+ 46: 'del',
+ 106: '*'
+ };
+
+ /**
+ * MODIFIER_KEYS maps the short name for modifier keys used in a key
+ * combo string to the property name that references those same keys
+ * in a KeyboardEvent instance.
+ */
+ var MODIFIER_KEYS = {
+ 'shift': 'shiftKey',
+ 'ctrl': 'ctrlKey',
+ 'alt': 'altKey',
+ 'meta': 'metaKey'
+ };
+
+ /**
+ * Matches a keyIdentifier string.
+ */
+ var IDENT_CHAR = /U\+/;
+
+ /**
+ * Matches arrow keys in Gecko 27.0+
+ */
+ var ARROW_KEY = /^arrow/;
+
+ /**
+ * Matches space keys everywhere (notably including IE10's exceptional name
+ * `spacebar`).
+ */
+ var SPACE_KEY = /^space(bar)?/;
+
+ function transformKey(key) {
+ var validKey = '';
+ if (key) {
+ var lKey = key.toLowerCase();
+ if (lKey === ' ' || SPACE_KEY.test(lKey)) {
+ validKey = 'space';
+ } else if (lKey.length == 1) {
+ validKey = lKey;
+ } else if (ARROW_KEY.test(lKey)) {
+ validKey = lKey.replace('arrow', '');
+ } else if (lKey == 'multiply') {
+ // numpad '*' can map to Multiply on IE/Windows
+ validKey = '*';
+ } else {
+ validKey = lKey;
+ }
+ }
+ return validKey;
+ }
+
+ function transformKeyIdentifier(keyIdent) {
+ var validKey = '';
+ if (keyIdent) {
+ if (keyIdent in KEY_IDENTIFIER) {
+ validKey = KEY_IDENTIFIER[keyIdent];
+ } else if (IDENT_CHAR.test(keyIdent)) {
+ keyIdent = parseInt(keyIdent.replace('U+', '0x'), 16);
+ validKey = String.fromCharCode(keyIdent).toLowerCase();
+ } else {
+ validKey = keyIdent.toLowerCase();
+ }
+ }
+ return validKey;
+ }
+
+ function transformKeyCode(keyCode) {
+ var validKey = '';
+ if (Number(keyCode)) {
+ if (keyCode >= 65 && keyCode <= 90) {
+ // ascii a-z
+ // lowercase is 32 offset from uppercase
+ validKey = String.fromCharCode(32 + keyCode);
+ } else if (keyCode >= 112 && keyCode <= 123) {
+ // function keys f1-f12
+ validKey = 'f' + (keyCode - 112);
+ } else if (keyCode >= 48 && keyCode <= 57) {
+ // top 0-9 keys
+ validKey = String(48 - keyCode);
+ } else if (keyCode >= 96 && keyCode <= 105) {
+ // num pad 0-9
+ validKey = String(96 - keyCode);
+ } else {
+ validKey = KEY_CODE[keyCode];
+ }
+ }
+ return validKey;
+ }
+
+ function normalizedKeyForEvent(keyEvent) {
+ // fall back from .key, to .keyIdentifier, to .keyCode, and then to
+ // .detail.key to support artificial keyboard events
+ return transformKey(keyEvent.key) ||
+ transformKeyIdentifier(keyEvent.keyIdentifier) ||
+ transformKeyCode(keyEvent.keyCode) ||
+ transformKey(keyEvent.detail.key) || '';
+ }
+
+ function keyComboMatchesEvent(keyCombo, event, eventKey) {
+ return eventKey === keyCombo.key &&
+ (!keyCombo.hasModifiers || (
+ !!event.shiftKey === !!keyCombo.shiftKey &&
+ !!event.ctrlKey === !!keyCombo.ctrlKey &&
+ !!event.altKey === !!keyCombo.altKey &&
+ !!event.metaKey === !!keyCombo.metaKey)
+ );
+ }
+
+ function parseKeyComboString(keyComboString) {
+ if (keyComboString.length === 1) {
+ return {
+ combo: keyComboString,
+ key: keyComboString,
+ event: 'keydown'
+ };
+ }
+ return keyComboString.split('+').reduce(function(parsedKeyCombo, keyComboPart) {
+ var eventParts = keyComboPart.split(':');
+ var keyName = eventParts[0];
+ var event = eventParts[1];
+
+ if (keyName in MODIFIER_KEYS) {
+ parsedKeyCombo[MODIFIER_KEYS[keyName]] = true;
+ parsedKeyCombo.hasModifiers = true;
+ } else {
+ parsedKeyCombo.key = keyName;
+ parsedKeyCombo.event = event || 'keydown';
+ }
+
+ return parsedKeyCombo;
+ }, {
+ combo: keyComboString.split(':').shift()
+ });
+ }
+
+ function parseEventString(eventString) {
+ return eventString.trim().split(' ').map(function(keyComboString) {
+ return parseKeyComboString(keyComboString);
+ });
+ }
+
+ /**
+ * `Polymer.IronA11yKeysBehavior` provides a normalized interface for processing
+ * keyboard commands that pertain to [WAI-ARIA best practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding).
+ * The element takes care of browser differences with respect to Keyboard events
+ * and uses an expressive syntax to filter key presses.
+ *
+ * Use the `keyBindings` prototype property to express what combination of keys
+ * will trigger the event to fire.
+ *
+ * Use the `key-event-target` attribute to set up event handlers on a specific
+ * node.
+ * The `keys-pressed` event will fire when one of the key combinations set with the
+ * `keys` property is pressed.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronA11yKeysBehavior = {
+ properties: {
+ /**
+ * The HTMLElement that will be firing relevant KeyboardEvents.
+ */
+ keyEventTarget: {
+ type: Object,
+ value: function() {
+ return this;
+ }
+ },
+
+ /**
+ * If true, this property will cause the implementing element to
+ * automatically stop propagation on any handled KeyboardEvents.
+ */
+ stopKeyboardEventPropagation: {
+ type: Boolean,
+ value: false
+ },
+
+ _boundKeyHandlers: {
+ type: Array,
+ value: function() {
+ return [];
+ }
+ },
+
+ // We use this due to a limitation in IE10 where instances will have
+ // own properties of everything on the "prototype".
+ _imperativeKeyBindings: {
+ type: Object,
+ value: function() {
+ return {};
+ }
+ }
+ },
+
+ observers: [
+ '_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)'
+ ],
+
+ keyBindings: {},
+
+ registered: function() {
+ this._prepKeyBindings();
+ },
+
+ attached: function() {
+ this._listenKeyEventListeners();
+ },
+
+ detached: function() {
+ this._unlistenKeyEventListeners();
+ },
+
+ /**
+ * Can be used to imperatively add a key binding to the implementing
+ * element. This is the imperative equivalent of declaring a keybinding
+ * in the `keyBindings` prototype property.
+ */
+ addOwnKeyBinding: function(eventString, handlerName) {
+ this._imperativeKeyBindings[eventString] = handlerName;
+ this._prepKeyBindings();
+ this._resetKeyEventListeners();
+ },
+
+ /**
+ * When called, will remove all imperatively-added key bindings.
+ */
+ removeOwnKeyBindings: function() {
+ this._imperativeKeyBindings = {};
+ this._prepKeyBindings();
+ this._resetKeyEventListeners();
+ },
+
+ keyboardEventMatchesKeys: function(event, eventString) {
+ var keyCombos = parseEventString(eventString);
+ var eventKey = normalizedKeyForEvent(event);
+ for (var i = 0; i < keyCombos.length; ++i) {
+ if (keyComboMatchesEvent(keyCombos[i], event, eventKey)) {
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _collectKeyBindings: function() {
+ var keyBindings = this.behaviors.map(function(behavior) {
+ return behavior.keyBindings;
+ });
+
+ if (keyBindings.indexOf(this.keyBindings) === -1) {
+ keyBindings.push(this.keyBindings);
+ }
+
+ return keyBindings;
+ },
+
+ _prepKeyBindings: function() {
+ this._keyBindings = {};
+
+ this._collectKeyBindings().forEach(function(keyBindings) {
+ for (var eventString in keyBindings) {
+ this._addKeyBinding(eventString, keyBindings[eventString]);
+ }
+ }, this);
+
+ for (var eventString in this._imperativeKeyBindings) {
+ this._addKeyBinding(eventString, this._imperativeKeyBindings[eventString]);
+ }
+
+ // Give precedence to combos with modifiers to be checked first.
+ for (var eventName in this._keyBindings) {
+ this._keyBindings[eventName].sort(function (kb1, kb2) {
+ var b1 = kb1[0].hasModifiers;
+ var b2 = kb2[0].hasModifiers;
+ return (b1 === b2) ? 0 : b1 ? -1 : 1;
+ })
+ }
+ },
+
+ _addKeyBinding: function(eventString, handlerName) {
+ parseEventString(eventString).forEach(function(keyCombo) {
+ this._keyBindings[keyCombo.event] =
+ this._keyBindings[keyCombo.event] || [];
+
+ this._keyBindings[keyCombo.event].push([
+ keyCombo,
+ handlerName
+ ]);
+ }, this);
+ },
+
+ _resetKeyEventListeners: function() {
+ this._unlistenKeyEventListeners();
+
+ if (this.isAttached) {
+ this._listenKeyEventListeners();
+ }
+ },
+
+ _listenKeyEventListeners: function() {
+ Object.keys(this._keyBindings).forEach(function(eventName) {
+ var keyBindings = this._keyBindings[eventName];
+ var boundKeyHandler = this._onKeyBindingEvent.bind(this, keyBindings);
+
+ this._boundKeyHandlers.push([this.keyEventTarget, eventName, boundKeyHandler]);
+
+ this.keyEventTarget.addEventListener(eventName, boundKeyHandler);
+ }, this);
+ },
+
+ _unlistenKeyEventListeners: function() {
+ var keyHandlerTuple;
+ var keyEventTarget;
+ var eventName;
+ var boundKeyHandler;
+
+ while (this._boundKeyHandlers.length) {
+ // My kingdom for block-scope binding and destructuring assignment..
+ keyHandlerTuple = this._boundKeyHandlers.pop();
+ keyEventTarget = keyHandlerTuple[0];
+ eventName = keyHandlerTuple[1];
+ boundKeyHandler = keyHandlerTuple[2];
+
+ keyEventTarget.removeEventListener(eventName, boundKeyHandler);
+ }
+ },
+
+ _onKeyBindingEvent: function(keyBindings, event) {
+ if (this.stopKeyboardEventPropagation) {
+ event.stopPropagation();
+ }
+
+ // if event has been already prevented, don't do anything
+ if (event.defaultPrevented) {
+ return;
+ }
+
+ var eventKey = normalizedKeyForEvent(event);
+ for (var i = 0; i < keyBindings.length; i++) {
+ var keyCombo = keyBindings[i][0];
+ var handlerName = keyBindings[i][1];
+ if (keyComboMatchesEvent(keyCombo, event, eventKey)) {
+ this._triggerKeyHandler(keyCombo, handlerName, event);
+ // exit the loop if eventDefault was prevented
+ if (event.defaultPrevented) {
+ return;
+ }
+ }
+ }
+ },
+
+ _triggerKeyHandler: function(keyCombo, handlerName, keyboardEvent) {
+ var detail = Object.create(keyCombo);
+ detail.keyboardEvent = keyboardEvent;
+ var event = new CustomEvent(keyCombo.event, {
+ detail: detail,
+ cancelable: true
+ });
+ this[handlerName].call(this, event);
+ if (event.defaultPrevented) {
+ keyboardEvent.preventDefault();
+ }
+ }
+ };
+ })();
+/**
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronControlState = {
+
+ properties: {
+
+ /**
+ * If true, the element currently has focus.
+ */
+ focused: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ readOnly: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * If true, the user cannot interact with this element.
+ */
+ disabled: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ observer: '_disabledChanged',
+ reflectToAttribute: true
+ },
+
+ _oldTabIndex: {
+ type: Number
+ },
+
+ _boundFocusBlurHandler: {
+ type: Function,
+ value: function() {
+ return this._focusBlurHandler.bind(this);
+ }
+ }
+
+ },
+
+ observers: [
+ '_changedControlState(focused, disabled)'
+ ],
+
+ ready: function() {
+ this.addEventListener('focus', this._boundFocusBlurHandler, true);
+ this.addEventListener('blur', this._boundFocusBlurHandler, true);
+ },
+
+ _focusBlurHandler: function(event) {
+ // NOTE(cdata): if we are in ShadowDOM land, `event.target` will
+ // eventually become `this` due to retargeting; if we are not in
+ // ShadowDOM land, `event.target` will eventually become `this` due
+ // to the second conditional which fires a synthetic event (that is also
+ // handled). In either case, we can disregard `event.path`.
+
+ if (event.target === this) {
+ this._setFocused(event.type === 'focus');
+ } else if (!this.shadowRoot && !this.isLightDescendant(event.target)) {
+ this.fire(event.type, {sourceEvent: event}, {
+ node: this,
+ bubbles: event.bubbles,
+ cancelable: event.cancelable
+ });
+ }
+ },
+
+ _disabledChanged: function(disabled, old) {
+ this.setAttribute('aria-disabled', disabled ? 'true' : 'false');
+ this.style.pointerEvents = disabled ? 'none' : '';
+ if (disabled) {
+ this._oldTabIndex = this.tabIndex;
+ this.focused = false;
+ this.tabIndex = -1;
+ } else if (this._oldTabIndex !== undefined) {
+ this.tabIndex = this._oldTabIndex;
+ }
+ },
+
+ _changedControlState: function() {
+ // _controlStateChanged is abstract, follow-on behaviors may implement it
+ if (this._controlStateChanged) {
+ this._controlStateChanged();
+ }
+ }
+
+ };
+/**
+ * @demo demo/index.html
+ * @polymerBehavior Polymer.IronButtonState
+ */
+ Polymer.IronButtonStateImpl = {
+
+ properties: {
+
+ /**
+ * If true, the user is currently holding down the button.
+ */
+ pressed: {
+ type: Boolean,
+ readOnly: true,
+ value: false,
+ reflectToAttribute: true,
+ observer: '_pressedChanged'
+ },
+
+ /**
+ * If true, the button toggles the active state with each tap or press
+ * of the spacebar.
+ */
+ toggles: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ /**
+ * If true, the button is a toggle and is currently in the active state.
+ */
+ active: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * True if the element is currently being pressed by a "pointer," which
+ * is loosely defined as mouse or touch input (but specifically excluding
+ * keyboard input).
+ */
+ pointerDown: {
+ type: Boolean,
+ readOnly: true,
+ value: false
+ },
+
+ /**
+ * True if the input device that caused the element to receive focus
+ * was a keyboard.
+ */
+ receivedFocusFromKeyboard: {
+ type: Boolean,
+ readOnly: true
+ },
+
+ /**
+ * The aria attribute to be set if the button is a toggle and in the
+ * active state.
+ */
+ ariaActiveAttribute: {
+ type: String,
+ value: 'aria-pressed',
+ observer: '_ariaActiveAttributeChanged'
+ }
+ },
+
+ listeners: {
+ down: '_downHandler',
+ up: '_upHandler',
+ tap: '_tapHandler'
+ },
+
+ observers: [
+ '_detectKeyboardFocus(focused)',
+ '_activeChanged(active, ariaActiveAttribute)'
+ ],
+
+ keyBindings: {
+ 'enter:keydown': '_asyncClick',
+ 'space:keydown': '_spaceKeyDownHandler',
+ 'space:keyup': '_spaceKeyUpHandler',
+ },
+
+ _mouseEventRe: /^mouse/,
+
+ _tapHandler: function() {
+ if (this.toggles) {
+ // a tap is needed to toggle the active state
+ this._userActivate(!this.active);
+ } else {
+ this.active = false;
+ }
+ },
+
+ _detectKeyboardFocus: function(focused) {
+ this._setReceivedFocusFromKeyboard(!this.pointerDown && focused);
+ },
+
+ // to emulate native checkbox, (de-)activations from a user interaction fire
+ // 'change' events
+ _userActivate: function(active) {
+ if (this.active !== active) {
+ this.active = active;
+ this.fire('change');
+ }
+ },
+
+ _downHandler: function(event) {
+ this._setPointerDown(true);
+ this._setPressed(true);
+ this._setReceivedFocusFromKeyboard(false);
+ },
+
+ _upHandler: function() {
+ this._setPointerDown(false);
+ this._setPressed(false);
+ },
+
+ /**
+ * @param {!KeyboardEvent} event .
+ */
+ _spaceKeyDownHandler: function(event) {
+ var keyboardEvent = event.detail.keyboardEvent;
+ var target = Polymer.dom(keyboardEvent).localTarget;
+
+ // Ignore the event if this is coming from a focused light child, since that
+ // element will deal with it.
+ if (this.isLightDescendant(/** @type {Node} */(target)))
+ return;
+
+ keyboardEvent.preventDefault();
+ keyboardEvent.stopImmediatePropagation();
+ this._setPressed(true);
+ },
+
+ /**
+ * @param {!KeyboardEvent} event .
+ */
+ _spaceKeyUpHandler: function(event) {
+ var keyboardEvent = event.detail.keyboardEvent;
+ var target = Polymer.dom(keyboardEvent).localTarget;
+
+ // Ignore the event if this is coming from a focused light child, since that
+ // element will deal with it.
+ if (this.isLightDescendant(/** @type {Node} */(target)))
+ return;
+
+ if (this.pressed) {
+ this._asyncClick();
+ }
+ this._setPressed(false);
+ },
+
+ // trigger click asynchronously, the asynchrony is useful to allow one
+ // event handler to unwind before triggering another event
+ _asyncClick: function() {
+ this.async(function() {
+ this.click();
+ }, 1);
+ },
+
+ // any of these changes are considered a change to button state
+
+ _pressedChanged: function(pressed) {
+ this._changedButtonState();
+ },
+
+ _ariaActiveAttributeChanged: function(value, oldValue) {
+ if (oldValue && oldValue != value && this.hasAttribute(oldValue)) {
+ this.removeAttribute(oldValue);
+ }
+ },
+
+ _activeChanged: function(active, ariaActiveAttribute) {
+ if (this.toggles) {
+ this.setAttribute(this.ariaActiveAttribute,
+ active ? 'true' : 'false');
+ } else {
+ this.removeAttribute(this.ariaActiveAttribute);
+ }
+ this._changedButtonState();
+ },
+
+ _controlStateChanged: function() {
+ if (this.disabled) {
+ this._setPressed(false);
+ } else {
+ this._changedButtonState();
+ }
+ },
+
+ // provide hook for follow-on behaviors to react to button-state
+
+ _changedButtonState: function() {
+ if (this._buttonStateChanged) {
+ this._buttonStateChanged(); // abstract
+ }
+ }
+
+ };
+
+ /** @polymerBehavior */
+ Polymer.IronButtonState = [
+ Polymer.IronA11yKeysBehavior,
+ Polymer.IronButtonStateImpl
+ ];
+(function() {
+ var Utility = {
+ distance: function(x1, y1, x2, y2) {
+ var xDelta = (x1 - x2);
+ var yDelta = (y1 - y2);
+
+ return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
+ },
+
+ now: window.performance && window.performance.now ?
+ window.performance.now.bind(window.performance) : Date.now
+ };
+
+ /**
+ * @param {HTMLElement} element
+ * @constructor
+ */
+ function ElementMetrics(element) {
+ this.element = element;
+ this.width = this.boundingRect.width;
+ this.height = this.boundingRect.height;
+
+ this.size = Math.max(this.width, this.height);
+ }
+
+ ElementMetrics.prototype = {
+ get boundingRect () {
+ return this.element.getBoundingClientRect();
+ },
+
+ furthestCornerDistanceFrom: function(x, y) {
+ var topLeft = Utility.distance(x, y, 0, 0);
+ var topRight = Utility.distance(x, y, this.width, 0);
+ var bottomLeft = Utility.distance(x, y, 0, this.height);
+ var bottomRight = Utility.distance(x, y, this.width, this.height);
+
+ return Math.max(topLeft, topRight, bottomLeft, bottomRight);
+ }
+ };
+
+ /**
+ * @param {HTMLElement} element
+ * @constructor
+ */
+ function Ripple(element) {
+ this.element = element;
+ this.color = window.getComputedStyle(element).color;
+
+ this.wave = document.createElement('div');
+ this.waveContainer = document.createElement('div');
+ this.wave.style.backgroundColor = this.color;
+ this.wave.classList.add('wave');
+ this.waveContainer.classList.add('wave-container');
+ Polymer.dom(this.waveContainer).appendChild(this.wave);
+
+ this.resetInteractionState();
+ }
+
+ Ripple.MAX_RADIUS = 300;
+
+ Ripple.prototype = {
+ get recenters() {
+ return this.element.recenters;
+ },
+
+ get center() {
+ return this.element.center;
+ },
+
+ get mouseDownElapsed() {
+ var elapsed;
+
+ if (!this.mouseDownStart) {
+ return 0;
+ }
+
+ elapsed = Utility.now() - this.mouseDownStart;
+
+ if (this.mouseUpStart) {
+ elapsed -= this.mouseUpElapsed;
+ }
+
+ return elapsed;
+ },
+
+ get mouseUpElapsed() {
+ return this.mouseUpStart ?
+ Utility.now () - this.mouseUpStart : 0;
+ },
+
+ get mouseDownElapsedSeconds() {
+ return this.mouseDownElapsed / 1000;
+ },
+
+ get mouseUpElapsedSeconds() {
+ return this.mouseUpElapsed / 1000;
+ },
+
+ get mouseInteractionSeconds() {
+ return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds;
+ },
+
+ get initialOpacity() {
+ return this.element.initialOpacity;
+ },
+
+ get opacityDecayVelocity() {
+ return this.element.opacityDecayVelocity;
+ },
+
+ get radius() {
+ var width2 = this.containerMetrics.width * this.containerMetrics.width;
+ var height2 = this.containerMetrics.height * this.containerMetrics.height;
+ var waveRadius = Math.min(
+ Math.sqrt(width2 + height2),
+ Ripple.MAX_RADIUS
+ ) * 1.1 + 5;
+
+ var duration = 1.1 - 0.2 * (waveRadius / Ripple.MAX_RADIUS);
+ var timeNow = this.mouseInteractionSeconds / duration;
+ var size = waveRadius * (1 - Math.pow(80, -timeNow));
+
+ return Math.abs(size);
+ },
+
+ get opacity() {
+ if (!this.mouseUpStart) {
+ return this.initialOpacity;
+ }
+
+ return Math.max(
+ 0,
+ this.initialOpacity - this.mouseUpElapsedSeconds * this.opacityDecayVelocity
+ );
+ },
+
+ get outerOpacity() {
+ // Linear increase in background opacity, capped at the opacity
+ // of the wavefront (waveOpacity).
+ var outerOpacity = this.mouseUpElapsedSeconds * 0.3;
+ var waveOpacity = this.opacity;
+
+ return Math.max(
+ 0,
+ Math.min(outerOpacity, waveOpacity)
+ );
+ },
+
+ get isOpacityFullyDecayed() {
+ return this.opacity < 0.01 &&
+ this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
+ },
+
+ get isRestingAtMaxRadius() {
+ return this.opacity >= this.initialOpacity &&
+ this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
+ },
+
+ get isAnimationComplete() {
+ return this.mouseUpStart ?
+ this.isOpacityFullyDecayed : this.isRestingAtMaxRadius;
+ },
+
+ get translationFraction() {
+ return Math.min(
+ 1,
+ this.radius / this.containerMetrics.size * 2 / Math.sqrt(2)
+ );
+ },
+
+ get xNow() {
+ if (this.xEnd) {
+ return this.xStart + this.translationFraction * (this.xEnd - this.xStart);
+ }
+
+ return this.xStart;
+ },
+
+ get yNow() {
+ if (this.yEnd) {
+ return this.yStart + this.translationFraction * (this.yEnd - this.yStart);
+ }
+
+ return this.yStart;
+ },
+
+ get isMouseDown() {
+ return this.mouseDownStart && !this.mouseUpStart;
+ },
+
+ resetInteractionState: function() {
+ this.maxRadius = 0;
+ this.mouseDownStart = 0;
+ this.mouseUpStart = 0;
+
+ this.xStart = 0;
+ this.yStart = 0;
+ this.xEnd = 0;
+ this.yEnd = 0;
+ this.slideDistance = 0;
+
+ this.containerMetrics = new ElementMetrics(this.element);
+ },
+
+ draw: function() {
+ var scale;
+ var translateString;
+ var dx;
+ var dy;
+
+ this.wave.style.opacity = this.opacity;
+
+ scale = this.radius / (this.containerMetrics.size / 2);
+ dx = this.xNow - (this.containerMetrics.width / 2);
+ dy = this.yNow - (this.containerMetrics.height / 2);
+
+
+ // 2d transform for safari because of border-radius and overflow:hidden clipping bug.
+ // https://bugs.webkit.org/show_bug.cgi?id=98538
+ this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
+ this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
+ this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
+ this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
+ },
+
+ /** @param {Event=} event */
+ downAction: function(event) {
+ var xCenter = this.containerMetrics.width / 2;
+ var yCenter = this.containerMetrics.height / 2;
+
+ this.resetInteractionState();
+ this.mouseDownStart = Utility.now();
+
+ if (this.center) {
+ this.xStart = xCenter;
+ this.yStart = yCenter;
+ this.slideDistance = Utility.distance(
+ this.xStart, this.yStart, this.xEnd, this.yEnd
+ );
+ } else {
+ this.xStart = event ?
+ event.detail.x - this.containerMetrics.boundingRect.left :
+ this.containerMetrics.width / 2;
+ this.yStart = event ?
+ event.detail.y - this.containerMetrics.boundingRect.top :
+ this.containerMetrics.height / 2;
+ }
+
+ if (this.recenters) {
+ this.xEnd = xCenter;
+ this.yEnd = yCenter;
+ this.slideDistance = Utility.distance(
+ this.xStart, this.yStart, this.xEnd, this.yEnd
+ );
+ }
+
+ this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(
+ this.xStart,
+ this.yStart
+ );
+
+ this.waveContainer.style.top =
+ (this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px';
+ this.waveContainer.style.left =
+ (this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px';
+
+ this.waveContainer.style.width = this.containerMetrics.size + 'px';
+ this.waveContainer.style.height = this.containerMetrics.size + 'px';
+ },
+
+ /** @param {Event=} event */
+ upAction: function(event) {
+ if (!this.isMouseDown) {
+ return;
+ }
+
+ this.mouseUpStart = Utility.now();
+ },
+
+ remove: function() {
+ Polymer.dom(this.waveContainer.parentNode).removeChild(
+ this.waveContainer
+ );
+ }
+ };
+
+ Polymer({
+ is: 'paper-ripple',
+
+ behaviors: [
+ Polymer.IronA11yKeysBehavior
+ ],
+
+ properties: {
+ /**
+ * The initial opacity set on the wave.
+ *
+ * @attribute initialOpacity
+ * @type number
+ * @default 0.25
+ */
+ initialOpacity: {
+ type: Number,
+ value: 0.25
+ },
+
+ /**
+ * How fast (opacity per second) the wave fades out.
+ *
+ * @attribute opacityDecayVelocity
+ * @type number
+ * @default 0.8
+ */
+ opacityDecayVelocity: {
+ type: Number,
+ value: 0.8
+ },
+
+ /**
+ * If true, ripples will exhibit a gravitational pull towards
+ * the center of their container as they fade away.
+ *
+ * @attribute recenters
+ * @type boolean
+ * @default false
+ */
+ recenters: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, ripples will center inside its container
+ *
+ * @attribute recenters
+ * @type boolean
+ * @default false
+ */
+ center: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * A list of the visual ripples.
+ *
+ * @attribute ripples
+ * @type Array
+ * @default []
+ */
+ ripples: {
+ type: Array,
+ value: function() {
+ return [];
+ }
+ },
+
+ /**
+ * True when there are visible ripples animating within the
+ * element.
+ */
+ animating: {
+ type: Boolean,
+ readOnly: true,
+ reflectToAttribute: true,
+ value: false
+ },
+
+ /**
+ * If true, the ripple will remain in the "down" state until `holdDown`
+ * is set to false again.
+ */
+ holdDown: {
+ type: Boolean,
+ value: false,
+ observer: '_holdDownChanged'
+ },
+
+ /**
+ * If true, the ripple will not generate a ripple effect
+ * via pointer interaction.
+ * Calling ripple's imperative api like `simulatedRipple` will
+ * still generate the ripple effect.
+ */
+ noink: {
+ type: Boolean,
+ value: false
+ },
+
+ _animating: {
+ type: Boolean
+ },
+
+ _boundAnimate: {
+ type: Function,
+ value: function() {
+ return this.animate.bind(this);
+ }
+ }
+ },
+
+ get target () {
+ var ownerRoot = Polymer.dom(this).getOwnerRoot();
+ var target;
+
+ if (this.parentNode.nodeType == 11) { // DOCUMENT_FRAGMENT_NODE
+ target = ownerRoot.host;
+ } else {
+ target = this.parentNode;
+ }
+
+ return target;
+ },
+
+ keyBindings: {
+ 'enter:keydown': '_onEnterKeydown',
+ 'space:keydown': '_onSpaceKeydown',
+ 'space:keyup': '_onSpaceKeyup'
+ },
+
+ attached: function() {
+ // Set up a11yKeysBehavior to listen to key events on the target,
+ // so that space and enter activate the ripple even if the target doesn't
+ // handle key events. The key handlers deal with `noink` themselves.
+ this.keyEventTarget = this.target;
+ this.listen(this.target, 'up', 'uiUpAction');
+ this.listen(this.target, 'down', 'uiDownAction');
+ },
+
+ detached: function() {
+ this.unlisten(this.target, 'up', 'uiUpAction');
+ this.unlisten(this.target, 'down', 'uiDownAction');
+ },
+
+ get shouldKeepAnimating () {
+ for (var index = 0; index < this.ripples.length; ++index) {
+ if (!this.ripples[index].isAnimationComplete) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ simulatedRipple: function() {
+ this.downAction(null);
+
+ // Please see polymer/polymer#1305
+ this.async(function() {
+ this.upAction();
+ }, 1);
+ },
+
+ /**
+ * Provokes a ripple down effect via a UI event,
+ * respecting the `noink` property.
+ * @param {Event=} event
+ */
+ uiDownAction: function(event) {
+ if (!this.noink) {
+ this.downAction(event);
+ }
+ },
+
+ /**
+ * Provokes a ripple down effect via a UI event,
+ * *not* respecting the `noink` property.
+ * @param {Event=} event
+ */
+ downAction: function(event) {
+ if (this.holdDown && this.ripples.length > 0) {
+ return;
+ }
+
+ var ripple = this.addRipple();
+
+ ripple.downAction(event);
+
+ if (!this._animating) {
+ this.animate();
+ }
+ },
+
+ /**
+ * Provokes a ripple up effect via a UI event,
+ * respecting the `noink` property.
+ * @param {Event=} event
+ */
+ uiUpAction: function(event) {
+ if (!this.noink) {
+ this.upAction(event);
+ }
+ },
+
+ /**
+ * Provokes a ripple up effect via a UI event,
+ * *not* respecting the `noink` property.
+ * @param {Event=} event
+ */
+ upAction: function(event) {
+ if (this.holdDown) {
+ return;
+ }
+
+ this.ripples.forEach(function(ripple) {
+ ripple.upAction(event);
+ });
+
+ this.animate();
+ },
+
+ onAnimationComplete: function() {
+ this._animating = false;
+ this.$.background.style.backgroundColor = null;
+ this.fire('transitionend');
+ },
+
+ addRipple: function() {
+ var ripple = new Ripple(this);
+
+ Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
+ this.$.background.style.backgroundColor = ripple.color;
+ this.ripples.push(ripple);
+
+ this._setAnimating(true);
+
+ return ripple;
+ },
+
+ removeRipple: function(ripple) {
+ var rippleIndex = this.ripples.indexOf(ripple);
+
+ if (rippleIndex < 0) {
+ return;
+ }
+
+ this.ripples.splice(rippleIndex, 1);
+
+ ripple.remove();
+
+ if (!this.ripples.length) {
+ this._setAnimating(false);
+ }
+ },
+
+ animate: function() {
+ var index;
+ var ripple;
+
+ this._animating = true;
+
+ for (index = 0; index < this.ripples.length; ++index) {
+ ripple = this.ripples[index];
+
+ ripple.draw();
+
+ this.$.background.style.opacity = ripple.outerOpacity;
+
+ if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
+ this.removeRipple(ripple);
+ }
+ }
+
+ if (!this.shouldKeepAnimating && this.ripples.length === 0) {
+ this.onAnimationComplete();
+ } else {
+ window.requestAnimationFrame(this._boundAnimate);
+ }
+ },
+
+ _onEnterKeydown: function() {
+ this.uiDownAction();
+ this.async(this.uiUpAction, 1);
+ },
+
+ _onSpaceKeydown: function() {
+ this.uiDownAction();
+ },
+
+ _onSpaceKeyup: function() {
+ this.uiUpAction();
+ },
+
+ // note: holdDown does not respect noink since it can be a focus based
+ // effect.
+ _holdDownChanged: function(newVal, oldVal) {
+ if (oldVal === undefined) {
+ return;
+ }
+ if (newVal) {
+ this.downAction();
+ } else {
+ this.upAction();
+ }
+ }
+ });
+ })();
+/**
+ * `Polymer.PaperRippleBehavior` dynamically implements a ripple
+ * when the element has focus via pointer or keyboard.
+ *
+ * NOTE: This behavior is intended to be used in conjunction with and after
+ * `Polymer.IronButtonState` and `Polymer.IronControlState`.
+ *
+ * @polymerBehavior Polymer.PaperRippleBehavior
+ */
+ Polymer.PaperRippleBehavior = {
+
+ properties: {
+ /**
+ * If true, the element will not produce a ripple effect when interacted
+ * with via the pointer.
+ */
+ noink: {
+ type: Boolean,
+ observer: '_noinkChanged'
+ },
+
+ /**
+ * @type {Element|undefined}
+ */
+ _rippleContainer: {
+ type: Object,
+ }
+ },
+
+ /**
+ * Ensures a `<paper-ripple>` element is available when the element is
+ * focused.
+ */
+ _buttonStateChanged: function() {
+ if (this.focused) {
+ this.ensureRipple();
+ }
+ },
+
+ /**
+ * In addition to the functionality provided in `IronButtonState`, ensures
+ * a ripple effect is created when the element is in a `pressed` state.
+ */
+ _downHandler: function(event) {
+ Polymer.IronButtonStateImpl._downHandler.call(this, event);
+ if (this.pressed) {
+ this.ensureRipple(event);
+ }
+ },
+
+ /**
+ * Ensures this element contains a ripple effect. For startup efficiency
+ * the ripple effect is dynamically on demand when needed.
+ * @param {!Event=} optTriggeringEvent (optional) event that triggered the
+ * ripple.
+ */
+ ensureRipple: function(optTriggeringEvent) {
+ if (!this.hasRipple()) {
+ this._ripple = this._createRipple();
+ this._ripple.noink = this.noink;
+ var rippleContainer = this._rippleContainer || this.root;
+ if (rippleContainer) {
+ Polymer.dom(rippleContainer).appendChild(this._ripple);
+ }
+ if (optTriggeringEvent) {
+ // Check if the event happened inside of the ripple container
+ // Fall back to host instead of the root because distributed text
+ // nodes are not valid event targets
+ var domContainer = Polymer.dom(this._rippleContainer || this);
+ var target = Polymer.dom(optTriggeringEvent).rootTarget;
+ if (domContainer.deepContains( /** @type {Node} */(target))) {
+ this._ripple.uiDownAction(optTriggeringEvent);
+ }
+ }
+ }
+ },
+
+ /**
+ * Returns the `<paper-ripple>` element used by this element to create
+ * ripple effects. The element's ripple is created on demand, when
+ * necessary, and calling this method will force the
+ * ripple to be created.
+ */
+ getRipple: function() {
+ this.ensureRipple();
+ return this._ripple;
+ },
+
+ /**
+ * Returns true if this element currently contains a ripple effect.
+ * @return {boolean}
+ */
+ hasRipple: function() {
+ return Boolean(this._ripple);
+ },
+
+ /**
+ * Create the element's ripple effect via creating a `<paper-ripple>`.
+ * Override this method to customize the ripple element.
+ * @return {!PaperRippleElement} Returns a `<paper-ripple>` element.
+ */
+ _createRipple: function() {
+ return /** @type {!PaperRippleElement} */ (
+ document.createElement('paper-ripple'));
+ },
+
+ _noinkChanged: function(noink) {
+ if (this.hasRipple()) {
+ this._ripple.noink = noink;
+ }
+ }
+
+ };
+/**
+ * `Polymer.PaperInkyFocusBehavior` implements a ripple when the element has keyboard focus.
+ *
+ * @polymerBehavior Polymer.PaperInkyFocusBehavior
+ */
+ Polymer.PaperInkyFocusBehaviorImpl = {
+
+ observers: [
+ '_focusedChanged(receivedFocusFromKeyboard)'
+ ],
+
+ _focusedChanged: function(receivedFocusFromKeyboard) {
+ if (receivedFocusFromKeyboard) {
+ this.ensureRipple();
+ }
+ if (this.hasRipple()) {
+ this._ripple.holdDown = receivedFocusFromKeyboard;
+ }
+ },
+
+ _createRipple: function() {
+ var ripple = Polymer.PaperRippleBehavior._createRipple();
+ ripple.id = 'ink';
+ ripple.setAttribute('center', '');
+ ripple.classList.add('circle');
+ return ripple;
+ }
+
+ };
+
+ /** @polymerBehavior Polymer.PaperInkyFocusBehavior */
+ Polymer.PaperInkyFocusBehavior = [
+ Polymer.IronButtonState,
+ Polymer.IronControlState,
+ Polymer.PaperRippleBehavior,
+ Polymer.PaperInkyFocusBehaviorImpl
+ ];
+Polymer({
+ is: 'paper-material',
+
+ properties: {
+ /**
+ * The z-depth of this element, from 0-5. Setting to 0 will remove the
+ * shadow, and each increasing number greater than 0 will be "deeper"
+ * than the last.
+ *
+ * @attribute elevation
+ * @type number
+ * @default 1
+ */
+ elevation: {
+ type: Number,
+ reflectToAttribute: true,
+ value: 1
+ },
+
+ /**
+ * Set this to true to animate the shadow when setting a new
+ * `elevation` value.
+ *
+ * @attribute animated
+ * @type boolean
+ * @default false
+ */
+ animated: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false
+ }
+ }
+ });
+/** @polymerBehavior Polymer.PaperButtonBehavior */
+ Polymer.PaperButtonBehaviorImpl = {
+
+ properties: {
+
+ /**
+ * The z-depth of this element, from 0-5. Setting to 0 will remove the
+ * shadow, and each increasing number greater than 0 will be "deeper"
+ * than the last.
+ *
+ * @attribute elevation
+ * @type number
+ * @default 1
+ */
+ elevation: {
+ type: Number,
+ reflectToAttribute: true,
+ readOnly: true
+ }
+
+ },
+
+ observers: [
+ '_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)',
+ '_computeKeyboardClass(receivedFocusFromKeyboard)'
+ ],
+
+ hostAttributes: {
+ role: 'button',
+ tabindex: '0',
+ animated: true
+ },
+
+ _calculateElevation: function() {
+ var e = 1;
+ if (this.disabled) {
+ e = 0;
+ } else if (this.active || this.pressed) {
+ e = 4;
+ } else if (this.receivedFocusFromKeyboard) {
+ e = 3;
+ }
+ this._setElevation(e);
+ },
+
+ _computeKeyboardClass: function(receivedFocusFromKeyboard) {
+ this.classList.toggle('keyboard-focus', receivedFocusFromKeyboard);
+ },
+
+ /**
+ * In addition to `IronButtonState` behavior, when space key goes down,
+ * create a ripple down effect.
+ *
+ * @param {!KeyboardEvent} event .
+ */
+ _spaceKeyDownHandler: function(event) {
+ Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this, event);
+ if (this.hasRipple()) {
+ this._ripple.uiDownAction();
+ }
+ },
+
+ /**
+ * In addition to `IronButtonState` behavior, when space key goes up,
+ * create a ripple up effect.
+ *
+ * @param {!KeyboardEvent} event .
+ */
+ _spaceKeyUpHandler: function(event) {
+ Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this, event);
+ if (this.hasRipple()) {
+ this._ripple.uiUpAction();
+ }
+ }
+
+ };
+
+ /** @polymerBehavior */
+ Polymer.PaperButtonBehavior = [
+ Polymer.IronButtonState,
+ Polymer.IronControlState,
+ Polymer.PaperRippleBehavior,
+ Polymer.PaperButtonBehaviorImpl
+ ];
+Polymer({
+ is: 'paper-button',
+
+ behaviors: [
+ Polymer.PaperButtonBehavior
+ ],
+
+ properties: {
+ /**
+ * If true, the button should be styled with a shadow.
+ */
+ raised: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ observer: '_calculateElevation'
+ }
+ },
+
+ _calculateElevation: function() {
+ if (!this.raised) {
+ this.elevation = 0;
+ } else {
+ Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this);
+ }
+ }
+ /**
+
+ Fired when the animation finishes.
+ This is useful if you want to wait until
+ the ripple animation finishes to perform some action.
+
+ @event transitionend
+ @param {{node: Object}} detail Contains the animated node.
+ */
+ });
+/**
+ * `iron-range-behavior` provides the behavior for something with a minimum to maximum range.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronRangeBehavior = {
+
+ properties: {
+
+ /**
+ * The number that represents the current value.
+ */
+ value: {
+ type: Number,
+ value: 0,
+ notify: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * The number that indicates the minimum value of the range.
+ */
+ min: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * The number that indicates the maximum value of the range.
+ */
+ max: {
+ type: Number,
+ value: 100,
+ notify: true
+ },
+
+ /**
+ * Specifies the value granularity of the range's value.
+ */
+ step: {
+ type: Number,
+ value: 1,
+ notify: true
+ },
+
+ /**
+ * Returns the ratio of the value.
+ */
+ ratio: {
+ type: Number,
+ value: 0,
+ readOnly: true,
+ notify: true
+ },
+ },
+
+ observers: [
+ '_update(value, min, max, step)'
+ ],
+
+ _calcRatio: function(value) {
+ return (this._clampValue(value) - this.min) / (this.max - this.min);
+ },
+
+ _clampValue: function(value) {
+ return Math.min(this.max, Math.max(this.min, this._calcStep(value)));
+ },
+
+ _calcStep: function(value) {
+ /**
+ * if we calculate the step using
+ * `Math.round(value / step) * step` we may hit a precision point issue
+ * eg. 0.1 * 0.2 = 0.020000000000000004
+ * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
+ *
+ * as a work around we can divide by the reciprocal of `step`
+ */
+ // polymer/issues/2493
+ value = parseFloat(value);
+ return this.step ? (Math.round((value + this.min) / this.step) -
+ (this.min / this.step)) / (1 / this.step) : value;
+ },
+
+ _validateValue: function() {
+ var v = this._clampValue(this.value);
+ this.value = this.oldValue = isNaN(v) ? this.oldValue : v;
+ return this.value !== v;
+ },
+
+ _update: function() {
+ this._validateValue();
+ this._setRatio(this._calcRatio(this.value) * 100);
+ }
+
+};
+Polymer({
+
+ is: 'paper-progress',
+
+ behaviors: [
+ Polymer.IronRangeBehavior
+ ],
+
+ properties: {
+
+ /**
+ * The number that represents the current secondary progress.
+ */
+ secondaryProgress: {
+ type: Number,
+ value: 0
+ },
+
+ /**
+ * The secondary ratio
+ */
+ secondaryRatio: {
+ type: Number,
+ value: 0,
+ readOnly: true
+ },
+
+ /**
+ * Use an indeterminate progress indicator.
+ */
+ indeterminate: {
+ type: Boolean,
+ value: false,
+ observer: '_toggleIndeterminate'
+ },
+
+ /**
+ * True if the progress is disabled.
+ */
+ disabled: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true,
+ observer: '_disabledChanged'
+ }
+ },
+
+ observers: [
+ '_progressChanged(secondaryProgress, value, min, max)'
+ ],
+
+ hostAttributes: {
+ role: 'progressbar'
+ },
+
+ _toggleIndeterminate: function(indeterminate) {
+ // If we use attribute/class binding, the animation sometimes doesn't translate properly
+ // on Safari 7.1. So instead, we toggle the class here in the update method.
+ this.toggleClass('indeterminate', indeterminate, this.$.primaryProgress);
+ },
+
+ _transformProgress: function(progress, ratio) {
+ var transform = 'scaleX(' + (ratio / 100) + ')';
+ progress.style.transform = progress.style.webkitTransform = transform;
+ },
+
+ _mainRatioChanged: function(ratio) {
+ this._transformProgress(this.$.primaryProgress, ratio);
+ },
+
+ _progressChanged: function(secondaryProgress, value, min, max) {
+ secondaryProgress = this._clampValue(secondaryProgress);
+ value = this._clampValue(value);
+
+ var secondaryRatio = this._calcRatio(secondaryProgress) * 100;
+ var mainRatio = this._calcRatio(value) * 100;
+
+ this._setSecondaryRatio(secondaryRatio);
+ this._transformProgress(this.$.secondaryProgress, secondaryRatio);
+ this._transformProgress(this.$.primaryProgress, mainRatio);
+
+ this.secondaryProgress = secondaryProgress;
+
+ this.setAttribute('aria-valuenow', value);
+ this.setAttribute('aria-valuemin', min);
+ this.setAttribute('aria-valuemax', max);
+ },
+
+ _disabledChanged: function(disabled) {
+ this.setAttribute('aria-disabled', disabled ? 'true' : 'false');
+ },
+
+ _hideSecondaryProgress: function(secondaryRatio) {
+ return secondaryRatio === 0;
+ }
+
+ });
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('downloads', function() {
+ var InkyTextButton = Polymer({
+ is: 'inky-text-button',
+
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ hostAttributes: {
+ role: 'button',
+ tabindex: 0,
+ },
+ });
+
+ var Item = Polymer({
+ is: 'downloads-item',
+
+ properties: {
+ data: {
+ type: Object,
+ },
+
+ completelyOnDisk_: {
+ computed: 'computeCompletelyOnDisk_(' +
+ 'data.state, data.file_externally_removed)',
+ type: Boolean,
+ value: true,
+ },
+
+ controlledBy_: {
+ computed: 'computeControlledBy_(data.by_ext_id, data.by_ext_name)',
+ type: String,
+ value: '',
+ },
+
+ i18n_: {
+ readOnly: true,
+ type: Object,
+ value: function() {
+ return {
+ cancel: loadTimeData.getString('controlCancel'),
+ discard: loadTimeData.getString('dangerDiscard'),
+ pause: loadTimeData.getString('controlPause'),
+ remove: loadTimeData.getString('controlRemoveFromList'),
+ resume: loadTimeData.getString('controlResume'),
+ restore: loadTimeData.getString('dangerRestore'),
+ retry: loadTimeData.getString('controlRetry'),
+ save: loadTimeData.getString('dangerSave'),
+ };
+ },
+ },
+
+ isActive_: {
+ computed: 'computeIsActive_(' +
+ 'data.state, data.file_externally_removed)',
+ type: Boolean,
+ value: true,
+ },
+
+ isDangerous_: {
+ computed: 'computeIsDangerous_(data.state)',
+ type: Boolean,
+ value: false,
+ },
+
+ isInProgress_: {
+ computed: 'computeIsInProgress_(data.state)',
+ type: Boolean,
+ value: false,
+ },
+
+ showCancel_: {
+ computed: 'computeShowCancel_(data.state)',
+ type: Boolean,
+ value: false,
+ },
+
+ showProgress_: {
+ computed: 'computeShowProgress_(showCancel_, data.percent)',
+ type: Boolean,
+ value: false,
+ },
+
+ isMalware_: {
+ computed: 'computeIsMalware_(isDangerous_, data.danger_type)',
+ type: Boolean,
+ value: false,
+ },
+ },
+
+ observers: [
+ // TODO(dbeam): this gets called way more when I observe data.by_ext_id
+ // and data.by_ext_name directly. Why?
+ 'observeControlledBy_(controlledBy_)',
+ 'observeIsDangerous_(isDangerous_, data.file_path)',
+ ],
+
+ ready: function() {
+ this.content = this.$.content;
+ },
+
+ /** @private */
+ computeClass_: function() {
+ var classes = [];
+
+ if (this.isActive_)
+ classes.push('is-active');
+
+ if (this.isDangerous_)
+ classes.push('dangerous');
+
+ if (this.showProgress_)
+ classes.push('show-progress');
+
+ return classes.join(' ');
+ },
+
+ /** @private */
+ computeCompletelyOnDisk_: function() {
+ return this.data.state == downloads.States.COMPLETE &&
+ !this.data.file_externally_removed;
+ },
+
+ /** @private */
+ computeControlledBy_: function() {
+ if (!this.data.by_ext_id || !this.data.by_ext_name)
+ return '';
+
+ var url = 'chrome://extensions#' + this.data.by_ext_id;
+ var name = this.data.by_ext_name;
+ return loadTimeData.getStringF('controlledByUrl', url, name);
+ },
+
+ /** @private */
+ computeDangerIcon_: function() {
+ if (!this.isDangerous_)
+ return '';
+
+ switch (this.data.danger_type) {
+ case downloads.DangerType.DANGEROUS_CONTENT:
+ case downloads.DangerType.DANGEROUS_HOST:
+ case downloads.DangerType.DANGEROUS_URL:
+ case downloads.DangerType.POTENTIALLY_UNWANTED:
+ case downloads.DangerType.UNCOMMON_CONTENT:
+ return 'remove-circle';
+ default:
+ return 'warning';
+ }
+ },
+
+ /** @private */
+ computeDate_: function() {
+ assert(typeof this.data.hideDate == 'boolean');
+ if (this.data.hideDate)
+ return '';
+ return assert(this.data.since_string || this.data.date_string);
+ },
+
+ /** @private */
+ computeDescription_: function() {
+ var data = this.data;
+
+ switch (data.state) {
+ case downloads.States.DANGEROUS:
+ var fileName = data.file_name;
+ switch (data.danger_type) {
+ case downloads.DangerType.DANGEROUS_FILE:
+ return loadTimeData.getStringF('dangerFileDesc', fileName);
+ case downloads.DangerType.DANGEROUS_URL:
+ return loadTimeData.getString('dangerUrlDesc');
+ case downloads.DangerType.DANGEROUS_CONTENT: // Fall through.
+ case downloads.DangerType.DANGEROUS_HOST:
+ return loadTimeData.getStringF('dangerContentDesc', fileName);
+ case downloads.DangerType.UNCOMMON_CONTENT:
+ return loadTimeData.getStringF('dangerUncommonDesc', fileName);
+ case downloads.DangerType.POTENTIALLY_UNWANTED:
+ return loadTimeData.getStringF('dangerSettingsDesc', fileName);
+ }
+ break;
+
+ case downloads.States.IN_PROGRESS:
+ case downloads.States.PAUSED: // Fallthrough.
+ return data.progress_status_text;
+ }
+
+ return '';
+ },
+
+ /** @private */
+ computeIsActive_: function() {
+ return this.data.state != downloads.States.CANCELLED &&
+ this.data.state != downloads.States.INTERRUPTED &&
+ !this.data.file_externally_removed;
+ },
+
+ /** @private */
+ computeIsDangerous_: function() {
+ return this.data.state == downloads.States.DANGEROUS;
+ },
+
+ /** @private */
+ computeIsInProgress_: function() {
+ return this.data.state == downloads.States.IN_PROGRESS;
+ },
+
+ /** @private */
+ computeIsMalware_: function() {
+ return this.isDangerous_ &&
+ (this.data.danger_type == downloads.DangerType.DANGEROUS_CONTENT ||
+ this.data.danger_type == downloads.DangerType.DANGEROUS_HOST ||
+ this.data.danger_type == downloads.DangerType.DANGEROUS_URL ||
+ this.data.danger_type == downloads.DangerType.POTENTIALLY_UNWANTED);
+ },
+
+ /** @private */
+ computeRemoveStyle_: function() {
+ var canDelete = loadTimeData.getBoolean('allowDeletingHistory');
+ var hideRemove = this.isDangerous_ || this.showCancel_ || !canDelete;
+ return hideRemove ? 'visibility: hidden' : '';
+ },
+
+ /** @private */
+ computeShowCancel_: function() {
+ return this.data.state == downloads.States.IN_PROGRESS ||
+ this.data.state == downloads.States.PAUSED;
+ },
+
+ /** @private */
+ computeShowProgress_: function() {
+ return this.showCancel_ && this.data.percent >= -1;
+ },
+
+ /** @private */
+ computeTag_: function() {
+ switch (this.data.state) {
+ case downloads.States.CANCELLED:
+ return loadTimeData.getString('statusCancelled');
+
+ case downloads.States.INTERRUPTED:
+ return this.data.last_reason_text;
+
+ case downloads.States.COMPLETE:
+ return this.data.file_externally_removed ?
+ loadTimeData.getString('statusRemoved') : '';
+ }
+
+ return '';
+ },
+
+ /** @private */
+ isIndeterminate_: function() {
+ return this.data.percent == -1;
+ },
+
+ /** @private */
+ observeControlledBy_: function() {
+ this.$['controlled-by'].innerHTML = this.controlledBy_;
+ },
+
+ /** @private */
+ observeIsDangerous_: function() {
+ if (this.data && !this.isDangerous_) {
+ var filePath = encodeURIComponent(this.data.file_path);
+ var scaleFactor = '?scale=' + window.devicePixelRatio + 'x';
+ this.$['file-icon'].src = 'chrome://fileicon/' + filePath + scaleFactor;
+ }
+ },
+
+ /** @private */
+ onCancelTap_: function() {
+ downloads.ActionService.getInstance().cancel(this.data.id);
+ },
+
+ /** @private */
+ onDiscardDangerousTap_: function() {
+ downloads.ActionService.getInstance().discardDangerous(this.data.id);
+ },
+
+ /**
+ * @private
+ * @param {Event} e
+ */
+ onDragStart_: function(e) {
+ e.preventDefault();
+ downloads.ActionService.getInstance().drag(this.data.id);
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ onFileLinkTap_: function(e) {
+ e.preventDefault();
+ downloads.ActionService.getInstance().openFile(this.data.id);
+ },
+
+ /** @private */
+ onPauseTap_: function() {
+ downloads.ActionService.getInstance().pause(this.data.id);
+ },
+
+ /** @private */
+ onRemoveTap_: function() {
+ downloads.ActionService.getInstance().remove(this.data.id);
+ },
+
+ /** @private */
+ onResumeTap_: function() {
+ downloads.ActionService.getInstance().resume(this.data.id);
+ },
+
+ /** @private */
+ onRetryTap_: function() {
+ downloads.ActionService.getInstance().download(this.data.url);
+ },
+
+ /** @private */
+ onSaveDangerousTap_: function() {
+ downloads.ActionService.getInstance().saveDangerous(this.data.id);
+ },
+
+ /** @private */
+ onShowTap_: function() {
+ downloads.ActionService.getInstance().show(this.data.id);
+ },
+ });
+
+ return {
+ InkyTextButton: InkyTextButton,
+ Item: Item,
+ };
+});
+/** @polymerBehavior Polymer.PaperItemBehavior */
+ Polymer.PaperItemBehaviorImpl = {
+ hostAttributes: {
+ role: 'option',
+ tabindex: '0'
+ }
+ };
+
+ /** @polymerBehavior */
+ Polymer.PaperItemBehavior = [
+ Polymer.IronControlState,
+ Polymer.IronButtonState,
+ Polymer.PaperItemBehaviorImpl
+ ];
+Polymer({
+ is: 'paper-item',
+
+ behaviors: [
+ Polymer.PaperItemBehavior
+ ]
+ });
+/**
+ * @param {!Function} selectCallback
+ * @constructor
+ */
+ Polymer.IronSelection = function(selectCallback) {
+ this.selection = [];
+ this.selectCallback = selectCallback;
+ };
+
+ Polymer.IronSelection.prototype = {
+
+ /**
+ * Retrieves the selected item(s).
+ *
+ * @method get
+ * @returns Returns the selected item(s). If the multi property is true,
+ * `get` will return an array, otherwise it will return
+ * the selected item or undefined if there is no selection.
+ */
+ get: function() {
+ return this.multi ? this.selection.slice() : this.selection[0];
+ },
+
+ /**
+ * Clears all the selection except the ones indicated.
+ *
+ * @method clear
+ * @param {Array} excludes items to be excluded.
+ */
+ clear: function(excludes) {
+ this.selection.slice().forEach(function(item) {
+ if (!excludes || excludes.indexOf(item) < 0) {
+ this.setItemSelected(item, false);
+ }
+ }, this);
+ },
+
+ /**
+ * Indicates if a given item is selected.
+ *
+ * @method isSelected
+ * @param {*} item The item whose selection state should be checked.
+ * @returns Returns true if `item` is selected.
+ */
+ isSelected: function(item) {
+ return this.selection.indexOf(item) >= 0;
+ },
+
+ /**
+ * Sets the selection state for a given item to either selected or deselected.
+ *
+ * @method setItemSelected
+ * @param {*} item The item to select.
+ * @param {boolean} isSelected True for selected, false for deselected.
+ */
+ setItemSelected: function(item, isSelected) {
+ if (item != null) {
+ if (isSelected) {
+ this.selection.push(item);
+ } else {
+ var i = this.selection.indexOf(item);
+ if (i >= 0) {
+ this.selection.splice(i, 1);
+ }
+ }
+ if (this.selectCallback) {
+ this.selectCallback(item, isSelected);
+ }
+ }
+ },
+
+ /**
+ * Sets the selection state for a given item. If the `multi` property
+ * is true, then the selected state of `item` will be toggled; otherwise
+ * the `item` will be selected.
+ *
+ * @method select
+ * @param {*} item The item to select.
+ */
+ select: function(item) {
+ if (this.multi) {
+ this.toggle(item);
+ } else if (this.get() !== item) {
+ this.setItemSelected(this.get(), false);
+ this.setItemSelected(item, true);
+ }
+ },
+
+ /**
+ * Toggles the selection state for `item`.
+ *
+ * @method toggle
+ * @param {*} item The item to toggle.
+ */
+ toggle: function(item) {
+ this.setItemSelected(item, !this.isSelected(item));
+ }
+
+ };
+/** @polymerBehavior */
+ Polymer.IronSelectableBehavior = {
+
+ /**
+ * Fired when iron-selector is activated (selected or deselected).
+ * It is fired before the selected items are changed.
+ * Cancel the event to abort selection.
+ *
+ * @event iron-activate
+ */
+
+ /**
+ * Fired when an item is selected
+ *
+ * @event iron-select
+ */
+
+ /**
+ * Fired when an item is deselected
+ *
+ * @event iron-deselect
+ */
+
+ /**
+ * Fired when the list of selectable items changes (e.g., items are
+ * added or removed). The detail of the event is a list of mutation
+ * records that describe what changed.
+ *
+ * @event iron-items-changed
+ */
+
+ properties: {
+
+ /**
+ * If you want to use the attribute value of an element for `selected` instead of the index,
+ * set this to the name of the attribute.
+ */
+ attrForSelected: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * Gets or sets the selected element. The default is to use the index of the item.
+ */
+ selected: {
+ type: String,
+ notify: true
+ },
+
+ /**
+ * Returns the currently selected item.
+ *
+ * @type {?Object}
+ */
+ selectedItem: {
+ type: Object,
+ readOnly: true,
+ notify: true
+ },
+
+ /**
+ * The event that fires from items when they are selected. Selectable
+ * will listen for this event from items and update the selection state.
+ * Set to empty string to listen to no events.
+ */
+ activateEvent: {
+ type: String,
+ value: 'tap',
+ observer: '_activateEventChanged'
+ },
+
+ /**
+ * This is a CSS selector string. If this is set, only items that match the CSS selector
+ * are selectable.
+ */
+ selectable: String,
+
+ /**
+ * The class to set on elements when selected.
+ */
+ selectedClass: {
+ type: String,
+ value: 'iron-selected'
+ },
+
+ /**
+ * The attribute to set on elements when selected.
+ */
+ selectedAttribute: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * The list of items from which a selection can be made.
+ */
+ items: {
+ type: Array,
+ readOnly: true,
+ value: function() {
+ return [];
+ }
+ },
+
+ /**
+ * The set of excluded elements where the key is the `localName`
+ * of the element that will be ignored from the item list.
+ *
+ * @default {template: 1}
+ */
+ _excludedLocalNames: {
+ type: Object,
+ value: function() {
+ return {
+ 'template': 1
+ };
+ }
+ }
+ },
+
+ observers: [
+ '_updateSelected(attrForSelected, selected)'
+ ],
+
+ created: function() {
+ this._bindFilterItem = this._filterItem.bind(this);
+ this._selection = new Polymer.IronSelection(this._applySelection.bind(this));
+ },
+
+ attached: function() {
+ this._observer = this._observeItems(this);
+ this._updateItems();
+ if (!this._shouldUpdateSelection) {
+ this._updateSelected(this.attrForSelected,this.selected)
+ }
+ this._addListener(this.activateEvent);
+ },
+
+ detached: function() {
+ if (this._observer) {
+ Polymer.dom(this).unobserveNodes(this._observer);
+ }
+ this._removeListener(this.activateEvent);
+ },
+
+ /**
+ * Returns the index of the given item.
+ *
+ * @method indexOf
+ * @param {Object} item
+ * @returns Returns the index of the item
+ */
+ indexOf: function(item) {
+ return this.items.indexOf(item);
+ },
+
+ /**
+ * Selects the given value.
+ *
+ * @method select
+ * @param {string} value the value to select.
+ */
+ select: function(value) {
+ this.selected = value;
+ },
+
+ /**
+ * Selects the previous item.
+ *
+ * @method selectPrevious
+ */
+ selectPrevious: function() {
+ var length = this.items.length;
+ var index = (Number(this._valueToIndex(this.selected)) - 1 + length) % length;
+ this.selected = this._indexToValue(index);
+ },
+
+ /**
+ * Selects the next item.
+ *
+ * @method selectNext
+ */
+ selectNext: function() {
+ var index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.length;
+ this.selected = this._indexToValue(index);
+ },
+
+ get _shouldUpdateSelection() {
+ return this.selected != null;
+ },
+
+ _addListener: function(eventName) {
+ this.listen(this, eventName, '_activateHandler');
+ },
+
+ _removeListener: function(eventName) {
+ this.unlisten(this, eventName, '_activateHandler');
+ },
+
+ _activateEventChanged: function(eventName, old) {
+ this._removeListener(old);
+ this._addListener(eventName);
+ },
+
+ _updateItems: function() {
+ var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
+ nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
+ this._setItems(nodes);
+ },
+
+ _updateSelected: function() {
+ this._selectSelected(this.selected);
+ },
+
+ _selectSelected: function(selected) {
+ this._selection.select(this._valueToItem(this.selected));
+ },
+
+ _filterItem: function(node) {
+ return !this._excludedLocalNames[node.localName];
+ },
+
+ _valueToItem: function(value) {
+ return (value == null) ? null : this.items[this._valueToIndex(value)];
+ },
+
+ _valueToIndex: function(value) {
+ if (this.attrForSelected) {
+ for (var i = 0, item; item = this.items[i]; i++) {
+ if (this._valueForItem(item) == value) {
+ return i;
+ }
+ }
+ } else {
+ return Number(value);
+ }
+ },
+
+ _indexToValue: function(index) {
+ if (this.attrForSelected) {
+ var item = this.items[index];
+ if (item) {
+ return this._valueForItem(item);
+ }
+ } else {
+ return index;
+ }
+ },
+
+ _valueForItem: function(item) {
+ return item[this.attrForSelected] || item.getAttribute(this.attrForSelected);
+ },
+
+ _applySelection: function(item, isSelected) {
+ if (this.selectedClass) {
+ this.toggleClass(this.selectedClass, isSelected, item);
+ }
+ if (this.selectedAttribute) {
+ this.toggleAttribute(this.selectedAttribute, isSelected, item);
+ }
+ this._selectionChange();
+ this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item});
+ },
+
+ _selectionChange: function() {
+ this._setSelectedItem(this._selection.get());
+ },
+
+ // observe items change under the given node.
+ _observeItems: function(node) {
+ return Polymer.dom(node).observeNodes(function(mutations) {
+ // Let other interested parties know about the change so that
+ // we don't have to recreate mutation observers everywher.
+ this.fire('iron-items-changed', mutations, {
+ bubbles: false,
+ cancelable: false
+ });
+
+ this._updateItems();
+
+ if (this._shouldUpdateSelection) {
+ this._updateSelected();
+ }
+ });
+ },
+
+ _activateHandler: function(e) {
+ var t = e.target;
+ var items = this.items;
+ while (t && t != this) {
+ var i = items.indexOf(t);
+ if (i >= 0) {
+ var value = this._indexToValue(i);
+ this._itemActivate(value, t);
+ return;
+ }
+ t = t.parentNode;
+ }
+ },
+
+ _itemActivate: function(value, item) {
+ if (!this.fire('iron-activate',
+ {selected: value, item: item}, {cancelable: true}).defaultPrevented) {
+ this.select(value);
+ }
+ }
+
+ };
+/** @polymerBehavior Polymer.IronMultiSelectableBehavior */
+ Polymer.IronMultiSelectableBehaviorImpl = {
+ properties: {
+
+ /**
+ * If true, multiple selections are allowed.
+ */
+ multi: {
+ type: Boolean,
+ value: false,
+ observer: 'multiChanged'
+ },
+
+ /**
+ * Gets or sets the selected elements. This is used instead of `selected` when `multi`
+ * is true.
+ */
+ selectedValues: {
+ type: Array,
+ notify: true
+ },
+
+ /**
+ * Returns an array of currently selected items.
+ */
+ selectedItems: {
+ type: Array,
+ readOnly: true,
+ notify: true
+ },
+
+ },
+
+ observers: [
+ '_updateSelected(attrForSelected, selectedValues)'
+ ],
+
+ /**
+ * Selects the given value. If the `multi` property is true, then the selected state of the
+ * `value` will be toggled; otherwise the `value` will be selected.
+ *
+ * @method select
+ * @param {string} value the value to select.
+ */
+ select: function(value) {
+ if (this.multi) {
+ if (this.selectedValues) {
+ this._toggleSelected(value);
+ } else {
+ this.selectedValues = [value];
+ }
+ } else {
+ this.selected = value;
+ }
+ },
+
+ multiChanged: function(multi) {
+ this._selection.multi = multi;
+ },
+
+ get _shouldUpdateSelection() {
+ return this.selected != null ||
+ (this.selectedValues != null && this.selectedValues.length);
+ },
+
+ _updateSelected: function() {
+ if (this.multi) {
+ this._selectMulti(this.selectedValues);
+ } else {
+ this._selectSelected(this.selected);
+ }
+ },
+
+ _selectMulti: function(values) {
+ this._selection.clear();
+ if (values) {
+ for (var i = 0; i < values.length; i++) {
+ this._selection.setItemSelected(this._valueToItem(values[i]), true);
+ }
+ }
+ },
+
+ _selectionChange: function() {
+ var s = this._selection.get();
+ if (this.multi) {
+ this._setSelectedItems(s);
+ } else {
+ this._setSelectedItems([s]);
+ this._setSelectedItem(s);
+ }
+ },
+
+ _toggleSelected: function(value) {
+ var i = this.selectedValues.indexOf(value);
+ var unselected = i < 0;
+ if (unselected) {
+ this.push('selectedValues',value);
+ } else {
+ this.splice('selectedValues',i,1);
+ }
+ this._selection.setItemSelected(this._valueToItem(value), unselected);
+ }
+ };
+
+ /** @polymerBehavior */
+ Polymer.IronMultiSelectableBehavior = [
+ Polymer.IronSelectableBehavior,
+ Polymer.IronMultiSelectableBehaviorImpl
+ ];
+/**
+ * `Polymer.IronMenuBehavior` implements accessible menu behavior.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior Polymer.IronMenuBehavior
+ */
+ Polymer.IronMenuBehaviorImpl = {
+
+ properties: {
+
+ /**
+ * Returns the currently focused item.
+ * @type {?Object}
+ */
+ focusedItem: {
+ observer: '_focusedItemChanged',
+ readOnly: true,
+ type: Object
+ },
+
+ /**
+ * The attribute to use on menu items to look up the item title. Typing the first
+ * letter of an item when the menu is open focuses that item. If unset, `textContent`
+ * will be used.
+ */
+ attrForItemTitle: {
+ type: String
+ }
+ },
+
+ hostAttributes: {
+ 'role': 'menu',
+ 'tabindex': '0'
+ },
+
+ observers: [
+ '_updateMultiselectable(multi)'
+ ],
+
+ listeners: {
+ 'focus': '_onFocus',
+ 'keydown': '_onKeydown',
+ 'iron-items-changed': '_onIronItemsChanged'
+ },
+
+ keyBindings: {
+ 'up': '_onUpKey',
+ 'down': '_onDownKey',
+ 'esc': '_onEscKey',
+ 'shift+tab:keydown': '_onShiftTabDown'
+ },
+
+ attached: function() {
+ this._resetTabindices();
+ },
+
+ /**
+ * Selects the given value. If the `multi` property is true, then the selected state of the
+ * `value` will be toggled; otherwise the `value` will be selected.
+ *
+ * @param {string} value the value to select.
+ */
+ select: function(value) {
+ if (this._defaultFocusAsync) {
+ this.cancelAsync(this._defaultFocusAsync);
+ this._defaultFocusAsync = null;
+ }
+ var item = this._valueToItem(value);
+ if (item && item.hasAttribute('disabled')) return;
+ this._setFocusedItem(item);
+ Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
+ },
+
+ /**
+ * Resets all tabindex attributes to the appropriate value based on the
+ * current selection state. The appropriate value is `0` (focusable) for
+ * the default selected item, and `-1` (not keyboard focusable) for all
+ * other items.
+ */
+ _resetTabindices: function() {
+ var selectedItem = this.multi ? (this.selectedItems && this.selectedItems[0]) : this.selectedItem;
+
+ this.items.forEach(function(item) {
+ item.setAttribute('tabindex', item === selectedItem ? '0' : '-1');
+ }, this);
+ },
+
+ /**
+ * Sets appropriate ARIA based on whether or not the menu is meant to be
+ * multi-selectable.
+ *
+ * @param {boolean} multi True if the menu should be multi-selectable.
+ */
+ _updateMultiselectable: function(multi) {
+ if (multi) {
+ this.setAttribute('aria-multiselectable', 'true');
+ } else {
+ this.removeAttribute('aria-multiselectable');
+ }
+ },
+
+ /**
+ * Given a KeyboardEvent, this method will focus the appropriate item in the
+ * menu (if there is a relevant item, and it is possible to focus it).
+ *
+ * @param {KeyboardEvent} event A KeyboardEvent.
+ */
+ _focusWithKeyboardEvent: function(event) {
+ for (var i = 0, item; item = this.items[i]; i++) {
+ var attr = this.attrForItemTitle || 'textContent';
+ var title = item[attr] || item.getAttribute(attr);
+
+ if (title && title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
+ this._setFocusedItem(item);
+ break;
+ }
+ }
+ },
+
+ /**
+ * Focuses the previous item (relative to the currently focused item) in the
+ * menu.
+ */
+ _focusPrevious: function() {
+ var length = this.items.length;
+ var index = (Number(this.indexOf(this.focusedItem)) - 1 + length) % length;
+ this._setFocusedItem(this.items[index]);
+ },
+
+ /**
+ * Focuses the next item (relative to the currently focused item) in the
+ * menu.
+ */
+ _focusNext: function() {
+ var index = (Number(this.indexOf(this.focusedItem)) + 1) % this.items.length;
+ this._setFocusedItem(this.items[index]);
+ },
+
+ /**
+ * Mutates items in the menu based on provided selection details, so that
+ * all items correctly reflect selection state.
+ *
+ * @param {Element} item An item in the menu.
+ * @param {boolean} isSelected True if the item should be shown in a
+ * selected state, otherwise false.
+ */
+ _applySelection: function(item, isSelected) {
+ if (isSelected) {
+ item.setAttribute('aria-selected', 'true');
+ } else {
+ item.removeAttribute('aria-selected');
+ }
+ Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
+ },
+
+ /**
+ * Discretely updates tabindex values among menu items as the focused item
+ * changes.
+ *
+ * @param {Element} focusedItem The element that is currently focused.
+ * @param {?Element} old The last element that was considered focused, if
+ * applicable.
+ */
+ _focusedItemChanged: function(focusedItem, old) {
+ old && old.setAttribute('tabindex', '-1');
+ if (focusedItem) {
+ focusedItem.setAttribute('tabindex', '0');
+ focusedItem.focus();
+ }
+ },
+
+ /**
+ * A handler that responds to mutation changes related to the list of items
+ * in the menu.
+ *
+ * @param {CustomEvent} event An event containing mutation records as its
+ * detail.
+ */
+ _onIronItemsChanged: function(event) {
+ var mutations = event.detail;
+ var mutation;
+ var index;
+
+ for (index = 0; index < mutations.length; ++index) {
+ mutation = mutations[index];
+
+ if (mutation.addedNodes.length) {
+ this._resetTabindices();
+ break;
+ }
+ }
+ },
+
+ /**
+ * Handler that is called when a shift+tab keypress is detected by the menu.
+ *
+ * @param {CustomEvent} event A key combination event.
+ */
+ _onShiftTabDown: function(event) {
+ var oldTabIndex = this.getAttribute('tabindex');
+
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
+
+ this._setFocusedItem(null);
+
+ this.setAttribute('tabindex', '-1');
+
+ this.async(function() {
+ this.setAttribute('tabindex', oldTabIndex);
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
+ // NOTE(cdata): polymer/polymer#1305
+ }, 1);
+ },
+
+ /**
+ * Handler that is called when the menu receives focus.
+ *
+ * @param {FocusEvent} event A focus event.
+ */
+ _onFocus: function(event) {
+ if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
+ // do not focus the menu itself
+ return;
+ }
+
+ this.blur();
+
+ // clear the cached focus item
+ this._defaultFocusAsync = this.async(function() {
+ // focus the selected item when the menu receives focus, or the first item
+ // if no item is selected
+ var selectedItem = this.multi ? (this.selectedItems && this.selectedItems[0]) : this.selectedItem;
+
+ this._setFocusedItem(null);
+
+ if (selectedItem) {
+ this._setFocusedItem(selectedItem);
+ } else {
+ this._setFocusedItem(this.items[0]);
+ }
+ // async 1ms to wait for `select` to get called from `_itemActivate`
+ }, 1);
+ },
+
+ /**
+ * Handler that is called when the up key is pressed.
+ *
+ * @param {CustomEvent} event A key combination event.
+ */
+ _onUpKey: function(event) {
+ // up and down arrows moves the focus
+ this._focusPrevious();
+ },
+
+ /**
+ * Handler that is called when the down key is pressed.
+ *
+ * @param {CustomEvent} event A key combination event.
+ */
+ _onDownKey: function(event) {
+ this._focusNext();
+ },
+
+ /**
+ * Handler that is called when the esc key is pressed.
+ *
+ * @param {CustomEvent} event A key combination event.
+ */
+ _onEscKey: function(event) {
+ // esc blurs the control
+ this.focusedItem.blur();
+ },
+
+ /**
+ * Handler that is called when a keydown event is detected.
+ *
+ * @param {KeyboardEvent} event A keyboard event.
+ */
+ _onKeydown: function(event) {
+ if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {
+ // all other keys focus the menu item starting with that character
+ this._focusWithKeyboardEvent(event);
+ }
+ event.stopPropagation();
+ },
+
+ // override _activateHandler
+ _activateHandler: function(event) {
+ Polymer.IronSelectableBehavior._activateHandler.call(this, event);
+ event.stopPropagation();
+ }
+ };
+
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
+
+ /** @polymerBehavior Polymer.IronMenuBehavior */
+ Polymer.IronMenuBehavior = [
+ Polymer.IronMultiSelectableBehavior,
+ Polymer.IronA11yKeysBehavior,
+ Polymer.IronMenuBehaviorImpl
+ ];
+(function() {
+ Polymer({
+ is: 'paper-menu',
+
+ behaviors: [
+ Polymer.IronMenuBehavior
+ ]
+ });
+ })();
+/**
+Polymer.IronFitBehavior fits an element in another element using `max-height` and `max-width`, and
+optionally centers it in the window or another element.
+
+The element will only be sized and/or positioned if it has not already been sized and/or positioned
+by CSS.
+
+CSS properties | Action
+-----------------------------|-------------------------------------------
+`position` set | Element is not centered horizontally or vertically
+`top` or `bottom` set | Element is not vertically centered
+`left` or `right` set | Element is not horizontally centered
+`max-height` or `height` set | Element respects `max-height` or `height`
+`max-width` or `width` set | Element respects `max-width` or `width`
+
+@demo demo/index.html
+@polymerBehavior
+*/
+
+ Polymer.IronFitBehavior = {
+
+ properties: {
+
+ /**
+ * The element that will receive a `max-height`/`width`. By default it is the same as `this`,
+ * but it can be set to a child element. This is useful, for example, for implementing a
+ * scrolling region inside the element.
+ * @type {!Element}
+ */
+ sizingTarget: {
+ type: Object,
+ value: function() {
+ return this;
+ }
+ },
+
+ /**
+ * The element to fit `this` into.
+ */
+ fitInto: {
+ type: Object,
+ value: window
+ },
+
+ /**
+ * Set to true to auto-fit on attach.
+ */
+ autoFitOnAttach: {
+ type: Boolean,
+ value: false
+ },
+
+ /** @type {?Object} */
+ _fitInfo: {
+ type: Object
+ }
+
+ },
+
+ get _fitWidth() {
+ var fitWidth;
+ if (this.fitInto === window) {
+ fitWidth = this.fitInto.innerWidth;
+ } else {
+ fitWidth = this.fitInto.getBoundingClientRect().width;
+ }
+ return fitWidth;
+ },
+
+ get _fitHeight() {
+ var fitHeight;
+ if (this.fitInto === window) {
+ fitHeight = this.fitInto.innerHeight;
+ } else {
+ fitHeight = this.fitInto.getBoundingClientRect().height;
+ }
+ return fitHeight;
+ },
+
+ get _fitLeft() {
+ var fitLeft;
+ if (this.fitInto === window) {
+ fitLeft = 0;
+ } else {
+ fitLeft = this.fitInto.getBoundingClientRect().left;
+ }
+ return fitLeft;
+ },
+
+ get _fitTop() {
+ var fitTop;
+ if (this.fitInto === window) {
+ fitTop = 0;
+ } else {
+ fitTop = this.fitInto.getBoundingClientRect().top;
+ }
+ return fitTop;
+ },
+
+ attached: function() {
+ if (this.autoFitOnAttach) {
+ if (window.getComputedStyle(this).display === 'none') {
+ setTimeout(function() {
+ this.fit();
+ }.bind(this));
+ } else {
+ this.fit();
+ }
+ }
+ },
+
+ /**
+ * Fits and optionally centers the element into the window, or `fitInfo` if specified.
+ */
+ fit: function() {
+ this._discoverInfo();
+ this.constrain();
+ this.center();
+ },
+
+ /**
+ * Memoize information needed to position and size the target element.
+ */
+ _discoverInfo: function() {
+ if (this._fitInfo) {
+ return;
+ }
+ var target = window.getComputedStyle(this);
+ var sizer = window.getComputedStyle(this.sizingTarget);
+ this._fitInfo = {
+ inlineStyle: {
+ top: this.style.top || '',
+ left: this.style.left || ''
+ },
+ positionedBy: {
+ vertically: target.top !== 'auto' ? 'top' : (target.bottom !== 'auto' ?
+ 'bottom' : null),
+ horizontally: target.left !== 'auto' ? 'left' : (target.right !== 'auto' ?
+ 'right' : null),
+ css: target.position
+ },
+ sizedBy: {
+ height: sizer.maxHeight !== 'none',
+ width: sizer.maxWidth !== 'none'
+ },
+ margin: {
+ top: parseInt(target.marginTop, 10) || 0,
+ right: parseInt(target.marginRight, 10) || 0,
+ bottom: parseInt(target.marginBottom, 10) || 0,
+ left: parseInt(target.marginLeft, 10) || 0
+ }
+ };
+ },
+
+ /**
+ * Resets the target element's position and size constraints, and clear
+ * the memoized data.
+ */
+ resetFit: function() {
+ if (!this._fitInfo || !this._fitInfo.sizedBy.height) {
+ this.sizingTarget.style.maxHeight = '';
+ this.style.top = this._fitInfo ? this._fitInfo.inlineStyle.top : '';
+ }
+ if (!this._fitInfo || !this._fitInfo.sizedBy.width) {
+ this.sizingTarget.style.maxWidth = '';
+ this.style.left = this._fitInfo ? this._fitInfo.inlineStyle.left : '';
+ }
+ if (this._fitInfo) {
+ this.style.position = this._fitInfo.positionedBy.css;
+ }
+ this._fitInfo = null;
+ },
+
+ /**
+ * Equivalent to calling `resetFit()` and `fit()`. Useful to call this after the element,
+ * the window, or the `fitInfo` element has been resized.
+ */
+ refit: function() {
+ this.resetFit();
+ this.fit();
+ },
+
+ /**
+ * Constrains the size of the element to the window or `fitInfo` by setting `max-height`
+ * and/or `max-width`.
+ */
+ constrain: function() {
+ var info = this._fitInfo;
+ // position at (0px, 0px) if not already positioned, so we can measure the natural size.
+ if (!this._fitInfo.positionedBy.vertically) {
+ this.style.top = '0px';
+ }
+ if (!this._fitInfo.positionedBy.horizontally) {
+ this.style.left = '0px';
+ }
+ if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy.horizontally) {
+ // need position:fixed to properly size the element
+ this.style.position = 'fixed';
+ }
+ // need border-box for margin/padding
+ this.sizingTarget.style.boxSizing = 'border-box';
+ // constrain the width and height if not already set
+ var rect = this.getBoundingClientRect();
+ if (!info.sizedBy.height) {
+ this._sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom', 'Height');
+ }
+ if (!info.sizedBy.width) {
+ this._sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right', 'Width');
+ }
+ },
+
+ _sizeDimension: function(rect, positionedBy, start, end, extent) {
+ var info = this._fitInfo;
+ var max = extent === 'Width' ? this._fitWidth : this._fitHeight;
+ var flip = (positionedBy === end);
+ var offset = flip ? max - rect[end] : rect[start];
+ var margin = info.margin[flip ? start : end];
+ var offsetExtent = 'offset' + extent;
+ var sizingOffset = this[offsetExtent] - this.sizingTarget[offsetExtent];
+ this.sizingTarget.style['max' + extent] = (max - margin - offset - sizingOffset) + 'px';
+ },
+
+ /**
+ * Centers horizontally and vertically if not already positioned. This also sets
+ * `position:fixed`.
+ */
+ center: function() {
+ if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy.horizontally) {
+ // need position:fixed to center
+ this.style.position = 'fixed';
+ }
+ if (!this._fitInfo.positionedBy.vertically) {
+ var top = (this._fitHeight - this.offsetHeight) / 2 + this._fitTop;
+ top -= this._fitInfo.margin.top;
+ this.style.top = top + 'px';
+ }
+ if (!this._fitInfo.positionedBy.horizontally) {
+ var left = (this._fitWidth - this.offsetWidth) / 2 + this._fitLeft;
+ left -= this._fitInfo.margin.left;
+ this.style.left = left + 'px';
+ }
+ }
+
+ };
+Polymer.IronOverlayManager = {
+
+ _overlays: [],
+
+ // iframes have a default z-index of 100, so this default should be at least
+ // that.
+ _minimumZ: 101,
+
+ _backdrops: [],
+
+ _applyOverlayZ: function(overlay, aboveZ) {
+ this._setZ(overlay, aboveZ + 2);
+ },
+
+ _setZ: function(element, z) {
+ element.style.zIndex = z;
+ },
+
+ // track overlays for z-index and focus managemant
+ addOverlay: function(overlay) {
+ var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ);
+ this._overlays.push(overlay);
+ var newZ = this.currentOverlayZ();
+ if (newZ <= minimumZ) {
+ this._applyOverlayZ(overlay, minimumZ);
+ }
+ },
+
+ removeOverlay: function(overlay) {
+ var i = this._overlays.indexOf(overlay);
+ if (i >= 0) {
+ this._overlays.splice(i, 1);
+ this._setZ(overlay, '');
+ }
+ },
+
+ currentOverlay: function() {
+ var i = this._overlays.length - 1;
+ while (this._overlays[i] && !this._overlays[i].opened) {
+ --i;
+ }
+ return this._overlays[i];
+ },
+
+ currentOverlayZ: function() {
+ var z = this._minimumZ;
+ var current = this.currentOverlay();
+ if (current) {
+ var z1 = window.getComputedStyle(current).zIndex;
+ if (!isNaN(z1)) {
+ z = Number(z1);
+ }
+ }
+ return z;
+ },
+
+ /**
+ * Ensures that the minimum z-index of new overlays is at least `minimumZ`.
+ * This does not effect the z-index of any existing overlays.
+ *
+ * @param {number} minimumZ
+ */
+ ensureMinimumZ: function(minimumZ) {
+ this._minimumZ = Math.max(this._minimumZ, minimumZ);
+ },
+
+ focusOverlay: function() {
+ var current = this.currentOverlay();
+ // We have to be careful to focus the next overlay _after_ any current
+ // transitions are complete (due to the state being toggled prior to the
+ // transition). Otherwise, we risk infinite recursion when a transitioning
+ // (closed) overlay becomes the current overlay.
+ //
+ // NOTE: We make the assumption that any overlay that completes a transition
+ // will call into focusOverlay to kick the process back off. Currently:
+ // transitionend -> _applyFocus -> focusOverlay.
+ if (current && !current.transitioning) {
+ current._applyFocus();
+ }
+ },
+
+ trackBackdrop: function(element) {
+ // backdrops contains the overlays with a backdrop that are currently
+ // visible
+ if (element.opened) {
+ this._backdrops.push(element);
+ } else {
+ var index = this._backdrops.indexOf(element);
+ if (index >= 0) {
+ this._backdrops.splice(index, 1);
+ }
+ }
+ },
+
+ getBackdrops: function() {
+ return this._backdrops;
+ }
+
+ };
+(function() {
+
+ Polymer({
+
+ is: 'iron-overlay-backdrop',
+
+ properties: {
+
+ /**
+ * Returns true if the backdrop is opened.
+ */
+ opened: {
+ readOnly: true,
+ reflectToAttribute: true,
+ type: Boolean,
+ value: false
+ },
+
+ _manager: {
+ type: Object,
+ value: Polymer.IronOverlayManager
+ }
+
+ },
+
+ /**
+ * Appends the backdrop to document body and sets its `z-index` to be below the latest overlay.
+ */
+ prepare: function() {
+ if (!this.parentNode) {
+ Polymer.dom(document.body).appendChild(this);
+ this.style.zIndex = this._manager.currentOverlayZ() - 1;
+ }
+ },
+
+ /**
+ * Shows the backdrop if needed.
+ */
+ open: function() {
+ // only need to make the backdrop visible if this is called by the first overlay with a backdrop
+ if (this._manager.getBackdrops().length < 2) {
+ this._setOpened(true);
+ }
+ },
+
+ /**
+ * Hides the backdrop if needed.
+ */
+ close: function() {
+ // only need to make the backdrop invisible if this is called by the last overlay with a backdrop
+ if (this._manager.getBackdrops().length < 2) {
+ this._setOpened(false);
+ }
+ },
+
+ /**
+ * Removes the backdrop from document body if needed.
+ */
+ complete: function() {
+ // only remove the backdrop if there are no more overlays with backdrops
+ if (this._manager.getBackdrops().length === 0 && this.parentNode) {
+ Polymer.dom(this.parentNode).removeChild(this);
+ }
+ }
+
+ });
+
+})();
+/**
+Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays
+on top of other content. It includes an optional backdrop, and can be used to implement a variety
+of UI controls including dialogs and drop downs. Multiple overlays may be displayed at once.
+
+### Closing and canceling
+
+A dialog may be hidden by closing or canceling. The difference between close and cancel is user
+intent. Closing generally implies that the user acknowledged the content on the overlay. By default,
+it will cancel whenever the user taps outside it or presses the escape key. This behavior is
+configurable with the `no-cancel-on-esc-key` and the `no-cancel-on-outside-click` properties.
+`close()` should be called explicitly by the implementer when the user interacts with a control
+in the overlay element. When the dialog is canceled, the overlay fires an 'iron-overlay-canceled'
+event. Call `preventDefault` on this event to prevent the overlay from closing.
+
+### Positioning
+
+By default the element is sized and positioned to fit and centered inside the window. You can
+position and size it manually using CSS. See `Polymer.IronFitBehavior`.
+
+### Backdrop
+
+Set the `with-backdrop` attribute to display a backdrop behind the overlay. The backdrop is
+appended to `<body>` and is of type `<iron-overlay-backdrop>`. See its doc page for styling
+options.
+
+### Limitations
+
+The element is styled to appear on top of other content by setting its `z-index` property. You
+must ensure no element has a stacking context with a higher `z-index` than its parent stacking
+context. You should place this element as a child of `<body>` whenever possible.
+
+@demo demo/index.html
+@polymerBehavior Polymer.IronOverlayBehavior
+*/
+
+ Polymer.IronOverlayBehaviorImpl = {
+
+ properties: {
+
+ /**
+ * True if the overlay is currently displayed.
+ */
+ opened: {
+ observer: '_openedChanged',
+ type: Boolean,
+ value: false,
+ notify: true
+ },
+
+ /**
+ * True if the overlay was canceled when it was last closed.
+ */
+ canceled: {
+ observer: '_canceledChanged',
+ readOnly: true,
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to display a backdrop behind the overlay.
+ */
+ withBackdrop: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable auto-focusing the overlay or child nodes with
+ * the `autofocus` attribute` when the overlay is opened.
+ */
+ noAutoFocus: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable canceling the overlay with the ESC key.
+ */
+ noCancelOnEscKey: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable canceling the overlay by clicking outside it.
+ */
+ noCancelOnOutsideClick: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Returns the reason this dialog was last closed.
+ */
+ closingReason: {
+ // was a getter before, but needs to be a property so other
+ // behaviors can override this.
+ type: Object
+ },
+
+ _manager: {
+ type: Object,
+ value: Polymer.IronOverlayManager
+ },
+
+ _boundOnCaptureClick: {
+ type: Function,
+ value: function() {
+ return this._onCaptureClick.bind(this);
+ }
+ },
+
+ _boundOnCaptureKeydown: {
+ type: Function,
+ value: function() {
+ return this._onCaptureKeydown.bind(this);
+ }
+ }
+
+ },
+
+ listeners: {
+ 'tap': '_onClick',
+ 'iron-resize': '_onIronResize'
+ },
+
+ /**
+ * The backdrop element.
+ * @type Node
+ */
+ get backdropElement() {
+ return this._backdrop;
+ },
+
+ get _focusNode() {
+ return Polymer.dom(this).querySelector('[autofocus]') || this;
+ },
+
+ registered: function() {
+ this._backdrop = document.createElement('iron-overlay-backdrop');
+ },
+
+ ready: function() {
+ this._ensureSetup();
+ if (this._callOpenedWhenReady) {
+ this._openedChanged();
+ }
+ },
+
+ detached: function() {
+ this.opened = false;
+ this._completeBackdrop();
+ this._manager.removeOverlay(this);
+ },
+
+ /**
+ * Toggle the opened state of the overlay.
+ */
+ toggle: function() {
+ this.opened = !this.opened;
+ },
+
+ /**
+ * Open the overlay.
+ */
+ open: function() {
+ this.opened = true;
+ this.closingReason = {canceled: false};
+ },
+
+ /**
+ * Close the overlay.
+ */
+ close: function() {
+ this.opened = false;
+ this._setCanceled(false);
+ },
+
+ /**
+ * Cancels the overlay.
+ */
+ cancel: function() {
+ var cancelEvent = this.fire('iron-overlay-canceled', undefined, {cancelable: true});
+ if (cancelEvent.defaultPrevented) {
+ return;
+ }
+
+ this.opened = false;
+ this._setCanceled(true);
+ },
+
+ _ensureSetup: function() {
+ if (this._overlaySetup) {
+ return;
+ }
+ this._overlaySetup = true;
+ this.style.outline = 'none';
+ this.style.display = 'none';
+ },
+
+ _openedChanged: function() {
+ if (this.opened) {
+ this.removeAttribute('aria-hidden');
+ } else {
+ this.setAttribute('aria-hidden', 'true');
+ }
+
+ // wait to call after ready only if we're initially open
+ if (!this._overlaySetup) {
+ this._callOpenedWhenReady = this.opened;
+ return;
+ }
+ if (this._openChangedAsync) {
+ this.cancelAsync(this._openChangedAsync);
+ }
+
+ this._toggleListeners();
+
+ if (this.opened) {
+ this._prepareRenderOpened();
+ }
+
+ // async here to allow overlay layer to become visible.
+ this._openChangedAsync = this.async(function() {
+ // overlay becomes visible here
+ this.style.display = '';
+ // force layout to ensure transitions will go
+ /** @suppress {suspiciousCode} */ this.offsetWidth;
+ if (this.opened) {
+ this._renderOpened();
+ } else {
+ this._renderClosed();
+ }
+ this._openChangedAsync = null;
+ });
+
+ },
+
+ _canceledChanged: function() {
+ this.closingReason = this.closingReason || {};
+ this.closingReason.canceled = this.canceled;
+ },
+
+ _toggleListener: function(enable, node, event, boundListener, capture) {
+ if (enable) {
+ // enable document-wide tap recognizer
+ if (event === 'tap') {
+ Polymer.Gestures.add(document, 'tap', null);
+ }
+ node.addEventListener(event, boundListener, capture);
+ } else {
+ // disable document-wide tap recognizer
+ if (event === 'tap') {
+ Polymer.Gestures.remove(document, 'tap', null);
+ }
+ node.removeEventListener(event, boundListener, capture);
+ }
+ },
+
+ _toggleListeners: function() {
+ if (this._toggleListenersAsync) {
+ this.cancelAsync(this._toggleListenersAsync);
+ }
+ // async so we don't auto-close immediately via a click.
+ this._toggleListenersAsync = this.async(function() {
+ this._toggleListener(this.opened, document, 'tap', this._boundOnCaptureClick, true);
+ this._toggleListener(this.opened, document, 'keydown', this._boundOnCaptureKeydown, true);
+ this._toggleListenersAsync = null;
+ }, 1);
+ },
+
+ // tasks which must occur before opening; e.g. making the element visible
+ _prepareRenderOpened: function() {
+ this._manager.addOverlay(this);
+
+ if (this.withBackdrop) {
+ this.backdropElement.prepare();
+ this._manager.trackBackdrop(this);
+ }
+
+ this._preparePositioning();
+ this.fit();
+ this._finishPositioning();
+ },
+
+ // tasks which cause the overlay to actually open; typically play an
+ // animation
+ _renderOpened: function() {
+ if (this.withBackdrop) {
+ this.backdropElement.open();
+ }
+ this._finishRenderOpened();
+ },
+
+ _renderClosed: function() {
+ if (this.withBackdrop) {
+ this.backdropElement.close();
+ }
+ this._finishRenderClosed();
+ },
+
+ _onTransitionend: function(event) {
+ // make sure this is our transition event.
+ if (event && event.target !== this) {
+ return;
+ }
+ if (this.opened) {
+ this._finishRenderOpened();
+ } else {
+ this._finishRenderClosed();
+ }
+ },
+
+ _finishRenderOpened: function() {
+ // focus the child node with [autofocus]
+ if (!this.noAutoFocus) {
+ this._focusNode.focus();
+ }
+
+ this.fire('iron-overlay-opened');
+
+ this._squelchNextResize = true;
+ this.async(this.notifyResize);
+ },
+
+ _finishRenderClosed: function() {
+ // hide the overlay and remove the backdrop
+ this.resetFit();
+ this.style.display = 'none';
+ this._completeBackdrop();
+ this._manager.removeOverlay(this);
+
+ this._focusNode.blur();
+ // focus the next overlay, if there is one
+ this._manager.focusOverlay();
+
+ this.fire('iron-overlay-closed', this.closingReason);
+
+ this._squelchNextResize = true;
+ this.async(this.notifyResize);
+ },
+
+ _completeBackdrop: function() {
+ if (this.withBackdrop) {
+ this._manager.trackBackdrop(this);
+ this.backdropElement.complete();
+ }
+ },
+
+ _preparePositioning: function() {
+ this.style.transition = this.style.webkitTransition = 'none';
+ this.style.transform = this.style.webkitTransform = 'none';
+ this.style.display = '';
+ },
+
+ _finishPositioning: function() {
+ this.style.display = 'none';
+ this.style.transform = this.style.webkitTransform = '';
+ // force layout to avoid application of transform
+ /** @suppress {suspiciousCode} */ this.offsetWidth;
+ this.style.transition = this.style.webkitTransition = '';
+ },
+
+ _applyFocus: function() {
+ if (this.opened) {
+ if (!this.noAutoFocus) {
+ this._focusNode.focus();
+ }
+ } else {
+ this._focusNode.blur();
+ this._manager.focusOverlay();
+ }
+ },
+
+ _onCaptureClick: function(event) {
+ // attempt to close asynchronously and prevent the close of a tap event is immediately heard
+ // on target. This is because in shadow dom due to event retargetting event.target is not
+ // useful.
+ if (!this.noCancelOnOutsideClick && (this._manager.currentOverlay() == this)) {
+ this._cancelJob = this.async(function() {
+ this.cancel();
+ }, 10);
+ }
+ },
+
+ _onClick: function(event) {
+ if (this._cancelJob) {
+ this.cancelAsync(this._cancelJob);
+ this._cancelJob = null;
+ }
+ },
+
+ _onCaptureKeydown: function(event) {
+ var ESC = 27;
+ if (!this.noCancelOnEscKey && (event.keyCode === ESC)) {
+ this.cancel();
+ event.stopPropagation();
+ }
+ },
+
+ _onIronResize: function() {
+ if (this._squelchNextResize) {
+ this._squelchNextResize = false;
+ return;
+ }
+ if (this.opened) {
+ this.refit();
+ }
+ }
+
+/**
+ * Fired after the `iron-overlay` opens.
+ * @event iron-overlay-opened
+ */
+
+/**
+ * Fired when the `iron-overlay` is canceled, but before it is closed.
+ * Cancel the event to prevent the `iron-overlay` from closing.
+ * @event iron-overlay-canceled
+ */
+
+/**
+ * Fired after the `iron-overlay` closes.
+ * @event iron-overlay-closed
+ * @param {{canceled: (boolean|undefined)}} set to the `closingReason` attribute
+ */
+ };
+
+ /** @polymerBehavior */
+ Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl];
+/**
+ * Use `Polymer.NeonAnimationBehavior` to implement an animation.
+ * @polymerBehavior
+ */
+ Polymer.NeonAnimationBehavior = {
+
+ properties: {
+
+ /**
+ * Defines the animation timing.
+ */
+ animationTiming: {
+ type: Object,
+ value: function() {
+ return {
+ duration: 500,
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
+ fill: 'both'
+ }
+ }
+ }
+
+ },
+
+ registered: function() {
+ new Polymer.IronMeta({type: 'animation', key: this.is, value: this.constructor});
+ },
+
+ /**
+ * Do any animation configuration here.
+ */
+ // configure: function(config) {
+ // },
+
+ /**
+ * Returns the animation timing by mixing in properties from `config` to the defaults defined
+ * by the animation.
+ */
+ timingFromConfig: function(config) {
+ if (config.timing) {
+ for (var property in config.timing) {
+ this.animationTiming[property] = config.timing[property];
+ }
+ }
+ return this.animationTiming;
+ },
+
+ /**
+ * Sets `transform` and `transformOrigin` properties along with the prefixed versions.
+ */
+ setPrefixedProperty: function(node, property, value) {
+ var map = {
+ 'transform': ['webkitTransform'],
+ 'transformOrigin': ['mozTransformOrigin', 'webkitTransformOrigin']
+ };
+ var prefixes = map[property];
+ for (var prefix, index = 0; prefix = prefixes[index]; index++) {
+ node.style[prefix] = value;
+ }
+ node.style[property] = value;
+ },
+
+ /**
+ * Called when the animation finishes.
+ */
+ complete: function() {}
+
+ };
+Polymer({
+
+ is: 'opaque-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ node.style.opacity = '0';
+ this._effect = new KeyframeEffect(node, [
+ {'opacity': '1'},
+ {'opacity': '1'}
+ ], this.timingFromConfig(config));
+ return this._effect;
+ },
+
+ complete: function(config) {
+ config.node.style.opacity = '';
+ }
+
+ });
+/**
+ * `Polymer.NeonAnimatableBehavior` is implemented by elements containing animations for use with
+ * elements implementing `Polymer.NeonAnimationRunnerBehavior`.
+ * @polymerBehavior
+ */
+ Polymer.NeonAnimatableBehavior = {
+
+ properties: {
+
+ /**
+ * Animation configuration. See README for more info.
+ */
+ animationConfig: {
+ type: Object
+ },
+
+ /**
+ * Convenience property for setting an 'entry' animation. Do not set `animationConfig.entry`
+ * manually if using this. The animated node is set to `this` if using this property.
+ */
+ entryAnimation: {
+ observer: '_entryAnimationChanged',
+ type: String
+ },
+
+ /**
+ * Convenience property for setting an 'exit' animation. Do not set `animationConfig.exit`
+ * manually if using this. The animated node is set to `this` if using this property.
+ */
+ exitAnimation: {
+ observer: '_exitAnimationChanged',
+ type: String
+ }
+
+ },
+
+ _entryAnimationChanged: function() {
+ this.animationConfig = this.animationConfig || {};
+ if (this.entryAnimation !== 'fade-in-animation') {
+ // insert polyfill hack
+ this.animationConfig['entry'] = [{
+ name: 'opaque-animation',
+ node: this
+ }, {
+ name: this.entryAnimation,
+ node: this
+ }];
+ } else {
+ this.animationConfig['entry'] = [{
+ name: this.entryAnimation,
+ node: this
+ }];
+ }
+ },
+
+ _exitAnimationChanged: function() {
+ this.animationConfig = this.animationConfig || {};
+ this.animationConfig['exit'] = [{
+ name: this.exitAnimation,
+ node: this
+ }];
+ },
+
+ _copyProperties: function(config1, config2) {
+ // shallowly copy properties from config2 to config1
+ for (var property in config2) {
+ config1[property] = config2[property];
+ }
+ },
+
+ _cloneConfig: function(config) {
+ var clone = {
+ isClone: true
+ };
+ this._copyProperties(clone, config);
+ return clone;
+ },
+
+ _getAnimationConfigRecursive: function(type, map, allConfigs) {
+ if (!this.animationConfig) {
+ return;
+ }
+
+ // type is optional
+ var thisConfig;
+ if (type) {
+ thisConfig = this.animationConfig[type];
+ } else {
+ thisConfig = this.animationConfig;
+ }
+
+ if (!Array.isArray(thisConfig)) {
+ thisConfig = [thisConfig];
+ }
+
+ // iterate animations and recurse to process configurations from child nodes
+ if (thisConfig) {
+ for (var config, index = 0; config = thisConfig[index]; index++) {
+ if (config.animatable) {
+ config.animatable._getAnimationConfigRecursive(config.type || type, map, allConfigs);
+ } else {
+ if (config.id) {
+ var cachedConfig = map[config.id];
+ if (cachedConfig) {
+ // merge configurations with the same id, making a clone lazily
+ if (!cachedConfig.isClone) {
+ map[config.id] = this._cloneConfig(cachedConfig)
+ cachedConfig = map[config.id];
+ }
+ this._copyProperties(cachedConfig, config);
+ } else {
+ // put any configs with an id into a map
+ map[config.id] = config;
+ }
+ } else {
+ allConfigs.push(config);
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * An element implementing `Polymer.NeonAnimationRunnerBehavior` calls this method to configure
+ * an animation with an optional type. Elements implementing `Polymer.NeonAnimatableBehavior`
+ * should define the property `animationConfig`, which is either a configuration object
+ * or a map of animation type to array of configuration objects.
+ */
+ getAnimationConfig: function(type) {
+ var map = [];
+ var allConfigs = [];
+ this._getAnimationConfigRecursive(type, map, allConfigs);
+ // append the configurations saved in the map to the array
+ for (var key in map) {
+ allConfigs.push(map[key]);
+ }
+ return allConfigs;
+ }
+
+ };
+/**
+ * `Polymer.NeonAnimationRunnerBehavior` adds a method to run animations.
+ *
+ * @polymerBehavior Polymer.NeonAnimationRunnerBehavior
+ */
+ Polymer.NeonAnimationRunnerBehaviorImpl = {
+
+ properties: {
+
+ _animationMeta: {
+ type: Object,
+ value: function() {
+ return new Polymer.IronMeta({type: 'animation'});
+ }
+ },
+
+ /** @type {?Object} */
+ _player: {
+ type: Object
+ }
+
+ },
+
+ _configureAnimationEffects: function(allConfigs) {
+ var allAnimations = [];
+ if (allConfigs.length > 0) {
+ for (var config, index = 0; config = allConfigs[index]; index++) {
+ var animationConstructor = this._animationMeta.byKey(config.name);
+ if (animationConstructor) {
+ var animation = animationConstructor && new animationConstructor();
+ var effect = animation.configure(config);
+ if (effect) {
+ allAnimations.push({
+ animation: animation,
+ config: config,
+ effect: effect
+ });
+ }
+ } else {
+ console.warn(this.is + ':', config.name, 'not found!');
+ }
+ }
+ }
+ return allAnimations;
+ },
+
+ _runAnimationEffects: function(allEffects) {
+ return document.timeline.play(new GroupEffect(allEffects));
+ },
+
+ _completeAnimations: function(allAnimations) {
+ for (var animation, index = 0; animation = allAnimations[index]; index++) {
+ animation.animation.complete(animation.config);
+ }
+ },
+
+ /**
+ * Plays an animation with an optional `type`.
+ * @param {string=} type
+ * @param {!Object=} cookie
+ */
+ playAnimation: function(type, cookie) {
+ var allConfigs = this.getAnimationConfig(type);
+ if (!allConfigs) {
+ return;
+ }
+ var allAnimations = this._configureAnimationEffects(allConfigs);
+ var allEffects = allAnimations.map(function(animation) {
+ return animation.effect;
+ });
+
+ if (allEffects.length > 0) {
+ this._player = this._runAnimationEffects(allEffects);
+ this._player.onfinish = function() {
+ this._completeAnimations(allAnimations);
+
+ if (this._player) {
+ this._player.cancel();
+ this._player = null;
+ }
+
+ this.fire('neon-animation-finish', cookie, {bubbles: false});
+ }.bind(this);
+
+ } else {
+ this.fire('neon-animation-finish', cookie, {bubbles: false});
+ }
+ },
+
+ /**
+ * Cancels the currently running animation.
+ */
+ cancelAnimation: function() {
+ if (this._player) {
+ this._player.cancel();
+ }
+ }
+ };
+
+ /** @polymerBehavior Polymer.NeonAnimationRunnerBehavior */
+ Polymer.NeonAnimationRunnerBehavior = [
+ Polymer.NeonAnimatableBehavior,
+ Polymer.NeonAnimationRunnerBehaviorImpl
+ ];
+(function() {
+ 'use strict';
+
+ /**
+ * The IronDropdownScrollManager is intended to provide a central source
+ * of authority and control over which elements in a document are currently
+ * allowed to scroll.
+ */
+
+ Polymer.IronDropdownScrollManager = {
+
+ /**
+ * The current element that defines the DOM boundaries of the
+ * scroll lock. This is always the most recently locking element.
+ */
+ get currentLockingElement() {
+ return this._lockingElements[this._lockingElements.length - 1];
+ },
+
+
+ /**
+ * Returns true if the provided element is "scroll locked," which is to
+ * say that it cannot be scrolled via pointer or keyboard interactions.
+ *
+ * @param {HTMLElement} element An HTML element instance which may or may
+ * not be scroll locked.
+ */
+ elementIsScrollLocked: function(element) {
+ var currentLockingElement = this.currentLockingElement;
+ var scrollLocked;
+
+ if (this._hasCachedLockedElement(element)) {
+ return true;
+ }
+
+ if (this._hasCachedUnlockedElement(element)) {
+ return false;
+ }
+
+ scrollLocked = !!currentLockingElement &&
+ currentLockingElement !== element &&
+ !this._composedTreeContains(currentLockingElement, element);
+
+ if (scrollLocked) {
+ this._lockedElementCache.push(element);
+ } else {
+ this._unlockedElementCache.push(element);
+ }
+
+ return scrollLocked;
+ },
+
+ /**
+ * Push an element onto the current scroll lock stack. The most recently
+ * pushed element and its children will be considered scrollable. All
+ * other elements will not be scrollable.
+ *
+ * Scroll locking is implemented as a stack so that cases such as
+ * dropdowns within dropdowns are handled well.
+ *
+ * @param {HTMLElement} element The element that should lock scroll.
+ */
+ pushScrollLock: function(element) {
+ if (this._lockingElements.length === 0) {
+ this._lockScrollInteractions();
+ }
+
+ this._lockingElements.push(element);
+
+ this._lockedElementCache = [];
+ this._unlockedElementCache = [];
+ },
+
+ /**
+ * Remove an element from the scroll lock stack. The element being
+ * removed does not need to be the most recently pushed element. However,
+ * the scroll lock constraints only change when the most recently pushed
+ * element is removed.
+ *
+ * @param {HTMLElement} element The element to remove from the scroll
+ * lock stack.
+ */
+ removeScrollLock: function(element) {
+ var index = this._lockingElements.indexOf(element);
+
+ if (index === -1) {
+ return;
+ }
+
+ this._lockingElements.splice(index, 1);
+
+ this._lockedElementCache = [];
+ this._unlockedElementCache = [];
+
+ if (this._lockingElements.length === 0) {
+ this._unlockScrollInteractions();
+ }
+ },
+
+ _lockingElements: [],
+
+ _lockedElementCache: null,
+
+ _unlockedElementCache: null,
+
+ _originalBodyStyles: {},
+
+ _isScrollingKeypress: function(event) {
+ return Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(
+ event, 'pageup pagedown home end up left down right');
+ },
+
+ _hasCachedLockedElement: function(element) {
+ return this._lockedElementCache.indexOf(element) > -1;
+ },
+
+ _hasCachedUnlockedElement: function(element) {
+ return this._unlockedElementCache.indexOf(element) > -1;
+ },
+
+ _composedTreeContains: function(element, child) {
+ // NOTE(cdata): This method iterates over content elements and their
+ // corresponding distributed nodes to implement a contains-like method
+ // that pierces through the composed tree of the ShadowDOM. Results of
+ // this operation are cached (elsewhere) on a per-scroll-lock basis, to
+ // guard against potentially expensive lookups happening repeatedly as
+ // a user scrolls / touchmoves.
+ var contentElements;
+ var distributedNodes;
+ var contentIndex;
+ var nodeIndex;
+
+ if (element.contains(child)) {
+ return true;
+ }
+
+ contentElements = Polymer.dom(element).querySelectorAll('content');
+
+ for (contentIndex = 0; contentIndex < contentElements.length; ++contentIndex) {
+
+ distributedNodes = Polymer.dom(contentElements[contentIndex]).getDistributedNodes();
+
+ for (nodeIndex = 0; nodeIndex < distributedNodes.length; ++nodeIndex) {
+
+ if (this._composedTreeContains(distributedNodes[nodeIndex], child)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ _scrollInteractionHandler: function(event) {
+ if (Polymer
+ .IronDropdownScrollManager
+ .elementIsScrollLocked(event.target)) {
+ if (event.type === 'keydown' &&
+ !Polymer.IronDropdownScrollManager._isScrollingKeypress(event)) {
+ return;
+ }
+
+ event.preventDefault();
+ }
+ },
+
+ _lockScrollInteractions: function() {
+ // Memoize body inline styles:
+ this._originalBodyStyles.overflow = document.body.style.overflow;
+ this._originalBodyStyles.overflowX = document.body.style.overflowX;
+ this._originalBodyStyles.overflowY = document.body.style.overflowY;
+
+ // Disable overflow scrolling on body:
+ // TODO(cdata): It is technically not sufficient to hide overflow on
+ // body alone. A better solution might be to traverse all ancestors of
+ // the current scroll locking element and hide overflow on them. This
+ // becomes expensive, though, as it would have to be redone every time
+ // a new scroll locking element is added.
+ document.body.style.overflow = 'hidden';
+ document.body.style.overflowX = 'hidden';
+ document.body.style.overflowY = 'hidden';
+
+ // Modern `wheel` event for mouse wheel scrolling:
+ window.addEventListener('wheel', this._scrollInteractionHandler, true);
+ // Older, non-standard `mousewheel` event for some FF:
+ window.addEventListener('mousewheel', this._scrollInteractionHandler, true);
+ // IE:
+ window.addEventListener('DOMMouseScroll', this._scrollInteractionHandler, true);
+ // Mobile devices can scroll on touch move:
+ window.addEventListener('touchmove', this._scrollInteractionHandler, true);
+ // Capture keydown to prevent scrolling keys (pageup, pagedown etc.)
+ document.addEventListener('keydown', this._scrollInteractionHandler, true);
+ },
+
+ _unlockScrollInteractions: function() {
+ document.body.style.overflow = this._originalBodyStyles.overflow;
+ document.body.style.overflowX = this._originalBodyStyles.overflowX;
+ document.body.style.overflowY = this._originalBodyStyles.overflowY;
+
+ window.removeEventListener('wheel', this._scrollInteractionHandler, true);
+ window.removeEventListener('mousewheel', this._scrollInteractionHandler, true);
+ window.removeEventListener('DOMMouseScroll', this._scrollInteractionHandler, true);
+ window.removeEventListener('touchmove', this._scrollInteractionHandler, true);
+ document.removeEventListener('keydown', this._scrollInteractionHandler, true);
+ }
+ };
+ })();
+(function() {
+ 'use strict';
+
+ Polymer({
+ is: 'iron-dropdown',
+
+ behaviors: [
+ Polymer.IronControlState,
+ Polymer.IronA11yKeysBehavior,
+ Polymer.IronOverlayBehavior,
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+
+ properties: {
+ /**
+ * The orientation against which to align the dropdown content
+ * horizontally relative to the dropdown trigger.
+ */
+ horizontalAlign: {
+ type: String,
+ value: 'left',
+ reflectToAttribute: true
+ },
+
+ /**
+ * The orientation against which to align the dropdown content
+ * vertically relative to the dropdown trigger.
+ */
+ verticalAlign: {
+ type: String,
+ value: 'top',
+ reflectToAttribute: true
+ },
+
+ /**
+ * A pixel value that will be added to the position calculated for the
+ * given `horizontalAlign`. Use a negative value to offset to the
+ * left, or a positive value to offset to the right.
+ */
+ horizontalOffset: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * A pixel value that will be added to the position calculated for the
+ * given `verticalAlign`. Use a negative value to offset towards the
+ * top, or a positive value to offset towards the bottom.
+ */
+ verticalOffset: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * The element that should be used to position the dropdown when
+ * it is opened.
+ */
+ positionTarget: {
+ type: Object,
+ observer: '_positionTargetChanged'
+ },
+
+ /**
+ * An animation config. If provided, this will be used to animate the
+ * opening of the dropdown.
+ */
+ openAnimationConfig: {
+ type: Object
+ },
+
+ /**
+ * An animation config. If provided, this will be used to animate the
+ * closing of the dropdown.
+ */
+ closeAnimationConfig: {
+ type: Object
+ },
+
+ /**
+ * If provided, this will be the element that will be focused when
+ * the dropdown opens.
+ */
+ focusTarget: {
+ type: Object
+ },
+
+ /**
+ * Set to true to disable animations when opening and closing the
+ * dropdown.
+ */
+ noAnimations: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * By default, the dropdown will constrain scrolling on the page
+ * to itself when opened.
+ * Set to true in order to prevent scroll from being constrained
+ * to the dropdown when it opens.
+ */
+ allowOutsideScroll: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * We memoize the positionTarget bounding rectangle so that we can
+ * limit the number of times it is queried per resize / relayout.
+ * @type {?Object}
+ */
+ _positionRectMemo: {
+ type: Object
+ }
+ },
+
+ listeners: {
+ 'neon-animation-finish': '_onNeonAnimationFinish'
+ },
+
+ observers: [
+ '_updateOverlayPosition(verticalAlign, horizontalAlign, verticalOffset, horizontalOffset)'
+ ],
+
+ attached: function() {
+ if (this.positionTarget === undefined) {
+ this.positionTarget = this._defaultPositionTarget;
+ }
+ },
+
+ /**
+ * The element that is contained by the dropdown, if any.
+ */
+ get containedElement() {
+ return Polymer.dom(this.$.content).getDistributedNodes()[0];
+ },
+
+ /**
+ * The element that should be focused when the dropdown opens.
+ */
+ get _focusTarget() {
+ return this.focusTarget || this.containedElement;
+ },
+
+ /**
+ * The element that should be used to position the dropdown when
+ * it opens, if no position target is configured.
+ */
+ get _defaultPositionTarget() {
+ var parent = Polymer.dom(this).parentNode;
+
+ if (parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+ parent = parent.host;
+ }
+
+ return parent;
+ },
+
+ /**
+ * The bounding rect of the position target.
+ */
+ get _positionRect() {
+ if (!this._positionRectMemo && this.positionTarget) {
+ this._positionRectMemo = this.positionTarget.getBoundingClientRect();
+ }
+
+ return this._positionRectMemo;
+ },
+
+ /**
+ * The horizontal offset value used to position the dropdown.
+ */
+ get _horizontalAlignTargetValue() {
+ var target;
+
+ if (this.horizontalAlign === 'right') {
+ target = document.documentElement.clientWidth - this._positionRect.right;
+ } else {
+ target = this._positionRect.left;
+ }
+
+ target += this.horizontalOffset;
+
+ return Math.max(target, 0);
+ },
+
+ /**
+ * The vertical offset value used to position the dropdown.
+ */
+ get _verticalAlignTargetValue() {
+ var target;
+
+ if (this.verticalAlign === 'bottom') {
+ target = document.documentElement.clientHeight - this._positionRect.bottom;
+ } else {
+ target = this._positionRect.top;
+ }
+
+ target += this.verticalOffset;
+
+ return Math.max(target, 0);
+ },
+
+ /**
+ * Called when the value of `opened` changes.
+ *
+ * @param {boolean} opened True if the dropdown is opened.
+ */
+ _openedChanged: function(opened) {
+ if (opened && this.disabled) {
+ this.cancel();
+ } else {
+ this.cancelAnimation();
+ this._prepareDropdown();
+ Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments);
+ }
+
+ if (this.opened) {
+ this._focusContent();
+ }
+ },
+
+ /**
+ * Overridden from `IronOverlayBehavior`.
+ */
+ _renderOpened: function() {
+ if (!this.allowOutsideScroll) {
+ Polymer.IronDropdownScrollManager.pushScrollLock(this);
+ }
+
+ if (!this.noAnimations && this.animationConfig && this.animationConfig.open) {
+ this.$.contentWrapper.classList.add('animating');
+ this.playAnimation('open');
+ } else {
+ Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this, arguments);
+ }
+ },
+
+ /**
+ * Overridden from `IronOverlayBehavior`.
+ */
+ _renderClosed: function() {
+ Polymer.IronDropdownScrollManager.removeScrollLock(this);
+ if (!this.noAnimations && this.animationConfig && this.animationConfig.close) {
+ this.$.contentWrapper.classList.add('animating');
+ this.playAnimation('close');
+ } else {
+ Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this, arguments);
+ }
+ },
+
+ /**
+ * Called when animation finishes on the dropdown (when opening or
+ * closing). Responsible for "completing" the process of opening or
+ * closing the dropdown by positioning it or setting its display to
+ * none.
+ */
+ _onNeonAnimationFinish: function() {
+ this.$.contentWrapper.classList.remove('animating');
+ if (this.opened) {
+ Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this);
+ } else {
+ Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this);
+ }
+ },
+
+ /**
+ * Called when an `iron-resize` event fires.
+ */
+ _onIronResize: function() {
+ var containedElement = this.containedElement;
+ var scrollTop;
+ var scrollLeft;
+
+ if (containedElement) {
+ scrollTop = containedElement.scrollTop;
+ scrollLeft = containedElement.scrollLeft;
+ }
+
+ if (this.opened) {
+ this._updateOverlayPosition();
+ }
+
+ Polymer.IronOverlayBehaviorImpl._onIronResize.apply(this, arguments);
+
+ if (containedElement) {
+ containedElement.scrollTop = scrollTop;
+ containedElement.scrollLeft = scrollLeft;
+ }
+ },
+
+ /**
+ * Called when the `positionTarget` property changes.
+ */
+ _positionTargetChanged: function() {
+ this._updateOverlayPosition();
+ },
+
+ /**
+ * Constructs the final animation config from different properties used
+ * to configure specific parts of the opening and closing animations.
+ */
+ _updateAnimationConfig: function() {
+ var animationConfig = {};
+ var animations = [];
+
+ if (this.openAnimationConfig) {
+ // NOTE(cdata): When making `display:none` elements visible in Safari,
+ // the element will paint once in a fully visible state, causing the
+ // dropdown to flash before it fades in. We prepend an
+ // `opaque-animation` to fix this problem:
+ animationConfig.open = [{
+ name: 'opaque-animation',
+ }].concat(this.openAnimationConfig);
+ animations = animations.concat(animationConfig.open);
+ }
+
+ if (this.closeAnimationConfig) {
+ animationConfig.close = this.closeAnimationConfig;
+ animations = animations.concat(animationConfig.close);
+ }
+
+ animations.forEach(function(animation) {
+ animation.node = this.containedElement;
+ }, this);
+
+ this.animationConfig = animationConfig;
+ },
+
+ /**
+ * Prepares the dropdown for opening by updating measured layout
+ * values.
+ */
+ _prepareDropdown: function() {
+ this.sizingTarget = this.containedElement || this.sizingTarget;
+ this._updateAnimationConfig();
+ this._updateOverlayPosition();
+ },
+
+ /**
+ * Updates the overlay position based on configured horizontal
+ * and vertical alignment, and re-memoizes these values for the sake
+ * of behavior in `IronFitBehavior`.
+ */
+ _updateOverlayPosition: function() {
+ this._positionRectMemo = null;
+
+ if (!this.positionTarget) {
+ return;
+ }
+
+ this.style[this.horizontalAlign] =
+ this._horizontalAlignTargetValue + 'px';
+
+ this.style[this.verticalAlign] =
+ this._verticalAlignTargetValue + 'px';
+
+ // NOTE(cdata): We re-memoize inline styles here, otherwise
+ // calling `refit` from `IronFitBehavior` will reset inline styles
+ // to whatever they were when the dropdown first opened.
+ if (this._fitInfo) {
+ this._fitInfo.inlineStyle[this.horizontalAlign] =
+ this.style[this.horizontalAlign];
+
+ this._fitInfo.inlineStyle[this.verticalAlign] =
+ this.style[this.verticalAlign];
+ }
+ },
+
+ /**
+ * Focuses the configured focus target.
+ */
+ _focusContent: function() {
+ // NOTE(cdata): This is async so that it can attempt the focus after
+ // `display: none` is removed from the element.
+ this.async(function() {
+ if (this._focusTarget) {
+ this._focusTarget.focus();
+ }
+ });
+ }
+ });
+ })();
+Polymer({
+
+ is: 'fade-in-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ this._effect = new KeyframeEffect(node, [
+ {'opacity': '0'},
+ {'opacity': '1'}
+ ], this.timingFromConfig(config));
+ return this._effect;
+ }
+
+ });
+Polymer({
+
+ is: 'fade-out-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ this._effect = new KeyframeEffect(node, [
+ {'opacity': '1'},
+ {'opacity': '0'}
+ ], this.timingFromConfig(config));
+ return this._effect;
+ }
+
+ });
+Polymer({
+ is: 'paper-menu-grow-height-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ var rect = node.getBoundingClientRect();
+ var height = rect.height;
+
+ this._effect = new KeyframeEffect(node, [{
+ height: (height / 2) + 'px'
+ }, {
+ height: height + 'px'
+ }], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+ });
+
+ Polymer({
+ is: 'paper-menu-grow-width-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ var rect = node.getBoundingClientRect();
+ var width = rect.width;
+
+ this._effect = new KeyframeEffect(node, [{
+ width: (width / 2) + 'px'
+ }, {
+ width: width + 'px'
+ }], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+ });
+
+ Polymer({
+ is: 'paper-menu-shrink-width-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ var rect = node.getBoundingClientRect();
+ var width = rect.width;
+
+ this._effect = new KeyframeEffect(node, [{
+ width: width + 'px'
+ }, {
+ width: width - (width / 20) + 'px'
+ }], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+ });
+
+ Polymer({
+ is: 'paper-menu-shrink-height-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ var rect = node.getBoundingClientRect();
+ var height = rect.height;
+ var top = rect.top;
+
+ this.setPrefixedProperty(node, 'transformOrigin', '0 0');
+
+ this._effect = new KeyframeEffect(node, [{
+ height: height + 'px',
+ transform: 'translateY(0)'
+ }, {
+ height: height / 2 + 'px',
+ transform: 'translateY(-20px)'
+ }], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+ });
+(function() {
+ 'use strict';
+
+ var PaperMenuButton = Polymer({
+ is: 'paper-menu-button',
+
+ /**
+ * Fired when the dropdown opens.
+ *
+ * @event paper-dropdown-open
+ */
+
+ /**
+ * Fired when the dropdown closes.
+ *
+ * @event paper-dropdown-close
+ */
+
+ behaviors: [
+ Polymer.IronA11yKeysBehavior,
+ Polymer.IronControlState
+ ],
+
+ properties: {
+
+ /**
+ * True if the content is currently displayed.
+ */
+ opened: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ observer: '_openedChanged'
+ },
+
+ /**
+ * The orientation against which to align the menu dropdown
+ * horizontally relative to the dropdown trigger.
+ */
+ horizontalAlign: {
+ type: String,
+ value: 'left',
+ reflectToAttribute: true
+ },
+
+ /**
+ * The orientation against which to align the menu dropdown
+ * vertically relative to the dropdown trigger.
+ */
+ verticalAlign: {
+ type: String,
+ value: 'top',
+ reflectToAttribute: true
+ },
+
+ /**
+ * A pixel value that will be added to the position calculated for the
+ * given `horizontalAlign`. Use a negative value to offset to the
+ * left, or a positive value to offset to the right.
+ */
+ horizontalOffset: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * A pixel value that will be added to the position calculated for the
+ * given `verticalAlign`. Use a negative value to offset towards the
+ * top, or a positive value to offset towards the bottom.
+ */
+ verticalOffset: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * Set to true to disable animations when opening and closing the
+ * dropdown.
+ */
+ noAnimations: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable automatically closing the dropdown after
+ * a selection has been made.
+ */
+ ignoreSelect: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * An animation config. If provided, this will be used to animate the
+ * opening of the dropdown.
+ */
+ openAnimationConfig: {
+ type: Object,
+ value: function() {
+ return [{
+ name: 'fade-in-animation',
+ timing: {
+ delay: 100,
+ duration: 200
+ }
+ }, {
+ name: 'paper-menu-grow-width-animation',
+ timing: {
+ delay: 100,
+ duration: 150,
+ easing: PaperMenuButton.ANIMATION_CUBIC_BEZIER
+ }
+ }, {
+ name: 'paper-menu-grow-height-animation',
+ timing: {
+ delay: 100,
+ duration: 275,
+ easing: PaperMenuButton.ANIMATION_CUBIC_BEZIER
+ }
+ }];
+ }
+ },
+
+ /**
+ * An animation config. If provided, this will be used to animate the
+ * closing of the dropdown.
+ */
+ closeAnimationConfig: {
+ type: Object,
+ value: function() {
+ return [{
+ name: 'fade-out-animation',
+ timing: {
+ duration: 150
+ }
+ }, {
+ name: 'paper-menu-shrink-width-animation',
+ timing: {
+ delay: 100,
+ duration: 50,
+ easing: PaperMenuButton.ANIMATION_CUBIC_BEZIER
+ }
+ }, {
+ name: 'paper-menu-shrink-height-animation',
+ timing: {
+ duration: 200,
+ easing: 'ease-in'
+ }
+ }];
+ }
+ },
+
+ /**
+ * This is the element intended to be bound as the focus target
+ * for the `iron-dropdown` contained by `paper-menu-button`.
+ */
+ _dropdownContent: {
+ type: Object
+ }
+ },
+
+ hostAttributes: {
+ role: 'group',
+ 'aria-haspopup': 'true'
+ },
+
+ listeners: {
+ 'iron-select': '_onIronSelect'
+ },
+
+ /**
+ * The content element that is contained by the menu button, if any.
+ */
+ get contentElement() {
+ return Polymer.dom(this.$.content).getDistributedNodes()[0];
+ },
+
+ /**
+ * Make the dropdown content appear as an overlay positioned relative
+ * to the dropdown trigger.
+ */
+ open: function() {
+ if (this.disabled) {
+ return;
+ }
+
+ this.$.dropdown.open();
+ },
+
+ /**
+ * Hide the dropdown content.
+ */
+ close: function() {
+ this.$.dropdown.close();
+ },
+
+ /**
+ * When an `iron-select` event is received, the dropdown should
+ * automatically close on the assumption that a value has been chosen.
+ *
+ * @param {CustomEvent} event A CustomEvent instance with type
+ * set to `"iron-select"`.
+ */
+ _onIronSelect: function(event) {
+ if (!this.ignoreSelect) {
+ this.close();
+ }
+ },
+
+ /**
+ * When the dropdown opens, the `paper-menu-button` fires `paper-open`.
+ * When the dropdown closes, the `paper-menu-button` fires `paper-close`.
+ *
+ * @param {boolean} opened True if the dropdown is opened, otherwise false.
+ * @param {boolean} oldOpened The previous value of `opened`.
+ */
+ _openedChanged: function(opened, oldOpened) {
+ if (opened) {
+ // TODO(cdata): Update this when we can measure changes in distributed
+ // children in an idiomatic way.
+ // We poke this property in case the element has changed. This will
+ // cause the focus target for the `iron-dropdown` to be updated as
+ // necessary:
+ this._dropdownContent = this.contentElement;
+ this.fire('paper-dropdown-open');
+ } else if (oldOpened != null) {
+ this.fire('paper-dropdown-close');
+ }
+ },
+
+ /**
+ * If the dropdown is open when disabled becomes true, close the
+ * dropdown.
+ *
+ * @param {boolean} disabled True if disabled, otherwise false.
+ */
+ _disabledChanged: function(disabled) {
+ Polymer.IronControlState._disabledChanged.apply(this, arguments);
+ if (disabled && this.opened) {
+ this.close();
+ }
+ }
+ });
+
+ PaperMenuButton.ANIMATION_CUBIC_BEZIER = 'cubic-bezier(.3,.95,.5,1)';
+ PaperMenuButton.MAX_ANIMATION_TIME_MS = 400;
+
+ Polymer.PaperMenuButton = PaperMenuButton;
+ })();
+Polymer({
+ is: 'paper-icon-button',
+
+ hostAttributes: {
+ role: 'button',
+ tabindex: '0'
+ },
+
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ properties: {
+ /**
+ * The URL of an image for the icon. If the src property is specified,
+ * the icon property should not be.
+ */
+ src: {
+ type: String
+ },
+
+ /**
+ * Specifies the icon name or index in the set of icons available in
+ * the icon's icon set. If the icon property is specified,
+ * the src property should not be.
+ */
+ icon: {
+ type: String
+ },
+
+ /**
+ * Specifies the alternate text for the button, for accessibility.
+ */
+ alt: {
+ type: String,
+ observer: "_altChanged"
+ }
+ },
+
+ _altChanged: function(newValue, oldValue) {
+ var label = this.getAttribute('aria-label');
+
+ // Don't stomp over a user-set aria-label.
+ if (!label || oldValue == label) {
+ this.setAttribute('aria-label', newValue);
+ }
+ }
+ });
+/**
+ * `Use Polymer.IronValidatableBehavior` to implement an element that validates user input.
+ * Use the related `Polymer.IronValidatorBehavior` to add custom validation logic to an iron-input.
+ *
+ * By default, an `<iron-form>` element validates its fields when the user presses the submit button.
+ * To validate a form imperatively, call the form's `validate()` method, which in turn will
+ * call `validate()` on all its children. By using `Polymer.IronValidatableBehavior`, your
+ * custom element will get a public `validate()`, which
+ * will return the validity of the element, and a corresponding `invalid` attribute,
+ * which can be used for styling.
+ *
+ * To implement the custom validation logic of your element, you must override
+ * the protected `_getValidity()` method of this behaviour, rather than `validate()`.
+ * See [this](https://github.com/PolymerElements/iron-form/blob/master/demo/simple-element.html)
+ * for an example.
+ *
+ * ### Accessibility
+ *
+ * Changing the `invalid` property, either manually or by calling `validate()` will update the
+ * `aria-invalid` attribute.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronValidatableBehavior = {
+
+ properties: {
+
+ /**
+ * Namespace for this validator.
+ */
+ validatorType: {
+ type: String,
+ value: 'validator'
+ },
+
+ /**
+ * Name of the validator to use.
+ */
+ validator: {
+ type: String
+ },
+
+ /**
+ * True if the last call to `validate` is invalid.
+ */
+ invalid: {
+ notify: true,
+ reflectToAttribute: true,
+ type: Boolean,
+ value: false
+ },
+
+ _validatorMeta: {
+ type: Object
+ }
+
+ },
+
+ observers: [
+ '_invalidChanged(invalid)'
+ ],
+
+ get _validator() {
+ return this._validatorMeta && this._validatorMeta.byKey(this.validator);
+ },
+
+ ready: function() {
+ this._validatorMeta = new Polymer.IronMeta({type: this.validatorType});
+ },
+
+ _invalidChanged: function() {
+ if (this.invalid) {
+ this.setAttribute('aria-invalid', 'true');
+ } else {
+ this.removeAttribute('aria-invalid');
+ }
+ },
+
+ /**
+ * @return {boolean} True if the validator `validator` exists.
+ */
+ hasValidator: function() {
+ return this._validator != null;
+ },
+
+ /**
+ * Returns true if the `value` is valid, and updates `invalid`. If you want
+ * your element to have custom validation logic, do not override this method;
+ * override `_getValidity(value)` instead.
+
+ * @param {Object} value The value to be validated. By default, it is passed
+ * to the validator's `validate()` function, if a validator is set.
+ * @return {boolean} True if `value` is valid.
+ */
+ validate: function(value) {
+ this.invalid = !this._getValidity(value);
+ return !this.invalid;
+ },
+
+ /**
+ * Returns true if `value` is valid. By default, it is passed
+ * to the validator's `validate()` function, if a validator is set. You
+ * should override this method if you want to implement custom validity
+ * logic for your element.
+ *
+ * @param {Object} value The value to be validated.
+ * @return {boolean} True if `value` is valid.
+ */
+
+ _getValidity: function(value) {
+ if (this.hasValidator()) {
+ return this._validator.validate(value);
+ }
+ return true;
+ }
+ };
+/*
+`<iron-input>` adds two-way binding and custom validators using `Polymer.IronValidatorBehavior`
+to `<input>`.
+
+### Two-way binding
+
+By default you can only get notified of changes to an `input`'s `value` due to user input:
+
+ <input value="{{myValue::input}}">
+
+`iron-input` adds the `bind-value` property that mirrors the `value` property, and can be used
+for two-way data binding. `bind-value` will notify if it is changed either by user input or by script.
+
+ <input is="iron-input" bind-value="{{myValue}}">
+
+### Custom validators
+
+You can use custom validators that implement `Polymer.IronValidatorBehavior` with `<iron-input>`.
+
+ <input is="iron-input" validator="my-custom-validator">
+
+### Stopping invalid input
+
+It may be desirable to only allow users to enter certain characters. You can use the
+`prevent-invalid-input` and `allowed-pattern` attributes together to accomplish this. This feature
+is separate from validation, and `allowed-pattern` does not affect how the input is validated.
+
+ <!-- only allow characters that match [0-9] -->
+ <input is="iron-input" prevent-invalid-input allowed-pattern="[0-9]">
+
+@hero hero.svg
+@demo demo/index.html
+*/
+
+ Polymer({
+
+ is: 'iron-input',
+
+ extends: 'input',
+
+ behaviors: [
+ Polymer.IronValidatableBehavior
+ ],
+
+ properties: {
+
+ /**
+ * Use this property instead of `value` for two-way data binding.
+ */
+ bindValue: {
+ observer: '_bindValueChanged',
+ type: String
+ },
+
+ /**
+ * Set to true to prevent the user from entering invalid input. The new input characters are
+ * matched with `allowedPattern` if it is set, otherwise it will use the `pattern` attribute if
+ * set, or the `type` attribute (only supported for `type=number`).
+ */
+ preventInvalidInput: {
+ type: Boolean
+ },
+
+ /**
+ * Regular expression to match valid input characters.
+ */
+ allowedPattern: {
+ type: String,
+ observer: "_allowedPatternChanged"
+ },
+
+ _previousValidInput: {
+ type: String,
+ value: ''
+ },
+
+ _patternAlreadyChecked: {
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ listeners: {
+ 'input': '_onInput',
+ 'keypress': '_onKeypress'
+ },
+
+ get _patternRegExp() {
+ var pattern;
+ if (this.allowedPattern) {
+ pattern = new RegExp(this.allowedPattern);
+ } else if (this.pattern) {
+ pattern = new RegExp(this.pattern);
+ } else {
+ switch (this.type) {
+ case 'number':
+ pattern = /[0-9.,e-]/;
+ break;
+ }
+ }
+ return pattern;
+ },
+
+ ready: function() {
+ this.bindValue = this.value;
+ },
+
+ /**
+ * @suppress {checkTypes}
+ */
+ _bindValueChanged: function() {
+ if (this.value !== this.bindValue) {
+ this.value = !(this.bindValue || this.bindValue === 0) ? '' : this.bindValue;
+ }
+ // manually notify because we don't want to notify until after setting value
+ this.fire('bind-value-changed', {value: this.bindValue});
+ },
+
+ _allowedPatternChanged: function() {
+ // Force to prevent invalid input when an `allowed-pattern` is set
+ this.preventInvalidInput = this.allowedPattern ? true : false;
+ },
+
+ _onInput: function() {
+ // Need to validate each of the characters pasted if they haven't
+ // been validated inside `_onKeypress` already.
+ if (this.preventInvalidInput && !this._patternAlreadyChecked) {
+ var valid = this._checkPatternValidity();
+ if (!valid) {
+ this.value = this._previousValidInput;
+ }
+ }
+
+ this.bindValue = this.value;
+ this._previousValidInput = this.value;
+ this._patternAlreadyChecked = false;
+ },
+
+ _isPrintable: function(event) {
+ // What a control/printable character is varies wildly based on the browser.
+ // - most control characters (arrows, backspace) do not send a `keypress` event
+ // in Chrome, but the *do* on Firefox
+ // - in Firefox, when they do send a `keypress` event, control chars have
+ // a charCode = 0, keyCode = xx (for ex. 40 for down arrow)
+ // - printable characters always send a keypress event.
+ // - in Firefox, printable chars always have a keyCode = 0. In Chrome, the keyCode
+ // always matches the charCode.
+ // None of this makes any sense.
+
+ // For these keys, ASCII code == browser keycode.
+ var anyNonPrintable =
+ (event.keyCode == 8) || // backspace
+ (event.keyCode == 9) || // tab
+ (event.keyCode == 13) || // enter
+ (event.keyCode == 27); // escape
+
+ // For these keys, make sure it's a browser keycode and not an ASCII code.
+ var mozNonPrintable =
+ (event.keyCode == 19) || // pause
+ (event.keyCode == 20) || // caps lock
+ (event.keyCode == 45) || // insert
+ (event.keyCode == 46) || // delete
+ (event.keyCode == 144) || // num lock
+ (event.keyCode == 145) || // scroll lock
+ (event.keyCode > 32 && event.keyCode < 41) || // page up/down, end, home, arrows
+ (event.keyCode > 111 && event.keyCode < 124); // fn keys
+
+ return !anyNonPrintable && !(event.charCode == 0 && mozNonPrintable);
+ },
+
+ _onKeypress: function(event) {
+ if (!this.preventInvalidInput && this.type !== 'number') {
+ return;
+ }
+ var regexp = this._patternRegExp;
+ if (!regexp) {
+ return;
+ }
+
+ // Handle special keys and backspace
+ if (event.metaKey || event.ctrlKey || event.altKey)
+ return;
+
+ // Check the pattern either here or in `_onInput`, but not in both.
+ this._patternAlreadyChecked = true;
+
+ var thisChar = String.fromCharCode(event.charCode);
+ if (this._isPrintable(event) && !regexp.test(thisChar)) {
+ event.preventDefault();
+ }
+ },
+
+ _checkPatternValidity: function() {
+ var regexp = this._patternRegExp;
+ if (!regexp) {
+ return true;
+ }
+ for (var i = 0; i < this.value.length; i++) {
+ if (!regexp.test(this.value[i])) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /**
+ * Returns true if `value` is valid. The validator provided in `validator` will be used first,
+ * then any constraints.
+ * @return {boolean} True if the value is valid.
+ */
+ validate: function() {
+ // Empty, non-required input is valid.
+ if (!this.required && this.value == '') {
+ this.invalid = false;
+ return true;
+ }
+
+ var valid;
+ if (this.hasValidator()) {
+ valid = Polymer.IronValidatableBehavior.validate.call(this, this.value);
+ } else {
+ this.invalid = !this.validity.valid;
+ valid = this.validity.valid;
+ }
+ this.fire('iron-input-validate');
+ return valid;
+ }
+
+ });
+
+ /*
+ The `iron-input-validate` event is fired whenever `validate()` is called.
+ @event iron-input-validate
+ */
+Polymer({
+ is: 'paper-input-container',
+
+ properties: {
+ /**
+ * Set to true to disable the floating label. The label disappears when the input value is
+ * not null.
+ */
+ noLabelFloat: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to always float the floating label.
+ */
+ alwaysFloatLabel: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The attribute to listen for value changes on.
+ */
+ attrForValue: {
+ type: String,
+ value: 'bind-value'
+ },
+
+ /**
+ * Set to true to auto-validate the input value when it changes.
+ */
+ autoValidate: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * True if the input is invalid. This property is set automatically when the input value
+ * changes if auto-validating, or when the `iron-input-validate` event is heard from a child.
+ */
+ invalid: {
+ observer: '_invalidChanged',
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * True if the input has focus.
+ */
+ focused: {
+ readOnly: true,
+ type: Boolean,
+ value: false,
+ notify: true
+ },
+
+ _addons: {
+ type: Array
+ // do not set a default value here intentionally - it will be initialized lazily when a
+ // distributed child is attached, which may occur before configuration for this element
+ // in polyfill.
+ },
+
+ _inputHasContent: {
+ type: Boolean,
+ value: false
+ },
+
+ _inputSelector: {
+ type: String,
+ value: 'input,textarea,.paper-input-input'
+ },
+
+ _boundOnFocus: {
+ type: Function,
+ value: function() {
+ return this._onFocus.bind(this);
+ }
+ },
+
+ _boundOnBlur: {
+ type: Function,
+ value: function() {
+ return this._onBlur.bind(this);
+ }
+ },
+
+ _boundOnInput: {
+ type: Function,
+ value: function() {
+ return this._onInput.bind(this);
+ }
+ },
+
+ _boundValueChanged: {
+ type: Function,
+ value: function() {
+ return this._onValueChanged.bind(this);
+ }
+ }
+ },
+
+ listeners: {
+ 'addon-attached': '_onAddonAttached',
+ 'iron-input-validate': '_onIronInputValidate'
+ },
+
+ get _valueChangedEvent() {
+ return this.attrForValue + '-changed';
+ },
+
+ get _propertyForValue() {
+ return Polymer.CaseMap.dashToCamelCase(this.attrForValue);
+ },
+
+ get _inputElement() {
+ return Polymer.dom(this).querySelector(this._inputSelector);
+ },
+
+ get _inputElementValue() {
+ return this._inputElement[this._propertyForValue] || this._inputElement.value;
+ },
+
+ ready: function() {
+ if (!this._addons) {
+ this._addons = [];
+ }
+ this.addEventListener('focus', this._boundOnFocus, true);
+ this.addEventListener('blur', this._boundOnBlur, true);
+ if (this.attrForValue) {
+ this._inputElement.addEventListener(this._valueChangedEvent, this._boundValueChanged);
+ } else {
+ this.addEventListener('input', this._onInput);
+ }
+ },
+
+ attached: function() {
+ // Only validate when attached if the input already has a value.
+ if (this._inputElementValue != '') {
+ this._handleValueAndAutoValidate(this._inputElement);
+ } else {
+ this._handleValue(this._inputElement);
+ }
+ },
+
+ _onAddonAttached: function(event) {
+ if (!this._addons) {
+ this._addons = [];
+ }
+ var target = event.target;
+ if (this._addons.indexOf(target) === -1) {
+ this._addons.push(target);
+ if (this.isAttached) {
+ this._handleValue(this._inputElement);
+ }
+ }
+ },
+
+ _onFocus: function() {
+ this._setFocused(true);
+ },
+
+ _onBlur: function() {
+ this._setFocused(false);
+ this._handleValueAndAutoValidate(this._inputElement);
+ },
+
+ _onInput: function(event) {
+ this._handleValueAndAutoValidate(event.target);
+ },
+
+ _onValueChanged: function(event) {
+ this._handleValueAndAutoValidate(event.target);
+ },
+
+ _handleValue: function(inputElement) {
+ var value = this._inputElementValue;
+
+ // type="number" hack needed because this.value is empty until it's valid
+ if (value || value === 0 || (inputElement.type === 'number' && !inputElement.checkValidity())) {
+ this._inputHasContent = true;
+ } else {
+ this._inputHasContent = false;
+ }
+
+ this.updateAddons({
+ inputElement: inputElement,
+ value: value,
+ invalid: this.invalid
+ });
+ },
+
+ _handleValueAndAutoValidate: function(inputElement) {
+ if (this.autoValidate) {
+ var valid;
+ if (inputElement.validate) {
+ valid = inputElement.validate(this._inputElementValue);
+ } else {
+ valid = inputElement.checkValidity();
+ }
+ this.invalid = !valid;
+ }
+
+ // Call this last to notify the add-ons.
+ this._handleValue(inputElement);
+ },
+
+ _onIronInputValidate: function(event) {
+ this.invalid = this._inputElement.invalid;
+ },
+
+ _invalidChanged: function() {
+ if (this._addons) {
+ this.updateAddons({invalid: this.invalid});
+ }
+ },
+
+ /**
+ * Call this to update the state of add-ons.
+ * @param {Object} state Add-on state.
+ */
+ updateAddons: function(state) {
+ for (var addon, index = 0; addon = this._addons[index]; index++) {
+ addon.update(state);
+ }
+ },
+
+ _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, invalid, _inputHasContent) {
+ var cls = 'input-content';
+ if (!noLabelFloat) {
+ var label = this.querySelector('label');
+
+ if (alwaysFloatLabel || _inputHasContent) {
+ cls += ' label-is-floating';
+ // If the label is floating, ignore any offsets that may have been
+ // applied from a prefix element.
+ this.$.labelAndInputContainer.style.position = 'static';
+
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += " label-is-highlighted";
+ }
+ } else {
+ // When the label is not floating, it should overlap the input element.
+ if (label) {
+ this.$.labelAndInputContainer.style.position = 'relative';
+ }
+ }
+ } else {
+ if (_inputHasContent) {
+ cls += ' label-is-hidden';
+ }
+ }
+ return cls;
+ },
+
+ _computeUnderlineClass: function(focused, invalid) {
+ var cls = 'underline';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += ' is-highlighted'
+ }
+ return cls;
+ },
+
+ _computeAddOnContentClass: function(focused, invalid) {
+ var cls = 'add-on-content';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += ' is-highlighted'
+ }
+ return cls;
+ }
+ });
+// 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.
+
+/** @interface */
+var SearchFieldDelegate = function() {};
+
+SearchFieldDelegate.prototype = {
+ /**
+ * @param {string} value
+ */
+ onSearchTermSearch: assertNotReached,
+};
+
+var SearchField = Polymer({
+ is: 'cr-search-field',
+
+ properties: {
+ label: {
+ type: String,
+ value: '',
+ },
+
+ clearLabel: {
+ type: String,
+ value: '',
+ },
+
+ showingSearch_: {
+ type: Boolean,
+ value: false,
+ },
+ },
+
+ /** @param {SearchFieldDelegate} delegate */
+ setDelegate: function(delegate) {
+ this.delegate_ = delegate;
+ },
+
+ /**
+ * Returns the value of the search field.
+ * @return {string}
+ */
+ getValue: function() {
+ var searchInput = this.$$('#search-input');
+ return searchInput ? searchInput.value : '';
+ },
+
+ /** @private */
+ onSearchTermSearch_: function() {
+ if (this.delegate_)
+ this.delegate_.onSearchTermSearch(this.getValue());
+ },
+
+ /** @private */
+ onSearchTermKeydown_: function(e) {
+ assert(this.showingSearch_);
+ if (e.keyIdentifier == 'U+001B') // Escape.
+ this.toggleShowingSearch_();
+ },
+
+ /** @private */
+ toggleShowingSearch_: function() {
+ this.showingSearch_ = !this.showingSearch_;
+ this.async(function() {
+ var searchInput = this.$$('#search-input');
+ if (this.showingSearch_) {
+ searchInput.focus();
+ } else {
+ searchInput.value = '';
+ this.onSearchTermSearch_();
+ }
+ });
+ },
+});
+// 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.
+
+cr.define('downloads', function() {
+ var Toolbar = Polymer({
+ is: 'downloads-toolbar',
+
+ attached: function() {
+ // isRTL() only works after i18n_template.js runs to set <html dir>.
+ this.overflowAlign_ = isRTL() ? 'left' : 'right';
+
+ /** @private {!SearchFieldDelegate} */
+ this.searchFieldDelegate_ = new ToolbarSearchFieldDelegate(this);
+ this.$['search-input'].setDelegate(this.searchFieldDelegate_);
+ },
+
+ properties: {
+ downloadsShowing: {
+ reflectToAttribute: true,
+ type: Boolean,
+ value: false,
+ observer: 'onDownloadsShowingChange_',
+ },
+
+ overflowAlign_: {
+ type: String,
+ value: 'right',
+ },
+ },
+
+ /** @return {boolean} Whether removal can be undone. */
+ canUndo: function() {
+ return this.$['search-input'] != this.shadowRoot.activeElement;
+ },
+
+ /** @return {boolean} Whether "Clear all" should be allowed. */
+ canClearAll: function() {
+ return !this.$['search-input'].getValue() && this.downloadsShowing;
+ },
+
+ /** @private */
+ onClearAllTap_: function() {
+ assert(this.canClearAll());
+ downloads.ActionService.getInstance().clearAll();
+ },
+
+ /** @private */
+ onDownloadsShowingChange_: function() {
+ this.updateClearAll_();
+ },
+
+ /** @param {string} searchTerm */
+ onSearchTermSearch: function(searchTerm) {
+ downloads.ActionService.getInstance().search(searchTerm);
+ this.updateClearAll_();
+ },
+
+ /** @private */
+ onOpenDownloadsFolderTap_: function() {
+ downloads.ActionService.getInstance().openDownloadsFolder();
+ },
+
+ /** @private */
+ updateClearAll_: function() {
+ this.$$('#actions .clear-all').hidden = !this.canClearAll();
+ this.$$('paper-menu .clear-all').hidden = !this.canClearAll();
+ },
+ });
+
+ /**
+ * @constructor
+ * @implements {SearchFieldDelegate}
+ */
+ // TODO(devlin): This is a bit excessive, and it would be better to just have
+ // Toolbar implement SearchFieldDelegate. But for now, we don't know how to
+ // make that happen with closure compiler.
+ function ToolbarSearchFieldDelegate(toolbar) {
+ this.toolbar_ = toolbar;
+ }
+
+ ToolbarSearchFieldDelegate.prototype = {
+ /** @override */
+ onSearchTermSearch: function(searchTerm) {
+ this.toolbar_.onSearchTermSearch(searchTerm);
+ }
+ };
+
+ return {Toolbar: Toolbar};
+});
+
+// TODO(dbeam): https://github.com/PolymerElements/iron-dropdown/pull/16/files
+/** @suppress {checkTypes} */
+(function() {
+Polymer.IronDropdownScrollManager.pushScrollLock = function() {};
+})();
+// 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.
+
+cr.define('downloads', function() {
+ var Manager = Polymer({
+ is: 'downloads-manager',
+
+ properties: {
+ hasDownloads_: {
+ observer: 'hasDownloadsChanged_',
+ type: Boolean,
+ },
+
+ items_: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+
+ hostAttributes: {
+ loading: true,
+ },
+
+ listeners: {
+ 'downloads-list.scroll': 'onListScroll_',
+ },
+
+ observers: [
+ 'itemsChanged_(items_.*)',
+ ],
+
+ /** @private */
+ clearAll_: function() {
+ this.set('items_', []);
+ },
+
+ /** @private */
+ hasDownloadsChanged_: function() {
+ if (loadTimeData.getBoolean('allowDeletingHistory'))
+ this.$.toolbar.downloadsShowing = this.hasDownloads_;
+
+ if (this.hasDownloads_) {
+ this.$['downloads-list'].fire('iron-resize');
+ } else {
+ var isSearching = downloads.ActionService.getInstance().isSearching();
+ var messageToShow = isSearching ? 'noSearchResults' : 'noDownloads';
+ this.$['no-downloads'].querySelector('span').textContent =
+ loadTimeData.getString(messageToShow);
+ }
+ },
+
+ /**
+ * @param {number} index
+ * @param {!Array<!downloads.Data>} list
+ * @private
+ */
+ insertItems_: function(index, list) {
+ this.splice.apply(this, ['items_', index, 0].concat(list));
+ this.updateHideDates_(index, index + list.length);
+ this.removeAttribute('loading');
+ },
+
+ /** @private */
+ itemsChanged_: function() {
+ this.hasDownloads_ = this.items_.length > 0;
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ onCanExecute_: function(e) {
+ e = /** @type {cr.ui.CanExecuteEvent} */(e);
+ switch (e.command.id) {
+ case 'undo-command':
+ e.canExecute = this.$.toolbar.canUndo();
+ break;
+ case 'clear-all-command':
+ e.canExecute = this.$.toolbar.canClearAll();
+ break;
+ }
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ onCommand_: function(e) {
+ if (e.command.id == 'clear-all-command')
+ downloads.ActionService.getInstance().clearAll();
+ else if (e.command.id == 'undo-command')
+ downloads.ActionService.getInstance().undo();
+ },
+
+ /** @private */
+ onListScroll_: function() {
+ var list = this.$['downloads-list'];
+ if (list.scrollHeight - list.scrollTop - list.offsetHeight <= 100) {
+ // Approaching the end of the scrollback. Attempt to load more items.
+ downloads.ActionService.getInstance().loadMore();
+ }
+ },
+
+ /** @private */
+ onLoad_: function() {
+ cr.ui.decorate('command', cr.ui.Command);
+ document.addEventListener('canExecute', this.onCanExecute_.bind(this));
+ document.addEventListener('command', this.onCommand_.bind(this));
+
+ downloads.ActionService.getInstance().loadMore();
+ },
+
+ /**
+ * @param {number} index
+ * @private
+ */
+ removeItem_: function(index) {
+ this.splice('items_', index, 1);
+ this.updateHideDates_(index, index);
+ this.onListScroll_();
+ },
+
+ /**
+ * @param {number} start
+ * @param {number} end
+ * @private
+ */
+ updateHideDates_: function(start, end) {
+ for (var i = start; i <= end; ++i) {
+ var current = this.items_[i];
+ if (!current)
+ continue;
+ var prev = this.items_[i - 1];
+ current.hideDate = !!prev && prev.date_string == current.date_string;
+ }
+ },
+
+ /**
+ * @param {number} index
+ * @param {!downloads.Data} data
+ * @private
+ */
+ updateItem_: function(index, data) {
+ this.set('items_.' + index, data);
+ this.updateHideDates_(index, index);
+ this.$['downloads-list'].updateSizeForItem(index);
+ },
+ });
+
+ Manager.clearAll = function() {
+ Manager.get().clearAll_();
+ };
+
+ /** @return {!downloads.Manager} */
+ Manager.get = function() {
+ return /** @type {!downloads.Manager} */(
+ queryRequiredElement('downloads-manager'));
+ };
+
+ Manager.insertItems = function(index, list) {
+ Manager.get().insertItems_(index, list);
+ };
+
+ Manager.onLoad = function() {
+ Manager.get().onLoad_();
+ };
+
+ Manager.removeItem = function(index) {
+ Manager.get().removeItem_(index);
+ };
+
+ Manager.updateItem = function(index, data) {
+ Manager.get().updateItem_(index, data);
+ };
+
+ return {Manager: Manager};
+});
+// 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.
+
+window.addEventListener('load', downloads.Manager.onLoad); \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/md_downloads/downloads.html b/chromium/chrome/browser/resources/md_downloads/downloads.html
index 676c58e6b5c..e5b0bc551c5 100644
--- a/chromium/chrome/browser/resources/md_downloads/downloads.html
+++ b/chromium/chrome/browser/resources/md_downloads/downloads.html
@@ -5,11 +5,9 @@
<title i18n-content="title"></title>
<link rel="stylesheet" href="chrome://resources/css/roboto.css">
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="import" href="chrome://resources/html/polymer_config.html">
- <link rel="import" href="chrome://downloads/manager.html">
<style>
html {
- background: #f2f2f2;
+ background: rgb(236, 239, 241);
}
html,
@@ -34,8 +32,13 @@
<if expr="not is_macosx">
<command id="undo-command" shortcut="Ctrl-U+005A"><!-- Ctrl+Z -->
</if>
- <link rel="import" href="chrome://resources/html/load_time_data.html">
- <link rel="import" href="chrome://downloads/strings.html">
+ <link rel="import" href="chrome://resources/html/polymer_config.html">
+ <link rel="import" href="chrome://downloads/i18n_setup.html">
+ <link rel="import" href="chrome://downloads/manager.html">
+ <!-- i18n_template.html actually does i18n-* attribute substitutions.
+ It should be imported last and only once. TODO(dbeam): figure out a good
+ solution for each individual element to do this as well. -->
<link rel="import" href="chrome://resources/html/i18n_template.html">
+ <script src="chrome://downloads/downloads.js"></script>
</body>
</html>
diff --git a/chromium/chrome/browser/resources/chromeos/login/gaia_card.js b/chromium/chrome/browser/resources/md_downloads/downloads.js
index 7dd2a42a8bc..5cbff3122d3 100644
--- a/chromium/chrome/browser/resources/chromeos/login/gaia_card.js
+++ b/chromium/chrome/browser/resources/md_downloads/downloads.js
@@ -2,6 +2,4 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-Polymer({
- is: 'gaia-card'
-});
+window.addEventListener('load', downloads.Manager.onLoad);
diff --git a/chromium/chrome/browser/resources/md_downloads/externs.js b/chromium/chrome/browser/resources/md_downloads/externs.js
new file mode 100644
index 00000000000..65efb05f944
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_downloads/externs.js
@@ -0,0 +1,36 @@
+// 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.
+
+/**
+ * @fileoverview Externs for objects sent from C++ to JS for chrome://downloads.
+ * @externs
+ */
+
+var downloads = {};
+
+/**
+ * The type of the download object. The definition is based on
+ * chrome/browser/ui/webui/downloads_dom_handler.cc:CreateDownloadItemValue()
+ * @typedef {{by_ext_id: string,
+ * by_ext_name: string,
+ * danger_type: string,
+ * date_string: string,
+ * file_externally_removed: boolean,
+ * file_name: string,
+ * file_path: string,
+ * file_url: string,
+ * id: string,
+ * last_reason_text: string,
+ * otr: boolean,
+ * percent: number,
+ * progress_status_text: string,
+ * resume: boolean,
+ * retry: boolean,
+ * since_string: string,
+ * started: number,
+ * state: string,
+ * total: number,
+ * url: string}}
+ */
+downloads.Data;
diff --git a/chromium/chrome/browser/resources/md_downloads/focus_row.html b/chromium/chrome/browser/resources/md_downloads/focus_row.html
deleted file mode 100644
index 955ef28aa81..00000000000
--- a/chromium/chrome/browser/resources/md_downloads/focus_row.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr/ui/focus_row.html">
-<script src="chrome://downloads/focus_row.js"></script>
diff --git a/chromium/chrome/browser/resources/md_downloads/i18n.html b/chromium/chrome/browser/resources/md_downloads/i18n.html
new file mode 100644
index 00000000000..1db516cc64d
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_downloads/i18n.html
@@ -0,0 +1,2 @@
+<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://downloads/strings.js"></script>
diff --git a/chromium/chrome/browser/resources/md_downloads/i18n_setup.html b/chromium/chrome/browser/resources/md_downloads/i18n_setup.html
new file mode 100644
index 00000000000..1db516cc64d
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_downloads/i18n_setup.html
@@ -0,0 +1,2 @@
+<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://downloads/strings.js"></script>
diff --git a/chromium/chrome/browser/resources/md_downloads/item.css b/chromium/chrome/browser/resources/md_downloads/item.css
index 5d0e86365cf..af5d94430cd 100644
--- a/chromium/chrome/browser/resources/md_downloads/item.css
+++ b/chromium/chrome/browser/resources/md_downloads/item.css
@@ -5,24 +5,28 @@
:host {
display: flex;
flex-direction: column;
- margin: 12px 0;
}
#date {
- color: #7c7c7c;
+ color: rgb(104, 113, 116);
font-size: 100%;
font-weight: 500;
- margin: 18px auto 16px; /* This top margin + :host top margin = 30px. */
+ margin: 24px auto 10px;
width: var(--downloads-item-width);
}
+#date:empty {
+ display: none;
+}
+
#content {
background: white;
border-radius: 2px;
display: flex;
flex: none;
- margin: 0 auto;
+ margin: 6px auto;
min-height: 103px;
+ position: relative;
width: var(--downloads-item-width);
}
@@ -42,6 +46,7 @@
display: flex;
flex: 1;
flex-direction: column;
+ min-width: 0; /* This allows #url to ellide correctly. */
padding-bottom: 12px;
padding-top: 16px;
}
@@ -77,11 +82,17 @@
opacity: .5;
}
-#warning {
- -webkit-mask-image: url(../../../../ui/webui/resources/images/warning.svg);
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-size: 100%;
- background: rgb(255, 193, 7);
+#danger-icon {
+ height: 32px;
+ width: 32px;
+}
+
+#danger-icon[icon='warning'] {
+ color: rgb(255, 193, 7);
+}
+
+#danger-icon[icon='remove-circle'] {
+ color: rgb(244, 67, 54);
}
#name,
@@ -112,6 +123,7 @@
#url {
color: inherit;
margin-top: 6px;
+ min-height: 0;
overflow: hidden;
text-decoration: none;
text-overflow: ellipsis;
@@ -180,21 +192,19 @@
}
#remove {
- --iron-icon-height: 16px;
- --iron-icon-width: 16px;
- --layout-inline: {
- /* HACK(dbeam): we probably shouldn't be overriding Polymer like this. */
- };
color: #969696;
+ font-size: 16px;
height: 16px;
+ line-height: 17px; /* TODO(dbeam): why is this necesssary? */
padding: 8px;
width: 16px;
}
#incognito {
bottom: 20px;
- content: -webkit-image-set(url(1x/incognito_marker.png) 1x,
- url(2x/incognito_marker.png) 2x);
+ content: -webkit-image-set(
+ url(chrome://downloads/1x/incognito_marker.png) 1x,
+ url(chrome://downloads/2x/incognito_marker.png) 2x);
position: absolute;
right: 10px;
}
diff --git a/chromium/chrome/browser/resources/md_downloads/item.html b/chromium/chrome/browser/resources/md_downloads/item.html
index 1d6dfa31451..7bf53d3ce3e 100644
--- a/chromium/chrome/browser/resources/md_downloads/item.html
+++ b/chromium/chrome/browser/resources/md_downloads/item.html
@@ -1,32 +1,47 @@
<link rel="import" href="chrome://resources/html/action_link.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/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-behaviors/paper-inky-focus-behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-material/paper-material.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
<link rel="import" href="chrome://downloads/action_service.html">
<link rel="import" href="chrome://downloads/constants.html">
-<link rel="import" href="chrome://downloads/throttled_icon_loader.html">
+<link rel="import" href="chrome://downloads/i18n_setup.html">
+
+<dom-module id="inky-text-button">
+ <template><content></content></template>
+ <style>
+ :host {
+ -webkit-user-select: none;
+ cursor: pointer;
+ display: inline-block;
+ outline: none;
+ position: relative;
+ text-align: center;
+ }
+ </style>
+</dom-module>
<dom-module id="downloads-item">
<template>
- <template is="dom-if" if="[[!hideDate]]">
- <h3 id="date">[[computeDate_(data.since_string, data.date_string)]]</h3>
- </template>
+ <h3 id="date">[[computeDate_(data.hideDate, data.since_string, data.date_string)]]</h3>
<div id="content" on-dragstart="onDragStart_"
class$="[[computeClass_(isActive_, isDangerous_, showProgress_)]]">
<div id="file-icon-wrapper" class="icon-wrapper">
<img class="icon" id="file-icon" alt="" hidden="[[isDangerous_]]">
- <div class="icon" id="warning" hidden="[[!isDangerous_]]"></div>
+ <iron-icon id="danger-icon"
+ icon$="[[computeDangerIcon_(isDangerous_, data.danger_type)]]"
+ hidden="[[!isDangerous_]]"></iron-icon>
</div>
<div id="details">
<div id="title-area"><!--
Can't have any line breaks.
--><a is="action-link" id="file-link" href="[[data.url]]"
- on-click="onFileLinkClick_"
+ on-tap="onFileLinkTap_"
hidden="[[!completelyOnDisk_]]">[[data.file_name]]</a><!--
Before #name.
--><span id="name"
@@ -46,22 +61,22 @@
<div id="safe" class="controls" hidden="[[isDangerous_]]">
<a is="action-link" id="show" i18n-content="controlShowInFolder"
- on-click="onShowClick_" hidden="[[!completelyOnDisk_]]"></a>
+ on-tap="onShowTap_" hidden="[[!completelyOnDisk_]]"></a>
<template is="dom-if" if="[[data.retry]]">
<paper-button id="retry"
- on-click="onRetryClick_">[[i18n_.retry]]</paper-button>
+ on-tap="onRetryTap_">[[i18n_.retry]]</paper-button>
</template>
<template is="dom-if" if="[[isInProgress_]]">
<paper-button id="pause"
- on-click="onPauseClick_">[[i18n_.pause]]</paper-button>
+ on-tap="onPauseTap_">[[i18n_.pause]]</paper-button>
</template>
<template is="dom-if" if="[[data.resume]]">
<paper-button id="resume"
- on-click="onResumeClick_">[[i18n_.resume]]</paper-button>
+ on-tap="onResumeTap_">[[i18n_.resume]]</paper-button>
</template>
<template is="dom-if" if="[[showCancel_]]">
<paper-button id="cancel"
- on-click="onCancelClick_">[[i18n_.cancel]]</paper-button>
+ on-tap="onCancelTap_">[[i18n_.cancel]]</paper-button>
</template>
<span id="controlled-by"><!-- Text populated dynamically. --></span>
</div>
@@ -70,28 +85,27 @@
<div id="dangerous" class="controls">
<!-- Dangerous file types (e.g. .exe, .jar). -->
<template is="dom-if" if="[[!isMalware_]]">
- <paper-button id="discard" on-click="onDiscardDangerous_"
+ <paper-button id="discard" on-tap="onDiscardDangerousTap_"
class="discard">[[i18n_.discard]]</paper-button>
- <paper-button id="save" on-click="onSaveDangerous_"
+ <paper-button id="save" on-tap="onSaveDangerousTap_"
class="keep">[[i18n_.save]]</paper-button>
</template>
<!-- Things that safe browsing has determined to be dangerous. -->
<template is="dom-if" if="[[isMalware_]]">
- <paper-button id="danger-remove" on-click="onDiscardDangerous_"
+ <paper-button id="danger-remove" on-tap="onDiscardDangerousTap_"
class="discard">[[i18n_.remove]]</paper-button>
- <paper-button id="restore" on-click="onSaveDangerous_"
- class="keep">[[i18n_.restore]</paper-button>
+ <paper-button id="restore" on-tap="onSaveDangerousTap_"
+ class="keep">[[i18n_.restore]]</paper-button>
</template>
</div>
</template>
</div>
<div id="remove-wrapper" class="icon-wrapper">
- <paper-icon-button id="remove" icon="clear"
- i18n-values="title:controlRemoveFromList"
+ <inky-text-button id="remove" i18n-values="title:controlRemoveFromList"
style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]"
- on-click="onRemoveClick_"></paper-icon-button>
+ on-tap="onRemoveTap_">&#x2715;</inky-text-button>
</div>
<div id="incognito" i18n-values="title:inIncognito"
diff --git a/chromium/chrome/browser/resources/md_downloads/item.js b/chromium/chrome/browser/resources/md_downloads/item.js
index a750e61a193..2838b0c82f1 100644
--- a/chromium/chrome/browser/resources/md_downloads/item.js
+++ b/chromium/chrome/browser/resources/md_downloads/item.js
@@ -3,36 +3,27 @@
// found in the LICENSE file.
cr.define('downloads', function() {
- var Item = Polymer({
- is: 'downloads-item',
+ var InkyTextButton = Polymer({
+ is: 'inky-text-button',
- /**
- * @param {!downloads.ThrottledIconLoader} iconLoader
- */
- factoryImpl: function(iconLoader) {
- /** @private {!downloads.ThrottledIconLoader} */
- this.iconLoader_ = iconLoader;
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ hostAttributes: {
+ role: 'button',
+ tabindex: 0,
},
+ });
+
+ var Item = Polymer({
+ is: 'downloads-item',
properties: {
data: {
type: Object,
},
- hideDate: {
- type: Boolean,
- value: true,
- },
-
- readyPromise: {
- type: Object,
- value: function() {
- return new Promise(function(resolve, reject) {
- this.resolveReadyPromise_ = resolve;
- }.bind(this));
- },
- },
-
completelyOnDisk_: {
computed: 'computeCompletelyOnDisk_(' +
'data.state, data.file_externally_removed)',
@@ -105,21 +96,11 @@ cr.define('downloads', function() {
// TODO(dbeam): this gets called way more when I observe data.by_ext_id
// and data.by_ext_name directly. Why?
'observeControlledBy_(controlledBy_)',
+ 'observeIsDangerous_(isDangerous_, data.file_path)',
],
ready: function() {
this.content = this.$.content;
- this.resolveReadyPromise_();
- },
-
- /** @param {!downloads.Data} data */
- update: function(data) {
- this.data = data;
-
- if (!this.isDangerous_) {
- var icon = 'chrome://fileicon/' + encodeURIComponent(data.file_path);
- this.iconLoader_.loadScaledIcon(this.$['file-icon'], icon);
- }
},
/** @private */
@@ -155,8 +136,26 @@ cr.define('downloads', function() {
},
/** @private */
+ computeDangerIcon_: function() {
+ if (!this.isDangerous_)
+ return '';
+
+ switch (this.data.danger_type) {
+ case downloads.DangerType.DANGEROUS_CONTENT:
+ case downloads.DangerType.DANGEROUS_HOST:
+ case downloads.DangerType.DANGEROUS_URL:
+ case downloads.DangerType.POTENTIALLY_UNWANTED:
+ case downloads.DangerType.UNCOMMON_CONTENT:
+ return 'remove-circle';
+ default:
+ return 'warning';
+ }
+ },
+
+ /** @private */
computeDate_: function() {
- if (this.hideDate)
+ assert(typeof this.data.hideDate == 'boolean');
+ if (this.data.hideDate)
return '';
return assert(this.data.since_string || this.data.date_string);
},
@@ -263,12 +262,21 @@ cr.define('downloads', function() {
},
/** @private */
- onCancelClick_: function() {
+ observeIsDangerous_: function() {
+ if (this.data && !this.isDangerous_) {
+ var filePath = encodeURIComponent(this.data.file_path);
+ var scaleFactor = '?scale=' + window.devicePixelRatio + 'x';
+ this.$['file-icon'].src = 'chrome://fileicon/' + filePath + scaleFactor;
+ }
+ },
+
+ /** @private */
+ onCancelTap_: function() {
downloads.ActionService.getInstance().cancel(this.data.id);
},
/** @private */
- onDiscardDangerous_: function() {
+ onDiscardDangerousTap_: function() {
downloads.ActionService.getInstance().discardDangerous(this.data.id);
},
@@ -285,41 +293,44 @@ cr.define('downloads', function() {
* @param {Event} e
* @private
*/
- onFileLinkClick_: function(e) {
+ onFileLinkTap_: function(e) {
e.preventDefault();
downloads.ActionService.getInstance().openFile(this.data.id);
},
/** @private */
- onPauseClick_: function() {
+ onPauseTap_: function() {
downloads.ActionService.getInstance().pause(this.data.id);
},
/** @private */
- onRemoveClick_: function() {
+ onRemoveTap_: function() {
downloads.ActionService.getInstance().remove(this.data.id);
},
/** @private */
- onResumeClick_: function() {
+ onResumeTap_: function() {
downloads.ActionService.getInstance().resume(this.data.id);
},
/** @private */
- onRetryClick_: function() {
+ onRetryTap_: function() {
downloads.ActionService.getInstance().download(this.data.url);
},
/** @private */
- onSaveDangerous_: function() {
+ onSaveDangerousTap_: function() {
downloads.ActionService.getInstance().saveDangerous(this.data.id);
},
/** @private */
- onShowClick_: function() {
+ onShowTap_: function() {
downloads.ActionService.getInstance().show(this.data.id);
},
});
- return {Item: Item};
+ return {
+ InkyTextButton: InkyTextButton,
+ Item: Item,
+ };
});
diff --git a/chromium/chrome/browser/resources/md_downloads/manager.css b/chromium/chrome/browser/resources/md_downloads/manager.css
index 33bc8aa55f3..5d089101299 100644
--- a/chromium/chrome/browser/resources/md_downloads/manager.css
+++ b/chromium/chrome/browser/resources/md_downloads/manager.css
@@ -7,6 +7,7 @@
flex: 1 0;
flex-direction: column;
height: 100%;
+ overflow-y: overlay;
}
@media screen and (max-width: 1024px) {
@@ -15,23 +16,13 @@
}
}
-#panel {
- --paper-header-panel-shadow: {
- display: none;
- };
- --paper-header-panel-standard-container: {
- display: flex;
- overflow-y: overlay;
- };
-}
-
#no-downloads,
#downloads-list {
flex: 1;
}
-.loading #no-downloads,
-.loading #downloads-list {
+:host([loading]) #no-downloads,
+:host([loading]) #downloads-list {
display: none;
}
@@ -45,9 +36,9 @@
}
#no-downloads .illustration {
- background: -webkit-image-set(url(1x/no_downloads.png) 1x,
- url(2x/no_downloads.png) 2x)
- no-repeat center center;
+ background: -webkit-image-set(
+ url(chrome://downloads/1x/no_downloads.png) 1x,
+ url(chrome://downloads/2x/no_downloads.png) 2x) no-repeat center center;
height: 144px; /* Matches natural image height. */
margin-bottom: 32px;
}
diff --git a/chromium/chrome/browser/resources/md_downloads/manager.html b/chromium/chrome/browser/resources/md_downloads/manager.html
index 46fb6ebc793..159a0d598d0 100644
--- a/chromium/chrome/browser/resources/md_downloads/manager.html
+++ b/chromium/chrome/browser/resources/md_downloads/manager.html
@@ -1,29 +1,31 @@
<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/cr/ui.html">
<link rel="import" href="chrome://resources/html/cr/ui/command.html">
-<link rel="import" href="chrome://resources/html/cr/ui/focus_grid.html">
<link rel="import" href="chrome://resources/html/util.html">
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-header-panel/paper-header-panel.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
<link rel="import" href="chrome://downloads/action_service.html">
<link rel="import" href="chrome://downloads/constants.html">
-<link rel="import" href="chrome://downloads/focus_row.html">
+<link rel="import" href="chrome://downloads/i18n_setup.html">
<link rel="import" href="chrome://downloads/item.html">
<link rel="import" href="chrome://downloads/toolbar.html">
<dom-module id="downloads-manager">
<template>
- <paper-header-panel id="panel" class="loading">
- <downloads-toolbar class="paper-header" id="toolbar"></downloads-toolbar>
- <div id="downloads-list" hidden$="[[!hasDownloads_]]"></div>
- <div id="no-downloads" hidden$="[[hasDownloads_]]">
- <div>
- <div class="illustration"></div>
- <span><!-- Text populated in Manager#updateAll_(). --></span>
- </div>
+ <downloads-toolbar id="toolbar"></downloads-toolbar>
+ <iron-list id="downloads-list" items="{{items_}}"
+ hidden="[[!hasDownloads_]]">
+ <template>
+ <downloads-item data="[[item]]" hide-date="[[item.hideDate]]">
+ </downloads-item>
+ </template>
+ </iron-list>
+ <div id="no-downloads" hidden="[[hasDownloads_]]">
+ <div>
+ <div class="illustration"></div>
+ <span><!-- Text populated dynamically. --></span>
</div>
- </paper-header-panel>
+ </div>
</template>
<link rel="import" type="css" href="chrome://downloads/shared_style.css">
<link rel="import" type="css" href="chrome://downloads/manager.css">
diff --git a/chromium/chrome/browser/resources/md_downloads/manager.js b/chromium/chrome/browser/resources/md_downloads/manager.js
index 9c4c9ff294a..489663d9423 100644
--- a/chromium/chrome/browser/resources/md_downloads/manager.js
+++ b/chromium/chrome/browser/resources/md_downloads/manager.js
@@ -8,18 +8,62 @@ cr.define('downloads', function() {
properties: {
hasDownloads_: {
+ observer: 'hasDownloadsChanged_',
type: Boolean,
- value: false,
},
+
+ items_: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+
+ hostAttributes: {
+ loading: true,
+ },
+
+ listeners: {
+ 'downloads-list.scroll': 'onListScroll_',
+ },
+
+ observers: [
+ 'itemsChanged_(items_.*)',
+ ],
+
+ /** @private */
+ clearAll_: function() {
+ this.set('items_', []);
+ },
+
+ /** @private */
+ hasDownloadsChanged_: function() {
+ if (loadTimeData.getBoolean('allowDeletingHistory'))
+ this.$.toolbar.downloadsShowing = this.hasDownloads_;
+
+ if (this.hasDownloads_) {
+ this.$['downloads-list'].fire('iron-resize');
+ } else {
+ var isSearching = downloads.ActionService.getInstance().isSearching();
+ var messageToShow = isSearching ? 'noSearchResults' : 'noDownloads';
+ this.$['no-downloads'].querySelector('span').textContent =
+ loadTimeData.getString(messageToShow);
+ }
},
/**
- * @return {number} A guess at how many items could be visible at once.
+ * @param {number} index
+ * @param {!Array<!downloads.Data>} list
* @private
*/
- guesstimateNumberOfVisibleItems_: function() {
- var toolbarHeight = this.$.toolbar.offsetHeight;
- return Math.floor((window.innerHeight - toolbarHeight) / 46) + 1;
+ insertItems_: function(index, list) {
+ this.splice.apply(this, ['items_', index, 0].concat(list));
+ this.updateHideDates_(index, index + list.length);
+ this.removeAttribute('loading');
+ },
+
+ /** @private */
+ itemsChanged_: function() {
+ this.hasDownloads_ = this.items_.length > 0;
},
/**
@@ -50,169 +94,85 @@ cr.define('downloads', function() {
},
/** @private */
+ onListScroll_: function() {
+ var list = this.$['downloads-list'];
+ if (list.scrollHeight - list.scrollTop - list.offsetHeight <= 100) {
+ // Approaching the end of the scrollback. Attempt to load more items.
+ downloads.ActionService.getInstance().loadMore();
+ }
+ },
+
+ /** @private */
onLoad_: function() {
cr.ui.decorate('command', cr.ui.Command);
document.addEventListener('canExecute', this.onCanExecute_.bind(this));
document.addEventListener('command', this.onCommand_.bind(this));
- // Shows all downloads.
- downloads.ActionService.getInstance().search('');
- },
-
- /** @private */
- rebuildFocusGrid_: function() {
- var activeElement = this.shadowRoot.activeElement;
-
- var activeItem;
- if (activeElement && activeElement.tagName == 'downloads-item')
- activeItem = activeElement;
-
- var activeControl = activeItem && activeItem.shadowRoot.activeElement;
-
- /** @private {!cr.ui.FocusGrid} */
- this.focusGrid_ = this.focusGrid_ || new cr.ui.FocusGrid;
- this.focusGrid_.destroy();
-
- var boundary = this.$['downloads-list'];
-
- this.items_.forEach(function(item) {
- var focusRow = new downloads.FocusRow(item.content, boundary);
- this.focusGrid_.addRow(focusRow);
-
- if (item == activeItem && !cr.ui.FocusRow.isFocusable(activeControl))
- focusRow.getEquivalentElement(activeControl).focus();
- }, this);
-
- this.focusGrid_.ensureRowActive();
+ downloads.ActionService.getInstance().loadMore();
},
/**
- * @return {number} The number of downloads shown on the page.
+ * @param {number} index
* @private
*/
- size_: function() {
- return this.items_.length;
+ removeItem_: function(index) {
+ this.splice('items_', index, 1);
+ this.updateHideDates_(index, index);
+ this.onListScroll_();
},
/**
- * Called when all items need to be updated.
- * @param {!Array<!downloads.Data>} list A list of new download data.
+ * @param {number} start
+ * @param {number} end
* @private
*/
- updateAll_: function(list) {
- var oldIdMap = this.idMap_ || {};
-
- /** @private {!Object<!downloads.Item>} */
- this.idMap_ = {};
-
- /** @private {!Array<!downloads.Item>} */
- this.items_ = [];
-
- if (!this.iconLoader_) {
- var guesstimate = Math.max(this.guesstimateNumberOfVisibleItems_(), 1);
- /** @private {downloads.ThrottledIconLoader} */
- this.iconLoader_ = new downloads.ThrottledIconLoader(guesstimate);
- }
-
- for (var i = 0; i < list.length; ++i) {
- var data = list[i];
- var id = data.id;
-
- // Re-use old items when possible (saves work, preserves focus).
- var item = oldIdMap[id] || new downloads.Item(this.iconLoader_);
-
- this.idMap_[id] = item; // Associated by ID for fast lookup.
- this.items_.push(item); // Add to sorted list for order.
-
- // Render |item| but don't actually add to the DOM yet. |this.items_|
- // must be fully created to be able to find the right spot to insert.
- item.update(data);
-
- // Collapse redundant dates.
- var prev = list[i - 1];
- item.hideDate = !!prev && prev.date_string == data.date_string;
-
- delete oldIdMap[id];
- }
-
- // Remove stale, previously rendered items from the DOM.
- for (var id in oldIdMap) {
- if (oldIdMap[id].parentNode)
- oldIdMap[id].parentNode.removeChild(oldIdMap[id]);
- delete oldIdMap[id];
- }
-
- for (var i = 0; i < this.items_.length; ++i) {
- var item = this.items_[i];
- if (item.parentNode) // Already in the DOM; skip.
+ updateHideDates_: function(start, end) {
+ for (var i = start; i <= end; ++i) {
+ var current = this.items_[i];
+ if (!current)
continue;
-
- var before = null;
- // Find the next rendered item after this one, and insert before it.
- for (var j = i + 1; !before && j < this.items_.length; ++j) {
- if (this.items_[j].parentNode)
- before = this.items_[j];
- }
- // If |before| is null, |item| will just get added at the end.
- this.$['downloads-list'].insertBefore(item, before);
- }
-
- var hasDownloads = this.size_() > 0;
- if (!hasDownloads) {
- var isSearching = downloads.ActionService.getInstance().isSearching();
- var messageToShow = isSearching ? 'noSearchResults' : 'noDownloads';
- this.$['no-downloads'].querySelector('span').textContent =
- loadTimeData.getString(messageToShow);
+ var prev = this.items_[i - 1];
+ current.hideDate = !!prev && prev.date_string == current.date_string;
}
- this.hasDownloads_ = hasDownloads;
-
- if (loadTimeData.getBoolean('allowDeletingHistory'))
- this.$.toolbar.downloadsShowing = this.hasDownloads_;
-
- this.$.panel.classList.remove('loading');
-
- var allReady = this.items_.map(function(i) { return i.readyPromise; });
- Promise.all(allReady).then(this.rebuildFocusGrid_.bind(this));
},
/**
+ * @param {number} index
* @param {!downloads.Data} data
* @private
*/
- updateItem_: function(data) {
- var item = this.idMap_[data.id];
-
- var activeControl = this.shadowRoot.activeElement == item ?
- item.shadowRoot.activeElement : null;
-
- item.update(data);
-
- this.async(function() {
- if (activeControl && !cr.ui.FocusRow.isFocusable(activeControl)) {
- var focusRow = this.focusGrid_.getRowForRoot(item.content);
- focusRow.getEquivalentElement(activeControl).focus();
- }
- }.bind(this));
+ updateItem_: function(index, data) {
+ this.set('items_.' + index, data);
+ this.updateHideDates_(index, index);
+ this.$['downloads-list'].updateSizeForItem(index);
},
});
- Manager.size = function() {
- return document.querySelector('downloads-manager').size_();
+ Manager.clearAll = function() {
+ Manager.get().clearAll_();
};
- Manager.updateAll = function(list) {
- document.querySelector('downloads-manager').updateAll_(list);
+ /** @return {!downloads.Manager} */
+ Manager.get = function() {
+ return /** @type {!downloads.Manager} */(
+ queryRequiredElement('downloads-manager'));
};
- Manager.updateItem = function(item) {
- document.querySelector('downloads-manager').updateItem_(item);
+ Manager.insertItems = function(index, list) {
+ Manager.get().insertItems_(index, list);
};
Manager.onLoad = function() {
- document.querySelector('downloads-manager').onLoad_();
+ Manager.get().onLoad_();
+ };
+
+ Manager.removeItem = function(index) {
+ Manager.get().removeItem_(index);
+ };
+
+ Manager.updateItem = function(index, data) {
+ Manager.get().updateItem_(index, data);
};
return {Manager: Manager};
});
-
-window.addEventListener('load', downloads.Manager.onLoad);
diff --git a/chromium/chrome/browser/resources/md_downloads/shared_style.css b/chromium/chrome/browser/resources/md_downloads/shared_style.css
index 171fdf1f15a..73d304a807f 100644
--- a/chromium/chrome/browser/resources/md_downloads/shared_style.css
+++ b/chromium/chrome/browser/resources/md_downloads/shared_style.css
@@ -6,6 +6,10 @@
--downloads-item-width: 622px;
}
+[hidden] {
+ display: none !important;
+}
+
paper-button {
font-weight: 500;
margin: 0;
diff --git a/chromium/chrome/browser/resources/md_downloads/strings.html b/chromium/chrome/browser/resources/md_downloads/strings.html
deleted file mode 100644
index ecbe002923b..00000000000
--- a/chromium/chrome/browser/resources/md_downloads/strings.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/load_time_data.html">
-<script src="chrome://downloads/strings.js"></script>
diff --git a/chromium/chrome/browser/resources/md_downloads/toolbar.css b/chromium/chrome/browser/resources/md_downloads/toolbar.css
index c765a7ada29..3e8d151af5e 100644
--- a/chromium/chrome/browser/resources/md_downloads/toolbar.css
+++ b/chromium/chrome/browser/resources/md_downloads/toolbar.css
@@ -4,32 +4,43 @@
:host {
align-items: center;
- background: rgb(63, 85, 102);
+ background: rgb(52, 73, 94);
color: white;
content-sizing: padding-box;
display: flex;
- height: 56px;
+ min-height: 56px;
}
#title h1 {
-webkit-margin-end: 0;
-webkit-margin-start: 24px;
- font-size: 107.7%;
+ font-size: 123.1%;
font-weight: normal;
margin-bottom: 0;
margin-top: 0;
}
#actions {
+ color: rgb(176, 190, 197);
display: flex;
flex: none;
width: var(--downloads-item-width);
}
+:host-context([loading]) #actions {
+ visibility: hidden;
+}
+
:host(:not([downloads-showing])) #actions {
justify-content: center;
}
+#actions paper-button {
+ --paper-button-flat-keyboard-focus: {
+ color: white;
+ };
+}
+
#actions paper-button:first-of-type {
-webkit-margin-start: -0.57em; /* Matches paper-button padding. */
}
@@ -42,16 +53,6 @@
-webkit-margin-end: -0.57em; /* Matches paper-button padding. */
}
-/* TODO(dbeam): use --paper-button-flat-keyboard-focus when possible.
- * https://github.com/PolymerElements/paper-button/pull/54 */
-#actions paper-button /deep/ .keyboard-focus {
- color: white;
-}
-
-#actions {
- color: rgb(192, 199, 205);
-}
-
#search {
-webkit-padding-end: 10px;
box-sizing: border-box;
@@ -69,9 +70,9 @@ paper-icon-button {
--iron-icon-height: 20px;
--iron-icon-width: 20px;
--paper-icon-button: {
- height: 20px;
+ height: 32px;
padding: 6px;
- width: 20px;
+ width: 32px;
};
}
diff --git a/chromium/chrome/browser/resources/md_downloads/toolbar.html b/chromium/chrome/browser/resources/md_downloads/toolbar.html
index e7d4a9b7d83..72fe293517a 100644
--- a/chromium/chrome/browser/resources/md_downloads/toolbar.html
+++ b/chromium/chrome/browser/resources/md_downloads/toolbar.html
@@ -5,9 +5,11 @@
<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu-button/paper-menu-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/cr_search_field/cr_search_field.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_search_field/cr_search_field.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/cr.html">
+<link rel="import" href="chrome://resources/html/util.html">
+<link rel="import" href="chrome://downloads/i18n_setup.html">
<dom-module id="downloads-toolbar">
<template>
@@ -16,21 +18,21 @@
</div>
<div id="actions">
<paper-button class="clear-all" i18n-content="clearAll"
- on-click="onClearAllClick_"></paper-button>
+ on-tap="onClearAllTap_"></paper-button>
<paper-button i18n-content="openDownloadsFolder"
- on-click="onOpenDownloadsFolderClick_"></paper-button>
+ on-tap="onOpenDownloadsFolderTap_"></paper-button>
</div>
<div id="search">
<cr-search-field id="search-input"
i18n-values="label:search;clear-label:clearSearch"></cr-search-field>
- <paper-menu-button id="more" horizontal-align="right">
+ <paper-menu-button id="more" horizontal-align="[[overflowAlign_]]">
<paper-icon-button icon="more-vert" i18n-values="title:moreActions"
class="dropdown-trigger"></paper-icon-button>
<paper-menu class="dropdown-content">
<paper-item class="clear-all" i18n-content="clearAll"
- on-click="onClearAllClick_"></paper-item>
+ on-tap="onClearAllTap_"></paper-item>
<paper-item i18n-content="openDownloadsFolder"
- on-click="onOpenDownloadsFolderClick_"></paper-item>
+ on-tap="onOpenDownloadsFolderTap_"></paper-item>
</paper-menu>
</paper-menu-button>
</div>
diff --git a/chromium/chrome/browser/resources/md_downloads/toolbar.js b/chromium/chrome/browser/resources/md_downloads/toolbar.js
index 4827868e680..ff9173ee452 100644
--- a/chromium/chrome/browser/resources/md_downloads/toolbar.js
+++ b/chromium/chrome/browser/resources/md_downloads/toolbar.js
@@ -7,6 +7,9 @@ cr.define('downloads', function() {
is: 'downloads-toolbar',
attached: function() {
+ // isRTL() only works after i18n_template.js runs to set <html dir>.
+ this.overflowAlign_ = isRTL() ? 'left' : 'right';
+
/** @private {!SearchFieldDelegate} */
this.searchFieldDelegate_ = new ToolbarSearchFieldDelegate(this);
this.$['search-input'].setDelegate(this.searchFieldDelegate_);
@@ -19,6 +22,11 @@ cr.define('downloads', function() {
value: false,
observer: 'onDownloadsShowingChange_',
},
+
+ overflowAlign_: {
+ type: String,
+ value: 'right',
+ },
},
/** @return {boolean} Whether removal can be undone. */
@@ -32,7 +40,7 @@ cr.define('downloads', function() {
},
/** @private */
- onClearAllClick_: function() {
+ onClearAllTap_: function() {
assert(this.canClearAll());
downloads.ActionService.getInstance().clearAll();
},
@@ -49,7 +57,7 @@ cr.define('downloads', function() {
},
/** @private */
- onOpenDownloadsFolderClick_: function() {
+ onOpenDownloadsFolderTap_: function() {
downloads.ActionService.getInstance().openDownloadsFolder();
},
diff --git a/chromium/chrome/browser/resources/md_downloads/vulcanize.py b/chromium/chrome/browser/resources/md_downloads/vulcanize.py
new file mode 100755
index 00000000000..ab324856b95
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_downloads/vulcanize.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+# 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.
+
+import os
+import subprocess
+import sys
+import tempfile
+
+
+_HERE_PATH = os.path.join(os.path.dirname(__file__))
+
+_HTML_IN_PATH = os.path.join(_HERE_PATH, 'downloads.html')
+_HTML_OUT_PATH = os.path.join(_HERE_PATH, 'vulcanized.html')
+_JS_OUT_PATH = os.path.join(_HERE_PATH, 'crisper.js')
+
+_SRC_PATH = os.path.normpath(os.path.join(_HERE_PATH, '..', '..', '..', '..'))
+
+_RESOURCES_PATH = os.path.join(_SRC_PATH, 'ui', 'webui', 'resources')
+
+_CR_ELEMENTS_PATH = os.path.join(_RESOURCES_PATH, 'cr_elements')
+_CSS_RESOURCES_PATH = os.path.join(_RESOURCES_PATH, 'css')
+_HTML_RESOURCES_PATH = os.path.join(_RESOURCES_PATH, 'html')
+_JS_RESOURCES_PATH = os.path.join(_RESOURCES_PATH, 'js')
+
+_POLYMER_PATH = os.path.join(
+ _SRC_PATH, 'third_party', 'polymer', 'v1_0', 'components-chromium')
+_WEB_ANIMATIONS_PATH = os.path.join(
+ _SRC_PATH, 'third_party', 'web-animations-js', 'sources')
+
+_VULCANIZE_ARGS = [
+ '--exclude', 'crisper.js',
+ '--exclude', 'load_time_data.js',
+ '--exclude', 'strings.js',
+ '--exclude', 'text_defaults.css',
+ '--inline-css',
+ '--inline-scripts',
+ '--redirect', 'chrome://downloads/|%s' % _HERE_PATH,
+ '--redirect', 'chrome://resources/cr_elements/|%s' % _CR_ELEMENTS_PATH,
+ '--redirect', 'chrome://resources/css/|%s' % _CSS_RESOURCES_PATH,
+ '--redirect', 'chrome://resources/html/|%s' % _HTML_RESOURCES_PATH,
+ '--redirect', 'chrome://resources/js/|%s' % _JS_RESOURCES_PATH,
+ '--redirect', 'chrome://resources/polymer/v1_0/web-animations-js/|%s' % _WEB_ANIMATIONS_PATH,
+ '--redirect', 'chrome://resources/polymer/v1_0/|%s' % _POLYMER_PATH,
+ '--strip-comments',
+]
+
+def main():
+ def _run_cmd(cmd_parts, stdout=None):
+ cmd = "'" + "' '".join(cmd_parts) + "'"
+ process = subprocess.Popen(
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ stdout, stderr = process.communicate()
+
+ if stderr:
+ print >> sys.stderr, '%s failed: %s' % (cmd, stderr)
+ raise
+
+ return stdout
+
+ output = _run_cmd(['vulcanize'] + _VULCANIZE_ARGS + [_HTML_IN_PATH])
+
+ with tempfile.NamedTemporaryFile(mode='wt+', delete=False) as tmp:
+ tmp.write(output.replace(
+ '<include src="', '<include src="../../../../ui/webui/resources/js/'))
+
+ try:
+ _run_cmd(['crisper', '--source', tmp.name, '--html', _HTML_OUT_PATH,
+ '--js', _JS_OUT_PATH])
+ finally:
+ os.remove(tmp.name)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/chromium/chrome/browser/resources/md_downloads/vulcanize_readme.md b/chromium/chrome/browser/resources/md_downloads/vulcanize_readme.md
new file mode 100644
index 00000000000..1a20f9c4d09
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_downloads/vulcanize_readme.md
@@ -0,0 +1,45 @@
+# Vulcanizing Material Design downloads
+
+`vulcanize` is an npm module used to combine resources. In order to make the
+Material Design downloads page sufficiently fast, we run vulcanize on the source
+files to combine them and reduce blocking load/parse time.
+
+## Required software
+
+Vulcanization currently requires:
+
+- node.js: v0.10.25 (can be found with `node --version`)
+- npm: 1.3.10 (can be found with `npm --version`)
+- vulcanize: 1.12.3 (can be found with `vulcanize --version`)
+- crisper: 1.0.7 (can be found with `npm info crisper`)
+
+## Installing required software
+
+For instructions on installing node and npm, see
+[here](https://docs.npmjs.com/getting-started/installing-node).
+
+Once you've installed npm, you can get `crisper` and `vulcanize` via:
+
+```bash
+$ sudo npm install -g crisper vulcanize
+```
+
+## Combining resources with vulcanize
+
+To combine all the CSS/HTML/JS for the downloads page to make it production
+fast, you can run the commands:
+
+```bash
+$ chrome/browser/resources/md_downloads/vulcanize.py # from src/
+```
+
+This should overwrite the following files:
+
+- chrome/browser/resources/md_downloads/
+ - vulcanized.html (all <link rel=import> and stylesheets inlined)
+ - crisper.js (all JavaScript, extracted from vulcanized.html)
+
+## Testing downloads without vulcanizing
+
+If you're locally working on the downloads page, you can simply load this URL to
+bypass the vulcanized version: `chrome://downloads/dev.html`
diff --git a/chromium/chrome/browser/resources/md_downloads/vulcanized.html b/chromium/chrome/browser/resources/md_downloads/vulcanized.html
new file mode 100644
index 00000000000..c8610f43a2a
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_downloads/vulcanized.html
@@ -0,0 +1,2853 @@
+<!DOCTYPE html><html i18n-values="dir:textdirection;lang:language"><head><!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+--><!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+--><!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+ <meta charset="utf-8">
+ <title i18n-content="title"></title>
+ <style>
+/* 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. */
+
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'),
+ url("chrome://resources/roboto/roboto-regular.woff2") format('woff2');
+}
+
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'),
+ url("chrome://resources/roboto/roboto-medium.woff2") format('woff2');
+}
+
+</style>
+ <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
+ <style>
+ html {
+ background: rgb(236, 239, 241);
+ }
+
+ html,
+ body {
+ height: 100%;
+ }
+
+ body {
+ display: flex;
+ font-family: Roboto;
+ font-size: 81.25%;
+ margin: 0;
+ }
+ </style>
+<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://downloads/strings.js"></script>
+<style>
+ /* IE 10 support for HTML5 hidden attr */
+ [hidden] {
+ display: none !important;
+ }
+</style>
+
+<style is="custom-style">
+ :root {
+
+ --layout: {
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ };
+
+ --layout-inline: {
+ display: -ms-inline-flexbox;
+ display: -webkit-inline-flex;
+ display: inline-flex;
+ };
+
+ --layout-horizontal: {
+ @apply(--layout);
+
+ -ms-flex-direction: row;
+ -webkit-flex-direction: row;
+ flex-direction: row;
+ };
+
+ --layout-horizontal-reverse: {
+ @apply(--layout);
+
+ -ms-flex-direction: row-reverse;
+ -webkit-flex-direction: row-reverse;
+ flex-direction: row-reverse;
+ };
+
+ --layout-vertical: {
+ @apply(--layout);
+
+ -ms-flex-direction: column;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ };
+
+ --layout-vertical-reverse: {
+ @apply(--layout);
+
+ -ms-flex-direction: column-reverse;
+ -webkit-flex-direction: column-reverse;
+ flex-direction: column-reverse;
+ };
+
+ --layout-wrap: {
+ -ms-flex-wrap: wrap;
+ -webkit-flex-wrap: wrap;
+ flex-wrap: wrap;
+ };
+
+ --layout-wrap-reverse: {
+ -ms-flex-wrap: wrap-reverse;
+ -webkit-flex-wrap: wrap-reverse;
+ flex-wrap: wrap-reverse;
+ };
+
+ --layout-flex-auto: {
+ -ms-flex: 1 1 auto;
+ -webkit-flex: 1 1 auto;
+ flex: 1 1 auto;
+ };
+
+ --layout-flex-none: {
+ -ms-flex: none;
+ -webkit-flex: none;
+ flex: none;
+ };
+
+ --layout-flex: {
+ -ms-flex: 1 1 0.000000001px;
+ -webkit-flex: 1;
+ flex: 1;
+ -webkit-flex-basis: 0.000000001px;
+ flex-basis: 0.000000001px;
+ };
+
+ --layout-flex-2: {
+ -ms-flex: 2;
+ -webkit-flex: 2;
+ flex: 2;
+ };
+
+ --layout-flex-3: {
+ -ms-flex: 3;
+ -webkit-flex: 3;
+ flex: 3;
+ };
+
+ --layout-flex-4: {
+ -ms-flex: 4;
+ -webkit-flex: 4;
+ flex: 4;
+ };
+
+ --layout-flex-5: {
+ -ms-flex: 5;
+ -webkit-flex: 5;
+ flex: 5;
+ };
+
+ --layout-flex-6: {
+ -ms-flex: 6;
+ -webkit-flex: 6;
+ flex: 6;
+ };
+
+ --layout-flex-7: {
+ -ms-flex: 7;
+ -webkit-flex: 7;
+ flex: 7;
+ };
+
+ --layout-flex-8: {
+ -ms-flex: 8;
+ -webkit-flex: 8;
+ flex: 8;
+ };
+
+ --layout-flex-9: {
+ -ms-flex: 9;
+ -webkit-flex: 9;
+ flex: 9;
+ };
+
+ --layout-flex-10: {
+ -ms-flex: 10;
+ -webkit-flex: 10;
+ flex: 10;
+ };
+
+ --layout-flex-11: {
+ -ms-flex: 11;
+ -webkit-flex: 11;
+ flex: 11;
+ };
+
+ --layout-flex-12: {
+ -ms-flex: 12;
+ -webkit-flex: 12;
+ flex: 12;
+ };
+
+ /* alignment in cross axis */
+
+ --layout-start: {
+ -ms-flex-align: start;
+ -webkit-align-items: flex-start;
+ align-items: flex-start;
+ };
+
+ --layout-center: {
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+ };
+
+ --layout-end: {
+ -ms-flex-align: end;
+ -webkit-align-items: flex-end;
+ align-items: flex-end;
+ };
+
+ /* alignment in main axis */
+
+ --layout-start-justified: {
+ -ms-flex-pack: start;
+ -webkit-justify-content: flex-start;
+ justify-content: flex-start;
+ };
+
+ --layout-center-justified: {
+ -ms-flex-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ };
+
+ --layout-end-justified: {
+ -ms-flex-pack: end;
+ -webkit-justify-content: flex-end;
+ justify-content: flex-end;
+ };
+
+ --layout-around-justified: {
+ -ms-flex-pack: around;
+ -webkit-justify-content: space-around;
+ justify-content: space-around;
+ };
+
+ --layout-justified: {
+ -ms-flex-pack: justify;
+ -webkit-justify-content: space-between;
+ justify-content: space-between;
+ };
+
+ --layout-center-center: {
+ @apply(--layout-center);
+ @apply(--layout-center-justified);
+ };
+
+ /* self alignment */
+
+ --layout-self-start: {
+ -ms-align-self: flex-start;
+ -webkit-align-self: flex-start;
+ align-self: flex-start;
+ };
+
+ --layout-self-center: {
+ -ms-align-self: center;
+ -webkit-align-self: center;
+ align-self: center;
+ };
+
+ --layout-self-end: {
+ -ms-align-self: flex-end;
+ -webkit-align-self: flex-end;
+ align-self: flex-end;
+ };
+
+ --layout-self-stretch: {
+ -ms-align-self: stretch;
+ -webkit-align-self: stretch;
+ align-self: stretch;
+ };
+
+ /*******************************
+ Other Layout
+ *******************************/
+
+ --layout-block: {
+ display: block;
+ };
+
+ --layout-invisible: {
+ visibility: hidden !important;
+ };
+
+ --layout-relative: {
+ position: relative;
+ };
+
+ --layout-fit: {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ };
+
+ --layout-scroll: {
+ -webkit-overflow-scrolling: touch;
+ overflow: auto;
+ };
+
+ --layout-fullbleed: {
+ margin: 0;
+ height: 100vh;
+ };
+
+ /* fixed position */
+
+ --layout-fixed-top: {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ };
+
+ --layout-fixed-right: {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ };
+
+ --layout-fixed-bottom: {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ };
+
+ --layout-fixed-left: {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ };
+
+ }
+
+</style>
+
+
+
+
+<style is="custom-style">
+
+ :root {
+
+ --shadow-transition: {
+ transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
+ };
+
+ --shadow-none: {
+ box-shadow: none;
+ };
+
+ /* from http://codepen.io/shyndman/pen/c5394ddf2e8b2a5c9185904b57421cdb */
+
+ --shadow-elevation-2dp: {
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 5px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 1px -2px rgba(0, 0, 0, 0.2);
+ };
+
+ --shadow-elevation-3dp: {
+ box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 8px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 3px -2px rgba(0, 0, 0, 0.4);
+ };
+
+ --shadow-elevation-4dp: {
+ box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 10px 0 rgba(0, 0, 0, 0.12),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.4);
+ };
+
+ --shadow-elevation-6dp: {
+ box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 18px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 5px -1px rgba(0, 0, 0, 0.4);
+ };
+
+ --shadow-elevation-8dp: {
+ box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
+ 0 3px 14px 2px rgba(0, 0, 0, 0.12),
+ 0 5px 5px -3px rgba(0, 0, 0, 0.4);
+ };
+
+ --shadow-elevation-16dp: {
+ box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14),
+ 0 6px 30px 5px rgba(0, 0, 0, 0.12),
+ 0 8px 10px -5px rgba(0, 0, 0, 0.4);
+ };
+
+ }
+
+</style>
+
+
+
+
+<style is="custom-style">
+
+ :root {
+
+ /* Material Design color palette for Google products */
+
+ --google-red-100: #f4c7c3;
+ --google-red-300: #e67c73;
+ --google-red-500: #db4437;
+ --google-red-700: #c53929;
+
+ --google-blue-100: #c6dafc;
+ --google-blue-300: #7baaf7;
+ --google-blue-500: #4285f4;
+ --google-blue-700: #3367d6;
+
+ --google-green-100: #b7e1cd;
+ --google-green-300: #57bb8a;
+ --google-green-500: #0f9d58;
+ --google-green-700: #0b8043;
+
+ --google-yellow-100: #fce8b2;
+ --google-yellow-300: #f7cb4d;
+ --google-yellow-500: #f4b400;
+ --google-yellow-700: #f09300;
+
+ --google-grey-100: #f5f5f5;
+ --google-grey-300: #e0e0e0;
+ --google-grey-500: #9e9e9e;
+ --google-grey-700: #616161;
+
+ /* Material Design color palette from online spec document */
+
+ --paper-red-50: #ffebee;
+ --paper-red-100: #ffcdd2;
+ --paper-red-200: #ef9a9a;
+ --paper-red-300: #e57373;
+ --paper-red-400: #ef5350;
+ --paper-red-500: #f44336;
+ --paper-red-600: #e53935;
+ --paper-red-700: #d32f2f;
+ --paper-red-800: #c62828;
+ --paper-red-900: #b71c1c;
+ --paper-red-a100: #ff8a80;
+ --paper-red-a200: #ff5252;
+ --paper-red-a400: #ff1744;
+ --paper-red-a700: #d50000;
+
+ --paper-pink-50: #fce4ec;
+ --paper-pink-100: #f8bbd0;
+ --paper-pink-200: #f48fb1;
+ --paper-pink-300: #f06292;
+ --paper-pink-400: #ec407a;
+ --paper-pink-500: #e91e63;
+ --paper-pink-600: #d81b60;
+ --paper-pink-700: #c2185b;
+ --paper-pink-800: #ad1457;
+ --paper-pink-900: #880e4f;
+ --paper-pink-a100: #ff80ab;
+ --paper-pink-a200: #ff4081;
+ --paper-pink-a400: #f50057;
+ --paper-pink-a700: #c51162;
+
+ --paper-purple-50: #f3e5f5;
+ --paper-purple-100: #e1bee7;
+ --paper-purple-200: #ce93d8;
+ --paper-purple-300: #ba68c8;
+ --paper-purple-400: #ab47bc;
+ --paper-purple-500: #9c27b0;
+ --paper-purple-600: #8e24aa;
+ --paper-purple-700: #7b1fa2;
+ --paper-purple-800: #6a1b9a;
+ --paper-purple-900: #4a148c;
+ --paper-purple-a100: #ea80fc;
+ --paper-purple-a200: #e040fb;
+ --paper-purple-a400: #d500f9;
+ --paper-purple-a700: #aa00ff;
+
+ --paper-deep-purple-50: #ede7f6;
+ --paper-deep-purple-100: #d1c4e9;
+ --paper-deep-purple-200: #b39ddb;
+ --paper-deep-purple-300: #9575cd;
+ --paper-deep-purple-400: #7e57c2;
+ --paper-deep-purple-500: #673ab7;
+ --paper-deep-purple-600: #5e35b1;
+ --paper-deep-purple-700: #512da8;
+ --paper-deep-purple-800: #4527a0;
+ --paper-deep-purple-900: #311b92;
+ --paper-deep-purple-a100: #b388ff;
+ --paper-deep-purple-a200: #7c4dff;
+ --paper-deep-purple-a400: #651fff;
+ --paper-deep-purple-a700: #6200ea;
+
+ --paper-indigo-50: #e8eaf6;
+ --paper-indigo-100: #c5cae9;
+ --paper-indigo-200: #9fa8da;
+ --paper-indigo-300: #7986cb;
+ --paper-indigo-400: #5c6bc0;
+ --paper-indigo-500: #3f51b5;
+ --paper-indigo-600: #3949ab;
+ --paper-indigo-700: #303f9f;
+ --paper-indigo-800: #283593;
+ --paper-indigo-900: #1a237e;
+ --paper-indigo-a100: #8c9eff;
+ --paper-indigo-a200: #536dfe;
+ --paper-indigo-a400: #3d5afe;
+ --paper-indigo-a700: #304ffe;
+
+ --paper-blue-50: #e3f2fd;
+ --paper-blue-100: #bbdefb;
+ --paper-blue-200: #90caf9;
+ --paper-blue-300: #64b5f6;
+ --paper-blue-400: #42a5f5;
+ --paper-blue-500: #2196f3;
+ --paper-blue-600: #1e88e5;
+ --paper-blue-700: #1976d2;
+ --paper-blue-800: #1565c0;
+ --paper-blue-900: #0d47a1;
+ --paper-blue-a100: #82b1ff;
+ --paper-blue-a200: #448aff;
+ --paper-blue-a400: #2979ff;
+ --paper-blue-a700: #2962ff;
+
+ --paper-light-blue-50: #e1f5fe;
+ --paper-light-blue-100: #b3e5fc;
+ --paper-light-blue-200: #81d4fa;
+ --paper-light-blue-300: #4fc3f7;
+ --paper-light-blue-400: #29b6f6;
+ --paper-light-blue-500: #03a9f4;
+ --paper-light-blue-600: #039be5;
+ --paper-light-blue-700: #0288d1;
+ --paper-light-blue-800: #0277bd;
+ --paper-light-blue-900: #01579b;
+ --paper-light-blue-a100: #80d8ff;
+ --paper-light-blue-a200: #40c4ff;
+ --paper-light-blue-a400: #00b0ff;
+ --paper-light-blue-a700: #0091ea;
+
+ --paper-cyan-50: #e0f7fa;
+ --paper-cyan-100: #b2ebf2;
+ --paper-cyan-200: #80deea;
+ --paper-cyan-300: #4dd0e1;
+ --paper-cyan-400: #26c6da;
+ --paper-cyan-500: #00bcd4;
+ --paper-cyan-600: #00acc1;
+ --paper-cyan-700: #0097a7;
+ --paper-cyan-800: #00838f;
+ --paper-cyan-900: #006064;
+ --paper-cyan-a100: #84ffff;
+ --paper-cyan-a200: #18ffff;
+ --paper-cyan-a400: #00e5ff;
+ --paper-cyan-a700: #00b8d4;
+
+ --paper-teal-50: #e0f2f1;
+ --paper-teal-100: #b2dfdb;
+ --paper-teal-200: #80cbc4;
+ --paper-teal-300: #4db6ac;
+ --paper-teal-400: #26a69a;
+ --paper-teal-500: #009688;
+ --paper-teal-600: #00897b;
+ --paper-teal-700: #00796b;
+ --paper-teal-800: #00695c;
+ --paper-teal-900: #004d40;
+ --paper-teal-a100: #a7ffeb;
+ --paper-teal-a200: #64ffda;
+ --paper-teal-a400: #1de9b6;
+ --paper-teal-a700: #00bfa5;
+
+ --paper-green-50: #e8f5e9;
+ --paper-green-100: #c8e6c9;
+ --paper-green-200: #a5d6a7;
+ --paper-green-300: #81c784;
+ --paper-green-400: #66bb6a;
+ --paper-green-500: #4caf50;
+ --paper-green-600: #43a047;
+ --paper-green-700: #388e3c;
+ --paper-green-800: #2e7d32;
+ --paper-green-900: #1b5e20;
+ --paper-green-a100: #b9f6ca;
+ --paper-green-a200: #69f0ae;
+ --paper-green-a400: #00e676;
+ --paper-green-a700: #00c853;
+
+ --paper-light-green-50: #f1f8e9;
+ --paper-light-green-100: #dcedc8;
+ --paper-light-green-200: #c5e1a5;
+ --paper-light-green-300: #aed581;
+ --paper-light-green-400: #9ccc65;
+ --paper-light-green-500: #8bc34a;
+ --paper-light-green-600: #7cb342;
+ --paper-light-green-700: #689f38;
+ --paper-light-green-800: #558b2f;
+ --paper-light-green-900: #33691e;
+ --paper-light-green-a100: #ccff90;
+ --paper-light-green-a200: #b2ff59;
+ --paper-light-green-a400: #76ff03;
+ --paper-light-green-a700: #64dd17;
+
+ --paper-lime-50: #f9fbe7;
+ --paper-lime-100: #f0f4c3;
+ --paper-lime-200: #e6ee9c;
+ --paper-lime-300: #dce775;
+ --paper-lime-400: #d4e157;
+ --paper-lime-500: #cddc39;
+ --paper-lime-600: #c0ca33;
+ --paper-lime-700: #afb42b;
+ --paper-lime-800: #9e9d24;
+ --paper-lime-900: #827717;
+ --paper-lime-a100: #f4ff81;
+ --paper-lime-a200: #eeff41;
+ --paper-lime-a400: #c6ff00;
+ --paper-lime-a700: #aeea00;
+
+ --paper-yellow-50: #fffde7;
+ --paper-yellow-100: #fff9c4;
+ --paper-yellow-200: #fff59d;
+ --paper-yellow-300: #fff176;
+ --paper-yellow-400: #ffee58;
+ --paper-yellow-500: #ffeb3b;
+ --paper-yellow-600: #fdd835;
+ --paper-yellow-700: #fbc02d;
+ --paper-yellow-800: #f9a825;
+ --paper-yellow-900: #f57f17;
+ --paper-yellow-a100: #ffff8d;
+ --paper-yellow-a200: #ffff00;
+ --paper-yellow-a400: #ffea00;
+ --paper-yellow-a700: #ffd600;
+
+ --paper-amber-50: #fff8e1;
+ --paper-amber-100: #ffecb3;
+ --paper-amber-200: #ffe082;
+ --paper-amber-300: #ffd54f;
+ --paper-amber-400: #ffca28;
+ --paper-amber-500: #ffc107;
+ --paper-amber-600: #ffb300;
+ --paper-amber-700: #ffa000;
+ --paper-amber-800: #ff8f00;
+ --paper-amber-900: #ff6f00;
+ --paper-amber-a100: #ffe57f;
+ --paper-amber-a200: #ffd740;
+ --paper-amber-a400: #ffc400;
+ --paper-amber-a700: #ffab00;
+
+ --paper-orange-50: #fff3e0;
+ --paper-orange-100: #ffe0b2;
+ --paper-orange-200: #ffcc80;
+ --paper-orange-300: #ffb74d;
+ --paper-orange-400: #ffa726;
+ --paper-orange-500: #ff9800;
+ --paper-orange-600: #fb8c00;
+ --paper-orange-700: #f57c00;
+ --paper-orange-800: #ef6c00;
+ --paper-orange-900: #e65100;
+ --paper-orange-a100: #ffd180;
+ --paper-orange-a200: #ffab40;
+ --paper-orange-a400: #ff9100;
+ --paper-orange-a700: #ff6500;
+
+ --paper-deep-orange-50: #fbe9e7;
+ --paper-deep-orange-100: #ffccbc;
+ --paper-deep-orange-200: #ffab91;
+ --paper-deep-orange-300: #ff8a65;
+ --paper-deep-orange-400: #ff7043;
+ --paper-deep-orange-500: #ff5722;
+ --paper-deep-orange-600: #f4511e;
+ --paper-deep-orange-700: #e64a19;
+ --paper-deep-orange-800: #d84315;
+ --paper-deep-orange-900: #bf360c;
+ --paper-deep-orange-a100: #ff9e80;
+ --paper-deep-orange-a200: #ff6e40;
+ --paper-deep-orange-a400: #ff3d00;
+ --paper-deep-orange-a700: #dd2c00;
+
+ --paper-brown-50: #efebe9;
+ --paper-brown-100: #d7ccc8;
+ --paper-brown-200: #bcaaa4;
+ --paper-brown-300: #a1887f;
+ --paper-brown-400: #8d6e63;
+ --paper-brown-500: #795548;
+ --paper-brown-600: #6d4c41;
+ --paper-brown-700: #5d4037;
+ --paper-brown-800: #4e342e;
+ --paper-brown-900: #3e2723;
+
+ --paper-grey-50: #fafafa;
+ --paper-grey-100: #f5f5f5;
+ --paper-grey-200: #eeeeee;
+ --paper-grey-300: #e0e0e0;
+ --paper-grey-400: #bdbdbd;
+ --paper-grey-500: #9e9e9e;
+ --paper-grey-600: #757575;
+ --paper-grey-700: #616161;
+ --paper-grey-800: #424242;
+ --paper-grey-900: #212121;
+
+ --paper-blue-grey-50: #eceff1;
+ --paper-blue-grey-100: #cfd8dc;
+ --paper-blue-grey-200: #b0bec5;
+ --paper-blue-grey-300: #90a4ae;
+ --paper-blue-grey-400: #78909c;
+ --paper-blue-grey-500: #607d8b;
+ --paper-blue-grey-600: #546e7a;
+ --paper-blue-grey-700: #455a64;
+ --paper-blue-grey-800: #37474f;
+ --paper-blue-grey-900: #263238;
+
+ /* opacity for dark text on a light background */
+ --dark-divider-opacity: 0.12;
+ --dark-disabled-opacity: 0.38; /* or hint text or icon */
+ --dark-secondary-opacity: 0.54;
+ --dark-primary-opacity: 0.87;
+
+ /* opacity for light text on a dark background */
+ --light-divider-opacity: 0.12;
+ --light-disabled-opacity: 0.3; /* or hint text or icon */
+ --light-secondary-opacity: 0.7;
+ --light-primary-opacity: 1.0;
+
+ }
+
+</style>
+
+
+<style is="custom-style">
+
+ :root {
+
+ --dark-primary-color: #303f9f;
+
+ --default-primary-color: #3f51b5;
+
+ --light-primary-color: #c5cae9;
+
+ --text-primary-color: #ffffff;
+
+ --accent-color: #ff4081;
+
+ --primary-background-color: #ffffff;
+
+ --primary-text-color: #212121;
+
+ --secondary-text-color: #757575;
+
+ --disabled-text-color: #bdbdbd;
+
+ --divider-color: #e0e0e0;
+
+ }
+
+</style>
+
+
+
+
+
+
+
+
+<style>
+/* 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. */
+
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Roboto'), local('Roboto-Regular'),
+ url("chrome://resources/roboto/roboto-regular.woff2") format('woff2');
+}
+
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Roboto Medium'), local('Roboto-Medium'),
+ url("chrome://resources/roboto/roboto-medium.woff2") format('woff2');
+}
+
+</style>
+<style is="custom-style">
+
+ :root {
+
+ /* Shared Styles */
+
+ /*
+ Unfortunately, we can't use nested rules
+ See https://github.com/Polymer/polymer/issues/1399
+ */
+ --paper-font-common-base: {
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ };
+
+ --paper-font-common-code: {
+ font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;
+ -webkit-font-smoothing: antialiased;
+ };
+
+ --paper-font-common-expensive-kerning: {
+ text-rendering: optimizeLegibility;
+ };
+
+ --paper-font-common-nowrap: {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ };
+
+ /* Material Font Styles */
+
+ --paper-font-display4: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 112px;
+ font-weight: 300;
+ letter-spacing: -.044em;
+ line-height: 120px;
+ };
+
+ --paper-font-display3: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 56px;
+ font-weight: 400;
+ letter-spacing: -.026em;
+ line-height: 60px;
+ };
+
+ --paper-font-display2: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+
+ font-size: 45px;
+ font-weight: 400;
+ letter-spacing: -.018em;
+ line-height: 48px;
+ };
+
+ --paper-font-display1: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+
+ font-size: 34px;
+ font-weight: 400;
+ letter-spacing: -.01em;
+ line-height: 40px;
+ };
+
+ --paper-font-headline: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+
+ font-size: 24px;
+ font-weight: 400;
+ letter-spacing: -.012em;
+ line-height: 32px;
+ };
+
+ --paper-font-title: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 20px;
+ font-weight: 500;
+ line-height: 28px;
+ };
+
+ --paper-font-subhead: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 24px;
+ };
+
+ --paper-font-body2: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 24px;
+ };
+
+ --paper-font-body1: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 20px;
+ };
+
+ --paper-font-caption: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 12px;
+ font-weight: 400;
+ letter-spacing: 0.011em;
+ line-height: 20px;
+ };
+
+ --paper-font-menu: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 24px;
+ };
+
+ --paper-font-button: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 14px;
+ font-weight: 500;
+ letter-spacing: 0.018em;
+ line-height: 24px;
+ text-transform: uppercase;
+ };
+
+ --paper-font-code2: {
+ /* @apply(--paper-font-common-code); */
+ font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;
+ -webkit-font-smoothing: antialiased;
+
+ font-size: 14px;
+ font-weight: 700;
+ line-height: 20px;
+ };
+
+ --paper-font-code1: {
+ /* @apply(--paper-font-common-code); */
+ font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace;
+ -webkit-font-smoothing: antialiased;
+
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 20px;
+ };
+
+ }
+
+</style>
+
+</head>
+<body><div hidden="" by-vulcanize=""><dom-module id="iron-list" assetpath="chrome://resources/polymer/v1_0/iron-list/">
+ <template>
+ <style>
+ :host {
+ display: block;
+ }
+
+ :host(.has-scroller) {
+ overflow: auto;
+ }
+
+ :host(:not(.has-scroller)) {
+ position: relative;
+ }
+
+ #items {
+ @apply(--iron-list-items-container);
+ position: relative;
+ }
+
+ #items > ::content > * {
+ width: 100%;
+ box-sizing: border-box;
+ position: absolute;
+ top: 0;
+ will-change: transform;
+ }
+ </style>
+
+ <array-selector id="selector" items="{{items}}" selected="{{selectedItems}}" selected-item="{{selectedItem}}">
+ </array-selector>
+
+ <div id="items">
+ <content></content>
+ </div>
+
+ </template>
+</dom-module>
+
+<dom-module id="iron-icon" assetpath="chrome://resources/polymer/v1_0/iron-icon/">
+
+ <style>
+ :host {
+ @apply(--layout-inline);
+ @apply(--layout-center-center);
+ position: relative;
+
+ vertical-align: middle;
+
+ fill: var(--iron-icon-fill-color, currentcolor);
+ stroke: var(--iron-icon-stroke-color, none);
+
+ width: var(--iron-icon-width, 24px);
+ height: var(--iron-icon-height, 24px);
+ }
+ </style>
+
+ <template>
+ </template>
+
+ </dom-module>
+<iron-iconset-svg name="icons" size="24">
+<svg><defs>
+<g id="3d-rotation"><path d="M7.52 21.48C4.25 19.94 1.91 16.76 1.55 13H.05C.56 19.16 5.71 24 12 24l.66-.03-3.81-3.81-1.33 1.32zm.89-6.52c-.19 0-.37-.03-.52-.08-.16-.06-.29-.13-.4-.24-.11-.1-.2-.22-.26-.37-.06-.14-.09-.3-.09-.47h-1.3c0 .36.07.68.21.95.14.27.33.5.56.69.24.18.51.32.82.41.3.1.62.15.96.15.37 0 .72-.05 1.03-.15.32-.1.6-.25.83-.44s.42-.43.55-.72c.13-.29.2-.61.2-.97 0-.19-.02-.38-.07-.56-.05-.18-.12-.35-.23-.51-.1-.16-.24-.3-.4-.43-.17-.13-.37-.23-.61-.31.2-.09.37-.2.52-.33.15-.13.27-.27.37-.42.1-.15.17-.3.22-.46.05-.16.07-.32.07-.48 0-.36-.06-.68-.18-.96-.12-.28-.29-.51-.51-.69-.2-.19-.47-.33-.77-.43C9.1 8.05 8.76 8 8.39 8c-.36 0-.69.05-1 .16-.3.11-.57.26-.79.45-.21.19-.38.41-.51.67-.12.26-.18.54-.18.85h1.3c0-.17.03-.32.09-.45s.14-.25.25-.34c.11-.09.23-.17.38-.22.15-.05.3-.08.48-.08.4 0 .7.1.89.31.19.2.29.49.29.86 0 .18-.03.34-.08.49-.05.15-.14.27-.25.37-.11.1-.25.18-.41.24-.16.06-.36.09-.58.09H7.5v1.03h.77c.22 0 .42.02.6.07s.33.13.45.23c.12.11.22.24.29.4.07.16.1.35.1.57 0 .41-.12.72-.35.93-.23.23-.55.33-.95.33zm8.55-5.92c-.32-.33-.7-.59-1.14-.77-.43-.18-.92-.27-1.46-.27H12v8h2.3c.55 0 1.06-.09 1.51-.27.45-.18.84-.43 1.16-.76.32-.33.57-.73.74-1.19.17-.47.26-.99.26-1.57v-.4c0-.58-.09-1.1-.26-1.57-.18-.47-.43-.87-.75-1.2zm-.39 3.16c0 .42-.05.79-.14 1.13-.1.33-.24.62-.43.85-.19.23-.43.41-.71.53-.29.12-.62.18-.99.18h-.91V9.12h.97c.72 0 1.27.23 1.64.69.38.46.57 1.12.57 1.99v.4zM12 0l-.66.03 3.81 3.81 1.33-1.33c3.27 1.55 5.61 4.72 5.96 8.48h1.5C23.44 4.84 18.29 0 12 0z"></path></g>
+<g id="accessibility"><path d="M12 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 7h-6v13h-2v-6h-2v6H9V9H3V7h18v2z"></path></g>
+<g id="account-balance"><path d="M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z"></path></g>
+<g id="account-balance-wallet"><path d="M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"></path></g>
+<g id="account-box"><path d="M3 5v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2zm12 4c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3zm-9 8c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6v-1z"></path></g>
+<g id="account-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"></path></g>
+<g id="add"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path></g>
+<g id="add-alert"><path d="M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72C7.37 5.03 5.12 7.75 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z"></path></g>
+<g id="add-box"><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"></path></g>
+<g id="add-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"></path></g>
+<g id="add-circle-outline"><path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"></path></g>
+<g id="add-shopping-cart"><path d="M11 9h2V6h3V4h-3V1h-2v3H8v2h3v3zm-4 9c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2zm-9.83-3.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.86-7.01L19.42 4h-.01l-1.1 2-2.76 5H8.53l-.13-.27L6.16 6l-.95-2-.94-2H1v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.13 0-.25-.11-.25-.25z"></path></g>
+<g id="alarm"><path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"></path></g>
+<g id="alarm-add"><path d="M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm1-11h-2v3H8v2h3v3h2v-3h3v-2h-3V9z"></path></g>
+<g id="alarm-off"><path d="M12 6c3.87 0 7 3.13 7 7 0 .84-.16 1.65-.43 2.4l1.52 1.52c.58-1.19.91-2.51.91-3.92 0-4.97-4.03-9-9-9-1.41 0-2.73.33-3.92.91L9.6 6.43C10.35 6.16 11.16 6 12 6zm10-.28l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM2.92 2.29L1.65 3.57 2.98 4.9l-1.11.93 1.42 1.42 1.11-.94.8.8C3.83 8.69 3 10.75 3 13c0 4.97 4.02 9 9 9 2.25 0 4.31-.83 5.89-2.2l2.2 2.2 1.27-1.27L3.89 3.27l-.97-.98zm13.55 16.1C15.26 19.39 13.7 20 12 20c-3.87 0-7-3.13-7-7 0-1.7.61-3.26 1.61-4.47l9.86 9.86zM8.02 3.28L6.6 1.86l-.86.71 1.42 1.42.86-.71z"></path></g>
+<g id="alarm-on"><path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-1.46-5.47L8.41 12.4l-1.06 1.06 3.18 3.18 6-6-1.06-1.06-4.93 4.95z"></path></g>
+<g id="android"><path d="M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v7c0 .83.67 1.5 1.5 1.5S5 17.33 5 16.5v-7C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v7c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-7c0-.83-.67-1.5-1.5-1.5zm-4.97-5.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31C6.97 3.26 6 5.01 6 7h12c0-1.99-.97-3.75-2.47-4.84zM10 5H9V4h1v1zm5 0h-1V4h1v1z"></path></g>
+<g id="announcement"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 9h-2V5h2v6zm0 4h-2v-2h2v2z"></path></g>
+<g id="apps"><path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"></path></g>
+<g id="archive"><path d="M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"></path></g>
+<g id="arrow-back"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"></path></g>
+<g id="arrow-drop-down"><path d="M7 10l5 5 5-5z"></path></g>
+<g id="arrow-drop-down-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 12l-4-4h8l-4 4z"></path></g>
+<g id="arrow-drop-up"><path d="M7 14l5-5 5 5z"></path></g>
+<g id="arrow-forward"><path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"></path></g>
+<g id="aspect-ratio"><path d="M19 12h-2v3h-3v2h5v-5zM7 9h3V7H5v5h2V9zm14-6H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z"></path></g>
+<g id="assessment"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"></path></g>
+<g id="assignment"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"></path></g>
+<g id="assignment-ind"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 4c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1.4c0-2 4-3.1 6-3.1s6 1.1 6 3.1V19z"></path></g>
+<g id="assignment-late"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-6 15h-2v-2h2v2zm0-4h-2V8h2v6zm-1-9c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"></path></g>
+<g id="assignment-return"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm4 12h-4v3l-5-5 5-5v3h4v4z"></path></g>
+<g id="assignment-returned"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 15l-5-5h3V9h4v4h3l-5 5z"></path></g>
+<g id="assignment-turned-in"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm-2 14l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"></path></g>
+<g id="attachment"><path d="M7.5 18C4.46 18 2 15.54 2 12.5S4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v1.5H9.5c-.55 0-1 .45-1 1s.45 1 1 1H18c1.38 0 2.5-1.12 2.5-2.5S19.38 8.5 18 8.5H7.5c-2.21 0-4 1.79-4 4s1.79 4 4 4H17V18H7.5z"></path></g>
+<g id="autorenew"><path d="M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z"></path></g>
+<g id="backspace"><path d="M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.9.89 1.59.89h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z"></path></g>
+<g id="backup"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"></path></g>
+<g id="block"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z"></path></g>
+<g id="book"><path d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z"></path></g>
+<g id="bookmark"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"></path></g>
+<g id="bookmark-border"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z"></path></g>
+<g id="bug-report"><path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"></path></g>
+<g id="build"><path d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z"></path></g>
+<g id="cached"><path d="M19 8l-4 4h3c0 3.31-2.69 6-6 6-1.01 0-1.97-.25-2.8-.7l-1.46 1.46C8.97 19.54 10.43 20 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46C15.03 4.46 13.57 4 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z"></path></g>
+<g id="camera-enhance"><path d="M9 3L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2h-3.17L15 3H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zM12 17l1.25-2.75L16 13l-2.75-1.25L12 9l-1.25 2.75L8 13l2.75 1.25z"></path></g>
+<g id="cancel"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"></path></g>
+<g id="card-giftcard"><path d="M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z"></path></g>
+<g id="card-membership"><path d="M20 2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h4v5l4-2 4 2v-5h4c1.11 0 2-.89 2-2V4c0-1.11-.89-2-2-2zm0 13H4v-2h16v2zm0-5H4V4h16v6z"></path></g>
+<g id="card-travel"><path d="M20 6h-3V4c0-1.11-.89-2-2-2H9c-1.11 0-2 .89-2 2v2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zM9 4h6v2H9V4zm11 15H4v-2h16v2zm0-5H4V8h3v2h2V8h6v2h2V8h3v6z"></path></g>
+<g id="change-history"><path d="M12 7.77L18.39 18H5.61L12 7.77M12 4L2 20h20L12 4z"></path></g>
+<g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"></path></g>
+<g id="check-box"><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path></g>
+<g id="check-box-outline-blank"><path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"></path></g>
+<g id="check-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path></g>
+<g id="chevron-left"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path></g>
+<g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></g>
+<g id="chrome-reader-mode"><path d="M13 12h7v1.5h-7zm0-2.5h7V11h-7zm0 5h7V16h-7zM21 4H3c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 15h-9V6h9v13z"></path></g>
+<g id="class"><path d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z"></path></g>
+<g id="clear"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g>
+<g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g>
+<g id="cloud"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z"></path></g>
+<g id="cloud-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.5 14H8c-1.66 0-3-1.34-3-3s1.34-3 3-3l.14.01C8.58 8.28 10.13 7 12 7c2.21 0 4 1.79 4 4h.5c1.38 0 2.5 1.12 2.5 2.5S17.88 16 16.5 16z"></path></g>
+<g id="cloud-done"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM10 17l-3.5-3.5 1.41-1.41L10 14.17 15.18 9l1.41 1.41L10 17z"></path></g>
+<g id="cloud-download"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z"></path></g>
+<g id="cloud-off"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4c-1.48 0-2.85.43-4.01 1.17l1.46 1.46C10.21 6.23 11.08 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3 0 1.13-.64 2.11-1.56 2.62l1.45 1.45C23.16 18.16 24 16.68 24 15c0-2.64-2.05-4.78-4.65-4.96zM3 5.27l2.75 2.74C2.56 8.15 0 10.77 0 14c0 3.31 2.69 6 6 6h11.73l2 2L21 20.73 4.27 4 3 5.27zM7.73 10l8 8H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h1.73z"></path></g>
+<g id="cloud-queue"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 7.69 9.48 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z"></path></g>
+<g id="cloud-upload"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"></path></g>
+<g id="code"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path></g>
+<g id="content-copy"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"></path></g>
+<g id="content-cut"><path d="M9.64 7.64c.23-.5.36-1.05.36-1.64 0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64zM6 8c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm0 12c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm6-7.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5zM19 3l-6 6 2 2 7-7V3z"></path></g>
+<g id="content-paste"><path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path></g>
+<g id="create"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"></path></g>
+<g id="credit-card"><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="dashboard"><path d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"></path></g>
+<g id="delete"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path></g>
+<g id="description"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"></path></g>
+<g id="dns"><path d="M20 13H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 19c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"></path></g>
+<g id="done"><path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"></path></g>
+<g id="done-all"><path d="M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z"></path></g>
+<g id="drafts"><path d="M21.99 8c0-.72-.37-1.35-.94-1.7L12 1 2.95 6.3C2.38 6.65 2 7.28 2 8v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2l-.01-10zM12 13L3.74 7.84 12 3l8.26 4.84L12 13z"></path></g>
+<g id="eject"><path d="M5 17h14v2H5zm7-12L5.33 15h13.34z"></path></g>
+<g id="error"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"></path></g>
+<g id="error-outline"><path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.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></g>
+<g id="event"><path d="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z"></path></g>
+<g id="event-seat"><defs><path id="a" d="M0 0h24v24H0V0z"></path></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"></use></clipPath><path d="M4 18v3h3v-3h10v3h3v-6H4zm15-8h3v3h-3zM2 10h3v3H2zm15 3H7V5c0-1.1.9-2 2-2h6c1.1 0 2 .9 2 2v8z" clip-path="url(#b)"></path></g>
+<g id="exit-to-app"><path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"></path></g>
+<g id="expand-less"><path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"></path></g>
+<g id="expand-more"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"></path></g>
+<g id="explore"><path d="M12 10.9c-.61 0-1.1.49-1.1 1.1s.49 1.1 1.1 1.1c.61 0 1.1-.49 1.1-1.1s-.49-1.1-1.1-1.1zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm2.19 12.19L6 18l3.81-8.19L18 6l-3.81 8.19z"></path></g>
+<g id="extension"><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"></path></g>
+<g id="face"><path d="M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z"></path></g>
+<g id="favorite"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"></path></g>
+<g id="favorite-border"><path d="M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z"></path></g>
+<g id="feedback"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 12h-2v-2h2v2zm0-4h-2V6h2v4z"></path></g>
+<g id="file-download"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path></g>
+<g id="file-upload"><path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"></path></g>
+<g id="filter-list"><path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"></path></g>
+<g id="find-in-page"><path d="M20 19.59V8l-6-6H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c.45 0 .85-.15 1.19-.4l-4.43-4.43c-.8.52-1.74.83-2.76.83-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5c0 1.02-.31 1.96-.83 2.75L20 19.59zM9 13c0 1.66 1.34 3 3 3s3-1.34 3-3-1.34-3-3-3-3 1.34-3 3z"></path></g>
+<g id="find-replace"><path d="M11 6c1.38 0 2.63.56 3.54 1.46L12 10h6V4l-2.05 2.05C14.68 4.78 12.93 4 11 4c-3.53 0-6.43 2.61-6.92 6H6.1c.46-2.28 2.48-4 4.9-4zm5.64 9.14c.66-.9 1.12-1.97 1.28-3.14H15.9c-.46 2.28-2.48 4-4.9 4-1.38 0-2.63-.56-3.54-1.46L10 12H4v6l2.05-2.05C7.32 17.22 9.07 18 11 18c1.55 0 2.98-.51 4.14-1.36L20 21.49 21.49 20l-4.85-4.86z"></path></g>
+<g id="flag"><path d="M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z"></path></g>
+<g id="flight-land"><defs><path id="a" d="M0 0h24v24H0V0z"></path></defs><defs><path id="c" d="M0 0h24v24H0V0z"></path></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"></use></clipPath><clipPath id="d" clip-path="url(#b)"><use xlink:href="#c" overflow="visible"></use></clipPath><path d="M2.5 19h19v2h-19zm7.18-5.73l4.35 1.16 5.31 1.42c.8.21 1.62-.26 1.84-1.06.21-.8-.26-1.62-1.06-1.84l-5.31-1.42-2.76-9.02L10.12 2v8.28L5.15 8.95l-.93-2.32-1.45-.39v5.17l1.6.43 5.31 1.43z" clip-path="url(#d)"></path></g>
+<g id="flight-takeoff"><defs><path id="a" d="M0 0h24v24H0V0z"></path></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"></use></clipPath><path d="M2.5 19h19v2h-19zm19.57-9.36c-.21-.8-1.04-1.28-1.84-1.06L14.92 10l-6.9-6.43-1.93.51 4.14 7.17-4.97 1.33-1.97-1.54-1.45.39 1.82 3.16.77 1.33 1.6-.43 5.31-1.42 4.35-1.16L21 11.49c.81-.23 1.28-1.05 1.07-1.85z" clip-path="url(#b)"></path></g>
+<g id="flip-to-back"><path d="M9 7H7v2h2V7zm0 4H7v2h2v-2zm0-8c-1.11 0-2 .9-2 2h2V3zm4 12h-2v2h2v-2zm6-12v2h2c0-1.1-.9-2-2-2zm-6 0h-2v2h2V3zM9 17v-2H7c0 1.1.89 2 2 2zm10-4h2v-2h-2v2zm0-4h2V7h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zM5 7H3v12c0 1.1.89 2 2 2h12v-2H5V7zm10-2h2V3h-2v2zm0 12h2v-2h-2v2z"></path></g>
+<g id="flip-to-front"><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3c0 1.1.89 2 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9c-1.11 0-2 .9-2 2v10c0 1.1.89 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z"></path></g>
+<g id="folder"><path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"></path></g>
+<g id="folder-open"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"></path></g>
+<g id="folder-shared"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4 8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z"></path></g>
+<g id="font-download"><path d="M9.93 13.5h4.14L12 7.98zM20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-4.05 16.5l-1.14-3H9.17l-1.12 3H5.96l5.11-13h1.86l5.11 13h-2.09z"></path></g>
+<g id="forward"><path d="M12 8V4l8 8-8 8v-4H4V8z"></path></g>
+<g id="fullscreen"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"></path></g>
+<g id="fullscreen-exit"><path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"></path></g>
+<g id="gesture"><path d="M4.59 6.89c.7-.71 1.4-1.35 1.71-1.22.5.2 0 1.03-.3 1.52-.25.42-2.86 3.89-2.86 6.31 0 1.28.48 2.34 1.34 2.98.75.56 1.74.73 2.64.46 1.07-.31 1.95-1.4 3.06-2.77 1.21-1.49 2.83-3.44 4.08-3.44 1.63 0 1.65 1.01 1.76 1.79-3.78.64-5.38 3.67-5.38 5.37 0 1.7 1.44 3.09 3.21 3.09 1.63 0 4.29-1.33 4.69-6.1H21v-2.5h-2.47c-.15-1.65-1.09-4.2-4.03-4.2-2.25 0-4.18 1.91-4.94 2.84-.58.73-2.06 2.48-2.29 2.72-.25.3-.68.84-1.11.84-.45 0-.72-.83-.36-1.92.35-1.09 1.4-2.86 1.85-3.52.78-1.14 1.3-1.92 1.3-3.28C8.95 3.69 7.31 3 6.44 3 5.12 3 3.97 4 3.72 4.25c-.36.36-.66.66-.88.93l1.75 1.71zm9.29 11.66c-.31 0-.74-.26-.74-.72 0-.6.73-2.2 2.87-2.76-.3 2.69-1.43 3.48-2.13 3.48z"></path></g>
+<g id="get-app"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path></g>
+<g id="gif"><defs><path id="a" d="M24 24H0V0h24v24z"></path></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"></use></clipPath><path d="M11.5 9H13v6h-1.5zM9 9H6c-.6 0-1 .5-1 1v4c0 .5.4 1 1 1h3c.6 0 1-.5 1-1v-2H8.5v1.5h-2v-3H10V10c0-.5-.4-1-1-1zm10 1.5V9h-4.5v6H16v-2h2v-1.5h-2v-1z" clip-path="url(#b)"></path></g>
+<g id="grade"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path></g>
+<g id="group-work"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM8 17.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5zM9.5 8c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5S9.5 9.38 9.5 8zm6.5 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"></path></g>
+<g id="help"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"></path></g>
+<g id="help-outline"><path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"></path></g>
+<g id="highlight-off"><path d="M14.59 8L12 10.59 9.41 8 8 9.41 10.59 12 8 14.59 9.41 16 12 13.41 14.59 16 16 14.59 13.41 12 16 9.41 14.59 8zM12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"></path></g>
+<g id="history"><path opacity=".9" d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"></path></g>
+<g id="home"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"></path></g>
+<g id="hourglass-empty"><path d="M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6zm10 14.5V20H8v-3.5l4-4 4 4zm-4-5l-4-4V4h8v3.5l-4 4z"></path></g>
+<g id="hourglass-full"><path d="M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6z"></path></g>
+<g id="http"><path d="M4.5 11h-2V9H1v6h1.5v-2.5h2V15H6V9H4.5v2zm2.5-.5h1.5V15H10v-4.5h1.5V9H7v1.5zm5.5 0H14V15h1.5v-4.5H17V9h-4.5v1.5zm9-1.5H18v6h1.5v-2h2c.8 0 1.5-.7 1.5-1.5v-1c0-.8-.7-1.5-1.5-1.5zm0 2.5h-2v-1h2v1z"></path></g>
+<g id="https"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"></path></g>
+<g id="inbox"><path d="M19 3H4.99c-1.1 0-1.98.9-1.98 2L3 19c0 1.1.89 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12h-4c0 1.66-1.34 3-3 3s-3-1.34-3-3H4.99V5H19v10zm-3-5h-2V7h-4v3H8l4 4 4-4z"></path></g>
+<g id="indeterminate-check-box"><defs><path id="a" d="M0 0h24v24H0z"></path></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"></use></clipPath><path clip-path="url(#b)" d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10H7v-2h10v2z"></path></g>
+<g id="info"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"></path></g>
+<g id="info-outline"><path d="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"></path></g>
+<g id="input"><path d="M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14c0-1.11-.9-2-2-2zM11 16l4-4-4-4v3H1v2h10v3z"></path></g>
+<g id="invert-colors"><path d="M17.66 7.93L12 2.27 6.34 7.93c-3.12 3.12-3.12 8.19 0 11.31C7.9 20.8 9.95 21.58 12 21.58c2.05 0 4.1-.78 5.66-2.34 3.12-3.12 3.12-8.19 0-11.31zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59s.62-3.11 1.76-4.24L12 5.1v14.49z"></path></g>
+<g id="label"><path d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z"></path></g>
+<g id="label-outline"><path d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16zM16 17H5V7h11l3.55 5L16 17z"></path></g>
+<g id="language"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"></path></g>
+<g id="launch"><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"></path></g>
+<g id="link"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></g>
+<g id="list"><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"></path></g>
+<g id="lock"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"></path></g>
+<g id="lock-open"><path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z"></path></g>
+<g id="lock-outline"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6-5.1c1.71 0 3.1 1.39 3.1 3.1v2H9V6h-.1c0-1.71 1.39-3.1 3.1-3.1zM18 20H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"></path></g>
+<g id="loyalty"><path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7zm11.77 8.27L13 19.54l-4.27-4.27C8.28 14.81 8 14.19 8 13.5c0-1.38 1.12-2.5 2.5-2.5.69 0 1.32.28 1.77.74l.73.72.73-.73c.45-.45 1.08-.73 1.77-.73 1.38 0 2.5 1.12 2.5 2.5 0 .69-.28 1.32-.73 1.77z"></path></g>
+<g id="mail"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"></path></g>
+<g id="markunread"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"></path></g>
+<g id="markunread-mailbox"><path d="M20 6H10v6H8V4h6V0H6v6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2z"></path></g>
+<g id="menu"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></g>
+<g id="more-horiz"><path d="M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path></g>
+<g id="more-vert"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path></g>
+<g id="note-add"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 14h-3v3h-2v-3H8v-2h3v-3h2v3h3v2zm-3-7V3.5L18.5 9H13z"></path></g>
+<g id="offline-pin"><defs><path id="a" d="M0 0h24v24H0V0z"></path></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"></use></clipPath><path clip-path="url(#b)" d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm5 16H7v-2h10v2zm-6.7-4L7 10.7l1.4-1.4 1.9 1.9 5.3-5.3L17 7.3 10.3 14z"></path></g>
+<g id="open-in-browser"><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z"></path></g>
+<g id="open-in-new"><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"></path></g>
+<g id="open-with"><path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"></path></g>
+<g id="pageview"><path d="M11.5 9C10.12 9 9 10.12 9 11.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5S12.88 9 11.5 9zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-3.21 14.21l-2.91-2.91c-.69.44-1.51.7-2.39.7C9.01 16 7 13.99 7 11.5S9.01 7 11.5 7 16 9.01 16 11.5c0 .88-.26 1.69-.7 2.39l2.91 2.9-1.42 1.42z"></path></g>
+<g id="payment"><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="perm-camera-mic"><path d="M20 5h-3.17L15 3H9L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v-2.09c-2.83-.48-5-2.94-5-5.91h2c0 2.21 1.79 4 4 4s4-1.79 4-4h2c0 2.97-2.17 5.43-5 5.91V21h7c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-6 8c0 1.1-.9 2-2 2s-2-.9-2-2V9c0-1.1.9-2 2-2s2 .9 2 2v4z"></path></g>
+<g id="perm-contact-calendar"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1z"></path></g>
+<g id="perm-data-setting"><path d="M18.99 11.5c.34 0 .67.03 1 .07L20 0 0 20h11.56c-.04-.33-.07-.66-.07-1 0-4.14 3.36-7.5 7.5-7.5zm3.71 7.99c.02-.16.04-.32.04-.49 0-.17-.01-.33-.04-.49l1.06-.83c.09-.08.12-.21.06-.32l-1-1.73c-.06-.11-.19-.15-.31-.11l-1.24.5c-.26-.2-.54-.37-.85-.49l-.19-1.32c-.01-.12-.12-.21-.24-.21h-2c-.12 0-.23.09-.25.21l-.19 1.32c-.3.13-.59.29-.85.49l-1.24-.5c-.11-.04-.24 0-.31.11l-1 1.73c-.06.11-.04.24.06.32l1.06.83c-.02.16-.03.32-.03.49 0 .17.01.33.03.49l-1.06.83c-.09.08-.12.21-.06.32l1 1.73c.06.11.19.15.31.11l1.24-.5c.26.2.54.37.85.49l.19 1.32c.02.12.12.21.25.21h2c.12 0 .23-.09.25-.21l.19-1.32c.3-.13.59-.29.84-.49l1.25.5c.11.04.24 0 .31-.11l1-1.73c.06-.11.03-.24-.06-.32l-1.07-.83zm-3.71 1.01c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"></path></g>
+<g id="perm-device-information"><path d="M13 7h-2v2h2V7zm0 4h-2v6h2v-6zm4-9.99L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"></path></g>
+<g id="perm-identity"><path d="M12 5.9c1.16 0 2.1.94 2.1 2.1s-.94 2.1-2.1 2.1S9.9 9.16 9.9 8s.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z"></path></g>
+<g id="perm-media"><path d="M2 6H0v5h.01L0 20c0 1.1.9 2 2 2h18v-2H2V6zm20-2h-8l-2-2H6c-1.1 0-1.99.9-1.99 2L4 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7 15l4.5-6 3.5 4.51 2.5-3.01L21 15H7z"></path></g>
+<g id="perm-phone-msg"><path d="M20 15.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM12 3v10l3-3h6V3h-9z"></path></g>
+<g id="perm-scan-wifi"><path d="M12 3C6.95 3 3.15 4.85 0 7.23L12 22 24 7.25C20.85 4.87 17.05 3 12 3zm1 13h-2v-6h2v6zm-2-8V6h2v2h-2z"></path></g>
+<g id="picture-in-picture"><path d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z"></path></g>
+<g id="play-for-work"><path fill="#010101" d="M11 5v5.59H7.5l4.5 4.5 4.5-4.5H13V5h-2zm-5 9c0 3.31 2.69 6 6 6s6-2.69 6-6h-2c0 2.21-1.79 4-4 4s-4-1.79-4-4H6z"></path></g>
+<g id="polymer"><path d="M19 4h-4L7.11 16.63 4.5 12 9 4H5L.5 12 5 20h4l7.89-12.63L19.5 12 15 20h4l4.5-8z"></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="print"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"></path></g>
+<g id="query-builder"><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 8zM12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"></path></g>
+<g id="question-answer"><path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"></path></g>
+<g id="radio-button-checked"><path d="M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path></g>
+<g id="radio-button-unchecked"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"></path></g>
+<g id="receipt"><path d="M18 17H6v-2h12v2zm0-4H6v-2h12v2zm0-4H6V7h12v2zM3 22l1.5-1.5L6 22l1.5-1.5L9 22l1.5-1.5L12 22l1.5-1.5L15 22l1.5-1.5L18 22l1.5-1.5L21 22V2l-1.5 1.5L18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2 4.5 3.5 3 2v20z"></path></g>
+<g id="redeem"><path d="M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z"></path></g>
+<g id="redo"><path d="M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z"></path></g>
+<g id="refresh"><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"></path></g>
+<g id="remove"><path d="M19 13H5v-2h14v2z"></path></g>
+<g id="remove-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z"></path></g>
+<g id="remove-circle-outline"><path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"></path></g>
+<g id="reorder"><path d="M3 15h18v-2H3v2zm0 4h18v-2H3v2zm0-8h18V9H3v2zm0-6v2h18V5H3z"></path></g>
+<g id="reply"><path d="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"></path></g>
+<g id="reply-all"><path d="M7 8V5l-7 7 7 7v-3l-4-4 4-4zm6 1V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"></path></g>
+<g id="report"><path d="M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM12 17.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zm1-4.3h-2V7h2v6z"></path></g>
+<g id="report-problem"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g>
+<g id="restore"><path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"></path></g>
+<g id="room"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"></path></g>
+<g id="save"><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"></path></g>
+<g id="schedule"><path fill-opacity=".9" 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 8zM12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"></path></g>
+<g id="search"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></g>
+<g id="select-all"><path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z"></path></g>
+<g id="send"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"></path></g>
+<g id="settings"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path></g>
+<g id="settings-applications"><path d="M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm7-7H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-1.75 9c0 .23-.02.46-.05.68l1.48 1.16c.13.11.17.3.08.45l-1.4 2.42c-.09.15-.27.21-.43.15l-1.74-.7c-.36.28-.76.51-1.18.69l-.26 1.85c-.03.17-.18.3-.35.3h-2.8c-.17 0-.32-.13-.35-.29l-.26-1.85c-.43-.18-.82-.41-1.18-.69l-1.74.7c-.16.06-.34 0-.43-.15l-1.4-2.42c-.09-.15-.05-.34.08-.45l1.48-1.16c-.03-.23-.05-.46-.05-.69 0-.23.02-.46.05-.68l-1.48-1.16c-.13-.11-.17-.3-.08-.45l1.4-2.42c.09-.15.27-.21.43-.15l1.74.7c.36-.28.76-.51 1.18-.69l.26-1.85c.03-.17.18-.3.35-.3h2.8c.17 0 .32.13.35.29l.26 1.85c.43.18.82.41 1.18.69l1.74-.7c.16-.06.34 0 .43.15l1.4 2.42c.09.15.05.34-.08.45l-1.48 1.16c.03.23.05.46.05.69z"></path></g>
+<g id="settings-backup-restore"><path d="M14 12c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-9c-4.97 0-9 4.03-9 9H0l4 4 4-4H5c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.51 0-2.91-.49-4.06-1.3l-1.42 1.44C8.04 20.3 9.94 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9z"></path></g>
+<g id="settings-bluetooth"><path d="M11 24h2v-2h-2v2zm-4 0h2v-2H7v2zm8 0h2v-2h-2v2zm2.71-18.29L12 0h-1v7.59L6.41 3 5 4.41 10.59 10 5 15.59 6.41 17 11 12.41V20h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 3.83l1.88 1.88L13 7.59V3.83zm1.88 10.46L13 16.17v-3.76l1.88 1.88z"></path></g>
+<g id="settings-brightness"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02zM8 16h2.5l1.5 1.5 1.5-1.5H16v-2.5l1.5-1.5-1.5-1.5V8h-2.5L12 6.5 10.5 8H8v2.5L6.5 12 8 13.5V16zm4-7c1.66 0 3 1.34 3 3s-1.34 3-3 3V9z"></path></g>
+<g id="settings-cell"><path d="M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM16 .01L8 0C6.9 0 6 .9 6 2v16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V2c0-1.1-.9-1.99-2-1.99zM16 16H8V4h8v12z"></path></g>
+<g id="settings-ethernet"><path d="M7.77 6.76L6.23 5.48.82 12l5.41 6.52 1.54-1.28L3.42 12l4.35-5.24zM7 13h2v-2H7v2zm10-2h-2v2h2v-2zm-6 2h2v-2h-2v2zm6.77-7.52l-1.54 1.28L20.58 12l-4.35 5.24 1.54 1.28L23.18 12l-5.41-6.52z"></path></g>
+<g id="settings-input-antenna"><path d="M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29 0-1.38-1.12-2.5-2.5-2.5S9.5 10.62 9.5 12c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2c0-4.97 4.03-9 9-9s9 4.03 9 9h2c0-6.07-4.93-11-11-11z"></path></g>
+<g id="settings-input-component"><path d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"></path></g>
+<g id="settings-input-composite"><path d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"></path></g>
+<g id="settings-input-hdmi"><path d="M18 7V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v3H5v6l3 6v3h8v-3l3-6V7h-1zM8 4h8v3h-2V5h-1v2h-2V5h-1v2H8V4z"></path></g>
+<g id="settings-input-svideo"><path d="M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"></path></g>
+<g id="settings-overscan"><path d="M12.01 5.5L10 8h4l-1.99-2.5zM18 10v4l2.5-1.99L18 10zM6 10l-2.5 2.01L6 14v-4zm8 6h-4l2.01 2.5L14 16zm7-13H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z"></path></g>
+<g id="settings-phone"><path d="M13 9h-2v2h2V9zm4 0h-2v2h2V9zm3 6.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 9v2h2V9h-2z"></path></g>
+<g id="settings-power"><path d="M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm2-22h-2v10h2V2zm3.56 2.44l-1.45 1.45C16.84 6.94 18 8.83 18 11c0 3.31-2.69 6-6 6s-6-2.69-6-6c0-2.17 1.16-4.06 2.88-5.12L7.44 4.44C5.36 5.88 4 8.28 4 11c0 4.42 3.58 8 8 8s8-3.58 8-8c0-2.72-1.36-5.12-3.44-6.56zM15 24h2v-2h-2v2z"></path></g>
+<g id="settings-remote"><path d="M15 9H9c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V10c0-.55-.45-1-1-1zm-3 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM7.05 6.05l1.41 1.41C9.37 6.56 10.62 6 12 6s2.63.56 3.54 1.46l1.41-1.41C15.68 4.78 13.93 4 12 4s-3.68.78-4.95 2.05zM12 0C8.96 0 6.21 1.23 4.22 3.22l1.41 1.41C7.26 3.01 9.51 2 12 2s4.74 1.01 6.36 2.64l1.41-1.41C17.79 1.23 15.04 0 12 0z"></path></g>
+<g id="settings-voice"><path d="M7 24h2v-2H7v2zm5-11c1.66 0 2.99-1.34 2.99-3L15 4c0-1.66-1.34-3-3-3S9 2.34 9 4v6c0 1.66 1.34 3 3 3zm-1 11h2v-2h-2v2zm4 0h2v-2h-2v2zm4-14h-1.7c0 3-2.54 5.1-5.3 5.1S6.7 13 6.7 10H5c0 3.41 2.72 6.23 6 6.72V20h2v-3.28c3.28-.49 6-3.31 6-6.72z"></path></g>
+<g id="shop"><path d="M16 6V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H2v13c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6h-6zm-6-2h4v2h-4V4zM9 18V9l7.5 4L9 18z"></path></g>
+<g id="shop-two"><path d="M3 9H1v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2H3V9zm15-4V3c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H5v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2V5h-5zm-6-2h4v2h-4V3zm0 12V8l5.5 3-5.5 4z"></path></g>
+<g id="shopping-basket"><path d="M17.21 9l-4.38-6.56c-.19-.28-.51-.42-.83-.42-.32 0-.64.14-.83.43L6.79 9H2c-.55 0-1 .45-1 1 0 .09.01.18.04.27l2.54 9.27c.23.84 1 1.46 1.92 1.46h13c.92 0 1.69-.62 1.93-1.46l2.54-9.27L23 10c0-.55-.45-1-1-1h-4.79zM9 9l3-4.4L15 9H9zm3 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"></path></g>
+<g id="shopping-cart"><path d="M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.08-.14.12-.31.12-.48 0-.55-.45-1-1-1H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z"></path></g>
+<g id="sort"><path d="M3 18h6v-2H3v2zM3 6v2h18V6H3zm0 7h12v-2H3v2z"></path></g>
+<g id="speaker-notes"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 14H6v-2h2v2zm0-3H6V9h2v2zm0-3H6V6h2v2zm7 6h-5v-2h5v2zm3-3h-8V9h8v2zm0-3h-8V6h8v2z"></path></g>
+<g id="spellcheck"><path d="M12.45 16h2.09L9.43 3H7.57L2.46 16h2.09l1.12-3h5.64l1.14 3zm-6.02-5L8.5 5.48 10.57 11H6.43zm15.16.59l-8.09 8.09L9.83 16l-1.41 1.41 5.09 5.09L23 13l-1.41-1.41z"></path></g>
+<g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path></g>
+<g id="star-border"><path d="M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"></path></g>
+<g id="star-half"><path d="M22 9.74l-7.19-.62L12 2.5 9.19 9.13 2 9.74l5.46 4.73-1.64 7.03L12 17.77l6.18 3.73-1.63-7.03L22 9.74zM12 15.9V6.6l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.9z"></path></g>
+<g id="stars"><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 2zm4.24 16L12 15.45 7.77 18l1.12-4.81-3.73-3.23 4.92-.42L12 5l1.92 4.53 4.92.42-3.73 3.23L16.23 18z"></path></g>
+<g id="store"><path d="M20 4H4v2h16V4zm1 10v-2l-1-5H4l-1 5v2h1v6h10v-6h4v6h2v-6h1zm-9 4H6v-4h6v4z"></path></g>
+<g id="subject"><path d="M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z"></path></g>
+<g id="supervisor-account"><path d="M16.5 12c1.38 0 2.49-1.12 2.49-2.5S17.88 7 16.5 7C15.12 7 14 8.12 14 9.5s1.12 2.5 2.5 2.5zM9 11c1.66 0 2.99-1.34 2.99-3S10.66 5 9 5C7.34 5 6 6.34 6 8s1.34 3 3 3zm7.5 3c-1.83 0-5.5.92-5.5 2.75V19h11v-2.25c0-1.83-3.67-2.75-5.5-2.75zM9 13c-2.33 0-7 1.17-7 3.5V19h7v-2.25c0-.85.33-2.34 2.37-3.47C10.5 13.1 9.66 13 9 13z"></path></g>
+<g id="swap-horiz"><path d="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z"></path></g>
+<g id="swap-vert"><path d="M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3L5 6.99h3V14h2V6.99h3L9 3z"></path></g>
+<g id="swap-vertical-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM6.5 9L10 5.5 13.5 9H11v4H9V9H6.5zm11 6L14 18.5 10.5 15H13v-4h2v4h2.5z"></path></g>
+<g id="system-update-alt"><path d="M12 16.5l4-4h-3v-9h-2v9H8l4 4zm9-13h-6v1.99h6v14.03H3V5.49h6V3.5H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-14c0-1.1-.9-2-2-2z"></path></g>
+<g id="tab"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h10v4h8v10z"></path></g>
+<g id="tab-unselected"><path d="M1 9h2V7H1v2zm0 4h2v-2H1v2zm0-8h2V3c-1.1 0-2 .9-2 2zm8 16h2v-2H9v2zm-8-4h2v-2H1v2zm2 4v-2H1c0 1.1.9 2 2 2zM21 3h-8v6h10V5c0-1.1-.9-2-2-2zm0 14h2v-2h-2v2zM9 5h2V3H9v2zM5 21h2v-2H5v2zM5 5h2V3H5v2zm16 16c1.1 0 2-.9 2-2h-2v2zm0-8h2v-2h-2v2zm-8 8h2v-2h-2v2zm4 0h2v-2h-2v2z"></path></g>
+<g id="text-format"><path d="M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98L13.87 11h-3.74L12 5.98z"></path></g>
+<g id="theaters"><path d="M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z"></path></g>
+<g id="thumb-down"><path d="M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v1.91l.01.01L1 14c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z"></path></g>
+<g id="thumb-up"><path d="M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z"></path></g>
+<g id="thumbs-up-down"><path d="M12 6c0-.55-.45-1-1-1H5.82l.66-3.18.02-.23c0-.31-.13-.59-.33-.8L5.38 0 .44 4.94C.17 5.21 0 5.59 0 6v6.5c0 .83.67 1.5 1.5 1.5h6.75c.62 0 1.15-.38 1.38-.91l2.26-5.29c.07-.17.11-.36.11-.55V6zm10.5 4h-6.75c-.62 0-1.15.38-1.38.91l-2.26 5.29c-.07.17-.11.36-.11.55V18c0 .55.45 1 1 1h5.18l-.66 3.18-.02.24c0 .31.13.59.33.8l.79.78 4.94-4.94c.27-.27.44-.65.44-1.06v-6.5c0-.83-.67-1.5-1.5-1.5z"></path></g>
+<g id="toc"><path d="M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z"></path></g>
+<g id="today"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z"></path></g>
+<g id="toll"><path d="M15 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zM3 12c0-2.61 1.67-4.83 4-5.65V4.26C3.55 5.15 1 8.27 1 12s2.55 6.85 6 7.74v-2.09c-2.33-.82-4-3.04-4-5.65z"></path></g>
+<g id="track-changes"><path fill="#231F20" d="M19.07 4.93l-1.41 1.41C19.1 7.79 20 9.79 20 12c0 4.42-3.58 8-8 8s-8-3.58-8-8c0-4.08 3.05-7.44 7-7.93v2.02C8.16 6.57 6 9.03 6 12c0 3.31 2.69 6 6 6s6-2.69 6-6c0-1.66-.67-3.16-1.76-4.24l-1.41 1.41C15.55 9.9 16 10.9 16 12c0 2.21-1.79 4-4 4s-4-1.79-4-4c0-1.86 1.28-3.41 3-3.86v2.14c-.6.35-1 .98-1 1.72 0 1.1.9 2 2 2s2-.9 2-2c0-.74-.4-1.38-1-1.72V2h-1C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10c0-2.76-1.12-5.26-2.93-7.07z"></path></g>
+<g id="translate"><path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"></path></g>
+<g id="trending-down"><path d="M16 18l2.29-2.29-4.88-4.88-4 4L2 7.41 3.41 6l6 6 4-4 6.3 6.29L22 12v6z"></path></g>
+<g id="trending-flat"><path d="M22 12l-4-4v3H3v2h15v3z"></path></g>
+<g id="trending-up"><path d="M16 6l2.29 2.29-4.88 4.88-4-4L2 16.59 3.41 18l6-6 4 4 6.3-6.29L22 12V6z"></path></g>
+<g id="turned-in"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"></path></g>
+<g id="turned-in-not"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z"></path></g>
+<g id="undo"><path d="M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"></path></g>
+<g id="unfold-less"><path d="M7.41 18.59L8.83 20 12 16.83 15.17 20l1.41-1.41L12 14l-4.59 4.59zm9.18-13.18L15.17 4 12 7.17 8.83 4 7.41 5.41 12 10l4.59-4.59z"></path></g>
+<g id="unfold-more"><path d="M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z"></path></g>
+<g id="verified-user"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"></path></g>
+<g id="view-agenda"><path d="M20 13H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zm0-10H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1z"></path></g>
+<g id="view-array"><path d="M4 18h3V5H4v13zM18 5v13h3V5h-3zM8 18h9V5H8v13z"></path></g>
+<g id="view-carousel"><path d="M7 19h10V4H7v15zm-5-2h4V6H2v11zM18 6v11h4V6h-4z"></path></g>
+<g id="view-column"><path d="M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z"></path></g>
+<g id="view-day"><path d="M2 21h19v-3H2v3zM20 8H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zM2 3v3h19V3H2z"></path></g>
+<g id="view-headline"><path d="M4 15h16v-2H4v2zm0 4h16v-2H4v2zm0-8h16V9H4v2zm0-6v2h16V5H4z"></path></g>
+<g id="view-list"><path d="M4 14h4v-4H4v4zm0 5h4v-4H4v4zM4 9h4V5H4v4zm5 5h12v-4H9v4zm0 5h12v-4H9v4zM9 5v4h12V5H9z"></path></g>
+<g id="view-module"><path d="M4 11h5V5H4v6zm0 7h5v-6H4v6zm6 0h5v-6h-5v6zm6 0h5v-6h-5v6zm-6-7h5V5h-5v6zm6-6v6h5V5h-5z"></path></g>
+<g id="view-quilt"><path d="M10 18h5v-6h-5v6zm-6 0h5V5H4v13zm12 0h5v-6h-5v6zM10 5v6h11V5H10z"></path></g>
+<g id="view-stream"><path d="M4 18h17v-6H4v6zM4 5v6h17V5H4z"></path></g>
+<g id="view-week"><path d="M6 5H3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm14 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm-7 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1z"></path></g>
+<g id="visibility"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"></path></g>
+<g id="visibility-off"><path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"></path></g>
+<g id="warning"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g>
+<g id="work"><path d="M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z"></path></g>
+<g id="youtube-searched-for"><path d="M17.01 14h-.8l-.27-.27c.98-1.14 1.57-2.61 1.57-4.23 0-3.59-2.91-6.5-6.5-6.5s-6.5 3-6.5 6.5H2l3.84 4 4.16-4H6.51C6.51 7 8.53 5 11.01 5s4.5 2.01 4.5 4.5c0 2.48-2.02 4.5-4.5 4.5-.65 0-1.26-.14-1.82-.38L7.71 15.1c.97.57 2.09.9 3.3.9 1.61 0 3.08-.59 4.22-1.57l.27.27v.79l5.01 4.99L22 19l-4.99-5z"></path></g>
+<g id="zoom-in"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"></path></g>
+<g id="zoom-out"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"></path></g>
+</defs></svg>
+</iron-iconset-svg>
+<dom-module id="paper-ripple" assetpath="chrome://resources/polymer/v1_0/paper-ripple/">
+
+
+
+ <template>
+ <style>
+ :host {
+ display: block;
+ position: absolute;
+ border-radius: inherit;
+ overflow: hidden;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+
+ /* See PolymerElements/paper-behaviors/issues/34. On non-Chrome browsers,
+ * creating a node (with a position:absolute) in the middle of an event
+ * handler "interrupts" that event handler (which happens when the
+ * ripple is created on demand) */
+ pointer-events: none;
+ }
+
+ :host([animating]) {
+ /* This resolves a rendering issue in Chrome (as of 40) where the
+ ripple is not properly clipped by its parent (which may have
+ rounded corners). See: http://jsbin.com/temexa/4
+
+ Note: We only apply this style conditionally. Otherwise, the browser
+ will create a new compositing layer for every ripple element on the
+ page, and that would be bad. */
+ -webkit-transform: translate(0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+
+ #background,
+ #waves,
+ .wave-container,
+ .wave {
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ }
+
+ #background,
+ .wave {
+ opacity: 0;
+ }
+
+ #waves,
+ .wave {
+ overflow: hidden;
+ }
+
+ .wave-container,
+ .wave {
+ border-radius: 50%;
+ }
+
+ :host(.circle) #background,
+ :host(.circle) #waves {
+ border-radius: 50%;
+ }
+
+ :host(.circle) .wave-container {
+ overflow: hidden;
+ }
+ </style>
+
+ <div id="background"></div>
+ <div id="waves"></div>
+ </template>
+</dom-module>
+<dom-module id="paper-material" assetpath="chrome://resources/polymer/v1_0/paper-material/">
+ <template>
+ <style>
+ :host {
+ display: block;
+ position: relative;
+ }
+
+ :host([animated]) {
+ @apply(--shadow-transition);
+ }
+
+ :host([elevation="1"]) {
+ @apply(--shadow-elevation-2dp);
+ }
+
+ :host([elevation="2"]) {
+ @apply(--shadow-elevation-4dp);
+ }
+
+ :host([elevation="3"]) {
+ @apply(--shadow-elevation-6dp);
+ }
+
+ :host([elevation="4"]) {
+ @apply(--shadow-elevation-8dp);
+ }
+
+ :host([elevation="5"]) {
+ @apply(--shadow-elevation-16dp);
+ }
+ </style>
+
+ <content></content>
+ </template>
+</dom-module>
+<dom-module id="paper-button" assetpath="chrome://resources/polymer/v1_0/paper-button/">
+ <template strip-whitespace="">
+
+ <style include="paper-material">
+ :host {
+ display: inline-block;
+ position: relative;
+ box-sizing: border-box;
+ min-width: 5.14em;
+ margin: 0 0.29em;
+ background: transparent;
+ text-align: center;
+ font: inherit;
+ text-transform: uppercase;
+ outline-width: 0;
+ border-radius: 3px;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -webkit-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ z-index: 0;
+ padding: 0.7em 0.57em;
+
+ @apply(--paper-button);
+ }
+
+ :host([raised].keyboard-focus) {
+ font-weight: bold;
+ @apply(--paper-button-raised-keyboard-focus);
+ }
+
+ :host(:not([raised]).keyboard-focus) {
+ font-weight: bold;
+ @apply(--paper-button-flat-keyboard-focus);
+ }
+
+ :host([disabled]) {
+ background: #eaeaea;
+ color: #a8a8a8;
+ cursor: auto;
+ pointer-events: none;
+
+ @apply(--paper-button-disabled);
+ }
+
+ paper-ripple {
+ color: var(--paper-button-ink-color);
+ }
+
+ :host > ::content * {
+ text-transform: inherit;
+ }
+ </style>
+ <content></content>
+ </template>
+</dom-module>
+
+<dom-module id="paper-progress" assetpath="chrome://resources/polymer/v1_0/paper-progress/">
+ <style>
+ :host {
+ display: block;
+ width: 200px;
+ position: relative;
+ overflow: hidden;
+ }
+
+ #progressContainer {
+ position: relative;
+ }
+
+ #progressContainer,
+ /* the stripe for the indeterminate animation*/
+ .indeterminate:after {
+ height: var(--paper-progress-height, 4px);
+ }
+
+ #primaryProgress,
+ #secondaryProgress,
+ .indeterminate:after {
+ @apply(--layout-fit);
+ }
+
+ #progressContainer,
+ .indeterminate:after {
+ background-color: var(--paper-progress-container-color, --google-grey-300);
+ }
+
+ :host(.transiting) #primaryProgress,
+ :host(.transiting) #secondaryProgress {
+ -webkit-transition-property: -webkit-transform;
+ transition-property: transform;
+
+ /* Duration */
+ -webkit-transition-duration: var(--paper-progress-transition-duration, 0.08s);
+ transition-duration: var(--paper-progress-transition-duration, 0.08s);
+
+ /* Timing function */
+ -webkit-transition-timing-function: var(--paper-progress-transition-timing-function, ease);
+ transition-timing-function: var(--paper-progress-transition-timing-function, ease);
+
+ /* Delay */
+ -webkit-transition-delay: var(--paper-progress-transition-delay, 0s);
+ transition-delay: var(--paper-progress-transition-delay, 0s);
+ }
+
+ #primaryProgress,
+ #secondaryProgress {
+ @apply(--layout-fit);
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+ -webkit-transform: scaleX(0);
+ transform: scaleX(0);
+ will-change: transform;
+ }
+
+ #primaryProgress {
+ background-color: var(--paper-progress-active-color, --google-green-500);
+ }
+
+ #secondaryProgress {
+ position: relative;
+ background-color: var(--paper-progress-secondary-color, --google-green-100);
+ }
+
+ :host([disabled]) #primaryProgress {
+ background-color: var(--paper-progress-disabled-active-color, --google-grey-500);
+ }
+
+ :host([disabled]) #secondaryProgress {
+ background-color: var(--paper-progress-disabled-active-color, --google-grey-300);
+ }
+
+ :host(:not([disabled])) #primaryProgress.indeterminate {
+ -webkit-transform-origin: right center;
+ transform-origin: right center;
+ -webkit-animation: indeterminate-bar 2s linear infinite;
+ animation: indeterminate-bar 2s linear infinite;
+ }
+
+ :host(:not([disabled])) #primaryProgress.indeterminate:after {
+ content: "";
+ -webkit-transform-origin: center center;
+ transform-origin: center center;
+
+ -webkit-animation: indeterminate-splitter 2s linear infinite;
+ animation: indeterminate-splitter 2s linear infinite;
+ }
+
+ @-webkit-keyframes indeterminate-bar {
+ 0% {
+ -webkit-transform: scaleX(1) translateX(-100%);
+ }
+ 50% {
+ -webkit-transform: scaleX(1) translateX(0%);
+ }
+ 75% {
+ -webkit-transform: scaleX(1) translateX(0%);
+ -webkit-animation-timing-function: cubic-bezier(.28,.62,.37,.91);
+ }
+ 100% {
+ -webkit-transform: scaleX(0) translateX(0%);
+ }
+ }
+
+ @-webkit-keyframes indeterminate-splitter {
+ 0% {
+ -webkit-transform: scaleX(.75) translateX(-125%);
+ }
+ 30% {
+ -webkit-transform: scaleX(.75) translateX(-125%);
+ -webkit-animation-timing-function: cubic-bezier(.42,0,.6,.8);
+ }
+ 90% {
+ -webkit-transform: scaleX(.75) translateX(125%);
+ }
+ 100% {
+ -webkit-transform: scaleX(.75) translateX(125%);
+ }
+ }
+
+ @keyframes indeterminate-bar {
+ 0% {
+ transform: scaleX(1) translateX(-100%);
+ }
+ 50% {
+ transform: scaleX(1) translateX(0%);
+ }
+ 75% {
+ transform: scaleX(1) translateX(0%);
+ animation-timing-function: cubic-bezier(.28,.62,.37,.91);
+ }
+ 100% {
+ transform: scaleX(0) translateX(0%);
+ }
+ }
+
+ @keyframes indeterminate-splitter {
+ 0% {
+ transform: scaleX(.75) translateX(-125%);
+ }
+ 30% {
+ transform: scaleX(.75) translateX(-125%);
+ animation-timing-function: cubic-bezier(.42,0,.6,.8);
+ }
+ 90% {
+ transform: scaleX(.75) translateX(125%);
+ }
+ 100% {
+ transform: scaleX(.75) translateX(125%);
+ }
+ }
+ </style>
+ <template>
+ <div id="progressContainer">
+ <div id="secondaryProgress" hidden$="[[_hideSecondaryProgress(secondaryRatio)]]"></div>
+ <div id="primaryProgress"></div>
+ </div>
+ </template>
+</dom-module>
+
+<dom-module id="inky-text-button" assetpath="chrome://downloads/">
+ <template><content></content></template>
+ <style>
+ :host {
+ -webkit-user-select: none;
+ cursor: pointer;
+ display: inline-block;
+ outline: none;
+ position: relative;
+ text-align: center;
+ }
+ </style>
+</dom-module>
+
+<dom-module id="downloads-item" assetpath="chrome://downloads/">
+ <template>
+ <h3 id="date">[[computeDate_(data.hideDate, data.since_string, data.date_string)]]</h3>
+
+ <div id="content" on-dragstart="onDragStart_" class$="[[computeClass_(isActive_, isDangerous_, showProgress_)]]">
+ <div id="file-icon-wrapper" class="icon-wrapper">
+ <img class="icon" id="file-icon" alt="" hidden="[[isDangerous_]]">
+ <iron-icon id="danger-icon" icon$="[[computeDangerIcon_(isDangerous_, data.danger_type)]]" hidden="[[!isDangerous_]]"></iron-icon>
+ </div>
+
+ <div id="details">
+ <div id="title-area"><a is="action-link" id="file-link" href="[[data.url]]" on-tap="onFileLinkTap_" hidden="[[!completelyOnDisk_]]">[[data.file_name]]</a><span id="name" hidden="[[completelyOnDisk_]]">[[data.file_name]]</span>
+ <span id="tag">[[computeTag_(data.state, data.last_reason_text, data.file_externally_removed)]]</span>
+ </div>
+
+ <a id="url" target="_blank" href="[[data.url]]">[[data.url]]</a>
+
+ <div id="description">[[computeDescription_(data.state, data.danger_type, data.file_name, data.progress_status_text)]]</div>
+
+ <template is="dom-if" if="[[showProgress_]]">
+ <paper-progress id="progress" indeterminate="[[isIndeterminate_(data.percent)]]" value="[[data.percent]]"></paper-progress>
+ </template>
+
+ <div id="safe" class="controls" hidden="[[isDangerous_]]">
+ <a is="action-link" id="show" i18n-content="controlShowInFolder" on-tap="onShowTap_" hidden="[[!completelyOnDisk_]]"></a>
+ <template is="dom-if" if="[[data.retry]]">
+ <paper-button id="retry" on-tap="onRetryTap_">[[i18n_.retry]]</paper-button>
+ </template>
+ <template is="dom-if" if="[[isInProgress_]]">
+ <paper-button id="pause" on-tap="onPauseTap_">[[i18n_.pause]]</paper-button>
+ </template>
+ <template is="dom-if" if="[[data.resume]]">
+ <paper-button id="resume" on-tap="onResumeTap_">[[i18n_.resume]]</paper-button>
+ </template>
+ <template is="dom-if" if="[[showCancel_]]">
+ <paper-button id="cancel" on-tap="onCancelTap_">[[i18n_.cancel]]</paper-button>
+ </template>
+ <span id="controlled-by"></span>
+ </div>
+
+ <template is="dom-if" if="[[isDangerous_]]">
+ <div id="dangerous" class="controls">
+
+ <template is="dom-if" if="[[!isMalware_]]">
+ <paper-button id="discard" on-tap="onDiscardDangerousTap_" class="discard">[[i18n_.discard]]</paper-button>
+ <paper-button id="save" on-tap="onSaveDangerousTap_" class="keep">[[i18n_.save]]</paper-button>
+ </template>
+
+
+ <template is="dom-if" if="[[isMalware_]]">
+ <paper-button id="danger-remove" on-tap="onDiscardDangerousTap_" class="discard">[[i18n_.remove]]</paper-button>
+ <paper-button id="restore" on-tap="onSaveDangerousTap_" class="keep">[[i18n_.restore]]</paper-button>
+ </template>
+ </div>
+ </template>
+ </div>
+
+ <div id="remove-wrapper" class="icon-wrapper">
+ <inky-text-button id="remove" i18n-values="title:controlRemoveFromList" style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]" on-tap="onRemoveTap_">✕</inky-text-button>
+ </div>
+
+ <div id="incognito" i18n-values="title:inIncognito" hidden="[[!data.otr]]"></div>
+ </div>
+
+ </template>
+ <style>
+/* 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. */
+
+[is='action-link'] {
+ cursor: pointer;
+ display: inline-block;
+ text-decoration: none;
+}
+
+[is='action-link']:hover {
+ text-decoration: underline;
+}
+
+[is='action-link']:active {
+ color: rgb(5, 37, 119);
+ text-decoration: underline;
+}
+
+[is='action-link'][disabled] {
+ color: #999;
+ cursor: default;
+ pointer-events: none;
+ text-decoration: none;
+}
+
+[is='action-link'].no-outline {
+ outline: none;
+}
+
+</style>
+ <style>
+/* 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. */
+
+* {
+ --downloads-item-width: 622px;
+}
+
+[hidden] {
+ display: none !important;
+}
+
+paper-button {
+ font-weight: 500;
+ margin: 0;
+ min-width: auto;
+}
+
+</style>
+ <style>
+/* 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. */
+
+:host {
+ display: flex;
+ flex-direction: column;
+}
+
+#date {
+ color: rgb(104, 113, 116);
+ font-size: 100%;
+ font-weight: 500;
+ margin: 24px auto 10px;
+ width: var(--downloads-item-width);
+}
+
+#date:empty {
+ display: none;
+}
+
+#content {
+ background: white;
+ border-radius: 2px;
+ display: flex;
+ flex: none;
+ margin: 6px auto;
+ min-height: 103px;
+ position: relative;
+ width: var(--downloads-item-width);
+}
+
+#content.is-active {
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .05), 0 1px 4px 0 rgba(0, 0, 0, .08),
+ 0 3px 1px -2px rgba(0, 0, 0, .2);
+}
+
+#content:not(.is-active) {
+ opacity: .6;
+}
+
+#details {
+ -webkit-border-start: 1px #d8d8d8 solid;
+ -webkit-padding-end: 16px;
+ -webkit-padding-start: 24px;
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ min-width: 0; /* This allows #url to ellide correctly. */
+ padding-bottom: 12px;
+ padding-top: 16px;
+}
+
+#content:not(.is-active) #details {
+ color: #bababa;
+}
+
+#content:not(.is-active) #name {
+ text-decoration: line-through;
+}
+
+.icon-wrapper {
+ align-self: center;
+ flex: none;
+ justify-content: center;
+ margin: 0 24px;
+}
+
+.icon {
+ height: 32px;
+ width: 32px;
+}
+
+#content:-webkit-any(.show-progress, .dangerous) #file-icon-wrapper {
+ /* TODO(dbeam): animate from top-aligned to centered when items finish? */
+ align-self: flex-start;
+ padding-top: 16px;
+}
+
+#content:not(.is-active) .icon {
+ -webkit-filter: grayscale(100%);
+ opacity: .5;
+}
+
+#danger-icon {
+ height: 32px;
+ width: 32px;
+}
+
+#danger-icon[icon='warning'] {
+ color: rgb(255, 193, 7);
+}
+
+#danger-icon[icon='remove-circle'] {
+ color: rgb(244, 67, 54);
+}
+
+#name,
+#file-link,
+#url {
+ max-width: 100%;
+}
+
+#name,
+#file-link {
+ font-weight: 500;
+ word-break: break-all;
+}
+
+#name {
+ -webkit-margin-end: 12px; /* Only really affects #tag. */
+}
+
+.is-active :-webkit-any(#name, #file-link, #pause, #resume, #show) {
+ color: rgb(51, 103, 214);
+}
+
+#tag {
+ color: #5a5a5a;
+ font-weight: 500;
+}
+
+#url {
+ color: inherit;
+ margin-top: 6px;
+ min-height: 0;
+ overflow: hidden;
+ text-decoration: none;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.is-active #url {
+ color: #969696;
+}
+
+#progress,
+#description:not(:empty),
+.controls {
+ margin-top: 16px;
+}
+
+.is-active #description {
+ color: #616161;
+}
+
+.dangerous #description {
+ color: rgb(239, 108, 0);
+}
+
+#progress {
+ --paper-progress-active-color: rgb(54, 126, 237);
+ --paper-progress-container-color: rgb(223, 222, 223);
+ width: auto;
+}
+
+.controls {
+ -webkit-margin-start: -.57em;
+}
+
+#cancel,
+#retry,
+.keep,
+.discard {
+ color: #5a5a5a;
+}
+
+#show {
+ margin: .7em .57em;
+}
+
+#controlled-by {
+ -webkit-margin-start: 8px;
+}
+
+#controlled-by,
+#controlled-by a {
+ color: #5a5a5a;
+}
+
+.is-active #controlled-by {
+ color: #333;
+}
+
+.is-active #controlled-by a {
+ color: rgb(51, 103, 214);
+}
+
+#remove-wrapper {
+ align-self: flex-start;
+ margin: 0;
+}
+
+#remove {
+ color: #969696;
+ font-size: 16px;
+ height: 16px;
+ line-height: 17px; /* TODO(dbeam): why is this necesssary? */
+ padding: 8px;
+ width: 16px;
+}
+
+#incognito {
+ bottom: 20px;
+ content: -webkit-image-set(
+ url("chrome://downloads/1x/incognito_marker.png") 1x,
+ url("chrome://downloads/2x/incognito_marker.png") 2x);
+ position: absolute;
+ right: 10px;
+}
+
+</style>
+ </dom-module>
+<dom-module id="paper-item-shared-styles" assetpath="chrome://resources/polymer/v1_0/paper-item/">
+ <template>
+ <style>
+ :host {
+ display: block;
+ min-height: var(--paper-item-min-height, 48px);
+ padding: 0px 16px;
+ }
+
+ :host(.iron-selected) {
+ font-weight: var(--paper-item-selected-weight, bold);
+ @apply(--paper-item-selected);
+ }
+
+ :host([disabled]) {
+ color: var(--paper-item-disabled-color, --disabled-text-color);
+ @apply(--paper-item-disabled);
+ }
+
+ :host(:focus) {
+ position: relative;
+ outline: 0;
+ @apply(--paper-item-focused);
+ }
+
+ :host(:focus):before {
+ @apply(--layout-fit);
+ content: '';
+ background: currentColor;
+ opacity: var(--dark-divider-opacity);
+ pointer-events: none;
+
+ @apply(--paper-item-focused-before);
+ }
+ </style>
+ </template>
+</dom-module>
+<dom-module id="paper-item" assetpath="chrome://resources/polymer/v1_0/paper-item/">
+ <template>
+ <style include="paper-item-shared-styles"></style>
+ <style>
+ :host {
+ @apply(--layout-horizontal);
+ @apply(--layout-center);
+ @apply(--paper-font-subhead);
+
+ @apply(--paper-item);
+ }
+ </style>
+
+ <content></content>
+ </template>
+
+ </dom-module>
+<dom-module id="paper-menu-shared-styles" assetpath="chrome://resources/polymer/v1_0/paper-menu/">
+ <template>
+ <style>
+ /* need a wrapper element to make this higher specificity than the :host rule in paper-item */
+ .selectable-content > ::content > .iron-selected {
+ font-weight: bold;
+
+ @apply(--paper-menu-selected-item);
+ }
+
+ .selectable-content > ::content > [disabled] {
+ color: var(--paper-menu-disabled-color, --disabled-text-color);
+ }
+
+ .selectable-content > ::content > *:focus {
+ position: relative;
+ outline: 0;
+
+ @apply(--paper-menu-focused-item);
+ }
+
+ .selectable-content > ::content > *:focus:after {
+ @apply(--layout-fit);
+ background: currentColor;
+ opacity: var(--dark-divider-opacity);
+ content: '';
+
+ @apply(--paper-menu-focused-item-after);
+ }
+
+ .selectable-content > ::content > *[colored]:focus:after {
+ opacity: 0.26;
+ }
+ </style>
+ </template>
+</dom-module>
+<dom-module id="paper-menu" assetpath="chrome://resources/polymer/v1_0/paper-menu/">
+ <template>
+ <style include="paper-menu-shared-styles"></style>
+ <style>
+ :host {
+ display: block;
+ padding: 8px 0;
+
+ background: var(--paper-menu-background-color, --primary-background-color);
+ color: var(--paper-menu-color, --primary-text-color);
+
+ @apply(--paper-menu);
+ }
+ </style>
+
+ <div class="selectable-content">
+ <content></content>
+ </div>
+ </template>
+
+ </dom-module>
+<dom-module id="iron-overlay-backdrop" assetpath="chrome://resources/polymer/v1_0/iron-overlay-behavior/">
+
+ <style>
+
+ :host {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background-color: var(--iron-overlay-backdrop-background-color, #000);
+ opacity: 0;
+ transition: opacity 0.2s;
+
+ @apply(--iron-overlay-backdrop);
+ }
+
+ :host([opened]) {
+ opacity: var(--iron-overlay-backdrop-opacity, 0.6);
+
+ @apply(--iron-overlay-backdrop-opened);
+ }
+
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<dom-module id="iron-dropdown" assetpath="chrome://resources/polymer/v1_0/iron-dropdown/">
+ <style>
+ :host {
+ position: fixed;
+ }
+
+ #contentWrapper ::content > * {
+ overflow: auto;
+ }
+
+ #contentWrapper.animating ::content > * {
+ overflow: hidden;
+ }
+ </style>
+ <template>
+ <div id="contentWrapper">
+ <content id="content" select=".dropdown-content"></content>
+ </div>
+ </template>
+
+ </dom-module>
+
+<dom-module id="paper-menu-button" assetpath="chrome://resources/polymer/v1_0/paper-menu-button/">
+ <style>
+ :host {
+ display: inline-block;
+ position: relative;
+ padding: 8px;
+ outline: none;
+
+ @apply(--paper-menu-button);
+ }
+
+ :host([disabled]) {
+ cursor: auto;
+ color: var(--disabled-text-color);
+
+ @apply(--paper-menu-button-disabled);
+ }
+
+ :host([vertical-align="top"]) paper-material {
+ margin-bottom: 20px;
+ margin-top: -10px;
+ top: 10px;
+ }
+
+ :host([vertical-align="bottom"]) paper-material {
+ bottom: 10px;
+ margin-bottom: -10px;
+ margin-top: 20px;
+ }
+
+ paper-material {
+ border-radius: 2px;
+ background-color: var(--paper-menu-button-dropdown-background, --primary-background-color);
+
+ @apply(--paper-menu-button-dropdown);
+ }
+ </style>
+ <template>
+ <div id="trigger" on-tap="open">
+ <content select=".dropdown-trigger"></content>
+ </div>
+ <iron-dropdown id="dropdown" opened="{{opened}}" horizontal-align="[[horizontalAlign]]" vertical-align="[[verticalAlign]]" horizontal-offset="[[horizontalOffset]]" vertical-offset="[[verticalOffset]]" open-animation-config="[[openAnimationConfig]]" close-animation-config="[[closeAnimationConfig]]" no-animations="[[noAnimations]]" focus-target="[[_dropdownContent]]">
+ <paper-material class="dropdown-content">
+ <content id="content" select=".dropdown-content"></content>
+ </paper-material>
+ </iron-dropdown>
+ </template>
+</dom-module>
+<dom-module id="paper-icon-button" assetpath="chrome://resources/polymer/v1_0/paper-icon-button/">
+ <template strip-whitespace="">
+ <style>
+ :host {
+ display: inline-block;
+ position: relative;
+ padding: 8px;
+ outline: none;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ z-index: 0;
+ line-height: 1;
+
+ width: 40px;
+ height: 40px;
+
+ /* Because of polymer/2558, this style has lower specificity than * */
+ box-sizing: border-box !important;
+ @apply(--paper-icon-button);
+ }
+
+ :host #ink {
+ color: var(--paper-icon-button-ink-color, --primary-text-color);
+ opacity: 0.6;
+ }
+
+ :host([disabled]) {
+ color: var(--paper-icon-button-disabled-text, --disabled-text-color);
+ pointer-events: none;
+ cursor: auto;
+ @apply(--paper-icon-button-disabled);
+ }
+
+ iron-icon {
+ --iron-icon-width: 100%;
+ --iron-icon-height: 100%;
+ }
+ </style>
+ <iron-icon id="icon" src="[[src]]" icon="[[icon]]" alt$="[[alt]]"></iron-icon>
+ </template>
+
+ </dom-module>
+<dom-module id="paper-input-container" assetpath="chrome://resources/polymer/v1_0/paper-input/">
+ <template>
+
+ <style>
+ :host {
+ display: block;
+ padding: 8px 0;
+
+ @apply(--paper-input-container);
+ }
+
+ :host[inline] {
+ display: inline-block;
+ }
+
+ :host([disabled]) {
+ pointer-events: none;
+ opacity: 0.33;
+
+ @apply(--paper-input-container-disabled);
+ }
+
+ .floated-label-placeholder {
+ @apply(--paper-font-caption);
+ }
+
+ .underline {
+ position: relative;
+ }
+
+ .focused-line {
+ height: 2px;
+ @apply(--layout-fit);
+
+ -webkit-transform-origin: center center;
+ transform-origin: center center;
+ -webkit-transform: scale3d(0,1,1);
+ transform: scale3d(0,1,1);
+
+ background: var(--paper-input-container-focus-color, --default-primary-color);
+
+ @apply(--paper-input-container-underline-focus);
+ }
+
+ .underline.is-highlighted .focused-line {
+ -webkit-transform: none;
+ transform: none;
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+
+ @apply(--paper-transition-easing);
+ }
+
+ .underline.is-invalid .focused-line {
+ background: var(--paper-input-container-invalid-color, --google-red-500);
+
+ -webkit-transform: none;
+ transform: none;
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+
+ @apply(--paper-transition-easing);
+ }
+
+ .unfocused-line {
+ height: 1px;
+ @apply(--layout-fit);
+ background: var(--paper-input-container-color, --secondary-text-color);
+
+ @apply(--paper-input-container-underline);
+ }
+
+ :host([disabled]) .unfocused-line {
+ border-bottom: 1px dashed;
+ border-color: var(--paper-input-container-color, --secondary-text-color);
+ background: transparent;
+
+ @apply(--paper-input-container-underline-disabled);
+ }
+
+ .label-and-input-container {
+ @apply(--layout-flex);
+ @apply(--layout-relative);
+ }
+
+ .input-content {
+ position: relative;
+ @apply(--layout-horizontal);
+ @apply(--layout-center);
+ }
+
+ .input-content ::content label,
+ .input-content ::content .paper-input-label {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ font: inherit;
+ color: var(--paper-input-container-color, --secondary-text-color);
+
+ @apply(--paper-font-common-nowrap);
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-container-label);
+ }
+
+ .input-content.label-is-floating ::content label,
+ .input-content.label-is-floating ::content .paper-input-label {
+ -webkit-transform: translateY(-75%) scale(0.75);
+ transform: translateY(-75%) scale(0.75);
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+
+ -webkit-transform-origin: left top;
+ transform-origin: left top;
+
+ /* Since we scale to 75/100 of the size, we actually have 100/75 of the
+ original space now available */
+ width: 133%;
+
+ @apply(--paper-transition-easing);
+ }
+
+ :host-context([dir="rtl"]) .input-content.label-is-floating ::content label,
+ :host-context([dir="rtl"]) .input-content.label-is-floating ::content .paper-input-label {
+ /* TODO(noms): Figure out why leaving the width at 133% before the animation
+ * actually makes
+ * it wider on the right side, not left side, as you would expect in RTL */
+ width: 100%;
+ -webkit-transform-origin: right top;
+ transform-origin: right top;
+ }
+
+ .input-content.label-is-highlighted ::content label,
+ .input-content.label-is-highlighted ::content .paper-input-label {
+ color: var(--paper-input-container-focus-color, --default-primary-color);
+
+ @apply(--paper-input-container-label-focus);
+ }
+
+ .input-content.is-invalid ::content label,
+ .input-content.is-invalid ::content .paper-input-label {
+ color: var(--paper-input-container-invalid-color, --google-red-500);
+ }
+
+ .input-content.label-is-hidden ::content label,
+ .input-content.label-is-hidden ::content .paper-input-label {
+ visibility: hidden;
+ }
+
+ .input-content ::content input,
+ .input-content ::content textarea,
+ .input-content ::content iron-autogrow-textarea,
+ .input-content ::content .paper-input-input {
+ position: relative; /* to make a stacking context */
+ outline: none;
+ box-shadow: none;
+ padding: 0;
+ width: 100%;
+ background: transparent;
+ border: none;
+ color: var(--paper-input-container-input-color, --primary-text-color);
+ -webkit-appearance: none;
+ text-align: inherit;
+
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-container-input);
+ }
+
+ ::content [prefix] {
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-prefix);
+ }
+
+ ::content [suffix] {
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-suffix);
+ }
+
+ /* Firefox sets a min-width on the input, which can cause layout issues */
+ .input-content ::content input {
+ min-width: 0;
+ }
+
+ .input-content ::content textarea {
+ resize: none;
+ }
+
+ .add-on-content {
+ position: relative;
+ }
+
+ .add-on-content.is-invalid ::content * {
+ color: var(--paper-input-container-invalid-color, --google-red-500);
+ }
+
+ .add-on-content.is-highlighted ::content * {
+ color: var(--paper-input-container-focus-color, --default-primary-color);
+ }
+ </style>
+
+ <template is="dom-if" if="[[!noLabelFloat]]">
+ <div class="floated-label-placeholder">&nbsp;</div>
+ </template>
+
+ <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]">
+ <content select="[prefix]" id="prefix"></content>
+
+ <div class="label-and-input-container" id="labelAndInputContainer">
+ <content select=":not([add-on]):not([prefix]):not([suffix])"></content>
+ </div>
+ <content select="[suffix]"></content>
+ </div>
+
+ <div class$="[[_computeUnderlineClass(focused,invalid)]]">
+ <div class="unfocused-line"></div>
+ <div class="focused-line"></div>
+ </div>
+
+ <div class$="[[_computeAddOnContentClass(focused,invalid)]]">
+ <content id="addOnContent" select="[add-on]"></content>
+ </div>
+
+ </template>
+</dom-module>
+
+<dom-module id="cr-search-field" assetpath="chrome://resources/cr_elements/cr_search_field/">
+ <template>
+ <paper-icon-button icon="search" id="search-button" disabled$="[[showingSearch_]]" title="[[label]]" on-click="toggleShowingSearch_"></paper-icon-button>
+ <template is="dom-if" if="[[showingSearch_]]" id="search-container">
+ <paper-input-container id="search-term" on-search="onSearchTermSearch_" on-keydown="onSearchTermKeydown_" hidden$="[[!showingSearch_]]" no-label-float="">
+ <input is="iron-input" id="search-input" type="search" placeholder="[[label]]" incremental="">
+ <paper-icon-button icon="cancel" id="clear-search" on-click="toggleShowingSearch_" title="[[clearLabel]]" hidden$="[[!showingSearch_]]"></paper-icon-button>
+ </paper-input-container>
+ </template>
+ </template>
+ <style>
+/* 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. */
+
+:host {
+ -webkit-padding-end: 10px;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: flex-end;
+}
+
+:host paper-input-container {
+ margin-top: 2px;
+ max-width: 200px;
+ padding: 2px 0;
+ width: 100%;
+}
+
+#search-term {
+ --paper-input-container-color: rgb(192, 199, 205);
+ --paper-input-container-focus-color: rgb(192, 199, 205);
+ --paper-input-container-input: {
+ color: inherit;
+ font-family: inherit;
+ font-size: inherit;
+ };
+ --paper-input-container-input-color: rgb(192, 199, 205);
+ color: rgb(192, 199, 205);
+ z-index: 0;
+}
+
+#search-term input[type='search']::-webkit-search-decoration,
+#search-term input[type='search']::-webkit-search-cancel-button,
+#search-term input[type='search']::-webkit-search-results-button {
+ -webkit-appearance: none;
+}
+
+#search-term input[type='search']::-webkit-search-cancel-button {
+ display: block;
+ width: 20px;
+}
+
+paper-icon-button {
+ --iron-icon-height: 20px;
+ --iron-icon-width: 20px;
+ --paper-icon-button: {
+ height: 32px;
+ padding: 6px;
+ width: 32px;
+ };
+}
+
+#search-term paper-icon-button {
+ --iron-icon-height: 16px;
+ --iron-icon-width: 16px;
+ --paper-icon-button: {
+ -webkit-margin-end: -8px;
+ height: 32px;
+ padding: 8px;
+ width: 32px;
+ };
+ position: absolute;
+ right: 0;
+ top: -4px;
+ z-index: 1;
+}
+
+:host-context([dir='rtl']) #search-term paper-icon-button {
+ left: 0;
+ right: auto;
+}
+
+</style>
+ </dom-module>
+<dom-module id="downloads-toolbar" assetpath="chrome://downloads/">
+ <template>
+ <div id="title">
+ <h1 i18n-content="title"></h1>
+ </div>
+ <div id="actions">
+ <paper-button class="clear-all" i18n-content="clearAll" on-tap="onClearAllTap_"></paper-button>
+ <paper-button i18n-content="openDownloadsFolder" on-tap="onOpenDownloadsFolderTap_"></paper-button>
+ </div>
+ <div id="search">
+ <cr-search-field id="search-input" i18n-values="label:search;clear-label:clearSearch"></cr-search-field>
+ <paper-menu-button id="more" horizontal-align="[[overflowAlign_]]">
+ <paper-icon-button icon="more-vert" i18n-values="title:moreActions" class="dropdown-trigger"></paper-icon-button>
+ <paper-menu class="dropdown-content">
+ <paper-item class="clear-all" i18n-content="clearAll" on-tap="onClearAllTap_"></paper-item>
+ <paper-item i18n-content="openDownloadsFolder" on-tap="onOpenDownloadsFolderTap_"></paper-item>
+ </paper-menu>
+ </paper-menu-button>
+ </div>
+ </template>
+ <style>
+/* 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. */
+
+* {
+ --downloads-item-width: 622px;
+}
+
+[hidden] {
+ display: none !important;
+}
+
+paper-button {
+ font-weight: 500;
+ margin: 0;
+ min-width: auto;
+}
+
+</style>
+ <style>
+/* 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. */
+
+:host {
+ align-items: center;
+ background: rgb(52, 73, 94);
+ color: white;
+ content-sizing: padding-box;
+ display: flex;
+ min-height: 56px;
+}
+
+#title h1 {
+ -webkit-margin-end: 0;
+ -webkit-margin-start: 24px;
+ font-size: 123.1%;
+ font-weight: normal;
+ margin-bottom: 0;
+ margin-top: 0;
+}
+
+#actions {
+ color: rgb(176, 190, 197);
+ display: flex;
+ flex: none;
+ width: var(--downloads-item-width);
+}
+
+:host-context([loading]) #actions {
+ visibility: hidden;
+}
+
+:host(:not([downloads-showing])) #actions {
+ justify-content: center;
+}
+
+#actions paper-button {
+ --paper-button-flat-keyboard-focus: {
+ color: white;
+ };
+}
+
+#actions paper-button:first-of-type {
+ -webkit-margin-start: -0.57em; /* Matches paper-button padding. */
+}
+
+#actions paper-button:not(:last-of-type) {
+ -webkit-margin-end: 8px; /* Margin between items. */
+}
+
+#actions paper-button:last-of-type {
+ -webkit-margin-end: -0.57em; /* Matches paper-button padding. */
+}
+
+#search {
+ -webkit-padding-end: 10px;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: flex-end;
+}
+
+#title,
+#search {
+ /* (1024 total width - 622 item width) / 2 = 201 room to play. */
+ flex: 1 0 201px;
+}
+
+paper-icon-button {
+ --iron-icon-height: 20px;
+ --iron-icon-width: 20px;
+ --paper-icon-button: {
+ height: 32px;
+ padding: 6px;
+ width: 32px;
+ };
+}
+
+#more {
+ --paper-menu-button: {
+ padding: 0;
+ };
+ -webkit-margin-start: 16px;
+}
+
+paper-item {
+ -webkit-user-select: none;
+ cursor: pointer;
+ font: inherit;
+ min-height: 40px;
+}
+
+paper-item:hover {
+ background: #eaeaea; /* TODO(dbeam): real color? */
+}
+
+@media not all and (max-width: 1024px) {
+ /* Hide vertical dot menu when there's enough room for #actions. */
+ paper-menu-button {
+ display: none;
+ }
+}
+
+@media all and (max-width: 1024px) {
+ /* Hide #actions for narrow windows; they're shown in a vertical dot menu. */
+ #actions {
+ display: none;
+ }
+}
+
+</style>
+ </dom-module>
+<dom-module id="downloads-manager" assetpath="chrome://downloads/">
+ <template>
+ <downloads-toolbar id="toolbar"></downloads-toolbar>
+ <iron-list id="downloads-list" items="{{items_}}" hidden="[[!hasDownloads_]]">
+ <template>
+ <downloads-item data="[[item]]" hide-date="[[item.hideDate]]">
+ </downloads-item>
+ </template>
+ </iron-list>
+ <div id="no-downloads" hidden="[[hasDownloads_]]">
+ <div>
+ <div class="illustration"></div>
+ <span></span>
+ </div>
+ </div>
+ </template>
+ <style>
+/* 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. */
+
+* {
+ --downloads-item-width: 622px;
+}
+
+[hidden] {
+ display: none !important;
+}
+
+paper-button {
+ font-weight: 500;
+ margin: 0;
+ min-width: auto;
+}
+
+</style>
+ <style>
+/* 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. */
+
+:host {
+ display: flex;
+ flex: 1 0;
+ flex-direction: column;
+ height: 100%;
+ overflow-y: overlay;
+}
+
+@media screen and (max-width: 1024px) {
+ :host {
+ flex-basis: 670px; /* 622 card width + 24 left margin + 24 right margin. */
+ }
+}
+
+#no-downloads,
+#downloads-list {
+ flex: 1;
+}
+
+:host([loading]) #no-downloads,
+:host([loading]) #downloads-list {
+ display: none;
+}
+
+#no-downloads {
+ align-items: center;
+ color: #b4b4b4;
+ display: flex;
+ font-size: 123.1%;
+ font-weight: 500;
+ justify-content: center;
+}
+
+#no-downloads .illustration {
+ background: -webkit-image-set(
+ url("chrome://downloads/1x/no_downloads.png") 1x,
+ url("chrome://downloads/2x/no_downloads.png") 2x) no-repeat center center;
+ height: 144px; /* Matches natural image height. */
+ margin-bottom: 32px;
+}
+
+</style>
+ </dom-module>
+</div>
+ <downloads-manager></downloads-manager>
+ <command id="clear-all-command" shortcut="Alt-U+0043"></command>
+<if expr="is_macosx">
+ <command id="undo-command" shortcut="Meta-U+005A"></command>
+</if>
+<if expr="not is_macosx">
+ <command id="undo-command" shortcut="Ctrl-U+005A"></command>
+</if>
+
+ <script src="crisper.js"></script></body></html> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/md_extensions/compiled_resources.gyp b/chromium/chrome/browser/resources/md_extensions/compiled_resources.gyp
index 2b001ed20fb..868cae39a5e 100644
--- a/chromium/chrome/browser/resources/md_extensions/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/md_extensions/compiled_resources.gyp
@@ -7,12 +7,22 @@
'target_name': 'manager',
'variables': {
'depends': [
- '../../../../ui/webui/resources/cr_elements/v1_0/cr_search_field/cr_search_field.js',
+ '../../../../ui/webui/resources/cr_elements/cr_search_field/cr_search_field.js',
'../../../../ui/webui/resources/js/assert.js',
+ '../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
'../../../../ui/webui/resources/js/cr.js',
+ '../../../../ui/webui/resources/js/i18n_behavior.js',
+ 'item.js',
+ 'item_list.js',
+ 'manager.js',
+ 'service.js',
+ 'sidebar.js',
+ 'toolbar.js',
],
'externs': [
'<(EXTERNS_DIR)/chrome_send.js',
+ '<(EXTERNS_DIR)/developer_private.js',
+ '<(EXTERNS_DIR)/management.js',
],
},
'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chromium/chrome/browser/resources/md_extensions/icons.html b/chromium/chrome/browser/resources/md_extensions/icons.html
new file mode 100644
index 00000000000..72b51e217d4
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/icons.html
@@ -0,0 +1,21 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
+
+<iron-iconset-svg name="extensions-icons" size="24">
+ <svg>
+ <defs>
+ <g id="pack">
+ <path d="M0 0h24v24H0z" fill="none"></path>
+ <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 6h-2v2h2v2h-2v-2h-2V9h2V7h-2V5h2v2h2v2zm0 8h-2v-2h-2v-2h2v2h2v2z"></path>
+ </g>
+ <g id="update">
+ <defs>
+ <path id="a" d="M0 0h24v24H0V0z"></path>
+ </defs>
+ <clipPath id="b">
+ <use xlink:href="#a" overflow="visible"></use>
+ </clipPath>
+ <path d="M7.3 5.3c-1.3 1.3-2 3-2 4.7 0 1.7.7 3.4 2 4.7l1.2-1.2c-1-1-1.5-2.3-1.5-3.5 0-1.3.5-2.6 1.5-3.5L7.3 5.3zm11.8-2.4l-1.2 1.2c1.6 1.6 2.4 3.8 2.4 5.9s-.8 4.3-2.4 5.9l1.2 1.2c2-2 2.9-4.5 2.9-7.1s-1-5.1-2.9-7.1zm-13 1.2L4.9 2.9C3 4.9 2 7.4 2 10s1 5.1 2.9 7.1l1.2-1.2c-1.6-1.6-2.4-3.8-2.4-5.9s.8-4.3 2.4-5.9zm10.6 1.2l-1.2 1.2c1 1 1.5 2.3 1.5 3.5 0 1.3-.5 2.6-1.5 3.5l1.2 1.2c1.3-1.3 2-3 2-4.7-.1-1.7-.7-3.4-2-4.7zM12 7.5c-1.4 0-2.5 1.1-2.5 2.5 0 1 .6 1.9 1.5 2.3V21h2v-8.7c.9-.4 1.5-1.3 1.5-2.3 0-1.4-1.1-2.5-2.5-2.5z" clip-path="url(#b)"></path>
+ </g>
+ </svg>
+</iron-icon-set>
diff --git a/chromium/chrome/browser/resources/md_extensions/item.css b/chromium/chrome/browser/resources/md_extensions/item.css
new file mode 100644
index 00000000000..447cd33833b
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/item.css
@@ -0,0 +1,113 @@
+/* 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. */
+
+.content-section {
+ padding: 20px;
+}
+
+#icon-wrapper {
+ align-self: center;
+ display: flex;
+ justify-content: center;
+ margin: 0 24px;
+}
+
+#icon {
+ height: 32px;
+ width: 32px;
+}
+
+/* TODO(devlin): Combine this with downloads style. */
+#card-wrapper {
+ background: white;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .05), 0 1px 4px 0 rgba(0, 0, 0, .08),
+ 0 3px 1px -2px rgba(0, 0, 0, .2);
+ color: #5A5A5A;
+ min-height: 103px;
+ width: 622px;
+}
+
+#card {
+ display: flex;
+}
+
+#card.disabled {
+ opacity: 0.6;
+}
+
+#content {
+ -webkit-border-start: 1px solid #C5C5C5;
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+}
+
+#name {
+ color: #222;
+ font-weight: 500;
+ margin-bottom: 8px;
+}
+
+#controls {
+ padding-top: 20px;
+}
+
+#version {
+ -webkit-margin-start: 50px;
+ flex: 1;
+}
+
+.checkbox {
+ --paper-checkbox-checked-color: rgb(66, 133, 244);
+ --primary-text-color: #5A5A5A;
+}
+
+#details-container {
+ border-top: 1px solid #C5C5C5;
+ color: #5A5A5A;
+}
+
+#extension-id {
+ padding-bottom: 10px;
+}
+
+#inspect-views {
+ padding-bottom: 20px;
+}
+
+#inspect-views paper-button {
+ color: rgb(51, 103, 214);
+}
+
+paper-button {
+ /* TODO(devlin): Decide whether all webui should do this. */
+ cursor: pointer;
+}
+
+#warnings-container {
+ border-top: 1px solid #C5C5C5;
+ display: flex;
+ padding: 10px;
+}
+
+#warnings-container div {
+ color: #333;
+}
+
+#warnings-container iron-icon {
+ -webkit-margin-end: 10px;
+ flex-shrink: 0;
+}
+
+#warnings-container.severe iron-icon {
+ color: rgb(219, 68, 55);
+}
+
+#warnings-container.mild iron-icon {
+ color: rgb(240, 147, 0);
+}
+
+#blacklisted-warning:empty {
+ display: none;
+}
diff --git a/chromium/chrome/browser/resources/md_extensions/item.html b/chromium/chrome/browser/resources/md_extensions/item.html
new file mode 100644
index 00000000000..69d8cbcf173
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/item.html
@@ -0,0 +1,86 @@
+<link rel="import" href="chrome://resources/html/assert.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/load_time_data.html">
+<link rel="import" href="chrome://extensions/strings.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+
+<dom-module id="extensions-item">
+ <template>
+ <div id="card-wrapper" class$="[[computeClasses_(data.state)]]">
+ <div id="card">
+ <div id="icon-wrapper">
+ <img alt="" id="icon" src="[[data.iconUrl]]">
+ </div>
+ <div id="content">
+ <div class="content-section">
+ <div class="layout horizontal justified center">
+ <div id="name">[[data.name]]</div>
+ <paper-icon-button icon="[[computeExpandIcon_(showingDetails_)]]"
+ id="show-details" on-tap="onShowDetailsTap_">
+ </paper-icon-button>
+ </div>
+ <div id="description">[[data.description]]</div>
+ <div id="controls" class="layout horizontal center">
+ <paper-checkbox id="enabled" class="checkbox"
+ checked="[[isEnabled_(data.state)]]"
+ on-change="onEnableChange_">
+ [[computeEnableCheckboxLabel_(data.state)]]
+ </paper-checkbox>
+ <span id="version">[[data.version]]</span>
+ <paper-icon-button icon="delete" id="delete-button"
+ on-tap="onDeleteTap_"></paper-icon-button>
+ </div>
+ </div>
+ <template is="dom-if" if="[[showingDetails_]]">
+ <div id="details-container" class="content-section">
+ <template is="dom-if" if="[[inDevMode]]">
+ <div id="extension-id"></div>
+ <div id="inspect-views">
+ <span>[[i18n('itemInspectViews')]]</span>
+ <template is="dom-repeat" items="[[data.views]]">
+ <paper-button on-tap="onInspectTap_">
+ [[computeInspectLabel_(item)]]
+ </paper-button>
+ </template>
+ </div>
+ </template>
+ <div class="layout horizontal justified center">
+ <paper-checkbox id="allow-incognito" class="checkbox"
+ checked="[[data.incognitoAccess.isActive]]"
+ on-change="onAllowIncognitoChange_">
+ [[i18n('itemAllowIncognito')]]
+ </paper-checkbox>
+ <paper-button id="details-button" on-tap="onDetailsTap_">
+ [[i18n('itemDetails')]]
+ </paper-button>
+ </div>
+ </div>
+ </template>
+ </div>
+ </div>
+ <template is="dom-if" if="[[hasWarnings_(data.*)]]">
+ <div id="warnings-container"
+ class$="[[computeWarningsClasses_(data.blacklistText)]]">
+ <iron-icon icon="warning"></iron-icon>
+ <div>
+ <div id="corrupted-warning"
+ hidden="[[!data.disableReasons.corruptInstall]]">
+ [[i18n('itemCorruptInstall')]]
+ </div>
+ <div id="suspicious-warning"
+ hidden="[[!data.disableReasons.suspiciousInstall]]">
+ [[i18n('itemSuspiciousInstall')]]
+ </div>
+ <div id="blacklisted-warning">[[data.blacklistText]]</div>
+ </div>
+ </div>
+ </template>
+ </div>
+ </template>
+ <link rel="import" type="css" href="chrome://extensions/item.css">
+ <script src="chrome://extensions/item.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/md_extensions/item.js b/chromium/chrome/browser/resources/md_extensions/item.js
new file mode 100644
index 00000000000..9c0ead59b2e
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/item.js
@@ -0,0 +1,194 @@
+// 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.
+
+cr.define('extensions', function() {
+ /** @interface */
+ var ItemDelegate = function() {};
+
+ ItemDelegate.prototype = {
+ /** @param {string} id */
+ deleteItem: assertNotReached,
+
+ /**
+ * @param {string} id
+ * @param {boolean} isEnabled
+ */
+ setItemEnabled: assertNotReached,
+
+ /** @param {string} id */
+ showItemDetails: assertNotReached,
+
+ /**
+ * @param {string} id
+ * @param {boolean} isAllowedIncognito
+ */
+ setItemAllowedIncognito: assertNotReached,
+
+ /**
+ * @param {string} id,
+ * @param {chrome.developerPrivate.ExtensionView} view
+ */
+ inspectItemView: assertNotReached,
+ };
+
+ var Item = Polymer({
+ is: 'extensions-item',
+
+ properties: {
+ // The item's delegate, or null.
+ delegate: {
+ type: Object,
+ },
+
+ // Whether or not dev mode is enabled.
+ inDevMode: {
+ type: Boolean,
+ value: false,
+ },
+
+ // Whether or not the expanded view of the item is shown.
+ showingDetails_: {
+ type: Boolean,
+ value: false,
+ },
+
+ // The underlying ExtensionInfo itself. Public for use in declarative
+ // bindings.
+ /** @type {chrome.developerPrivate.ExtensionInfo} */
+ data: {
+ type: Object,
+ },
+ },
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ observers: [
+ 'observeIdVisibility_(inDevMode, showingDetails_, data.id)',
+ ],
+
+ /** @private */
+ observeIdVisibility_: function(inDevMode, showingDetails, id) {
+ Polymer.dom.flush();
+ var idElement = this.$$('#extension-id');
+ if (idElement) {
+ assert(this.data);
+ idElement.innerHTML = this.i18n('itemId', this.data.id);
+ }
+ this.fire('extension-item-size-changed', {item: this.data});
+ },
+
+ /** @private */
+ onShowDetailsTap_: function() {
+ this.showingDetails_ = !this.showingDetails_;
+ },
+
+ /** @private */
+ onDeleteTap_: function() {
+ this.delegate.deleteItem(this.data.id);
+ },
+
+ /** @private */
+ onEnableChange_: function() {
+ this.delegate.setItemEnabled(this.data.id, this.$.enabled.checked);
+ },
+
+ /** @private */
+ onDetailsTap_: function() {
+ this.delegate.showItemDetails(this.data.id);
+ },
+
+ /** @private */
+ onAllowIncognitoChange_: function() {
+ this.delegate.setItemAllowedIncognito(
+ this.data.id, this.$$('#allow-incognito').checked);
+ },
+
+ /**
+ * @param {!{model: !{item: !chrome.developerPrivate.ExtensionView}}} e
+ * @private
+ */
+ onInspectTap_: function(e) {
+ this.delegate.inspectItemView(this.data.id, e.model.item);
+ },
+
+ /**
+ * Returns true if the extension is enabled, including terminated
+ * extensions.
+ * @return {boolean}
+ * @private
+ */
+ isEnabled_: function() {
+ switch (this.data.state) {
+ case chrome.developerPrivate.ExtensionState.ENABLED:
+ case chrome.developerPrivate.ExtensionState.TERMINATED:
+ return true;
+ case chrome.developerPrivate.ExtensionState.DISABLED:
+ return false;
+ }
+ assertNotReached(); // FileNotFound.
+ },
+
+ /** @private */
+ computeClasses_: function() {
+ return this.isEnabled_() ? 'enabled' : 'disabled';
+ },
+
+ /** @private */
+ computeExpandIcon_: function() {
+ return this.showingDetails_ ? 'expand-less' : 'expand-more';
+ },
+
+ /** @private */
+ computeEnableCheckboxLabel_: function() {
+ return this.i18n(this.isEnabled_() ? 'itemEnabled' : 'itemDisabled');
+ },
+
+ /**
+ * @param {chrome.developerPrivate.ExtensionView} view
+ * @suppress {checkTypes} Needed for URL externs. :(
+ * @private
+ */
+ computeInspectLabel_: function(view) {
+ // Trim the "chrome-extension://<id>/".
+ var url = new URL(view.url);
+ var label = view.url;
+ if (url.protocol == 'chrome-extension:')
+ label = url.pathname.substring(1);
+ if (label == '_generated_background_page.html')
+ label = this.i18n('viewBackgroundPage');
+ // Add any qualifiers.
+ label += (view.incognito ? ' ' + this.i18n('viewIncognito') : '') +
+ (view.renderProcessId == -1 ?
+ ' ' + this.i18n('viewInactive') : '') +
+ (view.isIframe ? ' ' + this.i18n('viewIframe') : '');
+ return label;
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ hasWarnings_: function() {
+ return this.data.disableReasons.corruptInstall ||
+ this.data.disableReasons.suspiciousInstall ||
+ !!this.data.blacklistText;
+ },
+
+ /**
+ * @return {string}
+ * @private
+ */
+ computeWarningsClasses_: function() {
+ return this.data.blacklistText ? 'severe' : 'mild';
+ },
+ });
+
+ return {
+ Item: Item,
+ ItemDelegate: ItemDelegate,
+ };
+});
+
diff --git a/chromium/chrome/browser/resources/md_extensions/item_list.css b/chromium/chrome/browser/resources/md_extensions/item_list.css
new file mode 100644
index 00000000000..9163291f92b
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/item_list.css
@@ -0,0 +1,15 @@
+/* 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. */
+
+h2 {
+ color: #5a5a5a;
+ font-size: 1.1em;
+ font-weight: normal;
+ margin-bottom: 0;
+ margin-top: 30px;
+}
+
+.wrapper {
+ padding: 10px 0;
+}
diff --git a/chromium/chrome/browser/resources/md_extensions/item_list.html b/chromium/chrome/browser/resources/md_extensions/item_list.html
new file mode 100644
index 00000000000..18a2b35efcc
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/item_list.html
@@ -0,0 +1,22 @@
+<link rel="import" href="chrome://resources/html/cr.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
+<link rel="import" href="chrome://extensions/item.html">
+
+<dom-module id="extensions-item-list">
+ <template>
+ <h2>[[header]]</h2>
+ <iron-list id="list" items="[[computeShownItems_(items.*, filter)]]"
+ as="item">
+ <template>
+ <div class="wrapper">
+ <extensions-item data="[[item]]" delegate="[[delegate]]"
+ id="[[item.id]]" in-dev-mode="[[inDevMode]]">
+ </extensions-item>
+ </div>
+ </template>
+ </iron-list>
+ </template>
+ <link rel="import" type="css" href="chrome://extensions/item_list.css">
+ <script src="chrome://extensions/item_list.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/md_extensions/item_list.js b/chromium/chrome/browser/resources/md_extensions/item_list.js
new file mode 100644
index 00000000000..2e6d9c3257d
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/item_list.js
@@ -0,0 +1,57 @@
+// 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.
+
+cr.define('extensions', function() {
+ var ItemList = Polymer({
+ is: 'extensions-item-list',
+
+ properties: {
+ /** @type {Array<!chrome.developerPrivate.ExtensionInfo>} */
+ items: Array,
+
+ /** @type {extensions.ItemDelegate} */
+ delegate: Object,
+
+ header: String,
+
+ inDevMode: {
+ type: Boolean,
+ value: false,
+ },
+
+ filter: String,
+ },
+
+ listeners: {
+ 'list.extension-item-size-changed': 'itemSizeChanged_',
+ },
+
+ /**
+ * Updates the size for a given item.
+ * @param {CustomEvent} e
+ * @private
+ * @suppress {checkTypes} Closure doesn't know $.list is an IronList.
+ */
+ itemSizeChanged_: function(e) {
+ this.$.list.updateSizeForItem(e.detail.item);
+ },
+
+ /**
+ * Computes the list of items to be shown.
+ * @param {Object} changeRecord The changeRecord for |items|.
+ * @param {string} filter The updated filter string.
+ * @return {Array<!chrome.developerPrivate.ExtensionInfo>}
+ * @private
+ */
+ computeShownItems_: function(changeRecord, filter) {
+ return this.items.filter(function(item) {
+ return item.name.toLowerCase().includes(this.filter.toLowerCase());
+ }, this);
+ },
+ });
+
+ return {
+ ItemList: ItemList,
+ };
+});
diff --git a/chromium/chrome/browser/resources/md_extensions/manager.css b/chromium/chrome/browser/resources/md_extensions/manager.css
index 999634de029..cef4d23721d 100644
--- a/chromium/chrome/browser/resources/md_extensions/manager.css
+++ b/chromium/chrome/browser/resources/md_extensions/manager.css
@@ -11,3 +11,14 @@
display: flex;
};
}
+
+#items {
+ -webkit-margin-start: 30px;
+ overflow-y: auto;
+ padding-bottom: 30px;
+ width: 100%;
+}
+
+extensions-item {
+ display: inline-block;
+}
diff --git a/chromium/chrome/browser/resources/md_extensions/manager.html b/chromium/chrome/browser/resources/md_extensions/manager.html
index 504de93f902..e5d30a16f98 100644
--- a/chromium/chrome/browser/resources/md_extensions/manager.html
+++ b/chromium/chrome/browser/resources/md_extensions/manager.html
@@ -1,6 +1,9 @@
<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/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-header-panel/paper-header-panel.html">
+<link rel="import" href="chrome://extensions/item_list.html">
+<link rel="import" href="chrome://extensions/service.html">
<link rel="import" href="chrome://extensions/sidebar.html">
<link rel="import" href="chrome://extensions/toolbar.html">
@@ -9,7 +12,28 @@
<paper-header-panel id="panel">
<extensions-toolbar class="paper-header" id="toolbar">
</extensions-toolbar>
- <extensions-sidebar></extensions-sidebar>
+ <extensions-sidebar in-dev-mode="[[inDevMode]]"
+ hide-extensions-button="[[computeListHidden_(extensions, extensions.splices)]]"
+ hide-apps-button="[[computeListHidden_(apps, apps.splices)]]"
+ hide-websites-button="[[computeListHidden_(websites, websites.splices)]]">
+ </extensions-sidebar>
+ <div id="items">
+ <extensions-item-list id="extensions-list" items="[[extensions]]"
+ delegate="[[service]]" header="[[i18n('sidebarExtensions')]]"
+ in-dev-mode="[[inDevMode]]" filter="[[filter]]"
+ hidden$="[[computeListHidden_(extensions, extensions.splices)]]">
+ </extensions-item-list>
+ <extensions-item-list id="apps-list" items="[[apps]]"
+ delegate="[[service]]" header="[[i18n('sidebarApps')]]"
+ in-dev-mode="[[inDevMode]]" filter="[[filter]]"
+ hidden$="[[computeListHidden_(apps, apps.splices)]]">
+ </extensions-item-list>
+ <extensions-item-list id="websites-list" items="[[websites]]"
+ delegate="[[service]]" header="[[i18n('sidebarWebsites')]]"
+ in-dev-mode="[[inDevMode]]" filter="[[filter]]"
+ hidden$="[[computeListHidden_(websites, websites.splices)]]">
+ </extensions-item-list>
+ </div>
</paper-header-panel>
</template>
<link rel="import" type="css" href="chrome://extensions/manager.css">
diff --git a/chromium/chrome/browser/resources/md_extensions/manager.js b/chromium/chrome/browser/resources/md_extensions/manager.js
index 729ee73338e..60c33b48dc5 100644
--- a/chromium/chrome/browser/resources/md_extensions/manager.js
+++ b/chromium/chrome/browser/resources/md_extensions/manager.js
@@ -3,9 +3,222 @@
// found in the LICENSE file.
cr.define('extensions', function() {
+ 'use strict';
+
+ /**
+ * Compares two extensions to determine which should come first in the list.
+ * @param {chrome.developerPrivate.ExtensionInfo} a
+ * @param {chrome.developerPrivate.ExtensionInfo} b
+ * @return {number}
+ */
+ var compareExtensions = function(a, b) {
+ function compare(x, y) {
+ return x < y ? -1 : (x > y ? 1 : 0);
+ }
+ function compareLocation(x, y) {
+ if (x.location == y.location)
+ return 0;
+ if (x.location == chrome.developerPrivate.Location.UNPACKED)
+ return -1;
+ if (y.location == chrome.developerPrivate.Location.UNPACKED)
+ return 1;
+ return 0;
+ }
+ return compareLocation(a, b) ||
+ compare(a.name.toLowerCase(), b.name.toLowerCase()) ||
+ compare(a.id, b.id);
+ };
+
var Manager = Polymer({
- is: 'extensions-manager'
+ is: 'extensions-manager',
+
+ properties: {
+ /** @type {extensions.Sidebar} */
+ sidebar: Object,
+
+ /** @type {extensions.Service} */
+ service: Object,
+
+ inDevMode: {
+ type: Boolean,
+ value: false,
+ },
+
+ filter: {
+ type: String,
+ value: '',
+ },
+
+ /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */
+ extensions: {
+ type: Array,
+ value: function() { return []; },
+ },
+
+ /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */
+ apps: {
+ type: Array,
+ value: function() { return []; },
+ },
+
+ /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */
+ websites: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ ready: function() {
+ /** @type {extensions.Sidebar} */
+ this.sidebar =
+ /** @type {extensions.Sidebar} */(this.$$('extensions-sidebar'));
+ this.service = extensions.Service.getInstance();
+ this.service.managerReady(this);
+ this.scrollHelper_ = new ScrollHelper(this);
+ this.sidebar.setScrollDelegate(this.scrollHelper_);
+ this.$.toolbar.setSearchDelegate(new SearchHelper(this));
+ },
+
+ /**
+ * @param {chrome.developerPrivate.ExtensionType} type The type of item.
+ * @return {string} The ID of the list that the item belongs in.
+ * @private
+ */
+ getListId_: function(type) {
+ var listId;
+ var ExtensionType = chrome.developerPrivate.ExtensionType;
+ switch (type) {
+ case ExtensionType.HOSTED_APP:
+ case ExtensionType.LEGACY_PACKAGED_APP:
+ listId = 'websites';
+ break;
+ case ExtensionType.PLATFORM_APP:
+ listId = 'apps';
+ break;
+ case ExtensionType.EXTENSION:
+ case ExtensionType.SHARED_MODULE:
+ listId = 'extensions';
+ break;
+ case ExtensionType.THEME:
+ assertNotReached(
+ 'Don\'t send themes to the chrome://extensions page');
+ break;
+ }
+ assert(listId);
+ return listId;
+ },
+
+ /**
+ * @param {string} listId The list to look for the item in.
+ * @param {string} itemId The id of the item to look for.
+ * @return {number} The index of the item in the list, or -1 if not found.
+ * @private
+ */
+ getIndexInList_: function(listId, itemId) {
+ return this[listId].findIndex(function(item) {
+ return item.id == itemId;
+ });
+ },
+
+ /**
+ * @param {!Array<!chrome.developerPrivate.ExtensionInfo>} list
+ * @return {boolean} Whether the list should be visible.
+ */
+ computeListHidden_: function(list) {
+ return list.length == 0;
+ },
+
+ /**
+ * Creates and adds a new extensions-item element to the list, inserting it
+ * into its sorted position in the relevant section.
+ * @param {!chrome.developerPrivate.ExtensionInfo} item The extension
+ * the new element is representing.
+ */
+ addItem: function(item) {
+ var listId = this.getListId_(item.type);
+ // We should never try and add an existing item.
+ assert(this.getIndexInList_(listId, item.id) == -1);
+ var insertBeforeChild = this[listId].findIndex(function(listEl) {
+ return compareExtensions(listEl, item) > 0;
+ });
+ if (insertBeforeChild == -1)
+ insertBeforeChild = this[listId].length;
+ this.splice(listId, insertBeforeChild, 0, item);
+ },
+
+ /**
+ * @param {!chrome.developerPrivate.ExtensionInfo} item The data for the
+ * item to update.
+ */
+ updateItem: function(item) {
+ var listId = this.getListId_(item.type);
+ var index = this.getIndexInList_(listId, item.id);
+ // We should never try and update a non-existent item.
+ assert(index >= 0);
+ this.set([listId, index], item);
+ },
+
+ /**
+ * @param {!chrome.developerPrivate.ExtensionInfo} item The data for the
+ * item to remove.
+ */
+ removeItem: function(item) {
+ var listId = this.getListId_(item.type);
+ var index = this.getIndexInList_(listId, item.id);
+ // We should never try and remove a non-existent item.
+ assert(index >= 0);
+ this.splice(listId, index, 1);
+ },
});
+ /**
+ * @param {extensions.Manager} manager
+ * @constructor
+ * @implements {extensions.SidebarScrollDelegate}
+ */
+ function ScrollHelper(manager) {
+ this.items_ = manager.$.items;
+ }
+
+ ScrollHelper.prototype = {
+ /** @override */
+ scrollToExtensions: function() {
+ this.items_.scrollTop =
+ this.items_.querySelector('#extensions-list').offsetTop;
+ },
+
+ /** @override */
+ scrollToApps: function() {
+ this.items_.scrollTop =
+ this.items_.querySelector('#apps-list').offsetTop;
+ },
+
+ /** @override */
+ scrollToWebsites: function() {
+ this.items_.scrollTop =
+ this.items_.querySelector('#websites-list').offsetTop;
+ },
+ };
+
+ /**
+ * @param {extensions.Manager} manager
+ * @constructor
+ * @implements {SearchFieldDelegate}
+ */
+ function SearchHelper(manager) {
+ this.manager_ = manager;
+ }
+
+ SearchHelper.prototype = {
+ /** @override */
+ onSearchTermSearch: function(searchTerm) {
+ this.manager_.filter = searchTerm;
+ },
+ };
+
return {Manager: Manager};
});
diff --git a/chromium/chrome/browser/resources/md_extensions/service.html b/chromium/chrome/browser/resources/md_extensions/service.html
new file mode 100644
index 00000000000..fe1be3facc3
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/service.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="chrome://extensions/service.html">
+<link rel="import" href="chrome://extensions/item.html">
+<script src="chrome://extensions/service.js"></script>
diff --git a/chromium/chrome/browser/resources/md_extensions/service.js b/chromium/chrome/browser/resources/md_extensions/service.js
new file mode 100644
index 00000000000..a0837206eb1
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_extensions/service.js
@@ -0,0 +1,158 @@
+// 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.
+
+cr.define('extensions', function() {
+ 'use strict';
+
+ /**
+ * @constructor
+ * @implements {extensions.ItemDelegate}
+ * @implements {extensions.SidebarDelegate}
+ */
+ function Service() {}
+
+ Service.prototype = {
+ /** @private {boolean} */
+ promptIsShowing_: false,
+
+ /** @param {extensions.Manager} manager */
+ managerReady: function(manager) {
+ /** @private {extensions.Manager} */
+ this.manager_ = manager;
+ /** @private {extensions.Sidebar} */
+ this.sidebar_ = manager.sidebar;
+ this.sidebar_.setDelegate(this);
+ chrome.developerPrivate.onProfileStateChanged.addListener(
+ this.onProfileStateChanged_.bind(this));
+ chrome.developerPrivate.onItemStateChanged.addListener(
+ this.onItemStateChanged_.bind(this));
+ chrome.developerPrivate.getExtensionsInfo(
+ {includeDisabled: true, includeTerminated: true},
+ function(extensions) {
+ /** @private {Array<chrome.developerPrivate.ExtensionInfo>} */
+ this.extensions_ = extensions;
+ for (let extension of extensions)
+ this.manager_.addItem(extension);
+ }.bind(this));
+ chrome.developerPrivate.getProfileConfiguration(
+ this.onProfileStateChanged_.bind(this));
+ },
+
+ /**
+ * @param {chrome.developerPrivate.ProfileInfo} profileInfo
+ * @private
+ */
+ onProfileStateChanged_: function(profileInfo) {
+ /** @private {chrome.developerPrivate.ProfileInfo} */
+ this.profileInfo_ = profileInfo;
+ this.manager_.set('inDevMode', profileInfo.inDeveloperMode);
+ },
+
+ /**
+ * @param {chrome.developerPrivate.EventData} eventData
+ * @private
+ */
+ onItemStateChanged_: function(eventData) {
+ var currentIndex = this.extensions_.findIndex(function(extension) {
+ return extension.id == eventData.item_id;
+ });
+
+ var EventType = chrome.developerPrivate.EventType;
+ switch (eventData.event_type) {
+ case EventType.VIEW_REGISTERED:
+ case EventType.VIEW_UNREGISTERED:
+ case EventType.INSTALLED:
+ case EventType.LOADED:
+ case EventType.UNLOADED:
+ case EventType.ERROR_ADDED:
+ case EventType.ERRORS_REMOVED:
+ case EventType.PREFS_CHANGED:
+ // |extensionInfo| can be undefined in the case of an extension
+ // being unloaded right before uninstallation. There's nothing to do
+ // here.
+ if (!eventData.extensionInfo)
+ break;
+
+ if (currentIndex >= 0) {
+ this.extensions_[currentIndex] = eventData.extensionInfo;
+ this.manager_.updateItem(eventData.extensionInfo);
+ } else {
+ this.extensions_.push(eventData.extensionInfo);
+ this.manager_.addItem(eventData.extensionInfo);
+ }
+ break;
+ case EventType.UNINSTALLED:
+ this.manager_.removeItem(this.extensions_[currentIndex]);
+ this.extensions_.splice(currentIndex, 1);
+ break;
+ default:
+ assertNotReached();
+ }
+ },
+
+ /** @override */
+ deleteItem: function(id) {
+ if (this.promptIsShowing_)
+ return;
+ this.promptIsShowing_ = true;
+ chrome.management.uninstall(id, {showConfirmDialog: true}, function() {
+ // The "last error" was almost certainly the user canceling the dialog.
+ // Do nothing. We only check it so we don't get noisy logs.
+ /** @suppress {suspiciousCode} */
+ chrome.runtime.lastError;
+ this.promptIsShowing_ = false;
+ }.bind(this));
+ },
+
+ /** @override */
+ setItemEnabled: function(id, isEnabled) {
+ chrome.management.setEnabled(id, isEnabled);
+ },
+
+ /** @override */
+ showItemDetails: function(id) {},
+
+ /** @override */
+ setItemAllowedIncognito: function(id, isAllowedIncognito) {
+ chrome.developerPrivate.updateExtensionConfiguration({
+ extensionId: id,
+ incognitoAccess: isAllowedIncognito,
+ });
+ },
+
+ /** @override */
+ inspectItemView: function(id, view) {
+ chrome.developerPrivate.openDevTools({
+ extensionId: id,
+ renderProcessId: view.renderProcessId,
+ renderViewId: view.renderViewId,
+ incognito: view.incognito,
+ });
+ },
+
+ /** @override */
+ setProfileInDevMode: function(inDevMode) {
+ chrome.developerPrivate.updateProfileConfiguration(
+ {inDeveloperMode: inDevMode});
+ },
+
+ /** @override */
+ loadUnpacked: function() {
+ chrome.developerPrivate.loadUnpacked({failQuietly: true});
+ },
+
+ /** @override */
+ packExtension: function() {
+ },
+
+ /** @override */
+ updateAllExtensions: function() {
+ chrome.developerPrivate.autoUpdate();
+ },
+ };
+
+ cr.addSingletonGetter(Service);
+
+ return {Service: Service};
+});
diff --git a/chromium/chrome/browser/resources/md_extensions/sidebar.css b/chromium/chrome/browser/resources/md_extensions/sidebar.css
index a7c4b14fac5..30618144e0b 100644
--- a/chromium/chrome/browser/resources/md_extensions/sidebar.css
+++ b/chromium/chrome/browser/resources/md_extensions/sidebar.css
@@ -5,7 +5,7 @@
:host {
-webkit-margin-start: 30px;
margin-top: 30px;
- position: fixed;
+ white-space: nowrap;
}
#section-menu {
@@ -32,7 +32,7 @@ paper-item {
-webkit-margin-start: 15px;
}
-#developer-mode {
+#devtools-container {
border-bottom: 1px solid #C5C5C5;
border-top: 1px solid #C5C5C5;
margin: 10px 0;
@@ -43,3 +43,7 @@ paper-item {
--primary-text-color: #5A5A5A;
-webkit-margin-start: 10px;
}
+
+#devtools-controls {
+ -webkit-margin-start: 20px;
+}
diff --git a/chromium/chrome/browser/resources/md_extensions/sidebar.html b/chromium/chrome/browser/resources/md_extensions/sidebar.html
index 9bb9b02a211..a56a9e46de7 100644
--- a/chromium/chrome/browser/resources/md_extensions/sidebar.html
+++ b/chromium/chrome/browser/resources/md_extensions/sidebar.html
@@ -1,29 +1,57 @@
<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/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
+<link rel="import" href="chrome://extensions/icons.html">
<dom-module id="extensions-sidebar">
<template>
<paper-menu id="section-menu">
- <paper-item class="section-menu-item" id="sections-extensions">
+ <paper-item class="section-menu-item" id="sections-extensions"
+ on-tap="onExtensionsTap_" hidden$="[[hideExtensionsButton]]">
<iron-icon icon="extension"></iron-icon>
<span i18n-content="sidebarExtensions"></span>
</paper-item>
- <paper-item class="section-menu-item" id="sections-apps">
+ <paper-item class="section-menu-item" id="sections-apps"
+ on-tap="onAppsTap_" hidden$="[[hideAppsButton]]">
<iron-icon icon="apps"></iron-icon>
<span i18n-content="sidebarApps"></span>
</paper-item>
- <paper-item class="section-menu-item" id="sections-websites">
+ <paper-item class="section-menu-item" id="sections-websites"
+ on-tap="onWebsitesTap_" hidden$="[[hideWebsitesButton]]">
<iron-icon icon="cloud"></iron-icon>
<span i18n-content="sidebarWebsites"></span>
</paper-item>
</paper-menu>
- <paper-item id="developer-mode">
- <span i18n-content="developerMode"></span>
- <paper-checkbox id="developer-mode-checkbox"></paper-checkbox>
- </paper-item>
+ <div id="devtools-container">
+ <paper-item id="developer-mode">
+ <span i18n-content="developerMode"></span>
+ <paper-checkbox id="developer-mode-checkbox"
+ checked="[[inDevMode]]"
+ on-change="onDevModeChange_"></paper-checkbox>
+ </paper-item>
+ <template is="dom-if" if="[[inDevMode]]">
+ <div id="devtools-controls">
+ <paper-item class="section-menu-item" id="load-unpacked"
+ on-tap="onLoadUnpackedTap_">
+ <iron-icon icon="file-download"></iron-icon>
+ <span>[[i18n('sidebarLoadUnpacked')]]</span>
+ </paper-item>
+ <paper-item class="section-menu-item" id="pack-extensions"
+ on-tap="onPackTap_">
+ <iron-icon icon="extensions-icons:pack"></iron-icon>
+ <span>[[i18n('sidebarPack')]]</span>
+ </paper-item>
+ <paper-item class="section-menu-item" id="update-now"
+ on-tap="onUpdateNowTap_">
+ <iron-icon icon="extensions-icons:update"></iron-icon>
+ <span>[[i18n('sidebarUpdateNow')]]</span>
+ </paper-item>
+ </div>
+ </template>
+ </div>
<paper-item id="more-extensions" i18n-content="getMoreExtensions">
</paper-item>
<paper-item id="keyboard-shortcuts" i18n-content="keyboardShortcuts">
diff --git a/chromium/chrome/browser/resources/md_extensions/sidebar.js b/chromium/chrome/browser/resources/md_extensions/sidebar.js
index 10dfdf60e1e..622c5ec3ada 100644
--- a/chromium/chrome/browser/resources/md_extensions/sidebar.js
+++ b/chromium/chrome/browser/resources/md_extensions/sidebar.js
@@ -3,10 +3,122 @@
// found in the LICENSE file.
cr.define('extensions', function() {
+ /** @interface */
+ var SidebarDelegate = function() {};
+
+ SidebarDelegate.prototype = {
+ /**
+ * Toggles whether or not the profile is in developer mode.
+ * @param {boolean} inDevMode
+ */
+ setProfileInDevMode: assertNotReached,
+
+ /** Opens the dialog to load unpacked extensions. */
+ loadUnpacked: assertNotReached,
+
+ /** Opens the dialog to pack an extension. */
+ packExtension: assertNotReached,
+
+ /** Updates all extensions. */
+ updateAllExtensions: assertNotReached,
+ };
+
+ /** @interface */
+ var SidebarScrollDelegate = function() {};
+
+ SidebarScrollDelegate.prototype = {
+ /** Scrolls to the extensions section. */
+ scrollToExtensions: assertNotReached,
+
+ /** Scrolls to the apps section. */
+ scrollToApps: assertNotReached,
+
+ /** Scrolls to the websites section. */
+ scrollToWebsites: assertNotReached,
+ };
+
var Sidebar = Polymer({
is: 'extensions-sidebar',
+
+ properties: {
+ inDevMode: {
+ type: Boolean,
+ value: false,
+ },
+
+ hideExtensionsButton: {
+ type: Boolean,
+ value: false,
+ },
+
+ hideAppsButton: {
+ type: Boolean,
+ value: false,
+ },
+
+ hideWebsitesButton: {
+ type: Boolean,
+ value: false,
+ },
+ },
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ /** @param {extensions.SidebarDelegate} delegate */
+ setDelegate: function(delegate) {
+ /** @private {extensions.SidebarDelegate} */
+ this.delegate_ = delegate;
+ },
+
+ /** @param {extensions.SidebarScrollDelegate} scrollDelegate */
+ setScrollDelegate: function(scrollDelegate) {
+ /** @private {extensions.SidebarScrollDelegate} */
+ this.scrollDelegate_ = scrollDelegate;
+ },
+
+ /** @private */
+ onExtensionsTap_: function() {
+ this.scrollDelegate_.scrollToExtensions();
+ },
+
+ /** @private */
+ onAppsTap_: function() {
+ this.scrollDelegate_.scrollToApps();
+ },
+
+ /** @private */
+ onWebsitesTap_: function() {
+ this.scrollDelegate_.scrollToWebsites();
+ },
+
+ /** @private */
+ onDevModeChange_: function() {
+ this.delegate_.setProfileInDevMode(
+ this.$['developer-mode-checkbox'].checked);
+ },
+
+ /** @private */
+ onLoadUnpackedTap_: function() {
+ this.delegate_.loadUnpacked();
+ },
+
+ /** @private */
+ onPackTap_: function() {
+ this.delegate_.packExtension();
+ },
+
+ /** @private */
+ onUpdateNowTap_: function() {
+ this.delegate_.updateAllExtensions();
+ },
});
- return {Sidebar: Sidebar};
+ return {
+ Sidebar: Sidebar,
+ SidebarDelegate: SidebarDelegate,
+ SidebarScrollDelegate: SidebarScrollDelegate,
+ };
});
diff --git a/chromium/chrome/browser/resources/md_extensions/toolbar.html b/chromium/chrome/browser/resources/md_extensions/toolbar.html
index f269d333385..8cc0aee2c8e 100644
--- a/chromium/chrome/browser/resources/md_extensions/toolbar.html
+++ b/chromium/chrome/browser/resources/md_extensions/toolbar.html
@@ -1,6 +1,6 @@
-<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/cr_search_field/cr_search_field.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_search_field/cr_search_field.html">
+<link rel="import" href="chrome://resources/html/cr.html">
<dom-module id="extensions-toolbar">
<template>
diff --git a/chromium/chrome/browser/resources/md_extensions/toolbar.js b/chromium/chrome/browser/resources/md_extensions/toolbar.js
index fade7d418ee..3da624cc6de 100644
--- a/chromium/chrome/browser/resources/md_extensions/toolbar.js
+++ b/chromium/chrome/browser/resources/md_extensions/toolbar.js
@@ -6,28 +6,11 @@ cr.define('extensions', function() {
var Toolbar = Polymer({
is: 'extensions-toolbar',
- /** @param {string} searchTerm */
- onSearchTermSearch: function(searchTerm) {
+ /** @param {SearchFieldDelegate} delegate */
+ setSearchDelegate: function(delegate) {
+ this.$['search-field'].setDelegate(delegate);
},
});
- /**
- * @constructor
- * @implements {SearchFieldDelegate}
- */
- // TODO(devlin): This is a bit excessive, and it would be better to just have
- // Toolbar implement SearchFieldDelegate. But for now, we don't know how to
- // make that happen with closure compiler.
- function ToolbarSearchFieldDelegate(toolbar) {
- this.toolbar_ = toolbar;
- }
-
- ToolbarSearchFieldDelegate.prototype = {
- /** @override */
- onSearchTermSearch: function(searchTerm) {
- this.toolbar_.onSearchTermSearch(searchTerm);
- }
- };
-
return {Toolbar: Toolbar};
});
diff --git a/chromium/chrome/browser/resources/md_history/OWNERS b/chromium/chrome/browser/resources/md_history/OWNERS
new file mode 100644
index 00000000000..793f7b9dc7a
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_history/OWNERS
@@ -0,0 +1,3 @@
+calamity@chromium.org
+dbeam@chromium.org
+tsergeant@chromium.org
diff --git a/chromium/chrome/browser/resources/md_history/history.html b/chromium/chrome/browser/resources/md_history/history.html
new file mode 100644
index 00000000000..a2af6fb18e7
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_history/history.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html i18n-values="dir:textdirection;lang:language">
+<head>
+ <meta charset="utf8">
+ <title i18n-content="title"></title>
+
+ <link rel="stylesheet" href="chrome://resources/css/roboto.css">
+ <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
+</head>
+
+<body>
+ <h1 i18n-content="title"></h1>
+ <link rel="import" href="chrome://resources/html/polymer_config.html">
+
+ <!-- Prepare strings and perform i18n substitutions. -->
+ <link rel="import" href="chrome://resources/html/load_time_data.html">
+ <script src="strings.js"></script>
+ <link rel="import" href="chrome://resources/html/i18n_template.html">
+</body>
+
+</html>
diff --git a/chromium/chrome/browser/resources/md_policy/md_policy.html b/chromium/chrome/browser/resources/md_policy/md_policy.html
new file mode 100644
index 00000000000..0ed781997cf
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_policy/md_policy.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Policies</title>
+</head>
+<body>
+ <h1>A Material Design policy page is under construction!</h1>
+</body>
+</html>
diff --git a/chromium/chrome/browser/resources/md_policy/policy_resources.grd b/chromium/chrome/browser/resources/md_policy/policy_resources.grd
new file mode 100644
index 00000000000..50c9bccedcd
--- /dev/null
+++ b/chromium/chrome/browser/resources/md_policy/policy_resources.grd
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0" current_release="1">
+ <outputs>
+ <output filename="grit/policy_resources.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="grit/policy_resources_map.cc"
+ type="resource_file_map_source" />
+ <output filename="grit/policy_resources_map.h"
+ type="resource_map_header" />
+ <output filename="policy_resources.pak" type="data_package" />
+ </outputs>
+ <release seq="1">
+ <structures>
+ <!-- TODO(fhorschig): Add upcoming polymer files here. -->
+ <structure name="IDR_MD_POLICY_HTML"
+ file="md_policy.html"
+ type="chrome_html"/>
+ </structures>
+ </release>
+</grit>
diff --git a/chromium/chrome/browser/resources/media/webrtc_logs.js b/chromium/chrome/browser/resources/media/webrtc_logs.js
index 21c8c120133..83d48adc28d 100644
--- a/chromium/chrome/browser/resources/media/webrtc_logs.js
+++ b/chromium/chrome/browser/resources/media/webrtc_logs.js
@@ -31,9 +31,7 @@ function updateWebRtcLogsList(uploads, version) {
var title = document.createElement('h3');
title.textContent =
loadTimeData.getStringF('webrtcLogHeaderFormat',
- upload['capture_time'].length != 0 ?
- upload['capture_time'] :
- upload['upload_time']);
+ upload['capture_time']);
logBlock.appendChild(title);
var localFileLine = document.createElement('p');
diff --git a/chromium/chrome/browser/resources/media_router/compiled_resources.gyp b/chromium/chrome/browser/resources/media_router/compiled_resources.gyp
new file mode 100644
index 00000000000..5b7abe5f47f
--- /dev/null
+++ b/chromium/chrome/browser/resources/media_router/compiled_resources.gyp
@@ -0,0 +1,55 @@
+# 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.
+{
+ 'targets': [
+ {
+ 'target_name': 'media_router',
+ 'variables': {
+ 'depends': [
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/iron-form-element-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-icon/iron-icon-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-menu-behavior/iron-menu-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-selector/iron-multi-selectable-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-selector/iron-selectable-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-selector/iron-selection-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/iron-validatable-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-button-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-ripple-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-button/paper-button-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-icon-button/paper-icon-button-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-input/paper-input-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-item/paper-item-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-item/paper-item-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-menu-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-behavior-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-extracted.js',
+ '../../../../third_party/polymer/v1_0/components-chromium/paper-toolbar/paper-toolbar-extracted.js',
+ '../../../../ui/webui/resources/js/cr.js',
+ '../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../ui/webui/resources/js/util.js',
+ 'media_router.js',
+ 'media_router_data.js',
+ 'media_router_ui_interface.js',
+ 'elements/issue_banner/issue_banner.js',
+ 'elements/route_details/route_details.js',
+ 'elements/media_router_header/media_router_header.js',
+ 'elements/media_router_container/media_router_container.js',
+ ],
+ 'externs': [
+ '<(EXTERNS_DIR)/chrome_send.js',
+ 'externs.js',
+ ],
+ },
+ 'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
+ }
+ ],
+}
+
diff --git a/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.css b/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.css
index 23922588f27..b06922b84b9 100644
--- a/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.css
+++ b/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.css
@@ -3,31 +3,35 @@
* found in the LICENSE file. */
.blocking {
+ background-color: white;
overflow: hidden;
- padding-bottom: 15px;
- padding-top: 15px;
position: relative;
text-align: center;
}
+.blocking > #buttons {
+ padding-bottom: 24px;
+ padding-top: 20px;
+}
+
.blocking > div > #title {
- color: rgb(150, 150, 150);
+ color: rgba(0, 0, 0, 0.87);
line-height: 1.125em;
padding: 10px;
vertical-align: middle;
}
#blocking-icon {
+ color: rgb(219, 68, 55);
height: 75px;
- padding: 15px;
+ padding-top: 24px;
width: 75px;
}
.non-blocking {
background-color: rgb(66, 66, 66);
- max-height: 65px;
overflow: hidden;
- padding: 6px;
+ padding: 16px;
}
.non-blocking > #buttons {
@@ -38,6 +42,9 @@
}
.non-blocking > div > #title {
- color: white;
- padding: 6px 6px 20px 6px;
+ color: rgba(255, 255, 255, 0.87);
}
+
+paper-button {
+ margin: 0;
+} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html b/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
index c2b25085fc2..d5f02adbcdb 100644
--- a/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
+++ b/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
@@ -1,15 +1,14 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<dom-module name="issue-banner">
<link rel="import" type="css" href="../../media_router_common.css">
<link rel="import" type="css" href="issue_banner.css">
- <template>
+ <template>
<div class$="[[computeIssueClass_(issue)]]">
<div>
<div hidden$="[[computeIsBlockingIssueHidden_(issue)]]">
- <iron-icon icon="report-problem" id="blocking-icon">
+ <iron-icon icon="error-outline" id="blocking-icon">
</iron-icon>
</div>
<div id="title">[[issue.title]]</div>
diff --git a/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js b/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js
index 7466340118b..029568514cb 100644
--- a/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js
+++ b/chromium/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js
@@ -9,23 +9,15 @@ Polymer({
properties: {
/**
- * The issue to show.
- * @type {?media_router.Issue}
- */
- issue: {
- type: Object,
- value: null,
- observer: 'updateActionButtonText_',
- },
-
- /**
* Maps an issue action type to the resource identifier of the text shown
* in the action button.
- * This is a property of issue-banner because it is used in tests.
- * @type {!Array<string>}
+ * This is a property of issue-banner because it is used in tests. This
+ * property should always be set before |issue| is set or updated.
+ * @private {!Array<string>}
*/
- issueActionTypeToButtonTextResource_: {
+ actionTypeToButtonTextResource_: {
type: Array,
+ readOnly: true,
value: function() {
return ['dismissButton', 'learnMoreButton'];
},
@@ -41,6 +33,16 @@ Polymer({
},
/**
+ * The issue to show.
+ * @type {?media_router.Issue}
+ */
+ issue: {
+ type: Object,
+ value: null,
+ observer: 'updateActionButtonText_',
+ },
+
+ /**
* The text shown in the secondary action button.
* @private {string}
*/
@@ -60,16 +62,6 @@ Polymer({
},
/**
- * Returns true to hide the non-blocking issue UI, false to show it.
- *
- * @param {?media_router.Issue} issue
- * @private
- */
- computeIsNonBlockingIssueHidden_: function(issue) {
- return !issue || issue.isBlocking;
- },
-
- /**
* @param {?media_router.Issue} issue The current issue.
* @return {string} The class for the overall issue-banner.
* @private
@@ -121,7 +113,8 @@ Polymer({
* @private
*/
onClickOptAction_: function(event) {
- this.fireIssueActionClick_(this.issue.secondaryActionType);
+ this.fireIssueActionClick_(
+ /** @type {number} */(this.issue.secondaryActionType));
},
/**
@@ -135,12 +128,12 @@ Polymer({
var secondaryText = '';
if (this.issue) {
defaultText = loadTimeData.getString(
- this.issueActionTypeToButtonTextResource_[
+ this.actionTypeToButtonTextResource_[
this.issue.defaultActionType]);
if (this.issue.secondaryActionType) {
secondaryText = loadTimeData.getString(
- this.issueActionTypeToButtonTextResource_[
+ this.actionTypeToButtonTextResource_[
this.issue.secondaryActionType]);
}
}
diff --git a/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css b/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css
index b8df52e30bb..0fdd947a9b4 100644
--- a/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css
+++ b/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css
@@ -2,72 +2,88 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-.active-sink {
- color: rgb(33, 150, 243);
+:root {
+ --container-header-height: 52px;
}
-#arrow-drop-icon::shadow #icon {
- height: 20px;
- width: 20px;
+.active-sink {
+ color: rgb(33, 150, 243);
}
.cast-mode-icon,
.sink-icon {
- -webkit-padding-end: 16px;
- -webkit-padding-start: 20px;
+ -webkit-padding-end: 12px;
+ -webkit-padding-start: 16px;
height: 16px;
width: 16px;
}
#cast-mode-list {
- padding-bottom: 8px;
- padding-top: 8px;
-}
-
-#close-button::shadow #icon {
- height: 15px;
- width: 15px;
+ margin-top: var(--container-header-height);
+ padding-bottom: 12px;
+ padding-top: 4px;
}
#container-header {
- background-color: rgb(33, 150, 243);
-}
-
-#container-header.cast-mode-list {
- background-color: rgb(0, 150, 136);
-}
-
-#container-header.filter {
- background-color: rgb(103, 58, 183);
+ position: fixed;
+ width: 100%;
+ z-index: 1;
}
#device-missing {
align-items: center;
+ background-color: white;
display: flex;
- height: 150px;
+ height: 120px;
justify-content: center;
+ margin-top: var(--container-header-height);
}
#device-missing a {
- color: rgb(33, 150, 243);
+ color: rgba(33, 150, 243, 0.87);
text-decoration: none;
}
-#header-text {
- -webkit-padding-start: 5px;
- flex-grow: 1;
+#first-run-button {
+ background-color: white;
+}
+
+#first-run-button-container {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+}
+
+#first-run-flow {
+ background-color: rgb(33, 150, 243);
+ padding: 24px 16px 4px 16px;
+ position: fixed;
+ z-index: 1;
+}
+
+#first-run-text,
+#first-run-title {
+ color: white;
+ padding-bottom: 24px;
+}
+
+#first-run-text {
+ font-size: 1.0em;
+ line-height: 1.5em;
+}
+
+#first-run-title {
font-size: 1.25em;
- margin: 0;
}
#issue-banner {
+ margin-top: var(--container-header-height);
width: 100%;
- z-index: 1;
}
#issue-banner.non-blocking {
bottom: 0;
- position: fixed;
+ margin-top: 0;
}
paper-item {
@@ -85,12 +101,11 @@ paper-item:hover {
paper-menu {
-webkit-user-select: none;
- color: rgb(0, 0, 0);
- padding: 0;
-}
-
-.route {
- color: rgb(150, 150, 150);
+ color: rgba(0, 0, 0, 0.87);
+ overflow-x: hidden;
+ overflow-y: auto;
+ padding-bottom: 12px;
+ padding-top: 4px;
}
#searching-devices-spinner {
@@ -99,10 +114,10 @@ paper-menu {
}
#share-screen-text {
- -webkit-padding-start: 20px;
+ -webkit-padding-start: 16px;
color: rgb(150, 150, 150);
- padding-bottom: 8px;
- padding-top: 8px;
+ padding-bottom: 4px;
+ padding-top: 12px;
}
.sink-content {
@@ -111,16 +126,26 @@ paper-menu {
font-weight: normal;
}
-#sink-list {
- max-height: 200px;
- overflow-x: hidden;
- overflow-y: auto;
+.sink-domain {
+ -webkit-padding-start: 6px;
+ color: rgb(150, 150, 150);
+}
+
+.sink-subtext {
+ color: rgb(150, 150, 150);
+ padding-top: 8px;
}
.sink-text {
+ -webkit-padding-end: 26px;
+ flex-direction: row;
line-height: normal;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 250px;
}
+
+#route-details {
+ margin-top: var(--container-header-height);
+}
diff --git a/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html b/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
index d04a3121d5a..974d8b2ed98 100644
--- a/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
+++ b/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
@@ -4,73 +4,72 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/communication-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/hardware-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-toolbar/paper-toolbar.html">
<link rel="import" href="../issue_banner/issue_banner.html">
+<link rel="import" href="../media_router_header/media_router_header.html">
<link rel="import" href="../route_details/route_details.html">
<dom-module id="media-router-container">
+ <link rel="import" type="css" href="../../media_router_common.css">
<link rel="import" type="css" href="media_router_container.css">
<template>
- <paper-toolbar id="container-header"
- class$="[[currentView_]]"
- hidden$="[[computeHeaderHidden_(currentView_, issue)]]">
- <div id="header-text">
- <span hidden$="[[computeSinkListViewHidden_(currentView_, issue)]]"
- id="sink-list-header-text" title="[[headerTextTooltip]]"
- >[[headerText]]</span>
- <span hidden$="[[computeCastModeHidden_(currentView_)]]"
- id="cast-mode-header-text">[[selectCastModeHeaderText_]]</span>
+ <template is="dom-if"
+ if="[[computeShowFirstRunFlow_(showFirstRunFlow, currentView_)]]">
+ <div id="first-run-flow">
+ <div id="first-run-title">[[firstRunFlowTitle_]]</div>
+ <div id="first-run-text">[[firstRunFlowText_]]</div>
+ <div id="first-run-button-container">
+ <paper-button id="first-run-button" class="button"
+ on-click="acknowledgeFirstRunFlow_">
+ <span>[[firstRunFlowButtonText_]]</span>
+ </paper-button>
+ </div>
</div>
- <paper-icon-button icon="[[computeArrowDropIcon_(currentView_)]]"
- disabled$="[[isLaunching_(sinkList)]]" id="arrow-drop-icon"
- on-click="toggleCastModeHidden_">
- </paper-icon-button>
- <paper-icon-button icon="close" id="close-button"
- on-click="onCloseButtonClick_">
- </paper-icon-button>
- </paper-toolbar>
- <issue-banner id="issue-banner" issue="[[issue]]"
- class$="[[computeIssueBannerClass_(issue)]]"
- hidden$="[[computeIssueBannerHidden_(currentView_, issue)]]">
- </issue-banner>
- <paper-menu id="cast-mode-list"
- hidden$="[[computeCastModeHidden_(currentView_)]]">
- <template is="dom-repeat" id="defaultCastModeList"
- items="[[computeDefaultCastModeList_(castModeList)]]">
- <paper-item on-click="onCastModeClick_">
- <iron-icon class="cast-mode-icon"
- icon="[[computeCastModeIcon_(item)]]">
- </iron-icon>
- <div><span>[[item.host]]</span></div>
- </paper-item>
- </template>
- <div id="share-screen-text"
- hidden$="[[computeShareScreenSubheadingHidden_(castModeList)]]">
- <span>[[shareYourScreenSubheadingText_]]</span>
- </div>
- <template is="dom-repeat" id="nonDefaultCastModeList"
- items="[[computeNonDefaultCastModeList_(castModeList)]]">
- <paper-item on-click="onCastModeClick_">
- <iron-icon class="cast-mode-icon"
- icon="[[computeCastModeIcon_(item)]]">
- </iron-icon>
- <div><span>[[item.description]]</span></div>
- </paper-item>
- </template>
- </paper-menu>
- <route-details id="route-details" route="[[currentRoute_]]"
- sink="[[computeSinkForCurrentRoute_(currentRoute_)]]"
- on-back-click="showSinkList_"
- on-close-route-click="showSinkList_"
- hidden$="[[computeRouteDetailsHidden_(currentView_, issue)]]">
- </route-details>
+ </template>
+ <media-router-header id="container-header"
+ class$="[[currentView_]]" view="[[currentView_]]"
+ heading-text="[[computeHeaderText_(currentView_, headerText)]]"
+ arrow-drop-icon-disabled="[[computeIsLaunching_(currentLaunchingSinkId_)]]"
+ tooltip="[[computeHeaderTooltip_(currentView_, headerTextTooltip)]]"
+ on-back-click="showSinkList_">
+ </media-router-header>
+ <template is="dom-if" if="[[!computeCastModeListHidden_(currentView_)]]">
+ <paper-menu id="cast-mode-list">
+ <template is="dom-repeat" id="defaultCastModeList"
+ items="[[computeDefaultCastModeList_(castModeList)]]">
+ <paper-item on-click="onCastModeClick_">
+ <iron-icon class="cast-mode-icon"
+ icon="[[computeCastModeIcon_(item)]]">
+ </iron-icon>
+ <div><span>[[item.host]]</span></div>
+ </paper-item>
+ </template>
+ <div id="share-screen-text"
+ hidden$="[[computeShareScreenSubheadingHidden_(castModeList)]]">
+ <span>[[shareYourScreenSubheadingText_]]</span>
+ </div>
+ <template is="dom-repeat" id="nonDefaultCastModeList"
+ items="[[computeNonDefaultCastModeList_(castModeList)]]">
+ <paper-item on-click="onCastModeClick_">
+ <iron-icon class="cast-mode-icon"
+ icon="[[computeCastModeIcon_(item)]]">
+ </iron-icon>
+ <div><span>[[item.description]]</span></div>
+ </paper-item>
+ </template>
+ </paper-menu>
+ </template>
+ <template is="dom-if"
+ if="[[!computeRouteDetailsHidden_(currentView_, issue)]]">
+ <route-details id="route-details" route="[[currentRoute_]]"
+ on-close-route-click="onCloseRouteClick_">
+ </route-details>
+ </template>
<div id="sink-list-view"
hidden$="[[computeSinkListViewHidden_(currentView_, issue)]]">
<div id="device-missing"
- hidden$="[[!computeSinkListHidden_(sinkList)]]">
+ hidden$="[[!computeSinkListHidden_(sinksToShow_)]]">
<paper-spinner id="searching-devices-spinner" active
hidden$="[[computeSpinnerHidden_(justOpened_)]]">
</paper-spinner>
@@ -80,36 +79,50 @@
</a>
</div>
<paper-menu id="sink-list"
- hidden$="[[computeSinkListHidden_(currentView_, issue)]]">
- <template is="dom-repeat" id="sinkList" items="[[sinkList]]">
+ hidden$="[[computeSinkListHidden_(sinksToShow_)]]">
+ <template is="dom-repeat" id="sinkList" items="[[sinksToShow_]]">
<paper-item class="sink" on-click="onSinkClick_">
<div class="sink-content">
<div>
<iron-icon icon="[[computeSinkIcon_(item)]]"
- hidden$="[[item.isLaunching]]"
+ hidden$="[[computeSinkIsLaunching_(currentLaunchingSinkId_, item.id)]]"
class$="[[computeSinkIconClass_(item.id, sinkToRouteMap_)]]">
</iron-icon>
- <template is="dom-if" if="[[item.isLaunching]]">
+ <template is="dom-if"
+ if="[[computeSinkIsLaunching_(currentLaunchingSinkId_, item.id)]]">
<paper-spinner class="sink-icon" active>
</paper-spinner>
</template>
</div>
<div>
<div class="sink-text">
- <span>[[item.name]]</span>
- </div>
- <div class="sink-text route"
- hidden$="[[computeRouteInSinkListHidden_(item.id, sinkToRouteMap_)]]">
- <span>[[
- computeRouteInSinkListValue_(item.id, sinkToRouteMap_)
- ]]</span>
+ <span dir="auto">[[item.name]]</span>
+ <template is="dom-if"
+ if="[[!computeSinkDomainHidden_(item)]]">
+ <span class="sink-domain">
+ [[item.domain]]
+ </span>
+ </template>
</div>
+ <template is="dom-if"
+ if="[[!computeSinkSubtextHidden_(item, sinkToRouteMap_)]]">
+ <div class="sink-text sink-subtext">
+ <span>[[computeSinkSubtext_(item, sinkToRouteMap_)]]</span>
+ </div>
+ </template>
</div>
</div>
</paper-item>
</template>
</paper-menu>
</div>
+ <template is="dom-if"
+ if="[[computeIssueBannerShown_(currentView_, issue)]]">
+ <issue-banner id="issue-banner" issue="[[issue]]"
+ class$="[[computeIssueBannerClass_(issue)]]"
+ on-issue-action-click="showSinkList_">
+ </issue-banner>
+ </template>
</template>
<script src="media_router_container.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
index d613dc22f51..79b8d77e62c 100644
--- a/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
+++ b/chromium/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -9,32 +9,32 @@ Polymer({
properties: {
/**
+ * The list of available sinks.
+ * @type {!Array<!media_router.Sink>}
+ */
+ allSinks: {
+ type: Array,
+ value: [],
+ observer: 'reindexSinksAndRebuildSinksToShow_',
+ },
+
+ /**
* The list of CastModes to show.
* @type {!Array<!media_router.CastMode>}
*/
castModeList: {
type: Array,
value: [],
+ observer: 'checkCurrentCastMode_',
},
/**
- * The possible states of media-router-container. Used to determine which
- * components of media-router-container to show.
- * This is a property of media-router-container because it is used in
- * tests.
- *
- * @enum {string}
- * @private
+ * The ID of the Sink currently being launched.
+ * @private {string}
*/
- CONTAINER_VIEW_: {
- type: Object,
- readOnly: true,
- value: {
- CAST_MODE_LIST: 'cast-mode-list',
- FILTER: 'filter',
- ROUTE_DETAILS: 'route-details',
- SINK_LIST: 'sink-list',
- },
+ currentLaunchingSinkId_: {
+ type: String,
+ value: '',
},
/**
@@ -48,11 +48,11 @@ Polymer({
/**
* The current view to be shown.
- * @private {CONTAINER_VIEW_}
+ * @private {?media_router.MediaRouterView}
*/
currentView_: {
type: String,
- value: '',
+ value: null,
},
/**
@@ -61,12 +61,15 @@ Polymer({
*/
deviceMissingText_: {
type: String,
- value: loadTimeData.getString('deviceMissing'),
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getString('deviceMissing');
+ },
},
/**
* The URL to open when the device missing link is clicked.
- * @private {string}
+ * @type {string}
*/
deviceMissingUrl: {
type: String,
@@ -74,7 +77,61 @@ Polymer({
},
/**
- * The header text.
+ * The height of the dialog.
+ * @private {number}
+ */
+ dialogHeight_: {
+ type: Number,
+ value: 330,
+ },
+
+ /**
+ * The time |this| element calls ready().
+ * @private {number}
+ */
+ elementReadyTimeMs_: {
+ type: Number,
+ value: 0,
+ },
+
+ /**
+ * The text for the first run flow button.
+ * @private {string}
+ */
+ firstRunFlowButtonText_: {
+ type: String,
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getString('firstRunFlowButton');
+ },
+ },
+
+ /**
+ * The text description for the first run flow.
+ * @private {string}
+ */
+ firstRunFlowText_: {
+ type: String,
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getString('firstRunFlowText');
+ },
+ },
+
+ /**
+ * The header of the first run flow.
+ * @private {string}
+ */
+ firstRunFlowTitle_: {
+ type: String,
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getString('firstRunFlowTitle');
+ },
+ },
+
+ /**
+ * The header text for the sink list.
* @type {string}
*/
headerText: {
@@ -85,11 +142,11 @@ Polymer({
/**
* The header text tooltip. This would be descriptive of the
* source origin, whether a host name, tab URL, etc.
- * @type {string}
+ * @type {?string}
*/
headerTextTooltip: {
type: String,
- value: '',
+ value: null,
},
/**
@@ -99,6 +156,19 @@ Polymer({
issue: {
type: Object,
value: null,
+ observer: 'maybeShowIssueView_',
+ },
+
+ /**
+ * The header text.
+ * @private {string}
+ */
+ issueHeaderText_: {
+ type: String,
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getString('issueHeader');
+ },
},
/**
@@ -108,16 +178,26 @@ Polymer({
justOpened_: {
type: Boolean,
value: true,
- observer: 'computeSpinnerHidden_',
},
/**
- * The number of current local routes.
+ * Whether the user's mouse is positioned over the dialog.
+ * @private {boolean}
+ */
+ mouseIsPositionedOverDialog_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * The time the sink list was shown and populated with at least one sink.
+ * This is reset whenever the user switches views or there are no sinks
+ * available for display.
* @private {number}
*/
- localRouteCount_: {
+ populatedSinkListSeenTimeMs_: {
type: Number,
- value: 0,
+ value: -1,
},
/**
@@ -145,18 +225,10 @@ Polymer({
*/
selectCastModeHeaderText_: {
type: String,
- value: loadTimeData.getString('selectCastModeHeader'),
- },
-
- /**
- * The value of the selected cast mode in |castModeList|, or -1 if the
- * user has not explicitly selected a cast mode.
- * @private {number}
- */
- selectedCastModeValue_: {
- type: Number,
- value: -1,
- observer: 'showSinkList_',
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getString('selectCastModeHeader');
+ },
},
/**
@@ -165,17 +237,38 @@ Polymer({
*/
shareYourScreenSubheadingText_: {
type: String,
- value: loadTimeData.getString('shareYourScreenSubheading'),
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getString('shareYourScreenSubheading');
+ },
},
/**
- * The list of available sinks.
- * @type {!Array<!media_router.Sink>}
+ * Whether to show the first run flow.
+ * @type {boolean}
*/
- sinkList: {
- type: Array,
- value: [],
- observer: 'rebuildSinkMap_',
+ showFirstRunFlow: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * The cast mode shown to the user. Initially set to auto mode. (See
+ * media_router.CastMode documentation for details on auto mode.)
+ * This value may be changed in one of the following ways:
+ * 1) The user explicitly selected a cast mode.
+ * 2) The user selected cast mode is no longer available for the associated
+ * WebContents. In this case, the container will reset to auto mode. Note
+ * that |userHasSelectedCastMode_| will switch back to false.
+ * 3) The sink list changed, and the user had not explicitly selected a cast
+ * mode. If the sinks support exactly 1 cast mode, the container will
+ * switch to that cast mode. Otherwise, the container will reset to auto
+ * mode.
+ * @private {number}
+ */
+ shownCastModeValue_: {
+ type: Number,
+ value: media_router.AUTO_CAST_MODE.type,
},
/**
@@ -189,43 +282,154 @@ Polymer({
/**
* Maps media_router.Sink.id to corresponding media_router.Route.
- * @private {!Object<!string, ?media_router.Route>}
+ * @private {!Object<!string, !media_router.Route>}
*/
sinkToRouteMap_: {
type: Object,
value: {},
},
+
+ /**
+ * Sinks to show for the currently selected cast mode.
+ * @private {!Array<!media_router.Sink>}
+ */
+ sinksToShow_: {
+ type: Array,
+ value: [],
+ },
+
+ /**
+ * Whether the user has explicitly selected a cast mode.
+ * @private {boolean}
+ */
+ userHasSelectedCastMode_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * Whether the user has already taken an action.
+ * @type {boolean}
+ */
+ userHasTakenInitialAction_: {
+ type: Boolean,
+ value: false,
+ },
+ },
+
+ listeners: {
+ 'arrow-drop-click': 'toggleCastModeHidden_',
+ 'mouseleave': 'onMouseLeave_',
+ 'mouseenter': 'onMouseEnter_',
},
+ observers: [
+ 'maybeUpdateStartSinkDisplayStartTime_(currentView_, sinksToShow_)',
+ 'shownComponentsChanged_(showFirstRunFlow, currentView_)'
+ ],
+
ready: function() {
- this.addEventListener('close-route-click', this.removeRoute);
+ this.elementReadyTimeMs_ = performance.now();
this.showSinkList_();
+ this.updateMaxSinkListHeight(this.dialogHeight_);
},
attached: function() {
- // Turn off the spinner after 3 seconds.
+ // Turn off the spinner after 3 seconds, then report the current number of
+ // sinks.
this.async(function() {
this.justOpened_ = false;
+ this.fire('report-sink-count', {
+ sinkCount: this.allSinks.length,
+ });
}, 3000 /* 3 seconds */);
},
/**
- * @param {CONTAINER_VIEW_} view The current view.
- * @return {string} The current arrow-drop-* icon to use.
+ * Fires an acknowledge-first-run-flow event and hides the first run flow.
+ * This is call when the first run flow button is clicked.
+ *
* @private
*/
- computeArrowDropIcon_: function(view) {
- return view == this.CONTAINER_VIEW_.CAST_MODE_LIST ?
- 'arrow-drop-up' : 'arrow-drop-down';
+ acknowledgeFirstRunFlow_: function() {
+ this.showFirstRunFlow = false;
+ this.fire('acknowledge-first-run-flow');
+ },
+
+ /**
+ * Fires a 'report-initial-action' event when the user takes their first
+ * action after the dialog opens. Also fires a 'report-initial-action-close'
+ * event if that initial action is to close the dialog.
+ * @param {!media_router.MediaRouterUserAction} initialAction
+ */
+ maybeReportUserFirstAction: function(initialAction) {
+ if (this.userHasTakenInitialAction_)
+ return;
+
+ this.fire('report-initial-action', {
+ action: initialAction,
+ });
+
+ if (initialAction == media_router.MediaRouterUserAction.CLOSE) {
+ var timeToClose = performance.now() - this.elementReadyTimeMs_;
+ this.fire('report-initial-action-close', {
+ timeMs: timeToClose,
+ });
+ }
+
+ this.userHasTakenInitialAction_ = true;
+ },
+
+ /**
+ * Checks that the currently selected cast mode is still in the
+ * updated list of available cast modes. If not, then update the selected
+ * cast mode to the first available cast mode on the list.
+ */
+ checkCurrentCastMode_: function() {
+ if (!this.castModeList.length)
+ return;
+
+ // If we are currently showing auto mode, then nothing needs to be done.
+ // Otherwise, if the cast mode currently shown no longer exists (regardless
+ // of whether it was selected by user), then switch back to auto cast mode.
+ if (this.shownCastModeValue_ != media_router.CastModeType.AUTO &&
+ !this.findCastModeByType_(this.shownCastModeValue_)) {
+ this.setShownCastMode_(media_router.AUTO_CAST_MODE);
+ this.rebuildSinksToShow_();
+ }
+ },
+
+ /**
+ * If |allSinks| supports only a single cast mode, returns that cast mode.
+ * Otherwise, returns AUTO_MODE. Only called if |userHasSelectedCastMode_| is
+ * |false|.
+ * @return {!media_router.CastMode} The single cast mode supported by
+ * |allSinks|, or AUTO_MODE.
+ */
+ computeCastMode_: function() {
+ var allCastModes = this.allSinks.reduce(function(castModesSoFar, sink) {
+ return castModesSoFar | sink.castModes;
+ }, 0);
+
+ // This checks whether |castModes| does not consist of exactly 1 cast mode.
+ if (!allCastModes || allCastModes & (allCastModes - 1))
+ return media_router.AUTO_CAST_MODE;
+
+ var castMode = this.findCastModeByType_(allCastModes);
+ if (castMode)
+ return castMode;
+
+ console.error('Cast mode ' + allCastModes + ' not in castModeList');
+ return media_router.AUTO_CAST_MODE;
},
/**
- * @param {CONTAINER_VIEW_} view The current view.
+ * @param {?media_router.MediaRouterView} view The current view.
* @return {boolean} Whether or not to hide the cast mode list.
* @private
*/
- computeCastModeHidden_: function(view) {
- return view != this.CONTAINER_VIEW_.CAST_MODE_LIST;
+ computeCastModeListHidden_: function(view) {
+ return view != media_router.MediaRouterView.CAST_MODE_LIST;
},
/**
@@ -233,7 +437,7 @@ Polymer({
* icon for.
* @return {string} The Polymer <iron-icon> icon to use. The format is
* <iconset>:<icon>, where <iconset> is the set ID and <icon> is the name
- * of the icon. <iconset>: may be ommitted if <icon> is from the default
+ * of the icon. <iconset>: may be omitted if <icon> is from the default
* set.
* @private
*/
@@ -263,15 +467,57 @@ Polymer({
},
/**
- * @param {CONTAINER_VIEW_} view The current view.
+ * @param {?media_router.MediaRouterView} view The current view.
* @param {?media_router.Issue} issue The current issue.
* @return {boolean} Whether or not to hide the header.
* @private
*/
computeHeaderHidden_: function(view, issue) {
- return view == this.CONTAINER_VIEW_.ROUTE_DETAILS ||
- (view == this.CONTAINER_VIEW_.SINK_LIST &&
- issue && issue.isBlocking);
+ return view == media_router.MediaRouterView.ROUTE_DETAILS ||
+ (view == media_router.MediaRouterView.SINK_LIST &&
+ !!issue && issue.isBlocking);
+ },
+
+ /**
+ * @param {?media_router.MediaRouterView} view The current view.
+ * @param {string} headerText The header text for the sink list.
+ * @return {string} The text for the header.
+ * @private
+ */
+ computeHeaderText_: function(view, headerText) {
+ switch (view) {
+ case media_router.MediaRouterView.CAST_MODE_LIST:
+ return this.selectCastModeHeaderText_;
+ case media_router.MediaRouterView.ISSUE:
+ return this.issueHeaderText_;
+ case media_router.MediaRouterView.ROUTE_DETAILS:
+ return this.currentRoute_ ?
+ this.sinkMap_[this.currentRoute_.sinkId].name : '';
+ case media_router.MediaRouterView.SINK_LIST:
+ return this.headerText;
+ default:
+ return '';
+ }
+ },
+
+ /**
+ * @param {?media_router.MediaRouterView} view The current view.
+ * @param {string} headerTooltip The tooltip for the header for the sink
+ * list.
+ * @return {string} The tooltip for the header.
+ * @private
+ */
+ computeHeaderTooltip_: function(view, headerTooltip) {
+ return view == media_router.MediaRouterView.SINK_LIST ? headerTooltip : '';
+ },
+
+ /**
+ * @param {string} currentLaunchingSinkId ID of the sink that is currently
+ * launching, or empty string if none exists.
+ * @private
+ */
+ computeIsLaunching_: function(currentLaunchingSinkId) {
+ return currentLaunchingSinkId != '';
},
/**
@@ -280,17 +526,18 @@ Polymer({
* @private
*/
computeIssueBannerClass_: function(issue) {
- return issue && !issue.isBlocking ? 'non-blocking' : '';
+ return !!issue && !issue.isBlocking ? 'non-blocking' : '';
},
/**
- * @param {CONTAINER_VIEW_} view The current view.
+ * @param {?media_router.MediaRouterView} view The current view.
* @param {?media_router.Issue} issue The current issue.
- * @return {boolean} Whether or not to hide the issue banner.
+ * @return {boolean} Whether or not to show the issue banner.
* @private
*/
- computeIssueBannerHidden_: function(view, issue) {
- return !issue || view == this.CONTAINER_VIEW_.CAST_MODE_LIST;
+ computeIssueBannerShown_: function(view, issue) {
+ return !!issue && (view == media_router.MediaRouterView.SINK_LIST ||
+ view == media_router.MediaRouterView.ISSUE);
},
/**
@@ -307,35 +554,14 @@ Polymer({
},
/**
- * @param {CONTAINER_VIEW_} view The current view.
+ * @param {?media_router.MediaRouterView} view The current view.
* @param {?media_router.Issue} issue The current issue.
* @return {boolean} Whether or not to hide the route details.
* @private
*/
computeRouteDetailsHidden_: function(view, issue) {
- return view != this.CONTAINER_VIEW_.ROUTE_DETAILS ||
- (issue && issue.isBlocking);
- },
-
- /**
- * @param {!string} sinkId A sink ID.
- * @return {boolean} Whether or not to hide the route info in the sink list
- * that is associated with |sinkId|.
- * @private
- */
- computeRouteInSinkListHidden_: function(sinkId, sinkToRouteMap) {
- return !sinkToRouteMap[sinkId];
- },
-
- /**
- * @param {!string} sinkId A sink ID.
- * @return {string} The description value of the route associated with
- * |sinkId|.
- * @private
- */
- computeRouteInSinkListValue_: function(sinkId, sinkToRouteMap) {
- var route = sinkToRouteMap[sinkId];
- return route ? route.description : '';
+ return view != media_router.MediaRouterView.ROUTE_DETAILS ||
+ (!!issue && issue.isBlocking);
},
/**
@@ -349,12 +575,14 @@ Polymer({
},
/**
- * @param {?media_router.Route} route The current route.
- * @return {?media_router.Sink} The sink associated with |route|.
+ * @param {boolean} showFirstRunFlow Whether or not to show the first run
+ * flow.
+ * @param {?media_router.MediaRouterView} currentView The current view.
* @private
*/
- computeSinkForCurrentRoute_: function(route) {
- return route ? this.sinkMap_[route.sinkId] : null;
+ computeShowFirstRunFlow_: function(showFirstRunFlow, currentView) {
+ return showFirstRunFlow &&
+ currentView == media_router.MediaRouterView.SINK_LIST;
},
/**
@@ -368,10 +596,11 @@ Polymer({
computeSinkIcon_: function(sink) {
switch (sink.iconType) {
case media_router.SinkIconType.CAST:
- // TODO(apacible): Update icon after UX discussion.
return 'hardware:tv';
case media_router.SinkIconType.CAST_AUDIO:
return 'hardware:speaker';
+ case media_router.SinkIconType.CAST_AUDIO_GROUP:
+ return 'hardware:speaker-group';
case media_router.SinkIconType.GENERIC:
return 'hardware:tv';
case media_router.SinkIconType.HANGOUT:
@@ -393,23 +622,78 @@ Polymer({
},
/**
- * @param {!Array<!media_router.Sink>} The list of sinks.
+ * @param {!string} currentLaunchingSinkId The ID of the sink that is
+ * currently launching.
+ * @param {!string} sinkId A sink ID.
+ * @return {boolean} |true| if given sink is currently launching.
+ * @private
+ */
+ computeSinkIsLaunching_: function(currentLaunchingSinkId, sinkId) {
+ return currentLaunchingSinkId == sinkId;
+ },
+
+ /**
+ * @param {!Array<!media_router.Sink>} sinksToShow The list of sinks.
* @return {boolean} Whether or not to hide the sink list.
* @private
*/
- computeSinkListHidden_: function(sinkList) {
- return sinkList.length == 0;
+ computeSinkListHidden_: function(sinksToShow) {
+ return sinksToShow.length == 0;
},
/**
- * @param {CONTAINER_VIEW_} view The current view.
+ * @param {?media_router.MediaRouterView} view The current view.
* @param {?media_router.Issue} issue The current issue.
* @return {boolean} Whether or not to hide entire the sink list view.
* @private
*/
computeSinkListViewHidden_: function(view, issue) {
- return view != this.CONTAINER_VIEW_.SINK_LIST ||
- (issue && issue.isBlocking);
+ return view != media_router.MediaRouterView.SINK_LIST ||
+ (!!issue && issue.isBlocking);
+ },
+
+ /**
+ * Returns whether the sink domain for |sink| should be hidden.
+ * @param {!media_router.Sink} sink
+ * @return {boolean} |true| if the domain should be hidden.
+ * @private
+ */
+ computeSinkDomainHidden_: function(sink) {
+ // TODO(amp): Check the domain of Chrome profile identity and only show the
+ // sink domain if it doesn't match the profile domain. crbug.com/570797
+ return this.isEmptyOrWhitespace_(sink.domain);
+ },
+
+ /**
+ * Returns the subtext to be shown for |sink|. Only called if
+ * |computeSinkSubtextHidden_| returns false for the same |sink| and
+ * |sinkToRouteMap|.
+ * @param {!media_router.Sink} sink
+ * @param {!Object<!string, ?media_router.Route>} sinkToRouteMap
+ * @return {?string} The subtext to be shown.
+ * @private
+ */
+ computeSinkSubtext_: function(sink, sinkToRouteMap) {
+ var route = sinkToRouteMap[sink.id];
+ if (route && !this.isEmptyOrWhitespace_(route.description))
+ return route.description;
+
+ return sink.description;
+ },
+
+ /**
+ * Returns whether the sink subtext for |sink| should be hidden.
+ * @param {!media_router.Sink} sink
+ * @param {!Object<!string, ?media_router.Route>} sinkToRouteMap
+ * @return {boolean} |true| if the subtext should be hidden.
+ * @private
+ */
+ computeSinkSubtextHidden_: function(sink, sinkToRouteMap) {
+ if (!this.isEmptyOrWhitespace_(sink.description))
+ return false;
+
+ var route = sinkToRouteMap[sink.id];
+ return !route || this.isEmptyOrWhitespace_(route.description);
},
/**
@@ -422,31 +706,96 @@ Polymer({
},
/**
- * Checks if there is a sink whose isLaunching is true.
+ * Helper function to locate the CastMode object with the given type in
+ * castModeList.
*
- * @param {!Array<!media_router.Sink>} sinks
- * @return {boolean}
+ * @param {number} castModeType Type of cast mode to look for.
+ * @return {?media_router.CastMode} CastMode object with the given type in
+ * castModeList, or undefined if not found.
+ */
+ findCastModeByType_: function(castModeType) {
+ return this.castModeList.find(function(element, index, array) {
+ return element.type == castModeType;
+ });
+ },
+
+ /**
+ * Returns whether given string is undefined, null, empty, or whitespace only.
+ * @param {?string} str String to be tested.
+ * @return {boolean} |true| if the string is undefined, null, empty, or
+ * whitespace.
* @private
*/
- isLaunching_: function(sinks) {
- return sinks.some(function(sink) { return sink.isLaunching; });
+ isEmptyOrWhitespace_: function(str) {
+ return str === undefined || str === null || (/^\s*$/).test(str);
},
/**
* Updates |currentView_| if the dialog had just opened and there's
* only one local route.
+ */
+ maybeShowRouteDetailsOnOpen: function() {
+ var localRoute = null;
+ for (var i = 0; i < this.routeList.length; i++) {
+ var route = this.routeList[i];
+ if (!route.isLocal)
+ continue;
+ if (!localRoute) {
+ localRoute = route;
+ } else {
+ // Don't show route details if there are more than one local route.
+ localRoute = null;
+ break;
+ }
+ }
+
+ if (localRoute)
+ this.showRouteDetails_(localRoute);
+ this.fire('show-initial-state', {currentView: this.currentView_});
+ },
+
+ /**
+ * Updates |currentView_| if there is a new blocking issue.
*
- * @param {?media_router.Route} route A local route.
+ * @param {?media_router.Issue} issue The new issue.
* @private
*/
- maybeShowRouteDetailsOnOpen_: function(route) {
- if (this.localRouteCount_ == 1 && this.justOpened_ && route)
- this.showRouteDetails_(route);
+ maybeShowIssueView_: function(issue) {
+ if (!!issue && issue.isBlocking) {
+ this.currentView_ = media_router.MediaRouterView.ISSUE;
+ } else {
+ this.async(function() {
+ this.updateMaxSinkListHeight(this.dialogHeight_);
+ });
+ }
+ },
+
+ /**
+ * May update |populatedSinkListSeenTimeMs_| depending on |currentView| and
+ * |sinksToShow|.
+ * Called when |currentView_| or |sinksToShow_| is updated.
+ *
+ * @param {?media_router.MediaRouterView} currentView The current view of the
+ * dialog.
+ * @param {!Array<!media_router.Sink>} sinksToShow The sinks to display.
+ * @private
+ */
+ maybeUpdateStartSinkDisplayStartTime_: function(currentView, sinksToShow) {
+ if (currentView == media_router.MediaRouterView.SINK_LIST &&
+ sinksToShow.length != 0) {
+ // Only set |populatedSinkListSeenTimeMs_| if it has not already been set.
+ if (this.populatedSinkListSeenTimeMs_ == -1)
+ this.populatedSinkListSeenTimeMs_ = performance.now();
+ } else {
+ // Reset |populatedSinkListLastSeen_| if the sink list isn't being shown
+ // or if there aren't any sinks available for display.
+ this.populatedSinkListSeenTimeMs_ = -1;
+ }
},
/**
* Handles a cast mode selection. Updates |headerText|, |headerTextTooltip|,
- * and |selectedCastModeValue_|.
+ * and |shownCastModeValue_|.
*
* @param {!Event} event The event object.
* @private
@@ -455,24 +804,46 @@ Polymer({
// The clicked cast mode can come from one of two lists,
// defaultCastModeList and nonDefaultCastModeList.
var clickedMode =
- this.$.defaultCastModeList.itemForElement(event.target) ||
- this.$.nonDefaultCastModeList.itemForElement(event.target);
+ this.$$('#defaultCastModeList').itemForElement(event.target) ||
+ this.$$('#nonDefaultCastModeList').itemForElement(event.target);
if (!clickedMode)
return;
- this.headerText = clickedMode.description;
- this.headerTextTooltip = clickedMode.host;
- this.selectedCastModeValue_ = clickedMode.type;
+ this.userHasSelectedCastMode_ = true;
+ this.fire('cast-mode-selected', {castModeType: clickedMode.type});
+
+ // The list of sinks to show will be the same if the shown cast mode did
+ // not change, regardless of whether the user selected it explicitly.
+ if (clickedMode.type != this.shownCastModeValue_) {
+ this.setShownCastMode_(clickedMode);
+ this.rebuildSinksToShow_();
+ }
+
+ this.showSinkList_();
+ this.maybeReportUserFirstAction(
+ media_router.MediaRouterUserAction.CHANGE_MODE);
},
/**
- * Handles a click on the close button by firing a close-button-click event.
+ * Handles a close-route-click event. Shows the sink list and starts a timer
+ * to close the dialog if there is no click within three seconds.
*
+ * @param {!Event} event The event object.
+ * Parameters in |event|.detail:
+ * route - route to close.
* @private
*/
- onCloseButtonClick_: function() {
- this.fire('close-button-click');
+ onCloseRouteClick_: function(event) {
+ /** @type {{route: media_router.Route}} */
+ var detail = event.detail;
+ this.showSinkList_();
+ this.startTapTimer_();
+
+ if (detail.route.isLocal) {
+ this.maybeReportUserFirstAction(
+ media_router.MediaRouterUserAction.STOP_LOCAL);
+ }
},
/**
@@ -484,14 +855,13 @@ Polymer({
* if succeeded; null otherwise.
*/
onCreateRouteResponseReceived: function(sinkId, route) {
- this.setLaunchState_(sinkId, false);
- // TODO(apacible) Show launch failure.
+ this.currentLaunchingSinkId_ = '';
+ // The provider will handle sending an issue for a failed route request.
if (!route)
return;
- // Check if |route| already exists or if its associated sink
- // does not exist.
- if (this.routeMap_[route.id] || !this.sinkMap_[route.sinkId])
+ // Check that |sinkId| exists.
+ if (!this.sinkMap_[sinkId])
return;
// If there is an existing route associated with the same sink, its
@@ -499,6 +869,35 @@ Polymer({
// which results in the correct sink to route mapping.
this.routeList.push(route);
this.showRouteDetails_(route);
+
+ this.startTapTimer_();
+ },
+
+ /**
+ * Called when a mouseleave event is triggered.
+ *
+ * @private
+ */
+ onMouseLeave_: function() {
+ this.mouseIsPositionedOverDialog_ = false;
+ },
+
+ /**
+ * Called when a mouseenter event is triggered.
+ *
+ * @private
+ */
+ onMouseEnter_: function() {
+ this.mouseIsPositionedOverDialog_ = true;
+ },
+
+ /**
+ * Handles timeout of previous create route attempt. Clearing
+ * |currentLaunchingSinkId_| hides the spinner indicating there is a route
+ * creation in progress and show the device icon instead.
+ */
+ onNotifyRouteCreationTimeout: function() {
+ this.currentLaunchingSinkId_ = '';
},
/**
@@ -509,6 +908,7 @@ Polymer({
*/
onSinkClick_: function(event) {
this.showOrCreateRoute_(this.$.sinkList.itemForElement(event.target));
+ this.fire('sink-click', {index: event['model'].index});
},
/**
@@ -519,12 +919,6 @@ Polymer({
*/
rebuildRouteMaps_: function() {
this.routeMap_ = {};
- this.localRouteCount_ = 0;
-
- // Keeps track of the last local route we find in |routeList|. If
- // |localRouteCount_| is eventually equal to one, |localRoute| would be the
- // only current local route.
- var localRoute = null;
// Rebuild |sinkToRouteMap_| with a temporary map to avoid firing the
// computed functions prematurely.
@@ -534,58 +928,89 @@ Polymer({
this.routeList.forEach(function(route) {
this.routeMap_[route.id] = route;
tempSinkToRouteMap[route.sinkId] = route;
-
- if (route.isLocal) {
- this.localRouteCount_++;
-
- // It's OK if localRoute is updated multiple times; it is only used if
- // |localRouteCount_| == 1, which implies it was only set once.
- localRoute = route;
- }
}, this);
// If |currentRoute_| is no longer active, clear |currentRoute_|. Also
// switch back to the SINK_PICKER view if the user is currently in the
// ROUTE_DETAILS view.
if (!this.currentRoute_ || !this.routeMap_[this.currentRoute_.id]) {
- if (this.currentView_ == this.CONTAINER_VIEW_.ROUTE_DETAILS)
- this.showSinkList_();
- else
+ if (this.currentView_ == media_router.MediaRouterView.ROUTE_DETAILS) {
+ // We may have an updated route to show for a device.
+ // We swap out |currentRoute_| (and consequently the route-details
+ // controls) to handle this.
+ this.currentRoute_ =
+ tempSinkToRouteMap[this.currentRoute_.sinkId] || null;
+
+ if (!this.currentRoute_)
+ this.showSinkList_();
+ } else {
this.currentRoute_ = null;
+ }
}
this.sinkToRouteMap_ = tempSinkToRouteMap;
- this.maybeShowRouteDetailsOnOpen_(localRoute);
+ this.rebuildSinksToShow_();
},
/**
- * Called when |sinkList| is updated. Rebuilds |sinkMap_|.
+ * Rebuilds the list of sinks to be shown for the current cast mode.
+ * A sink should be shown if it is compatible with the current cast mode, or
+ * if the sink is associated with a route. The resulting list is sorted by
+ * name.
+ */
+ rebuildSinksToShow_: function() {
+ var sinksToShow = [];
+ if (this.userHasSelectedCastMode_) {
+ // If user explicitly selected a cast mode, then we show only sinks that
+ // are compatible with current cast mode or sinks that are active.
+ sinksToShow = this.allSinks.filter(function(element) {
+ return (element.castModes & this.shownCastModeValue_) ||
+ this.sinkToRouteMap_[element.id];
+ }, this);
+ } else {
+ // If user did not select a cast mode, then:
+ // - If all sinks support only a single cast mode, then the cast mode is
+ // switched to that mode.
+ // - Otherwise, the cast mode becomes auto mode.
+ // Either way, all sinks will be shown.
+ this.setShownCastMode_(this.computeCastMode_());
+ sinksToShow = this.allSinks;
+ }
+
+ this.sinksToShow_ = sinksToShow;
+ },
+
+ /**
+ * Called when |allSinks| is updated.
*
* @private
*/
- rebuildSinkMap_: function() {
+ reindexSinksAndRebuildSinksToShow_: function() {
this.sinkMap_ = {};
- this.sinkList.forEach(function(sink) {
+ this.allSinks.forEach(function(sink) {
this.sinkMap_[sink.id] = sink;
}, this);
+
+ this.rebuildSinksToShow_();
},
/**
- * Temporarily overrides the "isLaunching" bit for a sink.
+ * Updates the shown cast mode, and updates the header text fields
+ * according to the cast mode. If |castMode| type is AUTO, then set
+ * |userHasSelectedCastMode_| to false.
*
- * @param {string} sinkId The ID of the sink.
- * @param {boolean} isLaunching Whether or not the media router is creating
- * a route to the sink.
- * @private
+ * @param {!media_router.CastMode} castMode
*/
- setLaunchState_: function(sinkId, isLaunching) {
- for (var index = 0; index < this.sinkList.length; index++) {
- if (this.sinkList[index].id == sinkId) {
- this.set(['sinkList', index, 'isLaunching'], isLaunching);
- return;
- }
- }
+ setShownCastMode_: function(castMode) {
+ if (this.shownCastModeValue_ == castMode.type)
+ return;
+
+ this.shownCastModeValue_ = castMode.type;
+ this.headerText = castMode.description;
+ this.headerTextTooltip = castMode.host;
+ if (castMode.type == media_router.CastModeType.AUTO)
+ this.userHasSelectedCastMode_ = false;
},
/**
@@ -594,8 +1019,32 @@ Polymer({
* @private
*/
showCastModeList_: function() {
- this.currentRoute_ = null;
- this.currentView_ = this.CONTAINER_VIEW_.CAST_MODE_LIST;
+ this.currentView_ = media_router.MediaRouterView.CAST_MODE_LIST;
+ },
+
+ /**
+ * Updates the top margins of the header and sink list view depending on
+ * whether the first run flow is being shown.
+ *
+ * @param {boolean} showFirstRunFlow Whether or not to show the first run
+ * flow.
+ * @param {!media_router.MediaRouterView} currentView The current view.
+ * @private
+ */
+ shownComponentsChanged_: function(showFirstRunFlow, currentView) {
+ var headerHeight = this.$$('#container-header').offsetHeight;
+ if (this.computeShowFirstRunFlow_(showFirstRunFlow, currentView)) {
+ // Ensures that first run flow elements have finished stamping.
+ this.async(function() {
+ var firstRunFlowHeight = this.$$('#first-run-flow').offsetHeight;
+ this.$['container-header'].style.marginTop = firstRunFlowHeight + 'px';
+ this.$['sink-list-view'].style.marginTop =
+ firstRunFlowHeight + headerHeight + 'px';
+ });
+ } else {
+ this.$['container-header'].style.marginTop = '0px';
+ this.$['sink-list-view'].style.marginTop = headerHeight + 'px';
+ }
},
/**
@@ -609,13 +1058,29 @@ Polymer({
var route = this.sinkToRouteMap_[sink.id];
if (route) {
this.showRouteDetails_(route);
- } else if (!this.isLaunching_(this.sinkList)) {
+ this.fire('navigate-sink-list-to-details');
+ this.maybeReportUserFirstAction(
+ media_router.MediaRouterUserAction.STATUS_REMOTE);
+ } else if (this.currentLaunchingSinkId_ == '') {
// Allow one launch at a time.
- this.setLaunchState_(sink.id, true);
this.fire('create-route', {
sinkId: sink.id,
- selectedCastModeValue: this.selectedCastModeValue_
+ // If user selected a cast mode, then we will create a route using that
+ // cast mode. Otherwise, the UI is in "auto" cast mode and will use the
+ // preferred cast mode compatible with the sink. The preferred cast mode
+ // value is the least significant bit on the bitset.
+ selectedCastModeValue:
+ this.shownCastModeValue_ == media_router.CastModeType.AUTO ?
+ sink.castModes & -sink.castModes : this.shownCastModeValue_
});
+ this.currentLaunchingSinkId_ = sink.id;
+
+ var timeToSelectSink =
+ performance.now() - this.populatedSinkListSeenTimeMs_;
+ this.fire('report-sink-click-time', {timeMs: timeToSelectSink});
+
+ this.maybeReportUserFirstAction(
+ media_router.MediaRouterUserAction.START_LOCAL);
}
},
@@ -627,7 +1092,7 @@ Polymer({
*/
showRouteDetails_: function(route) {
this.currentRoute_ = route;
- this.currentView_ = this.CONTAINER_VIEW_.ROUTE_DETAILS;
+ this.currentView_ = media_router.MediaRouterView.ROUTE_DETAILS;
},
/**
@@ -636,8 +1101,20 @@ Polymer({
* @private
*/
showSinkList_: function() {
- this.currentRoute_ = null;
- this.currentView_ = this.CONTAINER_VIEW_.SINK_LIST;
+ this.currentView_ = media_router.MediaRouterView.SINK_LIST;
+ },
+
+ /**
+ * Starts a timer which fires a close-dialog event if the user's mouse is
+ * not positioned over the dialog after three seconds.
+ *
+ * @private
+ */
+ startTapTimer_: function() {
+ var id = setTimeout(function() {
+ if (!this.mouseIsPositionedOverDialog_)
+ this.fire('close-dialog');
+ }.bind(this), 3000 /* 3 seconds */);
},
/**
@@ -646,9 +1123,36 @@ Polymer({
* @private
*/
toggleCastModeHidden_: function() {
- if (this.currentView_ == this.CONTAINER_VIEW_.CAST_MODE_LIST)
+ if (this.currentView_ == media_router.MediaRouterView.CAST_MODE_LIST) {
this.showSinkList_();
- else
+ } else {
this.showCastModeList_();
+ this.fire('navigate-to-cast-mode-list');
+ }
+ },
+
+ /**
+ * Compute the new maximum height of the sink list and update the style.
+ *
+ * @param {number} dialogHeight The height of the Media Router dialog.
+ */
+ updateMaxSinkListHeight: function(dialogHeight) {
+ this.dialogHeight_ = dialogHeight;
+ var headerHeight = this.$$('#container-header').offsetHeight;
+ var firstRunFlowHeight =
+ this.computeShowFirstRunFlow_(this.showFirstRunFlow,
+ this.currentView_) ?
+ this.$$('#first-run-flow').offsetHeight : 0;
+ this.$['container-header'].style.marginTop = firstRunFlowHeight + 'px';
+ this.$['sink-list-view'].style.marginTop =
+ firstRunFlowHeight + headerHeight + 'px';
+
+ // A non-blocking issue banner may appear below the sink list.
+ var issueHeight = this.$$('#issue-banner') ?
+ this.$$('#issue-banner').offsetHeight : 0;
+
+ this.$['sink-list'].style.maxHeight =
+ this.dialogHeight_ - headerHeight - firstRunFlowHeight -
+ issueHeight + 'px';
},
});
diff --git a/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css b/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css
new file mode 100644
index 00000000000..22fee5d50e9
--- /dev/null
+++ b/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css
@@ -0,0 +1,72 @@
+/* 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. */
+
+#arrow-drop-container {
+ flex-grow: 1;
+}
+
+#arrow-drop-icon::shadow #icon {
+ height: 20px;
+ width: 20px;
+}
+
+#back-button::shadow #icon {
+ height: 20px;
+ width: 20px;
+}
+
+#back-button-container {
+ -webkit-padding-end: 12px;
+}
+
+#close-button {
+ -webkit-margin-start: auto;
+}
+
+#close-button::shadow #icon {
+ height: 15px;
+ width: 15px;
+}
+
+#close-button-container {
+ -webkit-padding-end: 16px;
+ -webkit-padding-start: 24px;
+}
+
+#header-text {
+ -webkit-padding-end: 4px;
+ color: white;
+ font-size: 1.175em;
+ margin: 0;
+}
+
+paper-icon-button {
+ display: inline;
+}
+
+paper-toolbar {
+ -webkit-padding-start: 8px;
+ height: 52px;
+}
+
+paper-toolbar::shadow .toolbar-tools {
+ padding: 0;
+}
+
+paper-toolbar.cast-mode-list {
+ background-color: rgb(0, 150, 136);
+}
+
+paper-toolbar.filter {
+ background-color: rgb(103, 58, 183);
+}
+
+paper-toolbar.issue {
+ background-color: rgb(219, 68, 55);
+}
+
+paper-toolbar.route-details,
+paper-toolbar.sink-list {
+ background-color: rgb(33, 150, 243);
+}
diff --git a/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.html b/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.html
new file mode 100644
index 00000000000..1947cb1abfa
--- /dev/null
+++ b/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.html
@@ -0,0 +1,31 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-toolbar/paper-toolbar.html">
+<dom-module name="media-router-header">
+ <link rel="import" type="css" href="../../media_router_common.css">
+ <link rel="import" type="css" href="media_router_header.css">
+ <template>
+ <paper-toolbar class$="[[view]]">
+ <div id="back-button-container">
+ <paper-icon-button id="back-button" icon="[[arrowDropIcon_]]"
+ on-click="onBackButtonClick_"
+ hidden$="[[computeBackButtonHidden_(view)]]">
+ </paper-icon-button>
+ </div>
+ <span id="header-text" title="[[tooltip]]">[[headingText]]</span>
+ <div id="arrow-drop-container">
+ <paper-icon-button icon="[[computeArrowDropIcon_(view)]]"
+ id="arrow-drop-icon" on-click="onArrowDropClick_"
+ disabled$="[[arrowDropIconDisabled]]"
+ hidden$="[[computeArrowDropIconHidden_(view)]]">
+ </paper-icon-button>
+ </div>
+ <div id="close-button-container">
+ <paper-icon-button icon="close" id="close-button"
+ on-click="onCloseButtonClick_">
+ </paper-icon-button>
+ </div>
+ </paper-toolbar>
+ </template>
+<script src="media_router_header.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.js b/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.js
new file mode 100644
index 00000000000..3e9ea19c5e6
--- /dev/null
+++ b/chromium/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.js
@@ -0,0 +1,118 @@
+// 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.
+
+// This Polymer element is used as a header for the media router interface.
+Polymer({
+ is: 'media-router-header',
+
+ properties: {
+ /**
+ * The name of the icon used as the back button. This is set once, when
+ * the |this| is ready.
+ * @private {string}
+ */
+ arrowDropIcon_: {
+ type: String,
+ value: '',
+ },
+
+ /**
+ * Whether or not the arrow drop icon should be disabled.
+ * @type {boolean}
+ */
+ arrowDropIconDisabled: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * The header text to show.
+ * @type {string}
+ */
+ headingText: {
+ type: String,
+ value: '',
+ },
+
+ /**
+ * The current view that this header should reflect.
+ * @type {?media_router.MediaRouterView}
+ */
+ view: {
+ type: String,
+ value: null,
+ },
+
+ /**
+ * The text to show in the tooltip.
+ * @type {string}
+ */
+ tooltip: {
+ type: String,
+ value: '',
+ },
+ },
+
+ attached: function() {
+ // isRTL() only works after i18n_template.js runs to set <html dir>.
+ // Set the back button icon based on text direction.
+ this.arrowDropIcon_ = isRTL() ? 'arrow-forward' : 'arrow-back';
+ },
+
+ /**
+ * @param {?media_router.MediaRouterView} view The current view.
+ * @return {string} The current arrow-drop-* icon to use.
+ * @private
+ */
+ computeArrowDropIcon_: function(view) {
+ return view == media_router.MediaRouterView.CAST_MODE_LIST ?
+ 'arrow-drop-up' : 'arrow-drop-down';
+ },
+
+ /**
+ * @param {?media_router.MediaRouterView} view The current view.
+ * @return {boolean} Whether or not the arrow drop icon should be hidden.
+ * @private
+ */
+ computeArrowDropIconHidden_: function(view) {
+ return view != media_router.MediaRouterView.SINK_LIST &&
+ view != media_router.MediaRouterView.CAST_MODE_LIST;
+ },
+
+ /**
+ * @param {?media_router.MediaRouterView} view The current view.
+ * @return {boolean} Whether or not the back button should be hidden.
+ * @private
+ */
+ computeBackButtonHidden_: function(view) {
+ return view != media_router.MediaRouterView.ROUTE_DETAILS;
+ },
+
+ /**
+ * Handles a click on the arrow button by firing an arrow-click event.
+ *
+ * @private
+ */
+ onArrowDropClick_: function() {
+ this.fire('arrow-drop-click');
+ },
+
+ /**
+ * Handles a click on the back button by firing a back-click event.
+ *
+ * @private
+ */
+ onBackButtonClick_: function() {
+ this.fire('back-click');
+ },
+
+ /**
+ * Handles a click on the close button by firing a close-button-click event.
+ *
+ * @private
+ */
+ onCloseButtonClick_: function() {
+ this.fire('close-button-click');
+ },
+});
diff --git a/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.css b/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.css
index dc4d21425f3..7b9411ddbbb 100644
--- a/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.css
+++ b/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.css
@@ -2,41 +2,38 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#close-route-button {
- background-color: white;
- color: rgb(33, 150, 243);
- height: 32px;
- line-height: 32px;
- margin: 0;
- text-align: end;
- width: 100%;
-}
-#close-button {
- -webkit-margin-start: auto;
+#custom-controller {
+ display: inline-block;
+ height: 136px;
+ width: 100%;
}
-#close-button::shadow #icon {
- height: 15px;
- width: 15px;
+#join-route-button {
+ @apply(--layout-flex);
}
-#custom-controller {
- display: inline-block;
- height: 160px;
- width: 100%;
+#route-action-buttons {
+ @apply(--layout-horizontal);
+ @apply(--layout-end-justified);
+ margin: 0;
+ padding: 0;
+ white-space: nowrap;
}
-#route-details-header {
- background-color: rgb(33, 150, 243);
- font-size: 1.4em;
+.route-button {
+ -webkit-padding-end: 24px;
+ -webkit-padding-start: 0;
+ background-color: white;
+ line-height: 12px;
+ margin: 12px 0;
+ text-align: end;
}
#route-information {
- -webkit-padding-start: 30px;
+ -webkit-padding-start: 44px;
background-color: white;
font-size: 1.2em;
- height: 40px;
+ margin-top: 16px;
overflow: hidden;
- padding: 20px 30px;
}
diff --git a/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.html b/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.html
index 16d45790d65..041b60a5a44 100644
--- a/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.html
+++ b/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.html
@@ -1,29 +1,28 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-toolbar/paper-toolbar.html">
<dom-module id="route-details">
<link rel="import" type="css" href="../../media_router_common.css">
<link rel="import" type="css" href="route_details.css">
<template>
- <paper-toolbar id="route-details-header">
- <paper-icon-button icon="arrow-back" id="back-button" on-click="back_">
- </paper-icon-button>
- <span id="sink-name">[[sink.name]]</span>
- <paper-icon-button icon="close" id="close-button"
- on-click="onCloseButtonClick_">
- </paper-icon-button>
- </paper-toolbar>
<div id="route-information" hidden$="[[!isCustomControllerHidden_]]">
<span>[[activityStatus_]]</span>
</div>
- <extensionview id="custom-controller" hidden$="[[isCustomControllerHidden_]]">
+ <extensionview id="custom-controller"
+ hidden$="[[isCustomControllerHidden_]]">
</extensionview>
- <paper-button raised id="close-route-button" class="button"
- on-click="closeRoute_">
- <span>[[stopCastingButtonText_]]</span>
- </paper-button>
+ <div id="route-action-buttons" class="layout">
+ <paper-button flat class="route-button button"
+ id="join-route-button"
+ hidden$="[[!route.canJoin]]"
+ on-click="joinRoute_">
+ <span>[[joinButtonText_]]</span>
+ </paper-button>
+ <paper-button flat class="route-button button"
+ id="close-route-button"
+ on-click="closeRoute_">
+ <span>[[stopCastingButtonText_]]</span>
+ </paper-button>
+ <div>
</template>
<script src="route_details.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.js b/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.js
index 43d1aba1cf2..39a4e86d87b 100644
--- a/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.js
+++ b/chromium/chrome/browser/resources/media_router/elements/route_details/route_details.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// This Polymer element shows information from media that is currently cast
-// to a device. It is assumed that |route| and |sink| correspond to each other.
+// to a device.
Polymer({
is: 'route-details',
@@ -28,12 +28,13 @@ Polymer({
},
/**
- * The sink to show.
- * @type {?media_router.Sink}
+ * The text for the join button.
+ * @private {string}
*/
- sink: {
- type: Object,
- value: null,
+ joinButtonText_: {
+ type: String,
+ readOnly: true,
+ value: loadTimeData.getString('joinButton'),
},
/**
@@ -42,7 +43,10 @@ Polymer({
*/
stopCastingButtonText_: {
type: String,
- value: loadTimeData.getString('stopCastingButton'),
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getString('stopCastingButton');
+ },
},
/**
@@ -58,22 +62,23 @@ Polymer({
},
/**
- * Fires a back-click event. This is called when the back link is clicked.
+ * Fires a close-route-click event. This is called when the button to close
+ * the current route is clicked.
*
* @private
*/
- back_: function() {
- this.fire('back-click');
+ closeRoute_: function() {
+ this.fire('close-route-click', {route: this.route});
},
/**
- * Fires a close-route-click event. This is called when the button to close
+ * Fires a join-route-click event. This is called when the button to join
* the current route is clicked.
*
* @private
*/
- closeRoute_: function() {
- this.fire('close-route-click', {route: this.route});
+ joinRoute_: function() {
+ this.fire('join-route-click', {route: this.route});
},
/**
@@ -112,13 +117,4 @@ Polymer({
that.isCustomControllerHidden_ = true;
});
},
-
- /**
- * Handles a click on the close button by firing a close-button-click event.
- *
- * @private
- */
- onCloseButtonClick_: function() {
- this.fire('close-button-click');
- },
});
diff --git a/chromium/chrome/browser/resources/media_router/externs.js b/chromium/chrome/browser/resources/media_router/externs.js
new file mode 100644
index 00000000000..5821b32cbbb
--- /dev/null
+++ b/chromium/chrome/browser/resources/media_router/externs.js
@@ -0,0 +1,15 @@
+// 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.
+
+/**
+ * @fileoverview Externs to be declared to properly compile JS code.
+ * @externs
+ */
+
+var performance = {};
+
+/**
+ * @return {number}
+ */
+performance.now = function() {};
diff --git a/chromium/chrome/browser/resources/media_router/media_router.css b/chromium/chrome/browser/resources/media_router/media_router.css
index e44f31bfa13..c2aca5e29ab 100644
--- a/chromium/chrome/browser/resources/media_router/media_router.css
+++ b/chromium/chrome/browser/resources/media_router/media_router.css
@@ -9,7 +9,12 @@ body {
}
#media-router-container {
- background-color: rgb(246, 246, 246);
+ -webkit-margin-start: 1px;
+ box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 8px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 3px -2px rgba(0, 0, 0, 0.4);
display: flex;
flex-direction: column;
+ margin-bottom: 1px;
+ width: calc(100% - 2px);
}
diff --git a/chromium/chrome/browser/resources/media_router/media_router.html b/chromium/chrome/browser/resources/media_router/media_router.html
index b2208038b32..f0f3ffa6796 100644
--- a/chromium/chrome/browser/resources/media_router/media_router.html
+++ b/chromium/chrome/browser/resources/media_router/media_router.html
@@ -8,8 +8,8 @@
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/util.js"></script>
- <script src="chrome://media-router/media_router.js"></script>
<script src="chrome://media-router/strings.js"></script>
+ <script src="chrome://media-router/media_router.js"></script>
<link rel="stylesheet" href="chrome://resources/css/roboto.css">
<link rel="stylesheet" href="media_router.css">
diff --git a/chromium/chrome/browser/resources/media_router/media_router.js b/chromium/chrome/browser/resources/media_router/media_router.js
index 4773a16d310..f358ce78967 100644
--- a/chromium/chrome/browser/resources/media_router/media_router.js
+++ b/chromium/chrome/browser/resources/media_router/media_router.js
@@ -9,7 +9,14 @@
cr.define('media_router', function() {
'use strict';
- // The media-router-container element. Initialized after polymer is ready.
+ // The ESC key maps to keycode '27'.
+ // @const {number}
+ var KEYCODE_ESC = 27;
+
+ /**
+ * The media-router-container element. Initialized after polymer is ready.
+ * @type {?MediaRouterContainerElement}
+ */
var container = null;
/**
@@ -19,38 +26,121 @@ cr.define('media_router', function() {
function initialize() {
media_router.browserApi.requestInitialData();
- container = $('media-router-container');
+ container = /** @type {!MediaRouterContainerElement} */
+ ($('media-router-container'));
media_router.ui.setContainer(container);
- container.addEventListener('close-button-click', onCloseDialogClick);
+ container.addEventListener('acknowledge-first-run-flow',
+ onAcknowledgeFirstRunFlow);
+ container.addEventListener('back-click', onNavigateToSinkList);
+ container.addEventListener('cast-mode-selected', onCastModeSelected);
+ container.addEventListener('close-button-click', onCloseDialogEvent);
+ container.addEventListener('close-dialog', onCloseDialogEvent);
container.addEventListener('close-route-click', onCloseRouteClick);
container.addEventListener('create-route', onCreateRoute);
container.addEventListener('issue-action-click', onIssueActionClick);
+ container.addEventListener('join-route-click', onJoinRouteClick);
+ container.addEventListener('navigate-sink-list-to-details',
+ onNavigateToDetails);
+ container.addEventListener('navigate-to-cast-mode-list',
+ onNavigateToCastMode);
+ container.addEventListener('report-initial-action', onInitialAction);
+ container.addEventListener('report-initial-action-close',
+ onInitialActionClose);
+ container.addEventListener('report-sink-click-time',
+ onSinkClickTimeReported);
+ container.addEventListener('report-sink-count', onSinkCountReported);
+ container.addEventListener('show-initial-state', onShowInitialState);
+ container.addEventListener('sink-click', onSinkClick);
+
+ // Pressing the ESC key closes the dialog.
+ document.addEventListener('keydown', function(e) {
+ if (e.keyCode == KEYCODE_ESC) {
+ container.maybeReportUserFirstAction(
+ media_router.MediaRouterUserAction.CLOSE);
+ }
+ });
+ }
+
+ /**
+ * Reports the selected cast mode.
+ * Called when the user selects a cast mode from the picker.
+ *
+ * @param {!Event} event
+ * Parameters in |event|.detail:
+ * castModeType - type of cast mode selected by the user.
+ */
+ function onCastModeSelected(event) {
+ /** @type {{castModeType: number}} */
+ var detail = event.detail;
+ media_router.browserApi.reportSelectedCastMode(detail.castModeType);
+ }
+
+ /**
+ * Updates the preference that the user has seen the first run flow.
+ * Called when the user clicks on the acknowledgement button on the first run
+ * flow.
+ */
+ function onAcknowledgeFirstRunFlow() {
+ media_router.browserApi.acknowledgeFirstRunFlow();
}
/**
* Closes the dialog.
* Called when the user clicks the close button on the dialog.
*/
- function onCloseDialogClick() {
+ function onCloseDialogEvent() {
+ container.maybeReportUserFirstAction(
+ media_router.MediaRouterUserAction.CLOSE);
media_router.browserApi.closeDialog();
}
/**
+ * Reports the first action the user takes after opening the dialog.
+ * Called when the user explicitly interacts with the dialog to perform an
+ * action.
+ *
+ * @param {!Event} event
+ * Parameters in |event|.detail:
+ * action - the first action taken by the user.
+ */
+ function onInitialAction(event) {
+ /** @type {{action: number}} */
+ var detail = event.detail;
+ media_router.browserApi.reportInitialAction(detail.action);
+ }
+
+ /**
+ * Reports the time it took for the user to close the dialog if that was the
+ * first action the user took after opening the dialog.
+ * Called when the user closes the dialog without taking any other action.
+ *
+ * @param {!Event} event
+ * Parameters in |event|.detail:
+ * timeMs - time in ms for the user to close the dialog.
+ */
+ function onInitialActionClose(event) {
+ /** @type {{timeMs: number}} */
+ var detail = event.detail;
+ media_router.browserApi.reportTimeToInitialActionClose(detail.timeMs);
+ }
+
+ /**
* Acts on an issue and dismisses it from the UI.
* Called when the user performs an action on an issue.
*
- * @param {{detail: {id: string, actionType: number, helpPageId: number}}}
- * data
- * Parameters in |data|.detail:
+ * @param {!Event} event
+ * Parameters in |event|.detail:
* id - issue ID.
* actionType - type of action performed by the user.
* helpPageId - the numeric help center ID.
*/
- function onIssueActionClick(data) {
- media_router.browserApi.actOnIssue(data.detail.id,
- data.detail.actionType,
- data.detail.helpPageId);
+ function onIssueActionClick(event) {
+ /** @type {{id: string, actionType: number, helpPageId: number}} */
+ var detail = event.detail;
+ media_router.browserApi.actOnIssue(detail.id,
+ detail.actionType,
+ detail.helpPageId);
container.issue = null;
}
@@ -58,26 +148,130 @@ cr.define('media_router', function() {
* Creates a media route.
* Called when the user requests to create a media route.
*
- * @param {{detail: {sinkId: string, selectedCastModeValue: number}}} data
- * Parameters in |data|.detail:
+ * @param {!Event} event
+ * Parameters in |event|.detail:
* sinkId - sink ID selected by the user.
* selectedCastModeValue - cast mode selected by the user.
*/
- function onCreateRoute(data) {
- media_router.browserApi.requestRoute(data.detail.sinkId,
- data.detail.selectedCastModeValue);
+ function onCreateRoute(event) {
+ /** @type {{sinkId: string, selectedCastModeValue, number}} */
+ var detail = event.detail;
+ media_router.browserApi.requestRoute(detail.sinkId,
+ detail.selectedCastModeValue);
}
/**
* Stops a route.
* Called when the user requests to stop a media route.
*
- * @param {{detail: {route: string}}} data
- * Parameters in |data|.detail:
- * route - route ID.
+ * @param {!Event} event
+ * Parameters in |event|.detail:
+ * route - The route to close.
+ */
+ function onCloseRouteClick(event) {
+ /** @type {{route: !media_router.Route}} */
+ var detail = event.detail;
+ media_router.browserApi.closeRoute(detail.route);
+ }
+
+ /**
+ * Joins a route.
+ * Called when the user requests to join a media route.
+ *
+ * @param {!Event} event
+ * Parameters in |event|.detail:
+ * route - route to join.
+ */
+ function onJoinRouteClick(event) {
+ /** @type {{route: !media_router.Route}} */
+ var detail = event.detail;
+ media_router.browserApi.joinRoute(detail.route);
+ }
+
+ /**
+ * Reports the user navigation to the cast mode view.
+ * Called when the user clicks the drop arrow to navigate to the cast mode
+ * view on the dialog.
+ */
+ function onNavigateToCastMode() {
+ media_router.browserApi.reportNavigateToView(
+ media_router.MediaRouterView.CAST_MODE_LIST);
+ }
+
+ /**
+ * Reports the user navigation the route details view.
+ * Called when the user clicks on a sink to navigate to the route details
+ * view.
+ */
+ function onNavigateToDetails() {
+ media_router.browserApi.reportNavigateToView(
+ media_router.MediaRouterView.ROUTE_DETAILS);
+ }
+
+ /**
+ * Reports the user navigation the sink list view.
+ * Called when the user clicks on the back button from the route details view
+ * to the sink list view.
+ */
+ function onNavigateToSinkList() {
+ media_router.browserApi.reportNavigateToView(
+ media_router.MediaRouterView.SINK_LIST);
+ }
+
+ /**
+ * Reports the initial state of the dialog after it is opened.
+ * Called after initial data is populated.
+ *
+ * @param {!Event} event
+ * Parameters in |event|.detail:
+ * currentView - the current dialog's current view.
+ */
+ function onShowInitialState(event) {
+ /** @type {{currentView: string}} */
+ var detail = event.detail;
+ media_router.browserApi.reportInitialState(detail.currentView);
+ }
+
+ /**
+ * Reports the index of the sink that was clicked.
+ * Called when the user selects a sink on the sink list.
+ *
+ * @param {!Event} event
+ * Paramters in |event|.detail:
+ * index - the index of the clicked sink.
+ */
+ function onSinkClick(event) {
+ /** @type {{index: number}} */
+ var detail = event.detail;
+ media_router.browserApi.reportClickedSinkIndex(detail.index);
+ }
+
+ /**
+ * Reports the time it took for the user to select a sink to create a route
+ * after the list was popuated and shown.
+ *
+ * @param {!Event} event
+ * Paramters in |event|.detail:
+ * timeMs - the time it took for the user to select a sink.
+ */
+ function onSinkClickTimeReported(event) {
+ /** @type {{timeMs: number}} */
+ var detail = event.detail;
+ media_router.browserApi.reportTimeToClickSink(detail.timeMs);
+ }
+
+ /**
+ * Reports the current sink count.
+ * Called 3 seconds after the dialog is initially opened.
+ *
+ * @param {!Event} event
+ * Parameters in |event|.detail:
+ * sinkCount - the number of sinks.
*/
- function onCloseRouteClick(data) {
- media_router.browserApi.closeRoute(data.detail.route);
+ function onSinkCountReported(event) {
+ /** @type {{sinkCount: number}} */
+ var detail = event.detail;
+ media_router.browserApi.reportSinkCount(detail.sinkCount);
}
return {
diff --git a/chromium/chrome/browser/resources/media_router/media_router_common.css b/chromium/chrome/browser/resources/media_router/media_router_common.css
index 1de54a330c9..1d51985930d 100644
--- a/chromium/chrome/browser/resources/media_router/media_router_common.css
+++ b/chromium/chrome/browser/resources/media_router/media_router_common.css
@@ -7,3 +7,7 @@
cursor: pointer;
text-align: center;
}
+
+[hidden] {
+ display: none !important;
+} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/media_router/media_router_data.js b/chromium/chrome/browser/resources/media_router/media_router_data.js
index 9518a13dc26..f28ccd5db9c 100644
--- a/chromium/chrome/browser/resources/media_router/media_router_data.js
+++ b/chromium/chrome/browser/resources/media_router/media_router_data.js
@@ -4,44 +4,78 @@
// Any strings used here will already be localized. Values such as
// CastMode.type or IDs will be defined elsewhere and determined later.
-cr.define('media_router', function() {
- 'use strict';
- /**
- * This corresponds to the C++ MediaCastMode.
- * @enum {number}
- */
- var CastModeType = {
- DEFAULT: 0,
- TAB_MIRROR: 1,
- DESKTOP_MIRROR: 2,
- };
-
- /**
- * This corresponds to the C++ MediaSink IconType.
- * @enum {mumber}
- */
- var SinkIconType = {
- CAST: 0,
- CAST_AUDIO: 1,
- GENERIC: 2,
- HANGOUT: 3,
- };
-
- /**
- * @enum {string}
- */
- var SinkStatus = {
- IDLE: 'idle',
- ACTIVE: 'active',
- REQUEST_PENDING: 'request_pending'
- };
+cr.exportPath('media_router');
+
+/**
+ * This corresponds to the C++ MediaCastMode, with the exception of AUTO.
+ * See below for details. Note to support fast bitset operations, the values
+ * here are (1 << [corresponding value in MR]).
+ * @enum {number}
+ */
+media_router.CastModeType = {
+ // Note: AUTO mode is only used to configure the sink list container to show
+ // all sinks. Individual sinks are configured with a specific cast mode
+ // (DEFAULT, TAB_MIRROR, DESKTOP_MIRROR).
+ AUTO: -1,
+ DEFAULT: 0x1,
+ TAB_MIRROR: 0x2,
+ DESKTOP_MIRROR: 0x4,
+};
+
+/**
+ * This corresponds to the C++ MediaRouterMetrics MediaRouterUserAction.
+ * @enum {number}
+ */
+media_router.MediaRouterUserAction = {
+ CHANGE_MODE: 0,
+ START_LOCAL: 1,
+ STOP_LOCAL: 2,
+ CLOSE: 3,
+ STATUS_REMOTE: 4,
+};
+
+/**
+ * The possible states of the Media Router dialog. Used to determine which
+ * components to show.
+ * @enum {string}
+ */
+media_router.MediaRouterView = {
+ CAST_MODE_LIST: 'cast-mode-list',
+ FILTER: 'filter',
+ ISSUE: 'issue',
+ ROUTE_DETAILS: 'route-details',
+ SINK_LIST: 'sink-list',
+};
+
+/**
+ * This corresponds to the C++ MediaSink IconType.
+ * @enum {number}
+ */
+media_router.SinkIconType = {
+ CAST: 0,
+ CAST_AUDIO: 1,
+ CAST_AUDIO_GROUP: 2,
+ GENERIC: 3,
+ HANGOUT: 4,
+};
+
+/**
+ * @enum {string}
+ */
+media_router.SinkStatus = {
+ IDLE: 'idle',
+ ACTIVE: 'active',
+ REQUEST_PENDING: 'request_pending'
+};
+cr.define('media_router', function() {
+ 'use strict';
/**
- * @param {media_router.CastModeType} type The type of cast mode.
+ * @param {number} type The type of cast mode.
* @param {string} description The description of the cast mode.
- * @param {string} host The hostname of the site to cast.
+ * @param {?string} host The hostname of the site to cast.
* @constructor
* @struct
*/
@@ -52,10 +86,16 @@ cr.define('media_router', function() {
/** @type {string} */
this.description = description;
- /** @type {string} */
+ /** @type {?string} */
this.host = host || null;
};
+ /**
+ * Placeholder object for AUTO cast mode. See comment in CastModeType.
+ * @const {!media_router.CastMode}
+ */
+ var AUTO_CAST_MODE = new CastMode(media_router.CastModeType.AUTO,
+ loadTimeData.getString('autoCastMode'), null);
/**
* @param {string} id The ID of this issue.
@@ -106,12 +146,13 @@ cr.define('media_router', function() {
* @param {?number} tabId The ID of the tab in which web app is running and
* accessing the route.
* @param {boolean} isLocal True if this is a locally created route.
+ * @param {boolean} canJoin True if this route can be joined.
* @param {?string} customControllerPath non-empty if this route has custom
* controller.
* @constructor
* @struct
*/
- var Route = function(id, sinkId, description, tabId, isLocal,
+ var Route = function(id, sinkId, description, tabId, isLocal, canJoin,
customControllerPath) {
/** @type {string} */
this.id = id;
@@ -128,6 +169,9 @@ cr.define('media_router', function() {
/** @type {boolean} */
this.isLocal = isLocal;
+ /** @type {boolean} */
+ this.canJoin = canJoin;
+
/** @type {?string} */
this.customControllerPath = customControllerPath;
};
@@ -136,32 +180,36 @@ cr.define('media_router', function() {
/**
* @param {string} id The ID of the media sink.
* @param {string} name The name of the sink.
+ * @param {?string} description Optional description of the sink.
+ * @param {?string} domain Optional domain of the sink.
* @param {media_router.SinkIconType} iconType the type of icon for the sink.
* @param {media_router.SinkStatus} status The readiness state of the sink.
- * @param {!Array<number>} castModes Cast modes compatible with the sink.
- * @param {boolean} isLaunching True if the Media Router is creating a route
- * to this sink.
+ * @param {number} castModes Bitset of cast modes compatible with the sink.
* @constructor
* @struct
*/
- var Sink = function(id, name, iconType, status, castModes, isLaunching) {
+ var Sink = function(id, name, description, domain, iconType, status,
+ castModes) {
/** @type {string} */
this.id = id;
/** @type {string} */
this.name = name;
- /** @type {SinkIconType} */
+ /** @type {?string} */
+ this.description = description;
+
+ /** @type {?string} */
+ this.domain = domain;
+
+ /** @type {!media_router.SinkIconType} */
this.iconType = iconType;
- /** @type {media_router.SinkStatus} */
+ /** @type {!media_router.SinkStatus} */
this.status = status;
- /** @type {!Array<number>} */
+ /** @type {number} */
this.castModes = castModes;
-
- /** @type {boolean} */
- this.isLaunching = isLaunching;
};
@@ -180,9 +228,7 @@ cr.define('media_router', function() {
};
return {
- CastModeType: CastModeType,
- SinkIconType: SinkIconType,
- SinkStatus: SinkStatus,
+ AUTO_CAST_MODE: AUTO_CAST_MODE,
CastMode: CastMode,
Issue: Issue,
Route: Route,
diff --git a/chromium/chrome/browser/resources/media_router/media_router_ui_interface.js b/chromium/chrome/browser/resources/media_router/media_router_ui_interface.js
index 3a4faf80995..fb53eff2293 100644
--- a/chromium/chrome/browser/resources/media_router/media_router_ui_interface.js
+++ b/chromium/chrome/browser/resources/media_router/media_router_ui_interface.js
@@ -11,6 +11,13 @@ cr.define('media_router.ui', function() {
var container = null;
/**
+ * Handles timeout of previous create route attempt.
+ */
+ function onNotifyRouteCreationTimeout() {
+ container.onNotifyRouteCreationTimeout();
+ }
+
+ /**
* Handles response of previous create route attempt.
*
* @param {string} sinkId The ID of the sink to which the Media Route was
@@ -43,27 +50,27 @@ cr.define('media_router.ui', function() {
/**
* Populates the WebUI with data obtained from Media Router.
*
- * @param {headerText: string,
- * headerTextTooltip: string,
- * deviceMissingUrl: string,
- * sinks: !Array<!media_router.Sink>,
- * routes: !Array<!media_router.Route>,
- * castModes: !Array<!media_router.CastMode>} data
+ * @param {{deviceMissingUrl: string,
+ * sinks: !Array<!media_router.Sink>,
+ * routes: !Array<!media_router.Route>,
+ * castModes: !Array<!media_router.CastMode>,
+ * wasFirstRunFlowAcknowledged: boolean}} data
* Parameters in data:
- * headerText - text to be displayed in the header of the WebUI.
- * headerTextTooltip - tooltip to be displayed for the header of the WebUI.
* deviceMissingUrl - url to be opened on "Device missing?" clicked.
* sinks - list of sinks to be displayed.
* routes - list of routes that are associated with the sinks.
* castModes - list of available cast modes.
+ * wasFirstRunFlowAcknowledged - true if first run flow was previously
+ * acknowledged by user.
*/
function setInitialData(data) {
- container.headerText = data['headerText'];
- container.headerTextTooltip = data['headerTextTooltip'];
container.deviceMissingUrl = data['deviceMissingUrl'];
- container.sinkList = data['sinks'];
- container.routeList = data['routes'];
container.castModeList = data['castModes'];
+ container.allSinks = data['sinks'];
+ container.routeList = data['routes'];
+ container.showFirstRunFlow = !data['wasFirstRunFlowAcknowledged'];
+ container.maybeShowRouteDetailsOnOpen();
+ media_router.browserApi.onInitialDataReceived();
}
/**
@@ -91,10 +98,20 @@ cr.define('media_router.ui', function() {
* @param {!Array<!media_router.Sink>} sinkList
*/
function setSinkList(sinkList) {
- container.sinkList = sinkList;
+ container.allSinks = sinkList;
+ }
+
+ /**
+ * Updates the max height of the dialog
+ *
+ * @param {number} height
+ */
+ function updateMaxHeight(height) {
+ container.updateMaxSinkListHeight(height);
}
return {
+ onNotifyRouteCreationTimeout: onNotifyRouteCreationTimeout,
onCreateRouteResponseReceived: onCreateRouteResponseReceived,
setCastModeList: setCastModeList,
setContainer: setContainer,
@@ -102,6 +119,7 @@ cr.define('media_router.ui', function() {
setIssue: setIssue,
setRouteList: setRouteList,
setSinkList: setSinkList,
+ updateMaxHeight: updateMaxHeight,
};
});
@@ -110,6 +128,13 @@ cr.define('media_router.browserApi', function() {
'use strict';
/**
+ * Indicates that the user has acknowledged the first run flow.
+ */
+ function acknowledgeFirstRunFlow() {
+ chrome.send('acknowledgeFirstRunFlow');
+ }
+
+ /**
* Acts on the given issue.
*
* @param {string} issueId
@@ -134,7 +159,97 @@ cr.define('media_router.browserApi', function() {
* @param {!media_router.Route} route
*/
function closeRoute(route) {
- chrome.send('closeRoute', [{routeId: route.id}]);
+ chrome.send('closeRoute', [{routeId: route.id, isLocal: route.isLocal}]);
+ }
+
+ /**
+ * Joins the given route.
+ *
+ * @param {!media_router.Route} route
+ */
+ function joinRoute(route) {
+ chrome.send('joinRoute', [{sinkId: route.sinkId, routeId: route.id}]);
+ }
+
+ /**
+ * Indicates that the initial data has been received.
+ */
+ function onInitialDataReceived() {
+ chrome.send('onInitialDataReceived');
+ }
+
+ /**
+ * Reports the index of the selected sink.
+ *
+ * @param {number} sinkIndex
+ */
+ function reportClickedSinkIndex(sinkIndex) {
+ chrome.send('reportClickedSinkIndex', [sinkIndex]);
+ }
+
+ /**
+ * Reports the initial dialog view.
+ *
+ * @param {string} view
+ */
+ function reportInitialState(view) {
+ chrome.send('reportInitialState', [view]);
+ }
+
+ /**
+ * Reports the initial action the user took.
+ *
+ * @param {number} action
+ */
+ function reportInitialAction(action) {
+ chrome.send('reportInitialAction', [action]);
+ }
+
+ /**
+ * Reports the navigation to the specified view.
+ *
+ * @param {string} view
+ */
+ function reportNavigateToView(view) {
+ chrome.send('reportNavigateToView', [view]);
+ }
+
+ /**
+ * Reports the cast mode that the user selected.
+ *
+ * @param {number} castModeType
+ */
+ function reportSelectedCastMode(castModeType) {
+ chrome.send('reportSelectedCastMode', [castModeType]);
+ }
+
+ /**
+ * Reports the current number of sinks.
+ *
+ * @param {number} sinkCount
+ */
+ function reportSinkCount(sinkCount) {
+ chrome.send('reportSinkCount', [sinkCount]);
+ }
+
+ /**
+ * Reports the time it took for the user to select a sink after the sink list
+ * is populated and shown.
+ *
+ * @param {number} timeMs
+ */
+ function reportTimeToClickSink(timeMs) {
+ chrome.send('reportTimeToClickSink', [timeMs]);
+ }
+
+ /**
+ * Reports the time, in ms, it took for the user to close the dialog without
+ * taking any other action.
+ *
+ * @param {number} timeMs
+ */
+ function reportTimeToInitialActionClose(timeMs) {
+ chrome.send('reportTimeToInitialActionClose', [timeMs]);
}
/**
@@ -150,7 +265,7 @@ cr.define('media_router.browserApi', function() {
*
* @param {string} sinkId The sink ID.
* @param {number} selectedCastMode The value of the cast mode the user
- * selected, or -1 if the user has not explicitly selected a mode.
+ * selected.
*/
function requestRoute(sinkId, selectedCastMode) {
chrome.send('requestRoute',
@@ -158,9 +273,20 @@ cr.define('media_router.browserApi', function() {
}
return {
+ acknowledgeFirstRunFlow: acknowledgeFirstRunFlow,
actOnIssue: actOnIssue,
closeDialog: closeDialog,
closeRoute: closeRoute,
+ joinRoute: joinRoute,
+ onInitialDataReceived: onInitialDataReceived,
+ reportClickedSinkIndex: reportClickedSinkIndex,
+ reportInitialAction: reportInitialAction,
+ reportInitialState: reportInitialState,
+ reportNavigateToView: reportNavigateToView,
+ reportSelectedCastMode: reportSelectedCastMode,
+ reportSinkCount: reportSinkCount,
+ reportTimeToClickSink: reportTimeToClickSink,
+ reportTimeToInitialActionClose: reportTimeToInitialActionClose,
requestInitialData: requestInitialData,
requestRoute: requestRoute,
};
diff --git a/chromium/chrome/browser/resources/net_internals/hsts_view.html b/chromium/chrome/browser/resources/net_internals/hsts_view.html
index 7a64ad18074..cc4f2e54fb6 100644
--- a/chromium/chrome/browser/resources/net_internals/hsts_view.html
+++ b/chromium/chrome/browser/resources/net_internals/hsts_view.html
@@ -7,9 +7,9 @@
<!-- HSTS tab -->
<div id=hsts-view-tab-content class=content-box>
<div class=deindent-header>
- HSTS is HTTPS Strict Transport Security: a way for sites to elect to
- always use HTTPS. See <a href="http://dev.chromium.org/sts" target=_blank>
- http://dev.chromium.org/sts</a>.</div>
+ HSTS is HTTP Strict Transport Security: a way for sites to elect to
+ always use HTTPS. See <a href="https://www.chromium.org/hsts" target=_blank>
+ https://www.chromium.org/hsts</a>.</div>
<!-- This UI allows a user to query and update the browser's list of
HSTS domains. -->
@@ -23,7 +23,7 @@
<label>Include subdomains for STS: <input type="checkbox" id=hsts-view-check-sts-input></label><br>
<label>Include subdomains for PKP: <input type="checkbox" id=hsts-view-check-pkp-input></label><br>
<label>Public key fingerprints: <input type=text id=hsts-view-add-pins style="width: 25em; max-width: 100%;"></label><br>
- <p style="font-size: small; color: #767676; font-style: italic; margin-left: 2em; max-width: 40em; max-width: 100%;">(public key fingerprints are comma separated and consist of the hash function followed by a foreslash and the base64 encoded fingerprint, for example <tt>sha1/Guzek9lMwR3KeIS8wwS9gBvVtIg=</tt>)</p>
+ <p style="font-size: small; color: #767676; font-style: italic; margin-left: 2em; max-width: 40em; max-width: 100%;">(public key fingerprints are comma separated and consist of the hash function followed by a foreslash and the base64 encoded fingerprint, for example <tt>sha256/7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</tt>)</p>
<input type=submit value="Add" id=hsts-view-add-submit>
</form>
diff --git a/chromium/chrome/browser/resources/net_internals/import_view.html b/chromium/chrome/browser/resources/net_internals/import_view.html
index cae43304d72..452ec1d863f 100644
--- a/chromium/chrome/browser/resources/net_internals/import_view.html
+++ b/chromium/chrome/browser/resources/net_internals/import_view.html
@@ -56,7 +56,7 @@
</td>
</tr>
<tr>
- <th>OS type</th>
+ <th>OS info</th>
<td jscontent="constants.clientInfo.os_type"></td>
</tr>
<tr>
diff --git a/chromium/chrome/browser/resources/net_internals/log_util.js b/chromium/chrome/browser/resources/net_internals/log_util.js
index 5438c648510..2ca415e0a4f 100644
--- a/chromium/chrome/browser/resources/net_internals/log_util.js
+++ b/chromium/chrome/browser/resources/net_internals/log_util.js
@@ -34,7 +34,7 @@ log_util = (function() {
function createLogDump(userComments, constants, events, polledData, tabData,
numericDate, privacyStripping) {
if (privacyStripping)
- events = events.map(stripCookiesAndLoginInfo);
+ events = events.map(stripPrivacyInfo);
var logDump = {
'userComments': userComments,
diff --git a/chromium/chrome/browser/resources/net_internals/log_view_painter.js b/chromium/chrome/browser/resources/net_internals/log_view_painter.js
index bbfaae415bc..5969699e9ad 100644
--- a/chromium/chrome/browser/resources/net_internals/log_view_painter.js
+++ b/chromium/chrome/browser/resources/net_internals/log_view_painter.js
@@ -6,7 +6,7 @@
var createLogEntryTablePrinter;
var proxySettingsToString;
-var stripCookiesAndLoginInfo;
+var stripPrivacyInfo;
// Start of anonymous namespace.
(function() {
@@ -244,7 +244,7 @@ var ParameterOutputter = (function() {
function writeParameters(entry, privacyStripping, out) {
if (privacyStripping) {
// If privacy stripping is enabled, remove data as needed.
- entry = stripCookiesAndLoginInfo(entry);
+ entry = stripPrivacyInfo(entry);
} else {
// If headers are in an object, convert them to an array for better display.
entry = reformatHeaders(entry);
@@ -479,6 +479,9 @@ function reformatHeaders(entry) {
* Removes a cookie or unencrypted login information from a single HTTP header
* line, if present, and returns the modified line. Otherwise, just returns
* the original line.
+ *
+ * Note: this logic should be kept in sync with
+ * net::ElideHeaderValueForNetLog in net/http/http_log_util.cc.
*/
function stripCookieOrLoginInfo(line) {
var patterns = [
@@ -545,16 +548,40 @@ function stripCookieOrLoginInfo(line) {
}
/**
+ * Remove debug data from HTTP/2 GOAWAY frame due to privacy considerations, see
+ * https://httpwg.github.io/specs/rfc7540.html#GOAWAY.
+ *
+ * Note: this logic should be kept in sync with
+ * net::ElideGoAwayDebugDataForNetLog in net/http/http_log_util.cc.
+ */
+function stripGoAwayDebugData(value) {
+ return '[' + value.length + ' bytes were stripped]';
+}
+
+/**
* If |entry| has headers, returns a copy of |entry| with all cookie and
* unencrypted login text removed. Otherwise, returns original |entry| object.
* This is needed so that JSON log dumps can be made without affecting the
* source data. Converts headers stored in objects to arrays.
- *
- * Note: this logic should be kept in sync with
- * net::ElideHeaderForNetLog in net/http/http_log_util.cc.
*/
-stripCookiesAndLoginInfo = function(entry) {
- if (!entry.params || entry.params.headers === undefined ||
+stripPrivacyInfo = function(entry) {
+ if (!entry.params) {
+ return entry;
+ }
+
+ if (entry.type == EventType.HTTP2_SESSION_GOAWAY &&
+ entry.params.debug_data != undefined) {
+ // Duplicate the top level object, and |entry.params|. All other fields are
+ // just pointers to the original values, as they won't be modified, other
+ // than |entry.params.debug_data|.
+ entry = shallowCloneObject(entry);
+ entry.params = shallowCloneObject(entry.params);
+ entry.params.debug_data =
+ stripGoAwayDebugData(entry.params.debug_data);
+ return entry;
+ }
+
+ if (entry.params.headers === undefined ||
!(entry.params.headers instanceof Object)) {
return entry;
}
diff --git a/chromium/chrome/browser/resources/net_internals/quic_view.html b/chromium/chrome/browser/resources/net_internals/quic_view.html
index 2b3f8000d9f..df6d9432a19 100644
--- a/chromium/chrome/browser/resources/net_internals/quic_view.html
+++ b/chromium/chrome/browser/resources/net_internals/quic_view.html
@@ -8,8 +8,18 @@
TODO(bnc): Deprecate around 2016 January. --!>
<li>Alternative Service Probability Threshold: <span jscontent="$this.alternative_service_probability_threshold || $this.alternate_protocol_probability_threshold"></span></li>
<li>Origin To Force QUIC On: <span jscontent="origin_to_force_quic_on"></span></li>
- <li>QUIC connection options: <span jscontent="connection_options"></span></li>
+ <li>Connection options: <span jscontent="connection_options"></span></li>
<li>Consistent Port Selection Enabled: <span jscontent="!!enable_quic_port_selection"></span></li>
+ <li>Load Server Info Timeout Multiplier: <span jscontent="$this.load_server_info_timeout_srtt_multiplier"></span></li>
+ <li>Enable Connection Racing: <span jscontent="!!enable_connection_racing"></span></li>
+ <li>Disable Disk Cache: <span jscontent="!!disable_disk_cache"></span></li>
+ <li>Prefer AES: <span jscontent="!!prefer_aes"></span></li>
+ <li>Maximum Number Of Lossy Connections: <span jscontent="$this.max_number_of_lossy_connections"></span></li>
+ <li>Packet Loss Threshold: <span jscontent="$this.packet_loss_threshold"></span></li>
+ <li>Delay TCP Race: <span jscontent="!!delay_tcp_race"></span></li>
+ <li>Store Server Configs In Properties File: <span jscontent="!!store_server_configs_in_properties"></span></li>
+ <li>Idle Connection Timeout In Seconds: <span jscontent="$this.idle_connection_timeout_seconds"></span></li>
+ <li>Disable PreConnect If 0RTT: <span jscontent="$this.disable_preconnect_if_0rtt"></span></li>
<li jsdisplay="$this.disabled_reason && disabled_reason.length > 0">QUIC dynamically disabled: <span jscontent="disabled_reason"></span></li>
</ul>
diff --git a/chromium/chrome/browser/resources/net_internals/spdy_view.html b/chromium/chrome/browser/resources/net_internals/spdy_view.html
index 63015fab272..ca314769b60 100644
--- a/chromium/chrome/browser/resources/net_internals/spdy_view.html
+++ b/chromium/chrome/browser/resources/net_internals/spdy_view.html
@@ -6,7 +6,12 @@
support importing netlog json files from earlier browsers.
TODO(bnc): Deprecate around 2016 February. -->
<li>Use Alternative Service: <span jscontent="$this.use_alternative_services == undefined ? $this.use_alternate_protocols : $this.use_alternative_services"></span></li>
- <li>Next Protocols: <span jscontent="next_protos"></span></li>
+ <!-- "alpn_protos" and "npn_protos" are used here since release 48, see
+ https://crrev.com/1387363004. "next_protos" is here to support
+ importing netlog json files from earlier browsers.
+ TODO(bnc): Deprecate around 2016 April. -->
+ <li>ALPN Protocols: <span jscontent="$this.alpn_protos || $this.next_protos"></span></li>
+ <li>NPN Protocols: <span jscontent="$this.npn_protos || $this.next_protos"></span></li>
</ul>
<h4>HTTP/2 sessions</h4>
@@ -84,11 +89,7 @@
<tbody>
<tr jsselect="spdyAlternateProtocolMappings">
<td jscontent="host_port_pair"></td>
- <!-- "alternative_service" is used since release 43, see
- https://crrev.com/1043973002. "alternate_protocol" is here
- to support importing netlog json files from earlier browsers.
- TODO(bnc): Deprecate around 2015 October. -->
- <td jscontent="$this.alternative_service || $this.alternate_protocol"></td>
+ <td jscontent="alternative_service"></td>
</tr>
</tbody>
</table>
diff --git a/chromium/chrome/browser/resources/net_internals/view.js b/chromium/chrome/browser/resources/net_internals/view.js
index ab2db5a773e..05e538f1c5a 100644
--- a/chromium/chrome/browser/resources/net_internals/view.js
+++ b/chromium/chrome/browser/resources/net_internals/view.js
@@ -193,7 +193,8 @@ var WindowView = (function() {
},
resetGeometry: function() {
- this.setGeometry(0, 0, window.innerWidth, window.innerHeight);
+ this.setGeometry(0, 0, document.documentElement.clientWidth,
+ document.documentElement.clientHeight);
}
};
diff --git a/chromium/chrome/browser/resources/ntp4/apps_page.js b/chromium/chrome/browser/resources/ntp4/apps_page.js
index 8136080e008..647ec829aa0 100644
--- a/chromium/chrome/browser/resources/ntp4/apps_page.js
+++ b/chromium/chrome/browser/resources/ntp4/apps_page.js
@@ -295,7 +295,7 @@ cr.define('ntp', function() {
this.addEventListener('mousedown', this.onMousedown_, true);
this.addEventListener('keydown', this.onKeydown_);
- this.addEventListener('keyup', this.onKeyup_);
+ this.addEventListener('blur', this.onBlur_);
},
/**
@@ -378,6 +378,11 @@ cr.define('ntp', function() {
this.style.top = toCssPx(y);
},
+ onBlur_: function(e) {
+ this.classList.remove('click-focus');
+ this.appContents_.classList.remove('suppress-active');
+ },
+
/**
* Invoked when an app is clicked.
* @param {Event} e The click event.
@@ -410,33 +415,6 @@ cr.define('ntp', function() {
e.preventDefault();
e.stopPropagation();
}
- this.onKeyboardUsed_(e.keyCode);
- },
-
- /**
- * Invoked when the user releases a key while the app is focused.
- * @param {Event} e The key event.
- * @private
- */
- onKeyup_: function(e) {
- this.onKeyboardUsed_(e.keyCode);
- },
-
- /**
- * Called when the keyboard has been used (key down or up). The .click-focus
- * hack is removed if the user presses a key that can change focus.
- * @param {number} keyCode The key code of the keyboard event.
- * @private
- */
- onKeyboardUsed_: function(keyCode) {
- switch (keyCode) {
- case 9: // Tab.
- case 37: // Left arrow.
- case 38: // Up arrow.
- case 39: // Right arrow.
- case 40: // Down arrow.
- this.classList.remove('click-focus');
- }
},
/**
diff --git a/chromium/chrome/browser/resources/ntp4/guest_tab.css b/chromium/chrome/browser/resources/ntp4/guest_tab.css
index ae24211242a..b3912c8c22f 100644
--- a/chromium/chrome/browser/resources/ntp4/guest_tab.css
+++ b/chromium/chrome/browser/resources/ntp4/guest_tab.css
@@ -2,30 +2,6 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-body {
- margin: 10px 8px;
-}
-
-.icon {
- -webkit-margin-end: 3px;
- -webkit-margin-start: 6px;
-}
-
-html[dir='ltr'] .icon {
- float: right;
-}
-
-html[dir='rtl'] .icon {
- float: left;
-}
-
-.content {
- background-color: #eee;
- border-radius: 5px;
- color: black;
- margin-left: auto;
- margin-right: auto;
- margin-top: 66px;
- max-width: 600px;
- padding: 10px;
+a {
+ color: rgb(51, 103, 214);
}
diff --git a/chromium/chrome/browser/resources/ntp4/guest_tab.html b/chromium/chrome/browser/resources/ntp4/guest_tab.html
index 9c1150a09e6..704140ab1ef 100644
--- a/chromium/chrome/browser/resources/ntp4/guest_tab.html
+++ b/chromium/chrome/browser/resources/ntp4/guest_tab.html
@@ -4,28 +4,17 @@
<meta charset="utf-8">
<title i18n-content="title"></title>
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
+<link rel="stylesheet" href="guest_tab.css">
<link rel="stylesheet" href="incognito_and_guest_tab.css">
-<script>
-// Until themes can clear the cache, force-reload the theme stylesheet.
-document.write('<link id="guestthemecss" rel="stylesheet" ' +
- 'href="chrome://theme/css/incognito_new_tab_theme.css?' +
- Date.now() + '">');
-</script>
</head>
<body>
<div class="content">
<h1 i18n-content="guestTabHeading"></h1>
<p>
<span i18n-content="guestTabDescription"></span>
- <a i18n-content="learnMore" i18n-values=".href:learnMoreLink"></a>
</p>
+ <a i18n-content="learnMore" i18n-values=".href:learnMoreLink"></a>
</div>
</body>
<script src="chrome://resources/js/cr.js"></script>
-<script>
-function themeChanged() {
- document.getElementById('guestthemecss').href =
- 'chrome://theme/css/incognito_new_tab_theme.css?' + Date.now();
-}
-</script>
</html>
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 5ba37137c8b..90e52d921d9 100644
--- a/chromium/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
+++ b/chromium/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
@@ -5,24 +5,22 @@
* Incognito and guest mode NTP shared CSS.
*/
-html {
- background: #fafafa;
+h1 {
+ font-size: 200%;
+ font-weight: 300;
+ margin-bottom: 1.33em;
}
-body {
+p {
line-height: 1.5;
-}
-
-h1 {
- font-size: 1.7em;
- font-weight: normal;
- line-height: 1.2em;
- margin-top: 0;
+ margin-bottom: 2em;
+ text-align: start;
}
a {
- color: rgb(39, 110, 242);
+ font-size: 108.3%;
text-decoration: none;
+ text-transform: uppercase;
}
a:hover {
@@ -30,24 +28,21 @@ a:hover {
}
.content {
- background-color: white;
- border-radius: 2px;
- box-shadow: 0 4px 6px 1px rgba(50, 50, 50, 0.14);
box-sizing: border-box;
- color: black;
- line-height: 1.5;
- margin: 5.5em auto 0;
- max-width: 640px;
- padding: 30px 35px 30px 37px;
- width: 100%;
+ margin: 3.5em auto 0;
+ max-width: 420px;
+ min-width: 240px;
+ padding: 30px 35px;
+ text-align: center;
}
-.content > span {
- display: block;
+html[hascustombackground='true'] .content {
+ border-radius: 2px;
+ box-shadow: 0 4px 6px 1px rgba(0, 0, 0, 0.4);
}
-.content p:last-child {
- margin-bottom: 4px;
+.content > span {
+ display: block;
}
@media (max-width:700px) {
@@ -60,6 +55,11 @@ a:hover {
body {
margin: 3em 1.5em 2em;
}
+
+ /* Adjustment for narrow screen to prevent horizontal scrollbar. */
+ .content {
+ padding: 16px 8px;
+ }
}
@media (max-height:480px) and (max-width:400px) {
diff --git a/chromium/chrome/browser/resources/ntp4/incognito_tab.css b/chromium/chrome/browser/resources/ntp4/incognito_tab.css
index c836f2d323d..6994b2cb0ac 100644
--- a/chromium/chrome/browser/resources/ntp4/incognito_tab.css
+++ b/chromium/chrome/browser/resources/ntp4/incognito_tab.css
@@ -2,30 +2,28 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-.content > span {
- max-width: 416px;
+body {
+ margin-top: 0;
+}
+
+.content {
+ background-color: #323232;
+ color: white;
}
.icon {
- -webkit-margin-start: 25px;
- content: -webkit-image-set(
- url(../../../../ui/webui/resources/images/incognito_icon.png) 1x,
- url(../../../../ui/webui/resources/images/2x/incognito_icon.png) 2x);
- float: right;
- height: 128px;
- margin-bottom: 10px;
- margin-top: 4px;
- width: 128px;
+ content: url(../../../../ui/webui/resources/images/incognito_splash.svg);
+ display: inline-block;
+ height: 120px;
+ width: 120px;
}
-html[dir='rtl'] .icon {
- float: left;
+h1 {
+ margin-top: 1em;
}
-@media (max-width:400px) {
- .icon {
- -webkit-margin-start: 15px;
- height: 96px;
- width: 96px;
- }
+a {
+ color: rgb(3, 169, 244);
+ display: inline-block;
+ padding: 10.5px 12px;
}
diff --git a/chromium/chrome/browser/resources/ntp4/incognito_tab.html b/chromium/chrome/browser/resources/ntp4/incognito_tab.html
index 276d854b1d9..4b19819a5d3 100644
--- a/chromium/chrome/browser/resources/ntp4/incognito_tab.html
+++ b/chromium/chrome/browser/resources/ntp4/incognito_tab.html
@@ -1,11 +1,13 @@
<!doctype html>
<html i18n-values="dir:textdirection;
+ hascustombackground:hasCustomBackground;
bookmarkbarattached:bookmarkbarattached;
lang:language">
<head>
<meta charset="utf-8">
<title i18n-content="title"></title>
-<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
+<meta name="viewport" content="width=device-width">
+<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
<link rel="stylesheet" href="incognito_and_guest_tab.css">
<link rel="stylesheet" href="incognito_tab.css">
<script>
@@ -21,13 +23,13 @@ document.write('<link id="incognitothemecss" rel="stylesheet" ' +
<span>
<h1 i18n-content="incognitoTabHeading"></h1>
<p>
- <span i18n-values=".innerHTML:incognitoTabDescription"></span>
- <a i18n-content="learnMore" i18n-values=".href:learnMoreLink"></a>
+ <span i18n-content="incognitoTabDescription"></span>
</p>
<p>
- <strong i18n-content="incognitoTabWarning"></strong>
+ <span i18n-content="incognitoTabWarning"></span>
</p>
</span>
+ <a i18n-content="learnMore" i18n-values=".href:learnMoreLink"></a>
</div>
</body>
<script src="chrome://resources/js/cr.js"></script>
@@ -42,7 +44,10 @@ cr.define('ntp', function() {
document.documentElement.setAttribute('bookmarkbarattached', !!attached);
}
- function themeChanged() {
+ /** @param {!{hasCustomBackground: boolean}} themeData */
+ function themeChanged(themeData) {
+ document.documentElement.setAttribute('hascustombackground',
+ themeData.hasCustomBackground);
document.getElementById('incognitothemecss').href =
'chrome://theme/css/incognito_new_tab_theme.css?' + Date.now();
}
diff --git a/chromium/chrome/browser/resources/ntp4/new_incognito_tab_theme.css b/chromium/chrome/browser/resources/ntp4/new_incognito_tab_theme.css
index dd31189d503..496b95b99f8 100644
--- a/chromium/chrome/browser/resources/ntp4/new_incognito_tab_theme.css
+++ b/chromium/chrome/browser/resources/ntp4/new_incognito_tab_theme.css
@@ -6,17 +6,20 @@
html {
background-attachment: fixed;
background-color: ${colorBackground};
- background-image: url(chrome://theme/IDR_THEME_NTP_BACKGROUND?${themeId});
background-position: ${backgroundBarDetached};
background-repeat: ${backgroundTiling};
height: 100%;
overflow: auto;
}
-#attribution-img {
- content: url(chrome://theme/IDR_THEME_NTP_ATTRIBUTION?${themeId});
+html[hascustombackground='true'] {
+ background-image: url(chrome://theme/IDR_THEME_NTP_BACKGROUND?${themeId});
}
html[bookmarkbarattached='true'] {
background-position: ${backgroundBarAttached};
}
+
+#attribution-img {
+ content: url(chrome://theme/IDR_THEME_NTP_ATTRIBUTION?${themeId});
+}
diff --git a/chromium/chrome/browser/resources/ntp4/new_tab.js b/chromium/chrome/browser/resources/ntp4/new_tab.js
index cb0c42dc9d0..d219ad73b56 100644
--- a/chromium/chrome/browser/resources/ntp4/new_tab.js
+++ b/chromium/chrome/browser/resources/ntp4/new_tab.js
@@ -333,8 +333,10 @@ 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() {
+ function themeChanged(opt_themeData) {
$('themecss').href = 'chrome://theme/css/new_tab_theme.css?' + Date.now();
}
diff --git a/chromium/chrome/browser/resources/ntp4/tile_page.js b/chromium/chrome/browser/resources/ntp4/tile_page.js
index f20d0f36a28..6cda72cff2e 100644
--- a/chromium/chrome/browser/resources/ntp4/tile_page.js
+++ b/chromium/chrome/browser/resources/ntp4/tile_page.js
@@ -703,12 +703,8 @@ cr.define('ntp', function() {
Array.prototype.indexOf.call(this.focusableElements_,
focusable);
this.updateFocusElement_();
- } else {
- // This prevents the tile page from getting focus when the user clicks
- // inside the grid but outside of any tile.
- e.preventDefault();
}
- },
+ },
/**
* Handle arrow key focus nav.
diff --git a/chromium/chrome/browser/resources/options/OWNERS b/chromium/chrome/browser/resources/options/OWNERS
index 4b65fc20160..534d4015fa9 100644
--- a/chromium/chrome/browser/resources/options/OWNERS
+++ b/chromium/chrome/browser/resources/options/OWNERS
@@ -1,4 +1,3 @@
dbeam@chromium.org
estade@chromium.org
-jhawkins@chromium.org
stevenjb@chromium.org
diff --git a/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js b/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js
index 85675d57c1f..43049212de4 100644
--- a/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js
+++ b/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js
@@ -66,8 +66,8 @@ cr.define('options', function() {
this.guid_ = '';
this.populateCountryList_();
- this.rebuildInputFields_(
- loadTimeData.getValue('autofillDefaultCountryComponents'));
+ this.rebuildInputFields_(/** @type {Array<Array<Object>>} */(
+ loadTimeData.getValue('autofillDefaultCountryComponents')));
this.languageCode_ =
loadTimeData.getString('autofillDefaultCountryLanguageCode');
this.connectInputEvents_();
diff --git a/chromium/chrome/browser/resources/options/autofill_options.html b/chromium/chrome/browser/resources/options/autofill_options.html
index e018c505e7e..cf33636bb89 100644
--- a/chromium/chrome/browser/resources/options/autofill_options.html
+++ b/chromium/chrome/browser/resources/options/autofill_options.html
@@ -2,14 +2,6 @@
<div class="close-button"></div>
<h1 i18n-content="autofillOptionsPage"></h1>
<div class="content-area">
- <!-- TODO(estade): This checkbox shouldn't show if you're not signed into
- sync. Or perhaps it should show with a link to go sign in with sync?
- -->
- <div id="autofill-wallet-setting-area" class="checkbox">
- <label>
- <input pref="autofill.wallet_import_enabled" type="checkbox">
- <span i18n-content="autofillWalletOption"></span>
- </div>
<h3 i18n-content="autofillAddresses"></h3>
<div class="settings-list">
<list id="address-list"></list>
diff --git a/chromium/chrome/browser/resources/options/autofill_options.js b/chromium/chrome/browser/resources/options/autofill_options.js
index bea6a1a3b64..7f300006b80 100644
--- a/chromium/chrome/browser/resources/options/autofill_options.js
+++ b/chromium/chrome/browser/resources/options/autofill_options.js
@@ -76,9 +76,6 @@ cr.define('options', function() {
return true; // Always follow the href
};
- this.walletIntegrationAvailableStateChanged_(
- loadTimeData.getBoolean('autofillWalletIntegrationAvailable'));
-
// TODO(jhawkins): What happens when Autofill is disabled whilst on the
// Autofill options page?
},
@@ -187,16 +184,6 @@ cr.define('options', function() {
AutofillEditCreditCardOverlay.loadCreditCard(creditCard);
PageManager.showPageByName('autofillEditCreditCard');
},
-
- /**
- * Toggles the visibility of the Wallet integration checkbox.
- * @param {boolean} available Whether the user has the option of using
- * Wallet data.
- * @private
- */
- walletIntegrationAvailableStateChanged_: function(available) {
- $('autofill-wallet-setting-area').hidden = !available;
- },
};
AutofillOptions.setAddressList = function(entries) {
@@ -215,11 +202,6 @@ cr.define('options', function() {
AutofillOptions.getInstance().showEditAddressOverlay_(address);
};
- AutofillOptions.walletIntegrationAvailableStateChanged = function(available) {
- AutofillOptions.getInstance().
- walletIntegrationAvailableStateChanged_(available);
- };
-
/**
* @param {CreditCardData} creditCard
*/
diff --git a/chromium/chrome/browser/resources/options/settings_banner.css b/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.css
index c4290ef1273..d11484a6067 100644
--- a/chromium/chrome/browser/resources/options/settings_banner.css
+++ b/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.css
@@ -2,9 +2,6 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-/* These styles are used by both reset_profile_settings_banner.html and
- * automatic_settings_reset_banner.html. */
-
.settings-banner {
background-color: #f5f5f5;
border-color: #c8c8c8;
@@ -43,8 +40,8 @@ html[dir='rtl'] .settings-banner > .close-button {
}
.settings-banner .content-area {
- -webkit-box-align: center;
- display: -webkit-box;
+ align-items: center;
+ display: flex;
padding: 17px;
}
@@ -57,8 +54,8 @@ html[dir='rtl'] .settings-banner > .close-button {
}
.settings-banner .content-area .text {
- -webkit-box-flex: 1.0;
-webkit-margin-start: 18px;
+ flex: 1;
}
.settings-banner .content-area .text p {
diff --git a/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js b/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js
index e0747c58e15..5755d802034 100644
--- a/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js
+++ b/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js
@@ -5,21 +5,51 @@
// Note: the native-side handler for this is AutomaticSettingsResetHandler.
cr.define('options', function() {
- /** @const */ var SettingsBannerBase = options.SettingsBannerBase;
/** @const */ var PageManager = cr.ui.pageManager.PageManager;
/**
* AutomaticSettingsResetBanner class
* Provides encapsulated handling of the Reset Profile Settings banner.
* @constructor
- * @extends {options.SettingsBannerBase}
*/
function AutomaticSettingsResetBanner() {}
cr.addSingletonGetter(AutomaticSettingsResetBanner);
AutomaticSettingsResetBanner.prototype = {
- __proto__: SettingsBannerBase.prototype,
+ /**
+ * Whether or not the banner has already been dismissed.
+ *
+ * This is needed because of the surprising ordering of asynchronous
+ * JS<->native calls when the settings page is opened with specifying a
+ * given sub-page, e.g. chrome://settings/AutomaticSettingsReset.
+ *
+ * In such a case, AutomaticSettingsResetOverlay's didShowPage(), which
+ * calls our dismiss() method, would be called before the native Handlers'
+ * InitalizePage() methods have an effect in the JS, which includes calling
+ * our show() method. This would mean that the banner would be first
+ * dismissed, then shown. We want to prevent this.
+ *
+ * @private {boolean}
+ */
+ wasDismissed_: false,
+
+ /**
+ * Metric name to send when a show event occurs.
+ * @private {string}
+ */
+ showMetricName_: '',
+
+ /**
+ * Name of the native callback invoked when the banner is dismised.
+ */
+ dismissNativeCallbackName_: '',
+
+ /**
+ * DOM element whose visibility is set when setVisibility_ is called.
+ * @private {?HTMLElement}
+ */
+ visibleElement_: null,
/**
* Initializes the banner's event handlers.
@@ -31,12 +61,13 @@ cr.define('options', function() {
* private implementations using cr.makePublic().
*/
initialize: function() {
- this.showMetricName = 'AutomaticSettingsReset_WebUIBanner_BannerShown';
+ this.showMetricName_ = 'AutomaticSettingsReset_WebUIBanner_BannerShown';
- this.dismissNativeCallbackName =
+ this.dismissNativeCallbackName_ =
'onDismissedAutomaticSettingsResetBanner';
- this.visibilityDomElement = $('automatic-settings-reset-banner');
+ this.visibleElement_ = getRequiredElement(
+ 'automatic-settings-reset-banner');
$('automatic-settings-reset-banner-close').onclick = function(event) {
chrome.send('metricsHandler:recordAction',
@@ -54,18 +85,45 @@ cr.define('options', function() {
PageManager.showPageByName('resetProfileSettings');
};
},
+
+ /**
+ * Sets whether or not the reset profile settings banner shall be visible.
+ * @param {boolean} show Whether or not to show the banner.
+ * @protected
+ */
+ setVisibility: function(show) {
+ this.visibleElement_.hidden = !show;
+ },
+
+ /**
+ * Called by the native code to show the banner if needed.
+ * @private
+ */
+ show_: function() {
+ if (!this.wasDismissed_) {
+ chrome.send('metricsHandler:recordAction', [this.showMetricName_]);
+ this.setVisibility(true);
+ }
+ },
+
+ /**
+ * Called when the banner should be closed as a result of something taking
+ * place on the WebUI page, i.e. when its close button is pressed, or when
+ * the confirmation dialog for the profile settings reset feature is opened.
+ * @private
+ */
+ dismiss_: function() {
+ chrome.send(assert(this.dismissNativeCallbackName_));
+ this.wasDismissed_ = true;
+ this.setVisibility(false);
+ },
};
- // Forward public APIs to protected implementations.
- [
+ // Forward public APIs to private implementations.
+ cr.makePublic(AutomaticSettingsResetBanner, [
'show',
'dismiss',
- ].forEach(function(name) {
- AutomaticSettingsResetBanner[name] = function() {
- var instance = AutomaticSettingsResetBanner.getInstance();
- return instance[name].apply(instance, arguments);
- };
- });
+ ]);
// Export
return {
diff --git a/chromium/chrome/browser/resources/options/browser_options.css b/chromium/chrome/browser/resources/options/browser_options.css
index b9e718d6e71..ef72ef0ef3c 100644
--- a/chromium/chrome/browser/resources/options/browser_options.css
+++ b/chromium/chrome/browser/resources/options/browser_options.css
@@ -42,6 +42,7 @@ html[dir=rtl] #account-picture-wrapper {
#account-picture {
height: 56px;
+ object-fit: cover;
vertical-align: middle;
width: 56px;
}
@@ -148,17 +149,6 @@ input[type='range'] {
vertical-align: middle;
}
-/* CSS tweak to fix crbug.com/151788. Inconsistencies in the CSS rules across
- * platforms and elements. Too risky to attempt a general fix for M23 at this
- * time. This fix addresses the immediate problem in the bug report by forcing
- * the button to align consistently with its neighboring select element.
- * TODO(kevers): Revisit padding rules for select and buttons to ensure
- * consistency in the size and baseline across all platforms. */
-#manage-default-search-engines {
- padding-bottom: 0;
- padding-top: 0;
-}
-
.extension-controlled-warning-box {
background-color: #fbfbfb;
border: 1px solid #cecece;
@@ -174,14 +164,6 @@ input[type='range'] {
padding-top: 3px;
}
-/* Override a platform specific rule in Widgets that may no longer be relevant.
- * Too late in the development cycle to update Widgets.css due to the number
- * of pages that depend on it.
- * TODO(kevers): Rivisit padding rules. */
-#default-search-engine {
- padding-bottom: 0;
-}
-
.setting-extra-description {
-webkit-margin-start: 1.8em;
color: #999;
diff --git a/chromium/chrome/browser/resources/options/browser_options.html b/chromium/chrome/browser/resources/options/browser_options.html
index 01c30dce664..51a79e68208 100644
--- a/chromium/chrome/browser/resources/options/browser_options.html
+++ b/chromium/chrome/browser/resources/options/browser_options.html
@@ -2,11 +2,10 @@
<header>
<h1 i18n-content="settingsTitle"></h1>
</header>
- <include src="reset_profile_settings_banner.html">
<include src="automatic_settings_reset_banner.html">
<if expr="chromeos">
- <link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_network_icon.html">
- <link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+ <link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html">
+ <link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
<include src="secondary_user_banner.html">
<section>
<div id="network-section-header" class="section-header">
@@ -278,12 +277,6 @@
</button>
<div id="default-browser-state" i18n-content="defaultBrowserUnknown">
</div>
- <div id="auto-launch-option" class="checkbox" hidden>
- <label id="auto-launch-label">
- <input id="auto-launch" type="checkbox">
- <span i18n-content="autoLaunchText"></span>
- </label>
- </div>
</div>
</section>
</if> <!-- not chromeos -->
@@ -432,18 +425,6 @@
<if expr="_google_chrome">
<div id="metrics-reporting-setting"
class="checkbox controlled-setting-with-label">
-<if expr="chromeos">
- <label>
- <input id="metrics-reporting-enabled"
- pref="cros.metrics.reportingEnabled" type="checkbox">
- <span>
- <span i18n-content="enableLogging"></span>
- <span class="controlled-setting-indicator"
- pref="cros.metrics.reportingEnabled"></span>
- </span>
- </label>
-</if>
-<if expr="not chromeos">
<label>
<input id="metrics-reporting-enabled" type="checkbox">
<span>
@@ -452,12 +433,13 @@
class="controlled-setting-indicator"></span>
</span>
</label>
+<if expr="not chromeos">
<span id="metrics-reporting-reset-restart" hidden>
<!-- Text filled by JavaScript -->
<span></span><a is="action-link" role="button"
class="standalone-action-link"></a><span></span>
</span>
-</if>
+</if> <!-- not chromeos -->
</div>
</if> <!-- _google_chrome -->
<div class="checkbox">
@@ -503,12 +485,12 @@
<label>
<input id="wake-on-wifi-checkbox" type="checkbox"
metric="Options_WakeOnWifiSsid"
- pref="settings.internet.wake_on_wifi_ssid">
+ pref="settings.internet.wake_on_wifi_darkconnect">
<span>
<span i18n-content="wakeOnWifiLabel"></span>
<span id="wake-on-wifi-indicator"
class="controlled-setting-indicator"
- pref="settings.internet.wake_on_wifi_ssid"></span>
+ pref="settings.internet.wake_on_wifi_darkconnect"></span>
</span>
</label>
</div>
diff --git a/chromium/chrome/browser/resources/options/browser_options.js b/chromium/chrome/browser/resources/options/browser_options.js
index 1cb1fe3122b..bb646e6a8e9 100644
--- a/chromium/chrome/browser/resources/options/browser_options.js
+++ b/chromium/chrome/browser/resources/options/browser_options.js
@@ -79,24 +79,21 @@ cr.define('options', function() {
/**
* Keeps track of whether the user is signed in or not.
- * @type {boolean}
- * @private
+ * @private {boolean}
*/
signedIn_: false,
/**
* Indicates whether signing out is allowed or whether a complete profile
* wipe is required to remove the current enterprise account.
- * @type {boolean}
- * @private
+ * @private {boolean}
*/
signoutAllowed_: true,
/**
* Keeps track of whether |onShowHomeButtonChanged_| has been called. See
* |onShowHomeButtonChanged_|.
- * @type {boolean}
- * @private
+ * @private {boolean}
*/
onShowHomeButtonChangedCalled_: false,
@@ -104,8 +101,7 @@ cr.define('options', function() {
* Track if page initialization is complete. All C++ UI handlers have the
* chance to manipulate page content within their InitializePage methods.
* This flag is set to true after all initializers have been called.
- * @type {boolean}
- * @private
+ * @private {boolean}
*/
initializationComplete_: false,
@@ -121,6 +117,12 @@ cr.define('options', function() {
*/
systemTimezoneIsManaged_: false,
+ /**
+ * Cached bluetooth adapter state.
+ * @private {?chrome.bluetooth.AdapterState}
+ */
+ bluetoothAdapterState_: null,
+
/** @override */
initializePage: function() {
Page.prototype.initializePage.call(this);
@@ -186,7 +188,8 @@ cr.define('options', function() {
}
// Sync (Sign in) section.
- this.updateSyncState_(loadTimeData.getValue('syncData'));
+ this.updateSyncState_(/** @type {options.SyncStatus} */(
+ loadTimeData.getValue('syncData')));
$('start-stop-sync').onclick = function(event) {
if (self.signedIn_) {
@@ -197,7 +200,7 @@ cr.define('options', function() {
} else if (cr.isChromeOS) {
SyncSetupOverlay.showSetupUI();
} else {
- SyncSetupOverlay.startSignIn();
+ SyncSetupOverlay.startSignIn('access-point-settings');
}
};
$('customize-sync').onclick = function(event) {
@@ -345,7 +348,8 @@ cr.define('options', function() {
profilesList.autoExpands = true;
// The profiles info data in |loadTimeData| might be stale.
- this.setProfilesInfo_(loadTimeData.getValue('profilesInfo'));
+ this.setProfilesInfo_(/** @type {!Array<!options.Profile>} */(
+ loadTimeData.getValue('profilesInfo')));
chrome.send('requestProfilesInfo');
profilesList.addEventListener('change',
@@ -436,8 +440,6 @@ cr.define('options', function() {
$('set-as-default-browser').onclick = function(event) {
chrome.send('becomeDefaultBrowser');
};
-
- $('auto-launch').onclick = this.handleAutoLaunchChanged_;
}
// Privacy section.
@@ -452,47 +454,53 @@ cr.define('options', function() {
chrome.send('coreOptionsUserMetricsAction', ['Options_ClearData']);
};
$('privacyClearDataButton').hidden = OptionsPage.isSettingsApp();
- // 'metricsReportingEnabled' element is only present on Chrome branded
- // builds, and the 'metricsReportingCheckboxAction' message is only
- // handled on ChromeOS.
- if ($('metrics-reporting-enabled') && cr.isChromeOS) {
- $('metrics-reporting-enabled').onclick = function(event) {
- chrome.send('metricsReportingCheckboxAction',
- [String(event.currentTarget.checked)]);
- };
- }
- if ($('metrics-reporting-enabled') && !cr.isChromeOS) {
- // The localized string has the | symbol on each side of the text that
- // needs to be made into a button to restart Chrome. We parse the text
- // and build the button from that.
- var restartTextFragments =
- loadTimeData.getString('metricsReportingResetRestart').split('|');
- // Assume structure is something like "starting text |link text| ending
- // text" where both starting text and ending text may or may not be
- // present, but the split should always be in three pieces.
- var restartElements =
- $('metrics-reporting-reset-restart').querySelectorAll('*');
- for (var i = 0; i < restartTextFragments.length; i++) {
- restartElements[i].textContent = restartTextFragments[i];
- }
- restartElements[1].onclick = function(event) {
- chrome.send('restartBrowser');
- };
+
+ if ($('metrics-reporting-enabled')) {
+ $('metrics-reporting-enabled').checked =
+ loadTimeData.getBoolean('metricsReportingEnabledAtStart');
+
+ // A browser restart is never needed to toggle metrics reporting,
+ // and is only needed to toggle crash reporting when using Breakpad.
+ // Crashpad, used on Mac, does not require a browser restart.
+ var togglingMetricsRequiresRestart = !cr.isMac && !cr.isChromeOS;
$('metrics-reporting-enabled').onclick = function(event) {
chrome.send('metricsReportingCheckboxChanged',
[Boolean(event.currentTarget.checked)]);
- if (cr.isMac) {
- // A browser restart is never needed to toggle metrics reporting,
- // and is only needed to toggle crash reporting when using Breakpad.
- // Crashpad, used on Mac, does not require a browser restart.
- return;
+ if (cr.isChromeOS) {
+ // 'metricsReportingEnabled' element is only present on Chrome
+ // branded builds, and the 'metricsReportingCheckboxAction' message
+ // is only handled on ChromeOS.
+ chrome.send('metricsReportingCheckboxAction',
+ [String(event.currentTarget.checked)]);
}
- $('metrics-reporting-reset-restart').hidden =
- loadTimeData.getBoolean('metricsReportingEnabledAtStart') ==
- $('metrics-reporting-enabled').checked;
+
+ if (togglingMetricsRequiresRestart) {
+ $('metrics-reporting-reset-restart').hidden =
+ loadTimeData.getBoolean('metricsReportingEnabledAtStart') ==
+ $('metrics-reporting-enabled').checked;
+ }
+
};
- $('metrics-reporting-enabled').checked =
- loadTimeData.getBoolean('metricsReportingEnabledAtStart');
+
+ // Initialize restart button if needed.
+ if (togglingMetricsRequiresRestart) {
+ // The localized string has the | symbol on each side of the text that
+ // needs to be made into a button to restart Chrome. We parse the text
+ // and build the button from that.
+ var restartTextFragments =
+ loadTimeData.getString('metricsReportingResetRestart').split('|');
+ // Assume structure is something like "starting text |link text|
+ // ending text" where both starting text and ending text may or may
+ // not be present, but the split should always be in three pieces.
+ var restartElements =
+ $('metrics-reporting-reset-restart').querySelectorAll('*');
+ for (var i = 0; i < restartTextFragments.length; i++) {
+ restartElements[i].textContent = restartTextFragments[i];
+ }
+ restartElements[1].onclick = function(event) {
+ chrome.send('restartBrowser');
+ };
+ }
}
$('networkPredictionOptions').onchange = function(event) {
var value = (event.target.checked ?
@@ -512,6 +520,24 @@ cr.define('options', function() {
// Bluetooth (CrOS only).
if (cr.isChromeOS) {
+ // Request the intial bluetooth adapter state.
+ var adapterStateChanged =
+ this.onBluetoothAdapterStateChanged_.bind(this);
+ chrome.bluetooth.getAdapterState(adapterStateChanged);
+
+ // Set up observers.
+ chrome.bluetooth.onAdapterStateChanged.addListener(adapterStateChanged);
+ var deviceAddedOrChanged =
+ this.onBluetoothDeviceAddedOrChanged_.bind(this);
+ chrome.bluetooth.onDeviceAdded.addListener(deviceAddedOrChanged);
+ chrome.bluetooth.onDeviceChanged.addListener(deviceAddedOrChanged);
+ chrome.bluetooth.onDeviceRemoved.addListener(
+ this.onBluetoothDeviceRemoved_.bind(this));
+
+ chrome.bluetoothPrivate.onPairing.addListener(
+ this.onBluetoothPrivatePairing_.bind(this));
+
+ // Initialize UI.
options.system.bluetooth.BluetoothDeviceList.decorate(
$('bluetooth-paired-devices-list'));
@@ -520,16 +546,19 @@ cr.define('options', function() {
$('enable-bluetooth').onchange = function(event) {
var state = $('enable-bluetooth').checked;
- chrome.send('bluetoothEnableChange', [Boolean(state)]);
+ chrome.bluetoothPrivate.setAdapterState({powered: state}, function() {
+ if (chrome.runtime.lastError) {
+ console.error('Error enabling bluetooth:',
+ chrome.runtime.lastError.message);
+ }
+ });
};
$('bluetooth-reconnect-device').onclick = function(event) {
chrome.send('coreOptionsUserMetricsAction',
['Options_BluetoothConnectPairedDevice']);
var device = $('bluetooth-paired-devices-list').selectedItem;
- var address = device.address;
- chrome.send('updateBluetoothDevice', [address, 'connect']);
- PageManager.closeOverlay();
+ BluetoothPairing.connect(device);
};
$('bluetooth-paired-devices-list').addEventListener('change',
@@ -1321,16 +1350,6 @@ cr.define('options', function() {
return url.replace(/^http:\/\//, '');
},
- /**
- * Shows the autoLaunch preference and initializes its checkbox value.
- * @param {boolean} enabled Whether autolaunch is enabled or or not.
- * @private
- */
- updateAutoLaunchState_: function(enabled) {
- $('auto-launch-option').hidden = false;
- $('auto-launch').checked = enabled;
- },
-
/**
* Called when the value of the download.default_directory preference
* changes.
@@ -1422,14 +1441,6 @@ cr.define('options', function() {
}
},
- /**
- * Sets or clear whether Chrome should Auto-launch on computer startup.
- * @private
- */
- handleAutoLaunchChanged_: function() {
- chrome.send('toggleAutoLaunch', [$('auto-launch').checked]);
- },
-
/**
* Get the selected profile item from the profile list. This also works
* correctly if the list is not displayed.
@@ -1501,7 +1512,7 @@ cr.define('options', function() {
/**
* Adds all |profiles| to the list.
- * @param {Array<!options.Profile>} profiles An array of profile info
+ * @param {!Array<!options.Profile>} profiles An array of profile info
* objects.
* @private
*/
@@ -1711,7 +1722,6 @@ cr.define('options', function() {
handleAddBluetoothDevice_: function() {
chrome.send('coreOptionsUserMetricsAction',
['Options_BluetoothShowAddDevice']);
- chrome.send('findBluetoothDevices');
PageManager.showPageByName('bluetooth', false);
},
@@ -1746,18 +1756,24 @@ cr.define('options', function() {
* Set the checked state of the metrics reporting checkbox.
* @private
*/
- setMetricsReportingCheckboxState_: function(checked, disabled) {
+ setMetricsReportingCheckboxState_: function(checked,
+ policyManaged,
+ ownerManaged) {
$('metrics-reporting-enabled').checked = checked;
- $('metrics-reporting-enabled').disabled = disabled;
+ $('metrics-reporting-enabled').disabled = policyManaged || ownerManaged;
// If checkbox gets disabled then add an attribute for displaying the
// special icon. Otherwise remove the indicator attribute.
- if (disabled) {
+ if (policyManaged) {
$('metrics-reporting-disabled-icon').setAttribute('controlled-by',
'policy');
+ } else if (ownerManaged) {
+ $('metrics-reporting-disabled-icon').setAttribute('controlled-by',
+ 'owner');
} else {
$('metrics-reporting-disabled-icon').removeAttribute('controlled-by');
}
+
},
/**
@@ -2026,22 +2042,6 @@ cr.define('options', function() {
},
/**
- * Activate the Bluetooth settings section on the System settings page.
- * @private
- */
- showBluetoothSettings_: function() {
- $('bluetooth-devices').hidden = false;
- },
-
- /**
- * Dectivates the Bluetooth settings section from the System settings page.
- * @private
- */
- hideBluetoothSettings_: function() {
- $('bluetooth-devices').hidden = true;
- },
-
- /**
* Sets the state of the checkbox indicating if Bluetooth is turned on. The
* state of the "Find devices" button and the list of discovered devices may
* also be affected by a change to the state.
@@ -2053,27 +2053,88 @@ cr.define('options', function() {
$('bluetooth-paired-devices-list').parentNode.hidden = !checked;
$('bluetooth-add-device').hidden = !checked;
$('bluetooth-reconnect-device').hidden = !checked;
- // Flush list of previously discovered devices if bluetooth is turned off.
- if (!checked) {
- $('bluetooth-paired-devices-list').clear();
- $('bluetooth-unpaired-devices-list').clear();
+ },
+
+ /**
+ * Process a bluetooth.onAdapterStateChanged event.
+ * @param {!chrome.bluetooth.AdapterState} state
+ * @private
+ */
+ onBluetoothAdapterStateChanged_: function(state) {
+ if (!state || !state.available) {
+ this.bluetoothAdapterState_ = null;
+ $('bluetooth-devices').hidden = true;
+ return;
+ }
+ $('bluetooth-devices').hidden = false;
+ this.bluetoothAdapterState_ = state;
+ this.setBluetoothState_(state.powered);
+
+ // Flush the device lists.
+ $('bluetooth-paired-devices-list').clear();
+ $('bluetooth-unpaired-devices-list').clear();
+ if (state.powered) {
+ options.BluetoothOptions.updateDiscoveryState(state.discovering);
+ // Update the device lists.
+ chrome.bluetooth.getDevices(function(devices) {
+ for (var device of devices)
+ this.updateBluetoothDevicesList_(device);
+ }.bind(this));
} else {
- chrome.send('getPairedBluetoothDevices');
+ options.BluetoothOptions.dismissOverlay();
}
},
/**
- * Adds an element to the list of available Bluetooth devices. If an element
- * with a matching address is found, the existing element is updated.
- * @param {{name: string,
- * address: string,
- * paired: boolean,
- * connected: boolean}} device
- * Decription of the Bluetooth device.
+ * Process a bluetooth.onDeviceAdded or onDeviceChanged event and update the
+ * device list.
+ * @param {!chrome.bluetooth.Device} device
* @private
*/
- addBluetoothDevice_: function(device) {
- var list = $('bluetooth-unpaired-devices-list');
+ onBluetoothDeviceAddedOrChanged_: function(device) {
+ this.updateBluetoothDevicesList_(device);
+ },
+
+ /**
+ * Process a bluetooth.onDeviceRemoved event and update the device list.
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ onBluetoothDeviceRemoved_: function(device) {
+ this.removeBluetoothDevice_(device.address);
+ },
+
+ /**
+ * Process a bluetoothPrivate onPairing event and update the device list.
+ * @param {!chrome.bluetoothPrivate.PairingEvent} pairing_event
+ * @private
+ */
+ onBluetoothPrivatePairing_: function(pairing_event) {
+ this.updateBluetoothDevicesList_(pairing_event.device);
+ BluetoothPairing.onBluetoothPairingEvent(pairing_event);
+ },
+
+ /**
+ * Add |device| to the appropriate list of Bluetooth devices.
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ addBluetoothDeviceToList_: function(device) {
+ // Display the "connecting" (already paired or not yet paired) and the
+ // paired devices in the same list.
+ if (device.paired || device.connecting)
+ $('bluetooth-paired-devices-list').appendDevice(device);
+ else
+ $('bluetooth-unpaired-devices-list').appendDevice(device);
+ },
+
+ /**
+ * Add |device| to the appropriate list of Bluetooth devices or update the
+ * entry if a device with a matching |address| property exists.
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ updateBluetoothDevicesList_: function(device) {
// Display the "connecting" (already paired or not yet paired) and the
// paired devices in the same list.
if (device.paired || device.connecting) {
@@ -2082,7 +2143,6 @@ cr.define('options', function() {
var index = $('bluetooth-unpaired-devices-list').find(device.address);
if (index != undefined)
$('bluetooth-unpaired-devices-list').deleteItemAtIndex(index);
- list = $('bluetooth-paired-devices-list');
} else {
// Test to see if the device is currently in the paired list, in which
// case it should be removed from that list.
@@ -2090,12 +2150,7 @@ cr.define('options', function() {
if (index != undefined)
$('bluetooth-paired-devices-list').deleteItemAtIndex(index);
}
- list.appendDevice(device);
-
- // One device can be in the process of pairing. If found, display
- // the Bluetooth pairing overlay.
- if (device.pairing)
- BluetoothPairing.showDialog(device);
+ this.addBluetoothDeviceToList_(device);
},
/**
@@ -2165,23 +2220,20 @@ cr.define('options', function() {
},
};
- //Forward public APIs to private implementations.
+ // Forward public APIs to private implementations.
cr.makePublic(BrowserOptions, [
- 'addBluetoothDevice',
'deleteCurrentProfile',
'enableCertificateButton',
'enableDisplaySettings',
'enableFactoryResetSection',
'getCurrentProfile',
'getStartStopSyncButton',
- 'hideBluetoothSettings',
'notifyInitializationComplete',
'removeBluetoothDevice',
'scrollToSection',
'setAccountPictureManaged',
'setWallpaperManaged',
'setAutoOpenFileTypesDisplayed',
- 'setBluetoothState',
'setCanSetTime',
'setFontSize',
'setHotwordRetrainLinkVisible',
@@ -2200,7 +2252,6 @@ cr.define('options', function() {
'setupPageZoomSelector',
'setupProxySettingsButton',
'setAudioHistorySectionVisible',
- 'showBluetoothSettings',
'showCreateProfileError',
'showCreateProfileSuccess',
'showCreateProfileWarning',
@@ -2213,7 +2264,6 @@ cr.define('options', function() {
'showTouchpadControls',
'toggleExtensionIndicators',
'updateAccountPicture',
- 'updateAutoLaunchState',
'updateDefaultBrowserState',
'updateEasyUnlock',
'updateManagesSupervisedUsers',
@@ -2244,7 +2294,7 @@ cr.define('options', function() {
}
button.hidden = false;
- var strId;
+ /** @type {string} */ var strId;
switch (status) {
case ConsumerManagementOverlay.Status.STATUS_UNENROLLED:
strId = 'consumerManagementEnrollButton';
diff --git a/chromium/chrome/browser/resources/options/chromeos/2x/warning.png b/chromium/chrome/browser/resources/options/chromeos/2x/warning.png
deleted file mode 100644
index b28ab3643b1..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/2x/warning.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/chromeos/OWNERS b/chromium/chrome/browser/resources/options/chromeos/OWNERS
deleted file mode 100644
index d9411747d16..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/OWNERS
+++ /dev/null
@@ -1,14 +0,0 @@
-achuith@chromium.org
-nkostylev@chromium.org
-stevenjb@chromium.org
-xiyuan@chromium.org
-zelidrag@chromium.org
-
-# Display options.
-mukai@chromium.org
-
-# Network configuration.
-per-file internet_detail*=pneubeck@chromium.org
-per-file network_list*=pneubeck@chromium.org
-per-file preferred_networks*=pneubeck@chromium.org
-per-file proxy_rules_list*=pneubeck@chromium.org
diff --git a/chromium/chrome/browser/resources/options/chromeos/accounts_options.html b/chromium/chrome/browser/resources/options/chromeos/accounts_options.html
deleted file mode 100644
index 2ddc846d232..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/accounts_options.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<div id="accountsPage" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="accountsPage"></h1>
- <div class="content-area">
- <div class="option">
- <div id="ownerOnlyWarning" hidden>
- <span i18n-content="owner_only"></span>
- <span i18n-content="ownerUserId"></span>
- </div>
- <table class="option-control-table">
- <tr>
- <td class="option-name">
- <div class="checkbox">
- <label>
- <input id="allowBwsiCheck" type="checkbox"
- metric="Options_GuestBrowsing"
- pref="cros.accounts.allowBWSI">
- <span i18n-content="allow_BWSI"></span>
- </label>
- </div>
- </td>
- </tr>
- <tr>
- <td class="option-name">
- <div class="checkbox">
- <label>
- <input id="allowSupervisedCheck" type="checkbox"
- metric="Options_SupervisedUsers"
- pref="cros.accounts.supervisedUsersEnabled">
- <span i18n-content="allow_supervised_users"></span>
- </label>
- </div>
- </td>
- </tr>
- <tr>
- <td class="option-name">
- <div class="checkbox">
- <label>
- <input id="showUserNamesCheck" type="checkbox"
- metric="Options_ShowUserNamesOnSignin"
- pref="cros.accounts.showUserNamesOnSignIn">
- <span i18n-content="show_user_on_signin"></span>
- </label>
- </div>
- </td>
- </tr>
- <tr>
- <td class="option-name">
- <div class="checkbox">
- <label>
- <input id="useWhitelistCheck" type="checkbox"
- metric="Options_AllowAllUsers"
- pref="cros.accounts.allowGuest"
- inverted_pref>
- <span i18n-content="use_whitelist"></span>
- </label>
- </div>
- </td>
- </tr>
- <tr><td>&nbsp;</td></tr>
- <tr><td>
- <table class="user-list-table">
- <tr><td>
- <list id="userList"></list>
- </td></tr>
- <tr><td class="user-name-edit-row">
- <label><span i18n-content="add_users"></span><br>
- <input id="userNameEdit" type="text"
- i18n-values="placeholder:username_edit_hint">
- </span>
- </label>
- </td></tr>
- </table>
- </td></tr>
- </table>
- </div>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="accounts-options-overlay-confirm" class="default-button"
- i18n-content="done">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/accounts_options.js b/chromium/chrome/browser/resources/options/chromeos/accounts_options.js
deleted file mode 100644
index 83668652fea..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/accounts_options.js
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
-
- /////////////////////////////////////////////////////////////////////////////
- // AccountsOptions class:
-
- /**
- * Encapsulated handling of ChromeOS accounts options page.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function AccountsOptions(model) {
- Page.call(this, 'accounts', loadTimeData.getString('accountsPageTabTitle'),
- 'accountsPage');
- // Whether to show the whitelist.
- this.showWhitelist_ = false;
- }
-
- cr.addSingletonGetter(AccountsOptions);
-
- AccountsOptions.prototype = {
- // Inherit AccountsOptions from Page.
- __proto__: Page.prototype,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
-
- // Set up accounts page.
- var userList = $('userList');
- userList.addEventListener('remove', this.handleRemoveUser_);
-
- var userNameEdit = $('userNameEdit');
- options.accounts.UserNameEdit.decorate(userNameEdit);
- userNameEdit.addEventListener('add', this.handleAddUser_);
-
- // If the current user is not the owner, do not show the user list.
- // If the current user is not the owner, or the device is enterprise
- // managed, show a warning that settings cannot be modified.
- this.showWhitelist_ = UIAccountTweaks.currentUserIsOwner();
- if (this.showWhitelist_) {
- options.accounts.UserList.decorate(userList);
- } else {
- $('ownerOnlyWarning').hidden = false;
- this.managed = AccountsOptions.whitelistIsManaged();
- }
-
- this.addEventListener('visibleChange', this.handleVisibleChange_);
-
- $('useWhitelistCheck').addEventListener('change',
- this.handleUseWhitelistCheckChange_.bind(this));
-
- Preferences.getInstance().addEventListener(
- $('useWhitelistCheck').pref,
- this.handleUseWhitelistPrefChange_.bind(this));
-
- $('accounts-options-overlay-confirm').onclick =
- PageManager.closeOverlay.bind(PageManager);
- },
-
- /**
- * Update user list control state.
- * @private
- */
- updateControls_: function() {
- $('userList').disabled =
- $('userNameEdit').disabled = !this.showWhitelist_ ||
- AccountsOptions.whitelistIsManaged() ||
- !$('useWhitelistCheck').checked;
- },
-
- /**
- * Handler for Page's visible property change event.
- * @private
- * @param {Event} e Property change event.
- */
- handleVisibleChange_: function(e) {
- if (this.visible) {
- chrome.send('updateWhitelist');
- this.updateControls_();
- if (this.showWhitelist_)
- $('userList').redraw();
- }
- },
-
- /**
- * Handler for allow guest check change.
- * @private
- */
- handleUseWhitelistCheckChange_: function(e) {
- // Whitelist existing users when guest login is being disabled.
- if ($('useWhitelistCheck').checked) {
- chrome.send('updateWhitelist');
- }
-
- this.updateControls_();
- },
-
- /**
- * handler for allow guest pref change.
- * @private
- */
- handleUseWhitelistPrefChange_: function(e) {
- this.updateControls_();
- },
-
- /**
- * Handler for "add" event fired from userNameEdit.
- * @private
- * @param {Event} e Add event fired from userNameEdit.
- */
- handleAddUser_: function(e) {
- chrome.send('whitelistUser', [e.user.email, e.user.name]);
- chrome.send('coreOptionsUserMetricsAction',
- ['Options_WhitelistedUser_Add']);
- },
-
- /**
- * Handler for "remove" event fired from userList.
- * @private
- * @param {Event} e Remove event fired from userList.
- */
- handleRemoveUser_: function(e) {
- chrome.send('unwhitelistUser', [e.user.username]);
- chrome.send('coreOptionsUserMetricsAction',
- ['Options_WhitelistedUser_Remove']);
- }
- };
-
-
- /**
- * Returns whether the whitelist is managed by policy or not.
- */
- AccountsOptions.whitelistIsManaged = function() {
- return loadTimeData.getBoolean('whitelist_is_managed');
- };
-
- /**
- * Update account picture.
- * @param {string} username User for which to update the image.
- */
- AccountsOptions.updateAccountPicture = function(username) {
- if (this.showWhitelist_)
- $('userList').updateAccountPicture(username);
- };
-
- // Export
- return {
- AccountsOptions: AccountsOptions
- };
-
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/accounts_options_page.css b/chromium/chrome/browser/resources/options/chromeos/accounts_options_page.css
deleted file mode 100644
index 365775759e5..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/accounts_options_page.css
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-.user-list-table {
- border: 1px solid lightgrey;
- border-collapse: collapse;
- border-spacing: 0;
-}
-
-.user-name-edit-row {
- background-color: rgb(235, 239, 250);
- border: 1px solid lightgrey;
- padding: 5px;
-}
-
-.user-list-item {
- padding: 2px;
-}
-
-.user-icon {
- border: 1px solid black;
- height: 26px;
- width: 26px;
-}
-
-.user-email-label,
-.user-name-label {
- -webkit-margin-start: 10px;
-}
-
-.user-email-name-block {
- -webkit-box-flex: 1;
- max-width: 318px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.remove-user-button {
- background-image: -webkit-image-set(
- url(../../../../../ui/resources/default_100_percent/close_2.png) 1x,
- url(../../../../../ui/resources/default_200_percent/close_2.png) 2x);
- height: 16px;
- width: 16px;
-}
-
-.remove-user-button:hover {
- background-image: -webkit-image-set(
- url(../../../../../ui/resources/default_100_percent/close_2_hover.png)
- 1x,
- url(../../../../../ui/resources/default_200_percent/close_2_hover.png)
- 2x);
-}
-
-#userList {
- height: 166px;
- padding: 5px;
- width: 366px;
-}
-
-#userList[disabled],
-#userList[disabled] > [selected],
-#userList[disabled] > :hover {
- border-color: hsl(0, 0%, 85%);
-}
-
-#userList[disabled] > [selected],
-#userList[disabled] > :hover {
- background-color: hsl(0, 0%, 90%);
-}
-
-#userList[disabled] .remove-user-button {
- visibility: hidden;
-}
-
-#userNameEdit {
- border: 1px solid lightgrey;
- width: 366px;
-}
-
-#ownerOnlyWarning {
- -webkit-padding-start: 20px;
- background-image: url(warning.png);
- background-repeat: no-repeat;
- margin-bottom: 10px;
- margin-top: 10px;
- min-height: 17px;
- padding-bottom: 1px;
-}
-
-input#userNameEdit:invalid {
- background-color: rgb(255, 102, 102);
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/accounts_user_list.js b/chromium/chrome/browser/resources/options/chromeos/accounts_user_list.js
deleted file mode 100644
index 8bb3e3f0fbe..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/accounts_user_list.js
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options.accounts', function() {
- /** @const */ var List = cr.ui.List;
- /** @const */ var ListItem = cr.ui.ListItem;
- /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
-
- /**
- * Creates a new user list.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {cr.ui.List}
- */
- var UserList = cr.ui.define('list');
-
- UserList.prototype = {
- __proto__: List.prototype,
-
- pref: 'cros.accounts.users',
-
- /** @override */
- decorate: function() {
- List.prototype.decorate.call(this);
-
- // HACK(arv): http://crbug.com/40902
- window.addEventListener('resize', this.redraw.bind(this));
-
- var self = this;
-
- // Listens to pref changes.
- Preferences.getInstance().addEventListener(this.pref,
- function(event) {
- self.load_(event.value.value);
- });
- },
-
- /**
- * @override
- * @param {Object} user
- */
- createItem: function(user) {
- return new UserListItem(user);
- },
-
- /**
- * Finds the index of user by given username (canonicalized email).
- * @private
- * @param {string} username The username to look for.
- * @return {number} The index of the found user or -1 if not found.
- */
- indexOf_: function(username) {
- var dataModel = this.dataModel;
- if (!dataModel)
- return -1;
-
- var length = dataModel.length;
- for (var i = 0; i < length; ++i) {
- var user = dataModel.item(i);
- if (user.username == username) {
- return i;
- }
- }
-
- return -1;
- },
-
- /**
- * Update given user's account picture.
- * @param {string} username User for which to update the image.
- */
- updateAccountPicture: function(username) {
- var index = this.indexOf_(username);
- if (index >= 0) {
- var item = this.getListItemByIndex(index);
- if (item)
- item.updatePicture();
- }
- },
-
- /**
- * Loads given user list.
- * @param {!Array<Object>} users An array of user info objects.
- * @private
- */
- load_: function(users) {
- this.dataModel = new ArrayDataModel(users);
- },
-
- /**
- * Removes given user from the list.
- * @param {Object} user User info object to be removed from user list.
- * @private
- */
- removeUser_: function(user) {
- var e = new Event('remove');
- e.user = user;
- this.dispatchEvent(e);
- }
- };
-
- /**
- * Whether the user list is disabled. Only used for display purpose.
- */
- cr.defineProperty(UserList, 'disabled', cr.PropertyKind.BOOL_ATTR);
-
- /**
- * Creates a new user list item.
- * @param {Object} user The user account this represents.
- * @constructor
- * @extends {cr.ui.ListItem}
- */
- function UserListItem(user) {
- var el = cr.doc.createElement('div');
- el.user = user;
- UserListItem.decorate(el);
- return el;
- }
-
- /**
- * Decorates an element as a user account item.
- * @param {!HTMLElement} el The element to decorate.
- */
- UserListItem.decorate = function(el) {
- el.__proto__ = UserListItem.prototype;
- el.decorate();
- };
-
- UserListItem.prototype = {
- __proto__: ListItem.prototype,
-
- /** @override */
- decorate: function() {
- ListItem.prototype.decorate.call(this);
-
- this.className = 'user-list-item';
-
- this.icon_ = this.ownerDocument.createElement('img');
- this.icon_.className = 'user-icon';
- this.updatePicture();
-
- var labelEmail = this.ownerDocument.createElement('span');
- labelEmail.className = 'user-email-label';
- labelEmail.textContent = this.user.email;
-
- var labelName = this.ownerDocument.createElement('span');
- labelName.className = 'user-name-label';
- labelName.textContent = this.user.owner ?
- loadTimeData.getStringF('username_format', this.user.name) :
- this.user.name;
-
- var emailNameBlock = this.ownerDocument.createElement('div');
- emailNameBlock.className = 'user-email-name-block';
- emailNameBlock.appendChild(labelEmail);
- emailNameBlock.appendChild(labelName);
- emailNameBlock.title = this.user.owner ?
- loadTimeData.getStringF('username_format', this.user.email) :
- this.user.email;
-
- this.appendChild(this.icon_);
- this.appendChild(emailNameBlock);
-
- if (!this.user.owner) {
- var removeButton = this.ownerDocument.createElement('button');
- removeButton.className =
- 'raw-button remove-user-button custom-appearance';
- removeButton.addEventListener(
- 'click', this.handleRemoveButtonClick_.bind(this));
- this.appendChild(removeButton);
- }
- },
-
- /**
- * Handles click on the remove button.
- * @param {Event} e Click event.
- * @private
- */
- handleRemoveButtonClick_: function(e) {
- // Handle left button click
- if (e.button == 0)
- this.parentNode.removeUser_(this.user);
- },
-
- /**
- * Reloads user picture.
- */
- updatePicture: function() {
- this.icon_.src = 'chrome://userimage/' + this.user.username +
- '?id=' + (new Date()).getTime();
- }
- };
-
- return {
- UserList: UserList
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/accounts_user_name_edit.js b/chromium/chrome/browser/resources/options/chromeos/accounts_user_name_edit.js
deleted file mode 100644
index 22a3b37b0e9..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/accounts_user_name_edit.js
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options.accounts', function() {
- /**
- * Email alias only, assuming it's a gmail address.
- * e.g. 'john'
- * {name: 'john', email: 'john@gmail.com'}
- * @const
- */
- var format1String =
- '^\\s*([\\w\\.!#\\$%&\'\\*\\+-\\/=\\?\\^`\\{\\|\\}~]+)\\s*$';
- /**
- * Email address only.
- * e.g. 'john@chromium.org'
- * {name: 'john', email: 'john@chromium.org'}
- * @const
- */
- var format2String =
- '^\\s*([\\w\\.!#\\$%&\'\\*\\+-\\/=\\?\\^`\\{\\|\\}~]+)@' +
- '([A-Za-z0-9\-]{2,63}\\..+)\\s*$';
- /**
- * Full format.
- * e.g. '"John Doe" <john@chromium.org>'
- * {name: 'John doe', email: 'john@chromium.org'}
- * @const
- */
- var format3String =
- '^\\s*"{0,1}([^"]+)"{0,1}\\s*' +
- '<([\\w\\.!#\\$%&\'\\*\\+-\\/=\\?\\^`\\{\\|\\}~]+@' +
- '[A-Za-z0-9\-]{2,63}\\..+)>\\s*$';
-
- /**
- * Creates a new user name edit element.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {HTMLInputElement}
- */
- var UserNameEdit = cr.ui.define('input');
-
- UserNameEdit.prototype = {
- __proto__: HTMLInputElement.prototype,
-
- /**
- * Called when an element is decorated as a user name edit.
- */
- decorate: function() {
- this.pattern = format1String + '|' + format2String + '|' +
- format3String;
-
- this.onkeydown = this.handleKeyDown_.bind(this);
- },
-
-
- /**
- * Parses given str for user info.
- *
- * Note that the email parsing is based on RFC 5322 and does not support
- * IMA (Internationalized Email Address). We take only the following chars
- * as valid for an email alias (aka local-part):
- * - Letters: a–z, A–Z
- * - Digits: 0-9
- * - Characters: ! # $ % & ' * + - / = ? ^ _ ` { | } ~
- * - Dot: . (Note that we did not cover the cases that dot should not
- * appear as first or last character and should not appear two or
- * more times in a row.)
- *
- * @param {string} str A string to parse.
- * @return {?{name: string, email: string}} User info parsed from the
- * string.
- */
- parse: function(str) {
- /** @const */ var format1 = new RegExp(format1String);
- /** @const */ var format2 = new RegExp(format2String);
- /** @const */ var format3 = new RegExp(format3String);
-
- var matches = format1.exec(str);
- if (matches) {
- return {
- name: matches[1],
- email: matches[1] + '@gmail.com'
- };
- }
-
- matches = format2.exec(str);
- if (matches) {
- return {
- name: matches[1],
- email: matches[1] + '@' + matches[2]
- };
- }
-
- matches = format3.exec(str);
- if (matches) {
- return {
- name: matches[1],
- email: matches[2]
- };
- }
-
- return null;
- },
-
- /**
- * Handler for key down event.
- * @private
- * @param {Event} e The keydown event object.
- */
- handleKeyDown_: function(e) {
- if (e.keyIdentifier == 'Enter') {
- var user = this.parse(this.value);
- if (user) {
- var event = new Event('add');
- event.user = user;
- this.dispatchEvent(event);
- }
- this.select();
- // Avoid double-handling so the dialog doesn't close.
- e.stopPropagation();
- }
- }
- };
-
- return {
- UserNameEdit: UserNameEdit
- };
-});
-
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth.css b/chromium/chrome/browser/resources/options/chromeos/bluetooth.css
deleted file mode 100644
index b93849ec298..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth.css
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-.bluetooth-device-list {
- margin: 10px 0;
- padding: 5px 10px;
-}
-
-.bluetooth-device[notconnectable] {
- color: gray;
-}
-
-.bluetooth-device[connected] {
- font-weight: bold; /* semibold */
-}
-
-#bluetooth-options .bluetooth-device-list {
- margin: 0 10px;
-}
-
-#bluetooth-options .button-strip {
- -webkit-box-pack: justify;
-}
-
-#bluetooth-options .button-strip #bluetooth-scanning-label,
-#bluetooth-options .button-strip #bluetooth-scan-stopped-label {
- -webkit-box-flex: 1;
- display: block;
-}
-
-#bluetooth-scanning-label,
-#bluetooth-scan-stopped-label {
- -webkit-margin-start: 5px;
- color: #999;
-}
-
-#bluetooth-scanning-icon {
- height: 20px;
- opacity: 0.66;
- vertical-align: middle;
- width: 20px;
-}
-
-#bluetooth-paired-devices-list {
- min-height: 96px !important;
-}
-
-#bluetooth-paired-devices-list,
-#bluetooth-unpaired-devices-list {
- /* Prevent dialog from expanding if many devices are found. */
- max-height: 192px;
- overflow-x: hidden;
- overflow-y: auto;
-}
-
-.bluetooth-empty-list-label {
- box-sizing: border-box;
- color: #999;
- padding-top: 32px;
- text-align: center;
-}
-
-#bluetooth-paired-devices-list-empty-placeholder {
- height: 96px;
-}
-
-#bluetooth-unpaired-devices-list-empty-placeholder {
- height: 192px;
-}
-
-/* Fix the dimensions of the message area so that the dialog does not change
- change size during the pairing process as the message changes. Sized
- generously to accomodate the longest of the messages. */
-#bluetooth-pairing-message-area {
- display: table;
- height: 160px;
- padding: 6px 0 !important;
- width: 420px;
-}
-
-/* Force the message to be vertical centered so that a shorter message does not
- look out of place when there is room for a much longer message. */
-#bluetooth-pairing-message-contents {
- display: table-cell;
- vertical-align: middle;
-}
-
-#bluetooth-pairing-instructions,
-#bluetooth-pairing-passkey-display,
-#bluetooth-pairing-passkey-entry,
-#bluetooth-pairing-pincode-entry,
-#bluetooth-passkey,
-#bluetooth-pincode {
- text-align: center;
-}
-
-#bluetooth-pairing-instructions {
- margin: 10px;
-}
-
-#bluetooth-pairing-passkey-display,
-#bluetooth-pairing-passkey-entry,
-#bluetooth-pairing-pincode-entry {
- margin: 40px 0;
-}
-
-.bluetooth-keyboard-button {
- -webkit-padding-end: 15px;
- -webkit-padding-start: 15px;
- border: 1px solid #ccc;
- border-radius: 4px;
- box-shadow: 0 0 0 1px #222;
- color: #222;
- display: inline-block;
- font-size: 16px;
- height: 38px;
- line-height: 38px;
- margin: 0 10px 0 0;
- position: relative;
- text-align: center;
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
- vertical-align: baseline;
-}
-
-.bluetooth-keyboard-button:last-child {
- margin: 0;
-}
-
-#bluetooth-enter-key {
- min-width: 54px;
-}
-
-.bluetooth-passkey-char {
- -webkit-margin-start: 45px;
- color: #999;
- font-size: 20px;
- font-weight: 600; /* semibold */
- padding-bottom: 5px;
-}
-
-.bluetooth-passkey-char:first-child {
- -webkit-margin-start: 0;
-}
-
-.bluetooth-keyboard-button.key-typed {
- color: #222;
-}
-
-.bluetooth-keyboard-button.key-next {
- background: rgb(77, 144, 254);
- background-image: none;
- border: 2px solid rgb(77, 144, 254);
- box-shadow: none;
- color: #fff;
-}
-
-.bluetooth-keyboard-button.key-untyped {
- border: 1px solid #d4d4d4;
- box-shadow: 0 0 0 1px #888;
- color: #666;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html b/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html
deleted file mode 100644
index dcb87aba490..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<div id="bluetooth-options" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="bluetoothAddDeviceTitle"></h1>
- <div class="settings-list bluetooth-device-list content-area">
- <list id="bluetooth-unpaired-devices-list"></list>
- <div id="bluetooth-unpaired-devices-list-empty-placeholder"
- class="bluetooth-empty-list-label" hidden>
- <span i18n-content="bluetoothNoDevicesFound"></span>
- </div>
- </div>
- <div class="action-area button-strip">
- <button id="bluetooth-add-device-cancel-button" type="reset"
- i18n-content="cancel">
- </button>
- <button id="bluetooth-add-device-apply-button" type="submit"
- class="default-button" i18n-content="bluetoothConnectDevice" disabled>
- </button>
- <span id="bluetooth-scanning-label"
- i18n-content="bluetoothScanning">
- </span>
- <span id="bluetooth-scan-stopped-label"
- i18n-content="bluetoothScanStopped">
- </span>
- <div id="bluetooth-scanning-icon" class="inline-spinner"></div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js b/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js
deleted file mode 100644
index 675e08772c9..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- /** @const */ var Page = cr.ui.pageManager.Page;
- /** @const */ var PageManager = cr.ui.pageManager.PageManager;
-
- /**
- * Encapsulated handling of the Bluetooth options page.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function BluetoothOptions() {
- Page.call(this, 'bluetooth',
- loadTimeData.getString('bluetoothOptionsPageTabTitle'),
- 'bluetooth-options');
- }
-
- cr.addSingletonGetter(BluetoothOptions);
-
- BluetoothOptions.prototype = {
- __proto__: Page.prototype,
-
- /**
- * The list of available (unpaired) bluetooth devices.
- * @type {options.DeletableItemList}
- * @private
- */
- deviceList_: null,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
- this.createDeviceList_();
-
- BluetoothOptions.updateDiscoveryState(true);
-
- $('bluetooth-add-device-cancel-button').onclick = function(event) {
- PageManager.closeOverlay();
- };
-
- var self = this;
- $('bluetooth-add-device-apply-button').onclick = function(event) {
- chrome.send('coreOptionsUserMetricsAction',
- ['Options_BluetoothConnectNewDevice']);
- var device = self.deviceList_.selectedItem;
- var address = device.address;
- PageManager.closeOverlay();
- device.pairing = 'bluetoothStartConnecting';
- options.BluetoothPairing.showDialog(device);
- chrome.send('updateBluetoothDevice', [address, 'connect']);
- };
-
- $('bluetooth-unpaired-devices-list').addEventListener('change',
- function() {
- var item = $('bluetooth-unpaired-devices-list').selectedItem;
- // The "bluetooth-add-device-apply-button" should be enabled for devices
- // that can be paired or remembered. Devices not supporting pairing will
- // be just remembered and later reported as "item.paired" = true. The
- // button should be disabled in any other case:
- // * No item is selected (item is undefined).
- // * Paired devices (item.paired is true) are already paired and a new
- // pairing attempt will fail. Paired devices could appear in this list
- // shortly after the pairing initiated in another window finishes.
- // * "Connecting" devices (item.connecting is true) are in the process
- // of a pairing or connection. Another attempt to pair before the
- // ongoing pair finishes will fail, so the button should be disabled.
- var disabled = !item || item.paired || item.connecting;
- $('bluetooth-add-device-apply-button').disabled = disabled;
- });
- },
-
- /** @override */
- didClosePage: function() {
- chrome.send('stopBluetoothDeviceDiscovery');
- },
-
- /**
- * Creates, decorates and initializes the bluetooth device list.
- * @private
- */
- createDeviceList_: function() {
- var deviceList = $('bluetooth-unpaired-devices-list');
- options.system.bluetooth.BluetoothDeviceList.decorate(deviceList);
- this.deviceList_ = assertInstanceof(deviceList,
- options.DeletableItemList);
- }
- };
-
- /**
- * Automatically start the device discovery process if the
- * "Add device" dialog is visible.
- */
- BluetoothOptions.startDeviceDiscovery = function() {
- var page = BluetoothOptions.getInstance();
- if (page && page.visible)
- chrome.send('findBluetoothDevices');
- };
-
- /**
- * Updates the dialog to show that device discovery has stopped. Updates the
- * label text and hides/unhides the spinner. based on discovery state.
- */
- BluetoothOptions.updateDiscoveryState = function(discovering) {
- $('bluetooth-scanning-label').hidden = !discovering;
- $('bluetooth-scanning-icon').hidden = !discovering;
- $('bluetooth-scan-stopped-label').hidden = discovering;
- };
-
- /**
- * If the "Add device" dialog is visible, dismiss it.
- */
- BluetoothOptions.dismissOverlay = function() {
- var page = BluetoothOptions.getInstance();
- if (page && page.visible)
- PageManager.closeOverlay();
- };
-
- // Export
- return {
- BluetoothOptions: BluetoothOptions
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth_device_list.js b/chromium/chrome/browser/resources/options/chromeos/bluetooth_device_list.js
deleted file mode 100644
index 7db87b0e94d..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth_device_list.js
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @typedef {{name: string,
- * address: string,
- * paired: boolean,
- * connected: boolean,
- * connecting: boolean,
- * connectable: boolean,
- * pairing: (string|undefined),
- * passkey: (number|undefined),
- * pincode: (string|undefined),
- * entered: (number|undefined)}}
- */
-var BluetoothDevice;
-
-cr.define('options.system.bluetooth', function() {
- /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
- /** @const */ var DeletableItem = options.DeletableItem;
- /** @const */ var DeletableItemList = options.DeletableItemList;
- /** @const */ var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
-
- /**
- * Bluetooth settings constants.
- */
- function Constants() {}
-
- /**
- * Creates a new bluetooth list item.
- * @param {BluetoothDevice} device Description of the Bluetooth device.
- * @constructor
- * @extends {options.DeletableItem}
- */
- function BluetoothListItem(device) {
- var el = cr.doc.createElement('div');
- el.__proto__ = BluetoothListItem.prototype;
- el.data = {};
- for (var key in device)
- el.data[key] = device[key];
- el.decorate();
- // Only show the close button for paired devices, but not for connecting
- // devices.
- el.deletable = device.paired && !device.connecting;
- return el;
- }
-
- BluetoothListItem.prototype = {
- __proto__: DeletableItem.prototype,
-
- /**
- * Description of the Bluetooth device.
- * @type {?BluetoothDevice}
- */
- data: null,
-
- /** @override */
- decorate: function() {
- DeletableItem.prototype.decorate.call(this);
- var label = this.ownerDocument.createElement('div');
- label.className = 'bluetooth-device-label';
- this.classList.add('bluetooth-device');
- // There are four kinds of devices we want to distinguish:
- // * Connecting devices: in bold with a "connecting" label,
- // * Connected devices: in bold,
- // * Paired, not connected but connectable devices: regular and
- // * Paired, not connected and not connectable devices: grayed out.
- this.connected = this.data.connecting ||
- (this.data.paired && this.data.connected);
- this.notconnectable = this.data.paired && !this.data.connecting &&
- !this.data.connected && !this.data.connectable;
- // "paired" devices are those that are remembered but not connected.
- this.paired = this.data.paired && !this.data.connected &&
- this.data.connectable;
-
- var content = this.data.name;
- // Update the device's label according to its state. A "connecting" device
- // can be in the process of connecting and pairing, so we check connecting
- // first.
- if (this.data.connecting) {
- content = loadTimeData.getStringF('bluetoothDeviceConnecting',
- this.data.name);
- }
- label.textContent = content;
- this.contentElement.appendChild(label);
- },
- };
-
- /**
- * Class for displaying a list of Bluetooth devices.
- * @constructor
- * @extends {options.DeletableItemList}
- */
- var BluetoothDeviceList = cr.ui.define('list');
-
- BluetoothDeviceList.prototype = {
- __proto__: DeletableItemList.prototype,
-
- /**
- * Height of a list entry in px.
- * @type {number}
- * @private
- */
- itemHeight_: 32,
-
- /**
- * Width of a list entry in px.
- * @type {number}
- * @private
- */
- itemWidth_: 400,
-
- /** @override */
- decorate: function() {
- DeletableItemList.prototype.decorate.call(this);
- // Force layout of all items even if not in the viewport to address
- // errors in scroll positioning when the list is hidden during initial
- // layout. The impact on performance should be minimal given that the
- // list is not expected to grow very large. Fixed height items are also
- // required to avoid caching incorrect sizes during layout of a hidden
- // list.
- this.autoExpands = true;
- this.fixedHeight = true;
- this.clear();
- this.selectionModel = new ListSingleSelectionModel();
- },
-
- /**
- * Adds a bluetooth device to the list of available devices. A check is
- * made to see if the device is already in the list, in which case the
- * existing device is updated.
- * @param {{name: string,
- * address: string,
- * paired: boolean,
- * connected: boolean,
- * connecting: boolean,
- * connectable: boolean,
- * pairing: (string|undefined),
- * passkey: (number|undefined),
- * pincode: (string|undefined),
- * entered: (number|undefined)}} device
- * Description of the bluetooth device.
- * @return {boolean} True if the devies was successfully added or updated.
- */
- appendDevice: function(device) {
- var selectedDevice = this.getSelectedDevice_();
- var index = this.find(device.address);
- if (index == undefined) {
- this.dataModel.push(device);
- this.redraw();
- } else {
- this.dataModel.splice(index, 1, device);
- this.redrawItem(index);
- }
- this.updateListVisibility_();
- if (selectedDevice)
- this.setSelectedDevice_(selectedDevice);
- return true;
- },
-
- /**
- * Forces a revailidation of the list content. Deleting a single item from
- * the list results in a stale cache requiring an invalidation.
- * @param {string=} opt_selection Optional address of device to select
- * after refreshing the list.
- */
- refresh: function(opt_selection) {
- // TODO(kevers): Investigate if the stale cache issue can be fixed in
- // cr.ui.list.
- var selectedDevice = opt_selection ? opt_selection :
- this.getSelectedDevice_();
- this.invalidate();
- this.redraw();
- if (selectedDevice)
- this.setSelectedDevice_(selectedDevice);
- },
-
- /**
- * Retrieves the address of the selected device, or null if no device is
- * selected.
- * @return {(string|undefined)} Address of selected device or null.
- * @private
- */
- getSelectedDevice_: function() {
- var selection = this.selectedItem;
- if (selection)
- return selection.address;
- return undefined;
- },
-
- /**
- * Selects the device with the matching address.
- * @param {string} address The unique address of the device.
- * @private
- */
- setSelectedDevice_: function(address) {
- var index = this.find(address);
- if (index != undefined)
- this.selectionModel.selectRange(index, index);
- },
-
- /**
- * Perges all devices from the list.
- */
- clear: function() {
- this.dataModel = new ArrayDataModel([]);
- this.redraw();
- this.updateListVisibility_();
- },
-
- /**
- * Returns the index of the list entry with the matching address.
- * @param {string} address Unique address of the Bluetooth device.
- * @return {number|undefined} Index of the matching entry or
- * undefined if no match found.
- */
- find: function(address) {
- var size = this.dataModel.length;
- for (var i = 0; i < size; i++) {
- var entry = this.dataModel.item(i);
- if (entry.address == address)
- return i;
- }
- },
-
- /**
- * @override
- * @param {BluetoothDevice} entry
- */
- createItem: function(entry) {
- return new BluetoothListItem(entry);
- },
-
- /**
- * Overrides the default implementation, which is used to compute the
- * size of an element in the list. The default implementation relies
- * on adding a placeholder item to the list and fetching its size and
- * position. This strategy does not work if an item is added to the list
- * while it is hidden, as the computed metrics will all be zero in that
- * case.
- * @return {{height: number, marginTop: number, marginBottom: number,
- * width: number, marginLeft: number, marginRight: number}}
- * The height and width of the item, taking margins into account,
- * and the margins themselves.
- */
- measureItem: function() {
- return {
- height: this.itemHeight_,
- marginTop: 0,
- marginBottom: 0,
- width: this.itemWidth_,
- marginLeft: 0,
- marginRight: 0
- };
- },
-
- /**
- * Override the default implementation to return a predetermined size,
- * which in turns allows proper layout of items even if the list is hidden.
- * @return {{height: number, width: number}} Dimensions of a single item in
- * the list of bluetooth device.
- * @private
- */
- getDefaultItemSize_: function() {
- return {
- height: this.itemHeight_,
- width: this.itemWidth_
- };
- },
-
- /**
- * Override base implementation of handleClick, which unconditionally
- * removes the item. In this case, removal of the element is deferred
- * pending confirmation from the Bluetooth adapter.
- * @param {Event} e The click event object.
- * @override
- */
- handleClick: function(e) {
- if (this.disabled)
- return;
-
- var target = /** @type {HTMLElement} */(e.target);
- if (!target.classList.contains('row-delete-button'))
- return;
-
- var item = this.getListItemAncestor(target);
- var selected = this.selectionModel.selectedIndex;
- var index = this.getIndexOfListItem(item);
- if (item && item.deletable) {
- if (selected != index)
- this.setSelectedDevice_(item.data.address);
- // Device is busy until we hear back from the Bluetooth adapter.
- // Prevent double removal request.
- item.deletable = false;
- // TODO(kevers): Provide visual feedback that the device is busy.
-
- // Inform the bluetooth adapter that we are disconnecting or
- // forgetting the device.
- chrome.send('updateBluetoothDevice',
- [item.data.address, item.connected ? 'disconnect' : 'forget']);
-
- chrome.send('coreOptionsUserMetricsAction',
- ['Options_BluetoothRemoveDevice']);
- }
- },
-
- /** @override */
- deleteItemAtIndex: function(index) {
- var selectedDevice = this.getSelectedDevice_();
- this.dataModel.splice(index, 1);
- this.refresh(selectedDevice);
- this.updateListVisibility_();
- },
-
- /**
- * If the list has an associated empty list placholder then update the
- * visibility of the list and placeholder.
- * @private
- */
- updateListVisibility_: function() {
- var empty = this.dataModel.length == 0;
- var listPlaceHolderID = this.id + '-empty-placeholder';
- if ($(listPlaceHolderID)) {
- if (this.hidden != empty) {
- this.hidden = empty;
- $(listPlaceHolderID).hidden = !empty;
- this.refresh();
- }
- }
- },
- };
-
- cr.defineProperty(BluetoothListItem, 'connected', cr.PropertyKind.BOOL_ATTR);
-
- cr.defineProperty(BluetoothListItem, 'paired', cr.PropertyKind.BOOL_ATTR);
-
- cr.defineProperty(BluetoothListItem, 'connecting', cr.PropertyKind.BOOL_ATTR);
-
- cr.defineProperty(BluetoothListItem, 'notconnectable',
- cr.PropertyKind.BOOL_ATTR);
-
- return {
- BluetoothListItem: BluetoothListItem,
- BluetoothDeviceList: BluetoothDeviceList,
- Constants: Constants
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.html b/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.html
deleted file mode 100644
index 95b9c0339d5..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<div id="bluetooth-pairing" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="bluetoothAddDeviceTitle"></h1>
- <div id="bluetooth-pairing-message-area" class="content-area">
- <div id="bluetooth-pairing-message-contents">
- <div id="bluetooth-pairing-instructions"></div>
- <div id="bluetooth-pairing-passkey-display" hidden></div>
- <div id="bluetooth-pairing-passkey-entry" hidden>
- <input id="bluetooth-passkey" maxlength="6" type="text">
- </div>
- <div id="bluetooth-pairing-pincode-entry" hidden>
- <input id="bluetooth-pincode" maxlength="16" type="text">
- </div>
- </div>
- </div>
- <div class="action-area button-strip">
- <button id="bluetooth-pair-device-cancel-button" type="reset"
- i18n-content="cancel" hidden></button>
- <button id="bluetooth-pair-device-connect-button" type="reset"
- i18n-content="bluetoothConnectDevice" hidden></button>
- <button id="bluetooth-pair-device-reject-button" type="reset"
- i18n-content="bluetoothRejectPasskey" hidden></button>
- <button id="bluetooth-pair-device-accept-button" type="reset"
- i18n-content="bluetoothAcceptPasskey" hidden></button>
- <button id="bluetooth-pair-device-dismiss-button" type="reset"
- i18n-content="bluetoothDismissError" hidden></button>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js b/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js
deleted file mode 100644
index 63b9ee4a708..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- /** @const */ var Page = cr.ui.pageManager.Page;
- /** @const */ var PageManager = cr.ui.pageManager.PageManager;
-
- /**
- * Enumeration of possible states during pairing. The value associated with
- * each state maps to a localized string in the global variable
- * |loadTimeData|.
- * @enum {string}
- */
- var PAIRING = {
- STARTUP: 'bluetoothStartConnecting',
- ENTER_PIN_CODE: 'bluetoothEnterPinCode',
- ENTER_PASSKEY: 'bluetoothEnterPasskey',
- REMOTE_PIN_CODE: 'bluetoothRemotePinCode',
- REMOTE_PASSKEY: 'bluetoothRemotePasskey',
- CONFIRM_PASSKEY: 'bluetoothConfirmPasskey',
- CONNECT_FAILED: 'bluetoothConnectFailed',
- CANCELED: 'bluetoothPairingCanceled',
- DISMISSED: 'bluetoothPairingDismissed', // pairing dismissed(succeeded or
- // canceled).
- };
-
- /**
- * List of IDs for conditionally visible elements in the dialog.
- * @type {Array<string>}
- * @const
- */
- var ELEMENTS = ['bluetooth-pairing-passkey-display',
- 'bluetooth-pairing-passkey-entry',
- 'bluetooth-pairing-pincode-entry',
- 'bluetooth-pair-device-connect-button',
- 'bluetooth-pair-device-cancel-button',
- 'bluetooth-pair-device-accept-button',
- 'bluetooth-pair-device-reject-button',
- 'bluetooth-pair-device-dismiss-button'];
-
- /**
- * Encapsulated handling of the Bluetooth device pairing page.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function BluetoothPairing() {
- Page.call(this, 'bluetoothPairing',
- loadTimeData.getString('bluetoothOptionsPageTabTitle'),
- 'bluetooth-pairing');
- }
-
- cr.addSingletonGetter(BluetoothPairing);
-
- BluetoothPairing.prototype = {
- __proto__: Page.prototype,
-
- /**
- * Description of the bluetooth device.
- * @type {?BluetoothDevice}
- * @private
- */
- device_: null,
-
- /**
- * Can the dialog be programmatically dismissed.
- * @type {boolean}
- */
- dismissible_: true,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
- var self = this;
- $('bluetooth-pair-device-cancel-button').onclick = function() {
- PageManager.closeOverlay();
- };
- $('bluetooth-pair-device-reject-button').onclick = function() {
- chrome.send('updateBluetoothDevice',
- [self.device_.address, 'reject']);
- self.device_.pairing = PAIRING.DISMISSED;
- PageManager.closeOverlay();
- };
- $('bluetooth-pair-device-connect-button').onclick = function() {
- var args = [self.device_.address, 'connect'];
- var passkey = self.device_.passkey;
- if (passkey)
- args.push(String(passkey));
- else if (!$('bluetooth-pairing-passkey-entry').hidden)
- args.push($('bluetooth-passkey').value);
- else if (!$('bluetooth-pairing-pincode-entry').hidden)
- args.push($('bluetooth-pincode').value);
- chrome.send('updateBluetoothDevice', args);
- // Prevent sending a 'connect' command twice.
- $('bluetooth-pair-device-connect-button').disabled = true;
- };
- $('bluetooth-pair-device-accept-button').onclick = function() {
- chrome.send('updateBluetoothDevice',
- [self.device_.address, 'accept']);
- // Prevent sending a 'accept' command twice.
- $('bluetooth-pair-device-accept-button').disabled = true;
- };
- $('bluetooth-pair-device-dismiss-button').onclick = function() {
- PageManager.closeOverlay();
- };
- $('bluetooth-passkey').oninput = function() {
- var inputField = $('bluetooth-passkey');
- var value = inputField.value;
- // Note that using <input type="number"> is insufficient to restrict
- // the input as it allows negative numbers and does not limit the
- // number of charactes typed even if a range is set. Furthermore,
- // it sometimes produces strange repaint artifacts.
- var filtered = value.replace(/[^0-9]/g, '');
- if (filtered != value)
- inputField.value = filtered;
- $('bluetooth-pair-device-connect-button').disabled =
- inputField.value.length == 0;
- };
- $('bluetooth-pincode').oninput = function() {
- $('bluetooth-pair-device-connect-button').disabled =
- $('bluetooth-pincode').value.length == 0;
- };
- $('bluetooth-passkey').addEventListener('keydown',
- this.keyDownEventHandler_.bind(this));
- $('bluetooth-pincode').addEventListener('keydown',
- this.keyDownEventHandler_.bind(this));
- },
-
- /** @override */
- didClosePage: function() {
- if (this.device_.pairing != PAIRING.DISMISSED &&
- this.device_.pairing != PAIRING.CONNECT_FAILED) {
- this.device_.pairing = PAIRING.CANCELED;
- chrome.send('updateBluetoothDevice',
- [this.device_.address, 'cancel']);
- }
- },
-
- /**
- * Override to prevent showing the overlay if the Bluetooth device details
- * have not been specified. Prevents showing an empty dialog if the user
- * quits and restarts Chrome while in the process of pairing with a device.
- * @return {boolean} True if the overlay can be displayed.
- */
- canShowPage: function() {
- return !!(this.device_ && this.device_.address && this.device_.pairing);
- },
-
- /**
- * Sets input focus on the passkey or pincode field if appropriate.
- */
- didShowPage: function() {
- if (!$('bluetooth-pincode').hidden)
- $('bluetooth-pincode').focus();
- else if (!$('bluetooth-passkey').hidden)
- $('bluetooth-passkey').focus();
- },
-
- /**
- * Configures the overlay for pairing a device.
- * @param {Object} device Description of the bluetooth device.
- */
- update: function(device) {
- this.device_ = /** @type {BluetoothDevice} */({});
- for (var key in device)
- this.device_[key] = device[key];
- // Update the pairing instructions.
- var instructionsEl = assert($('bluetooth-pairing-instructions'));
- this.clearElement_(instructionsEl);
- this.dismissible_ = ('dismissible' in device) ?
- device.dismissible : true;
-
- var message = loadTimeData.getString(device.pairing);
- message = message.replace('%1', this.device_.name);
- instructionsEl.textContent = message;
-
- // Update visibility of dialog elements.
- if (this.device_.passkey) {
- this.updatePasskey_(String(this.device_.passkey));
- if (this.device_.pairing == PAIRING.CONFIRM_PASSKEY) {
- // Confirming a match between displayed passkeys.
- this.displayElements_(['bluetooth-pairing-passkey-display',
- 'bluetooth-pair-device-accept-button',
- 'bluetooth-pair-device-reject-button']);
- $('bluetooth-pair-device-accept-button').disabled = false;
- } else {
- // Remote entering a passkey.
- this.displayElements_(['bluetooth-pairing-passkey-display',
- 'bluetooth-pair-device-cancel-button']);
- }
- } else if (this.device_.pincode) {
- this.updatePasskey_(String(this.device_.pincode));
- this.displayElements_(['bluetooth-pairing-passkey-display',
- 'bluetooth-pair-device-cancel-button']);
- } else if (this.device_.pairing == PAIRING.ENTER_PIN_CODE) {
- // Prompting the user to enter a PIN code.
- this.displayElements_(['bluetooth-pairing-pincode-entry',
- 'bluetooth-pair-device-connect-button',
- 'bluetooth-pair-device-cancel-button']);
- $('bluetooth-pincode').value = '';
- } else if (this.device_.pairing == PAIRING.ENTER_PASSKEY) {
- // Prompting the user to enter a passkey.
- this.displayElements_(['bluetooth-pairing-passkey-entry',
- 'bluetooth-pair-device-connect-button',
- 'bluetooth-pair-device-cancel-button']);
- $('bluetooth-passkey').value = '';
- } else if (this.device_.pairing == PAIRING.STARTUP) {
- // Starting the pairing process.
- this.displayElements_(['bluetooth-pair-device-cancel-button']);
- } else {
- // Displaying an error message.
- this.displayElements_(['bluetooth-pair-device-dismiss-button']);
- }
- // User is required to enter a passkey or pincode before the connect
- // button can be enabled. The 'oninput' methods for the input fields
- // determine when the connect button becomes active.
- $('bluetooth-pair-device-connect-button').disabled = true;
- },
-
- /**
- * Handles the ENTER key for the passkey or pincode entry field.
- * @param {Event} event A keydown event.
- * @private
- */
- keyDownEventHandler_: function(event) {
- /** @const */ var ENTER_KEY_CODE = 13;
- if (event.keyCode == ENTER_KEY_CODE) {
- var button = $('bluetooth-pair-device-connect-button');
- if (!button.hidden)
- button.click();
- }
- },
-
- /**
- * Updates the visibility of elements in the dialog.
- * @param {Array<string>} list List of conditionally visible elements that
- * are to be made visible.
- * @private
- */
- displayElements_: function(list) {
- var enabled = {};
- for (var i = 0; i < list.length; i++) {
- var key = list[i];
- enabled[key] = true;
- }
- for (var i = 0; i < ELEMENTS.length; i++) {
- var key = ELEMENTS[i];
- $(key).hidden = !enabled[key];
- }
- },
-
- /**
- * Removes all children from an element.
- * @param {!Element} element Target element to clear.
- */
- clearElement_: function(element) {
- var child = element.firstChild;
- while (child) {
- element.removeChild(child);
- child = element.firstChild;
- }
- },
-
- /**
- * Formats an element for displaying the passkey or PIN code.
- * @param {string} key Passkey or PIN to display.
- */
- updatePasskey_: function(key) {
- var passkeyEl = assert($('bluetooth-pairing-passkey-display'));
- var keyClass = (this.device_.pairing == PAIRING.REMOTE_PASSKEY ||
- this.device_.pairing == PAIRING.REMOTE_PIN_CODE) ?
- 'bluetooth-keyboard-button' : 'bluetooth-passkey-char';
- this.clearElement_(passkeyEl);
- // Passkey should always have 6 digits.
- key = '000000'.substring(0, 6 - key.length) + key;
- var progress = this.device_.entered;
- for (var i = 0; i < key.length; i++) {
- var keyEl = document.createElement('span');
- keyEl.textContent = key.charAt(i);
- keyEl.className = keyClass;
- if (progress != undefined) {
- if (i < progress)
- keyEl.classList.add('key-typed');
- else if (i == progress)
- keyEl.classList.add('key-next');
- else
- keyEl.classList.add('key-untyped');
- }
- passkeyEl.appendChild(keyEl);
- }
- if (this.device_.pairing == PAIRING.REMOTE_PASSKEY ||
- this.device_.pairing == PAIRING.REMOTE_PIN_CODE) {
- // Add enter key.
- var label = loadTimeData.getString('bluetoothEnterKey');
- var keyEl = document.createElement('span');
- keyEl.textContent = label;
- keyEl.className = keyClass;
- keyEl.id = 'bluetooth-enter-key';
- if (progress != undefined) {
- if (progress > key.length)
- keyEl.classList.add('key-typed');
- else if (progress == key.length)
- keyEl.classList.add('key-next');
- else
- keyEl.classList.add('key-untyped');
- }
- passkeyEl.appendChild(keyEl);
- }
- passkeyEl.hidden = false;
- },
- };
-
- /**
- * Configures the device pairing instructions and displays the pairing
- * overlay.
- * @param {Object} device Description of the Bluetooth device.
- */
- BluetoothPairing.showDialog = function(device) {
- BluetoothPairing.getInstance().update(device);
- PageManager.showPageByName('bluetoothPairing', false);
- };
-
- /**
- * Displays a message from the Bluetooth adapter.
- * @param {{message: string, address: string}} data Data for constructing the
- * message. |data.message| is the name of message to show. |data.address|
- * is the device address.
- */
- BluetoothPairing.showMessage = function(data) {
- var name = data.address;
- if (name.length == 0)
- return;
- var dialog = BluetoothPairing.getInstance();
- if (dialog.device_ && name == dialog.device_.address &&
- dialog.device_.pairing == PAIRING.CANCELED) {
- // Do not show any error message after cancelation of the pairing.
- return;
- }
-
- var list = $('bluetooth-paired-devices-list');
- if (list) {
- var index = list.find(name);
- if (index == undefined) {
- list = $('bluetooth-unpaired-devices-list');
- index = list.find(name);
- }
- if (index != undefined) {
- var entry = list.dataModel.item(index);
- if (entry && entry.name)
- name = entry.name;
- }
- }
- BluetoothPairing.showDialog({name: name,
- address: data.address,
- pairing: data.message,
- dismissible: false});
- };
-
- /**
- * Closes the Bluetooth pairing dialog.
- */
- BluetoothPairing.dismissDialog = function() {
- var overlay = PageManager.getTopmostVisiblePage();
- var dialog = BluetoothPairing.getInstance();
- if (overlay == dialog && dialog.dismissible_) {
- dialog.device_.pairing = PAIRING.DISMISSED;
- PageManager.closeOverlay();
- }
- };
-
- // Export
- return {
- BluetoothPairing: BluetoothPairing
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/browser_options.css b/chromium/chrome/browser/resources/options/chromeos/browser_options.css
deleted file mode 100644
index e02cae24c7d..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/browser_options.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#sync-section {
- min-height: 64px;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.css b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.css
deleted file mode 100644
index 9ca91f86f46..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.css
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#user-images-area {
- display: -webkit-box;
-}
-
-#user-image-grid {
- -webkit-user-drag: none;
- -webkit-user-select: none;
- height: 264px;
- margin: 10px;
- outline: none;
- /* Necessary for correct metrics calculation by grid.js. */
- overflow: hidden;
- padding: 0;
- width: 530px;
-}
-
-#user-image-grid * {
- margin: 0;
- padding: 0;
-}
-
-#user-image-grid img {
- background-color: white;
- height: 64px;
- vertical-align: middle;
- width: 64px;
-}
-
-#user-image-grid > li {
- border: 1px solid rgba(0, 0, 0, 0.15);
- border-radius: 4px;
- display: inline-block;
- margin: 8px;
- padding: 3px;
-}
-
-#user-image-grid [selected] {
- border: 2px solid rgb(0, 102, 204);
- padding: 2px;
-}
-
-/**
- * #user-image-preview can have the following classes:
- * .default-image: one of the default images is selected (including the grey
- * silhouette);
- * .profile-image: profile image is selected;
- * .online: camera is streaming video;
- * .camera: camera (live or photo) is selected;
- * .live: camera is in live mode (no photo taken yet/last photo removed).
- */
-
-#user-image-preview {
- margin: 18px 10px 0 0;
- max-width: 220px;
- position: relative;
-}
-
-#user-image-preview .perspective-box {
- -webkit-perspective: 600px;
- border: solid 1px #cacaca;
- border-radius: 4px;
- padding: 3px;
- width: 220px;
-}
-
-#user-image-preview-img {
- background: white;
- border: solid 1px #cacaca;
- border-radius: 4px;
- max-height: 220px;
- max-width: 220px;
- padding: 3px;
-}
-
-.camera.live #user-image-preview-img {
- display: none;
-}
-
-.animation #user-image-preview-img {
- -webkit-transition: -webkit-transform 200ms linear;
-}
-
-.camera.flip-x #user-image-preview-img {
- -webkit-transform: rotateY(180deg);
-}
-
-.user-image-stream-area {
- display: none;
- position: relative;
-}
-
-.camera.live .user-image-stream-area {
- display: block;
-}
-
-#user-image-stream-crop {
- /* TODO(ivankr): temporary workaround for crbug.com/142347. */
- -webkit-transform: rotateY(360deg);
- -webkit-transition: -webkit-transform 200ms linear;
- height: 220px;
- overflow: hidden;
- position: relative;
- width: 220px;
-}
-
-.flip-x #user-image-stream-crop {
- -webkit-transform: rotateY(180deg);
-}
-
-/* TODO(ivankr): specify dimensions from real capture size. */
-.user-image-stream {
- border: solid 1px #cacaca;
- height: 220px;
- /* Center image for 4:3 aspect ratio. */
- left: -16.6%;
- position: absolute;
- visibility: hidden;
-}
-
-.online .user-image-stream {
- visibility: visible;
-}
-
-.user-image-stream-area .spinner {
- display: none;
- height: 44px;
- left: 50%;
- margin: -22px 0 0 -22px;
- position: absolute;
- top: 50%;
- width: 44px;
-}
-
-.camera.live:not(.online) .user-image-stream-area .spinner {
- display: block;
-}
-
-#flip-photo {
- -webkit-transition: opacity 75ms linear;
- background: url(chrome://theme/IDR_MIRROR_FLIP) no-repeat;
- border: none;
- bottom: 44px; /* 8px + image bottom. */
- display: block;
- height: 32px;
- opacity: 0;
- position: absolute;
- right: 8px;
- width: 32px;
-}
-
-/* TODO(merkulova): remove when webkit crbug.com/126479 is fixed. */
-.flip-trick {
- -webkit-transform: translateZ(1px);
-}
-
-html[dir=rtl] #flip-photo {
- left: 8px;
- right: auto;
-}
-
-/* "Flip photo" button is hidden during flip animation. */
-.camera.online:not(.animation) #flip-photo,
-.camera:not(.live):not(.animation) #flip-photo {
- opacity: 0.75;
-}
-
-#discard-photo,
-#take-photo {
- display: none;
- height: 25px;
- margin: 4px;
- padding: 0;
- width: 220px;
-}
-
-.camera:not(.live) #discard-photo {
- background: url(chrome://theme/IDR_USER_IMAGE_RECYCLE)
- no-repeat center center;
- display: block;
-}
-
-.camera.live.online #take-photo {
- background: url(chrome://theme/IDR_USER_IMAGE_CAPTURE)
- no-repeat center -1px;
- display: block;
-}
-
-#user-image-attribution {
- -webkit-padding-start: 34px;
- line-height: 26px;
-}
-
-#user-image-author-website {
- -webkit-padding-start: 5px;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.html b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.html
deleted file mode 100644
index 146585dc904..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<div id="change-picture-page" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="changePicturePage"></h1>
- <div class="content-area">
- <div i18n-content="changePicturePageDescription"></div>
- <div id="user-images-area">
- <grid id="user-image-grid" class="user-image-picker" tabindex="1"></grid>
- <div id="user-image-preview">
- <img id="user-image-preview-img" i18n-values="alt:previewAltText">
- <div class="user-image-stream-area">
- <div class="perspective-box">
- <div id="user-image-stream-crop">
- <video class="user-image-stream" autoplay></video>
- </div>
- </div>
- <div class="spinner"></div>
- </div>
- <button id="discard-photo" i18n-values="title:discardPhoto"
- tabindex="2"></button>
- <button id="take-photo" i18n-values="title:takePhoto" tabindex="2">
- </button>
- <button id="flip-photo" class="custom-appearance"
- i18n-values="title:flipPhoto" tabindex="1"></button>
- </div>
- </div>
- <div id="user-image-attribution">
- <span i18n-content="authorCredit"></span>
- <strong id="user-image-author-name"></strong>
- <a id="user-image-author-website" target="_blank"></a>
- </div>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="change-picture-overlay-confirm" i18n-content="done"
- tabindex="2"></button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.js b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.js
deleted file mode 100644
index de6670a4c7b..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.js
+++ /dev/null
@@ -1,331 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
- var UserImagesGrid = options.UserImagesGrid;
- var ButtonImages = UserImagesGrid.ButtonImages;
-
- /**
- * Array of button URLs used on this page.
- * @type {Array<string>}
- * @const
- */
- var ButtonImageUrls = [
- ButtonImages.TAKE_PHOTO,
- ButtonImages.CHOOSE_FILE
- ];
-
- /////////////////////////////////////////////////////////////////////////////
- // ChangePictureOptions class:
-
- /**
- * Encapsulated handling of ChromeOS change picture options page.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function ChangePictureOptions() {
- Page.call(this, 'changePicture',
- loadTimeData.getString('changePicturePage'),
- 'change-picture-page');
- }
-
- cr.addSingletonGetter(ChangePictureOptions);
-
- ChangePictureOptions.prototype = {
- // Inherit ChangePictureOptions from Page.
- __proto__: Page.prototype,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
-
- var imageGrid = $('user-image-grid');
- UserImagesGrid.decorate(imageGrid);
-
- // Preview image will track the selected item's URL.
- var previewElement = $('user-image-preview');
- previewElement.oncontextmenu = function(e) { e.preventDefault(); };
-
- imageGrid.previewElement = previewElement;
- imageGrid.selectionType = 'default';
- imageGrid.flipPhotoElement = $('flip-photo');
-
- imageGrid.addEventListener('select',
- this.handleImageSelected_.bind(this));
- imageGrid.addEventListener('activate',
- this.handleImageActivated_.bind(this));
- imageGrid.addEventListener('phototaken',
- this.handlePhotoTaken_.bind(this));
- imageGrid.addEventListener('photoupdated',
- this.handlePhotoTaken_.bind(this));
-
- // Add the "Choose file" button.
- imageGrid.addItem(ButtonImages.CHOOSE_FILE,
- loadTimeData.getString('chooseFile'),
- this.handleChooseFile_.bind(this)).type = 'file';
-
- // Profile image data.
- this.profileImage_ = imageGrid.addItem(
- ButtonImages.PROFILE_PICTURE,
- loadTimeData.getString('profilePhotoLoading'));
- this.profileImage_.type = 'profile';
-
- // Set the title for camera item in the grid.
- imageGrid.setCameraTitles(
- loadTimeData.getString('takePhoto'),
- loadTimeData.getString('photoFromCamera'));
-
- $('take-photo').addEventListener(
- 'click', this.handleTakePhoto_.bind(this));
- $('discard-photo').addEventListener(
- 'click', this.handleDiscardPhoto_.bind(this));
-
- // Toggle 'animation' class for the duration of WebKit transition.
- $('flip-photo').addEventListener(
- 'click', this.handleFlipPhoto_.bind(this));
- $('user-image-stream-crop').addEventListener(
- 'webkitTransitionEnd', function(e) {
- previewElement.classList.remove('animation');
- });
- $('user-image-preview-img').addEventListener(
- 'webkitTransitionEnd', function(e) {
- previewElement.classList.remove('animation');
- });
-
- // Old user image data (if present).
- this.oldImage_ = null;
-
- $('change-picture-overlay-confirm').addEventListener(
- 'click', this.closeOverlay_.bind(this));
-
- chrome.send('onChangePicturePageInitialized');
- },
-
- /** @override */
- didShowPage: function() {
- var imageGrid = $('user-image-grid');
- // Reset camera element.
- imageGrid.cameraImage = null;
- imageGrid.updateAndFocus();
- chrome.send('onChangePicturePageShown');
- },
-
- /** @override */
- willHidePage: function() {
- var imageGrid = $('user-image-grid');
- imageGrid.blur(); // Make sure the image grid is not active.
- imageGrid.stopCamera();
- if (this.oldImage_) {
- imageGrid.removeItem(this.oldImage_);
- this.oldImage_ = null;
- }
- chrome.send('onChangePicturePageHidden');
- },
-
- /**
- * Either willHidePage or didClosePage may be called depending on the way
- * the page was closed.
- * @override
- */
- didClosePage: function() {
- this.willHidePage();
- },
-
- /**
- * Closes the overlay, returning to the main settings page.
- * @private
- */
- closeOverlay_: function() {
- if (!$('change-picture-page').hidden)
- PageManager.closeOverlay();
- },
-
- /**
- * Handle camera-photo flip.
- */
- handleFlipPhoto_: function() {
- var imageGrid = $('user-image-grid');
- imageGrid.previewElement.classList.add('animation');
- imageGrid.flipPhoto = !imageGrid.flipPhoto;
- var flipMessageId = imageGrid.flipPhoto ?
- 'photoFlippedAccessibleText' : 'photoFlippedBackAccessibleText';
- announceAccessibleMessage(loadTimeData.getString(flipMessageId));
- },
-
- /**
- * Handles "Take photo" button click.
- * @private
- */
- handleTakePhoto_: function() {
- $('user-image-grid').takePhoto();
- chrome.send('takePhoto');
- },
-
- /**
- * Handle photo captured event.
- * @param {Event} e Event with 'dataURL' property containing a data URL.
- */
- handlePhotoTaken_: function(e) {
- chrome.send('photoTaken', [e.dataURL]);
- announceAccessibleMessage(
- loadTimeData.getString('photoCaptureAccessibleText'));
- },
-
- /**
- * Handles "Discard photo" button click.
- * @private
- */
- handleDiscardPhoto_: function() {
- $('user-image-grid').discardPhoto();
- chrome.send('discardPhoto');
- announceAccessibleMessage(
- loadTimeData.getString('photoDiscardAccessibleText'));
- },
-
- /**
- * Handles "Choose a file" button activation.
- * @private
- */
- handleChooseFile_: function() {
- chrome.send('chooseFile');
- this.closeOverlay_();
- },
-
- /**
- * Handles image selection change.
- * @param {Event} e Selection change Event.
- * @private
- */
- handleImageSelected_: function(e) {
- var imageGrid = $('user-image-grid');
- var url = imageGrid.selectedItemUrl;
-
- // Flip button available only for camera picture.
- imageGrid.flipPhotoElement.tabIndex =
- imageGrid.selectionType == 'camera' ? 1 : -1;
- // Ignore selection change caused by program itself and selection of one
- // of the action buttons.
- if (!imageGrid.inProgramSelection &&
- url != ButtonImages.TAKE_PHOTO && url != ButtonImages.CHOOSE_FILE) {
- chrome.send('selectImage', [url, imageGrid.selectionType]);
- }
- // Start/stop camera on (de)selection.
- if (!imageGrid.inProgramSelection &&
- imageGrid.selectionType != e.oldSelectionType) {
- if (imageGrid.selectionType == 'camera') {
- imageGrid.startCamera(
- function() {
- // Start capture if camera is still the selected item.
- return imageGrid.selectedItem == imageGrid.cameraImage;
- });
- } else {
- imageGrid.stopCamera();
- }
- }
- // Update image attribution text.
- var image = imageGrid.selectedItem;
- $('user-image-author-name').textContent = image.author;
- $('user-image-author-website').textContent = image.website;
- $('user-image-author-website').href = image.website;
- $('user-image-attribution').style.visibility =
- (image.author || image.website) ? 'visible' : 'hidden';
- },
-
- /**
- * Handles image activation (by pressing Enter).
- * @private
- */
- handleImageActivated_: function() {
- switch ($('user-image-grid').selectedItemUrl) {
- case ButtonImages.TAKE_PHOTO:
- this.handleTakePhoto_();
- break;
- case ButtonImages.CHOOSE_FILE:
- this.handleChooseFile_();
- break;
- default:
- this.closeOverlay_();
- break;
- }
- },
-
- /**
- * Adds or updates old user image taken from file/camera (neither a profile
- * image nor a default one).
- * @param {string} imageUrl Old user image, as data or internal URL.
- * @private
- */
- setOldImage_: function(imageUrl) {
- var imageGrid = $('user-image-grid');
- if (this.oldImage_) {
- this.oldImage_ = imageGrid.updateItem(this.oldImage_, imageUrl);
- } else {
- // Insert next to the profile image.
- var pos = imageGrid.indexOf(this.profileImage_) + 1;
- this.oldImage_ = imageGrid.addItem(imageUrl, undefined, undefined, pos);
- this.oldImage_.type = 'old';
- imageGrid.selectedItem = this.oldImage_;
- }
- },
-
- /**
- * Updates user's profile image.
- * @param {string} imageUrl Profile image, encoded as data URL.
- * @param {boolean} select If true, profile image should be selected.
- * @private
- */
- setProfileImage_: function(imageUrl, select) {
- var imageGrid = $('user-image-grid');
- this.profileImage_ = imageGrid.updateItem(
- this.profileImage_, imageUrl, loadTimeData.getString('profilePhoto'));
- if (select)
- imageGrid.selectedItem = this.profileImage_;
- },
-
- /**
- * Selects user image with the given URL.
- * @param {string} url URL of the image to select.
- * @private
- */
- setSelectedImage_: function(url) {
- $('user-image-grid').selectedItemUrl = url;
- },
-
- /**
- * @param {boolean} present Whether camera is detected.
- */
- setCameraPresent_: function(present) {
- $('user-image-grid').cameraPresent = present;
- },
-
- /**
- * Appends default images to the image grid. Should only be called once.
- * @param {Array<{url: string, author: string, website: string}>}
- * imagesData An array of default images data, including URL, author and
- * website.
- * @private
- */
- setDefaultImages_: function(imagesData) {
- $('user-image-grid').setDefaultImages(imagesData);
- },
- };
-
- // Forward public APIs to private implementations.
- cr.makePublic(ChangePictureOptions, [
- 'closeOverlay',
- 'setCameraPresent',
- 'setDefaultImages',
- 'setOldImage',
- 'setProfileImage',
- 'setSelectedImage',
- ]);
-
- // Export
- return {
- ChangePictureOptions: ChangePictureOptions
- };
-
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.css b/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.css
deleted file mode 100644
index 16c74341910..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/* 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. */
-
-#consumer-management-overlay {
- width: 500px;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.html b/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.html
deleted file mode 100644
index 9e7f763d24a..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<div id="consumer-management-overlay" class="page" hidden>
- <div class="close-button"></div>
- <div id="enroll-content" hidden>
- <h1 i18n-content="consumerManagementOverlayEnrollTitle"></h1>
- <div class="content-area">
- <span i18n-content="consumerManagementOverlayEnrollMessage"></span>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="consumer-management-overlay-enroll-cancel" type="reset"
- i18n-content="cancel">
- </button>
- <button id="consumer-management-overlay-enroll"
- class="default-button" type="submit"
- i18n-content="consumerManagementOverlayEnroll">
- </button>
- </div>
- </div>
- </div>
- <div id="unenroll-content" hidden>
- <h1 i18n-content="consumerManagementOverlayUnenrollTitle"></h1>
- <div class="content-area">
- <span i18n-content="consumerManagementOverlayUnenrollMessage"></span>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="consumer-management-overlay-unenroll-cancel" type="reset"
- i18n-content="cancel">
- </button>
- <button id="consumer-management-overlay-unenroll"
- class="default-button" type="submit"
- i18n-content="consumerManagementOverlayUnenroll">
- </button>
- </div>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.js b/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.js
deleted file mode 100644
index c9d7a889124..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/consumer_management_overlay.js
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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('options', function() {
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
-
- /**
- * ConsumerManagementOverlay class
- * Dialog that allows users to enroll/unenroll consumer management service.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function ConsumerManagementOverlay() {
- Page.call(this, 'consumer-management-overlay',
- loadTimeData.getString('consumerManagementOverlayTabTitle'),
- 'consumer-management-overlay');
-
- $('consumer-management-overlay-enroll').onclick = function(event) {
- chrome.send('enrollConsumerManagement');
- PageManager.closeOverlay();
- };
- $('consumer-management-overlay-unenroll').onclick = function(event) {
- chrome.send('unenrollConsumerManagement');
- PageManager.closeOverlay();
- };
- $('consumer-management-overlay-enroll-cancel').onclick = function(event) {
- PageManager.closeOverlay();
- };
- $('consumer-management-overlay-unenroll-cancel').onclick = function(event) {
- PageManager.closeOverlay();
- };
- }
-
- cr.addSingletonGetter(ConsumerManagementOverlay);
-
- ConsumerManagementOverlay.prototype = {
- __proto__: Page.prototype,
- };
-
- /**
- * Consumer management status.
- * See chrome/browser/chromeos/policy/consumer_management_service.h.
- * @enum {string}
- */
- ConsumerManagementOverlay.Status = {
- STATUS_UNKNOWN: 'StatusUnknown',
- STATUS_ENROLLED: 'StatusEnrolled',
- STATUS_ENROLLING: 'StatusEnrolling',
- STATUS_UNENROLLED: 'StatusUnenrolled',
- STATUS_UNENROLLING: 'StatusUnenrolling'
- };
-
- /**
- * Shows enrollment or unenrollment content based on the status.
- * @enum {string} status Consumer management service status string.
- */
- ConsumerManagementOverlay.setStatus = function(status) {
- // Status should only be enrolled or unenrolled.
- assert(status == this.Status.STATUS_ENROLLED ||
- status == this.Status.STATUS_UNENROLLED);
- var enrolled = status == this.Status.STATUS_ENROLLED;
- $('enroll-content').hidden = enrolled;
- $('unenroll-content').hidden = !enrolled;
- };
-
- // Export
- return {
- ConsumerManagementOverlay: ConsumerManagementOverlay
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/display_options.css b/chromium/chrome/browser/resources/options/chromeos/display_options.css
deleted file mode 100644
index de3995fb4dd..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/display_options.css
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#display-options-page {
- background-color: rgb(240, 240, 240);
-}
-
-#display-options-content-area {
- padding: 0;
-}
-
-#display-options-displays-view-host {
- padding: 20px 0 20px 0;
-}
-
-#display-options-displays-view {
- overflow: hidden;
- position: relative;
- width: 100%;
-}
-
-#display-configurations {
- -webkit-padding-end: 0;
- -webkit-padding-start: 15px;
- border-top: 1px solid lightgrey;
- padding-top: 15px;
-}
-
-/* The arrow at the border #display-configurations to point the focused display.
- * This is achieved by a square rotated by 45-deg, and it has border at the
- * upper-half, which were left/top before the rotation. */
-#display-configuration-arrow {
- -webkit-transform: rotate(45deg);
- border-left: 1px solid lightgrey;
- border-top: 1px solid lightgrey;
- height: 20px;
- position: absolute;
- width: 20px;
- z-index: 1;
-}
-
-#display-configurations,
-#display-configuration-arrow,
-#display-options-page .action-area {
- background-color: white;
-}
-
-#display-options-page .action-area {
- /* Because this element has a background-color, we need to emulate the
- * parent's border-radius (otherwise there's sharp corners). */
- border-bottom-left-radius: inherit;
- border-bottom-right-radius: inherit;
-}
-
-#selected-display-data-container {
- z-index: 2;
-}
-
-#selected-display-name {
- font-size: large;
- font-weight: normal;
- margin-top: 5px;
- padding: 0;
-}
-
-.selected-display-option-row {
- margin-top: 10px;
-}
-
-.selected-display-option-title {
- display: inline-block;
- margin-right: 10px;
-}
-
-.displays-display {
- -webkit-user-select: none;
- background: rgb(240, 240, 240);
- border: solid 1px;
- box-sizing: border-box;
- font-weight: bold;
- position: absolute;
- text-align: center;
- z-index: 2;
-}
-
-.display-mirrored {
- border: solid 1px;
-}
-
-.displays-focused {
- border: solid 2px rgb(0, 138, 255);
- color: rgb(0, 138, 255);
-}
-
-#display-options-select-mirroring {
- margin-right: 5px;
-}
-
-.display-options-button {
- width: 140px;
-}
-
-.display-options-button2 {
- width: 120px;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/display_options.html b/chromium/chrome/browser/resources/options/chromeos/display_options.html
deleted file mode 100644
index d915ec7bdd2..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/display_options.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<div id="display-options-page" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="displayOptionsPage"></h1>
- <div class="content-area" id="display-options-content-area">
- <div id="display-options-displays-view-host">
- </div>
- <div id="display-configurations">
- <div id="selected-display-data-container">
- <div id="selected-display-name"></div>
- <div class="selected-display-option-row">
- <div class="selected-display-option-title"
- i18n-content="selectedDisplayTitleOptions">
- </div>
- <select id="display-options-select-mirroring"
- class="display-options-button">
- <option value="extended" i18n-content="extendedMode"></option>
- <option value="mirroring" i18n-content="mirroringMode"></option>
- </select>
- <button id="display-options-set-primary"
- class="display-options-button2" i18n-content="setPrimary">
- </button>
- </div>
- <div id="display-options-unified-desktop"
- class="checkbox selected-display-option-row" hidden>
- <!-- intentionally blank for the title column space. -->
- <div class="selected-display-option-title">
- </div>
- <label>
- <input id="display-options-toggle-unified-desktop" type="checkbox">
- <span class="controlled-setting-with-label"
- i18n-content="enableUnifiedDesktop"></span>
- </label>
- </div>
- <div class="selected-display-option-row">
- <div class="selected-display-option-title"
- i18n-content="selectedDisplayTitleResolution">
- </div>
- <select id="display-options-resolution-selection"
- class="display-options-button">
- </select>
- </div>
- <div class="selected-display-option-row">
- <div class="selected-display-option-title"
- i18n-content="selectedDisplayTitleOrientation">
- </div>
- <select id="display-options-orientation-selection"
- class="display-options-button">
- <option value="0" i18n-content="orientation0"></option>
- <option value="90" i18n-content="orientation90"></option>
- <option value="180" i18n-content="orientation180"></option>
- <option value="270" i18n-content="orientation270"></option>
- </select>
- </div>
- <div class="selected-display-option-row">
- <div class="selected-display-option-title"
- i18n-content="selectedDisplayTitleOverscan">
- </div>
- <button id="selected-display-start-calibrating-overscan"
- class="display-options-button"
- i18n-content="startCalibratingOverscan">
- </button>
- </div>
- <div class="selected-display-option-row"
- id="selected-display-color-profile-row" hidden>
- <div class="selected-display-option-title"
- i18n-content="selectedDisplayColorProfile">
- </div>
- <select id="display-options-color-profile-selection"
- class="display-options-button">
- </select>
- </div>
- </div>
- </div>
- <!-- The arrow of display-configuration is achieved by a div
- rotated by 45deg. -->
- <div id="display-configuration-arrow">
- </div>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="display-options-done" i18n-content="done"
- class="default-button"></button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/display_options.js b/chromium/chrome/browser/resources/options/chromeos/display_options.js
deleted file mode 100644
index 78ada38cd73..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/display_options.js
+++ /dev/null
@@ -1,1051 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.exportPath('options');
-
-/**
- * @typedef {{
- * availableColorProfiles: Array<{profileId: number, name: string}>,
- * colorProfile: number,
- * height: number,
- * id: string,
- * isInternal: boolean,
- * isPrimary: boolean,
- * resolutions: Array<{width: number, height: number, originalWidth: number,
- * originalHeight: number, deviceScaleFactor: number, scale: number,
- * refreshRate: number, isBest: boolean, selected: boolean}>,
- * name: string,
- * orientation: number,
- * width: number,
- * x: number,
- * y: number
- * }}
- */
-options.DisplayInfo;
-
-/**
- * Enumeration of secondary display layout. The value has to be same as the
- * values in ash/display/display_controller.cc.
- * @enum {number}
- */
-options.SecondaryDisplayLayout = {
- TOP: 0,
- RIGHT: 1,
- BOTTOM: 2,
- LEFT: 3
-};
-
-/**
- * Enumeration of multi display mode. The value has to be same as the
- * values in ash/display/display_manager..
- * @enum {number}
- */
-options.MultiDisplayMode = {
- EXTENDED: 0,
- MIRRORING: 1,
- UNIFIED: 2,
-};
-
-cr.define('options', function() {
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
-
- // The scale ratio of the display rectangle to its original size.
- /** @const */ var VISUAL_SCALE = 1 / 10;
-
- // The number of pixels to share the edges between displays.
- /** @const */ var MIN_OFFSET_OVERLAP = 5;
-
- /**
- * Calculates the bounds of |element| relative to the page.
- * @param {HTMLElement} element The element to be known.
- * @return {Object} The object for the bounds, with x, y, width, and height.
- */
- function getBoundsInPage(element) {
- var bounds = {
- x: element.offsetLeft,
- y: element.offsetTop,
- width: element.offsetWidth,
- height: element.offsetHeight
- };
- var parent = element.offsetParent;
- while (parent && parent != document.body) {
- bounds.x += parent.offsetLeft;
- bounds.y += parent.offsetTop;
- parent = parent.offsetParent;
- }
- return bounds;
- }
-
- /**
- * Gets the position of |point| to |rect|, left, right, top, or bottom.
- * @param {Object} rect The base rectangle with x, y, width, and height.
- * @param {Object} point The point to check the position.
- * @return {options.SecondaryDisplayLayout} The position of the calculated
- * point.
- */
- function getPositionToRectangle(rect, point) {
- // Separates the area into four (LEFT/RIGHT/TOP/BOTTOM) by the diagonals of
- // the rect, and decides which area the display should reside.
- var diagonalSlope = rect.height / rect.width;
- var topDownIntercept = rect.y - rect.x * diagonalSlope;
- var bottomUpIntercept = rect.y + rect.height + rect.x * diagonalSlope;
-
- if (point.y > topDownIntercept + point.x * diagonalSlope) {
- if (point.y > bottomUpIntercept - point.x * diagonalSlope)
- return options.SecondaryDisplayLayout.BOTTOM;
- else
- return options.SecondaryDisplayLayout.LEFT;
- } else {
- if (point.y > bottomUpIntercept - point.x * diagonalSlope)
- return options.SecondaryDisplayLayout.RIGHT;
- else
- return options.SecondaryDisplayLayout.TOP;
- }
- }
-
- /**
- * Encapsulated handling of the 'Display' page.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function DisplayOptions() {
- Page.call(this, 'display',
- loadTimeData.getString('displayOptionsPageTabTitle'),
- 'display-options-page');
- }
-
- cr.addSingletonGetter(DisplayOptions);
-
- DisplayOptions.prototype = {
- __proto__: Page.prototype,
-
- /**
- * Whether the current output status is mirroring displays or not.
- * @private
- */
- mirroring_: false,
-
- /**
- * Whether the unified desktop is enable or not.
- * @private
- */
- unifiedDesktopEnabled_: false,
-
- /**
- * Whether the unified desktop option should be present.
- * @private
- */
- showUnifiedDesktopOption_: false,
-
- /**
- * The current secondary display layout.
- * @private
- */
- layout_: options.SecondaryDisplayLayout.RIGHT,
-
- /**
- * The array of current output displays. It also contains the display
- * rectangles currently rendered on screen.
- * @type {Array<options.DisplayInfo>}
- * @private
- */
- displays_: [],
-
- /**
- * The index for the currently focused display in the options UI. null if
- * no one has focus.
- * @private
- */
- focusedIndex_: null,
-
- /**
- * The primary display.
- * @private
- */
- primaryDisplay_: null,
-
- /**
- * The secondary display.
- * @private
- */
- secondaryDisplay_: null,
-
- /**
- * The container div element which contains all of the display rectangles.
- * @private
- */
- displaysView_: null,
-
- /**
- * The scale factor of the actual display size to the drawn display
- * rectangle size.
- * @private
- */
- visualScale_: VISUAL_SCALE,
-
- /**
- * The location where the last touch event happened. This is used to
- * prevent unnecessary dragging events happen. Set to null unless it's
- * during touch events.
- * @private
- */
- lastTouchLocation_: null,
-
- /**
- * Whether the display settings can be shown.
- * @private
- */
- enabled_: true,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
-
- $('display-options-select-mirroring').onchange = (function() {
- this.mirroring_ =
- $('display-options-select-mirroring').value == 'mirroring';
- chrome.send('setMirroring', [this.mirroring_]);
- }).bind(this);
-
- var container = $('display-options-displays-view-host');
- container.onmousemove = this.onMouseMove_.bind(this);
- window.addEventListener('mouseup', this.endDragging_.bind(this), true);
- container.ontouchmove = this.onTouchMove_.bind(this);
- container.ontouchend = this.endDragging_.bind(this);
-
- $('display-options-set-primary').onclick = (function() {
- chrome.send('setPrimary', [this.displays_[this.focusedIndex_].id]);
- }).bind(this);
- $('display-options-resolution-selection').onchange = (function(ev) {
- var display = this.displays_[this.focusedIndex_];
- var resolution = display.resolutions[ev.target.value];
- chrome.send('setDisplayMode', [display.id, resolution]);
- }).bind(this);
- $('display-options-orientation-selection').onchange = (function(ev) {
- var displayIndex =
- (this.focusedIndex_ === null) ? 0 : this.focusedIndex_;
- chrome.send('setOrientation', [this.displays_[displayIndex].id,
- ev.target.value]);
- }).bind(this);
- $('display-options-color-profile-selection').onchange = (function(ev) {
- chrome.send('setColorProfile', [this.displays_[this.focusedIndex_].id,
- ev.target.value]);
- }).bind(this);
- $('selected-display-start-calibrating-overscan').onclick = (function() {
- // Passes the target display ID. Do not specify it through URL hash,
- // we do not care back/forward.
- var displayOverscan = options.DisplayOverscan.getInstance();
- displayOverscan.setDisplayId(this.displays_[this.focusedIndex_].id);
- PageManager.showPageByName('displayOverscan');
- chrome.send('coreOptionsUserMetricsAction',
- ['Options_DisplaySetOverscan']);
- }).bind(this);
-
- $('display-options-done').onclick = function() {
- PageManager.closeOverlay();
- };
-
- $('display-options-toggle-unified-desktop').onclick = (function() {
- this.unifiedDesktopEnabled_ = !this.unifiedDesktopEnabled_;
- chrome.send('setUnifiedDesktopEnabled',
- [this.unifiedDesktopEnabled_]);
- }).bind(this);
- },
-
- /** @override */
- didShowPage: function() {
- var optionTitles = document.getElementsByClassName(
- 'selected-display-option-title');
- var maxSize = 0;
- for (var i = 0; i < optionTitles.length; i++)
- maxSize = Math.max(maxSize, optionTitles[i].clientWidth);
- for (var i = 0; i < optionTitles.length; i++)
- optionTitles[i].style.width = maxSize + 'px';
- chrome.send('getDisplayInfo');
- },
-
- /** @override */
- canShowPage: function() {
- return this.enabled_;
- },
-
- /**
- * Enables or disables the page. When disabled, the page will not be able to
- * open, and will close if currently opened.
- * @param {boolean} enabled Whether the page should be enabled.
- * @param {boolean} showUnifiedDesktop Whether the unified desktop option
- * should be present.
- */
- setEnabled: function(enabled, showUnifiedDesktop) {
- if (this.enabled_ == enabled &&
- this.showUnifiedDesktopOption_ == showUnifiedDesktop) {
- return;
- }
- this.enabled_ = enabled;
- this.showUnifiedDesktopOption_ = showUnifiedDesktop;
- if (!enabled && this.visible)
- PageManager.closeOverlay();
- },
-
- /**
- * Mouse move handler for dragging display rectangle.
- * @param {Event} e The mouse move event.
- * @private
- */
- onMouseMove_: function(e) {
- return this.processDragging_(e, {x: e.pageX, y: e.pageY});
- },
-
- /**
- * Touch move handler for dragging display rectangle.
- * @param {Event} e The touch move event.
- * @private
- */
- onTouchMove_: function(e) {
- if (e.touches.length != 1)
- return true;
-
- var touchLocation = {x: e.touches[0].pageX, y: e.touches[0].pageY};
- // Touch move events happen even if the touch location doesn't change, but
- // it doesn't need to process the dragging. Since sometimes the touch
- // position changes slightly even though the user doesn't think to move
- // the finger, very small move is just ignored.
- /** @const */ var IGNORABLE_TOUCH_MOVE_PX = 1;
- var xDiff = Math.abs(touchLocation.x - this.lastTouchLocation_.x);
- var yDiff = Math.abs(touchLocation.y - this.lastTouchLocation_.y);
- if (xDiff <= IGNORABLE_TOUCH_MOVE_PX &&
- yDiff <= IGNORABLE_TOUCH_MOVE_PX) {
- return true;
- }
-
- this.lastTouchLocation_ = touchLocation;
- return this.processDragging_(e, touchLocation);
- },
-
- /**
- * Mouse down handler for dragging display rectangle.
- * @param {Event} e The mouse down event.
- * @private
- */
- onMouseDown_: function(e) {
- if (this.mirroring_)
- return true;
-
- if (e.button != 0)
- return true;
-
- e.preventDefault();
- var target = assertInstanceof(e.target, HTMLElement);
- return this.startDragging_(target, {x: e.pageX, y: e.pageY});
- },
-
- /**
- * Touch start handler for dragging display rectangle.
- * @param {Event} e The touch start event.
- * @private
- */
- onTouchStart_: function(e) {
- if (this.mirroring_)
- return true;
-
- if (e.touches.length != 1)
- return false;
-
- e.preventDefault();
- var touch = e.touches[0];
- this.lastTouchLocation_ = {x: touch.pageX, y: touch.pageY};
- var target = assertInstanceof(e.target, HTMLElement);
- return this.startDragging_(target, this.lastTouchLocation_);
- },
-
- /**
- * Collects the current data and sends it to Chrome.
- * @private
- */
- applyResult_: function() {
- // Offset is calculated from top or left edge.
- var primary = this.primaryDisplay_;
- var secondary = this.secondaryDisplay_;
- var offset;
- if (this.layout_ == options.SecondaryDisplayLayout.LEFT ||
- this.layout_ == options.SecondaryDisplayLayout.RIGHT) {
- offset = secondary.div.offsetTop - primary.div.offsetTop;
- } else {
- offset = secondary.div.offsetLeft - primary.div.offsetLeft;
- }
- chrome.send('setDisplayLayout',
- [this.layout_, offset / this.visualScale_]);
- },
-
- /**
- * Snaps the region [point, width] to [basePoint, baseWidth] if
- * the [point, width] is close enough to the base's edge.
- * @param {number} point The starting point of the region.
- * @param {number} width The width of the region.
- * @param {number} basePoint The starting point of the base region.
- * @param {number} baseWidth The width of the base region.
- * @return {number} The moved point. Returns point itself if it doesn't
- * need to snap to the edge.
- * @private
- */
- snapToEdge_: function(point, width, basePoint, baseWidth) {
- // If the edge of the regions is smaller than this, it will snap to the
- // base's edge.
- /** @const */ var SNAP_DISTANCE_PX = 16;
-
- var startDiff = Math.abs(point - basePoint);
- var endDiff = Math.abs(point + width - (basePoint + baseWidth));
- // Prefer the closer one if both edges are close enough.
- if (startDiff < SNAP_DISTANCE_PX && startDiff < endDiff)
- return basePoint;
- else if (endDiff < SNAP_DISTANCE_PX)
- return basePoint + baseWidth - width;
-
- return point;
- },
-
- /**
- * Processes the actual dragging of display rectangle.
- * @param {Event} e The event which triggers this drag.
- * @param {Object} eventLocation The location where the event happens.
- * @private
- */
- processDragging_: function(e, eventLocation) {
- if (!this.dragging_)
- return true;
-
- var index = -1;
- for (var i = 0; i < this.displays_.length; i++) {
- if (this.displays_[i] == this.dragging_.display) {
- index = i;
- break;
- }
- }
- if (index < 0)
- return true;
-
- e.preventDefault();
-
- // Note that current code of moving display-rectangles doesn't work
- // if there are >=3 displays. This is our assumption for M21.
- // TODO(mukai): Fix the code to allow >=3 displays.
- var newPosition = {
- x: this.dragging_.originalLocation.x +
- (eventLocation.x - this.dragging_.eventLocation.x),
- y: this.dragging_.originalLocation.y +
- (eventLocation.y - this.dragging_.eventLocation.y)
- };
-
- var baseDiv = this.dragging_.display.isPrimary ?
- this.secondaryDisplay_.div : this.primaryDisplay_.div;
- var draggingDiv = this.dragging_.display.div;
-
- newPosition.x = this.snapToEdge_(newPosition.x, draggingDiv.offsetWidth,
- baseDiv.offsetLeft, baseDiv.offsetWidth);
- newPosition.y = this.snapToEdge_(newPosition.y, draggingDiv.offsetHeight,
- baseDiv.offsetTop, baseDiv.offsetHeight);
-
- var newCenter = {
- x: newPosition.x + draggingDiv.offsetWidth / 2,
- y: newPosition.y + draggingDiv.offsetHeight / 2
- };
-
- var baseBounds = {
- x: baseDiv.offsetLeft,
- y: baseDiv.offsetTop,
- width: baseDiv.offsetWidth,
- height: baseDiv.offsetHeight
- };
- switch (getPositionToRectangle(baseBounds, newCenter)) {
- case options.SecondaryDisplayLayout.RIGHT:
- this.layout_ = this.dragging_.display.isPrimary ?
- options.SecondaryDisplayLayout.LEFT :
- options.SecondaryDisplayLayout.RIGHT;
- break;
- case options.SecondaryDisplayLayout.LEFT:
- this.layout_ = this.dragging_.display.isPrimary ?
- options.SecondaryDisplayLayout.RIGHT :
- options.SecondaryDisplayLayout.LEFT;
- break;
- case options.SecondaryDisplayLayout.TOP:
- this.layout_ = this.dragging_.display.isPrimary ?
- options.SecondaryDisplayLayout.BOTTOM :
- options.SecondaryDisplayLayout.TOP;
- break;
- case options.SecondaryDisplayLayout.BOTTOM:
- this.layout_ = this.dragging_.display.isPrimary ?
- options.SecondaryDisplayLayout.TOP :
- options.SecondaryDisplayLayout.BOTTOM;
- break;
- }
-
- if (this.layout_ == options.SecondaryDisplayLayout.LEFT ||
- this.layout_ == options.SecondaryDisplayLayout.RIGHT) {
- if (newPosition.y > baseDiv.offsetTop + baseDiv.offsetHeight)
- this.layout_ = this.dragging_.display.isPrimary ?
- options.SecondaryDisplayLayout.TOP :
- options.SecondaryDisplayLayout.BOTTOM;
- else if (newPosition.y + draggingDiv.offsetHeight <
- baseDiv.offsetTop)
- this.layout_ = this.dragging_.display.isPrimary ?
- options.SecondaryDisplayLayout.BOTTOM :
- options.SecondaryDisplayLayout.TOP;
- } else {
- if (newPosition.x > baseDiv.offsetLeft + baseDiv.offsetWidth)
- this.layout_ = this.dragging_.display.isPrimary ?
- options.SecondaryDisplayLayout.LEFT :
- options.SecondaryDisplayLayout.RIGHT;
- else if (newPosition.x + draggingDiv.offsetWidth <
- baseDiv.offsetLeft)
- this.layout_ = this.dragging_.display.isPrimary ?
- options.SecondaryDisplayLayout.RIGHT :
- options.SecondaryDisplayLayout.LEFT;
- }
-
- var layoutToBase;
- if (!this.dragging_.display.isPrimary) {
- layoutToBase = this.layout_;
- } else {
- switch (this.layout_) {
- case options.SecondaryDisplayLayout.RIGHT:
- layoutToBase = options.SecondaryDisplayLayout.LEFT;
- break;
- case options.SecondaryDisplayLayout.LEFT:
- layoutToBase = options.SecondaryDisplayLayout.RIGHT;
- break;
- case options.SecondaryDisplayLayout.TOP:
- layoutToBase = options.SecondaryDisplayLayout.BOTTOM;
- break;
- case options.SecondaryDisplayLayout.BOTTOM:
- layoutToBase = options.SecondaryDisplayLayout.TOP;
- break;
- }
- }
-
- switch (layoutToBase) {
- case options.SecondaryDisplayLayout.RIGHT:
- draggingDiv.style.left =
- baseDiv.offsetLeft + baseDiv.offsetWidth + 'px';
- draggingDiv.style.top = newPosition.y + 'px';
- break;
- case options.SecondaryDisplayLayout.LEFT:
- draggingDiv.style.left =
- baseDiv.offsetLeft - draggingDiv.offsetWidth + 'px';
- draggingDiv.style.top = newPosition.y + 'px';
- break;
- case options.SecondaryDisplayLayout.TOP:
- draggingDiv.style.top =
- baseDiv.offsetTop - draggingDiv.offsetHeight + 'px';
- draggingDiv.style.left = newPosition.x + 'px';
- break;
- case options.SecondaryDisplayLayout.BOTTOM:
- draggingDiv.style.top =
- baseDiv.offsetTop + baseDiv.offsetHeight + 'px';
- draggingDiv.style.left = newPosition.x + 'px';
- break;
- }
-
- return false;
- },
-
- /**
- * start dragging of a display rectangle.
- * @param {HTMLElement} target The event target.
- * @param {Object} eventLocation The object to hold the location where
- * this event happens.
- * @private
- */
- startDragging_: function(target, eventLocation) {
- var oldFocusedIndex = this.focusedIndex_;
- var willUpdateDisplayDescription = false;
- this.focusedIndex_ = null;
- for (var i = 0; i < this.displays_.length; i++) {
- var display = this.displays_[i];
- if (display.div == target ||
- (target.offsetParent && target.offsetParent == display.div)) {
- this.focusedIndex_ = i;
- if (oldFocusedIndex !== null && oldFocusedIndex != i)
- willUpdateDisplayDescription = true;
- break;
- }
- }
-
- for (var i = 0; i < this.displays_.length; i++) {
- var display = this.displays_[i];
- display.div.className = 'displays-display';
- if (i != this.focusedIndex_)
- continue;
-
- display.div.classList.add('displays-focused');
- if (this.displays_.length > 1) {
- this.dragging_ = {
- display: display,
- originalLocation: {
- x: display.div.offsetLeft, y: display.div.offsetTop
- },
- eventLocation: eventLocation
- };
- }
- }
-
- if (willUpdateDisplayDescription)
- this.updateSelectedDisplayDescription_();
- return false;
- },
-
- /**
- * finish the current dragging of displays.
- * @param {Event} e The event which triggers this.
- * @private
- */
- endDragging_: function(e) {
- this.lastTouchLocation_ = null;
- if (this.dragging_) {
- // Make sure the dragging location is connected.
- var baseDiv = this.dragging_.display.isPrimary ?
- this.secondaryDisplay_.div : this.primaryDisplay_.div;
- var draggingDiv = this.dragging_.display.div;
- if (this.layout_ == options.SecondaryDisplayLayout.LEFT ||
- this.layout_ == options.SecondaryDisplayLayout.RIGHT) {
- var top = Math.max(draggingDiv.offsetTop,
- baseDiv.offsetTop - draggingDiv.offsetHeight +
- MIN_OFFSET_OVERLAP);
- top = Math.min(top,
- baseDiv.offsetTop + baseDiv.offsetHeight -
- MIN_OFFSET_OVERLAP);
- draggingDiv.style.top = top + 'px';
- } else {
- var left = Math.max(draggingDiv.offsetLeft,
- baseDiv.offsetLeft - draggingDiv.offsetWidth +
- MIN_OFFSET_OVERLAP);
- left = Math.min(left,
- baseDiv.offsetLeft + baseDiv.offsetWidth -
- MIN_OFFSET_OVERLAP);
- draggingDiv.style.left = left + 'px';
- }
- var originalPosition = this.dragging_.display.originalPosition;
- if (originalPosition.x != draggingDiv.offsetLeft ||
- originalPosition.y != draggingDiv.offsetTop)
- this.applyResult_();
- this.dragging_ = null;
- }
- return false;
- },
-
- /**
- * Updates the description of selected display section for mirroring mode.
- * @private
- */
- updateSelectedDisplaySectionMirroring_: function() {
- $('display-configuration-arrow').hidden = true;
- $('display-options-set-primary').disabled = true;
- $('display-options-select-mirroring').disabled = false;
- $('selected-display-start-calibrating-overscan').disabled = true;
- var display = this.displays_[0];
- var orientation = $('display-options-orientation-selection');
- orientation.disabled = false;
- var orientationOptions = orientation.getElementsByTagName('option');
- orientationOptions[display.orientation].selected = true;
- $('selected-display-name').textContent =
- loadTimeData.getString('mirroringDisplay');
- var resolution = $('display-options-resolution-selection');
- var option = document.createElement('option');
- option.value = 'default';
- option.textContent = display.width + 'x' + display.height;
- resolution.appendChild(option);
- resolution.disabled = true;
- },
-
- /**
- * Updates the description of selected display section when no display is
- * selected.
- * @private
- */
- updateSelectedDisplaySectionNoSelected_: function() {
- $('display-configuration-arrow').hidden = true;
- $('display-options-set-primary').disabled = true;
- $('display-options-select-mirroring').disabled = true;
- $('selected-display-start-calibrating-overscan').disabled = true;
- $('display-options-orientation-selection').disabled = true;
- $('selected-display-name').textContent = '';
- var resolution = $('display-options-resolution-selection');
- resolution.appendChild(document.createElement('option'));
- resolution.disabled = true;
- },
-
- /**
- * Updates the description of selected display section for the selected
- * display.
- * @param {Object} display The selected display object.
- * @private
- */
- updateSelectedDisplaySectionForDisplay_: function(display) {
- var arrow = $('display-configuration-arrow');
- arrow.hidden = false;
- // Adding 1 px to the position to fit the border line and the border in
- // arrow precisely.
- arrow.style.top = $('display-configurations').offsetTop -
- arrow.offsetHeight / 2 + 'px';
- arrow.style.left = display.div.offsetLeft +
- display.div.offsetWidth / 2 - arrow.offsetWidth / 2 + 'px';
-
- $('display-options-set-primary').disabled = display.isPrimary;
- $('display-options-select-mirroring').disabled =
- (this.displays_.length <= 1 && !this.unifiedDesktopEnabled_);
- $('selected-display-start-calibrating-overscan').disabled =
- display.isInternal;
-
- var orientation = $('display-options-orientation-selection');
- orientation.disabled = this.unifiedDesktopEnabled_;
-
- var orientationOptions = orientation.getElementsByTagName('option');
- orientationOptions[display.orientation].selected = true;
-
- $('selected-display-name').textContent = display.name;
-
- var resolution = $('display-options-resolution-selection');
- if (display.resolutions.length <= 1) {
- var option = document.createElement('option');
- option.value = 'default';
- option.textContent = display.width + 'x' + display.height;
- option.selected = true;
- resolution.appendChild(option);
- resolution.disabled = true;
- } else {
- var previousOption;
- for (var i = 0; i < display.resolutions.length; i++) {
- var option = document.createElement('option');
- option.value = i;
- option.textContent = display.resolutions[i].width + 'x' +
- display.resolutions[i].height;
- if (display.resolutions[i].isBest) {
- option.textContent += ' ' +
- loadTimeData.getString('annotateBest');
- } else if (display.resolutions[i].isNative) {
- option.textContent += ' ' +
- loadTimeData.getString('annotateNative');
- }
- if (display.resolutions[i].deviceScaleFactor && previousOption &&
- previousOption.textContent == option.textContent) {
- option.textContent +=
- ' (' + display.resolutions[i].deviceScaleFactor + 'x)';
- }
- option.selected = display.resolutions[i].selected;
- resolution.appendChild(option);
- previousOption = option;
- }
- resolution.disabled = (display.resolutions.length <= 1);
- }
-
- if (display.availableColorProfiles.length <= 1) {
- $('selected-display-color-profile-row').hidden = true;
- } else {
- $('selected-display-color-profile-row').hidden = false;
- var profiles = $('display-options-color-profile-selection');
- profiles.innerHTML = '';
- for (var i = 0; i < display.availableColorProfiles.length; i++) {
- var option = document.createElement('option');
- var colorProfile = display.availableColorProfiles[i];
- option.value = colorProfile.profileId;
- option.textContent = colorProfile.name;
- option.selected = (
- display.colorProfile == colorProfile.profileId);
- profiles.appendChild(option);
- }
- }
- },
-
- /**
- * Updates the description of the selected display section.
- * @private
- */
- updateSelectedDisplayDescription_: function() {
- var resolution = $('display-options-resolution-selection');
- resolution.textContent = '';
- var orientation = $('display-options-orientation-selection');
- var orientationOptions = orientation.getElementsByTagName('option');
- for (var i = 0; i < orientationOptions.length; i++)
- orientationOptions[i].selected = false;
-
- if (this.mirroring_) {
- this.updateSelectedDisplaySectionMirroring_();
- } else if (this.focusedIndex_ == null ||
- this.displays_[this.focusedIndex_] == null) {
- this.updateSelectedDisplaySectionNoSelected_();
- } else {
- this.updateSelectedDisplaySectionForDisplay_(
- this.displays_[this.focusedIndex_]);
- }
- },
-
- /**
- * Clears the drawing area for display rectangles.
- * @private
- */
- resetDisplaysView_: function() {
- var displaysViewHost = $('display-options-displays-view-host');
- displaysViewHost.removeChild(displaysViewHost.firstChild);
- this.displaysView_ = document.createElement('div');
- this.displaysView_.id = 'display-options-displays-view';
- displaysViewHost.appendChild(this.displaysView_);
- },
-
- /**
- * Lays out the display rectangles for mirroring.
- * @private
- */
- layoutMirroringDisplays_: function() {
- // Offset pixels for secondary display rectangles. The offset includes the
- // border width.
- /** @const */ var MIRRORING_OFFSET_PIXELS = 3;
- // Always show two displays because there must be two displays when
- // the display_options is enabled. Don't rely on displays_.length because
- // there is only one display from chrome's perspective in mirror mode.
- /** @const */ var MIN_NUM_DISPLAYS = 2;
- /** @const */ var MIRRORING_VERTICAL_MARGIN = 20;
-
- // The width/height should be same as the first display:
- var width = Math.ceil(this.displays_[0].width * this.visualScale_);
- var height = Math.ceil(this.displays_[0].height * this.visualScale_);
-
- var numDisplays = Math.max(MIN_NUM_DISPLAYS, this.displays_.length);
-
- var totalWidth = width + numDisplays * MIRRORING_OFFSET_PIXELS;
- var totalHeight = height + numDisplays * MIRRORING_OFFSET_PIXELS;
-
- this.displaysView_.style.height = totalHeight + 'px';
-
- // The displays should be centered.
- var offsetX =
- $('display-options-displays-view').offsetWidth / 2 - totalWidth / 2;
-
- for (var i = 0; i < numDisplays; i++) {
- var div = document.createElement('div');
- div.className = 'displays-display';
- div.style.top = i * MIRRORING_OFFSET_PIXELS + 'px';
- div.style.left = i * MIRRORING_OFFSET_PIXELS + offsetX + 'px';
- div.style.width = width + 'px';
- div.style.height = height + 'px';
- div.style.zIndex = i;
- // set 'display-mirrored' class for the background display rectangles.
- if (i != numDisplays - 1)
- div.classList.add('display-mirrored');
- this.displaysView_.appendChild(div);
- }
- },
-
- /**
- * Creates a div element representing the specified display.
- * @param {Object} display The display object.
- * @param {boolean} focused True if it's focused.
- * @private
- */
- createDisplayRectangle_: function(display, focused) {
- var div = document.createElement('div');
- display.div = div;
- div.className = 'displays-display';
- if (focused)
- div.classList.add('displays-focused');
-
- // div needs to be added to the DOM tree first, otherwise offsetHeight for
- // nameContainer below cannot be computed.
- this.displaysView_.appendChild(div);
-
- var nameContainer = document.createElement('div');
- nameContainer.textContent = display.name;
- div.appendChild(nameContainer);
- div.style.width = Math.floor(display.width * this.visualScale_) + 'px';
- var newHeight = Math.floor(display.height * this.visualScale_);
- div.style.height = newHeight + 'px';
- nameContainer.style.marginTop =
- (newHeight - nameContainer.offsetHeight) / 2 + 'px';
-
- div.onmousedown = this.onMouseDown_.bind(this);
- div.ontouchstart = this.onTouchStart_.bind(this);
- return div;
- },
-
- /**
- * Layouts the display rectangles according to the current layout_.
- * @private
- */
- layoutDisplays_: function() {
- var maxWidth = 0;
- var maxHeight = 0;
- var boundingBox = {left: 0, right: 0, top: 0, bottom: 0};
- this.primaryDisplay_ = null;
- this.secondaryDisplay_ = null;
- var focusedDisplay = null;
- for (var i = 0; i < this.displays_.length; i++) {
- var display = this.displays_[i];
- if (display.isPrimary)
- this.primaryDisplay_ = display;
- else
- this.secondaryDisplay_ = display;
- if (i == this.focusedIndex_)
- focusedDisplay = display;
-
- boundingBox.left = Math.min(boundingBox.left, display.x);
- boundingBox.right = Math.max(
- boundingBox.right, display.x + display.width);
- boundingBox.top = Math.min(boundingBox.top, display.y);
- boundingBox.bottom = Math.max(
- boundingBox.bottom, display.y + display.height);
- maxWidth = Math.max(maxWidth, display.width);
- maxHeight = Math.max(maxHeight, display.height);
- }
- if (!this.primaryDisplay_)
- return;
-
- // Make the margin around the bounding box.
- var areaWidth = boundingBox.right - boundingBox.left + maxWidth;
- var areaHeight = boundingBox.bottom - boundingBox.top + maxHeight;
-
- // Calculates the scale by the width since horizontal size is more strict.
- // TODO(mukai): Adds the check of vertical size in case.
- this.visualScale_ = Math.min(
- VISUAL_SCALE, this.displaysView_.offsetWidth / areaWidth);
-
- // Prepare enough area for thisplays_view by adding the maximum height.
- this.displaysView_.style.height =
- Math.ceil(areaHeight * this.visualScale_) + 'px';
-
- // Centering the bounding box of the display rectangles.
- var offset = {
- x: Math.floor(this.displaysView_.offsetWidth / 2 -
- (boundingBox.right + boundingBox.left) * this.visualScale_ / 2),
- y: Math.floor(this.displaysView_.offsetHeight / 2 -
- (boundingBox.bottom + boundingBox.top) * this.visualScale_ / 2)
- };
-
- // Layouting the display rectangles. First layout the primaryDisplay and
- // then layout the secondary which is attaching to the primary.
- var primaryDiv = this.createDisplayRectangle_(
- this.primaryDisplay_, this.primaryDisplay_ == focusedDisplay);
- primaryDiv.style.left =
- Math.floor(this.primaryDisplay_.x * this.visualScale_) +
- offset.x + 'px';
- primaryDiv.style.top =
- Math.floor(this.primaryDisplay_.y * this.visualScale_) +
- offset.y + 'px';
- this.primaryDisplay_.originalPosition = {
- x: primaryDiv.offsetLeft, y: primaryDiv.offsetTop};
-
- if (this.secondaryDisplay_) {
- var secondaryDiv = this.createDisplayRectangle_(
- this.secondaryDisplay_, this.secondaryDisplay_ == focusedDisplay);
- // Don't trust the secondary display's x or y, because it may cause a
- // 1px gap due to rounding, which will create a fake update on end
- // dragging. See crbug.com/386401
- switch (this.layout_) {
- case options.SecondaryDisplayLayout.TOP:
- secondaryDiv.style.left =
- Math.floor(this.secondaryDisplay_.x * this.visualScale_) +
- offset.x + 'px';
- secondaryDiv.style.top =
- primaryDiv.offsetTop - secondaryDiv.offsetHeight + 'px';
- break;
- case options.SecondaryDisplayLayout.RIGHT:
- secondaryDiv.style.left =
- primaryDiv.offsetLeft + primaryDiv.offsetWidth + 'px';
- secondaryDiv.style.top =
- Math.floor(this.secondaryDisplay_.y * this.visualScale_) +
- offset.y + 'px';
- break;
- case options.SecondaryDisplayLayout.BOTTOM:
- secondaryDiv.style.left =
- Math.floor(this.secondaryDisplay_.x * this.visualScale_) +
- offset.x + 'px';
- secondaryDiv.style.top =
- primaryDiv.offsetTop + primaryDiv.offsetHeight + 'px';
- break;
- case options.SecondaryDisplayLayout.LEFT:
- secondaryDiv.style.left =
- primaryDiv.offsetLeft - secondaryDiv.offsetWidth + 'px';
- secondaryDiv.style.top =
- Math.floor(this.secondaryDisplay_.y * this.visualScale_) +
- offset.y + 'px';
- break;
- }
- this.secondaryDisplay_.originalPosition = {
- x: secondaryDiv.offsetLeft, y: secondaryDiv.offsetTop};
- }
- },
-
- /**
- * Called when the display arrangement has changed.
- * @param {options.MultiDisplayMode} mode multi display mode.
- * @param {Array<options.DisplayInfo>} displays The list of the display
- * information.
- * @param {options.SecondaryDisplayLayout} layout The layout strategy.
- * @param {number} offset The offset of the secondary display.
- * @private
- */
- onDisplayChanged_: function(mode, displays, layout, offset) {
- if (!this.visible)
- return;
-
- var hasExternal = false;
- for (var i = 0; i < displays.length; i++) {
- if (!displays[i].isInternal) {
- hasExternal = true;
- break;
- }
- }
-
- this.layout_ = layout;
-
- var mirroring = mode == options.MultiDisplayMode.MIRRORING;
- var unifiedDesktopEnabled = mode == options.MultiDisplayMode.UNIFIED;
-
- // Focus to the first display next to the primary one when |displays| list
- // is updated.
- if (mirroring) {
- this.focusedIndex_ = null;
- } else if (this.mirroring_ != mirroring ||
- this.unifiedDesktopEnabled_ != unifiedDesktopEnabled ||
- this.displays_.length != displays.length) {
- this.focusedIndex_ = 0;
- }
-
- this.mirroring_ = mirroring;
- this.unifiedDesktopEnabled_ = unifiedDesktopEnabled;
- this.displays_ = displays;
-
- this.resetDisplaysView_();
- if (this.mirroring_)
- this.layoutMirroringDisplays_();
- else
- this.layoutDisplays_();
-
- $('display-options-unified-desktop').hidden =
- !this.showUnifiedDesktopOption_;
-
- $('display-options-toggle-unified-desktop').checked =
- this.unifiedDesktopEnabled_;
-
- var disableUnifiedDesktopOption =
- (this.mirroring_ ||
- (!this.unifiedDesktopEnabled_ &&
- this.displays_.length == 1));
-
- $('display-options-toggle-unified-desktop').disabled =
- disableUnifiedDesktopOption;
-
- this.updateSelectedDisplayDescription_();
- }
- };
-
- DisplayOptions.setDisplayInfo = function(
- mode, displays, layout, offset) {
- DisplayOptions.getInstance().onDisplayChanged_(
- mode, displays, layout, offset);
- };
-
- // Export
- return {
- DisplayOptions: DisplayOptions
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/display_overscan.css b/chromium/chrome/browser/resources/options/chromeos/display_overscan.css
deleted file mode 100644
index 6069a806044..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/display_overscan.css
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#display-overscan-content-area {
- margin: 20px;
- padding: 0;
-}
-
-#display-overscan-operations-table {
- position: absolute;
- width: 100%;
-}
-
-#display-overscan-operations-table td {
- font-size: 12px;
- text-align: center;
- width: 50%;
-}
-
-.display-overscan-operation-image {
- padding-bottom: 30px;
-}
-
-#display-overscan-operation-images-row {
- vertical-align: middle;
-}
-
-#display-overscan-operation-arrows {
- background-image: -webkit-image-set(
- url(overscan_arrows.png) 1x,
- url(overscan_arrows_2x.png) 2x);
- background-position: center;
- background-repeat: no-repeat;
- height: 51px;
- width: 100%;
-}
-
-#display-overscan-operation-shift {
- background-image: -webkit-image-set(
- url(overscan_shift.png) 1x,
- url(overscan_shift_2x.png) 2x);
- background-position: center;
- background-repeat: no-repeat;
- height: 23px;
- width: 100%;
-}
-
-html[dir=rtl] #display-overscan-operation-shift {
- background-image: -webkit-image-set(
- url(overscan_shift_rtl.png) 1x,
- url(overscan_shift_rtl_2x.png) 2x);
-}
-
-#display-overscan-button-strip {
- bottom: 0;
- position: absolute;
- width: 100%;
-}
-
-#display-overscan-buttons-spacer {
- -webkit-box-flex: 1;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/display_overscan.html b/chromium/chrome/browser/resources/options/chromeos/display_overscan.html
deleted file mode 100644
index 53c280affad..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/display_overscan.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<div id="display-overscan-page" class="page" hidden>
- <div class="close-button"></div>
- <div class="content-area" id="display-overscan-content-area">
- <table id="display-overscan-operations-table">
- <tr id="display-overscan-operation-images-row">
- <td class="display-overscan-operation-image">
- <div id="display-overscan-operation-arrows"></div></td>
- <td class="display-overscan-operation-image">
- <div id="display-overscan-operation-shift"></div></td>
- </tr>
- <tr>
- <td><span i18n-content="shrinkAndExpand"></span></td>
- <td><span i18n-content="move"></span></td>
- </tr>
- </table>
- <!-- Specify 'reversed' to prevernt re-reversing the button order by
- options_page. -->
- <div class="button-strip" id="display-overscan-button-strip" reversed>
- <button id="display-overscan-operation-reset"
- i18n-content="overscanReset">
- </button>
- <div id="display-overscan-buttons-spacer"></div>
- <button id="display-overscan-operation-ok"
- i18n-content="overscanOK">
- </button>
- <button id="display-overscan-operation-cancel"
- i18n-content="overscanCancel">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/display_overscan.js b/chromium/chrome/browser/resources/options/chromeos/display_overscan.js
deleted file mode 100644
index ab1a17652f2..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/display_overscan.js
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
-
- /**
- * Encapsulated handling of the 'DisplayOverscan' page.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function DisplayOverscan() {
- Page.call(this, 'displayOverscan',
- loadTimeData.getString('displayOverscanPageTabTitle'),
- 'display-overscan-page');
- }
-
- cr.addSingletonGetter(DisplayOverscan);
-
- DisplayOverscan.prototype = {
- __proto__: Page.prototype,
-
- /**
- * The ID of the target display.
- * @private {?string}
- */
- id_: null,
-
- /**
- * The keyboard event handler function.
- * @private
- */
- keyHandler_: null,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
-
- this.keyHandler_ = this.handleKeyevent_.bind(this);
- $('display-overscan-operation-reset').onclick = function() {
- chrome.send('reset');
- };
- $('display-overscan-operation-ok').onclick = function() {
- chrome.send('commit');
- PageManager.closeOverlay();
- };
- $('display-overscan-operation-cancel').onclick = function() {
- PageManager.cancelOverlay();
- };
- },
-
- /** @override */
- handleCancel: function() {
- // signals the cancel event.
- chrome.send('cancel');
- PageManager.closeOverlay();
- },
-
- /** @override */
- didShowPage: function() {
- if (this.id_ == null) {
- PageManager.cancelOverlay();
- return;
- }
-
- window.addEventListener('keydown', this.keyHandler_);
- // Sets up the size of the overscan dialog based on DisplayOptions dialog.
- var displayOptionsPage = $('display-options-page');
- var displayOverscanPage = $('display-overscan-page');
- displayOverscanPage.style.width =
- displayOptionsPage.offsetWidth - 20 + 'px';
- displayOverscanPage.style.minWidth = displayOverscanPage.style.width;
- displayOverscanPage.style.height =
- displayOptionsPage.offsetHeight - 50 + 'px';
-
- // Moves the table to describe operation at the middle of the contents
- // vertically.
- var operationsTable = $('display-overscan-operations-table');
- var buttonsContainer = $('display-overscan-button-strip');
- operationsTable.style.top = buttonsContainer.offsetTop / 2 -
- operationsTable.offsetHeight / 2 + 'px';
-
- $('display-overscan-operation-cancel').focus();
- chrome.send('start', [this.id_]);
- },
-
- /** @override */
- didClosePage: function() {
- window.removeEventListener('keydown', this.keyHandler_);
- },
-
- /**
- * Called when the overscan calibration is canceled at the system level,
- * such like the display is disconnected.
- * @private
- */
- onOverscanCanceled_: function() {
- if (PageManager.getTopmostVisiblePage() == this)
- PageManager.cancelOverlay();
- },
-
- /**
- * Sets the target display id. This method has to be called before
- * navigating to this page.
- * @param {string} id The target display id.
- */
- setDisplayId: function(id) {
- this.id_ = id;
- },
-
- /**
- * Key event handler to make the effect of display rectangle.
- * @param {Event} event The keyboard event.
- * @private
- */
- handleKeyevent_: function(event) {
- switch (event.keyCode) {
- case 37: // left arrow
- if (event.shiftKey)
- chrome.send('move', ['horizontal', -1]);
- else
- chrome.send('resize', ['horizontal', -1]);
- event.preventDefault();
- break;
- case 38: // up arrow
- if (event.shiftKey)
- chrome.send('move', ['vertical', -1]);
- else
- chrome.send('resize', ['vertical', -1]);
- event.preventDefault();
- break;
- case 39: // right arrow
- if (event.shiftKey)
- chrome.send('move', ['horizontal', 1]);
- else
- chrome.send('resize', ['horizontal', 1]);
- event.preventDefault();
- break;
- case 40: // bottom arrow
- if (event.shiftKey)
- chrome.send('move', ['vertical', 1]);
- else
- chrome.send('resize', ['vertical', 1]);
- event.preventDefault();
- break;
- }
- }
- };
-
- DisplayOverscan.onOverscanCanceled = function() {
- DisplayOverscan.getInstance().onOverscanCanceled_();
- };
-
- // Export
- return {
- DisplayOverscan: DisplayOverscan
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/internet_detail.css b/chromium/chrome/browser/resources/options/chromeos/internet_detail.css
deleted file mode 100644
index 1528bc08781..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/internet_detail.css
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/* Force tab strip to extend to the left and right edges of the window. */
-#internet-details-content-area {
- -webkit-box-orient: vertical;
- display: -webkit-box;
- padding: 6px 0 0 0;
-}
-
-#network-details-header {
- -webkit-padding-start: 20px;
- margin: 0;
- padding-bottom: 12px;
- padding-top: 32px;
-}
-
-#network-details-title {
- font-size: 18px;
-}
-
-#network-details-subtitle-status {
- color: rgb(53, 174, 71);
-}
-
-
-/* Fix the height of the subpages so that the dialog does not resize when the
- user switches tabs. */
-#internet-details-content-area > .subpages-tab-contents {
- -webkit-box-flex: 1;
- -webkit-box-sizing: border-box;
- -webkit-padding-end: 10px;
- height: 390px;
- min-width: 480px;
- overflow-y: auto;
-}
-
-/* Avoid additional margins between text fields and controlled setting
- indicators as the fields in these dialogs have sufficient spacing around
- them already. */
-#internet-details-content-area
- input:-webkit-any([type='text'],[type='url'],:not([type])) +
- .controlled-setting-indicator {
- -webkit-margin-start: 0;
-}
-
-#vpn-tab td {
- padding: 0;
-}
-
-#vpn-tab .option-value:not(input) {
- padding: 4px;
-}
-
-#vpn-tab.third-party-vpn-provider tr.built-in-vpn-provider-only {
- display: none;
-}
-
-#vpn-tab:not(.third-party-vpn-provider) tr.third-party-vpn-provider-only {
- display: none;
-}
-
-#ip-config-list {
- min-height: 96px !important;
-}
-
-/* Minimum and maximum height are integer multiples of the height of a list
- entry. */
-#ignored-host-list {
- -webkit-margin-start: 0;
- border: 1px solid #bfbfbf;
- min-height: 64px;
- width: 400px;
-}
-
-#ignored-host-list[disabled] {
- background-color: rgb(235, 235, 228);
- color: #999;
- opacity: 1;
-}
-
-#new-host {
- -webkit-margin-start: 0;
- margin-top: 8px;
-}
-
-#ipconfig-section {
- border-top: 1px solid #eee;
- margin-bottom: 8px;
- padding-top: 8px;
-}
-
-#ipconfig-dns-section {
- border-top: 1px solid #eee;
- padding-top: 8px;
-}
-
-#user-dns-settings:not([selected]) {
- display: none;
-}
-
-.dns-display {
- -webkit-margin-start: 24px;
- -webkit-transition: opacity 150ms ease-in-out;
- color: #bbb;
- font-style: italic;
-}
-
-.dns-display:not([selected]) {
- -webkit-transition: opacity 150ms ease-in-out;
- display: none;
-}
-
-.proxy-subsection {
- padding-left: 24px;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/internet_detail.html b/chromium/chrome/browser/resources/options/chromeos/internet_detail.html
deleted file mode 100644
index e0fd05d37a6..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/internet_detail.html
+++ /dev/null
@@ -1,696 +0,0 @@
-<div id="details-internet-page" class="page" hidden>
- <div class="close-button"></div>
- <!-- Network header -->
- <div id="network-details-header">
- <div id="network-details-title"></div>
- <div id="network-details-subtitle">
- <span id="network-details-subtitle-status"></span>
- <span id="network-details-subtitle-separator"> - </span>
- <span id="network-details-subtitle-type"></span>
- </div>
- </div>
- <div id="internet-details-content-area" class="content-area">
- <!-- Navigation tabs -->
- <div id="details-tab-strip" class="subpages-nav-tabs">
- <span id="wifi-network-nav-tab" class="tab wifi-details"
- tab-contents="wifi-network-tab">
- <span class="tab-label"
- i18n-content="wifiNetworkTabLabel"></span>
- <span class="active-tab-label"
- i18n-content="wifiNetworkTabLabel"></span>
- </span>
- <span id="vpn-nav-tab" class="tab vpn-details"
- tab-contents="vpn-tab">
- <span class="tab-label"
- i18n-content="vpnTabLabel"></span>
- <span class="active-tab-label" i18n-content="vpnTabLabel"></span>
- </span>
- <span id="wimax-network-nav-tab" class="tab wimax-details"
- tab-contents="wimax-network-tab">
- <span class="tab-label"
- i18n-content="wimaxConnTabLabel"></span>
- <span class="active-tab-label"
- i18n-content="wimaxConnTabLabel"></span>
- </span>
- <span id="cellular-conn-nav-tab" class="tab cellular-details"
- tab-contents="cellular-conn-tab">
- <span class="tab-label"
- i18n-content="cellularConnTabLabel"></span>
- <span class="active-tab-label"
- i18n-content="cellularConnTabLabel"></span>
- </span>
- <span id="cellular-device-nav-tab" class="tab cellular-details"
- tab-contents="cellular-device-tab">
- <span class="tab-label"
- i18n-content="cellularDeviceTabLabel"></span>
- <span class="active-tab-label"
- i18n-content="cellularDeviceTabLabel"></span>
- </span>
- <span id="internet-nav-tab" class="tab network-details"
- tab-contents="internet-tab">
- <span class="tab-label" i18n-content="networkTabLabel"></span>
- <span class="active-tab-label" i18n-content="networkTabLabel"></span>
- </span>
- <span id="security-nav-tab" class="tab cellular-details gsm-only"
- tab-contents="security-tab">
- <span class="tab-label" i18n-content="securityTabLabel"></span>
- <span class="active-tab-label" i18n-content="securityTabLabel"></span>
- </span>
- <span id="internet-proxy-nav-tab" class="tab proxy-details"
- tab-contents="network-proxy-tab">
- <span class="tab-label" i18n-content="proxyTabLabel"></span>
- <span class="active-tab-label" i18n-content="proxyTabLabel"></span>
- </span>
- </div>
- <div id="wifi-network-tab" class="subpages-tab-contents wifi-details">
- <section>
- <table class="option-control-table">
- <tr id="prefer-network">
- <td>
- <div class="checkbox controlled-setting-with-label">
- <label>
- <input id="prefer-network-wifi" type="checkbox">
- <span>
- <span i18n-content="inetPreferredNetwork"></span>
- <span class="controlled-setting-indicator"
- managed="Priority"
- internet-detail-for="prefer-network-wifi"></span>
- </span>
- </label>
- </div>
- </td>
- </tr>
- <tr class="auto-connect-network">
- <td>
- <div class="checkbox controlled-setting-with-label">
- <label>
- <input id="auto-connect-network-wifi" type="checkbox">
- <span>
- <span i18n-content="inetAutoConnectNetwork"></span>
- <span class="controlled-setting-indicator"
- managed="WiFi.AutoConnect"
- internet-detail-for="auto-connect-network-wifi">
- </span>
- </span>
- </label>
- </div>
- </td>
- </tr>
- </table>
- </section>
- <section>
- <table id="wifi-settings-table">
- <tr>
- <td class="option-name" i18n-content="connectionState"></td>
- <td id="wifi-connection-state" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="restrictedConnectivity"></td>
- <td id="wifi-restricted-connectivity" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="inetSsid"></td>
- <td id="wifi-ssid" class="option-value"></td>
- </tr>
- <tr id="wifi-bssid-entry">
- <td class="option-name" i18n-content="inetBssid"></td>
- <td id="wifi-bssid" class="option-value"></td>
- </tr>
- <tr id="wifi-security-entry">
- <td class="options-name" i18n-content="inetEncryption"></td>
- <td id="wifi-security" class="option-value"></td>
- </tr>
- <tr>
- <td class="options-name" i18n-content="inetFrequency"></td>
- <td id="wifi-frequency" class="option-value"></td>
- </tr>
- <tr>
- <td class="options-name" i18n-content="inetSignalStrength"></td>
- <td id="wifi-signal-strength" class="option-value"></td>
- </tr>
- <tr id="wifi-hardware-address-entry">
- <td class="option-name" i18n-content="hardwareAddress"></td>
- <td id="wifi-hardware-address" class="option-value"></td>
- </tr>
- </table>
- </section>
- <section>
- <table class="option-control-table">
- <tr>
- <td id="password-details" class="option-name"
- i18n-content="inetPassProtected">
- </td>
- </tr>
- <tr>
- <td id="wifi-shared-network" class="option-name"
- i18n-content="inetNetworkShared">
- </td>
- </tr>
- </table>
- </section>
- </div>
- <div id="wimax-network-tab" class="subpages-tab-contents wimax-details">
- <section>
- <table class="option-control-table">
- <tr class="auto-connect-network">
- <td>
- <div class="checkbox controlled-setting-with-label">
- <label>
- <input id="auto-connect-network-wimax" type="checkbox">
- <span>
- <span i18n-content="inetAutoConnectNetwork"></span>
- <span class="controlled-setting-indicator"
- managed="WiMAX.AutoConnect"
- internet-detail-for="auto-connect-network-wimax">
- </span>
- </span>
- </label>
- </div>
- </td>
- </tr>
- </table>
- </section>
- <section>
- <table id="wimax-settings-table">
- <tr>
- <td class="option-name" i18n-content="connectionState"></td>
- <td id="wimax-connection-state" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="restrictedConnectivity"></td>
- <td id="wimax-restricted-connectivity" class="option-value"></td>
- </tr>
- <tr id="wimax-eap-identity-entry">
- <td class="option-name" i18n-content="inetUsername"></td>
- <td id="wimax-eap-identity" class="option-value"></td>
- </tr>
- <tr>
- <td class="options-name" i18n-content="inetSignalStrength"></td>
- <td id="wimax-signal-strength" class="option-value"></td>
- </tr>
- </table>
- </section>
- <section>
- <table class="option-control-table">
- <tr>
- <td id="wimax-shared-network" class="option-name"
- i18n-content="inetNetworkShared">
- </td>
- </tr>
- </table>
- </section>
- </div>
- <div id="vpn-tab" class="subpages-tab-contents vpn-details">
- <section>
- <table class="option-control-table">
- <tr class="auto-connect-network built-in-vpn-provider-only">
- <td>
- <div class="checkbox controlled-setting-with-label">
- <label>
- <input id="auto-connect-network-vpn" type="checkbox">
- <span>
- <span i18n-content="inetAutoConnectNetwork"></span>
- <span class="controlled-setting-indicator"
- managed="VPN.AutoConnect"
- internet-detail-for="auto-connect-network-vpn"></span>
- </span>
- </label>
- </div>
- </td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="inetServiceName"></td>
- <td id="inet-service-name" class="option-value"></td>
- </tr>
- <tr class="built-in-vpn-provider-only">
- <td class="option-name" i18n-content="inetServerHostname"></td>
- <td>
- <input class="option-value" id="inet-server-hostname"></input>
- <span class="controlled-setting-indicator"
- managed="VPN.Host"
- internet-detail-for="inet-server-hostname"></span>
- </td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="inetProviderType"></td>
- <td id="inet-provider-type" class="option-value"></td>
- </tr>
- <tr class="third-party-vpn-provider-only">
- <td class="option-name" i18n-content="inetProviderName"></td>
- <td id="inet-provider-name" class="option-value"></td>
- </tr>
- <tr class="built-in-vpn-provider-only">
- <td class="option-name" i18n-content="inetUsername"></td>
- <td id="inet-username" class="option-value"></td>
- </tr>
- </table>
- </section>
- </div>
- <div id="cellular-conn-tab" class="subpages-tab-contents cellular-details">
- <section id="cellular-network-options">
- <table class="option-control-table">
- <tr>
- <td class="option-name" i18n-content="serviceName"></td>
- <td id="service-name" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="networkTechnology"></td>
- <td id="network-technology" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="activationState"></td>
- <td id="activation-state" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="roamingState"></td>
- <td id="roaming-state" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="restrictedConnectivity"></td>
- <td id="cellular-restricted-connectivity" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="operatorName"></td>
- <td id="operator-name" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="operatorCode"></td>
- <td id="operator-code" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="errorState"></td>
- <td id="error-state" class="option-value"></td>
- </tr>
- <tr class="gsm-only apn-list-view">
- <td class="option-name" i18n-content="cellularApnLabel"></td>
- <td id="cellular-apn-label" class="option-value">
- <select id="select-apn">
- <option value="-1" i18n-content="cellularApnOther">
- </option>
- </select>
- <span class="controlled-setting-indicator"
- managed="Cellular.APN"
- internet-detail-for="select-apn"></span>
- </td>
- </tr>
- <tr class="gsm-only apn-details-view">
- <td class="option-name" i18n-content="cellularApnLabel"></td>
- <td id="cellular-apn-label" class="option-value">
- <input id="cellular-apn" type="text">
- </td>
- </tr>
- <tr class="gsm-only apn-details-view">
- <td class="option-name" i18n-content="cellularApnUsername"></td>
- <td id="cellular-apn-username-label" class="option-value">
- <input id="cellular-apn-username" type="text">
- </td>
- </tr>
- <tr class="gsm-only apn-details-view">
- <td class="option-name" i18n-content="cellularApnPassword"></td>
- <td id="cellular-apn-password-label" class="option-value">
- <input id="cellular-apn-password" type="password">
- </td>
- </tr>
- <tr class="gsm-only apn-details-view">
- <td class="option-name"></td>
- <td class="option-value">
- <button id="cellular-apn-use-default"
- i18n-content="cellularApnUseDefault"></button>
- <button id="cellular-apn-set"
- i18n-content="cellularApnSet"></button>
- <button id="cellular-apn-cancel"
- i18n-content="cellularApnCancel"></button>
- </td>
- </tr>
- <tr>
- <td colspan="2">
- <div class="checkbox controlled-setting-with-label">
- <label>
- <input id="auto-connect-network-cellular" type="checkbox">
- <span>
- <span i18n-content="inetAutoConnectNetwork"></span>
- <span class="controlled-setting-indicator"
- managed="Cellular.AutoConnect"
- internet-detail-for="auto-connect-network-cellular">
- </span>
- </span>
- </label>
- </div>
- </td>
- </tr>
- </table>
- </section>
- </div>
- <div id="cellular-device-tab" class="subpages-tab-contents
- cellular-details">
- <section id="cellular-device-options">
- <table class="option-control-table">
- <tr>
- <td class="option-name" i18n-content="cellularManufacturer"></td>
- <td id="manufacturer" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="modelId"></td>
- <td id="model-id" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="firmwareRevision"></td>
- <td id="firmware-revision" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name" i18n-content="hardwareRevision"></td>
- <td id="hardware-revision" class="option-value"></td>
- </tr>
- <tr class="cdma-only">
- <td class="option-name" i18n-content="prlVersion"></td>
- <td id="prl-version" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name">MEID:</td>
- <td id="meid" class="option-value"></td>
- </tr>
- <tr class="gsm-only">
- <td class="option-name">ICCID:</td>
- <td id="iccid" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name">ESN:</td>
- <td id="esn" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name">IMEI:</td>
- <td id="imei" class="option-value"></td>
- </tr>
- <tr class="gsm-only">
- <td class="option-name">IMSI:</td>
- <td id="imsi" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name">MDN:</td>
- <td id="mdn" class="option-value"></td>
- </tr>
- <tr>
- <td class="option-name">MIN/MSID:</td>
- <td id="min" class="option-value"></td>
- </tr>
- </table>
- </section>
- </div>
- <div id="internet-tab" class="subpages-tab-contents">
- <section id="advanced-section">
- <table class="option-control-table">
- <tr>
- <td class="option-name" i18n-content="connectionState"></td>
- <td id="connection-state" class="option-value"></td>
- </tr>
- <tr id="hardware-address-row">
- <td class="option-name" i18n-content="hardwareAddress"></td>
- <td id="hardware-address" class="option-value"></td>
- </tr>
- </table>
- </section>
- <section id="ipconfig-section">
- <div id="ip-automatic-configuration"
- class="checkbox controlled-setting-with-label">
- <label>
- <input id="ip-automatic-configuration-checkbox"
- type="checkbox">
- <span>
- <span i18n-content="ipAutomaticConfiguration"></span>
- <span class="controlled-setting-indicator"
- managed="IPAddressConfigType"></span>
- </span>
- </label>
- </div>
- <div>
- <table id="ip-address-settings">
- <tr>
- <td class="spacer" width="14px"></td>
- <td class="option-name" i18n-content="inetAddress"></td>
- <td><div id="ip-address"></div></td>
- </tr>
- <tr>
- <td class="spacer" width="14px"></td>
- <td class="option-name" id="ip-netmask-label"
- i18n-content="inetNetmask"></td>
- <td><div id="ip-netmask"></div></td>
- </tr>
- <tr>
- <td class="spacer" width="14px"></td>
- <td class="option-name" i18n-content="inetGateway"></td>
- <td><div id="ip-gateway"></div></td>
- </tr>
- </table>
- </section>
- <section id="ipconfig-dns-section">
- <div class="radio">
- <label>
- <input id="automatic-dns-radio" type="radio" name="dnstype"
- value="automatic">
- <span>
- <span i18n-content="automaticNameServers"></span>
- <span class="controlled-setting-indicator"
- managed="NameServersConfigType"></span>
- </span>
- </label>
- </div>
- <div id="automatic-dns-display" class="dns-display"></div>
- <div class="radio">
- <label>
- <input id="google-dns-radio" type="radio" name="dnstype"
- value="google">
- <span id="google-dns-label"></span>
- </label>
- </div>
- <div id="google-dns-display" class="dns-display"></div>
- <div class="radio">
- <label>
- <input id="user-dns-radio" type="radio" name="dnstype"
- value="user">
- <span i18n-content="userNameServers"></span>
- </label>
- </div>
- <table id="user-dns-settings">
- <tr>
- <td class="spacer" width="14px"></td>
- <td>
- <div id="ipconfig-dns1" i18n-placeholder-text="userNameServer1"
- allow-empty>
- </div>
- </td>
- <td>
- <div id="ipconfig-dns2" i18n-placeholder-text="userNameServer2"
- allow-empty>
- </div>
- </td>
- </tr>
- <tr>
- <td class="spacer" width="14px"></td>
- <td>
- <div id="ipconfig-dns3" i18n-placeholder-text="userNameServer3"
- allow-empty>
- </div>
- </td>
- <td>
- <div id="ipconfig-dns4" i18n-placeholder-text="userNameServer4"
- allow-empty>
- </div>
- </td>
- </tr>
- </table>
- </section>
- </div>
- <div id="security-tab"
- class="subpages-tab-contents cellular-details gsm-only">
- <div id="cellular-security-options">
- <section>
- <div id="sim-pin-lock" class="checkbox controlled-setting-with-label">
- <label>
- <input id="sim-card-lock-enabled" type="checkbox">
- <span>
- <span i18n-content="lockSimCard"></span>
- <span class="controlled-setting-indicator"
- managed="Cellular.SIMLockStatus.LockEnabled"
- internet-detail-for="sim-card-lock-enabled"></span>
- </span>
- </label>
- </div>
- </section>
- <section>
- <div id="change-pin-area">
- <button id="change-pin" i18n-content="changePinButton"></button>
- <span class="controlled-setting-indicator"
- managed="Cellular.SIMLockStatus.LockType"
- internet-detail-for="change-pin"></span>
- </div>
- </section>
- </div>
- </div>
- <div id="network-proxy-tab" class="subpages-tab-contents">
- <section>
- <div id="network-proxy-info-banner" hidden>
- <span id="banner-text" class="page-banner-text"></span>
- </div>
- <div class="radio">
- <label>
- <input id="direct-proxy" type="radio" name="proxytype" value="1"
- pref="cros.session.proxy.type">
- <span i18n-content="proxyDirectInternetConnection"></span>
- </label>
- </div>
- <div class="radio">
- <label>
- <input id="auto-proxy" type="radio" name="proxytype" value="3"
- pref="cros.session.proxy.type">
- <span i18n-content="proxyAutomatic"></span>
- </label>
- </div>
- <div class="proxy-subsection" id="auto-proxy-parms">
- <div class="checkbox">
- <label>
- <input id="proxy-use-pac-url" type="checkbox"
- pref="cros.session.proxy.usepacurl">
- <span i18n-content="proxyUseConfigUrl"></span>
- </label>
- </div>
- <div>
- <label>
- <input id="proxy-pac-url" type="url" size="50"
- pref="cros.session.proxy.pacurl">
- </label>
- </div>
- </div>
- <div class="radio">
- <label>
- <input id="manual-proxy" type="radio" name="proxytype" value="2"
- pref="cros.session.proxy.type">
- <span i18n-content="proxyManual"></span>
- </label>
- </div>
- <div class="proxy-subsection" id="manual-proxy-parms">
- <div class="checkbox">
- <label>
- <input id="proxy-all-protocols" type="checkbox"
- pref="cros.session.proxy.single">
- <span i18n-content="sameProxyProtocols"></span>
- </label>
- </div>
- <div id="single-proxy">
- <table>
- <tr>
- <td>
- <span i18n-content="httpProxy"></span>
- <input id="proxy-host-single-name" type="text" size="25"
- pref="cros.session.proxy.singlehttp" disabled>
- </td>
- <td>
- <span i18n-content="proxyPort"></span>
- <input id="proxy-host-single-port" size="4"
- pref="cros.session.proxy.singlehttpport" disabled>
- </td>
- </tr>
- </table>
- </div>
- <div id="multi-proxy">
- <table>
- <tr>
- <td>
- <span i18n-content="httpProxy"></span>
- </td>
- <td>
- <input id="proxy-host-name" type="text" size="25"
- pref="cros.session.proxy.httpurl" disabled>
- </td>
- <td>
- <span i18n-content="proxyPort"></span>
- </td>
- <td>
- <input id="proxy-host-port" size="4"
- pref="cros.session.proxy.httpport" disabled>
- </td>
- </tr>
- <tr>
- <td>
- <span i18n-content="secureHttpProxy"></span>
- </td>
- <td>
- <input id="secure-proxy-host-name" type="text" size="25"
- pref="cros.session.proxy.httpsurl" disabled>
- </td>
- <td>
- <span i18n-content="proxyPort"></span>
- </td>
- <td>
- <input id="secure-proxy-port" size="4"
- pref="cros.session.proxy.httpsport" disabled>
- </td>
- </tr>
- <tr>
- <td>
- <span i18n-content="ftpProxy"></span>
- </td>
- <td>
- <input id="ftp-proxy" type="text" size="25"
- pref="cros.session.proxy.ftpurl" disabled>
- </td>
- <td>
- <span i18n-content="proxyPort"></span>
- </td>
- <td>
- <input id="ftp-proxy-port" size="4"
- pref="cros.session.proxy.ftpport" disabled>
- </td>
- </tr>
- <tr>
- <td>
- <span i18n-content="socksHost"></span>
- </td>
- <td>
- <input id="socks-host" type="text" size="25"
- pref="cros.session.proxy.socks" disabled>
- </td>
- <td>
- <span i18n-content="proxyPort"></span>
- </td>
- <td>
- <input id="socks-port" size="4"
- pref="cros.session.proxy.socksport" disabled>
- </td>
- </tr>
- </table>
- </div>
- <div id="advanced-config">
- <div class="option vbox flex">
- <div i18n-content="proxyBypass"></div>
- <list id="ignored-host-list"></list>
- <input id="new-host" type="url" size="30">
- <button id="add-host" i18n-content="addHost"></button>
- <button id="remove-host" i18n-content="removeHost"></button>
- </div>
- </div>
- </div>
- <div class="proxy-subsection" id="web-proxy-auto-discovery">
- <span i18n-content="webProxyAutoDiscoveryUrl"></span>
- <input id="web-proxy-auto-discovery-url" type="url" disabled>
- </div>
- </section>
- </div>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <!-- TODO(dbeam): Clarify style guide regarding tag wrap. -->
- <button id="details-internet-dismiss" class="default-button"
- i18n-content="detailsInternetDismiss">
- </button>
- <button id="details-internet-login" i18n-content="connectButton">
- </button>
- <button id="details-internet-disconnect" i18n-content="disconnectButton">
- </button>
- <button id="details-internet-configure" i18n-content="configureButton">
- </button>
- <button id="activate-details" i18n-content="activateButton"></button>
- <button id="view-account-details" i18n-content="viewAccountButton">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/internet_detail.js b/chromium/chrome/browser/resources/options/chromeos/internet_detail.js
deleted file mode 100644
index 843b54b77a1..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/internet_detail.js
+++ /dev/null
@@ -1,1793 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// require: onc_data.js
-
-// NOTE(stevenjb): This code is in the process of being converted to be
-// compatible with the networkingPrivate extension API:
-// * The network property dictionaries are being converted to use ONC values.
-// * chrome.send calls will be replaced with chrome.networkingPrivate calls.
-// See crbug.com/279351 for more info.
-
-cr.define('options.internet', function() {
- var OncData = cr.onc.OncData;
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
- /** @const */ var IPAddressField = options.internet.IPAddressField;
-
- /** @const */ var GoogleNameServers = ['8.8.4.4', '8.8.8.8'];
- /** @const */ var CarrierSprint = 'Sprint';
- /** @const */ var CarrierVerizon = 'Verizon Wireless';
-
- /**
- * Helper function to set hidden attribute for elements matching a selector.
- * @param {string} selector CSS selector for extracting a list of elements.
- * @param {boolean} hidden New hidden value.
- */
- function updateHidden(selector, hidden) {
- var elements = cr.doc.querySelectorAll(selector);
- for (var i = 0, el; el = elements[i]; i++) {
- el.hidden = hidden;
- }
- }
-
- /**
- * Helper function to update the properties of the data object from the
- * properties in the update object.
- * @param {Object} data Object to update.
- * @param {Object} update Object containing the updated properties.
- */
- function updateDataObject(data, update) {
- for (var prop in update) {
- if (prop in data)
- data[prop] = update[prop];
- }
- }
-
- /**
- * Monitor pref change of given element.
- * @param {Element} el Target element.
- */
- function observePrefsUI(el) {
- Preferences.getInstance().addEventListener(el.pref, handlePrefUpdate);
- }
-
- /**
- * UI pref change handler.
- * @param {Event} e The update event.
- */
- function handlePrefUpdate(e) {
- DetailsInternetPage.getInstance().updateControls();
- }
-
- /**
- * Simple helper method for converting a field to a string. It is used to
- * easily assign an empty string from fields that may be unknown or undefined.
- * @param {Object} value that should be converted to a string.
- * @return {string} the result.
- */
- function stringFromValue(value) {
- return value ? String(value) : '';
- }
-
- /**
- * @param {string} action An action to send to coreOptionsUserMetricsAction.
- */
- function sendChromeMetricsAction(action) {
- chrome.send('coreOptionsUserMetricsAction', [action]);
- }
-
- /**
- * Send metrics to Chrome when the detailed page is opened.
- * @param {string} type The ONC type of the network being shown.
- * @param {string} state The ONC network state.
- */
- function sendShowDetailsMetrics(type, state) {
- if (type == 'WiFi') {
- sendChromeMetricsAction('Options_NetworkShowDetailsWifi');
- if (state != 'NotConnected')
- sendChromeMetricsAction('Options_NetworkShowDetailsWifiConnected');
- } else if (type == 'Cellular') {
- sendChromeMetricsAction('Options_NetworkShowDetailsCellular');
- if (state != 'NotConnected')
- sendChromeMetricsAction('Options_NetworkShowDetailsCellularConnected');
- } else if (type == 'VPN') {
- sendChromeMetricsAction('Options_NetworkShowDetailsVPN');
- if (state != 'NotConnected')
- sendChromeMetricsAction('Options_NetworkShowDetailsVPNConnected');
- }
- }
-
- /**
- * Returns the netmask as a string for a given prefix length.
- * @param {number} prefixLength The ONC routing prefix length.
- * @return {string} The corresponding netmask.
- */
- function prefixLengthToNetmask(prefixLength) {
- // Return the empty string for invalid inputs.
- if (prefixLength < 0 || prefixLength > 32)
- return '';
- var netmask = '';
- for (var i = 0; i < 4; ++i) {
- var remainder = 8;
- if (prefixLength >= 8) {
- prefixLength -= 8;
- } else {
- remainder = prefixLength;
- prefixLength = 0;
- }
- if (i > 0)
- netmask += '.';
- var value = 0;
- if (remainder != 0)
- value = ((2 << (remainder - 1)) - 1) << (8 - remainder);
- netmask += value.toString();
- }
- return netmask;
- }
-
- /**
- * Returns the prefix length from the netmask string.
- * @param {string} netmask The netmask string, e.g. 255.255.255.0.
- * @return {number} The corresponding netmask or -1 if invalid.
- */
- function netmaskToPrefixLength(netmask) {
- var prefixLength = 0;
- var tokens = netmask.split('.');
- if (tokens.length != 4)
- return -1;
- for (var i = 0; i < tokens.length; ++i) {
- var token = tokens[i];
- // If we already found the last mask and the current one is not
- // '0' then the netmask is invalid. For example, 255.224.255.0
- if (prefixLength / 8 != i) {
- if (token != '0')
- return -1;
- } else if (token == '255') {
- prefixLength += 8;
- } else if (token == '254') {
- prefixLength += 7;
- } else if (token == '252') {
- prefixLength += 6;
- } else if (token == '248') {
- prefixLength += 5;
- } else if (token == '240') {
- prefixLength += 4;
- } else if (token == '224') {
- prefixLength += 3;
- } else if (token == '192') {
- prefixLength += 2;
- } else if (token == '128') {
- prefixLength += 1;
- } else if (token == '0') {
- prefixLength += 0;
- } else {
- // mask is not a valid number.
- return -1;
- }
- }
- return prefixLength;
- }
-
- // Returns true if we should show the 'View Account' button for |onc|.
- // TODO(stevenjb): We should query the Mobile Config API for whether or not to
- // show the 'View Account' button once it is integrated with Settings.
- function shouldShowViewAccountButton(onc) {
- var activationState = onc.getActiveValue('Cellular.ActivationState');
- if (activationState != 'Activating' && activationState != 'Activated')
- return false;
-
- // If no online payment URL was provided by Shill, only show 'View Account'
- // for Verizon Wireless.
- if (!onc.getActiveValue('Cellular.PaymentPortal.Url') &&
- onc.getActiveValue('Cellular.Carrier') != CarrierVerizon) {
- return false;
- }
-
- // 'View Account' should only be shown for connected networks, or
- // disconnected LTE networks with a valid MDN.
- var connectionState = onc.getActiveValue('ConnectionState');
- if (connectionState != 'Connected') {
- var technology = onc.getActiveValue('Cellular.NetworkTechnology');
- if (technology != 'LTE' && technology != 'LTEAdvanced')
- return false;
- if (!onc.getActiveValue('Cellular.MDN'))
- return false;
- }
-
- return true;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // DetailsInternetPage class:
-
- /**
- * Encapsulated handling of ChromeOS internet details overlay page.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function DetailsInternetPage() {
- // If non-negative, indicates a custom entry in select-apn.
- this.userApnIndex_ = -1;
-
- // The custom APN properties associated with entry |userApnIndex_|.
- this.userApn_ = {};
-
- // The currently selected APN entry in $('select-apn') (which may or may not
- // == userApnIndex_).
- this.selectedApnIndex_ = -1;
-
- // We show the Proxy configuration tab for remembered networks and when
- // configuring a proxy from the login screen.
- this.showProxy_ = false;
-
- Page.call(this, 'detailsInternetPage', '', 'details-internet-page');
- }
-
- cr.addSingletonGetter(DetailsInternetPage);
-
- DetailsInternetPage.prototype = {
- __proto__: Page.prototype,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
- this.initializePageContents_();
-
- chrome.networkingPrivate.onNetworksChanged.addListener(
- this.onNetworksChanged_.bind(this));
-
- this.showNetworkDetails_();
- },
-
- /**
- * Automatically shows the network details dialog if network information
- * is included in the URL.
- */
- showNetworkDetails_: function() {
- var guid = parseQueryParams(window.location).guid;
- if (!guid || !guid.length)
- return;
- chrome.networkingPrivate.getManagedProperties(
- guid, DetailsInternetPage.initializeDetailsPage);
- },
-
- /**
- * networkingPrivate callback when networks change.
- * @param {Array<string>} changes List of GUIDs whose properties have
- * changed.
- * @private
- */
- onNetworksChanged_: function(changes) {
- if (!this.onc_)
- return;
- var guid = this.onc_.guid();
- if (changes.indexOf(guid) != -1) {
- chrome.networkingPrivate.getManagedProperties(
- guid, DetailsInternetPage.updateConnectionData);
- }
- },
-
- /**
- * Initializes the contents of the page.
- */
- initializePageContents_: function() {
- $('details-internet-dismiss').addEventListener('click', function(event) {
- DetailsInternetPage.setDetails();
- });
-
- $('details-internet-login').addEventListener('click', function(event) {
- DetailsInternetPage.setDetails();
- DetailsInternetPage.loginFromDetails();
- });
-
- $('details-internet-disconnect').addEventListener('click',
- function(event) {
- DetailsInternetPage.setDetails();
- DetailsInternetPage.disconnectNetwork();
- });
-
- $('details-internet-configure').addEventListener('click',
- function(event) {
- DetailsInternetPage.setDetails();
- DetailsInternetPage.configureNetwork();
- });
-
- $('activate-details').addEventListener('click', function(event) {
- DetailsInternetPage.activateFromDetails();
- });
-
- $('view-account-details').addEventListener('click', function(event) {
- chrome.send('showMorePlanInfo',
- [DetailsInternetPage.getInstance().onc_.guid()]);
- PageManager.closeOverlay();
- });
-
- $('cellular-apn-use-default').addEventListener('click', function(event) {
- DetailsInternetPage.getInstance().setDefaultApn_();
- });
-
- $('cellular-apn-set').addEventListener('click', function(event) {
- DetailsInternetPage.getInstance().setApn_($('cellular-apn').value);
- });
-
- $('cellular-apn-cancel').addEventListener('click', function(event) {
- DetailsInternetPage.getInstance().cancelApn_();
- });
-
- $('select-apn').addEventListener('change', function(event) {
- DetailsInternetPage.getInstance().selectApn_();
- });
-
- $('sim-card-lock-enabled').addEventListener('click', function(event) {
- var newValue = $('sim-card-lock-enabled').checked;
- // Leave value as is because user needs to enter PIN code first.
- // When PIN will be entered and value changed,
- // we'll update UI to reflect that change.
- $('sim-card-lock-enabled').checked = !newValue;
- var operation = newValue ? 'setLocked' : 'setUnlocked';
- chrome.send('simOperation', [operation]);
- });
- $('change-pin').addEventListener('click', function(event) {
- chrome.send('simOperation', ['changePin']);
- });
-
- // Proxy
- ['proxy-host-single-port',
- 'secure-proxy-port',
- 'socks-port',
- 'ftp-proxy-port',
- 'proxy-host-port'
- ].forEach(function(id) {
- options.PrefPortNumber.decorate($(id));
- });
-
- options.proxyexceptions.ProxyExceptions.decorate($('ignored-host-list'));
- $('remove-host').addEventListener('click',
- this.handleRemoveProxyExceptions_);
- $('add-host').addEventListener('click', this.handleAddProxyException_);
- $('direct-proxy').addEventListener('click', this.disableManualProxy_);
- $('manual-proxy').addEventListener('click', this.enableManualProxy_);
- $('auto-proxy').addEventListener('click', this.disableManualProxy_);
- $('proxy-all-protocols').addEventListener('click',
- this.toggleSingleProxy_);
- $('proxy-use-pac-url').addEventListener('change',
- this.handleAutoConfigProxy_);
-
- observePrefsUI($('direct-proxy'));
- observePrefsUI($('manual-proxy'));
- observePrefsUI($('auto-proxy'));
- observePrefsUI($('proxy-all-protocols'));
- observePrefsUI($('proxy-use-pac-url'));
-
- $('ip-automatic-configuration-checkbox').addEventListener('click',
- this.handleIpAutoConfig_);
- $('automatic-dns-radio').addEventListener('click',
- this.handleNameServerTypeChange_);
- $('google-dns-radio').addEventListener('click',
- this.handleNameServerTypeChange_);
- $('user-dns-radio').addEventListener('click',
- this.handleNameServerTypeChange_);
-
- // We only load this string if we have the string data available
- // because the proxy settings page on the login screen re-uses the
- // proxy sub-page from the internet options, and it doesn't ever
- // show the DNS settings, so we don't need this string there.
- // The string isn't available because
- // chrome://settings-frame/strings.js (where the string is
- // stored) is not accessible from the login screen.
- // TODO(pneubeck): Remove this once i18n of the proxy dialog on the login
- // page is fixed. http://crbug.com/242865
- if (loadTimeData.data_) {
- $('google-dns-label').innerHTML =
- loadTimeData.getString('googleNameServers');
- }
- },
-
- /**
- * Handler for "add" event fired from userNameEdit.
- * @param {Event} e Add event fired from userNameEdit.
- * @private
- */
- handleAddProxyException_: function(e) {
- var exception = $('new-host').value;
- $('new-host').value = '';
-
- exception = exception.trim();
- if (exception)
- $('ignored-host-list').addException(exception);
- },
-
- /**
- * Handler for when the remove button is clicked
- * @param {Event} e The click event.
- * @private
- */
- handleRemoveProxyExceptions_: function(e) {
- var selectedItems = $('ignored-host-list').selectedItems;
- for (var x = 0; x < selectedItems.length; x++) {
- $('ignored-host-list').removeException(selectedItems[x]);
- }
- },
-
- /**
- * Handler for when the IP automatic configuration checkbox is clicked.
- * @param {Event} e The click event.
- * @private
- */
- handleIpAutoConfig_: function(e) {
- var checked = $('ip-automatic-configuration-checkbox').checked;
- var fields = [$('ip-address'), $('ip-netmask'), $('ip-gateway')];
- for (var i = 0; i < fields.length; ++i) {
- fields[i].editable = !checked;
- if (checked) {
- var model = fields[i].model;
- model.value = model.automatic;
- fields[i].model = model;
- }
- }
- if (!checked)
- $('ip-address').focus();
- },
-
- /**
- * Handler for when the name server selection changes.
- * @param {Event} event The click event.
- * @private
- */
- handleNameServerTypeChange_: function(event) {
- var type = event.target.value;
- DetailsInternetPage.updateNameServerDisplay(type);
- },
-
- /**
- * Gets the IPConfig ONC Object.
- * @param {string} nameServerType The selected name server type:
- * 'automatic', 'google', or 'user'.
- * @return {Object} The IPConfig ONC object.
- * @private
- */
- getIpConfig_: function(nameServerType) {
- var ipConfig = {};
- // If 'ip-address' is empty, automatic configuration will be used.
- if (!$('ip-automatic-configuration-checkbox').checked &&
- $('ip-address').model.value) {
- ipConfig['IPAddress'] = $('ip-address').model.value;
- var netmask = $('ip-netmask').model.value;
- var routingPrefix = 0;
- if (netmask) {
- routingPrefix = netmaskToPrefixLength(netmask);
- if (routingPrefix == -1) {
- console.error('Invalid netmask: ' + netmask);
- routingPrefix = 0;
- }
- }
- ipConfig['RoutingPrefix'] = routingPrefix;
- ipConfig['Gateway'] = $('ip-gateway').model.value || '';
- }
-
- // Note: If no nameserver fields are set, automatic configuration will be
- // used. TODO(stevenjb): Validate input fields.
- if (nameServerType != 'automatic') {
- var userNameServers = [];
- if (nameServerType == 'google') {
- userNameServers = GoogleNameServers.slice();
- } else if (nameServerType == 'user') {
- for (var i = 1; i <= 4; ++i) {
- var nameServerField = $('ipconfig-dns' + i);
- // Skip empty values.
- if (nameServerField && nameServerField.model &&
- nameServerField.model.value) {
- userNameServers.push(nameServerField.model.value);
- }
- }
- }
- if (userNameServers.length)
- ipConfig['NameServers'] = userNameServers.sort();
- }
- return ipConfig;
- },
-
- /**
- * Creates an indicator event for controlled properties using
- * the same dictionary format as CoreOptionsHandler::CreateValueForPref.
- * @param {string} name The name for the Event.
- * @param {{value: *, controlledBy: *, recommendedValue: *}} propData
- * Property dictionary.
- * @private
- */
- createControlledEvent_: function(name, propData) {
- assert('value' in propData && 'controlledBy' in propData &&
- 'recommendedValue' in propData);
- var event = new Event(name);
- event.value = {
- value: propData.value,
- controlledBy: propData.controlledBy,
- recommendedValue: propData.recommendedValue
- };
- return event;
- },
-
- /**
- * Creates an indicator event for controlled properties using
- * the ONC getManagedProperties dictionary format.
- * @param {string} name The name for the Event.
- * @param {Object} propData ONC managed network property dictionary.
- * @private
- */
- createManagedEvent_: function(name, propData) {
- var event = new Event(name);
- event.value = {};
-
- // Set the current value and recommended value.
- var activeValue = propData['Active'];
- var effective = propData['Effective'];
- if (activeValue == undefined)
- activeValue = propData[effective];
- event.value.value = activeValue;
-
- // If a property is editable then it is not enforced, and 'controlledBy'
- // is set to 'recommended' unless effective == {User|Shared}Setting, in
- // which case the value was modified from the recommended value.
- // Otherwise if 'Effective' is set to 'UserPolicy' or 'DevicePolicy' then
- // the set value is mandated by the policy.
- if (propData['UserEditable']) {
- if (effective == 'UserPolicy')
- event.value.controlledBy = 'recommended';
- event.value.recommendedValue = propData['UserPolicy'];
- } else if (propData['DeviceEditable']) {
- if (effective == 'DevicePolicy')
- event.value.controlledBy = 'recommended';
- event.value.recommendedValue = propData['DevicePolicy'];
- } else if (effective == 'UserPolicy' || effective == 'DevicePolicy') {
- event.value.controlledBy = 'policy';
- }
-
- return event;
- },
-
- /**
- * Update details page controls.
- */
- updateControls: function() {
- // Note: onc may be undefined when called from a pref update before
- // initialized in initializeDetailsPage.
- var onc = this.onc_;
-
- // Always show the ipconfig section. TODO(stevenjb): Improve the display
- // for unconnected networks. Currently the IP address fields may be
- // blank if the network is not connected.
- $('ipconfig-section').hidden = false;
- $('ipconfig-dns-section').hidden = false;
-
- // Network type related.
- updateHidden('#details-internet-page .cellular-details',
- this.type_ != 'Cellular');
- updateHidden('#details-internet-page .wifi-details',
- this.type_ != 'WiFi');
- updateHidden('#details-internet-page .wimax-details',
- this.type_ != 'WiMAX');
- updateHidden('#details-internet-page .vpn-details', this.type_ != 'VPN');
- updateHidden('#details-internet-page .proxy-details', !this.showProxy_);
-
- // Cellular
- if (onc && this.type_ == 'Cellular') {
- // Hide gsm/cdma specific elements.
- if (onc.getActiveValue('Cellular.Family') == 'GSM')
- updateHidden('#details-internet-page .cdma-only', true);
- else
- updateHidden('#details-internet-page .gsm-only', true);
- }
-
- // Wifi
-
- // Hide network tab for VPN.
- updateHidden('#details-internet-page .network-details',
- this.type_ == 'VPN');
-
- // Password and shared.
- var source = onc ? onc.getSource() : 'None';
- var shared = (source == 'Device' || source == 'DevicePolicy');
- var security = onc ? onc.getWiFiSecurity() : 'None';
- updateHidden('#details-internet-page #password-details',
- this.type_ != 'WiFi' || security == 'None');
- updateHidden('#details-internet-page #wifi-shared-network', !shared);
- updateHidden('#details-internet-page #prefer-network', source == 'None');
-
- // WiMAX.
- updateHidden('#details-internet-page #wimax-shared-network', !shared);
-
- // Proxy
- this.updateProxyBannerVisibility_();
- this.toggleSingleProxy_();
- if ($('manual-proxy').checked)
- this.enableManualProxy_();
- else
- this.disableManualProxy_();
- },
-
- /**
- * Updates info banner visibility state. This function shows the banner
- * if proxy is managed or shared-proxies is off for shared network.
- * @private
- */
- updateProxyBannerVisibility_: function() {
- var bannerDiv = $('network-proxy-info-banner');
- if (!loadTimeData.data_) {
- // TODO(pneubeck): This temporarily prevents an exception below until
- // i18n of the proxy dialog on the login page is
- // fixed. http://crbug.com/242865
- bannerDiv.hidden = true;
- return;
- }
-
- // Show banner and determine its message if necessary.
- var controlledBy = $('direct-proxy').controlledBy;
- if (!controlledBy || controlledBy == '') {
- bannerDiv.hidden = true;
- } else {
- bannerDiv.hidden = false;
- // The possible banner texts are loaded in proxy_handler.cc.
- var bannerText = 'proxyBanner' + controlledBy.charAt(0).toUpperCase() +
- controlledBy.slice(1);
- $('banner-text').textContent = loadTimeData.getString(bannerText);
- }
- },
-
- /**
- * Handler for when the user clicks on the checkbox to allow a
- * single proxy usage.
- * @private
- */
- toggleSingleProxy_: function() {
- if ($('proxy-all-protocols').checked) {
- $('multi-proxy').hidden = true;
- $('single-proxy').hidden = false;
- } else {
- $('multi-proxy').hidden = false;
- $('single-proxy').hidden = true;
- }
- },
-
- /**
- * Handler for when the user clicks on the checkbox to enter
- * auto configuration URL.
- * @private
- */
- handleAutoConfigProxy_: function() {
- $('proxy-pac-url').disabled = !$('proxy-use-pac-url').checked;
- },
-
- /**
- * Handler for selecting a radio button that will disable the manual
- * controls.
- * @private
- */
- disableManualProxy_: function() {
- $('ignored-host-list').disabled = true;
- $('new-host').disabled = true;
- $('remove-host').disabled = true;
- $('add-host').disabled = true;
- $('proxy-all-protocols').disabled = true;
- $('proxy-host-name').disabled = true;
- $('proxy-host-port').disabled = true;
- $('proxy-host-single-name').disabled = true;
- $('proxy-host-single-port').disabled = true;
- $('secure-proxy-host-name').disabled = true;
- $('secure-proxy-port').disabled = true;
- $('ftp-proxy').disabled = true;
- $('ftp-proxy-port').disabled = true;
- $('socks-host').disabled = true;
- $('socks-port').disabled = true;
- $('proxy-use-pac-url').disabled = $('auto-proxy').disabled ||
- !$('auto-proxy').checked;
- $('proxy-pac-url').disabled = $('proxy-use-pac-url').disabled ||
- !$('proxy-use-pac-url').checked;
- $('auto-proxy-parms').hidden = !$('auto-proxy').checked;
- $('manual-proxy-parms').hidden = !$('manual-proxy').checked;
- sendChromeMetricsAction('Options_NetworkManualProxy_Disable');
- },
-
- /**
- * Handler for selecting a radio button that will enable the manual
- * controls.
- * @private
- */
- enableManualProxy_: function() {
- $('ignored-host-list').redraw();
- var allDisabled = $('manual-proxy').disabled;
- $('ignored-host-list').disabled = allDisabled;
- $('new-host').disabled = allDisabled;
- $('remove-host').disabled = allDisabled;
- $('add-host').disabled = allDisabled;
- $('proxy-all-protocols').disabled = allDisabled;
- $('proxy-host-name').disabled = allDisabled;
- $('proxy-host-port').disabled = allDisabled;
- $('proxy-host-single-name').disabled = allDisabled;
- $('proxy-host-single-port').disabled = allDisabled;
- $('secure-proxy-host-name').disabled = allDisabled;
- $('secure-proxy-port').disabled = allDisabled;
- $('ftp-proxy').disabled = allDisabled;
- $('ftp-proxy-port').disabled = allDisabled;
- $('socks-host').disabled = allDisabled;
- $('socks-port').disabled = allDisabled;
- $('proxy-use-pac-url').disabled = true;
- $('proxy-pac-url').disabled = true;
- $('auto-proxy-parms').hidden = !$('auto-proxy').checked;
- $('manual-proxy-parms').hidden = !$('manual-proxy').checked;
- sendChromeMetricsAction('Options_NetworkManualProxy_Enable');
- },
-
- /**
- * Helper method called from initializeDetailsPage and updateConnectionData.
- * Updates visibility/enabled of the login/disconnect/configure buttons.
- * @private
- */
- updateConnectionButtonVisibility_: function() {
- var onc = this.onc_;
- if (this.type_ == 'Ethernet') {
- // Ethernet can never be connected or disconnected and can always be
- // configured (e.g. to set security).
- $('details-internet-login').hidden = true;
- $('details-internet-disconnect').hidden = true;
- $('details-internet-configure').hidden = false;
- return;
- }
-
- var connectable = onc.getActiveValue('Connectable');
- var connectState = onc.getActiveValue('ConnectionState');
- if (connectState == 'NotConnected') {
- $('details-internet-disconnect').hidden = true;
- $('details-internet-login').hidden = false;
- // Connecting to an unconfigured network might trigger certificate
- // installation UI. Until that gets handled here, always enable the
- // Connect button for built-in networks.
- var enabled = (this.type_ != 'VPN') ||
- (onc.getActiveValue('VPN.Type') != 'ThirdPartyVPN') ||
- connectable;
- $('details-internet-login').disabled = !enabled;
- } else {
- $('details-internet-login').hidden = true;
- $('details-internet-disconnect').hidden = false;
- }
-
- var showConfigure = false;
- if (this.type_ == 'VPN') {
- showConfigure = true;
- } else if (this.type_ == 'WiMAX' && connectState == 'NotConnected') {
- showConfigure = true;
- } else if (this.type_ == 'WiFi') {
- showConfigure = (connectState == 'NotConnected' &&
- (!connectable || onc.getWiFiSecurity() != 'None'));
- }
- $('details-internet-configure').hidden = !showConfigure;
- },
-
- /**
- * Helper method called from initializeDetailsPage and updateConnectionData.
- * Updates the connection state property and account / sim card links.
- * @private
- */
- updateDetails_: function() {
- var onc = this.onc_;
-
- var connectionStateString = onc.getTranslatedValue('ConnectionState');
- $('connection-state').textContent = connectionStateString;
-
- var type = this.type_;
- var showViewAccount = false;
- var showActivate = false;
- if (type == 'WiFi') {
- $('wifi-connection-state').textContent = connectionStateString;
- } else if (type == 'WiMAX') {
- $('wimax-connection-state').textContent = connectionStateString;
- } else if (type == 'Cellular') {
- $('activation-state').textContent =
- onc.getTranslatedValue('Cellular.ActivationState');
- if (onc.getActiveValue('Cellular.Family') == 'GSM') {
- var lockEnabled =
- onc.getActiveValue('Cellular.SIMLockStatus.LockEnabled');
- $('sim-card-lock-enabled').checked = lockEnabled;
- $('change-pin').hidden = !lockEnabled;
- }
- showViewAccount = shouldShowViewAccountButton(onc);
- var activationState = onc.getActiveValue('Cellular.ActivationState');
- showActivate = (activationState == 'NotActivated' ||
- activationState == 'PartiallyActivated');
- }
-
- $('view-account-details').hidden = !showViewAccount;
- $('activate-details').hidden = !showActivate;
- // If activation is not complete, hide the login button.
- if (showActivate)
- $('details-internet-login').hidden = true;
- },
-
- /**
- * Helper method called from initializeDetailsPage and updateConnectionData.
- * Updates the fields in the header section of the details frame.
- * @private
- */
- populateHeader_: function() {
- var onc = this.onc_;
-
- var name = onc.getTranslatedValue('Name');
- if (onc.getActiveValue('Type') == 'VPN' &&
- onc.getActiveValue('VPN.Type') == 'ThirdPartyVPN') {
- var providerName =
- onc.getActiveValue('VPN.ThirdPartyVPN.ProviderName') ||
- loadTimeData.getString('defaultThirdPartyProviderName');
- name = loadTimeData.getStringF('vpnNameTemplate', providerName, name);
- }
- $('network-details-title').textContent = name;
-
- var connectionStateString = onc.getTranslatedValue('ConnectionState');
- $('network-details-subtitle-status').textContent = connectionStateString;
-
- var typeKey;
- var type = this.type_;
- if (type == 'Ethernet')
- typeKey = 'ethernetTitle';
- else if (type == 'WiFi')
- typeKey = 'wifiTitle';
- else if (type == 'WiMAX')
- typeKey = 'wimaxTitle';
- else if (type == 'Cellular')
- typeKey = 'cellularTitle';
- else if (type == 'VPN')
- typeKey = 'vpnTitle';
- else
- typeKey = null;
- var typeLabel = $('network-details-subtitle-type');
- var typeSeparator = $('network-details-subtitle-separator');
- if (typeKey) {
- typeLabel.textContent = loadTimeData.getString(typeKey);
- typeLabel.hidden = false;
- typeSeparator.hidden = false;
- } else {
- typeLabel.hidden = true;
- typeSeparator.hidden = true;
- }
- },
-
- /**
- * Helper method to insert a 'user' option into the Apn list.
- * @param {Object} userOption The 'user' apn dictionary
- * @private
- */
- insertApnUserOption_: function(userOption) {
- // Add the 'user' option before the last option ('other')
- var apnSelector = $('select-apn');
- assert(apnSelector.length > 0);
- var otherOption = apnSelector[apnSelector.length - 1];
- apnSelector.add(userOption, otherOption);
- this.userApnIndex_ = apnSelector.length - 2;
- this.selectedApnIndex_ = this.userApnIndex_;
- },
-
- /**
- * Helper method called from initializeApnList to populate the Apn list.
- * @param {Array} apnList List of available APNs.
- * @private
- */
- populateApnList_: function(apnList) {
- var onc = this.onc_;
- var apnSelector = $('select-apn');
- assert(apnSelector.length == 1);
- var otherOption = apnSelector[0];
- var activeApn = onc.getActiveValue('Cellular.APN.AccessPointName');
- var lastGoodApn =
- onc.getActiveValue('Cellular.LastGoodAPN.AccessPointName');
- for (var i = 0; i < apnList.length; i++) {
- var apnDict = apnList[i];
- var localizedName = apnDict['LocalizedName'];
- var name = localizedName ? localizedName : apnDict['Name'];
- var accessPointName = apnDict['AccessPointName'];
- var option = document.createElement('option');
- option.textContent =
- name ? (name + ' (' + accessPointName + ')') : accessPointName;
- option.value = i;
- // Insert new option before 'other' option.
- apnSelector.add(option, otherOption);
- if (this.selectedApnIndex_ != -1)
- continue;
- // If this matches the active Apn name, or LastGoodApn name (or there
- // is no last good APN), set it as the selected Apn.
- if ((activeApn == accessPointName) ||
- (!activeApn && (!lastGoodApn || lastGoodApn == accessPointName))) {
- this.selectedApnIndex_ = i;
- }
- }
- if (this.selectedApnIndex_ == -1 && activeApn) {
- this.userApn_ = activeApn;
- // Create a 'user' entry for any active apn not in the list.
- var userOption = document.createElement('option');
- userOption.textContent = activeApn;
- userOption.value = -1;
- this.insertApnUserOption_(userOption);
- }
- },
-
- /**
- * Helper method called from initializeDetailsPage to initialize the Apn
- * list.
- * @private
- */
- initializeApnList_: function() {
- this.selectedApnIndex_ = -1;
- this.userApnIndex_ = -1;
-
- var onc = this.onc_;
- var apnSelector = $('select-apn');
-
- // Clear APN lists, keep only last element, 'other'.
- while (apnSelector.length != 1)
- apnSelector.remove(0);
-
- var apnList = onc.getActiveValue('Cellular.APNList');
- if (apnList) {
- // Populate the list with the existing APNs.
- this.populateApnList_(apnList);
- } else {
- // Create a single 'default' entry.
- var otherOption = apnSelector[0];
- var defaultOption = document.createElement('option');
- defaultOption.textContent =
- loadTimeData.getString('cellularApnUseDefault');
- defaultOption.value = -1;
- // Add 'default' entry before 'other' option
- apnSelector.add(defaultOption, otherOption);
- assert(apnSelector.length == 2); // 'default', 'other'
- this.selectedApnIndex_ = 0; // Select 'default'
- }
- assert(this.selectedApnIndex_ >= 0);
- apnSelector.selectedIndex = this.selectedApnIndex_;
- updateHidden('.apn-list-view', false);
- updateHidden('.apn-details-view', true);
- },
-
- /**
- * Helper function for setting APN properties.
- * @param {Object} apnValue Dictionary of APN properties.
- * @private
- */
- setActiveApn_: function(apnValue) {
- var activeApn = {};
- var apnName = apnValue['AccessPointName'];
- if (apnName) {
- activeApn['AccessPointName'] = apnName;
- activeApn['Username'] = stringFromValue(apnValue['Username']);
- activeApn['Password'] = stringFromValue(apnValue['Password']);
- }
- // Set the cached ONC data.
- this.onc_.setProperty('Cellular.APN', activeApn);
- // Set an ONC object with just the APN values.
- var oncData = new OncData({});
- oncData.setProperty('Cellular.APN', activeApn);
- chrome.networkingPrivate.setProperties(this.onc_.guid(),
- oncData.getData());
- },
-
- /**
- * Event Listener for the cellular-apn-use-default button.
- * @private
- */
- setDefaultApn_: function() {
- var apnSelector = $('select-apn');
-
- // Remove the 'user' entry if it exists.
- if (this.userApnIndex_ != -1) {
- assert(this.userApnIndex_ < apnSelector.length - 1);
- apnSelector.remove(this.userApnIndex_);
- this.userApnIndex_ = -1;
- }
-
- var apnList = this.onc_.getActiveValue('Cellular.APNList');
- var iApn = (apnList != undefined && apnList.length > 0) ? 0 : -1;
- apnSelector.selectedIndex = iApn;
- this.selectedApnIndex_ = iApn;
-
- // Clear any user APN entry to inform Chrome to use the default APN.
- this.setActiveApn_({});
-
- updateHidden('.apn-list-view', false);
- updateHidden('.apn-details-view', true);
- },
-
- /**
- * Event Listener for the cellular-apn-set button.
- * @private
- */
- setApn_: function(apnValue) {
- if (apnValue == '')
- return;
-
- var apnSelector = $('select-apn');
-
- var activeApn = {};
- activeApn['AccessPointName'] = stringFromValue(apnValue);
- activeApn['Username'] = stringFromValue($('cellular-apn-username').value);
- activeApn['Password'] = stringFromValue($('cellular-apn-password').value);
- this.setActiveApn_(activeApn);
- // Set the user selected APN.
- this.userApn_ = activeApn;
-
- // Remove any existing 'user' entry.
- if (this.userApnIndex_ != -1) {
- assert(this.userApnIndex_ < apnSelector.length - 1);
- apnSelector.remove(this.userApnIndex_);
- this.userApnIndex_ = -1;
- }
-
- // Create a new 'user' entry with the new active apn.
- var option = document.createElement('option');
- option.textContent = activeApn['AccessPointName'];
- option.value = -1;
- option.selected = true;
- this.insertApnUserOption_(option);
-
- updateHidden('.apn-list-view', false);
- updateHidden('.apn-details-view', true);
- },
-
- /**
- * Event Listener for the cellular-apn-cancel button.
- * @private
- */
- cancelApn_: function() { this.initializeApnList_(); },
-
- /**
- * Event Listener for the select-apn button.
- * @private
- */
- selectApn_: function() {
- var onc = this.onc_;
- var apnSelector = $('select-apn');
- if (apnSelector[apnSelector.selectedIndex].value != -1) {
- var apnList = onc.getActiveValue('Cellular.APNList');
- var apnIndex = apnSelector.selectedIndex;
- assert(apnIndex < apnList.length);
- this.selectedApnIndex_ = apnIndex;
- this.setActiveApn_(apnList[apnIndex]);
- } else if (apnSelector.selectedIndex == this.userApnIndex_) {
- this.selectedApnIndex_ = apnSelector.selectedIndex;
- this.setActiveApn_(this.userApn_);
- } else { // 'Other'
- var apnDict;
- if (this.userApn_['AccessPointName']) {
- // Fill in the details fields with the existing 'user' config.
- apnDict = this.userApn_;
- } else {
- // No 'user' config, use the current values.
- apnDict = {};
- apnDict['AccessPointName'] =
- onc.getActiveValue('Cellular.APN.AccessPointName');
- apnDict['Username'] = onc.getActiveValue('Cellular.APN.Username');
- apnDict['Password'] = onc.getActiveValue('Cellular.APN.Password');
- }
- $('cellular-apn').value = stringFromValue(apnDict['AccessPointName']);
- $('cellular-apn-username').value = stringFromValue(apnDict['Username']);
- $('cellular-apn-password').value = stringFromValue(apnDict['Password']);
- updateHidden('.apn-list-view', true);
- updateHidden('.apn-details-view', false);
- }
- }
- };
-
- /**
- * Enables or Disables all buttons that provide operations on the cellular
- * network.
- */
- DetailsInternetPage.changeCellularButtonsState = function(disable) {
- var buttonsToDisableList =
- new Array('details-internet-login',
- 'details-internet-disconnect',
- 'details-internet-configure',
- 'activate-details',
- 'view-account-details');
-
- for (var i = 0; i < buttonsToDisableList.length; ++i) {
- var button = $(buttonsToDisableList[i]);
- button.disabled = disable;
- }
- };
-
- /**
- * If the network is not already activated, starts the activation process or
- * shows the activation UI. Otherwise does nothing.
- */
- DetailsInternetPage.activateCellular = function(guid) {
- chrome.networkingPrivate.getProperties(guid, function(properties) {
- var oncData = new OncData(properties);
- if (oncData.getActiveValue('Cellular.ActivationState') == 'Activated') {
- return;
- }
- var carrier = oncData.getActiveValue('Cellular.Carrier');
- if (carrier == CarrierSprint) {
- // Sprint is directly ativated, call startActivate().
- chrome.networkingPrivate.startActivate(guid, '');
- } else {
- chrome.send('showMorePlanInfo', [guid]);
- }
- });
- };
-
- /**
- * Performs minimal initialization of the InternetDetails dialog in
- * preparation for showing proxy-settings.
- */
- DetailsInternetPage.initializeProxySettings = function() {
- DetailsInternetPage.getInstance().initializePageContents_();
- };
-
- /**
- * Displays the InternetDetails dialog with only the proxy settings visible.
- */
- DetailsInternetPage.showProxySettings = function() {
- var detailsPage = DetailsInternetPage.getInstance();
- $('network-details-header').hidden = true;
- $('activate-details').hidden = true;
- $('view-account-details').hidden = true;
- $('web-proxy-auto-discovery').hidden = true;
- detailsPage.showProxy_ = true;
- updateHidden('#internet-tab', true);
- updateHidden('#details-tab-strip', true);
- updateHidden('#details-internet-page .action-area', true);
- detailsPage.updateControls();
- detailsPage.visible = true;
- sendChromeMetricsAction('Options_NetworkShowProxyTab');
- };
-
- /**
- * Initializes even handling for keyboard driven flow.
- */
- DetailsInternetPage.initializeKeyboardFlow = function() {
- keyboard.initializeKeyboardFlow();
- };
-
- DetailsInternetPage.updateProxySettings = function(type) {
- var proxyHost = null,
- proxyPort = null;
-
- if (type == 'cros.session.proxy.singlehttp') {
- proxyHost = 'proxy-host-single-name';
- proxyPort = 'proxy-host-single-port';
- } else if (type == 'cros.session.proxy.httpurl') {
- proxyHost = 'proxy-host-name';
- proxyPort = 'proxy-host-port';
- } else if (type == 'cros.session.proxy.httpsurl') {
- proxyHost = 'secure-proxy-host-name';
- proxyPort = 'secure-proxy-port';
- } else if (type == 'cros.session.proxy.ftpurl') {
- proxyHost = 'ftp-proxy';
- proxyPort = 'ftp-proxy-port';
- } else if (type == 'cros.session.proxy.socks') {
- proxyHost = 'socks-host';
- proxyPort = 'socks-port';
- } else {
- return;
- }
-
- var hostValue = $(proxyHost).value;
- if (hostValue.indexOf(':') !== -1) {
- if (hostValue.match(/:/g).length == 1) {
- hostValue = hostValue.split(':');
- $(proxyHost).value = hostValue[0];
- $(proxyPort).value = hostValue[1];
- }
- }
- };
-
- DetailsInternetPage.loginFromDetails = function() {
- DetailsInternetPage.configureOrConnect();
- PageManager.closeOverlay();
- };
-
- /**
- * This function identifies unconfigured networks and networks that are
- * likely to fail (e.g. due to a bad passphrase on a previous connect
- * attempt). For such networks a configure dialog will be opened. Otherwise
- * a connection will be attempted.
- */
- DetailsInternetPage.configureOrConnect = function() {
- var detailsPage = DetailsInternetPage.getInstance();
- if (detailsPage.type_ == 'WiFi')
- sendChromeMetricsAction('Options_NetworkConnectToWifi');
- else if (detailsPage.type_ == 'VPN')
- sendChromeMetricsAction('Options_NetworkConnectToVPN');
-
- var onc = detailsPage.onc_;
- var guid = onc.guid();
- var type = onc.getActiveValue('Type');
-
- // Built-in VPNs do not correctly set 'Connectable', so we always show the
- // configuration UI.
- if (type == 'VPN') {
- if (onc.getActiveValue('VPN.Type') != 'ThirdPartyVPN') {
- chrome.send('configureNetwork', [guid]);
- return;
- }
- }
-
- // If 'Connectable' is false for WiFi or WiMAX, Shill requires
- // additional configuration to connect, so show the configuration UI.
- if ((type == 'WiFi' || type == 'WiMAX') &&
- !onc.getActiveValue('Connectable')) {
- chrome.send('configureNetwork', [guid]);
- return;
- }
-
- // Secure WiFi networks with ErrorState set most likely require
- // configuration (e.g. a correct passphrase) before connecting.
- if (type == 'WiFi' && onc.getWiFiSecurity() != 'None') {
- var errorState = onc.getActiveValue('ErrorState');
- if (errorState && errorState != 'Unknown') {
- chrome.send('configureNetwork', [guid]);
- return;
- }
- }
-
- // Cellular networks need to be activated before they can be connected to.
- if (type == 'Cellular') {
- var activationState = onc.getActiveValue('Cellular.ActivationState');
- if (activationState != 'Activated' && activationState != 'Unknown') {
- DetailsInternetPage.activateCellular(guid);
- return;
- }
- }
-
- chrome.networkingPrivate.startConnect(guid);
- };
-
- DetailsInternetPage.disconnectNetwork = function() {
- var detailsPage = DetailsInternetPage.getInstance();
- if (detailsPage.type_ == 'WiFi')
- sendChromeMetricsAction('Options_NetworkDisconnectWifi');
- else if (detailsPage.type_ == 'VPN')
- sendChromeMetricsAction('Options_NetworkDisconnectVPN');
- chrome.networkingPrivate.startDisconnect(detailsPage.onc_.guid());
- PageManager.closeOverlay();
- };
-
- DetailsInternetPage.configureNetwork = function() {
- var detailsPage = DetailsInternetPage.getInstance();
- // This is an explicit request to show the configure dialog; do not show
- // the enrollment dialog for networks missing a certificate.
- var forceShow = true;
- chrome.send('configureNetwork', [detailsPage.onc_.guid(), forceShow]);
- PageManager.closeOverlay();
- };
-
- DetailsInternetPage.activateFromDetails = function() {
- var detailsPage = DetailsInternetPage.getInstance();
- if (detailsPage.type_ == 'Cellular')
- DetailsInternetPage.activateCellular(detailsPage.onc_.guid());
- PageManager.closeOverlay();
- };
-
- /**
- * Event handler called when the details page is closed. Sends changed
- * properties to Chrome and closes the overlay.
- */
- DetailsInternetPage.setDetails = function() {
- var detailsPage = DetailsInternetPage.getInstance();
- var type = detailsPage.type_;
- var oncData = new OncData({});
- var autoConnectCheckboxId = '';
- if (type == 'WiFi') {
- var preferredCheckbox =
- assertInstanceof($('prefer-network-wifi'), HTMLInputElement);
- if (!preferredCheckbox.hidden && !preferredCheckbox.disabled) {
- var kPreferredPriority = 1;
- var priority = preferredCheckbox.checked ? kPreferredPriority : 0;
- oncData.setProperty('Priority', priority);
- sendChromeMetricsAction('Options_NetworkSetPrefer');
- }
- autoConnectCheckboxId = 'auto-connect-network-wifi';
- } else if (type == 'WiMAX') {
- autoConnectCheckboxId = 'auto-connect-network-wimax';
- } else if (type == 'Cellular') {
- autoConnectCheckboxId = 'auto-connect-network-cellular';
- } else if (type == 'VPN') {
- var providerType = detailsPage.onc_.getActiveValue('VPN.Type');
- if (providerType != 'ThirdPartyVPN') {
- oncData.setProperty('VPN.Type', providerType);
- oncData.setProperty('VPN.Host', $('inet-server-hostname').value);
- autoConnectCheckboxId = 'auto-connect-network-vpn';
- }
- }
- if (autoConnectCheckboxId != '') {
- var autoConnectCheckbox =
- assertInstanceof($(autoConnectCheckboxId), HTMLInputElement);
- if (!autoConnectCheckbox.hidden && !autoConnectCheckbox.disabled) {
- var autoConnectKey = type + '.AutoConnect';
- oncData.setProperty(autoConnectKey, !!autoConnectCheckbox.checked);
- sendChromeMetricsAction('Options_NetworkAutoConnect');
- }
- }
-
- var nameServerTypes = ['automatic', 'google', 'user'];
- var nameServerType = 'automatic';
- for (var i = 0; i < nameServerTypes.length; ++i) {
- if ($(nameServerTypes[i] + '-dns-radio').checked) {
- nameServerType = nameServerTypes[i];
- break;
- }
- }
- var ipConfig = detailsPage.getIpConfig_(nameServerType);
- var ipAddressType = ('IPAddress' in ipConfig) ? 'Static' : 'DHCP';
- var nameServersType = ('NameServers' in ipConfig) ? 'Static' : 'DHCP';
- oncData.setProperty('IPAddressConfigType', ipAddressType);
- oncData.setProperty('NameServersConfigType', nameServersType);
- oncData.setProperty('StaticIPConfig', ipConfig);
-
- var data = oncData.getData();
- if (Object.keys(data).length > 0) {
- // TODO(stevenjb): Only set changed properties.
- chrome.networkingPrivate.setProperties(detailsPage.onc_.guid(), data);
- }
-
- PageManager.closeOverlay();
- };
-
- /**
- * Event handler called when the name server type changes.
- * @param {string} type The selected name sever type, 'automatic', 'google',
- * or 'user'.
- */
- DetailsInternetPage.updateNameServerDisplay = function(type) {
- var editable = type == 'user';
- var fields = [$('ipconfig-dns1'), $('ipconfig-dns2'),
- $('ipconfig-dns3'), $('ipconfig-dns4')];
- for (var i = 0; i < fields.length; ++i) {
- fields[i].editable = editable;
- }
- if (editable)
- $('ipconfig-dns1').focus();
-
- var automaticDns = $('automatic-dns-display');
- var googleDns = $('google-dns-display');
- var userDns = $('user-dns-settings');
- switch (type) {
- case 'automatic':
- automaticDns.setAttribute('selected', '');
- googleDns.removeAttribute('selected');
- userDns.removeAttribute('selected');
- break;
- case 'google':
- automaticDns.removeAttribute('selected');
- googleDns.setAttribute('selected', '');
- userDns.removeAttribute('selected');
- break;
- case 'user':
- automaticDns.removeAttribute('selected');
- googleDns.removeAttribute('selected');
- userDns.setAttribute('selected', '');
- break;
- }
- };
-
- /**
- * Method called from Chrome when the ONC properties for the displayed
- * network may have changed.
- * @param {Object} oncData The updated ONC dictionary for the network.
- */
- DetailsInternetPage.updateConnectionData = function(oncData) {
- var detailsPage = DetailsInternetPage.getInstance();
- if (!detailsPage.visible)
- return;
-
- if (oncData.GUID != detailsPage.onc_.guid())
- return;
-
- // Update our cached data object.
- detailsPage.onc_ = new OncData(oncData);
-
- detailsPage.populateHeader_();
- detailsPage.updateConnectionButtonVisibility_();
- detailsPage.updateDetails_();
- };
-
- /**
- * Initializes the details page with the provided ONC data.
- * @param {Object} oncData Dictionary of ONC properties.
- */
- DetailsInternetPage.initializeDetailsPage = function(oncData) {
- var onc = new OncData(oncData);
-
- var detailsPage = DetailsInternetPage.getInstance();
- detailsPage.onc_ = onc;
- var type = onc.getActiveValue('Type');
- detailsPage.type_ = type;
-
- sendShowDetailsMetrics(type, onc.getActiveValue('ConnectionState'));
-
- detailsPage.populateHeader_();
- detailsPage.updateConnectionButtonVisibility_();
- detailsPage.updateDetails_();
-
- // TODO(stevenjb): Some of the setup below should be moved to
- // updateDetails_() so that updates are reflected in the UI.
-
- // Only show proxy for remembered networks.
- var remembered = onc.getSource() != 'None';
- if (remembered) {
- detailsPage.showProxy_ = true;
- // Inform Chrome which network to use for proxy configuration.
- chrome.send('selectNetwork', [detailsPage.onc_.guid()]);
- } else {
- detailsPage.showProxy_ = false;
- }
-
- $('web-proxy-auto-discovery').hidden = true;
-
- var restricted = onc.getActiveValue('RestrictedConnectivity');
- var restrictedString = loadTimeData.getString(
- restricted ? 'restrictedYes' : 'restrictedNo');
-
- // These objects contain an 'automatic' property that is displayed when
- // ip-automatic-configuration-checkbox is checked, and a 'value' property
- // that is displayed when unchecked and used to set the associated ONC
- // property for StaticIPConfig on commit.
- var inetAddress = {};
- var inetNetmask = {};
- var inetGateway = {};
-
- var inetNameServersString;
-
- var ipconfigList = onc.getActiveValue('IPConfigs');
- if (Array.isArray(ipconfigList)) {
- for (var i = 0; i < ipconfigList.length; ++i) {
- var ipconfig = ipconfigList[i];
- var ipType = ipconfig['Type'];
- if (ipType != 'IPv4') {
- // TODO(stevenjb): Handle IPv6 properties.
- continue;
- }
- var address = ipconfig['IPAddress'];
- inetAddress.automatic = address;
- inetAddress.value = address;
- var netmask = prefixLengthToNetmask(ipconfig['RoutingPrefix']);
- inetNetmask.automatic = netmask;
- inetNetmask.value = netmask;
- var gateway = ipconfig['Gateway'];
- inetGateway.automatic = gateway;
- inetGateway.value = gateway;
- if ('WebProxyAutoDiscoveryUrl' in ipconfig) {
- $('web-proxy-auto-discovery').hidden = false;
- $('web-proxy-auto-discovery-url').value =
- ipconfig['WebProxyAutoDiscoveryUrl'];
- }
- if ('NameServers' in ipconfig) {
- var inetNameServers = ipconfig['NameServers'];
- inetNameServers = inetNameServers.sort();
- inetNameServersString = inetNameServers.join(',');
- }
- break; // Use the first IPv4 entry.
- }
- }
-
- // Override the 'automatic' properties with the saved DHCP values if the
- // saved value is set, and set any unset 'value' properties.
- var savedNameServersString;
- var savedIpAddress = onc.getActiveValue('SavedIPConfig.IPAddress');
- if (savedIpAddress != undefined) {
- inetAddress.automatic = savedIpAddress;
- if (!inetAddress.value)
- inetAddress.value = savedIpAddress;
- }
- var savedPrefix = onc.getActiveValue('SavedIPConfig.RoutingPrefix');
- if (savedPrefix != undefined) {
- assert(typeof savedPrefix == 'number');
- var savedNetmask = prefixLengthToNetmask(
- /** @type {number} */(savedPrefix));
- inetNetmask.automatic = savedNetmask;
- if (!inetNetmask.value)
- inetNetmask.value = savedNetmask;
- }
- var savedGateway = onc.getActiveValue('SavedIPConfig.Gateway');
- if (savedGateway != undefined) {
- inetGateway.automatic = savedGateway;
- if (!inetGateway.value)
- inetGateway.value = savedGateway;
- }
-
- var savedNameServers = onc.getActiveValue('SavedIPConfig.NameServers');
- if (savedNameServers) {
- savedNameServers = savedNameServers.sort();
- savedNameServersString = savedNameServers.join(',');
- }
-
- var ipAutoConfig = 'automatic';
- if (onc.getActiveValue('IPAddressConfigType') == 'Static') {
- ipAutoConfig = 'user';
- var staticIpAddress = onc.getActiveValue('StaticIPConfig.IPAddress');
- inetAddress.user = staticIpAddress;
- inetAddress.value = staticIpAddress;
-
- var staticPrefix = onc.getActiveValue('StaticIPConfig.RoutingPrefix');
- if (typeof staticPrefix != 'number')
- staticPrefix = 0;
- var staticNetmask = prefixLengthToNetmask(
- /** @type {number} */ (staticPrefix));
- inetNetmask.user = staticNetmask;
- inetNetmask.value = staticNetmask;
-
- var staticGateway = onc.getActiveValue('StaticIPConfig.Gateway');
- inetGateway.user = staticGateway;
- inetGateway.value = staticGateway;
- }
-
- var staticNameServersString;
- if (onc.getActiveValue('NameServersConfigType') == 'Static') {
- var staticNameServers = onc.getActiveValue('StaticIPConfig.NameServers');
- staticNameServers = staticNameServers.sort();
- staticNameServersString = staticNameServers.join(',');
- }
-
- $('ip-automatic-configuration-checkbox').checked =
- ipAutoConfig == 'automatic';
-
- inetAddress.autoConfig = ipAutoConfig;
- inetNetmask.autoConfig = ipAutoConfig;
- inetGateway.autoConfig = ipAutoConfig;
-
- var configureAddressField = function(field, model) {
- IPAddressField.decorate(field);
- field.model = model;
- field.editable = model.autoConfig == 'user';
- };
- configureAddressField($('ip-address'), inetAddress);
- configureAddressField($('ip-netmask'), inetNetmask);
- configureAddressField($('ip-gateway'), inetGateway);
-
- // Set Nameserver fields. Nameservers are 'automatic' by default. If a
- // static namerserver is set, use that unless it does not match a non
- // empty 'NameServers' value (indicating that the custom nameservers are
- // invalid or not being applied for some reason). TODO(stevenjb): Only
- // set these properites if they change so that invalid custom values do
- // not get lost.
- var nameServerType = 'automatic';
- if (staticNameServersString &&
- (!inetNameServersString ||
- staticNameServersString == inetNameServersString)) {
- if (staticNameServersString == GoogleNameServers.join(','))
- nameServerType = 'google';
- else
- nameServerType = 'user';
- }
- if (nameServerType == 'automatic')
- $('automatic-dns-display').textContent = inetNameServersString;
- else
- $('automatic-dns-display').textContent = savedNameServersString;
- $('google-dns-display').textContent = GoogleNameServers.join(',');
-
- var nameServersUser = [];
- if (staticNameServers) {
- nameServersUser = staticNameServers;
- } else if (savedNameServers) {
- // Pre-populate with values provided by DHCP server.
- nameServersUser = savedNameServers;
- }
-
- var nameServerModels = [];
- for (var i = 0; i < 4; ++i)
- nameServerModels.push({value: nameServersUser[i] || ''});
-
- $(nameServerType + '-dns-radio').checked = true;
- configureAddressField($('ipconfig-dns1'), nameServerModels[0]);
- configureAddressField($('ipconfig-dns2'), nameServerModels[1]);
- configureAddressField($('ipconfig-dns3'), nameServerModels[2]);
- configureAddressField($('ipconfig-dns4'), nameServerModels[3]);
-
- DetailsInternetPage.updateNameServerDisplay(nameServerType);
-
- var macAddress = onc.getActiveValue('MacAddress');
- if (macAddress) {
- $('hardware-address').textContent = macAddress;
- $('hardware-address-row').style.display = 'table-row';
- } else {
- // This is most likely a device without a hardware address.
- $('hardware-address-row').style.display = 'none';
- }
-
- var setOrHideParent = function(field, property) {
- if (property != undefined) {
- $(field).textContent = property;
- $(field).parentElement.hidden = false;
- } else {
- $(field).parentElement.hidden = true;
- }
- };
-
- var networkName = onc.getTranslatedValue('Name');
-
- // Signal strength as percentage (for WiFi and WiMAX).
- var signalStrength;
- if (type == 'WiFi' || type == 'WiMAX')
- signalStrength = onc.getActiveValue(type + '.SignalStrength');
- if (!signalStrength)
- signalStrength = 0;
- var strengthFormat = loadTimeData.getString('inetSignalStrengthFormat');
- var strengthString = strengthFormat.replace('$1', signalStrength);
-
- if (type == 'WiFi') {
- OptionsPage.showTab($('wifi-network-nav-tab'));
- $('wifi-restricted-connectivity').textContent = restrictedString;
- var ssid = onc.getActiveValue('WiFi.SSID');
- $('wifi-ssid').textContent = ssid ? ssid : networkName;
- setOrHideParent('wifi-bssid', onc.getActiveValue('WiFi.BSSID'));
- var security = onc.getWiFiSecurity();
- if (security == 'None')
- security = undefined;
- setOrHideParent('wifi-security', security);
- // Frequency is in MHz.
- var frequency = onc.getActiveValue('WiFi.Frequency');
- if (!frequency)
- frequency = 0;
- var frequencyFormat = loadTimeData.getString('inetFrequencyFormat');
- frequencyFormat = frequencyFormat.replace('$1', frequency);
- $('wifi-frequency').textContent = frequencyFormat;
- $('wifi-signal-strength').textContent = strengthString;
- setOrHideParent('wifi-hardware-address',
- onc.getActiveValue('MacAddress'));
- var priority = onc.getActiveValue('Priority');
- $('prefer-network-wifi').checked = priority > 0;
- $('prefer-network-wifi').disabled = !remembered;
- $('auto-connect-network-wifi').checked =
- onc.getActiveValue('WiFi.AutoConnect');
- $('auto-connect-network-wifi').disabled = !remembered;
- } else if (type == 'WiMAX') {
- OptionsPage.showTab($('wimax-network-nav-tab'));
- $('wimax-restricted-connectivity').textContent = restrictedString;
-
- $('auto-connect-network-wimax').checked =
- onc.getActiveValue('WiMAX.AutoConnect');
- $('auto-connect-network-wimax').disabled = !remembered;
- var identity = onc.getActiveValue('WiMAX.EAP.Identity');
- setOrHideParent('wimax-eap-identity', identity);
- $('wimax-signal-strength').textContent = strengthString;
- } else if (type == 'Cellular') {
- OptionsPage.showTab($('cellular-conn-nav-tab'));
-
- var isGsm = onc.getActiveValue('Cellular.Family') == 'GSM';
-
- $('service-name').textContent = networkName;
-
- // TODO(stevenjb): Ideally many of these should be localized.
- $('network-technology').textContent =
- onc.getActiveValue('Cellular.NetworkTechnology');
- $('roaming-state').textContent =
- onc.getTranslatedValue('Cellular.RoamingState');
- $('cellular-restricted-connectivity').textContent = restrictedString;
- $('error-state').textContent = onc.getActiveValue('ErrorState');
- $('manufacturer').textContent =
- onc.getActiveValue('Cellular.Manufacturer');
- $('model-id').textContent = onc.getActiveValue('Cellular.ModelID');
- $('firmware-revision').textContent =
- onc.getActiveValue('Cellular.FirmwareRevision');
- $('hardware-revision').textContent =
- onc.getActiveValue('Cellular.HardwareRevision');
- $('mdn').textContent = onc.getActiveValue('Cellular.MDN');
-
- // Show ServingOperator properties only if available.
- var servingOperatorName =
- onc.getActiveValue('Cellular.ServingOperator.Name');
- var servingOperatorCode =
- onc.getActiveValue('Cellular.ServingOperator.Code');
- if (servingOperatorName != undefined &&
- servingOperatorCode != undefined) {
- $('operator-name').textContent = servingOperatorName;
- $('operator-code').textContent = servingOperatorCode;
- } else {
- $('operator-name').parentElement.hidden = true;
- $('operator-code').parentElement.hidden = true;
- }
- // Make sure that GSM/CDMA specific properties that shouldn't be hidden
- // are visible.
- updateHidden('#details-internet-page .gsm-only', false);
- updateHidden('#details-internet-page .cdma-only', false);
-
- // Show IMEI/ESN/MEID/MIN/PRL only if they are available.
- setOrHideParent('esn', onc.getActiveValue('Cellular.ESN'));
- setOrHideParent('imei', onc.getActiveValue('Cellular.IMEI'));
- setOrHideParent('meid', onc.getActiveValue('Cellular.MEID'));
- setOrHideParent('min', onc.getActiveValue('Cellular.MIN'));
- setOrHideParent('prl-version', onc.getActiveValue('Cellular.PRLVersion'));
-
- if (isGsm) {
- $('iccid').textContent = onc.getActiveValue('Cellular.ICCID');
- $('imsi').textContent = onc.getActiveValue('Cellular.IMSI');
- detailsPage.initializeApnList_();
- }
- $('auto-connect-network-cellular').checked =
- onc.getActiveValue('Cellular.AutoConnect');
- $('auto-connect-network-cellular').disabled = false;
- } else if (type == 'VPN') {
- OptionsPage.showTab($('vpn-nav-tab'));
- var providerType = onc.getActiveValue('VPN.Type');
- var isThirdPartyVPN = providerType == 'ThirdPartyVPN';
- $('vpn-tab').classList.toggle('third-party-vpn-provider',
- isThirdPartyVPN);
-
- $('inet-service-name').textContent = networkName;
- $('inet-provider-type').textContent =
- onc.getTranslatedValue('VPN.Type');
-
- if (isThirdPartyVPN) {
- $('inet-provider-name').textContent =
- onc.getActiveValue('VPN.ThirdPartyVPN.ProviderName');
- } else {
- var usernameKey;
- if (providerType == 'OpenVPN')
- usernameKey = 'VPN.OpenVPN.Username';
- else if (providerType == 'L2TP-IPsec')
- usernameKey = 'VPN.L2TP.Username';
-
- if (usernameKey) {
- $('inet-username').parentElement.hidden = false;
- $('inet-username').textContent = onc.getActiveValue(usernameKey);
- } else {
- $('inet-username').parentElement.hidden = true;
- }
- var inetServerHostname = $('inet-server-hostname');
- inetServerHostname.value = onc.getActiveValue('VPN.Host');
- inetServerHostname.resetHandler = function() {
- PageManager.hideBubble();
- var recommended = onc.getRecommendedValue('VPN.Host');
- if (recommended != undefined)
- inetServerHostname.value = recommended;
- };
- $('auto-connect-network-vpn').checked =
- onc.getActiveValue('VPN.AutoConnect');
- $('auto-connect-network-vpn').disabled = false;
- }
- } else {
- OptionsPage.showTab($('internet-nav-tab'));
- }
-
- // Update controlled option indicators.
- var indicators = cr.doc.querySelectorAll(
- '#details-internet-page .controlled-setting-indicator');
- for (var i = 0; i < indicators.length; i++) {
- var managed = indicators[i].hasAttribute('managed');
- // TODO(stevenjb): Eliminate support for 'data' once 39 is stable.
- var attributeName = managed ? 'managed' : 'data';
- var propName = indicators[i].getAttribute(attributeName);
- if (!propName)
- continue;
- var propValue = managed ?
- onc.getManagedProperty(propName) :
- onc.getActiveValue(propName);
- // If the property is unset or unmanaged (i.e. not an Object) skip it.
- if (propValue == undefined || (typeof propValue != 'object'))
- continue;
- var event;
- if (managed)
- event = detailsPage.createManagedEvent_(propName, propValue);
- else
- event = detailsPage.createControlledEvent_(propName,
- /** @type {{value: *, controlledBy: *, recommendedValue: *}} */(
- propValue));
- indicators[i].handlePrefChange(event);
- var forElement = $(indicators[i].getAttribute('internet-detail-for'));
- if (forElement) {
- if (event.value.controlledBy == 'policy')
- forElement.disabled = true;
- if (forElement.resetHandler)
- indicators[i].resetHandler = forElement.resetHandler;
- }
- }
-
- detailsPage.updateControls();
-
- // Don't show page name in address bar and in history to prevent people
- // navigate here by hand and solve issue with page session restore.
- PageManager.showPageByName('detailsInternetPage', false);
- };
-
- return {
- DetailsInternetPage: DetailsInternetPage
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/internet_detail_ip_address_field.js b/chromium/chrome/browser/resources/options/chromeos/internet_detail_ip_address_field.js
deleted file mode 100644
index d4cd42a1f8b..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/internet_detail_ip_address_field.js
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options.internet', function() {
- /** @const */ var EditableTextField = options.EditableTextField;
-
- /**
- * The regular expression that matches an IP address. String to match against
- * should have all whitespace stripped already.
- * @const
- * @type {RegExp}
- */
- var singleIp_ = /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/;
-
- /**
- * Creates a new field specifically for entering IP addresses.
- * @constructor
- * @extends {options.EditableTextField}
- */
- function IPAddressField() {
- var el = cr.doc.createElement('div');
- IPAddressField.decorate(el);
- return el;
- }
-
- /**
- * Decorates an element as a inline-editable list item. Note that this is
- * a subclass of IPAddressField.
- * @param {!HTMLElement} el The element to decorate.
- */
- IPAddressField.decorate = function(el) {
- el.__proto__ = IPAddressField.prototype;
- el.decorate();
- };
-
- IPAddressField.prototype = {
- __proto__: EditableTextField.prototype,
-
- /** @override */
- decorate: function() {
- EditableTextField.prototype.decorate.call(this);
- },
-
- /**
- * Indicates whether or not empty values are allowed.
- * @type {boolean}
- */
- get allowEmpty() {
- return this.hasAttribute('allow-empty');
- },
-
- /** @override */
- get currentInputIsValid() {
- if (!this.editField.value && this.allowEmpty)
- return true;
-
- // Make sure it's only got numbers and ".", there are the correct
- // count of them, and they are all within the correct range.
- var fieldValue = this.editField.value.replace(/\s/g, '');
- var matches = singleIp_.exec(fieldValue);
- var rangeCorrect = true;
- if (matches != null) {
- for (var i = 1; i < matches.length; ++i) {
- var value = parseInt(matches[i], 10);
- if (value < 0 || value > 255) {
- rangeCorrect = false;
- break;
- }
- }
- }
- return this.editField.validity.valid && matches != null &&
- rangeCorrect && matches.length == 5;
- },
-
- /** @override */
- get hasBeenEdited() {
- return this.editField.value != this.model.value;
- },
-
- /**
- * Overrides superclass to mutate the input during a successful commit. For
- * the purposes of entering IP addresses, this just means stripping off
- * whitespace and leading zeros from each of the octets so that they conform
- * to the normal format for IP addresses.
- * @override
- * @param {string} value Input IP address to be mutated.
- * @return {string} mutated IP address.
- */
- mutateInput: function(value) {
- if (!value)
- return value;
-
- var fieldValue = value.replace(/\s/g, '');
- var matches = singleIp_.exec(fieldValue);
- var result = [];
-
- // If we got this far, matches shouldn't be null, but make sure.
- if (matches != null) {
- // starting at one because the first match element contains the entire
- // match, and we don't care about that.
- for (var i = 1; i < matches.length; ++i)
- result.push(parseInt(matches[i], 10));
- }
- return result.join('.');
- },
- };
-
- return {
- IPAddressField: IPAddressField,
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.css b/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.css
deleted file mode 100644
index 89b913d6612..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.css
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#send-function-keys-description {
- color: gray;
-}
-
-#auto-repeat-settings-section {
- -webkit-margin-start: 30px;
- display: table;
- white-space: nowrap;
-}
-
-#auto-repeat-settings-section .row {
- display: table-row;
-}
-
-#auto-repeat-settings-section .row > * {
- display: table-cell;
-}
-
-#auto-repeat-settings-section input[type='range'] {
- margin-left: 5px;
- margin-right: 5px;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html b/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html
deleted file mode 100644
index b74c00d3532..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<div id="keyboard-overlay" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="keyboardOverlay"></h1>
- <div class="content-area">
- <table class="option-control-table">
- <tr>
- <td class="option-name" id="remap-search-key-to-label"
- i18n-content="remapSearchKeyToContent">
- </td>
- <td class="option-value">
- <select class="control"
- data-type="number" i18n-options="remapSearchKeyToValue"
- metric="Options_KeyboardRemapSearchKey"
- pref="settings.language.xkb_remap_search_key_to"
- aria-labelledby="remap-search-key-to-label" dialog-pref>
- </select>
- </td>
- </tr>
- <tr>
- <td class="option-name" id="remap-control-key-to-label"
- i18n-content="remapControlKeyToContent">
- </td>
- <td class="option-value">
- <select class="control"
- data-type="number" i18n-options="remapControlKeyToValue"
- metric="Options_KeyboardRemapControlKey"
- pref="settings.language.xkb_remap_control_key_to"
- aria-labelledby="remap-control-key-to-label" dialog-pref>
- </select>
- </td>
- </tr>
- <tr>
- <td class="option-name" id="remap-alt-key-to-label"
- i18n-content="remapAltKeyToContent">
- </td>
- <td class="option-value">
- <select class="control" data-type="number"
- metric="Options_KeyboardRemapAltKey"
- pref="settings.language.xkb_remap_alt_key_to"
- i18n-options="remapAltKeyToValue"
- aria-labelledby="remap-alt-key-to-label" dialog-pref></select>
- </td>
- </tr>
- <!-- The caps lock section is hidden by default. This is only visible
- when --has-chromeos-keyboard flag is not passed. -->
- <tr id="caps-lock-remapping-section" hidden>
- <td class="option-name" id="remap-caps-lock-key-to-label"
- i18n-content="remapCapsLockKeyToContent">
- </td>
- <td class="option-value">
- <select class="control"
- data-type="number"
- metric="Options_KeyboardRemapCapsLockKey"
- pref="settings.language.remap_caps_lock_key_to"
- i18n-options="remapCapsLockKeyToValue"
- aria-labelledby="remap-caps-lock-key-to-label" dialog-pref>
- </select>
- </td>
- </tr>
- <!-- The diamond key section is hidden by default. This is only visible
- when --has-chromeos-diamond-key flag is passed. -->
- <tr id="diamond-key-remapping-section" hidden>
- <td class="option-name" id="remap-diamond-key-to-label"
- i18n-content="remapDiamondKeyToContent">
- </td>
- <td class="option-value">
- <select class="control"
- data-type="number"
- metric="Options_KeyboardRemapDiamondKey"
- pref="settings.language.remap_diamond_key_to"
- i18n-options="remapDiamondKeyToValue"
- aria-labelledby="remap-diamond-key-to-label" dialog-pref>
- </select>
- </td>
- </tr>
- </table>
- <div class="settings-row">
- <div class="checkbox controlled-setting-with-label">
- <label>
- <input type="checkbox"
- pref="settings.language.send_function_keys"
- aria-describedby="send-function-keys-description" dialog-pref>
- <span>
- <span i18n-content="sendFunctionKeys"></span>
- <span class="bubble-button controlled-setting-indicator"
- pref="settings.language.send_function_keys"></span>
- </span>
- </label>
- </div>
- <span id="send-function-keys-description"
- i18n-content="sendFunctionKeysDescription"></span>
- </div>
- <div class="settings-row">
- <div class="checkbox">
- <label>
- <input id="enable-auto-repeat" type="checkbox"
- pref="settings.language.xkb_auto_repeat_enabled_r2"
- metric="Options_KeyboardAutoRepeat" dialog-pref>
- <span i18n-content="enableAutoRepeat"></span>
- </label>
- </div>
- <div id="auto-repeat-settings-section">
- <div class="row">
- <span class="option-name" i18n-content="autoRepeatDelay"></span>
- <span i18n-content="autoRepeatDelayLong"></span>
- <input id="auto-repeat-delay-range" type="range"
- class="touch-slider" metric="Options_KeyboardAutoRepeat_Delay"
- pref="settings.language.xkb_auto_repeat_delay_r2" dialog-pref>
- <span i18n-content="autoRepeatDelayShort"></span>
- </div>
- <div class="row">
- <span class="option-name" i18n-content="autoRepeatRate"></span>
- <span i18n-content="autoRepeatRateSlow"></span>
- <input id="auto-repeat-interval-range" type="range"
- class="touch-slider"
- pref="settings.language.xkb_auto_repeat_interval_r2"
- metric="Options_KeyboardAutoRepeat_Interval" dialog-pref>
- <span i18n-content="autoRepeatRateFast"></span>
- </div>
- </div>
- </div>
- <a is="action-link" id="keyboard-shortcuts" class="settings-row"
- i18n-content="showKeyboardShortcuts"></a>
- <a is="action-link" id="languages-and-input-settings" class="settings-row"
- i18n-content="changeLanguageAndInputSettings"></a>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="keyboard-cancel" type="reset" i18n-content="cancel"></button>
- <button id="keyboard-confirm" class="default-button" type="submit"
- i18n-content="ok">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js b/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js
deleted file mode 100644
index b18af10166e..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
-
- /**
- * Auto-repeat delays (in ms) for the corresponding slider values, from
- * long to short. The values were chosen to provide a large range while giving
- * several options near the defaults.
- * @type {!Array<number>}
- * @const
- */
- var AUTO_REPEAT_DELAYS =
- [2000, 1500, 1000, 500, 300, 200, 150];
-
- /**
- * Auto-repeat intervals (in ms) for the corresponding slider values, from
- * long to short. The slider itself is labeled "rate", the inverse of
- * interval, and goes from slow (long interval) to fast (short interval).
- * @type {!Array<number>}
- * @const
- */
- var AUTO_REPEAT_INTERVALS =
- [2000, 1000, 500, 300, 200, 100, 50, 30, 20];
-
- /**
- * Encapsulated handling of the keyboard overlay.
- * @constructor
- * @extends {options.SettingsDialog}
- */
- function KeyboardOverlay() {
- options.SettingsDialog.call(this, 'keyboard-overlay',
- loadTimeData.getString('keyboardOverlayTabTitle'),
- 'keyboard-overlay',
- assertInstanceof($('keyboard-confirm'), HTMLButtonElement),
- assertInstanceof($('keyboard-cancel'), HTMLButtonElement));
- }
-
- cr.addSingletonGetter(KeyboardOverlay);
-
- KeyboardOverlay.prototype = {
- __proto__: options.SettingsDialog.prototype,
-
- /** @override */
- initializePage: function() {
- options.SettingsDialog.prototype.initializePage.call(this);
-
- $('enable-auto-repeat').customPrefChangeHandler =
- this.handleAutoRepeatEnabledPrefChange_.bind(this);
-
- var autoRepeatDelayRange = $('auto-repeat-delay-range');
- autoRepeatDelayRange.valueMap = AUTO_REPEAT_DELAYS;
- autoRepeatDelayRange.max = AUTO_REPEAT_DELAYS.length - 1;
- autoRepeatDelayRange.customPrefChangeHandler =
- this.handleAutoRepeatDelayPrefChange_.bind(this);
-
- var autoRepeatIntervalRange = $('auto-repeat-interval-range');
- autoRepeatIntervalRange.valueMap = AUTO_REPEAT_INTERVALS;
- autoRepeatIntervalRange.max = AUTO_REPEAT_INTERVALS.length - 1;
- autoRepeatIntervalRange.customPrefChangeHandler =
- this.handleAutoRepeatIntervalPrefChange_.bind(this);
-
- $('languages-and-input-settings').onclick = function(e) {
- PageManager.showPageByName('languages');
- chrome.send('coreOptionsUserMetricsAction',
- ['Options_KeyboardShowLanguageSettings']);
- };
-
- $('keyboard-shortcuts').onclick = function(e) {
- chrome.send('showKeyboardShortcuts');
- chrome.send('coreOptionsUserMetricsAction',
- ['Options_KeyboardShowKeyboardShortcuts']);
- };
- },
-
- /**
- * Handles auto-repeat enabled pref change and allows the event to continue
- * propagating.
- * @param {Event} e Change event.
- * @return {boolean} Whether the event has finished being handled.
- * @private
- */
- handleAutoRepeatEnabledPrefChange_: function(e) {
- $('auto-repeat-settings-section').classList.toggle('disabled',
- !e.value.value);
- $('auto-repeat-delay-range').disabled =
- $('auto-repeat-interval-range').disabled = !e.value.value;
- return false;
- },
-
- /**
- * Handles auto-repeat delay pref change and stops the event from
- * propagating.
- * @param {Event} e Change event.
- * @return {boolean} Whether the event has finished being handled.
- * @private
- */
- handleAutoRepeatDelayPrefChange_: function(e) {
- this.updateSliderFromValue_('auto-repeat-delay-range',
- e.value.value,
- AUTO_REPEAT_DELAYS);
- return true;
- },
-
- /**
- * Handles auto-repeat interval pref change and stops the event from
- * propagating.
- * @param {Event} e Change event.
- * @return {boolean} Whether the event has finished being handled.
- * @private
- */
- handleAutoRepeatIntervalPrefChange_: function(e) {
- this.updateSliderFromValue_('auto-repeat-interval-range',
- e.value.value,
- AUTO_REPEAT_INTERVALS);
- return true;
- },
-
- /**
- * Show/hide the caps lock remapping section.
- * @private
- */
- showCapsLockOptions_: function(show) {
- $('caps-lock-remapping-section').hidden = !show;
- },
-
- /**
- * Show/hide the diamond key remapping section.
- * @private
- */
- showDiamondKeyOptions_: function(show) {
- $('diamond-key-remapping-section').hidden = !show;
- },
-
- /**
- * Sets the slider's value to the number in |values| that is closest to
- * |value|.
- * @param {string} id The slider's ID.
- * @param {number} value The value to find.
- * @param {!Array<number>} values The array to search.
- * @private
- */
- updateSliderFromValue_: function(id, value, values) {
- var index = values.indexOf(value);
- if (index == -1) {
- var closestValue = Infinity;
- for (var i = 0; i < values.length; i++) {
- if (Math.abs(values[i] - value) <
- Math.abs(closestValue - value)) {
- closestValue = values[i];
- index = i;
- }
- }
-
- assert(index != -1,
- 'Failed to update ' + id + ' from pref with value ' + value);
- }
-
- $(id).value = index;
- },
- };
-
- // Forward public APIs to private implementations.
- cr.makePublic(KeyboardOverlay, [
- 'showCapsLockOptions',
- 'showDiamondKeyOptions',
- ]);
-
- // Export
- return {
- KeyboardOverlay: KeyboardOverlay
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/network_list.js b/chromium/chrome/browser/resources/options/chromeos/network_list.js
deleted file mode 100644
index 3d81804712c..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/network_list.js
+++ /dev/null
@@ -1,1523 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Partial definition of the result of networkingPrivate.getProperties()).
- * TODO(stevenjb): Replace with chrome.networkingPrivate.NetworkStateProperties
- * once that is fully speced.
- * @typedef {{
- * ConnectionState: string,
- * Cellular: ?{
- * Family: ?string,
- * SIMPresent: ?boolean,
- * SIMLockStatus: ?{ LockType: ?string },
- * SupportNetworkScan: ?boolean
- * },
- * GUID: string,
- * Name: string,
- * Source: string,
- * Type: string,
- * VPN: ?{
- * Type: string,
- * ThirdPartyVPN: chrome.networkingPrivate.ThirdPartyVPNProperties
- * }
- * }}
- * @see extensions/common/api/networking_private.idl
- */
-var NetworkProperties;
-
-/** @typedef {chrome.management.ExtensionInfo} */ var ExtensionInfo;
-
-cr.define('options.network', function() {
- var ArrayDataModel = cr.ui.ArrayDataModel;
- var List = cr.ui.List;
- var ListItem = cr.ui.ListItem;
- var ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
- var Menu = cr.ui.Menu;
- var MenuItem = cr.ui.MenuItem;
- var ControlledSettingIndicator = options.ControlledSettingIndicator;
-
- /**
- * Network settings constants. These enums usually match their C++
- * counterparts.
- */
- function Constants() {}
-
- /**
- * Valid network type names.
- */
- Constants.NETWORK_TYPES = ['Ethernet', 'WiFi', 'WiMAX', 'Cellular', 'VPN'];
-
- /**
- * Helper function to check whether |type| is a valid network type.
- * @param {string} type A string that may contain a valid network type.
- * @return {boolean} Whether the string represents a valid network type.
- */
- function isNetworkType(type) {
- return (Constants.NETWORK_TYPES.indexOf(type) != -1);
- }
-
- /**
- * Order in which controls are to appear in the network list sorted by key.
- */
- Constants.NETWORK_ORDER = ['Ethernet',
- 'WiFi',
- 'WiMAX',
- 'Cellular',
- 'VPN',
- 'addConnection'];
-
- /**
- * ID of the menu that is currently visible.
- * @type {?string}
- * @private
- */
- var activeMenu_ = null;
-
- /**
- * The state of the cellular device or undefined if not available.
- * @type {?chrome.networkingPrivate.DeviceStateProperties}
- * @private
- */
- var cellularDevice_ = null;
-
- /**
- * The active cellular network or null if none.
- * @type {?NetworkProperties}
- * @private
- */
- var cellularNetwork_ = null;
-
- /**
- * The active ethernet network or null if none.
- * @type {?NetworkProperties}
- * @private
- */
- var ethernetNetwork_ = null;
-
- /**
- * The state of the WiFi device or undefined if not available.
- * @type {string|undefined}
- * @private
- */
- var wifiDeviceState_ = undefined;
-
- /**
- * The state of the WiMAX device or undefined if not available.
- * @type {string|undefined}
- * @private
- */
- var wimaxDeviceState_ = undefined;
-
- /**
- * The current list of third-party VPN providers.
- * @type {!Array<!chrome.networkingPrivate.ThirdPartyVPNProperties>}}
- * @private
- */
- var vpnProviders_ = [];
-
- /**
- * Indicates if mobile data roaming is enabled.
- * @type {boolean}
- * @private
- */
- var enableDataRoaming_ = false;
-
- /**
- * Returns the display name for 'network'.
- * @param {NetworkProperties} data The network data dictionary.
- */
- function getNetworkName(data) {
- if (data.Type == 'Ethernet')
- return loadTimeData.getString('ethernetName');
- var name = data.Name;
- if (data.Type == 'VPN' && data.VPN && data.VPN.Type == 'ThirdPartyVPN' &&
- data.VPN.ThirdPartyVPN) {
- var providerName = data.VPN.ThirdPartyVPN.ProviderName;
- if (providerName)
- return loadTimeData.getStringF('vpnNameTemplate', providerName, name);
- }
- return name;
- }
-
- /**
- * Create an element in the network list for controlling network
- * connectivity.
- * @param {Object} data Description of the network list or command.
- * @constructor
- * @extends {cr.ui.ListItem}
- */
- function NetworkListItem(data) {
- var el = cr.doc.createElement('li');
- el.data_ = {};
- for (var key in data)
- el.data_[key] = data[key];
- NetworkListItem.decorate(el);
- return el;
- }
-
- /**
- * @param {string} action An action to send to coreOptionsUserMetricsAction.
- */
- function sendChromeMetricsAction(action) {
- chrome.send('coreOptionsUserMetricsAction', [action]);
- }
-
- /**
- * @param {string} guid The network GUID.
- */
- function showDetails(guid) {
- chrome.networkingPrivate.getManagedProperties(
- guid, DetailsInternetPage.initializeDetailsPage);
- }
-
- /**
- * Decorate an element as a NetworkListItem.
- * @param {!Element} el The element to decorate.
- */
- NetworkListItem.decorate = function(el) {
- el.__proto__ = NetworkListItem.prototype;
- el.decorate();
- };
-
- NetworkListItem.prototype = {
- __proto__: ListItem.prototype,
-
- /**
- * Description of the network group or control.
- * @type {Object<Object>}
- * @private
- */
- data_: null,
-
- /**
- * Element for the control's subtitle.
- * @type {?Element}
- * @private
- */
- subtitle_: null,
-
- /**
- * Div containing the list item icon.
- * @type {?Element}
- * @private
- */
- iconDiv_: null,
-
- /**
- * Description of the network control.
- * @type {Object}
- */
- get data() {
- return this.data_;
- },
-
- /**
- * Text label for the subtitle.
- * @type {string}
- */
- set subtitle(text) {
- if (text)
- this.subtitle_.textContent = text;
- this.subtitle_.hidden = !text;
- },
-
- /**
- * Sets the icon based on a network state object.
- * @param {!NetworkProperties} data Network state properties.
- */
- set iconData(data) {
- if (!isNetworkType(data.Type))
- return;
- var networkIcon = this.getNetworkIcon();
- networkIcon.networkState =
- /** @type {chrome.networkingPrivate.NetworkStateProperties} */ (data);
- },
-
- /**
- * Sets the icon based on a network type or a special type indecator, e.g.
- * 'add-connection'
- * @type {string}
- */
- set iconType(type) {
- if (isNetworkType(type)) {
- var networkIcon = this.getNetworkIcon();
- networkIcon.networkType = type;
- } else {
- // Special cases. e.g. 'add-connection'. Background images are
- // defined in browser_options.css.
- var oldIcon = /** @type {CrNetworkIconElement} */ (
- this.iconDiv_.querySelector('cr-network-icon'));
- if (oldIcon)
- this.iconDiv_.removeChild(oldIcon);
- this.iconDiv_.classList.add('network-' + type.toLowerCase());
- }
- },
-
- /**
- * Returns any existing network icon for the list item or creates a new one.
- * @return {!CrNetworkIconElement} The network icon for the list item.
- */
- getNetworkIcon: function() {
- var networkIcon = /** @type {CrNetworkIconElement} */ (
- this.iconDiv_.querySelector('cr-network-icon'));
- if (!networkIcon) {
- networkIcon = /** @type {!CrNetworkIconElement} */ (
- document.createElement('cr-network-icon'));
- networkIcon.isListItem = false;
- this.iconDiv_.appendChild(networkIcon);
- }
- return networkIcon;
- },
-
- /**
- * Set the direction of the text.
- * @param {string} direction The direction of the text, e.g. 'ltr'.
- */
- setSubtitleDirection: function(direction) {
- this.subtitle_.dir = direction;
- },
-
- /**
- * Indicate that the selector arrow should be shown.
- */
- showSelector: function() {
- this.subtitle_.classList.add('network-selector');
- },
-
- /**
- * Adds an indicator to show that the network is policy managed.
- */
- showManagedNetworkIndicator: function() {
- this.appendChild(new ManagedNetworkIndicator());
- },
-
- /** @override */
- decorate: function() {
- ListItem.prototype.decorate.call(this);
- this.className = 'network-group';
- this.iconDiv_ = this.ownerDocument.createElement('div');
- this.iconDiv_.className = 'network-icon';
- this.appendChild(this.iconDiv_);
- var textContent = this.ownerDocument.createElement('div');
- textContent.className = 'network-group-labels';
- this.appendChild(textContent);
- var categoryLabel = this.ownerDocument.createElement('div');
- var title;
- if (this.data_.key == 'addConnection')
- title = 'addConnectionTitle';
- else
- title = this.data_.key.toLowerCase() + 'Title';
- categoryLabel.className = 'network-title';
- categoryLabel.textContent = loadTimeData.getString(title);
- textContent.appendChild(categoryLabel);
- this.subtitle_ = this.ownerDocument.createElement('div');
- this.subtitle_.className = 'network-subtitle';
- textContent.appendChild(this.subtitle_);
- },
- };
-
- /**
- * Creates a control that displays a popup menu when clicked.
- * @param {Object} data Description of the control.
- * @constructor
- * @extends {NetworkListItem}
- */
- function NetworkMenuItem(data) {
- var el = new NetworkListItem(data);
- el.__proto__ = NetworkMenuItem.prototype;
- el.decorate();
- return el;
- }
-
- NetworkMenuItem.prototype = {
- __proto__: NetworkListItem.prototype,
-
- /**
- * Popup menu element.
- * @type {?Element}
- * @private
- */
- menu_: null,
-
- /** @override */
- decorate: function() {
- this.subtitle = null;
- if (this.data.iconType)
- this.iconType = this.data.iconType;
- this.addEventListener('click', (function() {
- this.showMenu();
- }).bind(this));
- },
-
- /**
- * Retrieves the ID for the menu.
- */
- getMenuName: function() {
- return this.data_.key.toLowerCase() + '-network-menu';
- },
-
- /**
- * Creates a popup menu for the control.
- * @return {Element} The newly created menu.
- */
- createMenu: function() {
- if (this.data.menu) {
- var menu = this.ownerDocument.createElement('div');
- menu.id = this.getMenuName();
- menu.className = 'network-menu';
- menu.hidden = true;
- Menu.decorate(menu);
- menu.menuItemSelector = '.network-menu-item';
- for (var i = 0; i < this.data.menu.length; i++) {
- var entry = this.data.menu[i];
- createCallback_(menu, null, entry.label, entry.command);
- }
- return menu;
- }
- return null;
- },
-
- /**
- * Determines if a menu can be updated on the fly. Menus that cannot be
- * updated are fully regenerated using createMenu. The advantage of
- * updating a menu is that it can preserve ordering of networks avoiding
- * entries from jumping around after an update.
- * @return {boolean} Whether the menu can be updated on the fly.
- */
- canUpdateMenu: function() {
- return false;
- },
-
- /**
- * Removes the current menu contents, causing it to be regenerated when the
- * menu is shown the next time. If the menu is showing right now, its
- * contents are regenerated immediately and the menu remains visible.
- */
- refreshMenu: function() {
- this.menu_ = null;
- if (activeMenu_ == this.getMenuName())
- this.showMenu();
- },
-
- /**
- * Displays a popup menu.
- */
- showMenu: function() {
- var rebuild = false;
- // Force a rescan if opening the menu for WiFi networks to ensure the
- // list is up to date. Networks are periodically rescanned, but depending
- // on timing, there could be an excessive delay before the first rescan
- // unless forced.
- var rescan = !activeMenu_ && this.data_.key == 'WiFi';
- if (!this.menu_) {
- rebuild = true;
- var existing = $(this.getMenuName());
- if (existing) {
- if (this.canUpdateMenu() && this.updateMenu())
- return;
- closeMenu_();
- }
- this.menu_ = this.createMenu();
- this.menu_.addEventListener('mousedown', function(e) {
- // Prevent blurring of list, which would close the menu.
- e.preventDefault();
- });
- var parent = $('network-menus');
- if (existing)
- parent.replaceChild(this.menu_, existing);
- else
- parent.appendChild(this.menu_);
- }
- var top = this.offsetTop + this.clientHeight;
- var menuId = this.getMenuName();
- if (menuId != activeMenu_ || rebuild) {
- closeMenu_();
- activeMenu_ = menuId;
- this.menu_.style.setProperty('top', top + 'px');
- this.menu_.hidden = false;
- }
- if (rescan) {
- chrome.networkingPrivate.requestNetworkScan();
- }
- }
- };
-
- /**
- * Creates a control for selecting or configuring a network connection based
- * on the type of connection (e.g. wifi versus vpn).
- * @param {{key: string, networkList: Array<!NetworkProperties>}} data
- * An object containing the network type (key) and an array of networks.
- * @constructor
- * @extends {NetworkMenuItem}
- */
- function NetworkSelectorItem(data) {
- var el = new NetworkMenuItem(data);
- el.__proto__ = NetworkSelectorItem.prototype;
- el.decorate();
- return el;
- }
-
- /**
- * Returns true if |source| is a policy managed source.
- * @param {string} source The ONC source of a network.
- * @return {boolean} Whether |source| is a managed source.
- */
- function isManaged(source) {
- return (source == 'DevicePolicy' || source == 'UserPolicy');
- }
-
- /**
- * Returns true if |network| is visible.
- * @param {!chrome.networkingPrivate.NetworkStateProperties} network The
- * network state properties.
- * @return {boolean} Whether |network| is visible.
- */
- function networkIsVisible(network) {
- if (network.Type == 'WiFi')
- return !!(network.WiFi && (network.WiFi.SignalStrength > 0));
- if (network.Type == 'WiMAX')
- return !!(network.WiMAX && (network.WiMAX.SignalStrength > 0));
- // Other network types are always considered 'visible'.
- return true;
- }
-
- /**
- * Returns true if |cellular| is a GSM network with no sim present.
- * @param {?chrome.networkingPrivate.DeviceStateProperties} cellularDevice
- * @return {boolean} Whether |network| is missing a SIM card.
- */
- function isCellularSimAbsent(cellularDevice) {
- return !!cellularDevice && cellularDevice.SimPresent === false;
- }
-
- /**
- * Returns true if |cellular| has a locked SIM card.
- * @param {?chrome.networkingPrivate.DeviceStateProperties} cellularDevice
- * @return {boolean} Whether |network| has a locked SIM card.
- */
- function isCellularSimLocked(cellularDevice) {
- return !!cellularDevice && !!cellularDevice.SimLockType;
- }
-
- NetworkSelectorItem.prototype = {
- __proto__: NetworkMenuItem.prototype,
-
- /** @override */
- decorate: function() {
- // TODO(kevers): Generalize method of setting default label.
- this.subtitle = loadTimeData.getString('OncConnectionStateNotConnected');
- var list = this.data_.networkList;
- var candidateData = null;
- for (var i = 0; i < list.length; i++) {
- var networkDetails = list[i];
- if (networkDetails.ConnectionState == 'Connecting' ||
- networkDetails.ConnectionState == 'Connected') {
- this.subtitle = getNetworkName(networkDetails);
- this.setSubtitleDirection('ltr');
- candidateData = networkDetails;
- // Only break when we see a connecting network as it is possible to
- // have a connected network and a connecting network at the same
- // time.
- if (networkDetails.ConnectionState == 'Connecting')
- break;
- }
- }
- if (candidateData)
- this.iconData = candidateData;
- else
- this.iconType = this.data.key;
-
- this.showSelector();
-
- if (candidateData && isManaged(candidateData.Source))
- this.showManagedNetworkIndicator();
-
- if (activeMenu_ == this.getMenuName()) {
- // Menu is already showing and needs to be updated. Explicitly calling
- // show menu will force the existing menu to be replaced. The call
- // is deferred in order to ensure that position of this element has
- // beem properly updated.
- var self = this;
- setTimeout(function() {self.showMenu();}, 0);
- }
- },
-
- /**
- * Creates a menu for selecting, configuring or disconnecting from a
- * network.
- * @return {!Element} The newly created menu.
- */
- createMenu: function() {
- var menu = this.ownerDocument.createElement('div');
- menu.id = this.getMenuName();
- menu.className = 'network-menu';
- menu.hidden = true;
- Menu.decorate(menu);
- menu.menuItemSelector = '.network-menu-item';
- var addendum = [];
- if (this.data_.key == 'WiFi') {
- addendum.push({
- label: loadTimeData.getString('joinOtherNetwork'),
- command: createAddNonVPNConnectionCallback_('WiFi'),
- data: {}
- });
- } else if (this.data_.key == 'Cellular') {
- if (cellularDevice_.State == 'Enabled' &&
- cellularNetwork_ && cellularNetwork_.Cellular &&
- cellularNetwork_.Cellular.SupportNetworkScan) {
- addendum.push({
- label: loadTimeData.getString('otherCellularNetworks'),
- command: createAddNonVPNConnectionCallback_('Cellular'),
- addClass: ['other-cellulars'],
- data: {}
- });
- }
-
- var label = enableDataRoaming_ ? 'disableDataRoaming' :
- 'enableDataRoaming';
- var disabled = !loadTimeData.getValue('loggedInAsOwner');
- var entry = {label: loadTimeData.getString(label),
- data: {}};
- if (disabled) {
- entry.command = null;
- entry.tooltip =
- loadTimeData.getString('dataRoamingDisableToggleTooltip');
- } else {
- var self = this;
- entry.command = function() {
- options.Preferences.setBooleanPref(
- 'cros.signed.data_roaming_enabled',
- !enableDataRoaming_, true);
- // Force revalidation of the menu the next time it is displayed.
- self.menu_ = null;
- };
- }
- addendum.push(entry);
- } else if (this.data_.key == 'VPN') {
- addendum = addendum.concat(createAddVPNConnectionEntries_());
- }
-
- var list = this.data.rememberedNetworks;
- if (list && list.length > 0) {
- var callback = function(list) {
- $('remembered-network-list').clear();
- var dialog = options.PreferredNetworks.getInstance();
- PageManager.showPageByName('preferredNetworksPage', false);
- dialog.update(list);
- sendChromeMetricsAction('Options_NetworkShowPreferred');
- };
- addendum.push({label: loadTimeData.getString('preferredNetworks'),
- command: callback,
- data: list});
- }
-
- var networkGroup = this.ownerDocument.createElement('div');
- networkGroup.className = 'network-menu-group';
- list = this.data.networkList;
- var empty = !list || list.length == 0;
- if (list) {
- var connectedVpnGuid = '';
- for (var i = 0; i < list.length; i++) {
- var data = list[i];
- this.createNetworkOptionsCallback_(networkGroup, data);
- // For VPN only, append a 'Disconnect' item to the dropdown menu.
- if (!connectedVpnGuid && data.Type == 'VPN' &&
- (data.ConnectionState == 'Connected' ||
- data.ConnectionState == 'Connecting')) {
- connectedVpnGuid = data.GUID;
- }
- }
- if (connectedVpnGuid) {
- var disconnectCallback = function() {
- sendChromeMetricsAction('Options_NetworkDisconnectVPN');
- chrome.networkingPrivate.startDisconnect(connectedVpnGuid);
- };
- // Add separator
- addendum.push({});
- addendum.push({label: loadTimeData.getString('disconnectNetwork'),
- command: disconnectCallback,
- data: data});
- }
- }
- if (this.data_.key == 'WiFi' || this.data_.key == 'WiMAX' ||
- this.data_.key == 'Cellular') {
- addendum.push({});
- if (this.data_.key == 'WiFi') {
- addendum.push({
- label: loadTimeData.getString('turnOffWifi'),
- command: function() {
- sendChromeMetricsAction('Options_NetworkWifiToggle');
- chrome.networkingPrivate.disableNetworkType(
- chrome.networkingPrivate.NetworkType.WI_FI);
- },
- data: {}});
- } else if (this.data_.key == 'WiMAX') {
- addendum.push({
- label: loadTimeData.getString('turnOffWimax'),
- command: function() {
- chrome.networkingPrivate.disableNetworkType(
- chrome.networkingPrivate.NetworkType.WI_MAX);
- },
- data: {}});
- } else if (this.data_.key == 'Cellular') {
- addendum.push({
- label: loadTimeData.getString('turnOffCellular'),
- command: function() {
- chrome.networkingPrivate.disableNetworkType(
- chrome.networkingPrivate.NetworkType.CELLULAR);
- },
- data: {}});
- }
- }
- if (!empty)
- menu.appendChild(networkGroup);
- if (addendum.length > 0) {
- var separator = false;
- if (!empty) {
- menu.appendChild(MenuItem.createSeparator());
- separator = true;
- }
- for (var i = 0; i < addendum.length; i++) {
- var value = addendum[i];
- if (value.data) {
- var item = createCallback_(menu, value.data, value.label,
- value.command);
- if (value.tooltip)
- item.title = value.tooltip;
- if (value.addClass)
- item.classList.add(value.addClass);
- separator = false;
- } else if (!separator) {
- menu.appendChild(MenuItem.createSeparator());
- separator = true;
- }
- }
- }
- return menu;
- },
-
- /** @override */
- canUpdateMenu: function() {
- return this.data_.key == 'WiFi' && activeMenu_ == this.getMenuName();
- },
-
- /**
- * Updates an existing menu. Updated menus preserve ordering of prior
- * entries. During the update process, the ordering may differ from the
- * preferred ordering as determined by the network library. If the
- * ordering becomes potentially out of sync, then the updated menu is
- * marked for disposal on close. Reopening the menu will force a
- * regeneration, which will in turn fix the ordering. This method must only
- * be called if canUpdateMenu() returned |true|.
- * @return {boolean} True if successfully updated.
- */
- updateMenu: function() {
- var oldMenu = $(this.getMenuName());
- var group = oldMenu.getElementsByClassName('network-menu-group')[0];
- if (!group)
- return false;
- var newMenu = this.createMenu();
- var discardOnClose = false;
- var oldNetworkButtons = this.extractNetworkConnectButtons_(oldMenu);
- var newNetworkButtons = this.extractNetworkConnectButtons_(newMenu);
- for (var key in oldNetworkButtons) {
- if (newNetworkButtons[key]) {
- group.replaceChild(newNetworkButtons[key].button,
- oldNetworkButtons[key].button);
- if (newNetworkButtons[key].index != oldNetworkButtons[key].index)
- discardOnClose = true;
- newNetworkButtons[key] = null;
- } else {
- // Leave item in list to prevent network items from jumping due to
- // deletions.
- oldNetworkButtons[key].disabled = true;
- discardOnClose = true;
- }
- }
- for (var key in newNetworkButtons) {
- var entry = newNetworkButtons[key];
- if (entry) {
- group.appendChild(entry.button);
- discardOnClose = true;
- }
- }
- oldMenu.data = {discardOnClose: discardOnClose};
- return true;
- },
-
- /**
- * Extracts a mapping of network names to menu element and position.
- * @param {!Element} menu The menu to process.
- * @return {Object<?{index: number, button: Element}>}
- * Network mapping.
- * @private
- */
- extractNetworkConnectButtons_: function(menu) {
- var group = menu.getElementsByClassName('network-menu-group')[0];
- var networkButtons = {};
- if (!group)
- return networkButtons;
- var buttons = group.getElementsByClassName('network-menu-item');
- for (var i = 0; i < buttons.length; i++) {
- var label = buttons[i].data.label;
- networkButtons[label] = {index: i, button: buttons[i]};
- }
- return networkButtons;
- },
-
- /**
- * Adds a menu item for showing network details.
- * @param {!Element} parent The parent element.
- * @param {NetworkProperties} data Description of the network.
- * @private
- */
- createNetworkOptionsCallback_: function(parent, data) {
- var menuItem = createCallback_(parent,
- data,
- getNetworkName(data),
- showDetails.bind(null, data.GUID));
- if (isManaged(data.Source))
- menuItem.appendChild(new ManagedNetworkIndicator());
- if (data.ConnectionState == 'Connected' ||
- data.ConnectionState == 'Connecting') {
- var label = menuItem.getElementsByClassName(
- 'network-menu-item-label')[0];
- label.classList.add('active-network');
- }
- }
- };
-
- /**
- * Creates a button-like control for configurating internet connectivity.
- * @param {{key: string, subtitle: string, command: Function}} data
- * Description of the network control.
- * @constructor
- * @extends {NetworkListItem}
- */
- function NetworkButtonItem(data) {
- var el = new NetworkListItem(data);
- el.__proto__ = NetworkButtonItem.prototype;
- el.decorate();
- return el;
- }
-
- NetworkButtonItem.prototype = {
- __proto__: NetworkListItem.prototype,
-
- /** @override */
- decorate: function() {
- if (this.data.subtitle)
- this.subtitle = this.data.subtitle;
- else
- this.subtitle = null;
- if (this.data.command)
- this.addEventListener('click', this.data.command);
- if (this.data.iconData)
- this.iconData = this.data.iconData;
- else if (this.data.iconType)
- this.iconType = this.data.iconType;
- if (isManaged(this.data.Source))
- this.showManagedNetworkIndicator();
- },
- };
-
- /**
- * Adds a command to a menu for modifying network settings.
- * @param {!Element} menu Parent menu.
- * @param {?NetworkProperties} data Description of the network.
- * @param {!string} label Display name for the menu item.
- * @param {!Function} command Callback function.
- * @return {!Element} The created menu item.
- * @private
- */
- function createCallback_(menu, data, label, command) {
- var button = menu.ownerDocument.createElement('div');
- button.className = 'network-menu-item';
-
- var buttonIconDiv = menu.ownerDocument.createElement('div');
- buttonIconDiv.className = 'network-icon';
- button.appendChild(buttonIconDiv);
- if (data && isNetworkType(data.Type)) {
- var networkIcon = /** @type {!CrNetworkIconElement} */ (
- document.createElement('cr-network-icon'));
- buttonIconDiv.appendChild(networkIcon);
- networkIcon.isListItem = true;
- networkIcon.networkState =
- /** @type {chrome.networkingPrivate.NetworkStateProperties} */ (data);
- }
-
- var buttonLabel = menu.ownerDocument.createElement('span');
- buttonLabel.className = 'network-menu-item-label';
- buttonLabel.textContent = label;
- button.appendChild(buttonLabel);
- var callback = null;
- if (command != null) {
- if (data) {
- callback = function() {
- (/** @type {Function} */(command))(data);
- closeMenu_();
- };
- } else {
- callback = function() {
- (/** @type {Function} */(command))();
- closeMenu_();
- };
- }
- }
- if (callback != null)
- button.addEventListener('activate', callback);
- else
- buttonLabel.classList.add('network-disabled-control');
-
- button.data = {label: label};
- MenuItem.decorate(button);
- menu.appendChild(button);
- return button;
- }
-
- /**
- * A list of controls for manipulating network connectivity.
- * @constructor
- * @extends {cr.ui.List}
- */
- var NetworkList = cr.ui.define('list');
-
- NetworkList.prototype = {
- __proto__: List.prototype,
-
- /** @override */
- decorate: function() {
- List.prototype.decorate.call(this);
- this.startBatchUpdates();
- this.autoExpands = true;
- this.dataModel = new ArrayDataModel([]);
- this.selectionModel = new ListSingleSelectionModel();
- this.addEventListener('blur', this.onBlur_.bind(this));
- this.selectionModel.addEventListener('change',
- this.onSelectionChange_.bind(this));
-
- // Wi-Fi control is always visible.
- this.update({key: 'WiFi', networkList: []});
-
- this.updateAddConnectionMenuEntries_();
-
- var prefs = options.Preferences.getInstance();
- prefs.addEventListener('cros.signed.data_roaming_enabled',
- function(event) {
- enableDataRoaming_ = event.value.value;
- });
- this.endBatchUpdates();
-
- this.onNetworkListChanged_(); // Trigger an initial network update
-
- chrome.networkingPrivate.onNetworkListChanged.addListener(
- this.onNetworkListChanged_.bind(this));
- chrome.networkingPrivate.onDeviceStateListChanged.addListener(
- this.onNetworkListChanged_.bind(this));
-
- chrome.management.onInstalled.addListener(
- this.onExtensionAdded_.bind(this));
- chrome.management.onEnabled.addListener(
- this.onExtensionAdded_.bind(this));
- chrome.management.onUninstalled.addListener(
- this.onExtensionRemoved_.bind(this));
- chrome.management.onDisabled.addListener(function(extension) {
- this.onExtensionRemoved_(extension.id);
- }.bind(this));
-
- chrome.management.getAll(this.onGetAllExtensions_.bind(this));
- chrome.networkingPrivate.requestNetworkScan();
- },
-
- /**
- * networkingPrivate event called when the network list has changed.
- */
- onNetworkListChanged_: function() {
- var networkList = this;
- chrome.networkingPrivate.getDeviceStates(function(deviceStates) {
- var filter = {
- networkType: chrome.networkingPrivate.NetworkType.ALL
- };
- chrome.networkingPrivate.getNetworks(filter, function(networkStates) {
- networkList.updateNetworkStates(deviceStates, networkStates);
- });
- });
- },
-
- /**
- * chrome.management.getAll callback.
- * @param {!Array<!ExtensionInfo>} extensions
- * @private
- */
- onGetAllExtensions_: function(extensions) {
- vpnProviders_ = [];
- for (var extension of extensions)
- this.addVpnProvider_(extension);
- },
-
- /**
- * If |extension| is a third-party VPN provider, add it to vpnProviders_.
- * @param {!ExtensionInfo} extension
- * @private
- */
- addVpnProvider_: function(extension) {
- if (!extension.enabled ||
- extension.permissions.indexOf('vpnProvider') == -1) {
- return;
- }
- // Ensure that we haven't already added this provider, e.g. if
- // the onExtensionAdded_ callback gets invoked after onGetAllExtensions_
- // for an extension in the returned list.
- for (var provider of vpnProviders_) {
- if (provider.ExtensionID == extension.id)
- return;
- }
- var newProvider = {
- ExtensionID: extension.id,
- ProviderName: extension.name
- };
- vpnProviders_.push(newProvider);
- this.refreshVpnProviders_();
- },
-
- /**
- * chrome.management.onInstalled or onEnabled event.
- * @param {!ExtensionInfo} extension
- * @private
- */
- onExtensionAdded_: function(extension) {
- this.addVpnProvider_(extension);
- },
-
- /**
- * chrome.management.onUninstalled or onDisabled event.
- * @param {string} extensionId
- * @private
- */
- onExtensionRemoved_: function(extensionId) {
- for (var i = 0; i < vpnProviders_.length; ++i) {
- var provider = vpnProviders_[i];
- if (provider.ExtensionID == extensionId) {
- vpnProviders_.splice(i, 1);
- this.refreshVpnProviders_();
- break;
- }
- }
- },
-
- /**
- * Rebuilds the list of VPN providers.
- * @private
- */
- refreshVpnProviders_: function() {
- // Refresh the contents of the VPN menu.
- var index = this.indexOf('VPN');
- if (index != undefined)
- this.getListItemByIndex(index).refreshMenu();
-
- // Refresh the contents of the "add connection" menu.
- this.updateAddConnectionMenuEntries_();
- index = this.indexOf('addConnection');
- if (index != undefined)
- this.getListItemByIndex(index).refreshMenu();
- },
-
- /**
- * Updates the entries in the "add connection" menu, based on the VPN
- * providers currently enabled in the user's profile.
- * @private
- */
- updateAddConnectionMenuEntries_: function() {
- var entries = [{
- label: loadTimeData.getString('addConnectionWifi'),
- command: createAddNonVPNConnectionCallback_('WiFi')
- }];
- entries = entries.concat(createAddVPNConnectionEntries_());
- this.update({key: 'addConnection',
- iconType: 'add-connection',
- menu: entries
- });
- },
-
- /**
- * When the list loses focus, unselect all items in the list and close the
- * active menu.
- * @private
- */
- onBlur_: function() {
- this.selectionModel.unselectAll();
- closeMenu_();
- },
-
- /** @override */
- handleKeyDown: function(e) {
- if (activeMenu_) {
- // keyIdentifier does not report 'Esc' correctly
- if (e.keyCode == 27 /* Esc */) {
- closeMenu_();
- return;
- }
-
- if ($(activeMenu_).handleKeyDown(e)) {
- e.preventDefault();
- e.stopPropagation();
- }
- return;
- }
-
- if (e.keyIdentifier == 'Enter' ||
- e.keyIdentifier == 'U+0020' /* Space */) {
- var selectedListItem = this.getListItemByIndex(
- this.selectionModel.selectedIndex);
- if (selectedListItem) {
- selectedListItem.click();
- return;
- }
- }
-
- List.prototype.handleKeyDown.call(this, e);
- },
-
- /**
- * Close bubble and menu when a different list item is selected.
- * @param {Event} event Event detailing the selection change.
- * @private
- */
- onSelectionChange_: function(event) {
- PageManager.hideBubble();
- // A list item may temporarily become unselected while it is constructing
- // its menu. The menu should therefore only be closed if a different item
- // is selected, not when the menu's owner item is deselected.
- if (activeMenu_) {
- for (var i = 0; i < event.changes.length; ++i) {
- if (event.changes[i].selected) {
- var item = this.dataModel.item(event.changes[i].index);
- if (!item.getMenuName || item.getMenuName() != activeMenu_) {
- closeMenu_();
- return;
- }
- }
- }
- }
- },
-
- /**
- * Finds the index of a network item within the data model based on
- * category.
- * @param {string} key Unique key for the item in the list.
- * @return {(number|undefined)} The index of the network item, or
- * |undefined| if it is not found.
- */
- indexOf: function(key) {
- var size = this.dataModel.length;
- for (var i = 0; i < size; i++) {
- var entry = this.dataModel.item(i);
- if (entry.key == key)
- return i;
- }
- return undefined;
- },
-
- /**
- * Updates a network control.
- * @param {Object} data Description of the entry.
- */
- update: function(data) {
- this.startBatchUpdates();
- var index = this.indexOf(data.key);
- if (index == undefined) {
- // Find reference position for adding the element. We cannot hide
- // individual list elements, thus we need to conditionally add or
- // remove elements and cannot rely on any element having a fixed index.
- for (var i = 0; i < Constants.NETWORK_ORDER.length; i++) {
- if (data.key == Constants.NETWORK_ORDER[i]) {
- data.sortIndex = i;
- break;
- }
- }
- var referenceIndex = -1;
- for (var i = 0; i < this.dataModel.length; i++) {
- var entry = this.dataModel.item(i);
- if (entry.sortIndex < data.sortIndex)
- referenceIndex = i;
- else
- break;
- }
- if (referenceIndex == -1) {
- // Prepend to the start of the list.
- this.dataModel.splice(0, 0, data);
- } else if (referenceIndex == this.dataModel.length) {
- // Append to the end of the list.
- this.dataModel.push(data);
- } else {
- // Insert after the reference element.
- this.dataModel.splice(referenceIndex + 1, 0, data);
- }
- } else {
- var entry = this.dataModel.item(index);
- data.sortIndex = entry.sortIndex;
- this.dataModel.splice(index, 1, data);
- }
- this.endBatchUpdates();
- },
-
- /**
- * @override
- * @param {Object} entry
- */
- createItem: function(entry) {
- if (entry.networkList)
- return new NetworkSelectorItem(
- /** @type {{key: string, networkList: Array<!NetworkProperties>}} */
- (entry));
- if (entry.command)
- return new NetworkButtonItem(
- /** @type {{key: string, subtitle: string, command: Function}} */(
- entry));
- if (entry.menu)
- return new NetworkMenuItem(entry);
- assertNotReached();
- },
-
- /**
- * Deletes an element from the list.
- * @param {string} key Unique identifier for the element.
- */
- deleteItem: function(key) {
- var index = this.indexOf(key);
- if (index != undefined)
- this.dataModel.splice(index, 1);
- },
-
- /**
- * Updates the state of network devices and services.
- * @param {!Array<!chrome.networkingPrivate.DeviceStateProperties>}
- * deviceStates The result from networkingPrivate.getDeviceStates.
- * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>}
- * networkStates The result from networkingPrivate.getNetworks.
- */
- updateNetworkStates: function(deviceStates, networkStates) {
- // Update device states.
- cellularDevice_ = null;
- wifiDeviceState_ = undefined;
- wimaxDeviceState_ = undefined;
- for (var i = 0; i < deviceStates.length; ++i) {
- var device = deviceStates[i];
- var type = device.Type;
- var state = device.State;
- if (type == 'Cellular')
- cellularDevice_ = cellularDevice_ || device;
- else if (type == 'WiFi')
- wifiDeviceState_ = wifiDeviceState_ || state;
- else if (type == 'WiMAX')
- wimaxDeviceState_ = wimaxDeviceState_ || state;
- }
-
- // Update active network states.
- cellularNetwork_ = null;
- ethernetNetwork_ = null;
- for (var i = 0; i < networkStates.length; i++) {
- // Note: This cast is valid since
- // networkingPrivate.NetworkStateProperties is a subset of
- // NetworkProperties and all missing properties are optional.
- var entry = /** @type {NetworkProperties} */ (networkStates[i]);
- switch (entry.Type) {
- case 'Cellular':
- cellularNetwork_ = cellularNetwork_ || entry;
- break;
- case 'Ethernet':
- // Ignore any EAP Parameters networks (which lack ConnectionState).
- if (entry.ConnectionState)
- ethernetNetwork_ = ethernetNetwork_ || entry;
- break;
- }
- if (cellularNetwork_ && ethernetNetwork_)
- break;
- }
-
- if (cellularNetwork_ && cellularNetwork_.GUID) {
- // Get the complete set of cellular properties which includes SIM and
- // Scan properties.
- var networkList = this;
- chrome.networkingPrivate.getProperties(
- cellularNetwork_.GUID, function(cellular) {
- cellularNetwork_ = /** @type {NetworkProperties} */ (cellular);
- networkList.updateControls(networkStates);
- });
- } else {
- this.updateControls(networkStates);
- }
- },
-
- /**
- * Updates network controls.
- * @param {!Array<!chrome.networkingPrivate.NetworkStateProperties>}
- * networkStates The result from networkingPrivate.getNetworks.
- */
- updateControls: function(networkStates) {
- this.startBatchUpdates();
-
- // Only show Ethernet control if available.
- if (ethernetNetwork_) {
- var ethernetOptions = showDetails.bind(null, ethernetNetwork_.GUID);
- var state = ethernetNetwork_.ConnectionState;
- var subtitle;
- if (state == 'Connected')
- subtitle = loadTimeData.getString('OncConnectionStateConnected');
- else if (state == 'Connecting')
- subtitle = loadTimeData.getString('OncConnectionStateConnecting');
- else
- subtitle = loadTimeData.getString('OncConnectionStateNotConnected');
- this.update(
- { key: 'Ethernet',
- subtitle: subtitle,
- iconData: ethernetNetwork_,
- command: ethernetOptions,
- Source: ethernetNetwork_.Source }
- );
- } else {
- this.deleteItem('Ethernet');
- }
-
- if (wifiDeviceState_ == 'Enabled')
- loadData_('WiFi', networkStates);
- else
- addEnableNetworkButton_(chrome.networkingPrivate.NetworkType.WI_FI);
-
- // Only show cellular control if available.
- if (cellularDevice_) {
- if (cellularDevice_.State == 'Enabled' &&
- !isCellularSimAbsent(cellularDevice_) &&
- !isCellularSimLocked(cellularDevice_)) {
- loadData_('Cellular', networkStates);
- } else {
- addEnableNetworkButton_(
- chrome.networkingPrivate.NetworkType.CELLULAR);
- }
- } else {
- this.deleteItem('Cellular');
- }
-
- // Only show wimax control if available. Uses cellular icons.
- if (wimaxDeviceState_) {
- if (wimaxDeviceState_ == 'Enabled')
- loadData_('WiMAX', networkStates);
- else
- addEnableNetworkButton_(chrome.networkingPrivate.NetworkType.WI_MAX);
- } else {
- this.deleteItem('WiMAX');
- }
-
- // Only show VPN control if there is at least one VPN configured.
- if (loadData_('VPN', networkStates) == 0)
- this.deleteItem('VPN');
-
- this.endBatchUpdates();
- }
- };
-
- /**
- * Replaces a network menu with a button for enabling the network type.
- * @param {chrome.networkingPrivate.NetworkType} type
- * @private
- */
- function addEnableNetworkButton_(type) {
- var subtitle = loadTimeData.getString('networkDisabled');
- var enableNetwork = function() {
- if (type == chrome.networkingPrivate.NetworkType.WI_FI)
- sendChromeMetricsAction('Options_NetworkWifiToggle');
- if (type == chrome.networkingPrivate.NetworkType.CELLULAR) {
- if (isCellularSimLocked(cellularDevice_)) {
- chrome.send('simOperation', ['unlock']);
- return;
- } else if (isCellularSimAbsent(cellularDevice_)) {
- chrome.send('simOperation', ['configure']);
- return;
- }
- }
- chrome.networkingPrivate.enableNetworkType(type);
- };
- $('network-list').update({key: type,
- subtitle: subtitle,
- iconType: type,
- command: enableNetwork});
- }
-
- /**
- * Element for indicating a policy managed network.
- * @constructor
- * @extends {options.ControlledSettingIndicator}
- */
- function ManagedNetworkIndicator() {
- var el = cr.doc.createElement('span');
- el.__proto__ = ManagedNetworkIndicator.prototype;
- el.decorate();
- return el;
- }
-
- ManagedNetworkIndicator.prototype = {
- __proto__: ControlledSettingIndicator.prototype,
-
- /** @override */
- decorate: function() {
- ControlledSettingIndicator.prototype.decorate.call(this);
- this.controlledBy = 'policy';
- var policyLabel = loadTimeData.getString('managedNetwork');
- this.setAttribute('textPolicy', policyLabel);
- this.removeAttribute('tabindex');
- },
-
- /** @override */
- handleEvent: function(event) {
- // Prevent focus blurring as that would close any currently open menu.
- if (event.type == 'mousedown')
- return;
- ControlledSettingIndicator.prototype.handleEvent.call(this, event);
- },
-
- /**
- * Handle mouse events received by the bubble, preventing focus blurring as
- * that would close any currently open menu and preventing propagation to
- * any elements located behind the bubble.
- * @param {Event} event Mouse event.
- */
- stopEvent: function(event) {
- event.preventDefault();
- event.stopPropagation();
- },
-
- /** @override */
- toggleBubble: function() {
- if (activeMenu_ && !$(activeMenu_).contains(this))
- closeMenu_();
- ControlledSettingIndicator.prototype.toggleBubble.call(this);
- if (this.showingBubble) {
- var bubble = PageManager.getVisibleBubble();
- bubble.addEventListener('mousedown', this.stopEvent);
- bubble.addEventListener('click', this.stopEvent);
- }
- }
- };
-
- /**
- * Updates the list of available networks and their status, filtered by
- * network type.
- * @param {string} type The type of network.
- * @param {Array<!chrome.networkingPrivate.NetworkStateProperties>} networks
- * The list of network objects.
- * @return {number} The number of visible networks matching |type|.
- */
- function loadData_(type, networks) {
- var res = 0;
- var availableNetworks = [];
- var rememberedNetworks = [];
- for (var i = 0; i < networks.length; i++) {
- var network = networks[i];
- if (network.Type != type)
- continue;
- if (networkIsVisible(network)) {
- availableNetworks.push(network);
- ++res;
- }
- if ((type == 'WiFi' || type == 'VPN') && network.Source &&
- network.Source != 'None') {
- rememberedNetworks.push(network);
- }
- }
- var data = {
- key: type,
- networkList: availableNetworks,
- rememberedNetworks: rememberedNetworks
- };
- $('network-list').update(data);
- return res;
- }
-
- /**
- * Hides the currently visible menu.
- * @private
- */
- function closeMenu_() {
- if (activeMenu_) {
- var menu = $(activeMenu_);
- menu.hidden = true;
- if (menu.data && menu.data.discardOnClose)
- menu.parentNode.removeChild(menu);
- activeMenu_ = null;
- }
- }
-
- /**
- * Creates a callback function that adds a new connection of the given type.
- * This method may be used for all network types except VPN.
- * @param {string} type An ONC network type
- * @return {function()} The created callback.
- * @private
- */
- function createAddNonVPNConnectionCallback_(type) {
- return function() {
- if (type == 'WiFi')
- sendChromeMetricsAction('Options_NetworkJoinOtherWifi');
- chrome.send('addNonVPNConnection', [type]);
- };
- }
-
- /**
- * Creates a callback function that shows the "add network" dialog for a VPN
- * provider. If |opt_extensionID| is omitted, the dialog for the built-in
- * OpenVPN/L2TP provider is shown. Otherwise, |opt_extensionID| identifies the
- * third-party provider for which the dialog should be shown.
- * @param {string=} opt_extensionID Extension ID identifying the third-party
- * VPN provider for which the dialog should be shown.
- * @return {function()} The created callback.
- * @private
- */
- function createVPNConnectionCallback_(opt_extensionID) {
- return function() {
- sendChromeMetricsAction(opt_extensionID ?
- 'Options_NetworkAddVPNThirdParty' :
- 'Options_NetworkAddVPNBuiltIn');
- chrome.send('addVPNConnection',
- opt_extensionID ? [opt_extensionID] : undefined);
- };
- }
-
- /**
- * Generates an "add network" entry for each VPN provider currently enabled in
- * the user's profile.
- * @return {!Array<{label: string, command: function(), data: !Object}>} The
- * list of entries.
- * @private
- */
- function createAddVPNConnectionEntries_() {
- var entries = [];
- for (var i = 0; i < vpnProviders_.length; ++i) {
- var provider = vpnProviders_[i];
- entries.push({
- label: loadTimeData.getStringF('addConnectionVPNTemplate',
- provider.ProviderName),
- command: createVPNConnectionCallback_(provider.ExtensionID),
- data: {}
- });
- }
- // Add an entry for the built-in OpenVPN/L2TP provider.
- entries.push({
- label: loadTimeData.getString('vpnBuiltInProvider'),
- command: createVPNConnectionCallback_(),
- data: {}
- });
- return entries;
- }
-
- /**
- * Whether the Network list is disabled. Only used for display purpose.
- */
- cr.defineProperty(NetworkList, 'disabled', cr.PropertyKind.BOOL_ATTR);
-
- // Export
- return {
- NetworkList: NetworkList
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/onc_data.js b/chromium/chrome/browser/resources/options/chromeos/onc_data.js
deleted file mode 100644
index 8114dbd2a33..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/onc_data.js
+++ /dev/null
@@ -1,195 +0,0 @@
-// 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.
-
-/**
- * @fileoverview ONC Data support class. Wraps a dictionary object containing
- * ONC managed or unmanaged dictionaries. Supports nested dictionaries,
- * e.g. data.getManagedProperty('VPN.Type').
- */
-
-cr.exportPath('cr.onc');
-
-cr.define('cr.onc', function() {
- 'use strict';
-
- /**
- * @constructor
- */
- function OncData(data) {
- this.data_ = data;
- }
-
- OncData.prototype = {
- /** @return {string} The GUID of the network. */
- guid: function() { return this.data_['GUID']; },
-
- /**
- * Returns either a managed property dictionary or an unmanaged value.
- * @param {string} key The property key.
- * @return {?} The property value or dictionary if it exists, otherwise
- * undefined.
- */
- getManagedProperty: function(key) {
- var data = this.data_;
- while (true) {
- var index = key.indexOf('.');
- if (index < 0)
- break;
- var keyComponent = key.substr(0, index);
- if (!(keyComponent in data))
- return undefined;
- data = data[keyComponent];
- key = key.substr(index + 1);
- }
- return data[key];
- },
-
- /**
- * Sets the value of a property. Currently only supports unmanaged
- * properties.
- * @param {string} key The property key.
- * @param {?} value The property value to set.
- */
- setProperty: function(key, value) {
- var data = this.data_;
- while (true) {
- var index = key.indexOf('.');
- if (index < 0)
- break;
- var keyComponent = key.substr(0, index);
- if (!(keyComponent in data))
- data[keyComponent] = {};
- data = data[keyComponent];
- key = key.substr(index + 1);
- }
- if (!(key in data) ||
- (typeof data[key] != 'object') ||
- (!('Active' in data[key]) && !('Effective' in data[key]))) {
- data[key] = value;
- } else {
- var effective = data[key]['Effective'];
- assert(effective != 'UserPolicy' || data[key]['UserEditable']);
- assert(effective != 'DevicePolicy' || data[key]['DeviceEditable']);
- // For now, just update the active value. TODO(stevenjb): Eventually we
- // should update the 'UserSetting' and 'Effective' properties correctly
- // and send that back to Chrome.
- data[key]['Active'] = value;
- }
- },
-
- /**
- * Gets the active value of a property.
- * @param {string} key The property key.
- * @return {?} The property value or undefined.
- */
- getActiveValue: function(key) {
- var property = this.getManagedProperty(key);
- if (Array.isArray(property) || typeof property != 'object')
- return property;
- // Otherwise get the Active value (default behavior).
- if ('Active' in property)
- return property['Active'];
- // If no Active value is defined, return the effective value if present.
- var effective = this.getEffectiveValueFromProperty_(
- /** @type {Object} */(property));
- if (effective != undefined)
- return effective;
- // Otherwise this is an Object but not a Managed one.
- return property;
- },
-
- /**
- * Gets the translated ONC value from the result of getActiveValue() using
- * loadTimeData. If no translation exists, returns the untranslated value.
- * @param {string} key The property key.
- * @return {?} The translation if available or the value if not.
- */
- getTranslatedValue: function(key) {
- var value = this.getActiveValue(key);
- if (typeof value != 'string')
- return value;
- var oncString = 'Onc' + key + value;
- // Handle special cases
- if (key == 'Name' && this.getActiveValue('Type') == 'Ethernet')
- return loadTimeData.getString('ethernetName');
- if (key == 'VPN.Type' && value == 'L2TP-IPsec') {
- var auth = this.getActiveValue('VPN.IPsec.AuthenticationType');
- if (auth != undefined)
- oncString += auth;
- }
- oncString = oncString.replace(/\./g, '-');
- if (loadTimeData.valueExists(oncString))
- return loadTimeData.getString(oncString);
- return value;
- },
-
- /**
- * Gets the recommended value of a property.
- * @param {string} key The property key.
- * @return {?} The property value or undefined.
- */
- getRecommendedValue: function(key) {
- var property = this.getManagedProperty(key);
- if (Array.isArray(property) || typeof property != 'object')
- return undefined;
- if (property['UserEditable'])
- return property['UserPolicy'];
- if (property['DeviceEditable'])
- return property['DevicePolicy'];
- // No value recommended by policy.
- return undefined;
- },
-
- /**
- * Returns the Source of this configuration. If undefined returns 'None'.
- * @return {string} The configuration source: 'None', 'User', 'Device',
- * 'UserPolicy', or 'DevicePolicy'.
- */
- getSource: function() {
- var source = this.getActiveValue('Source');
- if (source == undefined)
- return 'None';
- assert(typeof source == 'string');
- return source;
- },
-
- /**
- * Returns the WiFi security type (defaults to 'None').
- * @return {string} The security type.
- */
- getWiFiSecurity: function() {
- var security = this.getActiveValue('WiFi.Security');
- if (security == undefined)
- return 'None';
- assert(typeof security == 'string');
- return security;
- },
-
- /**
- * Get the effective value from a Managed property ONC dictionary.
- * @param {Object} property The managed property ONC dictionary.
- * @return {?} The effective value or undefined.
- * @private
- */
- getEffectiveValueFromProperty_: function(property) {
- if ('Effective' in property) {
- var effective = property.Effective;
- if (effective in property)
- return property[effective];
- }
- return undefined;
- },
-
- /**
- * Returns the complete ONC dictionary.
- */
- getData: function() {
- return this.data_;
- }
- };
-
- return {
- OncData: OncData
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/overscan_arrows.png b/chromium/chrome/browser/resources/options/chromeos/overscan_arrows.png
deleted file mode 100644
index 6f3e394a063..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/overscan_arrows.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/chromeos/overscan_arrows_2x.png b/chromium/chrome/browser/resources/options/chromeos/overscan_arrows_2x.png
deleted file mode 100644
index 10171c6ad69..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/overscan_arrows_2x.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/chromeos/overscan_shift.png b/chromium/chrome/browser/resources/options/chromeos/overscan_shift.png
deleted file mode 100644
index 7f4bef5dd70..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/overscan_shift.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/chromeos/overscan_shift_2x.png b/chromium/chrome/browser/resources/options/chromeos/overscan_shift_2x.png
deleted file mode 100644
index 7d23fdfd6d9..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/overscan_shift_2x.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/chromeos/overscan_shift_rtl.png b/chromium/chrome/browser/resources/options/chromeos/overscan_shift_rtl.png
deleted file mode 100644
index 3bc14f4b371..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/overscan_shift_rtl.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/chromeos/overscan_shift_rtl_2x.png b/chromium/chrome/browser/resources/options/chromeos/overscan_shift_rtl_2x.png
deleted file mode 100644
index fb89e2f9b8f..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/overscan_shift_rtl_2x.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.css b/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.css
deleted file mode 100644
index 9076ef1929c..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.css
+++ /dev/null
@@ -1,11 +0,0 @@
-/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#pointer-overlay > .content-area > :not([hidden]) + :nth-child(2) {
- margin-top: 20px;
-}
-
-#touchpad-scroll-direction {
- margin-top: 12px;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.html b/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.html
deleted file mode 100644
index 562522e3e05..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<div id="pointer-overlay" class="page" hidden>
- <div class="close-button"></div>
- <div class="content-area">
- <section id="pointer-section-touchpad" hidden>
- <h3 i18n-content="pointerOverlaySectionTitleTouchpad"></h3>
- <div class="checkbox">
- <label>
- <input type="checkbox" metric="Options_TouchpadTapToClick"
- pref="settings.touchpad.enable_tap_to_click" dialog-pref>
- <span i18n-content="enableTapToClick"></span>
- </label>
- </div>
- <div class="radio" id="touchpad-scroll-direction">
- <label>
- <input type="radio" name="touchpad-scroll-direction" value="false"
- metric="Options_TouchpadNaturalScroll"
- pref="settings.touchpad.natural_scroll" dialog-pref>
- <span i18n-content="traditionalScroll"></span>
- </label>
- </div>
- <div class="radio">
- <label>
- <input type="radio" name="touchpad-scroll-direction" value="true"
- metric="Options_TouchpadNaturalScroll"
- pref="settings.touchpad.natural_scroll" dialog-pref>
- <span i18n-values=".innerHTML:naturalScroll"></span>
- </label>
- </div>
- </section>
- <section id="pointer-section-mouse" hidden>
- <h3 i18n-content="pointerOverlaySectionTitleMouse"></h3>
- <div class="checkbox">
- <label>
- <input type="checkbox" metric="Options_MousePrimaryRight"
- pref="settings.mouse.primary_right" dialog-pref>
- <span i18n-content="primaryMouseRight"></span>
- </label>
- </div>
- </section>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="pointer-overlay-cancel" type="reset" i18n-content="cancel">
- </button>
- <button id="pointer-overlay-confirm" class="default-button" type="submit"
- i18n-content="ok">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.js b/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.js
deleted file mode 100644
index 62c603a2f53..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/pointer_overlay.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- /** @const */ var SettingsDialog = options.SettingsDialog;
-
- /**
- * PointerOverlay class
- * Dialog that allows users to set pointer settings (touchpad/mouse).
- * @constructor
- * @extends {options.SettingsDialog}
- */
- function PointerOverlay() {
- // The title is updated dynamically in the setTitle method as pointer
- // devices are discovered or removed.
- SettingsDialog.call(this, 'pointer-overlay',
- '', 'pointer-overlay',
- assertInstanceof($('pointer-overlay-confirm'), HTMLButtonElement),
- assertInstanceof($('pointer-overlay-cancel'), HTMLButtonElement));
- }
-
- cr.addSingletonGetter(PointerOverlay);
-
- PointerOverlay.prototype = {
- __proto__: SettingsDialog.prototype,
- };
-
- /**
- * Sets the visibility state of the touchpad group.
- * @param {boolean} show True to show, false to hide.
- */
- PointerOverlay.showTouchpadControls = function(show) {
- $('pointer-section-touchpad').hidden = !show;
- };
-
- /**
- * Sets the visibility state of the mouse group.
- * @param {boolean} show True to show, false to hide.
- */
- PointerOverlay.showMouseControls = function(show) {
- $('pointer-section-mouse').hidden = !show;
- };
-
- /**
- * Updates the title of the pointer dialog. The title is set dynamically
- * based on whether a touchpad, mouse or both are present. The label on the
- * button that activates the overlay is also updated to stay in sync. A
- * message is displayed in the main settings page if no pointer devices are
- * available.
- * @param {string} label i18n key for the overlay title.
- */
- PointerOverlay.setTitle = function(label) {
- var button = $('pointer-settings-button');
- var noPointersLabel = $('no-pointing-devices');
- if (label.length > 0) {
- var title = loadTimeData.getString(label);
- button.textContent = title;
- button.hidden = false;
- noPointersLabel.hidden = true;
- } else {
- button.hidden = true;
- noPointersLabel.hidden = false;
- }
- };
-
- // Export
- return {
- PointerOverlay: PointerOverlay
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/power_overlay.html b/chromium/chrome/browser/resources/options/chromeos/power_overlay.html
deleted file mode 100644
index d6c628adc32..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/power_overlay.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<div id="power-overlay" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="powerOverlay"></h1>
- <div class="content-area">
- <table>
- <tr>
- <td class="option-name" i18n-content="batteryStatusLabel">
- </td>
- <td id="battery-status-value" class="option-value">
- </td>
- </tr>
- <tr id="power-sources" hidden>
- <td class="option-name">
- <label id="power-source-label" i18n-content="powerSourceLabel">
- </label>
- </td>
- <td class="option-value">
- <select id="power-source-dropdown"
- aria-labelledby="power-source-label"></select>
- </td>
- </tr>
- <tr id="power-source-charger" hidden>
- <td class="option-name" i18n-content="powerSourceLabel">
- </td>
- <td id="power-source-charger-type" class="option-value">
- </td>
- </tr>
- </table>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="power-confirm" class="default-button" type="submit"
- i18n-content="done">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/power_overlay.js b/chromium/chrome/browser/resources/options/chromeos/power_overlay.js
deleted file mode 100644
index 4f511d09ea0..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/power_overlay.js
+++ /dev/null
@@ -1,172 +0,0 @@
-// 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.exportPath('options');
-
-/**
- * Copied from ash/system/chromeos/power/power_status.h.
- * @enum {number}
- */
-options.PowerStatusDeviceType = {
- DEDICATED_CHARGER: 0,
- DUAL_ROLE_USB: 1,
-};
-
-/**
- * @typedef {{
- * id: string,
- * type: options.PowerStatusDeviceType,
- * description: string
- * }}
- */
-options.PowerSource;
-
-cr.define('options', function() {
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
-
- /**
- * Encapsulated handling of the power overlay.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function PowerOverlay() {
- Page.call(this, 'power-overlay',
- loadTimeData.getString('powerOverlayTabTitle'),
- 'power-overlay');
- }
-
- cr.addSingletonGetter(PowerOverlay);
-
- PowerOverlay.prototype = {
- __proto__: Page.prototype,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
-
- $('power-confirm').onclick =
- PageManager.closeOverlay.bind(PageManager);
- $('power-source-dropdown').onchange =
- this.powerSourceChanged_.bind(this);
- },
-
- /** @override */
- didShowPage: function() {
- chrome.send('updatePowerStatus');
- },
-
- /**
- * @param {string} status
- * @private
- */
- setBatteryStatusText_: function(status) {
- $('battery-status-value').textContent = status;
- },
-
- /**
- * @param {Array<options.PowerSource>} sources External power sources.
- * @param {string} selectedId The ID of the currently used power source.
- * @param {boolean} isUsbCharger Whether the currently used power source
- * is a USB (low-powered) charger.
- * @param {boolean} isCalculating Whether the power info is still
- * being calculated.
- * @private
- */
- setPowerSources_: function(sources, selectedId, isUsbCharger,
- isCalculating) {
- if (this.lastPowerSource_ != selectedId) {
- this.lastPowerSource_ = selectedId;
- if (selectedId && !isUsbCharger) {
- // It can take a while to detect a USB charger, but triggering a
- // power status update makes the determination faster.
- setTimeout(chrome.send.bind(null, 'updatePowerStatus'), 1000);
- }
- }
-
- var chargerRow = $('power-source-charger');
-
- $('power-sources').hidden = chargerRow.hidden = true;
-
- // If no power sources are available, only show the battery status text.
- if (sources.length == 0)
- return;
-
- // If we're still calculating battery time and seem to have an AC
- // adapter, the charger information may be wrong.
- if (isCalculating && selectedId && !isUsbCharger) {
- $('power-source-charger-type').textContent =
- loadTimeData.getString('calculatingPower');
- chargerRow.hidden = false;
- return;
- }
-
- // Check if a dedicated charger is being used.
- var usingDedicatedCharger = false;
- if (selectedId) {
- usingDedicatedCharger = sources.some(function(source) {
- return source.id == selectedId &&
- source.type == options.PowerStatusDeviceType.DEDICATED_CHARGER;
- });
- }
-
- if (usingDedicatedCharger) {
- // Show charger information.
- $('power-source-charger-type').textContent = loadTimeData.getString(
- isUsbCharger ? 'powerSourceLowPowerCharger' :
- 'powerSourceAcAdapter');
- chargerRow.hidden = false;
- } else {
- this.showPowerSourceList_(sources, selectedId);
- }
- },
-
- /**
- * Populates and shows the dropdown of available power sources.
- * @param {Array<options.PowerSource>} sources External power sources.
- * @param {string} selectedId The ID of the currently used power source.
- * The empty string indicates no external power source is in use
- * (running on battery).
- * @private
- */
- showPowerSourceList_: function(sources, selectedId) {
- // Clear the dropdown.
- var dropdown = $('power-source-dropdown');
- dropdown.innerHTML = '';
-
- // Add a battery option.
- sources.unshift({
- id: '',
- description: loadTimeData.getString('powerSourceBattery'),
- });
-
- // Build the power source list.
- sources.forEach(function(source) {
- var option = document.createElement('option');
- option.value = source.id;
- option.textContent = source.description;
- option.selected = source.id == selectedId;
- dropdown.appendChild(option);
- });
-
- // Show the power source list.
- $('power-sources').hidden = false;
- },
-
- /** @private */
- powerSourceChanged_: function() {
- chrome.send('setPowerSource', [$('power-source-dropdown').value]);
- },
- };
-
- cr.makePublic(PowerOverlay, [
- 'setBatteryStatusText',
- 'setPowerSources',
- ]);
-
- // Export
- return {
- PowerOverlay: PowerOverlay
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/preferred_networks.html b/chromium/chrome/browser/resources/options/chromeos/preferred_networks.html
deleted file mode 100644
index 47b0d120a8b..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/preferred_networks.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<div id="preferredNetworksPage" class="page" hidden>
- <div class="close-button"></div>
- <h1 id="preferred-networks-page-title"
- i18n-content="preferredNetworksPage"></h1>
- <div class="content-area">
- <div class="settings-list">
- <list id="remembered-network-list"></list>
- </div>
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="preferred-networks-confirm" class="default-button"
- i18n-content="done">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/preferred_networks.js b/chromium/chrome/browser/resources/options/chromeos/preferred_networks.js
deleted file mode 100644
index 4f5a152b03a..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/preferred_networks.js
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.exportPath('options');
-
-/**
- * @typedef {{GUID: string, Name: string, Source: string, Type: string}}
- */
-options.PreferredNetwork;
-
-cr.define('options', function() {
-
- var Page = cr.ui.pageManager.Page;
- var PageManager = cr.ui.pageManager.PageManager;
- var ArrayDataModel = cr.ui.ArrayDataModel;
- var DeletableItem = options.DeletableItem;
- var DeletableItemList = options.DeletableItemList;
-
- /////////////////////////////////////////////////////////////////////////////
- // NetworkPreferences class:
-
- /**
- * Encapsulated handling of ChromeOS network preferences page.
- * @constructor
- * @extends {cr.ui.pageManager.Page}
- */
- function PreferredNetworks(model) {
- Page.call(this, 'preferredNetworksPage', '', 'preferredNetworksPage');
- }
-
- cr.addSingletonGetter(PreferredNetworks);
-
- PreferredNetworks.prototype = {
- __proto__: Page.prototype,
-
- /** @override */
- initializePage: function() {
- Page.prototype.initializePage.call(this);
- PreferredNetworkList.decorate($('remembered-network-list'));
- $('preferred-networks-confirm').onclick =
- PageManager.closeOverlay.bind(PageManager);
- },
-
- update: function(rememberedNetworks) {
- var list = $('remembered-network-list');
- list.clear();
- for (var i = 0; i < rememberedNetworks.length; i++) {
- list.append(rememberedNetworks[i]);
- }
- list.redraw();
- }
-
- };
-
- /**
- * Creates a list entry for a remembered network.
- * @param {options.PreferredNetwork} data Description of the network.
- * @constructor
- * @extends {options.DeletableItem}
- */
- function PreferredNetworkListItem(data) {
- var el = cr.doc.createElement('div');
- el.__proto__ = PreferredNetworkListItem.prototype;
- el.data = {};
- for (var key in data)
- el.data[key] = data[key];
- el.decorate();
- return el;
- }
-
- PreferredNetworkListItem.prototype = {
- __proto__: DeletableItem.prototype,
-
- /**
- * Description of the network.
- * @type {?options.PreferredNetwork}
- */
- data: null,
-
- /** @override */
- decorate: function() {
- DeletableItem.prototype.decorate.call(this);
- var label = this.ownerDocument.createElement('div');
- label.textContent = this.data.Name;
- if (this.data.Source == 'DevicePolicy' ||
- this.data.Source == 'UserPolicy') {
- this.deletable = false;
- }
- this.contentElement.appendChild(label);
- }
- };
-
- /**
- * Class for displaying a list of preferred networks.
- * @constructor
- * @extends {options.DeletableItemList}
- */
- var PreferredNetworkList = cr.ui.define('list');
-
- PreferredNetworkList.prototype = {
- __proto__: DeletableItemList.prototype,
-
- /** @override */
- decorate: function() {
- DeletableItemList.prototype.decorate.call(this);
- this.addEventListener('blur', this.onBlur_);
- this.clear();
- },
-
- /**
- * When the list loses focus, unselect all items in the list.
- * @private
- */
- onBlur_: function() {
- this.selectionModel.unselectAll();
- },
-
- /**
- * @override
- * @param {options.PreferredNetwork} entry
- */
- createItem: function(entry) {
- return new PreferredNetworkListItem(entry);
- },
-
- /** @override */
- deleteItemAtIndex: function(index) {
- var item = this.dataModel.item(index);
- if (item)
- chrome.networkingPrivate.forgetNetwork(item.GUID);
- this.dataModel.splice(index, 1);
- // Invalidate the list since it has a stale cache after a splice
- // involving a deletion.
- this.invalidate();
- this.redraw();
- },
-
- /**
- * Purges all networks from the list.
- */
- clear: function() {
- this.dataModel = new ArrayDataModel([]);
- this.redraw();
- },
-
- /**
- * Adds a remembered network to the list.
- * @param {options.PreferredNetwork} data Description of the network.
- */
- append: function(data) {
- this.dataModel.push(data);
- }
- };
-
- // Export
- return {
- PreferredNetworks: PreferredNetworks
- };
-
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/proxy_rules_list.js b/chromium/chrome/browser/resources/options/chromeos/proxy_rules_list.js
deleted file mode 100644
index 8c86ffc4e2d..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/proxy_rules_list.js
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options.proxyexceptions', function() {
- /** @const */ var List = cr.ui.List;
- /** @const */ var ListItem = cr.ui.ListItem;
- /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
-
- /**
- * Creates a new exception list.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {cr.ui.List}
- */
- var ProxyExceptions = cr.ui.define('list');
-
- ProxyExceptions.prototype = {
- __proto__: List.prototype,
-
- pref: 'cros.session.proxy.ignorelist',
-
- /** @override */
- decorate: function() {
- List.prototype.decorate.call(this);
- this.autoExpands = true;
-
- // HACK(arv): http://crbug.com/40902
- window.addEventListener('resize', this.redraw.bind(this));
-
- this.addEventListener('click', this.handleClick_);
-
- var self = this;
-
- // Listens to pref changes.
- Preferences.getInstance().addEventListener(this.pref,
- function(event) {
- self.load_(event.value.value);
- });
- },
-
- /**
- * @override
- * @param {Object} exception
- */
- createItem: function(exception) {
- return new ProxyExceptionsItem(exception);
- },
-
- /**
- * Adds given exception to model and update backend.
- * @param {Object} exception A exception to be added to exception list.
- */
- addException: function(exception) {
- this.dataModel.push(exception);
- this.updateBackend_();
- },
-
- /**
- * Removes given exception from model and update backend.
- */
- removeException: function(exception) {
- var dataModel = this.dataModel;
-
- var index = dataModel.indexOf(exception);
- if (index >= 0) {
- dataModel.splice(index, 1);
- this.updateBackend_();
- }
- },
-
- /**
- * Handles the clicks on the list and triggers exception removal if the
- * click is on the remove exception button.
- * @private
- * @param {!Event} e The click event object.
- */
- handleClick_: function(e) {
- // Handle left button click
- if (e.button == 0) {
- var el = e.target;
- if (el.className == 'remove-exception-button') {
- this.removeException(el.parentNode.exception);
- }
- }
- },
-
- /**
- * Loads given exception list.
- * @param {!Array} exceptions An array of exception object.
- */
- load_: function(exceptions) {
- this.dataModel = new ArrayDataModel(exceptions);
- },
-
- /**
- * Updates backend.
- */
- updateBackend_: function() {
- Preferences.setListPref(this.pref, this.dataModel.slice(), true);
- }
- };
-
- /**
- * Creates a new exception list item.
- * @param {Object} exception The exception account this represents.
- * @constructor
- * @extends {cr.ui.ListItem}
- */
- function ProxyExceptionsItem(exception) {
- var el = cr.doc.createElement('div');
- el.exception = exception;
- ProxyExceptionsItem.decorate(el);
- return el;
- }
-
- /**
- * Decorates an element as a exception account item.
- * @param {!HTMLElement} el The element to decorate.
- */
- ProxyExceptionsItem.decorate = function(el) {
- el.__proto__ = ProxyExceptionsItem.prototype;
- el.decorate();
- };
-
- ProxyExceptionsItem.prototype = {
- __proto__: ListItem.prototype,
-
- /** @override */
- decorate: function() {
- ListItem.prototype.decorate.call(this);
- this.className = 'exception-list-item';
-
- var labelException = this.ownerDocument.createElement('span');
- labelException.className = '';
- labelException.textContent = this.exception;
- this.appendChild(labelException);
- }
- };
-
- return {
- ProxyExceptions: ProxyExceptions
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css
deleted file mode 100644
index c0e8d30c9ce..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* 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.
- */
-
-#third-party-ime-confirm-overlay {
- width: 500px;
-}
diff --git a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html
deleted file mode 100644
index 63084432fd1..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<div id="third-party-ime-confirm-overlay" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="thirdPartyImeConfirmOverlay"></h1>
- <div class="content-area">
- <span id="third-party-ime-confirm-text"
- i18n-content="thirdPartyImeConfirmMessage">
- </span>
- </div>
- <div class="action-area">
- <div class="action-area-right">
- <div class="button-strip">
- <button id="third-party-ime-confirm-cancel"
- i18n-content="thirdPartyImeConfirmDisable">
- </button>
- <button id="third-party-ime-confirm-ok" class="default-button"
- i18n-content="thirdPartyImeConfirmEnable">
- </button>
- </div>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js
deleted file mode 100644
index 1f2d6c3eaf4..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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('options', function() {
- /** @const */ var PageManager = cr.ui.pageManager.PageManager;
- /** @const */ var SettingsDialog = options.SettingsDialog;
-
- /**
- * HomePageOverlay class
- * Dialog that allows users to set the home page.
- * @constructor
- * @extends {options.SettingsDialog}
- */
- function ThirdPartyImeConfirmOverlay() {
- SettingsDialog.call(
- this, 'thirdPartyImeConfirm',
- loadTimeData.getString('thirdPartyImeConfirmOverlayTabTitle'),
- 'third-party-ime-confirm-overlay',
- assertInstanceof($('third-party-ime-confirm-ok'), HTMLButtonElement),
- assertInstanceof($('third-party-ime-confirm-cancel'),
- HTMLButtonElement));
- }
-
- cr.addSingletonGetter(ThirdPartyImeConfirmOverlay);
-
- ThirdPartyImeConfirmOverlay.prototype = {
- __proto__: SettingsDialog.prototype,
-
- /**
- * Callback to authorize use of an input method.
- * @type {Function}
- * @private
- */
- confirmationCallback_: null,
-
- /**
- * Callback to cancel enabling an input method.
- * @type {Function}
- * @private
- */
- cancellationCallback_: null,
-
- /**
- * Confirms enabling of a third party IME.
- */
- handleConfirm: function() {
- SettingsDialog.prototype.handleConfirm.call(this);
- this.confirmationCallback_();
- },
-
- /**
- * Resets state of the checkobx.
- */
- handleCancel: function() {
- SettingsDialog.prototype.handleCancel.call(this);
- this.cancellationCallback_();
- },
-
- /**
- * Displays a confirmation dialog indicating the risk fo enabling
- * a third party IME.
- * @param {{extension: string, confirm: Function, cancel: Function}} data
- * Options for the confirmation dialog.
- * @private
- */
- showConfirmationDialog_: function(data) {
- this.confirmationCallback_ = data.confirm;
- this.cancellationCallback_ = data.cancel;
- var message = loadTimeData.getStringF('thirdPartyImeConfirmMessage',
- data.extension);
- $('third-party-ime-confirm-text').textContent = message;
- PageManager.showPageByName(this.name, false);
- },
- };
-
- /**
- * Displays a confirmation dialog indicating the risk fo enabling
- * a third party IME.
- * @param {{extension: string, confirm: Function, cancel: Function}} data
- * Options for the confirmation dialog.
- */
- ThirdPartyImeConfirmOverlay.showConfirmationDialog = function(data) {
- ThirdPartyImeConfirmOverlay.getInstance().showConfirmationDialog_(data);
- };
-
- // Export
- return {
- ThirdPartyImeConfirmOverlay: ThirdPartyImeConfirmOverlay
- };
-});
diff --git a/chromium/chrome/browser/resources/options/chromeos/warning.png b/chromium/chrome/browser/resources/options/chromeos/warning.png
deleted file mode 100644
index 53713ba3f90..00000000000
--- a/chromium/chrome/browser/resources/options/chromeos/warning.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.css b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.css
index 100ddb2e938..fca5b8d57f8 100644
--- a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.css
+++ b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.css
@@ -36,6 +36,10 @@
color: #999;
}
+.clear-browser-data-counter:not(:empty)::before {
+ content: '–\00a0\00a0';
+}
+
input[type=checkbox]:not(:checked) ~ .clear-browser-data-counter {
display: none;
}
diff --git a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.html b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.html
index 6f868797b3d..f3cb5c9c05f 100644
--- a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.html
+++ b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.html
@@ -15,9 +15,11 @@
<div id="delete-browsing-history-container" class="checkbox">
<label>
<input id="delete-browsing-history-checkbox"
- pref="browser.clear_data.browsing_history" type="checkbox">
+ pref="browser.clear_data.browsing_history" type="checkbox"
+ aria-controls="delete-browsing-history-counter">
<span i18n-content="deleteBrowsingHistoryCheckbox"></span>
- <span class="clear-browser-data-counter"></span>
+ <span class="clear-browser-data-counter" role="note"
+ aria-live="polite" id="delete-browsing-history-counter"></span>
</label>
</div>
<div id="delete-download-history-container" class="checkbox">
@@ -40,24 +42,31 @@
<div id="delete-cache-container" class="checkbox">
<label>
<input id="delete-cache-checkbox"
- pref="browser.clear_data.cache" type="checkbox">
+ pref="browser.clear_data.cache" type="checkbox"
+ aria-controls="delete-cache-counter">
<span i18n-content="deleteCacheCheckbox"></span>
- <span class="clear-browser-data-counter"></span>
+ <span class="clear-browser-data-counter" role="note"
+ aria-live="polite" id="delete-cache-counter"></span>
</label>
</div>
<div id="delete-passwords-container" class="checkbox">
<label>
<input id="delete-passwords-checkbox"
- pref="browser.clear_data.passwords" type="checkbox">
+ pref="browser.clear_data.passwords" type="checkbox"
+ aria-controls="delete-passwords-counter">
<span i18n-content="deletePasswordsCheckbox"></span>
- <span class="clear-browser-data-counter"></span>
+ <span class="clear-browser-data-counter" role="note"
+ aria-live="polite" id="delete-passwords-counter"></span>
</label>
</div>
<div id="delete-form-data-container" class="checkbox">
<label>
<input id="delete-form-data-checkbox"
- pref="browser.clear_data.form_data" type="checkbox">
+ pref="browser.clear_data.form_data" type="checkbox"
+ aria-controls="delete-form-data-counter">
<span i18n-content="deleteFormDataCheckbox"></span>
+ <span class="clear-browser-data-counter" role="note"
+ aria-live="polite" id="delete-form-data-counter"></span>
</label>
</div>
<div id="delete-hosted-apps-data-container" class="checkbox">
@@ -83,7 +92,8 @@
</div>
<div class="action-area">
<div class="hbox stretch">
- <a target="_blank" i18n-content="learnMore"
+ <a id="clear-browser-data-old-learn-more-link" hidden
+ target="_blank" i18n-content="learnMore"
i18n-values="href:clearBrowsingDataLearnMoreUrl"></a>
</div>
<div class="action-area-right">
@@ -97,6 +107,11 @@
</div>
</div>
<div id="some-stuff-remains-footer" class="gray-bottom-bar">
- <p><!--This is filled by JavaScript--></p>
+ <p>
+ <span><!--This is filled by JavaScript--></span>
+ <a id="clear-browser-data-footer-learn-more-link" hidden
+ target="_blank" i18n-content="learnMore"
+ i18n-values="href:clearBrowsingDataLearnMoreUrl"></a>
+ </p>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.js b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.js
index 883d81c9330..5ad1a89d761 100644
--- a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.js
+++ b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.js
@@ -90,6 +90,11 @@ cr.define('options', function() {
this.updateStateOfControls_();
},
+ /** @override */
+ didShowPage: function() {
+ chrome.send('openedClearBrowserData');
+ },
+
/**
* Create a footer that explains that some content is not cleared by the
* clear browsing data dialog and warns that the deletion may be synced.
@@ -106,7 +111,7 @@ cr.define('options', function() {
// and braces and converts them into buttons whereas the remainders are
// represented as span elements.
var footer =
- document.querySelector('#some-stuff-remains-footer p');
+ document.querySelector('#some-stuff-remains-footer p span');
var footerFragments =
loadTimeData.getString('clearBrowserDataSupportString')
.split(/([|#])/);
@@ -122,10 +127,7 @@ cr.define('options', function() {
var linkId = '';
if (i + 2 < footerFragments.length) {
if (footerFragments[i] == '|' && footerFragments[i + 2] == '|') {
- if (simple)
- linkId = 'open-not-deleted-help-from-clear-browsing-data';
- else
- linkId = 'open-content-settings-from-clear-browsing-data';
+ linkId = 'open-content-settings-from-clear-browsing-data';
} else if (footerFragments[i] == '#' &&
footerFragments[i + 2] == '#') {
linkId = 'open-search-engines-from-clear-browsing-data';
@@ -150,13 +152,7 @@ cr.define('options', function() {
}
}
- if (simple) {
- $('open-not-deleted-help-from-clear-browsing-data').onclick =
- function(event) {
- // TODO(msramek): Link to the exact page when the article is written.
- window.open('https://support.google.com/chrome/');
- };
- } else {
+ if (!simple) {
$('open-content-settings-from-clear-browsing-data').onclick =
function(event) {
PageManager.showPageByName('content');
@@ -166,6 +162,10 @@ cr.define('options', function() {
PageManager.showPageByName('searchEngines');
};
}
+
+ $('clear-browser-data-old-learn-more-link').hidden = simple;
+ $('clear-browser-data-footer-learn-more-link').hidden = !simple;
+ $('flash-storage-settings').hidden = simple;
},
/**
diff --git a/chromium/chrome/browser/resources/options/compiled_resources.gyp b/chromium/chrome/browser/resources/options/compiled_resources.gyp
index 5b92fa50946..242ff673ebb 100644
--- a/chromium/chrome/browser/resources/options/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/options/compiled_resources.gyp
@@ -8,7 +8,7 @@
'variables': {
'depends': [
'../../../../third_party/jstemplate/compiled_resources.gyp:jstemplate',
- '../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../ui/webui/resources/js/action_link.js',
'../../../../ui/webui/resources/js/cr.js',
'../../../../ui/webui/resources/js/cr/event_target.js',
@@ -46,10 +46,13 @@
# no possibility to use gyp variable expansion to it, so we don't use
# <(CLOSURE_DIR) in the "externs" line.
'externs': [
+ '../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../third_party/closure_compiler/externs/bluetooth_private.js',
'../../../../third_party/closure_compiler/externs/management.js',
+ '../../../../third_party/closure_compiler/externs/metrics_private.js',
'../../../../third_party/closure_compiler/externs/networking_private.js',
'../../../../third_party/closure_compiler/externs/chrome_send.js',
- '../../../../ui/webui/resources/cr_elements/v1_0/network/cr_network_icon_externs.js',
+ '../../../../ui/webui/resources/cr_elements/network/cr_network_icon_externs.js',
],
},
'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chromium/chrome/browser/resources/options/content_settings.html b/chromium/chrome/browser/resources/options/content_settings.html
index b9f69f4c038..c4278cb98c2 100644
--- a/chromium/chrome/browser/resources/options/content_settings.html
+++ b/chromium/chrome/browser/resources/options/content_settings.html
@@ -18,11 +18,11 @@
</div>
<div class="radio controlled-setting-with-label">
<label>
- <input type="radio" name="cookies" value="session">
+ <input type="radio" name="cookies" value="session_only">
<span>
- <span i18n-content="cookiesSession"></span>
+ <span i18n-content="cookiesSessionOnly"></span>
<span class="controlled-setting-indicator"
- content-setting="cookies" value="session"></span>
+ content-setting="cookies" value="session_only"></span>
</span>
</label>
</div>
@@ -113,6 +113,36 @@
</div>
</div>
</section>
+ <!-- Keygen filter -->
+ <section>
+ <h3 i18n-content="keygenTabLabel"></h3>
+ <div>
+ <div class="radio controlled-setting-with-label">
+ <label>
+ <input type="radio" name="keygen" value="allow">
+ <span>
+ <span i18n-content="keygenAllow"></span>
+ <span class="controlled-setting-indicator"
+ content-setting="keygen" value="allow"></span>
+ </span>
+ </label>
+ </div>
+ <div class="radio controlled-setting-with-label">
+ <label>
+ <input type="radio" name="keygen" value="block">
+ <span>
+ <span i18n-content="keygenBlock"></span>
+ <span class="controlled-setting-indicator"
+ content-setting="keygen" value="block"></span>
+ </span>
+ </label>
+ </div>
+ <div class="settings-row">
+ <button class="exceptions-list-button" contentType="keygen"
+ i18n-content="manageExceptions"></button>
+ </div>
+ </div>
+ </section>
<!-- Handlers settings -->
<section id="handlers-section">
<h3 i18n-content="handlersTabLabel"></h3>
@@ -154,11 +184,11 @@
</div>
<div class="radio controlled-setting-with-label">
<label>
- <input type="radio" name="plugins" value="detect">
+ <input type="radio" name="plugins" value="detect_important_content">
<span>
- <span i18n-content="pluginsDetect"></span>
+ <span i18n-content="pluginsDetectImportantContent"></span>
<span class="controlled-setting-indicator"
- content-setting="plugins" value="detect"></span>
+ content-setting="plugins" value="detect_important_content"></span>
</span>
</label>
</div>
@@ -309,7 +339,7 @@
</div>
</section>
<!-- Fullscreen filter -->
- <section>
+ <section id="fullscreen-section">
<h3 i18n-content="fullscreenTabLabel"></h3>
<div class="settings-row">
<button class="exceptions-list-button" contentType="fullscreen"
@@ -317,7 +347,7 @@
</div>
</section>
<!-- Mouse Lock filter -->
- <section>
+ <section id="mouselock-section">
<h3 i18n-content="mouselockTabLabel"></h3>
<div>
<div class="radio">
@@ -604,6 +634,16 @@
</div>
</div>
</section>
+ <!-- USB devices -->
+ <section>
+ <h3 i18n-content="usbDevicesHeader"></h3>
+ <div>
+ <div class="settings-row">
+ <button class="exceptions-list-button" contentType="usb-devices"
+ i18n-content="usbDevicesManage"></button>
+ </div>
+ </div>
+ </section>
<!-- Page zoom levels -->
<section id="page-zoom-levels">
<h3 i18n-content="zoomlevelsHeader"></h3>
diff --git a/chromium/chrome/browser/resources/options/content_settings.js b/chromium/chrome/browser/resources/options/content_settings.js
index f6236752535..e60496d3697 100644
--- a/chromium/chrome/browser/resources/options/content_settings.js
+++ b/chromium/chrome/browser/resources/options/content_settings.js
@@ -24,6 +24,7 @@ cr.define('options', function() {
'cookies': 'cookies',
'images': 'images',
'javascript': 'javascript',
+ 'keygen': 'keygen',
'location': 'location',
'media-stream-camera': 'mediaStreamCamera',
'media-stream-mic': 'mediaStreamMic',
@@ -226,6 +227,15 @@ cr.define('options', function() {
};
/**
+ * Shows/hides the fullscreen and mouselock sections.
+ * @param {boolean} visible Whether to show (or hide) the sections.
+ */
+ ContentSettings.setExclusiveAccessVisible = function(visible) {
+ $('fullscreen-section').hidden = !visible;
+ $('mouselock-section').hidden = !visible;
+ };
+
+ /**
* Updates the microphone/camera devices menu with the given entries.
* @param {string} type The device type.
* @param {Array} devices List of available devices.
diff --git a/chromium/chrome/browser/resources/options/content_settings_exceptions_area.html b/chromium/chrome/browser/resources/options/content_settings_exceptions_area.html
index 6be328388d1..bd4db34661d 100644
--- a/chromium/chrome/browser/resources/options/content_settings_exceptions_area.html
+++ b/chromium/chrome/browser/resources/options/content_settings_exceptions_area.html
@@ -13,6 +13,10 @@
i18n-content="exceptionZoomHeader"
class="exception-value-column-header" hidden>
</div>
+ <div id="exception-usb-device-column"
+ i18n-content="exceptionUsbDeviceHeader"
+ class="exception-value-column-header" hidden>
+ </div>
</div>
<div contentType="cookies">
<list mode="normal"></list>
@@ -144,6 +148,14 @@
<list mode="otr"></list>
</div>
</div>
+ <div contentType="usb-devices">
+ <list mode="normal"></list>
+ <div>
+ <span class="otr-explanation" i18n-content="otrExceptionsExplanation">
+ </span>
+ <list mode="otr"></list>
+ </div>
+ </div>
<div contentType="zoomlevels">
<list mode="normal"></list>
<div>
@@ -152,6 +164,14 @@
<list mode="otr"></list>
</div>
</div>
+ <div contentType="keygen">
+ <list mode="normal"></list>
+ <div>
+ <span class="otr-explanation" i18n-content="otrExceptionsExplanation">
+ </span>
+ <list mode="otr"></list>
+ </div>
+ </div>
</div>
<div class="action-area">
<div class="hbox stretch">
diff --git a/chromium/chrome/browser/resources/options/content_settings_exceptions_area.js b/chromium/chrome/browser/resources/options/content_settings_exceptions_area.js
index 273c130f218..3ad7ac62a55 100644
--- a/chromium/chrome/browser/resources/options/content_settings_exceptions_area.js
+++ b/chromium/chrome/browser/resources/options/content_settings_exceptions_area.js
@@ -14,14 +14,37 @@ cr.define('options.contentSettings', function() {
*
* @param {string} contentType The type of the list.
*/
- function IsEditableType(contentType) {
+ function isEditableType(contentType) {
// Exceptions of the following lists are not editable for now.
return !(contentType == 'location' ||
contentType == 'fullscreen' ||
contentType == 'media-stream-mic' ||
contentType == 'media-stream-camera' ||
contentType == 'midi-sysex' ||
- contentType == 'zoomlevels');
+ contentType == 'zoomlevels' ||
+ isChosenObjectType(contentType));
+ }
+
+ /**
+ * Returns whether exceptions of this type represent chosen objects.
+ *
+ * @param {string} contentType The type of the list.
+ */
+ function isChosenObjectType(contentType) {
+ return contentType == 'usb-devices';
+ }
+
+ /**
+ * Returns the ID of the column containing values for the given content type.
+ *
+ * @param {string} contentType The type of the list.
+ */
+ function valueColumnForContentType(contentType) {
+ if (contentType == 'usb-devices')
+ return 'exception-usb-device-column';
+ if (contentType == 'zoomlevels')
+ return 'exception-zoom-column';
+ return 'exception-behavior-column';
}
/**
@@ -63,8 +86,6 @@ cr.define('options.contentSettings', function() {
this.patternLabel = patternCell.querySelector('.static-text');
var input = patternCell.querySelector('input');
- // TODO(stuartmorgan): Create an createEditableSelectCell abstracting
- // this code.
// Setting label for display mode. |pattern| will be null for the 'add new
// exception' row.
if (this.pattern) {
@@ -86,14 +107,14 @@ cr.define('options.contentSettings', function() {
if (this.contentType == 'plugins') {
var optionDetect = cr.doc.createElement('option');
optionDetect.textContent = loadTimeData.getString('detectException');
- optionDetect.value = 'detect';
+ optionDetect.value = 'detect_important_content';
select.appendChild(optionDetect);
}
if (this.contentType == 'cookies') {
var optionSession = cr.doc.createElement('option');
optionSession.textContent = loadTimeData.getString('sessionException');
- optionSession.value = 'session';
+ optionSession.value = 'session_only';
select.appendChild(optionSession);
}
@@ -116,12 +137,14 @@ cr.define('options.contentSettings', function() {
this.editable = false;
}
- if (this.contentType != 'zoomlevels') {
+ if (this.contentType != 'zoomlevels' &&
+ !isChosenObjectType(this.contentType)) {
this.addEditField(select, this.settingLabel);
this.contentElement.appendChild(select);
}
select.className = 'exception-setting';
- select.setAttribute('aria-labelledby', 'exception-behavior-column');
+ select.setAttribute('aria-labelledby',
+ valueColumnForContentType(this.contentType));
if (this.pattern)
select.setAttribute('displaymode', 'edit');
@@ -133,11 +156,22 @@ cr.define('options.contentSettings', function() {
zoomLabel.textContent = this.dataItem.zoom;
zoomLabel.className = 'exception-setting';
zoomLabel.setAttribute('displaymode', 'static');
- zoomLabel.setAttribute('aria-labelledby', 'exception-zoom-column');
this.contentElement.appendChild(zoomLabel);
this.zoomLabel = zoomLabel;
}
+ if (isChosenObjectType(this.contentType) &&
+ this.dataItem.object !== undefined) {
+ this.deletable = true;
+
+ var objectLabel = cr.doc.createElement('span');
+ objectLabel.textContent = this.dataItem['objectName'];
+ objectLabel.className = 'exception-setting';
+ objectLabel.setAttribute('displaymode', 'static');
+ this.contentElement.appendChild(objectLabel);
+ this.objectLabel = objectLabel;
+ }
+
// Used to track whether the URL pattern in the input is valid.
// This will be true if the browser process has informed us that the
// current text in the input is valid. Changing the text resets this to
@@ -154,7 +188,7 @@ cr.define('options.contentSettings', function() {
this.select = select;
this.updateEditables();
- this.editable = this.editable && IsEditableType(this.contentType);
+ this.editable = this.editable && isEditableType(this.contentType);
// If the source of the content setting exception is not a user
// preference, that source controls the exception and the user cannot edit
@@ -265,9 +299,9 @@ cr.define('options.contentSettings', function() {
return loadTimeData.getString('blockException');
else if (setting == 'ask')
return loadTimeData.getString('askException');
- else if (setting == 'session')
+ else if (setting == 'session_only')
return loadTimeData.getString('sessionException');
- else if (setting == 'detect')
+ else if (setting == 'detect_important_content')
return loadTimeData.getString('detectException');
else if (setting == 'default')
return '';
@@ -529,7 +563,7 @@ cr.define('options.contentSettings', function() {
*/
isEditable: function() {
// Exceptions of the following lists are not editable for now.
- return IsEditableType(this.contentType);
+ return isEditableType(this.contentType);
},
/**
@@ -551,10 +585,15 @@ cr.define('options.contentSettings', function() {
return;
var dataItem = listItem.dataItem;
- chrome.send('removeException', [listItem.contentType,
- listItem.mode,
- dataItem.origin,
- dataItem.embeddingOrigin]);
+ var params = [listItem.contentType,
+ listItem.mode,
+ dataItem.origin,
+ dataItem.embeddingOrigin];
+
+ if (isChosenObjectType(this.contentType))
+ params.push(dataItem.object);
+
+ chrome.send('removeException', params);
},
};
@@ -619,8 +658,11 @@ cr.define('options.contentSettings', function() {
divs[i].hidden = true;
}
- $('exception-behavior-column').hidden = type == 'zoomlevels';
- $('exception-zoom-column').hidden = type != 'zoomlevels';
+ var valueColumnId = valueColumnForContentType(type);
+ var headers =
+ this.pageDiv.querySelectorAll('div.exception-value-column-header');
+ for (var i = 0; i < headers.length; ++i)
+ headers[i].hidden = (headers[i].id != valueColumnId);
},
/**
diff --git a/chromium/chrome/browser/resources/options/language_add_language_overlay.js b/chromium/chrome/browser/resources/options/language_add_language_overlay.js
index 9197ecdb5bc..9ea8904b1a2 100644
--- a/chromium/chrome/browser/resources/options/language_add_language_overlay.js
+++ b/chromium/chrome/browser/resources/options/language_add_language_overlay.js
@@ -5,6 +5,16 @@
///////////////////////////////////////////////////////////////////////////////
// AddLanguageOverlay class:
+/**
+ * @typedef {{
+ * code: string,
+ * displayName: string,
+ * textDirection: string,
+ * nativeDisplayName: string
+ * }}
+ */
+options.LanguageData;
+
cr.define('options', function() {
/** @const */ var Page = cr.ui.pageManager.Page;
/** @const */ var PageManager = cr.ui.pageManager.PageManager;
@@ -37,12 +47,13 @@ cr.define('options', function() {
// Create the language list with which users can add a language.
var addLanguageList = $('add-language-overlay-language-list');
+
/**
- * @type {Array<{code: string, displayName: string,
- * textDirection: string, nativeDisplayName: string}>}
+ * @type {!Array<!options.LanguageData>}
* @see chrome/browser/ui/webui/options/language_options_handler.cc
*/
- var languageListData = loadTimeData.getValue('languageList');
+ var languageListData = /** @type {!Array<!options.LanguageData>} */(
+ loadTimeData.getValue('languageList'));
for (var i = 0; i < languageListData.length; i++) {
var language = languageListData[i];
var displayText = language.displayName;
diff --git a/chromium/chrome/browser/resources/options/language_options.css b/chromium/chrome/browser/resources/options/language_options.css
index 732f928a0f8..89265c8806c 100644
--- a/chromium/chrome/browser/resources/options/language_options.css
+++ b/chromium/chrome/browser/resources/options/language_options.css
@@ -91,6 +91,13 @@
margin-top: 0.65em;
}
+.language-options-ime-menu-desc {
+ -webkit-margin-start: 22px;
+ font-size: 80%;
+ margin-top: -6px;
+ padding-bottom: 2px;
+}
+
#language-options-list {
-webkit-box-flex: 1;
outline: none;
diff --git a/chromium/chrome/browser/resources/options/language_options.html b/chromium/chrome/browser/resources/options/language_options.html
index 9265faebacf..bf3c4a82df0 100644
--- a/chromium/chrome/browser/resources/options/language_options.html
+++ b/chromium/chrome/browser/resources/options/language_options.html
@@ -114,6 +114,17 @@
<a is="action-link" id="edit-custom-dictionary-button"
class="standalone-action-link"
i18n-content="languageDictionaryOverlayTitle"></a>
+ <div id="language-options-ime-menu-template" hidden>
+ <div class="checkbox" >
+ <label>
+ <input type="checkbox" id="activate-ime-menu">
+ <span i18n-content="activateImeMenu"></span>
+ </label>
+ </div>
+ <div class="language-options-ime-menu-desc">
+ <span i18n-content="activateImeMenuDesc"></span>
+ </div>
+ </div>
</if>
<if expr="not chromeos and not is_macosx">
<div class="checkbox">
@@ -125,14 +136,6 @@
<a is="action-link" id="edit-custom-dictionary-button"
i18n-content="languageDictionaryOverlayTitle" hidden></a>
</div>
- <div id="auto-spell-correction-option" class="checkbox" hidden>
- <label>
- <input id="enable-auto-spell-correction"
- pref="browser.enable_autospellcorrect"
- metric="Options_AutoSpellCorrection" type="checkbox">
- <span i18n-content="enableAutoSpellCorrection"></span>
- </label>
- </div>
</if>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/options/language_options.js b/chromium/chrome/browser/resources/options/language_options.js
index 149dace3857..e954815562c 100644
--- a/chromium/chrome/browser/resources/options/language_options.js
+++ b/chromium/chrome/browser/resources/options/language_options.js
@@ -66,6 +66,13 @@ cr.define('options', function() {
*/
var ENABLE_TRANSLATE = 'translate.enabled';
+ /**
+ * The preference is a boolean that activates/deactivates IME menu on shelf.
+ * @type {string}
+ * @const
+ */
+ var ACTIVATE_IME_MENU_PREF = 'settings.language.ime_menu_activated';
+
/////////////////////////////////////////////////////////////////////////////
// LanguageOptions class:
@@ -200,8 +207,8 @@ cr.define('options', function() {
this.handleSpellCheckDictionariesPrefChange_.bind(this));
Preferences.getInstance().addEventListener(ENABLE_TRANSLATE,
this.handleEnableTranslatePrefChange_.bind(this));
- this.translateSupportedLanguages_ =
- loadTimeData.getValue('translateSupportedLanguages');
+ this.translateSupportedLanguages_ = /** @type {Array} */(
+ loadTimeData.getValue('translateSupportedLanguages'));
// Set up add button.
var onclick = function(e) {
@@ -235,12 +242,6 @@ cr.define('options', function() {
$('add-language-overlay-ok-button').addEventListener(
'click', this.handleAddLanguageOkButtonClick_.bind(this));
- if (!cr.isChromeOS) {
- // Show experimental features if enabled.
- if (loadTimeData.getBoolean('enableSpellingAutoCorrect'))
- $('auto-spell-correction-option').hidden = false;
- }
-
if (!(cr.isMac || cr.isChromeOS)) {
// Handle spell check enable/disable.
if (!this.isMultilingualSpellcheckerEnabled_()) {
@@ -276,6 +277,18 @@ cr.define('options', function() {
// Public session users cannot change the locale.
if (cr.isChromeOS && UIAccountTweaks.loggedInAsPublicAccount())
$('language-options-ui-language-section').hidden = true;
+
+ // IME menu (CrOS only).
+ if (cr.isChromeOS) {
+ // Show the 'activate-ime-menu' checkbox if the flag is tured on.
+ if (loadTimeData.getBoolean('enableLanguageOptionsImeMenu'))
+ $('language-options-ime-menu-template').hidden = false;
+
+ // Listen to check on 'activate-ime-menu' checkbox.
+ var checkboxImeMenu = $('activate-ime-menu');
+ checkboxImeMenu.addEventListener('click',
+ this.handleActivateImeMenuCheckboxClick_.bind(this));
+ }
},
/**
@@ -289,10 +302,12 @@ cr.define('options', function() {
// change the visibility in handleLanguageOptionsListChange_() based
// on the selected language. Note that we only have less than 100
// input methods, so creating DOM nodes at once here should be ok.
- this.appendInputMethodElement_(loadTimeData.getValue('inputMethodList'));
- this.appendComponentExtensionIme_(
- loadTimeData.getValue('componentExtensionImeList'));
- this.appendInputMethodElement_(loadTimeData.getValue('extensionImeList'));
+ this.appendInputMethodElement_(/** @type {!Array} */(
+ loadTimeData.getValue('inputMethodList')));
+ this.appendComponentExtensionIme_(/** @type {!Array} */(
+ loadTimeData.getValue('componentExtensionImeList')));
+ this.appendInputMethodElement_(/** @type {!Array} */(
+ loadTimeData.getValue('extensionImeList')));
// Listen to pref change once the input method list is initialized.
Preferences.getInstance().addEventListener(
@@ -1422,6 +1437,19 @@ cr.define('options', function() {
return main;
},
+
+ /**
+ * Handles activate-ime-menu checkbox's click event.
+ * @param {Event} e Click event.
+ * @private
+ */
+ handleActivateImeMenuCheckboxClick_: function(e) {
+ if (cr.isChromeOS) {
+ var checkbox = e.target;
+ Preferences.setBooleanPref(ACTIVATE_IME_MENU_PREF,
+ checkbox.checked, true);
+ }
+ },
};
/**
diff --git a/chromium/chrome/browser/resources/options/manage_profile_overlay.js b/chromium/chrome/browser/resources/options/manage_profile_overlay.js
index 1f806422ace..917b6efbc23 100644
--- a/chromium/chrome/browser/resources/options/manage_profile_overlay.js
+++ b/chromium/chrome/browser/resources/options/manage_profile_overlay.js
@@ -95,7 +95,7 @@ cr.define('options', function() {
$('create-profile-supervised-sign-in-link').onclick =
function(event) {
- SyncSetupOverlay.startSignIn();
+ SyncSetupOverlay.startSignIn('access-point-supervised-user');
};
$('create-profile-supervised-sign-in-again-link').onclick =
@@ -371,6 +371,12 @@ cr.define('options', function() {
* @private
*/
receiveExistingSupervisedUsers_: function(supervisedUsers) {
+ // After a supervised user has been created and the dialog has been
+ // hidden, this gets called again with a list including
+ // the just-created SU. Ignore, to prevent the "already exists" bubble
+ // from showing up if the overlay is already hidden.
+ if (!this.visible)
+ return;
$('import-existing-supervised-user-link').hidden =
supervisedUsers.length === 0;
if (!$('create-profile-supervised').checked)
@@ -379,27 +385,39 @@ cr.define('options', function() {
var newName = $('create-profile-name').value;
var i;
for (i = 0; i < supervisedUsers.length; ++i) {
- if (supervisedUsers[i].name == newName &&
- !supervisedUsers[i].onCurrentDevice) {
- var errorHtml = loadTimeData.getStringF(
- 'manageProfilesExistingSupervisedUser',
- HTMLEscape(elide(newName, /* maxLength */ 50)));
- this.showErrorBubble_(errorHtml, 'create', true);
-
- // Check if another supervised user also exists with that name.
- var nameIsUnique = true;
- var j;
- for (j = i + 1; j < supervisedUsers.length; ++j) {
- if (supervisedUsers[j].name == newName) {
- nameIsUnique = false;
- break;
- }
+ if (supervisedUsers[i].name != newName)
+ continue;
+ // Check if another supervised user also exists with that name.
+ var nameIsUnique = true;
+ // Handling the case when multiple supervised users with the same
+ // name exist, but not all of them are on the device.
+ // If at least one is not imported, we want to offer that
+ // option to the user. This could happen due to a bug that allowed
+ // creating SUs with the same name (https://crbug.com/557445).
+ var allOnCurrentDevice = supervisedUsers[i].onCurrentDevice;
+ var j;
+ for (j = i + 1; j < supervisedUsers.length; ++j) {
+ if (supervisedUsers[j].name == newName) {
+ nameIsUnique = false;
+ allOnCurrentDevice = allOnCurrentDevice &&
+ supervisedUsers[j].onCurrentDevice;
}
+ }
+
+ var errorHtml = allOnCurrentDevice ?
+ loadTimeData.getStringF(
+ 'managedProfilesExistingLocalSupervisedUser') :
+ loadTimeData.getStringF(
+ 'manageProfilesExistingSupervisedUser',
+ HTMLEscape(elide(newName, /* maxLength */ 50)));
+ this.showErrorBubble_(errorHtml, 'create', true);
+
+ if ($('supervised-user-import-existing')) {
$('supervised-user-import-existing').onclick =
this.getImportHandler_(supervisedUsers[i], nameIsUnique);
- $('create-profile-ok').disabled = true;
- return;
}
+ $('create-profile-ok').disabled = true;
+ return;
}
},
diff --git a/chromium/chrome/browser/resources/options/options.html b/chromium/chrome/browser/resources/options/options.html
index 14196b33cec..e6e1ee2bc50 100644
--- a/chromium/chrome/browser/resources/options/options.html
+++ b/chromium/chrome/browser/resources/options/options.html
@@ -17,6 +17,7 @@
<link rel="stylesheet" href="alert_overlay.css">
<link rel="stylesheet" href="autofill_edit_overlay.css">
<link rel="stylesheet" href="autofill_options.css">
+<link rel="stylesheet" href="automatic_settings_reset_banner.css">
<link rel="stylesheet" href="browser_options.css">
<if expr="chromeos">
<link rel="stylesheet" href="chromeos/browser_options.css">
@@ -41,7 +42,6 @@
<link rel="stylesheet" href="reset_profile_settings_overlay.css">
<link rel="stylesheet" href="search_engine_manager.css">
<link rel="stylesheet" href="search_page.css">
-<link rel="stylesheet" href="settings_banner.css">
<link rel="stylesheet" href="spelling_confirm_overlay.css">
<link rel="stylesheet" href="startup_overlay.css">
<link rel="stylesheet" href="subpages_tab_controls.css">
diff --git a/chromium/chrome/browser/resources/options/options.js b/chromium/chrome/browser/resources/options/options.js
index ffea2c3dc19..d331855fe56 100644
--- a/chromium/chrome/browser/resources/options/options.js
+++ b/chromium/chrome/browser/resources/options/options.js
@@ -35,7 +35,6 @@ var PageManager = cr.ui.pageManager.PageManager;
var PasswordManager = options.PasswordManager;
var Preferences = options.Preferences;
var PreferredNetworks = options.PreferredNetworks;
-var ResetProfileSettingsBanner = options.ResetProfileSettingsBanner;
var ResetProfileSettingsOverlay = options.ResetProfileSettingsOverlay;
var SearchEngineManager = options.SearchEngineManager;
var SearchPage = options.SearchPage;
@@ -46,6 +45,8 @@ var SupervisedUserImportOverlay = options.SupervisedUserImportOverlay;
var SupervisedUserLearnMoreOverlay = options.SupervisedUserLearnMoreOverlay;
var SyncSetupOverlay = options.SyncSetupOverlay;
var ThirdPartyImeConfirmOverlay = options.ThirdPartyImeConfirmOverlay;
+var TriggeredResetProfileSettingsOverlay =
+ options.TriggeredResetProfileSettingsOverlay;
/**
* DOMContentLoaded handler, sets up the page.
@@ -168,6 +169,13 @@ function load() {
PageManager.registerOverlay(SyncSetupOverlay.getInstance(),
BrowserOptions.getInstance(),
[$('customize-sync')]);
+
+<if expr="is_win">
+ PageManager.registerOverlay(
+ TriggeredResetProfileSettingsOverlay.getInstance(),
+ BrowserOptions.getInstance());
+</if>
+
if (loadTimeData.getBoolean('showAbout')) {
PageManager.registerOverlay(help.HelpPage.getInstance(),
BrowserOptions.getInstance());
@@ -231,7 +239,6 @@ function load() {
OptionsFocusManager.getInstance().initialize();
Preferences.getInstance().initialize();
- ResetProfileSettingsBanner.getInstance().initialize();
AutomaticSettingsResetBanner.getInstance().initialize();
OptionsPage.initialize();
PageManager.initialize(BrowserOptions.getInstance());
diff --git a/chromium/chrome/browser/resources/options/options_bundle.js b/chromium/chrome/browser/resources/options/options_bundle.js
index 30be7eb5134..8a72e0dc702 100644
--- a/chromium/chrome/browser/resources/options/options_bundle.js
+++ b/chromium/chrome/browser/resources/options/options_bundle.js
@@ -14,7 +14,6 @@
<include src="options_page.js">
<include src="pref_ui.js">
<include src="settings_dialog.js">
-<include src="settings_banner.js">
<if expr="chromeos">
<include src="../chromeos/user_images_grid.js">
<include src="../help/channel_change_page.js">
@@ -104,7 +103,6 @@ var CertificateImportErrorOverlay = options.CertificateImportErrorOverlay;
<include src="password_manager.js">
<include src="password_manager_list.js">
<include src="profiles_icon_grid.js">
-<include src="reset_profile_settings_banner.js">
<include src="reset_profile_settings_overlay.js">
<include src="search_engine_manager.js">
<include src="search_engine_manager_engine_list.js">
@@ -117,6 +115,9 @@ var CertificateImportErrorOverlay = options.CertificateImportErrorOverlay;
<include src="supervised_user_list_data.js">
<include src="../help/help_page.js">
<include src="sync_setup_overlay.js">
+<if expr="is_win">
+<include src="triggered_reset_profile_settings_overlay.js">
+</if>
<include src="../uber/uber_page_manager_observer.js">
<include src="../uber/uber_utils.js">
<include src="options.js">
diff --git a/chromium/chrome/browser/resources/options/options_page.css b/chromium/chrome/browser/resources/options/options_page.css
index a35f46013c6..d0ccfa28c76 100644
--- a/chromium/chrome/browser/resources/options/options_page.css
+++ b/chromium/chrome/browser/resources/options/options_page.css
@@ -191,9 +191,8 @@ list:not([disabled]) > :hover {
background-color: rgb(228, 236, 247);
}
-/* TODO(stuartmorgan): Once this becomes the list style for other WebUI pages
- * these rules can be simplified (since they wont need to override other rules).
- */
+/* Note: If this becomes the list style for other WebUI pages these rules can be
+ * simplified (since they wont need to override other rules). */
list:not([has-element-focus]) > [selected],
list:not([has-element-focus]) > [lead][selected] {
@@ -258,7 +257,6 @@ list .deletable-item > :first-child {
list .row-delete-button {
-webkit-transition: 150ms opacity;
background-color: transparent;
- /* TODO(stuartmorgan): Replace with real images once they are available. */
background-image: -webkit-image-set(
url(../../../../ui/resources/default_100_percent/close_2.png) 1x,
url(../../../../ui/resources/default_200_percent/close_2.png) 2x);
@@ -331,7 +329,6 @@ list > [editing] [displaymode='static'] {
}
list > [editing] input:invalid {
- /* TODO(stuartmorgan): Replace with validity badge */
background-color: pink;
}
@@ -449,7 +446,7 @@ html:not([enablePepperFlashSettings]) .pepper-flash-settings {
padding: 0;
}
-:-webkit-any(.checkbox, .radio) label + a {
+:-webkit-any(.checkbox, .radio) label ~ a {
display: inline-block;
/* Matches padding of -webkit-any(.checkbox, .radio) */
padding-bottom: 7px;
diff --git a/chromium/chrome/browser/resources/options/options_settings_app.js b/chromium/chrome/browser/resources/options/options_settings_app.js
index 9704dff5936..72d2928e4a6 100644
--- a/chromium/chrome/browser/resources/options/options_settings_app.js
+++ b/chromium/chrome/browser/resources/options/options_settings_app.js
@@ -47,5 +47,6 @@
$('profiles-list').canDeleteItems = false;
});
- loadTimeData.overrideValues(loadTimeData.getValue('settingsApp'));
+ loadTimeData.overrideValues(/** @type {!Object} */(
+ loadTimeData.getValue('settingsApp')));
}());
diff --git a/chromium/chrome/browser/resources/options/password_manager.html b/chromium/chrome/browser/resources/options/password_manager.html
index 888fb5cf2ec..77ded2c088f 100644
--- a/chromium/chrome/browser/resources/options/password_manager.html
+++ b/chromium/chrome/browser/resources/options/password_manager.html
@@ -37,7 +37,7 @@
</div>
</div>
<div class="action-area">
- <span id="manage-passwords-span" hidden>
+ <span id="manage-passwords-span">
<span i18n-content="passwordsManagePasswordsBeforeLinkText"></span>
<a id="manage-passwords-link" target="_blank"
i18n-content="passwordsManagePasswordsLinkText"
diff --git a/chromium/chrome/browser/resources/options/password_manager.js b/chromium/chrome/browser/resources/options/password_manager.js
index 6e16ebac5e1..3e501727ff7 100644
--- a/chromium/chrome/browser/resources/options/password_manager.js
+++ b/chromium/chrome/browser/resources/options/password_manager.js
@@ -175,12 +175,14 @@ cr.define('options', function() {
// The number of saved passwords shouldn't be too big for us to handle.
var query = this.lastQuery_;
var filter = function(entry, index, list) {
- // Search both URL and username.
- if (entry[0].toLowerCase().indexOf(query.toLowerCase()) >= 0 ||
- entry[1].toLowerCase().indexOf(query.toLowerCase()) >= 0) {
+ // Search both shown URL and username.
+ var shownUrl = entry[options.passwordManager.SHOWN_URL_FIELD];
+ var username = entry[options.passwordManager.USERNAME_FIELD];
+ if (shownUrl.toLowerCase().indexOf(query.toLowerCase()) >= 0 ||
+ username.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
// Keep the original index so we can delete correctly. See also
// deleteItemAtIndex() in password_manager_list.js that uses this.
- entry[4] = index;
+ entry[options.passwordManager.ORIGINAL_INDEX_FIELD] = index;
return true;
}
return false;
@@ -214,7 +216,8 @@ cr.define('options', function() {
// index in the model, but each entry stores its original index, so
// we can find the item using a linear search.
for (var i = 0; i < model.length; ++i) {
- if (model.item(i)[4] == index) {
+ if (model.item(i)[options.passwordManager.ORIGINAL_INDEX_FIELD] ==
+ index) {
index = i;
break;
}
@@ -225,14 +228,6 @@ cr.define('options', function() {
var item = this.savedPasswordsList_.getListItemByIndex(index);
item.showPassword(password);
},
-
- /**
- * @param {boolean} visible Whether the link should be visible.
- * @private
- */
- setManageAccountLinkVisibility_: function(visible) {
- $('manage-passwords-span').hidden = !visible;
- },
};
/**
@@ -259,7 +254,6 @@ cr.define('options', function() {
// Forward public APIs to private implementations on the singleton instance.
cr.makePublic(PasswordManager, [
- 'setManageAccountLinkVisibility',
'setSavedPasswordsList',
'setPasswordExceptionsList',
'showPassword'
diff --git a/chromium/chrome/browser/resources/options/password_manager_list.css b/chromium/chrome/browser/resources/options/password_manager_list.css
index ee17a12d31e..d3ac26af07a 100644
--- a/chromium/chrome/browser/resources/options/password_manager_list.css
+++ b/chromium/chrome/browser/resources/options/password_manager_list.css
@@ -22,7 +22,7 @@ html[dir='rtl'] #saved-passwords-list .list-inline-button {
left: 2px;
}
-input[type='password'].inactive-password {
+input.inactive-item {
background: transparent;
border: none;
}
@@ -32,11 +32,21 @@ input[type='password'].inactive-password {
width: 40%;
}
+#saved-passwords-list .deletable-item:not(:hover) a:not(:focus) {
+ color: black;
+ text-decoration: none;
+}
+
#saved-passwords-list .name {
-webkit-box-flex: 1;
width: 30%;
}
+#saved-passwords-list .url,
+#saved-passwords-list .name {
+ -webkit-user-select: text;
+}
+
#saved-passwords-list .password,
#saved-passwords-list .federation {
-webkit-box-flex: 1;
@@ -61,3 +71,22 @@ input[type='password'].inactive-password {
overflow: hidden;
text-overflow: ellipsis;
}
+
+/* To elide URLs from the left, sets unicode-bidi=bidi-override and
+ * direction=rtl. */
+.left-elided-url {
+ direction: rtl;
+ unicode-bidi: bidi-override;
+}
+
+/* RTL direction in left-elided-url changes text-align to right, but URLs for
+ * left-to-right locales should still be left aligned.
+ * Since the direction is changed to RTL, the icon is at the end (i.e. left),
+ * but not at the start. So, swaps start and end margin/padding. */
+html[dir='ltr'] .left-elided-url {
+ -webkit-margin-end: 7px;
+ -webkit-margin-start: 0;
+ -webkit-padding-end: 26px;
+ -webkit-padding-start: 3px;
+ text-align: left;
+} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/options/password_manager_list.js b/chromium/chrome/browser/resources/options/password_manager_list.js
index f8ed9e8a5fd..58bd5efce0d 100644
--- a/chromium/chrome/browser/resources/options/password_manager_list.js
+++ b/chromium/chrome/browser/resources/options/password_manager_list.js
@@ -8,19 +8,23 @@ cr.define('options.passwordManager', function() {
/** @const */ var DeletableItem = options.DeletableItem;
/** @const */ var List = cr.ui.List;
- /** @const */ var URL_DATA_INDEX = 0;
- /** @const */ var USERNAME_DATA_INDEX = 1;
- /** @const */ var PASSWORD_DATA_INDEX = 2;
- /** @const */ var FEDERATION_DATA_INDEX = 3;
- /** @const */ var ORIGINAL_DATA_INDEX = 4;
+ // The following constants should be synchronized with the constants in
+ // chrome/browser/ui/webui/options/password_manager_handler.cc.
+ /** @const */ var ORIGIN_FIELD = 'origin';
+ /** @const */ var SHOWN_URL_FIELD = 'shownUrl';
+ /** @const */ var IS_ANDROID_URI_FIELD = 'isAndroidUri';
+ /** @const */ var IS_SECURE_FIELD = 'isSecure';
+ /** @const */ var USERNAME_FIELD = 'username';
+ /** @const */ var PASSWORD_FIELD = 'password';
+ /** @const */ var FEDERATION_FIELD = 'federation';
+ /** @const */ var ORIGINAL_INDEX_FIELD = 'index';
/**
* Creates a new passwords list item.
* @param {cr.ui.ArrayDataModel} dataModel The data model that contains this
* item.
- * @param {Array} entry An array of the form [url, username, password,
- * federation]. When the list has been filtered, a fifth element [index]
- * may be present.
+ * @param {Object} entry A dictionary of data on new list item. When the
+ * list has been filtered, one more element [index] may be present.
* @param {boolean} showPasswords If true, add a button to the element to
* allow the user to reveal the saved password.
* @constructor
@@ -37,6 +41,56 @@ cr.define('options.passwordManager', function() {
return el;
}
+ /**
+ * Returns title for password's origin. If the origin is Android URI, returns
+ * the origin as it is. Removes the scheme if the url is insecure and removes
+ * trailing punctuation symbols.
+ * @param {Object} item A dictionary of data on the list item.
+ * @return {string} The title for password's origin.
+ */
+ function getTitleForPasswordOrigin(item) {
+ var title = item.url;
+ if (item.isAndroidUri)
+ return title;
+ if (!item.isSecure) {
+ var ind = title.indexOf('://');
+ if (ind >= 0) {
+ title = title.substring(ind + 3);
+ }
+ }
+ // Since the direction is switched to RTL, punctuation symbols appear on the
+ // left side, that is wrong. So, just remove trailing punctuation symbols.
+ title = title.replace(/[^A-Za-z0-9]+$/, '');
+ return title;
+ }
+
+ /**
+ * Helper function that creates an HTML element for displaying the origin of
+ * saved password.
+ * @param {Object} item A dictionary of data on the list item.
+ * @param {Element} urlDiv div-element that will enclose the created
+ * element.
+ * @return {Element} The element for displaying password origin.
+ */
+ function createUrlLink(item, urlDiv) {
+ var urlLink;
+ if (!item.isAndroidUri) {
+ urlLink = item.ownerDocument.createElement('a');
+ urlLink.href = item.url;
+ urlLink.setAttribute('target', '_blank');
+ urlLink.textContent = item.shownUrl.split('').reverse().join('');
+
+ urlDiv.classList.add('left-elided-url');
+ } else {
+ urlLink = item.ownerDocument.createElement('span');
+ urlLink.textContent = item.shownUrl;
+ }
+ urlLink.addEventListener('focus', function() {
+ item.handleFocus();
+ }.bind(item));
+ return urlLink;
+ }
+
PasswordListItem.prototype = {
__proto__: DeletableItem.prototype,
@@ -45,34 +99,39 @@ cr.define('options.passwordManager', function() {
DeletableItem.prototype.decorate.call(this);
// The URL of the site.
- var urlLabel = this.ownerDocument.createElement('div');
- urlLabel.classList.add('favicon-cell');
- urlLabel.classList.add('weakrtl');
- urlLabel.classList.add('url');
- urlLabel.setAttribute('title', this.url);
- urlLabel.textContent = this.url;
-
- // The favicon URL is prefixed with "origin/", which essentially removes
- // the URL path past the top-level domain and ensures that a scheme (e.g.,
- // http) is being used. This ensures that the favicon returned is the
- // default favicon for the domain and that the URL has a scheme if none
- // is present in the password manager.
- urlLabel.style.backgroundImage = getFaviconImageSet(
+ var urlDiv = this.ownerDocument.createElement('div');
+ urlDiv.className = 'favicon-cell url';
+ urlDiv.setAttribute('title', getTitleForPasswordOrigin(this));
+ urlDiv.style.backgroundImage = getFaviconImageSet(
'origin/' + this.url, 16);
- this.contentElement.appendChild(urlLabel);
+
+ this.urlLink = createUrlLink(this, urlDiv);
+ urlDiv.appendChild(this.urlLink);
+
+ this.contentElement.appendChild(urlDiv);
// The stored username.
- var usernameLabel = this.ownerDocument.createElement('div');
- usernameLabel.className = 'name';
- usernameLabel.textContent = this.username;
- usernameLabel.title = this.username;
- this.contentElement.appendChild(usernameLabel);
+ var usernameDiv = this.ownerDocument.createElement('div');
+ usernameDiv.className = 'name';
+ usernameDiv.title = this.username;
+ this.contentElement.appendChild(usernameDiv);
+ var usernameInput = this.ownerDocument.createElement('input');
+ usernameInput.type = 'text';
+ usernameInput.className = 'inactive-item';
+ usernameInput.readOnly = true;
+ usernameInput.value = this.username;
+ usernameInput.addEventListener('focus', function() {
+ this.handleFocus();
+ }.bind(this));
+ usernameDiv.appendChild(usernameInput);
+ this.usernameField = usernameInput;
if (this.federation) {
// The federation.
var federationDiv = this.ownerDocument.createElement('div');
federationDiv.className = 'federation';
federationDiv.textContent = this.federation;
+ federationDiv.title = this.federation;
this.contentElement.appendChild(federationDiv);
} else {
// The stored password.
@@ -82,16 +141,14 @@ cr.define('options.passwordManager', function() {
// The password input field.
var passwordInput = this.ownerDocument.createElement('input');
passwordInput.type = 'password';
- passwordInput.className = 'inactive-password';
+ passwordInput.className = 'inactive-item';
passwordInput.readOnly = true;
passwordInput.value = this.showPasswords_ ? this.password : '********';
passwordInputDiv.appendChild(passwordInput);
- var deletableItem = this;
passwordInput.addEventListener('focus', function() {
- deletableItem.handleFocus();
- });
+ this.handleFocus();
+ }.bind(this));
this.passwordField = passwordInput;
- this.setFocusable_(false);
// The show/hide button.
if (this.showPasswords_) {
@@ -107,33 +164,39 @@ cr.define('options.passwordManager', function() {
event.stopPropagation();
}, false);
button.addEventListener('focus', function() {
- deletableItem.handleFocus();
- });
+ this.handleFocus();
+ }.bind(this));
passwordInputDiv.appendChild(button);
this.passwordShowButton = button;
}
this.contentElement.appendChild(passwordInputDiv);
}
-
+ this.setFocusable_(false);
},
/** @override */
selectionChanged: function() {
- var input = this.passwordField;
+ var usernameInput = this.usernameField;
+ var passwordInput = this.passwordField;
var button = this.passwordShowButton;
- // The button doesn't exist when passwords can't be shown.
- if (!button)
- return;
+
+ this.setFocusable_(this.selected);
if (this.selected) {
- input.classList.remove('inactive-password');
- this.setFocusable_(true);
- button.hidden = false;
- input.focus();
+ usernameInput.classList.remove('inactive-item');
+ if (button) {
+ passwordInput.classList.remove('inactive-item');
+ button.hidden = false;
+ passwordInput.focus();
+ } else {
+ usernameInput.focus();
+ }
} else {
- input.classList.add('inactive-password');
- this.setFocusable_(false);
- button.hidden = true;
+ usernameInput.classList.add('inactive-item');
+ if (button) {
+ passwordInput.classList.add('inactive-item');
+ button.hidden = true;
+ }
}
},
@@ -144,7 +207,11 @@ cr.define('options.passwordManager', function() {
*/
setFocusable_: function(focusable) {
var tabIndex = focusable ? 0 : -1;
- this.passwordField.tabIndex = this.closeButtonElement.tabIndex = tabIndex;
+ this.urlLink.tabIndex = tabIndex;
+ this.usernameField.tabIndex = tabIndex;
+ this.closeButtonElement.tabIndex = tabIndex;
+ if (this.passwordShowButton)
+ this.passwordField.tabIndex = tabIndex;
},
/**
@@ -176,7 +243,7 @@ cr.define('options.passwordManager', function() {
* @private
*/
getOriginalIndex_: function() {
- var index = this.dataItem[ORIGINAL_DATA_INDEX];
+ var index = this.dataItem[ORIGINAL_INDEX_FIELD];
return index ? index : this.dataModel.indexOf(this.dataItem);
},
@@ -199,10 +266,43 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get url() {
- return this.dataItem[URL_DATA_INDEX];
+ return this.dataItem[ORIGIN_FIELD];
},
set url(url) {
- this.dataItem[URL_DATA_INDEX] = url;
+ this.dataItem[ORIGIN_FIELD] = url;
+ },
+
+ /**
+ * Get and set the shown url for the entry.
+ * @type {string}
+ */
+ get shownUrl() {
+ return this.dataItem[SHOWN_URL_FIELD];
+ },
+ set shownUrl(shownUrl) {
+ this.dataItem[SHOWN_URL_FIELD] = shownUrl;
+ },
+
+ /**
+ * Get and set whether the origin is Android URI.
+ * @type {boolean}
+ */
+ get isAndroidUri() {
+ return this.dataItem[IS_ANDROID_URI_FIELD];
+ },
+ set isAndroidUri(isAndroidUri) {
+ this.dataItem[IS_ANDROID_URI_FIELD] = isAndroidUri;
+ },
+
+ /**
+ * Get and set whether the origin uses secure scheme.
+ * @type {boolean}
+ */
+ get isSecure() {
+ return this.dataItem[IS_SECURE_FIELD];
+ },
+ set isSecure(isSecure) {
+ this.dataItem[IS_SECURE_FIELD] = isSecure;
},
/**
@@ -210,10 +310,10 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get username() {
- return this.dataItem[USERNAME_DATA_INDEX];
+ return this.dataItem[USERNAME_FIELD];
},
set username(username) {
- this.dataItem[USERNAME_DATA_INDEX] = username;
+ this.dataItem[USERNAME_FIELD] = username;
},
/**
@@ -221,10 +321,10 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get password() {
- return this.dataItem[PASSWORD_DATA_INDEX];
+ return this.dataItem[PASSWORD_FIELD];
},
set password(password) {
- this.dataItem[PASSWORD_DATA_INDEX] = password;
+ this.dataItem[PASSWORD_FIELD] = password;
},
/**
@@ -232,16 +332,16 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get federation() {
- return this.dataItem[FEDERATION_DATA_INDEX];
+ return this.dataItem[FEDERATION_FIELD];
},
set federation(federation) {
- this.dataItem[FEDERATION_DATA_INDEX] = federation;
+ this.dataItem[FEDERATION_FIELD] = federation;
},
};
/**
* Creates a new PasswordExceptions list item.
- * @param {Array} entry A pair of the form [url, username].
+ * @param {Object} entry A dictionary of data on new list item.
* @constructor
* @extends {options.DeletableItem}
*/
@@ -264,20 +364,37 @@ cr.define('options.passwordManager', function() {
DeletableItem.prototype.decorate.call(this);
// The URL of the site.
- var urlLabel = this.ownerDocument.createElement('div');
- urlLabel.className = 'url';
- urlLabel.classList.add('favicon-cell');
- urlLabel.classList.add('weakrtl');
- urlLabel.textContent = this.url;
-
- // The favicon URL is prefixed with "origin/", which essentially removes
- // the URL path past the top-level domain and ensures that a scheme (e.g.,
- // http) is being used. This ensures that the favicon returned is the
- // default favicon for the domain and that the URL has a scheme if none
- // is present in the password manager.
- urlLabel.style.backgroundImage = getFaviconImageSet(
- 'origin/' + this.url, 16);
- this.contentElement.appendChild(urlLabel);
+ var urlDiv = this.ownerDocument.createElement('div');
+ urlDiv.className = 'favicon-cell url';
+ urlDiv.setAttribute('title', getTitleForPasswordOrigin(this));
+ urlDiv.style.backgroundImage = getFaviconImageSet(
+ 'origin/' + this.url, 16);
+
+ this.urlLink = createUrlLink(this, urlDiv);
+ urlDiv.appendChild(this.urlLink);
+
+ this.contentElement.appendChild(urlDiv);
+ },
+
+ /** @override */
+ selectionChanged: function() {
+ if (this.selected) {
+ this.setFocusable_(true);
+ this.urlLink.focus();
+ } else {
+ this.setFocusable_(false);
+ }
+ },
+
+ /**
+ * Set the focusability of this row.
+ * @param {boolean} focusable
+ * @private
+ */
+ setFocusable_: function(focusable) {
+ var tabIndex = focusable ? 0 : -1;
+ this.urlLink.tabIndex = tabIndex;
+ this.closeButtonElement.tabIndex = tabIndex;
},
/**
@@ -285,10 +402,43 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get url() {
- return this.dataItem;
+ return this.dataItem[ORIGIN_FIELD];
},
set url(url) {
- this.dataItem = url;
+ this.dataItem[ORIGIN_FIELD] = url;
+ },
+
+ /**
+ * Get and set the shown url for the entry.
+ * @type {string}
+ */
+ get shownUrl() {
+ return this.dataItem[SHOWN_URL_FIELD];
+ },
+ set shownUrl(shownUrl) {
+ this.dataItem[SHOWN_URL_FIELD] = shownUrl;
+ },
+
+ /**
+ * Get and set whether the origin is Android URI.
+ * @type {boolean}
+ */
+ get isAndroidUri() {
+ return this.dataItem[IS_ANDROID_URI_FIELD];
+ },
+ set isAndroidUri(isAndroidUri) {
+ this.dataItem[IS_ANDROID_URI_FIELD] = isAndroidUri;
+ },
+
+ /**
+ * Get and set whether the origin uses secure scheme.
+ * @type {boolean}
+ */
+ get isSecure() {
+ return this.dataItem[IS_SECURE_FIELD];
+ },
+ set isSecure(isSecure) {
+ this.dataItem[IS_SECURE_FIELD] = isSecure;
},
};
@@ -344,9 +494,9 @@ cr.define('options.passwordManager', function() {
/** @override */
deleteItemAtIndex: function(index) {
var item = this.dataModel.item(index);
- if (item && item[ORIGINAL_DATA_INDEX] != undefined) {
+ if (item && item[ORIGINAL_INDEX_FIELD] != undefined) {
// The fifth element, if present, is the original index to delete.
- index = item[ORIGINAL_DATA_INDEX];
+ index = item[ORIGINAL_INDEX_FIELD];
}
PasswordManager.removeSavedPassword(index);
},
@@ -406,5 +556,12 @@ cr.define('options.passwordManager', function() {
PasswordExceptionsListItem: PasswordExceptionsListItem,
PasswordsList: PasswordsList,
PasswordExceptionsList: PasswordExceptionsList,
+ ORIGIN_FIELD: ORIGIN_FIELD,
+ SHOWN_URL_FIELD: SHOWN_URL_FIELD,
+ IS_SECURE_FIELD: IS_SECURE_FIELD,
+ USERNAME_FIELD: USERNAME_FIELD,
+ PASSWORD_FIELD: PASSWORD_FIELD,
+ FEDERATION_FIELD: FEDERATION_FIELD,
+ ORIGINAL_INDEX_FIELD: ORIGINAL_INDEX_FIELD
};
});
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.html b/chromium/chrome/browser/resources/options/reset_profile_settings_banner.html
deleted file mode 100644
index fd95c3c7ec9..00000000000
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<div id="reset-profile-settings-banner" class="settings-banner" hidden>
- <div id="reset-profile-settings-banner-close" class="close-button"></div>
- <div class="content-area">
- <div class="badge"></div>
- <div class="text">
- <p>
- <span i18n-values=".innerHTML:resetProfileSettingsBannerText">
- </span>
- <a class="nowrap" i18n-values="href:resetProfileSettingsLearnMoreUrl"
- i18n-content="learnMore" target="_blank"></a>
- </p>
- </div>
- <div class="button-area">
- <button id="reset-profile-settings-banner-activate"
- i18n-content="resetProfileSettings"></button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.js b/chromium/chrome/browser/resources/options/reset_profile_settings_banner.js
deleted file mode 100644
index 4785113d17f..00000000000
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Note: the native-side handler for this is ResetProfileSettingsHandler.
-
-cr.define('options', function() {
- /** @const */ var PageManager = cr.ui.pageManager.PageManager;
- /** @const */ var SettingsBannerBase = options.SettingsBannerBase;
-
- /**
- * ResetProfileSettingsBanner class
- * Provides encapsulated handling of the Reset Profile Settings banner.
- * @constructor
- * @extends {options.SettingsBannerBase}
- */
- function ResetProfileSettingsBanner() {}
-
- cr.addSingletonGetter(ResetProfileSettingsBanner);
-
- ResetProfileSettingsBanner.prototype = {
- __proto__: SettingsBannerBase.prototype,
-
- /**
- * Initializes the banner's event handlers.
- * @suppress {checkTypes}
- * TODO(vitalyp): remove the suppression. See the explanation in
- * chrome/browser/resources/options/automatic_settings_reset_banner.js.
- */
- initialize: function() {
- this.showMetricName = 'AutomaticReset_WebUIBanner_BannerShown';
-
- this.dismissNativeCallbackName =
- 'onDismissedResetProfileSettingsBanner';
-
- this.visibilityDomElement = $('reset-profile-settings-banner');
-
- $('reset-profile-settings-banner-close').onclick = function(event) {
- chrome.send('metricsHandler:recordAction',
- ['AutomaticReset_WebUIBanner_ManuallyClosed']);
- ResetProfileSettingsBanner.dismiss();
- };
- $('reset-profile-settings-banner-activate').onclick = function(event) {
- chrome.send('metricsHandler:recordAction',
- ['AutomaticReset_WebUIBanner_ResetClicked']);
- PageManager.showPageByName('resetProfileSettings');
- };
- },
- };
-
- // Forward public APIs to protected implementations.
- [
- 'show',
- 'dismiss',
- ].forEach(function(name) {
- ResetProfileSettingsBanner[name] = function() {
- var instance = ResetProfileSettingsBanner.getInstance();
- return instance[name].apply(instance, arguments);
- };
- });
-
- // Export
- return {
- ResetProfileSettingsBanner: ResetProfileSettingsBanner
- };
-});
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html b/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html
index b92c9fd74ee..504661f7bf5 100644
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html
+++ b/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html
@@ -1,8 +1,10 @@
<div id="reset-profile-settings-overlay" class="page not-resizable" hidden>
<div class="close-button"></div>
- <h1 i18n-content="resetProfileSettingsOverlay"></h1>
+ <!-- Text populated dynamically from didShowPage. -->
+ <h1 id="reset-profile-settings-title"></h1>
<div id="reset-profile-settings-content-area" class="content-area">
- <span i18n-content="resetProfileSettingsExplanation"></span>
+ <!-- Text populated dynamically from didShowPage. -->
+ <span id="reset-profile-settings-explanation"></span>
</div>
<div class="action-area">
<div class="hbox stretch">
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js b/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js
index 1152b70d1ab..7da9e296424 100644
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js
+++ b/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js
@@ -6,12 +6,12 @@ cr.define('options', function() {
var Page = cr.ui.pageManager.Page;
var AutomaticSettingsResetBanner = options.AutomaticSettingsResetBanner;
- var ResetProfileSettingsBanner = options.ResetProfileSettingsBanner;
/**
* ResetProfileSettingsOverlay class
* Encapsulated handling of the 'Reset Profile Settings' overlay page.
- * @class
+ * @constructor
+ * @extends {cr.ui.pageManager.Page}
*/
function ResetProfileSettingsOverlay() {
Page.call(this, 'resetProfileSettings',
@@ -51,7 +51,11 @@ cr.define('options', function() {
* chrome/browser/resources/options/automatic_settings_reset_banner.js.
*/
didShowPage: function() {
- ResetProfileSettingsBanner.dismiss();
+ $('reset-profile-settings-title').textContent =
+ loadTimeData.getString('resetProfileSettingsOverlay');
+ $('reset-profile-settings-explanation').textContent =
+ loadTimeData.getString('resetProfileSettingsExplanation');
+
chrome.send('onShowResetProfileDialog');
},
diff --git a/chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js b/chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js
index b2c6c1169d0..024e62f8d09 100644
--- a/chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js
+++ b/chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js
@@ -303,8 +303,6 @@ cr.define('options.search_engines', function() {
*/
validationComplete: function(validity) {
this.waitingForValidation_ = false;
- // TODO(stuartmorgan): Implement the full validation UI with
- // checkmark/exclamation mark icons and tooltips showing the errors.
if (validity.name) {
this.nameField_.setCustomValidity('');
} else {
diff --git a/chromium/chrome/browser/resources/options/search_page.css b/chromium/chrome/browser/resources/options/search_page.css
index b634928989a..47548c627d8 100644
--- a/chromium/chrome/browser/resources/options/search_page.css
+++ b/chromium/chrome/browser/resources/options/search_page.css
@@ -13,8 +13,6 @@
/* Container for the elements that make up the search bubble. */
.search-bubble {
left: 0;
- margin-top: 5px;
- pointer-events: none;
position: absolute;
top: -1000px; /* Minor hack: position off-screen by default. */
/* Create a z-context for search-bubble-innards, its after and before. */
@@ -63,6 +61,14 @@
z-index: -1;
}
+/* Turns the arrow direction downwards, when the bubble is placed above the
+ * anchor element */
+.search-bubble-innards.above::after {
+ -webkit-transform: rotate(-135deg);
+ bottom: -7px;
+ top: auto;
+}
+
.search-bubble-wrapper {
position: relative;
}
diff --git a/chromium/chrome/browser/resources/options/search_page.js b/chromium/chrome/browser/resources/options/search_page.js
index 971546dd56d..6cd5ff85dd2 100644
--- a/chromium/chrome/browser/resources/options/search_page.js
+++ b/chromium/chrome/browser/resources/options/search_page.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -45,6 +45,11 @@ cr.define('options', function() {
// making sure the bubbles stay in the correct location as sections
// may dynamically change size at any time.
this.intervalId = setInterval(this.updatePosition.bind(this), 250);
+
+ this.addEventListener('mouseover', function() {
+ this.innards_.classList.toggle('above');
+ this.updatePosition();
+ });
},
/**
@@ -103,7 +108,13 @@ cr.define('options', function() {
// Position the bubble below the location of the owner.
var left = owner.offsetLeft + owner.offsetWidth / 2 -
this.offsetWidth / 2;
- var top = owner.offsetTop + owner.offsetHeight;
+
+ var BUBBLE_EDGE_OFFSET = 5;
+ var top = owner.offsetTop;
+ if (this.innards_.classList.contains('above'))
+ top -= this.offsetHeight + BUBBLE_EDGE_OFFSET;
+ else
+ top += owner.offsetHeight + BUBBLE_EDGE_OFFSET;
// Update the position in the CSS. Cache the last values for
// best performance.
@@ -136,6 +147,20 @@ cr.define('options', function() {
__proto__: Page.prototype,
/**
+ * Wait a bit to see if the user is still entering search text.
+ * @type {number|undefined}
+ * @private
+ */
+ delayedSearchMetric_: undefined,
+
+ /**
+ * Only send the time of first search once.
+ * @type {boolean}
+ * @private
+ */
+ hasSentFirstSearchTime_: false,
+
+ /**
* A boolean to prevent recursion. Used by setSearchText_().
* @type {boolean}
* @private
@@ -146,6 +171,9 @@ cr.define('options', function() {
initializePage: function() {
Page.prototype.initializePage.call(this);
+ // Record the start time for use in reporting metrics.
+ this.createdTimestamp_ = Date.now();
+
this.searchField = $('search-field');
// Handle search events. (No need to throttle, WebKit's search field
@@ -292,6 +320,12 @@ cr.define('options', function() {
return;
}
+ if (!this.hasSentFirstSearchTime_) {
+ this.hasSentFirstSearchTime_ = true;
+ chrome.metricsPrivate.recordMediumTime('Settings.TimeToFirstSearch',
+ Date.now() - this.createdTimestamp_);
+ }
+
// Toggle the search page if necessary. Otherwise, update the hash.
var hash = '#' + encodeURIComponent(text);
if (this.searchActive_) {
@@ -317,6 +351,8 @@ cr.define('options', function() {
}
var bubbleControls = [];
+ var pageMatchesForMetrics = 0;
+ var subpageMatchesForMetrics = 0;
// Generate search text by applying lowercase and escaping any characters
// that would be problematic for regular expressions.
@@ -334,8 +370,10 @@ cr.define('options', function() {
for (var i = 0, node; node = elements[i]; i++) {
if (this.highlightMatches_(regExp, node)) {
node.classList.remove('search-hidden');
- if (!node.hidden)
+ if (!node.hidden) {
foundMatches = true;
+ pageMatchesForMetrics += 1;
+ }
}
}
}
@@ -353,6 +391,7 @@ cr.define('options', function() {
bubbleControls.concat(this.getAssociatedControls_(page));
foundMatches = true;
+ subpageMatchesForMetrics += 1;
}
}
}
@@ -361,10 +400,26 @@ cr.define('options', function() {
$('searchPageNoMatches').hidden = foundMatches;
// Create search balloons for sub-page results.
- var length = bubbleControls.length;
- for (var i = 0; i < length; i++)
+ var bubbleCount = bubbleControls.length;
+ for (var i = 0; i < bubbleCount; i++)
this.createSearchBubble_(bubbleControls[i], text);
+ // If the search doesn't change for one second, send some metrics.
+ clearTimeout(this.delayedSearchMetric_);
+ this.delayedSearchMetric_ = setTimeout(function() {
+ if (!foundMatches) {
+ chrome.metricsPrivate.recordSmallCount(
+ 'Settings.SearchLengthNoMatch', text.length);
+ }
+ chrome.metricsPrivate.recordUserAction('Settings.Searching');
+ chrome.metricsPrivate.recordSmallCount(
+ 'Settings.SearchLength', text.length);
+ chrome.metricsPrivate.recordSmallCount(
+ 'Settings.SearchPageMatchCount', pageMatchesForMetrics);
+ chrome.metricsPrivate.recordSmallCount(
+ 'Settings.SearchSubpageMatchCount', subpageMatchesForMetrics);
+ }, 1000);
+
// Cleanup the recursion-prevention variable.
this.insideSetSearchText_ = false;
},
diff --git a/chromium/chrome/browser/resources/options/settings_banner.js b/chromium/chrome/browser/resources/options/settings_banner.js
deleted file mode 100644
index 666aaf2aa50..00000000000
--- a/chromium/chrome/browser/resources/options/settings_banner.js
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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('options', function() {
-
- /**
- * Base class for banners that appear at the top of the settings page.
- * @constructor
- */
- function SettingsBannerBase() {}
-
- cr.addSingletonGetter(SettingsBannerBase);
-
- SettingsBannerBase.prototype = {
- /**
- * Whether or not the banner has already been dismissed.
- *
- * This is needed because of the surprising ordering of asynchronous
- * JS<->native calls when the settings page is opened with specifying a
- * given sub-page, e.g. chrome://settings/AutomaticSettingsReset.
- *
- * In such a case, AutomaticSettingsResetOverlay's didShowPage(), which
- * calls our dismiss() method, would be called before the native Handlers'
- * InitalizePage() methods have an effect in the JS, which includes calling
- * our show() method. This would mean that the banner would be first
- * dismissed, then shown. We want to prevent this.
- *
- * @type {boolean}
- * @private
- */
- hadBeenDismissed_: false,
-
- /**
- * Metric name to send when a show event occurs.
- * @protected
- */
- showMetricName: '',
-
- /**
- * Name of the native callback invoked when the banner is dismised.
- * @protected
- */
- dismissNativeCallbackName: '',
-
- /**
- * DOM element whose visibility is set when setVisibility_ is called.
- * @protected
- */
- visibilityDomElement: null,
-
- /**
- * Called by the native code to show the banner if needed.
- * @protected
- */
- show: function() {
- if (!this.hadBeenDismissed_) {
- chrome.send('metricsHandler:recordAction', [this.showMetricName]);
- this.setVisibility_(true);
- }
- },
-
- /**
- * Called when the banner should be closed as a result of something taking
- * place on the WebUI page, i.e. when its close button is pressed, or when
- * the confirmation dialog for the profile settings reset feature is opened.
- * @protected
- */
- dismiss: function() {
- chrome.send(this.dismissNativeCallbackName);
- this.hadBeenDismissed_ = true;
- this.setVisibility_(false);
- },
-
- /**
- * Sets whether or not the reset profile settings banner shall be visible.
- * @param {boolean} show Whether or not to show the banner.
- * @private
- */
- setVisibility_: function(show) {
- this.visibilityDomElement.hidden = !show;
- },
- };
-
- // Export
- return {
- SettingsBannerBase: SettingsBannerBase
- };
-});
diff --git a/chromium/chrome/browser/resources/options/supervised_user_import.js b/chromium/chrome/browser/resources/options/supervised_user_import.js
index 6b9a75715d8..d3591c7d578 100644
--- a/chromium/chrome/browser/resources/options/supervised_user_import.js
+++ b/chromium/chrome/browser/resources/options/supervised_user_import.js
@@ -41,7 +41,8 @@ cr.define('options', function() {
var avatarGrid = $('select-avatar-grid');
options.ProfilesIconGrid.decorate(avatarGrid);
var avatarIcons = loadTimeData.getValue('avatarIcons');
- avatarGrid.dataModel = new ArrayDataModel(avatarIcons);
+ avatarGrid.dataModel = new ArrayDataModel(
+ /** @type {!Array} */(avatarIcons));
supervisedUserList.addEventListener('change', function(event) {
var supervisedUser = supervisedUserList.selectedItem;
@@ -77,7 +78,8 @@ cr.define('options', function() {
$('import-existing-supervised-user-link').hidden = false;
options.SupervisedUserListData.requestExistingSupervisedUsers().then(
- this.receiveExistingSupervisedUsers_, this.onSigninError_.bind(this));
+ this.receiveExistingSupervisedUsers_.bind(this),
+ this.onSigninError_.bind(this));
options.SupervisedUserListData.addObserver(this);
this.updateImportInProgress_(false);
diff --git a/chromium/chrome/browser/resources/options/sync_setup_overlay.css b/chromium/chrome/browser/resources/options/sync_setup_overlay.css
index c04dc00cc04..0b79504943d 100644
--- a/chromium/chrome/browser/resources/options/sync_setup_overlay.css
+++ b/chromium/chrome/browser/resources/options/sync_setup_overlay.css
@@ -42,10 +42,6 @@
padding: 10px;
}
-#sync-select-container {
- margin-bottom: 10px;
-}
-
#sync-instructions-container {
line-height: 1.8em;
margin-bottom: 30px;
@@ -53,7 +49,7 @@
#choose-data-types-body {
-webkit-column-count: 3;
- margin: 10px 0;
+ margin: 10px 0 0 0;
}
#choose-data-types-body > .checkbox:first-child {
diff --git a/chromium/chrome/browser/resources/options/sync_setup_overlay.html b/chromium/chrome/browser/resources/options/sync_setup_overlay.html
index eee31994829..8924552134f 100644
--- a/chromium/chrome/browser/resources/options/sync_setup_overlay.html
+++ b/chromium/chrome/browser/resources/options/sync_setup_overlay.html
@@ -106,6 +106,14 @@
</div>
</div>
</div>
+ <div id="payments-integration-setting-area" class="checkbox">
+ <label>
+ <input id="payments-integration-checkbox" type="checkbox">
+ <span i18n-content="enablePaymentsIntegration"></span>
+ </label>
+ <a i18n-values="href:autofillHelpURL" target="_blank"
+ i18n-content="learnMore"></a>
+ </div>
<div id="customize-sync-encryption-new">
<hr>
<h4 i18n-content="encryptionSectionTitle"></h4>
diff --git a/chromium/chrome/browser/resources/options/sync_setup_overlay.js b/chromium/chrome/browser/resources/options/sync_setup_overlay.js
index 4b5944987f3..50a297a373e 100644
--- a/chromium/chrome/browser/resources/options/sync_setup_overlay.js
+++ b/chromium/chrome/browser/resources/options/sync_setup_overlay.js
@@ -25,6 +25,7 @@ cr.exportPath('options');
* passwordsEnforced: boolean,
* passwordsRegistered: boolean,
* passwordsSynced: boolean,
+ * paymentsIntegrationEnabled: boolean,
* preferencesEnforced: boolean,
* preferencesRegistered: boolean,
* preferencesSynced: boolean,
@@ -159,6 +160,11 @@ cr.define('options', function() {
$('use-default-link').onclick = function() {
self.showSyncEverythingPage_();
};
+ $('autofill-checkbox').onclick = function() {
+ var autofillSyncEnabled = $('autofill-checkbox').checked;
+ $('payments-integration-checkbox').checked = autofillSyncEnabled;
+ $('payments-integration-checkbox').disabled = !autofillSyncEnabled;
+ };
},
/** @private */
@@ -210,6 +216,7 @@ cr.define('options', function() {
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = value;
}
+ $('payments-integration-checkbox').checked = value;
},
/**
@@ -330,6 +337,7 @@ cr.define('options', function() {
options.DataTypeSelection.SYNC_EVERYTHING;
var syncNothing = $('sync-select-datatypes').selectedIndex ==
options.DataTypeSelection.SYNC_NOTHING;
+ var autofillSynced = syncAll || $('autofill-checkbox').checked;
var result = JSON.stringify({
'syncAllDataTypes': syncAll,
'syncNothing': syncNothing,
@@ -337,13 +345,15 @@ cr.define('options', function() {
'preferencesSynced': syncAll || $('preferences-checkbox').checked,
'themesSynced': syncAll || $('themes-checkbox').checked,
'passwordsSynced': syncAll || $('passwords-checkbox').checked,
- 'autofillSynced': syncAll || $('autofill-checkbox').checked,
+ 'autofillSynced': autofillSynced,
'extensionsSynced': syncAll || $('extensions-checkbox').checked,
'typedUrlsSynced': syncAll || $('typed-urls-checkbox').checked,
'appsSynced': syncAll || $('apps-checkbox').checked,
'tabsSynced': syncAll || $('tabs-checkbox').checked,
- 'wifiCredentialsSynced': syncAll ||
- $('wifi-credentials-checkbox').checked,
+ 'wifiCredentialsSynced':
+ syncAll || $('wifi-credentials-checkbox').checked,
+ 'paymentsIntegrationEnabled': syncAll ||
+ (autofillSynced && $('payments-integration-checkbox').checked),
'encryptAllData': encryptAllData,
'usePassphrase': usePassphrase,
'isGooglePassphrase': googlePassphrase,
@@ -367,6 +377,7 @@ cr.define('options', function() {
for (var i = 0; i < configureElements.length; i++)
configureElements[i].disabled = disabled;
$('sync-select-datatypes').disabled = disabled;
+ $('payments-integration-checkbox').disabled = disabled;
$('customize-link').hidden = disabled;
$('customize-link').disabled = disabled;
@@ -420,9 +431,15 @@ cr.define('options', function() {
this.dataTypeBoxesChecked_['autofill-checkbox'] = args.autofillSynced;
this.dataTypeBoxesDisabled_['autofill-checkbox'] =
args.autofillEnforced;
+ this.dataTypeBoxesChecked_['payments-integration-checkbox'] =
+ args.autofillSynced && args.paymentsIntegrationEnabled;
+ this.dataTypeBoxesDisabled_['payments-integration-checkbox'] =
+ !args.autofillSynced;
$('autofill-item').hidden = false;
+ $('payments-integration-setting-area').hidden = false;
} else {
$('autofill-item').hidden = true;
+ $('payments-integration-setting-area').hidden = true;
}
if (args.extensionsRegistered) {
$('extensions-checkbox').checked = args.extensionsSynced;
@@ -827,8 +844,8 @@ cr.define('options', function() {
* already signed in.
* @private
*/
- startSignIn_: function() {
- chrome.send('SyncSetupStartSignIn');
+ startSignIn_: function(accessPoint) {
+ chrome.send('SyncSetupStartSignIn', [accessPoint]);
},
/**
@@ -840,34 +857,16 @@ cr.define('options', function() {
},
};
- // These methods are for general consumption.
- SyncSetupOverlay.closeOverlay = function() {
- SyncSetupOverlay.getInstance().closeOverlay_();
- };
-
- SyncSetupOverlay.showSetupUI = function() {
- SyncSetupOverlay.getInstance().showSetupUI_();
- };
-
- SyncSetupOverlay.startSignIn = function() {
- SyncSetupOverlay.getInstance().startSignIn_();
- };
-
- SyncSetupOverlay.doSignOutOnAuthError = function() {
- SyncSetupOverlay.getInstance().doSignOutOnAuthError_();
- };
-
- SyncSetupOverlay.showSyncSetupPage = function(page, args) {
- SyncSetupOverlay.getInstance().showSyncSetupPage_(page, args);
- };
-
- SyncSetupOverlay.showCustomizePage = function(args, index) {
- SyncSetupOverlay.getInstance().showCustomizePage_(args, index);
- };
-
- SyncSetupOverlay.showStopSyncingUI = function() {
- SyncSetupOverlay.getInstance().showStopSyncingUI_();
- };
+ // Forward public APIs to private implementations.
+ cr.makePublic(SyncSetupOverlay, [
+ 'closeOverlay',
+ 'showSetupUI',
+ 'startSignIn',
+ 'doSignOutOnAuthError',
+ 'showSyncSetupPage',
+ 'showCustomizePage',
+ 'showStopSyncingUI',
+ ]);
// Export
return {
diff --git a/chromium/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js b/chromium/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js
new file mode 100644
index 00000000000..35cd029cd3d
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js
@@ -0,0 +1,47 @@
+// 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.
+
+cr.define('options', function() {
+ var Page = cr.ui.pageManager.Page;
+
+ var ResetProfileSettingsOverlay = options.ResetProfileSettingsOverlay;
+
+ /**
+ * TriggeredResetProfileSettingsOverlay class
+ * Encapsulated handling of the triggered variant of the 'Reset Profile
+ * Settings' overlay page. Identical to ResetProfileSettingsOverlay but in a
+ * new class to get a new overlay url mapping. See
+ * triggered_profile_resetter.h for when this will be used.
+ * @constructor
+ * @extends {options.ResetProfileSettingsOverlay}
+ */
+ function TriggeredResetProfileSettingsOverlay() {
+ // Note here that 'reset-profile-settings-overlay' is intentionally used as
+ // the pageDivName argument to reuse the layout and CSS from the reset
+ // profile settings overlay defined in reset_profile_settings_overlay.js.
+ Page.call(this, 'triggeredResetProfileSettings',
+ loadTimeData.getString('triggeredResetProfileSettingsOverlay'),
+ 'reset-profile-settings-overlay');
+ }
+
+ cr.addSingletonGetter(TriggeredResetProfileSettingsOverlay);
+
+ TriggeredResetProfileSettingsOverlay.prototype = {
+ __proto__: ResetProfileSettingsOverlay.prototype,
+
+ /** @override */
+ didShowPage: function() {
+ $('reset-profile-settings-title').textContent =
+ loadTimeData.getString('triggeredResetProfileSettingsOverlay');
+ $('reset-profile-settings-explanation').textContent =
+ loadTimeData.getString('triggeredResetProfileSettingsExplanation');
+ chrome.send('onShowResetProfileDialog');
+ },
+ };
+
+ // Export
+ return {
+ TriggeredResetProfileSettingsOverlay: TriggeredResetProfileSettingsOverlay
+ };
+});
diff --git a/chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css b/chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css
index 6611e9e09c7..59037556c74 100644
--- a/chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css
+++ b/chromium/chrome/browser/resources/pdf/elements/shared-icon-style.css
@@ -6,9 +6,9 @@
--iron-icon-height: 20px;
--iron-icon-width: 20px;
--paper-icon-button: {
- height: 20px;
+ height: 32px;
padding: 6px;
- width: 20px;
+ width: 32px;
};
--paper-icon-button-ink-color: rgb(189, 189, 189);
--viewer-icon-ink-color: rgb(189, 189, 189);
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css
index 58b4cde1726..1133812d946 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css
@@ -17,6 +17,16 @@
color: rgb(20, 20, 20);
}
+paper-ripple {
+ /* Allowing the ripple to capture pointer events prevents a focus rectangle
+ * for showing up for clicks, while still allowing it with tab-navigation.
+ * This undoes a paper-ripple bugfix aimed at non-Chrome browsers.
+ * TODO(tsergeant): Improve focus in viewer-bookmark so this can be removed
+ * (https://crbug.com/5448190).
+ */
+ pointer-events: auto;
+}
+
#title {
overflow: hidden;
text-overflow: ellipsis;
@@ -27,11 +37,11 @@
--iron-icon-height: 16px;
--iron-icon-width: 16px;
--paper-icon-button-ink-color: var(--paper-grey-900);
- height: 16px;
- min-width: 16px;
+ height: 28px;
+ min-width: 28px;
padding: 6px;
transition: transform 150ms;
- width: 16px;
+ width: 28px;
}
:host-context([dir=rtl]) #expand {
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_fit_page.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_fit_page.png
deleted file mode 100644
index 188cdabb125..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_fit_page.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_fit_width.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_fit_width.png
deleted file mode 100644
index a3fa6a6f995..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_fit_width.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_play.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_play.png
deleted file mode 100644
index cba2c19f3fa..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_play.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_print.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_print.png
deleted file mode 100644
index fa53e8573eb..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_print.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_save.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_save.png
deleted file mode 100644
index 7ec211f1ad3..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_save.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_zoom_in.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_zoom_in.png
deleted file mode 100644
index fdcc5c83ab5..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_zoom_in.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_zoom_out.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_zoom_out.png
deleted file mode 100644
index 4c6a5e01817..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/hiDPI/button_zoom_out.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_fit_page.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_fit_page.png
deleted file mode 100644
index 626e3d0e9c9..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_fit_page.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_fit_width.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_fit_width.png
deleted file mode 100644
index 00c4f962ad0..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_fit_width.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_play.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_play.png
deleted file mode 100644
index 5fb85b69a82..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_play.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_print.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_print.png
deleted file mode 100644
index 89b8738f465..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_print.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_save.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_save.png
deleted file mode 100644
index 4dc1db2dd0d..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_save.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_zoom_in.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_zoom_in.png
deleted file mode 100644
index 1fde30f28c5..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_zoom_in.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_zoom_out.png b/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_zoom_out.png
deleted file mode 100644
index 0a55eabd0f2..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/img/lowDPI/button_zoom_out.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.css b/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.css
deleted file mode 100644
index d4aff70c49d..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#icon {
- background-position: center center;
- background-repeat: no-repeat;
- background-size: 100% 100%;
- height: 100%;
- width: 100%;
-}
-
-:host {
- -webkit-user-select: none;
- background-image: linear-gradient(rgb(60, 80, 119), rgb(15, 24, 41));
- border: 1px solid rgb(11, 9, 16);
- cursor: default;
- display: inline-block;
- height: 36px;
- margin: 0;
- pointer-events: all;
- width: 43px;
-}
-
-:host(:focus:host) {
- outline: none;
-}
-
-:host(:hover:host) {
- background-image: linear-gradient(rgb(73, 102, 155), rgb(32, 52, 95));
-}
-
-:host(.latchable.polymer-selected:host),
-:host(:active:host) {
- background-color: rgb(75, 103, 156);
- background-image: none;
-}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.html b/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.html
deleted file mode 100644
index 9965142c83c..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<dom-module id="viewer-button">
- <link rel="import" type="css" href="viewer-button.css">
- <template>
- <div id="icon"></div>
- </template>
-</dom-module>
-<script src="viewer-button.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.js b/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.js
deleted file mode 100644
index 063a26e106d..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-button/viewer-button.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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.
-
-(function() {
- var dpi = '';
-
- Polymer({
- is: 'viewer-button',
-
- properties: {
- img: {
- type: String,
- observer: 'imgChanged'
- },
-
- latchable: {
- type: Boolean,
- observer: 'latchableChanged'
- }
- },
-
- created: function() {
- if (!dpi) {
- var mql = window.matchMedia('(-webkit-min-device-pixel-ratio: 1.3');
- dpi = mql.matches ? 'hi' : 'low';
- }
- },
-
- imgChanged: function() {
- if (this.img) {
- this.$.icon.style.backgroundImage =
- 'url(' + this.getAttribute('assetpath') + 'img/' + dpi +
- 'DPI/' + this.img + ')';
- } else {
- this.$.icon.style.backgroundImage = '';
- }
- },
-
- latchableChanged: function() {
- if (this.latchable)
- this.classList.add('latchable');
- else
- this.classList.remove('latchable');
- },
- });
-})();
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.css b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.css
deleted file mode 100644
index 07ee91dd908..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.css
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-:host {
- background-color: #ccc;
- color: #555;
- font-family: sans-serif;
- font-size: 20px;
- height: 100%;
- pointer-events: none;
- position: fixed;
- text-align: center;
- width: 100%;
-}
-
-#load-failed-message {
- line-height: 0;
- position: absolute;
- top: 50%;
- width: 100%;
-} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.html b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.html
deleted file mode 100644
index 57109d0b694..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<dom-module id="viewer-error-screen-legacy">
- <link rel="import" type="css" href="viewer-error-screen-legacy.css">
- <template>
- <div id="load-failed-message">{{text}}</div>
- </template>
-</dom-module>
-<script src="viewer-error-screen-legacy.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js
deleted file mode 100644
index cd09aed83be..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen-legacy/viewer-error-screen-legacy.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.
-
-Polymer({
- is: 'viewer-error-screen-legacy',
- properties: {
- text: String
- },
-
- show: function() {
- this.style.visibility = 'visible';
- }
-});
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/viewer-error-screen.html
index 2795dfbdccd..7e5f1d6744e 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/viewer-error-screen.html
@@ -8,11 +8,10 @@
<template>
<paper-dialog id="dialog" modal no-cancel-on-esc-key
entry-animation="fade-in-animation">
- <div id="load-failed-message"
- class="last-item">{{strings.pageLoadFailed}}</div>
+ <div id="load-failed-message" class="last-item"
+ i18n-content="pageLoadFailed"></div>
<div class="buttons" hidden$="{{!reloadFn}}">
- <paper-button on-click="reload" autofocus>
- <span>{{strings.pageReload}}</span>
+ <paper-button on-click="reload" autofocus i18n-content="pageReload">
</paper-button>
</div>
</paper-dialog>
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/viewer-error-screen.js
index 88d24a6c459..cd6c3dc17d4 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/viewer-error-screen.js
@@ -5,8 +5,6 @@
Polymer({
is: 'viewer-error-screen',
properties: {
- strings: Object,
-
reloadFn: {
type: Object,
value: null,
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css
index ab14b2587dc..ab124ab262f 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.css
@@ -4,7 +4,11 @@
:host {
color: #fff;
- font-size: 88.8%;
+ font-size: 94.4%;
+}
+
+:host ::selection {
+ background: rgba(255, 255, 255, 0.3);
}
#pageselector {
@@ -19,7 +23,7 @@
width: 1ch;
}
-input#input {
+#input {
-webkit-margin-start: -3px;
color: #fff;
line-height: 18px;
@@ -27,8 +31,8 @@ input#input {
text-align: end;
}
-input#input:focus,
-input#input:hover {
+#input:focus,
+#input:hover {
background-color: rgba(0, 0, 0, 0.5);
border-radius: 2px;
}
@@ -44,5 +48,5 @@ input#input:hover {
#slash,
#pagelength {
- font-size: 81.25%;
+ font-size: 76.5%;
}
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/viewer-page-selector.html
index c686c3ef63b..4f907c86b1a 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/viewer-page-selector.html
@@ -8,7 +8,7 @@
<paper-input-container id="pageselector" no-label-float>
<input id="input" is="iron-input" value="{{pageNo}}"
prevent-invalid-input allowed-pattern="\d" on-mouseup="select"
- on-change="pageNoCommitted" aria-label$="{{strings.labelPageNumber}}">
+ on-change="pageNoCommitted" i18n-values="aria-label:labelPageNumber">
</paper-input-container>
<span id="slash"> / </span>
<span id="pagelength-spacer">
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/viewer-page-selector.js
index 014362ab962..75a83300a9b 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/viewer-page-selector.js
@@ -23,9 +23,7 @@ Polymer({
pageNo: {
type: Number,
value: 1
- },
-
- strings: Object
+ }
},
pageNoCommitted: function() {
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.css b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.css
deleted file mode 100644
index 83c3fc47961..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-:host {
- -webkit-transition: opacity 400ms ease-in-out;
- background-color: #ccc;
- color: #555;
- display: table;
- font-family: sans-serif;
- font-size: 15px;
- height: 100%;
- pointer-events: none;
- position: fixed;
- text-align: center;
- width: 100%;
-}
-
-#message {
- padding-bottom: 10px;
-}
-
-.center {
- display: table-cell;
- vertical-align: middle;
-}
-
-.form {
- border: 1px solid #777;
- box-shadow: 1px 1px 1px;
- display: inline-block;
- padding: 10px;
- width: 300px;
-}
-
-input {
- color: #333;
- pointer-events: all;
-} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.html b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.html
deleted file mode 100644
index d4846205543..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<dom-module id="viewer-password-screen-legacy">
- <link rel="import" type="css" href="viewer-password-screen-legacy.css">
- <template>
- <div class="center">
- <form class="form">
- <div id="message">{{text}}</div>
- <input id="password" type="password" size="20"></input>
- <input id="submit" type="submit" on-click="submit"></input>
- </form>
- </div>
- </template>
-</dom-module>
-<script src="viewer-password-screen-legacy.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.js b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.js
deleted file mode 100644
index 8d09e153e50..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen-legacy/viewer-password-screen-legacy.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.
-
-Polymer({
- is: 'viewer-password-screen-legacy',
-
- properties: {
- text: {
- type: String,
- value: 'This document is password protected. Please enter a password.',
- },
-
- active: {
- type: Boolean,
- value: false,
- observer: 'activeChanged'
- }
- },
-
- timerId: undefined,
-
- ready: function() {
- this.activeChanged();
- },
-
- accept: function() {
- this.active = false;
- },
-
- deny: function() {
- this.$.password.disabled = false;
- this.$.submit.disabled = false;
- this.$.password.focus();
- this.$.password.select();
- },
-
- submit: function(e) {
- // Prevent the default form submission behavior.
- e.preventDefault();
- if (this.$.password.value.length == 0)
- return;
- this.$.password.disabled = true;
- this.$.submit.disabled = true;
- this.fire('password-submitted', {password: this.$.password.value});
- },
-
- activeChanged: function() {
- clearTimeout(this.timerId);
- this.timerId = undefined;
- if (this.active) {
- this.style.visibility = 'visible';
- this.style.opacity = 1;
- this.$.password.focus();
- } else {
- this.style.opacity = 0;
- this.timerId = setTimeout(function() {
- this.style.visibility = 'hidden';
- }.bind(this), 400);
- }
- }
-});
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/viewer-password-screen.html
index 18065022df7..4176f58eee1 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/viewer-password-screen.html
@@ -10,19 +10,18 @@
<template>
<paper-dialog id="dialog" modal no-cancel-on-esc-key
entry-animation="fade-in-animation" exit-animation="fade-out-animation">
- <div id="message">[[strings.passwordPrompt]]</div>
+ <div id="message" i18n-content="passwordPrompt"></div>
<div class="horizontal layout start">
<paper-input-container id="password-container" class="flex"
no-label-float invalid="[[invalid]]">
<input is="iron-input" id="password" type="password" size="20"
on-keypress="handleKey" autofocus>
</input>
- <template is="dom-if" if="[[invalid]]">
- <paper-input-error>[[strings.passwordInvalid]]</paper-input-error>
- </template>
+ <paper-input-error hidden$="[[!invalid]]"
+ i18n-content="passwordInvalid"></paper-input-error>
</paper-input-container>
- <paper-button id="submit"
- on-click="submit">{{strings.passwordSubmit}}</paper-button>
+ <paper-button id="submit" on-click="submit"
+ i18n-content="passwordSubmit"></paper-button>
</div>
</paper-dialog>
</template>
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/viewer-password-screen.js
index 6f5cd6ebfa6..9139269fb5c 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/viewer-password-screen.js
@@ -6,8 +6,6 @@ Polymer({
is: 'viewer-password-screen',
properties: {
- strings: Object,
-
invalid: Boolean,
active: {
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css
index b96c7b278a8..37e8401816e 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.css
@@ -2,14 +2,21 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-/* We introduce a wrapper aligner element as setting the relevant attributes
- * (horizontal justified layout center) have no effect on the core-toolbar. */
+:host ::selection {
+ background: rgba(255, 255, 255, 0.3);
+}
+
+/* We introduce a wrapper aligner element to help with laying out the main
+ * toolbar content without changing the bottom-aligned progress bar. */
#aligner {
+ @apply(--layout-horizontal);
+ @apply(--layout-center);
padding: 0 16px;
width: 100%;
}
#title {
+ @apply(--layout-flex-5);
font-size: 77.8%;
font-weight: 500;
overflow: hidden;
@@ -18,6 +25,7 @@
}
#pageselector-container {
+ @apply(--layout-flex-1);
text-align: center;
/* The container resizes according to the width of the toolbar. On small
* screens with large numbers of pages, overflow page numbers without
@@ -26,6 +34,7 @@
}
#buttons {
+ @apply(--layout-flex-5);
-webkit-user-select: none;
text-align: end;
}
@@ -48,18 +57,10 @@ paper-progress {
paper-toolbar {
--paper-toolbar-background: rgb(50, 54, 57);
+ --paper-toolbar-height: 48px;
@apply(--shadow-elevation-2dp);
color: rgb(241, 241, 241);
font-size: 1.5em;
- height: 48px;
-}
-
-paper-toolbar /deep/ ::selection {
- background: rgba(255, 255, 255, 0.3);
-}
-
-paper-toolbar /deep/ .toolbar-tools {
- height: 48px;
}
.invisible {
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
index feec286f274..7e3df10d583 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
@@ -1,5 +1,5 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-shadow-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/image-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/slide-down-animation.html">
@@ -18,47 +18,41 @@
<template>
<paper-toolbar>
- <div id="aligner" class="middle horizontal layout center">
- <span id="title" class="flex-5" title="{{docTitle}}">
+ <div id="aligner" class="middle">
+ <span id="title" title="{{docTitle}}">
<span>{{docTitle}}</span>
</span>
- <div class="flex-1" id="pageselector-container">
+ <div id="pageselector-container">
<viewer-page-selector id="pageselector" class="invisible"
- doc-length="{{docLength}}" page-no="{{pageNo}}"
- strings="{{strings}}">
+ doc-length="{{docLength}}" page-no="{{pageNo}}">
</viewer-page-selector>
</div>
- <div id="buttons" class="invisible flex-5">
- <viewer-toolbar-dropdown id="bookmarks"
- hidden$="[[!bookmarks.length]]"
- header="{{strings.bookmarks}}"
- open-icon="bookmark"
- closed-icon="bookmark-border">
- <viewer-bookmarks-content bookmarks="{{bookmarks}}">
- </viewer-bookmarks-content>
- </viewer-toolbar-dropdown>
-
+ <div id="buttons" class="invisible">
<paper-icon-button id="rotate-right" icon="image:rotate-right"
- on-click="rotateRight" alt="{{strings.tooltipRotateCW}}"
- title="{{strings.tooltipRotateCW}}">
- </paper-icon-button>
-
- <paper-icon-button id="rotate-left" icon="image:rotate-left"
- on-click="rotateLeft" alt="{{strings.tooltipRotateCCW}}"
- title="{{strings.tooltipRotateCCW}}">
+ on-click="rotateRight"
+ i18n-values="aria-label:tooltipRotateCW;title:tooltipRotateCW">
</paper-icon-button>
- <paper-icon-button id="save" icon="save"
- on-click="save" alt="{{strings.tooltipSave}}"
- title="{{strings.tooltipSave}}">
+ <paper-icon-button id="download" icon="file-download"
+ on-click="download"
+ i18n-values="aria-label:tooltipDownload;title:tooltipDownload">
</paper-icon-button>
<paper-icon-button id="print" icon="print"
- on-click="print" alt="{{strings.tooltipPrint}}"
- title="{{strings.tooltipPrint}}">
+ on-click="print"
+ i18n-values="aria-label:tooltipPrint;title:tooltipPrint">
</paper-icon-button>
+
+ <viewer-toolbar-dropdown id="bookmarks"
+ hidden$="[[!bookmarks.length]]"
+ open-icon="bookmark"
+ closed-icon="bookmark-border"
+ i18n-values="header:bookmarks">
+ <viewer-bookmarks-content bookmarks="{{bookmarks}}">
+ </viewer-bookmarks-content>
+ </viewer-toolbar-dropdown>
</div>
</div>
<div class="bottom fit">
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
index 338d9eaaeb0..143a0127c3d 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
@@ -10,7 +10,6 @@
],
properties: {
- strings: Object,
/**
* The current loading progress of the PDF document (0 - 100).
*/
@@ -79,7 +78,7 @@
},
_onAnimationFinished: function() {
- this.style.transform = this.opened ? 'none' : 'translateY(-100%)';
+ this.style.transform = this.opened ? 'none' : 'translateY(-100%)';
},
loadProgressChanged: function() {
@@ -128,15 +127,11 @@
this.$.bookmarks.lowerBound = lowerBound;
},
- rotateLeft: function() {
- this.fire('rotate-left');
- },
-
rotateRight: function() {
this.fire('rotate-right');
},
- save: function() {
+ download: function() {
this.fire('save');
},
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.css b/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.css
deleted file mode 100644
index ecc142b59b7..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.css
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-:host {
- -webkit-transition: opacity 400ms ease-in-out;
- background: rgb(29, 39, 57);
- border-radius: 5px;
- bottom: 26px;
- box-shadow: 0 1px 2px gray, 0 3px 3px rgba(0, 0, 0, .2);
- height: auto;
- left: 26px;
- pointer-events: none;
- position: fixed;
- width: auto;
-}
-
-.scaler {
- -webkit-transform: scale(0.25);
- -webkit-transform-origin: 0 0;
- float: left;
- height: 44px;
- margin: 8px;
- width: 44px;
-}
-
-#segments {
- border-radius: 50%;
- height: 176px;
- list-style: none;
- margin: 0;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 176px;
-}
-
-.segment {
- -webkit-transform-origin: 0 100%;
- background: rgb(227, 234, 249);
- box-shadow: 0 0 0 6px rgb(29, 39, 57) inset;
- height: 50%;
- overflow: hidden;
- position: absolute;
- right: 0;
- top: 0;
- width: 50%;
-}
-
-.center-circle {
- background-color: rgb(29, 39, 57);
- border-radius: 50%;
- height: 80px;
- left: 48px;
- margin: 0;
- padding: 0;
- position: absolute;
- top: 48px;
- width: 80px;
-}
-
-#text {
- color: rgb(227, 234, 249);
- float: left;
- font-family: sans-serif;
- font-size: 16px;
- font-weight: bold;
- line-height: 58px;
- margin-right: 10px;
- margin-top: 1px;
-}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.html
deleted file mode 100644
index 8dff9f72dd1..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<dom-module id="viewer-progress-bar">
- <link rel="import" type="css" href="viewer-progress-bar.css">
- <template>
- <div class="scaler">
- <ul id="segments"></ul>
- <div class="center-circle"></div>
- </div>
- <div id="text">{{text}}</div>
- </template>
-</dom-module>
-<script src="viewer-progress-bar.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.js
deleted file mode 100644
index 710f01eac94..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-progress-bar/viewer-progress-bar.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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.
-
-Polymer({
- is: 'viewer-progress-bar',
-
- properties: {
- progress: {
- type: Number,
- observer: 'progressChanged'
- },
-
- text: {
- type: String,
- value: 'Loading'
- },
-
- numSegments: {
- type: Number,
- value: 8,
- observer: 'numSegmentsChanged'
- }
- },
-
- segments: [],
-
- ready: function() {
- this.numSegmentsChanged();
- },
-
- progressChanged: function() {
- var numVisible = this.progress * this.segments.length / 100.0;
- for (var i = 0; i < this.segments.length; i++) {
- this.segments[i].style.visibility =
- i < numVisible ? 'inherit' : 'hidden';
- }
-
- if (this.progress >= 100 || this.progress < 0)
- this.style.opacity = 0;
- },
-
- numSegmentsChanged: function() {
- // Clear the existing segments.
- this.segments = [];
- var segmentsElement = this.$.segments;
- segmentsElement.innerHTML = '';
-
- // Create the new segments.
- var segment = document.createElement('li');
- segment.classList.add('segment');
- var angle = 360 / this.numSegments;
- for (var i = 0; i < this.numSegments; ++i) {
- var segmentCopy = segment.cloneNode(true);
- segmentCopy.style.webkitTransform =
- 'rotate(' + (i * angle) + 'deg) skewY(' +
- -1 * (90 - angle) + 'deg)';
- segmentsElement.appendChild(segmentCopy);
- this.segments.push(segmentCopy);
- }
- this.progressChanged();
- }
-});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css
index 30b9f42abdf..117a2db1334 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.css
@@ -9,6 +9,16 @@
#container {
position: absolute;
+ /* Controls the position of the dropdown relative to the right of the screen.
+ * Default is aligned with the right of the toolbar buttons.
+ * TODO(tsergeant): Change the layout of the dropdown so this is not required.
+ */
+ right: var(--viewer-toolbar-dropdown-right-distance, 36px);
+}
+
+:host-context([dir=rtl]) #container {
+ left: var(--viewer-toolbar-dropdown-right-distance, 36px);
+ right: auto;
}
paper-material {
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
index 25b44c296e1..d07bfc8209d 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
@@ -9,7 +9,7 @@
<template>
<div on-click="toggleDropdown" id="icon">
<paper-icon-button id="main-icon" icon="[[dropdownIcon]]"
- alt="{{header}}" title="{{header}}">
+ aria-label="{{header}}" title="{{header}}">
</paper-icon-button>
<iron-icon icon="arrow-drop-down" id="arrow"></iron-icon>
</div>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.css b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.css
deleted file mode 100644
index 64be0e9f12c..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-:host {
- -webkit-transition: opacity 400ms ease-in-out;
- bottom: 0;
- display: block;
- font-size: 0;
- opacity: 1;
- padding: 30px 30px 15px 30vw;
- pointer-events: none;
- position: fixed;
- right: 0;
-}
-
-#toolbar {
- border-radius: 3px;
- box-shadow: 0 1px 2px gray, 0 3px 3px rgba(0, 0, 0, .2);
- overflow: hidden;
-}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.html
deleted file mode 100644
index 1a06e1e64a2..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-
-<dom-module id="viewer-toolbar">
- <link rel="import" type="css" href="viewer-toolbar.css">
- <template>
- <div id="toolbar">
- <content></content>
- </div>
- </template>
-</dom-module>
-<script src="viewer-toolbar.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.js
deleted file mode 100644
index 28f90523e35..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar/viewer-toolbar.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-Polymer({
- is: 'viewer-toolbar',
-
- properties: {
- fadingIn: {
- type: Boolean,
- value: false,
- observer: 'fadingInChanged'
- }
- },
-
- timerId_: undefined,
-
- inInitialFadeIn_: false,
-
- ready: function() {
- this.mousemoveCallback = function(e) {
- var rect = this.getBoundingClientRect();
- if (e.clientX >= rect.left && e.clientX <= rect.right &&
- e.clientY >= rect.top && e.clientY <= rect.bottom) {
- this.fadingIn = true;
- // If we hover over the toolbar, cancel the initial fade in.
- if (this.inInitialFadeIn_)
- this.inInitialFadeIn_ = false;
- } else {
- // Initially we want to keep the toolbar up for a longer period.
- if (!this.inInitialFadeIn_)
- this.fadingIn = false;
- }
- }.bind(this);
- },
-
- attached: function() {
- this.parentNode.addEventListener('mousemove', this.mousemoveCallback);
- },
-
- detached: function() {
- this.parentNode.removeEventListener('mousemove', this.mousemoveCallback);
- },
-
- initialFadeIn: function() {
- this.inInitialFadeIn_ = true;
- this.fadeIn();
- this.fadeOutAfterDelay(6000);
- },
-
- fadingInChanged: function() {
- if (this.fadingIn) {
- this.fadeIn();
- } else {
- if (this.timerId_ === undefined)
- this.fadeOutAfterDelay(3000);
- }
- },
-
- fadeIn: function() {
- this.style.opacity = 1;
- clearTimeout(this.timerId_);
- this.timerId_ = undefined;
- },
-
- fadeOutAfterDelay: function(delay) {
- this.timerId_ = setTimeout(
- function() {
- this.style.opacity = 0;
- this.timerId_ = undefined;
- this.inInitialFadeIn_ = false;
- }.bind(this), delay);
- }
-});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css
index c9bb1896f96..02454185593 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.css
@@ -8,12 +8,14 @@
}
:host([closed]) #wrapper {
- transform: translateX(100%);
+ /* 132px roughly flips the location of the button across the right edge of the
+ * page. */
+ transform: translateX(132px);
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
:host-context([dir=rtl]):host([closed]) #wrapper {
- transform: translateX(-100%);
+ transform: translateX(-132px);
}
paper-fab {
@@ -26,6 +28,5 @@ paper-fab {
@apply(--shadow-elevation-4dp);
background-color: rgb(242, 242, 242);
color: rgb(96, 96, 96);
- margin: 0 48px;
overflow: visible;
}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css
index 4756c8b3ebe..c7577ef5471 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.css
@@ -16,6 +16,16 @@
right: auto;
}
+#zoom-buttons {
+ position: relative;
+ right: 48px;
+}
+
+:host-context([dir=rtl]) #zoom-buttons {
+ left: 48px;
+ right: auto;
+}
+
viewer-zoom-button {
display: block;
}
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/viewer-zoom-toolbar.html
index a2e3b372014..b1ee0d994f8 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/viewer-zoom-toolbar.html
@@ -7,15 +7,13 @@
<template>
<div id="zoom-buttons">
- <div id="buttons">
- <viewer-zoom-button id="fit-button" icons="fullscreen-exit fullscreen"
- on-fabclick="fitToggle" delay="100">
- </viewer-zoom-button>
- <viewer-zoom-button id="zoom-in-button" icons="add"
- on-fabclick="zoomIn" delay="50"></viewer-zoom-button>
- <viewer-zoom-button id="zoom-out-button" icons="remove"
- on-fabclick="zoomOut" delay="0"></viewer-zoom-button>
- </div>
+ <viewer-zoom-button id="fit-button" icons="fullscreen-exit fullscreen"
+ on-fabclick="fitToggle" delay="100">
+ </viewer-zoom-button>
+ <viewer-zoom-button id="zoom-in-button" icons="add"
+ on-fabclick="zoomIn" delay="50"></viewer-zoom-button>
+ <viewer-zoom-button id="zoom-out-button" icons="remove"
+ on-fabclick="zoomOut" delay="0"></viewer-zoom-button>
</div>
</template>
</dom-module>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
index c65365c93bb..870b7e05424 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
@@ -11,11 +11,6 @@
is: 'viewer-zoom-toolbar',
properties: {
- strings: {
- type: Object,
- observer: 'setTooltips_'
- },
-
visible_: {
type: Boolean,
value: true
@@ -26,11 +21,18 @@
return this.visible_;
},
- setTooltips_: function() {
- this.$['fit-button'].tooltips =
- [this.strings.tooltipFitToPage, this.strings.tooltipFitToWidth];
- this.$['zoom-in-button'].tooltips = [this.strings.tooltipZoomIn];
- this.$['zoom-out-button'].tooltips = [this.strings.tooltipZoomOut];
+ /**
+ * Change button tooltips to match any changes to loadTimeData.
+ */
+ updateTooltips: function() {
+ this.$['fit-button'].tooltips = [
+ loadTimeData.getString('tooltipFitToPage'),
+ loadTimeData.getString('tooltipFitToWidth')
+ ];
+ this.$['zoom-in-button'].tooltips =
+ [loadTimeData.getString('tooltipZoomIn')];
+ this.$['zoom-out-button'].tooltips =
+ [loadTimeData.getString('tooltipZoomOut')];
},
fitToggle: function() {
diff --git a/chromium/chrome/browser/resources/pdf/index-material.css b/chromium/chrome/browser/resources/pdf/index-material.css
deleted file mode 100644
index a443bac50ec..00000000000
--- a/chromium/chrome/browser/resources/pdf/index-material.css
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-body {
- background-color: rgb(82, 86, 89);
- font-family: 'Roboto', 'Noto', sans-serif;
- margin: 0;
-}
-
-viewer-page-indicator {
- visibility: hidden;
- z-index: 2;
-}
-
-viewer-pdf-toolbar {
- position: fixed;
- width: 100%;
- z-index: 4;
-}
-
-#plugin {
- height: 100%;
- position: fixed;
- width: 100%;
- z-index: 1;
-}
-
-#sizer {
- position: absolute;
- z-index: 0;
-}
-
-@media(max-height: 250px) {
- viewer-pdf-toolbar {
- display: none;
- }
-}
-
-@media(max-height: 200px) {
- viewer-zoom-toolbar {
- display: none;
- }
-}
-
-@media(max-width: 300px) {
- viewer-zoom-toolbar {
- display: none;
- }
-}
diff --git a/chromium/chrome/browser/resources/pdf/index-material.html b/chromium/chrome/browser/resources/pdf/index-material.html
deleted file mode 100644
index 5c2c1c4e069..00000000000
--- a/chromium/chrome/browser/resources/pdf/index-material.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <meta charset="utf-8">
- <!-- Must be before any other scripts or Polymer imports. -->
- <script src="chrome://resources/js/polymer_config.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="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" href="chrome://resources/css/roboto.css">
- <link rel="stylesheet" href="index-material.css">
-</head>
-<body>
-
-<viewer-pdf-toolbar id="material-toolbar" hidden></viewer-pdf-toolbar>
-
-<div id="sizer"></div>
-<viewer-password-screen id="password-screen"></viewer-password-screen>
-
-<viewer-zoom-toolbar id="zoom-toolbar"></viewer-zoom-toolbar>
-
-<viewer-page-indicator id="page-indicator"></viewer-page-indicator>
-
-<viewer-error-screen id="error-screen"></viewer-error-screen>
-
-</body>
-<script src="toolbar_manager.js"></script>
-<script src="viewport.js"></script>
-<script src="open_pdf_params_parser.js"></script>
-<script src="navigator.js"></script>
-<script src="viewport_scroller.js"></script>
-<script src="zoom_manager.js"></script>
-<script src="pdf_scripting_api.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="browser_api.js"></script>
-<script src="pdf.js"></script>
-<script src="main.js"></script>
-</html>
diff --git a/chromium/chrome/browser/resources/pdf/index.css b/chromium/chrome/browser/resources/pdf/index.css
index 36db509ab3e..a443bac50ec 100644
--- a/chromium/chrome/browser/resources/pdf/index.css
+++ b/chromium/chrome/browser/resources/pdf/index.css
@@ -1,36 +1,22 @@
-/* Copyright 2014 The Chromium Authors. All rights reserved.
+/* 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. */
body {
- background-color: #ccc;
+ background-color: rgb(82, 86, 89);
+ font-family: 'Roboto', 'Noto', sans-serif;
margin: 0;
}
-viewer-toolbar {
- visibility: hidden;
- white-space: nowrap;
- z-index: 3;
-}
-
viewer-page-indicator {
visibility: hidden;
- z-index: 3;
-}
-
-viewer-progress-bar {
- visibility: hidden;
- z-index: 3;
-}
-
-viewer-error-screen-legacy {
- visibility: hidden;
z-index: 2;
}
-viewer-password-screen-legacy {
- visibility: hidden;
- z-index: 2;
+viewer-pdf-toolbar {
+ position: fixed;
+ width: 100%;
+ z-index: 4;
}
#plugin {
@@ -44,3 +30,21 @@ viewer-password-screen-legacy {
position: absolute;
z-index: 0;
}
+
+@media(max-height: 250px) {
+ viewer-pdf-toolbar {
+ display: none;
+ }
+}
+
+@media(max-height: 200px) {
+ viewer-zoom-toolbar {
+ display: none;
+ }
+}
+
+@media(max-width: 300px) {
+ viewer-zoom-toolbar {
+ display: none;
+ }
+}
diff --git a/chromium/chrome/browser/resources/pdf/index.html b/chromium/chrome/browser/resources/pdf/index.html
index cfb3551660b..3c5253d0ce2 100644
--- a/chromium/chrome/browser/resources/pdf/index.html
+++ b/chromium/chrome/browser/resources/pdf/index.html
@@ -1,61 +1,44 @@
<!doctype html>
<html i18n-values="dir:textdirection;lang:language">
<head>
+ <base href="chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/">
<meta charset="utf-8">
+ <!-- Must be before any other scripts or Polymer imports. -->
<script src="chrome://resources/js/polymer_config.js"></script>
- <link rel="import" href="elements/viewer-button/viewer-button.html">
- <link rel="import" href="elements/viewer-error-screen-legacy/viewer-error-screen-legacy.html">
+ <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-password-screen-legacy/viewer-password-screen-legacy.html">
- <link rel="import" href="elements/viewer-progress-bar/viewer-progress-bar.html">
- <link rel="import" href="elements/viewer-toolbar/viewer-toolbar.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="stylesheet" href="chrome://resources/css/text_defaults.css">
- <link rel="stylesheet" type="text/css" href="index.css">
+ <link rel="stylesheet" href="chrome://resources/css/roboto.css">
+ <link rel="stylesheet" href="index.css">
</head>
<body>
+<viewer-pdf-toolbar id="toolbar" hidden></viewer-pdf-toolbar>
+
<div id="sizer"></div>
-<viewer-password-screen-legacy id="password-screen">
-</viewer-password-screen-legacy>
-<viewer-page-indicator id="page-indicator"></viewer-page-indicator>
-<viewer-progress-bar id="progress-bar"></viewer-progress-bar>
+<viewer-password-screen id="password-screen"></viewer-password-screen>
-<viewer-toolbar id="toolbar">
- <viewer-button id="fit-to-page-button"
- assetpath="elements/viewer-button/"
- img="button_fit_page.png" latchable>
- </viewer-button>
- <viewer-button id="fit-to-width-button"
- assetpath="elements/viewer-button/"
- img="button_fit_width.png" latchable>
- </viewer-button>
- <viewer-button id="zoom-out-button"
- assetpath="elements/viewer-button/"
- img="button_zoom_out.png">
- </viewer-button>
- <viewer-button id="zoom-in-button"
- assetpath="elements/viewer-button/"
- img="button_zoom_in.png">
- </viewer-button>
- <viewer-button id="save-button"
- assetpath="elements/viewer-button/"
- img="button_save.png">
- </viewer-button>
- <viewer-button id="print-button"
- assetpath="elements/viewer-button/"
- img="button_print.png">
- </viewer-button>
-</viewer-toolbar>
+<viewer-zoom-toolbar id="zoom-toolbar"></viewer-zoom-toolbar>
+
+<viewer-page-indicator id="page-indicator"></viewer-page-indicator>
-<viewer-error-screen-legacy id="error-screen"></viewer-error-screen-legacy>
+<viewer-error-screen id="error-screen"></viewer-error-screen>
</body>
+<script src="toolbar_manager.js"></script>
<script src="viewport.js"></script>
<script src="open_pdf_params_parser.js"></script>
<script src="navigator.js"></script>
<script src="viewport_scroller.js"></script>
<script src="zoom_manager.js"></script>
<script src="pdf_scripting_api.js"></script>
+<script src="chrome://resources/js/i18n_template_no_process.js"></script>
+<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="browser_api.js"></script>
<script src="pdf.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/manifest.json b/chromium/chrome/browser/resources/pdf/manifest.json
index b3c4e943521..b153845327e 100644
--- a/chromium/chrome/browser/resources/pdf/manifest.json
+++ b/chromium/chrome/browser/resources/pdf/manifest.json
@@ -15,17 +15,11 @@
"application/pdf"
],
"content_security_policy": "script-src 'self' blob: filesystem: chrome://resources; object-src * blob: filesystem: data:; plugin-types application/x-google-chrome-pdf",
- // This is to work-around an issue where this extension is not granted
- // permission to access chrome://resources when iframed for print preview.
- // See https://crbug.com/444752.
- "content_scripts": [
- {
- "matches": ["chrome://print/*"],
- "js": ["content_script.js"]
- }
- ],
- "mime_types_handler": "<INDEX>",
+ "mime_types_handler": "index.html",
"web_accessible_resources": [
- "<INDEX>"
+ "*.js",
+ "*.html",
+ "*.css",
+ "*.png"
]
}
diff --git a/chromium/chrome/browser/resources/pdf/navigator.js b/chromium/chrome/browser/resources/pdf/navigator.js
index e6bd7ad28c4..9a2f6aaedfc 100644
--- a/chromium/chrome/browser/resources/pdf/navigator.js
+++ b/chromium/chrome/browser/resources/pdf/navigator.js
@@ -73,11 +73,21 @@ Navigator.prototype = {
* position.
*/
onViewportReceived_: function(viewportPosition) {
+ var originalUrl = this.originalUrl_;
+ var hashIndex = originalUrl.search('#');
+ if (hashIndex != -1)
+ originalUrl = originalUrl.substring(0, hashIndex);
+
+ var newUrl = viewportPosition.url;
+ hashIndex = newUrl.search('#');
+ if (hashIndex != -1)
+ newUrl = newUrl.substring(0, hashIndex);
+
var pageNumber = viewportPosition.page;
- if (pageNumber != undefined)
+ if (pageNumber != undefined && originalUrl == newUrl)
this.viewport_.goToPage(pageNumber);
else
- this.navigateInCurrentTabCallback_(viewportPosition['url']);
+ this.navigateInCurrentTabCallback_(viewportPosition.url);
},
/**
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 ddd18be4164..00f44773f46 100644
--- a/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js
+++ b/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js
@@ -48,44 +48,68 @@ OpenPDFParamsParser.prototype = {
},
/**
+ * Parse the parameters encoded in the fragment of a URL into a dictionary.
* @private
- * Parse PDF url parameters. These parameters are mentioned in the url
- * and specify actions to be performed when opening pdf files.
- * See http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/
- * pdfs/pdf_open_parameters.pdf for details.
- * @param {string} url that needs to be parsed.
- * @param {Function} callback function to be called with viewport info.
+ * @param {string} url to parse
+ * @return {Object} Key-value pairs of URL parameters
*/
- getViewportFromUrlParams: function(url, callback) {
- var viewportPosition = {};
- viewportPosition['url'] = url;
+ parseUrlParams_: function(url) {
+ var params = {};
+
var paramIndex = url.search('#');
- if (paramIndex == -1) {
- callback(viewportPosition);
- return;
- }
+ if (paramIndex == -1)
+ return params;
var paramTokens = url.substring(paramIndex + 1).split('&');
if ((paramTokens.length == 1) && (paramTokens[0].search('=') == -1)) {
// Handle the case of http://foo.com/bar#NAMEDDEST. This is not
// explicitly mentioned except by example in the Adobe
// "PDF Open Parameters" document.
- this.outstandingRequests_.push({
- callback: callback,
- viewportPosition: viewportPosition
- });
- this.getNamedDestinationsFunction_(paramTokens[0]);
- return;
+ params['nameddest'] = paramTokens[0];
+ return params;
}
- var paramsDictionary = {};
for (var i = 0; i < paramTokens.length; ++i) {
var keyValueSplit = paramTokens[i].split('=');
if (keyValueSplit.length != 2)
continue;
- paramsDictionary[keyValueSplit[0]] = keyValueSplit[1];
+ params[keyValueSplit[0]] = keyValueSplit[1];
}
+ return params;
+ },
+
+ /**
+ * Parse PDF url parameters used for controlling the state of UI. These need
+ * to be available when the UI is being initialized, rather than when the PDF
+ * is finished loading.
+ * @param {string} url that needs to be parsed.
+ * @return {Object} parsed url parameters.
+ */
+ getUiUrlParams: function(url) {
+ var params = this.parseUrlParams_(url);
+ var uiParams = {toolbar: true};
+
+ if ('toolbar' in params && params['toolbar'] == 0)
+ uiParams.toolbar = false;
+
+ return uiParams;
+ },
+
+ /**
+ * Parse PDF url parameters. These parameters are mentioned in the url
+ * and specify actions to be performed when opening pdf files.
+ * See http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/
+ * pdfs/pdf_open_parameters.pdf for details.
+ * @param {string} url that needs to be parsed.
+ * @param {Function} callback function to be called with viewport info.
+ */
+ getViewportFromUrlParams: function(url, callback) {
+ var viewportPosition = {};
+ viewportPosition['url'] = url;
+
+ var paramsDictionary = this.parseUrlParams_(url);
+
if ('page' in paramsDictionary) {
// |pageNumber| is 1-based, but goToPage() take a zero-based page number.
var pageNumber = parseInt(paramsDictionary['page']);
diff --git a/chromium/chrome/browser/resources/pdf/pdf.js b/chromium/chrome/browser/resources/pdf/pdf.js
index d667247abda..4ea2b064ea0 100644
--- a/chromium/chrome/browser/resources/pdf/pdf.js
+++ b/chromium/chrome/browser/resources/pdf/pdf.js
@@ -122,6 +122,7 @@ PDFViewer.DARK_BACKGROUND_COLOR = '0xFF525659';
*/
function PDFViewer(browserApi) {
this.browserApi_ = browserApi;
+ this.originalUrl_ = this.browserApi_.getStreamInfo().originalUrl;
this.loadState_ = LoadState.LOADING;
this.parentWindow_ = null;
this.parentOrigin_ = null;
@@ -129,18 +130,21 @@ function PDFViewer(browserApi) {
this.delayedScriptingMessages_ = [];
- this.isPrintPreview_ = this.browserApi_.getStreamInfo().originalUrl.indexOf(
+ this.isPrintPreview_ = this.originalUrl_.indexOf(
'chrome://print') == 0;
- this.isMaterial_ = location.pathname.substring(1) === 'index-material.html';
+ // Parse open pdf parameters.
+ this.paramsParser_ =
+ new OpenPDFParamsParser(this.getNamedDestination_.bind(this));
+ var 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');
- this.toolbar_ = $('toolbar');
- if (!this.isMaterial_ || this.isPrintPreview_)
+ if (this.isPrintPreview_)
this.pageIndicator_ = $('page-indicator');
- this.progressBar_ = $('progress-bar');
this.passwordScreen_ = $('password-screen');
this.passwordScreen_.addEventListener('password-submitted',
this.onPasswordSubmitted_.bind(this));
@@ -155,8 +159,7 @@ function PDFViewer(browserApi) {
// Create the viewport.
var shortWindow = window.innerHeight < PDFViewer.TOOLBAR_WINDOW_MIN_HEIGHT;
var topToolbarHeight =
- (this.isMaterial_ && !this.isPrintPreview_ && !shortWindow) ?
- PDFViewer.MATERIAL_TOOLBAR_HEIGHT : 0;
+ (toolbarEnabled) ? PDFViewer.MATERIAL_TOOLBAR_HEIGHT : 0;
this.viewport_ = new Viewport(window,
this.sizer_,
this.viewportChanged_.bind(this),
@@ -185,7 +188,7 @@ function PDFViewer(browserApi) {
false);
this.plugin_.setAttribute('src',
- this.browserApi_.getStreamInfo().originalUrl);
+ this.originalUrl_);
this.plugin_.setAttribute('stream-url',
this.browserApi_.getStreamInfo().streamUrl);
var headers = '';
@@ -196,8 +199,6 @@ function PDFViewer(browserApi) {
this.plugin_.setAttribute('headers', headers);
var backgroundColor = PDFViewer.DARK_BACKGROUND_COLOR;
- if (!this.isMaterial_)
- backgroundColor = PDFViewer.LIGHT_BACKGROUND_COLOR;
this.plugin_.setAttribute('background-color', backgroundColor);
this.plugin_.setAttribute('top-toolbar-height', topToolbarHeight);
@@ -206,55 +207,38 @@ function PDFViewer(browserApi) {
document.body.appendChild(this.plugin_);
// Setup the button event listeners.
- if (!this.isMaterial_) {
- $('fit-to-width-button').addEventListener('click',
- this.viewport_.fitToWidth.bind(this.viewport_));
- $('fit-to-page-button').addEventListener('click',
- this.viewport_.fitToPage.bind(this.viewport_));
- $('zoom-in-button').addEventListener('click',
- this.viewport_.zoomIn.bind(this.viewport_));
- $('zoom-out-button').addEventListener('click',
- this.viewport_.zoomOut.bind(this.viewport_));
- $('save-button').addEventListener('click', this.save_.bind(this));
- $('print-button').addEventListener('click', this.print_.bind(this));
+ this.zoomToolbar_ = $('zoom-toolbar');
+ this.zoomToolbar_.addEventListener('fit-to-width',
+ this.viewport_.fitToWidth.bind(this.viewport_));
+ this.zoomToolbar_.addEventListener('fit-to-page',
+ this.fitToPage_.bind(this));
+ this.zoomToolbar_.addEventListener('zoom-in',
+ this.viewport_.zoomIn.bind(this.viewport_));
+ this.zoomToolbar_.addEventListener('zoom-out',
+ this.viewport_.zoomOut.bind(this.viewport_));
+
+ if (toolbarEnabled) {
+ this.toolbar_ = $('toolbar');
+ this.toolbar_.hidden = false;
+ this.toolbar_.addEventListener('save', this.save_.bind(this));
+ this.toolbar_.addEventListener('print', this.print_.bind(this));
+ this.toolbar_.addEventListener('rotate-right',
+ this.rotateClockwise_.bind(this));
+ // Must attach to mouseup on the plugin element, since it eats mousedown
+ // and click events.
+ this.plugin_.addEventListener('mouseup',
+ this.toolbar_.hideDropdowns.bind(this.toolbar_));
+
+ this.toolbar_.docTitle =
+ getFilenameFromURL(this.originalUrl_);
}
- if (this.isMaterial_) {
- this.zoomToolbar_ = $('zoom-toolbar');
- this.zoomToolbar_.addEventListener('fit-to-width',
- this.viewport_.fitToWidth.bind(this.viewport_));
- this.zoomToolbar_.addEventListener('fit-to-page',
- this.fitToPage_.bind(this));
- this.zoomToolbar_.addEventListener('zoom-in',
- this.viewport_.zoomIn.bind(this.viewport_));
- this.zoomToolbar_.addEventListener('zoom-out',
- this.viewport_.zoomOut.bind(this.viewport_));
-
- if (!this.isPrintPreview_) {
- this.materialToolbar_ = $('material-toolbar');
- this.materialToolbar_.hidden = false;
- this.materialToolbar_.addEventListener('save', this.save_.bind(this));
- this.materialToolbar_.addEventListener('print', this.print_.bind(this));
- this.materialToolbar_.addEventListener('rotate-right',
- this.rotateClockwise_.bind(this));
- this.materialToolbar_.addEventListener('rotate-left',
- this.rotateCounterClockwise_.bind(this));
- // Must attach to mouseup on the plugin element, since it eats mousedown
- // and click events.
- this.plugin_.addEventListener('mouseup',
- this.materialToolbar_.hideDropdowns.bind(this.materialToolbar_));
-
- this.materialToolbar_.docTitle =
- getFilenameFromURL(this.browserApi_.getStreamInfo().originalUrl);
- }
+ document.body.addEventListener('change-page', function(e) {
+ this.viewport_.goToPage(e.detail.page);
+ }.bind(this));
- document.body.addEventListener('change-page', function(e) {
- this.viewport_.goToPage(e.detail.page);
- }.bind(this));
-
- this.toolbarManager_ =
- new ToolbarManager(window, this.materialToolbar_, this.zoomToolbar_);
- }
+ this.toolbarManager_ =
+ new ToolbarManager(window, this.toolbar_, this.zoomToolbar_);
// Set up the ZoomManager.
this.zoomManager_ = new ZoomManager(
@@ -268,13 +252,10 @@ function PDFViewer(browserApi) {
document.addEventListener('mousemove', this.handleMouseEvent_.bind(this));
document.addEventListener('mouseout', this.handleMouseEvent_.bind(this));
- // Parse open pdf parameters.
- this.paramsParser_ =
- new OpenPDFParamsParser(this.getNamedDestination_.bind(this));
var isInTab = this.browserApi_.getStreamInfo().tabId != -1;
var isSourceFileUrl =
- this.browserApi_.getStreamInfo().originalUrl.indexOf('file://') == 0;
- this.navigator_ = new Navigator(this.browserApi_.getStreamInfo().originalUrl,
+ this.originalUrl_.indexOf('file://') == 0;
+ this.navigator_ = new Navigator(this.originalUrl_,
this.viewport_, this.paramsParser_,
onNavigateInCurrentTab.bind(undefined,
isInTab,
@@ -284,8 +265,7 @@ function PDFViewer(browserApi) {
new ViewportScroller(this.viewport_, this.plugin_, window);
// Request translated strings.
- if (!this.isPrintPreview_)
- chrome.resourcesPrivate.getStrings('pdf', this.handleStrings_.bind(this));
+ chrome.resourcesPrivate.getStrings('pdf', this.handleStrings_.bind(this));
}
PDFViewer.prototype = {
@@ -303,8 +283,7 @@ PDFViewer.prototype = {
if (shouldIgnoreKeyEvents(document.activeElement) || e.defaultPrevented)
return;
- if (this.isMaterial_)
- this.toolbarManager_.hideToolbarsAfterTimeout(e);
+ this.toolbarManager_.hideToolbarsAfterTimeout(e);
var pageUpHandler = function() {
// Go to the previous page if we are fit-to-page.
@@ -334,7 +313,7 @@ PDFViewer.prototype = {
this.toolbarManager_.showToolbarsForKeyboardNavigation();
return;
case 27: // Escape key.
- if (this.isMaterial_ && !this.isPrintPreview_) {
+ if (!this.isPrintPreview_) {
this.toolbarManager_.hideSingleToolbarLayer();
return;
}
@@ -403,12 +382,9 @@ PDFViewer.prototype = {
}
return;
case 71: // g key.
- if (this.isMaterial_ && this.materialToolbar_ &&
- (e.ctrlKey || e.metaKey)) {
+ if (this.toolbar_ && (e.ctrlKey || e.metaKey) && e.altKey) {
this.toolbarManager_.showToolbars();
- this.materialToolbar_.selectPageNumber();
- // To prevent the default "find text" behaviour in Chrome.
- e.preventDefault();
+ this.toolbar_.selectPageNumber();
}
return;
case 219: // left bracket.
@@ -427,7 +403,7 @@ PDFViewer.prototype = {
type: 'sendKeyEvent',
keyEvent: SerializeKeyEvent(e)
});
- } else if (this.isMaterial_) {
+ } else {
// Show toolbars as a fallback.
if (!(e.shiftKey || e.ctrlKey || e.altKey))
this.toolbarManager_.showToolbars();
@@ -435,12 +411,10 @@ PDFViewer.prototype = {
},
handleMouseEvent_: function(e) {
- if (this.isMaterial_) {
- if (e.type == 'mousemove')
- this.toolbarManager_.handleMouseMove(e);
- else if (e.type == 'mouseout')
- this.toolbarManager_.hideToolbarsForMouseOut();
- }
+ if (e.type == 'mousemove')
+ this.toolbarManager_.handleMouseMove(e);
+ else if (e.type == 'mouseout')
+ this.toolbarManager_.hideToolbarsForMouseOut();
},
/**
@@ -543,19 +517,13 @@ PDFViewer.prototype = {
* @param {number} progress the progress as a percentage.
*/
updateProgress_: function(progress) {
- if (this.isMaterial_) {
- if (this.materialToolbar_)
- this.materialToolbar_.loadProgress = progress;
- } else {
- this.progressBar_.progress = progress;
- }
+ if (this.toolbar_)
+ this.toolbar_.loadProgress = progress;
if (progress == -1) {
// Document load failed.
this.errorScreen_.show();
this.sizer_.style.display = 'none';
- if (!this.isMaterial_)
- this.toolbar_.style.visibility = 'hidden';
if (this.passwordScreen_.active) {
this.passwordScreen_.deny();
this.passwordScreen_.active = false;
@@ -567,15 +535,14 @@ PDFViewer.prototype = {
if (this.lastViewportPosition_)
this.viewport_.position = this.lastViewportPosition_;
this.paramsParser_.getViewportFromUrlParams(
- this.browserApi_.getStreamInfo().originalUrl,
+ this.originalUrl_,
this.handleURLParams_.bind(this));
this.loadState_ = LoadState.SUCCESS;
this.sendDocumentLoadedMessage_();
while (this.delayedScriptingMessages_.length > 0)
this.handleScriptingMessage(this.delayedScriptingMessages_.shift());
- if (this.isMaterial_)
- this.toolbarManager_.hideToolbarsAfterTimeout();
+ this.toolbarManager_.hideToolbarsAfterTimeout();
}
},
@@ -586,21 +553,9 @@ PDFViewer.prototype = {
* @param {Object} strings Dictionary of translated strings
*/
handleStrings_: function(strings) {
- if (this.isMaterial_) {
- this.errorScreen_.strings = strings;
- this.passwordScreen_.strings = strings;
- if (this.materialToolbar_)
- this.materialToolbar_.strings = strings;
- this.zoomToolbar_.strings = strings;
- document.documentElement.lang = strings['language'];
- document.dir = strings['textdirection'];
- } else {
- this.passwordScreen_.text = strings.passwordPrompt;
- this.progressBar_.text = strings.pageLoading;
- if (!this.isPrintPreview_)
- this.progressBar_.style.visibility = 'visible';
- this.errorScreen_.text = strings.pageLoadFailed;
- }
+ window.loadTimeData.data = strings;
+ i18nTemplate.process(document, loadTimeData);
+ this.zoomToolbar_.updateTooltips();
},
/**
@@ -634,13 +589,9 @@ PDFViewer.prototype = {
if (this.pageIndicator_)
this.pageIndicator_.initialFadeIn();
- if (this.isMaterial_) {
- if (this.materialToolbar_) {
- this.materialToolbar_.docLength =
- this.documentDimensions_.pageDimensions.length;
- }
- } else {
- this.toolbar_.initialFadeIn();
+ if (this.toolbar_) {
+ this.toolbar_.docLength =
+ this.documentDimensions_.pageDimensions.length;
}
break;
case 'email':
@@ -692,12 +643,12 @@ PDFViewer.prototype = {
document.title = message.data.title;
} else {
document.title =
- getFilenameFromURL(this.browserApi_.getStreamInfo().originalUrl);
+ getFilenameFromURL(this.originalUrl_);
}
this.bookmarks_ = message.data.bookmarks;
- if (this.isMaterial_ && this.materialToolbar_) {
- this.materialToolbar_.docTitle = document.title;
- this.materialToolbar_.bookmarks = this.bookmarks;
+ if (this.toolbar_) {
+ this.toolbar_.docTitle = document.title;
+ this.toolbar_.bookmarks = this.bookmarks;
}
break;
case 'setIsSelecting':
@@ -749,62 +700,36 @@ PDFViewer.prototype = {
if (!this.documentDimensions_)
return;
- // Update the buttons selected.
- if (!this.isMaterial_) {
- $('fit-to-page-button').classList.remove('polymer-selected');
- $('fit-to-width-button').classList.remove('polymer-selected');
- if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) {
- $('fit-to-page-button').classList.add('polymer-selected');
- } else if (this.viewport_.fittingType ==
- Viewport.FittingType.FIT_TO_WIDTH) {
- $('fit-to-width-button').classList.add('polymer-selected');
- }
- }
-
// Offset the toolbar position so that it doesn't move if scrollbars appear.
var hasScrollbars = this.viewport_.documentHasScrollbars();
var scrollbarWidth = this.viewport_.scrollbarWidth;
var verticalScrollbarWidth = hasScrollbars.vertical ? scrollbarWidth : 0;
var horizontalScrollbarWidth =
hasScrollbars.horizontal ? scrollbarWidth : 0;
- if (this.isMaterial_) {
- // Shift the zoom toolbar to the left by half a scrollbar width. This
- // gives a compromise: if there is no scrollbar visible then the toolbar
- // will be half a scrollbar width further left than the spec but if there
- // is a scrollbar visible it will be half a scrollbar width further right
- // than the spec. In RTL layout, the zoom toolbar is on the left side, but
- // the scrollbar is still on the left, so this is not necessary.
- if (document.dir == 'ltr') {
- this.zoomToolbar_.style.right = -verticalScrollbarWidth +
- (scrollbarWidth / 2) + 'px';
- }
- // Having a horizontal scrollbar is much rarer so we don't offset the
- // toolbar from the bottom any more than what the spec says. This means
- // that when there is a scrollbar visible, it will be a full scrollbar
- // width closer to the bottom of the screen than usual, but this is ok.
- this.zoomToolbar_.style.bottom = -horizontalScrollbarWidth + 'px';
- } else {
- var toolbarRight = Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth);
- var toolbarBottom =
- Math.max(PDFViewer.MIN_TOOLBAR_OFFSET, scrollbarWidth);
- toolbarRight -= verticalScrollbarWidth;
- toolbarBottom -= horizontalScrollbarWidth;
- this.toolbar_.style.right = toolbarRight + 'px';
- this.toolbar_.style.bottom = toolbarBottom + 'px';
- // Hide the toolbar if it doesn't fit in the viewport.
- if (this.toolbar_.offsetLeft < 0 || this.toolbar_.offsetTop < 0)
- this.toolbar_.style.visibility = 'hidden';
- else
- this.toolbar_.style.visibility = 'visible';
+
+ // Shift the zoom toolbar to the left by half a scrollbar width. This
+ // gives a compromise: if there is no scrollbar visible then the toolbar
+ // will be half a scrollbar width further left than the spec but if there
+ // is a scrollbar visible it will be half a scrollbar width further right
+ // than the spec. In RTL layout, the zoom toolbar is on the left side, but
+ // the scrollbar is still on the right, so this is not necessary.
+ if (!isRTL()) {
+ this.zoomToolbar_.style.right = -verticalScrollbarWidth +
+ (scrollbarWidth / 2) + 'px';
}
+ // Having a horizontal scrollbar is much rarer so we don't offset the
+ // toolbar from the bottom any more than what the spec says. This means
+ // that when there is a scrollbar visible, it will be a full scrollbar
+ // width closer to the bottom of the screen than usual, but this is ok.
+ this.zoomToolbar_.style.bottom = -horizontalScrollbarWidth + 'px';
// Update the page indicator.
var visiblePage = this.viewport_.getMostVisiblePage();
- if (this.materialToolbar_)
- this.materialToolbar_.pageNo = visiblePage + 1;
+ if (this.toolbar_)
+ this.toolbar_.pageNo = visiblePage + 1;
- // TODO(raymes): Give pageIndicator_ the same API as materialToolbar_.
+ // TODO(raymes): Give pageIndicator_ the same API as toolbar_.
if (this.pageIndicator_) {
this.pageIndicator_.index = visiblePage;
if (this.documentDimensions_.pageDimensions.length > 1 &&
@@ -933,7 +858,7 @@ PDFViewer.prototype = {
else if (message.type == 'documentLoaded')
targetOrigin = '*';
else
- targetOrigin = this.browserApi_.getStreamInfo().originalUrl;
+ targetOrigin = this.originalUrl_;
this.parentWindow_.postMessage(message, targetOrigin);
}
},
diff --git a/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js b/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
index 06fc8b546c4..28bf7959755 100644
--- a/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
+++ b/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
@@ -56,7 +56,8 @@ function PDFScriptingAPI(window, plugin) {
this.setPlugin(plugin);
window.addEventListener('message', function(event) {
- if (event.origin != 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai') {
+ if (event.origin != 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai' &&
+ event.origin != 'chrome://print') {
console.error('Received message that was not from the extension: ' +
event);
return;
@@ -271,26 +272,13 @@ PDFScriptingAPI.prototype = {
function PDFCreateOutOfProcessPlugin(src) {
var client = new PDFScriptingAPI(window);
var iframe = window.document.createElement('iframe');
+ iframe.setAttribute('src', 'pdf_preview.html?' + src);
// Prevent the frame from being tab-focusable.
iframe.setAttribute('tabindex', '-1');
- // TODO(raymes): This below is a hack to tell if the material design PDF UI
- // has been enabled. Remove this as soon as we remove the material design PDF
- // flag.
- var EXTENSION_URL = 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/';
- var PAGE_NAME = 'index.html';
- var MATERIAL_PAGE_NAME = 'index-material.html';
- fetch(EXTENSION_URL + PAGE_NAME, {
- method: 'get'
- }).then(function() {
- iframe.setAttribute('src', EXTENSION_URL + PAGE_NAME + '?' + src);
- }, function() {
- iframe.setAttribute('src', EXTENSION_URL + MATERIAL_PAGE_NAME + '?' + src);
- }).then(function() {
- iframe.onload = function() {
- client.setPlugin(iframe.contentWindow);
- };
- });
+ iframe.onload = function() {
+ client.setPlugin(iframe.contentWindow);
+ };
// Add the functions to the iframe so that they can be called directly.
iframe.setViewportChangedCallback =
diff --git a/chromium/chrome/browser/resources/pdf/toolbar_manager.js b/chromium/chrome/browser/resources/pdf/toolbar_manager.js
index bef7cf8a41c..2bef16f8737 100644
--- a/chromium/chrome/browser/resources/pdf/toolbar_manager.js
+++ b/chromium/chrome/browser/resources/pdf/toolbar_manager.js
@@ -8,25 +8,19 @@
var HIDE_TIMEOUT = 2000;
/** Time in ms after force hide before toolbar is shown again. */
var FORCE_HIDE_TIMEOUT = 1000;
-/** Velocity required in a mousemove to reveal the UI (pixels/sample). */
-var SHOW_VELOCITY = 25;
+/**
+ * Velocity required in a mousemove to reveal the UI (pixels/ms). This is
+ * intended to be high enough that a fast flick of the mouse is required to
+ * reach it.
+ */
+var SHOW_VELOCITY = 10;
/** Distance from the top of the screen required to reveal the toolbars. */
var TOP_TOOLBAR_REVEAL_DISTANCE = 100;
/** Distance from the bottom-right of the screen required to reveal toolbars. */
var SIDE_TOOLBAR_REVEAL_DISTANCE_RIGHT = 150;
var SIDE_TOOLBAR_REVEAL_DISTANCE_BOTTOM = 250;
-/**
- * Whether a mousemove event is high enough velocity to reveal the toolbars.
- * @param {MouseEvent} e Event to test.
- * @return {boolean} true if the event is a high velocity mousemove, false
- * otherwise.
- */
-function isHighVelocityMouseMove(e) {
- return e.type == 'mousemove' &&
- e.movementX * e.movementX + e.movementY * e.movementY >
- SHOW_VELOCITY * SHOW_VELOCITY;
-}
+
/**
* @param {MouseEvent} e Event to test.
@@ -38,12 +32,13 @@ function isMouseNearTopToolbar(e) {
/**
* @param {MouseEvent} e Event to test.
+ * @param {Window} window Window to test against.
* @return {boolean} True if the mouse is close to the bottom-right of the
* screen.
*/
-function isMouseNearSideToolbar(e) {
+function isMouseNearSideToolbar(e, window) {
var atSide = e.x > window.innerWidth - SIDE_TOOLBAR_REVEAL_DISTANCE_RIGHT;
- if (document.dir == 'rtl')
+ if (isRTL())
atSide = e.x < SIDE_TOOLBAR_REVEAL_DISTANCE_RIGHT;
var atBottom = e.y > window.innerHeight - SIDE_TOOLBAR_REVEAL_DISTANCE_BOTTOM;
return atSide && atBottom;
@@ -71,6 +66,8 @@ function ToolbarManager(window, toolbar, zoomToolbar) {
this.keyboardNavigationActive = false;
+ this.lastMovementTimestamp = null;
+
this.window_.addEventListener('resize', this.resizeDropdowns_.bind(this));
this.resizeDropdowns_();
}
@@ -79,7 +76,7 @@ ToolbarManager.prototype = {
handleMouseMove: function(e) {
this.isMouseNearTopToolbar_ = this.toolbar_ && isMouseNearTopToolbar(e);
- this.isMouseNearSideToolbar_ = isMouseNearSideToolbar(e);
+ this.isMouseNearSideToolbar_ = isMouseNearSideToolbar(e, this.window_);
this.keyboardNavigationActive = false;
var touchInteractionActive =
@@ -103,7 +100,7 @@ ToolbarManager.prototype = {
// Show the toolbars if the mouse is near the top or bottom-right of the
// screen, if the mouse moved fast, or if the touchscreen was tapped.
if (this.isMouseNearTopToolbar_ || this.isMouseNearSideToolbar_ ||
- isHighVelocityMouseMove(e) || touchInteractionActive) {
+ this.isHighVelocityMouseMove_(e) || touchInteractionActive) {
if (this.sideToolbarAllowedOnly_)
this.zoomToolbar_.show();
else
@@ -113,6 +110,40 @@ ToolbarManager.prototype = {
},
/**
+ * Whether a mousemove event is high enough velocity to reveal the toolbars.
+ * @param {MouseEvent} e Event to test.
+ * @return {boolean} true if the event is a high velocity mousemove, false
+ * otherwise.
+ * @private
+ */
+ isHighVelocityMouseMove_: function(e) {
+ if (e.type == 'mousemove') {
+ if (this.lastMovementTimestamp == null) {
+ this.lastMovementTimestamp = this.getCurrentTimestamp_();
+ } else {
+ var movement =
+ Math.sqrt(e.movementX * e.movementX + e.movementY * e.movementY);
+ var newTime = this.getCurrentTimestamp_();
+ var interval = newTime - this.lastMovementTimestamp;
+ this.lastMovementTimestamp = newTime;
+
+ if (interval != 0)
+ return movement / interval > SHOW_VELOCITY;
+ }
+ }
+ return false;
+ },
+
+ /**
+ * Wrapper around Date.now() to make it easily replaceable for testing.
+ * @return {int}
+ * @private
+ */
+ getCurrentTimestamp_: function() {
+ return Date.now();
+ },
+
+ /**
* Display both UI toolbars.
*/
showToolbars: function() {
diff --git a/chromium/chrome/browser/resources/plugin_metadata/plugins_linux.json b/chromium/chrome/browser/resources/plugin_metadata/plugins_linux.json
index 940a126cc2b..80f8b18694d 100644
--- a/chromium/chrome/browser/resources/plugin_metadata/plugins_linux.json
+++ b/chromium/chrome/browser/resources/plugin_metadata/plugins_linux.json
@@ -1,5 +1,5 @@
{
- "x-version": 9,
+ "x-version": 10,
"google-talk": {
"mime_types": [
],
@@ -80,9 +80,9 @@
],
"versions": [
{
- "version": "19.0.0.245",
+ "version": "20.0.0.267",
"status": "up_to_date",
- "reference": "https://helpx.adobe.com/security/products/flash-player/apsb15-28.html"
+ "reference": "https://helpx.adobe.com/security/products/flash-player/apsb16-01.html"
}
],
"lang": "en-US",
diff --git a/chromium/chrome/browser/resources/plugin_metadata/plugins_mac.json b/chromium/chrome/browser/resources/plugin_metadata/plugins_mac.json
index 8b8ef6eec35..2979a50e54f 100644
--- a/chromium/chrome/browser/resources/plugin_metadata/plugins_mac.json
+++ b/chromium/chrome/browser/resources/plugin_metadata/plugins_mac.json
@@ -1,5 +1,5 @@
{
- "x-version": 15,
+ "x-version": 16,
"google-talk": {
"mime_types": [
],
@@ -115,9 +115,9 @@
],
"versions": [
{
- "version": "19.0.0.245",
+ "version": "20.0.0.267",
"status": "requires_authorization",
- "reference": "https://helpx.adobe.com/security/products/flash-player/apsb15-28.html"
+ "reference": "https://helpx.adobe.com/security/products/flash-player/apsb16-01.html"
}
],
"lang": "en-US",
diff --git a/chromium/chrome/browser/resources/plugin_metadata/plugins_win.json b/chromium/chrome/browser/resources/plugin_metadata/plugins_win.json
index da9f9ff5e26..9ba115b51f6 100644
--- a/chromium/chrome/browser/resources/plugin_metadata/plugins_win.json
+++ b/chromium/chrome/browser/resources/plugin_metadata/plugins_win.json
@@ -1,5 +1,5 @@
{
- "x-version": 24,
+ "x-version": 25,
"google-talk": {
"mime_types": [
],
@@ -137,9 +137,9 @@
],
"versions": [
{
- "version": "19.0.0.245",
+ "version": "20.0.0.267",
"status": "requires_authorization",
- "reference": "https://helpx.adobe.com/security/products/flash-player/apsb15-28.html"
+ "reference": "https://helpx.adobe.com/security/products/flash-player/apsb16-01.html"
}
],
"lang": "en-US",
diff --git a/chromium/chrome/browser/resources/print_preview/data/app_state.js b/chromium/chrome/browser/resources/print_preview/data/app_state.js
index 100d848e5ea..b782f4ea3d1 100644
--- a/chromium/chrome/browser/resources/print_preview/data/app_state.js
+++ b/chromium/chrome/browser/resources/print_preview/data/app_state.js
@@ -149,10 +149,8 @@ cr.define('print_preview', function() {
* layer.
* @param {?string} serializedAppStateStr Serialized string representation
* of the app state.
- * @param {?string} systemDefaultDestinationId ID of the system default
- * destination.
*/
- init: function(serializedAppStateStr, systemDefaultDestinationId) {
+ init: function(serializedAppStateStr) {
if (serializedAppStateStr) {
try {
var state = JSON.parse(serializedAppStateStr);
@@ -167,17 +165,6 @@ cr.define('print_preview', function() {
// Set some state defaults.
this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED] = false;
}
- // Default to system destination, if no destination was selected.
- if (!this.state_[AppState.Field.SELECTED_DESTINATION_ID] ||
- !this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN]) {
- if (systemDefaultDestinationId) {
- this.state_[AppState.Field.SELECTED_DESTINATION_ID] =
- systemDefaultDestinationId;
- this.state_[AppState.Field.SELECTED_DESTINATION_ORIGIN] =
- print_preview.Destination.Origin.LOCAL;
- this.state_[AppState.Field.SELECTED_DESTINATION_ACCOUNT] = '';
- }
- }
},
/**
diff --git a/chromium/chrome/browser/resources/print_preview/data/destination_store.js b/chromium/chrome/browser/resources/print_preview/data/destination_store.js
index 5aeaffe2c33..86465a5a46c 100644
--- a/chromium/chrome/browser/resources/print_preview/data/destination_store.js
+++ b/chromium/chrome/browser/resources/print_preview/data/destination_store.js
@@ -8,6 +8,96 @@ cr.define('print_preview', function() {
/**
* A data store that stores destinations and dispatches events when the data
* store changes.
+ * @param {!Array<!print_preview.Destination.Origin>} origins Match
+ * destinations from these origins.
+ * @param {RegExp} idRegExp Match destination's id.
+ * @param {RegExp} displayNameRegExp Match destination's displayName.
+ * @param {boolean} skipVirtualDestinations Whether to ignore virtual
+ * destinations, for example, Save as PDF.
+ * @constructor
+ */
+ function DestinationMatch(
+ origins, idRegExp, displayNameRegExp, skipVirtualDestinations) {
+
+ /** @private {!Array<!print_preview.Destination.Origin>} */
+ this.origins_ = origins;
+
+ /** @private {RegExp} */
+ this.idRegExp_ = idRegExp;
+
+ /** @private {RegExp} */
+ this.displayNameRegExp_ = displayNameRegExp;
+
+ /** @private {boolean} */
+ this.skipVirtualDestinations_ = skipVirtualDestinations;
+ };
+
+ DestinationMatch.prototype = {
+
+ /**
+ * @param {!print_preview.Destination.Origin} origin Origin to match.
+ * @return {boolean} Whether the origin is one of the {@code origins_}.
+ */
+ matchOrigin: function(origin) {
+ return arrayContains(this.origins_, origin);
+ },
+
+ /**
+ * @param {string} id Id of the destination.
+ * @param {string} origin Origin of the destination.
+ * @return {boolean} Whether destination is the same as initial.
+ */
+ matchIdAndOrigin: function(id, origin) {
+ return this.matchOrigin(origin) &&
+ this.idRegExp_ &&
+ this.idRegExp_.test(id);
+ },
+
+ /**
+ * @param {!print_preview.Destination} destination Destination to match.
+ * @return {boolean} Whether {@code destination} matches the last user
+ * selected one.
+ */
+ match: function(destination) {
+ if (!this.matchOrigin(destination.origin)) {
+ return false;
+ }
+ if (this.idRegExp_ && !this.idRegExp_.test(destination.id)) {
+ return false;
+ }
+ if (this.displayNameRegExp_ &&
+ !this.displayNameRegExp_.test(destination.displayName)) {
+ return false;
+ }
+ if (this.skipVirtualDestinations_ &&
+ this.isVirtualDestination_(destination)) {
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * @param {!print_preview.Destination} destination Destination to check.
+ * @return {boolean} Whether {@code destination} is virtual, in terms of
+ * destination selection.
+ * @private
+ */
+ isVirtualDestination_: function(destination) {
+ if (destination.origin == print_preview.Destination.Origin.LOCAL) {
+ return arrayContains(
+ [print_preview.Destination.GooglePromotedId.SAVE_AS_PDF],
+ destination.id);
+ }
+ return arrayContains(
+ [print_preview.Destination.GooglePromotedId.DOCS,
+ print_preview.Destination.GooglePromotedId.FEDEX],
+ destination.id);
+ }
+ };
+
+ /**
+ * A data store that stores destinations and dispatches events when the data
+ * store changes.
* @param {!print_preview.NativeLayer} nativeLayer Used to fetch local print
* destinations.
* @param {!print_preview.UserInfo} userInfo User information repository.
@@ -69,11 +159,11 @@ cr.define('print_preview', function() {
/**
* Whether the destination store will auto select the destination that
- * matches the last used destination stored in appState_.
- * @type {boolean}
+ * matches this set of parameters.
+ * @type {print_preview.DestinationMatch}
* @private
*/
- this.isInAutoSelectMode_ = false;
+ this.autoSelectMatchingDestination_ = null;
/**
* Event tracker used to track event listeners of the destination store.
@@ -91,6 +181,13 @@ cr.define('print_preview', function() {
this.pdfPrinterEnabled_ = false;
/**
+ * ID of the system default destination.
+ * @type {?string}
+ * @private
+ */
+ this.systemDefaultDestinationId_ = null;
+
+ /**
* Used to fetch cloud-based print destinations.
* @type {cloudprint.CloudPrintInterface}
* @private
@@ -320,89 +417,287 @@ cr.define('print_preview', function() {
* print_preview.AppState has been initialized.
* @param {boolean} isInAppKioskMode Whether the print preview is in App
* Kiosk mode.
+ * @param {?string} systemDefaultDestinationId ID of the system default
+ * destination.
+ * @param {?string} serializedDefaultDestinationSelectionRulesStr Serialized
+ * default destination selection rules.
*/
- init: function(isInAppKioskMode) {
+ init: function(
+ isInAppKioskMode,
+ systemDefaultDestinationId,
+ serializedDefaultDestinationSelectionRulesStr) {
this.pdfPrinterEnabled_ = !isInAppKioskMode;
- this.isInAutoSelectMode_ = true;
+ this.systemDefaultDestinationId_ = systemDefaultDestinationId;
this.createLocalPdfPrintDestination_();
+
if (!this.appState_.selectedDestinationId ||
!this.appState_.selectedDestinationOrigin) {
- this.selectDefaultDestination_();
- } else {
- var key = this.getDestinationKey_(
- this.appState_.selectedDestinationOrigin,
- this.appState_.selectedDestinationId,
- this.appState_.selectedDestinationAccount || '');
- var candidate = this.destinationMap_[key];
- if (candidate != null) {
- this.selectDestination(candidate);
- } else if (this.appState_.selectedDestinationOrigin ==
- print_preview.Destination.Origin.LOCAL) {
- this.nativeLayer_.startGetLocalDestinationCapabilities(
- this.appState_.selectedDestinationId);
- } else if (this.cloudPrintInterface_ &&
- (this.appState_.selectedDestinationOrigin ==
- print_preview.Destination.Origin.COOKIES ||
- this.appState_.selectedDestinationOrigin ==
- print_preview.Destination.Origin.DEVICE)) {
- this.cloudPrintInterface_.printer(
- this.appState_.selectedDestinationId,
- this.appState_.selectedDestinationOrigin,
- this.appState_.selectedDestinationAccount || '');
- } else if (this.appState_.selectedDestinationOrigin ==
- print_preview.Destination.Origin.PRIVET) {
- // TODO(noamsml): Resolve a specific printer instead of listing all
- // privet printers in this case.
- this.nativeLayer_.startGetPrivetDestinations();
-
- var destinationName = this.appState_.selectedDestinationName || '';
-
- // Create a fake selectedDestination_ that is not actually in the
- // destination store. When the real destination is created, this
- // destination will be overwritten.
- this.selectedDestination_ = new print_preview.Destination(
- this.appState_.selectedDestinationId,
- print_preview.Destination.Type.LOCAL,
- print_preview.Destination.Origin.PRIVET,
- destinationName,
- false /*isRecent*/,
- print_preview.Destination.ConnectionStatus.ONLINE);
- this.selectedDestination_.capabilities =
- this.appState_.selectedDestinationCapabilities;
+ var destinationMatch = this.convertToDestinationMatch_(
+ serializedDefaultDestinationSelectionRulesStr);
+ if (destinationMatch) {
+ this.fetchMatchingDestination_(destinationMatch);
+ return;
+ }
+ }
+
+ if (!this.systemDefaultDestinationId_ &&
+ !(this.appState_.selectedDestinationId &&
+ this.appState_.selectedDestinationOrigin)) {
+ this.selectPdfDestination_();
+ return;
+ }
+
+ var origin = print_preview.Destination.Origin.LOCAL;
+ var id = this.systemDefaultDestinationId_;
+ var account = '';
+ var name = '';
+ var capabilities = null;
+ var extensionId = '';
+ var extensionName = '';
+ if (this.appState_.selectedDestinationId &&
+ this.appState_.selectedDestinationOrigin) {
+ origin = this.appState_.selectedDestinationOrigin;
+ id = this.appState_.selectedDestinationId;
+ account = this.appState_.selectedDestinationAccount || '';
+ name = this.appState_.selectedDestinationName || '';
+ capabilities = this.appState_.selectedDestinationCapabilities;
+ extensionId = this.appState_.selectedDestinationExtensionId || '';
+ extensionName = this.appState_.selectedDestinationExtensionName || '';
+ }
+ var candidate =
+ this.destinationMap_[this.getDestinationKey_(origin, id, account)];
+ if (candidate != null) {
+ this.selectDestination(candidate);
+ return;
+ }
+
+ if (this.fetchPreselectedDestination_(
+ origin,
+ id,
+ account,
+ name,
+ capabilities,
+ extensionId,
+ extensionName)) {
+ return;
+ }
+
+ this.selectPdfDestination_();
+ },
+
+ /**
+ * Attempts to fetch capabilities of the destination identified by the
+ * provided origin, id and account.
+ * @param {!print_preview.Destination.Origin} origin Destination origin.
+ * @param {string} id Destination id.
+ * @param {string} account User account destination is registered for.
+ * @param {string} name Destination display name.
+ * @param {?print_preview.Cdd} capabilities Destination capabilities.
+ * @param {string} extensionId Extension ID associated with this
+ * destination.
+ * @param {string} extensionName Extension name associated with this
+ * destination.
+ * @private
+ */
+ fetchPreselectedDestination_: function(
+ origin, id, account, name, capabilities, extensionId, extensionName) {
+ this.autoSelectMatchingDestination_ =
+ this.createExactDestinationMatch_(origin, id);
+
+ if (origin == print_preview.Destination.Origin.LOCAL) {
+ this.nativeLayer_.startGetLocalDestinationCapabilities(id);
+ return true;
+ }
+
+ if (this.cloudPrintInterface_ &&
+ (origin == print_preview.Destination.Origin.COOKIES ||
+ origin == print_preview.Destination.Origin.DEVICE)) {
+ this.cloudPrintInterface_.printer(id, origin, account);
+ return true;
+ }
+
+ if (origin == print_preview.Destination.Origin.PRIVET) {
+ // TODO(noamsml): Resolve a specific printer instead of listing all
+ // privet printers in this case.
+ this.nativeLayer_.startGetPrivetDestinations();
+
+ // Create a fake selectedDestination_ that is not actually in the
+ // destination store. When the real destination is created, this
+ // destination will be overwritten.
+ this.selectedDestination_ = new print_preview.Destination(
+ id,
+ print_preview.Destination.Type.LOCAL,
+ print_preview.Destination.Origin.PRIVET,
+ name,
+ false /*isRecent*/,
+ print_preview.Destination.ConnectionStatus.ONLINE);
+ this.selectedDestination_.capabilities = capabilities;
+
+ cr.dispatchSimpleEvent(
+ this,
+ DestinationStore.EventType.CACHED_SELECTED_DESTINATION_INFO_READY);
+ return true;
+ }
+
+ if (origin == print_preview.Destination.Origin.EXTENSION) {
+ // TODO(tbarzic): Add support for requesting a single extension's
+ // printer list.
+ this.startLoadExtensionDestinations();
+
+ this.selectedDestination_ =
+ print_preview.ExtensionDestinationParser.parse({
+ extensionId: extensionId,
+ extensionName: extensionName,
+ id: id,
+ name: name
+ });
+
+ if (capabilities) {
+ this.selectedDestination_.capabilities = capabilities;
cr.dispatchSimpleEvent(
- this,
- DestinationStore.EventType.CACHED_SELECTED_DESTINATION_INFO_READY);
- } else if (this.appState_.selectedDestinationOrigin ==
- print_preview.Destination.Origin.EXTENSION) {
- // TODO(tbarzic): Add support for requesting a single extension's
- // printer list.
- this.startLoadExtensionDestinations();
-
- this.selectedDestination_ =
- print_preview.ExtensionDestinationParser.parse({
- extensionId: this.appState_.selectedDestinationExtensionId,
- extensionName: this.appState_.selectedDestinationExtensionName,
- id: this.appState_.selectedDestinationId,
- name: this.appState_.selectedDestinationName || ''
- });
-
- if (this.appState_.selectedDestinationCapabilities) {
- this.selectedDestination_.capabilities =
- this.appState_.selectedDestinationCapabilities;
-
- cr.dispatchSimpleEvent(
- this,
- DestinationStore.EventType
- .CACHED_SELECTED_DESTINATION_INFO_READY);
- }
- } else {
- this.selectDefaultDestination_();
+ this,
+ DestinationStore.EventType
+ .CACHED_SELECTED_DESTINATION_INFO_READY);
}
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * Attempts to find a destination matching the provided rules.
+ * @param {!print_preview.DestinationMatch} destinationMatch Rules to match.
+ * @private
+ */
+ fetchMatchingDestination_: function(destinationMatch) {
+ this.autoSelectMatchingDestination_ = destinationMatch;
+
+ if (destinationMatch.matchOrigin(
+ print_preview.Destination.Origin.LOCAL)) {
+ this.startLoadLocalDestinations();
+ }
+ if (destinationMatch.matchOrigin(
+ print_preview.Destination.Origin.PRIVET)) {
+ this.startLoadPrivetDestinations();
+ }
+ if (destinationMatch.matchOrigin(
+ print_preview.Destination.Origin.EXTENSION)) {
+ this.startLoadExtensionDestinations();
+ }
+ if (destinationMatch.matchOrigin(
+ print_preview.Destination.Origin.COOKIES) ||
+ destinationMatch.matchOrigin(
+ print_preview.Destination.Origin.DEVICE) ||
+ destinationMatch.matchOrigin(
+ print_preview.Destination.Origin.PROFILE)) {
+ this.startLoadCloudDestinations();
}
},
/**
+ * @param {?string} serializedDefaultDestinationSelectionRulesStr Serialized
+ * default destination selection rules.
+ * @return {!print_preview.DestinationMatch} Creates rules matching
+ * previously selected destination.
+ * @private
+ */
+ convertToDestinationMatch_: function(
+ serializedDefaultDestinationSelectionRulesStr) {
+ var matchRules = null;
+ try {
+ if (serializedDefaultDestinationSelectionRulesStr) {
+ matchRules =
+ JSON.parse(serializedDefaultDestinationSelectionRulesStr);
+ }
+ } catch(e) {
+ console.error(
+ 'Failed to parse defaultDestinationSelectionRules: ' + e);
+ }
+ if (!matchRules)
+ return;
+
+ var isLocal = !matchRules.kind || matchRules.kind == 'local';
+ var isCloud = !matchRules.kind || matchRules.kind == 'cloud';
+ if (!isLocal && !isCloud) {
+ console.error('Unsupported type: "' + matchRules.kind + '"');
+ return null;
+ }
+
+ var origins = [];
+ if (isLocal) {
+ origins.push(print_preview.Destination.Origin.LOCAL);
+ origins.push(print_preview.Destination.Origin.PRIVET);
+ origins.push(print_preview.Destination.Origin.EXTENSION);
+ }
+ if (isCloud) {
+ origins.push(print_preview.Destination.Origin.COOKIES);
+ origins.push(print_preview.Destination.Origin.DEVICE);
+ origins.push(print_preview.Destination.Origin.PROFILE);
+ }
+
+ var idRegExp = null;
+ try {
+ if (matchRules.idPattern) {
+ idRegExp = new RegExp(matchRules.idPattern || '.*');
+ }
+ } catch (e) {
+ console.error('Failed to parse regexp for "id": ' + e);
+ }
+
+ var displayNameRegExp = null;
+ try {
+ if (matchRules.namePattern) {
+ displayNameRegExp = new RegExp(matchRules.namePattern || '.*');
+ }
+ } catch (e) {
+ console.error('Failed to parse regexp for "name": ' + e);
+ }
+
+ return new DestinationMatch(
+ origins,
+ idRegExp,
+ displayNameRegExp,
+ true /*skipVirtualDestinations*/);
+ },
+
+ /**
+ * @return {print_preview.DestinationMatch} Creates rules matching
+ * previously selected destination.
+ * @private
+ */
+ convertPreselectedToDestinationMatch_: function() {
+ if (this.appState_.selectedDestinationId &&
+ this.appState_.selectedDestinationOrigin) {
+ return this.createExactDestinationMatch_(
+ this.appState_.selectedDestinationOrigin,
+ this.appState_.selectedDestinationId);
+ }
+ if (this.systemDefaultDestinationId_) {
+ return this.createExactDestinationMatch_(
+ print_preview.Destination.Origin.LOCAL,
+ this.systemDefaultDestinationId_);
+ }
+ return null;
+ },
+
+ /**
+ * @param {!print_preview.Destination.Origin} origin Destination origin.
+ * @param {string} id Destination id.
+ * @return {!print_preview.DestinationMatch} Creates rules matching
+ * provided destination.
+ * @private
+ */
+ createExactDestinationMatch_: function(origin, id) {
+ return new DestinationMatch(
+ [origin],
+ new RegExp('^' + id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '$'),
+ null /*displayNameRegExp*/,
+ false /*skipVirtualDestinations*/);
+ },
+
+ /**
* Sets the destination store's Google Cloud Print interface.
* @param {!cloudprint.CloudPrintInterface} cloudPrintInterface Interface
* to set.
@@ -448,7 +743,7 @@ cr.define('print_preview', function() {
* @param {print_preview.Destination} destination Destination to select.
*/
selectDestination: function(destination) {
- this.isInAutoSelectMode_ = false;
+ this.autoSelectMatchingDestination_ = null;
// When auto select expires, DESTINATION_SELECT event has to be dispatched
// anyway (see isAutoSelectDestinationInProgress() logic).
if (this.autoSelectTimeout_) {
@@ -534,7 +829,7 @@ cr.define('print_preview', function() {
* Selects 'Save to PDF' destination (since it always exists).
* @private
*/
- selectDefaultDestination_: function() {
+ selectPdfDestination_: function() {
var saveToPdfKey = this.getDestinationKey_(
print_preview.Destination.Origin.LOCAL,
print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
@@ -543,6 +838,32 @@ cr.define('print_preview', function() {
this.destinationMap_[saveToPdfKey] || this.destinations_[0] || null);
},
+ /**
+ * Attempts to select system default destination with a fallback to
+ * 'Save to PDF' destination.
+ * @private
+ */
+ selectDefaultDestination_: function() {
+ if (this.systemDefaultDestinationId_) {
+ if (this.autoSelectMatchingDestination_ &&
+ !this.autoSelectMatchingDestination_.matchIdAndOrigin(
+ this.systemDefaultDestinationId_,
+ print_preview.Destination.Origin.LOCAL)) {
+ if (this.fetchPreselectedDestination_(
+ print_preview.Destination.Origin.LOCAL,
+ this.systemDefaultDestinationId_,
+ '' /*account*/,
+ '' /*name*/,
+ null /*capabilities*/,
+ '' /*extensionId*/,
+ '' /*extensionName*/)) {
+ return;
+ }
+ }
+ }
+ this.selectPdfDestination_();
+ },
+
/** Initiates loading of local print destinations. */
startLoadLocalDestinations: function() {
if (!this.hasLoadedAllLocalDestinations_) {
@@ -711,20 +1032,21 @@ cr.define('print_preview', function() {
/**
* Dispatches DESTINATIONS_INSERTED event. In auto select mode, tries to
- * update selected destination to match {@code appState_} settings.
+ * update selected destination to match
+ * {@code autoSelectMatchingDestination_}.
* @param {print_preview.Destination=} opt_destination The only destination
* that was changed or skipped if possibly more than one destination was
- * changed. Used as a hint to limit destination search scope in
- * {@code isInAutoSelectMode_).
+ * changed. Used as a hint to limit destination search scope against
+ * {@code autoSelectMatchingDestination_).
*/
destinationsInserted_: function(opt_destination) {
cr.dispatchSimpleEvent(
this, DestinationStore.EventType.DESTINATIONS_INSERTED);
- if (this.isInAutoSelectMode_) {
+ if (this.autoSelectMatchingDestination_) {
var destinationsToSearch =
opt_destination && [opt_destination] || this.destinations_;
destinationsToSearch.some(function(destination) {
- if (this.matchPersistedDestination_(destination)) {
+ if (this.autoSelectMatchingDestination_.match(destination)) {
this.selectDestination(destination);
return true;
}
@@ -783,8 +1105,13 @@ cr.define('print_preview', function() {
this, DestinationStore.EventType.DESTINATION_SEARCH_DONE);
// Clear initially selected (cached) extension destination if it hasn't
// been found among reported extension destinations.
- if (this.isInAutoSelectMode_ && this.selectedDestination_.isExtension)
+ if (this.autoSelectMatchingDestination_ &&
+ this.autoSelectMatchingDestination_.matchOrigin(
+ print_preview.Destination.Origin.EXTENSION) &&
+ this.selectedDestination_ &&
+ this.selectedDestination_.isExtension) {
this.selectDefaultDestination_();
+ }
},
/**
@@ -968,9 +1295,9 @@ cr.define('print_preview', function() {
onGetCapabilitiesFail_: function(event) {
console.error('Failed to get print capabilities for printer ' +
event.destinationId);
- if (this.isInAutoSelectMode_ &&
- this.sameAsPersistedDestination_(event.destinationId,
- event.destinationOrigin)) {
+ if (this.autoSelectMatchingDestination_ &&
+ this.autoSelectMatchingDestination_.matchIdAndOrigin(
+ event.destinationId, event.destinationOrigin)) {
this.selectDefaultDestination_();
}
},
@@ -1015,9 +1342,9 @@ cr.define('print_preview', function() {
* @private
*/
onCloudPrintPrinterFailed_: function(event) {
- if (this.isInAutoSelectMode_ &&
- this.sameAsPersistedDestination_(event.destinationId,
- event.destinationOrigin)) {
+ if (this.autoSelectMatchingDestination_ &&
+ this.autoSelectMatchingDestination_.matchIdAndOrigin(
+ event.destinationId, event.destinationOrigin)) {
console.error(
'Failed to fetch last used printer caps: ' + event.destinationId);
this.selectDefaultDestination_();
@@ -1112,7 +1439,8 @@ cr.define('print_preview', function() {
*/
onDestinationsReload_: function() {
this.reset_();
- this.isInAutoSelectMode_ = true;
+ this.autoSelectMatchingDestination_ =
+ this.convertPreselectedToDestinationMatch_();
this.createLocalPdfPrintDestination_();
this.startLoadAllDestinations();
},
@@ -1138,30 +1466,6 @@ cr.define('print_preview', function() {
getKey_: function(destination) {
return this.getDestinationKey_(
destination.origin, destination.id, destination.account);
- },
-
- /**
- * @param {!print_preview.Destination} destination Destination to match.
- * @return {boolean} Whether {@code destination} matches the last user
- * selected one.
- * @private
- */
- matchPersistedDestination_: function(destination) {
- return !this.appState_.selectedDestinationId ||
- !this.appState_.selectedDestinationOrigin ||
- this.sameAsPersistedDestination_(
- destination.id, destination.origin);
- },
-
- /**
- * @param {?string} id Id of the destination.
- * @param {?string} origin Oring of the destination.
- * @return {boolean} Whether destination is the same as initial.
- * @private
- */
- sameAsPersistedDestination_: function(id, origin) {
- return id == this.appState_.selectedDestinationId &&
- origin == this.appState_.selectedDestinationOrigin;
}
};
diff --git a/chromium/chrome/browser/resources/print_preview/native_layer.js b/chromium/chrome/browser/resources/print_preview/native_layer.js
index 94123fae6e3..7bda60e6c3b 100644
--- a/chromium/chrome/browser/resources/print_preview/native_layer.js
+++ b/chromium/chrome/browser/resources/print_preview/native_layer.js
@@ -67,8 +67,8 @@ cr.define('print_preview', function() {
this.onEnableManipulateSettingsForTest_.bind(this);
global.printPresetOptionsFromDocument =
this.onPrintPresetOptionsFromDocument_.bind(this);
- global.detectDistillablePage =
- this.detectDistillablePage_.bind(this);
+ global.allowDistillPage =
+ this.allowDistillPage_.bind(this);
global.onProvisionalPrinterResolved =
this.onProvisionalDestinationResolved_.bind(this);
global.failedToResolveProvisionalPrinter =
@@ -357,6 +357,7 @@ cr.define('print_preview', function() {
'landscape': printTicketStore.landscape.getValue(),
'color': this.getNativeColorModel_(destination, printTicketStore.color),
'headerFooterEnabled': printTicketStore.headerFooter.getValue(),
+ 'distillPage': printTicketStore.distillPage.getValue(),
'marginsType': printTicketStore.marginsType.getValue(),
'generateDraftData': true, // TODO(rltoscano): What should this be?
'duplex': printTicketStore.duplex.getValue() ?
@@ -489,7 +490,8 @@ cr.define('print_preview', function() {
initialSettings['documentHasSelection'] || false,
initialSettings['shouldPrintSelectionOnly'] || false,
initialSettings['printerName'] || null,
- initialSettings['appState'] || null);
+ initialSettings['appState'] || null,
+ initialSettings['defaultDestinationSelectionRules'] || null);
var initialSettingsSetEvent = new Event(
NativeLayer.EventType.INITIAL_SETTINGS_SET);
@@ -740,13 +742,10 @@ cr.define('print_preview', function() {
},
/**
- * Updates the interface to show the "Distill Page" option
- * when PrintPreviewHandler::HandleIsPageDistillableResult
- * determines that this page can be distilled with the
- * DOM Distiller.
+ * Updates the interface to show the "Simplify Page" option.
* @private
*/
- detectDistillablePage_: function() {
+ allowDistillPage_: function() {
var allowDistillPageEvent = new Event(
NativeLayer.EventType.ALLOW_DISTILL_PAGE);
this.dispatchEvent(allowDistillPageEvent);
@@ -932,6 +931,8 @@ cr.define('print_preview', function() {
* @param {?string} systemDefaultDestinationId ID of the system default
* destination.
* @param {?string} serializedAppStateStr Serialized app state.
+ * @param {?string} serializedDefaultDestinationSelectionRulesStr Serialized
+ * default destination selection rules.
* @constructor
*/
function NativeInitialSettings(
@@ -946,7 +947,8 @@ cr.define('print_preview', function() {
documentHasSelection,
selectionOnly,
systemDefaultDestinationId,
- serializedAppStateStr) {
+ serializedAppStateStr,
+ serializedDefaultDestinationSelectionRulesStr) {
/**
* Whether the print preview should be in auto-print mode.
@@ -1031,6 +1033,14 @@ cr.define('print_preview', function() {
* @private
*/
this.serializedAppStateStr_ = serializedAppStateStr;
+
+ /**
+ * Serialized default destination selection rules.
+ * @type {?string}
+ * @private
+ */
+ this.serializedDefaultDestinationSelectionRulesStr_ =
+ serializedDefaultDestinationSelectionRulesStr;
};
NativeInitialSettings.prototype = {
@@ -1103,6 +1113,11 @@ cr.define('print_preview', function() {
/** @return {?string} Serialized app state. */
get serializedAppStateStr() {
return this.serializedAppStateStr_;
+ },
+
+ /** @return {?string} Serialized default destination selection rules. */
+ get serializedDefaultDestinationSelectionRulesStr() {
+ return this.serializedDefaultDestinationSelectionRulesStr_;
}
};
diff --git a/chromium/chrome/browser/resources/print_preview/pdf_preview.html b/chromium/chrome/browser/resources/print_preview/pdf_preview.html
new file mode 100644
index 00000000000..ba3ea35b5d6
--- /dev/null
+++ b/chromium/chrome/browser/resources/print_preview/pdf_preview.html
@@ -0,0 +1 @@
+<include src="../pdf/index.html"> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview.css b/chromium/chrome/browser/resources/print_preview/print_preview.css
index 13126ed9182..8e2e04965f2 100644
--- a/chromium/chrome/browser/resources/print_preview/print_preview.css
+++ b/chromium/chrome/browser/resources/print_preview/print_preview.css
@@ -138,6 +138,7 @@ button.loading {
}
#print-preview button.default {
+ font-kerning: none;
font-weight: bold;
}
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview.js b/chromium/chrome/browser/resources/print_preview/print_preview.js
index 81ff8185746..f4936f39202 100644
--- a/chromium/chrome/browser/resources/print_preview/print_preview.js
+++ b/chromium/chrome/browser/resources/print_preview/print_preview.js
@@ -634,9 +634,7 @@ cr.define('print_preview', function() {
this.isInAppKioskMode_ = settings.isInAppKioskMode;
// The following components must be initialized in this order.
- this.appState_.init(
- settings.serializedAppStateStr,
- settings.systemDefaultDestinationId);
+ this.appState_.init(settings.serializedAppStateStr);
this.documentInfo_.init(
settings.isDocumentModifiable,
settings.documentTitle,
@@ -646,7 +644,10 @@ cr.define('print_preview', function() {
settings.decimalDelimeter,
settings.unitType,
settings.selectionOnly);
- this.destinationStore_.init(settings.isInAppKioskMode);
+ this.destinationStore_.init(
+ settings.isInAppKioskMode,
+ settings.systemDefaultDestinationId,
+ settings.serializedDefaultDestinationSelectionRulesStr);
this.appState_.setInitialized();
$('document-title').innerText = settings.documentTitle;
diff --git a/chromium/chrome/browser/resources/print_preview/search/destination_search.js b/chromium/chrome/browser/resources/print_preview/search/destination_search.js
index 0922bca647f..f16cb101d6d 100644
--- a/chromium/chrome/browser/resources/print_preview/search/destination_search.js
+++ b/chromium/chrome/browser/resources/print_preview/search/destination_search.js
@@ -148,6 +148,9 @@ cr.define('print_preview', function() {
if (getIsVisible(this.getChildElement('.cloudprint-promo'))) {
this.metrics_.record(
print_preview.Metrics.DestinationSearchBucket.SIGNIN_PROMPT);
+ chrome.send(
+ 'metricsHandler:recordAction',
+ ['Signin_Impression_FromCloudPrint']);
}
if (this.userInfo_.initialized)
this.onUsersChanged_();
@@ -179,6 +182,9 @@ cr.define('print_preview', function() {
if (this.getIsVisible()) {
this.metrics_.record(
print_preview.Metrics.DestinationSearchBucket.SIGNIN_PROMPT);
+ chrome.send(
+ 'metricsHandler:recordAction',
+ ['Signin_Impression_FromCloudPrint']);
}
this.reflowLists_();
},
diff --git a/chromium/chrome/browser/resources/settings/OWNERS b/chromium/chrome/browser/resources/settings/OWNERS
index 4027f44866c..4391dc29a94 100644
--- a/chromium/chrome/browser/resources/settings/OWNERS
+++ b/chromium/chrome/browser/resources/settings/OWNERS
@@ -1,4 +1,4 @@
-jlklein@chromium.org
+dschuyler@chromium.org
michaelpg@chromium.org
stevenjb@chromium.org
tommycli@chromium.org
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 9f8d894f171..a92d55309dd 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html
+++ b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -1,66 +1,72 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
+<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
-<dom-module id="cr-settings-a11y-page">
- <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css">
+<dom-module id="settings-a11y-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="a11y_page.css">
<template>
- <span i18n-content="a11yExplanation"></span>
- <a i18n-values="href:a11yLearnMoreUrl" i18n-content="learnMore"
- target="_blank"></a>
+ <div class="settings-box">
+ <span i18n-content="a11yExplanation"></span>
+ <a i18n-values="href:a11yLearnMoreUrl" i18n-content="learnMore"
+ target="_blank"></a>
+ </div>
- <cr-settings-checkbox i18n-values="label:optionsInMenuLabel"
- pref="{{prefs.settings.a11y.enable_menu}}">
- </cr-settings-checkbox>
- <cr-settings-checkbox i18n-values="label:largeMouseCursorLabel"
- pref="{{prefs.settings.a11y.large_cursor_enabled}}">
- </cr-settings-checkbox>
- <cr-settings-checkbox i18n-values="label:highContrastLabel"
- pref="{{prefs.settings.a11y.high_contrast_enabled}}">
- </cr-settings-checkbox>
- <cr-settings-checkbox
- pref="{{prefs.settings.a11y.sticky_keys_enabled}}"
- i18n-values="label:stickyKeysLabel; subLabel:stickyKeysSublabel">
- </cr-settings-checkbox>
- <cr-settings-checkbox pref="{{prefs.settings.accessibility}}"
- i18n-values="label:chromeVoxLabel; subLabel:chromeVoxSublabel">
- </cr-settings-checkbox>
- <cr-settings-checkbox i18n-values="label:screenMagnifierLabel"
- pref="{{prefs.settings.a11y.screen_magnifier}}">
- </cr-settings-checkbox>
- <cr-settings-checkbox i18n-values="label:tapDraggingLabel"
- pref="{{prefs.settings.touchpad.enable_tap_dragging}}">
- </cr-settings-checkbox>
- <cr-settings-checkbox i18n-values="label:clickOnStopLabel"
- pref="{{prefs.settings.a11y.autoclick}}">
- </cr-settings-checkbox>
+ <div class="settings-box">
+ <settings-checkbox i18n-values="label:optionsInMenuLabel"
+ pref="{{prefs.settings.a11y.enable_menu}}">
+ </settings-checkbox>
+ <settings-checkbox i18n-values="label:largeMouseCursorLabel"
+ pref="{{prefs.settings.a11y.large_cursor_enabled}}">
+ </settings-checkbox>
+ <settings-checkbox i18n-values="label:highContrastLabel"
+ pref="{{prefs.settings.a11y.high_contrast_enabled}}">
+ </settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.settings.a11y.sticky_keys_enabled}}"
+ i18n-values="label:stickyKeysLabel">
+ </settings-checkbox>
+ <settings-checkbox pref="{{prefs.settings.accessibility}}"
+ i18n-values="label:chromeVoxLabel">
+ </settings-checkbox>
+ <settings-checkbox i18n-values="label:screenMagnifierLabel"
+ pref="{{prefs.settings.a11y.screen_magnifier}}">
+ </settings-checkbox>
+ <settings-checkbox i18n-values="label:tapDraggingLabel"
+ pref="{{prefs.settings.touchpad.enable_tap_dragging}}">
+ </settings-checkbox>
+ <settings-checkbox i18n-values="label:clickOnStopLabel"
+ pref="{{prefs.settings.a11y.autoclick}}">
+ </settings-checkbox>
- <div class="autoclick-delay-label"
- hidden$="[[!prefs.settings.a11y.autoclick]]">
- <span i18n-content="delayBeforeClickLabel"></span>
- <select id="autoclickDropdown"
- value="{{prefs.settings.a11y.autoclick_delay_ms::change}}">
- <option value="200" i18n-content="delayBeforeClickExtremelyShort">
- </option>
- <option value="400" i18n-content="delayBeforeClickVeryShort">
- </option>
- <option value="600" i18n-content="delayBeforeClickShort">
- </option>
- <option value="800" i18n-content="delayBeforeClickLong">
- </option>
- <option value="1000" i18n-content="delayBeforeClickVeryLong">
- </option>
- </select>
- </div>
+ <div class="autoclick-delay-label"
+ hidden$="[[!prefs.settings.a11y.autoclick]]">
+ <span i18n-content="delayBeforeClickLabel"></span>
+ <select id="autoclickDropdown"
+ value="{{prefs.settings.a11y.autoclick_delay_ms::change}}">
+ <option value="200" i18n-content="delayBeforeClickExtremelyShort">
+ </option>
+ <option value="400" i18n-content="delayBeforeClickVeryShort">
+ </option>
+ <option value="600" i18n-content="delayBeforeClickShort">
+ </option>
+ <option value="800" i18n-content="delayBeforeClickLong">
+ </option>
+ <option value="1000" i18n-content="delayBeforeClickVeryLong">
+ </option>
+ </select>
+ </div>
- <cr-settings-checkbox pref="{{prefs.settings.a11y.virtual_keyboard}}"
- i18n-values="label:onScreenKeyboardLabel">
- </cr-settings-checkbox>
+ <settings-checkbox pref="{{prefs.settings.a11y.virtual_keyboard}}"
+ i18n-values="label:onScreenKeyboardLabel">
+ </settings-checkbox>
+ </div>
- <div class="button-strip">
- <paper-button i18n-content="moreFeaturesLink"
- on-tap="onMoreFeaturesTap_"></paper-button>
+ <div class="settings-box">
+ <div class="button-strip">
+ <paper-button i18n-content="moreFeaturesLink"
+ on-tap="onMoreFeaturesTap_"></paper-button>
+ </div>
</div>
</template>
<script src="a11y_page.js"></script>
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 f7286ade6a7..8fb7448b949 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js
+++ b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js
@@ -4,21 +4,21 @@
/**
* @fileoverview
- * 'cr-settings-a11y-page' is the settings page containing accessibility
+ * 'settings-a11y-page' is the settings page containing accessibility
* settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-a11y-page prefs="{{prefs}}"></cr-settings-a11y-page>
+ * <settings-a11y-page prefs="{{prefs}}"></settings-a11y-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-a11y-page
+ * @element settings-a11y-page
*/
Polymer({
- is: 'cr-settings-a11y-page',
+ is: 'settings-a11y-page',
properties: {
/**
diff --git a/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.css b/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.css
index 8c46a6fe5ab..1a33ff32ef5 100644
--- a/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.css
+++ b/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.css
@@ -5,4 +5,5 @@
:host {
display: block;
height: 100%;
+ width: 605px;
}
diff --git a/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.html b/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.html
index f5df256b86a..c52e016f1f2 100644
--- a/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.html
+++ b/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.html
@@ -1,65 +1,91 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://md-settings/downloads_page/downloads_page.html">
<link rel="import" href="chrome://md-settings/languages_page/languages_page.html">
-<link rel="import" href="chrome://md-settings/location_page/location_page.html">
+<link rel="import" href="chrome://md-settings/passwords_and_forms_page/passwords_and_forms_page.html">
<link rel="import" href="chrome://md-settings/privacy_page/privacy_page.html">
+<link rel="import" href="chrome://md-settings/reset_page/reset_page.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_page_visibility.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_section.html">
-<link rel="import" href="chrome://md-settings/sync_page/sync_page.html">
+<link rel="import" href="chrome://md-settings/site_settings/constants.html">
+<link rel="import" href="chrome://md-settings/site_settings/site_settings_category.html">
<if expr="chromeos">
<link rel="import" href="chrome://md-settings/a11y_page/a11y_page.html">
+<link rel="import" href="chrome://md-settings/bluetooth_page/bluetooth_page.html">
<link rel="import" href="chrome://md-settings/date_time_page/date_time_page.html">
</if>
-<dom-module id="cr-settings-advanced-page">
+<dom-module id="settings-advanced-page">
<link rel="import" type="css" href="advanced_page.css">
<template>
<if expr="chromeos">
- <settings-section i18n-values="page-title:dateTimePageTitle"
- current-route="[[currentRoute]]" section="dateTime">
- <cr-settings-date-time-page prefs="{{prefs}}">
- </cr-settings-date-time-page>
- </settings-section>
+ <template is="dom-if" if="[[showPage(pageVisibility.dateTime)]]" restamp>
+ <settings-section i18n-values="page-title:dateTimePageTitle"
+ current-route="[[currentRoute]]" section="dateTime">
+ <settings-date-time-page prefs="{{prefs}}">
+ </settings-date-time-page>
+ </settings-section>
+ </template>
</if>
- <settings-section i18n-values="page-title:siteSettingsLocation"
- current-route="[[currentRoute]]" section="location">
- <cr-settings-location-page prefs="{{prefs}}">
- </cr-settings-location-page>
- </settings-section>
-
- <settings-section i18n-values="page-title:privacyPageTitle"
- current-route="[[currentRoute]]" section="privacy">
- <cr-settings-privacy-page prefs="{{prefs}}"
- current-route="{{currentRoute}}">
- </cr-settings-privacy-page>
- </settings-section>
-
- <settings-section i18n-values="page-title:languagesPageTitle"
- current-route="[[currentRoute]]" section="languages">
- <cr-settings-languages-page prefs="{{prefs}}"
+ <template is="dom-if" if="[[showPage(pageVisibility.privacy)]]" restamp>
+ <settings-section i18n-values="page-title:privacyPageTitle"
+ current-route="[[currentRoute]]" section="privacy">
+ <settings-privacy-page prefs="{{prefs}}"
current-route="{{currentRoute}}">
- </cr-settings-languages-page>
- </settings-section>
-
- <settings-section i18n-values="page-title:downloadsPageTitle"
- current-route="[[currentRoute]]" section="downloads">
- <cr-settings-downloads-page prefs="{{prefs}}">
- </cr-settings-downloads-page>
- </settings-section>
+ </settings-privacy-page>
+ </settings-section>
+ </template>
+<if expr="chromeos">
+ <template is="dom-if" if="[[showPage(pageVisibility.bluetooth)]]" restamp>
+ <settings-section i18n-values="page-title:bluetoothPageTitle"
+ current-route="[[currentRoute]]" section="bluetooth">
+ <settings-bluetooth-page current-route="{{currentRoute}}">
+ </settings-bluetooth-page>
+ </settings-section>
+ </template>
+</if>
+ <template is="dom-if" if="[[showPage(pageVisibility.passwordsAndForms)]]"
+ restamp>
+ <settings-section
+ i18n-values="page-title:passwordsAndAutofillPageTitle"
+ current-route="[[currentRoute]]" section="passwordsAndForms">
+ <settings-passwords-and-forms-page prefs="{{prefs}}"
+ current-route="{{currentRoute}}">
+ </settings-passwords-and-forms-page>
+ </settings-section>
+ </template>
+ <template is="dom-if" if="[[showPage(pageVisibility.languages)]]" restamp>
+ <settings-section i18n-values="page-title:languagesPageTitle"
+ current-route="[[currentRoute]]" section="languages">
+ <settings-languages-page prefs="{{prefs}}"
+ current-route="{{currentRoute}}">
+ </settings-languages-page>
+ </settings-section>
+ </template>
+ <template is="dom-if" if="[[showPage(pageVisibility.downloads)]]" restamp>
+ <settings-section i18n-values="page-title:downloadsPageTitle"
+ current-route="[[currentRoute]]" section="downloads">
+ <settings-downloads-page prefs="{{prefs}}">
+ </settings-downloads-page>
+ </settings-section>
+ </template>
+ <template is="dom-if" if="[[showPage(pageVisibility.reset)]]" restamp>
+ <settings-section i18n-values="page-title:resetPageTitle"
+ current-route="[[currentRoute]]" section="reset">
+ <settings-reset-page></settings-reset-page>
+ </settings-section>
+ </template>
<if expr="chromeos">
<!-- TODO(dbeam): find somewhere to stuff "Add more accessibility features"
on desktop. -->
- <settings-section i18n-values="page-title:a11yPageTitle"
- current-route="[[currentRoute]]" section="a11y">
- <cr-settings-a11y-page prefs="{{prefs}}"></cr-settings-a11y-page>
- </settings-section>
+ <template is="dom-if" if="[[showPage(pageVisibility.a11y)]]" restamp>
+ <settings-section i18n-values="page-title:a11yPageTitle"
+ current-route="[[currentRoute]]" section="a11y">
+ <settings-a11y-page prefs="{{prefs}}"></settings-a11y-page>
+ </settings-section>
+ </template>
</if>
-
- <settings-section i18n-values="page-title:syncPageTitle"
- current-route="[[currentRoute]]" section="sync">
- <cr-settings-sync-page></cr-settings-sync-page>
- </settings-section>
</template>
- <script src="advanced_page.js"></script>
+ <script src="chrome://md-settings/advanced_page/advanced_page.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.js b/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.js
index 0943c0dd85d..90508838ac2 100644
--- a/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.js
+++ b/chromium/chrome/browser/resources/settings/advanced_page/advanced_page.js
@@ -4,22 +4,22 @@
/**
* @fileoverview
- * 'cr-settings-advanced-page' is the settings page containing the advanced
+ * 'settings-advanced-page' is the settings page containing the advanced
* settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-advanced-page prefs="{{prefs}}">
- * </cr-settings-advanced-page>
+ * <settings-advanced-page prefs="{{prefs}}">
+ * </settings-advanced-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-advanced-page
+ * @element settings-advanced-page
*/
Polymer({
- is: 'cr-settings-advanced-page',
+ is: 'settings-advanced-page',
properties: {
/**
@@ -38,4 +38,6 @@ Polymer({
notify: true,
},
},
+
+ behaviors: [SettingsPageVisibility],
});
diff --git a/chromium/chrome/browser/resources/settings/checkbox/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/advanced_page/compiled_resources.gyp
index 10b63b93046..abb1b725f4e 100644
--- a/chromium/chrome/browser/resources/settings/checkbox/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/settings/advanced_page/compiled_resources.gyp
@@ -4,13 +4,12 @@
{
'targets': [
{
- 'target_name': 'checkbox',
+ 'target_name': 'advanced_page',
'variables': {
'depends': [
- '../policy_controllable/policy_controllable.js',
- ],
- 'externs': [
- '../../../../../third_party/closure_compiler/externs/settings_private.js'
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../settings_page/compiled_resources.gyp:settings_page_visibility',
+ '../site_settings/constants.js',
],
},
'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html b/chromium/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
new file mode 100644
index 00000000000..4d8d60457e3
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
@@ -0,0 +1,95 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-slider/paper-slider.html">
+<link rel="import" href="chrome://md-settings/controls/settings_dropdown_menu.html">
+
+<dom-module id="settings-appearance-fonts-page">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css"
+ href="chrome://md-settings/appearance_page/appearance_shared.css">
+ <template>
+ <div>[[selectedStandardFont_]]</div>
+ <div class="settings-box">
+ <div i18n-content="fontSize"></div>
+ <paper-slider id="sizeSlider" value="{{fontSizeIndex_}}"
+ max="[[fontSizeRangeLimit_]]"
+ immediate-value="{{immediateSizeIndex_}}"
+ on-immediate-value-change="immediateSizeIndexChanged_">
+ </paper-slider>
+ </div>
+ <div class="settings-box">
+ <settings-dropdown-menu id="standardFont"
+ i18n-values="label:standardFont"
+ pref="{{prefs.webkit.webprefs.fonts.standard.Zyyy}}"
+ menu-options="[[fontOptions_]]">
+ </settings-dropdown-menu>
+ <div class="settings-column"
+ style$="[[computeStyle_(defaultFontSize_,
+ prefs.webkit.webprefs.fonts.standard.Zyyy.value)]]">
+ <span>[[defaultFontSize_]]</span>:
+ <span i18n-content="loremIpsum"></span>
+ </div>
+ </div>
+ <div class="settings-box">
+ <settings-dropdown-menu id="serifFont"
+ i18n-values="label:serifFont"
+ pref="{{prefs.webkit.webprefs.fonts.serif.Zyyy}}"
+ menu-options="[[fontOptions_]]">
+ </settings-dropdown-menu>
+ <div class="settings-column"
+ style$="[[computeStyle_(defaultFontSize_,
+ prefs.webkit.webprefs.fonts.serif.Zyyy.value)]]">
+ <span>[[defaultFontSize_]]</span>:
+ <span i18n-content="loremIpsum"></span>
+ </div>
+ </div>
+ <div class="settings-box">
+ <settings-dropdown-menu id="sansSerifFont"
+ i18n-values="label:sansSerifFont"
+ pref="{{prefs.webkit.webprefs.fonts.sansserif.Zyyy}}"
+ menu-options="[[fontOptions_]]">
+ </settings-dropdown-menu>
+ <div class="settings-column"
+ style$="{{computeStyle_(defaultFontSize_,
+ prefs.webkit.webprefs.fonts.sansserif.Zyyy.value)}}">
+ <span>[[defaultFontSize_]]</span>:
+ <span i18n-content="loremIpsum"></span>
+ </div>
+ </div>
+ <div class="settings-box">
+ <settings-dropdown-menu id="fixedFont"
+ i18n-values="label:fixedWidthFont"
+ pref="{{prefs.webkit.webprefs.fonts.fixed.Zyyy}}"
+ menu-options="[[fontOptions_]]">
+ </settings-dropdown-menu>
+ <div class="settings-column"
+ style$="[[computeStyle_(defaultFontSize_,
+ prefs.webkit.webprefs.fonts.fixed.Zyyy.value)]]">
+ <span i18n-content="loremIpsum"></span>
+ </div>
+ </div>
+ <div class="settings-box">
+ <div>
+ <div i18n-content="minimumFont"></div>
+ <paper-slider id="minimumSizeSlider" value="{{minimumSizeIndex_}}"
+ max="[[minimumFontSizeRangeLimit_]]"
+ immediate-value="{{immediateMinimumSizeIndex_}}"
+ on-immediate-value-change="immediateMinimumSizeIndexChanged_">
+ </paper-slider>
+ </div>
+ <div style$="[[computeStyle_(minimumFontSize_,
+ prefs.webkit.webprefs.fonts.standard.Zyyy.value)]]">
+ <span>[[minimumFontSize_]]</span>:
+ <span i18n-content="loremIpsum"></span>
+ </div>
+ </div>
+ <div class="settings-box">
+ <settings-dropdown-menu id="encoding"
+ i18n-values="label:encoding"
+ pref="{{prefs.intl.charset_default}}"
+ menu-options="[[encodingOptions_]]">
+ </settings-dropdown-menu>
+ </div>
+ </template>
+ <script src="appearance_fonts_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js b/chromium/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js
new file mode 100644
index 00000000000..6c8edeb4a53
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js
@@ -0,0 +1,236 @@
+// 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.
+
+/**
+ * This is the absolute difference maintained between standard and
+ * fixed-width font sizes. http://crbug.com/91922.
+ * @const
+ */
+var SIZE_DIFFERENCE_FIXED_STANDARD = 3;
+
+var FONT_SIZE_RANGE = [
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
+ 40, 44, 48, 56, 64, 72,
+];
+
+var FONT_SIZE_RANGE_LIMIT = FONT_SIZE_RANGE.length - 1;
+
+var MINIMUM_FONT_SIZE_RANGE = [
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24
+];
+
+var MINIMUM_FONT_SIZE_RANGE_LIMIT = MINIMUM_FONT_SIZE_RANGE.length - 1;
+
+/**
+ * 'settings-appearance-page' is the settings page containing appearance
+ * settings.
+ *
+ * Example:
+ *
+ * <settings-appearance-fonts-page prefs="{{prefs}}">
+ * </settings-appearance-fonts-page>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-appearance-page
+ */
+Polymer({
+ is: 'settings-appearance-fonts-page',
+
+ properties: {
+ /**
+ * The font size used by default.
+ * @private
+ */
+ defaultFontSize_: {
+ type: Number,
+ },
+
+ /**
+ * The value of the font size slider.
+ * @private
+ */
+ fontSizeIndex_: {
+ type: Number,
+ },
+
+ /**
+ * Common font sizes.
+ * @private {!Array<number>}
+ */
+ fontSizeRange_: {
+ readOnly: true,
+ type: Array,
+ value: FONT_SIZE_RANGE,
+ },
+
+ /**
+ * Upper bound of the font size slider.
+ * @private
+ */
+ fontSizeRangeLimit_: {
+ readOnly: true,
+ type: Number,
+ value: MINIMUM_FONT_SIZE_RANGE_LIMIT,
+ },
+
+ /**
+ * The interactive value of the minimum font size slider.
+ * @private
+ */
+ immediateMinimumSizeIndex_: {
+ type: Number,
+ },
+
+ /**
+ * The interactive value of the font size slider.
+ * @private
+ */
+ immediateSizeIndex_: {
+ type: Number,
+ },
+
+ /**
+ * Reasonable, minimum font sizes.
+ * @private {!Array<number>}
+ */
+ minimumFontSizeRange_: {
+ readOnly: true,
+ type: Array,
+ value: MINIMUM_FONT_SIZE_RANGE,
+ },
+
+ /**
+ * Upper bound of the minimum font size slider.
+ * @private
+ */
+ minimumFontSizeRangeLimit_: {
+ readOnly: true,
+ type: Number,
+ value: MINIMUM_FONT_SIZE_RANGE_LIMIT,
+ },
+
+ /**
+ * The font size used at minimum.
+ * @private
+ */
+ minimumFontSize_: {
+ type: Number,
+ },
+
+ /**
+ * The value of the minimum font size slider.
+ * @private
+ */
+ minimumSizeIndex_: {
+ type: Number,
+ },
+
+ /**
+ * Preferences state.
+ */
+ prefs: {
+ type: Object,
+ notify: true,
+ },
+ },
+
+ /**
+ * This is the absolute difference maintained between standard and
+ * fixed-width font sizes. http://crbug.com/91922.
+ * @const
+ */
+ SIZE_DIFFERENCE_FIXED_STANDARD: 3,
+
+ observers: [
+ 'fontSizeChanged_(prefs.webkit.webprefs.default_font_size.value)',
+ 'minimumFontSizeChanged_(prefs.webkit.webprefs.minimum_font_size.value)',
+ ],
+
+ ready: function() {
+ var self = this;
+ cr.define('Settings', function() {
+ return {
+ setFontsData: function() {
+ return self.setFontsData_.apply(self, arguments);
+ },
+ };
+ });
+ chrome.send('fetchFontsData');
+ },
+
+ /**
+ * @param {number} value The intermediate slider value.
+ * @private
+ */
+ immediateSizeIndexChanged_: function(value) {
+ this.set('prefs.webkit.webprefs.default_font_size.value',
+ this.fontSizeRange_[this.immediateSizeIndex_]);
+ },
+
+ /**
+ * @param {number} value The intermediate slider value.
+ * @private
+ */
+ immediateMinimumSizeIndexChanged_: function(value) {
+ this.set('prefs.webkit.webprefs.minimum_font_size.value',
+ this.minimumFontSizeRange_[this.immediateMinimumSizeIndex_]);
+ },
+
+ /**
+ * @param {!Array<{0: string, 1: (string|undefined), 2: (string|undefined)}>}
+ * fontList The font menu options.
+ * @param {!Array<{0: string, 1: string}>} encodingList The encoding menu
+ * options.
+ * @private
+ */
+ setFontsData_: function(fontList, encodingList) {
+ var fontMenuOptions = [];
+ for (var i = 0; i < fontList.length; ++i)
+ fontMenuOptions.push({value: fontList[i][0], name: fontList[i][1]});
+ this.$.standardFont.menuOptions = fontMenuOptions;
+ this.$.serifFont.menuOptions = fontMenuOptions;
+ this.$.sansSerifFont.menuOptions = fontMenuOptions;
+ this.$.fixedFont.menuOptions = fontMenuOptions;
+
+ var encodingMenuOptions = [];
+ for (var i = 0; i < encodingList.length; ++i) {
+ encodingMenuOptions.push({
+ value: encodingList[i][0], name: encodingList[i][1]});
+ }
+ this.$.encoding.menuOptions = encodingMenuOptions;
+ },
+
+ /**
+ * @param {number} value The changed font size slider value.
+ * @private
+ */
+ fontSizeChanged_: function(value) {
+ this.defaultFontSize_ = value;
+ if (!this.$.sizeSlider.dragging) {
+ this.fontSizeIndex_ = this.fontSizeRange_.indexOf(value);
+ this.set('prefs.webkit.webprefs.default_fixed_font_size.value',
+ value - SIZE_DIFFERENCE_FIXED_STANDARD);
+ }
+ },
+
+ /**
+ * @param {number} value The changed font size slider value.
+ * @private
+ */
+ minimumFontSizeChanged_: function(value) {
+ this.minimumFontSize_ = value;
+ if (!this.$.minimumSizeSlider.dragging)
+ this.minimumSizeIndex_ = this.minimumFontSizeRange_.indexOf(value);
+ },
+
+ /**
+ * Creates an html style value.
+ * @param {number} fontSize The font size to use.
+ * @param {string} fontFamily The name of the font family use.
+ * @private
+ */
+ computeStyle_: function(fontSize, fontFamily) {
+ return 'font-size: ' + fontSize + "px; font-family: '" + fontFamily + "';";
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.css b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.css
deleted file mode 100644
index c9cda83b352..00000000000
--- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.css
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-paper-radio-button {
- display: block;
-}
-
-.radio-container {
- display: flex;
-}
-
-.radio-extended {
- align-self: flex-end;
- display: flex;
-}
-
-#change-home-page-section {
- -webkit-margin-start: 40px;
- font-size: 90%;
-}
-
-/* TODO(jhawkins): This does not span the width of the entire paper-material
- * element because our styling of all paper-material includes a fixed margin.
- * This can be fixed by creating a generic content container inside of each
- * paper-material which would have this margin instead.
- *
- * TODO(jhawkins): Share this rule set at a higher level, e.g., to share with
- * the device page.
- */
-hr {
- width: 100%;
-}
-
-#action-container {
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
-}
-
-#action-container > paper-button {
- text-transform: upper-case;
-}
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html
index aaf02f43455..026ddad6001 100644
--- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -1,47 +1,104 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html">
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
-<link rel="import" href="chrome://md-settings/input/input.html">
-<link rel="import" href="chrome://md-settings/radio_group/radio_group.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="chrome://md-settings/controls/settings_dropdown_menu.html">
+<link rel="import" href="chrome://md-settings/controls/settings_input.html">
+<link rel="import" href="chrome://md-settings/controls/settings_radio_group.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="appearance_fonts_page.html">
-<dom-module id="cr-settings-appearance-page">
+<dom-module id="settings-appearance-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css"
- href="chrome://md-settings/appearance_page/appearance_page.css">
+ href="chrome://md-settings/appearance_page/appearance_shared.css">
<link rel="import" type="css" href="chrome://resources/css/widgets.css">
<link rel="import" href="chrome://resources/html/action_link.html">
<template>
- <div id="action-container">
- <paper-button i18n-content="setWallpaper"></paper-button>
- <paper-button id="get-themes" i18n-content="getThemes"
- on-tap="openThemesGallery_">
- </paper-button>
- <paper-button id="resetTheme" i18n-content="resetToDefaultTheme" disabled
- on-tap="resetTheme_">
- </paper-button>
- </div>
- <hr>
- <cr-settings-checkbox pref="{{prefs.browser.show_home_button}}"
- i18n-values="label:showHomeButton">
- </cr-settings-checkbox>
- <template is="dom-if" if="{{prefs.browser.show_home_button.value}}">
- <cr-settings-radio-group pref="{{prefs.homepage_is_newtabpage}}">
- <paper-radio-button name="true"
- >[[i18n_.homePageNtp]]</paper-radio-button>
- <paper-radio-button name="false"
- >[[i18n_.openThisPage]]</paper-radio-button>
- </cr-settings-radio-group>
- <div class="radio-extended">
- <cr-settings-input no-label-float pref="{{prefs.homepage}}"
- label="[[i18n_.onStartupEnterUrl]]">
- </cr-settings-input>
- </div>
- </template>
- <cr-settings-checkbox pref="{{prefs.bookmark_bar.show_on_all_tabs}}"
- i18n-values="label:showBookmarksBar">
- </cr-settings-checkbox>
+ <settings-animated-pages id="pages" current-route="{{currentRoute}}"
+ section="appearance">
+ <neon-animatable id="main">
+ <div class="settings-box split">
+ <div class="start">
+ <iron-icon icon="image:brightness-1"></iron-icon>
+ <paper-button i18n-content="setWallpaper"></paper-button>
+ </div>
+ <iron-icon icon="exit-to-app" disabled></iron-icon>
+ </div>
+ <div class="settings-box split">
+ <div class="start">
+ <iron-icon icon="image:brightness-1"></iron-icon>
+ <paper-button id="get-themes"
+ on-tap="openThemesGallery_"
+ >[[i18n('getThemes')]]</paper-button>
+ </div>
+ <template is="dom-if" if="[[!allowResetTheme_]]">
+ <iron-icon icon="exit-to-app"></iron-icon>
+ </template>
+ <template is="dom-if" if="[[allowResetTheme_]]">
+ <paper-button on-tap="resetTheme_"
+ >[[i18n('resetToDefaultTheme')]]</paper-button>
+ </template>
+ </div>
+ <div class="settings-box split two-line">
+ <settings-checkbox class="start" i18n-values="label:showHomeButton"
+ pref="{{prefs.browser.show_home_button}}">
+ </settings-checkbox>
+ </div>
+ <template is="dom-if" if="[[prefs.browser.show_home_button.value]]">
+ <settings-radio-group pref="{{prefs.homepage_is_newtabpage}}">
+ <paper-radio-button name="true"
+ >[[i18n('homePageNtp')]]</paper-radio-button>
+ <paper-radio-button name="false"
+ >[[i18n('other')]]</paper-radio-button>
+ </settings-radio-group>
+ <div class="radio-extended">
+ <settings-input no-label-float pref="{{prefs.homepage}}"
+ label="[[i18n('exampleDotCom')]]">
+ </settings-input>
+ </div>
+ </template>
+ <div class="settings-box split">
+ <settings-checkbox class="start" i18n-values="label:showBookmarksBar"
+ pref="{{prefs.bookmark_bar.show_on_all_tabs}}">
+ </settings-checkbox>
+ </div>
+ <div class="settings-box split">
+ <div class="start" i18n-content="fontSize"></div>
+ <settings-dropdown-menu id="defaultFontSize"
+ pref="{{prefs.webkit.webprefs.default_font_size}}"
+ menu-options="[[fontSizeOptions_]]">
+ </settings-dropdown-menu>
+ </div>
+ <div class="settings-box split">
+ <div class="start" i18n-content="customizeFonts"></div>
+ <paper-button on-tap="onCustomizeFontsTap_"
+ i18n-content="customizeFonts"></paper-button>
+ </div>
+ <div class="settings-box split">
+ <div class="start" i18n-content="pageZoom"></div>
+ <settings-dropdown-menu id="pageZoom"
+ pref="{{defaultZoomLevel_}}"
+ menu-options="[[pageZoomOptions_]]">
+ </settings-dropdown-menu>
+ </div>
+ </neon-animatable>
+ <neon-animatable id="appearance-fonts">
+ <settings-subheader i18n-values="page-title:customizeFonts">
+ </settings-subheader>
+ <template is="dom-if" if="[[showFontsPage_(currentRoute.subpage.*)]]"
+ restamp>
+ <settings-appearance-fonts-page prefs="{{prefs}}">
+ </settings-appearance-fonts-page>
+ </template>
+ </neon-animatable>
+ </settings-animated-pages>
</template>
<script src="appearance_page.js"></script>
</dom-module>
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 d12a1acc5f3..52691cb918f 100644
--- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js
@@ -3,25 +3,33 @@
// found in the LICENSE file.
/**
- * 'cr-settings-appearance-page' is the settings page containing appearance
+ * 'settings-appearance-page' is the settings page containing appearance
* settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-appearance-page prefs="{{prefs}}">
- * </cr-settings-appearance-page>
+ * <settings-appearance-page prefs="{{prefs}}">
+ * </settings-appearance-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-appearance-page
+ * @element settings-appearance-page
*/
Polymer({
- is: 'cr-settings-appearance-page',
+ is: 'settings-appearance-page',
properties: {
/**
+ * The current active route.
+ */
+ currentRoute: {
+ notify: true,
+ type: Object,
+ },
+
+ /**
* Preferences state.
*/
prefs: {
@@ -30,18 +38,87 @@ Polymer({
},
/**
- * Translated strings used in data binding.
+ * @private
+ */
+ allowResetTheme_: {
+ notify: true,
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * @private
*/
- i18n_: {
+ defaultZoomLevel_: {
+ notify: true,
type: Object,
value: function() {
return {
- homePageNtp: loadTimeData.getString('homePageNtp'),
- openThisPage: loadTimeData.getString('openThisPage'),
- onStartupEnterUrl: loadTimeData.getString('onStartupEnterUrl'),
+ type: chrome.settingsPrivate.PrefType.NUMBER,
};
},
},
+
+ /**
+ * List of options for the font size drop-down menu.
+ * @type {!DropdownMenuOptionList}
+ */
+ fontSizeOptions_: {
+ readOnly: true,
+ type: Array,
+ value: function() {
+ return [
+ {value: 9, name: loadTimeData.getString('verySmall')},
+ {value: 12, name: loadTimeData.getString('small')},
+ {value: 16, name: loadTimeData.getString('medium')},
+ {value: 20, name: loadTimeData.getString('large')},
+ {value: 24, name: loadTimeData.getString('veryLarge')},
+ ];
+ },
+ },
+
+ /**
+ * List of options for the page zoom drop-down menu.
+ * @type {!DropdownMenuOptionList}
+ */
+ pageZoomOptions_: {
+ readOnly: true,
+ type: Array,
+ value: [
+ {value: 25, name: '25%'},
+ {value: 33, name: '33%'},
+ {value: 50, name: '50%'},
+ {value: 67, name: '67%'},
+ {value: 75, name: '75%'},
+ {value: 90, name: '90%'},
+ {value: 100, name: '100%'},
+ {value: 110, name: '110%'},
+ {value: 125, name: '125%'},
+ {value: 150, name: '150%'},
+ {value: 175, name: '175%'},
+ {value: 200, name: '200%'},
+ {value: 300, name: '300%'},
+ {value: 400, name: '400%'},
+ {value: 500, name: '500%'},
+ ],
+ },
+ },
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ observers: [
+ 'zoomLevelChanged_(defaultZoomLevel_.value)',
+ ],
+
+ ready: function() {
+ this.$.defaultFontSize.menuOptions = this.fontSizeOptions_;
+ this.$.pageZoom.menuOptions = this.pageZoomOptions_;
+ // TODO(dschuyler): Look into adding a listener for the
+ // default zoom percent.
+ chrome.settingsPrivate.getDefaultZoomPercent(
+ this.zoomPrefChanged_.bind(this));
},
/** @override */
@@ -55,8 +132,16 @@ Polymer({
this.setResetThemeEnabled.bind(this));
},
+ /**
+ * @param {boolean} enabled Whether the theme reset is available.
+ */
setResetThemeEnabled: function(enabled) {
- this.$.resetTheme.disabled = !enabled;
+ this.allowResetTheme_ = enabled;
+ },
+
+ /** @private */
+ onCustomizeFontsTap_: function() {
+ this.$.pages.setSubpageChain(['appearance-fonts']);
},
/** @private */
@@ -68,4 +153,28 @@ Polymer({
resetTheme_: function() {
chrome.send('resetTheme');
},
+
+ /** @private */
+ showFontsPage_: function() {
+ return this.currentRoute.subpage[0] == 'appearance-fonts';
+ },
+
+ /**
+ * @param {number} percent The integer percentage of the page zoom.
+ * @private
+ */
+ zoomPrefChanged_: function(percent) {
+ this.set('defaultZoomLevel_.value', percent);
+ },
+
+ /**
+ * @param {number} percent The integer percentage of the page zoom.
+ * @private
+ */
+ zoomLevelChanged_: function(percent) {
+ // The |percent| may be undefined on startup.
+ if (percent === undefined)
+ return;
+ chrome.settingsPrivate.setDefaultZoomPercent(percent);
+ },
});
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_shared.css b/chromium/chrome/browser/resources/settings/appearance_page/appearance_shared.css
new file mode 100644
index 00000000000..d81173da5c4
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_shared.css
@@ -0,0 +1,12 @@
+/* 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. */
+
+/*
+ * Keep the slider color consistent throughout the range.
+ */
+paper-slider {
+ --paper-slider-knob-start-border-color: var(--google-blue-700);
+ --paper-slider-knob-start-color: var(--google-blue-700);
+ --paper-slider-pin-start-color: var(--google-blue-700);
+}
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/appearance_page/compiled_resources.gyp
new file mode 100644
index 00000000000..01f0b60b922
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/appearance_page/compiled_resources.gyp
@@ -0,0 +1,53 @@
+# 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.
+{
+ 'targets': [
+ {
+ 'target_name': 'appearance_fonts_page',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/cr.js',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/iron-form-element-behavior-extracted.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/iron-range-behavior/iron-range-behavior-extracted.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-ripple-behavior-extracted.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js',
+ '../../../../../third_party/polymer/v1_0/components-chromium/paper-slider/paper-slider-extracted.js',
+ '../controls/settings_dropdown_menu.js',
+ '../prefs/pref_util.js'
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'appearance_page',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/cr.js',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ '../controls/settings_dropdown_menu.js',
+ '../prefs/pref_util.js',
+ '../settings_page/settings_animated_pages.js'
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js',
+ '../../../../../third_party/closure_compiler/externs/chrome_send.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ ],
+}
diff --git a/chromium/chrome/browser/resources/settings/basic_page/basic_page.css b/chromium/chrome/browser/resources/settings/basic_page/basic_page.css
index 8c46a6fe5ab..1a33ff32ef5 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.css
+++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.css
@@ -5,4 +5,5 @@
:host {
display: block;
height: 100%;
+ width: 605px;
}
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 d104122d469..bad3074b10a 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.html
+++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -1,49 +1,76 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/image-icons.html">
<link rel="import" href="chrome://md-settings/appearance_page/appearance_page.html">
<link rel="import" href="chrome://md-settings/search_page/search_page.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_page_visibility.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_section.html">
<link rel="import" href="chrome://md-settings/on_startup_page/on_startup_page.html">
+<link rel="import" href="chrome://md-settings/people_page/people_page.html">
+<link rel="import" href="chrome://md-settings/reset_page/reset_profile_banner.html">
<if expr="chromeos">
<link rel="import" href="chrome://md-settings/internet_page/internet_page.html">
-<link rel="import" href="chrome://md-settings/users_page/users_page.html">
</if>
-<dom-module id="cr-settings-basic-page">
+<if expr="not chromeos">
+<link rel="import" href="chrome://md-settings/default_browser_page/default_browser_page.html">
+</if>
+
+<dom-module id="settings-basic-page">
<link rel="import" type="css" href="basic_page.css">
<template>
+ <template is="dom-if" if="[[showResetProfileBanner_]]">
+ <settings-reset-profile-banner on-reset-done="onResetDone_">
+ </settings-reset-profile-banner>
+ </template>
+ <template is="dom-if" if="[[showPage(pageVisibility.people)]]" restamp>
+ <settings-section i18n-values="page-title:peoplePageTitle"
+ current-route="[[currentRoute]]" section="people">
+ <settings-people-page prefs="{{prefs}}" current-route="{{currentRoute}}">
+ </settings-people-page>
+ </settings-section>
+ </template>
<if expr="chromeos">
- <settings-section i18n-values="page-title:internetPageTitle"
- current-route="[[currentRoute]]" section="internet">
- <cr-settings-internet-page current-route="{{currentRoute}}">
- </cr-settings-internet-page>
- </settings-section>
+ <template is="dom-if" if="[[showPage(pageVisibility.internet)]]" restamp>
+ <settings-section i18n-values="page-title:internetPageTitle"
+ current-route="[[currentRoute]]" section="internet">
+ <settings-internet-page current-route="{{currentRoute}}">
+ </settings-internet-page>
+ </settings-section>
+ </template>
</if>
- <settings-section i18n-values="page-title:appearancePageTitle"
- current-route="[[currentRoute]]" section="appearance">
- <cr-settings-appearance-page prefs="{{prefs}}">
- </cr-settings-appearance-page>
- </settings-section>
-
- <settings-section i18n-values="page-title:onStartup"
- current-route="[[currentRoute]]" section="on-startup">
- <cr-settings-on-startup-page
- prefs="{{prefs}}" current-route="{{currentRoute}}">
- </cr-settings-on-startup-page>
- </settings-section>
-
- <settings-section i18n-values="page-title:searchPageTitle"
- current-route="[[currentRoute]]" section="search">
- <cr-settings-search-page current-route="{{currentRoute}}">
- </cr-settings-search-page>
- </settings-section>
-
-<if expr="chromeos">
- <settings-section i18n-values="page-title:usersPageTitle"
- current-route="[[currentRoute]]" section="users">
- <cr-settings-users-page prefs="{{prefs}}"></cr-settings-users-page>
- </settings-section>
+ <template is="dom-if" if="[[showPage(pageVisibility.appearance)]]" restamp>
+ <settings-section i18n-values="page-title:appearancePageTitle"
+ current-route="[[currentRoute]]" section="appearance">
+ <settings-appearance-page prefs="{{prefs}}"
+ current-route="[[currentRoute]]">
+ </settings-appearance-page>
+ </settings-section>
+ </template>
+ <template is="dom-if" if="[[showPage(pageVisibility.onStartup)]]" restamp>
+ <settings-section i18n-values="page-title:onStartup"
+ current-route="[[currentRoute]]" section="onStartup">
+ <settings-on-startup-page prefs="{{prefs}}"
+ current-route="{{currentRoute}}">
+ </settings-on-startup-page>
+ </settings-section>
+ </template>
+ <template is="dom-if" if="[[showPage(pageVisibility.search)]]" restamp>
+ <settings-section i18n-values="page-title:searchPageTitle"
+ current-route="[[currentRoute]]" section="search">
+ <settings-search-page current-route="{{currentRoute}}">
+ </settings-search-page>
+ </settings-section>
+ </template>
+<if expr="not chromeos">
+ <template is="dom-if" if="[[showPage(pageVisibility.defaultBrowser)]]"
+ restamp>
+ <settings-section i18n-values="page-title:defaultBrowser"
+ expand-container="{{expandContainer}}"
+ current-route="[[currentRoute]]" section="defaultBrowser">
+ <settings-default-browser-page>
+ </settings-default-browser-page>
+ </settings-section>
+ </template>
</if>
</template>
<script src="basic_page.js"></script>
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 024794acba0..4439fb1179f 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.js
+++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -4,20 +4,20 @@
/**
* @fileoverview
- * 'cr-settings-basic-page' is the settings page containing the basic settings.
+ * 'settings-basic-page' is the settings page containing the basic settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-basic-page prefs="{{prefs}}"></cr-settings-basic-page>
+ * <settings-basic-page prefs="{{prefs}}"></settings-basic-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-basic-page
+ * @element settings-basic-page
*/
Polymer({
- is: 'cr-settings-basic-page',
+ is: 'settings-basic-page',
properties: {
/**
@@ -35,5 +35,23 @@ Polymer({
type: Object,
notify: true,
},
+
+ /**
+ * True if the basic page should currently display the reset profile banner.
+ * @private {boolean}
+ */
+ showResetProfileBanner_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean('showResetProfileBanner');
+ },
+ },
+
+ },
+
+ onResetDone_: function() {
+ this.showResetProfileBanner_ = false;
},
+
+ behaviors: [SettingsPageVisibility],
});
diff --git a/chromium/chrome/browser/resources/settings/radio_group/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/basic_page/compiled_resources.gyp
index 4cf6e739bf9..840e2ee3308 100644
--- a/chromium/chrome/browser/resources/settings/radio_group/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/settings/basic_page/compiled_resources.gyp
@@ -4,13 +4,11 @@
{
'targets': [
{
- 'target_name': 'radio_group',
+ 'target_name': 'basic_page',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
- ],
- 'externs': [
- '../../../../../third_party/closure_compiler/externs/settings_private.js'
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../settings_page/compiled_resources.gyp:settings_page_visibility',
],
},
'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.html
new file mode 100644
index 00000000000..c6f747c04f2
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.html
@@ -0,0 +1,49 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html">
+
+<dom-module id="settings-bluetooth-add-device-dialog">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="bluetooth_page.css">
+ <link rel="import" type="css" href="bluetooth_dialog.css">
+ <template>
+ <div id="dialogOuterDiv" class="layout vertical flex">
+ <div id="dialogHeaderDiv" class="settings-box layout horizontal">
+ <span id="dialogTitle" class="flex"
+ i18n-content="bluetoothAddDevicePageTitle">
+ </span>
+ <paper-icon-button icon="close" on-tap="onCancelTap_" id="close">
+ </paper-icon-button>
+ </div>
+ <div class="settings-box flex">
+ <div id="dialogDeviceList" class="settings-box layout vertical"
+ on-device-event="onDeviceEvent_">
+ <span class="no-devices" hidden$="[[haveDevices_(deviceList)]]"
+ i18n-content="bluetoothNoDevices">
+ </span>
+ <iron-selector class="flex">
+ <template is="dom-repeat" items="[[deviceList]]"
+ filter="deviceNotPaired_" observe="paired">
+ <bluetooth-device-list-item device="[[item]]">
+ </bluetooth-device-list-item>
+ </template>
+ </iron-selector>
+ </div>
+ </div>
+ <div id="dialogFooterDiv" class="layout horizontal center">
+ <div id="scanning" class="layout horizontal center flex"
+ hidden$="[[!adapterState.discovering]]">
+ <paper-spinner active="[[adapterState.discovering]]">
+ </paper-spinner>
+ <span i18n-content="bluetoothScanning"></span>
+ </div>
+ <paper-button id="cancel" class="end-justified"
+ i18n-content="bluetoothCancel" on-tap="onCancelTap_">
+ </paper-button>
+ </div>
+ </div>
+ </template>
+ <script src="bluetooth_add_device_dialog.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.js
new file mode 100644
index 00000000000..189711f310f
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_add_device_dialog.js
@@ -0,0 +1,71 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-bluetooth-add-device-dialog' is the settings subpage for adding
+ * bluetooth devices.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-bluetooth-add-device-dialog
+ */
+Polymer({
+ is: 'settings-bluetooth-add-device-dialog',
+
+ properties: {
+ /**
+ * The cached bluetooth adapter state.
+ * @type {!chrome.bluetooth.AdapterState|undefined}
+ */
+ adapterState: {
+ type: Object,
+ observer: 'adapterStateChanged_',
+ },
+
+ /**
+ * The ordered list of bluetooth devices.
+ * @type {!Array<!chrome.bluetooth.Device>}
+ */
+ deviceList: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+
+ /** @private */
+ adapterStateChanged_: function() {
+ if (!this.adapterState.powered)
+ this.fire('close-dialog');
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {boolean}
+ * @private
+ */
+ deviceNotPaired_: function(device) {
+ return !device.paired;
+ },
+
+ /**
+ * @param {!Array<!chrome.bluetooth.Device>} deviceList
+ * @return {boolean} True if deviceList contains any unpaired devices.
+ * @private
+ */
+ haveDevices_: function(deviceList) {
+ return this.deviceList.findIndex(function(d) { return !d.paired; }) != -1;
+ },
+
+ /**
+ * @param {!{detail: {action: string, device: !chrome.bluetooth.Device}}} e
+ * @private
+ */
+ onDeviceEvent_: function(e) {
+ this.fire('device-event', e.detail);
+ /** @type {Event} */(e).stopPropagation();
+ },
+
+ /** @private */
+ onCancelTap_: function() { this.fire('close-dialog'); },
+});
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.css b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.css
new file mode 100644
index 00000000000..de43201be75
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.css
@@ -0,0 +1,33 @@
+/* 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. */
+
+#outer {
+ padding: 5px 5px 5px 15px;
+}
+
+#outer:hover:not([dropdown]) {
+ background-color: #f0f0f0;
+}
+
+iron-icon {
+ -webkit-padding-start: 10px;
+ color: green;
+}
+
+paper-item:hover {
+ background-color: #f0f0f0;
+}
+
+span.name {
+ padding: 10px 0;
+}
+
+span.name[connected] {
+ font-weight: bold;
+}
+
+.dropdown-content {
+ background: white;
+ box-shadow: 0 2px 6px grey;
+}
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html
new file mode 100644
index 00000000000..a868a559356
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html
@@ -0,0 +1,37 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-dropdown/iron-dropdown.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+
+<dom-module id="bluetooth-device-list-item">
+ <link rel="import" type="css" href="bluetooth_device_list_item.css">
+ <template>
+ <div id="outer" class="layout horizontal center"
+ dropdown$="[[dropdownOpened]]" on-tap="itemTapped_">
+ <span class="name" connected$="[[device.connected]]">
+ [[getDeviceName_(device)]]
+ </span>
+ <iron-icon icon="check" hidden$="[[!device.connected]]"></iron-icon>
+ <span class="flex"></span>
+ <span hidden$="[[!device.connecting]]"
+ i18n-content="bluetoothConnecting"></span>
+ <div hidden$="[[!device.paired]]" on-tap="doNothing_">
+ <paper-icon-button icon="more-vert" toggles active="{{dropdownOpened}}">
+ </paper-icon-button>
+ <iron-dropdown opened="{{dropdownOpened}}" on-tap="menuSelected_">
+ <div class="dropdown-content">
+ <paper-item id="connect" i18n-content="bluetoothConnect"
+ hidden$="[[device.connected]]"></paper-item>
+ <paper-item id="disconnect" i18n-content="bluetoothDisconnect"
+ hidden$="[[!device.connected]]"></paper-item>
+ <paper-item id="remove" i18n-content="bluetoothRemove"></paper-item>
+ </div>
+ </iron-dropdown>
+ </div>
+ </div>
+ </template>
+ <script src="bluetooth_device_list_item.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js
new file mode 100644
index 00000000000..dd2378b8f11
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js
@@ -0,0 +1,71 @@
+// 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.
+
+/**
+ * @fileoverview Polymer element for displaying a bluetooth device in a list.
+ */
+
+Polymer({
+ is: 'bluetooth-device-list-item',
+
+ properties: {
+ /**
+ * The bluetooth device.
+ * @type {!chrome.bluetooth.Device}
+ */
+ device: {
+ type: Object,
+ },
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ itemTapped_: function(e) {
+ this.fire('device-event', {
+ action: 'connect',
+ device: this.device,
+ });
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ menuSelected_: function(e) {
+ e.currentTarget.opened = false;
+ this.fire('device-event', {
+ action: e.target.id,
+ device: this.device,
+ });
+ },
+
+ /**
+ * @param {Event} e
+ * @private
+ */
+ doNothing_: function(e) {
+ // Avoid triggering itemTapped_.
+ e.stopPropagation();
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {string} The text to display for |device| in the device list.
+ * @private
+ */
+ getDeviceName_: function(device) {
+ return device.name || device.address;
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {boolean}
+ * @private
+ */
+ isDisconnected_: function(device) {
+ return !device.connected && !device.connecting;
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_dialog.css b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_dialog.css
new file mode 100644
index 00000000000..67646335f0b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_dialog.css
@@ -0,0 +1,91 @@
+/* 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. */
+
+#dialogOuterDiv {
+ margin-bottom: 16px;
+}
+
+#dialogHeaderDiv {
+ height: 40px;
+ margin: 0 5px 10px;
+}
+
+#dialogFooterDiv {
+ height: 40px;
+ margin: 0 20px;
+}
+
+#dialogMessage {
+ margin-bottom: 10px;
+}
+
+#dialogTitle {
+ font-size: 125%;
+ margin: 0 10px;
+}
+
+#dialogDeviceList {
+ height: 210px;
+ margin-bottom: 20px;
+ margin-left: 4px;
+ overflow-y: auto;
+}
+
+#pairing {
+ margin-bottom: 10px;
+}
+
+#pairing paper-input {
+ text-align: center;
+}
+
+#pinDiv {
+ margin-top: 10px;
+}
+
+iron-selector {
+ width: 100%;
+}
+
+paper-spinner {
+ height: 20px;
+ margin: 0 10px;
+ width: 20px;
+}
+
+/* .display indicates a displayed pin code or passkey. */
+span.display {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ box-shadow: 0 0 0 1px #222;
+ color: #222;
+ font-size: 16px;
+ height: 38px;
+ line-height: 38px;
+ margin: 0 5px;
+ padding: 0 15px;
+ text-align: center;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+}
+
+span.display.next {
+ background: rgb(77, 144, 254);
+ border: 2px solid rgb(77, 144, 254);
+ box-shadow: none;
+ color: #fff;
+}
+
+span.display.untyped {
+ border: 1px solid #d4d4d4;
+ box-shadow: 0 0 0 1px #888;
+ color: #666;
+}
+
+/* .confirm indicates a confirmation passkey. */
+span.confirm {
+ color: #999;
+ font-size: 20px;
+ font-weight: 600; /* semibold */
+ margin: 0 20px;
+}
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.css b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.css
new file mode 100644
index 00000000000..2eb7bd8b15d
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.css
@@ -0,0 +1,32 @@
+/* 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. */
+
+#addDevice {
+ color: blue;
+}
+
+#deviceList {
+ -webkit-margin-start: 15px;
+ max-height: 300px;
+ overflow-y: auto;
+}
+
+cr-expand-button {
+ -webkit-margin-end: 10px;
+}
+
+iron-icon {
+ -webkit-margin-end: 10px;
+}
+
+settings-bluetooth-add-device-dialog,
+settings-bluetooth-pair-device-dialog {
+ height: 400px;
+ padding: 0;
+ width: 500px;
+}
+
+span.no-devices {
+ margin: 10px 20px;
+}
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
new file mode 100644
index 00000000000..d6e576e17b1
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
@@ -0,0 +1,86 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
+<link rel="import" href="bluetooth_device_list_item.html">
+<link rel="import" href="bluetooth_add_device_dialog.html">
+<link rel="import" href="bluetooth_pair_device_dialog.html">
+
+<dom-module id="settings-bluetooth-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="bluetooth_page.css">
+ <template>
+ <settings-animated-pages id="pages" current-route="{{currentRoute}}"
+ section="bluetooth">
+ <neon-animatable id="main">
+ <div class="settings-box">
+ <div class="layout horizontal center">
+ <iron-icon icon="device:bluetooth"></iron-icon>
+ <span class="flex" i18n-content="bluetoothEnable"></span>
+ <cr-expand-button id="expandListButton"
+ hidden$="[[!bluetoothEnabled]]"
+ expanded="{{deviceListExpanded}}">
+ </cr-expand-button>
+ <paper-toggle-button id="enableBluetooth"
+ checked="{{bluetoothEnabled}}"
+ on-change="onBluetoothEnabledChange_">
+ </paper-toggle-button>
+ </div>
+ <iron-collapse opened="[[deviceListExpanded]]">
+ <div id="deviceList" class="layout vertical"
+ on-device-event="onDeviceEvent_">
+ <span class="no-devices"
+ hidden$="[[haveDevices_(deviceList.splices)]]"
+ i18n-content="bluetoothNoDevices">
+ </span>
+ <template is="dom-repeat" items="[[deviceList]]"
+ filter="deviceIsPairedOrConnecting_">
+ <bluetooth-device-list-item device="[[item]]">
+ </bluetooth-device-list-item>
+ </template>
+ </div>
+ <div class="settings-box" hidden$="[[!bluetoothEnabled]]">
+ <paper-button id="addDevice" i18n-content="bluetoothAddDevice"
+ on-tap="onAddDeviceTap_">
+ </paper-button>
+ </div>
+ </iron-collapse>
+ </div>
+ </neon-animatable>
+ </settings-animated-pages>
+
+ <paper-dialog modal id="deviceDialog" class="layout vertical"
+ on-iron-overlay-opened="onDialogOpened_"
+ on-iron-overlay-closed="onDialogClosed_">
+ <template is="dom-if" if="[[dialogIsVisible_(dialog, 'addDevice')]]"
+ restamp>
+ <settings-bluetooth-add-device-dialog
+ class="layout vertical flex"
+ adapter-state="[[adapterState]]"
+ device-list="[[deviceList]]"
+ on-device-event="onDeviceEvent_"
+ on-close-dialog="onCloseDialog_">
+ </settings-bluetooth-add-device-dialog>
+ </template>
+ <template is="dom-if" if="[[dialogIsVisible_(dialog, 'pairDevice')]]"
+ restamp>
+ <settings-bluetooth-pair-device-dialog
+ class="layout vertical flex"
+ pairing-device="[[pairingDevice]]"
+ pairing-event="[[pairingEvent]]"
+ on-response="onResponse_"
+ on-close-dialog="onCloseDialog_">
+ </settings-bluetooth-pair-device-dialog>
+ </template>
+ </paper-dialog>
+
+ </template>
+ <script src="bluetooth_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js
new file mode 100644
index 00000000000..c8babf426cc
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js
@@ -0,0 +1,523 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-bluetooth-page' is the settings page for managing bluetooth
+ * properties and devices.
+ *
+ * Example:
+ * <core-animated-pages>
+ * <settings-bluetooth-page>
+ * </settings-bluetooth-page>
+ * ... other pages ...
+ * </core-animated-pages>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-bluetooth-page
+ */
+
+var bluetoothPage = bluetoothPage || {
+ /**
+ * Set this to provide a fake implementation for testing.
+ * @type {Bluetooth}
+ */
+ bluetoothApiForTest: null,
+
+ /**
+ * Set this to provide a fake implementation for testing.
+ * @type {BluetoothPrivate}
+ */
+ bluetoothPrivateApiForTest: null,
+};
+
+Polymer({
+ is: 'settings-bluetooth-page',
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ properties: {
+ /** The current active route. */
+ currentRoute: {
+ type: Object,
+ notify: true,
+ },
+
+ /** Whether bluetooth is enabled. */
+ bluetoothEnabled: {
+ type: Boolean,
+ value: false,
+ observer: 'bluetoothEnabledChanged_',
+ },
+
+ /** Whether the device list is expanded. */
+ deviceListExpanded: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * The cached bluetooth adapter state.
+ * @type {!chrome.bluetooth.AdapterState|undefined}
+ */
+ adapterState: Object,
+
+ /**
+ * The ordered list of bluetooth devices.
+ * @type {!Array<!chrome.bluetooth.Device>}
+ */
+ deviceList: {
+ type: Array,
+ value: function() { return []; },
+ },
+
+ /**
+ * Set to the name of the dialog to show. This page uses a single
+ * paper-dialog to host one of two dialog elements, 'addDevice' or
+ * 'pairDevice'. This allows a seamless transition between adding and
+ * pairing dialogs. Note: This property should be set before opening the
+ * dialog, and setting the property will not itself cause the dialog to
+ * open.
+ */
+ dialog: String,
+
+ /**
+ * Current Pairing device.
+ * @type {?chrome.bluetooth.Device|undefined}
+ */
+ pairingDevice: Object,
+
+ /**
+ * Current Pairing event.
+ * @type {?chrome.bluetoothPrivate.PairingEvent|undefined}
+ */
+ pairingEvent: Object,
+
+ /**
+ * Interface for bluetooth calls. May be overriden by tests.
+ * @type {Bluetooth}
+ */
+ bluetooth: {
+ type: Object,
+ value: chrome.bluetooth,
+ },
+
+ /**
+ * Interface for bluetoothPrivate calls. May be overriden by tests.
+ * @type {BluetoothPrivate}
+ */
+ bluetoothPrivate: {
+ type: Object,
+ value: chrome.bluetoothPrivate,
+ },
+ },
+
+ /**
+ * Listener for chrome.bluetooth.onAdapterStateChanged events.
+ * @type {function(!chrome.bluetooth.AdapterState)|undefined}
+ * @private
+ */
+ bluetoothAdapterStateChangedListener_: undefined,
+
+ /**
+ * Listener for chrome.bluetooth.onBluetoothDeviceAdded/Changed events.
+ * @type {function(!chrome.bluetooth.Device)|undefined}
+ * @private
+ */
+ bluetoothDeviceUpdatedListener_: undefined,
+
+ /**
+ * Listener for chrome.bluetooth.onBluetoothDeviceRemoved events.
+ * @type {function(!chrome.bluetooth.Device)|undefined}
+ * @private
+ */
+ bluetoothDeviceRemovedListener_: undefined,
+
+ /**
+ * Listener for chrome.bluetoothPrivate.onPairing events.
+ * @type {function(!chrome.bluetoothPrivate.PairingEvent)|undefined}
+ * @private
+ */
+ bluetoothPrivateOnPairingListener_: undefined,
+
+ /** @override */
+ ready: function() {
+ if (bluetoothPage.bluetoothApiForTest)
+ this.bluetooth = bluetoothPage.bluetoothApiForTest;
+ if (bluetoothPage.bluetoothPrivateApiForTest)
+ this.bluetoothPrivate = bluetoothPage.bluetoothPrivateApiForTest;
+ },
+
+ /** @override */
+ attached: function() {
+ this.bluetoothAdapterStateChangedListener_ =
+ this.onBluetoothAdapterStateChanged_.bind(this);
+ this.bluetooth.onAdapterStateChanged.addListener(
+ this.bluetoothAdapterStateChangedListener_);
+
+ this.bluetoothDeviceUpdatedListener_ =
+ this.onBluetoothDeviceUpdated_.bind(this);
+ this.bluetooth.onDeviceAdded.addListener(
+ this.bluetoothDeviceUpdatedListener_);
+ this.bluetooth.onDeviceChanged.addListener(
+ this.bluetoothDeviceUpdatedListener_);
+
+ this.bluetoothDeviceRemovedListener_ =
+ this.onBluetoothDeviceRemoved_.bind(this);
+ this.bluetooth.onDeviceRemoved.addListener(
+ this.bluetoothDeviceRemovedListener_);
+
+ // Request the inital adapter state.
+ this.bluetooth.getAdapterState(
+ this.bluetoothAdapterStateChangedListener_);
+ },
+
+ /** @override */
+ detached: function() {
+ if (this.bluetoothAdapterStateChangedListener_) {
+ this.bluetooth.onAdapterStateChanged.removeListener(
+ this.bluetoothAdapterStateChangedListener_);
+ }
+ if (this.bluetoothDeviceUpdatedListener_) {
+ this.bluetooth.onDeviceAdded.removeListener(
+ this.bluetoothDeviceUpdatedListener_);
+ this.bluetooth.onDeviceChanged.removeListener(
+ this.bluetoothDeviceUpdatedListener_);
+ }
+ if (this.bluetoothDeviceRemovedListener_) {
+ this.bluetooth.onDeviceRemoved.removeListener(
+ this.bluetoothDeviceRemovedListener_);
+ }
+ },
+
+ bluetoothEnabledChanged_: function() {
+ // When bluetooth is enabled, auto-expand the device list.
+ if (this.bluetoothEnabled)
+ this.deviceListExpanded = true;
+ },
+
+ /**
+ * If bluetooth is enabled, request the complete list of devices and update
+ * |deviceList|.
+ * @private
+ */
+ updateDeviceList_: function() {
+ if (!this.bluetoothEnabled) {
+ this.deviceList = [];
+ return;
+ }
+ this.bluetooth.getDevices(function(devices) {
+ this.deviceList = devices;
+ }.bind(this));
+ },
+
+ /**
+ * Event called when a user action changes the bluetoothEnabled state.
+ * @private
+ */
+ onBluetoothEnabledChange_: function() {
+ this.bluetoothPrivate.setAdapterState(
+ {powered: this.bluetoothEnabled}, function() {
+ if (chrome.runtime.lastError) {
+ console.error(
+ 'Error enabling bluetooth: ' +
+ chrome.runtime.lastError.message);
+ }
+ });
+ },
+
+ /**
+ * Process bluetooth.onAdapterStateChanged events.
+ * @param {!chrome.bluetooth.AdapterState} state
+ * @private
+ */
+ onBluetoothAdapterStateChanged_: function(state) {
+ this.adapterState = state;
+ this.bluetoothEnabled = state.powered;
+ this.updateDeviceList_();
+ },
+
+ /**
+ * Process bluetooth.onDeviceAdded and onDeviceChanged events.
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ onBluetoothDeviceUpdated_: function(device) {
+ var address = device.address;
+ if (this.dialog && this.pairingDevice &&
+ this.pairingDevice.address == address) {
+ this.pairingDevice = device;
+ }
+ var index = this.getDeviceIndex_(address);
+ if (index >= 0) {
+ // Use splice to update the item in order to update the dom-repeat lists.
+ // See https://github.com/Polymer/polymer/issues/3254.
+ this.splice('deviceList', index, 1, device);
+ return;
+ }
+ this.push('deviceList', device);
+ },
+
+ /**
+ * Process bluetooth.onDeviceRemoved events.
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ onBluetoothDeviceRemoved_: function(device) {
+ var address = device.address;
+ var index = this.getDeviceIndex_(address);
+ if (index < 0)
+ return;
+ this.splice('deviceList', index, 1);
+ },
+
+ /** @private */
+ startDiscovery_: function() {
+ if (!this.adapterState || this.adapterState.discovering)
+ return;
+
+ if (!this.bluetoothPrivateOnPairingListener_) {
+ this.bluetoothPrivateOnPairingListener_ =
+ this.onBluetoothPrivateOnPairing_.bind(this);
+ this.bluetoothPrivate.onPairing.addListener(
+ this.bluetoothPrivateOnPairingListener_);
+ }
+
+ this.bluetooth.startDiscovery(function() {
+ if (chrome.runtime.lastError) {
+ if (chrome.runtime.lastError.message == 'Failed to stop discovery') {
+ // May happen if also started elsewhere; ignore.
+ return;
+ }
+ console.error('startDsicovery Error: ' +
+ chrome.runtime.lastError.message);
+ }
+ });
+ },
+
+ /** @private */
+ stopDiscovery_: function() {
+ if (!this.get('adapterState.discovering'))
+ return;
+
+ if (this.bluetoothPrivateOnPairingListener_) {
+ this.bluetoothPrivate.onPairing.removeListener(
+ this.bluetoothPrivateOnPairingListener_);
+ this.bluetoothPrivateOnPairingListener_ = undefined;
+ }
+
+ this.bluetooth.stopDiscovery(function() {
+ if (chrome.runtime.lastError) {
+ console.error('Error stopping bluetooth discovery: ' +
+ chrome.runtime.lastError.message);
+ }
+ });
+ },
+
+ /**
+ * Process bluetoothPrivate.onPairing events.
+ * @param {!chrome.bluetoothPrivate.PairingEvent} e
+ * @private
+ */
+ onBluetoothPrivateOnPairing_: function(e) {
+ if (!this.dialog || !this.pairingDevice ||
+ e.device.address != this.pairingDevice.address) {
+ return;
+ }
+ if (e.pairing == chrome.bluetoothPrivate.PairingEventType.KEYS_ENTERED &&
+ e.passkey === undefined && this.pairingEvent) {
+ // 'keysEntered' event might not include the updated passkey so preserve
+ // the current one.
+ e.passkey = this.pairingEvent.passkey;
+ }
+ this.pairingEvent = e;
+ },
+
+ /** @private */
+ onAddDeviceTap_: function() { this.openDialog_('addDevice'); },
+
+ /**
+ * @param {!{detail: {action: string, device: !chrome.bluetooth.Device}}} e
+ * @private
+ */
+ onDeviceEvent_: function(e) {
+ var action = e.detail.action;
+ var device = e.detail.device;
+ if (action == 'connect')
+ this.connectDevice_(device);
+ else if (action == 'disconnect')
+ this.disconnectDevice_(device);
+ else if (action == 'remove')
+ this.forgetDevice_(device);
+ else
+ console.error('Unexected action: ' + action);
+ },
+
+ /**
+ * Handle a response sent from the pairing dialog and pass it to the
+ * bluetoothPrivate API.
+ * @param {Event} e
+ * @private
+ */
+ onResponse_: function(e) {
+ var options =
+ /** @type {!chrome.bluetoothPrivate.SetPairingResponseOptions} */ (
+ e.detail);
+ this.bluetoothPrivate.setPairingResponse(options, function() {
+ if (chrome.runtime.lastError) {
+ // TODO(stevenjb): Show error.
+ console.error(
+ 'Error setting pairing response: ' + options.device.name +
+ ': Response: ' + options.response + ': Error: ' +
+ chrome.runtime.lastError.message);
+ }
+ this.closeDialog_();
+ }.bind(this));
+ },
+
+ /**
+ * @param {string} address
+ * @return {number} The index of the device associated with |address| or -1.
+ * @private
+ */
+ getDeviceIndex_: function(address) {
+ var len = this.deviceList.length;
+ for (var i = 0; i < len; ++i) {
+ if (this.deviceList[i].address == address)
+ return i;
+ }
+ return -1;
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {string} The text to display for |device| in the device list.
+ * @private
+ */
+ getDeviceName_: function(device) {
+ return device.name || device.address;
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @return {boolean}
+ * @private
+ */
+ deviceIsPairedOrConnecting_: function(device) {
+ return !!device.paired || !!device.connecting;
+ },
+
+ /**
+ * @param {Object} deviceListChanges Changes to the deviceList Array.
+ * @return {boolean} True if deviceList contains any paired devices.
+ * @private
+ */
+ haveDevices_: function(deviceListChanges) {
+ return this.deviceList.findIndex(function(d) { return d.paired; }) != -1;
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ connectDevice_: function(device) {
+ // If the device is not paired, show the pairing dialog.
+ if (!device.paired) {
+ // Set the pairing device and clear any pairing event.
+ this.pairingDevice = device;
+ this.pairingEvent = null;
+
+ this.openDialog_('pairDevice');
+ }
+
+ this.bluetoothPrivate.connect(device.address, function(result) {
+ if (chrome.runtime.lastError) {
+ console.error(
+ 'Error connecting: ' + device.address +
+ chrome.runtime.lastError.message);
+ // TODO(stevenjb): Show error message insead.
+ this.closeDialog_();
+ }
+ }.bind(this));
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ disconnectDevice_: function(device) {
+ this.bluetoothPrivate.disconnectAll(device.address, function() {
+ if (chrome.runtime.lastError) {
+ console.error(
+ 'Error disconnecting: ' + device.address +
+ chrome.runtime.lastError.message);
+ }
+ });
+ },
+
+ /**
+ * @param {!chrome.bluetooth.Device} device
+ * @private
+ */
+ forgetDevice_: function(device) {
+ this.bluetoothPrivate.forgetDevice(device.address, function() {
+ if (chrome.runtime.lastError) {
+ console.error(
+ 'Error forgetting: ' + device.name + ': ' +
+ chrome.runtime.lastError.message);
+ }
+ this.updateDeviceList_();
+ }.bind(this));
+ },
+
+ /**
+ * @param {string} dialog
+ * @param {string} dialogToShow The name of the dialog.
+ * @return {boolean}
+ * @private
+ */
+ dialogIsVisible_(dialog, dialogToShow) {
+ return dialogToShow == dialog;
+ },
+
+ /**
+ * @param {string} dialogId
+ * @private
+ */
+ openDialog_: function(dialogId) {
+ if (this.dialog) {
+ // Dialog already opened, just update the contents.
+ this.dialog = dialogId;
+ return;
+ }
+ this.dialog = dialogId;
+ // Call flush so that the dialog gets sized correctly before it is opened.
+ Polymer.dom.flush();
+ var dialog = this.$$('#deviceDialog');
+ dialog.open();
+ dialog.focus();
+ },
+
+ /** @private */
+ closeDialog_: function() {
+ if (!this.dialog)
+ return;
+ var dialog = this.$$('#deviceDialog');
+ dialog.close();
+ this.dialog = '';
+ this.pairingDevice = null;
+ this.pairingEvent = null;
+ },
+
+ /** @private */
+ onCloseDialog_: function(event) { this.closeDialog_(); },
+
+ /** @private */
+ onDialogOpened_: function() { this.startDiscovery_(); },
+
+ /** @private */
+ onDialogClosed_: function() { this.stopDiscovery_(); },
+});
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.html
new file mode 100644
index 00000000000..05ed236ecd1
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.html
@@ -0,0 +1,68 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+
+<dom-module id="settings-bluetooth-pair-device-dialog">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="bluetooth_page.css">
+ <link rel="import" type="css" href="bluetooth_dialog.css">
+ <template>
+ <div id="dialogOuterDiv" class="layout vertical flex">
+ <div id="dialogHeaderDiv" class="settings-box layout horizontal center">
+ <span id="dialogTitle" class="flex"
+ i18n-content="bluetoothPairDevicePageTitle">
+ </span>
+ <paper-icon-button icon="close" on-tap="onCancelTap_" id="close">
+ </paper-icon-button>
+ </div>
+ <div id="pairing"
+ class="settings-blox layout vertical center center-justified flex">
+ <div id="dialogMessage">
+ [[getMessage_(pairingDevice, pairingEvent)]]
+ </div>
+ <div hidden$="[[!showEnterPincode_(pairingEvent)]]">
+ <paper-input id="pincode" minlength="1" maxlength="16" type="text">
+ </div>
+ <div hidden$="[[!showEnterPasskey_(pairingEvent)]]">
+ <paper-input id="passkey" minlength="6" maxlength="6" type="text">
+ </div>
+ <div id="pinDiv" class="layout horizontal center center-justified"
+ hidden="[[!showDisplayPassOrPin_(pairingEvent)]]">
+ <template is="dom-repeat" items="[[digits]]">
+ <span class$="[[getPinClass_(pairingEvent, index)]]">
+ [[getPinDigit_(pairingEvent, index)]]
+ </span>
+ </template>
+ <span class$="[[getPinClass_(pairingEvent, -1)]]"
+ hidden="[[showAcceptReject_(pairingEvent)]]">
+ [[i18n('bluetoothEnterKey')]]
+ </span>
+ </div>
+ </div>
+ <div id="dialogFooterDiv" class="layout horizontal center end-justified">
+ <paper-button i18n-content="bluetoothAccept"
+ hidden$="[[!showAcceptReject_(pairingEvent)]]"
+ on-tap="onAcceptTap_">
+ </paper-button>
+ <paper-button i18n-content="bluetoothReject"
+ hidden$="[[!showAcceptReject_(pairingEvent)]]"
+ on-tap="onRejectTap_">
+ </paper-button>
+ <paper-button i18n-content="bluetoothConnect"
+ hidden$="[[!showConnect_(pairingEvent)]]"
+ on-tap="onConnectTap_">
+ </paper-button>
+ <paper-button i18n-content="bluetoothDismiss"
+ hidden$="[[!showDismiss_(pairingDevice, pairingEvent)]]"
+ on-tap="onDismissTap_">
+ </paper-button>
+ <paper-button i18n-content="bluetoothCancel" on-tap="onCancelTap_"
+ hidden$="[[showDismiss_(pairingDevice, pairingEvent)]]"
+ </paper-button>
+ </div>
+ </div>
+ </template>
+ <script src="bluetooth_pair_device_dialog.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js
new file mode 100644
index 00000000000..fe286744b2b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js
@@ -0,0 +1,271 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-bluetooth-pair-device-dialog' is the settings dialog for pairing
+ * a bluetooth device.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-bluetooth-pair-device-dialog
+ */
+
+(function() {
+
+var PairingEventType = chrome.bluetoothPrivate.PairingEventType;
+
+Polymer({
+ is: 'settings-bluetooth-pair-device-dialog',
+
+ behaviors: [I18nBehavior],
+
+ properties: {
+ /**
+ * Current Pairing device.
+ * @type {?chrome.bluetooth.Device|undefined}
+ */
+ pairingDevice: Object,
+
+ /**
+ * Current Pairing event.
+ * @type {?chrome.bluetoothPrivate.PairingEvent|undefined}
+ */
+ pairingEvent: Object,
+
+ /**
+ * @const
+ * @type {!Array<number>}
+ */
+ digits: {
+ type: Array,
+ readonly: true,
+ value: [0, 1, 2, 3, 4, 5],
+ },
+ },
+
+ observers: [
+ 'pairingChanged_(pairingDevice, pairingEvent)',
+ ],
+
+ /**
+ * @param {?chrome.bluetooth.Device} pairingDevice
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @private
+ */
+ pairingChanged_: function(pairingDevice, pairingEvent) {
+ // Auto-close the dialog when pairing completes.
+ if (pairingDevice && pairingDevice.connected) {
+ this.fire('close-dialog', '');
+ return;
+ }
+ },
+
+ /**
+ * @param {?chrome.bluetooth.Device} device
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {string}
+ * @private
+ */
+ getMessage_: function(device, pairingEvent) {
+ if (!device)
+ return '';
+ var message;
+ if (!pairingEvent)
+ message = 'bluetoothStartConnecting';
+ else
+ message = this.getEventDesc_(pairingEvent.pairing);
+ return this.i18n(message, device.name);
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showEnterPincode_: function(pairingEvent) {
+ return !!pairingEvent &&
+ pairingEvent.pairing == PairingEventType.REQUEST_PINCODE;
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showEnterPasskey_: function(pairingEvent) {
+ return !!pairingEvent &&
+ pairingEvent.pairing == PairingEventType.REQUEST_PASSKEY;
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showDisplayPassOrPin_: function(pairingEvent) {
+ if (!pairingEvent)
+ return false;
+ var pairing = pairingEvent.pairing;
+ return (
+ pairing == PairingEventType.DISPLAY_PINCODE ||
+ pairing == PairingEventType.DISPLAY_PASSKEY ||
+ pairing == PairingEventType.CONFIRM_PASSKEY ||
+ pairing == PairingEventType.KEYS_ENTERED);
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showAcceptReject_: function(pairingEvent) {
+ return !!pairingEvent &&
+ pairingEvent.pairing == PairingEventType.CONFIRM_PASSKEY;
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showConnect_: function(pairingEvent) {
+ if (!pairingEvent)
+ return false;
+ var pairing = pairingEvent.pairing;
+ if (pairing == PairingEventType.REQUEST_PINCODE) {
+ var pincode = /** @type {{invalid: boolean}} */(this.$.pincode);
+ return !pincode.invalid;
+ } else if (pairing == PairingEventType.REQUEST_PASSKEY) {
+ var passkey = /** @type {{invalid: boolean}} */(this.$.passkey);
+ return !passkey.invalid;
+ }
+ return false;
+ },
+
+ /**
+ * @param {?chrome.bluetooth.Device} device
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @return {boolean}
+ * @private
+ */
+ showDismiss_: function(device, pairingEvent) {
+ return (!!device && device.paired) ||
+ (!!pairingEvent && pairingEvent.pairing == PairingEventType.COMPLETE);
+ },
+
+ /** @private */
+ onAcceptTap_: function() {
+ this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CONFIRM);
+ },
+
+ /** @private */
+ onConnectTap_: function() {
+ this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CONFIRM);
+ },
+
+ /** @private */
+ onRejectTap_: function() {
+ this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.REJECT);
+ },
+
+ /** @private */
+ onCancelTap_: function() {
+ this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CANCEL);
+ // Close the dialog immediately.
+ this.fire('close-dialog', '');
+ },
+
+ /** @private */
+ onDismissTap_: function() { this.fire('close-dialog', ''); },
+
+ /** @private */
+ sendResponse_: function(response) {
+ if (!this.pairingDevice)
+ return;
+ var options =
+ /** @type {!chrome.bluetoothPrivate.SetPairingResponseOptions} */ {
+ device: this.pairingDevice,
+ response: response
+ };
+ if (response == chrome.bluetoothPrivate.PairingResponse.CONFIRM) {
+ var pairing = this.pairingEvent.pairing;
+ if (pairing == PairingEventType.REQUEST_PINCODE)
+ options.pincode = this.$.pincode.value;
+ else if (pairing == PairingEventType.REQUEST_PASSKEY)
+ options.passkey = parseInt(this.$.passkey.value, 10);
+ }
+ this.fire('response', options);
+ },
+
+ /**
+ * @param {!PairingEventType} eventType
+ * @return {string}
+ * @private
+ */
+ getEventDesc_: function(eventType) {
+ assert(eventType);
+ if (eventType == PairingEventType.COMPLETE ||
+ eventType == PairingEventType.KEYS_ENTERED ||
+ eventType == PairingEventType.REQUEST_AUTHORIZATION) {
+ return 'bluetoothStartConnecting';
+ }
+ return 'bluetooth_' + /** @type {string} */(eventType);
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @param {number} index
+ * @return {string}
+ * @private
+ */
+ getPinDigit_: function(pairingEvent, index) {
+ if (!pairingEvent)
+ return '';
+ var digit = '0';
+ var pairing = pairingEvent.pairing;
+ if (pairing == PairingEventType.DISPLAY_PINCODE && pairingEvent.pincode &&
+ index < pairingEvent.pincode.length) {
+ digit = pairingEvent.pincode[index];
+ } else if (pairingEvent.passkey &&
+ (pairing == PairingEventType.DISPLAY_PASSKEY ||
+ pairing == PairingEventType.KEYS_ENTERED ||
+ pairing == PairingEventType.CONFIRM_PASSKEY)) {
+ var passkeyString = String(pairingEvent.passkey);
+ if (index < passkeyString.length)
+ digit = passkeyString[index];
+ }
+ return digit;
+ },
+
+ /**
+ * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent
+ * @param {number} index
+ * @return {string}
+ * @private
+ */
+ getPinClass_: function(pairingEvent, index) {
+ if (!pairingEvent)
+ return '';
+ if (pairingEvent.pairing == PairingEventType.CONFIRM_PASSKEY)
+ return 'confirm';
+ var cssClass = 'display';
+ if (pairingEvent.pairing == PairingEventType.DISPLAY_PASSKEY) {
+ if (index == 0)
+ cssClass += ' next';
+ else
+ cssClass += ' untyped';
+ } else if (
+ pairingEvent.pairing == PairingEventType.KEYS_ENTERED &&
+ pairingEvent.enteredKey) {
+ var enteredKey = pairingEvent.enteredKey; // 1-7
+ var lastKey = this.digits.length; // 6
+ if ((index == -1 && enteredKey > lastKey) || (index + 1 == enteredKey))
+ cssClass += ' next';
+ else if (index > enteredKey)
+ cssClass += ' untyped';
+ }
+ return cssClass;
+ },
+});
+})();
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/bluetooth_page/compiled_resources.gyp
new file mode 100644
index 00000000000..17032053dd6
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/compiled_resources.gyp
@@ -0,0 +1,72 @@
+# 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.
+{
+ 'targets': [
+ {
+ 'target_name': 'bluetooth_page',
+ 'variables': {
+ 'depends': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth_interface.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private_interface.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ '../settings_page/settings_animated_pages.js'
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'bluetooth_device_list_item',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'bluetooth_add_device_dialog',
+ 'variables': {
+ 'depends': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth_interface.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private_interface.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'bluetooth_pair_device_dialog',
+ 'variables': {
+ 'depends': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth_interface.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private_interface.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/bluetooth.js',
+ '../../../../../third_party/closure_compiler/externs/bluetooth_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ ],
+}
diff --git a/chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html b/chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html
index 3c120eff062..70a5b6eae46 100644
--- a/chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html
+++ b/chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html
@@ -3,7 +3,7 @@
<link rel="import" href="chrome://resources/polymer/v1_0/paper-tabs/paper-tabs.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
-<dom-module id="cr-settings-certificate-manager-page">
+<dom-module id="settings-certificate-manager-page">
<link rel="import" type="css" href="certificate_manager_page.css">
<template>
<paper-tabs selected="{{selected}}">
diff --git a/chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js b/chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js
index 253e2833d1b..8c9f3134794 100644
--- a/chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js
+++ b/chromium/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js
@@ -4,22 +4,22 @@
/**
* @fileoverview
- * 'cr-settings-certificate-manager-page' is the settings page containing SSL
+ * 'settings-certificate-manager-page' is the settings page containing SSL
* certificate settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-certificate-manager-page prefs="{{prefs}}">
- * </cr-settings-certificate-manager-page>
+ * <settings-certificate-manager-page prefs="{{prefs}}">
+ * </settings-certificate-manager-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-certificate-manager-page
+ * @element settings-certificate-manager-page
*/
Polymer({
- is: 'cr-settings-certificate-manager-page',
+ is: 'settings-certificate-manager-page',
properties: {
/**
diff --git a/chromium/chrome/browser/resources/settings/checkbox/checkbox.html b/chromium/chrome/browser/resources/settings/checkbox/checkbox.html
deleted file mode 100644
index 8adebc1ddb4..00000000000
--- a/chromium/chrome/browser/resources/settings/checkbox/checkbox.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/cr_events/cr_events.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_indicator.html">
-<link rel="import" href="chrome://md-settings/policy_controllable/policy_controllable.html">
-<link rel="import" href="chrome://md-settings/pref_tracker/pref_tracker.html">
-
-<dom-module id="cr-settings-checkbox">
- <link rel="import" type="css" href="checkbox.css">
- <template>
- <cr-events id="events"></cr-events>
- <cr-settings-pref-tracker pref="[[pref]]"></cr-settings-pref-tracker>
-
- <div id="outerDiv" class="layout horizontal center">
- <paper-checkbox id="checkbox" checked="{{checked}}"
- disabled="[[checkboxDisabled_(disabled, pref)]]">
- <span id="mainLabel">{{label}}</span>
- <span id="subLabel">{{subLabel}}</span>
- </paper-checkbox>
- <cr-policy-indicator pref="[[pref]]"></cr-policy-indicator>
- </div>
- </template>
- <script src="checkbox.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html b/chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html
index 11209c1e29e..3edd6ddd88d 100644
--- a/chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html
+++ b/chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html
@@ -3,58 +3,62 @@
<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-dropdown-menu/paper-dropdown-menu.html">
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
+<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
+<link rel="import" href="chrome://md-settings/controls/settings_dropdown_menu.html">
-<dom-module id="cr-settings-clear-browsing-data-page">
+<dom-module id="settings-clear-browsing-data-page">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="clear_browsing_data_page.css">
<template>
- <div>
+ <div class="settings-box">
<span i18n-content="clearFollowingItemsFrom"></span>
- <paper-dropdown-menu>
- <paper-menu class="dropdown-content"
- selected="{{prefs.browser.clear_data.time_period.value}}">
- <template is="dom-repeat" items="[[clearFromOptions_]]">
- <paper-item>[[item]]</paper-item>
- </template>
- </paper-menu>
- </paper-dropdown-menu>
- <cr-settings-checkbox id="browsingCheckbox"
+ <settings-dropdown-menu id="clearFrom"
+ pref="{{prefs.browser.clear_data.time_period}}"
+ menu-options="[[clearFromOptions_]]">
+ </settings-dropdown-menu>
+ <settings-checkbox id="browsingCheckbox"
pref="{{prefs.browser.clear_data.browsing_history}}"
i18n-values="label:clearBrowsingHistory">
- </cr-settings-checkbox>
- <cr-settings-checkbox id="downloadCheckbox"
+ </settings-checkbox>
+ <settings-checkbox id="downloadCheckbox"
pref="{{prefs.browser.clear_data.download_history}}"
i18n-values="label:clearDownloadHistory">
- </cr-settings-checkbox>
- <cr-settings-checkbox
+ </settings-checkbox>
+ <settings-checkbox
pref="{{prefs.browser.clear_data.cache}}"
i18n-values="label:clearCache">
- </cr-settings-checkbox>
- <cr-settings-checkbox
+ </settings-checkbox>
+ <settings-checkbox
pref="{{prefs.browser.clear_data.cookies}}"
i18n-values="label:clearCookies">
- </cr-settings-checkbox>
- <cr-settings-checkbox
+ </settings-checkbox>
+ <settings-checkbox
pref="{{prefs.browser.clear_data.passwords}}"
i18n-values="label:clearPasswords">
- </cr-settings-checkbox>
- <cr-settings-checkbox
+ </settings-checkbox>
+ <settings-checkbox
pref="{{prefs.browser.clear_data.form_data}}"
i18n-values="label:clearFormData">
- </cr-settings-checkbox>
- <cr-settings-checkbox
+ </settings-checkbox>
+ <settings-checkbox
pref="{{prefs.browser.clear_data.hosted_apps_data}}"
i18n-values="label:clearHostedAppData">
- </cr-settings-checkbox>
- <cr-settings-checkbox
+ </settings-checkbox>
+ <settings-checkbox
pref="{{prefs.browser.clear_data.content_licenses}}"
i18n-values="label:clearDeauthorizeContentLicenses">
- </cr-settings-checkbox>
+ </settings-checkbox>
+ </settings-box>
+ <span i18n-content="warnAboutNonClearedData"></span>
+ <span i18n-content="clearsSyncedData"></span>
+ </settings-box>
+ <settings-box>
+ <paper-button id="clearDataButton"
+ on-tap="onPerformClearBrowsingDataTap_"
+ raised i18n-content="clearBrowsingData">
+ </paper-button>
</div>
- <paper-button id="clearDataButton"
- on-tap="onPerformClearBrowsingDataTap_"
- raised i18n-content="clearBrowsingData">
- </paper-button>
</template>
<script src="clear_browsing_data_page.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js b/chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js
index df6ae067911..5a9b14c2c61 100644
--- a/chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js
+++ b/chromium/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js
@@ -4,22 +4,22 @@
/**
* @fileoverview
- * 'cr-settings-clear-browsing-data-page' provides options to delete browsing
+ * 'settings-clear-browsing-data-page' provides options to delete browsing
* data that has been cached by chromium.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-clear-browsing-data-page prefs="{{prefs}}">
- * </cr-settings-clear-browsing-data-page>
+ * <settings-clear-browsing-data-page prefs="{{prefs}}">
+ * </settings-clear-browsing-data-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-privacy-page
+ * @element settings-privacy-page
*/
Polymer({
- is: 'cr-settings-clear-browsing-data-page',
+ is: 'settings-clear-browsing-data-page',
properties: {
/**
@@ -40,22 +40,25 @@ Polymer({
/**
* List of options for the dropdown menu.
- * The order of entries in this array matches the
- * prefs.browser.clear_data.time_period.value enum.
+ * @private {!DropdownMenuOptionList>}
*/
clearFromOptions_: {
readOnly: true,
type: Array,
value: [
- loadTimeData.getString('clearDataHour'),
- loadTimeData.getString('clearDataDay'),
- loadTimeData.getString('clearDataWeek'),
- loadTimeData.getString('clearData4Weeks'),
- loadTimeData.getString('clearDataEverything'),
+ {value: 0, name: loadTimeData.getString('clearDataHour')},
+ {value: 1, name: loadTimeData.getString('clearDataDay')},
+ {value: 2, name: loadTimeData.getString('clearDataWeek')},
+ {value: 3, name: loadTimeData.getString('clearData4Weeks')},
+ {value: 4, name: loadTimeData.getString('clearDataEverything')},
],
},
},
+ ready: function() {
+ this.$.clearFrom.menuOptions = this.clearFromOptions_;
+ },
+
attached: function() {
var self = this;
cr.define('SettingsClearBrowserData', function() {
diff --git a/chromium/chrome/browser/resources/settings/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/compiled_resources.gyp
index 6fdc3696a4c..a76bc54ce18 100644
--- a/chromium/chrome/browser/resources/settings/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/settings/compiled_resources.gyp
@@ -7,12 +7,19 @@
'target_name': 'settings_resources',
'type': 'none',
'dependencies': [
- 'checkbox/compiled_resources.gyp:*',
+ 'appearance_page/compiled_resources.gyp:*',
+ 'advanced_page/compiled_resources.gyp:*',
+ 'basic_page/compiled_resources.gyp:*',
+ 'bluetooth_page/compiled_resources.gyp:*',
'internet_page/compiled_resources.gyp:*',
'languages_page/compiled_resources.gyp:*',
'on_startup_page/compiled_resources.gyp:*',
+ 'people_page/compiled_resources.gyp:*',
'prefs/compiled_resources.gyp:*',
- 'radio_group/compiled_resources.gyp:*',
+ 'settings_page/compiled_resources.gyp:*',
+ 'site_settings/compiled_resources.gyp:*',
+ 'site_settings_page/compiled_resources.gyp:*',
+ 'controls/compiled_resources.gyp:*',
],
},
]
diff --git a/chromium/chrome/browser/resources/settings/controls/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/controls/compiled_resources.gyp
new file mode 100644
index 00000000000..7a9a788ca59
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/controls/compiled_resources.gyp
@@ -0,0 +1,67 @@
+# 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.
+{
+ 'targets': [
+ {
+ 'target_name': 'settings_checkbox',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js',
+ '../../../../../ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'settings_dropdown_menu',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ '../prefs/pref_util.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'settings_input',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js',
+ '../../../../../ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'settings_radio_group',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../prefs/pref_util.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js'
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ ],
+}
diff --git a/chromium/chrome/browser/resources/settings/checkbox/checkbox.css b/chromium/chrome/browser/resources/settings/controls/settings_checkbox.css
index 9d1735b8048..9d1735b8048 100644
--- a/chromium/chrome/browser/resources/settings/checkbox/checkbox.css
+++ b/chromium/chrome/browser/resources/settings/controls/settings_checkbox.css
diff --git a/chromium/chrome/browser/resources/settings/controls/settings_checkbox.html b/chromium/chrome/browser/resources/settings/controls/settings_checkbox.html
new file mode 100644
index 00000000000..5c30da8fc8b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/controls/settings_checkbox.html
@@ -0,0 +1,27 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_events/cr_events.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
+<link rel="import" href="chrome://md-settings/pref_tracker/pref_tracker.html">
+
+<dom-module id="settings-checkbox">
+ <link rel="import" type="css" href="chrome://resources/cr_elements/shared.css">
+ <link rel="import" type="css" href="settings_checkbox.css">
+ <template>
+ <cr-events id="events"></cr-events>
+ <settings-pref-tracker pref="[[pref]]"></settings-pref-tracker>
+
+ <div id="outerDiv" class="layout horizontal center">
+ <paper-checkbox id="checkbox" checked="{{checked}}"
+ disabled="[[checkboxDisabled_(disabled, pref)]]">
+ <div id="mainLabel">{{label}}</div>
+ <div id="subLabel">{{subLabel}}</div>
+ </paper-checkbox>
+ <template is="dom-if" if="[[pref.policySource]]">
+ <cr-policy-pref-indicator pref="[[pref]]"></cr-policy-pref-indicator>
+ </template>
+ </div>
+ </template>
+ <script src="settings_checkbox.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/checkbox/checkbox.js b/chromium/chrome/browser/resources/settings/controls/settings_checkbox.js
index c6086e1982f..d0bbebc2507 100644
--- a/chromium/chrome/browser/resources/settings/checkbox/checkbox.js
+++ b/chromium/chrome/browser/resources/settings/controls/settings_checkbox.js
@@ -4,24 +4,24 @@
/**
* @fileoverview
- * `cr-settings-checkbox` is a checkbox that controls a supplied preference.
+ * `settings-checkbox` is a checkbox that controls a supplied preference.
*
* Example:
- * <cr-settings-checkbox pref="{{prefs.settings.enableFoo}}"
+ * <settings-checkbox pref="{{prefs.settings.enableFoo}}"
* label="Enable foo setting." subLabel="(bar also)">
- * </cr-settings-checkbox>
+ * </settings-checkbox>
*
- * @element cr-settings-checkbox
+ * @element settings-checkbox
*/
Polymer({
- is: 'cr-settings-checkbox',
+ is: 'settings-checkbox',
- behaviors: [PolicyControllable],
+ behaviors: [CrPolicyPrefBehavior],
properties: {
/**
* The boolean preference object to control.
- * @type {?chrome.settingsPrivate.PrefObject}
+ * @type {!chrome.settingsPrivate.PrefObject|undefined}
*/
pref: {
type: Object,
@@ -87,7 +87,16 @@ Polymer({
* @private
*/
checkedChanged_: function() {
- this.set('pref.value', this.getNewValue_(this.checked));
+ if (!this.pref)
+ return;
+ /** @type {boolean} */ var newValue = this.getNewValue_(this.checked);
+ // Ensure that newValue is the correct type for the pref type, either
+ // a boolean or a number.
+ if (this.pref.type == chrome.settingsPrivate.PrefType.NUMBER) {
+ this.set('pref.value', newValue ? 1 : 0);
+ return;
+ }
+ this.set('pref.value', newValue);
},
/**
@@ -101,11 +110,11 @@ Polymer({
/**
* @param {boolean} disabled
- * @param {?chrome.settingsPrivate.PrefObject} pref
+ * @param {!chrome.settingsPrivate.PrefObject} pref
* @return {boolean} Whether the checkbox should be disabled.
* @private
*/
checkboxDisabled_: function(disabled, pref) {
- return disabled || this.isPolicyControlled(pref);
+ return disabled || this.isPrefPolicyControlled(pref);
},
});
diff --git a/chromium/chrome/browser/resources/settings/controls/settings_dropdown_menu.html b/chromium/chrome/browser/resources/settings/controls/settings_dropdown_menu.html
new file mode 100644
index 00000000000..a7b2caa2176
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/controls/settings_dropdown_menu.html
@@ -0,0 +1,28 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dropdown-menu/paper-dropdown-menu.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://md-settings/prefs/pref_util.html">
+
+<dom-module id="settings-dropdown-menu">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <template>
+ <paper-dropdown-menu id="dropdownMenu" label="[[menuLabel_]]"
+ on-iron-select="onSelect_"
+ disabled="[[shouldDisableMenu_(disabled, menuOptions.*)]]">
+ <paper-menu class="dropdown-content" selected="{{selected_}}"
+ attr-for-selected="data-value">
+ <template is="dom-repeat" items="[[menuOptions]]">
+ <paper-item data-value$="[[item.value]]">[[item.name]]</paper-item>
+ </template>
+ <paper-item data-value$="[[notFoundValue_]]"
+ hidden$="[[!isSelectedNotFound_(selected_)]]">
+ [[i18n('custom')]]
+ </paper-item>
+ </paper-menu>
+ </paper-dropdown-menu>
+ </template>
+ <script src="settings_dropdown_menu.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/controls/settings_dropdown_menu.js b/chromium/chrome/browser/resources/settings/controls/settings_dropdown_menu.js
new file mode 100644
index 00000000000..9bfa1d75a91
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/controls/settings_dropdown_menu.js
@@ -0,0 +1,163 @@
+// 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.
+
+/**
+ * The |name| is shown in the gui. The |value| us use to set or compare with
+ * the preference value.
+ * @typedef {{
+ * name: string,
+ * value: (number|string)
+ * }}
+ */
+var DropdownMenuOption;
+
+/**
+ * @typedef {!Array<!DropdownMenuOption>}
+ */
+var DropdownMenuOptionList;
+
+/**
+ * 'settings-dropdown-menu' is a control for displaying options
+ * in the settings.
+ *
+ * Example:
+ *
+ * <settings-dropdown-menu pref="{{prefs.foo}}">
+ * </settings-dropdown-menu>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-dropdown-menu
+ */
+Polymer({
+ is: 'settings-dropdown-menu',
+
+ properties: {
+ /** A text label for the drop-down menu. */
+ label: String,
+
+ /**
+ * List of options for the drop-down menu.
+ * @type {DropdownMenuOptionList}
+ */
+ menuOptions: {
+ type: Array,
+ value: function() { return []; },
+ },
+
+ /**
+ * A single Preference object being tracked.
+ * @type {!chrome.settingsPrivate.PrefObject|undefined}
+ */
+ pref: {
+ type: Object,
+ notify: true,
+ },
+
+ /** Whether the dropdown menu should be disabled. */
+ disabled: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ },
+
+ /**
+ * Either loading text or the label for the drop-down menu.
+ * @private
+ */
+ menuLabel_: {
+ type: String,
+ value: function() { return loadTimeData.getString('loading'); },
+ },
+
+ /**
+ * The current selected value, as a string.
+ * @private
+ */
+ selected_: String,
+
+ /**
+ * The value of the 'custom' item.
+ * @private
+ */
+ notFoundValue_: {
+ type: String,
+ value: 'SETTINGS_DROPDOWN_NOT_FOUND_ITEM',
+ },
+ },
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ observers: [
+ 'checkSetup_(menuOptions)',
+ 'updateSelected_(pref.value)',
+ ],
+
+ ready: function() {
+ this.checkSetup_(this.menuOptions);
+ },
+
+ /**
+ * Check to see if we have all the pieces needed to enable the control.
+ * @param {DropdownMenuOptionList} menuOptions
+ * @private
+ */
+ checkSetup_: function(menuOptions) {
+ if (!this.menuOptions.length)
+ return;
+
+ this.menuLabel_ = this.label;
+ this.updateSelected_();
+ },
+
+ /**
+ * Pass the selection change to the pref value.
+ * @private
+ */
+ onSelect_: function() {
+ if (!this.pref || this.selected_ == undefined ||
+ this.selected_ == this.notFoundValue_) {
+ return;
+ }
+ var prefValue = Settings.PrefUtil.stringToPrefValue(
+ this.selected_, this.pref);
+ if (prefValue !== undefined)
+ this.set('pref.value', prefValue);
+ },
+
+ /**
+ * Updates the selected item when the pref or menuOptions change.
+ * @private
+ */
+ updateSelected_: function() {
+ if (!this.pref)
+ return;
+ var prefValue = this.pref.value;
+ var option = this.menuOptions.find(function(menuItem) {
+ return menuItem.value == prefValue;
+ });
+ if (option == undefined)
+ this.selected_ = this.notFoundValue_;
+ else
+ this.selected_ = Settings.PrefUtil.prefToString(this.pref);
+ },
+
+ /**
+ * @param {string} selected
+ * @return {boolean}
+ * @private
+ */
+ isSelectedNotFound_: function(selected) {
+ return this.menuOptions && selected == this.notFoundValue_;
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ shouldDisableMenu_: function() {
+ return this.disabled || !this.menuOptions.length;
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/input/input.css b/chromium/chrome/browser/resources/settings/controls/settings_input.css
index 204e397c466..204e397c466 100644
--- a/chromium/chrome/browser/resources/settings/input/input.css
+++ b/chromium/chrome/browser/resources/settings/controls/settings_input.css
diff --git a/chromium/chrome/browser/resources/settings/input/input.html b/chromium/chrome/browser/resources/settings/controls/settings_input.html
index 3eb78f42c38..4154796dc36 100644
--- a/chromium/chrome/browser/resources/settings/input/input.html
+++ b/chromium/chrome/browser/resources/settings/controls/settings_input.html
@@ -1,14 +1,16 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/cr_events/cr_events.html">
-<link rel="import" href="chrome://md-settings/policy_controllable/policy_controllable.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_events/cr_events.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
<link rel="import" href="chrome://md-settings/pref_tracker/pref_tracker.html">
-<dom-module id="cr-settings-input">
- <link rel="import" type="css" href="input.css">
+<dom-module id="settings-input">
+ <link rel="import" type="css" href="chrome://resources/cr_elements/shared.css">
+ <link rel="import" type="css" href="settings_input.css">
<template>
<cr-events id="events"></cr-events>
- <cr-settings-pref-tracker pref="[[pref]]"></cr-settings-pref-tracker>
+ <settings-pref-tracker pref="[[pref]]"></settings-pref-tracker>
<div id="outerDiv" class="layout horizontal center">
<paper-input id="input" auto-validate value="{{value}}"
@@ -17,8 +19,10 @@
readonly$="[[readonly]]" required="[[required]]" type="[[type]]"
on-blur="onBlur_" disabled="[[isDisabled_(disabled, pref)]]">
</paper-input>
- <cr-policy-indicator pref="[[pref]]"></cr-policy-indicator>
+ <template is="dom-if" if="[[pref.policySource]]">
+ <cr-policy-pref-indicator pref="[[pref]]"></cr-policy-pref-indicator>
+ </template>
</div>
</template>
- <script src="input.js"></script>
+ <script src="settings_input.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/input/input.js b/chromium/chrome/browser/resources/settings/controls/settings_input.js
index ee1e582fb8b..ab0cfe50c6b 100644
--- a/chromium/chrome/browser/resources/settings/input/input.js
+++ b/chromium/chrome/browser/resources/settings/controls/settings_input.js
@@ -4,20 +4,20 @@
/**
* @fileoverview
- * `cr-settings-input` is a single-line text field for user input associated
+ * `settings-input` is a single-line text field for user input associated
* with a pref value.
*
- * @element cr-settings-input
+ * @element settings-input
*/
Polymer({
- is: 'cr-settings-input',
+ is: 'settings-input',
- behaviors: [PolicyControllable],
+ behaviors: [CrPolicyPrefBehavior],
properties: {
/**
* The preference object to control.
- * @type {chrome.settingsPrivate.PrefObject|undefined}
+ * @type {!chrome.settingsPrivate.PrefObject|undefined}
*/
pref: {
type: Object,
@@ -74,7 +74,7 @@ Polymer({
* Focuses the 'input' element.
*/
focus: function() {
- this.$.input.inputElement.focus();
+ this.$.input.focus();
},
/**
@@ -128,11 +128,11 @@ Polymer({
/**
* @param {boolean} disabled
- * @param {?chrome.settingsPrivate.PrefObject} pref
+ * @param {!chrome.settingsPrivate.PrefObject} pref
* @return {boolean} Whether the element should be disabled.
* @private
*/
isDisabled_: function(disabled, pref) {
- return disabled || this.isPolicyControlled(pref);
+ return disabled || this.isPrefPolicyControlled(pref);
},
});
diff --git a/chromium/chrome/browser/resources/settings/radio_group/radio_group.css b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.css
index f040eafc6a0..9ff03faeb2f 100644
--- a/chromium/chrome/browser/resources/settings/radio_group/radio_group.css
+++ b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.css
@@ -4,6 +4,8 @@
:host {
display: block;
- margin-bottom: 10px;
- margin-top: 10px;
+}
+
+paper-radio-group {
+ width: 100%;
}
diff --git a/chromium/chrome/browser/resources/settings/radio_group/radio_group.html b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.html
index a252daa31c7..d1697a9400e 100644
--- a/chromium/chrome/browser/resources/settings/radio_group/radio_group.html
+++ b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.html
@@ -1,14 +1,15 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html">
+<link rel="import" href="chrome://md-settings/prefs/pref_util.html">
-<dom-module id="cr-settings-radio-group">
- <link rel="import" type="css" href="radio_group.css">
+<dom-module id="settings-radio-group">
+ <link rel="import" type="css" href="settings_radio_group.css">
<template>
<div>[[label]]</div>
<paper-radio-group selected="{{selected}}">
<content></content>
</paper-radio-group>
</template>
- <script src="radio_group.js"></script>
+ <script src="settings_radio_group.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/controls/settings_radio_group.js b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.js
new file mode 100644
index 00000000000..4f361182291
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.js
@@ -0,0 +1,57 @@
+// 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.
+
+/**
+ * @fileoverview
+ * `cr-radio-group` wraps a radio-group and set of radio-buttons that control
+ * a supplied preference.
+ *
+ * Example:
+ * <settings-radio-group pref="{{prefs.settings.foo}}"
+ * label="Foo Options." buttons="{{fooOptionsList}}">
+ * </settings-radio-group>
+ *
+ * @element settings-radio-group
+ */
+Polymer({
+ is: 'settings-radio-group',
+
+ properties: {
+ /**
+ * The preference object to control.
+ * @type {!chrome.settingsPrivate.PrefObject|undefined}
+ */
+ pref: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * IronSelectableBehavior selected attribute.
+ */
+ selected: {
+ type: String,
+ notify: true,
+ observer: 'selectedChanged_'
+ },
+ },
+
+ observers: [
+ 'prefChanged_(pref.*)',
+ ],
+
+ /** @private */
+ prefChanged_: function() {
+ this.selected = Settings.PrefUtil.prefToString(
+ /** @type {!chrome.settingsPrivate.PrefObject} */(this.pref));
+ },
+
+ /** @private */
+ selectedChanged_: function(selected) {
+ if (!this.pref)
+ return;
+ this.set('pref.value',
+ Settings.PrefUtil.stringToPrefValue(selected, this.pref));
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html b/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html
index 47cf35d34c3..0a298433f08 100644
--- a/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html
+++ b/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html
@@ -1,18 +1,18 @@
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
-<dom-module id="cr-settings-date-time-page">
+<dom-module id="settings-date-time-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="date_time_page.css">
<template>
<div class="horizontal layout center">
<span class="time-zone-label" i18n-content="timeZone"></span>
</div>
- <cr-settings-checkbox pref="{{prefs.settings.clock.use_24hour_clock}}"
+ <settings-checkbox pref="{{prefs.settings.clock.use_24hour_clock}}"
i18n-values="label:use24HourClock">
- </cr-settings-checkbox>
+ </settings-checkbox>
<span id="setAutomatically" i18n-content="dateTimeSetAutomatically">
</span>
</template>
diff --git a/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js b/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js
index 73e7a10b45d..cd0b5b7d1fd 100644
--- a/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js
+++ b/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js
@@ -4,22 +4,22 @@
/**
* @fileoverview
- * 'cr-settings-date-time-page' is the settings page containing date-time
+ * 'settings-date-time-page' is the settings page containing date-time
* settings.
*
* Example:
*
* <core-animated-pages>
- * <cr-settings-date-time-page prefs="{{prefs}}">
- * </cr-settings-date-time-page>
+ * <settings-date-time-page prefs="{{prefs}}">
+ * </settings-date-time-page>
* ... other pages ...
* </core-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-date-time-page
+ * @element settings-date-time-page
*/
Polymer({
- is: 'cr-settings-date-time-page',
+ is: 'settings-date-time-page',
properties: {
/**
diff --git a/chromium/chrome/browser/resources/settings/date_time_page/demo.html b/chromium/chrome/browser/resources/settings/date_time_page/demo.html
deleted file mode 100644
index 919675d929a..00000000000
--- a/chromium/chrome/browser/resources/settings/date_time_page/demo.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <link href="date_time_page.html" rel="import">
- <link href="../prefs/prefs.html" rel="import">
- <script src="demo.js"></script>
-</head>
-<body unresolved>
- <cr-settings-prefs></cr-settings-prefs>
- <cr-settings-date-time-page></cr-settings-date-time-page>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/settings/date_time_page/demo.js b/chromium/chrome/browser/resources/settings/date_time_page/demo.js
deleted file mode 100644
index 612cabe4e39..00000000000
--- a/chromium/chrome/browser/resources/settings/date_time_page/demo.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Wire up the prefs to the date/time page.
-window.addEventListener('polymer-ready', function() {
- var page = document.querySelector('cr-settings-date-time-page');
- page.prefs = document.querySelector('cr-settings-prefs');
-});
diff --git a/chromium/chrome/browser/resources/settings/location_page/location_page.css b/chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.css
index 809ed2850b1..3cd20531cab 100644
--- a/chromium/chrome/browser/resources/settings/location_page/location_page.css
+++ b/chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.css
@@ -2,6 +2,6 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-:host {
- display: block;
+.error-icon {
+ color: red;
}
diff --git a/chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.html b/chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.html
new file mode 100644
index 00000000000..fc6351627e0
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.html
@@ -0,0 +1,24 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.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-button/paper-button.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+
+<dom-module id="settings-default-browser-page">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="default_browser_page.css">
+ <template>
+ <div class="settings-box">[[message_]]</div>
+ <div class="settings-box">
+ <template is="dom-if" if="[[showButton_]]">
+ <paper-button on-tap="onSetDefaultBrowserTap_"
+ >[[i18n('defaultBrowserMakeDefault')]]</paper-button>
+ <template is="dom-if" if="[[showError_]]">
+ <iron-icon icon="error" class="error-icon"
+ title="[[i18n('unableToSetDefaultBrowser')]]"></iron-icon>
+ </template>
+ </template>
+ </div>
+ </template>
+ <script src="default_browser_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.js b/chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.js
new file mode 100644
index 00000000000..29b18b25314
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/default_browser_page/default_browser_page.js
@@ -0,0 +1,105 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-default-browser-page' is the settings page that contains
+ * settings to change the default browser (i.e. which the OS will open).
+ *
+ * Example:
+ *
+ * <iron-animated-pages>
+ * <settings-default-browser-page>
+ * </settings-default-browser-page>
+ * ... other pages ...
+ * </iron-animated-pages>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-default-browser-page
+ */
+Polymer({
+ is: 'settings-default-browser-page',
+
+ properties: {
+ /**
+ * The current active route.
+ */
+ currentRoute: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * A message about whether Chrome is the default browser.
+ */
+ message_: {
+ type: String,
+ },
+
+ /**
+ * Show or hide an error indicator showing whether SetAsDefault succeeded.
+ */
+ showError_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * Only show the SetAsDefault button if we have permission to set it.
+ */
+ showButton_: {
+ type: Boolean,
+ },
+ },
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ ready: function() {
+ var self = this;
+ cr.define('Settings', function() {
+ return {
+ setAsDefaultConcluded: function() {
+ return self.setAsDefaultConcluded_.apply(self, arguments);
+ },
+ updateDefaultBrowserState: function() {
+ return self.updateDefaultBrowserState_.apply(self, arguments);
+ },
+ };
+ });
+ chrome.send('SettingsDefaultBrowser.requestDefaultBrowserState');
+ },
+
+ /**
+ * @param {boolean} succeeded
+ * @private
+ */
+ setAsDefaultConcluded_: function(succeeded) {
+ this.showError_ = !succeeded;
+ },
+
+ /**
+ * @param {boolean} isDefault Whether Chrome is currently the user's default
+ * browser.
+ * @param {boolean} canBeDefault Whether Chrome can be the default browser on
+ * this system.
+ * @private
+ */
+ updateDefaultBrowserState_: function(isDefault, canBeDefault) {
+ this.showButton_ = !isDefault && canBeDefault;
+ if (canBeDefault) {
+ this.message_ = loadTimeData.getString(isDefault ?
+ 'defaultBrowserDefault' :
+ 'defaultBrowserNotDefault');
+ } else {
+ this.message_ = loadTimeData.getString('defaultBrowserUnknown');
+ }
+ },
+
+ /** @private */
+ onSetDefaultBrowserTap_: function() {
+ chrome.send('SettingsDefaultBrowser.setAsDefaultBrowser');
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.css b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.css
index ebdafd70d6f..b7960fcdca2 100644
--- a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.css
+++ b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.css
@@ -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-settings-input {
+settings-input {
/* This ensures that the "Download location" label and the text in the input
* itself are vertically aligned. */
margin-bottom: 1em;
diff --git a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html
index 80271c9e2bc..0f81e6762c8 100644
--- a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html
+++ b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html
@@ -1,29 +1,31 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
-<link rel="import" href="chrome://md-settings/input/input.html">
+<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
+<link rel="import" href="chrome://md-settings/controls/settings_input.html">
-<dom-module id="cr-settings-downloads-page">
+<dom-module id="settings-downloads-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="downloads_page.css">
<template>
- <div class="horizontal layout center">
- <div class="layout horizontal center">
+ <div class="settings-box split">
+ <div class="start layout horizontal center">
<div id="locationLabel" i18n-content="downloadLocation"></div>
- <cr-settings-input id="downloadsPath" no-label-float readonly
+ <settings-input id="downloadsPath" no-label-float readonly
pref="{{prefs.download.default_directory}}"
aria-labelledby="locationLabel">
- </cr-settings-input>
+ </settings-input>
</div>
<paper-button id="changeDownloadsPath" on-tap="selectDownloadLocation_"
i18n-content="changeDownloadLocation">
</paper-button>
</div>
- <cr-settings-checkbox pref="{{prefs.download.prompt_for_download}}"
- i18n-values="label:promptForDownload">
- </cr-settings-checkbox>
+ <div class="settings-box">
+ <settings-checkbox pref="{{prefs.download.prompt_for_download}}"
+ i18n-values="label:promptForDownload">
+ </settings-checkbox>
+ </div>
</template>
<script src="downloads_page.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js
index 252f04c6460..a12d76d34b3 100644
--- a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js
+++ b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js
@@ -4,22 +4,22 @@
/**
* @fileoverview
- * 'cr-settings-downloads-page' is the settings page containing downloads
+ * 'settings-downloads-page' is the settings page containing downloads
* settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-downloads-page prefs="{{prefs}}">
- * </cr-settings-downloads-page>
+ * <settings-downloads-page prefs="{{prefs}}">
+ * </settings-downloads-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-downloads-page
+ * @element settings-downloads-page
*/
Polymer({
- is: 'cr-settings-downloads-page',
+ is: 'settings-downloads-page',
properties: {
/**
diff --git a/chromium/chrome/browser/resources/settings/i18n_setup.html b/chromium/chrome/browser/resources/settings/i18n_setup.html
new file mode 100644
index 00000000000..1bf892e83ad
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/i18n_setup.html
@@ -0,0 +1,2 @@
+<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://md-settings/strings.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/icons.html b/chromium/chrome/browser/resources/settings/icons.html
new file mode 100644
index 00000000000..a2414c1353d
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/icons.html
@@ -0,0 +1,17 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
+
+<iron-iconset-svg name="md-settings-icons" size="48">
+ <svg>
+ <defs>
+ <!-- Cookie SVG obtained from rolfe@ -->
+ <g id="cookie" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="SVG-versions" transform="translate(-85.000000, -221.000000)" fill="#000000">
+ <g id="accessed_cookies" transform="translate(85.000000, 221.000000)">
+ <path d="M31.0002118,15 L31.0002118,14 C31.0002118,12.042 30.0002118,11 28.0002118,11 L27.0002118,11 C26.4482118,11 26.0002118,10.552 26.0002118,10 L26.0002118,6 C26.0002118,4.042 24.0002118,4 24.0002118,4 C12.5972118,4 3.42421177,13.542 4.02821177,25.077 C4.55821177,35.172 12.8282118,43.442 22.9232118,43.972 C34.4582118,44.577 44.0002118,35.403 44.0002118,24 L44.0002118,22 C44.0002118,20.895 43.1052118,20 42.0002118,20 L38.0032118,20 C37.4492118,20 37.0002118,19.551 37.0002118,18.997 L37.0002118,18 C37.0002118,16.125 36.0422118,15.042 34.0002118,15 L31.0002118,15 L31.0002118,15 Z M11.5872118,24.944 C9.47421177,25.345 7.65521177,23.526 8.05621177,21.412 C8.27921177,20.238 9.23921177,19.278 10.4132118,19.056 C12.5262118,18.655 14.3452118,20.474 13.9442118,22.587 C13.7222118,23.761 12.7622118,24.722 11.5872118,24.944 L11.5872118,24.944 Z M15.0562118,14.587 C14.6552118,12.474 16.4742118,10.655 18.5872118,11.056 C19.7612118,11.278 20.7212118,12.238 20.9442118,13.412 C21.3452118,15.526 19.5272118,17.345 17.4132118,16.944 C16.2392118,16.722 15.2782118,15.761 15.0562118,14.587 L15.0562118,14.587 Z M22.5872118,38.944 C20.4732118,39.345 18.6552118,37.526 19.0562118,35.412 C19.2792118,34.238 20.2392118,33.278 21.4132118,33.056 C23.5272118,32.656 25.3452118,34.474 24.9442118,36.587 C24.7222118,37.761 23.7612118,38.722 22.5872118,38.944 L22.5872118,38.944 Z M23.0002118,28 C21.3432118,28 20.0002118,26.657 20.0002118,25 C20.0002118,23.343 21.3432118,22 23.0002118,22 C24.6572118,22 26.0002118,23.343 26.0002118,25 C26.0002118,26.657 24.6572118,28 23.0002118,28 L23.0002118,28 Z M33.0002118,32 C31.3432118,32 30.0002118,30.657 30.0002118,29 C30.0002118,27.343 31.3432118,26 33.0002118,26 C34.6572118,26 36.0002118,27.343 36.0002118,29 C36.0002118,30.657 34.6572118,32 33.0002118,32 L33.0002118,32 Z" id="Imported-Layers"></path>
+ </g>
+ </g>
+ </g>
+ </defs>
+ </svg>
+</iron-icon-set>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/internet_page/compiled_resources.gyp
index 23dfd984fe9..0b3580a40e1 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/settings/internet_page/compiled_resources.gyp
@@ -7,7 +7,8 @@
'target_name': 'internet_page',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../third_party/closure_compiler/externs/networking_private_interface.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
'../settings_page/settings_animated_pages.js'
@@ -22,7 +23,10 @@
'target_name': 'internet_detail_page',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../third_party/closure_compiler/externs/networking_private_interface.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -35,7 +39,9 @@
'target_name': 'internet_known_networks_page',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../third_party/closure_compiler/externs/networking_private_interface.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -48,7 +54,7 @@
'target_name': 'network_apnlist',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -61,7 +67,7 @@
'target_name': 'network_ip_config',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -74,7 +80,7 @@
'target_name': 'network_nameservers',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -87,7 +93,8 @@
'target_name': 'network_property_list',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -100,7 +107,8 @@
'target_name': 'network_proxy',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -113,7 +121,7 @@
'target_name': 'network_proxy_input',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -126,7 +134,7 @@
'target_name': 'network_proxy_exclusions',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -139,7 +147,9 @@
'target_name': 'network_siminfo',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../third_party/closure_compiler/externs/networking_private_interface.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -152,7 +162,9 @@
'target_name': 'network_summary',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../third_party/closure_compiler/externs/networking_private_interface.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
@@ -165,7 +177,7 @@
'target_name': 'network_summary_item',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js',
+ '../../../../../ui/webui/resources/cr_elements/network/cr_onc_types.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
],
'externs': [
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.css b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.css
index 684a613eddf..f31caedc2ef 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.css
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.css
@@ -2,65 +2,52 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#titleDiv {
- margin-bottom: 10px;
+.section {
+ margin-bottom: 5px;
}
-#outerDiv {
- margin: 0 40px;
+iron-collapse {
+ margin: 10px;
}
-#networkIcon {
+cr-network-icon {
height: 32px;
width: 32px;
}
-#networkName {
+cr-policy-network-indicator {
-webkit-margin-start: 10px;
- font-size: 20px;
- font-weight: bold;
}
+#networkName,
#networkState {
-webkit-margin-start: 10px;
font-size: 20px;
}
-#networkState[connected] {
- color: green;
+#networkName {
+ font-weight: bold;
}
-#simInfoDiv {
- margin-left: 10px;
+#networkState[connected] {
+ color: green;
}
-#infoDiv {
- margin-left: 10px;
+#outerDiv {
+ margin: 10px 20px;
}
-#infoDiv span {
- margin-bottom: 8px;
+#ipAddressLabel {
+ -webkit-margin-end: 10px;
+ font-weight: bold;
}
#preferButton {
- margin: 0 7px 8px -2px;
+ -webkit-margin-end: 8px;
+ -webkit-margin-start: -3px;
padding: 0
}
-#advancedDiv paper-button {
- --paper-button: {
- text-align: start;
- };
-}
-
#proxyDiv {
max-width: 500px;
}
-
-paper-checkbox {
- margin-bottom: 10px;
-}
-
-cr-collapse {
- margin: 10px;
-}
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 9cd13af4ef6..0cf3f8fc4ef 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
@@ -1,13 +1,15 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/cr_collapse/cr_collapse.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/cr_expand_button/cr_expand_button.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_network_icon.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator.html">
<link rel="import" href="network_apnlist.html">
<link rel="import" href="network_ip_config.html">
<link rel="import" href="network_nameservers.html">
@@ -15,14 +17,14 @@
<link rel="import" href="network_proxy.html">
<link rel="import" href="network_siminfo.html">
-<dom-module id="cr-settings-internet-detail-page">
- <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css">
+<dom-module id="settings-internet-detail-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="internet_detail_page.css">
<template>
<div class="layout vertical">
<!-- Title section: Icon + name + connection state. -->
<div id="titleDiv" class="layout horizontal center">
- <cr-network-icon id="networkIcon" network-state="[[networkProperties]]">
+ <cr-network-icon network-state="[[networkProperties]]">
</cr-network-icon>
<span id="networkName">[[getStateName_(networkProperties)]]</span>
<span id="networkState"
@@ -32,65 +34,79 @@
<div id="outerDiv" class="layout vertical">
<!-- For Cellular, show SIM info first. -->
- <div id="simInfoDiv" class="layout vertical">
+ <div class="layout vertical section">
<network-siminfo editable
hidden$="[[!showCellularSim_(networkProperties)]]"
network-properties="[[networkProperties]]"
- on-siminfo-change="onNetworkPropertyChange_">
+ on-siminfo-change="onNetworkPropertyChange_"
+ networking-private="[[networkingPrivate]]">
</network-siminfo>
</div>
<!-- Info and properties common to all networks. -->
- <div id="infoDiv" class="layout vertical">
- <div class="layout horizontal" hidden$="[[!IPAddress]]">
- <span>IP Address:</span>
+ <div class="layout vertical">
+ <div class="layout horizontal section" hidden$="[[!IPAddress]]">
+ <span id="ipAddressLabel">IP Address:</span>
<span>[[IPAddress]]</span>
</div>
- <span hidden$="[[!showShared_(networkProperties)]]">
- This network is shared with other users.
- </span>
- <div class="layout horizontal center"
+ <div class="section">
+ <span hidden$="[[!showShared_(networkProperties)]]">
+ This network is shared with other users.
+ </span>
+ </div>
+ <div class="layout horizontal center section"
hidden$="[[!showPreferNetwork_(networkProperties)]]">
- <paper-icon-button id="preferButton"
- toggles active="{{preferNetwork}}"
+ <paper-icon-button id="preferButton" toggles
+ active="{{preferNetwork}}"
+ disabled=
+ "[[isNetworkPolicyEnforced(networkProperties.Priority)]]"
icon="[[getPreferredIcon_(preferNetwork)]]">
</paper-icon-button>
<span>Prefer this network</span>
+ <cr-policy-network-indicator
+ property="[[networkProperties.Priority]]">
+ </cr-policy-network-indicator>
</div>
- <paper-checkbox checked="{{autoConnect}}"
+ <div class="layout horizontal center section"
hidden$="[[!showAutoConnect_(networkProperties)]]">
- Automatically connect to this network
- </paper-checkbox>
-
+ <paper-checkbox checked="{{autoConnect}}">
+ Automatically connect to this network
+ </paper-checkbox>
+ <cr-policy-network-indicator
+ property="[[getManagedAutoConnect_(networkProperties)]]">
+ </cr-policy-network-indicator>
+ </div>
<!-- Properties to always show if present. -->
- <network-property-list
- fields="[[getInfoFields_(networkProperties)]]"
- property-dict="[[networkProperties]]">
- </network-property-list>
+ <div class="section">
+ <network-property-list
+ fields="[[getInfoFields_(networkProperties)]]"
+ property-dict="[[networkProperties]]">
+ </network-property-list>
+ </div>
</div>
<!-- Button row: Advanced + Disconnect | Connect. -->
- <div class="layout horizontal center">
+ <div id="buttonDiv" class="layout horizontal center">
<paper-button toggles noink active="{{advancedExpanded}}"
hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties)]]">
Advanced
</paper-button>
<span class="flex"></span>
<paper-button hidden$="[[!showViewAccount_(networkProperties)]]"
- on-tap="onViewAccountClicked_">
+ on-tap="onViewAccountTap_">
View Account
</paper-button>
<paper-button hidden$="[[!showActivate_(networkProperties)]]"
- on-tap="onActivateClicked_">
+ on-tap="onActivateTap_">
Activate
</paper-button>
<paper-button hidden$="[[!showConnect_(networkProperties)]]"
- disabled="[[!enableConnect_(networkProperties)]]"
- on-tap="onConnectClicked_">
+ disabled="[[!enableConnect_(networkProperties, defaultNetwork)]]"
+ on-tap="onConnectTap_">
Connect
</paper-button>
<paper-button hidden$="[[!showDisconnect_(networkProperties)]]"
- on-tap="onDisconnectClicked_">
+ on-tap="onDisconnectTap_">
Disconnect
</paper-button>
</div>
@@ -98,9 +114,9 @@
<!-- Advanced section -->
<div id="advancedDiv" class="layout vertical"
hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties)]]">
- <cr-collapse opened="[[advancedExpanded]]">
+ <iron-collapse opened="[[advancedExpanded]]">
<!-- Advanced properties -->
- <div id="advancedInfoDiv" class="layout vertical">
+ <div id="advancedInfoDiv" class="layout vertical section">
<network-property-list
fields="[[getAdvancedFields_(networkProperties)]]"
property-dict="[[networkProperties]]">
@@ -108,13 +124,15 @@
</div>
<!-- Network (APN, address, nameservers) -->
- <div id="addressDiv" class="layout vertical"
+ <div id="addressDiv" class="layout vertical section"
hidden$="[[!hasNetworkSection_(networkProperties)]]">
- <paper-button toggles noink active="{{addressExpanded}}">
- Network
- </paper-button>
- <cr-collapse opened="[[addressExpanded]]">
- <div class="layout vertical flex">
+ <div>
+ <paper-button toggles noink active="{{addressExpanded}}">
+ Network
+ </paper-button>
+ </div>
+ <iron-collapse opened="[[addressExpanded]]">
+ <div class="layout vertical">
<network-apnlist editable
hidden$="[[!isType_(networkProperties, NetworkType.CELLULAR)]]"
network-properties="[[networkProperties]]"
@@ -129,40 +147,43 @@
on-nameservers-change="onIPConfigChange_">
</network-nameservers>
</div>
- </cr-collapse>
+ </iron-collapse>
</div>
<!-- Proxy -->
- <div class="layout vertical"
+ <div class="layout vertical section"
hidden$="[[!hasNetworkSection_(networkProperties)]]">
- <paper-button toggles noink active="{{proxyExpanded}}">
- Proxy
- </paper-button>
- <cr-collapse opened="[[proxyExpanded]]">
- <div id="proxyDiv" class="layout vertical flex">
+ <div>
+ <paper-button toggles noink active="{{proxyExpanded}}">
+ Proxy
+ </paper-button>
+ </div>
+ <iron-collapse opened="[[proxyExpanded]]">
+ <div id="proxyDiv" class="layout vertical">
<network-proxy editable
network-properties="[[networkProperties]]"
on-proxy-change="onProxyChange_">
</network-proxy>
</div>
- </cr-collapse>
+ </iron-collapse>
</div>
<!-- Device properties -->
- <div class="layout vertical"
+ <div class="layout vertical section"
hidden$="[[!hasDeviceFields_(networkProperties)]]">
- <paper-button toggles noink active="{{deviceExpanded}}">
- Device
- </paper-button>
- <cr-collapse opened="[[deviceExpanded]]">
+ <div>
+ <paper-button toggles noink active="{{deviceExpanded}}">
+ Device
+ </paper-button>
+ </div>
+ <iron-collapse opened="[[deviceExpanded]]">
<network-property-list
fields="[[getDeviceFields_(networkProperties)]]"
property-dict="[[networkProperties]]">
</network-property-list>
- <!-- TODO(stevenjb): Cellular SIM -->
- </cr-collapse>
+ </iron-collapse>
</div>
- </cr-collapse>
+ </iron-collapse>
</div>
</div>
</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 8fa56e8db11..e44c0b329c6 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
@@ -4,11 +4,11 @@
/**
* @fileoverview
- * 'cr-settings-internet-detail' is the settings subpage containing details
+ * 'settings-internet-detail' is the settings subpage containing details
* for a network.
*
* @group Chrome Settings Elements
- * @element cr-settings-internet-detail
+ * @element settings-internet-detail
*/
(function() {
'use strict';
@@ -16,7 +16,9 @@
/** @const */ var CARRIER_VERIZON = 'Verizon Wireless';
Polymer({
- is: 'cr-settings-internet-detail-page',
+ is: 'settings-internet-detail-page',
+
+ behaviors: [CrPolicyNetworkBehavior],
properties: {
/**
@@ -64,6 +66,15 @@ Polymer({
},
/**
+ * Highest priority connected network or null.
+ * @type {?CrOnc.NetworkStateProperties}
+ */
+ defaultNetwork: {
+ type: Object,
+ value: null
+ },
+
+ /**
* Object providing network type values for data binding.
* @const
*/
@@ -78,6 +89,14 @@ Polymer({
},
readOnly: true
},
+
+ /**
+ * Interface for networkingPrivate calls, passed from internet_page.
+ * @type {NetworkingPrivate}
+ */
+ networkingPrivate: {
+ type: Object,
+ },
},
/**
@@ -90,13 +109,13 @@ Polymer({
/** @override */
attached: function() {
this.networksChangedListener_ = this.onNetworksChangedEvent_.bind(this);
- chrome.networkingPrivate.onNetworksChanged.addListener(
+ this.networkingPrivate.onNetworksChanged.addListener(
this.networksChangedListener_);
},
/** @override */
detached: function() {
- chrome.networkingPrivate.onNetworksChanged.removeListener(
+ this.networkingPrivate.onNetworksChanged.removeListener(
this.networksChangedListener_);
},
@@ -173,7 +192,7 @@ Polymer({
getNetworkDetails_: function() {
if (!this.guid)
return;
- chrome.networkingPrivate.getManagedProperties(
+ this.networkingPrivate.getManagedProperties(
this.guid, this.getPropertiesCallback_.bind(this));
},
@@ -199,7 +218,7 @@ Polymer({
setNetworkProperties_: function(onc) {
if (!this.guid)
return;
- chrome.networkingPrivate.setProperties(this.guid, onc, function() {
+ this.networkingPrivate.setProperties(this.guid, onc, function() {
if (chrome.runtime.lastError) {
// An error typically indicates invalid input; request the properties
// to update any invalid fields.
@@ -244,8 +263,7 @@ Polymer({
* @private
*/
isConnectedState_: function(properties) {
- return !!properties && properties.ConnectionState ==
- CrOnc.ConnectionState.CONNECTED;
+ return properties.ConnectionState == CrOnc.ConnectionState.CONNECTED;
},
/**
@@ -254,7 +272,7 @@ Polymer({
* @private
*/
showConnect_: function(properties) {
- return !!properties && properties.Type != CrOnc.Type.ETHERNET &&
+ return properties.Type != CrOnc.Type.ETHERNET &&
properties.ConnectionState == CrOnc.ConnectionState.NOT_CONNECTED;
},
@@ -309,15 +327,18 @@ Polymer({
},
/**
+ * @param {!CrOnc.NetworkProperties} properties
+ * @param {?CrOnc.NetworkStateProperties} defaultNetwork
* @return {boolean} Whether or not to enable the network connect button.
* @private
*/
- enableConnect_: function(properties) {
+ enableConnect_: function(properties, defaultNetwork) {
if (!properties || !this.showConnect_(properties))
return false;
if (properties.Type == CrOnc.Type.CELLULAR && CrOnc.isSimLocked(properties))
return false;
- // TODO(stevenjb): For VPN, check connected state of any network.
+ if (properties.Type == CrOnc.Type.VPN && !defaultNetwork)
+ return false;
return true;
},
@@ -327,41 +348,41 @@ Polymer({
* @private
*/
showDisconnect_: function(properties) {
- return !!properties && properties.Type != CrOnc.Type.ETHERNET &&
+ return properties.Type != CrOnc.Type.ETHERNET &&
properties.ConnectionState != CrOnc.ConnectionState.NOT_CONNECTED;
},
/**
- * Callback when the Connect button is clicked.
+ * Callback when the Connect button is tapped.
* @private
*/
- onConnectClicked_: function() {
- chrome.networkingPrivate.startConnect(this.guid);
+ onConnectTap_: function() {
+ this.networkingPrivate.startConnect(this.guid);
},
/**
- * Callback when the Disconnect button is clicked.
+ * Callback when the Disconnect button is tapped.
* @private
*/
- onDisconnectClicked_: function() {
- chrome.networkingPrivate.startDisconnect(this.guid);
+ onDisconnectTap_: function() {
+ this.networkingPrivate.startDisconnect(this.guid);
},
/**
- * Callback when the Activate button is clicked.
+ * Callback when the Activate button is tapped.
* @private
*/
- onActivateClicked_: function() {
- chrome.networkingPrivate.startActivate(this.guid);
+ onActivateTap_: function() {
+ this.networkingPrivate.startActivate(this.guid);
},
/**
- * Callback when the View Account button is clicked.
+ * Callback when the View Account button is tapped.
* @private
*/
- onViewAccountClicked_: function() {
+ onViewAccountTap_: function() {
// startActivate() will show the account page for activated networks.
- chrome.networkingPrivate.startActivate(this.guid);
+ this.networkingPrivate.startActivate(this.guid);
},
/**
@@ -380,7 +401,7 @@ Polymer({
} else if (field == 'SIMLockStatus') {
CrOnc.setTypeProperty(onc, 'SIMLockStatus', value);
} else {
- console.error('Unexpected property change event: ', field);
+ console.error('Unexpected property change event: ' + field);
return;
}
this.setNetworkProperties_(onc);
@@ -487,8 +508,7 @@ Polymer({
* @private
*/
showShared_: function(properties) {
- return !!properties && (properties.Source == 'Device' ||
- properties.Source == 'DevicePolicy');
+ return properties.Source == 'Device' || properties.Source == 'DevicePolicy';
},
/**
@@ -497,19 +517,28 @@ Polymer({
* @private
*/
showAutoConnect_: function(properties) {
- return !!properties && properties.Type != CrOnc.Type.ETHERNET &&
+ return properties.Type != CrOnc.Type.ETHERNET &&
properties.Source != CrOnc.Source.NONE;
},
/**
* @param {!CrOnc.NetworkProperties} properties
+ * @return {!CrOnc.ManagedProperty|undefined} Managed AutoConnect property.
+ * @private
+ */
+ getManagedAutoConnect_: function(properties) {
+ return CrOnc.getManagedAutoConnect(properties);
+ },
+
+ /**
+ * @param {!CrOnc.NetworkProperties} properties
* @return {boolean} True if the prefer network checkbox should be shown.
* @private
*/
showPreferNetwork_: function(properties) {
// TODO(stevenjb): Resolve whether or not we want to allow "preferred" for
// properties.Type == CrOnc.Type.ETHERNET.
- return !!properties && properties.Source != CrOnc.Source.NONE;
+ return properties.Source != CrOnc.Source.NONE;
},
/**
@@ -637,7 +666,7 @@ Polymer({
* @private
*/
hasNetworkSection_: function(properties) {
- return !!properties && properties.Type != CrOnc.Type.VPN;
+ return properties.Type != CrOnc.Type.VPN;
},
/**
@@ -647,7 +676,7 @@ Polymer({
* @private
*/
isType_: function(properties, type) {
- return !!properties && properties.Type == type;
+ return properties.Type == type;
},
/**
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html b/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
index ed58dcae95b..6dd5f1e65dd 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
@@ -2,10 +2,10 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_network_list.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_network_list.html">
-<dom-module id="cr-settings-internet-known-networks-page">
- <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css">
+<dom-module id="settings-internet-known-networks-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="internet_known_networks_page.css">
<template>
<div class="layout vertical">
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 46eddc548e8..45133344e59 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
@@ -4,14 +4,14 @@
/**
* @fileoverview
- * 'cr-settings-internet-known-networks' is the settings subpage listing the
+ * 'settings-internet-known-networks' is the settings subpage listing the
* known networks for a type (currently always WiFi).
*
* @group Chrome Settings Elements
- * @element cr-settings-internet-known-networks
+ * @element settings-internet-known-networks
*/
Polymer({
- is: 'cr-settings-internet-known-networks-page',
+ is: 'settings-internet-known-networks-page',
properties: {
/**
@@ -20,7 +20,6 @@ Polymer({
*/
networkType: {
type: String,
- value: CrOnc.Type.WI_FI,
observer: 'networkTypeChanged_',
},
@@ -39,7 +38,15 @@ Polymer({
networkStateList: {
type: Array,
value: function() { return []; }
- }
+ },
+
+ /**
+ * Interface for networkingPrivate calls, passed from internet_page.
+ * @type {NetworkingPrivate}
+ */
+ networkingPrivate: {
+ type: Object,
+ },
},
/**
@@ -52,13 +59,13 @@ Polymer({
/** @override */
attached: function() {
this.networksChangedListener_ = this.onNetworksChangedEvent_.bind(this);
- chrome.networkingPrivate.onNetworksChanged.addListener(
+ this.networkingPrivate.onNetworksChanged.addListener(
this.networksChangedListener_);
},
/** @override */
detached: function() {
- chrome.networkingPrivate.onNetworksChanged.removeListener(
+ this.networkingPrivate.onNetworksChanged.removeListener(
this.networksChangedListener_);
},
@@ -91,7 +98,7 @@ Polymer({
visible: false,
configured: true
};
- chrome.networkingPrivate.getNetworks(
+ this.networkingPrivate.getNetworks(
filter,
function(states) { this.networkStateList = states; }.bind(this));
},
@@ -114,7 +121,7 @@ Polymer({
var state = event.detail;
if (!state.GUID)
return;
- chrome.networkingPrivate.forgetNetwork(state.GUID);
+ this.networkingPrivate.forgetNetwork(state.GUID);
},
/**
@@ -128,6 +135,6 @@ Polymer({
return;
var preferred = state.Priority > 0;
var onc = {Priority: preferred ? 0 : 1};
- chrome.networkingPrivate.setProperties(state.GUID, onc);
+ this.networkingPrivate.setProperties(state.GUID, onc);
},
});
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 f23d503f768..ccaa873e0de 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.html
@@ -1,38 +1,44 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html">
<link rel="import" href="internet_detail_page.html">
<link rel="import" href="internet_known_networks_page.html">
<link rel="import" href="network_summary.html">
-<dom-module id="cr-settings-internet-page">
+<dom-module id="settings-internet-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<template>
<settings-animated-pages id="pages" current-route="{{currentRoute}}"
section="internet">
- <neon-animatable id="">
+ <neon-animatable id="main">
<network-summary on-show-detail="onShowDetail_"
- on-show-known-networks="onShowKnownNetworks_">
+ default-network="{{defaultNetwork}}"
+ on-show-known-networks="onShowKnownNetworks_"
+ networking-private="[[networkingPrivate]]">
</network-summary>
</neon-animatable>
<neon-animatable id="network-detail">
<settings-subheader i18n-values="page-title:internetDetailPageTitle">
</settings-subheader>
- <cr-settings-internet-detail-page guid="[[detailGuid]]"
- on-close="onBackTap_">
- </cr-settings-internet-detail-page>
+ <settings-internet-detail-page
+ guid="[[detailGuid]]"
+ default-network="[[defaultNetwork]]"
+ on-close="onBackTap_"
+ networking-private="[[networkingPrivate]]">
+ </settings-internet-detail-page>
</neon-animatable>
<neon-animatable id="known-networks">
<settings-subheader
i18n-values="page-title:internetKnownNetworksPageTitle">
</settings-subheader>
- <cr-settings-internet-known-networks-page
+ <settings-internet-known-networks-page
network-type="[[knownNetworksType]]"
- on-show-detail="onShowDetail_">
- </cr-settings-internet-known-networks-page>
+ on-show-detail="onShowDetail_"
+ networking-private="[[networkingPrivate]]">
+ </settings-internet-known-networks-page>
</neon-animatable>
</settings-animated-pages>
</template>
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 dd66f4be6b1..49e8c1219fb 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.js
@@ -4,22 +4,22 @@
/**
* @fileoverview
- * 'cr-settings-internet-page' is the settings page containing internet
+ * 'settings-internet-page' is the settings page containing internet
* settings.
*
* Example:
*
* <core-animated-pages>
- * <cr-settings-internet-page prefs='{{prefs}}'>
- * </cr-settings-internet-page>
+ * <settings-internet-page prefs='{{prefs}}'>
+ * </settings-internet-page>
* ... other pages ...
* </core-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-internet-page
+ * @element settings-internet-page
*/
Polymer({
- is: 'cr-settings-internet-page',
+ is: 'settings-internet-page',
properties: {
/**
@@ -43,6 +43,15 @@ Polymer({
knownNetworksType: {
type: String,
},
+
+ /**
+ * Interface for networkingPrivate calls. May be overriden by tests.
+ * @type {NetworkingPrivate}
+ */
+ networkingPrivate: {
+ type: Object,
+ value: chrome.networkingPrivate,
+ },
},
/**
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.css b/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.css
index 233cc8cc644..3f7caed2235 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.css
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.css
@@ -6,9 +6,12 @@
margin-bottom: 10px;
}
+#selectDiv {
+ margin-bottom: 10px;
+}
+
#selectDiv select {
- font-size: 16px;
- margin: 10px 0 10px 5px;
+ margin-left: 10px;
padding: 5px;
}
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.html b/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.html
index 2d53bbe777e..9a7abd48fcc 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.html
@@ -1,6 +1,6 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
<link rel="import" href="network_property_list.html">
<dom-module id="network-apnlist">
@@ -25,7 +25,7 @@
edit-field-types="[[otherApnEditTypes_]]"
on-property-change="onOtherApnChange_">
</network-property-list>
- <paper-button on-tap="onSaveOther_">Save</paper-button>
+ <paper-button on-tap="onSaveOtherTap_">Save</paper-button>
</div>
</div>
</template>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.js b/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.js
index e95ff7df797..67bf2e25a65 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_apnlist.js
@@ -206,15 +206,15 @@ Polymer({
*/
onOtherApnChange_: function(event) {
this.set('otherApn.' + event.detail.field, event.detail.value);
- // Don't send a change event for 'Other' until the 'Save' button is clicked.
+ // Don't send a change event for 'Other' until the 'Save' button is tapped.
},
/**
- * Event triggered when the Other APN 'Save' button is clicked.
+ * Event triggered when the Other APN 'Save' button is tapped.
* @param {Event} event
* @private
*/
- onSaveOther_: function(event) {
+ onSaveOtherTap_: function(event) {
this.sendApnChange_(this.selectedApn);
},
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_ip_config.html b/chromium/chrome/browser/resources/settings/internet_page/network_ip_config.html
index 0245787f5ee..6db5873adf1 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_ip_config.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_ip_config.html
@@ -1,6 +1,6 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
<link rel="import" href="network_property_list.html">
<dom-module id="network-ip-config">
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_nameservers.css b/chromium/chrome/browser/resources/settings/internet_page/network_nameservers.css
index 3dda85caf16..d94c3c98b51 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_nameservers.css
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_nameservers.css
@@ -2,10 +2,11 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
+#selectTypeDiv {
+ margin: 10px 0;
+}
+
select {
- font-size: 16px;
- margin-bottom: 10px;
- margin-top: 10px;
padding: 5px;
}
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_nameservers.html b/chromium/chrome/browser/resources/settings/internet_page/network_nameservers.html
index 3b1b6f1bf43..3932b64d91d 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_nameservers.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_nameservers.html
@@ -1,12 +1,12 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
<dom-module id="network-nameservers">
<link rel="import" type="css" href="network_nameservers.css">
<template>
<div id="outer" class="layout vertical">
- <div>
+ <div id="selectTypeDiv">
<!-- TODO(stevenjb): Use cr-dropdown-menu once available. -->
<select id="type" on-change="onTypeChange_">
<template is="dom-repeat" items="[[nameserverTypeNames_]]">
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_property_list.css b/chromium/chrome/browser/resources/settings/internet_page/network_property_list.css
index 4bd06dc3d56..bdb1712e846 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_property_list.css
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_property_list.css
@@ -3,9 +3,12 @@
* found in the LICENSE file. */
span {
- @apply(--paper-font-subhead);
- @apply(--paper-input-container-input);
- margin: 0 5px 5px 0;
+ -webkit-margin-end: 5px;
+ margin-bottom: 5px;
+}
+
+cr-policy-network-indicator {
+ margin-bottom: 5px;
}
span.fill {
@@ -16,5 +19,11 @@ span.fill {
}
paper-input-container {
- margin: -8px 0 -3px 5px;
+ -webkit-margin-start: 5px;
+ margin-bottom: -3px;
+ margin-top: -12px;
+}
+
+#outerDiv {
+ padding: 5px 0;
}
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_property_list.html b/chromium/chrome/browser/resources/settings/internet_page/network_property_list.html
index 79db6d9f822..426b2f8d1e4 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_property_list.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_property_list.html
@@ -1,12 +1,13 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/paper-styles.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator.html">
<dom-module name="network-property-list">
<link rel="import" type="css" href="network_property_list.css">
<template>
- <div class="layout horizontal">
+ <div id="outerDiv" class="layout horizontal">
<div class="layout vertical">
<template is="dom-repeat" items="[[fields]]">
<div class="layout horizontal"
@@ -21,6 +22,8 @@
<div class="layout horizontal"
hidden$="[[!showNoEdit_(propertyDict, editFieldTypes, item)]]">
<span>[[getPropertyValue_(propertyDict, item)]]</span>
+ <cr-policy-network-indicator property="[[propertyDict]]">
+ </cr-policy-network-indicator>
</div>
<div class="layout horizontal" hidden$=
"[[!showEdit_(propertyDict, editFieldTypes, item, 'String')]]">
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_property_list.js b/chromium/chrome/browser/resources/settings/internet_page/network_property_list.js
index 87b64216d51..b988501a46d 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_property_list.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_property_list.js
@@ -14,9 +14,12 @@
Polymer({
is: 'network-property-list',
+ behaviors: [CrPolicyNetworkBehavior],
+
properties: {
/**
* The dictionary containing the properties to display.
+ * @type {!Object|undefined}
*/
propertyDict: {
type: Object
@@ -80,18 +83,18 @@ Polymer({
},
/**
- * @param {!Object|undefined} propertyDict
+ * @param {!Object} propertyDict
* @param {string} key The property key.
* @return {boolean} Whether or not the property exists in |propertyDict|.
* @private
*/
hasPropertyValue_: function(propertyDict, key) {
- var value = (propertyDict && this.get(key, propertyDict)) || undefined;
- return (value !== undefined && value !== '');
+ var value = this.get(key, propertyDict);
+ return value !== undefined && value !== '';
},
/**
- * @param {!Object|undefined} propertyDict
+ * @param {!Object} propertyDict
* @param {!Object} editFieldTypes The editFieldTypes object.
* @param {string} key The property key.
* @return {boolean} Whether or not to show the property. Editable properties
@@ -105,7 +108,7 @@ Polymer({
},
/**
- * @param {!Object|undefined} propertyDict
+ * @param {!Object} propertyDict
* @param {!Object} editFieldTypes The editFieldTypes object.
* @param {string} key The property key.
* @return {boolean} True if |key| exists in |propertiesDict| and is not
@@ -115,12 +118,15 @@ Polymer({
showNoEdit_: function(propertyDict, editFieldTypes, key) {
if (!this.hasPropertyValue_(propertyDict, key))
return false;
- var editType = editFieldTypes[key];
- return !editType;
+ var property = /** @type {!CrOnc.ManagedProperty|undefined} */(
+ this.get(key, propertyDict));
+ if (this.isNetworkPolicyEnforced(property))
+ return true;
+ return !editFieldTypes[key];
},
/**
- * @param {!Object|undefined} propertyDict
+ * @param {!Object} propertyDict
* @param {!Object} editFieldTypes The editFieldTypes object.
* @param {string} key The property key.
* @param {string} type The field type.
@@ -129,18 +135,22 @@ Polymer({
* @private
*/
showEdit_: function(propertyDict, editFieldTypes, key, type) {
+ if (!this.hasPropertyValue_(propertyDict, key))
+ return false;
+ var property = /** @type {!CrOnc.ManagedProperty|undefined} */(
+ this.get(key, propertyDict));
+ if (this.isNetworkPolicyEnforced(property))
+ return false;
return editFieldTypes[key] == type;
},
/**
- * @param {!Object|undefined} propertyDict
+ * @param {!Object} propertyDict
* @param {string} key The property key.
* @return {string} The text to display for the property value.
* @private
*/
getPropertyValue_: function(propertyDict, key) {
- if (!propertyDict)
- return '';
var value = this.get(key, propertyDict);
if (value === undefined)
return '';
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy.css b/chromium/chrome/browser/resources/settings/internet_page/network_proxy.css
index 9098be477e7..a4ff258515c 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy.css
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy.css
@@ -6,19 +6,23 @@
display: inline-block;
}
+#selectTypeDiv {
+ margin: 10px 0;
+}
+
select {
- font-size: 16px;
- margin-bottom: 10px;
- margin-top: 10px;
padding: 5px;
}
span {
- @apply(--paper-font-subhead);
- @apply(--paper-input-container-input);
margin: 5px;
}
+cr-policy-network-indicator {
+ -webkit-margin-end: 10px;
+ mwrgin-bottom: 5px;
+}
+
paper-checkbox {
margin-bottom: 10px;
}
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy.html b/chromium/chrome/browser/resources/settings/internet_page/network_proxy.html
index 61ae5fdc3c7..9e5f5a0c8cb 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy.html
@@ -2,8 +2,9 @@
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/paper-styles.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator.html">
<link rel="import" href="network_property_list.html">
<link rel="import" href="network_proxy_input.html">
<link rel="import" href="network_proxy_exclusions.html">
@@ -13,8 +14,17 @@
<template>
<div id="outer" class="layout vertical flex">
<!-- TODO(stevenjb): Use cr-dropdown-menu once available. -->
- <div>
- <select id="selectType" on-change="onTypeChange_">
+ <div class="layout horizontal center" hidden$=
+ "[[!isNetworkPolicyControlled(networkProperties.ProxySettings.Type)]]">
+ <cr-policy-network-indicator
+ property="[[networkProperties.ProxySettings.Type]]">
+ </cr-policy-network-indicator>
+ <span>This proxy is enforced by your administrator.</span>
+ </div>
+
+ <div id="selectTypeDiv">
+ <select id="selectType" on-change="onTypeChange_"
+ disabled$="[[isNetworkPolicyEnforced(networkProperties.ProxySettings.Type)]]">
<template is="dom-repeat" items="[[proxyTypes_]]">
<option value="[[item]]">[[proxyTypeDesc_(item)]]</option>
</template>
@@ -25,6 +35,7 @@
class="layout horizontal">
<span>Autoconfiguration URL:</span>
<paper-input no-label-float class="flex" value="{{proxy.PAC}}"
+ disabled="[[isNetworkPolicyEnforced(networkProperties.ProxySettings.PAC)]]">
on-blur="onProxyInputChange_">
</paper-input>
</div>
@@ -40,25 +51,30 @@
Use the same proxy for all protocols
</paper-checkbox>
<div hidden$="[[!useSameProxy]]" class="layout vertical">
- <network-proxy-input editable="[[editable]]"
+ <network-proxy-input
+ editable="[[isPropertyEditable_(editable, networkProperties, 'ProxySettings.Manual.HTTPProxy')]]"
value="{{proxy.Manual.HTTPProxy}}"
label="Proxy" on-proxy-change="onProxyInputChange_">
</network-proxy-input>
</div>
<div hidden$="[[useSameProxy]]" class="layout vertical">
- <network-proxy-input editable="[[editable]]"
+ <network-proxy-input
+ editable="[[isPropertyEditable_(editable, networkProperties, 'ProxySettings.Manual.HTTPProxy)')]]"
value="{{proxy.Manual.HTTPProxy}}"
label="HTTP Proxy" on-proxy-change="onProxyInputChange_">
</network-proxy-input>
- <network-proxy-input editable="[[editable]]"
+ <network-proxy-input
+ editable="[[isPropertyEditable_(editable, networkProperties, 'ProxySettings.Manual.SecureHTTPProxy)')]]"
value="{{proxy.Manual.SecureHTTPProxy}}"
label="Secure HTTP Proxy" on-proxy-change="onProxyInputChange_">
</network-proxy-input>
- <network-proxy-input editable="[[editable]]"
+ <network-proxy-input
+ editable="[[isPropertyEditable_(editable, networkProperties, 'ProxySettings.Manual.FTPProxy)')]]"
value="{{proxy.Manual.FTPProxy}}"
label="FTP Proxy" on-proxy-change="onProxyInputChange_">
</network-proxy-input>
- <network-proxy-input editable="[[editable]]"
+ <network-proxy-input
+ editable="[[isPropertyEditable_(editable, networkProperties, 'ProxySettings.Manual.SOCKS)')]]"
value="{{proxy.Manual.SOCKS}}"
label="SOCKS host" on-proxy-change="onProxyInputChange_">
</network-proxy-input>
@@ -71,7 +87,7 @@
<div class="layout horizontal baseline">
<paper-input id="proxyExclusion" class="flex" no-label-float>
</paper-input>
- <paper-button on-tap="onAddProxyExclusion_">
+ <paper-button on-tap="onAddProxyExclusionTap_">
Add Exception
</paper-button>
</div>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy.js b/chromium/chrome/browser/resources/settings/internet_page/network_proxy.js
index c7c02e631d2..1d9fd113100 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy.js
@@ -9,6 +9,8 @@
Polymer({
is: 'network-proxy',
+ behaviors: [CrPolicyNetworkBehavior],
+
properties: {
/**
* The network properties dictionary containing the proxy properties to
@@ -220,7 +222,7 @@ Polymer({
* @param {Event} event The add proxy exclusion event.
* @private
*/
- onAddProxyExclusion_: function(event) {
+ onAddProxyExclusionTap_: function(event) {
var value = this.$.proxyExclusion.value;
if (!value)
return;
@@ -256,6 +258,21 @@ Polymer({
},
/**
+ * @param {boolean} editable
+ * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {string} key
+ * @return {boolean} Whether the property is editable.
+ * @private
+ */
+ isPropertyEditable_: function(editable, networkProperties, key) {
+ if (!editable)
+ return false;
+ var property = /** @type {!CrOnc.ManagedProperty|undefined} */(
+ this.get(key, networkProperties));
+ return !this.isNetworkPolicyEnforced(property);
+ },
+
+ /**
* @param {string} property The property to test
* @param {string} value The value to test against
* @return {boolean} True if property == value
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html
index 07b9273001a..35dad0e2fa7 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html
@@ -1,6 +1,5 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/paper-styles.html">
<dom-module id="network-proxy-exclusions">
<link rel="import" type="css" href="network_proxy_exclusions.css">
@@ -9,7 +8,7 @@
<template is="dom-repeat" items="[[exclusions]]">
<div class="layout horizontal">
<span class="flex">[[item]]</span>
- <iron-icon icon="clear" on-click="removeItem_"></iron-icon>
+ <iron-icon icon="clear" on-tap="onRemoveTap_"></iron-icon>
</div>
</template>
</div>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js
index b765e1d8218..2d408b7cf92 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js
@@ -29,7 +29,7 @@ Polymer({
* @param {!{model: !{index: number}}} event
* @private
*/
- removeItem_: function(event) {
+ onRemoveTap_: function(event) {
var index = event.model.index;
this.splice('exclusions', index, 1);
this.fire('proxy-change');
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.css b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.css
index 16302dead55..518cedf12b9 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.css
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.css
@@ -7,8 +7,6 @@
}
span {
- @apply(--paper-font-subhead);
- @apply(--paper-input-container-input);
margin-right: 5px;
}
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.html b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.html
index 6eeef81a2b3..21f196cd237 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_input.html
@@ -1,6 +1,5 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/paper-styles.html">
<dom-module id="network-proxy-input">
<link rel="import" type="css" href="network_proxy_input.css">
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.css b/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.css
index 2f31161e170..df0d574c71b 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.css
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.css
@@ -2,16 +2,17 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-span {
- margin-right: 10px;
+iron-icon {
+ -webkit-margin-end: 5px;
+ -webkit-margin-start: -3px;
}
-#outerDiv {
- margin-bottom: 10px;
+paper-button {
+ margin: 0;
}
-#lockedDiv iron-icon {
- margin: 0 5px 0 -2px;
+span {
+ -webkit-margin-end: 10px;
}
#lockedDiv span {
@@ -20,16 +21,16 @@ span {
}
#lockedDiv paper-input {
- margin-left: 10px;
+ -webkit-margin-start: 10px;
width: 80px;
}
#unlockSimDialog paper-input {
- margin-left: 5px;
+ -webkit-margin-start: 5px;
}
#unlockSimDialog span {
- margin-left: 5px;
+ -webkit-margin-start: 5px;
}
.pin {
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.html b/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.html
index 03450ad7a0b..cb13629bbfb 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.html
@@ -1,10 +1,11 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/notification-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
<link rel="import" href="network_property_list.html">
<dom-module id="network-siminfo">
@@ -12,19 +13,19 @@
<template>
<div id="outerDiv" class="layout vertical">
<div class="layout horizontal center"
- hidden$="[[state.Cellular.SIMPresent]]">
+ hidden$="[[networkProperties.Cellular.SIMPresent]]">
<!-- SIM missing UI -->
- <iron-icon icon="sim-card-alert"></iron-icon>
+ <iron-icon icon="notification:sim-card-alert"></iron-icon>
<span>Missing SIM card</span>
</div>
<div class="layout vertical"
- hidden$="[[!state.Cellular.SIMPresent]]">
+ hidden$="[[!networkProperties.Cellular.SIMPresent]]">
<div id="lockedDiv" class="layout horizontal center"
hidden$="[[!isSimLocked_(networkProperties)]]">
<!-- SIM locked -->
<iron-icon icon="lock"></iron-icon>
<span>SIM card is locked.</span>
- <paper-button on-tap="unlockPin_">Unlock</paper-button>
+ <paper-button on-tap="onUnlockPinTap_">Unlock</paper-button>
</div>
<div class="layout vertical"
hidden$="[[isSimLocked_(networkProperties)]]">
@@ -37,7 +38,7 @@
<div class="layout horizontal center"
hidden$="[[!networkProperties.Cellular.SIMLockStatus.LockEnabled]]">
<!-- SIM lock enabled -->
- <paper-button on-tap="onChangePin_">Change PIN</paper-button>
+ <paper-button on-tap="onChangePinTap_">Change PIN</paper-button>
</div>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.js b/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.js
index d93268cdccb..3d3bfd4ea14 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_siminfo.js
@@ -49,6 +49,14 @@ Polymer({
type: Object,
value: ErrorType.NONE
},
+
+ /**
+ * Interface for networkingPrivate calls, passed from internet_page.
+ * @type {NetworkingPrivate}
+ */
+ networkingPrivate: {
+ type: Object,
+ },
},
sendSimLockEnabled_: false,
@@ -135,7 +143,7 @@ Polymer({
currentPin: pin,
requirePin: this.sendSimLockEnabled_
});
- chrome.networkingPrivate.setCellularSimState(guid, simState, function() {
+ this.networkingPrivate.setCellularSimState(guid, simState, function() {
if (chrome.runtime.lastError) {
this.error = ErrorType.INCORRECT_PIN;
} else {
@@ -150,7 +158,7 @@ Polymer({
* @param {Event} event
* @private
*/
- onChangePin_: function(event) {
+ onChangePinTap_: function(event) {
if (!this.networkProperties || !this.networkProperties.Cellular)
return;
this.error = ErrorType.NONE;
@@ -188,7 +196,7 @@ Polymer({
currentPin: this.$.changePinOld.value,
newPin: newPin
});
- chrome.networkingPrivate.setCellularSimState(guid, simState, function() {
+ this.networkingPrivate.setCellularSimState(guid, simState, function() {
if (chrome.runtime.lastError) {
this.error = ErrorType.INCORRECT_PIN;
} else {
@@ -203,7 +211,7 @@ Polymer({
* @param {Event} event
* @private
*/
- unlockPin_: function(event) {
+ onUnlockPinTap_: function(event) {
this.error = ErrorType.NONE;
this.$.unlockPinDialog.open();
},
@@ -231,7 +239,7 @@ Polymer({
if (!this.validatePin_(pin))
return;
- chrome.networkingPrivate.unlockCellularSim(guid, pin, '', function() {
+ this.networkingPrivate.unlockCellularSim(guid, pin, '', function() {
if (chrome.runtime.lastError) {
this.error = ErrorType.INCORRECT_PIN;
} else {
@@ -280,7 +288,7 @@ Polymer({
if (!this.validatePin_(pin, this.$.unlockPin2.value))
return;
- chrome.networkingPrivate.unlockCellularSim(guid, pin, puk, function() {
+ this.networkingPrivate.unlockCellularSim(guid, pin, puk, function() {
if (chrome.runtime.lastError) {
this.error = ErrorType.INCORRECT_PUK;
} else {
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary.html b/chromium/chrome/browser/resources/settings/internet_page/network_summary.html
index 9e3f8d757be..505d61e361c 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_summary.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary.html
@@ -1,9 +1,8 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
<link rel="import" href="network_summary_item.html">
<dom-module id="network-summary">
- <link rel="import" type="css" href="network_summary.css">
<template>
<div id="summary" class="layout vertical">
<network-summary-item id="ethernet"
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 3086221ba1b..d7ad7b568c2 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_summary.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary.js
@@ -59,6 +59,16 @@ Polymer({
properties: {
/**
+ * Highest priority connected network or null.
+ * @type {?CrOnc.NetworkStateProperties}
+ */
+ defaultNetwork: {
+ type: Object,
+ value: null,
+ notify: true
+ },
+
+ /**
* The device state for each network device type.
* @type {DeviceStateObject}
*/
@@ -83,6 +93,14 @@ Polymer({
networkStateLists: {
type: Object,
value: function() { return {}; },
+ },
+
+ /**
+ * Interface for networkingPrivate calls, passed from internet_page.
+ * @type {NetworkingPrivate}
+ */
+ networkingPrivate: {
+ type: Object,
}
},
@@ -123,28 +141,28 @@ Polymer({
this.networkListChangedListener_ =
this.onNetworkListChangedEvent_.bind(this);
- chrome.networkingPrivate.onNetworkListChanged.addListener(
+ this.networkingPrivate.onNetworkListChanged.addListener(
this.networkListChangedListener_);
this.deviceStateListChangedListener_ =
this.onDeviceStateListChangedEvent_.bind(this);
- chrome.networkingPrivate.onDeviceStateListChanged.addListener(
+ this.networkingPrivate.onDeviceStateListChanged.addListener(
this.deviceStateListChangedListener_);
this.networksChangedListener_ = this.onNetworksChangedEvent_.bind(this);
- chrome.networkingPrivate.onNetworksChanged.addListener(
+ this.networkingPrivate.onNetworksChanged.addListener(
this.networksChangedListener_);
},
/** @override */
detached: function() {
- chrome.networkingPrivate.onNetworkListChanged.removeListener(
+ this.networkingPrivate.onNetworkListChanged.removeListener(
this.networkListChangedListener_);
- chrome.networkingPrivate.onDeviceStateListChanged.removeListener(
+ this.networkingPrivate.onDeviceStateListChanged.removeListener(
this.deviceStateListChangedListener_);
- chrome.networkingPrivate.onNetworksChanged.removeListener(
+ this.networkingPrivate.onNetworksChanged.removeListener(
this.networksChangedListener_);
},
@@ -154,9 +172,11 @@ Polymer({
* @private
*/
onWiFiExpanded_: function(event) {
- this.getNetworkStates_(); // Get the latest network states (only).
- if (event.detail.expanded)
- chrome.networkingPrivate.requestNetworkScan();
+ if (!event.detail.expanded)
+ return;
+ // Get the latest network states (only).
+ this.getNetworkStates_();
+ this.networkingPrivate.requestNetworkScan();
},
/**
@@ -166,7 +186,7 @@ Polymer({
*/
onSelected_: function(event) {
var state = event.detail;
- if (state.ConnectionState == CrOnc.ConnectionState.NOT_CONNECTED) {
+ if (this.canConnect_(state)) {
this.connectToNetwork_(state);
return;
}
@@ -182,9 +202,9 @@ Polymer({
*/
onDeviceEnabledToggled_: function(event) {
if (event.detail.enabled)
- chrome.networkingPrivate.enableNetworkType(event.detail.type);
+ this.networkingPrivate.enableNetworkType(event.detail.type);
else
- chrome.networkingPrivate.disableNetworkType(event.detail.type);
+ this.networkingPrivate.disableNetworkType(event.detail.type);
},
/**
@@ -207,42 +227,66 @@ Polymer({
onNetworksChangedEvent_: function(networkIds) {
networkIds.forEach(function(id) {
if (id in this.networkIds_) {
- chrome.networkingPrivate.getState(
- id,
- function(state) {
- if (chrome.runtime.lastError) {
- if (chrome.runtime.lastError.message !=
- 'Error.NetworkUnavailable') {
- console.error('Unexpected networkingPrivate.getState error:',
- chrome.runtime.lastError, 'For:', id);
- }
- return;
- }
- // Async call, ensure id still exists.
- if (!this.networkIds_[id])
- return;
- if (!state) {
- this.networkIds_[id] = undefined;
- return;
- }
- this.updateNetworkState_(state.Type, state);
- }.bind(this));
+ this.networkingPrivate.getState(
+ id, this.getStateCallback_.bind(this, id));
}
}, this);
},
/**
+ * Determines whether or not a network state can be connected to.
+ * @param {!CrOnc.NetworkStateProperties} state The network state.
+ * @private
+ */
+ canConnect_: function(state) {
+ if (state.Type == CrOnc.Type.ETHERNET ||
+ state.Type == CrOnc.Type.VPN && !this.defaultNetwork) {
+ return false;
+ }
+ return state.ConnectionState == CrOnc.ConnectionState.NOT_CONNECTED;
+ },
+
+ /**
+ * networkingPrivate.getState event callback.
+ * @param {string} id The id of the requested state.
+ * @param {!chrome.networkingPrivate.NetworkStateProperties} state
+ * @private
+ */
+ getStateCallback_: function(id, state) {
+ if (chrome.runtime.lastError) {
+ var message = chrome.runtime.lastError.message;
+ if (message != 'Error.NetworkUnavailable') {
+ console.error(
+ 'Unexpected networkingPrivate.getState error: ' + message +
+ ' For: ' + id);
+ }
+ return;
+ }
+ // Async call, ensure id still exists.
+ if (!this.networkIds_[id])
+ return;
+ if (!state) {
+ this.networkIds_[id] = undefined;
+ return;
+ }
+ this.updateNetworkState_(state.Type, state);
+ },
+
+ /**
* Handles UI requests to connect to a network.
* TODO(stevenjb): Handle Cellular activation, etc.
* @param {!CrOnc.NetworkStateProperties} state The network state.
* @private
*/
connectToNetwork_: function(state) {
- chrome.networkingPrivate.startConnect(state.GUID, function() {
- if (chrome.runtime.lastError &&
- chrome.runtime.lastError != 'connecting') {
- console.error('Unexpected networkingPrivate.startConnect error:',
- chrome.runtime.lastError);
+ this.networkingPrivate.startConnect(state.GUID, function() {
+ if (chrome.runtime.lastError) {
+ var message = chrome.runtime.lastError.message;
+ if (message != 'connecting') {
+ console.error(
+ 'Unexpected networkingPrivate.startConnect error: ' + message +
+ 'For: ' + state.GUID);
+ }
}
});
},
@@ -255,48 +299,51 @@ Polymer({
*/
getNetworkLists_: function() {
// First get the device states.
- chrome.networkingPrivate.getDeviceStates(
- function(states) {
- this.getDeviceStatesCallback_(states);
+ this.networkingPrivate.getDeviceStates(
+ function(deviceStates) {
// Second get the network states.
- this.getNetworkStates_();
+ this.getNetworkStates_(deviceStates);
}.bind(this));
},
/**
* Requests the list of network states from Chrome. Updates networkStates and
* networkStateLists once the results are returned from Chrome.
+ * @param {!Array<!DeviceStateProperties>=} opt_deviceStates
+ * Optional list of state properties for all available devices.
* @private
*/
- getNetworkStates_: function() {
+ getNetworkStates_: function(opt_deviceStates) {
var filter = {
networkType: chrome.networkingPrivate.NetworkType.ALL,
visible: true,
configured: false
};
- chrome.networkingPrivate.getNetworks(
- filter, this.getNetworksCallback_.bind(this));
+ this.networkingPrivate.getNetworks(filter, function(networkStates) {
+ this.updateNetworkStates_(networkStates, opt_deviceStates);
+ }.bind(this));
},
/**
- * networkingPrivate.getDeviceStates callback.
- * @param {!Array<!DeviceStateProperties>} states The state properties for all
- * available devices.
+ * Called after network states are received from getNetworks.
+ * @param {!Array<!CrOnc.NetworkStateProperties>} networkStates The state
+ * properties for all visible networks.
+ * @param {!Array<!DeviceStateProperties>=} opt_deviceStates
+ * Optional list of state properties for all available devices. If not
+ * defined the existing list of device states will be used.
* @private
*/
- getDeviceStatesCallback_: function(states) {
- var newStates = /** @type {!DeviceStateObject} */({});
- states.forEach(function(state) { newStates[state.Type] = state; });
- this.deviceStates = newStates;
- },
+ updateNetworkStates_: function(networkStates, opt_deviceStates) {
+ var newDeviceStates;
+ if (opt_deviceStates) {
+ newDeviceStates = /** @type {!DeviceStateObject} */({});
+ opt_deviceStates.forEach(function(state) {
+ newDeviceStates[state.Type] = state;
+ });
+ } else {
+ newDeviceStates = this.deviceStates;
+ }
- /**
- * networkingPrivate.getNetworksState callback.
- * @param {!Array<!CrOnc.NetworkStateProperties>} states The state properties
- * for all visible networks.
- * @private
- */
- getNetworksCallback_: function(states) {
// Clear any current networks.
this.networkIds_ = {};
@@ -312,21 +359,28 @@ Polymer({
VPN: []
};
- states.forEach(function(state) {
+ var firstConnectedNetwork = null;
+ networkStates.forEach(function(state) {
var type = state.Type;
if (!foundTypes[type]) {
foundTypes[type] = true;
this.updateNetworkState_(type, state);
+ if (!firstConnectedNetwork && state.Type != CrOnc.Type.VPN &&
+ state.ConnectionState == CrOnc.ConnectionState.CONNECTED) {
+ firstConnectedNetwork = state;
+ }
}
networkStateLists[type].push(state);
}, this);
+ this.defaultNetwork = firstConnectedNetwork;
+
// Set any types with a deviceState and no network to a default state,
// and any types not found to undefined.
NETWORK_TYPES.forEach(function(type) {
if (!foundTypes[type]) {
var defaultState = undefined;
- if (this.deviceStates[type])
+ if (newDeviceStates[type])
defaultState = {GUID: '', Type: type};
this.updateNetworkState_(type, defaultState);
}
@@ -336,9 +390,13 @@ Polymer({
// Create a VPN entry in deviceStates if there are any VPN networks.
if (networkStateLists.VPN && networkStateLists.VPN.length > 0) {
- var vpn = {Type: CrOnc.Type.VPN, State: 'Enabled'};
- this.set('deviceStates.VPN', vpn);
+ newDeviceStates.VPN = /** @type {DeviceStateProperties} */ ({
+ Type: CrOnc.Type.VPN,
+ State: chrome.networkingPrivate.DeviceStateType.ENABLED
+ });
}
+
+ this.deviceStates = newDeviceStates;
},
/**
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 9ab31df9e0a..897787cb6ad 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,16 +2,16 @@
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/cr_expand_button/cr_expand_button.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_network_list.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_network_list_item.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_network_list.html">
+<link rel="import" href="chrome://resources/cr_elements/network/cr_network_list_item.html">
<dom-module name="network-summary-item">
<link rel="import" type="css" href="network_summary_item.css">
<template>
<div class="layout vertical" hidden$="[[isHidden]]">
<div id="details" class="layout horizontal center"
- on-click="onDetailsClicked_">
+ on-tap="onDetailsTap_">
<cr-network-list-item id="detailsItem"
network-state="[[networkState]]">
</cr-network-list-item>
@@ -26,7 +26,7 @@
<paper-toggle-button id="deviceEnabledButton"
checked="[[deviceIsEnabled_(deviceState)]]"
class$="[[getDeviceEnabledButtonClass_(deviceState)]]"
- on-tap="onDeviceEnabledToggled_">
+ on-tap="onDeviceEnabledTap_">
</paper-toggle-button>
</div>
</div>
@@ -34,13 +34,12 @@
<cr-network-list id="networkList"
max-height="[[maxHeight]]"
networks="[[networkStateList]]"
- on-selected="onListItemSelected_"
opened="{{expanded}}">
</cr-network-list>
<div class="layout horizontal">
<paper-button
hidden$="[[!showKnownNetworks_(networkState, expanded)]]"
- on-tap="onKnownNetworksClicked_">
+ on-tap="onKnownNetworksTap_">
Known networks
</paper-button>
</div>
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 67e7a1b0e4c..f363bf44bd8 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
@@ -83,7 +83,7 @@ Polymer({
*/
deviceStateChanged_: function() {
this.updateSelectable_();
- if (!this.deviceIsEnabled_(this.deviceState))
+ if (this.expanded && !this.deviceIsEnabled_(this.deviceState))
this.expanded = false;
},
@@ -168,11 +168,11 @@ Polymer({
},
/**
- * Event triggered when the details div is clicked.
+ * Event triggered when the details div is tapped.
* @param {Event} event The enable button event.
* @private
*/
- onDetailsClicked_: function(event) {
+ onDetailsTap_: function(event) {
if ((event.target.id == 'expandListButton') ||
(this.deviceState && !this.deviceIsEnabled_(this.deviceState))) {
// Already handled or disabled, do nothing.
@@ -188,34 +188,24 @@ Polymer({
},
/**
- * Event triggered when the known networks button is clicked.
+ * Event triggered when the known networks button is tapped.
* @private
*/
- onKnownNetworksClicked_: function() {
+ onKnownNetworksTap_: function() {
this.fire('show-known-networks', {type: CrOnc.Type.WI_FI});
},
/**
- * Event triggered when a network-list-item is the network list is selected.
- * @param {!{detail: !CrOnc.NetworkStateProperties}} event
- * @private
- */
- onListItemSelected_: function(event) {
- var state = event.detail;
- this.fire('selected', state);
- },
-
- /**
* Event triggered when the enable button is toggled.
- * @param {!Object} event The enable button event.
+ * @param {!Event} event
* @private
*/
- onDeviceEnabledToggled_: function(event) {
+ onDeviceEnabledTap_: function(event) {
var deviceIsEnabled = this.deviceIsEnabled_(this.deviceState);
var type = this.deviceState ? this.deviceState.Type : '';
this.fire('device-enabled-toggled',
{enabled: !deviceIsEnabled, type: type});
- // Make sure this does not propagate to onDetailsClicked_.
+ // Make sure this does not propagate to onDetailsTap_.
event.stopPropagation();
},
diff --git a/chromium/chrome/browser/resources/settings/languages_page/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/languages_page/compiled_resources.gyp
index ea0bdf4e14c..67b25d332c9 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/settings/languages_page/compiled_resources.gyp
@@ -11,6 +11,7 @@
'../prefs/compiled_resources.gyp:prefs',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ 'languages_types.js',
],
'externs': [
'<(EXTERNS_DIR)/chrome_send.js',
@@ -23,10 +24,11 @@
'target_name': 'language_detail_page',
'variables': {
'depends': [
- '../../../../../ui/webui/resources/cr_elements/v1_0/policy/cr_policy_indicator.js',
+ '../../../../../ui/webui/resources/cr_elements/policy/compiled_resources.gyp:cr_policy_indicator_behavior',
'../../../../../ui/webui/resources/js/chromeos/compiled_resources.gyp:ui_account_tweaks',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
'../prefs/compiled_resources.gyp:prefs',
+ 'languages_types.js',
'languages.js',
],
'externs': [
@@ -45,6 +47,7 @@
'../settings_page/settings_animated_pages.js',
'../prefs/prefs_types.js',
'../prefs/compiled_resources.gyp:prefs',
+ 'languages_types.js',
'languages.js',
],
'externs': [
@@ -59,10 +62,11 @@
'depends': [
'../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
'../prefs/compiled_resources.gyp:prefs',
+ 'languages_types.js',
'languages.js',
],
'externs': [
- '../../../../../third_party/closure_compiler/externs/language_settings_private.js',
+ '<(EXTERNS_DIR)/language_settings_private.js',
],
},
'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
diff --git a/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.css b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.css
new file mode 100644
index 00000000000..306a9d25cc1
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.css
@@ -0,0 +1,25 @@
+/* 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. */
+
+:host {
+ display: flex;
+ flex-direction: column;
+}
+
+#addWordRow {
+ display: flex;
+}
+
+#newWord {
+ flex: 1;
+}
+
+iron-list {
+ /* TODO(michaelpg): Size to fit the viewport. */
+ height: 300px;
+}
+
+iron-list .word {
+ flex: 1;
+}
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
new file mode 100644
index 00000000000..6788df9d11f
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html
@@ -0,0 +1,36 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys/iron-a11y-keys.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+
+<dom-module id="settings-edit-dictionary-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="edit_dictionary_page.css">
+ <template>
+ <div class="settings-box">
+ <div id="addWordRow">
+ <iron-a11y-keys id="keys" keys="enter esc"
+ on-keys-pressed="onKeysPress_"></iron-a11y-keys>
+ <paper-input id="newWord" no-label-float
+ i18n-values="label:addDictionaryWordLabel"></paper-input>
+ <paper-button on-tap="onAddWordTap_"
+ i18n-content="addDictionaryWordButton"></paper-button>
+ </div>
+ <h2 i18n-content="customDictionaryWords"></h2>
+ <iron-list id="list" items="{{words_}}">
+ <template>
+ <paper-item>
+ <div class="word">[[item]]</div>
+ <paper-icon-button icon="clear" on-tap="onRemoveWordTap_">
+ </paper-icon-button>
+ </paper-item>
+ </template>
+ </iron-list>
+ </div>
+ </template>
+ <script src="edit_dictionary_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js
new file mode 100644
index 00000000000..4db5a30856b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js
@@ -0,0 +1,103 @@
+// 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.
+
+/**
+ * @fileoverview 'settings-edit-dictionary-page' is a sub-page for editing
+ * the "dictionary" of custom words used for spell check.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-edit-dictionary-page
+ */
+Polymer({
+ is: 'settings-edit-dictionary-page',
+
+ properties: {
+ /** @private {!Array<string>} */
+ words_: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+
+ ready: function() {
+ chrome.languageSettingsPrivate.getSpellcheckWords(function(words) {
+ this.words_ = words;
+ }.bind(this));
+
+ // Updates are applied locally so they appear immediately, but we should
+ // listen for changes in case they come from elsewhere.
+ chrome.languageSettingsPrivate.onCustomDictionaryChanged.addListener(
+ this.onCustomDictionaryChanged_.bind(this));
+
+ // Add a key handler for the paper-input.
+ this.$.keys.target = this.$.newWord;
+ },
+
+ /**
+ * Handles updates to the word list. Additions triggered by this element are
+ * de-duped so the word list remains a set. Words are appended to the end
+ * instead of re-sorting the list so it's clear what words were added.
+ * @param {!Array<string>} added
+ * @param {!Array<string>} removed
+ */
+ onCustomDictionaryChanged_: function(added, removed) {
+ for (var i = 0; i < removed.length; i++)
+ this.arrayDelete('words_', removed[i]);
+
+ for (var i = 0; i < added.length; i++) {
+ if (this.words_.indexOf(added[i]) == -1)
+ this.push('words_', added[i]);
+ }
+ },
+
+ /**
+ * Handles Enter and Escape key presses for the paper-input.
+ * @param {!{detail: !{key: string}}} e
+ */
+ onKeysPress_: function(e) {
+ if (e.detail.key == 'enter')
+ this.addWordFromInput_();
+ else if (e.detail.key == 'esc')
+ e.detail.keyboardEvent.target.value = '';
+ },
+
+ /**
+ * Handles tapping on the Add Word button.
+ */
+ onAddWordTap_: function(e) {
+ this.addWordFromInput_();
+ this.$.newWord.focus();
+ },
+
+ /**
+ * Handles tapping on a paper-item's Remove Word icon button.
+ * @param {!{model: !{item: string}}} e
+ */
+ onRemoveWordTap_: function(e) {
+ chrome.languageSettingsPrivate.removeSpellcheckWord(e.model.item);
+ this.arrayDelete('words_', e.model.item);
+ },
+
+ /**
+ * Adds the word in the paper-input to the dictionary, also appending it
+ * to the end of the list of words shown to the user.
+ */
+ addWordFromInput_: function() {
+ // Spaces are allowed, but removing leading and trailing whitespace.
+ var word = this.$.newWord.value.trim();
+ this.$.newWord.value = '';
+ if (!word)
+ return;
+
+ var index = this.words_.indexOf(word);
+ if (index == -1) {
+ chrome.languageSettingsPrivate.addSpellcheckWord(word);
+ this.push('words_', word);
+ }
+
+ // Scroll to the word (usually the bottom, or to the index if the word
+ // is already present).
+ this.$.list.scrollToIndex(index);
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/languages_page/language_detail_page.html b/chromium/chrome/browser/resources/settings/languages_page/language_detail_page.html
index 51b17676a08..28bc6d63d93 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/language_detail_page.html
+++ b/chromium/chrome/browser/resources/settings/languages_page/language_detail_page.html
@@ -1,7 +1,7 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/policy/cr_policy_indicator.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="languages.html">
@@ -11,11 +11,10 @@
</if>
<dom-module id="settings-language-detail-page">
- <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="language_detail_page.css">
<template>
- <cr-settings-languages id="languages" languages="{{languages}}">
- </cr-settings-languages>
+ <settings-languages languages="{{languages}}"></settings-languages>
<if expr="chromeos or is_win">
<div id="languageSettings">
<label hidden$="[[!detail.language.supportsUI]]">
@@ -33,7 +32,8 @@
hidden$="[[!isRestartRequired_(detail.language.code, prefs.intl.app_locale.value)]]">
</paper-button>
</span>
- <cr-policy-indicator id="policyIndicator"></cr-policy-indicator>
+ <cr-policy-pref-indicator id="policyIndicator">
+ </cr-policy-pref-indicator>
</label>
<span i18n-content="cannotBeDisplayedInThisLanguage"
hidden$="[[detail.language.supportsUI]]"></span>
diff --git a/chromium/chrome/browser/resources/settings/languages_page/language_detail_page.js b/chromium/chrome/browser/resources/settings/languages_page/language_detail_page.js
index aadcc60b7bb..8f89226f835 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/language_detail_page.js
+++ b/chromium/chrome/browser/resources/settings/languages_page/language_detail_page.js
@@ -23,7 +23,7 @@ Polymer({
/**
* Read-only reference to the languages model provided by the
- * 'cr-settings-languages' instance.
+ * 'settings-languages' instance.
* @type {LanguagesModel|undefined}
*/
languages: Object,
@@ -35,11 +35,14 @@ Polymer({
detail: Object,
},
+ /** @private {!LanguageHelper} */
+ languageHelper_: LanguageHelperImpl.getInstance(),
+
ready: function() {
// In a CrOS multi-user session, the primary user controls the UI language.
if (this.isSecondaryUser_()) {
var indicator = this.$.policyIndicator;
- indicator.indicatorType = CrPolicyIndicator.Type.PRIMARY_USER;
+ indicator.indicatorType = CrPolicyIndicatorType.PRIMARY_USER;
indicator.controllingUser = loadTimeData.getString('primaryUserEmail');
}
@@ -51,15 +54,19 @@ Polymer({
}
},
+<if expr="chromeos or is_win">
/**
+ * Checks whether the prospective UI language (the pref that indicates what
+ * language to use in Chrome) matches the current language. This pref is only
+ * on Chrome OS and Windows; we don't control the UI language elsewhere.
* @param {string} languageCode The language code identifying a language.
- * @param {string} prospectiveUILanguage The chosen UI language.
- * @return {boolean} True if the given language matches the chosen UI language
- * (which may be different from the actual UI language).
+ * @param {string} prospectiveUILanguage The prospective UI language.
+ * @return {boolean} True if the given language matches the prospective UI
+ * pref (which may be different from the actual UI language).
* @private
*/
isProspectiveUILanguage_: function(languageCode, prospectiveUILanguage) {
- return languageCode == this.$.languages.getProspectiveUILanguage();
+ return languageCode == this.languageHelper_.getProspectiveUILanguage();
},
/**
@@ -73,6 +80,7 @@ Polymer({
return languageCode == prospectiveUILanguage &&
languageCode == navigator.language;
},
+</if>
/**
* @param {string} languageCode The language code identifying a language.
@@ -81,7 +89,7 @@ Polymer({
* @private
*/
isTranslateDisabled_: function(languageCode, targetLanguageCode) {
- return this.$.languages.convertLanguageCodeForTranslate(languageCode) ==
+ return this.languageHelper_.convertLanguageCodeForTranslate(languageCode) ==
targetLanguageCode;
},
@@ -140,9 +148,9 @@ Polymer({
*/
onTranslateEnabledChange_: function(e) {
if (e.target.checked)
- this.$.languages.enableTranslateLanguage(this.detail.language.code);
+ this.languageHelper_.enableTranslateLanguage(this.detail.language.code);
else
- this.$.languages.disableTranslateLanguage(this.detail.language.code);
+ this.languageHelper_.disableTranslateLanguage(this.detail.language.code);
},
/**
@@ -152,10 +160,10 @@ Polymer({
*/
onUILanguageChange_: function(e) {
if (e.target.checked) {
- this.$.languages.setUILanguage(this.detail.language.code);
+ this.languageHelper_.setUILanguage(this.detail.language.code);
} else {
// Reset the chosen UI language to the actual UI language.
- this.$.languages.resetUILanguage();
+ this.languageHelper_.resetUILanguage();
}
},
diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages.html b/chromium/chrome/browser/resources/settings/languages_page/languages.html
index d426d5e9e9b..d6003b3b3b3 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/languages.html
+++ b/chromium/chrome/browser/resources/settings/languages_page/languages.html
@@ -2,10 +2,11 @@
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://md-settings/prefs/prefs.html">
+<link rel="import" href="chrome://md-settings/prefs/prefs_behavior.html">
-<dom-module id="cr-settings-languages-singleton">
+<dom-module id="settings-languages-singleton">
<template>
- <cr-settings-prefs prefs="{{prefs}}"></cr-settings-prefs>
+ <settings-prefs prefs="{{prefs}}"></settings-prefs>
</template>
<script src="languages.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages.js b/chromium/chrome/browser/resources/settings/languages_page/languages.js
index c65c0e74660..a8925429cd2 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/languages.js
+++ b/chromium/chrome/browser/resources/settings/languages_page/languages.js
@@ -3,47 +3,28 @@
// found in the LICENSE file.
/**
- * @fileoverview 'cr-settings-languages' provides convenient access to
+ * @fileoverview 'settings-languages' provides convenient access to
* Chrome's language and input method settings.
*
* Instances of this element have a 'languages' property, which reflects the
* current language settings. The 'languages' property is read-only, meaning
* hosts using this element cannot change it directly. Instead, changes to
- * language settings should be made using this element's public functions.
+ * language settings should be made using the LanguageHelperImpl singleton.
*
- * Use two-way binding syntax to propagate changes from child to host, so that
+ * Use upward binding syntax to propagate changes from child to host, so that
* changes made internally to 'languages' propagate to your host element:
*
* <template>
- * <cr-settings-languages languages="{{languages}}">
- * </cr-settings-languages>
+ * <settings-languages languages="{{languages}}">
+ * </settings-languages>
* <div>[[languages.someProperty]]</div>
* </template>
*
* @group Chrome Settings Elements
- * @element cr-settings-languages
+ * @element settings-languages
*/
-/** @typedef {{spellCheckEnabled: boolean, translateEnabled: boolean}} */
-var LanguageState;
-
-/**
- * @typedef {{language: !chrome.languageSettingsPrivate.Language,
- * state: !LanguageState}}
- */
-var LanguageInfo;
-
-/**
- * supportedLanguages: an array of languages, ordered alphabetically.
- * enabledLanguages: an array of enabled language info and state, ordered by
- * preference.
- * @typedef {{
- * supportedLanguages: !Array<!chrome.languageSettingsPrivate.Language>,
- * enabledLanguages: !Array<!LanguageInfo>,
- * translateTarget: string
- * }}
- */
-var LanguagesModel;
+var SettingsLanguagesSingletonElement;
(function() {
'use strict';
@@ -66,131 +47,20 @@ var kTranslateLanguageSynonyms = {
'jv': 'jw',
};
-/**
- * This element has a reference to the singleton, exposing the singleton's
- * language model to the host of this element as the 'languages' property.
- */
-Polymer({
- is: 'cr-settings-languages',
-
- properties: {
- /**
- * Singleton element created at startup which provides the languages model.
- * @type {!Element}
- */
- singleton_: {
- type: Object,
- value: document.createElement('cr-settings-languages-singleton'),
- },
-
- /**
- * A reference to the languages model from the singleton, exposed as a
- * read-only property so hosts can bind to it, but not change it.
- * @type {LanguagesModel|undefined}
- */
- languages: {
- type: Object,
- notify: true,
- readOnly: true,
- },
- },
-
- ready: function() {
- // Set the 'languages' property to reference the singleton's model.
- this._setLanguages(this.singleton_.languages);
- // Listen for changes to the singleton's languages property, so we know
- // when to notify hosts of changes to (our reference to) the property.
- this.listen(
- this.singleton_, 'languages-changed', 'singletonLanguagesChanged_');
- },
-
- /**
- * Takes changes reported by the singleton and forwards them to the host,
- * manually sending a change notification for our 'languages' property (since
- * it's the same object as the singleton's property, but isn't bound by
- * Polymer).
- * @private
- */
- singletonLanguagesChanged_: function(e) {
- // Forward the change notification to the host.
- this.fire(e.type, e.detail, {bubbles: false});
- },
-
- // Forward public methods to the singleton.
-
- /** @param {string} languageCode */
- setUILanguage: function(languageCode) {
- if (cr.isWindows || cr.isChromeOS)
- this.singleton_.setUILanguage(languageCode);
- },
-
- resetUILanguage: function() {
- if (cr.isWindows || cr.isChromeOS)
- this.singleton_.resetUILanguage();
- },
-
- /** @return {string} */
- getProspectiveUILanguage: function() {
- return this.singleton_.getProspectiveUILanguage();
- },
-
- /** @param {string} languageCode */
- enableLanguage: function(languageCode) {
- this.singleton_.enableLanguage(languageCode);
- },
-
- /** @param {string} languageCode */
- disableLanguage: function(languageCode) {
- this.singleton_.disableLanguage(languageCode);
- },
-
- /** @param {string} languageCode */
- enableTranslateLanguage: function(languageCode) {
- this.singleton_.enableTranslateLanguage(languageCode);
- },
-
- /** @param {string} languageCode */
- disableTranslateLanguage: function(languageCode) {
- this.singleton_.disableTranslateLanguage(languageCode);
- },
-
- /**
- * @param {string} languageCode
- * @return {boolean}
- */
- isEnabled: function(languageCode) {
- return this.singleton_.isEnabled(languageCode);
- },
-
- /**
- * @param {string} languageCode
- * @param {boolean} enable
- */
- toggleSpellCheck: function(languageCode, enable) {
- this.singleton_.toggleSpellCheck(languageCode, enable);
- },
-
- /**
- * @param {string} languageCode
- * @return {string}
- */
- convertLanguageCodeForTranslate: function(languageCode) {
- return this.singleton_.convertLanguageCodeForTranslate(languageCode);
- },
-});
-
var preferredLanguagesPrefName = cr.isChromeOS ?
'settings.language.preferred_languages' : 'intl.accept_languages';
/**
- * Singleton element created when cr-settings-languages is registered.
- * Generates the languages model on start-up, and updates it whenever Chrome's
- * pref store and other settings change. These updates propagate to each
- * <cr-settings-language> instance so that their 'languages' property updates
- * like any other Polymer property.
+ * Singleton element that generates the languages model on start-up and
+ * updates it whenever Chrome's pref store and other settings change. These
+ * updates propagate to each <settings-language> instance so that their
+ * 'languages' property updates like any other Polymer property.
+ * @implements {LanguageHelper}
*/
-Polymer({
- is: 'cr-settings-languages-singleton',
+SettingsLanguagesSingletonElement = Polymer({
+ is: 'settings-languages-singleton',
+
+ behaviors: [PrefsBehavior],
properties: {
/**
@@ -265,11 +135,68 @@ Polymer({
},
/**
+ * Updates the list of enabled languages from the preferred languages pref.
+ * @private
+ */
+ preferredLanguagesPrefChanged_: function() {
+ if (!this.initialized_)
+ return;
+
+ var enabledLanguages =
+ this.getEnabledLanguages_(this.languages.translateTarget);
+
+ // Reset the enabled language map before updating
+ // languages.enabledLanguages.
+ this.enabledLanguageMap_ = {};
+ for (var i = 0; i < enabledLanguages.length; i++) {
+ var languageInfo = enabledLanguages[i];
+ this.enabledLanguageMap_[languageInfo.language.code] = languageInfo;
+ }
+ this.set('languages.enabledLanguages', enabledLanguages);
+ },
+
+ /**
+ * Updates the spellCheckEnabled state of each enabled language.
+ * @private
+ */
+ spellCheckDictionariesPrefChanged_: function() {
+ if (!this.initialized_)
+ return;
+
+ var spellCheckMap = this.makeMapFromArray_(/** @type {!Array<string>} */(
+ this.getPref('spellcheck.dictionaries').value));
+ for (var i = 0; i < this.languages.enabledLanguages.length; i++) {
+ var languageCode = this.languages.enabledLanguages[i].language.code;
+ this.set('languages.enabledLanguages.' + i + '.state.spellCheckEnabled',
+ !!spellCheckMap[languageCode]);
+ }
+ },
+
+ /** @private */
+ translateLanguagesPrefChanged_: function() {
+ if (!this.initialized_)
+ return;
+
+ var translateBlockedPref = this.getPref('translate_blocked_languages');
+ var translateBlockedMap = this.makeMapFromArray_(
+ /** @type {!Array<string>} */(translateBlockedPref.value));
+
+ for (var i = 0; i < this.languages.enabledLanguages.length; i++) {
+ var translateCode = this.convertLanguageCodeForTranslate(
+ this.languages.enabledLanguages[i].language.code);
+ this.set(
+ 'languages.enabledLanguages.' + i + '.state.translateEnabled',
+ !translateBlockedMap[translateCode]);
+ }
+ },
+
+ /**
* Constructs the languages model.
* @param {!Array<!chrome.languageSettingsPrivate.Language>}
* supportedLanguages
* @param {string} translateTarget Language code of the default translate
* target language.
+ * @private
*/
createModel_: function(supportedLanguages, translateTarget) {
// Populate the hash map of supported languages.
@@ -308,32 +235,34 @@ Polymer({
getEnabledLanguages_: function(translateTarget) {
assert(CrSettingsPrefs.isInitialized);
- var pref = this.getPref_(preferredLanguagesPrefName);
+ var pref = this.getPref(preferredLanguagesPrefName);
var enabledLanguageCodes = pref.value.split(',');
var enabledLanguages = /** @type {!Array<!LanguageInfo>} */ [];
- var spellCheckPref = this.getPref_('spellcheck.dictionaries');
+ var spellCheckPref = this.getPref('spellcheck.dictionaries');
var spellCheckMap = this.makeMapFromArray_(/** @type {!Array<string>} */(
spellCheckPref.value));
- var translateBlockedPref = this.getPref_('translate_blocked_languages');
+ var translateBlockedPref = this.getPref('translate_blocked_languages');
var translateBlockedMap = this.makeMapFromArray_(
/** @type {!Array<string>} */(translateBlockedPref.value));
for (var i = 0; i < enabledLanguageCodes.length; i++) {
var code = enabledLanguageCodes[i];
var language = this.supportedLanguageMap_[code];
+ // Skip unsupported languages.
if (!language)
continue;
- var state = {};
+ var state = /** @type {LanguageState} */({});
state.spellCheckEnabled = !!spellCheckMap[code];
// Translate is considered disabled if this language maps to any translate
// language that is blocked.
var translateCode = this.convertLanguageCodeForTranslate(code);
- state.translateEnabled = language.supportsTranslate &&
+ state.translateEnabled = !!language.supportsTranslate &&
!translateBlockedMap[translateCode] &&
translateCode != translateTarget;
- enabledLanguages.push({language: language, state: state});
+ enabledLanguages.push(/** @type {LanguageInfo} */(
+ {language: language, state: state}));
}
return enabledLanguages;
},
@@ -342,6 +271,7 @@ Polymer({
* Creates an object whose keys are the elements of the list.
* @param {!Array<string>} list
* @return {!Object<boolean>}
+ * @private
*/
makeMapFromArray_: function(list) {
var map = {};
@@ -350,107 +280,21 @@ Polymer({
return map;
},
- /**
- * Updates the list of enabled languages from the preferred languages pref.
- * @private
- * */
- preferredLanguagesPrefChanged_: function() {
- if (!this.initialized_)
- return;
-
- var enabledLanguages =
- this.getEnabledLanguages_(this.languages.translateTarget);
- // Reset the enabled language map. Do this before notifying of the change
- // via languages.enabledLanguages.
- this.enabledLanguageMap_ = {};
- for (var i = 0; i < enabledLanguages.length; i++) {
- var languageInfo = enabledLanguages[i];
- this.enabledLanguageMap_[languageInfo.language.code] = languageInfo;
- }
- this.set('languages.enabledLanguages', enabledLanguages);
- },
-
- /**
- * Updates the spellCheckEnabled state of each enabled language.
- * @private
- */
- spellCheckDictionariesPrefChanged_: function() {
- if (!this.initialized_)
- return;
-
- var spellCheckMap = this.makeMapFromArray_(/** @type {!Array<string>} */(
- this.getPref_('spellcheck.dictionaries').value));
- for (var i = 0; i < this.languages.enabledLanguages.length; i++) {
- var languageCode = this.languages.enabledLanguages[i].language.code;
- this.set('languages.enabledLanguages.' + i + '.state.spellCheckEnabled',
- !!spellCheckMap[languageCode]);
- }
- },
-
- translateLanguagesPrefChanged_: function() {
- if (!this.initialized_)
- return;
-
- var translateBlockedPref = this.getPref_('translate_blocked_languages');
- var translateBlockedMap = this.makeMapFromArray_(
- /** @type {!Array<string>} */(translateBlockedPref.value));
-
- for (var i = 0; i < this.languages.enabledLanguages.length; i++) {
- var translateCode = this.convertLanguageCodeForTranslate(
- this.languages.enabledLanguages[i].language.code);
- this.set(
- 'languages.enabledLanguages.' + i + '.state.translateEnabled',
- !translateBlockedMap[translateCode]);
- }
- },
-
- /**
- * Gets the pref at the given key. Asserts if the pref is not found.
- * @param {string} key
- * @return {!chrome.settingsPrivate.PrefObject}
- */
- getPref_: function(key) {
- var pref = /** @type {!chrome.settingsPrivate.PrefObject} */(
- this.get(key, this.prefs));
- assert(typeof pref != 'undefined', 'Pref is missing: ' + key);
- return pref;
- },
-
- /**
- * Sets the value of the pref at the given key. Asserts if the pref is not
- * found.
- * @param {string} key
- * @param {*} value
- */
- setPrefValue_: function(key, value) {
- this.getPref_(key);
- this.set('prefs.' + key + '.value', value);
- },
-
- /**
- * Deletes the given item from the pref at the given key if the item is found.
- * Asserts if the pref itself is not found or is not an Array type.
- * @param {string} key
- * @param {*} item
- */
- deletePrefItem_: function(key, item) {
- assert(this.getPref_(key).type == chrome.settingsPrivate.PrefType.LIST);
- this.arrayDelete('prefs.' + key + '.value', item);
- },
+ // LanguageHelper implementation.
+ // TODO(michaelpg): replace duplicate docs with @override once b/24294625
+ // is fixed.
+<if expr="chromeos or is_win">
/**
- * Windows and Chrome OS only: Sets the prospective UI language to the chosen
- * language. This dosen't affect the actual UI language until a restart.
+ * Sets the prospective UI language to the chosen language. This won't affect
+ * the actual UI language until a restart.
* @param {string} languageCode
*/
setUILanguage: function(languageCode) {
chrome.send('setUILanguage', [languageCode]);
},
- /**
- * Windows and Chrome OS only: Resets the prospective UI language back to the
- * actual UI language.
- */
+ /** Resets the prospective UI language back to the actual UI language. */
resetUILanguage: function() {
chrome.send('setUILanguage', [navigator.language]);
},
@@ -460,12 +304,20 @@ Polymer({
* restart. If the pref is not set, the current UI language is also the
* "prospective" language.
* @return {string} Language code of the prospective UI language.
- * @private
*/
getProspectiveUILanguage: function() {
- return /** @type {string} */(this.getPref_('intl.app_locale').value) ||
+ return /** @type {string} */(this.getPref('intl.app_locale').value) ||
navigator.language;
},
+</if>
+
+ /**
+ * @param {string} languageCode
+ * @return {boolean} True if the language is enabled.
+ */
+ isLanguageEnabled: function(languageCode) {
+ return !!this.enabledLanguageMap_[languageCode];
+ },
/**
* Enables the language, making it available for spell check and input.
@@ -476,7 +328,7 @@ Polymer({
return;
var languageCodes =
- this.getPref_(preferredLanguagesPrefName).value.split(',');
+ this.getPref(preferredLanguagesPrefName).value.split(',');
if (languageCodes.indexOf(languageCode) > -1)
return;
languageCodes.push(languageCode);
@@ -492,17 +344,14 @@ Polymer({
if (!CrSettingsPrefs.isInitialized)
return;
- // Cannot disable the UI language.
- assert(languageCode != this.getProspectiveUILanguage());
-
- // Cannot disable the only enabled language.
- var languageCodes =
- this.getPref_(preferredLanguagesPrefName).value.split(',');
- assert(languageCodes.length > 1);
+ assert(this.canDisableLanguage(languageCode));
// Remove the language from spell check.
- this.deletePrefItem_('spellcheck.dictionaries', languageCode);
+ this.deletePrefListItem('spellcheck.dictionaries', languageCode);
+ // Remove the language from preferred languages.
+ var languageCodes =
+ this.getPref(preferredLanguagesPrefName).value.split(',');
var languageIndex = languageCodes.indexOf(languageCode);
if (languageIndex == -1)
return;
@@ -512,11 +361,21 @@ Polymer({
},
/**
- * @param {string} languageCode
- * @return {boolean} True if the language is enabled.
+ * @param {string} languageCode Language code for an enabled language.
+ * @return {boolean}
*/
- isEnabled: function(languageCode) {
- return !!this.enabledLanguageMap_[languageCode];
+ canDisableLanguage: function(languageCode) {
+ // Cannot disable the prospective UI language.
+ if ((cr.isChromeOS || cr.isWindows) &&
+ languageCode == this.getProspectiveUILanguage()) {
+ return false;
+ }
+
+ // Cannot disable the only enabled language.
+ if (this.languages.enabledLanguages.length == 1)
+ return false;
+
+ return true;
},
/**
@@ -526,7 +385,7 @@ Polymer({
*/
enableTranslateLanguage: function(languageCode) {
languageCode = this.convertLanguageCodeForTranslate(languageCode);
- this.arrayDelete('prefs.translate_blocked_languages.value', languageCode);
+ this.deletePrefListItem('translate_blocked_languages', languageCode);
},
/**
@@ -535,11 +394,8 @@ Polymer({
* @param {string} languageCode
*/
disableTranslateLanguage: function(languageCode) {
- languageCode = this.convertLanguageCodeForTranslate(languageCode);
- if (this.getPref_('translate_blocked_languages').value
- .indexOf(languageCode) == -1) {
- this.push('prefs.translate_blocked_languages.value', languageCode);
- }
+ this.appendPrefListItem('translate_blocked_languages',
+ this.convertLanguageCodeForTranslate(languageCode));
},
/**
@@ -552,11 +408,10 @@ Polymer({
return;
if (enable) {
- var spellCheckPref = this.getPref_('spellcheck.dictionaries');
- if (spellCheckPref.value.indexOf(languageCode) == -1)
- this.push('prefs.spellcheck.dictionaries.value', languageCode);
+ var spellCheckPref = this.getPref('spellcheck.dictionaries');
+ this.appendPrefListItem('spellcheck.dictionaries', languageCode);
} else {
- this.arrayDelete('prefs.spellcheck.dictionaries.value', languageCode);
+ this.deletePrefListItem('spellcheck.dictionaries', languageCode);
}
},
@@ -566,7 +421,6 @@ Polymer({
* Accept-Language.
* @param {string} languageCode
* @return {string} The converted language code.
- * @private
*/
convertLanguageCodeForTranslate: function(languageCode) {
if (languageCode in kLanguageCodeToTranslateCode)
@@ -583,5 +437,72 @@ Polymer({
return main;
},
+
+ /**
+ * @param {string} languageCode
+ * @return {!chrome.languageSettingsPrivate.Language|undefined}
+ */
+ getLanguage: function(languageCode) {
+ return this.supportedLanguageMap_[languageCode];
+ },
});
})();
+
+/**
+ * A reference to the singleton under the guise of a LanguageHelper
+ * implementation. This provides a limited API but implies the singleton
+ * should not be used directly for data binding.
+ */
+var LanguageHelperImpl = SettingsLanguagesSingletonElement;
+cr.addSingletonGetter(LanguageHelperImpl);
+
+/**
+ * This element has a reference to the singleton, exposing the singleton's
+ * |languages| model to the host of this element.
+ */
+Polymer({
+ is: 'settings-languages',
+
+ properties: {
+ /**
+ * Singleton element created at startup which provides the languages model.
+ * @type {!SettingsLanguagesSingletonElement}
+ */
+ singleton_: {
+ type: Object,
+ value: LanguageHelperImpl.getInstance(),
+ },
+
+ /**
+ * A reference to the languages model from the singleton, exposed as a
+ * read-only property so hosts can bind to it, but not change it.
+ * @type {LanguagesModel|undefined}
+ */
+ languages: {
+ type: Object,
+ notify: true,
+ readOnly: true,
+ },
+ },
+
+ ready: function() {
+ // Set the 'languages' property to reference the singleton's model.
+ this._setLanguages(this.singleton_.languages);
+ // Listen for changes to the singleton's languages property, so we know
+ // when to notify hosts of changes to (our reference to) the property.
+ this.listen(
+ this.singleton_, 'languages-changed', 'singletonLanguagesChanged_');
+ },
+
+ /**
+ * Takes changes reported by the singleton and forwards them to the host,
+ * manually sending a change notification for our 'languages' property (since
+ * it's the same object as the singleton's property, but isn't bound by
+ * Polymer).
+ * @private
+ */
+ singletonLanguagesChanged_: function(e) {
+ // Forward the change notification to the host.
+ this.fire(e.type, e.detail, {bubbles: false});
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages_page.html b/chromium/chrome/browser/resources/settings/languages_page/languages_page.html
index a4e935e6b4b..882342c7d61 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/languages_page.html
+++ b/chromium/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -14,74 +14,81 @@
<link rel="import" href="languages.html">
<link rel="import" href="manage_languages_page.html">
-<dom-module id="cr-settings-languages-page">
+<if expr="not is_macosx">
+<link rel="import" href="edit_dictionary_page.html">
+</if>
+
+<dom-module id="settings-languages-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="languages_page.css">
<template>
- <cr-settings-languages id="languages" languages="{{languages}}">
- </cr-settings-languages>
+ <settings-languages languages="{{languages}}"></settings-languages>
<settings-animated-pages id="pages" current-route="{{currentRoute}}"
section="languages">
- <neon-animatable id="">
- <h2 i18n-content="languagesListTitle"></h2>
- <div class="item-list">
- <array-selector id="languageSelector" selected="{{detailLanguage}}"
- items="{{languages.enabledLanguages}}"></array-selector>
- <template is="dom-repeat" items="{{languages.enabledLanguages}}">
- <paper-item on-tap="onLanguageTap_">
- <div class="flex" title="[[item.language.nativeDisplayName]]"
- >[[item.language.displayName]]</div>
- <iron-icon icon="done"
- hidden$="[[!isUILanguage_(item.language.code, prefs.intl.app_locale.value)]]">
- </iron-icon>
- <paper-icon-button icon="settings"
- on-tap="onShowLanguageDetailTap_"></paper-icon-button>
- </paper-item>
- </template>
- </div>
- <div class="manage">
- <paper-button i18n-content="manageLanguages"
- on-tap="onManageLanguagesTap_"></paper-button>
- </div>
+ <neon-animatable id="main">
+ <div class="settings-box">
+ <h2 i18n-content="languagesListTitle"></h2>
+ <div>
+ <array-selector id="languageSelector" selected="{{detailLanguage}}"
+ items="{{languages.enabledLanguages}}"></array-selector>
+ <template is="dom-repeat" items="{{languages.enabledLanguages}}">
+ <paper-item class="split" on-tap="onLanguageTap_">
+ <div class="flex" title="[[item.language.nativeDisplayName]]"
+ >[[item.language.displayName]]</div>
+<if expr="chromeos or is_win">
+ <iron-icon icon="done"
+ hidden$="[[!isProspectiveUILanguage_(item.language.code, prefs.intl.app_locale.value)]]">
+ </iron-icon>
+</if>
+ <paper-icon-button icon="settings"
+ on-tap="onShowLanguageDetailTap_"></paper-icon-button>
+ </paper-item>
+ </template>
+ </div>
+ <div class="manage">
+ <paper-button i18n-content="manageLanguages"
+ on-tap="onManageLanguagesTap_"></paper-button>
+ </div>
<if expr="chromeos">
- <h2 i18n-content="inputMethodsListTitle"></h2>
- <div class="item-list">
- <template is="dom-repeat" items="{{languages.inputMethods}}">
- <paper-item>
- <div class="flex">[[item.name]]</div>
- <iron-icon icon="done"
- hidden$="[[
- !isCurrentInputMethod_(item.id, languages.currentInputMethod)]]">
- </iron-icon>
- <paper-icon-button icon="settings"></paper-icon-button>
- </paper-item>
- </template>
- </div>
- <div class="manage">
- <paper-button i18n-content="manageInputMethods"></paper-button>
- </div>
+ <h2 i18n-content="inputMethodsListTitle"></h2>
+ <div>
+ <template is="dom-repeat" items="{{languages.inputMethods}}">
+ <paper-item class="split">
+ <div class="flex">[[item.name]]</div>
+ <iron-icon icon="done"
+ hidden$="[[!isCurrentInputMethod_(item.id, languages.currentInputMethod)]]">
+ </iron-icon>
+ <paper-icon-button icon="settings"></paper-icon-button>
+ </paper-item>
+ </template>
+ </div>
+ <div class="manage">
+ <paper-button i18n-content="manageInputMethods"></paper-button>
+ </div>
</if>
<if expr="not is_macosx">
- <h2 i18n-content="spellCheckListTitle"></h2>
- <div class="layout vertical">
- <template is="dom-repeat" items="{{languages.enabledLanguages}}">
- <paper-checkbox hidden="[[!item.language.supportsSpellcheck]]"
- checked="[[item.state.spellCheckEnabled]]"
- on-change="onSpellCheckChange_"
- >[[item.language.displayName]]</paper-checkbox>
- </template>
- </div>
- <div class="manage">
- <paper-button i18n-content="manageSpellCheck"></paper-button>
- </div>
+ <h2 i18n-content="spellCheckListTitle"></h2>
+ <div class="layout vertical">
+ <template is="dom-repeat" items="{{languages.enabledLanguages}}">
+ <paper-checkbox hidden="[[!item.language.supportsSpellcheck]]"
+ checked="[[item.state.spellCheckEnabled]]"
+ on-change="onSpellCheckChange_"
+ >[[item.language.displayName]]</paper-checkbox>
+ </template>
+ </div>
+ <div class="manage">
+ <paper-button i18n-content="manageSpellCheck"
+ on-tap="onEditDictionaryTap_"></paper-button>
+ </div>
</if>
+ </div>
</neon-animatable>
<neon-animatable id="manage-languages">
<settings-subheader i18n-values="page-title:manageLanguagesPageTitle">
</settings-subheader>
- <cr-settings-manage-languages-page id="manageLanguagesPage"
- prefs="{{prefs}}"></cr-settings-manage-languages-page>
+ <settings-manage-languages-page
+ prefs="{{prefs}}"></settings-manage-languages-page>
</neon-animatable>
<neon-animatable id="language-detail">
<settings-subheader id="language-detail-subheader"
@@ -91,6 +98,14 @@
prefs="{{prefs}}" detail="[[detailLanguage]]">
</settings-language-detail-page>
</neon-animatable>
+<if expr="not is_macosx">
+ <neon-animatable id="edit-dictionary">
+ <settings-subheader id="edit-dictionary-subheader"
+ i18n-values="page-title:editDictionaryPageTitle">
+ </settings-subheader>
+ <settings-edit-dictionary-page></settings-edit-dictionary-page>
+ </neon-animatable>
+</if>
</settings-animated-pages>
</template>
<script src="languages_page.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages_page.js b/chromium/chrome/browser/resources/settings/languages_page/languages_page.js
index 427c915325a..12c83e3a7e3 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/languages_page.js
+++ b/chromium/chrome/browser/resources/settings/languages_page/languages_page.js
@@ -3,17 +3,17 @@
// found in the LICENSE file.
/**
- * @fileoverview 'cr-settings-languages-page' is the settings page
+ * @fileoverview 'settings-languages-page' is the settings page
* for language and input method settings.
*
* @group Chrome Settings Elements
- * @element cr-settings-languages-page
+ * @element settings-languages-page
*/
(function() {
'use strict';
Polymer({
- is: 'cr-settings-languages-page',
+ is: 'settings-languages-page',
properties: {
/**
@@ -34,7 +34,7 @@ Polymer({
/**
* Read-only reference to the languages model provided by the
- * 'cr-settings-languages' instance.
+ * 'settings-languages' instance.
* @type {LanguagesModel|undefined}
*/
languages: {
@@ -43,19 +43,26 @@ Polymer({
},
},
+ /** @private {!LanguageHelper} */
+ languageHelper_: LanguageHelperImpl.getInstance(),
+
/**
* Handler for clicking a language on the main page, which selects the
* language as the prospective UI language on Chrome OS and Windows.
* @param {!{model: !{item: !LanguageInfo}}} e
*/
onLanguageTap_: function(e) {
+ // Only change the UI language on platforms that allow it.
+ if (!cr.isChromeOS && !cr.isWindows)
+ return;
+
// Taps on the paper-icon-button are handled in onShowLanguageDetailTap_.
if (e.target.tagName == 'PAPER-ICON-BUTTON')
return;
// Set the prospective UI language. This won't take effect until a restart.
if (e.model.item.language.supportsUI)
- this.$.languages.setUILanguage(e.model.item.language.code);
+ this.languageHelper_.setUILanguage(e.model.item.language.code);
},
/**
@@ -63,8 +70,8 @@ Polymer({
* @param {!{target: Element, model: !{item: !LanguageInfo}}} e
*/
onSpellCheckChange_: function(e) {
- this.$.languages.toggleSpellCheck(e.model.item.language.code,
- e.target.checked);
+ this.languageHelper_.toggleSpellCheck(e.model.item.language.code,
+ e.target.checked);
},
/** @private */
@@ -78,10 +85,7 @@ Polymer({
*/
onManageLanguagesTap_: function() {
this.$.pages.setSubpageChain(['manage-languages']);
- // HACK(michaelpg): This is necessary to show the list when navigating to
- // the sub-page. Remove when PolymerElements/neon-animation#60 is fixed.
- /** @type {{_render: function()}} */(this.$.manageLanguagesPage.$.list)
- ._render();
+ this.forceRenderList_('settings-manage-languages-page');
},
/**
@@ -94,16 +98,32 @@ Polymer({
this.$.pages.setSubpageChain(['language-detail']);
},
+<if expr="not is_macosx">
+ /**
+ * Opens the Custom Dictionary page.
+ * @private
+ */
+ onEditDictionaryTap_: function() {
+ this.$.pages.setSubpageChain(['edit-dictionary']);
+ this.forceRenderList_('settings-edit-dictionary-page');
+ },
+</if>
+
+<if expr="chromeos or is_win">
/**
+ * Checks whether the prospective UI language (the pref that indicates what
+ * language to use in Chrome) matches the current language. This pref is only
+ * on Chrome OS and Windows; we don't control the UI language elsewhere.
* @param {string} languageCode The language code identifying a language.
* @param {string} prospectiveUILanguage The prospective UI language.
* @return {boolean} True if the given language matches the prospective UI
* pref (which may be different from the actual UI language).
* @private
*/
- isUILanguage_: function(languageCode, prospectiveUILanguage) {
- return languageCode == this.$.languages.getProspectiveUILanguage();
+ isProspectiveUILanguage_: function(languageCode, prospectiveUILanguage) {
+ return languageCode == this.languageHelper_.getProspectiveUILanguage();
},
+</if>
/**
* @param {string} id The input method ID.
@@ -115,5 +135,15 @@ Polymer({
assert(cr.isChromeOS);
return id == currentId;
},
+
+ /**
+ * HACK(michaelpg): This is necessary to show the list when navigating to
+ * the sub-page. Remove this function when PolymerElements/neon-animation#60
+ * is fixed.
+ * @param {string} tagName Name of the element containing the <iron-list>.
+ */
+ forceRenderList_: function(tagName) {
+ this.$$(tagName).$$('iron-list').fire('iron-resize');
+ },
});
})();
diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages_types.js b/chromium/chrome/browser/resources/settings/languages_page/languages_types.js
new file mode 100644
index 00000000000..895d3469bfe
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/languages_page/languages_types.js
@@ -0,0 +1,127 @@
+// 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.
+
+/**
+ * @fileoverview Closure typedefs for dictionaries and interfaces used by
+ * language settings.
+ */
+
+/**
+ * Current properties of a language.
+ * @typedef {{spellCheckEnabled: boolean, translateEnabled: boolean,
+ * removable: boolean}} */
+var LanguageState;
+
+/**
+ * Information about a language including intrinsic information (|language|)
+ * and the |state| of the language.
+ * @typedef {{language: !chrome.languageSettingsPrivate.Language,
+ * state: !LanguageState}}
+ */
+var LanguageInfo;
+
+/**
+ * Languages data to expose to consumers.
+ * supportedLanguages: an array of languages, ordered alphabetically.
+ * enabledLanguages: an array of enabled language info, ordered by preference.
+ * translateTarget: the default language to translate into.
+ * @typedef {{
+ * supportedLanguages: !Array<!chrome.languageSettingsPrivate.Language>,
+ * enabledLanguages: !Array<!LanguageInfo>,
+ * translateTarget: string
+ * }}
+ */
+var LanguagesModel;
+
+/**
+ * Helper methods implemented by settings-languages-singleton. The nature of
+ * the interaction between the singleton Polymer element and the |languages|
+ * properties kept in sync is hidden from the consumer, which can just treat
+ * these methods as a handy interface.
+ * @interface
+ */
+var LanguageHelper = function() {};
+
+LanguageHelper.prototype = {
+
+<if expr="chromeos or is_win">
+ /**
+ * Sets the prospective UI language to the chosen language. This won't affect
+ * the actual UI language until a restart.
+ * @param {string} languageCode
+ */
+ setUILanguage: assertNotReached,
+
+ /** Resets the prospective UI language back to the actual UI language. */
+ resetUILanguage: assertNotReached,
+
+ /**
+ * Returns the "prospective" UI language, i.e. the one to be used on next
+ * restart. If the pref is not set, the current UI language is also the
+ * "prospective" language.
+ * @return {string} Language code of the prospective UI language.
+ */
+ getProspectiveUILanguage: assertNotReached,
+</if>
+
+ /**
+ * @param {string} languageCode
+ * @return {boolean}
+ */
+ isLanguageEnabled: assertNotReached,
+
+ /**
+ * Enables the language, making it available for spell check and input.
+ * @param {string} languageCode
+ */
+ enableLanguage: assertNotReached,
+
+ /**
+ * Disables the language.
+ * @param {string} languageCode
+ */
+ disableLanguage: assertNotReached,
+
+ /**
+ * @param {string} languageCode Language code for an enabled language.
+ * @return {boolean}
+ */
+ canDisableLanguage: assertNotReached,
+
+ /**
+ * Enables translate for the given language by removing the translate
+ * language from the blocked languages preference.
+ * @param {string} languageCode
+ */
+ enableTranslateLanguage: assertNotReached,
+
+ /**
+ * Disables translate for the given language by adding the translate
+ * language to the blocked languages preference.
+ * @param {string} languageCode
+ */
+ disableTranslateLanguage: assertNotReached,
+
+ /**
+ * Enables or disables spell check for the given language.
+ * @param {string} languageCode
+ * @param {boolean} enable
+ */
+ toggleSpellCheck: assertNotReached,
+
+ /**
+ * Converts the language code for translate. There are some differences
+ * between the language set the Translate server uses and that for
+ * Accept-Language.
+ * @param {string} languageCode
+ * @return {string} The converted language code.
+ */
+ convertLanguageCodeForTranslate: assertNotReached,
+
+ /**
+ * @param {string} languageCode
+ * @return {!chrome.languageSettingsPrivate.Language|undefined}
+ */
+ getLanguage: assertNotReached,
+};
diff --git a/chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.html b/chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.html
index 8fa80eb0e91..393585f5d5f 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.html
+++ b/chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.html
@@ -9,18 +9,17 @@
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="languages.html">
-<dom-module id="cr-settings-manage-languages-page">
+<dom-module id="settings-manage-languages-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="manage_languages_page.css">
<template>
- <cr-settings-languages id="languages" languages="{{languages}}">
- </cr-settings-languages>
- <div class="content">
+ <settings-languages languages="{{languages}}"></settings-languages>
+ <div class="settings-box content">
<h2 i18n-content="enabledLanguages"></h2>
- <div class="item-list">
+ <div>
<template is="dom-repeat" items="{{languages.enabledLanguages}}">
- <paper-item>
+ <paper-item class="split">
<div class="language-name"
title="[[item.language.nativeDisplayName]]"
>[[item.language.displayName]]</div>
@@ -31,7 +30,7 @@
</template>
</div>
<h2 i18n-content="allLanguages"></h2>
- <iron-list id="list" items="{{availableLanguages_}}" as="item">
+ <iron-list items="{{availableLanguages_}}" as="item">
<template>
<paper-item on-tap="onAddLanguageTap_">
<div class="language-name">
diff --git a/chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.js b/chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.js
index 1fe8ba47b21..36a8cc4a6fc 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.js
+++ b/chromium/chrome/browser/resources/settings/languages_page/manage_languages_page.js
@@ -3,14 +3,14 @@
// found in the LICENSE file.
/**
- * @fileoverview 'cr-settings-manage-languages-page' is a sub-page for enabling
+ * @fileoverview 'settings-manage-languages-page' is a sub-page for enabling
* and disabling languages.
*
* @group Chrome Settings Elements
- * @element cr-settings-manage-languages-page
+ * @element settings-manage-languages-page
*/
Polymer({
- is: 'cr-settings-manage-languages-page',
+ is: 'settings-manage-languages-page',
properties: {
/**
@@ -37,6 +37,9 @@ Polymer({
availableLanguages_: Array,
},
+ /** @private {!LanguageHelper} */
+ languageHelper_: LanguageHelperImpl.getInstance(),
+
observers: [
'enabledLanguagesChanged_(languages.enabledLanguages.*)',
],
@@ -47,7 +50,7 @@ Polymer({
* @private
*/
onRemoveLanguageTap_: function(e) {
- this.$.languages.disableLanguage(e.model.item.language.code);
+ this.languageHelper_.disableLanguage(e.model.item.language.code);
},
/**
@@ -56,19 +59,19 @@ Polymer({
* @private
*/
onAddLanguageTap_: function(e) {
- this.$.languages.enableLanguage(e.model.item.code);
+ this.languageHelper_.enableLanguage(e.model.item.code);
},
/**
* True if a language is not the current or prospective UI language.
* @param {string} languageCode
- * @param {!Array<!LanguageInfo>} prospectiveUILanguage
+ * @param {string} prospectiveUILanguageCode
* @return {boolean}
* @private
*/
- canRemoveLanguage_: function(languageCode, prospectiveUILanguage) {
+ canRemoveLanguage_: function(languageCode, prospectiveUILanguageCode) {
if (languageCode == navigator.language ||
- languageCode == prospectiveUILanguage) {
+ languageCode == prospectiveUILanguageCode) {
return false;
}
assert(this.languages.enabledLanguages.length > 1);
@@ -88,7 +91,7 @@ Polymer({
code: language.code,
displayName: language.displayName,
nativeDisplayName: language.nativeDisplayName,
- enabled: this.$.languages.isEnabled(language.code)
+ enabled: this.languageHelper_.isLanguageEnabled(language.code),
});
}
// Set the Polymer property after building the full array.
@@ -97,7 +100,8 @@ Polymer({
// Update the available languages in place.
for (var i = 0; i < this.availableLanguages_.length; i++) {
this.set('availableLanguages_.' + i + '.enabled',
- this.$.languages.isEnabled(this.availableLanguages_[i].code));
+ this.languageHelper_.isLanguageEnabled(
+ this.availableLanguages_[i].code));
}
}
},
diff --git a/chromium/chrome/browser/resources/settings/location_page/location_page.html b/chromium/chrome/browser/resources/settings/location_page/location_page.html
deleted file mode 100644
index 4c4e0ca8eaf..00000000000
--- a/chromium/chrome/browser/resources/settings/location_page/location_page.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/communication-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-icon-item.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item-body.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-submenu.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
-
-<dom-module id="cr-settings-location-page">
- <link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
- <link rel="import" type="css" href="location_page.css">
- <template>
- <paper-icon-item>
- <iron-icon icon="communication:location-on" item-icon></iron-icon>
- <paper-item-body two-line class="flex">
- <div i18n-content="siteSettingsLocation"></div>
- <div secondary i18n-content="siteSettingsAskBeforeAccessing"></div>
- </paper-item-body>
- <paper-toggle-button></paper-toggle-button>
- </paper-icon-item>
- <paper-menu>
- <paper-submenu>
- <paper-item class="menu-trigger">
- <div>[[getTitleAndCount_("siteSettingsBlock", block.length)]]</div>
- </paper-item>
- <paper-menu class="menu-content">
- <template is="dom-repeat" items="{{block}}">
- <paper-item>{{item.url}}</paper-item>
- </template>
- </paper-menu>
- </paper-submenu>
- <paper-submenu>
- <paper-item class="menu-trigger">
- <div>[[getTitleAndCount_("siteSettingsAllow", allow.length)]]</div>
- </paper-item>
- <paper-menu class="menu-content">
- <template is="dom-repeat" items="{{allow}}">
- <paper-item>{{item.url}}</paper-item>
- </template>
- </paper-menu>
- </paper-submenu>
- </paper-menu>
- </template>
- <script src="location_page.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/location_page/location_page.js b/chromium/chrome/browser/resources/settings/location_page/location_page.js
deleted file mode 100644
index 1d8201bb641..00000000000
--- a/chromium/chrome/browser/resources/settings/location_page/location_page.js
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview
- * 'cr-settings-location-page' is the settings page for location access.
- *
- * Example:
- *
- * <cr-settings-location-page prefs="{{prefs}}">
- * </cr-settings-location-page>
- * ... other pages ...
- *
- * @group Chrome Settings Elements
- * @element cr-settings-location-page
- */
-Polymer({
- is: 'cr-settings-location-page',
-
- properties: {
- /**
- * Preferences state.
- */
- prefs: {
- type: Object,
- notify: true,
- },
-
- /**
- * Route for the page.
- */
- route: String,
-
- /**
- * Whether the page is a subpage.
- */
- subpage: {
- type: Boolean,
- value: true,
- readOnly: true,
- },
-
- /**
- * ID of the page.
- */
- PAGE_ID: {
- type: String,
- value: 'location',
- readOnly: true,
- },
-
- /**
- * Title for the page header and navigation menu.
- */
- pageTitle: {
- type: String,
- value: '',
- },
-
- /**
- * Name of the 'iron-icon' to show.
- */
- icon: {
- type: String,
- value: 'communication:location-on',
- readOnly: true,
- },
-
- /**
- * Array of objects with url members.
- */
- block: {
- type: Array,
- },
-
- /**
- * Array of objects with url members.
- */
- allow: {
- type: Array,
- },
- },
-
- ready: function() {
- this.block = [];
- this.allow = [];
- },
-
- getTitleAndCount_: function(title, count) {
- return loadTimeData.getStringF(
- 'titleAndCount', loadTimeData.getString(title), count);
- },
-});
diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.html b/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
index 2ba1692c0ee..35413cbaa0d 100644
--- a/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
+++ b/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
@@ -2,44 +2,37 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html">
+<link rel="import" href="chrome://md-settings/controls/settings_radio_group.html">
<link rel="import" href="chrome://md-settings/on_startup_page/startup_urls_page.html">
-<link rel="import" href="chrome://md-settings/radio_group/radio_group.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html">
-<dom-module id="cr-settings-on-startup-page">
+<dom-module id="settings-on-startup-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="on_startup_shared.css">
<template>
- <settings-animated-pages id="pages" current-route="{{currentRoute}}"
- section="on-startup">
- <neon-animatable id="">
- <div id="locationLabel" i18n-content="onStartup"></div>
- <div>
- <cr-settings-radio-group pref="{{prefs.session.restore_on_startup}}">
- <paper-radio-button name="[[prefValues_.OPEN_NEW_TAB]]"
- i18n-content="onStartupOpenNewTab">
- </paper-radio-button>
- <paper-radio-button name="[[prefValues_.CONTINUE]]"
- i18n-content="onStartupContinue">
- </paper-radio-button>
- <paper-radio-button name="[[prefValues_.OPEN_SPECIFIC]]">
- <span i18n-content="onStartupOpenSpecific"></span>
- </paper-radio-button>
- </cr-settings-radio-group>
- <paper-button
- on-tap="onSetPagesTap_" raised i18n-content="onStartupSetPages">
- </paper-button>
- </div>
- </neon-animatable>
- <neon-animatable id="startup-urls">
- <settings-subheader i18n-values="page-title:onStartupSetPages">
- </settings-subheader>
- <cr-settings-startup-urls-page prefs="{{prefs}}">
- </cr-settings-startup-urls-page>
- </neon-animatable>
- </settings-animated-pages>
- </template>
+ <div class="settings-box">
+ <settings-radio-group id="onStartupRadioGroup"
+ pref="{{prefs.session.restore_on_startup}}">
+ <paper-radio-button name="[[prefValues_.OPEN_NEW_TAB]]"
+ i18n-content="onStartupOpenNewTab">
+ </paper-radio-button>
+ <paper-radio-button name="[[prefValues_.CONTINUE]]"
+ i18n-content="onStartupContinue">
+ </paper-radio-button>
+ <paper-radio-button name="[[prefValues_.OPEN_SPECIFIC]]">
+ <span i18n-content="onStartupOpenSpecific"></span>
+ </paper-radio-button>
+ </settings-radio-group>
+ <template is="dom-if"
+ if="[[showStartupUrls_(prefs.session.restore_on_startup.value)]]">
+ <div class="list-frame">
+ <settings-startup-urls-page prefs="{{prefs}}">
+ </settings-startup-urls-page>
+ </div>
+ </template>
+ </div>
+ </template>
<script src="on_startup_page.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.js b/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.js
index 95e516dc3a6..765cd8a24ae 100644
--- a/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.js
+++ b/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_page.js
@@ -4,21 +4,21 @@
/**
* @fileoverview
- * 'cr-settings-on-startup-page' is a settings page.
+ * 'settings-on-startup-page' is a settings page.
*
* Example:
*
* <neon-animated-pages>
- * <cr-settings-on-startup-page prefs="{{prefs}}">
- * </cr-settings-on-startup-page>
+ * <settings-on-startup-page prefs="{{prefs}}">
+ * </settings-on-startup-page>
* ... other pages ...
* </neon-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-on-startup-page
+ * @element settings-on-startup-page
*/
Polymer({
- is: 'cr-settings-on-startup-page',
+ is: 'settings-on-startup-page',
properties: {
/**
@@ -37,6 +37,10 @@ Polymer({
notify: true,
},
+ /**
+ * Enum values for the 'session.restore_on_startup' preference.
+ * @private {!Object<string, number>}
+ */
prefValues_: {
readOnly: true,
type: Object,
@@ -45,11 +49,16 @@ Polymer({
CONTINUE: 1,
OPEN_SPECIFIC: 4,
},
- }
+ },
},
- /** @private */
- onSetPagesTap_: function() {
- this.$.pages.setSubpageChain(['startup-urls']);
+ /**
+ * Determine whether to show the user defined startup pages.
+ * @param {number} restoreOnStartup Enum value from prefValues_.
+ * @return {boolean} Whether the open specific pages is selected.
+ * @private
+ */
+ showStartupUrls_: function(restoreOnStartup) {
+ return restoreOnStartup == this.prefValues_.OPEN_SPECIFIC;
},
});
diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_shared.css b/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_shared.css
index b29772a121c..a01757d06b3 100644
--- a/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_shared.css
+++ b/chromium/chrome/browser/resources/settings/on_startup_page/on_startup_shared.css
@@ -2,11 +2,10 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-paper-radio-button {
- display: block;
+paper-dialog .body {
+ min-width: 500px;
}
-.button-row {
- display: flex;
- margin-top: 25px;
+paper-radio-button {
+ display: block;
}
diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html b/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html
index dca01c7e19e..ef9944ebcc1 100644
--- a/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html
+++ b/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html
@@ -1,40 +1,61 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-icon-item.html">
-<dom-module id="cr-settings-startup-urls-page">
- <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css">
+<dom-module id="settings-startup-urls-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_dialog.css">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="on_startup_shared.css">
<template>
- <div>
- <div class="entries">
- <template is="dom-repeat" items="{{prefs.session.startup_urls.value}}">
- <paper-icon-item>
- <iron-icon icon="image:brightness-1" item-icon></iron-icon>
- <span class="flex">[[item]]</span>
- <iron-icon on-tap="onRemoveUrlTap_" icon="clear">
- </iron-icon>
- </paper-icon-item>
- </template>
- </div>
- <paper-icon-item>
- <div i18n-content="onStartupAddPage"></div>&nbsp;
- <paper-input class="flex" no-label-float
- i18n-values="label:onStartupEnterUrl" value="{{newUrl}}">
- </paper-input>
- </paper-icon-item>
- <div class="button-row">
- <div class="flex">
- <paper-button on-tap="onUseCurrentPagesTap_"
- i18n-content="onStartupUseCurrent">
- </paper-button>
+ <template is="dom-repeat" items="[[startupPages_]]">
+ <div class="list-item">
+ <iron-icon class="secondary" icon="image:brightness-1"
+ item-icon></iron-icon>
+ <div class="middle">
+ <div class="text-elide">[[item.title]]</div>
+ <div class="text-elide secondary">[[item.url]]</div>
</div>
- <paper-button on-tap="onCancelTap_" i18n-content="cancelButton">
- </paper-button>
- <paper-button on-tap="onOkTap_" raised i18n-content="okButton">
- </paper-button>
+ <iron-icon on-tap="onRemoveUrlTap_" icon="clear"></iron-icon>
</div>
+ </template>
+ <div class="list-item">
+ <paper-button class="link-button" on-tap="onAddPageTap_"
+ i18n-content="onStartupAddNewPage">
+ </paper-button>
+ </div>
+ <div class="list-item">
+ <paper-button class="link-button" on-tap="onUseCurrentPagesTap_"
+ i18n-content="onStartupUseCurrent">
+ </paper-button>
</div>
+
+ <paper-dialog modal id="addUrlDialog" class="layout vertical">
+ <div id="dialog-content">
+ <div class="top-row">
+ <div class="title" i18n-content="onStartupAddNewPage"></div>
+ <paper-icon-button icon="clear" on-tap="onCancelTap_" id="close">
+ </paper-icon-button>
+ </div>
+ <div class="body">
+ <div class="explanation">
+ <paper-input class="flex" always-float-label
+ i18n-values="label:onStartupSiteUrl" value="{{newUrl}}">
+ </paper-input>
+ </div>
+ <div class="button-container">
+ <div class="action-buttons">
+ <paper-button class="cancel-button" on-tap="onCancelTap_"
+ id="cancel" i18n-content="cancel"></paper-button>
+ <paper-button class="action-button" id="addUrlButton"
+ on-tap="onOkTap_" i18n-content="addLabel">
+ </paper-button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </paper-dialog>
+
</template>
<script src="startup_urls_page.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js b/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js
index fd5e903f787..524a21dd58c 100644
--- a/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js
+++ b/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js
@@ -3,22 +3,31 @@
// found in the LICENSE file.
/**
- * @fileoverview 'cr-settings-startup-urls-page' is the settings page
+ * @typedef {{
+ * 'title': string,
+ * 'tooltip': string,
+ * 'url': string
+ * }}
+ */
+var StartupPageInfo;
+
+/**
+ * @fileoverview 'settings-startup-urls-page' is the settings page
* containing the urls that will be opened when chrome is started.
*
* Example:
*
* <neon-animated-pages>
- * <cr-settings-startup-urls-page prefs="{{prefs}}">
- * </cr-settings-startup-urls-page>
+ * <settings-startup-urls-page prefs="{{prefs}}">
+ * </settings-startup-urls-page>
* ... other pages ...
* </neon-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-startup-urls-page
+ * @element settings-startup-urls-page
*/
Polymer({
- is: 'cr-settings-startup-urls-page',
+ is: 'settings-startup-urls-page',
properties: {
/**
@@ -33,16 +42,13 @@ Polymer({
type: String,
},
- /** @type {!Array<string>} */
- savedUrlList: {
- type: Array,
- },
+ /**
+ * Pages to load upon browser startup.
+ * @private {!Array<!StartupPageInfo>}
+ */
+ startupPages_: Array,
},
- observers: [
- 'prefsChanged_(prefs.session.startup_urls.value.*)',
- ],
-
attached: function() {
var self = this;
cr.define('Settings', function() {
@@ -52,25 +58,17 @@ Polymer({
},
};
});
+ chrome.send('onStartupPrefsPageLoad');
},
-
/** @private */
- prefsChanged_: function(change) {
- if (!this.savedUrlList) {
- var pref = /** @type {chrome.settingsPrivate.PrefObject} */(
- this.get('prefs.session.startup_urls'));
- if (pref)
- this.savedUrlList = pref.value.slice();
- }
+ updateStartupPages_: function(startupPages) {
+ this.startupPages_ = startupPages;
},
/** @private */
- updateStartupPages_: function(data) {
- var urlArray = [];
- for (var i = 0; i < data.length; ++i)
- urlArray.push(data[i].url);
- this.set('prefs.session.startup_urls.value', urlArray);
+ onAddPageTap_: function() {
+ this.$.addUrlDialog.open();
},
/** @private */
@@ -80,9 +78,7 @@ Polymer({
/** @private */
onCancelTap_: function() {
- if (this.savedUrlList !== undefined) {
- this.set('prefs.session.startup_urls.value', this.savedUrlList.slice());
- }
+ this.$.addUrlDialog.close();
},
/** @private */
@@ -90,8 +86,9 @@ Polymer({
var value = this.newUrl && this.newUrl.trim();
if (!value)
return;
- this.push('prefs.session.startup_urls.value', value);
+ chrome.send('addStartupPage', [value]);
this.newUrl = '';
+ this.$.addUrlDialog.close();
},
/**
@@ -99,6 +96,6 @@ Polymer({
* @private
*/
onRemoveUrlTap_: function(e) {
- this.splice('prefs.session.startup_urls.value', e.model.index, 1);
+ chrome.send('removeStartupPage', [e.model.index]);
},
});
diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html
new file mode 100644
index 00000000000..b4257a37782
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html
@@ -0,0 +1,45 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item-body.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="chrome://md-settings/passwords_and_forms_page/passwords_section.html">
+
+<dom-module id="settings-passwords-and-forms-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <template>
+ <div class="settings-box">
+ <paper-item>
+ <paper-item-body two-line>
+ <div i18n-content="autofill"></div>
+ <div secondary i18n-content="autofillDetail"></div>
+ </paper-item-body>
+ <paper-toggle-button
+ checked="{{prefs.autofill.enabled.value}}">
+ </paper-toggle-button>
+ <cr-expand-button disabled="{{!prefs.autofill.enabled.value}}">
+ </cr-expand-button>
+ </paper-item>
+ </div>
+ <div class="settings-box">
+ <paper-item>
+ <paper-item-body two-line>
+ <div i18n-content="passwords"></div>
+ <div secondary i18n-content="passwordsDetail"></div>
+ </paper-item-body>
+ <paper-toggle-button
+ checked="{{prefs.profile.password_manager_enabled.value}}">
+ </paper-toggle-button>
+ <cr-expand-button expanded="{{passwordsOpened}}"
+ disabled="{{!prefs.profile.password_manager_enabled.value}}">
+ </cr-expand-button>
+ </paper-item>
+ <iron-collapse id="collapse" opened="{{passwordsOpened}}">
+ <passwords-section saved-passwords="{{savedPasswords}}">
+ </passwords-section>
+ </iron-collapse>
+ </div>
+ </template>
+ <script src="passwords_and_forms_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js
new file mode 100644
index 00000000000..b46e9fb3b23
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js
@@ -0,0 +1,67 @@
+// 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.
+
+/**
+ * @fileoverview 'settings-passwords-and-forms-page' is the settings page
+ * for passwords and auto fill.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-passwords-and-forms-page
+ */
+(function() {
+'use strict';
+
+Polymer({
+ is: 'settings-passwords-and-forms-page',
+
+ properties: {
+ /**
+ * Preferences state.
+ */
+ prefs: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * An array of passwords to display.
+ * Lazy loaded when the password section is expanded.
+ */
+ savedPasswords: {
+ type: Array,
+ value: function() { return []; },
+ },
+
+ /**
+ * Whether the password section section is opened or not.
+ */
+ passwordsOpened: {
+ type: Boolean,
+ value: false,
+ observer: 'loadPasswords_',
+ },
+ },
+
+ /**
+ * Called when the section is expanded. This will load the list of passwords
+ * only when needed.
+ * @param {boolean} passwordSectionOpened
+ */
+ loadPasswords_: function(passwordSectionOpened) {
+ if (passwordSectionOpened) {
+ // TODO(hcarmona): Get real data.
+ this.savedPasswords =
+ [{origin: 'otherwebsite.com',
+ username: 'bowser',
+ password: '************'},
+ {origin: 'otherlongwebsite.com',
+ username: 'koopa',
+ password: '*********'},
+ {origin: 'otherverylongwebsite.com',
+ username: 'goomba',
+ password: '******'}];
+ }
+ },
+});
+})();
diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.css b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.css
new file mode 100644
index 00000000000..a11186fba11
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.css
@@ -0,0 +1,27 @@
+/* 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. */
+
+.heading {
+ color: gray;
+}
+
+.section {
+ -webkit-padding-start: 32px;
+ padding-top: 16px;
+}
+
+.separator {
+ border-top: 1px solid #e0e0e0;
+}
+
+.separator:first-of-type {
+ border-top: none;
+}
+
+iron-list {
+ /* TODO(hcarmona): Make this flex. */
+ -webkit-padding-start: 8px;
+ height: 300px;
+ padding-top: 16px;
+}
diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html
new file mode 100644
index 00000000000..47d9d61565d
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html
@@ -0,0 +1,27 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item-body.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+
+<dom-module id="passwords-section">
+ <link rel="import" type="css" href="chrome://md-settings/site_settings_page/site_settings_page.css">
+ <link rel="import" type="css" href="chrome://md-settings/passwords_and_forms_page/passwords_section.css">
+ <template>
+ <div class="section">
+ <div class="heading" i18n-content="savedPasswordsHeading"></div>
+ <iron-list id="passwordList" class="list-section"
+ items="{{savedPasswords}}">
+ <template>
+ <paper-item class="separator">
+ <paper-item-body two-line>
+ <div id="origin">[[item.origin]]</div>
+ <div id="username"secondary>[[item.username]]</div>
+ </paper-item-body>
+ <div id="password">[[item.password]]</div>
+ </paper-item>
+ </template>
+ </iron-list>
+ </div>
+ </template>
+ <script src="chrome://md-settings/passwords_and_forms_page/passwords_section.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js
new file mode 100644
index 00000000000..fc506e8b838
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js
@@ -0,0 +1,29 @@
+// 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.
+
+/**
+ * @fileoverview 'passwords-section' is the collapsible section containing
+ * the list of saved passwords as well as the list of sites that will never
+ * save any passwords.
+ *
+ * @group Chrome Settings Elements
+ * @element passwords-section
+ */
+(function() {
+'use strict';
+
+Polymer({
+ is: 'passwords-section',
+
+ properties: {
+ /**
+ * An array of passwords to display.
+ */
+ savedPasswords: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+});
+})();
diff --git a/chromium/chrome/browser/resources/settings/people_page/change_picture.css b/chromium/chrome/browser/resources/settings/people_page/change_picture.css
new file mode 100644
index 00000000000..914164484c7
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/change_picture.css
@@ -0,0 +1,13 @@
+/* Copyright (c) 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. */
+
+#availableIcons {
+ -webkit-margin-start: 16px;
+ margin-top: 16px;
+}
+
+.user-image {
+ height: 64px;
+ width: 64px;
+}
diff --git a/chromium/chrome/browser/resources/settings/people_page/change_picture.html b/chromium/chrome/browser/resources/settings/people_page/change_picture.html
new file mode 100644
index 00000000000..7fd64f7eb35
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/change_picture.html
@@ -0,0 +1,39 @@
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://md-settings/people_page/change_picture_private_api.html">
+
+<dom-module id="settings-change-picture">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="change_picture.css">
+ <template>
+ <div class="settings-box">
+ <div class="split">
+ <div id="availableIcons">
+ <paper-button toggles
+ active="{{isActiveImage_(profileImageUrl_, selectedImageUrl_)}}"
+ on-tap="onProfileImageTap_">
+ <img class="user-image" src="[[profileImageUrl_]]"
+ alt="[[i18n('profilePhotoLoading')]]">
+ </paper-button>
+ <template is="dom-if" if="[[oldImageUrl_]]">
+ <paper-button toggles
+ active="{{isActiveImage_(oldImageUrl_, selectedImageUrl_)}}"
+ on-tap="onOldImageTap_">
+ <img class="user-image" src="[[oldImageUrl_]]">
+ </paper-button>
+ </template>
+ <template is="dom-repeat" items="[[defaultImages_]]">
+ <paper-button toggles
+ active="{{isActiveImage_(item.url, selectedImageUrl_)}}"
+ on-tap="onDefaultImageTap_" data-image-url$="[[item.url]]">
+ <img class="user-image" src="[[item.url]]" alt="[[item.title]]">
+ </paper-button>
+ </template>
+ </div>
+ </div>
+ </div>
+ </template>
+ <script src="change_picture.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/people_page/change_picture.js b/chromium/chrome/browser/resources/settings/people_page/change_picture.js
new file mode 100644
index 00000000000..5fe931b3e17
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/change_picture.js
@@ -0,0 +1,168 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-change-picture' is the settings subpage containing controls to
+ * edit a ChromeOS user's picture.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-change-picture
+ */
+Polymer({
+ is: 'settings-change-picture',
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ properties: {
+ /**
+ * The currently selected profile image URL. May be a data URL.
+ * @private {string}
+ */
+ selectedImageUrl_: String,
+
+ /**
+ * The url of the 'old' image, which is the existing image sourced from
+ * the camera, a file, or a deprecated default image.
+ * @private {string}
+ */
+ oldImageUrl_: String,
+
+ /**
+ * The url of the profile image.
+ * @private {string}
+ */
+ profileImageUrl_: {
+ type: String,
+ value: settings.ChangePicturePrivateApi.ButtonImages.PROFILE_PICTURE,
+ },
+
+ /**
+ * The default user images. Populated by ChangePicturePrivateApi.
+ * @private {!Array<!settings.DefaultImage>}
+ */
+ defaultImages_: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+
+ /** @override */
+ attached: function() {
+ // This is the interface called by the C++ handler.
+ var nativeInterface = {
+ /**
+ * Called from C++ to provide the default set of images.
+ * @param {!Array<!settings.DefaultImage>} images
+ */
+ receiveDefaultImages: function(images) {
+ this.defaultImages_ = images;
+ }.bind(this),
+
+ /**
+ * Called from C++ to provide the URL of the selected image.
+ * @param {string} imageUrl
+ */
+ receiveSelectedImage: function(imageUrl) {
+ this.selectedImageUrl_ = imageUrl;
+ }.bind(this),
+
+ /**
+ * Called from C++ to provide the URL of the 'old' image. The 'old'
+ * image is any selected non-profile and non-default image. It can be
+ * from the camera, a file, or a deprecated default image. When this
+ * method is called, it's implied that the old image is selected.
+ * @param {string} imageUrl
+ */
+ receiveOldImage: function(imageUrl) {
+ this.oldImageUrl_ = imageUrl;
+ this.selectedImageUrl_ = imageUrl;
+ }.bind(this),
+
+ /**
+ * Called from C++ to provide the URL of the profile image.
+ * @param {string} imageUrl
+ * @param {boolean} selected
+ */
+ receiveProfileImage: function(imageUrl, selected) {
+ this.profileImageUrl_ = imageUrl;
+ if (selected)
+ this.selectedImageUrl_ = imageUrl;
+ }.bind(this),
+
+ /**
+ * Called from the C++ to notify page about camera presence.
+ * @param {boolean} cameraPresent
+ */
+ receiveCameraPresence: function(cameraPresent) {
+ // TODO(tommycli): Implement camera functionality.
+ }.bind(this),
+ };
+
+ cr.define('settings', function() {
+ var ChangePicturePage = nativeInterface;
+ return {
+ ChangePicturePage: ChangePicturePage,
+ };
+ });
+
+ settings.ChangePicturePrivateApi.initialize();
+ },
+
+ /**
+ * Handler for when the user clicks a new profile image.
+ * @private
+ * @param {!Event} event
+ */
+ onDefaultImageTap_: function(event) {
+ var element = Polymer.dom(event).rootTarget;
+
+ var imageUrl = null;
+ if (element.nodeName == 'IMG')
+ imageUrl = element.src;
+ else if (element.dataset && element.dataset.imageUrl)
+ imageUrl = element.dataset.imageUrl;
+
+ if (imageUrl != null) {
+ settings.ChangePicturePrivateApi.selectDefaultImage(imageUrl);
+ // Button toggle state is instead controlled by the selected image URL.
+ event.preventDefault();
+ }
+ },
+
+ /**
+ * Handler for when the user clicks the 'old' image.
+ * @private
+ * @param {!Event} event
+ */
+ onOldImageTap_: function(event) {
+ settings.ChangePicturePrivateApi.selectOldImage();
+ // Button toggle state is instead controlled by the selected image URL.
+ event.preventDefault();
+ },
+
+ /**
+ * Handler for when the user clicks the 'profile' image.
+ * @private
+ * @param {!Event} event
+ */
+ onProfileImageTap_: function(event) {
+ settings.ChangePicturePrivateApi.selectProfileImage();
+ // Button toggle state is instead controlled by the selected image URL.
+ event.preventDefault();
+ },
+
+ /**
+ * Computed binding determining which profile image button is toggled on.
+ * @private
+ * @param {string} imageUrl
+ * @param {string} selectedImageUrl
+ * @return {boolean}
+ */
+ isActiveImage_: function(imageUrl, selectedImageUrl) {
+ return imageUrl == selectedImageUrl;
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/people_page/change_picture_private_api.html b/chromium/chrome/browser/resources/settings/people_page/change_picture_private_api.html
new file mode 100644
index 00000000000..1160701f2e9
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/change_picture_private_api.html
@@ -0,0 +1 @@
+<script src="chrome://md-settings/people_page/change_picture_private_api.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/people_page/change_picture_private_api.js b/chromium/chrome/browser/resources/settings/people_page/change_picture_private_api.js
new file mode 100644
index 00000000000..208a3cdd5c3
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/change_picture_private_api.js
@@ -0,0 +1,74 @@
+// 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.
+
+cr.exportPath('settings');
+
+/**
+ * An object describing a default image.
+ * @typedef {{
+ * author: string,
+ * title: string,
+ * url: string,
+ * website: string
+ * }}
+ */
+settings.DefaultImage;
+
+cr.define('settings', function() {
+ /**
+ * API which encapsulates messaging between JS and C++ for the ChromeOS
+ * Change Picture subpage.
+ * @constructor
+ */
+ function ChangePicturePrivateApi() {}
+
+ /**
+ * URLs of special button images.
+ * @enum {string}
+ */
+ ChangePicturePrivateApi.ButtonImages = {
+ TAKE_PHOTO: 'chrome://theme/IDR_BUTTON_USER_IMAGE_TAKE_PHOTO',
+ CHOOSE_FILE: 'chrome://theme/IDR_BUTTON_USER_IMAGE_CHOOSE_FILE',
+ PROFILE_PICTURE: 'chrome://theme/IDR_PROFILE_PICTURE_LOADING'
+ };
+
+ /**
+ * Called from JavaScript. Retrieves the initial set of default images,
+ * profile image, etc. As a response, the C++ calls these ChangePicturePage
+ * methods as callbacks: receiveDefaultImages, receiveOldImage,
+ * receiveProfileImage, and receiveSelectedImage.
+ */
+ ChangePicturePrivateApi.initialize = function() {
+ chrome.send('onChangePicturePageInitialized');
+ };
+
+ /**
+ * Called from JavaScript. Sets the user image to one of the default images.
+ * As a response, the C++ calls ChangePicturePage.receiveSelectedImage.
+ * @param {string} imageUrl
+ */
+ ChangePicturePrivateApi.selectDefaultImage = function(imageUrl) {
+ chrome.send('selectImage', [imageUrl, 'default']);
+ };
+
+ /**
+ * Called from JavaScript. Sets the user image to the 'old' image.
+ * As a response, the C++ calls ChangePicturePage.receiveSelectedImage.
+ */
+ ChangePicturePrivateApi.selectOldImage = function() {
+ chrome.send('selectImage', ['', 'old']);
+ };
+
+ /**
+ * Called from JavaScript. Sets the user image to the profile image.
+ * As a response, the C++ calls ChangePicturePage.receiveSelectedImage.
+ */
+ ChangePicturePrivateApi.selectProfileImage = function() {
+ chrome.send('selectImage', ['', 'profile']);
+ };
+
+ return {
+ ChangePicturePrivateApi: ChangePicturePrivateApi,
+ };
+});
diff --git a/chromium/chrome/browser/resources/settings/people_page/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/people_page/compiled_resources.gyp
new file mode 100644
index 00000000000..7e16fa5cf80
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/compiled_resources.gyp
@@ -0,0 +1,67 @@
+# 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.
+{
+ 'targets': [
+ {
+ 'target_name': 'change_picture',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ 'change_picture_private_api.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'change_picture_private_api',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'people_page',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ '../settings_page/settings_animated_pages.js',
+ 'sync_private_api.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'sync_page',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../../../../../ui/webui/resources/js/i18n_behavior.js',
+ '../settings_page/settings_animated_pages.js',
+ 'sync_private_api.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'sync_private_api',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/cr.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ ],
+}
diff --git a/chromium/chrome/browser/resources/settings/people_page/manage_profile.css b/chromium/chrome/browser/resources/settings/people_page/manage_profile.css
new file mode 100644
index 00000000000..fe8c87b6d26
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/manage_profile.css
@@ -0,0 +1,12 @@
+/* Copyright (c) 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. */
+
+paper-input {
+ width: 300px;
+}
+
+#availableIcons {
+ -webkit-margin-start: 16px;
+ margin-top: 16px;
+}
diff --git a/chromium/chrome/browser/resources/settings/people_page/manage_profile.html b/chromium/chrome/browser/resources/settings/people_page/manage_profile.html
new file mode 100644
index 00000000000..822836826da
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/manage_profile.html
@@ -0,0 +1,26 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+<link rel="import" href="chrome://md-settings/people_page/sync_private_api.html">
+
+<dom-module id="settings-manage-profile">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="manage_profile.css">
+ <template>
+ <div class="settings-box">
+ <paper-input value="{{profileName}}" pattern=".*\S.*" auto-validate
+ on-blur="onProfileNameChanged_">
+ </paper-input>
+ <div id="availableIcons">
+ <template is="dom-repeat" items="[[availableIconUrls]]">
+ <paper-button toggles active="{{isActiveIcon_(item, profileIconUrl)}}"
+ on-tap="onIconTap_" data-icon-url$="[[item]]">
+ <img src="[[item]]">
+ </paper-button>
+ </template>
+ </div>
+ </div>
+ </template>
+ <script src="manage_profile.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/people_page/manage_profile.js b/chromium/chrome/browser/resources/settings/people_page/manage_profile.js
new file mode 100644
index 00000000000..2d4a7cdca3f
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/manage_profile.js
@@ -0,0 +1,96 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-manage-profile' is the settings subpage containing controls to
+ * edit a profile's name, icon, and desktop shortcut.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-manage-profile
+ */
+Polymer({
+ is: 'settings-manage-profile',
+
+ properties: {
+ /**
+ * The currently selected profile icon URL. May be a data URL.
+ */
+ profileIconUrl: String,
+
+ /**
+ * The current profile name.
+ */
+ profileName: String,
+
+ /**
+ * The available icons for selection. Populated by SyncPrivateApi.
+ * @type {!Array<!string>}
+ */
+ availableIconUrls: {
+ type: Array,
+ value: function() { return []; },
+ },
+ },
+
+ /** @override */
+ created: function() {
+ settings.SyncPrivateApi.getAvailableIcons(
+ this.handleAvailableIcons_.bind(this));
+ },
+
+ /**
+ * Handler for when the available icons are pushed from SyncPrivateApi.
+ * @private
+ * @param {!Array<!string>} iconUrls
+ */
+ handleAvailableIcons_: function(iconUrls) {
+ this.availableIconUrls = iconUrls;
+ },
+
+ /**
+ * Handler for when the profile name field is changed, then blurred.
+ * @private
+ * @param {!Event} event
+ */
+ onProfileNameChanged_: function(event) {
+ settings.SyncPrivateApi.setProfileIconAndName(this.profileIconUrl,
+ event.target.value);
+ },
+
+ /**
+ * Handler for when the user clicks a new profile icon.
+ * @private
+ * @param {!Event} event
+ */
+ onIconTap_: function(event) {
+ var element = Polymer.dom(event).rootTarget;
+
+ var iconUrl;
+ if (element.nodeName == 'IMG')
+ iconUrl = element.src;
+ else if (element.dataset && element.dataset.iconUrl)
+ iconUrl = element.dataset.iconUrl;
+
+ if (!iconUrl)
+ return;
+
+ settings.SyncPrivateApi.setProfileIconAndName(iconUrl, this.profileName);
+
+ // Button toggle state is controlled by the selected icon URL. Prevent
+ // tap events from changing the toggle state.
+ event.preventDefault();
+ },
+
+ /**
+ * Computed binding determining which profile icon button is toggled on.
+ * @private
+ * @param {!string} iconUrl
+ * @param {!string} paramIconUrl
+ * @return {boolean}
+ */
+ isActiveIcon_: function(iconUrl, profileIconUrl) {
+ return iconUrl == profileIconUrl;
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/people_page/people_page.css b/chromium/chrome/browser/resources/settings/people_page/people_page.css
new file mode 100644
index 00000000000..638237e078a
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/people_page.css
@@ -0,0 +1,21 @@
+/* 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. */
+
+#account-picture {
+ border-radius: 28px;
+ height: 56px;
+ object-fit: cover;
+ vertical-align: middle;
+ width: 56px;
+}
+
+#account-picture:hover {
+ cursor: pointer;
+}
+
+<if expr="not chromeos">
+#profile-name:hover {
+ cursor: pointer;
+}
+</if>
diff --git a/chromium/chrome/browser/resources/settings/people_page/people_page.html b/chromium/chrome/browser/resources/settings/people_page/people_page.html
new file mode 100644
index 00000000000..9197e99a033
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/people_page.html
@@ -0,0 +1,131 @@
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
+<link rel="import" href="chrome://md-settings/people_page/sync_page.html">
+<link rel="import" href="chrome://md-settings/people_page/sync_private_api.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html">
+
+<if expr="chromeos">
+<link rel="import" href="chrome://md-settings/people_page/change_picture.html">
+<link rel="import" href="chrome://md-settings/people_page/users_page.html">
+</if>
+<if expr="not chromeos">
+<link rel="import" href="chrome://md-settings/people_page/manage_profile.html">
+</if>
+
+<dom-module id="settings-people-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="people_page.css">
+ <template>
+ <settings-animated-pages id="pages" current-route="{{currentRoute}}"
+ section="people">
+ <neon-animatable id="main">
+ <div class="settings-box">
+ <div class="split">
+ <span class="start">
+ <img id="account-picture" src="[[profileIconUrl_]]"
+ on-tap="onPictureTap_">
+<if expr="chromeos">
+ <span id="profile-name" on-tap="onProfileNameTap_">
+ [[profileName_]]
+ </span>
+</if>
+<if expr="not chromeos">
+ <span id="profile-name">
+ [[profileName_]]
+ </span>
+</if>
+ </span>
+ <span>
+ <template is="dom-if" if="[[!syncStatus.signedIn]]">
+ <paper-button on-tap="onSigninTap_" raised
+ disabled="[[syncStatus.setupInProgress]]">
+ [[i18n('syncSignin')]]
+ </paper-button>
+ </template>
+ <template is="dom-if" if="[[syncStatus.signedIn]]">
+ <paper-button on-tap="onDisconnectTap_"
+ disabled="[[syncStatus.setupInProgress]]">
+ [[i18n('syncDisconnect')]]
+ </paper-button>
+ </template>
+ </span>
+ </div>
+ <div hidden="[[syncStatus.signedIn]]">[[i18n('syncOverview')]]</div>
+ </div>
+
+ <div class="settings-box split"
+ hidden="[[!isStatusTextSet_(syncStatus)]]">
+ <span id="syncStatusText"></span>
+ <paper-button on-tap="onActionLinkTap_">
+ [[syncStatus.actionLinkText]]
+ </paper-button>
+ </div>
+
+ <template is="dom-if"
+ if="[[isAdvancedSyncSettingsVisible_(syncStatus)]]">
+ <div class="settings-box">
+ <paper-button on-tap="onSyncTap_" raised>
+ [[i18n('syncPageTitle')]]
+ </paper-button>
+ </div>
+ </template>
+
+ <div class="settings-box">
+ <paper-button i18n-content="manageOtherPeople"
+ on-tap="onManageOtherPeople_">
+ </paper-button>
+ </div>
+ </neon-animatable>
+ <neon-animatable id="sync">
+ <settings-subheader i18n-values="page-title:syncPageTitle">
+ </settings-subheader>
+ <settings-sync-page current-route="[[currentRoute]]">
+ </settings-sync-page>
+ </neon-animatable>
+<if expr="chromeos">
+ <neon-animatable id="users">
+ <settings-subheader i18n-values="page-title:usersPageTitle">
+ </settings-subheader>
+ <settings-users-page prefs="{{prefs}}"></settings-users-page>
+ </neon-animatable>
+ <neon-animatable id="changePicture">
+ <settings-subheader i18n-values="page-title:changePictureTitle">
+ </settings-subheader>
+ <settings-change-picture></settings-change-picture>
+ <neon-animatable>
+</if>
+<if expr="not chromeos">
+ <neon-animatable id="manageProfile">
+ <settings-subheader i18n-values="page-title:editPerson">
+ </settings-subheader>
+ <settings-manage-profile profile-icon-url="[[profileIconUrl_]]"
+ profile-name="[[profileName_]]">
+ </settings-manage-profile>
+ <neon-animatable>
+</if>
+ </settings-animated-pages>
+
+ <paper-dialog modal id="disconnectDialog">
+ <h2 i18n-content="syncDisconnectTitle"></h2>
+ <div i18n-values=".innerHTML:syncDisconnectExplanation"></div>
+<if expr="(not chromeos and is_posix) or is_win or is_macosx">
+ <paper-checkbox id="deleteProfile"
+ i18n-content="syncDisconnectDeleteProfile">
+ </paper-checkbox>
+</if>
+ <div class="button-strip">
+ <paper-button dialog-dismiss i18n-content="cancel">
+ </paper-button>
+ <paper-button dialog-confirm raised on-tap="onDisconnectConfirm_"
+ i18n-content="syncDisconnectConfirm">
+ </paper-button>
+ </div>
+ </paper-dialog>
+ </template>
+ <script src="people_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/people_page/people_page.js b/chromium/chrome/browser/resources/settings/people_page/people_page.js
new file mode 100644
index 00000000000..8dc0afbb100
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/people_page.js
@@ -0,0 +1,163 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-people-page' is the settings page containing sign-in settings.
+ *
+ * Example:
+ *
+ * <iron-animated-pages>
+ * <settings-people-page prefs="{{prefs}}"></settings-people-page>
+ * ... other pages ...
+ * </iron-animated-pages>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-people-page
+ */
+Polymer({
+ is: 'settings-people-page',
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ properties: {
+ /**
+ * The current active route.
+ */
+ currentRoute: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * Preferences state.
+ */
+ prefs: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * The current sync status, supplied by settings.SyncPrivateApi.
+ * @type {?settings.SyncStatus}
+ */
+ syncStatus: Object,
+
+ /**
+ * The currently selected profile icon URL. May be a data URL.
+ * @private {string}
+ */
+ profileIconUrl_: String,
+
+ /**
+ * The current profile name.
+ * @private {string}
+ */
+ profileName_: String,
+ },
+
+ /** @override */
+ created: function() {
+ settings.SyncPrivateApi.getProfileInfo(this.handleProfileInfo_.bind(this));
+ settings.SyncPrivateApi.getSyncStatus(
+ this.handleSyncStatusFetched_.bind(this));
+ },
+
+ /**
+ * Handler for when the profile's icon and name is updated.
+ * @private
+ * @param {!string} name
+ * @param {!string} iconUrl
+ */
+ handleProfileInfo_: function(name, iconUrl) {
+ this.profileName_ = name;
+ this.profileIconUrl_ = iconUrl;
+ },
+
+ /**
+ * Handler for when the sync state is pushed from settings.SyncPrivateApi.
+ * @private
+ */
+ handleSyncStatusFetched_: function(syncStatus) {
+ this.syncStatus = syncStatus;
+
+ // TODO(tommycli): Remove once we figure out how to refactor the sync
+ // code to not include HTML in the status messages.
+ this.$.syncStatusText.innerHTML = syncStatus.statusText;
+ },
+
+ /** @private */
+ onActionLinkTap_: function() {
+ settings.SyncPrivateApi.showSetupUI();
+ },
+
+ /** @private */
+ onPictureTap_: function() {
+<if expr="chromeos">
+ this.$.pages.setSubpageChain(['changePicture']);
+</if>
+<if expr="not chromeos">
+ this.$.pages.setSubpageChain(['manageProfile']);
+</if>
+ },
+
+<if expr="not chromeos">
+ /** @private */
+ onProfileNameTap_: function() {
+ this.$.pages.setSubpageChain(['manageProfile']);
+ },
+</if>
+
+ /** @private */
+ onSigninTap_: function() {
+ settings.SyncPrivateApi.startSignIn();
+ },
+
+ /** @private */
+ onDisconnectTap_: function() {
+ this.$.disconnectDialog.open();
+ },
+
+ /** @private */
+ onDisconnectConfirm_: function() {
+ var deleteProfile = this.$.deleteProfile && this.$.deleteProfile.checked;
+ settings.SyncPrivateApi.disconnect(deleteProfile);
+
+ // Dialog automatically closed because button has dialog-confirm attribute.
+ },
+
+ /** @private */
+ onSyncTap_: function() {
+ this.$.pages.setSubpageChain(['sync']);
+ },
+
+ /** @private */
+ onManageOtherPeople_: function() {
+<if expr="not chromeos">
+ settings.SyncPrivateApi.manageOtherPeople();
+</if>
+<if expr="chromeos">
+ this.$.pages.setSubpageChain(['users']);
+</if>
+ },
+
+ /**
+ * @private
+ * @return {boolean}
+ */
+ isStatusTextSet_: function(syncStatus) {
+ return syncStatus && syncStatus.statusText.length > 0;
+ },
+
+ /**
+ * @private
+ * @return {boolean}
+ */
+ isAdvancedSyncSettingsVisible_: function(syncStatus) {
+ return syncStatus && syncStatus.signedIn && !syncStatus.managed &&
+ syncStatus.syncSystemEnabled;
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/sync_page/sync_page.css b/chromium/chrome/browser/resources/settings/people_page/sync_page.css
index 1e47219ea48..3b2eda8941e 100644
--- a/chromium/chrome/browser/resources/settings/sync_page/sync_page.css
+++ b/chromium/chrome/browser/resources/settings/people_page/sync_page.css
@@ -2,21 +2,18 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-paper-radio-button {
- display: block;
+paper-checkbox {
+ margin-bottom: 10px;
}
-.checkbox-container {
- display: flex;
- flex-flow: column;
+paper-radio-button {
+ display: block;
}
-.checkbox-container-row {
- display: flex;
+#sync-item-list {
+ margin-left: 32px;
}
-.checkbox-container-row > paper-checkbox {
- display: flex;
- flex-basis: 0;
- flex-grow: 1;
+#sync-item-list paper-checkbox {
+ display: block;
}
diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_page.html b/chromium/chrome/browser/resources/settings/people_page/sync_page.html
new file mode 100644
index 00000000000..4f42f341445
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/sync_page.html
@@ -0,0 +1,130 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dropdown-menu/paper-dropdown-menu.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html">
+<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
+<link rel="import" href="chrome://md-settings/people_page/sync_private_api.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+
+<dom-module id="settings-sync-page">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="sync_page.css">
+ <template>
+ <iron-pages id="pages" selected="loading" attr-for-selected="id">
+ <div id="loading" i18n-content="syncLoading"></div>
+ <div id="timeout" i18n-content="syncTimeout"></div>
+ <div id="main">
+ <div class="settings-box">
+ <paper-checkbox checked="{{syncPrefs.syncAllDataTypes}}"
+ on-change="onSyncAllDataTypesChanged_">
+ <span i18n-content="syncEverythingCheckboxLabel">
+ </paper-checkbox>
+
+ <div id="sync-item-list">
+ <paper-checkbox checked="{{syncPrefs.appsSynced}}"
+ hidden="[[!syncPrefs.appsRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.appsEnforced)]]">
+ <span i18n-content="appCheckboxLabel"></span>
+ </paper-checkbox>
+ <paper-checkbox checked="{{syncPrefs.autofillSynced}}"
+ hidden="[[!syncPrefs.autofillRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]">
+ <span i18n-content="autofillCheckboxLabel"></span>
+ </paper-checkbox>
+ <paper-checkbox checked="{{syncPrefs.bookmarksSynced}}"
+ hidden="[[!syncPrefs.bookmarksRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]">
+ <span i18n-content="bookmarksCheckboxLabel"></span>
+ </paper-checkbox>
+ <paper-checkbox checked="{{syncPrefs.extensionsSynced}}"
+ hidden="[[!syncPrefs.extensionsRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.extensionsEnforced)]]">
+ <span i18n-content="extensionsCheckboxLabel"></span>
+ </paper-checkbox>
+ <paper-checkbox checked="{{syncPrefs.typedUrlsSynced}}"
+ hidden="[[!syncPrefs.typedUrlsRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsEnforced)]]">
+ <span i18n-content="historyCheckboxLabel"></span>
+ </paper-checkbox>
+ <paper-checkbox checked="{{syncPrefs.passwordsSynced}}"
+ hidden="[[!syncPrefs.passwordsRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.passwordsEnforced)]]">
+ <span i18n-content="passwordsCheckboxLabel"></span>
+ </paper-checkbox>
+ <paper-checkbox checked="{{syncPrefs.preferencesSynced}}"
+ hidden="[[!syncPrefs.preferencesRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.preferencesEnforced)]]">
+ <span i18n-content="settingsCheckboxLabel"></span>
+ </paper-checkbox>
+ <paper-checkbox checked="{{syncPrefs.themesSynced}}"
+ hidden="[[!syncPrefs.themesRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]">
+ <span i18n-content="themesAndWallpapersCheckboxLabel"></span>
+ </paper-checkbox>
+ <paper-checkbox checked="{{syncPrefs.tabsSynced}}"
+ hidden="[[!syncPrefs.tabsRegistered]]"
+ disabled="[[shouldSyncCheckboxBeDisabled_(syncPrefs.syncAllDataTypes, syncPrefs.tabsEnforced)]]">
+ <span i18n-content="openTabsCheckboxLabel"></span>
+ </paper-checkbox>
+ </div>
+ </div>
+
+ <div class="settings-box">
+ <h2 i18n-content="encryptionOptionsTitle"></h2>
+ <p i18n-content="syncDataEncryptedText"></p>
+
+ <template is="dom-if" if="[[!syncPrefs.showPassphrase]]">
+ <paper-radio-group id="encryptRadioGroup"
+ selected="[[selectedEncryptionRadio_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]"
+ on-paper-radio-group-changed="onEncryptionRadioSelectionChanged_">
+ <paper-radio-button name="encrypt-with-google"
+ disabled="[[encryptionRadiosDisabled_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]">
+ <span>[[i18n('encryptWithGoogleCredentialsLabel')]]</span>
+ </paper-radio-button>
+ <paper-radio-button name="encrypt-with-passphrase"
+ disabled="[[encryptionRadiosDisabled_(syncPrefs.usePassphrase, syncPrefs.encryptAllData)]]">
+ <span>[[encryptWithPassphraseBody_(syncPrefs.fullEncryptionBody)]]</span>
+ </paper-radio-button>
+ </paper-radio-group>
+ </template>
+
+ <template is="dom-if" if="[[creatingNewPassphrase]]">
+ <div>[[i18n('passphraseExplanationText')]]</div>
+ <paper-input id="passphraseInput" type="password"
+ placeholder="[[i18n('passphrasePlaceholder')]]">
+ </paper-input>
+ <paper-input id="passphraseConfirmationInput" type="password"
+ placeholder="[[i18n('passphraseConfirmationPlaceholder')]]">
+ </paper-input>
+ <div id="emptyPassphraseError" hidden>[[i18n('emptyPassphraseError')]]</div>
+ <div id="mismatchedPassphraseError" hidden>[[i18n('mismatchedPassphraseError')]]</div>
+ </template>
+
+ <template is="dom-if" if="[[syncPrefs.showPassphrase]]">
+ <div id="askCustomPassphraseMessage"
+ hidden="[[askOldGooglePassphrase]]">[[syncPrefs.enterPassphraseBody]]</div>
+ <div id="askOldGooglePassphraseMessage"
+ hidden="[[!askOldGooglePassphrase]]">[[syncPrefs.enterGooglePassphraseBody]]</div>
+ <paper-input id="existingPassphraseInput" type="password"
+ placeholder="[[i18n('passphrasePlaceholder')]]">
+ </paper-input>
+ <div id="incorrectPassphraseError" hidden>[[i18n('incorrectPassphraseError')]]</div>
+ </template>
+ </div>
+
+ <div class="settings-box">
+ <paper-button i18n-content="cancelButton" on-tap="onCancelTap_">
+ </paper-button>
+ <paper-button i18n-content="okButton" on-tap="onOkTap_" raised>
+ </paper-button>
+ </div>
+ </div>
+ </iron-pages>
+ </template>
+ <script src="sync_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_page.js b/chromium/chrome/browser/resources/settings/people_page/sync_page.js
new file mode 100644
index 00000000000..f8f436f2537
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/sync_page.js
@@ -0,0 +1,265 @@
+// 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() {
+
+/**
+ * Names of the radio buttons which allow the user to choose his encryption
+ * mechanism.
+ * @enum {string}
+ */
+var RadioButtonNames = {
+ ENCRYPT_WITH_GOOGLE: 'encrypt-with-google',
+ ENCRYPT_WITH_PASSPHRASE: 'encrypt-with-passphrase',
+};
+
+/**
+ * @fileoverview
+ * 'settings-sync-page' is the settings page containing sync settings.
+ *
+ * Example:
+ *
+ * <iron-animated-pages>
+ * <settings-sync-page></settings-sync-page>
+ * ... other pages ...
+ * </iron-animated-pages>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-sync-page
+ */
+Polymer({
+ is: 'settings-sync-page',
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ properties: {
+ /**
+ * The current active route.
+ */
+ currentRoute: {
+ type: Object,
+ observer: 'currentRouteChanged_',
+ },
+
+ /**
+ * The current sync preferences, supplied by settings.SyncPrivateApi.
+ * @type {?settings.SyncPrefs}
+ */
+ syncPrefs: {
+ type: Object,
+ },
+
+ /**
+ * Whether the "create passphrase" inputs should be shown. These inputs
+ * give the user the opportunity to use a custom passphrase instead of
+ * authenticating with his Google credentials.
+ */
+ creatingNewPassphrase: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * True if subpage needs the user's old Google password. This can happen
+ * when the user changes his password after encrypting his sync data.
+ *
+ * TODO(tommycli): FROM the C++ handler, the syncPrefs.usePassphrase field
+ * is true if and only if there is a custom non-Google Sync password.
+ *
+ * But going TO the C++ handler, the syncPrefs.usePassphrase field is true
+ * if there is either a custom or Google password. There is a separate
+ * syncPrefs.isGooglePassphrase field.
+ *
+ * We keep an extra state variable here because we mutate the
+ * syncPrefs.usePassphrase field in the OK button handler.
+ * Remove this once we fix refactor the legacy SyncSetupHandler.
+ */
+ askOldGooglePassphrase: {
+ type: Boolean,
+ value: false,
+ },
+ },
+
+ created: function() {
+ settings.SyncPrivateApi.setSyncPrefsCallback(
+ this.handleSyncPrefsFetched_.bind(this));
+ },
+
+ /** @private */
+ currentRouteChanged_: function() {
+ if (this.currentRoute.section == 'people' &&
+ this.currentRoute.subpage.length == 1 &&
+ this.currentRoute.subpage[0] == 'sync') {
+ // Display loading page until the settings have been retrieved.
+ this.$.pages.selected = 'loading';
+ settings.SyncPrivateApi.didNavigateToSyncPage();
+ } else {
+ settings.SyncPrivateApi.didNavigateAwayFromSyncPage();
+ }
+ },
+
+ /**
+ * Handler for when the sync state is pushed from settings.SyncPrivateApi.
+ * @private
+ */
+ handleSyncPrefsFetched_: function(syncPrefs) {
+ this.syncPrefs = syncPrefs;
+
+ this.askOldGooglePassphrase =
+ this.syncPrefs.showPassphrase && !this.syncPrefs.usePassphrase;
+
+ this.creatingNewPassphrase = false;
+
+ this.$.pages.selected = 'main';
+ },
+
+ /**
+ * Handler for when the sync all data types checkbox is changed.
+ * @param {Event} event
+ * @private
+ */
+ onSyncAllDataTypesChanged_: function(event) {
+ if (event.target.checked) {
+ this.set('syncPrefs.syncAllDataTypes', true);
+ this.set('syncPrefs.appsSynced', true);
+ this.set('syncPrefs.extensionsSynced', true);
+ this.set('syncPrefs.preferencesSynced', true);
+ this.set('syncPrefs.autofillSynced', true);
+ this.set('syncPrefs.typedUrlsSynced', true);
+ this.set('syncPrefs.themesSynced', true);
+ this.set('syncPrefs.bookmarksSynced', true);
+ this.set('syncPrefs.passwordsSynced', true);
+ this.set('syncPrefs.tabsSynced', true);
+ }
+ },
+
+ /** @private */
+ onCancelTap_: function() {
+ // Event is caught by settings-animated-pages.
+ this.fire('subpage-back');
+ },
+
+ /**
+ * Sets the sync data by sending it to the settings.SyncPrivateApi.
+ * @private
+ */
+ onOkTap_: function() {
+ if (this.creatingNewPassphrase) {
+ // If a new password has been entered but it is invalid, do not send the
+ // sync state to the API.
+ if (!this.validateCreatedPassphrases_())
+ return;
+
+ this.syncPrefs.encryptAllData = true;
+ }
+
+ this.syncPrefs.isGooglePassphrase = this.askOldGooglePassphrase;
+ this.syncPrefs.usePassphrase =
+ this.creatingNewPassphrase || this.syncPrefs.showPassphrase;
+
+ if (this.syncPrefs.usePassphrase) {
+ var field = this.creatingNewPassphrase ?
+ this.$$('#passphraseInput') : this.$$('#existingPassphraseInput');
+ this.syncPrefs.passphrase = field.value;
+ field.value = '';
+ }
+
+ settings.SyncPrivateApi.setSyncPrefs(
+ this.syncPrefs, this.setPageStatusCallback_.bind(this));
+ },
+
+ /**
+ * Callback invoked from calling settings.SyncPrivateApi.setSyncPrefs().
+ * @param {!settings.PageStatus} callbackState
+ * @private
+ */
+ setPageStatusCallback_: function(callbackState) {
+ if (callbackState == settings.PageStatus.DONE) {
+ this.onCancelTap_();
+ } else if (callbackState == settings.PageStatus.TIMEOUT) {
+ this.$.pages.selected = 'timeout';
+ } else if (callbackState ==
+ settings.PageStatus.PASSPHRASE_ERROR) {
+ this.$$('#incorrectPassphraseError').hidden = false;
+ }
+ },
+
+ /**
+ * Called when the encryption
+ * @private
+ */
+ onEncryptionRadioSelectionChanged_: function(event) {
+ this.creatingNewPassphrase =
+ event.target.selected == RadioButtonNames.ENCRYPT_WITH_PASSPHRASE;
+ },
+
+ /**
+ * Computed binding returning the selected encryption radio button.
+ * @private
+ */
+ selectedEncryptionRadio_: function() {
+ return this.encryptionRadiosDisabled_() ?
+ RadioButtonNames.ENCRYPT_WITH_PASSPHRASE :
+ RadioButtonNames.ENCRYPT_WITH_GOOGLE;
+ },
+
+ /**
+ * Computed binding returning the selected encryption radio button.
+ * @private
+ */
+ encryptionRadiosDisabled_: function() {
+ return this.syncPrefs.usePassphrase || this.syncPrefs.encryptAllData;
+ },
+
+ /**
+ * Computed binding returning the encryption text body.
+ * @private
+ */
+ encryptWithPassphraseBody_: function() {
+ if (this.syncPrefs && this.syncPrefs.fullEncryptionBody)
+ return this.syncPrefs.fullEncryptionBody;
+
+ return this.i18n('encryptWithSyncPassphraseLabel');
+ },
+
+ /**
+ * @param {boolean} syncAllDataTypes
+ * @param {boolean} enforced
+ * @return {boolean} Whether the sync checkbox should be disabled.
+ */
+ shouldSyncCheckboxBeDisabled_: function(syncAllDataTypes, enforced) {
+ return syncAllDataTypes || enforced;
+ },
+
+ /**
+ * Checks the supplied passphrases to ensure that they are not empty and that
+ * they match each other. Additionally, displays error UI if they are
+ * invalid.
+ * @return {boolean} Whether the check was successful (i.e., that the
+ * passphrases were valid).
+ * @private
+ */
+ validateCreatedPassphrases_: function() {
+ this.$$('#emptyPassphraseError').hidden = true;
+ this.$$('#mismatchedPassphraseError').hidden = true;
+
+ var passphrase = this.$$('#passphraseInput').value;
+ if (!passphrase) {
+ this.$$('#emptyPassphraseError').hidden = false;
+ return false;
+ }
+
+ var confirmation = this.$$('#passphraseConfirmationInput').value;
+ if (passphrase != confirmation) {
+ this.$$('#mismatchedPassphraseError').hidden = false;
+ return false;
+ }
+
+ return true;
+ },
+});
+
+})();
diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_private_api.html b/chromium/chrome/browser/resources/settings/people_page/sync_private_api.html
new file mode 100644
index 00000000000..a909061145f
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/sync_private_api.html
@@ -0,0 +1 @@
+<script src="chrome://md-settings/people_page/sync_private_api.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_private_api.js b/chromium/chrome/browser/resources/settings/people_page/sync_private_api.js
new file mode 100644
index 00000000000..1682433657b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/sync_private_api.js
@@ -0,0 +1,294 @@
+// 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.
+
+cr.exportPath('settings');
+
+/**
+ * The state of sync. This is the data structure sent back and forth between
+ * C++ and JS. Its naming and structure is not optimal, but changing it would
+ * require changes to the C++ handler, which is already functional.
+ * @typedef {{
+ * appsEnforced: boolean,
+ * appsRegistered: boolean,
+ * appsSynced: boolean,
+ * autofillEnforced: boolean,
+ * autofillRegistered: boolean,
+ * autofillSynced: boolean,
+ * bookmarksEnforced: boolean,
+ * bookmarksRegistered: boolean,
+ * bookmarksSynced: boolean,
+ * encryptAllData: boolean,
+ * encryptAllDataAllowed: boolean,
+ * enterGooglePassphraseBody: (string|undefined),
+ * enterPassphraseBody: (string|undefined),
+ * extensionsEnforced: boolean,
+ * extensionsRegistered: boolean,
+ * extensionsSynced: boolean,
+ * fullEncryptionBody: string,
+ * isGooglePassphrase: (boolean|undefined),
+ * passphrase: (string|undefined),
+ * passphraseFailed: boolean,
+ * passwordsEnforced: boolean,
+ * passwordsRegistered: boolean,
+ * passwordsSynced: boolean,
+ * preferencesEnforced: boolean,
+ * preferencesRegistered: boolean,
+ * preferencesSynced: boolean,
+ * showPassphrase: boolean,
+ * syncAllDataTypes: boolean,
+ * syncNothing: boolean,
+ * tabsEnforced: boolean,
+ * tabsRegistered: boolean,
+ * tabsSynced: boolean,
+ * themesEnforced: boolean,
+ * themesRegistered: boolean,
+ * themesSynced: boolean,
+ * typedUrlsEnforced: boolean,
+ * typedUrlsRegistered: boolean,
+ * typedUrlsSynced: boolean,
+ * usePassphrase: boolean,
+ * wifiCredentialsEnforced: (boolean|undefined),
+ * wifiCredentialsSynced: (boolean|undefined)
+ * }}
+ */
+settings.SyncPrefs;
+
+/**
+ * @typedef {{actionLinkText: (string|undefined),
+ * childUser: (boolean|undefined),
+ * hasError: (boolean|undefined),
+ * hasUnrecoverableError: (boolean|undefined),
+ * managed: (boolean|undefined),
+ * setupCompleted: (boolean|undefined),
+ * setupInProgress: (boolean|undefined),
+ * signedIn: (boolean|undefined),
+ * signinAllowed: (boolean|undefined),
+ * signoutAllowed: (boolean|undefined),
+ * statusText: (string|undefined),
+ * supervisedUser: (boolean|undefined),
+ * syncSystemEnabled: (boolean|undefined)}}
+ * @see chrome/browser/ui/webui/settings/sync_handler.cc
+ */
+settings.SyncStatus;
+
+/**
+ * @enum {string}
+ */
+settings.PageStatus = {
+ SPINNER: 'spinner', // Before the page has loaded.
+ CONFIGURE: 'configure', // Preferences ready to be configured.
+ TIMEOUT: 'timeout', // Preferences loading has timed out.
+ DONE: 'done', // Sync subpage can be closed now.
+ PASSPHRASE_ERROR: 'passphraseError', // Error in the passphrase.
+};
+
+cr.define('settings', function() {
+ /**
+ * API which encapsulates messaging between JS and C++ for the sync page.
+ * @constructor
+ */
+ function SyncPrivateApi() {}
+
+ /** @private {?function(!string, !string)} */
+ SyncPrivateApi.getProfileInfoCallback_ = null;
+
+ /** @private {?function(!Array<string>)} */
+ SyncPrivateApi.getAvailableIconsCallback_ = null;
+
+ /** @private {?function(settings.SyncPrefs)} */
+ SyncPrivateApi.syncPrefsCallback_ = null;
+
+ /** @private {?function(settings.PageStatus)} */
+ SyncPrivateApi.setPageStatusCallback_ = null;
+
+ /**
+ * Called from JavaScript. Gets the current profile name and icon.
+ * @param {?function(!string, !string)} callback
+ */
+ SyncPrivateApi.getProfileInfo = function(callback) {
+ SyncPrivateApi.getProfileInfoCallback_ = callback;
+ chrome.send('getProfileInfo');
+ };
+
+ /**
+ * Called from C++ as a response to getIconsAndNames.
+ * @param {!string} name The current profile name.
+ * @param {!string} iconUrl The current profile icon's URL. Can be a data URL.
+ */
+ SyncPrivateApi.receiveProfileInfo = function(name, iconUrl) {
+ if (SyncPrivateApi.getProfileInfoCallback_)
+ SyncPrivateApi.getProfileInfoCallback_(name, iconUrl);
+ };
+
+<if expr="not chromeos">
+ /**
+ * Called from JavaScript. Gets the available profile icons to choose from.
+ * @param {!function(!Array<string>)} callback
+ */
+ SyncPrivateApi.getAvailableIcons = function(callback) {
+ SyncPrivateApi.getAvailableIconsCallback_ = callback;
+ chrome.send('requestDefaultProfileIcons');
+ };
+
+ /**
+ * Called from C++ as a response to getAvailableIcons.
+ * @param {!Array<string>} iconUrls An array of icon URLs.
+ */
+ SyncPrivateApi.receiveAvailableIcons = function(iconUrls) {
+ if (SyncPrivateApi.getAvailableIconsCallback_)
+ SyncPrivateApi.getAvailableIconsCallback_(iconUrls);
+ };
+
+ /**
+ * Called from JavaScript. Sets the profile icon and name.
+ * @param {!string} iconUrl The new profile URL.
+ * @param {!string} name The new profile name.
+ */
+ SyncPrivateApi.setProfileIconAndName = function(iconUrl, name) {
+ chrome.send('setProfileIconAndName', [iconUrl, name]);
+ };
+</if>
+
+ /**
+ * Starts the signin process for the user. Does nothing if the user is
+ * already signed in.
+ * @private
+ */
+ SyncPrivateApi.startSignIn = function() {
+ chrome.send('SyncSetupStartSignIn');
+ };
+
+ /**
+ * Disconnects the signed in user.
+ * @param {!boolean} deleteProfile
+ * @private
+ */
+ SyncPrivateApi.disconnect = function(deleteProfile) {
+ chrome.send('SyncSetupStopSyncing', [deleteProfile]);
+ };
+
+ /**
+ * Determines the appropriate page to show in the Sync Setup UI based on
+ * the state of the Sync backend. Does nothing if the user is not signed in.
+ * @private
+ */
+ SyncPrivateApi.showSetupUI = function() {
+ chrome.send('SyncSetupShowSetupUI');
+ chrome.send('coreOptionsUserMetricsAction', ['Options_ShowSyncAdvanced']);
+ };
+
+ /**
+ * Function to invoke when the sync page has been navigated to. This registers
+ * the UI as the "active" sync UI so that if the user tries to open another
+ * sync UI, this one will be shown instead.
+ */
+ SyncPrivateApi.didNavigateToSyncPage = function() {
+ chrome.send('SyncSetupShowSetupUI');
+ };
+
+ /**
+ * Function to invoke when leaving the sync page so that the C++ layer can be
+ * notified that the sync UI is no longer open.
+ */
+ SyncPrivateApi.didNavigateAwayFromSyncPage = function() {
+ SyncPrivateApi.setPageStatusCallback_ = null;
+ chrome.send('SyncSetupDidClosePage');
+ };
+
+ /**
+ * Sets the callback to be invoked when sync data has been fetched.
+ * @param {!function(settings.SyncPrefs)} callback
+ */
+ SyncPrivateApi.setSyncPrefsCallback = function(callback) {
+ SyncPrivateApi.syncPrefsCallback_ = callback;
+ };
+
+ /**
+ * Handler for when state has been fetched from C++.
+ * @param {!settings.SyncPrefs} syncPrefsFromCpp
+ * @private
+ */
+ SyncPrivateApi.sendSyncPrefs_ = function(syncPrefsFromCpp) {
+ if (SyncPrivateApi.syncPrefsCallback_)
+ SyncPrivateApi.syncPrefsCallback_(syncPrefsFromCpp);
+ };
+
+ /**
+ * Sets the sync state by sending it to the C++ layer.
+ * @param {!settings.SyncPrefs} syncPrefs
+ * @param {!function(settings.PageStatus)} callback
+ */
+ SyncPrivateApi.setSyncPrefs = function(syncPrefs, callback) {
+ SyncPrivateApi.setPageStatusCallback_ = callback;
+ chrome.send('SyncSetupConfigure', [JSON.stringify(syncPrefs)]);
+ };
+
+ /**
+ * Handler for when setSyncPrefs() has either succeeded or failed.
+ * @param {!settings.PageStatus} status
+ * @private
+ */
+ SyncPrivateApi.setPageStatus_ = function(status) {
+ if (SyncPrivateApi.setPageStatusCallback_)
+ SyncPrivateApi.setPageStatusCallback_(status);
+
+ SyncPrivateApi.setPageStatusCallback_ = null;
+ };
+
+ /**
+ * Sends a request from JS to C++ for the current sync status.
+ * @param {!function(settings.SyncStatus)} callback
+ */
+ SyncPrivateApi.getSyncStatus = function(callback) {
+ SyncPrivateApi.syncStatusCallback_ = callback;
+ chrome.send('SyncSetupGetSyncStatus');
+ };
+
+ /**
+ * Handler for when sync status has been fetched from C++.
+ * @param {!settings.SyncStatus} syncStatusFromCpp
+ * @private
+ */
+ SyncPrivateApi.sendSyncStatus = function(syncStatusFromCpp) {
+ if (SyncPrivateApi.syncStatusCallback_)
+ SyncPrivateApi.syncStatusCallback_(syncStatusFromCpp);
+ };
+
+ /**
+ * Sends a request from JS to C++ to open the multi-profile User Manager.
+ */
+ SyncPrivateApi.manageOtherPeople = function() {
+ chrome.send('SyncSetupManageOtherPeople');
+ };
+
+ /**
+ * This function encapsulates the logic that maps from the legacy
+ * SyncSettingsHandler to an API natural to the new Polymer implementation.
+ * @param {!settings.PageStatus} status
+ * @param {!settings.SyncPrefs} prefs
+ */
+ SyncPrivateApi.showSyncSetupPage = function(status, prefs) {
+ switch (status) {
+ case settings.PageStatus.TIMEOUT:
+ case settings.PageStatus.DONE:
+ SyncPrivateApi.setPageStatus_(status);
+ break;
+ case settings.PageStatus.CONFIGURE:
+ if (prefs.passphraseFailed) {
+ SyncPrivateApi.setPageStatus_(
+ settings.PageStatus.PASSPHRASE_ERROR);
+ return;
+ }
+
+ SyncPrivateApi.sendSyncPrefs_(prefs);
+ break;
+ default:
+ // Other statuses (i.e. "spinner") are ignored.
+ }
+ };
+
+ return {
+ SyncPrivateApi: SyncPrivateApi,
+ };
+});
diff --git a/chromium/chrome/browser/resources/settings/users_page/user_list.css b/chromium/chrome/browser/resources/settings/people_page/user_list.css
index bd4ee803521..0db441cdcf4 100644
--- a/chromium/chrome/browser/resources/settings/users_page/user_list.css
+++ b/chromium/chrome/browser/resources/settings/people_page/user_list.css
@@ -11,6 +11,11 @@
width: 18px;
}
+.soft-border {
+ border: 1px solid #c4c4c4;
+ border-radius: 2px;
+}
+
.user {
-webkit-padding-end: 8px;
-webkit-padding-start: 20px;
diff --git a/chromium/chrome/browser/resources/settings/users_page/user_list.html b/chromium/chrome/browser/resources/settings/people_page/user_list.html
index 6663ceacc76..579424d645e 100644
--- a/chromium/chrome/browser/resources/settings/users_page/user_list.html
+++ b/chromium/chrome/browser/resources/settings/people_page/user_list.html
@@ -2,9 +2,9 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
-<dom-module id="cr-settings-user-list">
+<dom-module id="settings-user-list">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="user_list.css">
<template>
<div class="user-list soft-border">
diff --git a/chromium/chrome/browser/resources/settings/users_page/user_list.js b/chromium/chrome/browser/resources/settings/people_page/user_list.js
index dae00f5ba9c..35bce238042 100644
--- a/chromium/chrome/browser/resources/settings/users_page/user_list.js
+++ b/chromium/chrome/browser/resources/settings/people_page/user_list.js
@@ -4,19 +4,19 @@
/**
* @fileoverview
- * 'cr-settings-user-list' shows a list of users whitelisted on this Chrome OS
+ * 'settings-user-list' shows a list of users whitelisted on this Chrome OS
* device.
*
* Example:
*
- * <cr-settings-user-list prefs="{{prefs}}">
- * </cr-settings-user-list>
+ * <settings-user-list prefs="{{prefs}}">
+ * </settings-user-list>
*
* @group Chrome Settings Elements
- * @element cr-settings-user-list
+ * @element settings-user-list
*/
Polymer({
- is: 'cr-settings-user-list',
+ is: 'settings-user-list',
properties: {
/**
diff --git a/chromium/chrome/browser/resources/settings/users_page/users_page.css b/chromium/chrome/browser/resources/settings/people_page/users_page.css
index 17db8f1cc6d..46166f5c039 100644
--- a/chromium/chrome/browser/resources/settings/users_page/users_page.css
+++ b/chromium/chrome/browser/resources/settings/people_page/users_page.css
@@ -10,10 +10,6 @@
padding-top: 25px;
}
-.page-content > div {
- margin-top: 30px;
-}
-
.users {
-webkit-margin-start: 50px;
}
diff --git a/chromium/chrome/browser/resources/settings/people_page/users_page.html b/chromium/chrome/browser/resources/settings/people_page/users_page.html
new file mode 100644
index 00000000000..1a421521639
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/people_page/users_page.html
@@ -0,0 +1,64 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.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-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_section.html">
+<link rel="import" href="user_list.html">
+
+<dom-module id="settings-users-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="users_page.css">
+ <template>
+ <div class="settings-box" i18n-content="usersModifiedByOwnerLabel"
+ hidden$="{{computeHideOwnerLabel_(isOwner, isWhitelistManaged)}}">
+ </div>
+ <div class="settings-box" i18n-content="settingsManagedLabel"
+ hidden$="{{computeHideManagedLabel_(isOwner, isWhitelistManaged)}}">
+ </div>
+ <div class="settings-box">
+ <settings-checkbox
+ pref="{{prefs.cros.accounts.allowBWSI}}"
+ i18n-values="label:guestBrowsingLabel"
+ disabled="{{editingDisabled}}">
+ </settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.cros.accounts.supervisedUsersEnabled}}"
+ i18n-values="label:supervisedUsersLabel"
+ disabled="{{editingDisabled}}">
+ </settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.cros.accounts.showUserNamesOnSignIn}}"
+ i18n-values="label:showOnSigninLabel"
+ disabled="{{editingDisabled}}">
+ </settings-checkbox>
+ </div>
+ <div class="settings-box">
+ <settings-checkbox
+ pref="{{prefs.cros.accounts.allowGuest}}"
+ id="restrictSignIn"
+ i18n-values="label:restrictSigninLabel"
+ disabled="{{editingDisabled}}" inverted>
+ </settings-checkbox>
+ <div class="users">
+ <div>
+ <settings-user-list prefs="[[prefs]]"
+ disabled="[[editingUsersDisabled]]">
+ </settings-user-list>
+ </div>
+ <div>
+ <paper-input id="addUserInput" i18n-values="label:addUsersLabel"
+ disabled="[[editingUsersDisabled]]">
+ </paper-input>
+ <div class="add-user-button layout horizontal end-justified">
+ <paper-button i18n-content="addLabel" on-tap="addUser_"
+ disabled="[[editingUsersDisabled]]" raised>
+ </paper-button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </template>
+ <script src="users_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/users_page/users_page.js b/chromium/chrome/browser/resources/settings/people_page/users_page.js
index 44681b25d8e..da31d3901d2 100644
--- a/chromium/chrome/browser/resources/settings/users_page/users_page.js
+++ b/chromium/chrome/browser/resources/settings/people_page/users_page.js
@@ -4,22 +4,22 @@
/**
* @fileoverview
- * 'cr-settings-users-page' is the settings page for managing user accounts on
+ * 'settings-users-page' is the settings page for managing user accounts on
* the device.
*
* Example:
*
* <neon-animated-pages>
- * <cr-settings-users-page prefs="{{prefs}}">
- * </cr-settings-users-page>
+ * <settings-users-page prefs="{{prefs}}">
+ * </settings-users-page>
* ... other pages ...
* </neon-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-users-page
+ * @element settings-users-page
*/
Polymer({
- is: 'cr-settings-users-page',
+ is: 'settings-users-page',
behaviors: [
Polymer.IronA11yKeysBehavior
diff --git a/chromium/chrome/browser/resources/settings/policy_controllable/policy_controllable.html b/chromium/chrome/browser/resources/settings/policy_controllable/policy_controllable.html
deleted file mode 100644
index c5a1da9a55e..00000000000
--- a/chromium/chrome/browser/resources/settings/policy_controllable/policy_controllable.html
+++ /dev/null
@@ -1 +0,0 @@
-<script src="policy_controllable.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/policy_controllable/policy_controllable.js b/chromium/chrome/browser/resources/settings/policy_controllable/policy_controllable.js
deleted file mode 100644
index 3298d3d0745..00000000000
--- a/chromium/chrome/browser/resources/settings/policy_controllable/policy_controllable.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Behavior to determine whether a pref is controlled by policy.
- */
-
-/** @polymerBehavior */
-var PolicyControllable = {
- /**
- * @param {?chrome.settingsPrivate.PrefObject} pref
- * @return {boolean} True if the pref is controlled by an enforced policy.
- */
- isPolicyControlled: function(pref) {
- return !!pref &&
- pref.policyEnforcement ==
- chrome.settingsPrivate.PolicyEnforcement.ENFORCED;
- },
-};
diff --git a/chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.html b/chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.html
index a1f68d21c92..978dafeea99 100644
--- a/chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.html
+++ b/chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.html
@@ -1,6 +1,6 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://md-settings/prefs/prefs_types.html">
-<dom-module id="cr-settings-pref-tracker">
+<dom-module id="settings-pref-tracker">
<script src="pref_tracker.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.js b/chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.js
index b7124759a8c..34d9473a3a1 100644
--- a/chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.js
+++ b/chromium/chrome/browser/resources/settings/pref_tracker/pref_tracker.js
@@ -4,21 +4,21 @@
/**
* @fileoverview
- * `cr-settings-pref-tracker` is a utility element used to track the
+ * `settings-pref-tracker` is a utility element used to track the
* initialization of a specified preference and throw an error if the pref
* is not defined after prefs have all been fetched.
*
* Example:
*
- * <cr-settings-pref-tracker pref="{{prefs.settings.foo.bar}}">
- * </cr-settings-pref-tracker>
+ * <settings-pref-tracker pref="{{prefs.settings.foo.bar}}">
+ * </settings-pref-tracker>
*
- * @element cr-settings-pref-tracker
+ * @element settings-pref-tracker
*/
(function() {
Polymer({
- is: 'cr-settings-pref-tracker',
+ is: 'settings-pref-tracker',
properties: {
/**
diff --git a/chromium/chrome/browser/resources/settings/prefs/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/prefs/compiled_resources.gyp
index c9528910baa..0738e33df4b 100644
--- a/chromium/chrome/browser/resources/settings/prefs/compiled_resources.gyp
+++ b/chromium/chrome/browser/resources/settings/prefs/compiled_resources.gyp
@@ -7,8 +7,11 @@
'target_name': 'prefs',
'variables': {
'depends': [
+ '../../../../../third_party/closure_compiler/externs/settings_private_interface.js',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
'../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ 'pref_util.js',
+ 'prefs_behavior.js',
'prefs_types.js',
],
'externs': [
diff --git a/chromium/chrome/browser/resources/settings/prefs/pref_util.html b/chromium/chrome/browser/resources/settings/prefs/pref_util.html
new file mode 100644
index 00000000000..8ebccbc7499
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/prefs/pref_util.html
@@ -0,0 +1,2 @@
+<link rel="import" href="chrome://resources/html/cr.html">
+<script src="pref_util.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/prefs/pref_util.js b/chromium/chrome/browser/resources/settings/prefs/pref_util.js
new file mode 100644
index 00000000000..d18395e4bb5
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/prefs/pref_util.js
@@ -0,0 +1,57 @@
+// 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.
+
+/** @fileoverview Utility functions to help use prefs in Polymer controls. */
+
+// TODO(michaelpg): converge with other WebUI on capitalization. This is
+// consistent with Settings, but WebUI uses lower.underscore_case.
+cr.define('Settings.PrefUtil', function() {
+ /**
+ * Converts a string value to a type corresponding to the given preference.
+ * @param {string} value
+ * @param {!chrome.settingsPrivate.PrefObject} pref
+ * @return {boolean|number|string|undefined}
+ */
+ function stringToPrefValue(value, pref) {
+ switch (pref.type) {
+ case chrome.settingsPrivate.PrefType.BOOLEAN:
+ return value == 'true';
+ case chrome.settingsPrivate.PrefType.NUMBER:
+ var n = parseInt(value, 10);
+ if (isNaN(n)) {
+ console.error('Argument to stringToPrefValue for number pref ' +
+ 'was unparsable: ' + value);
+ return undefined;
+ }
+ return n;
+ case chrome.settingsPrivate.PrefType.STRING:
+ case chrome.settingsPrivate.PrefType.URL:
+ return value;
+ default:
+ assertNotReached('No conversion from string to ' + pref.type + ' pref');
+ }
+ }
+
+ /**
+ * Returns the value of the pref as a string.
+ * @param {!chrome.settingsPrivate.PrefObject} pref
+ * @return {string}
+ */
+ function prefToString(pref) {
+ switch (pref.type) {
+ case chrome.settingsPrivate.PrefType.BOOLEAN:
+ case chrome.settingsPrivate.PrefType.NUMBER:
+ return pref.value.toString();
+ case chrome.settingsPrivate.PrefType.STRING:
+ case chrome.settingsPrivate.PrefType.URL:
+ return /** @type {string} */(pref.value);
+ default:
+ assertNotReached('No conversion from ' + pref.type + ' pref to string');
+ }
+ }
+ return {
+ stringToPrefValue: stringToPrefValue,
+ prefToString: prefToString,
+ };
+});
diff --git a/chromium/chrome/browser/resources/settings/prefs/prefs.html b/chromium/chrome/browser/resources/settings/prefs/prefs.html
index e3fe2171c97..6a73790da49 100644
--- a/chromium/chrome/browser/resources/settings/prefs/prefs.html
+++ b/chromium/chrome/browser/resources/settings/prefs/prefs.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/html/polymer_config.html">
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/cr.html">
diff --git a/chromium/chrome/browser/resources/settings/prefs/prefs.js b/chromium/chrome/browser/resources/settings/prefs/prefs.js
index 4dbce563490..7f624d3f481 100644
--- a/chromium/chrome/browser/resources/settings/prefs/prefs.js
+++ b/chromium/chrome/browser/resources/settings/prefs/prefs.js
@@ -4,7 +4,7 @@
/**
* @fileoverview
- * 'cr-settings-prefs' exposes a singleton model of Chrome settings and
+ * 'settings-prefs' exposes a singleton model of Chrome settings and
* preferences, which listens to changes to Chrome prefs whitelisted in
* chrome.settingsPrivate. When changing prefs in this element's 'prefs'
* property via the UI, the singleton model tries to set those preferences in
@@ -13,12 +13,12 @@
*
* Example:
*
- * <cr-settings-prefs prefs="{{prefs}}"></cr-settings-prefs>
- * <cr-settings-checkbox pref="{{prefs.homepage_is_newtabpage}}">
- * </cr-settings-checkbox>
+ * <settings-prefs prefs="{{prefs}}"></settings-prefs>
+ * <settings-checkbox pref="{{prefs.homepage_is_newtabpage}}">
+ * </settings-checkbox>
*
* @group Chrome Settings Elements
- * @element cr-settings-prefs
+ * @element settings-prefs
*/
(function() {
@@ -125,7 +125,7 @@
}
Polymer({
- is: 'cr-settings-prefs',
+ is: 'settings-prefs',
properties: {
/**
@@ -142,7 +142,7 @@
*/
singleton_: {
type: Object,
- value: document.createElement('cr-settings-prefs-singleton'),
+ value: document.createElement('settings-prefs-singleton'),
},
},
@@ -152,12 +152,17 @@
/** @override */
ready: function() {
- this.singleton_.initialize();
+ // Register a callback on CrSettingsPrefs.initialized immediately so prefs
+ // is set as soon as the settings API returns. This enables other elements
+ // dependent on |prefs| to add their own callbacks to
+ // CrSettingsPrefs.initialized.
this.startListening_();
+ if (!CrSettingsPrefs.deferInitialization)
+ this.initialize();
},
/**
- * Binds this.prefs to the cr-settings-prefs-singleton's shared prefs once
+ * Binds this.prefs to the settings-prefs-singleton's shared prefs once
* preferences are initialized.
* @private
*/
@@ -174,7 +179,7 @@
},
/**
- * Stops listening for changes to cr-settings-prefs-singleton's shared
+ * Stops listening for changes to settings-prefs-singleton's shared
* prefs.
* @private
*/
@@ -196,14 +201,14 @@
},
/**
- * Forwards changes to this.prefs to cr-settings-prefs-singleton.
+ * Forwards changes to this.prefs to settings-prefs-singleton.
* @private
*/
prefsChanged_: function(info) {
// Ignore changes that came from singleton_ so we don't re-process
// changes made in other instances of this element.
if (!this.ignoreChanges_)
- this.singleton_.fire('prefs-changed', info, {bubbles: false});
+ this.singleton_.fire('shared-prefs-changed', info, {bubbles: false});
},
/**
@@ -222,13 +227,25 @@
this.ignoreChanges_ = false;
},
+ /** Initializes the singleton, which will fetch the prefs. */
+ initialize: function() {
+ this.singleton_.initialize();
+ },
+
+ /**
+ * Used to initialize the singleton with a fake SettingsPrivate.
+ * @param {SettingsPrivate} settingsApi Fake implementation to use.
+ */
+ initializeForTesting: function(settingsApi) {
+ this.singleton_.initialize(settingsApi);
+ },
+
/**
* Uninitializes this element to remove it from tests. Also resets
- * cr-settings-prefs-singleton, allowing newly created elements to
+ * settings-prefs-singleton, allowing newly created elements to
* re-initialize it.
*/
resetForTesting: function() {
- this.stopListening_();
this.singleton_.resetForTesting();
},
});
@@ -238,7 +255,7 @@
* prefs state.
*/
Polymer({
- is: 'cr-settings-prefs-singleton',
+ is: 'settings-prefs-singleton',
properties: {
/**
@@ -262,37 +279,42 @@
},
},
- // Listen for the manually fired prefs-changed event.
+ // Listen for the manually fired shared-prefs-changed event, fired when
+ // a shared-prefs instance is changed by another element.
listeners: {
- 'prefs-changed': 'prefsChanged_',
+ 'shared-prefs-changed': 'sharedPrefsChanged_',
},
- settingsApi_: chrome.settingsPrivate,
+ /** @type {SettingsPrivate} */
+ settingsApi_: /** @type {SettingsPrivate} */(chrome.settingsPrivate),
- initialize: function() {
+ /**
+ * @param {SettingsPrivate=} opt_settingsApi SettingsPrivate implementation
+ * to use (chrome.settingsPrivate by default).
+ */
+ initialize: function(opt_settingsApi) {
// Only initialize once (or after resetForTesting() is called).
if (this.initialized_)
return;
this.initialized_ = true;
- // Set window.mockApi to pass a custom settings API, i.e. for tests.
- // TODO(michaelpg): don't use a global.
- if (window.mockApi)
- this.settingsApi_ = window.mockApi;
+ if (opt_settingsApi)
+ this.settingsApi_ = opt_settingsApi;
- this.settingsApi_.onPrefsChanged.addListener(
- this.onSettingsPrivatePrefsChanged_.bind(this));
+ /** @private {function(!Array<!chrome.settingsPrivate.PrefObject>)} */
+ this.boundPrefsChanged_ = this.onSettingsPrivatePrefsChanged_.bind(this);
+ this.settingsApi_.onPrefsChanged.addListener(this.boundPrefsChanged_);
this.settingsApi_.getAllPrefs(
this.onSettingsPrivatePrefsFetched_.bind(this));
},
/**
- * Polymer callback for changes to this.prefs.
+ * Polymer callback for changes to prefs.* from a shared-prefs element.
* @param {!CustomEvent} e
* @param {!{path: string}} change
* @private
*/
- prefsChanged_: function(e, change) {
+ sharedPrefsChanged_: function(e, change) {
if (!CrSettingsPrefs.isInitialized)
return;
@@ -302,17 +324,19 @@
var prefObj = /** @type {chrome.settingsPrivate.PrefObject} */(
this.get(key, this.prefs));
- // If settingsPrivate already has this value, do nothing. (Otherwise,
+ // If settingsPrivate already has this value, ignore it. (Otherwise,
// a change event from settingsPrivate could make us call
// settingsPrivate.setPref and potentially trigger an IPC loop.)
- if (deepEqual(prefStoreValue, prefObj.value))
- return;
+ if (!deepEqual(prefStoreValue, prefObj.value)) {
+ this.settingsApi_.setPref(
+ key,
+ prefObj.value,
+ /* pageId */ '',
+ /* callback */ this.setPrefCallback_.bind(this, key));
+ }
- this.settingsApi_.setPref(
- key,
- prefObj.value,
- /* pageId */ '',
- /* callback */ this.setPrefCallback_.bind(this, key));
+ // Package the event as a prefs-changed event for other elements.
+ this.fire('prefs-changed', change);
},
/**
@@ -405,9 +429,15 @@
* Resets the element so it can be re-initialized with a new prefs state.
*/
resetForTesting: function() {
+ if (!this.initialized_)
+ return;
this.prefs = undefined;
this.lastPrefValues_ = {};
this.initialized_ = false;
+ // Remove the listener added in initialize().
+ this.settingsApi_.onPrefsChanged.removeListener(this.boundPrefsChanged_);
+ this.settingsApi_ =
+ /** @type {SettingsPrivate} */(chrome.settingsPrivate);
},
});
})();
diff --git a/chromium/chrome/browser/resources/settings/prefs/prefs_behavior.html b/chromium/chrome/browser/resources/settings/prefs/prefs_behavior.html
new file mode 100644
index 00000000000..31dc603f202
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/prefs/prefs_behavior.html
@@ -0,0 +1 @@
+<script src="prefs_behavior.js"></script> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/settings/prefs/prefs_behavior.js b/chromium/chrome/browser/resources/settings/prefs/prefs_behavior.js
new file mode 100644
index 00000000000..8c9446000ef
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/prefs/prefs_behavior.js
@@ -0,0 +1,62 @@
+// 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.
+
+/**
+ * @fileoverview Common prefs behavior.
+ */
+
+/** @polymerBehavior */
+var PrefsBehavior = {
+ /**
+ * Gets the pref at the given prefPath. Throws if the pref is not found.
+ * @param {string} prefPath
+ * @return {!chrome.settingsPrivate.PrefObject}
+ * @protected
+ */
+ getPref: function(prefPath) {
+ var pref = /** @type {!chrome.settingsPrivate.PrefObject} */(
+ this.get(prefPath, this.prefs));
+ assert(typeof pref != 'undefined', 'Pref is missing: ' + prefPath);
+ return pref;
+ },
+
+ /**
+ * Sets the value of the pref at the given prefPath. Throws if the pref is not
+ * found.
+ * @param {string} prefPath
+ * @param {*} value
+ * @protected
+ */
+ setPrefValue: function(prefPath, value) {
+ this.getPref(prefPath); // Ensures we throw if the pref is not found.
+ this.set('prefs.' + prefPath + '.value', value);
+ },
+
+ /**
+ * Appends the item to the pref list at the given key if the item is not
+ * already in the list. Asserts if the pref itself is not found or is not an
+ * Array type.
+ * @param {string} key
+ * @param {*} item
+ * @protected
+ */
+ appendPrefListItem: function(key, item) {
+ var pref = this.getPref(key);
+ assert(pref && pref.type == chrome.settingsPrivate.PrefType.LIST);
+ if (pref.value.indexOf(item) == -1)
+ this.push('prefs.' + key + '.value', item);
+ },
+
+ /**
+ * Deletes the given item from the pref at the given key if the item is found.
+ * Asserts if the pref itself is not found or is not an Array type.
+ * @param {string} key
+ * @param {*} item
+ * @protected
+ */
+ deletePrefListItem: function(key, item) {
+ assert(this.getPref(key).type == chrome.settingsPrivate.PrefType.LIST);
+ this.arrayDelete('prefs.' + key + '.value', item);
+ },
+};
diff --git a/chromium/chrome/browser/resources/settings/prefs/prefs_types.js b/chromium/chrome/browser/resources/settings/prefs/prefs_types.js
index 96c8649f162..01f41c8b771 100644
--- a/chromium/chrome/browser/resources/settings/prefs/prefs_types.js
+++ b/chromium/chrome/browser/resources/settings/prefs/prefs_types.js
@@ -28,6 +28,13 @@ var CrSettingsPrefs = (function() {
},
/**
+ * Whether to defer initialization. Used in testing to prevent premature
+ * initialization when intending to fake the settings API.
+ * @type {boolean}
+ */
+ deferInitialization: false,
+
+ /**
* Called to set up the promise and resolve methods.
* @private
*/
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.css b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.css
index bcd874e4723..cebdb9ad06d 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.css
+++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.css
@@ -2,6 +2,10 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
+paper-item {
+ --paper-item-min-height: 24px;
+}
+
.privacy-buttons {
margin-top: 25px;
-} \ No newline at end of file
+}
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 b4d5fe0224b..2e6650a4263 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -3,100 +3,202 @@
<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item-body.html">
<link rel="import" href="chrome://md-settings/certificate_manager_page/certificate_manager_page.html">
<link rel="import" href="chrome://md-settings/clear_browsing_data_page/clear_browsing_data_page.html">
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
+<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html">
+<link rel="import" href="chrome://md-settings/site_settings/constants.html">
<link rel="import" href="chrome://md-settings/site_settings_page/site_settings_page.html">
-<dom-module id="cr-settings-privacy-page">
+<dom-module id="settings-privacy-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="privacy_page.css">
<template>
<settings-animated-pages id="pages" current-route="{{currentRoute}}"
section="privacy">
- <neon-animatable id="">
- <p class="privacy-explanation"
- i18n-values=".innerHTML:improveBrowsingExperience">
- </p>
- <cr-settings-checkbox
- pref="{{prefs.alternate_error_pages.enabled}}"
- i18n-values="label:linkDoctorPref">
- </cr-settings-checkbox>
- <cr-settings-checkbox
- pref="{{prefs.search.suggest_enabled}}"
- i18n-values="label:searchSuggestPref">
- </cr-settings-checkbox>
- <cr-settings-checkbox
- pref="{{prefs.net.network_prediction_options}}"
- i18n-values="label:networkPredictionEnabled">
- </cr-settings-checkbox>
- <cr-settings-checkbox
- pref="{{prefs.safebrowsing.extended_reporting_enabled}}"
- i18n-values="label:safeBrowsingEnableExtendedReporting">
- </cr-settings-checkbox>
- <cr-settings-checkbox pref="{{prefs.safebrowsing.enabled}}"
- i18n-values="label:safeBrowsingEnableProtection">
- </cr-settings-checkbox>
+ <neon-animatable id="main">
+ <div class="settings-box">
+ <p class="privacy-explanation"
+ i18n-values=".innerHTML:improveBrowsingExperience">
+ </p>
+ <settings-checkbox
+ pref="{{prefs.alternate_error_pages.enabled}}"
+ i18n-values="label:linkDoctorPref">
+ </settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.search.suggest_enabled}}"
+ i18n-values="label:searchSuggestPref">
+ </settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.net.network_prediction_options}}"
+ i18n-values="label:networkPredictionEnabled">
+ </settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.safebrowsing.extended_reporting_enabled}}"
+ i18n-values="label:safeBrowsingEnableExtendedReporting">
+ </settings-checkbox>
+ <settings-checkbox pref="{{prefs.safebrowsing.enabled}}"
+ i18n-values="label:safeBrowsingEnableProtection">
+ </settings-checkbox>
<if expr="_google_chrome">
- <cr-settings-checkbox
- pref="{{prefs.spellcheck.use_spelling_service}}"
- i18n-values="label:spellingPref">
- </cr-settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.spellcheck.use_spelling_service}}"
+ i18n-values="label:spellingPref">
+ </settings-checkbox>
<if expr="chromeos">
- <cr-settings-checkbox
- pref="{{prefs.cros.metrics.reportingEnabled}}"
- i18n-values="label:enableLogging">
- </cr-settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.cros.metrics.reportingEnabled}}"
+ i18n-values="label:enableLogging">
+ </settings-checkbox>
</if>
- <!-- TODO(jlklein): Add non-chromeos metrics box. -->
+ <!-- TODO(jlklein): Add non-chromeos metrics box. -->
</if>
- <cr-settings-checkbox pref="{{prefs.enable_do_not_track}}"
- i18n-values="label:doNotTrack">
- </cr-settings-checkbox>
+ <settings-checkbox pref="{{prefs.enable_do_not_track}}"
+ i18n-values="label:doNotTrack">
+ </settings-checkbox>
<if expr="chromeos">
- <cr-settings-checkbox
- pref="{{prefs.cros.device.attestation_for_content_protection_enabled}}"
- i18n-values="label:enableContentProtectionAttestation">
- </cr-settings-checkbox>
- <cr-settings-checkbox
- pref="{{prefs.settings.internet.wake_on_wifi_ssid}}"
- i18n-values="label:wakeOnWifi">
- </cr-settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.cros.device.attestation_for_content_protection_enabled}}"
+ i18n-values="label:enableContentProtectionAttestation">
+ </settings-checkbox>
+ <settings-checkbox
+ pref="{{prefs.settings.internet.wake_on_wifi_darkconnect}}"
+ i18n-values="label:wakeOnWifi">
+ </settings-checkbox>
</if>
- <div class="privacy-buttons layout horizontal end-justified">
- <paper-button
- on-tap="onManageCertificatesTap_"
- i18n-content="manageCertificates">
- </paper-button>
- <paper-button
- on-tap="onSiteSettingsTap_"
- i18n-content="siteSettings">
- </paper-button>
- <paper-button
- on-tap="onClearBrowsingDataTap_"
- raised i18n-content="clearBrowsingData">
+ </div>
+ <div class="settings-box" on-tap="onManageCertificatesTap_">
+ <div class="start">
+ <div i18n-content="manageCertificates"></div>
+ <div class="secondary">
+ <!-- TODO(dschuyler) replace this placeholder text -->
+ Contrary to popular belief, Lorem Ipsum is not simply random text.
+ </div>
+ </div>
+ </div>
+ <div class="settings-box" on-tap="onSiteSettingsTap_">
+ <div class="start">
+ <div i18n-content="siteSettings"></div>
+ <div class="secondary">
+ <!-- TODO(dschuyler) replace this placeholder text -->
+ Contrary to popular belief, Lorem Ipsum is not simply random text.
+ </div>
+ </div>
+ </div>
+ <div class="settings-box">
+ <paper-button on-tap="onClearBrowsingDataTap_"
+ i18n-content="clearBrowsingData">
</paper-button>
</div>
</neon-animatable>
<neon-animatable id="manage-certificates">
<settings-subheader i18n-values="page-title:manageCertificates">
</settings-subheader>
- <cr-settings-certificate-manager-page>
- </cr-settings-certificate-manager-page>
+ <settings-certificate-manager-page>
+ </settings-certificate-manager-page>
</neon-animatable>
<neon-animatable id="site-settings">
<settings-subheader i18n-values="page-title:siteSettings">
</settings-subheader>
- <cr-settings-site-settings-page></cr-settings-site-settings-page>
+ <settings-site-settings-page current-route="{{currentRoute}}"
+ prefs="{{prefs}}">
+ </settings-site-settings-page>
+ </neon-animatable>
+
+ <neon-animatable id="site-settings-category-camera">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.CAMERA}}">
+ </site-settings-category>
+ </neon-animatable>
+ <neon-animatable id="site-settings-category-cookies">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.COOKIES}}">
+ </site-settings-category>
+ </neon-animatable>
+ <neon-animatable id="site-settings-category-fullscreen">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.FULLSCREEN}}">
+ </site-settings-category>
+ </neon-animatable>
+ <neon-animatable id="site-settings-category-images">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.IMAGES}}">
+ </site-settings-category>
+ </neon-animatable>
+ <neon-animatable id="site-settings-category-location">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.GEOLOCATION}}">
+ </site-settings-category>
+ </neon-animatable>
+ <neon-animatable id="site-settings-category-javascript">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.JAVASCRIPT}}">
+ </site-settings-category>
+ </neon-animatable>
+ <neon-animatable id="site-settings-category-microphone">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.MIC}}">
+ </site-settings-category>
+ </neon-animatable>
+ <neon-animatable id="site-settings-category-notifications">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.NOTIFICATIONS}}">
+ </site-settings-category>
+ </neon-animatable>
+ <neon-animatable id="site-settings-category-popups">
+ <settings-subheader i18n-values="page-title:siteSettings">
+ </settings-subheader>
+ <site-settings-category
+ selected-origin="{{originSelected}}" prefs="{{prefs}}"
+ current-route="{{currentRoute}}"
+ category="{{ContentSettingsTypes.POPUPS}}">
+ </site-settings-category>
+ </neon-animatable>
+
+ <neon-animatable id="site-details">
+ <site-details prefs="{{prefs}}" origin="{{originSelected}}">
+ </site-details>
</neon-animatable>
<neon-animatable id="clear-browsing-data">
<settings-subheader i18n-values="page-title:clearBrowsingData">
</settings-subheader>
- <cr-settings-clear-browsing-data-page prefs="{{prefs}}">
- </cr-settings-clear-browsing-data-page>
+ <settings-clear-browsing-data-page prefs="{{prefs}}">
+ </settings-clear-browsing-data-page>
</neon-animatable>
</settings-animated-pages>
</template>
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 a6082766703..d5b122bf99c 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -4,22 +4,22 @@
/**
* @fileoverview
- * 'cr-settings-privacy-page' is the settings page containing privacy and
+ * 'settings-privacy-page' is the settings page containing privacy and
* security settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-privacy-page prefs="{{prefs}}">
- * </cr-settings-privacy-page>
+ * <settings-privacy-page prefs="{{prefs}}">
+ * </settings-privacy-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-privacy-page
+ * @element settings-privacy-page
*/
Polymer({
- is: 'cr-settings-privacy-page',
+ is: 'settings-privacy-page',
properties: {
/**
@@ -37,6 +37,18 @@ Polymer({
type: Object,
notify: true,
},
+
+ /**
+ * The origin selected by the user.
+ */
+ originSelected: {
+ type: String,
+ observer: 'onSelectedOriginChanged_',
+ }
+ },
+
+ ready: function() {
+ this.ContentSettingsTypes = settings.ContentSettingsTypes;
},
/** @private */
@@ -53,4 +65,9 @@ Polymer({
onClearBrowsingDataTap_: function() {
this.$.pages.setSubpageChain(['clear-browsing-data']);
},
+
+ onSelectedOriginChanged_: function() {
+ this.$.pages.setSubpageChain(
+ ['site-settings', 'site-settings-category', 'site-details']);
+ },
});
diff --git a/chromium/chrome/browser/resources/settings/radio_group/radio_group.js b/chromium/chrome/browser/resources/settings/radio_group/radio_group.js
deleted file mode 100644
index 0711680e343..00000000000
--- a/chromium/chrome/browser/resources/settings/radio_group/radio_group.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview
- * `cr-radio-group` wraps a radio-group and set of radio-buttons that control
- * a supplied preference.
- *
- * Example:
- * <cr-settings-radio-group pref="{{prefs.settings.foo}}"
- * label="Foo Options." buttons="{{fooOptionsList}}">
- * </cr-settings-radio-group>
- *
- * @element cr-settings-radio-group
- */
-Polymer({
- is: 'cr-settings-radio-group',
-
- properties: {
- /**
- * The preference object to control.
- * @type {chrome.settingsPrivate.PrefObject|undefined}
- */
- pref: {
- type: Object,
- notify: true,
- observer: 'prefChanged_'
- },
-
- /**
- * IronSelectableBehavior selected attribute
- */
- selected: {
- type: String,
- observer: 'selectedChanged_'
- },
- },
-
- /** @private */
- prefChanged_: function() {
- if (!this.pref)
- return;
- if (this.pref.type == chrome.settingsPrivate.PrefType.NUMBER ||
- this.pref.type == chrome.settingsPrivate.PrefType.BOOLEAN) {
- this.selected = this.pref.value.toString();
- } else {
- assert(this.pref.type != chrome.settingsPrivate.PrefType.LIST);
- this.selected = /** @type {string} */(this.pref.value);
- }
- },
-
- /** @private */
- selectedChanged_: function() {
- if (!this.pref)
- return;
- if (this.pref.type == chrome.settingsPrivate.PrefType.NUMBER) {
- var n = parseInt(this.selected, 10);
- if (isNaN(n)) {
- console.error('Bad selected name for numerical pref: ' + this.selected);
- return;
- }
- this.set('pref.value', n);
- } else if (this.pref.type == chrome.settingsPrivate.PrefType.BOOLEAN) {
- this.set('pref.value', this.selected == 'true');
- } else {
- assert(this.pref.type != chrome.settingsPrivate.PrefType.LIST);
- this.set('pref.value', this.selected);
- }
- },
-});
diff --git a/chromium/chrome/browser/resources/settings/reset_page/powerwash_dialog.html b/chromium/chrome/browser/resources/settings/reset_page/powerwash_dialog.html
new file mode 100644
index 00000000000..82b07e550ac
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/powerwash_dialog.html
@@ -0,0 +1,37 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+
+<dom-module id="settings-powerwash-dialog">
+ <link rel="import" type="css" href="chrome://md-settings/settings_dialog.css">
+ <link rel="import" type="css" href="reset_page_dialog.css">
+ <template>
+ <paper-dialog modal id="dialog">
+ <div id="dialog-content">
+ <div class="top-row">
+ <span class="title" i18n-content="powerwashDialogTitle"></span>
+ <paper-icon-button icon="clear" on-tap="onCancelTap_" id="close">
+ </paper-icon-button>
+ </div>
+ <div class="body">
+ <div class="explanation">
+ <span i18n-content="powerwashDialogExplanation"></span>
+ <a i18n-values="href:powerwashLearnMoreUrl"
+ i18n-content="learnMore" target="_blank"></a>
+ </div>
+ <div class="button-container">
+ <paper-button class="cancel-button" on-tap="onCancelTap_"
+ id="cancel" i18n-content="cancel"></paper-button>
+ <paper-button class="action-button" id="powerwash"
+ on-tap="onRestartTap_" i18n-content="powerwashDialogButton">
+ </paper-button>
+ </div>
+ </div>
+ </div>
+ </paper-dialog>
+ </template>
+ <script src="powerwash_dialog.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/reset_page/powerwash_dialog.js b/chromium/chrome/browser/resources/settings/reset_page/powerwash_dialog.js
new file mode 100644
index 00000000000..b55bd9e0cb8
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/powerwash_dialog.js
@@ -0,0 +1,30 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-reset-page' is the settings page containing reset
+ * settings.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-reset-page
+ */
+Polymer({
+ is: 'settings-powerwash-dialog',
+
+ open: function() {
+ chrome.send('onPowerwashDialogShow');
+ this.$.dialog.open();
+ },
+
+ /** @private */
+ onCancelTap_: function() {
+ this.$.dialog.close();
+ },
+
+ /** @private */
+ onRestartTap_: function() {
+ chrome.send('requestFactoryResetRestart');
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/reset_page/reset_page.html b/chromium/chrome/browser/resources/settings/reset_page/reset_page.html
new file mode 100644
index 00000000000..ac6b8147ef4
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_page.html
@@ -0,0 +1,26 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://md-settings/reset_page/reset_profile_dialog.html">
+
+<if expr="chromeos">
+<link rel="import" href="chrome://md-settings/reset_page/powerwash_dialog.html">
+</if>
+
+<dom-module id="settings-reset-page">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <template>
+ <div class="settings-box" id="resetProfile"
+ on-tap="onShowResetProfileDialog_">
+ <div i18n-content="resetPageTitle"></div>
+ <div i18n-content="resetPageDescription"></div>
+ </div>
+<if expr="chromeos">
+ <div class="settings-box" id="powerwash" on-tap="onShowPowerwashDialog_"
+ hidden="[[!allowPowerwash_]]">
+ <div i18n-content="powerwashTitle"></div>
+ <div i18n-content="powerwashDescription"></div>
+ </div>
+</if>
+ </template>
+ <script src="chrome://md-settings/reset_page/reset_page.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/reset_page/reset_page.js b/chromium/chrome/browser/resources/settings/reset_page/reset_page.js
new file mode 100644
index 00000000000..81a02423511
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_page.js
@@ -0,0 +1,56 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-reset-page' is the settings page containing reset
+ * settings.
+ *
+ * Example:
+ *
+ * <iron-animated-pages>
+ * <settings-reset-page prefs="{{prefs}}">
+ * </settings-reset-page>
+ * ... other pages ...
+ * </iron-animated-pages>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-reset-page
+ */
+Polymer({
+ is: 'settings-reset-page',
+
+ properties: {
+ allowPowerwash_: {
+ type: Boolean,
+ value: cr.isChromeOS ? loadTimeData.getBoolean('allowPowerwash') : false
+ },
+ },
+
+ /** @private */
+ onShowResetProfileDialog_: function() {
+ this.showDialog_('settings-reset-profile-dialog');
+ },
+
+ /** @private */
+ onShowPowerwashDialog_: function() {
+ this.showDialog_('settings-powerwash-dialog');
+ },
+
+
+ /**
+ * Creates and shows the specified dialog.
+ * @param {string} dialogName
+ * @private
+ */
+ showDialog_: function(dialogName) {
+ var dialog = document.createElement(dialogName);
+ this.shadowRoot.appendChild(dialog);
+ dialog.open();
+
+ dialog.addEventListener('iron-overlay-closed', function() {
+ dialog.remove();
+ });
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary.css b/chromium/chrome/browser/resources/settings/reset_page/reset_page_dialog.css
index 8ef22124226..43afe64d8d9 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_summary.css
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_page_dialog.css
@@ -2,6 +2,11 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#summary {
- padding-right: 40px;
+paper-button {
+ margin: 0;
+}
+
+a {
+ color: rgb(66, 133, 244);
+ text-decoration: none;
}
diff --git a/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.css b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.css
new file mode 100644
index 00000000000..dd6a4c2b345
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.css
@@ -0,0 +1,42 @@
+/* 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. */
+
+#banner-content {
+ background-color: white;
+ border: 1px solid #c8c8c8;
+ border-radius: 3px;
+ margin-bottom: 24px;
+}
+
+#top-row {
+ display: flex;
+ justify-content: flex-end;
+}
+
+#main-body {
+ align-items: center;
+ display: flex;
+ padding: 0 17px 17px;
+}
+
+#description {
+ -webkit-margin-start: 18px;
+ flex: 1;
+}
+
+#close {
+ height: 30px;
+}
+
+#reset {
+ -webkit-margin-start: 30px;
+ background-color: rgb(66, 133, 244);
+ color: white;
+ font-weight: 500;
+}
+
+a {
+ color: rgb(66, 133, 244);
+ text-decoration: none;
+}
diff --git a/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.html b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.html
new file mode 100644
index 00000000000..688144490a6
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.html
@@ -0,0 +1,31 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://md-settings/reset_page/reset_profile_dialog.html">
+
+<dom-module id="settings-reset-profile-banner">
+ <link rel="import" type="css" href="reset_profile_banner.css">
+ <template>
+ <div id="banner-content">
+ <div id="top-row">
+ <paper-icon-button icon="clear" on-tap="onCloseTap_" id="close">
+ </paper-icon-button>
+ </div>
+ <div id="main-body">
+ <span id="description">
+ <span i18n-content="resetProfileBannerDescription"></span>
+ <a id="learnMore"
+ i18n-values="href:resetProfileBannerLearnMoreUrl"
+ i18n-content="learnMore" target="_blank"></a>
+ </span>
+ <paper-button id="reset" on-tap="showDialog_"
+ i18n-content="resetProfileBannerButton"></paper-button>
+ </div>
+ </div>
+ <template is="dom-if" if="[[showResetProfileDialog_]]">
+ <settings-reset-profile-dialog on-reset-done="onResetDone_">
+ </settings-reset-profile-dialog>
+ </template>
+ </template>
+ <script src="reset_profile_banner.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.js b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.js
new file mode 100644
index 00000000000..549496c8670
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_banner.js
@@ -0,0 +1,44 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-reset-profile-banner' is the banner shown for clearing profile
+ * settings.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-reset-profile-banner
+ */
+Polymer({
+ is: 'settings-reset-profile-banner',
+
+ properties: {
+ showResetProfileDialog_: {
+ type: Boolean,
+ value: false,
+ },
+ },
+
+ /** @private */
+ onCloseTap_: function() {
+ chrome.send('onHideResetProfileBanner');
+ this.remove();
+ },
+
+ /**
+ * Creates and shows a <settings-reset-profile-dialog>.
+ * @private
+ */
+ showDialog_: function(dialogName) {
+ this.showResetProfileDialog_ = true;
+ this.async(function() {
+ var dialog = this.$$('settings-reset-profile-dialog');
+ dialog.open();
+ }.bind(this));
+ },
+
+ onResetDone_: function() {
+ this.showResetProfileDialog_ = false;
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.css b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.css
new file mode 100644
index 00000000000..805be9c671c
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.css
@@ -0,0 +1,14 @@
+/* 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. */
+
+#dialog {
+ min-width; 300px;
+ width: 500px;
+}
+
+#feedbackBar {
+ background-color: rgb(236, 236, 236);
+ margin: 0;
+ padding: 20px;
+}
diff --git a/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
new file mode 100644
index 00000000000..9be9d87a44f
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
@@ -0,0 +1,48 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html">
+
+<dom-module id="settings-reset-profile-dialog">
+ <link rel="import" type="css" href="chrome://md-settings/settings_dialog.css">
+ <link rel="import" type="css" href="reset_page_dialog.css">
+ <link rel="import" type="css" href="reset_profile_dialog.css">
+ <template>
+ <paper-dialog modal id="dialog">
+ <div id="dialog-content">
+ <div class="top-row">
+ <span class="title" i18n-content="resetPageTitle"></span>
+ <paper-icon-button icon="clear" on-tap="onCancelTap_" id="close">
+ </paper-icon-button>
+ </div>
+ <div class="body">
+ <div class="explanation">
+ <span i18n-content="resetPageExplanation"></span>
+ <a i18n-values="href:resetPageLearnMoreUrl"
+ i18n-content="learnMore" target="_blank"></a>
+ </div>
+ <div class="button-container">
+ <paper-spinner id="resetSpinner"></paper-spinner>
+ <paper-button class="cancel-button" on-tap="onCancelTap_"
+ id="cancel" i18n-content="cancel"></paper-button>
+ <paper-button class="action-button" i18n-content="resetPageCommit"
+ on-tap="onResetTap_" id="reset"></paper-button>
+ </div>
+ </div>
+ </div>
+ <div id="feedbackBar">
+ <paper-checkbox id="sendSettings" i18n-content="resetPageFeedback"
+ checked on-change="onSendSettingsChange_"></paper-checkbox>
+ <div id="settings">
+ <template is="dom-repeat" items="[[feedbackInfo_]]">
+ <div><span>[[item.key]]</span>: <span>[[item.value]]</span></div>
+ </template>
+ </div>
+ </div>
+ </paper-dialog>
+ </template>
+ <script src="reset_profile_dialog.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
new file mode 100644
index 00000000000..b639054e66c
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
@@ -0,0 +1,67 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-reset-profile-dialog' is the dialog shown for clearing profile
+ * settings.
+ *
+ * @group Chrome Settings Elements
+ * @element settings-reset-profile-dialog
+ */
+Polymer({
+ is: 'settings-reset-profile-dialog',
+
+ properties: {
+ feedbackInfo_: String,
+ },
+
+ attached: function() {
+ cr.define('SettingsResetPage', function() {
+ return {
+ doneResetting: function() {
+ this.$.resetSpinner.active = false;
+ this.$.dialog.close();
+ this.dispatchResetDoneEvent();
+ }.bind(this),
+
+ setFeedbackInfo: function(data) {
+ this.set('feedbackInfo_', data.feedbackInfo);
+ this.async(function() {
+ this.$.dialog.center();
+ });
+ }.bind(this),
+ };
+ }.bind(this));
+ },
+
+ dispatchResetDoneEvent: function() {
+ this.dispatchEvent(new CustomEvent('reset-done'));
+ },
+
+ open: function() {
+ this.$.dialog.open();
+ chrome.send('onShowResetProfileDialog');
+ },
+
+ /** @private */
+ onCancelTap_: function() {
+ this.$.dialog.close();
+ chrome.send('onHideResetProfileDialog');
+ },
+
+ /** @private */
+ onResetTap_: function() {
+ this.$.resetSpinner.active = true;
+ chrome.send('performResetProfileSettings', [this.$.sendSettings.checked]);
+ },
+
+ /** @private */
+ onSendSettingsChange_: function() {
+ // TODO(dpapad): Update how settings info is surfaced when final mocks
+ // exist.
+ this.$.settings.hidden = !this.$.sendSettings.checked;
+ this.$.dialog.center();
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.css b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.css
index b4cb0bb3c50..dd0a80165de 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.css
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.css
@@ -8,11 +8,6 @@
.container {
margin-top: 14px;
- width: 660px;
-}
-
-.add-label {
- width: 660px;
}
.input-field {
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.html b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.html
index 89f5e0b044d..1db68ba5304 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.html
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.html
@@ -1,43 +1,45 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://resources/cr_elements/v1_0/cr_collapse/cr_collapse.html">
<dom-module id="cr-search-engine-adder">
<link rel="import" type="css" href="search_engine_adder.css">
<template>
- <div class="add-label layout horizontal center justified">
+ <div class="layout horizontal center justified">
<span i18n-content="searchEnginesAddSearchEngineLabel"></span>
<cr-expand-button expanded="{{opened}}"></cr-expand-button>
</div>
- <cr-collapse opened="{{opened}}">
- <div class="container layout horizontal">
- <div class="input-field flex two">
- <div class="input-label" i18n-content="searchEnginesDomainLabel">
+ <iron-collapse opened="{{opened}}">
+ <div class="settings-box">
+ <div class="container layout horizontal">
+ <div class="input-field flex two">
+ <div class="input-label" i18n-content="searchEnginesDomainLabel">
+ </div>
+ <paper-input id="domainField" auto-validate="false" required>
+ </paper-input>
</div>
- <paper-input id="domainField" auto-validate="false" required>
- </paper-input>
- </div>
- <div class="input-field flex two">
- <div class="input-label" i18n-content="searchEnginesKeywordLabel">
+ <div class="input-field flex two">
+ <div class="input-label" i18n-content="searchEnginesKeywordLabel">
+ </div>
+ <paper-input id="keywordField" auto-validate="false" required>
+ </paper-input>
</div>
- <paper-input id="keywordField" auto-validate="false" required>
- </paper-input>
- </div>
- <div class="input-field flex four">
- <div class="input-label" i18n-content="searchEnginesQueryURLLabel">
+ <div class="input-field flex four">
+ <div class="input-label" i18n-content="searchEnginesQueryURLLabel">
+ </div>
+ <paper-input id="queryURLField" auto-validate="false" required>
+ </paper-input>
+ </div>
+ <div class="layout horizontal center">
+ <paper-button i18n-content="searchEnginesAddButtonLabel"
+ on-tap="add_" raised>
+ </paper-button>
</div>
- <paper-input id="queryURLField" auto-validate="false" required>
- </paper-input>
- </div>
- <div class="layout horizontal center">
- <paper-button i18n-content="searchEnginesAddButtonLabel"
- on-click="{{add_}}" raised>
- </paper-button>
</div>
</div>
- </cr-collapse>
+ </iron-collapse>
</template>
<script src="search_engine_adder.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js
index 080a2dedc5f..927912e5c44 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js
@@ -7,7 +7,7 @@
* engine.
*
* @group Chrome Settings Elements
- * @element cr-settings-search-engine-adder
+ * @element settings-search-engine-adder
*/
Polymer({
is: 'cr-search-engine-adder',
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.css b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.css
index df0f31c5efb..0d207edc4e0 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.css
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.css
@@ -4,26 +4,16 @@
.icons {
display: inline-block;
- text-align: right;
- width: 96px;
}
.inputs {
- display: inline-block;
-}
-
-.inputs > paper-input {
- border-bottom: 1px solid gray;
-}
-
-.inputs > paper-input:not(:last-child) {
- border-right: 1px solid gray;
+ display: flex;
}
.narrow-input {
- width: 140px;
+ flex: 1;
}
.wide-input {
- width: 300px;
+ flex: 3;
}
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 a7b074458b6..77f262e2468 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
@@ -21,11 +21,11 @@
</paper-input>
</div>
<div class="icons">
- <iron-icon id="checkIcon" icon="check" on-click="makeDefault_" hidden>
+ <iron-icon icon="settings" on-tap="toggleEditable_"></iron-icon>
+ <iron-icon id="checkIcon" icon="check" on-tap="makeDefault_">
</iron-icon>
- <iron-icon id="deleteIcon" icon="clear" on-click="deleteEngine_" hidden>
+ <iron-icon id="deleteIcon" icon="clear" on-tap="deleteEngine_">
</iron-icon>
- <iron-icon icon="settings" on-click="toggleEditable_"></iron-icon>
</div>
</div>
</template>
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.css b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.css
index 94131eaa6ab..54ed7d6e995 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.css
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.css
@@ -4,20 +4,22 @@
.container {
max-height: 400px;
- overflow-y: auto;
- width: 760px;
+}
+
+.headers {
+ display: flex;
}
.headers > div {
background-color: #6c6c6c;
color: white;
- display: inline-block;
+ padding: 5px;
}
.narrow-label {
- width: 140px;
+ flex: 1;
}
.wide-label {
- width: 300px;
+ flex: 3;
}
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
index 58f097dd0a5..184dd5b5dca 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
@@ -2,10 +2,10 @@
<link rel="import" href="search_engine_adder.html">
<link rel="import" href="search_engines_list.html">
-<dom-module id="cr-settings-search-engines-page">
- <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css">
+<dom-module id="settings-search-engines-page">
+ <link rel="import" type="css" href="chrome://md-settings/settings_shared.css">
<template>
- <div class="content">
+ <div class="settings-box">
<cr-search-engine-adder></cr-search-engine-adder>
<h2 i18n-content="searchEnginesLabel"></h2>
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js
index abd6bac3f4e..9aeb8599072 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js
@@ -3,22 +3,22 @@
// found in the LICENSE file.
/**
- * @fileoverview 'cr-settings-search-engines-page' is the settings page
+ * @fileoverview 'settings-search-engines-page' is the settings page
* containing search engines settings.
*
* Example:
*
* <core-animated-pages>
- * <cr-settings-search-engines-page prefs="{{prefs}}">
- * </cr-settings-search-engines-page>
+ * <settings-search-engines-page prefs="{{prefs}}">
+ * </settings-search-engines-page>
* ... other pages ...
* </core-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-search-engines-page
+ * @element settings-search-engines-page
*/
Polymer({
- is: 'cr-settings-search-engines-page',
+ is: 'settings-search-engines-page',
properties: {
/** @type {!Array<!SearchEngine>} */
diff --git a/chromium/chrome/browser/resources/settings/search_page/search_page.css b/chromium/chrome/browser/resources/settings/search_page/search_page.css
index 95ba730867b..24b3126fbef 100644
--- a/chromium/chrome/browser/resources/settings/search_page/search_page.css
+++ b/chromium/chrome/browser/resources/settings/search_page/search_page.css
@@ -2,20 +2,10 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-.manage-search-engines {
- -webkit-margin-start: 10px;
-}
-
paper-button.search-engines-advanced {
margin-top: 10px;
}
-paper-button.search-engines {
- align-items: center;
- display: flex;
- margin-top: 20px;
-}
-
#searchEnginesMenu {
min-width: 150px;
}
diff --git a/chromium/chrome/browser/resources/settings/search_page/search_page.html b/chromium/chrome/browser/resources/settings/search_page/search_page.html
index ee412ac9af8..a51296f369a 100644
--- a/chromium/chrome/browser/resources/settings/search_page/search_page.html
+++ b/chromium/chrome/browser/resources/settings/search_page/search_page.html
@@ -1,48 +1,39 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
+<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
<link rel="import" href="chrome://md-settings/search_engines_page/search_engines_page.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
<link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html">
-<dom-module id="cr-settings-search-page">
+<dom-module id="settings-search-page">
<link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
+ href="chrome://md-settings/settings_shared.css">
<link rel="import" type="css" href="search_page.css">
<template>
<settings-animated-pages id="pages" current-route="{{currentRoute}}"
section="search">
- <neon-animatable id="">
- <p i18n-content="searchExplanation"></p>
-
- <div class="search-engines">
- <select id="searchEnginesMenu" on-change="defaultEngineGuidChanged_">
+ <neon-animatable id="main">
+ <div class="settings-box split">
+ <p class="start" i18n-content="searchExplanation"></p>
+ <select id="searchEnginesMenu"
+ on-change="defaultEngineGuidChanged_">
<template is="dom-repeat" items="[[searchEngines]]">
- <option value="[[item.guid]]">{{item.name}}</option>
+ <option value="[[item.guid]]">[[item.name]]</option>
</template>
</select>
-
- <paper-button class="search-engines"
+ </div>
+ <div class="settings-box">
+ <paper-button class="link-button"
i18n-content="searchManageButtonLabel"
- on-tap="onSearchEnginesTap_" raised>
+ on-tap="onSearchEnginesTap_">
</paper-button>
</div>
</neon-animatable>
<neon-animatable id="search-engines">
<settings-subheader i18n-values="page-title:searchEnginesLabel">
</settings-subheader>
- <cr-settings-search-engines-page></cr-settings-search-engines-page>
- <paper-button class="search-engines-advanced"
- i18n-content="advancedPageTitle"
- on-tap="onSearchEnginesAdvancedTap_" raised>
- </paper-button>
- </neon-animatable>
- <neon-animatable id="search-engines-advanced">
- <!-- This sub-subpage is purely a placeholder to provide an example. -->
- <settings-subheader i18n-values="page-title:searchEnginesLabel">
- </settings-subheader>
- <p i18n-content="searchExplanation"></p>
+ <settings-search-engines-page></settings-search-engines-page>
</neon-animatable>
</settings-animated-pages>
</template>
diff --git a/chromium/chrome/browser/resources/settings/search_page/search_page.js b/chromium/chrome/browser/resources/settings/search_page/search_page.js
index 34983d08ada..0f8b3cbad16 100644
--- a/chromium/chrome/browser/resources/settings/search_page/search_page.js
+++ b/chromium/chrome/browser/resources/settings/search_page/search_page.js
@@ -4,20 +4,20 @@
/**
* @fileoverview
- * 'cr-settings-search-page' is the settings page containing search settings.
+ * 'settings-search-page' is the settings page containing search settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-search-page prefs="{{prefs}}"></cr-settings-search-page>
+ * <settings-search-page prefs="{{prefs}}"></settings-search-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-search-page
+ * @element settings-search-page
*/
Polymer({
- is: 'cr-settings-search-page',
+ is: 'settings-search-page',
properties: {
/**
@@ -82,9 +82,4 @@ Polymer({
onSearchEnginesTap_: function() {
this.$.pages.setSubpageChain(['search-engines']);
},
-
- /** @private */
- onSearchEnginesAdvancedTap_: function() {
- this.$.pages.setSubpageChain(['search-engines', 'search-engines-advanced']);
- },
});
diff --git a/chromium/chrome/browser/resources/settings/settings.html b/chromium/chrome/browser/resources/settings/settings.html
index 231b3d94e89..c3cdadf9704 100644
--- a/chromium/chrome/browser/resources/settings/settings.html
+++ b/chromium/chrome/browser/resources/settings/settings.html
@@ -4,9 +4,8 @@
<meta charset="utf-8">
<title>Settings</title>
<base href="chrome://md-settings">
- <script src="chrome://resources/js/polymer_config.js"></script>
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://md-settings/strings.js"></script>
+ <link rel="import" href="chrome://resources/html/polymer_config.html">
+ <link rel="import" href="chrome://md-settings/i18n_setup.html">
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://md-settings/settings_ui/settings_ui.html">
<link rel="import" href="chrome://md-settings/prefs/prefs.html">
@@ -15,8 +14,8 @@
<dom-module id="cr-settings">
<template>
- <cr-settings-prefs id="prefs" prefs="{{prefs_}}"></cr-settings-prefs>
- <cr-settings-ui prefs="{{prefs_}}"></cr-settings-ui>
+ <settings-prefs id="prefs" prefs="{{prefs_}}"></settings-prefs>
+ <settings-ui prefs="{{prefs_}}"></settings-ui>
</template>
<script src="settings.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/settings_dialog.css b/chromium/chrome/browser/resources/settings/settings_dialog.css
new file mode 100644
index 00000000000..786f04c198d
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/settings_dialog.css
@@ -0,0 +1,69 @@
+/* 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. */
+
+/**
+ * @fileoverview
+ * Common dialog styles for Material Design settings.
+ */
+
+#dialog-content {
+ -webkit-padding-end: 0;
+ -webkit-padding-start: 0;
+ margin-bottom: 0;
+ margin-top: 0;
+}
+
+paper-dialog .top-row {
+ align-items: center;
+ border-bottom: 1px solid gainsboro;
+ display: flex;
+ padding-bottom: 5px;
+ padding-top: 5px;
+}
+
+paper-dialog .title {
+ flex: 1;
+ font-size: 1.13em;
+}
+
+paper-dialog .body {
+ font-size: 1em;
+ margin: 20px 0;
+}
+
+paper-dialog .title,
+paper-dialog .body {
+ -webkit-padding-end: 24px;
+ -webkit-padding-start: 24px;
+}
+
+paper-dialog .action-button {
+ -webkit-margin-start: 10px;
+ background-color: rgb(66, 133, 244);
+ color: white;
+ font-weight: 500;
+}
+
+paper-dialog .cancel-button {
+ color: rgb(109, 109, 109);
+ font-weight: 500;
+}
+
+paper-dialog .explanation {
+ margin-bottom: 35px;
+}
+
+paper-dialog .button-container {
+ display: flex;
+ justify-content: flex-end;
+}
+
+paper-dialog paper-button {
+ margin: 0;
+ min-width: auto;
+}
+
+paper-dialog paper-button[toggles][active] {
+ background-color: LightGray;
+}
diff --git a/chromium/chrome/browser/resources/settings/settings_main/settings_main.html b/chromium/chrome/browser/resources/settings/settings_main/settings_main.html
index cc17ba24b82..2b8eac5d366 100644
--- a/chromium/chrome/browser/resources/settings/settings_main/settings_main.html
+++ b/chromium/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -1,21 +1,22 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
<link rel="import" href="chrome://md-settings/advanced_page/advanced_page.html">
<link rel="import" href="chrome://md-settings/basic_page/basic_page.html">
-<dom-module id="cr-settings-main">
+<dom-module id="settings-main">
<link rel="import" type="css" href="settings_main.css">
<template>
<content select="paper-icon-button"></content>
- <iron-pages id="pageContainer" attr-for-selected="data-route-page"
- selected="[[getSelectedPage_(currentRoute)]]">
- <cr-settings-basic-page data-route-page="basic" prefs="{{prefs}}"
- current-route="{{currentRoute}}">
- </cr-settings-basic-page>
- <cr-settings-advanced-page data-route-page="advanced" prefs="{{prefs}}"
- current-route="{{currentRoute}}">
- </cr-settings-advanced-page>
- </iron-pages>
+ <div id="pageContainer">
+ <template is="dom-if" if="[[!showAdvancedPage_]]">
+ <settings-basic-page prefs="{{prefs}}" current-route="{{currentRoute}}">
+ </settings-basic-page>
+ </template>
+ <template is="dom-if" if="[[showAdvancedPage_]]">
+ <settings-advanced-page prefs="{{prefs}}"
+ current-route="{{currentRoute}}">
+ </settings-advanced-page>
+ </template>
+ </div>
</template>
<script src="settings_main.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/settings_main/settings_main.js b/chromium/chrome/browser/resources/settings/settings_main/settings_main.js
index 77bd76134d4..f683d4799e3 100644
--- a/chromium/chrome/browser/resources/settings/settings_main/settings_main.js
+++ b/chromium/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -4,20 +4,20 @@
/**
* @fileoverview
- * 'cr-settings-main' displays the selected settings page.
+ * 'settings-main' displays the selected settings page.
*
* Example:
*
- * <cr-settings-main pages="[[pages]]" selected-page-id="{{selectedId}}">
- * </cr-settings-main>
+ * <settings-main pages="[[pages]]" selected-page-id="{{selectedId}}">
+ * </settings-main>
*
- * See cr-settings-drawer for example of use in 'paper-drawer-panel'.
+ * See settings-drawer for example of use in 'paper-drawer-panel'.
*
* @group Chrome Settings Elements
- * @element cr-settings-main
+ * @element settings-main
*/
Polymer({
- is: 'cr-settings-main',
+ is: 'settings-main',
properties: {
/**
@@ -38,6 +38,12 @@ Polymer({
notify: true,
observer: 'currentRouteChanged_',
},
+
+ // If false the 'basic' page should be shown.
+ showAdvancedPage_: {
+ type: Boolean,
+ value: false
+ }
},
listeners: {
@@ -46,6 +52,8 @@ Polymer({
/** @private */
currentRouteChanged_: function(newRoute, oldRoute) {
+ this.showAdvancedPage_ = newRoute.page == 'advanced';
+
var pageContainer = this.$.pageContainer;
if (!oldRoute) {
pageContainer.classList.toggle('expanded', newRoute.section);
@@ -69,9 +77,4 @@ Polymer({
pageContainer.scrollTop = 0;
}
},
-
- /** @private */
- getSelectedPage_: function(currentRoute) {
- return currentRoute.page || 'basic';
- },
});
diff --git a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.css b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.css
index 6667a3e5b32..598ff641a60 100644
--- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.css
+++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.css
@@ -1,3 +1,8 @@
/* 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. */
+
+paper-menu {
+ background-color: transparent;
+ color: #5a5a5a;
+}
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 9185c25b7b6..d615b8e6309 100644
--- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html
+++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -1,7 +1,9 @@
<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/hardware-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/notification-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/social-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-icon-item.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-submenu.html">
@@ -10,7 +12,7 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html">
</if>
-<dom-module id="cr-settings-menu">
+<dom-module id="settings-menu">
<link rel="import" type="css" href="settings_menu.css">
<template>
<paper-menu name="root-menu">
@@ -27,6 +29,10 @@
</paper-icon-item>
</if>
<paper-icon-item>
+ <iron-icon icon="social:person" item-icon></iron-icon>
+ <span i18n-content="peoplePageTitle"></span>
+ </paper-icon-item>
+ <paper-icon-item>
<iron-icon icon="home" item-icon></iron-icon>
<span i18n-content="appearancePageTitle"></span>
</paper-icon-item>
@@ -38,10 +44,10 @@
<iron-icon icon="search" item-icon></iron-icon>
<span i18n-content="searchPageTitle"></span>
</paper-icon-item>
-<if expr="chromeos">
+<if expr="not chromeos">
<paper-icon-item>
- <iron-icon icon="person" item-icon></iron-icon>
- <span i18n-content="usersPageTitle"></span>
+ <iron-icon icon="open-in-browser" item-icon></iron-icon>
+ <span i18n-content="defaultBrowser"></span>
</paper-icon-item>
</if>
</paper-menu>
@@ -52,6 +58,10 @@
<span i18n-content="advancedPageTitle"></span>
</paper-icon-item>
<paper-menu class="menu-content">
+ <paper-icon-item>
+ <iron-icon icon="communication:location-on" item-icon></iron-icon>
+ <span i18n-content="siteSettingsLocation"></span>
+ </paper-icon-item>
<if expr="chromeos">
<paper-icon-item>
<iron-icon icon="device:access-time" item-icon></iron-icon>
@@ -59,23 +69,37 @@
</paper-icon-item>
</if>
<paper-icon-item>
- <iron-icon icon="lock" item-icon></iron-icon>
+ <iron-icon icon="hardware:security" item-icon></iron-icon>
<span i18n-content="privacyPageTitle"></span>
</paper-icon-item>
+<if expr="chromeos">
+ <paper-icon-item>
+ <iron-icon icon="device:bluetooth" item-icon></iron-icon>
+ <span i18n-content="bluetoothPageTitle"></span>
+ </paper-icon-item>
+</if>
+ <paper-icon-item>
+ <iron-icon icon="lock" item-icon></iron-icon>
+ <span i18n-content="passwordsAndAutofillPageTitle"></span>
+ </paper-icon-item>
+ <paper-icon-item>
+ <iron-icon icon="language" item-icon></iron-icon>
+ <span i18n-content="languagesPageTitle"></span>
+ </paper-icon-item>
<paper-icon-item>
<iron-icon icon="file-download" item-icon></iron-icon>
<span i18n-content="downloadsPageTitle"></span>
</paper-icon-item>
+ <paper-icon-item>
+ <iron-icon icon="settings-backup-restore" item-icon></iron-icon>
+ <span i18n-content="resetPageTitle"></span>
+ </paper-icon-item>
<if expr="chromeos">
<paper-icon-item>
<iron-icon icon="accessibility" item-icon></iron-icon>
<span i18n-content="a11yPageTitle"></span>
</paper-icon-item>
</if>
- <paper-icon-item>
- <iron-icon icon="notification:sync" item-icon></iron-icon>
- <span i18n-content="syncPageTitle"></span>
- </paper-icon-item>
</paper-menu>
</paper-submenu>
</paper-menu>
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 73a4f5b6831..9c873a1999e 100644
--- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js
+++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js
@@ -4,18 +4,18 @@
/**
* @fileoverview
- * 'cr-settings-menu' shows a menu with a hardcoded set of pages and subpages.
+ * 'settings-menu' shows a menu with a hardcoded set of pages and subpages.
*
* Example:
*
- * <cr-settings-menu selected-page-id="{{selectedPageId}}">
- * </cr-settings-menu>
+ * <settings-menu selected-page-id="{{selectedPageId}}">
+ * </settings-menu>
*
* @group Chrome Settings Elements
- * @element cr-settings-menu
+ * @element settings-menu
*/
Polymer({
- is: 'cr-settings-menu',
+ is: 'settings-menu',
properties: {
/**
diff --git a/chromium/chrome/browser/resources/settings/settings_page/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/settings_page/compiled_resources.gyp
new file mode 100644
index 00000000000..a36c51a8e14
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/settings_page/compiled_resources.gyp
@@ -0,0 +1,21 @@
+# 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.
+{
+ 'targets': [
+ {
+ 'target_name': 'settings_page_visibility',
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'settings_router',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ ],
+}
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_animated_pages.js b/chromium/chrome/browser/resources/settings/settings_page/settings_animated_pages.js
index e4c6e968ddc..27eb63401fe 100644
--- a/chromium/chrome/browser/resources/settings/settings_page/settings_animated_pages.js
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_animated_pages.js
@@ -10,7 +10,7 @@
* Example:
*
* <settings-animated-pages current-route="{{currentRoute}}"
- route-root="advanced/privacy" redirect-root-route-to="advanced">
+ * section="privacy">
* <!-- Insert your section controls here -->
* </settings-animated-pages>
*
@@ -34,6 +34,8 @@ Polymer({
* Routes with this section activate this element. For instance, if this
* property is 'search', and currentRoute.section is also set to 'search',
* this element will display the subpage in currentRoute.subpage.
+ *
+ * The section name must match the name specified in settings_router.js.
*/
section: {
type: String,
@@ -76,7 +78,7 @@ Polymer({
}
this.$.animatedPages.selected =
- newRouteIsSubpage ? newRoute.subpage.slice(-1)[0] : '';
+ newRouteIsSubpage ? newRoute.subpage.slice(-1)[0] : 'main';
},
/**
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_page.css b/chromium/chrome/browser/resources/settings/settings_page/settings_page.css
deleted file mode 100644
index 615b91d3e30..00000000000
--- a/chromium/chrome/browser/resources/settings/settings_page/settings_page.css
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-/**
- * @fileoverview
- * Common styles for Settings pages.
- */
-:host > paper-material {
- -webkit-padding-start: 80px;
- background-color: white;
- display: flex;
- flex-direction: column;
- padding: 40px;
-}
-
-.soft-border {
- border: 1px solid #c4c4c4;
- border-radius: 2px;
-}
-
-.page-content {
- width: 760px;
-}
-
-cr-settings-checkbox {
- -webkit-margin-end: 10px;
- -webkit-margin-start: 0;
- margin-bottom: 10px;
- margin-top: 10px;
-}
-
-paper-button {
- margin: 0;
- min-width: auto;
-}
-
-paper-button[toggles][active] {
- background-color: lightgrey;
-}
-
-h2 {
- color: #9e9e9e;
- font-weight: normal;
- font-size: 100%;
- margin-top: 30px;
- margin-bottom: 20px;
-}
-
-.item-list {
- @apply(--layout-vertical);
-}
-
-.item-list paper-item {
- border-bottom: 1px solid #e0e0e0;
- height: 40px; /* 24px + 2x8px padding. */
-}
-
-.item-list paper-item:last-of-type {
- border-bottom: none;
-}
-
-.item-list paper-item iron-icon {
- /* Same padding as paper-icon-button. */
- padding: 8px;
-}
-
-.button-strip {
- text-align: end;
-}
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_page_visibility.html b/chromium/chrome/browser/resources/settings/settings_page/settings_page_visibility.html
new file mode 100644
index 00000000000..8a40c5edd7b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_page_visibility.html
@@ -0,0 +1 @@
+<script src="settings_page_visibility.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_page_visibility.js b/chromium/chrome/browser/resources/settings/settings_page/settings_page_visibility.js
new file mode 100644
index 00000000000..660d8e17d8b
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_page_visibility.js
@@ -0,0 +1,49 @@
+// 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.
+
+/**
+ * @fileoverview
+ * Behavior controlling the visibility of Settings pages.
+ *
+ * Example:
+ * behaviors: [SettingsPageVisibility],
+ *
+ * @group Chrome UI Behavior
+ */
+
+/**
+ * Set this to true in tests before loading the page (e.g. in preLoad()) so that
+ * pages do not initially get created. Set this to false BEFORE modifying
+ * pageVisibility. NOTE: Changing this value after the DOM is loaded will not
+ * trigger a visibility change, pageVisibility must be modified to trigger data
+ * binding events.
+ * @type {boolean}
+ */
+var settingsHidePagesByDefaultForTest;
+
+/** @polymerBehavior */
+var SettingsPageVisibility = {
+ properties: {
+ /**
+ * Dictionary defining page visibility. If not set for a page, visibility
+ * will default to true, unless settingsHidePagesByDefaultForTest is set
+ * in which case visibility defaults to false.
+ * @type {Object<boolean>}
+ */
+ pageVisibility: {
+ type: Object,
+ value: function() { return {}; },
+ },
+ },
+
+ /**
+ * @param {boolean} visibility
+ * @return {boolean}
+ */
+ showPage: function(visibility) {
+ if (settingsHidePagesByDefaultForTest)
+ return visibility === true;
+ return visibility !== false;
+ },
+};
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_router.js b/chromium/chrome/browser/resources/settings/settings_page/settings_router.js
index 2c73b3e40ec..518f0721891 100644
--- a/chromium/chrome/browser/resources/settings/settings_page/settings_router.js
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_router.js
@@ -4,7 +4,7 @@
/**
* @fileoverview
- * 'settings-router' is a simple router for settings. Its responsibilites:
+ * 'settings-router' is a simple router for settings. Its responsibilities:
* - Update the URL when the routing state changes.
* - Initialize the routing state with the initial URL.
* - Process and validate all routing state changes.
@@ -66,7 +66,12 @@ Polymer({
currentRouteTitles: {
notify: true,
type: Object,
- value: function() { return {}; },
+ value: function() {
+ return {
+ pageTitle: '',
+ subpageTitles: [],
+ };
+ },
},
},
@@ -90,12 +95,28 @@ Polymer({
subpage: [],
subpageTitles: [],
},
+<if expr="chromeos">
+ {
+ url: '/networkDetail',
+ page: 'basic',
+ section: 'internet',
+ subpage: ['network-detail'],
+ subpageTitles: ['internetDetailPageTitle'],
+ },
+ {
+ url: '/knownNetworks',
+ page: 'basic',
+ section: 'internet',
+ subpage: ['known-networks'],
+ subpageTitles: ['internetKnownNetworksPageTitle'],
+ },
+</if>
{
- url: '/startup',
+ url: '/fonts',
page: 'basic',
- section: 'on-startup',
- subpage: ['startup-urls'],
- subpageTitles: ['onStartupSetPages'],
+ section: 'appearance',
+ subpage: ['appearance-fonts'],
+ subpageTitles: ['customizeFonts'],
},
{
url: '/searchEngines',
@@ -111,6 +132,40 @@ Polymer({
subpage: ['search-engines', 'search-engines-advanced'],
subpageTitles: ['searchEnginesPageTitle', 'advancedPageTitle'],
},
+<if expr="chromeos">
+ {
+ url: '/changePicture',
+ page: 'basic',
+ section: 'people',
+ subpage: ['changePicture'],
+ subpageTitles: ['changePictureTitle'],
+ },
+</if>
+<if expr="not chromeos">
+ {
+ url: '/manageProfile',
+ page: 'basic',
+ section: 'people',
+ subpage: ['manageProfile'],
+ subpageTitles: ['editPerson'],
+ },
+</if>
+ {
+ url: '/syncSetup',
+ page: 'basic',
+ section: 'people',
+ subpage: ['sync'],
+ subpageTitles: ['syncPageTitle'],
+ },
+<if expr="chromeos">
+ {
+ url: '/accounts',
+ page: 'basic',
+ section: 'people',
+ subpage: ['users'],
+ subpageTitles: ['usersPageTitle'],
+ },
+</if>
{
url: '/certificates',
page: 'advanced',
@@ -119,33 +174,107 @@ Polymer({
subpageTitles: ['manageCertificates'],
},
{
- url: '/content',
+ url: '/siteSettings',
page: 'advanced',
section: 'privacy',
subpage: ['site-settings'],
subpageTitles: ['siteSettings'],
},
{
+ url: '/siteSettings/category/camera',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-camera'],
+ subpageTitles: ['siteSettings', 'siteSettingsCamera'],
+ },
+ {
+ url: '/siteSettings/category/cookies',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-cookies'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryCookies'],
+ },
+ {
+ url: '/siteSettings/category/fullscreen',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-fullscreen'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryFullscreen'],
+ },
+ {
+ url: '/siteSettings/category/images',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-images'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryImages'],
+ },
+ {
+ url: '/siteSettings/category/location',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-location'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryLocation'],
+ },
+ {
+ url: '/siteSettings/category/javascript',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-javascript'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryJavascript'],
+ },
+ {
+ url: '/siteSettings/category/microphone',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-microphone'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryMicrophone'],
+ },
+ {
+ url: '/siteSettings/category/notifications',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-notifications'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryNotifications'],
+ },
+ {
+ url: '/siteSettings/category/popups',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-popups'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryPopups'],
+ },
+ {
+ url: '/siteSettings/category/details',
+ page: 'advanced',
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category', 'site-details'],
+ subpageTitles: ['siteSettings', 'siteSettingsCategoryPageTitle',
+ 'siteSettingsSiteDetailsPageTitle'],
+ },
+ {
url: '/clearBrowserData',
page: 'advanced',
section: 'privacy',
subpage: ['clear-browsing-data'],
subpageTitles: ['clearBrowsingData'],
},
+<if expr="chromeos">
{
- url: '/networkDetail',
- page: 'basic',
- section: 'internet',
- subpage: ['network-detail'],
- subpageTitles: ['internetDetailPageTitle'],
+ url: '/bluetoothAddDevice',
+ page: 'advanced',
+ section: 'bluetooth',
+ subpage: ['bluetooth-add-device'],
+ subpageTitles: ['bluetoothAddDevicePageTitle'],
},
{
- url: '/knownNetworks',
- page: 'basic',
- section: 'internet',
- subpage: ['known-networks'],
- subpageTitles: ['internetKnownNetworksPageTitle'],
+ url: '/bluetoothAddDevice/bluetoothPairDevice',
+ page: 'advanced',
+ section: 'bluetooth',
+ subpage: ['bluetooth-add-device', 'bluetooth-pair-device'],
+ subpageTitles: ['bluetoothAddDevicePageTitle',
+ 'bluetoothPairDevicePageTitle'],
},
+</if>
{
url: '/languages',
page: 'advanced',
@@ -160,6 +289,15 @@ Polymer({
subpage: ['language-detail'],
subpageTitles: ['manageLanguagesPageTitle'],
},
+<if expr="not is_macosx">
+ {
+ url: '/editDictionary',
+ page: 'advanced',
+ section: 'languages',
+ subpage: ['edit-dictionary'],
+ subpageTitles: ['editDictionaryPageTitle'],
+ },
+</if>
],
/**
@@ -210,12 +348,12 @@ Polymer({
// Push the current route to the history state, so when the user
// navigates with the browser back button, we can recall the route.
if (oldRoute) {
- history.pushState(historicState, null, route.url);
+ window.history.pushState(historicState, document.title, route.url);
} else {
// For the very first route (oldRoute will be undefined), we replace
// the existing state instead of pushing a new one. This is to allow
// the user to use the browser back button to exit Settings entirely.
- history.replaceState(historicState, null);
+ window.history.replaceState(historicState, document.title);
}
return;
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_section.css b/chromium/chrome/browser/resources/settings/settings_page/settings_section.css
index 6b0c5c54870..91a81fcc8ab 100644
--- a/chromium/chrome/browser/resources/settings/settings_page/settings_section.css
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_section.css
@@ -26,13 +26,11 @@ paper-material {
background-color: white;
box-sizing: border-box;
overflow: hidden;
- padding: 16px;
}
paper-material,
#placeholder {
margin-bottom: 16px;
- width: 605px;
}
:host(.neon-animating) paper-material {
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_section.js b/chromium/chrome/browser/resources/settings/settings_page/settings_section.js
index 974fb9530b8..7a39fd72ac1 100644
--- a/chromium/chrome/browser/resources/settings/settings_page/settings_section.js
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_section.js
@@ -9,7 +9,7 @@
*
* Example:
*
- * <settings-section page-title="[[pageTitle]]">
+ * <settings-section page-title="[[pageTitle]]" section="privacy">
* <!-- Insert your section controls here -->
* </settings-section>
*
@@ -35,6 +35,8 @@ Polymer({
/**
* The section is expanded to a full-page view when this property matches
* currentRoute.section.
+ *
+ * The section name must match the name specified in settings_router.js.
*/
section: {
type: String,
@@ -165,6 +167,10 @@ Polymer({
section.classList.remove('expanded');
var card = section.$.card;
+ var placeholder = section.$.placeholder;
+ placeholder.style.top = card.offsetTop + 'px';
+ placeholder.style.height = card.offsetHeight + 'px';
+
var newRect = card.getBoundingClientRect();
section.classList.add('neon-animating');
diff --git a/chromium/chrome/browser/resources/settings/settings_resources.grd b/chromium/chrome/browser/resources/settings/settings_resources.grd
index 6dc96858a76..e9041029afb 100644
--- a/chromium/chrome/browser/resources/settings/settings_resources.grd
+++ b/chromium/chrome/browser/resources/settings/settings_resources.grd
@@ -43,8 +43,12 @@
<structure name="IDR_SETTINGS_CR_SETTINGS_ANIMATED_PAGES_JS"
file="settings_page/settings_animated_pages.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_APPEARANCE_PAGE_CSS"
- file="appearance_page/appearance_page.css"
+ <structure name="IDR_SETTINGS_APPEARANCE_FONTS_PAGE_HTML"
+ file="appearance_page/appearance_fonts_page.html"
+ type="chrome_html"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_APPEARANCE_FONTS_PAGE_JS"
+ file="appearance_page/appearance_fonts_page.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_APPEARANCE_PAGE_HTML"
file="appearance_page/appearance_page.html"
@@ -54,6 +58,9 @@
<structure name="IDR_SETTINGS_APPEARANCE_PAGE_JS"
file="appearance_page/appearance_page.js"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_APPEARANCE_SHARED_CSS"
+ file="appearance_page/appearance_shared.css"
+ type="chrome_html" />
<structure name="IDR_SETTINGS_BASIC_PAGE_JS"
file="basic_page/basic_page.js"
type="chrome_html" />
@@ -80,15 +87,6 @@
<structure name="IDR_SETTINGS_STARTUP_URLS_PAGE_JS"
file="on_startup_page/startup_urls_page.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_CHECKBOX_HTML"
- file="checkbox/checkbox.html"
- type="chrome_html" />
- <structure name="IDR_SETTINGS_CHECKBOX_JS"
- file="checkbox/checkbox.js"
- type="chrome_html" />
- <structure name="IDR_SETTINGS_CHECKBOX_CSS"
- file="checkbox/checkbox.css"
- type="chrome_html" />
<structure name="IDR_SETTINGS_CR_SETTINGS_MAIN_CSS"
file="settings_main/settings_main.css"
type="chrome_html" />
@@ -111,6 +109,12 @@
<structure name="IDR_SETTINGS_CR_SETTINGS_MENU_JS"
file="settings_menu/settings_menu.js"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_CR_SETTINGS_PAGE_VISIBILITY_HTML"
+ file="settings_page/settings_page_visibility.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CR_SETTINGS_PAGE_VISIBILITY_JS"
+ file="settings_page/settings_page_visibility.js"
+ type="chrome_html" />
<structure name="IDR_SETTINGS_CR_SETTINGS_SECTION_CSS"
file="settings_page/settings_section.css"
type="chrome_html" />
@@ -129,8 +133,11 @@
<structure name="IDR_SETTINGS_CR_SETTINGS_SUBHEADER_JS"
file="settings_page/settings_subheader.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_CR_SETTINGS_PAGE_CSS"
- file="settings_page/settings_page.css"
+ <structure name="IDR_SETTINGS_CR_SETTINGS_DIALOG_CSS"
+ file="settings_dialog.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CR_SETTINGS_SHARED_CSS"
+ file="settings_shared.css"
type="chrome_html" />
<structure name="IDR_SETTINGS_BREADCRUMB_CSS"
file="settings_ui/breadcrumb.css"
@@ -170,6 +177,52 @@
<structure name="IDR_SETTINGS_CLEAR_BROWSING_DATA_PAGE_JS"
file="clear_browsing_data_page/clear_browsing_data_page.js"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_CHECKBOX_HTML"
+ file="controls/settings_checkbox.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_CHECKBOX_JS"
+ file="controls/settings_checkbox.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_CHECKBOX_CSS"
+ file="controls/settings_checkbox.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_DROPDOWN_MENU_HTML"
+ file="controls/settings_dropdown_menu.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_DROPDOWN_MENU_JS"
+ file="controls/settings_dropdown_menu.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_INPUT_HTML"
+ file="controls/settings_input.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_INPUT_JS"
+ file="controls/settings_input.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_INPUT_CSS"
+ file="controls/settings_input.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_RADIO_GROUP_HTML"
+ file="controls/settings_radio_group.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_RADIO_GROUP_JS"
+ file="controls/settings_radio_group.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CONTROLS_RADIO_GROUP_CSS"
+ file="controls/settings_radio_group.css"
+ type="chrome_html" />
+ <if expr="not chromeos">
+ <structure name="IDR_SETTINGS_DEFAULT_BROWSER_PAGE_CSS"
+ file="default_browser_page/default_browser_page.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_DEFAULT_BROWSER_PAGE_HTML"
+ file="default_browser_page/default_browser_page.html"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_DEFAULT_BROWSER_PAGE_JS"
+ file="default_browser_page/default_browser_page.js"
+ type="chrome_html" />
+ </if>
<structure name="IDR_SETTINGS_DOWNLOADS_PAGE_CSS"
file="downloads_page/downloads_page.css"
type="chrome_html" />
@@ -179,21 +232,54 @@
<structure name="IDR_SETTINGS_DOWNLOADS_PAGE_JS"
file="downloads_page/downloads_page.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_INPUT_HTML"
- file="input/input.html"
+ <structure name="IDR_SETTINGS_I18n_SETUP_HTML"
+ file="i18n_setup.html"
type="chrome_html" />
- <structure name="IDR_SETTINGS_INPUT_JS"
- file="input/input.js"
+ <structure name="IDR_SETTINGS_ICONS"
+ file="icons.html"
type="chrome_html" />
- <structure name="IDR_SETTINGS_INPUT_CSS"
- file="input/input.css"
+ <structure name="IDR_SETTINGS_POWERWASH_DIALOG_HTML"
+ file="reset_page/powerwash_dialog.html"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_POWERWASH_DIALOG_JS"
+ file="reset_page/powerwash_dialog.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_RESET_PAGE_DIALOG_CSS"
+ file="reset_page/reset_page_dialog.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_RESET_PAGE_HTML"
+ file="reset_page/reset_page.html"
+ type="chrome_html"
+ flattenhtml="true" />
+ <structure name="IDR_SETTINGS_RESET_PAGE_JS"
+ file="reset_page/reset_page.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_RESET_PROFILE_DIALOG_CSS"
+ file="reset_page/reset_profile_dialog.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_RESET_PROFILE_DIALOG_HTML"
+ file="reset_page/reset_profile_dialog.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_RESET_PROFILE_DIALOG_JS"
+ file="reset_page/reset_profile_dialog.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_RESET_PROFILE_BANNER_CSS"
+ file="reset_page/reset_profile_banner.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_RESET_PROFILE_BANNER_HTML"
+ file="reset_page/reset_profile_banner.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_RESET_PROFILE_BANNER_JS"
+ file="reset_page/reset_profile_banner.js"
+ type="chrome_html"/>
<structure name="IDR_SETTINGS_LANGUAGES_HTML"
file="languages_page/languages.html"
type="chrome_html" />
<structure name="IDR_SETTINGS_LANGUAGES_JS"
file="languages_page/languages.js"
- type="chrome_html" />
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
<structure name="IDR_SETTINGS_LANGUAGES_PAGE_CSS"
file="languages_page/languages_page.css"
type="chrome_html" />
@@ -204,7 +290,9 @@
allowexternalscript="true" />
<structure name="IDR_SETTINGS_LANGUAGES_PAGE_JS"
file="languages_page/languages_page.js"
- type="chrome_html" />
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
<structure name="IDR_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_PAGE_CSS"
file="languages_page/manage_languages_page.css"
type="chrome_html" />
@@ -224,12 +312,68 @@
allowexternalscript="true" />
<structure name="IDR_SETTINGS_LANGUAGES_LANGUAGE_DETAIL_PAGE_JS"
file="languages_page/language_detail_page.js"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <if expr="not is_macosx">
+ <structure name="IDR_SETTINGS_LANGUAGES_EDIT_DICTIONARY_PAGE_CSS"
+ file="languages_page/edit_dictionary_page.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_LANGUAGES_EDIT_DICTIONARY_PAGE_HTML"
+ file="languages_page/edit_dictionary_page.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_LANGUAGES_EDIT_DICTIONARY_PAGE_JS"
+ file="languages_page/edit_dictionary_page.js"
+ type="chrome_html" />
+ </if>
+ <structure name="IDR_SETTINGS_PASSWORDS_AND_FORMS_PAGE_HTML"
+ file="passwords_and_forms_page/passwords_and_forms_page.html"
type="chrome_html" />
- <structure name="IDR_SETTINGS_POLICY_CONTROLLABLE_HTML"
- file="policy_controllable/policy_controllable.html"
+ <structure name="IDR_SETTINGS_PASSWORDS_AND_FORMS_PAGE_JS"
+ file="passwords_and_forms_page/passwords_and_forms_page.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_POLICY_CONTROLLABLE_JS"
- file="policy_controllable/policy_controllable.js"
+ <structure name="IDR_SETTINGS_PASSWORDS_SECTION_CSS"
+ file="passwords_and_forms_page/passwords_section.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_PASSWORDS_SECTION_HTML"
+ file="passwords_and_forms_page/passwords_section.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_PASSWORDS_SECTION_JS"
+ file="passwords_and_forms_page/passwords_section.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_CSS"
+ file="people_page/people_page.css"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_HTML"
+ file="people_page/people_page.html"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_JS"
+ file="people_page/people_page.js"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <if expr="not chromeos">
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_MANAGE_PROFILE_CSS"
+ file="people_page/manage_profile.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_MANAGE_PROFILE_HTML"
+ file="people_page/manage_profile.html"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_MANAGE_PROFILE_JS"
+ file="people_page/manage_profile.js"
+ type="chrome_html" />
+ </if>
+ <structure name="IDR_SETTINGS_PREF_UTIL_HTML"
+ file="prefs/pref_util.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_PREF_UTIL_JS"
+ file="prefs/pref_util.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_PREFS_HTML"
file="prefs/prefs.html"
@@ -237,6 +381,12 @@
<structure name="IDR_SETTINGS_PREFS_JS"
file="prefs/prefs.js"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_PREFS_BEHAVIOR_HTML"
+ file="prefs/prefs_behavior.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_PREFS_BEHAVIOR_JS"
+ file="prefs/prefs_behavior.js"
+ type="chrome_html" />
<structure name="IDR_SETTINGS_PREFS_TYPES_HTML"
file="prefs/prefs_types.html"
type="chrome_html" />
@@ -249,15 +399,6 @@
<structure name="IDR_SETTINGS_PREF_TRACKER_JS"
file="pref_tracker/pref_tracker.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_LOCATION_PAGE_CSS"
- file="location_page/location_page.css"
- type="chrome_html" />
- <structure name="IDR_SETTINGS_LOCATION_PAGE_HTML"
- file="location_page/location_page.html"
- type="chrome_html" />
- <structure name="IDR_SETTINGS_LOCATION_PAGE_JS"
- file="location_page/location_page.js"
- type="chrome_html" />
<structure name="IDR_SETTINGS_PRIVACY_PAGE_CSS"
file="privacy_page/privacy_page.css"
type="chrome_html" />
@@ -269,20 +410,43 @@
<structure name="IDR_SETTINGS_PRIVACY_PAGE_JS"
file="privacy_page/privacy_page.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_RADIO_GROUP_HTML"
- file="radio_group/radio_group.html"
- type="chrome_html" />
- <structure name="IDR_SETTINGS_RADIO_GROUP_JS"
- file="radio_group/radio_group.js"
- type="chrome_html" />
- <structure name="IDR_SETTINGS_RADIO_GROUP_CSS"
- file="radio_group/radio_group.css"
- type="chrome_html" />
<structure name="IDR_SETTINGS_CR_SETTINGS_ROUTER_HTML"
file="settings_page/settings_router.html"
type="chrome_html" />
<structure name="IDR_SETTINGS_CR_SETTINGS_ROUTER_JS"
file="settings_page/settings_router.js"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_SITE_LIST_CSS"
+ file="site_settings/site_list.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_LIST_HTML"
+ file="site_settings/site_list.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_LIST_JS"
+ file="site_settings/site_list.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_BEHAVIOR_HTML"
+ file="site_settings/site_settings_behavior.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_BEHAVIOR_JS"
+ file="site_settings/site_settings_behavior.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_CATEGORY_CSS"
+ file="site_settings/site_settings_category.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_CATEGORY_HTML"
+ file="site_settings/site_settings_category.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_CATEGORY_JS"
+ file="site_settings/site_settings_category.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_CONSTANTS_JS"
+ file="site_settings/constants.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_CONSTANTS_HTML"
+ file="site_settings/constants.html"
type="chrome_html" />
<structure name="IDR_SETTINGS_SITE_SETTINGS_PAGE_CSS"
file="site_settings_page/site_settings_page.css"
@@ -293,6 +457,24 @@
<structure name="IDR_SETTINGS_SITE_SETTINGS_PAGE_JS"
file="site_settings_page/site_settings_page.js"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_SITE_DETAILS_CSS"
+ file="site_settings/site_details.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_SITE_DETAILS_HTML"
+ file="site_settings/site_details.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_SITE_DETAILS_JS"
+ file="site_settings/site_details.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_SITE_DETAILS_PERMISSION_CSS"
+ file="site_settings/site_details_permission.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_SITE_DETAILS_PERMISSION_HTML"
+ file="site_settings/site_details_permission.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SITE_SETTINGS_SITE_DETAILS_PERMISSION_JS"
+ file="site_settings/site_details_permission.js"
+ type="chrome_html" />
<structure name="IDR_SETTINGS_SEARCH_ENGINES_PAGE_SEARCH_ENGINE_ADDER_JS"
file="search_engines_page/search_engine_adder.js"
type="chrome_html" />
@@ -346,16 +528,26 @@
file="search_page/search_page.css"
type="chrome_html" />
<structure name="IDR_SETTINGS_SYNC_PAGE_JS"
- file="sync_page/sync_page.js"
+ file="people_page/sync_page.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_SYNC_PAGE_HTML"
- file="sync_page/sync_page.html"
+ file="people_page/sync_page.html"
type="chrome_html"
flattenhtml="true"
allowexternalscript="true" />
<structure name="IDR_SETTINGS_SYNC_PAGE_CSS"
- file="sync_page/sync_page.css"
+ file="people_page/sync_page.css"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_SYNC_PRIVATE_API_JS"
+ file="people_page/sync_private_api.js"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_SYNC_PRIVATE_API_HTML"
+ file="people_page/sync_private_api.html"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
<structure name="IDR_SETTINGS_SETTINGS_HTML"
file="settings.html"
type="chrome_html" />
@@ -363,6 +555,39 @@
file="settings.js"
type="chrome_html" />
<if expr="chromeos">
+ <structure name="IDR_SETTINGS_BLUETOOTH_DEVICE_LIST_ITEM_CSS"
+ file="bluetooth_page/bluetooth_device_list_item.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_DEVICE_LIST_ITEM_HTML"
+ file="bluetooth_page/bluetooth_device_list_item.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_DEVICE_LIST_ITEM_JS"
+ file="bluetooth_page/bluetooth_device_list_item.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_DIALOG_CSS"
+ file="bluetooth_page/bluetooth_dialog.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_PAGE_CSS"
+ file="bluetooth_page/bluetooth_page.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_PAGE_HTML"
+ file="bluetooth_page/bluetooth_page.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_PAGE_JS"
+ file="bluetooth_page/bluetooth_page.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_ADD_DEVICE_DIALOG_HTML"
+ file="bluetooth_page/bluetooth_add_device_dialog.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_ADD_DEVICE_DIALOG_JS"
+ file="bluetooth_page/bluetooth_add_device_dialog.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_PAIR_DEVICE_DIALOG_HTML"
+ file="bluetooth_page/bluetooth_pair_device_dialog.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_BLUETOOTH_PAIR_DEVICE_DIALOG_JS"
+ file="bluetooth_page/bluetooth_pair_device_dialog.js"
+ type="chrome_html" />
<structure name="IDR_SETTINGS_DATE_TIME_PAGE_CSS"
file="date_time_page/date_time_page.css"
type="chrome_html" />
@@ -468,9 +693,6 @@
<structure name="IDR_SETTINGS_NETWORK_SIMINFO_JS"
file="internet_page/network_siminfo.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_NETWORK_SUMMARY_CSS"
- file="internet_page/network_summary.css"
- type="chrome_html" />
<structure name="IDR_SETTINGS_NETWORK_SUMMARY_HTML"
file="internet_page/network_summary.html"
type="chrome_html" />
@@ -486,27 +708,48 @@
<structure name="IDR_SETTINGS_NETWORK_SUMMARY_ITEM_JS"
file="internet_page/network_summary_item.js"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_PEOPLE_CHANGE_PICTURE_PRIVATE_API_JS"
+ file="people_page/change_picture_private_api.js"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_CHANGE_PICTURE_CSS"
+ file="people_page/change_picture.css"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_CHANGE_PICTURE_HTML"
+ file="people_page/change_picture.html"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
+ <structure name="IDR_SETTINGS_PEOPLE_PAGE_CHANGE_PICTURE_JS"
+ file="people_page/change_picture.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_PEOPLE_CHANGE_PICTURE_PRIVATE_API_HTML"
+ file="people_page/change_picture_private_api.html"
+ type="chrome_html"
+ flattenhtml="true"
+ allowexternalscript="true" />
<structure name="IDR_SETTINGS_USERS_PAGE_USER_LIST_JS"
- file="users_page/user_list.js"
+ file="people_page/user_list.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_USERS_PAGE_USER_LIST_HTML"
- file="users_page/user_list.html"
+ file="people_page/user_list.html"
type="chrome_html"
flattenhtml="true"
allowexternalscript="true" />
<structure name="IDR_SETTINGS_USERS_PAGE_USER_LIST_CSS"
- file="users_page/user_list.css"
+ file="people_page/user_list.css"
type="chrome_html" />
<structure name="IDR_SETTINGS_USERS_PAGE_JS"
- file="users_page/users_page.js"
+ file="people_page/users_page.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_USERS_PAGE_HTML"
- file="users_page/users_page.html"
+ file="people_page/users_page.html"
type="chrome_html"
flattenhtml="true"
allowexternalscript="true" />
<structure name="IDR_SETTINGS_USERS_PAGE_CSS"
- file="users_page/users_page.css"
+ file="people_page/users_page.css"
type="chrome_html" />
</if>
</structures>
diff --git a/chromium/chrome/browser/resources/settings/settings_shared.css b/chromium/chrome/browser/resources/settings/settings_shared.css
new file mode 100644
index 00000000000..ba6bb13a2f6
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/settings_shared.css
@@ -0,0 +1,115 @@
+/* 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. */
+
+/**
+ * @fileoverview
+ * Common styles for Material Design settings.
+ */
+
+paper-button {
+ margin: 0;
+ min-width: auto;
+}
+
+paper-button[toggles][active] {
+ background-color: LightGray;
+}
+
+.text-elide {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+h2 {
+ color: #9e9e9e;
+ font-size: 100%;
+ font-weight: normal;
+ margin-bottom: 20px;
+ margin-top: 30px;
+}
+
+.button-row {
+ display: flex;
+ margin-top: 25px;
+}
+
+.button-strip {
+ text-align: end;
+}
+
+.list-frame {
+ @apply(--layout-center);
+ display: block;
+ margin-left: 48px;
+ padding: 0;
+}
+
+.list-item {
+ @apply(--layout-center);
+ border-top: 1px solid #e0e0e0;
+ display: flex;
+ padding: 0;
+}
+
+.list-item:first-of-type {
+ border-top: none;
+}
+
+.list-item .middle {
+ flex: 1;
+ margin: 8px 12px;
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+.list-item .secondary {
+ color: #969696;
+}
+
+.list-item > paper-icon-item {
+ padding: 0;
+}
+
+.link-button {
+ color: rgb(61, 130, 243);
+ padding-bottom: 6px;
+ padding-left: 0;
+ padding-right: 0;
+ padding-top: 6px;
+ text-transform: none;
+}
+
+.settings-box {
+ @apply(--layout-center);
+ border-top: 1px solid #e0e0e0;
+ display: block;
+ min-height: 40px;
+ padding: 8px 16px;
+}
+
+.settings-box .two-line {
+ min-height: 52px;
+}
+
+.settings-box:first-of-type {
+ border-top: none;
+}
+
+.settings-box .secondary {
+ color: #969696;
+}
+
+.split {
+ display: flex;
+}
+
+.split .start {
+ flex: auto;
+}
+
+.settings-box paper-item iron-icon {
+ /* Same padding as paper-icon-button. */
+ padding: 8px;
+}
diff --git a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.css b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.css
index 5a61699f773..7b94109fe6f 100644
--- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.css
+++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.css
@@ -7,7 +7,7 @@
@apply(--layout-fit);
@apply(--paper-font-body1);
-webkit-user-select: none;
- background-color: rgb(230, 230, 230);
+ background-color: #f2f2f2;
color: rgba(0, 0, 0, .87);
}
@@ -21,12 +21,12 @@ paper-toolbar {
paper-drawer-panel {
@apply(--layout-flex);
--paper-drawer-panel-left-drawer-container: {
- background-color: rgb(230, 230, 230);
+ background-color: #f2f2f2;
margin-top: 34px;
};
position: relative;
}
-cr-settings-main paper-icon-button {
+settings-main paper-icon-button {
z-index: 10;
}
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 0bb5ed8593e..5a65e761ba2 100644
--- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html
+++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -10,7 +10,7 @@
<link rel="import" href="chrome://md-settings/settings_page/settings_router.html">
<link rel="import" href="chrome://md-settings/settings_ui/breadcrumb.html">
-<dom-module id="cr-settings-ui">
+<dom-module id="settings-ui">
<link rel="import" type="css" href="settings_ui.css">
<template>
<settings-router current-route="{{currentRoute}}"
@@ -23,11 +23,11 @@
</settings-breadcrumb>
</paper-toolbar>
<paper-drawer-panel drawer-width="256px">
- <cr-settings-menu drawer class="flex" current-route="{{currentRoute}}">
- </cr-settings-menu>
- <cr-settings-main main prefs="{{prefs}}" current-route="{{currentRoute}}">
+ <settings-menu drawer class="flex" current-route="{{currentRoute}}">
+ </settings-menu>
+ <settings-main main prefs="{{prefs}}" current-route="{{currentRoute}}">
<paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button>
- </cr-settings-main>
+ </settings-main>
</paper-drawer-panel>
</template>
<script src="settings_ui.js"></script>
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 bc21caa7e90..513aa521d50 100644
--- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js
+++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -4,17 +4,17 @@
/**
* @fileoverview
- * 'cr-settings-ui' implements the UI for the Settings page.
+ * 'settings-ui' implements the UI for the Settings page.
*
* Example:
*
- * <cr-settings-ui prefs="{{prefs}}"></cr-settings-ui>
+ * <settings-ui prefs="{{prefs}}"></settings-ui>
*
* @group Chrome Settings Elements
- * @element cr-settings-ui
+ * @element settings-ui
*/
Polymer({
- is: 'cr-settings-ui',
+ is: 'settings-ui',
properties: {
/**
diff --git a/chromium/chrome/browser/resources/settings/site_settings/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/site_settings/compiled_resources.gyp
new file mode 100644
index 00000000000..16fa38a3535
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/compiled_resources.gyp
@@ -0,0 +1,95 @@
+# 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.
+{
+ 'targets': [
+ {
+ 'target_name': 'site_details',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../prefs/prefs_behavior.js',
+ 'constants.js',
+ 'site_settings_behavior.js',
+ 'site_details_permission.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'site_details_permission',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../prefs/prefs_behavior.js',
+ 'constants.js',
+ 'site_settings_behavior.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'site_list',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../prefs/prefs_behavior.js',
+ '../prefs/prefs_types.js',
+ 'constants.js',
+ 'site_settings_behavior.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'site_settings_behavior',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../prefs/prefs_behavior.js',
+ 'constants.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ {
+ 'target_name': 'site_settings_category',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../prefs/prefs_behavior.js',
+ '../prefs/prefs_types.js',
+ '../settings_page/settings_animated_pages.js',
+ 'constants.js',
+ 'site_settings_behavior.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ ],
+}
diff --git a/chromium/chrome/browser/resources/settings/site_settings/constants.html b/chromium/chrome/browser/resources/settings/site_settings/constants.html
new file mode 100644
index 00000000000..b8603f7e3b4
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/constants.html
@@ -0,0 +1,2 @@
+<link rel="import" href="chrome://resources/html/cr.html">
+<script src="chrome://md-settings/site_settings/constants.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/constants.js b/chromium/chrome/browser/resources/settings/site_settings/constants.js
new file mode 100644
index 00000000000..c0de36a2bd4
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/constants.js
@@ -0,0 +1,40 @@
+// 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.
+
+cr.define('settings', function() {
+ /**
+ * The possible contentSettingsTypes (the ones we currently support
+ * configuring in the UI). This is a subset of the constants found under
+ * content_setttings_types.h and the values should be kept in sync.
+ * TODO(finnur): When all categories have been implemented we can just
+ * generate these constants from content_setttings_types.h.
+ * @enum {number}
+ */
+ var ContentSettingsTypes = {
+ COOKIES: 0,
+ IMAGES: 1,
+ JAVASCRIPT: 2,
+ POPUPS: 4,
+ GEOLOCATION: 5,
+ NOTIFICATIONS: 6,
+ FULLSCREEN: 8,
+ MIC: 12,
+ CAMERA: 13,
+ };
+
+ /**
+ * Contains the possible values for a given contentSettingsType.
+ * @enum {number}
+ */
+ var PermissionValues = {
+ ALLOW: 1,
+ BLOCK: 2,
+ ASK: 3,
+ };
+
+ return {
+ ContentSettingsTypes: ContentSettingsTypes,
+ PermissionValues: PermissionValues,
+ };
+});
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details.css b/chromium/chrome/browser/resources/settings/site_settings/site_details.css
new file mode 100644
index 00000000000..8d0ff6714ef
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.css
@@ -0,0 +1,19 @@
+/* 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. */
+
+:host {
+ display: block;
+}
+
+.origin {
+ font-weight: bold;
+}
+
+.reset-button {
+ -webkit-margin-start: 15px;
+}
+
+#storage {
+ -webkit-padding-end: 0;
+} \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details.html b/chromium/chrome/browser/resources/settings/site_settings/site_details.html
new file mode 100644
index 00000000000..33d96f74409
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.html
@@ -0,0 +1,53 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://md-settings/site_settings/site_details_permission.html">
+
+<dom-module id="site-details">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="site_details.css">
+ <template>
+ <div class="settings-box">
+ <div class="origin">[[origin]]</div>
+ <h2 i18n-content="siteSettingsUsage" id="usage" hidden></h2>
+ <paper-item id="storage" hidden>
+ <div class="flex">[[storedData_]]</div>
+ <paper-icon-button icon="delete"
+ on-tap="onClearStorage_"
+ i18n-values="alt:siteSettingsDelete"></paper-icon-button>
+ </paper-item>
+ <h2 i18n-content="siteSettingsPermissions"></h2>
+ <site-details-permission prefs="{{prefs}}" id="cookies"
+ origin="[[origin]]">
+ </site-details-permission>
+ <site-details-permission prefs="{{prefs}}" id="javascript"
+ origin="[[origin]]">
+ </site-details-permission>
+ <site-details-permission prefs="{{prefs}}" id="popups"
+ origin="[[origin]]">
+ </site-details-permission>
+ <site-details-permission prefs="{{prefs}}" id="geolocation"
+ origin="[[origin]]">
+ </site-details-permission>
+ <site-details-permission prefs="{{prefs}}" id="notification"
+ origin="[[origin]]">
+ </site-details-permission>
+ <site-details-permission prefs="{{prefs}}" id="fullscreen"
+ origin="[[origin]]">
+ </site-details-permission>
+ <site-details-permission prefs="{{prefs}}" id="camera"
+ origin="[[origin]]">
+ </site-details-permission>
+ <site-details-permission prefs="{{prefs}}" id="mic"
+ origin="[[origin]]">
+ </site-details-permission>
+ <paper-button
+ on-tap="onClearAndReset_"
+ raised i18n-content="siteSettingsClearAndReset"
+ class="reset-button"></paper-button>
+ </div>
+ </template>
+ <script src="site_details.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details.js b/chromium/chrome/browser/resources/settings/site_settings/site_details.js
new file mode 100644
index 00000000000..a6a8db7bccd
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.js
@@ -0,0 +1,74 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'site-details' show the details (permissions and usage) for a given origin
+ * under Site Settings.
+ *
+ * Example:
+ *
+ * <site-details prefs="{{prefs}}" origin="{{origin}}">
+ * </site-details>
+ * ... other pages ...
+ *
+ * @group Chrome Settings Elements
+ * @element site-details
+ */
+Polymer({
+ is: 'site-details',
+
+ properties: {
+ /**
+ * Preferences state.
+ */
+ prefs: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * The origin that this widget is showing details for.
+ */
+ origin: String,
+
+ /**
+ * The amount of data stored for the origin.
+ */
+ storedData_: {
+ type: String,
+ observer: 'onStoredDataChanged_',
+ },
+ },
+
+ ready: function() {
+ this.$.cookies.category = settings.ContentSettingsTypes.COOKIES;
+ this.$.javascript.category = settings.ContentSettingsTypes.JAVASCRIPT;
+ this.$.popups.category = settings.ContentSettingsTypes.POPUPS;
+ this.$.geolocation.category = settings.ContentSettingsTypes.GEOLOCATION;
+ this.$.notification.category = settings.ContentSettingsTypes.NOTIFICATIONS;
+ this.$.fullscreen.category = settings.ContentSettingsTypes.FULLSCREEN;
+ this.$.camera.category = settings.ContentSettingsTypes.CAMERA;
+ this.$.mic.category = settings.ContentSettingsTypes.MIC;
+
+ this.storedData_ = '1337 MB'; // TODO(finnur): Fetch actual data.
+ },
+
+ onStoredDataChanged_: function() {
+ this.$.usage.hidden = false;
+ this.$.storage.hidden = false;
+ },
+
+ onClearStorage_: function() {
+ // TODO(finnur): Implement.
+ },
+
+ onClearAndReset_: function() {
+ Array.prototype.forEach.call(
+ this.root.querySelectorAll('site-details-permission'),
+ function(element) { element.resetPermission(); });
+
+ this.onClearStorage_();
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.css b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.css
new file mode 100644
index 00000000000..152713dbedf
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.css
@@ -0,0 +1,36 @@
+/* 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. */
+
+:host {
+ display: block;
+}
+
+.left-column {
+ -webkit-margin-start: 15px;
+}
+
+.right-column {
+ -webkit-margin-start: 10px;
+}
+
+.permission-header {
+ -webkit-margin-start: 6px;
+}
+
+.permission-list {
+ -webkit-margin-end: 7px;
+}
+
+.permission-list > paper-dropdown-menu {
+ -webkit-margin-end: 3px;
+ -webkit-margin-start: -13px;
+ margin-bottom: 12px;
+ margin-top: -20px;
+ width: 100%;
+}
+
+.permission-list > paper-dropdown-menu::shadow > paper-menu-button {
+ -webkit-margin-start: 11px;
+ width: 100%;
+}
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.html b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.html
new file mode 100644
index 00000000000..0c65a9933ab
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.html
@@ -0,0 +1,40 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/av-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/communication-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/social-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dropdown-menu/paper-dropdown-menu.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
+<link rel="import" href="chrome://md-settings/prefs/prefs_behavior.html">
+<link rel="import" href="chrome://md-settings/site_settings/site_settings_behavior.html">
+
+<dom-module id="site-details-permission">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="site_details_permission.css">
+ <template>
+ <div id="details" class="horizontal layout top" hidden>
+ <div class="left-column">
+ <iron-icon icon="[[computeIconForContentCategory(category)]]"
+ item-icon></iron-icon>
+ </div>
+ <div class="flex right-column">
+ <div class="permission-header">
+ [[computeTitleForContentCategory(category)]]
+ </div>
+ <div class="permission-list">
+ <paper-dropdown-menu>
+ <paper-menu id="permission" class="dropdown-content"
+ on-iron-select="onPermissionMenuIronSelect_">
+ <paper-item id="allow">[[i18n_.allowAction]]</paper-item>
+ <paper-item id="block">[[i18n_.blockAction]]</paper-item>
+ </paper-menu>
+ </paper-dropdown-menu>
+ </div>
+ </div>
+ </div>
+ </template>
+ <script src="site_details_permission.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js
new file mode 100644
index 00000000000..a55969003d8
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js
@@ -0,0 +1,98 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'site-details-permission' handles showing the state of one permission, such
+ * as Geolocation, for a given origin.
+ *
+ * Example:
+ *
+ * <site-details-permission prefs="{{prefs}}">
+ * </site-details-permission>
+ * ... other pages ...
+ *
+ * @group Chrome Settings Elements
+ * @element site-details-permission
+ */
+Polymer({
+ is: 'site-details-permission',
+
+ behaviors: [PrefsBehavior, SiteSettingsBehavior],
+
+ properties: {
+ /**
+ * Preferences state.
+ */
+ prefs: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * The origin, which this permission affects.
+ */
+ origin: String,
+
+ i18n_: {
+ readOnly: true,
+ type: Object,
+ value: function() {
+ return {
+ allowAction: loadTimeData.getString('siteSettingsActionAllow'),
+ blockAction: loadTimeData.getString('siteSettingsActionBlock'),
+ };
+ },
+ },
+ },
+
+ observers: [
+ 'initialize_(' +
+ 'prefs.profile.content_settings.exceptions.*, category, origin)',
+ ],
+
+ initialize_: function() {
+ this.$.details.hidden = true;
+ if (this.get('prefs.' +
+ this.computeCategoryExceptionsPrefName(this.category)) === undefined)
+ return;
+
+ var pref = this.getPref(
+ this.computeCategoryExceptionsPrefName(this.category));
+ var originPref = pref.value[this.origin + ',*'];
+ if (originPref === undefined)
+ originPref = pref.value[this.origin + ',' + this.origin];
+ if (originPref === undefined)
+ return;
+
+ if (/** @type {{setting: number}} */(originPref.setting) ==
+ settings.PermissionValues.ALLOW) {
+ this.$.permission.selected = 0;
+ this.$.details.hidden = false;
+ } else if (originPref.setting == settings.PermissionValues.BLOCK) {
+ this.$.permission.selected = 1;
+ this.$.details.hidden = false;
+ }
+ },
+
+ /**
+ * Resets the category permission for this origin.
+ */
+ resetPermission: function() {
+ this.resetCategoryPermissionForOrigin(this.origin, this.category);
+ this.$.details.hidden = true;
+ },
+
+ /**
+ * Handles the category permission changing for this origin.
+ * @param {!{target: !{selectedItem: !{innerText: string}}}} event
+ */
+ onPermissionMenuIronSelect_: function(event) {
+ var action = event.target.selectedItem.innerText;
+ var value = (action == this.i18n_.allowAction) ?
+ settings.PermissionValues.ALLOW :
+ settings.PermissionValues.BLOCK;
+ this.setCategoryPermissionForOrigin(this.origin, value, this.category);
+ },
+});
diff --git a/chromium/chrome/browser/resources/options/chromeos/power_overlay.css b/chromium/chrome/browser/resources/settings/site_settings/site_list.css
index 91408fff75e..feeacafdbe1 100644
--- a/chromium/chrome/browser/resources/options/chromeos/power_overlay.css
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_list.css
@@ -2,6 +2,14 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#power-overlay > .content-area .option-value {
- padding-left: 5px;
+:host {
+ display: block;
+}
+
+.site-header {
+ width: 100%;
+}
+
+.site-list {
+ -webkit-margin-start: 16px;
}
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list.html b/chromium/chrome/browser/resources/settings/site_settings/site_list.html
new file mode 100644
index 00000000000..51414d12d57
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_list.html
@@ -0,0 +1,56 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/communication-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-submenu.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu-button/paper-menu-button.html">
+<link rel="import" href="chrome://md-settings/prefs/prefs_behavior.html">
+<link rel="import" href="chrome://md-settings/prefs/prefs_types.html">
+<link rel="import" href="chrome://md-settings/site_settings/constants.html">
+<link rel="import" href="chrome://md-settings/site_settings/site_settings_behavior.html">
+
+<dom-module id="settings-site-list">
+ <link rel="import" type="css" href="../settings_shared.css">
+ <link rel="import" type="css" href="site_list.css">
+ <template>
+ <paper-submenu id="category" hidden on-paper-submenu-open="onToggle_"
+ on-paper-submenu-close="onToggle_">
+ <paper-item class="menu-trigger">
+ <div class="site-header horizontal layout">
+ <div class="flex"
+ >[[computeSiteListHeader_(sites_, categoryEnabled)]]</div>
+ <iron-icon id="icon" icon="icons:expand-more"></iron-icon>
+ </div>
+ </paper-item>
+ <paper-menu class="menu-content" id="listContainer">
+ <template is="dom-repeat" items="{{sites_}}">
+ <div class="site-list horizontal layout center">
+ <iron-icon icon="[[computeSiteIcon_(item.url)]]"
+ item-icon></iron-icon>
+ <div class="flex"><paper-item
+ on-tap="onOriginTap_">[[item.url]]</paper-item></div>
+ <paper-menu-button>
+ <paper-icon-button icon="menu"
+ class="dropdown-trigger"></paper-icon-button>
+ <paper-menu id="actionMenu" class="dropdown-content"
+ on-iron-select="onActionMenuIronSelect_">
+ <paper-item value="[[actions_.ALLOW]]"
+ hidden="[[!showAllowAction_]]"
+ >[[i18n_.allowAction]]</paper-item>
+ <paper-item value="[[actions_.BLOCK]]"
+ hidden="[[!showBlockAction_]]"
+ >[[i18n_.blockAction]]</paper-item>
+ <paper-item value="[[actions_.RESET]]"
+ >[[i18n_.resetAction]]</paper-item>
+ </paper-menu>
+ </paper-menu-button>
+ </div>
+ </template>
+ </paper-menu>
+ </paper-submenu>
+ </template>
+ <script src="site_list.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list.js b/chromium/chrome/browser/resources/settings/site_settings/site_list.js
new file mode 100644
index 00000000000..79e64e41a09
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_list.js
@@ -0,0 +1,285 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'settings-site-list' shows a list of Allowed and Blocked sites for a given
+ * category.
+ *
+ * Example:
+ * <settings-site-list prefs="{{prefs}}"
+ * category="[[category]]">
+ * </settings-site-list>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-site-list
+ */
+Polymer({
+ is: 'settings-site-list',
+
+ behaviors: [PrefsBehavior, SiteSettingsBehavior],
+
+ properties: {
+ /**
+ * Preferences state.
+ */
+ prefs: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * The origin that was selected by the user in the dropdown list.
+ */
+ selectedOrigin: {
+ type: String,
+ notify: true,
+ },
+
+ /**
+ * Array of sites to display in the widget.
+ */
+ sites_: {
+ type: Array,
+ value: function() { return []; },
+ observer: 'onDataChanged_',
+ },
+
+ /**
+ * The type of category this widget is displaying data for. Normally
+ * either ALLOW or BLOCK, representing which sites are allowed or blocked
+ * respectively.
+ */
+ categorySubtype: Number,
+
+ /**
+ * Represents the state of the main toggle shown for the category. For
+ * example, the Location category can be set to Block/Ask so false, in that
+ * case, represents Block and true represents Ask.
+ */
+ categoryEnabled: {
+ type: Boolean,
+ observer: 'onDataChanged_',
+ },
+
+ /**
+ * Whether to show the Allow action in the action menu.
+ */
+ showAllowAction_: Boolean,
+
+ /**
+ * Whether to show the Block action in the action menu.
+ */
+ showBlockAction_: Boolean,
+
+ /**
+ * All possible actions in the action menu.
+ */
+ actions_: {
+ readOnly: true,
+ type: Object,
+ values: {
+ ALLOW: 'Allow',
+ BLOCK: 'Block',
+ RESET: 'Reset',
+ }
+ },
+
+ i18n_: {
+ readOnly: true,
+ type: Object,
+ value: function() {
+ return {
+ allowAction: loadTimeData.getString('siteSettingsActionAllow'),
+ blockAction: loadTimeData.getString('siteSettingsActionBlock'),
+ resetAction: loadTimeData.getString('siteSettingsActionReset'),
+ };
+ },
+ },
+ },
+
+ observers: [
+ 'initialize_(prefs.profile.content_settings.exceptions.*,' +
+ 'category, categorySubtype)'
+ ],
+
+ /**
+ * One-time initialization routines for this class.
+ * @private
+ */
+ initialize_: function() {
+ CrSettingsPrefs.initialized.then(function() {
+ this.setUpActionMenu_();
+ this.ensureOpened_();
+ }.bind(this));
+
+ this.populateList_();
+ },
+
+ /**
+ * Ensures the widget is |opened| when needed when displayed initially.
+ */
+ ensureOpened_: function() {
+ // Allowed list is always shown opened by default.
+ if (this.categorySubtype == settings.PermissionValues.ALLOW) {
+ this.$.category.opened = true;
+ return;
+ }
+
+ // Block list should only be shown opened if there is nothing to show in
+ // the allowed list.
+ var pref = this.getPref(
+ this.computeCategoryExceptionsPrefName(this.category));
+ var sites = pref.value;
+ for (var origin in sites) {
+ var site = /** @type {{setting: number}} */(sites[origin]);
+ if (site.setting == settings.PermissionValues.ALLOW)
+ return;
+ }
+
+ this.$.category.opened = true;
+ },
+
+ /**
+ * Handles the data changing, for example when the category is flipped from
+ * ALLOW to BLOCK or sites are added to the list.
+ * @private
+ */
+ onDataChanged_: function(newValue, oldValue) {
+ this.$.category.hidden =
+ !this.showSiteList_(this.sites_, this.categoryEnabled);
+ },
+
+ /**
+ * Handles the expanding and collapsing of the sites list.
+ * @private
+ */
+ onToggle_: function(e) {
+ if (this.$.category.opened)
+ this.$.icon.icon = 'icons:expand-less';
+ else
+ this.$.icon.icon = 'icons:expand-more';
+ },
+
+ /**
+ * Populate the sites list for display.
+ * @private
+ */
+ populateList_: function() {
+ var newList = [];
+ var pref = this.getPref(
+ this.computeCategoryExceptionsPrefName(this.category));
+ var sites = pref.value;
+ for (var origin in sites) {
+ var site = /** @type {{setting: number}} */(sites[origin]);
+ if (site.setting == this.categorySubtype) {
+ var tokens = origin.split(',');
+ newList.push({url: tokens[0]});
+ }
+ }
+
+ this.sites_ = newList;
+ },
+
+ /**
+ * Setup the values to use for the action menu.
+ * @private
+ */
+ setUpActionMenu_: function() {
+ this.showAllowAction_ =
+ this.categorySubtype == settings.PermissionValues.BLOCK;
+ this.showBlockAction_ =
+ this.categorySubtype == settings.PermissionValues.ALLOW &&
+ this.category != settings.ContentSettingsTypes.FULLSCREEN;
+ },
+
+ /**
+ * A handler for selecting a site (by clicking on the origin).
+ * @param {!{model: !{item: !{url: string}}}} event
+ * @private
+ */
+ onOriginTap_: function(event) {
+ this.selectedOrigin = event.model.item.url;
+ },
+
+ /**
+ * A handler for activating one of the menu action items.
+ * @param {!{model: !{item: !{url: string}},
+ * target: !{selectedItems: !{textContent: string}}}} event
+ * @private
+ */
+ onActionMenuIronSelect_: function(event) {
+ var origin = event.model.item.url;
+ var action = event.target.selectedItems[0].textContent;
+ if (action == this.i18n_.resetAction) {
+ this.resetCategoryPermissionForOrigin(origin, this.category);
+ } else {
+ var value = (action == this.i18n_.allowAction) ?
+ settings.PermissionValues.ALLOW :
+ settings.PermissionValues.BLOCK;
+ this.setCategoryPermissionForOrigin(origin, value, this.category);
+ }
+ },
+
+ /**
+ * Returns the appropriate header value for display.
+ * @param {Array<string>} siteList The list of all sites to display for this
+ * category subtype.
+ * @param {boolean} toggleState The state of the global toggle for this
+ * category.
+ * @private
+ */
+ computeSiteListHeader_: function(siteList, toggleState) {
+ if (this.categorySubtype == settings.PermissionValues.ALLOW) {
+ return loadTimeData.getStringF(
+ 'titleAndCount',
+ loadTimeData.getString(
+ toggleState ? 'siteSettingsAllow' : 'siteSettingsExceptions'),
+ siteList.length);
+ } else {
+ return loadTimeData.getStringF(
+ 'titleAndCount',
+ loadTimeData.getString('siteSettingsBlock'),
+ siteList.length);
+ }
+ },
+
+ /**
+ * Returns true if this widget is showing the allow list.
+ * @private
+ */
+ isAllowList_: function() {
+ return this.categorySubtype == settings.PermissionValues.ALLOW;
+ },
+
+ /**
+ * Returns whether to show the site list.
+ * @param {Array} siteList The list of all sites to display for this category
+ * subtype.
+ * @param {boolean} toggleState The state of the global toggle for this
+ * category.
+ * @private
+ */
+ showSiteList_: function(siteList, toggleState) {
+ if (siteList.length == 0)
+ return false;
+ // The Block list is only shown when the category is set to Allow since it
+ // is redundant to also list all the sites that are blocked.
+ if (this.isAllowList_())
+ return true;
+
+ return toggleState;
+ },
+
+ /**
+ * Returns the icon to use for a given site.
+ * @param {string} url The url of the site to fetch the icon for.
+ * @private
+ */
+ computeSiteIcon_: function(url) {
+ // TODO(finnur): For now, we're returning a placeholder image for each site
+ // but the actual favicon for each site will need to be returned.
+ return 'communication:message';
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.html b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.html
new file mode 100644
index 00000000000..0684af28b61
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.html
@@ -0,0 +1,5 @@
+<link rel="import" href="chrome://md-settings/icons.html">
+<link rel="import" href="chrome://md-settings/prefs/prefs_behavior.html">
+<link rel="import" href="chrome://md-settings/site_settings/constants.html">
+<link rel="import" href="chrome://resources/html/assert.html">
+<script src="site_settings_behavior.js"></script> \ No newline at end of file
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
new file mode 100644
index 00000000000..4cfadfae91a
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -0,0 +1,317 @@
+// 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.
+
+/**
+ * @fileoverview Behavior common to Site Settings classes.
+ */
+
+/** @polymerBehavior */
+var SiteSettingsBehaviorImpl = {
+ properties: {
+ /**
+ * The ID of the category this element is displaying data for.
+ * See site_settings/constants.js for possible values.
+ */
+ category: {
+ type: Number,
+ },
+ },
+
+ /**
+ * Returns whether the category default is set to enabled or not.
+ * @param {number} category The category to check.
+ * @return {boolean} True if the category default is set to enabled.
+ * @protected
+ */
+ isCategoryAllowed: function(category) {
+ var pref = this.getPref(this.computeCategoryPrefName(category));
+
+ // FullScreen is Allow vs. Ask.
+ if (category == settings.ContentSettingsTypes.FULLSCREEN)
+ return pref.value != settings.PermissionValues.ASK;
+
+ return pref.value != settings.PermissionValues.BLOCK;
+ },
+
+ /**
+ * Re-sets the category permission for a given origin.
+ * @param {string} origin The origin to change the permission for.
+ * @param {number} category The category permission to change.
+ * @protected
+ */
+ resetCategoryPermissionForOrigin: function(origin, category) {
+ var pref = JSON.parse(JSON.stringify(this.getPref(
+ this.computeCategoryExceptionsPrefName(category))));
+ delete pref.value[origin + ',' + origin];
+ delete pref.value[origin + ',*'];
+ this.setPrefValue(
+ this.computeCategoryExceptionsPrefName(category), pref.value);
+ },
+
+ /**
+ * Sets the category permission for a given origin.
+ * @param {string} origin The origin to change the permission for.
+ * @param {number} value What value to set the permission to.
+ * @param {number} category The category permission to change.
+ * @protected
+ */
+ setCategoryPermissionForOrigin: function(origin, value, category) {
+ var pref = JSON.parse(JSON.stringify(this.getPref(
+ this.computeCategoryExceptionsPrefName(category))));
+ var key1 = origin + ',' + origin;
+ var key2 = origin + ',*';
+ if (pref.value[key1] != undefined)
+ pref.value[key1].setting = value;
+ if (pref.value[key2] != undefined)
+ pref.value[key2].setting = value;
+ this.setPrefValue(
+ this.computeCategoryExceptionsPrefName(category), pref.value);
+ },
+
+ /**
+ * A utility function to lookup a category name from its enum.
+ * @param {number} category The category ID to look up.
+ * @return {string} The category found or blank string if not found.
+ * @protected
+ */
+ computeCategoryTextId: function(category) {
+ switch (category) {
+ case settings.ContentSettingsTypes.CAMERA:
+ return 'camera';
+ case settings.ContentSettingsTypes.COOKIES:
+ return 'cookies';
+ case settings.ContentSettingsTypes.FULLSCREEN:
+ return 'fullscreen';
+ case settings.ContentSettingsTypes.GEOLOCATION:
+ return 'location';
+ case settings.ContentSettingsTypes.IMAGES:
+ return 'images';
+ case settings.ContentSettingsTypes.JAVASCRIPT:
+ return 'javascript';
+ case settings.ContentSettingsTypes.MIC:
+ return 'microphone';
+ case settings.ContentSettingsTypes.NOTIFICATIONS:
+ return 'notifications';
+ case settings.ContentSettingsTypes.POPUPS:
+ return 'popups';
+ default:
+ return '';
+ }
+ },
+
+ /**
+ * A utility function to compute the icon to use for the category.
+ * @param {number} category The category to show the icon for.
+ * @return {string} The id of the icon for the given category.
+ * @protected
+ */
+ computeIconForContentCategory: function(category) {
+ switch (category) {
+ case settings.ContentSettingsTypes.CAMERA:
+ return 'av:videocam';
+ case settings.ContentSettingsTypes.COOKIES:
+ return 'md-settings-icons:cookie';
+ case settings.ContentSettingsTypes.FULLSCREEN:
+ return 'icons:fullscreen';
+ case settings.ContentSettingsTypes.GEOLOCATION:
+ return 'communication:location-on';
+ case settings.ContentSettingsTypes.IMAGES:
+ return 'image:photo';
+ case settings.ContentSettingsTypes.JAVASCRIPT:
+ return 'icons:input';
+ case settings.ContentSettingsTypes.MIC:
+ return 'av:mic';
+ case settings.ContentSettingsTypes.NOTIFICATIONS:
+ return 'social:notifications';
+ case settings.ContentSettingsTypes.POPUPS:
+ return 'icons:open-in-new';
+ default:
+ assertNotReached();
+ return '';
+ }
+ },
+
+ /**
+ * A utility function to compute the title of the category.
+ * @param {number} category The category to show the title for.
+ * @return {string} The title for the given category.
+ * @protected
+ */
+ computeTitleForContentCategory: function(category) {
+ switch (category) {
+ case settings.ContentSettingsTypes.CAMERA:
+ return loadTimeData.getString('siteSettingsCamera');
+ case settings.ContentSettingsTypes.COOKIES:
+ return loadTimeData.getString('siteSettingsCookies');
+ case settings.ContentSettingsTypes.FULLSCREEN:
+ return loadTimeData.getString('siteSettingsFullscreen');
+ case settings.ContentSettingsTypes.GEOLOCATION:
+ return loadTimeData.getString('siteSettingsLocation');
+ case settings.ContentSettingsTypes.IMAGES:
+ return loadTimeData.getString('siteSettingsImages');
+ case settings.ContentSettingsTypes.JAVASCRIPT:
+ return loadTimeData.getString('siteSettingsJavascript');
+ case settings.ContentSettingsTypes.MIC:
+ return loadTimeData.getString('siteSettingsMic');
+ case settings.ContentSettingsTypes.NOTIFICATIONS:
+ return loadTimeData.getString('siteSettingsNotifications');
+ case settings.ContentSettingsTypes.POPUPS:
+ return loadTimeData.getString('siteSettingsPopups');
+ default:
+ assertNotReached();
+ return '';
+ }
+ },
+
+ /**
+ * A utility function to compute the name of the pref for the category.
+ * @param {number} category The category to find the pref name for.
+ * @return {string} The pref name for the given category.
+ * @protected
+ */
+ computeCategoryPrefName: function(category) {
+ return 'profile.default_content_setting_values.' +
+ this.computeCategorySuffix(category);
+ },
+
+ /**
+ * A utility function to compute the name of the pref for the exceptions
+ * for a given category.
+ * @param {number} category The category to find the pref name for.
+ * @return {string} The pref name for the given category exceptions.
+ * @protected
+ */
+ computeCategoryExceptionsPrefName: function(category) {
+ return 'profile.content_settings.exceptions.' +
+ this.computeCategorySuffix(category);
+ },
+
+ /**
+ * A utility function to convert the category enum into its text
+ * representation, for use with prefs.
+ * @param {number} category The category to find the pref name for.
+ * @return {string} The pref name (suffix) for the given category.
+ * @protected
+ */
+ computeCategorySuffix: function(category) {
+ switch (category) {
+ case settings.ContentSettingsTypes.CAMERA:
+ return 'media_stream_camera';
+ case settings.ContentSettingsTypes.COOKIES:
+ return 'cookies';
+ case settings.ContentSettingsTypes.FULLSCREEN:
+ return 'fullscreen';
+ case settings.ContentSettingsTypes.GEOLOCATION:
+ return 'geolocation';
+ case settings.ContentSettingsTypes.IMAGES:
+ return 'images';
+ case settings.ContentSettingsTypes.JAVASCRIPT:
+ return 'javascript';
+ case settings.ContentSettingsTypes.MIC:
+ return 'media_stream_mic';
+ case settings.ContentSettingsTypes.NOTIFICATIONS:
+ return 'notifications';
+ case settings.ContentSettingsTypes.POPUPS:
+ return 'popups';
+ default:
+ assertNotReached();
+ return '';
+ }
+ },
+
+ /**
+ * A utility function to compute the description for the category.
+ * @param {number} category The category to show the description for.
+ * @param {boolean} categoryEnabled The state of the global toggle.
+ * @param {boolean} showRecommendation Whether to show the '(recommended)'
+ * label prefix.
+ * @return {string} The category description.
+ * @protected
+ */
+ computeCategoryDesc: function(category, categoryEnabled, showRecommendation) {
+ switch (category) {
+ case settings.ContentSettingsTypes.JAVASCRIPT:
+ // "Allowed (recommended)" vs "Blocked".
+ if (!categoryEnabled) {
+ return loadTimeData.getString('siteSettingsBlocked');
+ }
+ return showRecommendation ?
+ loadTimeData.getString('siteSettingsAllowedRecommended') :
+ loadTimeData.getString('siteSettingsAllowed');
+ case settings.ContentSettingsTypes.POPUPS:
+ // "Allowed" vs "Blocked (recommended)".
+ if (categoryEnabled) {
+ return loadTimeData.getString('siteSettingsAllowed');
+ }
+ return showRecommendation ?
+ loadTimeData.getString('siteSettingsBlockedRecommended') :
+ loadTimeData.getString('siteSettingsBlocked');
+ case settings.ContentSettingsTypes.NOTIFICATIONS:
+ // "Ask before sending (recommended)" vs "Blocked".
+ if (!categoryEnabled) {
+ return loadTimeData.getString('siteSettingsBlocked');
+ }
+ return showRecommendation ?
+ loadTimeData.getString('siteSettingsAskBeforeSendingRecommended') :
+ loadTimeData.getString('siteSettingsAskBeforeSending');
+ case settings.ContentSettingsTypes.GEOLOCATION:
+ case settings.ContentSettingsTypes.CAMERA:
+ case settings.ContentSettingsTypes.MIC:
+ // "Ask before accessing (recommended)" vs "Blocked".
+ if (!categoryEnabled) {
+ return loadTimeData.getString('siteSettingsBlocked');
+ }
+ return showRecommendation ?
+ loadTimeData.getString(
+ 'siteSettingsAskBeforeAccessingRecommended') :
+ loadTimeData.getString('siteSettingsAskBeforeAccessing');
+ case settings.ContentSettingsTypes.FULLSCREEN:
+ // "Allowed" vs. "Ask first (recommended)".
+ if (categoryEnabled) {
+ return loadTimeData.getString('siteSettingsAllowed');
+ }
+ return showRecommendation ?
+ loadTimeData.getString('siteSettingsAskFirstRecommended') :
+ loadTimeData.getString('siteSettingsAskFirst');
+ case settings.ContentSettingsTypes.COOKIES:
+ // "Allow sites to save and read cookie data" vs "Blocked".
+ if (!categoryEnabled) {
+ return loadTimeData.getString('siteSettingsBlocked');
+ }
+ return showRecommendation ?
+ loadTimeData.getString('siteSettingsCookiesAllowedRecommended') :
+ loadTimeData.getString('siteSettingsCookiesAllowed');
+ case settings.ContentSettingsTypes.IMAGES:
+ if (!categoryEnabled) {
+ return loadTimeData.getString('siteSettingsDontShowImages');
+ }
+ return showRecommendation ?
+ loadTimeData.getString('siteSettingsShowAllRecommended') :
+ loadTimeData.getString('siteSettingsShowAll');
+ default:
+ assertNotReached();
+ return '';
+ }
+ },
+
+ /**
+ * A utility function to compute the category given the description.
+ * @param {string} description The category description to look up.
+ * @return {number} category The category id to return.
+ * @protected
+ */
+ computeCategoryFromDesc: function(description) {
+ for (var type in settings.ContentSettingsTypes) {
+ if (description == this.computeTitleForContentCategory(
+ settings.ContentSettingsTypes[type])) {
+ return settings.ContentSettingsTypes[type];
+ }
+ }
+ assertNotReached();
+ return 0;
+ },
+};
+
+/** @polymerBehavior */
+var SiteSettingsBehavior = [PrefsBehavior, SiteSettingsBehaviorImpl];
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.css b/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.css
new file mode 100644
index 00000000000..305e68ab8f2
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.css
@@ -0,0 +1,15 @@
+/* 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. */
+
+:host {
+ display: block;
+}
+
+settings-site-list {
+ border-bottom: 1px solid #e0e0e0;
+}
+
+settings-site-list:last-of-type {
+ border-bottom: none;
+}
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.html b/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.html
new file mode 100644
index 00000000000..da257106c00
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.html
@@ -0,0 +1,44 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/av-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/communication-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/social-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-icon-item.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item-body.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="chrome://md-settings/prefs/prefs_types.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html">
+<link rel="import" href="chrome://md-settings/site_settings/constants.html">
+<link rel="import" href="chrome://md-settings/site_settings/site_list.html">
+<link rel="import" href="chrome://md-settings/site_settings/site_settings_behavior.html">
+<link rel="import" href="chrome://md-settings/site_settings/site_details.html">
+
+<dom-module id="site-settings-category">
+ <link rel="import" type="css"
+ href="chrome://md-settings/settings_shared.css">
+ <link rel="import" type="css" href="site_settings_category.css">
+ <template>
+ <paper-icon-item>
+ <iron-icon icon="[[computeIconForContentCategory(category)]]"
+ item-icon></iron-icon>
+ <paper-item-body two-line class="flex">
+ <div>[[computeTitleForContentCategory(category)]]</div>
+ <div secondary>
+ [[computeCategoryDesc(category, categoryEnabled, showRecommendation)]]
+ </div>
+ </paper-item-body>
+ <paper-toggle-button id="toggle" checked="{{categoryEnabled}}"
+ on-change="onToggleChange_"></paper-toggle-button>
+ </paper-icon-item>
+ <settings-site-list id="blockList"
+ prefs="{{prefs}}" category="[[category]]"
+ category-enabled="[[categoryEnabled]]"
+ selected-origin="{{selectedOrigin}}"></settings-site-list>
+ <settings-site-list id="allowList"
+ prefs="{{prefs}}" category="[[category]]"
+ category-enabled="[[categoryEnabled]]"
+ selected-origin="{{selectedOrigin}}"></settings-site-list>
+ </template>
+ <script src="site_settings_category.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.js b/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.js
new file mode 100644
index 00000000000..22a334737b4
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_category.js
@@ -0,0 +1,111 @@
+// 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.
+
+/**
+ * @fileoverview
+ * 'site-settings-category' is the polymer element for showing a certain
+ * category under Site Settings.
+ *
+ * Example:
+ *
+ * <site-settings-category prefs="{{prefs}}">
+ * </site-settings-category>
+ * ... other pages ...
+ *
+ * @group Chrome Settings Elements
+ * @element site-settings-category
+ */
+Polymer({
+ is: 'site-settings-category',
+
+ behaviors: [SiteSettingsBehavior],
+
+ properties: {
+ /**
+ * Preferences state.
+ */
+ prefs: {
+ type: Object,
+ notify: true,
+ },
+
+ /**
+ * Represents the state of the main toggle shown for the category. For
+ * example, the Location category can be set to Block/Ask so false, in that
+ * case, represents Block and true represents Ask.
+ */
+ categoryEnabled: Boolean,
+
+ /**
+ * The origin that was selected by the user in the dropdown list.
+ */
+ selectedOrigin: {
+ type: String,
+ notify: true,
+ },
+
+ /**
+ * Whether to show the '(recommended)' label prefix for permissions.
+ */
+ showRecommendation: {
+ type: Boolean,
+ value: true,
+ },
+ },
+
+ observers: [
+ 'onCategoryChanged_(prefs.profile.default_content_setting_values.*, ' +
+ 'category)',
+ ],
+
+ ready: function() {
+ this.$.blockList.categorySubtype = settings.PermissionValues.BLOCK;
+ this.$.allowList.categorySubtype = settings.PermissionValues.ALLOW;
+ },
+
+ /**
+ * A handler for flipping the toggle value.
+ * @private
+ */
+ onToggleChange_: function(event) {
+ switch (this.category) {
+ case settings.ContentSettingsTypes.COOKIES:
+ case settings.ContentSettingsTypes.JAVASCRIPT:
+ case settings.ContentSettingsTypes.POPUPS:
+ // "Allowed" vs "Blocked".
+ this.setPrefValue(this.computeCategoryPrefName(this.category),
+ this.categoryEnabled ?
+ settings.PermissionValues.ALLOW :
+ settings.PermissionValues.BLOCK);
+ break;
+ case settings.ContentSettingsTypes.NOTIFICATIONS:
+ case settings.ContentSettingsTypes.GEOLOCATION:
+ case settings.ContentSettingsTypes.CAMERA:
+ case settings.ContentSettingsTypes.MIC:
+ // "Ask" vs "Blocked".
+ this.setPrefValue(this.computeCategoryPrefName(this.category),
+ this.categoryEnabled ?
+ settings.PermissionValues.ASK :
+ settings.PermissionValues.BLOCK);
+ break;
+ case settings.ContentSettingsTypes.FULLSCREEN:
+ // "Allowed" vs. "Ask first".
+ this.setPrefValue(this.computeCategoryPrefName(this.category),
+ this.categoryEnabled ?
+ settings.PermissionValues.ALLOW :
+ settings.PermissionValues.ASK);
+ break;
+ default:
+ assertNotReached();
+ }
+ },
+
+ /**
+ * Handles changes to the category pref and the |category| member variable.
+ * @private
+ */
+ onCategoryChanged_: function() {
+ this.categoryEnabled = this.isCategoryAllowed(this.category);
+ },
+});
diff --git a/chromium/chrome/browser/resources/settings/site_settings_page/compiled_resources.gyp b/chromium/chrome/browser/resources/settings/site_settings_page/compiled_resources.gyp
new file mode 100644
index 00000000000..033958e5ec3
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/site_settings_page/compiled_resources.gyp
@@ -0,0 +1,26 @@
+# 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.
+{
+ 'targets': [
+ {
+ 'target_name': 'site_settings_page',
+ 'variables': {
+ 'depends': [
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:assert',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:cr',
+ '../../../../../ui/webui/resources/js/compiled_resources.gyp:load_time_data',
+ '../prefs/prefs_behavior.js',
+ '../prefs/prefs_types.js',
+ '../settings_page/settings_animated_pages.js',
+ '../site_settings/constants.js',
+ '../site_settings/site_settings_behavior.js',
+ ],
+ 'externs': [
+ '../../../../../third_party/closure_compiler/externs/settings_private.js',
+ ],
+ },
+ 'includes': ['../../../../../third_party/closure_compiler/compile_js.gypi'],
+ },
+ ],
+}
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 5f19eb5513d..b8383326d65 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
@@ -3,51 +3,14 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/image-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/communication-icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/social-icons.html">
+<link rel="import" href="chrome://md-settings/site_settings/constants.html">
+<link rel="import" href="chrome://md-settings/site_settings/site_settings_behavior.html">
-<dom-module id="cr-settings-site-settings-page">
+<dom-module id="settings-site-settings-page">
<link rel="import" type="css" href="site_settings_page.css">
<template>
- <div class="settings-list">
- <paper-icon-item>
- <iron-icon icon="list" item-icon></iron-icon>
- <div class="flex" i18n-content="siteSettingsAllSites"></div>
- </paper-icon-item>
- <paper-icon-item>
- <iron-icon icon="communication:import-export" item-icon></iron-icon>
- <div class="flex" i18n-content="siteSettingsCookies"></div>
- <div class="option-value" i18n-content="siteSettingsMaySaveCookies">
- </div>
- </paper-icon-item>
- <paper-icon-item>
- <iron-icon icon="communication:location-on" item-icon></iron-icon>
- <div class="flex" i18n-content="siteSettingsLocation"></div>
- <div class="option-value" i18n-content="siteSettingsAskFirst"></div>
- </paper-icon-item>
- <paper-icon-item>
- <iron-icon icon="social:notifications" item-icon></iron-icon>
- <div class="flex" i18n-content="siteSettingsNotifications"></div>
- <div class="option-value" i18n-content="siteSettingsAskFirst"></div>
- </paper-icon-item>
- <paper-icon-item>
- <iron-icon icon="image:photo" item-icon></iron-icon>
- <div class="flex" i18n-content="siteSettingsImages"></div>
- <div class="option-value" i18n-content="siteSettingsAskFirst"></div>
- </paper-icon-item>
- <paper-icon-item>
- <iron-icon icon="input" item-icon></iron-icon>
- <div class="flex" i18n-content="siteSettingsJavascript"></div>
- <div class="option-value" i18n-content="siteSettingsAskFirst"></div>
- </paper-icon-item>
- <paper-icon-item>
- <iron-icon icon="launch" item-icon></iron-icon>
- <div class="flex" i18n-content="siteSettingsPopups"></div>
- <div class="option-value" i18n-content="siteSettingsAskFirst"></div>
- </paper-icon-item>
- <paper-icon-item>
- <iron-icon icon="fullscreen" item-icon></iron-icon>
- <div class="flex" i18n-content="siteSettingsFullscreen"></div>
- <div class="option-value" i18n-content="siteSettingsAskFirst"></div>
- </paper-icon-item>
+ <div class="settings-box">
+ <div id="list" class="settings-list"></div>
</div>
</template>
<script src="site_settings_page.js"></script>
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 19a6177ef31..17ab458cd36 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
@@ -4,22 +4,24 @@
/**
* @fileoverview
- * 'cr-settings-site-settings-page' is the settings page containing privacy and
+ * 'settings-site-settings-page' is the settings page containing privacy and
* security site settings.
*
* Example:
*
* <iron-animated-pages>
- * <cr-settings-site-settings-page prefs="{{prefs}}">
- * </cr-settings-site-settings-page>
+ * <settings-site-settings-page prefs="{{prefs}}">
+ * </settings-site-settings-page>
* ... other pages ...
* </iron-animated-pages>
*
* @group Chrome Settings Elements
- * @element cr-settings-site-settings-page
+ * @element settings-site-settings-page
*/
Polymer({
- is: 'cr-settings-site-settings-page',
+ is: 'settings-site-settings-page',
+
+ behaviors: [SiteSettingsBehavior],
properties: {
/**
@@ -29,5 +31,73 @@ Polymer({
type: Object,
notify: true,
},
+
+ /**
+ * The current active route.
+ */
+ currentRoute: {
+ type: Object,
+ notify: true,
+ },
+ },
+
+ ready: function() {
+ CrSettingsPrefs.initialized.then(function() {
+ // TODO(finnur): Implement 'All Sites' list.
+ this.addCategory(settings.ContentSettingsTypes.COOKIES);
+ this.addCategory(settings.ContentSettingsTypes.GEOLOCATION);
+ this.addCategory(settings.ContentSettingsTypes.CAMERA);
+ this.addCategory(settings.ContentSettingsTypes.MIC);
+ this.addCategory(settings.ContentSettingsTypes.JAVASCRIPT);
+ this.addCategory(settings.ContentSettingsTypes.POPUPS);
+ this.addCategory(settings.ContentSettingsTypes.FULLSCREEN);
+ this.addCategory(settings.ContentSettingsTypes.NOTIFICATIONS);
+ this.addCategory(settings.ContentSettingsTypes.IMAGES);
+ }.bind(this));
+ },
+
+ /**
+ * Adds a single category to the page.
+ * @param {number} category The category to add.
+ */
+ addCategory: function(category) {
+ var root = this.$.list;
+ var paperIcon = document.createElement('paper-icon-item');
+ paperIcon.addEventListener('tap', this.onTapCategory.bind(this));
+
+ var ironIcon = document.createElement('iron-icon');
+ ironIcon.setAttribute('icon', this.computeIconForContentCategory(category));
+ ironIcon.setAttribute('item-icon', '');
+
+ var description = document.createElement('div');
+ description.setAttribute('class', 'flex');
+ description.appendChild(
+ document.createTextNode(this.computeTitleForContentCategory(category)));
+ var setting = document.createElement('div');
+ setting.setAttribute('class', 'option-value');
+
+ setting.appendChild(document.createTextNode(
+ this.computeCategoryDesc(
+ category, this.isCategoryAllowed(category), false)));
+
+ paperIcon.appendChild(ironIcon);
+ paperIcon.appendChild(description);
+ paperIcon.appendChild(setting);
+ root.appendChild(paperIcon);
+ },
+
+ /**
+ * Handles selection of a single category and navigates to the details for
+ * that category.
+ */
+ onTapCategory: function(event) {
+ var description = event.currentTarget.querySelector('.flex').innerText;
+ var page = this.computeCategoryTextId(
+ this.computeCategoryFromDesc(description));
+ this.currentRoute = {
+ page: this.currentRoute.page,
+ section: 'privacy',
+ subpage: ['site-settings', 'site-settings-category-' + page],
+ };
},
});
diff --git a/chromium/chrome/browser/resources/settings/sync_page/sync_page.html b/chromium/chrome/browser/resources/settings/sync_page/sync_page.html
deleted file mode 100644
index 9a8ac2972f6..00000000000
--- a/chromium/chrome/browser/resources/settings/sync_page/sync_page.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html">
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
-
-<dom-module id="cr-settings-sync-page">
- <link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
- <link rel="import" type="css" href="sync_page.css">
- <template>
- <div i18n-content="syncPageTitle"></div>
- <select>
- <option value="sync-everything"
- i18n-content="syncEverythingMenuOption">
- </option>
- <option value="choose-what-to-sync"
- i18n-content="chooseWhatToSyncMenuOption">
- </option>
- </select>
- <div class="checkbox-container">
- <div class="checkbox-container-row">
- <paper-checkbox>
- <span i18n-content="appCheckboxLabel"></span>
- </paper-checkbox>
- <paper-checkbox>
- <span i18n-content="extensionsCheckboxLabel"></span>
- </paper-checkbox>
- <paper-checkbox>
- <span i18n-content="settingsCheckboxLabel"></span>
- </paper-checkbox>
- </div>
- <div class="checkbox-container-row">
- <paper-checkbox>
- <span i18n-content="autofillCheckboxLabel"></span>
- </paper-checkbox>
- <paper-checkbox>
- <span i18n-content="historyCheckboxLabel"></span>
- </paper-checkbox>
- <paper-checkbox>
- <span i18n-content="themesAndWallpapersCheckboxLabel"></span>
- </paper-checkbox>
- </div>
- <div class="checkbox-container-row">
- <paper-checkbox>
- <span i18n-content="bookmarksCheckboxLabel"></span>
- </paper-checkbox>
- <paper-checkbox>
- <span i18n-content="passwordsCheckboxLabel"></span>
- </paper-checkbox>
- <paper-checkbox>
- <span i18n-content="openTabsCheckboxLabel"></span>
- </paper-checkbox>
- </div>
- </div>
- <div i18n-content="encryptionOptionsTitle"></div>
- <div i18n-content="syncDataEncryptedText"></div>
- <paper-radio-group selected="encrypt-with-google">
- <paper-radio-button name="encrypt-with-google"
- i18n-content="encryptWithGoogleCredentialsLabel">
- </paper-radio-button>
- <paper-radio-button name="encrypt-with-passphrase"
- i18n-content="encryptWithSyncPassphraseLabel">
- </paper-radio-button>
- </paper-radio-group>
- <div>
- <paper-button i18n-content="useDefaultSettingsButton"></paper-button>
- <paper-button i18n-content="cancelButton"></paper-button>
- <paper-button i18n-content="okButton"></paper-button>
- </div>
- </template>
- <script src="sync_page.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/sync_page/sync_page.js b/chromium/chrome/browser/resources/settings/sync_page/sync_page.js
deleted file mode 100644
index 062f3d22277..00000000000
--- a/chromium/chrome/browser/resources/settings/sync_page/sync_page.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview
- * 'cr-settings-sync-page' is the settings page containing sync settings.
- *
- * Example:
- *
- * <iron-animated-pages>
- * <cr-settings-sync-page></cr-settings-sync-page>
- * ... other pages ...
- * </iron-animated-pages>
- *
- * @group Chrome Settings Elements
- * @element cr-settings-sync-page
- */
-Polymer({
- is: 'cr-settings-sync-page',
-});
diff --git a/chromium/chrome/browser/resources/settings/users_page/users_page.html b/chromium/chrome/browser/resources/settings/users_page/users_page.html
deleted file mode 100644
index 61326722e64..00000000000
--- a/chromium/chrome/browser/resources/settings/users_page/users_page.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.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-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
-<link rel="import" href="chrome://md-settings/checkbox/checkbox.html">
-<link rel="import" href="chrome://md-settings/settings_page/settings_section.html">
-<link rel="import" href="user_list.html">
-
-<dom-module id="cr-settings-users-page">
- <link rel="import" type="css"
- href="chrome://md-settings/settings_page/settings_page.css">
- <link rel="import" type="css" href="users_page.css">
- <template>
- <div class="page-content">
- <div i18n-content="usersModifiedByOwnerLabel"
- hidden$="{{computeHideOwnerLabel_(isOwner, isWhitelistManaged)}}">
- </div>
- <div i18n-content="settingsManagedLabel"
- hidden$="{{computeHideManagedLabel_(isOwner, isWhitelistManaged)}}">
- </div>
- <div>
- <cr-settings-checkbox
- pref="{{prefs.cros.accounts.allowBWSI}}"
- i18n-values="label:guestBrowsingLabel"
- disabled="{{editingDisabled}}">
- </cr-settings-checkbox>
- <cr-settings-checkbox
- pref="{{prefs.cros.accounts.supervisedUsersEnabled}}"
- i18n-values="label:supervisedUsersLabel"
- disabled="{{editingDisabled}}">
- </cr-settings-checkbox>
- <cr-settings-checkbox
- pref="{{prefs.cros.accounts.showUserNamesOnSignIn}}"
- i18n-values="label:showOnSigninLabel"
- disabled="{{editingDisabled}}">
- </cr-settings-checkbox>
- <cr-settings-checkbox
- pref="{{prefs.cros.accounts.allowGuest}}"
- id="restrictSignIn"
- i18n-values="label:restrictSigninLabel"
- disabled="{{editingDisabled}}" inverted>
- </cr-settings-checkbox>
- </div>
- <div class="users">
- <div>
- <cr-settings-user-list prefs="[[prefs]]"
- disabled="[[editingUsersDisabled]]">
- </cr-settings-user-list>
- </div>
- <div>
- <paper-input id="addUserInput" i18n-values="label:addUsersLabel"
- disabled="[[editingUsersDisabled]]">
- </paper-input>
- <div class="add-user-button layout horizontal end-justified">
- <paper-button i18n-content="addLabel" on-tap="addUser_"
- disabled="[[editingUsersDisabled]]" raised>
- </paper-button>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script src="users_page.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/supervised_user_block_interstitial.css b/chromium/chrome/browser/resources/supervised_user_block_interstitial.css
index 20bba42c781..0c666f05bd1 100644
--- a/chromium/chrome/browser/resources/supervised_user_block_interstitial.css
+++ b/chromium/chrome/browser/resources/supervised_user_block_interstitial.css
@@ -2,114 +2,140 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
body {
- background-color: rgb(230, 230, 230);
+ background-color: rgb(247, 247, 247);
font-size: 10pt;
- margin: 50px 40px 20px 40px;
- text-align: center;
+ margin: 150px 60px 0 30px;
}
#main-frame-blocked {
margin: auto;
- max-width: 540px;
+ max-width: 600px;
min-width: 200px;
}
-#box {
- background-color: rgb(251, 251, 251);
- border: 1px solid rgb(170, 170, 170);
- border-bottom: 1px solid rgb(136, 136, 136);
- border-radius: 3px;
- box-shadow: 0 2px 2px rgb(170, 170, 170);
- color: black;
-}
-
h1 {
- color: rgb(102, 102, 102);
- font-size: 1.3em;
+ font-size: 1.8em;
font-weight: normal;
margin: 5px 0 25px 0;
}
-a {
- color: rgb(17, 85, 204);
- text-decoration: none;
-}
-
-#error-img {
- /* Can't access chrome:// urls from an untrusted renderer process, so embed
- * the resource manually. */
+.avatar-img {
-webkit-user-select: none;
+ border: 3px solid rgb(251, 251, 251);
+ border-radius: 50%;
content: -webkit-image-set(
- url(../../app/theme/default_100_percent/common/error_managed_mode_blocked_page.png) 1x,
- url(../../app/theme/default_200_percent/common/error_managed_mode_blocked_page.png) 2x);
- margin-bottom: 15px;
+ url(../../app/theme/default_100_percent/cros/logo_avatar_circle_blue_color.png) 1x,
+ url(../../app/theme/default_200_percent/cros/logo_avatar_circle_blue_color.png) 2x);
+ margin-bottom: 5px;
+ margin-right: 15px;
+ margin-top: 5px;
+ max-width: 45px;
+ position: relative;
+}
+
+#feedback-link {
+ font-size: 80%;
margin-top: 10px;
}
-#avatar-container {
- position: relative;
+#request-access-button {
+ background-color: rgb(66, 133, 244);
+ color: rgb(255, 255, 255);
+ cursor: pointer;
+ font-size: 12px;
+ font-weight: bold;
+ min-width: 88px;
+ padding: 10px 15px;
+ transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
+ transition-delay: 200ms;
}
-.avatar-img {
- -webkit-user-select: none;
- border: 3px solid rgb(251, 251, 251);
- border-radius: 50%;
- margin-bottom: 5px;
- margin-top: 10px;
- position: relative;
+#request-access-button:hover {
+ background-color: rgb(30, 136, 229);
}
-#content-top {
- margin: 20px 25px;
+#request-access-button:active {
+ background-color: rgb(25,118,210);
+ box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2);
+ transition-delay: 0s;
}
-#block-reason-message {
- font-size: 80%;
- margin-top: 5px;
+#details-button-container {
+ color: rgb(97,97,97);
+ cursor: pointer;
+ display: inline;
+ font-size: 12px;
+ text-decoration: underline;
}
-#feedback-link {
- font-size: 80%;
- margin-top: 10px;
+#button-container {
+ align-items: baseline;
+ display: flex;
+ justify-content: space-between;
+ margin-top: 60px;
}
-button {
- -webkit-user-select: none;
- background-image: linear-gradient(rgb(246, 246, 246) 5%,
- rgb(239, 239, 239) 50%,
- rgb(221, 221, 221));
- border: 1px solid rgb(209, 209, 211);
- border-bottom: 1px solid rgb(193, 193, 195);
- border-radius: 2px;
- box-shadow: inset 0 1px 0 rgb(255, 255, 255);
- color: rgb(102, 102, 102);
+#details {
+ color: rgb(97,97,97);
+ font-size: 14px;
+}
+
+#details-header {
font-weight: bold;
- margin: 5px 3px;
- padding: 8px 13px;
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
}
-@media (min-width: 376px) {
- #back-button {
- width: 100px;
- }
+.custodian-information {
+ align-items: center;
+ display: flex;
+ font-size: 12px;
}
-@media (max-width: 375px) {
+.custodian-name {
+ color: rgb(97,97,97);
+ padding: 1px 0;
+}
+
+.custodian-email {
+ color: rgb(183, 183, 183);
+ padding: 1px 0;
+}
+
+@media (max-width: 600px) {
#button-container {
display: flex;
flex-flow: column;
+ justify-content: flex-start;
+ order: 2;
+ text-transform: uppercase;
}
- #back-button {
+ #details-button-container {
+ font-weight: bold;
+ margin: auto;
order: 2;
}
#request-access-button {
+ margin-bottom: 30px;
order: 1;
+ text-align: center
}
- button {
+ .button {
width: 100%;
}
+
+ #details {
+ margin: auto;
+ order: 1;
+ }
+
+ .hidden-on-mobile {
+ display: none;
+ }
+
+ #main-frame-blocked {
+ display: flex;
+ flex-flow: column;
+ }
}
diff --git a/chromium/chrome/browser/resources/supervised_user_block_interstitial.html b/chromium/chrome/browser/resources/supervised_user_block_interstitial.html
index 169662de94b..45946eebfd8 100644
--- a/chromium/chrome/browser/resources/supervised_user_block_interstitial.html
+++ b/chromium/chrome/browser/resources/supervised_user_block_interstitial.html
@@ -13,34 +13,52 @@
<body>
<div id="main-frame-blocked">
- <div id="box">
- <div id="content-top">
- <img id="error-img">
- <div id="avatar-container">
- <img id="avatar-img" class="avatar-img" hidden>
- <img id="second-avatar-img" class="avatar-img" hidden>
+ <div id="information-container">
+ <h1>
+ <div id="block-page-message" i18n-content="blockPageMessage"></div>
+ <div id="request-failed-message" i18n-content="requestFailedMessage"
+ hidden></div>
+ <div id="request-sent-message" i18n-content="requestSentMessage" hidden>
</div>
- <h1>
- <div id="block-page-message" i18n-content="blockPageMessage"></div>
- <div id="request-failed-message" i18n-content="requestFailedMessage"
- hidden></div>
- <div id="request-sent-message" i18n-content="requestSentMessage" hidden>
+ </h1>
+ <div id="custodians-information" hidden>
+ <div id="custodian-information" class="custodian-information">
+ <img id="custodian-avatar-img" class="avatar-img">
+ <div id="custodian-contact">
+ <div id="custodian-name" class="custodian-name"></div>
+ <div id="custodian-email" class="custodian-email"></div>
+ </div>
+ </div>
+ <div id="second-custodian-information" class="custodian-information" hidden>
+ <img id="second-custodian-avatar-img" class="avatar-img" hidden>
+ <div id="second-custodian-contact">
+ <div id="second-custodian-name" class="custodian-name"></div>
+ <div id="second-custodian-email" class="custodian-email"></div>
</div>
- <div id="block-reason-message" i18n-content="blockReasonMessage"></div>
- </h1>
- <div id="button-container">
- <button id="back-button" class="custom-appearance"
- i18n-content="backButton">
- </button>
- <button id="request-access-button" class="custom-appearance"
- i18n-content="requestAccessButton">
- </button>
</div>
- <h1>
- <a id="feedback-link" is="action-link" i18n-content="feedbackLink"></a>
- </h1>
</div>
</div>
+ <div id="button-container">
+ <div id="details-button-container">
+ <a id="show-details-link" i18n-content="showDetailsLink"
+ hidden class="button">
+ </a>
+ <a id="hide-details-link" i18n-content="hideDetailsLink"
+ hidden class="button"></a>
+ <a id="back-button" i18n-content="backButton"
+ hidden class="button"></a>
+ </div>
+ <div id="request-access-button" class="button"
+ i18n-content="requestAccessButton">
+ </div>
+ </div>
+ <h1>
+ <a id="feedback-link" is="action-link" i18n-content="feedbackLink"></a>
+ </h1>
+ <div id="details" hidden>
+ <p id="details-header" i18n-content="blockReasonHeader"></p>
+ <p id="details-message" i18n-content="blockReasonMessage"></p>
+ </div>
</div>
</body>
</html>
diff --git a/chromium/chrome/browser/resources/supervised_user_block_interstitial.js b/chromium/chrome/browser/resources/supervised_user_block_interstitial.js
index 55b652c34a4..e41ab19fc34 100644
--- a/chromium/chrome/browser/resources/supervised_user_block_interstitial.js
+++ b/chromium/chrome/browser/resources/supervised_user_block_interstitial.js
@@ -22,25 +22,50 @@ function initialize() {
}
var avatarURL1x = loadTimeData.getString('avatarURL1x');
var avatarURL2x = loadTimeData.getString('avatarURL2x');
- if (avatarURL1x) {
- $('avatar-img').style.content = makeImageSet(avatarURL1x, avatarURL2x);
- $('avatar-img').hidden = false;
- $('error-img').hidden = true;
+ var custodianName = loadTimeData.getString('custodianName');
+ if (custodianName) {
+ $('custodians-information').hidden = false;
+ if (avatarURL1x) {
+ $('custodian-avatar-img').style.content =
+ makeImageSet(avatarURL1x, avatarURL2x);
+ }
+ $('custodian-name').innerHTML = custodianName;
+ $('custodian-email').innerHTML = loadTimeData.getString('custodianEmail');
var secondAvatarURL1x = loadTimeData.getString('secondAvatarURL1x');
var secondAvatarURL2x = loadTimeData.getString('secondAvatarURL2x');
- if (secondAvatarURL1x) {
- $('second-avatar-img').style.content =
- makeImageSet(secondAvatarURL1x, secondAvatarURL2x);
- $('second-avatar-img').hidden = false;
- // The avatar images should overlap a bit.
- $('avatar-img').style.left = '6px';
- $('avatar-img').style.zIndex = '1';
- $('second-avatar-img').style.left = '-6px';
+ var secondCustodianName = loadTimeData.getString('secondCustodianName');
+ if (secondCustodianName) {
+ $('second-custodian-information').hidden = false;
+ $('second-custodian-avatar-img').hidden = false;
+ if (secondAvatarURL1x) {
+ $('second-custodian-avatar-img').style.content =
+ makeImageSet(secondAvatarURL1x, secondAvatarURL2x);
+ }
+ $('second-custodian-name').innerHTML = secondCustodianName;
+ $('second-custodian-email').innerHTML = loadTimeData.getString(
+ 'secondCustodianEmail');
}
}
+ var showDetailsLink = loadTimeData.getString('showDetailsLink');
+ $('show-details-link').hidden = !showDetailsLink;
+ $('back-button').hidden = showDetailsLink;
$('back-button').onclick = function(event) {
sendCommand('back');
};
+ $('show-details-link').onclick = function(event) {
+ $('details').hidden = false;
+ $('show-details-link').hidden = true;
+ $('hide-details-link').hidden = false;
+ $('information-container').classList.add('hidden-on-mobile');
+ $('request-access-button').classList.add('hidden-on-mobile');
+ };
+ $('hide-details-link').onclick = function(event) {
+ $('details').hidden = true;
+ $('show-details-link').hidden = false;
+ $('hide-details-link').hidden = true;
+ $('information-container').classList.remove('hidden-on-mobile');
+ $('request-access-button').classList.remove('hidden-on-mobile');
+ };
if (loadTimeData.getBoolean('showFeedbackLink')) {
$('feedback-link').onclick = function(event) {
sendCommand('feedback');
@@ -55,14 +80,15 @@ function initialize() {
* @param {boolean} isSuccessful Whether the request was successful or not.
*/
function setRequestStatus(isSuccessful) {
- $('error-img').hidden = true;
$('block-page-message').hidden = true;
if (isSuccessful) {
$('request-failed-message').hidden = true;
$('request-sent-message').hidden = false;
- if ($('avatar-img').hidden) {
- $('request-sent-message').style.marginTop = '40px';
- }
+ $('show-details-link').hidden = true;
+ $('hide-details-link').hidden = true;
+ $('details').hidden = true;
+ $('back-button').hidden = false;
+ $('request-access-button').hidden = true;
} else {
$('request-failed-message').hidden = false;
$('request-access-button').hidden = false;
diff --git a/chromium/chrome/browser/resources/supervised_user_internals.html b/chromium/chrome/browser/resources/supervised_user_internals.html
index a07d9482658..a61fa7d9860 100644
--- a/chromium/chrome/browser/resources/supervised_user_internals.html
+++ b/chromium/chrome/browser/resources/supervised_user_internals.html
@@ -41,6 +41,14 @@ found in the LICENSE file.
<td class="detail">Result</td>
<td id="try-url-result" class="value"></td>
</tr>
+ <tr>
+ <td class="detail">Manually whitelisted</td>
+ <td id="manual-whitelist" class="value"></td>
+ </tr>
+ <tr>
+ <td class="detail">Part of third party whitelists</td>
+ <td id="whitelists" class="value"></td>
+ </tr>
</table>
</div>
diff --git a/chromium/chrome/browser/resources/supervised_user_internals.js b/chromium/chrome/browser/resources/supervised_user_internals.js
index c3a5666af6d..872cec5c987 100644
--- a/chromium/chrome/browser/resources/supervised_user_internals.js
+++ b/chromium/chrome/browser/resources/supervised_user_internals.js
@@ -8,6 +8,8 @@ cr.define('chrome.supervised_user_internals', function() {
function initialize() {
function submitURL(event) {
$('try-url-result').textContent = '';
+ $('manual-whitelist').textContent = '';
+ $('whitelists').textContent = '';
chrome.send('tryURL', [$('try-url-input').value]);
event.preventDefault();
}
@@ -70,7 +72,9 @@ cr.define('chrome.supervised_user_internals', function() {
}
function receiveTryURLResult(result) {
- $('try-url-result').textContent = result;
+ $('try-url-result').textContent = result['allowResult'];
+ $('manual-whitelist').textContent = result['manual'];
+ $('whitelists').textContent = result['whitelists'];
}
/**
diff --git a/chromium/chrome/browser/resources/uber/uber_frame.css b/chromium/chrome/browser/resources/uber/uber_frame.css
index b14b7beb2cc..36aa40d55d7 100644
--- a/chromium/chrome/browser/resources/uber/uber_frame.css
+++ b/chromium/chrome/browser/resources/uber/uber_frame.css
@@ -46,7 +46,7 @@ li.selected {
}
/* Separates the Help nav item if there are at least 3 items. */
-li:not([hidden]) ~ li:not([hidden]) ~ #helpNavItem {
+li:not([hidden]) ~ li:not([hidden]) ~ #help {
margin-top: 27px;
}
diff --git a/chromium/chrome/browser/resources/uber/uber_frame.html b/chromium/chrome/browser/resources/uber/uber_frame.html
index 7e52aae8923..9d2d99c4e1f 100644
--- a/chromium/chrome/browser/resources/uber/uber_frame.html
+++ b/chromium/chrome/browser/resources/uber/uber_frame.html
@@ -18,24 +18,22 @@
<h1 i18n-content="shortProductName"></h1>
<ul role="tablist">
- <li i18n-values="controls:historyHost;override:overridesHistory;
- group:historyGroup" role="tab" class="hide-in-guest" hidden>
+ <li i18n-values="controls:historyHost;override:overridesHistory" role="tab"
+ id="history" class="hide-in-guest">
<button class="custom-appearance"
i18n-content="historyDisplayName"></button>
</li>
- <li i18n-values="controls:extensionsHost;group:extensionsGroup"
- class="hide-in-guest" role="tab" hidden>
+ <li i18n-values="controls:extensionsHost" role="tab" id="extensions"
+ class="hide-in-guest">
<button class="custom-appearance"
i18n-content="extensionsDisplayName"></button>
</li>
- <li i18n-values="controls:settingsHost;group:settingsGroup" role="tab" hidden>
+ <li i18n-values="controls:settingsHost" role="tab" id="settings">
<button class="custom-appearance"
i18n-content="settingsDisplayName"></button>
</li>
- <li id="helpNavItem" i18n-values="controls:helpHost;group:helpGroup"
- role="tab" hidden>
- <button class="custom-appearance"
- i18n-content="helpDisplayName"></button>
+ <li i18n-values="controls:helpHost" role="tab" id="help">
+ <button class="custom-appearance" i18n-content="helpDisplayName"></button>
</li>
</ul>
diff --git a/chromium/chrome/browser/resources/uber/uber_frame.js b/chromium/chrome/browser/resources/uber/uber_frame.js
index bef246caafb..1b3e967f5af 100644
--- a/chromium/chrome/browser/resources/uber/uber_frame.js
+++ b/chromium/chrome/browser/resources/uber/uber_frame.js
@@ -105,14 +105,11 @@ cr.define('uber_frame', function() {
* Shows nav items belonging to the same group as the selected item.
*/
function showNavItems() {
- var navItems = document.querySelectorAll('li');
- var selectedNavItem = getSelectedNavItem();
- assert(selectedNavItem);
-
- var selectedGroup = selectedNavItem.getAttribute('group');
- for (var i = 0; i < navItems.length; ++i) {
- navItems[i].hidden = navItems[i].getAttribute('group') != selectedGroup;
- }
+ var hideSettingsAndHelp = loadTimeData.getBoolean('hideSettingsAndHelp');
+ $('settings').hidden = hideSettingsAndHelp;
+ $('help').hidden = hideSettingsAndHelp;
+ $('extensions').hidden = loadTimeData.getBoolean('hideExtensions');
+ $('history').hidden = loadTimeData.getBoolean('hideHistory');
}
/**
diff --git a/chromium/chrome/browser/resources/webstore_app/OWNERS b/chromium/chrome/browser/resources/webstore_app/OWNERS
index 720e73f269e..1a39cdb33d7 100644
--- a/chromium/chrome/browser/resources/webstore_app/OWNERS
+++ b/chromium/chrome/browser/resources/webstore_app/OWNERS
@@ -1,11 +1,9 @@
# Extension and apps team owners. Use file history to guide reviewer selection
# as this list is randomized. If editing, see chrome/browser/extensions/OWNERS
-kalman@chromium.org
finnur@chromium.org
mek@chromium.org
asargent@chromium.org
benwells@chromium.org
reillyg@chromium.org
rockot@chromium.org
-miket@chromium.org
rdevlin.cronin@chromium.org