Commit 43be2077 authored by Kuo Jen Wei's avatar Kuo Jen Wei Committed by Commit Bot

CCA: Prevent chromevox navigate to preview video element

The preview video element is not interactable with chromevox. This CL
prevent chromevox navigate to preview by creating preview video from
template with aria-hide=true.

Bug: 1135052
Test: Manually with chromevox
Test: tast run <DUT> "camera.CCAUI*"

Change-Id: I1dfc87b564dd1db119c10643b587fa254470493a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2454913
Auto-Submit: Inker Kuo <inker@chromium.org>
Commit-Queue: Shik Chen <shik@chromium.org>
Reviewed-by: default avatarShik Chen <shik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814585}
parent e9f7b295
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import {assertInstanceof} from './chrome_util.js';
import {setupI18nElements} from './util.js';
// Disables eslint check for closure compiler constructor type.
/* eslint-disable valid-jsdoc */
......@@ -10,7 +11,7 @@ import {assertInstanceof} from './chrome_util.js';
/**
* Gets an element matching css selector under the target element and checks its
* type.
* @param {(!HTMLElement|!HTMLDocument)} target
* @param {!Node} target
* @param {string} selector
* @param {function(new: T, ...)} type A user-defined constructor.
* @return {T}
......@@ -23,7 +24,7 @@ export function getFrom(target, selector, type) {
/**
* Gets all elements matching css selector under the target element and asserts
* their type to be specific type.
* @param {(!HTMLElement|!HTMLDocument)} target
* @param {!Node} target
* @param {string} selector
* @param {function(new: T, ...)} type A user-defined constructor.
* @return {!NodeList<T>}
......@@ -60,4 +61,16 @@ export function getAll(selector, type) {
return getAllFrom(document, selector, type);
}
/**
* Instantiates template with the target selector.
* @param {string} selector
* @return {!Node}
*/
export function instantiateTemplate(selector) {
const tpl = get(selector, HTMLTemplateElement);
const node = document.importNode(tpl.content, true);
setupI18nElements(node);
return node;
}
/* eslint-enable valid-jsdoc */
......@@ -290,7 +290,8 @@ export function openHelp() {
/**
* Sets up i18n messages on DOM subtree by i18n attributes.
* @param {!HTMLElement} rootElement Root of DOM subtree to be set up with.
* @param {!Node} rootElement Root of DOM subtree to be set up
* with.
*/
export function setupI18nElements(rootElement) {
const getElements = (attr) => rootElement.querySelectorAll('[' + attr + ']');
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import {browserProxy} from '../../browser_proxy/browser_proxy.js';
import {assertInstanceof} from '../../chrome_util.js';
import * as dom from '../../dom.js';
import {DeviceOperator, parseMetadata} from '../../mojo/device_operator.js';
import * as nav from '../../nav.js';
......@@ -109,11 +108,8 @@ export class Preview {
* @return {!Promise} Promise for the operation.
*/
async setSource_(stream) {
const video =
assertInstanceof(document.createElement('video'), HTMLVideoElement);
video.id = 'preview-video';
video.classList = this.video_.classList;
video.muted = true; // Mute to avoid echo from the captured audio.
const node = dom.instantiateTemplate('#preview-video-template');
const video = dom.getFrom(node, 'video', HTMLVideoElement);
await new Promise((resolve) => {
const handler = () => {
video.removeEventListener('canplay', handler);
......@@ -123,7 +119,7 @@ export class Preview {
video.srcObject = stream;
});
await video.play();
this.video_.parentElement.replaceChild(video, this.video_);
this.video_.parentElement.replaceChild(node, this.video_);
this.video_.removeAttribute('srcObject');
this.video_.load();
this.video_ = video;
......
......@@ -225,20 +225,6 @@ export class ResolutionSettings extends BaseSettings {
*/
this.backVideoItem_ = dom.get('#settings-back-videores', HTMLElement);
/**
* @type {!HTMLTemplateElement}
* @private
*/
this.resItemTempl_ =
dom.get('#resolution-item-template', HTMLTemplateElement);
/**
* @type {!HTMLTemplateElement}
* @private
*/
this.extcamItemTempl_ =
dom.get('#extcam-resolution-item-template', HTMLTemplateElement);
/**
* Device setting of front camera. Null if no front camera.
* @type {?DeviceSetting}
......@@ -454,9 +440,8 @@ export class ResolutionSettings extends BaseSettings {
let /** !HTMLElement */ photoItem;
let /** !HTMLElement */ videoItem;
if (deviceId !== focusedId) {
const extItem = /** @type {!HTMLElement} */ (
document.importNode(this.extcamItemTempl_.content, true));
util.setupI18nElements(extItem);
const extItem =
dom.instantiateTemplate('#extcam-resolution-item-template');
[titleItem, photoItem, videoItem] =
dom.getAllFrom(extItem, '.menu-item', HTMLElement);
......@@ -625,8 +610,7 @@ export class ResolutionSettings extends BaseSettings {
.forEach((element) => element.parentNode.removeChild(element));
resolutions.forEach((r) => {
const item = /** @type {!HTMLElement} */ (
document.importNode(this.resItemTempl_.content, true));
const item = dom.instantiateTemplate('#resolution-item-template');
const label = dom.getFrom(item, 'label', HTMLLabelElement);
util.setInkdropEffect(label);
const input = dom.getFrom(item, 'input', HTMLInputElement);
......
......@@ -406,6 +406,10 @@
<audio id="sound-rec-end" src="/sounds/record_end.ogg" data-timeout="450">
<audio id="sound-rec-pause" src="/sounds/record_pause.ogg"
data-timeout="500">
<template id="preview-video-template">
<video id="preview-video" class="preview-content" aria-hidden="true"
muted></video>
</template>
<template id="resolution-item-template">
<label class="menu-item circle resolution-option">
<input class="icon" type="radio" tabindex="0">
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment