1+ define ( "ace/ext/code_lens" , [ "require" , "exports" , "module" , "ace/line_widgets" , "ace/lib/event" , "ace/lib/lang" , "ace/lib/dom" , "ace/editor" , "ace/config" ] , function ( require , exports , module ) {
2+ "use strict" ;
3+ var LineWidgets = require ( "../line_widgets" ) . LineWidgets ;
4+ var event = require ( "../lib/event" ) ;
5+ var lang = require ( "../lib/lang" ) ;
6+ var dom = require ( "../lib/dom" ) ;
7+
8+ function clearLensElements ( renderer ) {
9+ var textLayer = renderer . $textLayer ;
10+ var lensElements = textLayer . $lenses ;
11+ if ( lensElements )
12+ lensElements . forEach ( function ( el ) { el . remove ( ) ; } ) ;
13+ textLayer . $lenses = null ;
14+ }
15+
16+ function renderWidgets ( changes , renderer ) {
17+ var changed = changes & renderer . CHANGE_LINES
18+ || changes & renderer . CHANGE_FULL
19+ || changes & renderer . CHANGE_SCROLL
20+ || changes & renderer . CHANGE_TEXT ;
21+ if ( ! changed )
22+ return ;
23+
24+ var session = renderer . session ;
25+ var lineWidgets = renderer . session . lineWidgets ;
26+ var textLayer = renderer . $textLayer ;
27+ var lensElements = textLayer . $lenses ;
28+ if ( ! lineWidgets ) {
29+ if ( lensElements )
30+ clearLensElements ( renderer ) ;
31+ return ;
32+ }
33+
34+ var textCells = renderer . $textLayer . $lines . cells ;
35+ var config = renderer . layerConfig ;
36+ var padding = renderer . $padding ;
37+
38+ if ( ! lensElements )
39+ lensElements = textLayer . $lenses = [ ] ;
40+
41+
42+ var index = 0 ;
43+ for ( var i = 0 ; i < textCells . length ; i ++ ) {
44+ var row = textCells [ i ] . row ;
45+ var widget = lineWidgets [ row ] ;
46+ var lenses = widget && widget . lenses ;
47+
48+ if ( ! lenses || ! lenses . length ) continue ;
49+
50+ var lensContainer = lensElements [ index ] ;
51+ if ( ! lensContainer ) {
52+ lensContainer = lensElements [ index ]
53+ = dom . buildDom ( [ "div" , { class : "ace_codeLens" } ] , renderer . container ) ;
54+ }
55+ lensContainer . style . height = config . lineHeight + "px" ;
56+ index ++ ;
57+
58+ for ( var j = 0 ; j < lenses . length ; j ++ ) {
59+ var el = lensContainer . childNodes [ 2 * j ] ;
60+ if ( ! el ) {
61+ if ( j != 0 ) lensContainer . appendChild ( dom . createTextNode ( "\xa0|\xa0" ) ) ;
62+ el = dom . buildDom ( [ "a" ] , lensContainer ) ;
63+ }
64+ el . textContent = lenses [ j ] . title ;
65+ el . lensCommand = lenses [ j ] ;
66+ }
67+ while ( lensContainer . childNodes . length > 2 * j - 1 )
68+ lensContainer . lastChild . remove ( ) ;
69+
70+ var top = renderer . $cursorLayer . getPixelPosition ( {
71+ row : row ,
72+ column : 0
73+ } , true ) . top - config . lineHeight * widget . rowsAbove - config . offset ;
74+ lensContainer . style . top = top + "px" ;
75+
76+ var left = renderer . gutterWidth ;
77+ var indent = session . getLine ( row ) . search ( / \S | $ / ) ;
78+ if ( indent == - 1 )
79+ indent = 0 ;
80+ left += indent * config . characterWidth ;
81+ left -= renderer . scrollLeft ;
82+ lensContainer . style . paddingLeft = padding + left + "px" ;
83+ }
84+ while ( index < lensElements . length )
85+ lensElements . pop ( ) . remove ( ) ;
86+ }
87+
88+ function clearCodeLensWidgets ( session ) {
89+ if ( ! session . lineWidgets ) return ;
90+ var widgetManager = session . widgetManager ;
91+ session . lineWidgets . forEach ( function ( widget ) {
92+ if ( widget && widget . lenses )
93+ widgetManager . removeLineWidget ( widget ) ;
94+ } ) ;
95+ }
96+
97+ exports . setLenses = function ( session , lenses ) {
98+ var firstRow = Number . MAX_VALUE ;
99+
100+ clearCodeLensWidgets ( session ) ;
101+ lenses && lenses . forEach ( function ( lens ) {
102+ var row = lens . start . row ;
103+ var column = lens . start . column ;
104+ var widget = session . lineWidgets && session . lineWidgets [ row ] ;
105+ if ( ! widget || ! widget . lenses ) {
106+ widget = session . widgetManager . $registerLineWidget ( {
107+ rowCount : 1 ,
108+ rowsAbove : 1 ,
109+ row : row ,
110+ column : column ,
111+ lenses : [ ]
112+ } ) ;
113+ }
114+ widget . lenses . push ( lens . command ) ;
115+ if ( row < firstRow )
116+ firstRow = row ;
117+ } ) ;
118+ session . _emit ( "changeFold" , { data : { start : { row : firstRow } } } ) ;
119+ } ;
120+
121+ function attachToEditor ( editor ) {
122+ editor . codeLensProviders = [ ] ;
123+ editor . renderer . on ( "afterRender" , renderWidgets ) ;
124+ if ( ! editor . $codeLensClickHandler ) {
125+ editor . $codeLensClickHandler = function ( e ) {
126+ var command = e . target . lensCommand ;
127+ if ( command )
128+ editor . execCommand ( command . id , command . arguments ) ;
129+ } ;
130+ event . addListener ( editor . container , "click" , editor . $codeLensClickHandler , editor ) ;
131+ }
132+ editor . $updateLenses = function ( ) {
133+ var session = editor . session ;
134+ if ( ! session ) return ;
135+
136+ if ( ! session . widgetManager ) {
137+ session . widgetManager = new LineWidgets ( session ) ;
138+ session . widgetManager . attach ( editor ) ;
139+ }
140+
141+ var providersToWaitNum = editor . codeLensProviders . length ;
142+ var lenses = [ ] ;
143+ editor . codeLensProviders . forEach ( function ( provider ) {
144+ provider . provideCodeLenses ( session , function ( err , payload ) {
145+ if ( err ) return ;
146+ payload . forEach ( function ( lens ) {
147+ lenses . push ( lens ) ;
148+ } ) ;
149+ providersToWaitNum -- ;
150+ if ( providersToWaitNum == 0 ) {
151+ applyLenses ( ) ;
152+ }
153+ } ) ;
154+ } ) ;
155+
156+ function applyLenses ( ) {
157+ var cursor = session . selection . cursor ;
158+ var oldRow = session . documentToScreenRow ( cursor ) ;
159+ exports . setLenses ( session , lenses ) ;
160+
161+ var lastDelta = session . $undoManager && session . $undoManager . $lastDelta ;
162+ if ( lastDelta && lastDelta . action == "remove" && lastDelta . lines . length > 1 )
163+ return ;
164+ var row = session . documentToScreenRow ( cursor ) ;
165+ var lineHeight = editor . renderer . layerConfig . lineHeight ;
166+ var top = session . getScrollTop ( ) + ( row - oldRow ) * lineHeight ;
167+ session . setScrollTop ( top ) ;
168+ }
169+ } ;
170+ var updateLenses = lang . delayedCall ( editor . $updateLenses ) ;
171+ editor . $updateLensesOnInput = function ( ) {
172+ updateLenses . delay ( 250 ) ;
173+ } ;
174+ editor . on ( "input" , editor . $updateLensesOnInput ) ;
175+ }
176+
177+ function detachFromEditor ( editor ) {
178+ editor . off ( "input" , editor . $updateLensesOnInput ) ;
179+ editor . renderer . off ( "afterRender" , renderWidgets ) ;
180+ if ( editor . $codeLensClickHandler )
181+ editor . container . removeEventListener ( "click" , editor . $codeLensClickHandler ) ;
182+ }
183+
184+ exports . registerCodeLensProvider = function ( editor , codeLensProvider ) {
185+ editor . setOption ( "enableCodeLens" , true ) ;
186+ editor . codeLensProviders . push ( codeLensProvider ) ;
187+ editor . $updateLensesOnInput ( ) ;
188+ } ;
189+
190+ exports . clear = function ( session ) {
191+ exports . setLenses ( session , null ) ;
192+ } ;
193+
194+ var Editor = require ( "../editor" ) . Editor ;
195+ require ( "../config" ) . defineOptions ( Editor . prototype , "editor" , {
196+ enableCodeLens : {
197+ set : function ( val ) {
198+ if ( val ) {
199+ attachToEditor ( this ) ;
200+ } else {
201+ detachFromEditor ( this ) ;
202+ }
203+ }
204+ }
205+ } ) ;
206+
207+ dom . importCssString ( "\
208+ .ace_codeLens {\
209+ position: absolute;\
210+ color: #aaa;\
211+ font-size: 88%;\
212+ background: inherit;\
213+ width: 100%;\
214+ display: flex;\
215+ align-items: flex-end;\
216+ pointer-events: none;\
217+ }\
218+ .ace_codeLens > a {\
219+ cursor: pointer;\
220+ pointer-events: auto;\
221+ }\
222+ .ace_codeLens > a:hover {\
223+ color: #0000ff;\
224+ text-decoration: underline;\
225+ }\
226+ .ace_dark > .ace_codeLens > a:hover {\
227+ color: #4e94ce;\
228+ }\
229+ " , "codelense.css" , false ) ;
230+
231+ } ) ; ( function ( ) {
232+ window . require ( [ "ace/ext/code_lens" ] , function ( m ) {
233+ if ( typeof module == "object" && typeof exports == "object" && module ) {
234+ module . exports = m ;
235+ }
236+ } ) ;
237+ } ) ( ) ;
238+
0 commit comments