Commit f436780d authored by Gavin Williams's avatar Gavin Williams Committed by Chromium LUCI CQ

scanning: Move settings dropdown functionality to SelectBehavior

Move the common dropdown code for sorting and choosing the default
option to SelectBehavior.

Add getSelectedOption(), sortOptions(), and isDefaultOption() to each
settings dropdown. These functions are called from SelectBehavior.

Bug: 1168346
Change-Id: I186a6e2ef18b335fdba0f81e4002f4859d27d0eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2638499
Commit-Queue: Gavin Williams <gavinwill@chromium.org>
Reviewed-by: default avatarJesse Schettler <jschettler@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845545}
parent 1b7c1479
......@@ -42,7 +42,7 @@ export function colorModeSelectTest() {
const firstColorMode = ColorMode.COLOR;
const secondColorMode = ColorMode.GRAYSCALE;
colorModeSelect.colorModes = [firstColorMode, secondColorMode];
colorModeSelect.options = [firstColorMode, secondColorMode];
flush();
// Verify that adding color modes results in the dropdown displaying the
......@@ -58,28 +58,25 @@ export function colorModeSelectTest() {
});
test('colorModesSortedAlphabetically', () => {
colorModeSelect.colorModes =
colorModeSelect.options =
[ColorMode.GRAYSCALE, ColorMode.BLACK_AND_WHITE, ColorMode.COLOR];
flush();
// Verify the color modes are sorted alphabetically and that color is
// selected by default.
assertOrderedAlphabetically(
colorModeSelect.colorModes,
(colorMode) => getColorModeString(colorMode));
assertEquals(ColorMode.COLOR.toString(), colorModeSelect.selectedColorMode);
colorModeSelect.options, (colorMode) => getColorModeString(colorMode));
assertEquals(ColorMode.COLOR.toString(), colorModeSelect.selectedOption);
});
test('firstColorModeUsedWhenDefaultNotAvailable', () => {
colorModeSelect.colorModes =
[ColorMode.GRAYSCALE, ColorMode.BLACK_AND_WHITE];
colorModeSelect.options = [ColorMode.GRAYSCALE, ColorMode.BLACK_AND_WHITE];
flush();
// Verify the first color mode in the sorted color mode array is selected by
// default when color is not an available option.
assertEquals(
ColorMode.BLACK_AND_WHITE.toString(),
colorModeSelect.selectedColorMode);
ColorMode.BLACK_AND_WHITE.toString(), colorModeSelect.selectedOption);
});
// Verify the correct default option is selected when a scanner is selected
......@@ -87,22 +84,22 @@ export function colorModeSelectTest() {
test('selectDefaultWhenOptionsChange', () => {
const select =
/** @type {!HTMLSelectElement} */ (colorModeSelect.$$('select'));
colorModeSelect.colorModes =
colorModeSelect.options =
[ColorMode.GRAYSCALE, ColorMode.BLACK_AND_WHITE, ColorMode.COLOR];
flush();
return changeSelect(select, /* value */ null, /* selectedIndex */ 0)
.then(() => {
assertEquals(
ColorMode.BLACK_AND_WHITE.toString(),
colorModeSelect.selectedColorMode);
colorModeSelect.selectedOption);
assertEquals(
ColorMode.BLACK_AND_WHITE.toString(),
select.options[select.selectedIndex].value);
colorModeSelect.colorModes = [ColorMode.GRAYSCALE, ColorMode.COLOR];
colorModeSelect.options = [ColorMode.GRAYSCALE, ColorMode.COLOR];
flush();
assertEquals(
ColorMode.COLOR.toString(), colorModeSelect.selectedColorMode);
ColorMode.COLOR.toString(), colorModeSelect.selectedOption);
assertEquals(
ColorMode.COLOR.toString(),
select.options[select.selectedIndex].value);
......
......@@ -43,7 +43,7 @@ export function pageSizeSelectTest() {
const firstPageSize = PageSize.A4;
const secondPageSize = PageSize.Max;
pageSizeSelect.pageSizes = [firstPageSize, secondPageSize];
pageSizeSelect.options = [firstPageSize, secondPageSize];
flush();
// Verify that adding page sizes results in the dropdown displaying the
......@@ -61,33 +61,33 @@ export function pageSizeSelectTest() {
select, secondPageSize.toString(), /* selectedIndex */ null)
.then(() => {
assertEquals(
secondPageSize.toString(), pageSizeSelect.selectedPageSize);
secondPageSize.toString(), pageSizeSelect.selectedOption);
});
});
test('pageSizesSortedCorrectly', () => {
pageSizeSelect.pageSizes = [PageSize.Letter, PageSize.Max, PageSize.A4];
pageSizeSelect.options = [PageSize.Letter, PageSize.Max, PageSize.A4];
flush();
// Verify the page sizes are sorted alphabetically except for the fit to
// scan area option, which should always be last. Verify that Letter is
// selected by default.
assertOrderedAlphabetically(
pageSizeSelect.pageSizes.slice(0, pageSizeSelect.pageSizes.length - 1),
pageSizeSelect.options.slice(0, pageSizeSelect.options.length - 1),
(pageSize) => getPageSizeString(pageSize));
assertEquals(
PageSize.Max,
pageSizeSelect.pageSizes[pageSizeSelect.pageSizes.length - 1]);
assertEquals(PageSize.Letter.toString(), pageSizeSelect.selectedPageSize);
pageSizeSelect.options[pageSizeSelect.options.length - 1]);
assertEquals(PageSize.Letter.toString(), pageSizeSelect.selectedOption);
});
test('firstPageSizeUsedWhenDefaultNotAvailable', () => {
pageSizeSelect.pageSizes = [PageSize.Max, PageSize.A4];
pageSizeSelect.options = [PageSize.Max, PageSize.A4];
flush();
// Verify the first page size in the sorted page sizes array is selected by
// default when Letter is not an available option.
assertEquals(PageSize.A4.toString(), pageSizeSelect.selectedPageSize);
assertEquals(PageSize.A4.toString(), pageSizeSelect.selectedOption);
});
// Verify the correct default option is selected when a scanner is selected
......@@ -95,19 +95,19 @@ export function pageSizeSelectTest() {
test('selectDefaultWhenOptionsChange', () => {
const select =
/** @type {!HTMLSelectElement} */ (pageSizeSelect.$$('select'));
pageSizeSelect.pageSizes = [PageSize.Letter, PageSize.Max, PageSize.A4];
pageSizeSelect.options = [PageSize.Letter, PageSize.Max, PageSize.A4];
flush();
return changeSelect(select, /* value */ null, /* selectedIndex */ 0)
.then(() => {
assertEquals(PageSize.A4.toString(), pageSizeSelect.selectedPageSize);
assertEquals(PageSize.A4.toString(), pageSizeSelect.selectedOption);
assertEquals(
PageSize.A4.toString(),
select.options[select.selectedIndex].value);
pageSizeSelect.pageSizes = [PageSize.Letter, PageSize.Max];
pageSizeSelect.options = [PageSize.Letter, PageSize.Max];
flush();
assertEquals(
PageSize.Letter.toString(), pageSizeSelect.selectedPageSize);
PageSize.Letter.toString(), pageSizeSelect.selectedOption);
assertEquals(
PageSize.Letter.toString(),
select.options[select.selectedIndex].value);
......
......@@ -36,7 +36,7 @@ export function resolutionSelectTest() {
const firstResolution = 75;
const secondResolution = 300;
resolutionSelect.resolutions = [firstResolution, secondResolution];
resolutionSelect.options = [firstResolution, secondResolution];
flush();
// Verify that adding resolutions results in the dropdown displaying the
......@@ -55,31 +55,29 @@ export function resolutionSelectTest() {
select, secondResolution.toString(), /* selectedIndex */ null)
.then(() => {
assertEquals(
secondResolution.toString(), resolutionSelect.selectedResolution);
secondResolution.toString(), resolutionSelect.selectedOption);
});
});
test('resolutionsSortedCorrectly', () => {
resolutionSelect.resolutions = [150, 300, 75, 600, 1200, 200];
resolutionSelect.options = [150, 300, 75, 600, 1200, 200];
flush();
// Verify the resolutions are sorted in descending order and that 300 is
// selected by default.
for (let i = 0; i < resolutionSelect.resolutions.length - 1; i++) {
assert(
resolutionSelect.resolutions[i] >
resolutionSelect.resolutions[i + 1]);
for (let i = 0; i < resolutionSelect.options.length - 1; i++) {
assert(resolutionSelect.options[i] > resolutionSelect.options[i + 1]);
}
assertEquals('300', resolutionSelect.selectedResolution);
assertEquals('300', resolutionSelect.selectedOption);
});
test('firstResolutionUsedWhenDefaultNotAvailable', () => {
resolutionSelect.resolutions = [150, 75, 600, 1200, 200];
resolutionSelect.options = [150, 75, 600, 1200, 200];
flush();
// Verify the first resolution in the sorted resolution array is selected by
// default when 300 is not an available option.
assertEquals('1200', resolutionSelect.selectedResolution);
assertEquals('1200', resolutionSelect.selectedOption);
});
// Verify the correct default option is selected when a scanner is selected
......@@ -87,16 +85,16 @@ export function resolutionSelectTest() {
test('selectDefaultWhenOptionsChange', () => {
const select =
/** @type {!HTMLSelectElement} */ (resolutionSelect.$$('select'));
resolutionSelect.resolutions = [600, 300, 150];
resolutionSelect.options = [600, 300, 150];
flush();
return changeSelect(select, /* value */ null, /* selectedIndex */ 0)
.then(() => {
assertEquals('600', resolutionSelect.selectedResolution);
assertEquals('600', resolutionSelect.selectedOption);
assertEquals('600', select.options[select.selectedIndex].value);
resolutionSelect.resolutions = [300, 150];
resolutionSelect.options = [300, 150];
flush();
assertEquals('300', resolutionSelect.selectedResolution);
assertEquals('300', resolutionSelect.selectedOption);
assertEquals('300', select.options[select.selectedIndex].value);
});
});
......
......@@ -60,7 +60,7 @@ export function sourceSelectTest() {
const secondSource =
createScannerSource(SourceType.FLATBED, 'platen', pageSizes);
const sourceArr = [firstSource, secondSource];
sourceSelect.sources = sourceArr;
sourceSelect.options = sourceArr;
flush();
// Verify that adding sources results in the dropdown displaying the correct
......@@ -83,10 +83,10 @@ export function sourceSelectTest() {
createScannerSource(SourceType.FLATBED, 'D', pageSizes),
createScannerSource(SourceType.ADF_DUPLEX, 'A', pageSizes),
];
sourceSelect.sources = sources;
sourceSelect.options = sources;
flush();
assertOrderedAlphabetically(
sourceSelect.sources, (source) => getSourceTypeString(source.type));
sourceSelect.options, (source) => getSourceTypeString(source.type));
});
test('flatbedSelectedByDefaultIfProvided', () => {
......@@ -95,11 +95,11 @@ export function sourceSelectTest() {
createScannerSource(SourceType.ADF_SIMPLEX, 'B', pageSizes),
createScannerSource(SourceType.ADF_DUPLEX, 'A', pageSizes),
];
sourceSelect.sources = sources;
sourceSelect.options = sources;
flush();
const flatbedSource =
sourceSelect.sources.find(source => source.type === SourceType.FLATBED);
assertEquals(sourceSelect.selectedSource, flatbedSource.name);
sourceSelect.options.find(source => source.type === SourceType.FLATBED);
assertEquals(sourceSelect.selectedOption, flatbedSource.name);
});
test('firstSourceUsedWhenFlatbedNotProvided', () => {
......@@ -107,8 +107,8 @@ export function sourceSelectTest() {
createScannerSource(SourceType.ADF_SIMPLEX, 'C', pageSizes),
createScannerSource(SourceType.ADF_DUPLEX, 'B', pageSizes),
];
sourceSelect.sources = sources;
sourceSelect.options = sources;
flush();
assertEquals(sourceSelect.selectedSource, sourceSelect.sources[0].name);
assertEquals(sourceSelect.selectedOption, sourceSelect.options[0].name);
});
}
......@@ -40,7 +40,6 @@ js_library("color_mode_select") {
js_library("file_type_select") {
deps = [
":select_behavior",
"//chromeos/components/scanning/mojom:mojom_js_library_for_compile",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:i18n_behavior.m",
......@@ -63,7 +62,6 @@ js_library("resolution_select") {
"//chromeos/components/scanning/mojom:mojom_js_library_for_compile",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:i18n_behavior.m",
"//ui/webui/resources/js:load_time_data.m",
]
}
......@@ -72,7 +70,6 @@ js_library("scan_done_section") {
":scanning_app_types",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:i18n_behavior.m",
"//ui/webui/resources/js:load_time_data.m",
]
}
......@@ -83,13 +80,11 @@ js_library("scan_preview") {
"//chromeos/components/scanning/mojom:mojom_js_library_for_compile",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:i18n_behavior.m",
"//ui/webui/resources/js:load_time_data.m",
]
}
js_library("scan_to_select") {
deps = [
":select_behavior",
"//chromeos/components/scanning/mojom:mojom_js_library_for_compile",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:i18n_behavior.m",
......@@ -100,7 +95,6 @@ js_library("scanner_select") {
deps = [
":scanning_app_types",
":scanning_app_util",
":select_behavior",
"//chromeos/components/scanning/mojom:mojom_js_library_for_compile",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:i18n_behavior.m",
......
......@@ -5,11 +5,11 @@
</span>
<div slot="settings">
<select id="colorModeSelect" class="md-select"
value="{{selectedColorMode::change}}" disabled="[[disabled]]"
value="{{selectedOption::change}}" disabled="[[disabled]]"
aria-labelledby="colorModeLabel">
<template is="dom-repeat" items="[[colorModes]]" as="colorMode">
<template is="dom-repeat" items="[[options]]" as="colorMode">
<option value="[[colorMode]]"
selected$="[[isDefaultColorMode_(colorMode)]]">
selected$="[[isDefaultOption(colorMode)]]">
[[getColorModeString_(colorMode)]]
</option>
</template>
......
......@@ -27,24 +27,18 @@ Polymer({
behaviors: [I18nBehavior, SelectBehavior],
properties: {
/** @type {!Array<chromeos.scanning.mojom.ColorMode>} */
colorModes: {
type: Array,
value: () => [],
},
/**
* @param {number} index
* @return {string}
*/
getOptionAtIndex(index) {
assert(index < this.options.length);
/** @type {string} */
selectedColorMode: {
type: String,
notify: true,
},
return this.options[index].toString();
},
observers: ['onColorModesChange_(colorModes.*)'],
/**
* @param {chromeos.scanning.mojom.ColorMode} mojoColorMode
* @param {!chromeos.scanning.mojom.ColorMode} mojoColorMode
* @return {string}
* @private
*/
......@@ -52,49 +46,17 @@ Polymer({
return getColorModeString(mojoColorMode);
},
/**
* Get the index of the default option if it exists. If not, use the index of
* the first color mode in the color modes array.
* @return {number}
* @private
*/
getDefaultSelectedColorModeIndex_() {
assert(this.colorModes.length > 0);
const defaultColorModeIndex = this.colorModes.findIndex((colorMode) => {
return this.isDefaultColorMode_(colorMode);
sortOptions() {
this.options.sort((a, b) => {
return alphabeticalCompare(getColorModeString(a), getColorModeString(b));
});
return defaultColorModeIndex === -1 ? 0 : defaultColorModeIndex;
},
/**
* Sorts the color modes and sets the selected color mode when the color modes
* array changes.
* @private
*/
onColorModesChange_() {
if (this.colorModes.length > 1) {
this.colorModes.sort((a, b) => {
return alphabeticalCompare(
getColorModeString(a), getColorModeString(b));
});
}
if (this.colorModes.length > 0) {
const selectedColorModeIndex = this.getDefaultSelectedColorModeIndex_();
this.selectedColorMode =
this.colorModes[selectedColorModeIndex].toString();
this.$.colorModeSelect.selectedIndex = selectedColorModeIndex;
}
},
/**
* @param {!chromeos.scanning.mojom.ColorMode} colorMode
* @param {!chromeos.scanning.mojom.ColorMode} option
* @return {boolean}
* @private
*/
isDefaultColorMode_(colorMode) {
return colorMode === DEFAULT_COLOR_MODE;
isDefaultOption(option) {
return option === DEFAULT_COLOR_MODE;
},
});
......@@ -9,8 +9,6 @@ import './strings.m.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {SelectBehavior} from './select_behavior.js';
/**
* @fileoverview
* 'file-type-select' displays the available file types in a dropdown.
......@@ -20,9 +18,12 @@ Polymer({
_template: html`{__html_template__}`,
behaviors: [I18nBehavior, SelectBehavior],
behaviors: [I18nBehavior],
properties: {
/** @type {boolean} */
disabled: Boolean,
/** @type {string} */
selectedFileType: {
type: String,
......
......@@ -5,11 +5,10 @@
</span>
<div slot="settings">
<select id="pageSizeSelect" class="md-select"
value="{{selectedPageSize::change}}" disabled="[[disabled]]"
value="{{selectedOption::change}}" disabled="[[disabled]]"
aria-labelledby="pageSizeLabel">
<template is="dom-repeat" items="[[pageSizes]]" as="pageSize">
<option value="[[pageSize]]"
selected$="[[isDefaultPageSize_(pageSize)]]">
<template is="dom-repeat" items="[[options]]" as="pageSize">
<option value="[[pageSize]]" selected$="[[isDefaultOption(pageSize)]]">
[[getPageSizeString_(pageSize)]]
</option>
</template>
......
......@@ -6,6 +6,7 @@ import './scanning.mojom-lite.js';
import './scan_settings_section.js';
import './strings.m.js';
import {assert} from 'chrome://resources/js/assert.m.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
......@@ -26,22 +27,16 @@ Polymer({
behaviors: [I18nBehavior, SelectBehavior],
properties: {
/** @type {!Array<chromeos.scanning.mojom.PageSize>} */
pageSizes: {
type: Array,
value: () => [],
},
/**
* @param {number} index
* @return {string}
*/
getOptionAtIndex(index) {
assert(index < this.options.length);
/** @type {string} */
selectedPageSize: {
type: String,
notify: true,
},
return this.options[index].toString();
},
observers: ['onPageSizesChange_(pageSizes.*)'],
/**
* @param {!chromeos.scanning.mojom.PageSize} pageSize
* @return {string}
......@@ -51,54 +46,28 @@ Polymer({
return getPageSizeString(pageSize);
},
/**
* Get the index of the default option if it exists. If not, use the index of
* the first page size in the page sizes array.
* @return {number}
* @private
*/
getDefaultSelectedPageSizeIndex_() {
let defaultPageSizeIndex = this.pageSizes.findIndex((pageSize) => {
return this.isDefaultPageSize_(pageSize);
});
return defaultPageSizeIndex === -1 ? 0 : defaultPageSizeIndex;
},
/**
* Sorts the page sizes and sets the selected page size when the page sizes
* array changes.
* @private
*/
onPageSizesChange_() {
if (this.pageSizes.length > 1) {
this.pageSizes.sort((a, b) => {
sortOptions() {
this.options.sort((a, b) => {
return alphabeticalCompare(getPageSizeString(a), getPageSizeString(b));
});
// If the fit to scan area option exists, move it to the end of the page
// sizes array.
const fitToScanAreaIndex = this.pageSizes.findIndex((pageSize) => {
const fitToScanAreaIndex = this.options.findIndex((pageSize) => {
return pageSize === chromeos.scanning.mojom.PageSize.kMax;
});
if (fitToScanAreaIndex !== -1) {
this.pageSizes.push(this.pageSizes.splice(fitToScanAreaIndex, 1)[0]);
}
}
if (this.pageSizes.length > 0) {
const selectedPageSizeIndex = this.getDefaultSelectedPageSizeIndex_();
this.selectedPageSize = this.pageSizes[selectedPageSizeIndex].toString();
this.$.pageSizeSelect.selectedIndex = selectedPageSizeIndex;
if (fitToScanAreaIndex !== -1) {
this.options.push(this.options.splice(fitToScanAreaIndex, 1)[0]);
}
},
/**
* @param {!chromeos.scanning.mojom.PageSize} pageSize
* @param {!chromeos.scanning.mojom.PageSize} option
* @return {boolean}
* @private
*/
isDefaultPageSize_(pageSize) {
return pageSize === DEFAULT_PAGE_SIZE;
isDefaultOption(option) {
return option === DEFAULT_PAGE_SIZE;
},
});
......@@ -5,11 +5,11 @@
</span>
<div slot="settings">
<select id="resolutionSelect" class="md-select"
value="{{selectedResolution::change}}" disabled="[[disabled]]"
value="{{selectedOption::change}}" disabled="[[disabled]]"
aria-labelledby="resolutionLabel">
<template is="dom-repeat" items="[[resolutions]]" as="resolution">
<template is="dom-repeat" items="[[options]]" as="resolution">
<option value="[[resolution]]"
selected$="[[isDefaultResolution_(resolution)]]">
selected$="[[isDefaultOption(resolution)]]">
[[getResolutionString_(resolution)]]
</option>
</template>
......
......@@ -6,8 +6,8 @@ import './scanning.mojom-lite.js';
import './scan_settings_section.js';
import './strings.m.js';
import {assert} from 'chrome://resources/js/assert.m.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {SelectBehavior} from './select_behavior.js';
......@@ -26,73 +26,37 @@ Polymer({
behaviors: [I18nBehavior, SelectBehavior],
properties: {
/** @type {!Array<number>} */
resolutions: {
type: Array,
value: () => [],
},
/**
* @param {number} index
* @return {string}
*/
getOptionAtIndex(index) {
assert(index < this.options.length);
/** @type {string} */
selectedResolution: {
type: String,
notify: true,
},
return this.options[index].toString();
},
observers: ['onResolutionsChange_(resolutions.*)'],
/**
* @param {number} resolution
* @return {string}
* @private
*/
getResolutionString_(resolution) {
return loadTimeData.getStringF(
'resolutionOptionText', resolution.toString());
return this.i18n('resolutionOptionText', resolution);
},
/**
* Get the index of the default option if it exists. If not, use the index of
* the first resolution in the resolutions array.
* @return {number}
* @private
*/
getDefaultSelectedResolutionIndex_() {
const defaultResolutionIndex = this.resolutions.findIndex((resolution) => {
return this.isDefaultResolution_(resolution);
});
return defaultResolutionIndex === -1 ? 0 : defaultResolutionIndex;
},
/**
* Sorts the resolutions and sets the selected resolution when the resolutions
* array changes.
* @private
*/
onResolutionsChange_() {
if (this.resolutions.length > 1) {
sortOptions() {
// Sort the resolutions in descending order.
this.resolutions.sort(function(a, b) {
this.options.sort(function(a, b) {
return b - a;
});
}
if (this.resolutions.length > 0) {
const selectedResolutionIndex = this.getDefaultSelectedResolutionIndex_();
this.selectedResolution =
this.resolutions[selectedResolutionIndex].toString();
this.$.resolutionSelect.selectedIndex = selectedResolutionIndex;
}
},
/**
* @param {number} resolution
* @param {number} option
* @return {boolean}
* @private
*/
isDefaultResolution_(resolution) {
return resolution === DEFAULT_RESOLUTION;
isDefaultOption(option) {
return option === DEFAULT_RESOLUTION;
},
});
......@@ -9,7 +9,6 @@ import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {ScanningBrowserProxy, ScanningBrowserProxyImpl, SelectedPath} from './scanning_browser_proxy.js';
import {SelectBehavior} from './select_behavior.js';
/**
* @fileoverview
......@@ -20,12 +19,15 @@ Polymer({
_template: html`{__html_template__}`,
behaviors: [I18nBehavior, SelectBehavior],
behaviors: [I18nBehavior],
/** @private {?ScanningBrowserProxy}*/
browserProxy_: null,
properties: {
/** @type {boolean} */
disabled: Boolean,
/**
* The lowest level directory in |selectedFilePath|.
* @type {string}
......
......@@ -15,7 +15,6 @@ import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bun
import {ScannerArr} from './scanning_app_types.js';
import {alphabeticalCompare, getScannerDisplayName, tokenToString} from './scanning_app_util.js';
import {SelectBehavior} from './select_behavior.js';
/**
* @fileoverview
......@@ -26,9 +25,12 @@ Polymer({
_template: html`{__html_template__}`,
behaviors: [I18nBehavior, SelectBehavior],
behaviors: [I18nBehavior],
properties: {
/** @type {boolean} */
disabled: Boolean,
/** @type {!ScannerArr} */
scanners: {
type: Array,
......
......@@ -190,9 +190,9 @@
loaded="[[scannersLoaded_]]"
disabled="[[settingsDisabled_]]"
selected-scanner-id="{{selectedScannerId}}"></scanner-select>
<source-select id="sourceSelect" sources="[[capabilities_.sources]]"
<source-select id="sourceSelect" options="[[capabilities_.sources]]"
disabled="[[settingsDisabled_]]"
selected-source="{{selectedSource}}"></source-select>
selected-option="{{selectedSource}}"></source-select>
<scan-to-select id="scanToSelect"
disabled="[[settingsDisabled_]]"
selected-file-path="{{selectedFilePath}}"
......@@ -211,19 +211,19 @@
</cr-button>
<iron-collapse id="collapse" opened="{{opened_}}">
<color-mode-select id="colorModeSelect"
color-modes="[[capabilities_.colorModes]]"
options="[[capabilities_.colorModes]]"
disabled="[[settingsDisabled_]]"
selected-color-mode="{{selectedColorMode}}">
selected-option="{{selectedColorMode}}">
</color-mode-select>
<page-size-select id="pageSizeSelect"
page-sizes="[[selectedSourcePageSizes_]]"
options="[[selectedSourcePageSizes_]]"
disabled="[[settingsDisabled_]]"
selected-page-size="{{selectedPageSize}}">
selected-option="{{selectedPageSize}}">
</page-size-select>
<resolution-select id="resolutionSelect"
resolutions="[[capabilities_.resolutions]]"
options="[[capabilities_.resolutions]]"
disabled="[[settingsDisabled_]]"
selected-resolution="{{selectedResolution}}">
selected-option="{{selectedResolution}}">
</resolution-select>
</iron-collapse>
</template>
......
......@@ -2,16 +2,64 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {assert} from 'chrome://resources/js/assert.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
/**
* Helper functions for custom elements that implement a scan setting using a
* single select element.
* single select element. Elements that use this behavior are required to
* implement getOptionAtIndex(), sortOptions(), and isDefaultOption().
* @polymerBehavior
*/
export const SelectBehavior = {
properties: {
/** @type {boolean} */
disabled: Boolean,
/** @type {!Array} */
options: {
type: Array,
value: () => [],
},
/** @type {string} */
selectedOption: {
type: String,
notify: true,
},
},
observers: ['onOptionsChange_(options.*)'],
/**
* Get the index of the default option if it exists. If not, use the index of
* the first option in the options array.
* @return {number}
* @private
*/
getDefaultSelectedIndex_() {
assert(this.options.length > 0);
const defaultIndex = this.options.findIndex((option) => {
return this.isDefaultOption(option);
});
return defaultIndex === -1 ? 0 : defaultIndex;
},
/**
* Sorts the options and sets the selected option.
* @private
*/
onOptionsChange_() {
if (this.options.length > 1) {
this.sortOptions();
}
if (this.options.length > 0) {
const selectedOptionIndex = this.getDefaultSelectedIndex_();
this.selectedOption = this.getOptionAtIndex(selectedOptionIndex);
this.$$('select').selectedIndex = selectedOptionIndex;
}
},
};
......@@ -5,11 +5,10 @@
</span>
<div slot="settings">
<select id="sourceSelect" class="md-select"
value="{{selectedSource::change}}" disabled="[[disabled]]"
value="{{selectedOption::change}}" disabled="[[disabled]]"
aria-labelledby="sourceLabel">
<template is="dom-repeat" items="[[sources]]" as="source">
<option value="[[source.name]]"
selected$='[[isDefaultSource_(source.type)]]'>
<template is="dom-repeat" items="[[options]]" as="source">
<option value="[[source.name]]" selected$='[[isDefaultOption(source)]]'>
[[getSourceTypeString_(source.type)]]
</option>
</template>
......
......@@ -6,12 +6,16 @@ import './scanning.mojom-lite.js';
import './scan_settings_section.js';
import './strings.m.js';
import {assert} from 'chrome://resources/js/assert.m.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {alphabeticalCompare, getSourceTypeString} from './scanning_app_util.js';
import {SelectBehavior} from './select_behavior.js';
/** @type {chromeos.scanning.mojom.SourceType} */
const DEFAULT_SOURCE_TYPE = chromeos.scanning.mojom.SourceType.kFlatbed;
/**
* @fileoverview
* 'source-select' displays the available scanner sources in a dropdown.
......@@ -23,21 +27,15 @@ Polymer({
behaviors: [I18nBehavior, SelectBehavior],
properties: {
/** @type {!Array<!chromeos.scanning.mojom.ScanSource>} */
sources: {
type: Array,
value: () => [],
},
/**
* @param {number} index
* @return {string}
*/
getOptionAtIndex(index) {
assert(index < this.options.length);
/** @type {string} */
selectedSource: {
type: String,
notify: true,
return this.options[index].name;
},
},
observers: ['onSourcesChange_(sources.*)'],
/**
* @param {chromeos.scanning.mojom.SourceType} mojoSourceType
......@@ -48,44 +46,18 @@ Polymer({
return getSourceTypeString(mojoSourceType);
},
/**
* "Flatbed" should always be the default option if it exists. If not, use
* the first source in the sources array.
* @return {string}
* @private
*/
getDefaultSelectedSource_() {
const flatbedSourceIndex = this.sources.findIndex((source) => {
return source.type === chromeos.scanning.mojom.SourceType.kFlatbed;
});
return flatbedSourceIndex === -1 ? this.sources[0].name :
this.sources[flatbedSourceIndex].name;
},
/**
* Sorts the sources and sets the selected source when sources change.
* @private
*/
onSourcesChange_() {
if (this.sources.length > 1) {
this.sources.sort((a, b) => {
sortOptions() {
this.options.sort((a, b) => {
return alphabeticalCompare(
getSourceTypeString(a.type), getSourceTypeString(b.type));
});
}
if (this.sources.length > 0) {
this.selectedSource = this.getDefaultSelectedSource_();
}
},
/**
* @param {!chromeos.scanning.mojom.SourceType} sourceType
* @param {!chromeos.scanning.mojom.ScanSource} option
* @return {boolean}
* @private
*/
isDefaultSource_(sourceType) {
return sourceType === chromeos.scanning.mojom.SourceType.kFlatbed;
isDefaultOption(option) {
return option.type === DEFAULT_SOURCE_TYPE;
},
});
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