UNPKG

@react-native/debugger-frontend

Version:
2 lines (1 loc) • 14.5 kB
const e=()=>{};class t{#e;#t;#n;constructor(t){if("silent"===t)this.#e=e,this.#t=e,this.#n=e;else this.#e=console.log,this.#t=console.time,this.#n=console.timeEnd}log(...e){this.#e(...e)}timed(e,t){this.#t(e);const n=t();return this.#n(e),n}}class n{#o=new WeakMap;#r=1;getOrInsert=e=>{const t=this.#o.get(e);return void 0!==t?t:(this.#o.set(e,this.#r),this.#r++,this.#r-1)}}class o{#i;constructor(e){this.#i=e}#s=(e,t)=>{const n=[];let o=document;for(const r of e){let e=this.#c(o,r.name);if(e)n.push(r.name),o=e;else if(t&&(e=this.#l(o,r.role),e))n.push(`[role="${r.role}"]`),o=e;else{if(e=this.#a(o,r.name,r.role),!e)return;n.push(`${r.name}[role="${r.role}"]`),o=e}}return n};#c=(e,t)=>{if(!t)return null;const n=this.#d(e,t,void 0,2);return 1!==n.length?null:n[0]};#l=(e,t)=>{if(!t)return null;const n=this.#d(e,void 0,t,2);return 1!==n.length?null:n[0]};#a=(e,t,n)=>{if(!n||!t)return null;const o=this.#d(e,t,n,2);return 1!==o.length?null:o[0]};#d=(e,t,n,o=0)=>{const r=[];if(!t&&!n)throw new Error("Both role and name are empty");const i=Boolean(t),s=Boolean(n),c=e=>{const l=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);do{const e=l.currentNode;if(e.shadowRoot&&c(e.shadowRoot),!(e instanceof ShadowRoot)&&(!i||this.#i.getAccessibleName(e)===t)&&(!s||this.#i.getAccessibleRole(e)===n)&&(r.push(e),o&&r.length>=o))return}while(l.nextNode())};return c(e instanceof Document?document.documentElement:e),r};compute=e=>{let t,n=e;const o=[];for(;n;){const r=this.#i.getAccessibleRole(n),i=this.#i.getAccessibleName(n);if(r||i){if(o.unshift({name:i,role:r}),t=this.#s(o,n!==e),t)break;n!==e&&o.shift()}else if(n===e)break;n=n.parentNode,n instanceof ShadowRoot&&(n=n.host)}return t}}class r{value;optimized;constructor(e,t){this.value=e,this.optimized=t||!1}toString(){return this.value}}const i=e=>`#${CSS.escape(e)}`,s=(e,t)=>`[${e}='${CSS.escape(t)}']`,c=(e,t=[])=>{if(!(e instanceof Element))return;for(const n of t){const t=e.getAttribute(n);if(t)return new r(s(n,t),!0)}if((e=>Boolean(e.id)&&1===e.getRootNode().querySelectorAll(i(e.id)).length)(e))return new r(i(e.id),!0);const n=e.tagName.toLowerCase();switch(e.tagName){case"BODY":case"HEAD":case"HTML":return new r(n,!0)}const o=e.parentNode;if(!o)return new r(n,!0);const c=o.children;if(((e,t)=>{for(const n of t)if(n!==e&&n.tagName===e.tagName)return!1;return!0})(e,c))return new r(n,!0);if(e instanceof HTMLInputElement&&((e,t)=>{for(const n of t)if(n!==e&&n instanceof HTMLInputElement&&n.type===e.type)return!1;return!0})(e,c))return new r(((e,t)=>`${e}${s("type",t)}`)(n,e.type),!0);const l=((e,t)=>{const n=new Set(e.classList);for(const o of t)if(o!==e){for(const e of o.classList)n.delete(e);if(0===n.size)break}if(n.size>0)return n.values().next().value})(e,c);return void 0!==l?new r(((e,t)=>`${e}.${CSS.escape(t)}`)(n,l),!0):new r(((e,t)=>`${e}:nth-of-type(${t+1})`)(n,((e,t)=>{let n=0;for(const o of t){if(o===e)return n;o.tagName===e.tagName&&++n}throw new Error("Node not found in children")})(e,c)),!1)},l=([e,t],n)=>{n.self??=e=>e;let o,r,i=n.inc(e);do{for(o=n.valueOf(e),r=!0;i!==t;)if(e=n.self(i),i=n.inc(e),!n.gte(o,i)){r=!1;break}}while(!r);return o};class a{#u=[[]];#h;#f=0;constructor(e=[]){this.#h=e}inc(e){return e.parentNode??e.getRootNode()}valueOf(e){const t=c(e,this.#h);if(!t)throw new Error("Node is not an element");return this.#f>1?this.#u.unshift([t]):this.#u[0].unshift(t),this.#f=0,this.#u.map((e=>e.join(" > "))).join(" ")}gte(e,t){return++this.#f,1===t.querySelectorAll(e).length}}const d=(e,t)=>{const n=[],o=e=>{const r=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);do{const i=r.currentNode;i.shadowRoot&&o(i.shadowRoot),i instanceof ShadowRoot||i!==e&&i.matches(t)&&n.push(i)}while(r.nextNode())};return e instanceof Document&&(e=e.documentElement),o(e),n};class u{#g=[[]];#h;#f=0;constructor(e=[]){this.#h=e}inc(e){return e.getRootNode()}self(e){return e instanceof ShadowRoot?e.host:e}valueOf(e){const t=l([e,e.getRootNode()],new a(this.#h));return this.#f>1?this.#g.unshift([t]):this.#g[0].unshift(t),this.#f=0,this.#g}gte(e,t){return++this.#f,1===d(t,e[0][0]).length}}const h=new Set(["checkbox","image","radio"]),f=new Set(["SCRIPT","STYLE"]),g=e=>!f.has(e.nodeName)&&!document.head?.contains(e),p=new WeakMap,m=e=>{for(;e;)p.delete(e),e=e instanceof ShadowRoot?e.host:e.parentNode},w=new WeakSet,E=new MutationObserver((e=>{for(const t of e)m(t.target)})),T=e=>{let t=p.get(e);if(t)return t;if(t={full:"",immediate:[]},!g(e))return t;let n="";if((o=e)instanceof HTMLSelectElement||o instanceof HTMLTextAreaElement||o instanceof HTMLInputElement&&!h.has(o.type))t.full=e.value,t.immediate.push(e.value),e.addEventListener("input",(e=>{m(e.target)}),{once:!0,capture:!0});else{for(let o=e.firstChild;o;o=o.nextSibling)o.nodeType!==Node.TEXT_NODE?(n&&t.immediate.push(n),n="",o.nodeType===Node.ELEMENT_NODE&&(t.full+=T(o).full)):(t.full+=o.nodeValue??"",n+=o.nodeValue??"");n&&t.immediate.push(n),e instanceof Element&&e.shadowRoot&&(t.full+=T(e.shadowRoot).full),w.has(e)||(E.observe(e,{childList:!0,characterData:!0,subtree:!0}),w.add(e))}var o;return p.set(e,t),t},S=function*(e,t){let n=!1;for(const o of e.childNodes)if(o instanceof Element&&g(o)){let e;e=o.shadowRoot?S(o.shadowRoot,t):S(o,t);for(const t of e)yield t,n=!0}if(!n&&e instanceof Element&&g(e)){T(e).full.includes(t)&&(yield e)}},y=(e,t=1/0)=>{const n=[];for(const o of e){if(t<=0)break;n.push(o),--t}return n},N=(e,t)=>`//*[@${e}=${JSON.stringify(t)}]`,v=(e,t,n=[])=>{let o;switch(e.nodeType){case Node.ELEMENT_NODE:if(!(e instanceof Element))return;if(t)for(const t of n)if(o=e.getAttribute(t)??"",o)return new r(N(t,o),!0);if(e.id)return new r(N("id",e.id),!0);o=e.localName;break;case Node.ATTRIBUTE_NODE:o="@"+e.nodeName;break;case Node.TEXT_NODE:case Node.CDATA_SECTION_NODE:o="text()";break;case Node.PROCESSING_INSTRUCTION_NODE:o="processing-instruction()";break;case Node.COMMENT_NODE:o="comment()";break;case Node.DOCUMENT_NODE:default:o=""}const i=b(e);return i>0&&(o+=`[${i}]`),new r(o,e.nodeType===Node.DOCUMENT_NODE)},b=e=>{function t(e,t){if(e===t)return!0;if(e instanceof Element&&t instanceof Element)return e.localName===t.localName;if(e.nodeType===t.nodeType)return!0;return(e.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:e.nodeType)===(t.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:t.nodeType)}const n=e.parentNode?e.parentNode.children:null;if(!n)return 0;let o;for(let r=0;r<n.length;++r)if(t(e,n[r])&&n[r]!==e){o=!0;break}if(!o)return 0;let r=1;for(let o=0;o<n.length;++o)if(t(e,n[o])){if(n[o]===e)return r;++r}throw new Error("This is impossible; a child must be the child of the parent")},k=(e,t)=>{if(void 0!==e)return"string"==typeof e?`${t}/${e}`:e.map((e=>`${t}/${e}`))};class C{#p=["data-testid","data-test","data-qa","data-cy","data-test-id","data-qa-id","data-testing"];#i;#m;#w=new n;#E;constructor(e,t,n="",o){this.#i=e,this.#m=t;let r=["aria","css","xpath","pierce","text"];n&&(this.#p.unshift(n),r=["css","xpath","pierce","aria","text"]),this.#E=r.filter((e=>!o||o.includes(e))).map((e=>{switch(e){case"css":return this.getCSSSelector.bind(this);case"xpath":return this.getXPathSelector.bind(this);case"pierce":return this.getPierceSelector.bind(this);case"aria":return this.getARIASelector.bind(this);case"text":return this.getTextSelector.bind(this);default:throw new Error("Unknown selector type: "+e)}}))}getSelectors(e){const t=[];for(const n of this.#E){const o=n(e);o&&t.push(o)}return t}getCSSSelector(e){return this.#m.timed(`getCSSSelector: ${this.#w.getOrInsert(e)} ${e.nodeName}`,(()=>((e,t)=>{const n=[];try{let o;for(;e instanceof Element;)o=e.getRootNode(),n.unshift(l([e,o],new a(t))),e=o instanceof ShadowRoot?o.host:o}catch{return}return n})(e,this.#p)))}getTextSelector(e){return this.#m.timed(`getTextSelector: ${this.#w.getOrInsert(e)} ${e.nodeName}`,(()=>k((e=>{const t=T(e).full.trim();if(!t)return;if(t.length<=12){const n=y(S(document,t),2);if(1!==n.length||n[0]!==e)return;return[t]}if(t.length>64)return;let n=12,o=t.length;for(;n<=o;){const r=n+(o-n>>2),i=y(S(document,t.slice(0,r)),2);1!==i.length||i[0]!==e?n=r+1:o=r-1}if(o===t.length)return;const r=o+1,i=t.slice(r,r+64);return[t.slice(0,r+i.search(/ |$/))]})(e),"text")))}getXPathSelector(e){return this.#m.timed(`getXPathSelector: ${this.#w.getOrInsert(e)} ${e.nodeName}`,(()=>k(((e,t,n)=>{if(e.nodeType===Node.DOCUMENT_NODE)return"/";const o=[],r=[];let i=e;for(;i!==document&&i;){const e=v(i,t,n);if(!e)return;r.unshift(e),i=e.optimized?i.getRootNode():i.parentNode,i instanceof ShadowRoot&&(o.unshift((r[0].optimized?"":"/")+r.join("/")),r.splice(0,r.length),i=i.host)}return r.length&&o.unshift((r[0].optimized?"":"/")+r.join("/")),!o.length||o.length>1?void 0:o})(e,!0,this.#p),"xpath")))}getPierceSelector(e){return this.#m.timed(`getPierceSelector: ${this.#w.getOrInsert(e)} ${e.nodeName}`,(()=>k(((e,t)=>{try{const n=new u(t);return l([e,document],n).flat()}catch{return}})(e,this.#p),"pierce")))}getARIASelector(e){return this.#m.timed(`getARIASelector: ${this.#w.getOrInsert(e)} ${e.nodeName}`,(()=>k(((e,t)=>new o(t).compute(e))(e,this.#i),"aria")))}}const I=e=>{e.preventDefault(),e.stopImmediatePropagation()},O=(e,t)=>{const n=t.getBoundingClientRect();return{offsetX:e.clientX-n.x,offsetY:e.clientY-n.y}},A=e=>{for(const t of e.composedPath()){if(!(t instanceof Element))continue;const e=t.getBoundingClientRect();if(0!==e.width&&0!==e.height)return t}throw new Error(`No target is found in event of type ${e.type}`)},R=e=>Object.values(e).filter((e=>Boolean(e))).length.toString();class D{static defaultSetupOptions=Object.freeze({debug:!1,allowUntrustedEvents:!1,selectorTypesToRecord:["aria","css","text","xpath","pierce"]});#T;#S=e=>e.isTrusted;#y=[];#m;constructor(e,n=D.defaultSetupOptions){this.#m=new t(n.debug?"debug":"silent"),this.#m.log("creating a RecordingClient"),this.#T=new C(e,this.#m,n.selectorAttribute,n.selectorTypesToRecord),n.allowUntrustedEvents&&(this.#S=()=>!0),this.#y=n.stopShortcuts??[]}start=()=>{this.#m.log("Setting up recording listeners"),window.addEventListener("keydown",this.#N,!0),window.addEventListener("beforeinput",this.#v,!0),window.addEventListener("input",this.#b,!0),window.addEventListener("keyup",this.#k,!0),window.addEventListener("pointerdown",this.#C,!0),window.addEventListener("click",this.#I,!0),window.addEventListener("auxclick",this.#I,!0),window.addEventListener("beforeunload",this.#O,!0)};stop=()=>{this.#m.log("Tearing down client listeners"),window.removeEventListener("keydown",this.#N,!0),window.removeEventListener("beforeinput",this.#v,!0),window.removeEventListener("input",this.#b,!0),window.removeEventListener("keyup",this.#k,!0),window.removeEventListener("pointerdown",this.#C,!0),window.removeEventListener("click",this.#I,!0),window.removeEventListener("auxclick",this.#I,!0),window.removeEventListener("beforeunload",this.#O,!0)};getSelectors=e=>this.#T.getSelectors(e);getCSSSelector=e=>this.#T.getCSSSelector(e);getTextSelector=e=>this.#T.getTextSelector(e);queryCSSSelectorAllForTesting=e=>(e=>{if("string"==typeof e)e=[e];else if(0===e.length)return[];let t=[[document.documentElement]];do{const n=e.shift(),o=[];for(const e of t)for(const t of e){const e=(t.shadowRoot??t).querySelectorAll(n);e.length>0&&o.push(e)}t=o}while(e.length>0&&t.length>0);return t.flatMap((e=>[...e]))})(e);#A=e=>{for(const t of this.#y??[])if(e.shiftKey===t.shift&&e.ctrlKey===t.ctrl&&e.metaKey===t.meta&&e.keyCode===t.keyCode)return this.stop(),I(e),window.stopShortcut(R(t)),!0;return!1};#R={element:document.documentElement,selectors:[]};#D=e=>{const t=e.composedPath()[0];!function(e){if(!e)throw new Error("Assertion failed!")}(t instanceof Element),this.#R.element!==t&&(this.#R={element:t,selectors:this.getSelectors(t)})};#N=e=>{this.#S(e)&&(this.#A(e)||(this.#D(e),this.#L({type:"keyDown",key:e.key})))};#v=e=>{this.#S(e)&&this.#D(e)};#b=e=>{if(!this.#S(e))return;if(this.#D(e),(e=>{if(e instanceof HTMLInputElement)switch(e.type){case"checkbox":case"radio":return!0}return!1})(this.#R.element))return;const{element:t,selectors:n}=this.#R;this.#L({type:"change",selectors:n,value:"value"in t?t.value:t.textContent})};#k=e=>{this.#S(e)&&this.#L({type:"keyUp",key:e.key})};#P={element:document.documentElement,selectors:[]};#x=e=>{const t=A(e);this.#P.element!==t&&(this.#P={element:t,selectors:this.#T.getSelectors(t)})};#$=0;#C=e=>{this.#S(e)&&(this.#$=e.timeStamp,this.#x(e))};#I=e=>{if(!this.#S(e))return;this.#x(e);const t=((e,t)=>{let n;if(e instanceof PointerEvent)switch(e.pointerType){case"mouse":break;case"pen":case"touch":n=e.pointerType;break;default:return}const{offsetX:o,offsetY:r}=O(e,t);if(!(o<0||r<0))return{button:["auxiliary","secondary","back","forward"][e.button-1],deviceType:n,offsetX:o,offsetY:r}})(e,this.#P.element);if(!t)return;const n=e.timeStamp-this.#$;this.#L({type:2===e.detail?"doubleClick":"click",selectors:this.#P.selectors,duration:n>350?n:void 0,...t})};#O=e=>{this.#m.log("Unloading..."),this.#S(e)&&this.#L({type:"beforeUnload"})};#L=e=>{const t=JSON.stringify(e);this.#m.log(`Adding step: ${t}`),window.addStep(t)}}class L{#m;#T;constructor(e,n="",o=!0){this.#m=new t(o?"debug":"silent"),this.#m.log("Creating a SelectorPicker"),this.#T=new C(e,this.#m,n)}#B=e=>{I(e);const t=A(e);window.captureSelectors(JSON.stringify({selectors:this.#T.getSelectors(t),...O(e,t)}))};start=()=>{this.#m.log("Setting up selector listeners"),window.addEventListener("click",this.#B,!0),window.addEventListener("mousedown",I,!0),window.addEventListener("mouseup",I,!0)};stop=()=>{this.#m.log("Tearing down selector listeners"),window.removeEventListener("click",this.#B,!0),window.removeEventListener("mousedown",I,!0),window.removeEventListener("mouseup",I,!0)}}class P{#_;startRecording(e,t){if(this.#_)throw new Error("Recording client already started.");if(this.#M)throw new Error("Selector picker is active.");this.#_=new D(e,t),this.#_.start()}stopRecording(){if(!this.#_)throw new Error("Recording client was not started.");this.#_.stop(),this.#_=void 0}get recordingClientForTesting(){if(!this.#_)throw new Error("Recording client was not started.");return this.#_}#M;startSelectorPicker(e,t,n){if(this.#M)throw new Error("Selector picker already started.");this.#_&&this.#_.stop(),this.#M=new L(e,t,n),this.#M.start()}stopSelectorPicker(){if(!this.#M)throw new Error("Selector picker was not started.");this.#M.stop(),this.#M=void 0,this.#_&&this.#_.start()}}window.DevToolsRecorder||(window.DevToolsRecorder=new P);