Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview Introduces users to ChromeVox. | 6 * @fileoverview Introduces users to ChromeVox. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 goog.provide('Tutorial'); | 9 goog.provide('Tutorial'); |
| 10 | 10 |
| 11 goog.require('Msgs'); | 11 goog.require('Msgs'); |
| 12 | 12 |
| 13 /** | 13 /** |
| 14 * @constructor | 14 * @constructor |
| 15 */ | 15 */ |
| 16 Tutorial = function() { | 16 Tutorial = function() { |
| 17 /** | 17 /** |
| 18 * The 0-based index of the current page of the tutorial. | 18 * The 0-based index of the current page of the tutorial. |
| 19 * @type {number} | 19 * @type {number} |
| 20 * @private | 20 * @private |
| 21 */ | 21 */ |
| 22 this.page_ = 0; | 22 this.page_; |
| 23 | |
| 24 this.page = sessionStorage['tutorial_page_pos'] !== undefined ? | |
| 25 sessionStorage['tutorial_page_pos'] : 0; | |
| 23 }; | 26 }; |
| 24 | 27 |
| 25 /** | 28 /** |
| 26 * Data for the ChromeVox tutorial consisting of a list of pages, | 29 * Data for the ChromeVox tutorial consisting of a list of pages, |
| 27 * each one of which contains a list of objects, where each object has | 30 * each one of which contains a list of objects, where each object has |
| 28 * a message ID for some text, and optional attributes indicating if it's | 31 * a message ID for some text, and optional attributes indicating if it's |
| 29 * a heading, link, text for only one platform, etc. | 32 * a heading, link, text for only one platform, etc. |
| 30 * | 33 * |
| 31 * @type Array<Object> | 34 * @type Array<Array<Object>> |
| 32 */ | 35 */ |
| 33 Tutorial.PAGES = [ | 36 Tutorial.PAGES = [ |
| 34 [ | 37 [ |
| 35 { msgid: 'tutorial_welcome_heading', heading: true }, | 38 { msgid: 'tutorial_welcome_heading', heading: true }, |
| 36 { msgid: 'tutorial_welcome_text' }, | 39 { msgid: 'tutorial_welcome_text' }, |
| 37 { msgid: 'tutorial_enter_to_advance', repeat: true }, | 40 { msgid: 'tutorial_enter_to_advance', repeat: true }, |
| 38 ], | 41 ], |
| 39 [ | 42 [ |
| 40 { msgid: 'tutorial_on_off_heading', heading: true }, | 43 { msgid: 'tutorial_on_off_heading', heading: true }, |
| 41 { msgid: 'tutorial_control' }, | 44 { msgid: 'tutorial_control' }, |
| 42 { msgid: 'tutorial_on_off' }, | 45 { msgid: 'tutorial_on_off' }, |
| 43 { msgid: 'tutorial_enter_to_advance', repeat: true }, | 46 { msgid: 'tutorial_enter_to_advance', repeat: true }, |
| 44 ], | 47 ], |
| 45 [ | 48 [ |
| 46 { msgid: 'tutorial_modifier_heading', heading: true }, | 49 { msgid: 'tutorial_modifier_heading', heading: true }, |
| 47 { msgid: 'tutorial_modifier' }, | 50 { msgid: 'tutorial_modifier' }, |
| 48 { msgid: 'tutorial_chromebook_search', chromebookOnly: true }, | 51 { msgid: 'tutorial_chromebook_search', chromebookOnly: true }, |
| 49 { msgid: 'tutorial_any_key' }, | 52 { msgid: 'tutorial_any_key' }, |
| 50 { msgid: 'tutorial_enter_to_advance', repeat: true }, | 53 { msgid: 'tutorial_enter_to_advance', repeat: true }, |
| 51 ], | 54 ], |
| 52 [ | 55 [ |
| 53 { msgid: 'tutorial_basic_navigation_heading', heading: true }, | 56 { msgid: 'tutorial_basic_navigation_heading', heading: true }, |
| 54 { msgid: 'tutorial_basic_navigation' }, | 57 { msgid: 'tutorial_basic_navigation' }, |
| 55 { msgid: 'tutorial_click_next' }, | 58 { msgid: 'tutorial_click_next' }, |
| 56 ], | 59 ], |
| 57 [ | 60 [ |
| 58 { msgid: 'tutorial_jump_heading', heading: true }, | 61 { msgid: 'tutorial_jump_heading', heading: true }, |
| 59 { msgid: 'tutorial_jump' }, | 62 { msgid: 'tutorial_jump' }, |
| 63 { msgid: 'tutorial_jump_second_heading', heading: true }, | |
| 64 { msgid: 'tutorial_jump_wrap_heading', heading: true }, | |
| 60 { msgid: 'tutorial_click_next' }, | 65 { msgid: 'tutorial_click_next' }, |
| 61 ], | 66 ], |
| 62 [ | 67 [ |
| 63 { msgid: 'tutorial_menus_heading', heading: true }, | 68 { msgid: 'tutorial_menus_heading', heading: true }, |
| 64 { msgid: 'tutorial_menus' }, | 69 { msgid: 'tutorial_menus' }, |
| 65 { msgid: 'tutorial_click_next' }, | 70 { msgid: 'tutorial_click_next' }, |
| 66 ], | 71 ], |
| 67 [ | 72 [ |
| 68 { msgid: 'tutorial_chrome_shortcuts_heading', heading: true }, | 73 { msgid: 'tutorial_chrome_shortcuts_heading', heading: true }, |
| 69 { msgid: 'tutorial_chrome_shortcuts' }, | 74 { msgid: 'tutorial_chrome_shortcuts' }, |
| 70 { msgid: 'tutorial_chromebook_ctrl_forward', chromebookOnly: true }, | 75 { msgid: 'tutorial_chromebook_ctrl_forward', chromebookOnly: true } |
| 71 { msgid: 'tutorial_chromeos_ctrl_f2', chromebookOnly: false }, | |
| 72 ], | 76 ], |
| 73 [ | 77 [ |
| 74 { msgid: 'tutorial_learn_more_heading', heading: true }, | 78 { msgid: 'tutorial_learn_more_heading', heading: true }, |
| 75 { msgid: 'tutorial_learn_more' }, | 79 { msgid: 'tutorial_learn_more' }, |
| 76 { msgid: 'next_command_reference', | 80 { msgid: 'next_command_reference', |
| 77 link: 'http://www.chromevox.com/next_keyboard_shortcuts.html' }, | 81 link: 'http://www.chromevox.com/next_keyboard_shortcuts.html' }, |
| 78 { msgid: 'chrome_keyboard_shortcuts', | 82 { msgid: 'chrome_keyboard_shortcuts', |
| 79 link: 'https://support.google.com/chromebook/answer/183101?hl=en' }, | 83 link: 'https://support.google.com/chromebook/answer/183101?hl=en' }, |
| 80 { msgid: 'touchscreen_accessibility', | 84 { msgid: 'touchscreen_accessibility', |
| 81 link: 'https://support.google.com/chromebook/answer/6103702?hl=en' }, | 85 link: 'https://support.google.com/chromebook/answer/6103702?hl=en' }, |
| 82 ], | 86 ], |
| 83 ]; | 87 ]; |
| 84 | 88 |
| 85 Tutorial.prototype = { | 89 Tutorial.prototype = { |
| 86 /** Open the first page in the tutorial. */ | 90 /** Open the last viewed page in the tutorial. */ |
| 87 firstPage: function() { | 91 lastViewedPage: function() { |
| 88 this.page_ = 0; | 92 this.page = sessionStorage['tutorial_page_pos'] !== undefined ? |
| 89 this.showPage_(); | 93 sessionStorage['tutorial_page_pos'] : 0; |
| 94 if (this.page == -1) | |
| 95 this.page = 0; | |
| 96 this.showCurrentPage_(); | |
| 97 }, | |
| 98 | |
| 99 /** Open the update notes page. */ | |
| 100 updateNotes: function() { | |
| 101 delete sessionStorage['tutorial_page_pos']; | |
| 102 this.page = -1; | |
| 103 this.showPage_([ | |
|
dmazzoni
2016/11/08 00:55:15
Maybe make this a constant at the top like Tutoria
| |
| 104 { msgid: 'update_56_title', heading: true }, | |
| 105 { msgid: 'update_56_intro' }, | |
| 106 { | |
| 107 list: true, | |
| 108 items: [ | |
| 109 {msgid: 'update_56_item_1', listItem: true}, | |
| 110 {msgid: 'update_56_item_2', listItem: true}, | |
| 111 {msgid: 'update_56_item_3', listItem: true}, | |
| 112 ], | |
| 113 }, | |
| 114 { msgid: 'update_56_OUTTRO' }, | |
| 115 ]); | |
| 90 }, | 116 }, |
| 91 | 117 |
| 92 /** Move to the next page in the tutorial. */ | 118 /** Move to the next page in the tutorial. */ |
| 93 nextPage: function() { | 119 nextPage: function() { |
| 94 if (this.page_ < Tutorial.PAGES.length - 1) { | 120 if (this.page < Tutorial.PAGES.length - 1) { |
| 95 this.page_++; | 121 this.page++; |
| 96 this.showPage_(); | 122 this.showCurrentPage_(); |
| 97 } | 123 } |
| 98 }, | 124 }, |
| 99 | 125 |
| 100 /** Move to the previous page in the tutorial. */ | 126 /** Move to the previous page in the tutorial. */ |
| 101 previousPage: function() { | 127 previousPage: function() { |
| 102 if (this.page_ > 0) { | 128 if (this.page > 0) { |
| 103 this.page_--; | 129 this.page--; |
| 104 this.showPage_(); | 130 this.showCurrentPage_(); |
| 105 } | 131 } |
| 106 }, | 132 }, |
| 107 | 133 |
| 108 /** | 134 /** |
| 109 * Recreate the tutorial DOM for page |this.page_|. | 135 * Shows the page for page |this.page_|. |
| 136 */ | |
| 137 showCurrentPage_: function() { | |
| 138 var pageElements = Tutorial.PAGES[this.page] || []; | |
| 139 this.showPage_(pageElements); | |
| 140 }, | |
| 141 | |
| 142 /** | |
| 143 * Recreate the tutorial DOM using |pageElements|. | |
| 144 * @param {!Array<Object>} pageElements | |
| 110 * @private | 145 * @private |
| 111 */ | 146 */ |
| 112 showPage_: function() { | 147 showPage_: function(pageElements) { |
| 113 var tutorialContainer = $('tutorial_main'); | 148 var tutorialContainer = $('tutorial_main'); |
| 114 tutorialContainer.innerHTML = ''; | 149 tutorialContainer.innerHTML = ''; |
| 150 this.buildDom_(pageElements, tutorialContainer); | |
| 151 this.finalizeDom_(); | |
| 152 }, | |
| 115 | 153 |
| 116 var pageElements = Tutorial.PAGES[this.page_]; | 154 /** |
| 155 * Builds a dom under the container | |
| 156 * @param {!Array<Object>} pageElements | |
| 157 * @param {!Node} container | |
| 158 * @private | |
| 159 */ | |
| 160 buildDom_: function(pageElements, container) { | |
| 161 var focus; | |
| 117 for (var i = 0; i < pageElements.length; ++i) { | 162 for (var i = 0; i < pageElements.length; ++i) { |
| 118 var pageElement = pageElements[i]; | 163 var pageElement = pageElements[i]; |
| 119 var msgid = pageElement.msgid; | 164 var msgid = pageElement.msgid; |
| 120 var text = Msgs.getMsg(msgid); | 165 var text = ''; |
| 166 if (msgid) | |
| 167 text = Msgs.getMsg(msgid); | |
| 121 var element; | 168 var element; |
| 122 if (pageElement.heading) { | 169 if (pageElement.heading) { |
| 123 element = document.createElement('h2'); | 170 element = document.createElement('h2'); |
| 171 element.setAttribute('tabindex', -1); | |
| 172 if (!focus) | |
| 173 focus = element; | |
| 174 } else if (pageElement.list) { | |
| 175 element = document.createElement('ul'); | |
| 176 this.buildDom_(pageElement.items, element); | |
| 177 } else if (pageElement.listItem) { | |
| 178 element = document.createElement('li'); | |
| 124 } else if (pageElement.link) { | 179 } else if (pageElement.link) { |
| 125 element = document.createElement('a'); | 180 element = document.createElement('a'); |
| 126 element.href = pageElement.link; | 181 element.href = pageElement.link; |
| 127 element.target = '_blank'; | 182 element.target = '_blank'; |
| 128 } else { | 183 } else { |
| 129 element = document.createElement('p'); | 184 element = document.createElement('p'); |
| 130 } | 185 } |
| 131 element.innerText = text; | 186 if (text) |
| 132 tutorialContainer.appendChild(element); | 187 element.innerText = text; |
| 188 container.appendChild(element); | |
| 133 } | 189 } |
| 190 if (focus) | |
| 191 focus.focus(); | |
| 192 }, | |
| 193 | |
| 194 /** @private */ | |
| 195 finalizeDom_: function() { | |
| 196 var disableNext = this.page == (Tutorial.PAGES.length - 1); | |
| 197 var disablePrevious = this.page == 0; | |
| 198 $('tutorial_next').setAttribute('aria-disabled', disableNext); | |
|
dmazzoni
2016/11/08 00:55:15
Can you do both disabled and aria-disabled? Disabl
David Tseng
2016/11/08 01:20:27
Yeah I tried that too.
No unfortunately that actu
| |
| 199 $('tutorial_previous').setAttribute('aria-disabled', disablePrevious); | |
| 200 }, | |
| 201 | |
| 202 get page() { | |
| 203 return this.page_; | |
| 204 }, | |
| 205 | |
| 206 set page(val) { | |
| 207 this.page_ = val; | |
| 208 sessionStorage['tutorial_page_pos'] = this.page_; | |
| 134 } | 209 } |
| 135 }; | 210 }; |
| OLD | NEW |