@@ -63,25 +63,23 @@ class Inspector {
6363 // message element
6464 const modalNode = document . getElementById ( this . modalNode ) ;
6565
66- function insert_modal_text ( response , modal_id ) {
66+ const insert_modal_text = ( response , modal_id ) => {
6767 console . log ( "insert_modal_text .................." )
6868 if ( response [ "info" ] == "success" ) {
69- // show message about element
7069 const modalText = 'Element data was recorded. Please Click "Add by AI"' ;
7170 console . log ( modalText ) ;
72- if ( modalNode ) {
73- modalNode . innerText = modalText ;
74- } else {
75- const modalHtml = document . createElement ( 'div ') ;
76- modalHtml . innerText = modalText ;
77- modalHtml . id = modal_id ;
78- document . body . appendChild ( modalHtml ) ;
71+
72+ if ( this . successContainer ) {
73+ this . successContainer . textContent = modalText ;
74+ this . successContainer . classList . add ( 'show ') ;
75+ setTimeout ( ( ) => {
76+ this . successContainer . classList . remove ( 'show' ) ;
77+ } , 3000 ) ;
7978 }
8079 return true ;
8180 }
8281 console . error ( response [ "info" ] ) ;
8382 return false ;
84-
8583 }
8684
8785 async function send_data ( server_url , api_key , data , modal_id , refinedHtml ) {
@@ -295,23 +293,6 @@ class Inspector {
295293
296294 setOptions ( options ) {
297295 this . options = options ;
298- let position = 'bottom:0;left:0' ;
299- let positionParent = 'top:0;left:0' ;
300- let positionModal = 'top:50%;left:40%' ;
301- switch ( options . position ) {
302- case 'tl' :
303- position = 'top:0;left:0' ;
304- break ;
305- case 'tr' :
306- position = 'top:0;right:0' ;
307- break ;
308- case 'br' :
309- position = 'bottom:0;right:0' ;
310- break ;
311- default :
312- break ;
313- }
314- this . styles = `*{cursor:crosshair!important;}#xpath-content{${ position } ;cursor:initial!important;padding:10px;background:gray;color:white;position:fixed;font-size:14px;z-index:10000001;}#xpath-parent-content{${ positionParent } ;cursor:initial!important;padding:10px;background:gray;color:white;position:fixed;font-size:14px;z-index:10000001;}#${ this . modalNode } {${ position } ;cursor:initial!important;padding:10px;background:#F2F2F2;color:green;position:fixed;font-size:14px;z-index:10000001;}#${ this . elementNode } {${ positionParent } ;cursor:initial!important;padding:10px;background:gray;color:white;position:fixed;font-size:14px;z-index:10000001;}` ;
315296 this . activate ( ) ;
316297 }
317298
@@ -354,6 +335,102 @@ class Inspector {
354335 overlayHtml && overlayHtml . remove ( ) ;
355336 }
356337
338+ createAttributeDisplay ( ) {
339+ const host = document . createElement ( 'div' ) ;
340+ host . id = 'zeuz-attributes-host' ;
341+ Object . assign ( host . style , {
342+ position : 'fixed' ,
343+ top : '10px' ,
344+ left : '10px' ,
345+ zIndex : '2147483647' ,
346+ pointerEvents : 'none'
347+ } ) ;
348+ document . body . appendChild ( host ) ;
349+
350+ const shadow = host . attachShadow ( { mode : 'open' } ) ;
351+ const style = document . createElement ( 'style' ) ;
352+ style . textContent = `
353+ .attributes-container {
354+ background: rgba(0, 0, 0, 0.8);
355+ color: white;
356+ padding: 6px 10px;
357+ border-radius: 4px;
358+ font-family: monospace;
359+ font-size: 11px;
360+ max-width: 300px;
361+ word-break: break-all;
362+ backdrop-filter: blur(4px);
363+ border: 1px solid rgba(255, 255, 255, 0.2);
364+ }
365+ ` ;
366+ shadow . appendChild ( style ) ;
367+
368+ const container = document . createElement ( 'div' ) ;
369+ container . className = 'attributes-container' ;
370+ shadow . appendChild ( container ) ;
371+
372+ this . attributesHost = host ;
373+ this . attributesContainer = container ;
374+ }
375+
376+ createSuccessMessage ( ) {
377+ const host = document . createElement ( 'div' ) ;
378+ host . id = 'zeuz-success-host' ;
379+ Object . assign ( host . style , {
380+ position : 'fixed' ,
381+ top : '20px' ,
382+ left : '50%' ,
383+ transform : 'translateX(-50%)' ,
384+ zIndex : '2147483647' ,
385+ pointerEvents : 'none'
386+ } ) ;
387+ document . body . appendChild ( host ) ;
388+
389+ const shadow = host . attachShadow ( { mode : 'open' } ) ;
390+ const style = document . createElement ( 'style' ) ;
391+ style . textContent = `
392+ .success-message {
393+ background: linear-gradient(135deg, #4ade80, #22c55e);
394+ color: white;
395+ padding: 12px 20px;
396+ border-radius: 8px;
397+ font-family: sans-serif;
398+ font-size: 14px;
399+ font-weight: 500;
400+ box-shadow: 0 4px 12px rgba(34, 197, 94, 0.3);
401+ border: 1px solid rgba(255, 255, 255, 0.2);
402+ opacity: 0;
403+ transform: translateY(-10px);
404+ transition: all 0.3s ease;
405+ }
406+ .success-message.show {
407+ opacity: 1;
408+ transform: translateY(0);
409+ }
410+ ` ;
411+ shadow . appendChild ( style ) ;
412+
413+ const container = document . createElement ( 'div' ) ;
414+ container . className = 'success-message' ;
415+ shadow . appendChild ( container ) ;
416+
417+ this . successHost = host ;
418+ this . successContainer = container ;
419+ }
420+
421+ updateAttributePosition ( mouseY ) {
422+ if ( this . attributesHost ) {
423+ const isTopHalf = mouseY < window . innerHeight / 2 ;
424+ if ( isTopHalf ) {
425+ this . attributesHost . style . top = 'auto' ;
426+ this . attributesHost . style . bottom = '10px' ;
427+ } else {
428+ this . attributesHost . style . top = '10px' ;
429+ this . attributesHost . style . bottom = 'auto' ;
430+ }
431+ }
432+ }
433+
357434 copyText ( XPath ) {
358435 const hdInp = document . createElement ( 'textarea' ) ;
359436 hdInp . textContent = XPath ;
@@ -387,35 +464,32 @@ class Inspector {
387464
388465 this . doc . body . appendChild ( this . container ) ;
389466
467+ // attributes display if not exists
468+ if ( ! this . attributesHost ) {
469+ this . createAttributeDisplay ( ) ;
470+ }
471+
472+ // position based on mouse location
473+ this . updateAttributePosition ( e . clientY ) ;
390474
391- // show element attributes
392- const elementNode = document . getElementById ( this . elementNode ) ;
393- var elementText = "" ;
475+ let elementText = "" ;
394476 for ( let name of e . target . getAttributeNames ( ) ) {
395477 let value = e . target . getAttribute ( name ) ;
396- var each = name + " = \"" + value + "\", " ;
397- elementText += each ;
478+ elementText += `${ name } ="${ value } " ` ;
398479 }
399- if ( elementNode ) {
400- elementNode . innerText = elementText ;
401- } else {
402- const elementHtml = document . createElement ( 'div' ) ;
403- elementHtml . innerText = elementText ;
404- elementHtml . id = this . elementNode ;
405- document . body . appendChild ( elementHtml ) ;
406- }
407-
480+
481+ this . attributesContainer . textContent = elementText . trim ( ) ;
408482 }
409483
410484 activate ( ) {
411485 this . createOverlayElements ( ) ;
412- // add styles
413- if ( ! document . getElementById ( this . cssNode ) ) {
414- const styles = document . createElement ( 'style' ) ;
415- styles . innerText = this . styles ;
416- styles . id = this . cssNode ;
417- document . getElementsByTagName ( ' head' ) [ 0 ] . appendChild ( styles ) ;
418- }
486+ this . createSuccessMessage ( ) ;
487+
488+ const style = document . createElement ( 'style' ) ;
489+ style . id = this . cssNode ;
490+ style . textContent = '*{cursor:crosshair!important;}' ;
491+ document . head . appendChild ( style ) ;
492+
419493 // add listeners
420494 document . addEventListener ( 'click' , this . getData , true ) ;
421495 this . options . inspector && ( document . addEventListener ( 'mouseover' , this . draw ) ) ;
@@ -425,30 +499,27 @@ class Inspector {
425499 // remove overlay
426500 this . removeOverlay ( ) ;
427501
428- this . cssNode = 'xpath-css' ;
429- this . overlayElement = 'xpath-overlay' ;
430- this . modalNode = 'zeuzMyModal' ;
431- this . elementNode = 'zeuzMyElement' ;
432-
433502 let Remove = [
434503 this . cssNode ,
435504 this . overlayElement ,
436- this . modalNode ,
437- this . elementNode ,
505+ 'zeuz-attributes-host' ,
506+ 'zeuz-success-host'
438507 ]
439508
440- for ( let elem of Remove ) {
441- elem = document . getElementById ( elem ) ;
509+ for ( let elemId of Remove ) {
510+ const elem = document . getElementById ( elemId ) ;
442511 elem && elem . remove ( ) ;
443512 }
444513
445- // remove styles
446- const cssNode = document . getElementById ( this . cssNode ) ;
447- cssNode && cssNode . remove ( ) ;
448-
449514 // remove listeners
450515 document . removeEventListener ( 'click' , this . getData , true ) ;
451516 this . options && this . options . inspector && ( document . removeEventListener ( 'mouseover' , this . draw ) ) ;
517+
518+ // reset
519+ this . attributesHost = null ;
520+ this . attributesContainer = null ;
521+ this . successHost = null ;
522+ this . successContainer = null ;
452523 }
453524
454525 getXPath ( el ) {
0 commit comments