/* tslint:disable:max-line-length */ "use strict"; import React, { Component } from "react"; import EditableListItem from "./EditableListItem"; const _ = browser.i18n.getMessage; interface EditableListProps { data: string[]; itemPattern: RegExp; onChange (data: string[]): void; itemPatternError (err?: string): string; } interface EditableListState { addingNewItem: boolean; rawView: boolean; rawViewValue: string; } export default class EditableList extends Component< EditableListProps, EditableListState> { private rawViewTextArea: HTMLTextAreaElement; constructor (props: EditableListProps) { super(props); this.state = { addingNewItem: false , rawView: false , rawViewValue: "" }; this.handleItemRemove = this.handleItemRemove.bind(this); this.handleItemEdit = this.handleItemEdit.bind(this); this.handleSwitchView = this.handleSwitchView.bind(this); this.handleSaveRaw = this.handleSaveRaw.bind(this); this.handleRawViewTextAreaChange = this.handleRawViewTextAreaChange.bind(this); this.handleAddItem = this.handleAddItem.bind(this); this.handleNewItemRemove = this.handleNewItemRemove.bind(this); this.handleNewItemEdit = this.handleNewItemEdit.bind(this); } public render () { return (
{ this.state.rawView && }

{ this.state.rawView ? ( ) : ( )}
); } private handleItemRemove (item: string) { const newItems = new Set(this.props.data); newItems.delete(item); this.props.onChange([...newItems]); } private handleItemEdit (item: string, newValue: string) { this.props.onChange(this.props.data.map( currentItem => currentItem === item ? newValue : currentItem)); } private handleSwitchView () { this.setState(currentState => { if (currentState.rawView) { return { rawView: false , rawViewValue: "" }; } return { rawView: true , rawViewValue: this.props.data.join("\n") }; }); } private handleSaveRaw () { this.setState(currentState => { const newItems = currentState.rawViewValue.split("\n") .filter(item => item !== ""); if ("itemPattern" in this.props) { for (const item of newItems) { if (!this.props.itemPattern.test(item)) { this.rawViewTextArea.setCustomValidity( this.props.itemPatternError(item)); return; } } this.rawViewTextArea.setCustomValidity(""); } this.props.onChange(newItems); }); } private handleRawViewTextAreaChange (ev: React.ChangeEvent) { if (this.rawViewTextArea.scrollHeight > this.rawViewTextArea.clientHeight) { this.rawViewTextArea.style.height = `${this.rawViewTextArea.scrollHeight}px`; } this.setState({ rawViewValue: ev.target.value }); } private handleAddItem () { this.setState({ addingNewItem: true }); } private handleNewItemRemove () { this.setState({ addingNewItem: false }); } private handleNewItemEdit (item: string, newItem: string) { this.setState({ addingNewItem: false }, () => { this.props.onChange([ ...this.props.data, newItem ]); }); } }