11/*
22 Package: Dom-Selector
3- Version: 1.1 .0
3+ Version: 2.0 .0
44 Author: Shivam Dewangan https://github.com/shivamdevs
55 License: MIT License
66*/
77
8- ( function ( ) {
9- function initCode ( ) {
10- const $ = window . Js ;
11- const selector = $ . ce ( 'dom-element-selector.hidden' , $ . ce ( 'data-selector' ) ) . appendTo ( "body" ) ;
12- const opter = $ . ce ( 'dom-element-selector-opter' , `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="20" fill="currentColor" height="20"><path xmlns="http://www.w3.org/2000/svg" d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM288 176c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 48.8 46.5 111.6 68.6 138.6c6 7.3 16.8 7.3 22.7 0c22.1-27 68.6-89.8 68.6-138.6zm-48 0c0 17.7-14.3 32-32 32s-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32z"/></svg>` ) . appendTo ( "body" ) . click ( function ( ) {
13- $ ( this ) . toggleClass ( 'opted' ) ;
14- selector . toggleClass ( 'hidden' ) ;
15- } ) ;
16- $ ( window ) . mouseover ( function ( ) {
17- if ( selector . hasClass ( 'hidden' ) ) return ;
18- selector . addClass ( 'surfing' ) ;
19- } ) . mouseout ( function ( ) {
20- if ( selector . hasClass ( 'hidden' ) ) return ;
21- selector . removeClass ( 'surfing' ) ;
22- } ) . mousemove ( function ( eve ) {
23- if ( selector . hasClass ( 'hidden' ) ) return ;
24- selector . removeClass ( 'surfing' ) ;
25- selector . find ( 'data-selector' ) . removeClass ( 'offset outset lowset stcset' ) . empty ( ) ;
26- const doc = document . elementFromPoint ( eve . clientX , eve . clientY ) ;
27- if ( ! doc ) return ;
28- const rec = doc . getBoundingClientRect ( ) ;
29- selector . css ( {
30- top : rec . top + 'px' ,
31- left : rec . left + 'px' ,
32- width : rec . width + 'px' ,
33- height : rec . height + 'px' ,
34- } ) ;
35- let info = `<span class="node">${ doc . nodeName . toLowerCase ( ) } </span>` ;
36- if ( doc . classList . value || doc . classList . length ) info += doc . classList . value . replace ( / + / g, ' ' ) . split ( " " ) . reduce ( ( acc , cls ) => cls && ( acc += '<span class="class">.' + cls + '</span>' ) , '' ) ;
37- if ( doc . id || doc . getAttribute ( "id" ) ) info += `<span class="id">#${ doc . id || doc . getAttribute ( "id" ) } </span>` ;
38- selector . find ( 'data-selector' ) . html ( info ) ;
39- selector . addClass ( 'surfing' ) ;
40- if ( selector . find ( 'data-selector' ) . height ( ) + 100 > selector . height ( ) ) selector . find ( 'data-selector' ) . addClass ( 'offset' ) ;
41- let dta = selector . find ( 'data-selector' ) [ 0 ] . getBoundingClientRect ( ) ;
42- if ( ( dta . left + dta . width + 15 ) > window . innerWidth ) selector . find ( 'data-selector' ) . addClass ( 'outset' ) ;
43- dta = selector . find ( 'data-selector' ) [ 0 ] . getBoundingClientRect ( ) ;
44- if ( ( dta . top - 6 ) < 0 ) selector . find ( 'data-selector' ) . addClass ( 'lowset' ) ;
45- dta = selector . find ( 'data-selector' ) [ 0 ] . getBoundingClientRect ( ) ;
46- if ( ( dta . top + dta . height + 15 ) > window . innerHeight ) selector . find ( 'data-selector' ) . addClass ( 'stcset' ) ;
47- } ) . mousedown ( function ( eve ) {
48- if ( selector . hasClass ( 'hidden' ) ) return ;
49- selector . toggleClass ( 'surfing hidden' ) ;
50- opter . removeClass ( 'opted' ) ;
51- console . log ( document . elementFromPoint ( eve . clientX , eve . clientY ) ) ;
52- } ) . mouseup ( function ( ) {
53- if ( selector . hasClass ( 'hidden' ) ) return ;
54- selector . addClass ( 'surfing' ) ;
55- } ) ;
56- $ . styleSheet ( `dom-element-selector-opter{position:fixed;inset:auto 0 20px auto;background:#fff;padding:5px 10px;border-radius:20px 0 0 20px;box-shadow:-2px 2px 4px 2px #0002;border:1px solid #0004;z-index:9999999999999998;transition:all .2s ease;cursor:pointer;color:#000}dom-element-selector-opter:hover{color:#ff8c00}dom-element-selector-opter.opted{color:#00f;translate:calc(100% + 10px) 0}dom-element-selector,dom-element-selector *,dom-element-selector-opter{box-sizing:border-box;display:block;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Fira Sans','Droid Sans','Helvetica Neue',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}dom-element-selector{z-index:9999999999999999;position:fixed;top:0;left:0;width:40px;height:40px;background:#2a52be77;border:1px solid #2a52be}dom-element-selector.hidden,dom-element-selector:not(.surfing){display:none}dom-element-selector data-selector:not(:empty){display:flex;align-items:center;flex-wrap:wrap;position:absolute;inset:0 auto auto 0;font-size:14px;font-weight:500;background:#fff;color:#000;padding:6px 18px;margin:6px;box-shadow:2px 2px 4px 2px #0002;user-select:none;border-radius:6px;max-width:calc(100vw - 12px)}dom-element-selector data-selector,dom-element-selector data-selector:not(:empty)>span{white-space:nowrap}dom-element-selector data-selector.lowset{top:100%}dom-element-selector data-selector.outset{right:0;left:auto}dom-element-selector data-selector.offset{translate:0 calc(-100% - 15px)}dom-element-selector data-selector.lowset{translate:0 5px}dom-element-selector data-selector.stcset{position:fixed;top:0;left:inherit;right:inherit}dom-element-selector data-selector span.node{color:purple}dom-element-selector data-selector span.class{color:#00f}dom-element-selector data-selector span.id{color:#ff8c00}` , "head" , '[pass-test]' ) ;
8+ ( function ( context , name , enableSelector ) {
9+ const style = document . createElement ( "style" ) ;
10+ style . setAttribute ( "DomSelector" , "" ) ;
11+ style . setAttribute ( "type" , "text/css" ) ;
12+ style . innerHTML = `
13+ dom-selector,
14+ dom-selector * {
15+ box-sizing: border-box;
16+ display: block;
17+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
18+ -webkit-font-smoothing: antialiased;
19+ -moz-osx-font-smoothing: grayscale;
20+ }
21+ dom-selector {
22+ z-index: 999999999999999999;
23+ position: fixed;
24+ top: 0;
25+ left: 0;
26+ width: 40px;
27+ height: 40px;
28+ background: #1e90ff77;
29+ border-style: solid;
30+ border-color: #ff8c0099;
31+ --bt: 1px;
32+ --br: 1px;
33+ --bb: 1px;
34+ --bl: 1px;
35+ --mt: 0px;
36+ --mr: 0px;
37+ --mb: 0px;
38+ --ml: 0px;
39+ --pt: 0px;
40+ --pr: 0px;
41+ --pb: 0px;
42+ --pl: 0px;
43+ }
44+ dom-selector:not(.surfing) {
45+ display: none;
46+ }
47+ dom-selector {
48+ border-width: var(--bt) var(--br) var(--bb) var(--bl);
49+ }
50+ dom-selector::before {
51+ box-sizing: content-box;
52+ content: " ";
53+ position: absolute;
54+ top: calc(0px - var(--mt) - var(--bt));
55+ right: calc(0px - var(--mr) - var(--br));
56+ bottom: calc(0px - var(--mb) - var(--bb));
57+ left: calc(0px - var(--ml) - var(--bl));
58+ border: 0 solid #ff8c0055;
59+ border-width: var(--mt) var(--mr) var(--mb) var(--ml);
60+ }
61+ dom-selector::after {
62+ box-sizing: content-box;
63+ content: " ";
64+ inset: 0;
65+ position: absolute;
66+ border: 0 solid #20c02077;
67+ border-width: var(--pt) var(--pr) var(--pb) var(--pl);
68+ }
69+ dom-selector-data {
70+ z-index: 1;
71+ display: flex;
72+ align-items: baseline;
73+ flex-wrap: nowrap;
74+ position: absolute;
75+ inset: 0 auto auto 0;
76+ margin: 6px;
77+ background: #fff;
78+ overflow: hidden;
79+ box-shadow: 2px 2px 4px 2px #0002, 0 0 0 1px #0001;
80+ border-radius: 6px;
81+ max-width: 340px;
82+ padding: 6px 6px 6px 18px;
83+ }
84+ dom-selector-closer {
85+ display: inline-flex;
86+ justify-content: center;
87+ align-items: stretch;
88+ float: right;
89+ width: 18px;
90+ height: 18px;
91+ font-size: 16px;
92+ line-height: 14px;
93+ font-weight: 700;
94+ color: red;
95+ box-shadow: 0 0 0 1px red;
96+ border-radius: 10px;
97+ user-select: none;
98+ cursor: pointer;
99+ }
100+ dom-selector:not(.selected) {
101+ user-select: none;
102+ }
103+ dom-selector:not(.selected) dom-selector-closer {
104+ display: none;
105+ }
106+ dom-selector-info {
107+ color: #727888;
108+ font-size: 14px;
109+ font-weight: 500;
110+ padding-right: 12px;
111+ flex: 1;
112+ max-width: 300px;
113+ }
114+ dom-selector-info span {
115+ display: inline-block;
116+ }
117+ dom-selector-info span[node] {
118+ color: purple;
119+ }
120+ dom-selector-info span[class] {
121+ color: #00f;
122+ }
123+ dom-selector-info span[id] {
124+ color: #ff8c00;
125+ }
126+ dom-selector-info span[display] {
127+ color: brown;
128+ padding-left: 10px;
129+ }
130+ dom-selector-info > div {
131+ display: block;
132+ margin: 5px auto;
133+ font-size: 12px;
134+ }
135+ dom-selector-info div[dimension]:not(:last-child) {
136+ border-bottom: 1px solid #0002;
137+ padding-bottom: 5px;
138+ }
139+ dom-selector-info span[padding] {
140+ color: green;
141+ font-size: 12px;
142+ }
143+ dom-selector-info span[margin] {
144+ color: orange;
145+ font-size: 12px;
146+ }
147+ dom-selector-info div[border] {
148+ color: #1e90ff;
149+ }
150+ dom-selector-info div[styling] {
151+ font-weight: 700;
152+ display: flex;
153+ align-items: center;
154+ }
155+ dom-selector-info div[styling] > span {
156+ min-width: 14px;
157+ min-height: 14px;
158+ border: 1px solid #0005;
159+ }
160+ dom-selector-data.setbelow {
161+ top: 100%;
162+ }
163+ dom-selector-data.fromright {
164+ right: 0;
165+ left: auto;
166+ }
167+ dom-selector-data.outside {
168+ translate: 0 calc(-100% - 15px);
169+ }
170+ dom-selector-data.setbelow {
171+ translate: 5px;
172+ }
173+ dom-selector-data.scrollable {
174+ position: fixed;
175+ top: 0;
176+ left: inherit;
177+ right: inherit;
178+ }
179+ ` ;
180+ document . head . appendChild ( style ) ;
181+
182+ const wrap = document . createElement ( 'dom-selector' ) ;
183+ const data = document . createElement ( 'dom-selector-data' ) ;
184+ const closer = document . createElement ( 'dom-selector-closer' ) ;
185+ const info = document . createElement ( 'dom-selector-info' ) ;
186+
187+ wrap . classList . add ( 'inactive' ) ;
188+ closer . innerHTML = '×' ;
189+ closer . addEventListener ( 'click' , reset ) ;
190+ data . appendChild ( info ) ;
191+ data . appendChild ( closer ) ;
192+ wrap . appendChild ( data ) ;
193+ document . body . appendChild ( wrap ) ;
194+
195+ window . addEventListener ( 'mouseover' , function ( e ) {
196+ if ( wrap . classList . contains ( 'inactive' ) || wrap . classList . contains ( 'selected' ) ) return ;
197+ wrap . classList . add ( 'surfing' ) ;
198+ } ) ;
199+ window . addEventListener ( 'mouseout' , function ( e ) {
200+ if ( wrap . classList . contains ( 'inactive' ) || wrap . classList . contains ( 'selected' ) ) return ;
201+ wrap . classList . remove ( 'surfing' ) ;
202+ } ) ;
203+ window . addEventListener ( 'mousemove' , mapE ) ;
204+ window . addEventListener ( 'scroll' , mapE ) ;
205+
206+ const history = { x :0 , y :0 } ;
207+
208+ function mapE ( e ) {
209+ if ( wrap . classList . contains ( 'inactive' ) || wrap . classList . contains ( 'selected' ) ) return ;
210+ wrap . classList . remove ( 'surfing' ) ;
211+ info . innerHTML = '' ;
212+ data . removeAttribute ( 'class' ) ;
213+ if ( e . type && e . type === 'scroll' ) e . clientX = history . x , e . clientY = history . y ; else history . x = e . clientX , history . y = e . clientY ;
214+ const element = document . elementFromPoint ( e . clientX , e . clientY ) ;
215+ if ( ! element ) return ;
216+ const rect = element . getBoundingClientRect ( ) ;
217+ const style = window . getComputedStyle ( element ) ;
218+ setStyle ( element ) ;
219+
220+ info . innerHTML = `<span node>${ element . nodeName . toLowerCase ( ) } </span>` ;
221+ if ( element . classList . value || element . classList . length ) info . innerHTML += element . classList . value . replace ( / + / g, ' ' ) . split ( " " ) . reduce ( ( acc , cls ) => cls && ( acc += '<span class>.' + cls + '</span>' ) , '' ) ;
222+ if ( element . id || element . getAttribute ( "id" ) ) info . innerHTML += `<span id>#${ element . id || element . getAttribute ( "id" ) } </span>` ;
223+ info . innerHTML += `<div dimension>${ parse ( rect . width ) } ×${ parse ( rect . height ) } ${ style . display !== 'block' ? `<span display>${ style . display } </span>` : '' } </div>` ;
224+ info . innerHTML += `<div styling>Bg: <span style="background: ${ style . backgroundColor } " title="${ style . backgroundColor } "></span> Color: <span style="background: ${ style . color } " title="${ style . color } "></span></div>` ;
225+ if ( style . padding && style . padding !== '0px' ) info . innerHTML += `<span padding>${ style . padding } </span>` ;
226+ if ( style . margin && style . margin !== '0px' ) info . innerHTML += `${ style . padding && style . padding !== '0px' ? ' ' : '' } <span margin>${ style . margin } </span>` ;
227+ if ( style . border && style . borderWidth !== '0px' && style . borderStyle !== 'none' ) info . innerHTML += `<div border>${ style . border } </div>` ;
228+ wrap . classList . add ( 'surfing' ) ;
229+
230+ setPosition ( ) ;
57231 }
58232
59- ( function ( ) { // load jscript for easier navigation
60- if ( window . Js ) return initCode ( ) ;
61- const scr = document . createElement ( 'script' ) ;
62- scr . setAttribute ( 'Pass-test' , '' ) ;
63- scr . onload = initCode ;
64- scr . src = "https://cdn.jsdelivr.net/gh/shivamdevs/[email protected] /jscript.js" ; 65- document . head . appendChild ( scr ) ;
66- } ( ) ) ;
67- } ( ) ) ;
233+ function setStyle ( node ) {
234+ const rect = node . getBoundingClientRect ( ) ;
235+ const style = window . getComputedStyle ( node ) ;
236+ wrap . style . top = rect . top + 'px' ;
237+ wrap . style . left = rect . left + 'px' ;
238+ wrap . style . width = rect . width + 'px' ;
239+ wrap . style . height = rect . height + 'px' ;
240+ wrap . style . setProperty ( '--bt' , parseInt ( style . borderTopWidth , 10 ) >= 0 ? style . borderTopWidth : '0px' ) ;
241+ wrap . style . setProperty ( '--br' , parseInt ( style . borderRightWidth , 10 ) >= 0 ? style . borderRightWidth : '0px' ) ;
242+ wrap . style . setProperty ( '--bb' , parseInt ( style . borderBottomWidth , 10 ) >= 0 ? style . borderBottomWidth : '0px' ) ;
243+ wrap . style . setProperty ( '--bl' , parseInt ( style . borderLeftWidth , 10 ) >= 0 ? style . borderLeftWidth : '0px' ) ;
244+ wrap . style . setProperty ( '--mt' , ( parseInt ( style . marginTop , 10 ) >= 0 ? style . marginTop : '0px' ) ) ;
245+ wrap . style . setProperty ( '--mr' , ( parseInt ( style . marginRight , 10 ) >= 0 ? style . marginRight : '0px' ) ) ;
246+ wrap . style . setProperty ( '--mb' , ( parseInt ( style . marginBottom , 10 ) >= 0 ? style . marginBottom : '0px' ) ) ;
247+ wrap . style . setProperty ( '--ml' , ( parseInt ( style . marginLeft , 10 ) >= 0 ? style . marginLeft : '0px' ) ) ;
248+ wrap . style . setProperty ( '--pt' , ( parseInt ( style . paddingTop , 10 ) >= 0 ? style . paddingTop : '0px' ) ) ;
249+ wrap . style . setProperty ( '--pr' , ( parseInt ( style . paddingRight , 10 ) >= 0 ? style . paddingRight : '0px' ) ) ;
250+ wrap . style . setProperty ( '--pb' , ( parseInt ( style . paddingBottom , 10 ) >= 0 ? style . paddingBottom : '0px' ) ) ;
251+ wrap . style . setProperty ( '--pl' , ( parseInt ( style . paddingLeft , 10 ) >= 0 ? style . paddingLeft : '0px' ) ) ;
252+ }
253+
254+ function setPosition ( ) {
255+ const rect = ( ) => data . getBoundingClientRect ( ) ;
256+ const sect = ( ) => wrap . getBoundingClientRect ( ) ;
257+ if ( rect ( ) . height + 20 > sect ( ) . height ) data . classList . add ( 'outside' ) ;
258+ if ( rect ( ) . left + rect ( ) . width + 15 > context . innerWidth ) data . classList . add ( 'fromright' ) ;
259+ if ( rect ( ) . top - 6 < 0 ) data . classList . add ( 'setbelow' ) ;
260+ if ( rect ( ) . top + rect ( ) . height + 15 > context . innerHeight ) data . classList . add ( 'scrollable' ) ;
261+ }
262+
263+ function parse ( num ) {
264+ const countDecimals = function ( n ) {
265+ if ( Math . floor ( n . valueOf ( ) ) === n . valueOf ( ) ) return 0 ;
266+ return n . toString ( ) . split ( "." ) [ 1 ] . length || 0 ;
267+ }
268+ num = parseFloat ( num ) ;
269+ if ( countDecimals ( num ) > 2 ) {
270+ num = parseFloat ( num . toFixed ( 2 ) ) ;
271+ if ( num == parseFloat ( num . toFixed ( 1 ) ) ) num = parseFloat ( num . toFixed ( 1 ) ) ;
272+ }
273+ return num ;
274+ }
275+
276+ function reset ( ) {
277+ wrap . removeAttribute ( "class" ) ;
278+ wrap . classList . add ( 'inactive' ) ;
279+ data . removeAttribute ( 'class' ) ;
280+ info . innerHTML = '' ;
281+ wrap . removeAttribute ( "style" ) ;
282+ }
283+
284+ context [ name ] = function ( showPreview = false ) {
285+ return new Promise ( ( resolve , reject ) => {
286+ if ( ! wrap . classList . contains ( 'inactive' ) || wrap . classList . contains ( 'selected' ) ) reject ( 'Error: Another instance of \'DomSelector\' is already running. Finish it before starting another one.' ) ;
287+ wrap . classList . remove ( 'inactive' ) ;
288+ window . addEventListener ( 'mousedown' , function ( e ) {
289+ if ( wrap . classList . contains ( 'inactive' ) ) reject ( 'Error: Another instance of \'DomSelector\' is already running. Finish it before starting another one.' ) ;
290+ if ( showPreview ) wrap . classList . add ( 'selected' ) ;
291+ wrap . classList . remove ( 'surfing' ) ;
292+ const selected = document . elementFromPoint ( e . clientX , e . clientY ) ;
293+ if ( showPreview ) wrap . classList . add ( 'surfing' ) ; else reset ( ) ;
294+ if ( selected ) resolve ( selected ) ; else reject ( 'Error: Failed to find the Selected element. Try to fetch again.' ) ;
295+ } , { once : true } ) ;
296+ } ) ;
297+ } ;
298+ } ( window , 'DomSelector' , true ) ) ;
0 commit comments