@@ -16,37 +16,74 @@ import * as marked from 'marked'
1616export default function onHasCompletion ( cm , data , onHintInformationRender ) {
1717 const CodeMirror = require ( 'codemirror' )
1818
19+ let wrapper
1920 let information
2021 let deprecation
2122
22- // When a hint result is selected, we augment the UI with information .
23+ // When a hint result is selected, we touch the UI.
2324 CodeMirror . on ( data , 'select' , ( ctx , el ) => {
2425 // Only the first time (usually when the hint UI is first displayed)
25- // do we create the information nodes.
26- if ( ! information ) {
26+ // do we create the wrapping node.
27+ if ( ! wrapper ) {
28+ // Wrap the existing hint UI, so we have a place to put information.
2729 const hintsUl = el . parentNode
30+ const container = hintsUl . parentNode
31+ wrapper = document . createElement ( 'div' )
32+ container . appendChild ( wrapper )
33+
34+ // CodeMirror vertically inverts the hint UI if there is not enough
35+ // space below the cursor. Since this modified UI appends to the bottom
36+ // of CodeMirror's existing UI, it could cover the cursor. This adjusts
37+ // the positioning of the hint UI to accomodate.
38+ let top = hintsUl . style . top
39+ let bottom = ''
40+ const cursorTop = cm . cursorCoords ( ) . top
41+ if ( parseInt ( top , 10 ) < cursorTop ) {
42+ top = ''
43+ bottom = window . innerHeight - cursorTop + 3 + 'px'
44+ }
45+
46+ // Style the wrapper, remove positioning from hints. Note that usage
47+ // of this option will need to specify CSS to remove some styles from
48+ // the existing hint UI.
49+ wrapper . className = 'CodeMirror-hints-wrapper'
50+ wrapper . style . left = hintsUl . style . left
51+ wrapper . style . top = top
52+ wrapper . style . bottom = bottom
53+ hintsUl . style . left = ''
54+ hintsUl . style . top = ''
2855
2956 // This "information" node will contain the additional info about the
3057 // highlighted typeahead option.
3158 information = document . createElement ( 'div' )
3259 information . className = 'CodeMirror-hint-information'
33- hintsUl . appendChild ( information )
3460
3561 // This "deprecation" node will contain info about deprecated usage.
3662 deprecation = document . createElement ( 'div' )
3763 deprecation . className = 'CodeMirror-hint-deprecation'
38- hintsUl . appendChild ( deprecation )
64+
65+ if ( bottom ) {
66+ wrapper . appendChild ( deprecation )
67+ wrapper . appendChild ( information )
68+ wrapper . appendChild ( hintsUl )
69+ } else {
70+ wrapper . appendChild ( hintsUl )
71+ wrapper . appendChild ( information )
72+ wrapper . appendChild ( deprecation )
73+ }
3974
4075 // When CodeMirror attempts to remove the hint UI, we detect that it was
41- // removed and in turn remove the information nodes.
76+ // removed from our wrapper and in turn remove the wrapper from the
77+ // original container.
4278 let onRemoveFn
43- hintsUl . addEventListener (
79+ wrapper . addEventListener (
4480 'DOMNodeRemoved' ,
4581 ( onRemoveFn = event => {
4682 if ( event . target === hintsUl ) {
47- hintsUl . removeEventListener ( 'DOMNodeRemoved' , onRemoveFn )
83+ wrapper . removeEventListener ( 'DOMNodeRemoved' , onRemoveFn )
84+ wrapper . parentNode . removeChild ( wrapper )
85+ wrapper = null
4886 information = null
49- deprecation = null
5087 onRemoveFn = null
5188 }
5289 } ) ,
0 commit comments