2012-02-23 20:11:04 +00:00
app = function ( ) {
var _this = this ,
$document = $ ( document ) ;
this . $editor = $ ( '#editor' ) ;
this . $editor . bind ( {
'focus' : function ( e ) {
$document . unbind ( '.surfaceView' ) ;
$document . bind ( {
'keydown.surfaceView' : function ( e ) {
return _this . onKeyDown ( e ) ;
} ,
'keyup.surfaceView' : function ( e ) {
return _this . onKeyUp ( e ) ;
} ,
'keypress.surfaceView' : function ( e ) {
return _this . onKeyPress ( e ) ;
}
} ) ;
} ,
'blur' : function ( e ) {
$document . unbind ( '.surfaceView' ) ;
}
} ) ;
this . $editor . mousedown ( function ( e ) {
return _this . onMouseDown ( e ) ;
} ) ;
// Set initial content for the "editor"
this . $editor . html ( "<b>Lorem Ipsum is simply dummy text</b> of the printing and typesetting industry. <b>Lorem Ipsum has been the <i>industry's</i> standard</b> dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it <u>to <b>make <i>a type</i> specimen</b> book.</u>" ) ;
this . $editor . addClass ( 'leafNode' ) ;
2012-02-24 01:43:33 +00:00
this . lastKeydown = null ;
2012-02-23 20:11:04 +00:00
this . keydown = false ;
2012-02-23 23:20:35 +00:00
this . keyup = false ;
this . keypress = false ;
2012-02-23 20:11:04 +00:00
this . mousedown = false ;
2012-02-24 01:43:33 +00:00
this . diff = false ;
2012-02-23 20:11:04 +00:00
this . prevText = app . getDOMText ( this . $editor [ 0 ] ) ;
2012-02-24 01:43:33 +00:00
this . prevOffset = null ;
this . loop = false ;
2012-02-23 20:11:04 +00:00
2012-02-24 01:43:33 +00:00
this . logkey = false ;
2012-02-23 20:11:04 +00:00
} ;
2012-02-23 23:20:35 +00:00
app . prototype . onKeyDown = function ( e ) {
2012-02-24 01:43:33 +00:00
if ( this . logkey ) console . log ( "onKeyDown" , e . which ) ;
2012-02-23 23:20:35 +00:00
this . keydown = true ;
2012-02-24 01:43:33 +00:00
this . lastKeydown = e . which ;
2012-02-23 20:11:04 +00:00
} ;
2012-02-23 23:20:35 +00:00
app . prototype . onKeyUp = function ( e ) {
2012-02-24 01:43:33 +00:00
if ( this . logkey ) console . log ( "onKeyUp" , e . which ) ;
2012-02-23 20:11:04 +00:00
this . keyup = true ;
} ;
2012-02-23 23:20:35 +00:00
app . prototype . onKeyPress = function ( e ) {
2012-02-24 01:43:33 +00:00
if ( this . logkey ) console . log ( "onKeyPress" ) ;
2012-02-23 23:20:35 +00:00
this . keypress = true ;
2012-02-23 20:11:04 +00:00
} ;
2012-02-23 23:20:35 +00:00
app . prototype . onMouseDown = function ( e ) {
2012-02-24 01:43:33 +00:00
if ( this . logkey ) console . log ( "onMouseDown" ) ;
2012-02-23 20:11:04 +00:00
this . mousedown = true ;
2012-02-24 01:43:33 +00:00
if ( this . loop == false ) {
var _this = this ;
setInterval ( function ( ) {
_this . loopFunc ( ) ;
} , 100 ) ;
2012-02-23 20:11:04 +00:00
}
} ;
app . prototype . loopFunc = function ( ) {
2012-02-24 01:43:33 +00:00
var text = app . getDOMText ( this . $editor [ 0 ] ) . replace ( String . fromCharCode ( 32 ) , " " ) . replace ( String . fromCharCode ( 160 ) , " " ) ;
var selection = rangy . getSelection ( ) ;
if ( ! selection . anchorNode ) {
console . log ( "och" ) ;
return ;
}
var offset = this . getOffset ( selection . anchorNode , selection . anchorOffset ) ;
2012-02-23 20:11:04 +00:00
if ( text != this . prevText ) {
2012-02-24 01:43:33 +00:00
var textDiffLength = text . length - this . prevText . length ;
var offsetDiff = offset - this . prevOffset ;
var sameFromLeft = 0 ;
var l = text . length ;
while ( sameFromLeft < l && this . prevText [ sameFromLeft ] == text [ sameFromLeft ] ) {
++ sameFromLeft ;
2012-02-23 23:20:35 +00:00
}
2012-02-24 01:43:33 +00:00
2012-02-23 23:20:35 +00:00
2012-02-24 01:43:33 +00:00
if ( false ) {
console . log ( "change start" , sameFromLeft , offset ) ;
console . log ( "different content" , textDiffLength ) ;
console . log ( "different offset" , offsetDiff ) ;
}
2012-02-23 23:20:35 +00:00
2012-02-24 01:43:33 +00:00
if ( sameFromLeft != offset - textDiffLength ) {
console . log ( 'spell' ) ;
}
2012-02-23 20:11:04 +00:00
2012-02-24 01:43:33 +00:00
/ *
else if ( textDiffLength === - 1 && offsetDiff === - 1 && offset === sameFromLeft ) {
console . log ( "IME.1" ) ;
} else if ( textDiffLength === 0 && offsetDiff === 0 && offset - 1 === sameFromLeft ) {
console . log ( "IME.2" ) ;
} else if ( textDiffLength < 0 || ( offset - textDiffLength ) !== sameFromLeft ) {
console . log ( "SPELLCHECK" ) ;
} else {
console . log ( "!" ) ;
2012-02-23 20:11:04 +00:00
}
2012-02-24 01:43:33 +00:00
* /
2012-02-23 20:11:04 +00:00
2012-02-24 01:43:33 +00:00
if ( textDiffLength !== offsetDiff ) {
//console.log("!!!!#####!!!!!");
2012-02-23 20:11:04 +00:00
}
2012-02-24 01:43:33 +00:00
if ( ! this . keydown ) {
//console.log("## not keyboard");
} else {
//console.log("@@ keyboard");
}
/ *
if ( ( this . keydown || this . keyup ) && this . lastKeydown !== 229 ) {
console . log ( "" ) ;
} else {
console . log ( "Do NOT re-render" ) ;
}
* /
2012-02-23 20:11:04 +00:00
this . prevText = text ;
2012-02-24 01:43:33 +00:00
this . diff = true ;
} else {
this . diff = false ;
2012-02-23 20:11:04 +00:00
}
2012-02-24 01:43:33 +00:00
this . prevOffset = offset ;
2012-02-23 20:11:04 +00:00
this . keypress = false ;
this . keyup = false ;
this . keydown = false ;
this . mousedown = false ;
} ;
app . getDOMText = function ( elem ) {
var nodeType = elem . nodeType ,
ret = '' ;
if ( nodeType === 1 || nodeType === 9 ) {
// Use textContent || innerText for elements
if ( typeof elem . textContent === 'string' ) {
return elem . textContent ;
} else if ( typeof elem . innerText === 'string' ) {
// Replace IE's carriage returns
return elem . innerText . replace ( /\r\n/g , '' ) ;
} else {
// Traverse it's children
for ( elem = elem . firstChild ; elem ; elem = elem . nextSibling ) {
ret += app . getDOMText ( elem ) ;
}
}
} else if ( nodeType === 3 || nodeType === 4 ) {
return elem . nodeValue ;
}
2012-02-24 01:43:33 +00:00
return ret ;
2012-02-23 20:11:04 +00:00
} ;
app . prototype . getOffset = function ( localNode , localOffset ) {
var $node = $ ( localNode ) ;
if ( $node . hasClass ( 'leafNode' ) ) {
return localOffset ;
}
while ( ! $node . hasClass ( 'leafNode' ) ) {
$node = $node . parent ( ) ;
}
var current = [ $node . contents ( ) , 0 ] ;
var stack = [ current ] ;
var offset = 0 ;
while ( stack . length > 0 ) {
if ( current [ 1 ] >= current [ 0 ] . length ) {
stack . pop ( ) ;
current = stack [ stack . length - 1 ] ;
continue ;
}
var item = current [ 0 ] [ current [ 1 ] ] ;
var $item = current [ 0 ] . eq ( current [ 1 ] ) ;
if ( item . nodeType === 3 ) {
if ( item === localNode ) {
offset += localOffset ;
break ;
} else {
offset += item . textContent . length ;
}
} else if ( item . nodeType === 1 ) {
if ( $ ( item ) . attr ( 'contentEditable' ) === "false" ) {
offset += 1 ;
} else {
if ( item === localNode ) {
offset += localOffset ;
break ;
}
stack . push ( [ $item . contents ( ) , 0 ] ) ;
current [ 1 ] ++ ;
current = stack [ stack . length - 1 ] ;
continue ;
}
}
current [ 1 ] ++ ;
}
return offset ;
} ;
$ ( function ( ) {
new app ( ) ;
} ) ;