94 lines
2.4 KiB
JavaScript
94 lines
2.4 KiB
JavaScript
|
/**
|
||
|
* Copyright 2013-present, Facebook, Inc.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* This source code is licensed under the BSD-style license found in the
|
||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
var _assign = require('object-assign');
|
||
|
|
||
|
var PooledClass = require('./PooledClass');
|
||
|
|
||
|
var getTextContentAccessor = require('./getTextContentAccessor');
|
||
|
|
||
|
/**
|
||
|
* This helper class stores information about text content of a target node,
|
||
|
* allowing comparison of content before and after a given event.
|
||
|
*
|
||
|
* Identify the node where selection currently begins, then observe
|
||
|
* both its text content and its current position in the DOM. Since the
|
||
|
* browser may natively replace the target node during composition, we can
|
||
|
* use its position to find its replacement.
|
||
|
*
|
||
|
* @param {DOMEventTarget} root
|
||
|
*/
|
||
|
function FallbackCompositionState(root) {
|
||
|
this._root = root;
|
||
|
this._startText = this.getText();
|
||
|
this._fallbackText = null;
|
||
|
}
|
||
|
|
||
|
_assign(FallbackCompositionState.prototype, {
|
||
|
destructor: function () {
|
||
|
this._root = null;
|
||
|
this._startText = null;
|
||
|
this._fallbackText = null;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get current text of input.
|
||
|
*
|
||
|
* @return {string}
|
||
|
*/
|
||
|
getText: function () {
|
||
|
if ('value' in this._root) {
|
||
|
return this._root.value;
|
||
|
}
|
||
|
return this._root[getTextContentAccessor()];
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Determine the differing substring between the initially stored
|
||
|
* text content and the current content.
|
||
|
*
|
||
|
* @return {string}
|
||
|
*/
|
||
|
getData: function () {
|
||
|
if (this._fallbackText) {
|
||
|
return this._fallbackText;
|
||
|
}
|
||
|
|
||
|
var start;
|
||
|
var startValue = this._startText;
|
||
|
var startLength = startValue.length;
|
||
|
var end;
|
||
|
var endValue = this.getText();
|
||
|
var endLength = endValue.length;
|
||
|
|
||
|
for (start = 0; start < startLength; start++) {
|
||
|
if (startValue[start] !== endValue[start]) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var minEnd = startLength - start;
|
||
|
for (end = 1; end <= minEnd; end++) {
|
||
|
if (startValue[startLength - end] !== endValue[endLength - end]) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var sliceTail = end > 1 ? 1 - end : undefined;
|
||
|
this._fallbackText = endValue.slice(start, sliceTail);
|
||
|
return this._fallbackText;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
PooledClass.addPoolingTo(FallbackCompositionState);
|
||
|
|
||
|
module.exports = FallbackCompositionState;
|