6464else if ( typeof define == "function" && define . amd ) // AMD
6565return define ( [ ] , mod ) ;
6666else // Plain browser env
67- this . CodeMirror = mod ( ) ;
67+ ( this || window ) . CodeMirror = mod ( ) ;
6868} ) ( function ( ) {
6969"use strict" ;
7070
874874// given line.
875875function updateWidgetHeight ( line ) {
876876if ( line . widgets ) for ( var i = 0 ; i < line . widgets . length ; ++ i )
877- line . widgets [ i ] . height = line . widgets [ i ] . node . offsetHeight ;
877+ line . widgets [ i ] . height = line . widgets [ i ] . node . parentNode . offsetHeight ;
878878}
879879
880880// Do a bulk-read of the DOM positions and sizes needed to draw the
11451145if ( ! cm . state . focused ) { cm . display . input . focus ( ) ; onFocus ( cm ) ; }
11461146}
11471147
1148- function isReadOnly ( cm ) {
1149- return cm . options . readOnly || cm . doc . cantEdit ;
1150- }
1151-
11521148// This will be set to an array of strings when copying, so that,
11531149// when pasting, we know what kind of selections the copied text
11541150// was made out of.
12031199var pasted = e . clipboardData && e . clipboardData . getData ( "text/plain" ) ;
12041200if ( pasted ) {
12051201e . preventDefault ( ) ;
1206- if ( ! isReadOnly ( cm ) && ! cm . options . disableInput )
1202+ if ( ! cm . isReadOnly ( ) && ! cm . options . disableInput )
12071203runInOp ( cm , function ( ) { applyTextInput ( cm , pasted , 0 , null , "paste" ) ; } ) ;
12081204return true ;
12091205}
13061302} ) ;
13071303
13081304on ( te , "paste" , function ( e ) {
1309- if ( handlePaste ( e , cm ) ) return true ;
1305+ if ( signalDOMEvent ( cm , e ) || handlePaste ( e , cm ) ) return
13101306
13111307cm . state . pasteIncoming = true ;
13121308input . fastPoll ( ) ;
13401336on ( te , "copy" , prepareCopyCut ) ;
13411337
13421338on ( display . scroller , "paste" , function ( e ) {
1343- if ( eventInWidget ( display , e ) ) return ;
1339+ if ( eventInWidget ( display , e ) || signalDOMEvent ( cm , e ) ) return ;
13441340cm . state . pasteIncoming = true ;
13451341input . focus ( ) ;
13461342} ) ;
14741470// in which case reading its value would be expensive.
14751471if ( this . contextMenuPending || ! cm . state . focused ||
14761472( hasSelection ( input ) && ! prevInput && ! this . composing ) ||
1477- isReadOnly ( cm ) || cm . options . disableInput || cm . state . keySeq )
1473+ cm . isReadOnly ( ) || cm . options . disableInput || cm . state . keySeq )
14781474return false ;
14791475
14801476var text = input . value ;
16251621var div = input . div = display . lineDiv ;
16261622disableBrowserMagic ( div ) ;
16271623
1628- on ( div , "paste" , function ( e ) { handlePaste ( e , cm ) ; } )
1624+ on ( div , "paste" , function ( e ) {
1625+ if ( ! signalDOMEvent ( cm , e ) ) handlePaste ( e , cm ) ;
1626+ } )
16291627
16301628on ( div , "compositionstart" , function ( e ) {
16311629var data = e . data ;
16631661
16641662on ( div , "input" , function ( ) {
16651663if ( input . composing ) return ;
1666- if ( isReadOnly ( cm ) || ! input . pollContent ( ) )
1664+ if ( cm . isReadOnly ( ) || ! input . pollContent ( ) )
16671665runInOp ( input . cm , function ( ) { regChange ( cm ) ; } ) ;
16681666} ) ;
16691667
17431741try { var rng = range ( start . node , start . offset , end . offset , end . node ) ; }
17441742catch ( e ) { } // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
17451743if ( rng ) {
1746- sel . removeAllRanges ( ) ;
1747- sel . addRange ( rng ) ;
1744+ if ( ! gecko && this . cm . state . focused ) {
1745+ sel . collapse ( start . node , start . offset ) ;
1746+ if ( ! rng . collapsed ) sel . addRange ( rng ) ;
1747+ } else {
1748+ sel . removeAllRanges ( ) ;
1749+ sel . addRange ( rng ) ;
1750+ }
17481751if ( old && sel . anchorNode == null ) sel . addRange ( old ) ;
17491752else if ( gecko ) this . startGracePeriod ( ) ;
17501753}
18881891this . div . focus ( ) ;
18891892} ,
18901893applyComposition : function ( composing ) {
1891- if ( isReadOnly ( this . cm ) )
1894+ if ( this . cm . isReadOnly ( ) )
18921895operation ( this . cm , regChange ) ( this . cm )
18931896else if ( composing . data && composing . data != composing . startData )
18941897operation ( this . cm , applyTextInput ) ( this . cm , composing . data , 0 , composing . sel ) ;
19001903
19011904onKeyPress : function ( e ) {
19021905e . preventDefault ( ) ;
1903- if ( ! isReadOnly ( this . cm ) )
1906+ if ( ! this . cm . isReadOnly ( ) )
19041907operation ( this . cm , applyTextInput ) ( this . cm , String . fromCharCode ( e . charCode == null ? e . keyCode : e . charCode ) , 0 ) ;
19051908} ,
19061909
22052208
22062209// Give beforeSelectionChange handlers a change to influence a
22072210// selection update.
2208- function filterSelectionChange ( doc , sel ) {
2211+ function filterSelectionChange ( doc , sel , options ) {
22092212var obj = {
22102213ranges : sel . ranges ,
22112214update : function ( ranges ) {
22122215this . ranges = [ ] ;
22132216for ( var i = 0 ; i < ranges . length ; i ++ )
22142217this . ranges [ i ] = new Range ( clipPos ( doc , ranges [ i ] . anchor ) ,
22152218clipPos ( doc , ranges [ i ] . head ) ) ;
2216- }
2219+ } ,
2220+ origin : options && options . origin
22172221} ;
22182222signal ( doc , "beforeSelectionChange" , doc , obj ) ;
22192223if ( doc . cm ) signal ( doc . cm , "beforeSelectionChange" , doc . cm , obj ) ;
22392243
22402244function setSelectionNoUndo ( doc , sel , options ) {
22412245if ( hasHandler ( doc , "beforeSelectionChange" ) || doc . cm && hasHandler ( doc . cm , "beforeSelectionChange" ) )
2242- sel = filterSelectionChange ( doc , sel ) ;
2246+ sel = filterSelectionChange ( doc , sel , options ) ;
22432247
22442248var bias = options && options . bias ||
22452249( cmp ( sel . primary ( ) . head , doc . sel . primary ( ) . head ) < 0 ? - 1 : 1 ) ;
22732277var out ;
22742278for ( var i = 0 ; i < sel . ranges . length ; i ++ ) {
22752279var range = sel . ranges [ i ] ;
2276- var newAnchor = skipAtomic ( doc , range . anchor , bias , mayClear ) ;
2277- var newHead = skipAtomic ( doc , range . head , bias , mayClear ) ;
2280+ var old = sel . ranges . length == doc . sel . ranges . length && doc . sel . ranges [ i ] ;
2281+ var newAnchor = skipAtomic ( doc , range . anchor , old && old . anchor , bias , mayClear ) ;
2282+ var newHead = skipAtomic ( doc , range . head , old && old . head , bias , mayClear ) ;
22782283if ( out || newAnchor != range . anchor || newHead != range . head ) {
22792284if ( ! out ) out = sel . ranges . slice ( 0 , i ) ;
22802285out [ i ] = new Range ( newAnchor , newHead ) ;
22832288return out ? normalizeSelection ( out , sel . primIndex ) : sel ;
22842289}
22852290
2286- // Ensure a given position is not inside an atomic range.
2287- function skipAtomic ( doc , pos , bias , mayClear ) {
2288- var flipped = false , curPos = pos ;
2289- var dir = bias || 1 ;
2290- doc . cantEdit = false ;
2291- search: for ( ; ; ) {
2292- var line = getLine ( doc , curPos . line ) ;
2293- if ( line . markedSpans ) {
2294- for ( var i = 0 ; i < line . markedSpans . length ; ++ i ) {
2295- var sp = line . markedSpans [ i ] , m = sp . marker ;
2296- if ( ( sp . from == null || ( m . inclusiveLeft ? sp . from <= curPos . ch : sp . from < curPos . ch ) ) &&
2297- ( sp . to == null || ( m . inclusiveRight ? sp . to >= curPos . ch : sp . to > curPos . ch ) ) ) {
2298- if ( mayClear ) {
2299- signal ( m , "beforeCursorEnter" ) ;
2300- if ( m . explicitlyCleared ) {
2301- if ( ! line . markedSpans ) break ;
2302- else { -- i ; continue ; }
2303- }
2304- }
2305- if ( ! m . atomic ) continue ;
2306- var newPos = m . find ( dir < 0 ? - 1 : 1 ) ;
2307- if ( cmp ( newPos , curPos ) == 0 ) {
2308- newPos . ch += dir ;
2309- if ( newPos . ch < 0 ) {
2310- if ( newPos . line > doc . first ) newPos = clipPos ( doc , Pos ( newPos . line - 1 ) ) ;
2311- else newPos = null ;
2312- } else if ( newPos . ch > line . text . length ) {
2313- if ( newPos . line < doc . first + doc . size - 1 ) newPos = Pos ( newPos . line + 1 , 0 ) ;
2314- else newPos = null ;
2315- }
2316- if ( ! newPos ) {
2317- if ( flipped ) {
2318- // Driven in a corner -- no valid cursor position found at all
2319- // -- try again *with* clearing, if we didn't already
2320- if ( ! mayClear ) return skipAtomic ( doc , pos , bias , true ) ;
2321- // Otherwise, turn off editing until further notice, and return the start of the doc
2322- doc . cantEdit = true ;
2323- return Pos ( doc . first , 0 ) ;
2324- }
2325- flipped = true ; newPos = pos ; dir = - dir ;
2326- }
2327- }
2328- curPos = newPos ;
2329- continue search;
2291+ function skipAtomicInner ( doc , pos , oldPos , dir , mayClear ) {
2292+ var line = getLine ( doc , pos . line ) ;
2293+ if ( line . markedSpans ) for ( var i = 0 ; i < line . markedSpans . length ; ++ i ) {
2294+ var sp = line . markedSpans [ i ] , m = sp . marker ;
2295+ if ( ( sp . from == null || ( m . inclusiveLeft ? sp . from <= pos . ch : sp . from < pos . ch ) ) &&
2296+ ( sp . to == null || ( m . inclusiveRight ? sp . to >= pos . ch : sp . to > pos . ch ) ) ) {
2297+ if ( mayClear ) {
2298+ signal ( m , "beforeCursorEnter" ) ;
2299+ if ( m . explicitlyCleared ) {
2300+ if ( ! line . markedSpans ) break ;
2301+ else { -- i ; continue ; }
23302302}
23312303}
2304+ if ( ! m . atomic ) continue ;
2305+
2306+ if ( oldPos ) {
2307+ var near = m . find ( dir < 0 ? 1 : - 1 ) , diff ;
2308+ if ( dir < 0 ? m . inclusiveRight : m . inclusiveLeft ) near = movePos ( doc , near , - dir , line ) ;
2309+ if ( near && near . line == pos . line && ( diff = cmp ( near , oldPos ) ) && ( dir < 0 ? diff < 0 : diff > 0 ) )
2310+ return skipAtomicInner ( doc , near , pos , dir , mayClear ) ;
2311+ }
2312+
2313+ var far = m . find ( dir < 0 ? - 1 : 1 ) ;
2314+ if ( dir < 0 ? m . inclusiveLeft : m . inclusiveRight ) far = movePos ( doc , far , dir , line ) ;
2315+ return far ? skipAtomicInner ( doc , far , pos , dir , mayClear ) : null ;
23322316}
2333- return curPos ;
2317+ }
2318+ return pos ;
2319+ }
2320+
2321+ // Ensure a given position is not inside an atomic range.
2322+ function skipAtomic ( doc , pos , oldPos , bias , mayClear ) {
2323+ var dir = bias || 1 ;
2324+ var found = skipAtomicInner ( doc , pos , oldPos , dir , mayClear ) ||
2325+ ( ! mayClear && skipAtomicInner ( doc , pos , oldPos , dir , true ) ) ||
2326+ skipAtomicInner ( doc , pos , oldPos , - dir , mayClear ) ||
2327+ ( ! mayClear && skipAtomicInner ( doc , pos , oldPos , - dir , true ) ) ;
2328+ if ( ! found ) {
2329+ doc . cantEdit = true ;
2330+ return Pos ( doc . first , 0 ) ;
2331+ }
2332+ return found ;
2333+ }
2334+
2335+ function movePos ( doc , pos , dir , line ) {
2336+ if ( dir < 0 && pos . ch == 0 ) {
2337+ if ( pos . line > doc . first ) return clipPos ( doc , Pos ( pos . line - 1 ) ) ;
2338+ else return null ;
2339+ } else if ( dir > 0 && pos . ch == ( line || getLine ( doc , pos . line ) ) . text . length ) {
2340+ if ( pos . line < doc . first + doc . size - 1 ) return Pos ( pos . line + 1 , 0 ) ;
2341+ else return null ;
2342+ } else {
2343+ return new Pos ( pos . line , pos . ch + dir ) ;
23342344}
23352345}
23362346
36593669}
36603670
36613671var sel = cm . doc . sel , modifier = mac ? e . metaKey : e . ctrlKey , contained ;
3662- if ( cm . options . dragDrop && dragAndDrop && ! isReadOnly ( cm ) &&
3672+ if ( cm . options . dragDrop && dragAndDrop && ! cm . isReadOnly ( ) &&
36633673type == "single" && ( contained = sel . contains ( start ) ) > - 1 &&
36643674( cmp ( ( contained = sel . ranges [ contained ] ) . from ( ) , start ) < 0 || start . xRel > 0 ) &&
36653675( cmp ( contained . to ( ) , start ) > 0 || start . xRel < 0 ) )
38833893e_preventDefault ( e ) ;
38843894if ( ie ) lastDrop = + new Date ;
38853895var pos = posFromMouse ( cm , e , true ) , files = e . dataTransfer . files ;
3886- if ( ! pos || isReadOnly ( cm ) ) return ;
3896+ if ( ! pos || cm . isReadOnly ( ) ) return ;
38873897// Might be a file drop, in which case we simply extract the text
38883898// and insert it.
38893899if ( files && files . length && window . FileReader && window . File ) {
41224132cm . display . input . ensurePolled ( ) ;
41234133var prevShift = cm . display . shift , done = false ;
41244134try {
4125- if ( isReadOnly ( cm ) ) cm . state . suppressEdits = true ;
4135+ if ( cm . isReadOnly ( ) ) cm . state . suppressEdits = true ;
41264136if ( dropShift ) cm . display . shift = false ;
41274137done = bound ( cm ) != Pass ;
41284138} finally {
48954905if ( dir > 0 && ! moveOnce ( ! first ) ) break ;
48964906}
48974907}
4898- var result = skipAtomic ( doc , Pos ( line , ch ) , origDir , true ) ;
4908+ var result = skipAtomic ( doc , Pos ( line , ch ) , pos , origDir , true ) ;
48994909if ( ! possible ) result . hitSide = true ;
49004910return result ;
49014911}
52835293signal ( this , "overwriteToggle" , this , this . state . overwrite ) ;
52845294} ,
52855295hasFocus : function ( ) { return this . display . input . getField ( ) == activeElt ( ) ; } ,
5296+ isReadOnly : function ( ) { return ! ! ( this . options . readOnly || this . doc . cantEdit ) ; } ,
52865297
52875298scrollTo : methodOp ( function ( x , y ) {
52885299if ( x != null || y != null ) resolveScrollToPos ( this ) ;
67196730parentStyle += "width: " + cm . display . wrapper . clientWidth + "px;" ;
67206731removeChildrenAndAdd ( cm . display . measure , elt ( "div" , [ widget . node ] , null , parentStyle ) ) ;
67216732}
6722- return widget . height = widget . node . offsetHeight ;
6733+ return widget . height = widget . node . parentNode . offsetHeight ;
67236734}
67246735
67256736function addLineWidget ( doc , handle , node , options ) {
71297140if ( nextChange == pos ) { // Update current marker set
71307141spanStyle = spanEndStyle = spanStartStyle = title = css = "" ;
71317142collapsed = null ; nextChange = Infinity ;
7132- var foundBookmarks = [ ] ;
7143+ var foundBookmarks = [ ] , endStyles
71337144for ( var j = 0 ; j < spans . length ; ++ j ) {
71347145var sp = spans [ j ] , m = sp . marker ;
71357146if ( m . type == "bookmark" && sp . from == pos && m . widgetNode ) {
71427153if ( m . className ) spanStyle += " " + m . className ;
71437154if ( m . css ) css = ( css ? css + "" : "" ) + m . css ;
71447155if ( m . startStyle && sp . from == pos ) spanStartStyle += " " + m . startStyle ;
7145- if ( m . endStyle && sp . to == nextChange ) spanEndStyle += " " + m . endStyle ;
7156+ if ( m . endStyle && sp . to == nextChange ) ( endStyles || ( endStyles = [ ] ) ) . push ( m . endStyle , sp . to )
71467157if ( m . title && ! title ) title = m . title ;
71477158if ( m . collapsed && ( ! collapsed || compareCollapsedMarkers ( collapsed . marker , m ) < 0 ) )
71487159collapsed = sp ;
71497160} else if ( sp . from > pos && nextChange > sp . from ) {
71507161nextChange = sp . from ;
71517162}
71527163}
7164+ if ( endStyles ) for ( var j = 0 ; j < endStyles . length ; j += 2 )
7165+ if ( endStyles [ j + 1 ] == nextChange ) spanEndStyle += " " + endStyles [ j ]
7166+
71537167if ( collapsed && ( collapsed . from || 0 ) == pos ) {
71547168buildCollapsedSpan ( builder , ( collapsed . to == null ? len + 1 : collapsed . to ) - pos ,
71557169collapsed . marker , collapsed . from == null ) ;
74977511extendSelection ( this , clipPos ( this , head ) , other && clipPos ( this , other ) , options ) ;
74987512} ) ,
74997513extendSelections : docMethodOp ( function ( heads , options ) {
7500- extendSelections ( this , clipPosArray ( this , heads , options ) ) ;
7514+ extendSelections ( this , clipPosArray ( this , heads ) , options ) ;
75017515} ) ,
75027516extendSelectionsBy : docMethodOp ( function ( f , options ) {
7503- extendSelections ( this , map ( this . sel . ranges , f ) , options ) ;
7517+ var heads = map ( this . sel . ranges , f ) ;
7518+ extendSelections ( this , clipPosArray ( this , heads ) , options ) ;
75047519} ) ,
75057520setSelections : docMethodOp ( function ( ranges , primary , options ) {
75067521if ( ! ranges . length ) return ;
89178932
89188933// THE END
89198934
8920- CodeMirror . version = "5.9 .0" ;
8935+ CodeMirror . version = "5.10 .0" ;
89218936
89228937return CodeMirror ;
89238938} ) ;
89298944var CM = require ( 'codemirror' ) ;
89308945var React = ( typeof window !== "undefined" ? window [ 'React' ] : typeof global !== "undefined" ? global [ 'React' ] : null ) ;
89318946var className = require ( 'classnames' ) ;
8932-
89338947var CodeMirror = React . createClass ( {
89348948displayName : 'CodeMirror' ,
89358949
@@ -8947,7 +8961,6 @@ var CodeMirror = React.createClass({
89478961isFocused : false
89488962} ;
89498963} ,
8950-
89518964componentDidMount : function componentDidMount ( ) {
89528965var textareaNode = this . refs . textarea ;
89538966this . codeMirror = CM . fromTextArea ( textareaNode , this . props . options ) ;
@@ -8956,8 +8969,8 @@ var CodeMirror = React.createClass({
89568969this . codeMirror . on ( 'blur' , this . focusChanged . bind ( this , false ) ) ;
89578970this . _currentCodemirrorValue = this . props . defaultValue || this . props . value || '' ;
89588971this . codeMirror . setValue ( this . _currentCodemirrorValue ) ;
8972+ this . props . interact ( this . codeMirror ) ;
89598973} ,
8960-
89618974componentWillUnmount : function componentWillUnmount ( ) {
89628975// todo: is there a lighter-weight way to remove the cm instance?
89638976if ( this . codeMirror ) {
0 commit comments