@@ -49,7 +49,6 @@ function RemoteFunctions(config = {}) {
4949 let _nodeInfoBox ;
5050 let _nodeMoreOptionsBox ;
5151 let _moreOptionsDropdown ;
52- let _aiPromptBox ;
5352 let _hotCorner ;
5453 let _setup = false ;
5554 let _hoverLockTimer = null ;
@@ -294,18 +293,6 @@ function RemoteFunctions(config = {}) {
294293 return element . offsetTop + ( element . offsetParent ? getDocumentOffsetTop ( element . offsetParent ) : 0 ) ;
295294 }
296295
297- /**
298- * This function gets called when the AI button is clicked
299- * it shows a AI prompt box to the user
300- * @param {Event } event
301- * @param {DOMElement } element - the HTML DOM element that was clicked
302- */
303- function _handleAIOptionClick ( event , element ) {
304- // make sure there is no existing AI prompt box, and no other box as well
305- dismissAllUIBoxes ( ) ;
306- _aiPromptBox = new AIPromptBox ( element ) ; // create a new one
307- }
308-
309296 /**
310297 * This function will get triggered when from the multiple advance DOM buttons, one is clicked
311298 * this function just checks which exact button was clicked and call the required function
@@ -316,9 +303,7 @@ function RemoteFunctions(config = {}) {
316303 function handleOptionClick ( e , action , element ) {
317304 if ( action === "edit-text" ) {
318305 startEditing ( element ) ;
319- } else if ( action === "ai" ) {
320- _handleAIOptionClick ( e , element ) ;
321- } else if ( LivePreviewView . getNodeMoreOptionsHandler ( action ) ) {
306+ } else if ( LivePreviewView . getNodeMoreOptionsHandler ( action ) ) {
322307 const handler = LivePreviewView . getNodeMoreOptionsHandler ( action ) ;
323308 return handler && handler . handleClick && handler . handleClick ( e , element ) ;
324309 }
@@ -684,12 +669,6 @@ function RemoteFunctions(config = {}) {
684669
685670 let content = `<div class="node-options">` ;
686671
687- // @abose @devansh
688- // hiding it for now as AI is not yet ready
689- // content += `<span data-action="ai" title="${strings.ai}">
690- // ${ICONS.ai}
691- // </span>`;
692-
693672 // Only include edit text option if element supports it
694673 if ( showEditTextOption ) {
695674 content += `<span data-action="edit-text" class="lp-opt-edit-text" title="${ strings . editText } ">
@@ -1097,210 +1076,6 @@ function RemoteFunctions(config = {}) {
10971076 }
10981077 } ;
10991078
1100- // AI prompt box, it is displayed when user clicks on the AI button in the more options box
1101- function AIPromptBox ( element ) {
1102- this . element = element ;
1103- this . selectedModel = 'fast' ;
1104- this . remove = this . remove . bind ( this ) ;
1105- this . create ( ) ;
1106- }
1107-
1108- AIPromptBox . prototype = {
1109- _getBoxPosition : function ( boxWidth , boxHeight ) {
1110- const elemBounds = this . element . getBoundingClientRect ( ) ;
1111- const offset = LivePreviewView . screenOffset ( this . element ) ;
1112-
1113- let topPos = offset . top - boxHeight - 6 ; // 6 for just some little space to breathe
1114- let leftPos = offset . left + elemBounds . width - boxWidth ;
1115-
1116- // Check if the box would go off the top of the viewport
1117- if ( elemBounds . top - boxHeight < 6 ) {
1118- topPos = offset . top + elemBounds . height + 6 ;
1119- }
1120-
1121- // Check if the box would go off the left of the viewport
1122- if ( leftPos < 0 ) {
1123- leftPos = offset . left ;
1124- }
1125-
1126- return { topPos : topPos , leftPos : leftPos } ;
1127- } ,
1128-
1129- _style : function ( ) {
1130- this . body = window . document . createElement ( "div" ) ;
1131- this . body . setAttribute ( GLOBALS . PHCODE_INTERNAL_ATTR , "true" ) ;
1132- // using shadow dom so that user styles doesn't override it
1133- const shadow = this . body . attachShadow ( { mode : "open" } ) ;
1134-
1135- // Calculate responsive dimensions based on viewport width
1136- const viewportWidth = window . innerWidth ;
1137- let boxWidth , boxHeight ;
1138-
1139- if ( viewportWidth >= 400 ) {
1140- boxWidth = Math . min ( 310 , viewportWidth * 0.85 ) ;
1141- boxHeight = 60 ;
1142- } else if ( viewportWidth >= 350 ) {
1143- boxWidth = Math . min ( 275 , viewportWidth * 0.85 ) ;
1144- boxHeight = 70 ;
1145- } else if ( viewportWidth >= 300 ) {
1146- boxWidth = Math . min ( 230 , viewportWidth * 0.85 ) ;
1147- boxHeight = 80 ;
1148- } else if ( viewportWidth >= 250 ) {
1149- boxWidth = Math . min ( 180 , viewportWidth * 0.85 ) ;
1150- boxHeight = 100 ;
1151- } else if ( viewportWidth >= 200 ) {
1152- boxWidth = Math . min ( 130 , viewportWidth * 0.85 ) ;
1153- boxHeight = 120 ;
1154- } else {
1155- boxWidth = Math . min ( 100 , viewportWidth * 0.85 ) ;
1156- boxHeight = 140 ;
1157- }
1158-
1159- const content = `
1160- <div class="phoenix-ai-prompt-box">
1161- <div class="phoenix-ai-prompt-input-container">
1162- <textarea
1163- class="phoenix-ai-prompt-textarea"
1164- placeholder="${ strings . aiPromptPlaceholder } "
1165- ></textarea>
1166- </div>
1167- <div class="phoenix-ai-bottom-controls">
1168- <select class="phoenix-ai-model-select">
1169- <option value="fast">Fast AI</option>
1170- <option value="moderate">Moderate AI</option>
1171- <option value="slow">Slow AI</option>
1172- </select>
1173- <button class="phoenix-ai-prompt-send-button" disabled>
1174- ${ icons . paperPlane }
1175- </button>
1176- </div>
1177- </div>
1178- ` ;
1179-
1180- shadow . innerHTML = `
1181- <style>
1182- ${ cssStyles . aiPromptBox }
1183- :host {
1184- --ai-box-width: ${ boxWidth } px;
1185- --ai-box-height: ${ boxHeight } px;
1186- }
1187- </style>
1188- ${ content }
1189- ` ;
1190- this . _shadow = shadow ;
1191- } ,
1192-
1193- create : function ( ) {
1194- this . _style ( ) ;
1195- window . document . body . appendChild ( this . body ) ;
1196-
1197- // Get the actual rendered dimensions of the box and position it
1198- const boxElement = this . _shadow . querySelector ( '.phoenix-ai-prompt-box' ) ;
1199- if ( boxElement ) {
1200- const boxRect = boxElement . getBoundingClientRect ( ) ;
1201- const pos = this . _getBoxPosition ( boxRect . width , boxRect . height ) ;
1202-
1203- boxElement . style . left = pos . leftPos + 'px' ;
1204- boxElement . style . top = pos . topPos + 'px' ;
1205- }
1206-
1207- // Focus on the textarea
1208- const textarea = this . _shadow . querySelector ( '.phoenix-ai-prompt-textarea' ) ;
1209- if ( textarea ) { // small timer to make sure that the text area element is fetched
1210- setTimeout ( ( ) => textarea . focus ( ) , 50 ) ;
1211- }
1212-
1213- this . _attachEventHandlers ( ) ;
1214-
1215- // Prevent clicks inside the AI box from bubbling up and closing it
1216- this . body . addEventListener ( 'click' , ( event ) => {
1217- event . stopPropagation ( ) ;
1218- } ) ;
1219- } ,
1220-
1221- _attachEventHandlers : function ( ) {
1222- const textarea = this . _shadow . querySelector ( '.phoenix-ai-prompt-textarea' ) ;
1223- const sendButton = this . _shadow . querySelector ( '.phoenix-ai-prompt-send-button' ) ;
1224- const modelSelect = this . _shadow . querySelector ( '.phoenix-ai-model-select' ) ;
1225-
1226- // Handle textarea input to enable/disable send button
1227- if ( textarea && sendButton ) {
1228- textarea . addEventListener ( 'input' , ( event ) => {
1229- const hasText = event . target . value . trim ( ) . length > 0 ;
1230- sendButton . disabled = ! hasText ;
1231- } ) ;
1232-
1233- // enter key
1234- textarea . addEventListener ( 'keydown' , ( event ) => {
1235- if ( event . key === 'Enter' && ! event . shiftKey ) {
1236- event . preventDefault ( ) ;
1237- if ( textarea . value . trim ( ) ) {
1238- this . _handleSend ( event , textarea . value . trim ( ) ) ;
1239- }
1240- } else if ( event . key === 'Escape' ) {
1241- event . preventDefault ( ) ;
1242- this . remove ( ) ;
1243- }
1244- } ) ;
1245- }
1246-
1247- // send button click
1248- if ( sendButton ) {
1249- sendButton . addEventListener ( 'click' , ( event ) => {
1250- event . preventDefault ( ) ;
1251- event . stopPropagation ( ) ;
1252- if ( textarea && textarea . value . trim ( ) ) {
1253- this . _handleSend ( event , textarea . value . trim ( ) ) ;
1254- }
1255- } ) ;
1256- }
1257-
1258- // model selection change
1259- if ( modelSelect ) {
1260- modelSelect . addEventListener ( 'change' , ( event ) => {
1261- this . selectedModel = event . target . value ;
1262- } ) ;
1263- }
1264- } ,
1265-
1266- _handleSend : function ( event , prompt ) {
1267- const element = this . element ;
1268- if ( ! LivePreviewView . isElementEditable ( element ) ) {
1269- return ;
1270- }
1271- const tagId = element . getAttribute ( GLOBALS . DATA_BRACKETS_ID_ATTR ) ;
1272-
1273- window . _Brackets_MessageBroker . send ( {
1274- livePreviewEditEnabled : true ,
1275- event : event ,
1276- element : element ,
1277- prompt : prompt ,
1278- tagId : Number ( tagId ) ,
1279- selectedModel : this . selectedModel ,
1280- AISend : true
1281- } ) ;
1282- this . remove ( ) ;
1283- } ,
1284-
1285- remove : function ( ) {
1286- if ( this . _handleKeydown ) {
1287- document . removeEventListener ( 'keydown' , this . _handleKeydown ) ;
1288- this . _handleKeydown = null ;
1289- }
1290-
1291- if ( this . _handleResize ) {
1292- window . removeEventListener ( 'resize' , this . _handleResize ) ;
1293- this . _handleResize = null ;
1294- }
1295-
1296- if ( this . body && this . body . parentNode && this . body . parentNode === window . document . body ) {
1297- window . document . body . removeChild ( this . body ) ;
1298- this . body = null ;
1299- _aiPromptBox = null ;
1300- }
1301- }
1302- } ;
1303-
13041079 /**
13051080 * hot corner class,
13061081 * to switch to preview mode and back
@@ -1793,7 +1568,6 @@ function RemoteFunctions(config = {}) {
17931568 function selectElement ( element ) {
17941569 dismissNodeMoreOptionsBox ( ) ;
17951570 dismissMoreOptionsDropdown ( ) ;
1796- dismissAIPromptBox ( ) ;
17971571 dismissNodeInfoBox ( ) ;
17981572 dismissToastMessage ( ) ;
17991573 cleanupPreviousElementState ( ) ;
@@ -2068,12 +1842,6 @@ function RemoteFunctions(config = {}) {
20681842 _nodeInfoBox . remove ( ) ;
20691843 _nodeInfoBox = new NodeInfoBox ( element ) ;
20701844 }
2071-
2072- if ( _aiPromptBox ) {
2073- const element = _aiPromptBox . element ;
2074- _aiPromptBox . remove ( ) ;
2075- _aiPromptBox = new AIPromptBox ( element ) ;
2076- }
20771845 }
20781846
20791847 // redraw active highlights
@@ -2158,49 +1926,16 @@ function RemoteFunctions(config = {}) {
21581926 }
21591927 }
21601928
2161- // this function is responsible to reposition the AI box
2162- // so we need to reposition it when for ex: a fixed positioned element is selected in the live preview
2163- // now when live preview is scrolled the element remains at a fixed position but the AI box will drift away
2164- // so we reposition it when its a fixed element
2165- function _repositionAIBox ( ) {
2166- if ( ! _aiPromptBox || ! _aiPromptBox . element || ! _aiPromptBox . _shadow ) { return ; }
2167-
2168- const aiBox = _aiPromptBox . _shadow . querySelector ( '.phoenix-ai-prompt-box' ) ;
2169- if ( ! aiBox ) { return ; }
2170-
2171- const aiBoxBounds = aiBox . getBoundingClientRect ( ) ;
2172- const elementBounds = _aiPromptBox . element . getBoundingClientRect ( ) ;
2173-
2174- // this is to store the prev value, so that we can compare it the second time
2175- if ( ! _aiPromptBox . _possDifference ) {
2176- _aiPromptBox . _possDifference = aiBoxBounds . top - elementBounds . top ;
2177- } else {
2178- const calcNewDifference = aiBoxBounds . top - elementBounds . top ;
2179- const prevDifference = _aiPromptBox . _possDifference ;
2180-
2181- // 4 is just for pixelated differences
2182- if ( Math . abs ( calcNewDifference - prevDifference ) > 4 ) {
2183- const boxPositions = _aiPromptBox . _getBoxPosition ( aiBoxBounds . width , aiBoxBounds . height ) ;
2184-
2185- aiBox . style . left = boxPositions . leftPos + 'px' ;
2186- aiBox . style . top = boxPositions . topPos + 'px' ;
2187- _aiPromptBox . _possDifference = calcNewDifference ;
2188- }
2189- }
2190- }
2191-
21921929 function _scrollHandler ( e ) {
21931930 // Document scrolls can be updated immediately. Any other scrolls
21941931 // need to be updated on a timer to ensure the layout is correct.
21951932 if ( e . target === window . document ) {
21961933 _dismissBoxesForFixedElements ( ) ;
2197- _repositionAIBox ( ) ; // and reposition the AI box
21981934 } else {
21991935 if ( _localHighlight ) {
22001936 window . setTimeout ( redrawHighlights , 0 ) ;
22011937 }
22021938 _dismissBoxesForFixedElements ( ) ;
2203- _repositionAIBox ( ) ;
22041939 }
22051940 }
22061941
@@ -2574,23 +2309,12 @@ function RemoteFunctions(config = {}) {
25742309 }
25752310 }
25762311
2577- /**
2578- * Helper function to dismiss AIPromptBox if it exists
2579- */
2580- function dismissAIPromptBox ( ) {
2581- if ( _aiPromptBox ) {
2582- _aiPromptBox . remove ( ) ;
2583- _aiPromptBox = null ;
2584- }
2585- }
2586-
25872312 /**
25882313 * Helper function to dismiss all UI boxes at once
25892314 */
25902315 function dismissAllUIBoxes ( ) {
25912316 dismissNodeMoreOptionsBox ( ) ;
25922317 dismissMoreOptionsDropdown ( ) ;
2593- dismissAIPromptBox ( ) ;
25942318 dismissNodeInfoBox ( ) ;
25952319 dismissToastMessage ( ) ;
25962320 getAllNodeMoreOptionsHandlers ( ) . forEach ( handler => ( handler . dismiss && handler . dismiss ( ) ) ) ;
0 commit comments