@@ -32,6 +32,9 @@ define(function (require, exports, module) {
3232 NewFileContentManager = brackets . getModule ( "features/NewFileContentManager" ) ,
3333 CSSUtils = brackets . getModule ( "language/CSSUtils" ) ,
3434 StringMatch = brackets . getModule ( "utils/StringMatch" ) ,
35+ LiveDevelopment = brackets . getModule ( "LiveDevelopment/main" ) ,
36+ KeyEvent = brackets . getModule ( "utils/KeyEvent" ) ,
37+ Metrics = brackets . getModule ( "utils/Metrics" ) ,
3538 HTMLTags = require ( "text!HtmlTags.json" ) ,
3639 HTMLAttributes = require ( "text!HtmlAttributes.json" ) ,
3740 HTMLTemplate = require ( "text!template.html" ) ,
@@ -228,7 +231,7 @@ define(function (require, exports, module) {
228231 hints = hints . splice ( 0 , MAX_CLASS_HINTS ) ;
229232 }
230233 return hints . map ( function ( token ) {
231- let $hintObj = $ ( " <span>" ) . addClass ( "brackets-html-hints brackets-hints" ) ;
234+ let $hintObj = $ ( ` <span data-val=' ${ token . label || token . value || token . text } '></span>` ) . addClass ( "brackets-html-hints brackets-hints" ) ;
232235
233236 // highlight the matched portion of each hint
234237 if ( token . stringRanges ) {
@@ -336,6 +339,62 @@ define(function (require, exports, module) {
336339 }
337340 } ;
338341
342+ const HISTORY_PREFIX = "Live_hint_CSS" ;
343+ let hintSessionId = 0 , isInLiveHighlightSession = false ;
344+
345+ AttrHints . prototype . onClose = function ( ) {
346+ if ( isInLiveHighlightSession ) {
347+ this . editor . restoreHistoryPoint ( `${ HISTORY_PREFIX } ${ hintSessionId } ` ) ;
348+ isInLiveHighlightSession = false ;
349+ }
350+ hintSessionId ++ ;
351+ } ;
352+
353+ AttrHints . prototype . onHighlight = function ( $highlightedEl , _$descriptionElem , reason ) {
354+ if ( ! reason ) {
355+ console . error ( "OnHighlight called without reason, should never happen!" ) ;
356+ hintSessionId ++ ;
357+ return ;
358+ }
359+ const tokenType = this . tagInfo . position . tokenType ;
360+ const currentLivePreviewDetails = LiveDevelopment . getLivePreviewDetails ( ) ;
361+ if ( ! ( currentLivePreviewDetails && currentLivePreviewDetails . liveDocument )
362+ || ! ( tokenType === HTMLUtils . ATTR_VALUE && this . tagInfo . attr . name === "class" ) ) {
363+ // live hints only for live previewed page on class attribute values
364+ return ;
365+ }
366+ const currentlyEditedFile = this . editor . document . file . fullPath ;
367+ const livePreviewedFile = currentLivePreviewDetails . liveDocument . doc . file . fullPath ;
368+ if ( currentlyEditedFile !== livePreviewedFile ) {
369+ // file is not current html file being live previewed. we dont show hints in the case
370+ return ;
371+ }
372+ if ( reason . source === CodeHintManager . SELECTION_REASON . SESSION_START ) {
373+ hintSessionId ++ ;
374+ this . editor . createHistoryRestorePoint ( `${ HISTORY_PREFIX } ${ hintSessionId } ` ) ;
375+ return ;
376+ }
377+ if ( reason . source !== CodeHintManager . SELECTION_REASON . KEYBOARD_NAV ) {
378+ return ;
379+ }
380+ const event = reason . event ;
381+ if ( ! ( event . keyCode === KeyEvent . DOM_VK_UP ||
382+ event . keyCode === KeyEvent . DOM_VK_DOWN ||
383+ event . keyCode === KeyEvent . DOM_VK_PAGE_UP ||
384+ event . keyCode === KeyEvent . DOM_VK_PAGE_DOWN ) ) {
385+ return ;
386+ }
387+ Metrics . countEvent ( Metrics . EVENT_TYPE . LIVE_PREVIEW , "htmlClassHint" , "preview" ) ;
388+ const $hintItem = $highlightedEl . find ( ".brackets-html-hints" ) ;
389+ const highligtedValue = $highlightedEl . find ( ".brackets-html-hints" ) . data ( "val" ) ;
390+ if ( ! highligtedValue || ! $hintItem . is ( ":visible" ) ) {
391+ return ;
392+ }
393+ isInLiveHighlightSession = true ;
394+ this . editor . restoreHistoryPoint ( `${ HISTORY_PREFIX } ${ hintSessionId } ` ) ;
395+ this . insertHint ( $highlightedEl . find ( ".brackets-html-hints" ) , true ) ;
396+ } ;
397+
339398 /**
340399 * Determines whether HTML attribute hints are available in the current
341400 * editor context.
@@ -524,14 +583,14 @@ define(function (require, exports, module) {
524583 /**
525584 * Inserts a given HTML attribute hint into the current editor context.
526585 *
527- * @param {string } hint
586+ * @param {string } completion
528587 * The hint to be inserted into the editor context.
529588 *
530589 * @return {boolean }
531590 * Indicates whether the manager should follow hint insertion with an
532591 * additional explicit hint request.
533592 */
534- AttrHints . prototype . insertHint = function ( completion ) {
593+ AttrHints . prototype . insertHint = function ( completion , isLiveHighlight ) {
535594 var cursor = this . editor . getCursorPos ( ) ,
536595 start = { line : - 1 , ch : - 1 } ,
537596 end = { line : - 1 , ch : - 1 } ,
@@ -602,6 +661,28 @@ define(function (require, exports, module) {
602661 start . ch = cursor . ch - offset ;
603662 end . ch = start . ch + charCount ;
604663
664+ if ( isLiveHighlight ) {
665+ // this is via user press up and down arrows when code hints is visible
666+ if ( ! this . editor . hasSelection ( ) ) {
667+ this . editor . setSelection ( start , end ) ;
668+ }
669+ this . editor . replaceSelection ( completion , 'around' , "liveHints" ) ;
670+ return true ;
671+ }
672+
673+ // this is commit flow
674+ if ( isInLiveHighlightSession ) {
675+ // end previous highlight session.
676+ isInLiveHighlightSession = false ;
677+ hintSessionId ++ ;
678+ }
679+
680+ if ( this . editor . hasSelection ( ) ) {
681+ // this is when user commits in a live selection
682+ this . editor . replaceSelection ( completion , 'end' ) ;
683+ return true ;
684+ }
685+
605686 if ( shouldReplace ) {
606687 if ( start . ch !== end . ch ) {
607688 this . editor . document . replaceRange ( completion , start , end ) ;
0 commit comments