implement Y.*Binding approach
This commit is contained in:
parent
41a88dbc43
commit
94f6a0fd9c
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<textarea style="width:80%;" rows=40 id="textfield" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>
|
<textarea style="width:80%;" rows=40 autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>
|
||||||
<script src="../../y.js"></script>
|
<script src="../../y.js"></script>
|
||||||
<script src='../../../y-websockets-client/y-websockets-client.js'></script>
|
<script src='../../../y-websockets-client/y-websockets-client.js'></script>
|
||||||
<script src="./index.js"></script>
|
<script src="./index.js"></script>
|
||||||
|
@ -11,7 +11,5 @@ window.yTextarea = y
|
|||||||
|
|
||||||
// bind the textarea to a shared text element
|
// bind the textarea to a shared text element
|
||||||
let type = y.define('textarea', Y.Text)
|
let type = y.define('textarea', Y.Text)
|
||||||
let textarea = document.getElementById('textfield')
|
let textarea = document.querySelector('textarea')
|
||||||
let binding = new Y.TextareaBinding(type, textarea)
|
let binding = new Y.TextareaBinding(type, textarea)
|
||||||
|
|
||||||
// binding.destroy()
|
|
||||||
|
15
src/Binding/Binding.js
Normal file
15
src/Binding/Binding.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
import { createMutualExclude } from '../Util/mutualExclude.js'
|
||||||
|
|
||||||
|
|
||||||
|
export default class Binding {
|
||||||
|
constructor (type, target) {
|
||||||
|
this.type = type
|
||||||
|
this.target = target
|
||||||
|
this._mutualExclude = createMutualExclude()
|
||||||
|
}
|
||||||
|
destroy () {
|
||||||
|
this.type = null
|
||||||
|
this.target = null
|
||||||
|
}
|
||||||
|
}
|
0
src/Binding/DomBinding.js
Normal file
0
src/Binding/DomBinding.js
Normal file
45
src/Binding/TextareaBinding.js
Normal file
45
src/Binding/TextareaBinding.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
import Binding from './Binding.js'
|
||||||
|
import simpleDiff from '../Util/simpleDiff.js'
|
||||||
|
import { getRelativePosition, fromRelativePosition } from '../Util/relativePosition.js'
|
||||||
|
|
||||||
|
function typeObserver () {
|
||||||
|
this._mutualExclude(() => {
|
||||||
|
const textarea = this.target
|
||||||
|
const textType = this.type
|
||||||
|
const relativeStart = getRelativePosition(textType, textarea.selectionStart)
|
||||||
|
const relativeEnd = getRelativePosition(textType, textarea.selectionEnd)
|
||||||
|
textarea.value = textType.toString()
|
||||||
|
const start = fromRelativePosition(textType._y, relativeStart)
|
||||||
|
const end = fromRelativePosition(textType._y, relativeEnd)
|
||||||
|
textarea.setSelectionRange(start, end)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function domObserver () {
|
||||||
|
this._mutualExclude(() => {
|
||||||
|
let diff = simpleDiff(this.type.toString(), this.target.value)
|
||||||
|
this.type.delete(diff.pos, diff.remove)
|
||||||
|
this.type.insert(diff.pos, diff.insert)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class TextareaBinding extends Binding {
|
||||||
|
constructor (textType, domTextarea) {
|
||||||
|
// Binding handles textType as this.type and domTextarea as this.target
|
||||||
|
super(textType, domTextarea)
|
||||||
|
// set initial value
|
||||||
|
domTextarea.value = textType.toString()
|
||||||
|
// Observers are handled by this class
|
||||||
|
this._typeObserver = typeObserver.bind(this)
|
||||||
|
this._domObserver = domObserver.bind(this)
|
||||||
|
textType.observe(this._typeObserver)
|
||||||
|
domTextarea.addEventListener('input', this._domObserver)
|
||||||
|
}
|
||||||
|
destroy () {
|
||||||
|
// Remove everything that is handled by this class
|
||||||
|
this.type.unobserve(this._typeObserver)
|
||||||
|
this.target.unobserve(this._domObserver)
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
}
|
4
src/Y.js
4
src/Y.js
@ -22,6 +22,8 @@ import { addStruct as addType } from './Util/structReferences.js'
|
|||||||
import debug from 'debug'
|
import debug from 'debug'
|
||||||
import Transaction from './Transaction.js'
|
import Transaction from './Transaction.js'
|
||||||
|
|
||||||
|
import TextareaBinding from './Binding/TextareaBinding.js'
|
||||||
|
|
||||||
export default class Y extends NamedEventHandler {
|
export default class Y extends NamedEventHandler {
|
||||||
constructor (room, opts, persistence) {
|
constructor (room, opts, persistence) {
|
||||||
super()
|
super()
|
||||||
@ -197,6 +199,8 @@ Y.XmlFragment = YXmlFragment
|
|||||||
Y.XmlText = YXmlText
|
Y.XmlText = YXmlText
|
||||||
Y.XmlHook = YXmlHook
|
Y.XmlHook = YXmlHook
|
||||||
|
|
||||||
|
Y.TextareaBinding = TextareaBinding
|
||||||
|
|
||||||
Y.utils = {
|
Y.utils = {
|
||||||
BinaryDecoder,
|
BinaryDecoder,
|
||||||
UndoManager,
|
UndoManager,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user