@@ -603,8 +603,12 @@ bot.Keyboard.prototype.updateOnCharacter_ = function(key) {
603
603
604
604
var character = this . getChar_ ( key ) ;
605
605
var newPos = goog . dom . selection . getStart ( this . getElement ( ) ) + 1 ;
606
- goog . dom . selection . setText ( this . getElement ( ) , character ) ;
607
- goog . dom . selection . setStart ( this . getElement ( ) , newPos ) ;
606
+ if ( bot . Keyboard . supportsSelection ( this . getElement ( ) ) ) {
607
+ goog . dom . selection . setText ( this . getElement ( ) , character ) ;
608
+ goog . dom . selection . setStart ( this . getElement ( ) , newPos ) ;
609
+ } else {
610
+ this . getElement ( ) . value += character ;
611
+ }
608
612
if ( goog . userAgent . WEBKIT ) {
609
613
this . fireHtmlEvent ( bot . events . EventType . TEXTINPUT ) ;
610
614
}
@@ -629,8 +633,12 @@ bot.Keyboard.prototype.updateOnEnter_ = function() {
629
633
if ( bot . dom . isElement ( this . getElement ( ) , goog . dom . TagName . TEXTAREA ) ) {
630
634
var newPos = goog . dom . selection . getStart ( this . getElement ( ) ) +
631
635
bot . Keyboard . NEW_LINE_ . length ;
632
- goog . dom . selection . setText ( this . getElement ( ) , bot . Keyboard . NEW_LINE_ ) ;
633
- goog . dom . selection . setStart ( this . getElement ( ) , newPos ) ;
636
+ if ( bot . Keyboard . supportsSelection ( this . getElement ( ) ) ) {
637
+ goog . dom . selection . setText ( this . getElement ( ) , bot . Keyboard . NEW_LINE_ ) ;
638
+ goog . dom . selection . setStart ( this . getElement ( ) , newPos ) ;
639
+ } else {
640
+ this . getElement ( ) . value += bot . Keyboard . NEW_LINE_ ;
641
+ }
634
642
if ( ! goog . userAgent . IE ) {
635
643
this . fireHtmlEvent ( bot . events . EventType . INPUT ) ;
636
644
}
@@ -650,6 +658,7 @@ bot.Keyboard.prototype.updateOnBackspaceOrDelete_ = function(key) {
650
658
651
659
// Determine what should be deleted. If text is already selected, that
652
660
// text is deleted, else we move left/right from the current cursor.
661
+ bot . Keyboard . checkCanUpdateSelection_ ( this . getElement ( ) ) ;
653
662
var endpoints = goog . dom . selection . getEndPoints ( this . getElement ( ) ) ;
654
663
if ( endpoints [ 0 ] == endpoints [ 1 ] ) {
655
664
if ( key == bot . Keyboard . Keys . BACKSPACE ) {
@@ -692,6 +701,7 @@ bot.Keyboard.prototype.updateOnBackspaceOrDelete_ = function(key) {
692
701
* @private
693
702
*/
694
703
bot . Keyboard . prototype . updateOnLeftOrRight_ = function ( key ) {
704
+ bot . Keyboard . checkCanUpdateSelection_ ( this . getElement ( ) ) ;
695
705
var element = this . getElement ( ) ;
696
706
var start = goog . dom . selection . getStart ( element ) ;
697
707
var end = goog . dom . selection . getEnd ( element ) ;
@@ -758,6 +768,7 @@ bot.Keyboard.prototype.updateOnLeftOrRight_ = function(key) {
758
768
* @private
759
769
*/
760
770
bot . Keyboard . prototype . updateOnHomeOrEnd_ = function ( key ) {
771
+ bot . Keyboard . checkCanUpdateSelection_ ( this . getElement ( ) ) ;
761
772
var element = this . getElement ( ) ;
762
773
var start = goog . dom . selection . getStart ( element ) ;
763
774
var end = goog . dom . selection . getEnd ( element ) ;
@@ -792,6 +803,47 @@ bot.Keyboard.prototype.updateOnHomeOrEnd_ = function(key) {
792
803
} ;
793
804
794
805
806
+ /**
807
+ * Checks that the cursor position can be updated for the given element.
808
+ * @param {!Element } element The element to test.
809
+ * @throws {Error } If the cursor position cannot be updated for the given
810
+ * element.
811
+ * @see https://code.google.com/p/chromium/issues/detail?id=330456
812
+ * @private
813
+ */
814
+ bot . Keyboard . checkCanUpdateSelection_ = function ( element ) {
815
+ try {
816
+ /** @suppress {suspiciousCode} */
817
+ element . selectionStart ;
818
+ } catch ( ex ) {
819
+ // The native error message is actually pretty informative, just add a
820
+ // reference to the relevant Chrome bug to provide more context.
821
+ if ( ex . message . indexOf ( 'does not support selection.' ) != - 1 ) {
822
+ // message is a readonly property, so need to rethrow.
823
+ throw Error ( ex . message + ' (For more information, see ' +
824
+ 'https://code.google.com/p/chromium/issues/detail?id=330456)' ) ;
825
+ }
826
+ throw ex ;
827
+ }
828
+ } ;
829
+
830
+
831
+ /**
832
+ * @param {!Element } element The element to test.
833
+ * @return {boolean } Whether the given element supports the input element
834
+ * selection API.
835
+ * @see https://code.google.com/p/chromium/issues/detail?id=330456
836
+ */
837
+ bot . Keyboard . supportsSelection = function ( element ) {
838
+ try {
839
+ bot . Keyboard . checkCanUpdateSelection_ ( element ) ;
840
+ } catch ( ex ) {
841
+ return false ;
842
+ }
843
+ return true ;
844
+ } ;
845
+
846
+
795
847
/**
796
848
* @param {number } pos New position of the cursor.
797
849
* @private
0 commit comments