react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / browser / ui / ReactInputSelection.js
81155 views/**1* Copyright 2013-2014, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under the BSD-style license found in the5* LICENSE file in the root directory of this source tree. An additional grant6* of patent rights can be found in the PATENTS file in the same directory.7*8* @providesModule ReactInputSelection9*/1011"use strict";1213var ReactDOMSelection = require('ReactDOMSelection');1415var containsNode = require('containsNode');16var focusNode = require('focusNode');17var getActiveElement = require('getActiveElement');1819function isInDocument(node) {20return containsNode(document.documentElement, node);21}2223/**24* @ReactInputSelection: React input selection module. Based on Selection.js,25* but modified to be suitable for react and has a couple of bug fixes (doesn't26* assume buttons have range selections allowed).27* Input selection module for React.28*/29var ReactInputSelection = {3031hasSelectionCapabilities: function(elem) {32return elem && (33(elem.nodeName === 'INPUT' && elem.type === 'text') ||34elem.nodeName === 'TEXTAREA' ||35elem.contentEditable === 'true'36);37},3839getSelectionInformation: function() {40var focusedElem = getActiveElement();41return {42focusedElem: focusedElem,43selectionRange:44ReactInputSelection.hasSelectionCapabilities(focusedElem) ?45ReactInputSelection.getSelection(focusedElem) :46null47};48},4950/**51* @restoreSelection: If any selection information was potentially lost,52* restore it. This is useful when performing operations that could remove dom53* nodes and place them back in, resulting in focus being lost.54*/55restoreSelection: function(priorSelectionInformation) {56var curFocusedElem = getActiveElement();57var priorFocusedElem = priorSelectionInformation.focusedElem;58var priorSelectionRange = priorSelectionInformation.selectionRange;59if (curFocusedElem !== priorFocusedElem &&60isInDocument(priorFocusedElem)) {61if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {62ReactInputSelection.setSelection(63priorFocusedElem,64priorSelectionRange65);66}67focusNode(priorFocusedElem);68}69},7071/**72* @getSelection: Gets the selection bounds of a focused textarea, input or73* contentEditable node.74* -@input: Look up selection bounds of this input75* -@return {start: selectionStart, end: selectionEnd}76*/77getSelection: function(input) {78var selection;7980if ('selectionStart' in input) {81// Modern browser with input or textarea.82selection = {83start: input.selectionStart,84end: input.selectionEnd85};86} else if (document.selection && input.nodeName === 'INPUT') {87// IE8 input.88var range = document.selection.createRange();89// There can only be one selection per document in IE, so it must90// be in our element.91if (range.parentElement() === input) {92selection = {93start: -range.moveStart('character', -input.value.length),94end: -range.moveEnd('character', -input.value.length)95};96}97} else {98// Content editable or old IE textarea.99selection = ReactDOMSelection.getOffsets(input);100}101102return selection || {start: 0, end: 0};103},104105/**106* @setSelection: Sets the selection bounds of a textarea or input and focuses107* the input.108* -@input Set selection bounds of this input or textarea109* -@offsets Object of same form that is returned from get*110*/111setSelection: function(input, offsets) {112var start = offsets.start;113var end = offsets.end;114if (typeof end === 'undefined') {115end = start;116}117118if ('selectionStart' in input) {119input.selectionStart = start;120input.selectionEnd = Math.min(end, input.value.length);121} else if (document.selection && input.nodeName === 'INPUT') {122var range = input.createTextRange();123range.collapse(true);124range.moveStart('character', start);125range.moveEnd('character', end - start);126range.select();127} else {128ReactDOMSelection.setOffsets(input, offsets);129}130}131};132133module.exports = ReactInputSelection;134135136