mirror of
https://github.com/mitmproxy/mitmproxy.git
synced 2024-11-23 05:09:57 +00:00
[web] editor config for line endings
This commit is contained in:
parent
f5c597a9e3
commit
4ce7a9ba77
@ -3,3 +3,4 @@ indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
|
@ -1,166 +1,166 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import {Key} from '../../utils.js'
|
||||
|
||||
export default class EditorBase extends Component {
|
||||
|
||||
static propTypes = {
|
||||
content: PropTypes.string.isRequired,
|
||||
onDone: PropTypes.func.isRequired,
|
||||
contentToHtml: PropTypes.func,
|
||||
nodeToContent: PropTypes.func,
|
||||
onStop: PropTypes.func,
|
||||
submitOnEnter: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
tag: PropTypes.string,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
contentToHtml: content => _.escape(content),
|
||||
nodeToContent: node => node.textContent,
|
||||
submitOnEnter: true,
|
||||
className: '',
|
||||
tag: 'div',
|
||||
onStop: _.noop,
|
||||
onMouseDown: _.noop,
|
||||
onBlur: _.noop,
|
||||
onInput: _.noop,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {editable: false}
|
||||
|
||||
this.onPaste = this.onPaste.bind(this)
|
||||
this.onMouseDown = this.onMouseDown.bind(this)
|
||||
this.onMouseUp = this.onMouseUp.bind(this)
|
||||
this.onFocus = this.onFocus.bind(this)
|
||||
this.onClick = this.onClick.bind(this)
|
||||
this.stop = this.stop.bind(this)
|
||||
this.onBlur = this.onBlur.bind(this)
|
||||
this.reset = this.reset.bind(this)
|
||||
this.onKeyDown = this.onKeyDown.bind(this)
|
||||
this.onInput = this.onInput.bind(this)
|
||||
}
|
||||
|
||||
stop() {
|
||||
// a stop would cause a blur as a side-effect.
|
||||
// but a blur event must trigger a stop as well.
|
||||
// to fix this, make stop = blur and do the actual stop in the onBlur handler.
|
||||
ReactDOM.findDOMNode(this).blur()
|
||||
this.props.onStop()
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<this.props.tag
|
||||
{...this.props}
|
||||
tabIndex="0"
|
||||
className={`inline-input ${this.props.className}`}
|
||||
contentEditable={this.state.editable || undefined}
|
||||
onFocus={this.onFocus}
|
||||
onMouseDown={this.onMouseDown}
|
||||
onClick={this.onClick}
|
||||
onBlur={this.onBlur}
|
||||
onKeyDown={this.onKeyDown}
|
||||
onInput={this.onInput}
|
||||
onPaste={this.onPaste}
|
||||
dangerouslySetInnerHTML={{ __html: this.props.contentToHtml(this.props.content) }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
onPaste(e) {
|
||||
e.preventDefault()
|
||||
var content = e.clipboardData.getData('text/plain')
|
||||
document.execCommand('insertHTML', false, content)
|
||||
}
|
||||
|
||||
onMouseDown(e) {
|
||||
this._mouseDown = true
|
||||
window.addEventListener('mouseup', this.onMouseUp)
|
||||
this.props.onMouseDown(e)
|
||||
}
|
||||
|
||||
onMouseUp() {
|
||||
if (this._mouseDown) {
|
||||
this._mouseDown = false
|
||||
window.removeEventListener('mouseup', this.onMouseUp)
|
||||
}
|
||||
}
|
||||
|
||||
onClick(e) {
|
||||
this.onMouseUp()
|
||||
this.onFocus(e)
|
||||
}
|
||||
|
||||
onFocus(e) {
|
||||
if (this._mouseDown || this._ignore_events || this.state.editable) {
|
||||
return
|
||||
}
|
||||
|
||||
// contenteditable in FireFox is more or less broken.
|
||||
// - we need to blur() and then focus(), otherwise the caret is not shown.
|
||||
// - blur() + focus() == we need to save the caret position before
|
||||
// Firefox sometimes just doesn't set a caret position => use caretPositionFromPoint
|
||||
const sel = window.getSelection()
|
||||
let range
|
||||
if (sel.rangeCount > 0) {
|
||||
range = sel.getRangeAt(0)
|
||||
} else if (document.caretPositionFromPoint && e.clientX && e.clientY) {
|
||||
const pos = document.caretPositionFromPoint(e.clientX, e.clientY)
|
||||
range = document.createRange()
|
||||
range.setStart(pos.offsetNode, pos.offset)
|
||||
} else if (document.caretRangeFromPoint && e.clientX && e.clientY) {
|
||||
range = document.caretRangeFromPoint(e.clientX, e.clientY)
|
||||
} else {
|
||||
range = document.createRange()
|
||||
range.selectNodeContents(ReactDOM.findDOMNode(this))
|
||||
}
|
||||
|
||||
this._ignore_events = true
|
||||
this.setState({ editable: true }, () => {
|
||||
const node = ReactDOM.findDOMNode(this)
|
||||
node.blur()
|
||||
node.focus()
|
||||
this._ignore_events = false
|
||||
})
|
||||
}
|
||||
|
||||
onBlur(e) {
|
||||
if (this._ignore_events) {
|
||||
return
|
||||
}
|
||||
window.getSelection().removeAllRanges() //make sure that selection is cleared on blur
|
||||
this.setState({ editable: false })
|
||||
this.props.onDone(this.props.nodeToContent(ReactDOM.findDOMNode(this)))
|
||||
this.props.onBlur(e)
|
||||
}
|
||||
|
||||
reset() {
|
||||
ReactDOM.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content)
|
||||
}
|
||||
|
||||
onKeyDown(e) {
|
||||
e.stopPropagation()
|
||||
switch (e.keyCode) {
|
||||
case Key.ESC:
|
||||
e.preventDefault()
|
||||
this.reset()
|
||||
this.stop()
|
||||
break
|
||||
case Key.ENTER:
|
||||
if (this.props.submitOnEnter && !e.shiftKey) {
|
||||
e.preventDefault()
|
||||
this.stop()
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
onInput() {
|
||||
this.props.onInput(this.props.nodeToContent(ReactDOM.findDOMNode(this)))
|
||||
}
|
||||
}
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import {Key} from '../../utils.js'
|
||||
|
||||
export default class EditorBase extends Component {
|
||||
|
||||
static propTypes = {
|
||||
content: PropTypes.string.isRequired,
|
||||
onDone: PropTypes.func.isRequired,
|
||||
contentToHtml: PropTypes.func,
|
||||
nodeToContent: PropTypes.func,
|
||||
onStop: PropTypes.func,
|
||||
submitOnEnter: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
tag: PropTypes.string,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
contentToHtml: content => _.escape(content),
|
||||
nodeToContent: node => node.textContent,
|
||||
submitOnEnter: true,
|
||||
className: '',
|
||||
tag: 'div',
|
||||
onStop: _.noop,
|
||||
onMouseDown: _.noop,
|
||||
onBlur: _.noop,
|
||||
onInput: _.noop,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {editable: false}
|
||||
|
||||
this.onPaste = this.onPaste.bind(this)
|
||||
this.onMouseDown = this.onMouseDown.bind(this)
|
||||
this.onMouseUp = this.onMouseUp.bind(this)
|
||||
this.onFocus = this.onFocus.bind(this)
|
||||
this.onClick = this.onClick.bind(this)
|
||||
this.stop = this.stop.bind(this)
|
||||
this.onBlur = this.onBlur.bind(this)
|
||||
this.reset = this.reset.bind(this)
|
||||
this.onKeyDown = this.onKeyDown.bind(this)
|
||||
this.onInput = this.onInput.bind(this)
|
||||
}
|
||||
|
||||
stop() {
|
||||
// a stop would cause a blur as a side-effect.
|
||||
// but a blur event must trigger a stop as well.
|
||||
// to fix this, make stop = blur and do the actual stop in the onBlur handler.
|
||||
ReactDOM.findDOMNode(this).blur()
|
||||
this.props.onStop()
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<this.props.tag
|
||||
{...this.props}
|
||||
tabIndex="0"
|
||||
className={`inline-input ${this.props.className}`}
|
||||
contentEditable={this.state.editable || undefined}
|
||||
onFocus={this.onFocus}
|
||||
onMouseDown={this.onMouseDown}
|
||||
onClick={this.onClick}
|
||||
onBlur={this.onBlur}
|
||||
onKeyDown={this.onKeyDown}
|
||||
onInput={this.onInput}
|
||||
onPaste={this.onPaste}
|
||||
dangerouslySetInnerHTML={{ __html: this.props.contentToHtml(this.props.content) }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
onPaste(e) {
|
||||
e.preventDefault()
|
||||
var content = e.clipboardData.getData('text/plain')
|
||||
document.execCommand('insertHTML', false, content)
|
||||
}
|
||||
|
||||
onMouseDown(e) {
|
||||
this._mouseDown = true
|
||||
window.addEventListener('mouseup', this.onMouseUp)
|
||||
this.props.onMouseDown(e)
|
||||
}
|
||||
|
||||
onMouseUp() {
|
||||
if (this._mouseDown) {
|
||||
this._mouseDown = false
|
||||
window.removeEventListener('mouseup', this.onMouseUp)
|
||||
}
|
||||
}
|
||||
|
||||
onClick(e) {
|
||||
this.onMouseUp()
|
||||
this.onFocus(e)
|
||||
}
|
||||
|
||||
onFocus(e) {
|
||||
if (this._mouseDown || this._ignore_events || this.state.editable) {
|
||||
return
|
||||
}
|
||||
|
||||
// contenteditable in FireFox is more or less broken.
|
||||
// - we need to blur() and then focus(), otherwise the caret is not shown.
|
||||
// - blur() + focus() == we need to save the caret position before
|
||||
// Firefox sometimes just doesn't set a caret position => use caretPositionFromPoint
|
||||
const sel = window.getSelection()
|
||||
let range
|
||||
if (sel.rangeCount > 0) {
|
||||
range = sel.getRangeAt(0)
|
||||
} else if (document.caretPositionFromPoint && e.clientX && e.clientY) {
|
||||
const pos = document.caretPositionFromPoint(e.clientX, e.clientY)
|
||||
range = document.createRange()
|
||||
range.setStart(pos.offsetNode, pos.offset)
|
||||
} else if (document.caretRangeFromPoint && e.clientX && e.clientY) {
|
||||
range = document.caretRangeFromPoint(e.clientX, e.clientY)
|
||||
} else {
|
||||
range = document.createRange()
|
||||
range.selectNodeContents(ReactDOM.findDOMNode(this))
|
||||
}
|
||||
|
||||
this._ignore_events = true
|
||||
this.setState({ editable: true }, () => {
|
||||
const node = ReactDOM.findDOMNode(this)
|
||||
node.blur()
|
||||
node.focus()
|
||||
this._ignore_events = false
|
||||
})
|
||||
}
|
||||
|
||||
onBlur(e) {
|
||||
if (this._ignore_events) {
|
||||
return
|
||||
}
|
||||
window.getSelection().removeAllRanges() //make sure that selection is cleared on blur
|
||||
this.setState({ editable: false })
|
||||
this.props.onDone(this.props.nodeToContent(ReactDOM.findDOMNode(this)))
|
||||
this.props.onBlur(e)
|
||||
}
|
||||
|
||||
reset() {
|
||||
ReactDOM.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content)
|
||||
}
|
||||
|
||||
onKeyDown(e) {
|
||||
e.stopPropagation()
|
||||
switch (e.keyCode) {
|
||||
case Key.ESC:
|
||||
e.preventDefault()
|
||||
this.reset()
|
||||
this.stop()
|
||||
break
|
||||
case Key.ENTER:
|
||||
if (this.props.submitOnEnter && !e.shiftKey) {
|
||||
e.preventDefault()
|
||||
this.stop()
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
onInput() {
|
||||
this.props.onInput(this.props.nodeToContent(ReactDOM.findDOMNode(this)))
|
||||
}
|
||||
}
|
||||
|
@ -1,58 +1,58 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import EditorBase from './EditorBase'
|
||||
|
||||
export default class ValidateEditor extends Component {
|
||||
|
||||
static propTypes = {
|
||||
content: PropTypes.string.isRequired,
|
||||
onDone: PropTypes.func.isRequired,
|
||||
onInput: PropTypes.func,
|
||||
isValid: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { currentContent: props.content }
|
||||
this.onInput = this.onInput.bind(this)
|
||||
this.onDone = this.onDone.bind(this)
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setState({ currentContent: nextProps.content })
|
||||
}
|
||||
|
||||
onInput(currentContent) {
|
||||
this.setState({ currentContent })
|
||||
this.props.onInput && this.props.onInput(currentContent)
|
||||
}
|
||||
|
||||
onDone(content) {
|
||||
if (this.props.isValid && !this.props.isValid(content)) {
|
||||
this.refs.editor.reset()
|
||||
content = this.props.content
|
||||
}
|
||||
this.props.onDone(content)
|
||||
}
|
||||
|
||||
render() {
|
||||
let className = this.props.className || ''
|
||||
if (this.props.isValid) {
|
||||
if (this.props.isValid(this.state.currentContent)) {
|
||||
className += ' has-success'
|
||||
} else {
|
||||
className += ' has-warning'
|
||||
}
|
||||
}
|
||||
return (
|
||||
<EditorBase
|
||||
{...this.props}
|
||||
ref="editor"
|
||||
className={className}
|
||||
onDone={this.onDone}
|
||||
onInput={this.onInput}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import EditorBase from './EditorBase'
|
||||
|
||||
export default class ValidateEditor extends Component {
|
||||
|
||||
static propTypes = {
|
||||
content: PropTypes.string.isRequired,
|
||||
onDone: PropTypes.func.isRequired,
|
||||
onInput: PropTypes.func,
|
||||
isValid: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { currentContent: props.content }
|
||||
this.onInput = this.onInput.bind(this)
|
||||
this.onDone = this.onDone.bind(this)
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setState({ currentContent: nextProps.content })
|
||||
}
|
||||
|
||||
onInput(currentContent) {
|
||||
this.setState({ currentContent })
|
||||
this.props.onInput && this.props.onInput(currentContent)
|
||||
}
|
||||
|
||||
onDone(content) {
|
||||
if (this.props.isValid && !this.props.isValid(content)) {
|
||||
this.refs.editor.reset()
|
||||
content = this.props.content
|
||||
}
|
||||
this.props.onDone(content)
|
||||
}
|
||||
|
||||
render() {
|
||||
let className = this.props.className || ''
|
||||
if (this.props.isValid) {
|
||||
if (this.props.isValid(this.state.currentContent)) {
|
||||
className += ' has-success'
|
||||
} else {
|
||||
className += ' has-warning'
|
||||
}
|
||||
}
|
||||
return (
|
||||
<EditorBase
|
||||
{...this.props}
|
||||
ref="editor"
|
||||
className={className}
|
||||
onDone={this.onDone}
|
||||
onInput={this.onInput}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user