@inploi/plugin-collaborate 0.0.12 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cdn/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/cdn/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// This is an inploi sdk script. Learn more at https://inploi.com
|
|
2
2
|
|
|
3
|
-
"use strict";(()=>{var P=Object.defineProperty;var m=Object.getOwnPropertySymbols;var v=Object.prototype.hasOwnProperty,_=Object.prototype.propertyIsEnumerable;var h=(e,t,n)=>t in e?P(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,E=(e,t)=>{for(var n in t||(t={}))v.call(t,n)&&h(e,n,t[n]);if(m)for(var n of m(t))_.call(t,n)&&h(e,n,t[n]);return e};var f=e=>e;var O="isdk_session";var
|
|
3
|
+
"use strict";(()=>{var P=Object.defineProperty;var m=Object.getOwnPropertySymbols;var v=Object.prototype.hasOwnProperty,_=Object.prototype.propertyIsEnumerable;var h=(e,t,n)=>t in e?P(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,E=(e,t)=>{for(var n in t||(t={}))v.call(t,n)&&h(e,n,t[n]);if(m)for(var n of m(t))_.call(t,n)&&h(e,n,t[n]);return e};var f=e=>e;var O="isdk_session";var D=new RegExp(`${O}=([^;]+)`);var x=["(",")",".",",","_","%"],R=e=>{let t=!1,n="";for(let r of e)r==="["?(t=!0,n+=r):r==="]"?(t=!1,n+=r):t&&x.includes(r)?n+="\\"+r:n+=r;return n},y=e=>R(e).replace(new RegExp("(?<!\\\\)[:[\\]/+]","g"),"\\$&"),I=e=>{var r,i,u,a,d,s,o,p;if(((r=e.element)==null?void 0:r.getAttribute("id"))!==null&&!((i=e.id)!=null&&i.length))return e.id=`#${(u=e.element)==null?void 0:u.getAttribute("id")}`,e;if(e.element&&e.element.className.length>0&&!((a=e.classes)!=null&&a.length))return e.classes=`.${y(e.element.className).split(" ").join(".")}`,e;let t=[e.classes,e.id].filter(Boolean).join("")||((d=e.element)==null?void 0:d.tagName),n=(s=e.element)==null?void 0:s.parentElement;if(n){let l=Array.from(n.children).findIndex(S=>S===e.element);return{element:(o=e.element)==null?void 0:o.parentElement,children:[`${t}:nth-child(${l+1})`,...(p=e.children)!=null?p:[]]}}throw new Error("Unable to uniquely identify selector: not unique enough")},b=(e,t)=>{let n=r=>{var d;let i=I(r),u=[[i.classes,i.id].filter(Boolean).join(""),...(d=i.children)!=null?d:[]].filter(Boolean).join(">"),a=t.querySelectorAll(u);return a.length>1&&a.length<100?n(i):a.length===1?u:null};return n({element:e,children:[]})};var c=e=>{window.parent.postMessage(E({source:"inploi-collaborate"},e),"*")};var C=e=>e.data.source==="inploi-collaborate";var g=e=>{let t=e.getBoundingClientRect();return{_brand:"pin",x:window.scrollX+t.x,y:window.scrollY+t.y,width:t.width,height:t.height}},T=e=>{let t={};for(let n of e){let r=document.querySelector(y(n));t[n]=r?g(r):null}return t};function N(e,t){let n;return(...r)=>{clearTimeout(n),n=setTimeout(()=>e(...r),t)}}var L=({logger:e,signal:t})=>{let n=[],r;c({type:"READY"}),e.info("Collaborate bridge: Ready");let i=N(()=>{c({type:"SELECTOR_RECTS",selectorRects:T(n)})},50),u=()=>{r&&c({type:"HOVER_ELEMENT",rect:g(r)})},a=d=>{if(C(d)===!1)return;let s=d.data;switch(s.type){case"WATCH_SELECTORS":{n=s.selectors,i();break}case"MOUSE_POSITION":{let o=document.elementsFromPoint(s.x,s.y)[0];if(o===r)return;r=o,u();break}case"DROP_PIN":{let o=document.elementsFromPoint(s.x,s.y)[0];if(!o)return;let p=b(o,document.body);if(!p)return;let l=o.getBoundingClientRect();c({type:"PIN_POSITION",pin:{rect:g(o),selector:p,xPercent:(s.x-l.x)/l.width,yPercent:(s.y-l.y)/l.height}});break}case"SETUP_EVENT_HANDLERS":{e.info("Collaborate bridge: Setting up event handlers"),window.addEventListener("beforeunload",()=>{c({type:"DISPOSE"})}),c({type:"RESIZE",scrollHeight:document.body.scrollHeight}),window.addEventListener("resize",()=>{i(),c({type:"RESIZE",scrollHeight:document.body.scrollHeight})},{signal:t}),document.body.addEventListener("click",o=>{if(o.preventDefault(),o.stopPropagation(),!r)return;let p=b(r,document.body);if(!p)return;let l=r.getBoundingClientRect();u(),c({type:"PIN_POSITION",pin:{rect:g(r),selector:p,xPercent:(o.clientX-l.x)/l.width,yPercent:(o.clientY-l.y)/l.height}})},{signal:t}),e.info("Collaborate bridge: Event handlers set up");break}case"SCROLL":window.scrollTo({left:s.scrollX,top:s.scrollY,behavior:"instant"}),i();break;default:}};window.addEventListener("message",a,{signal:t}),t==null||t.addEventListener("abort",()=>{e.info("Collaborate bridge: disposing"),c({type:"DISPOSE"}),window.removeEventListener("message",a)})},w=()=>f(({logger:e})=>({setupBridge:t=>L({logger:e,signal:t==null?void 0:t.signal})}));if(!window.inploi)throw new Error("Please insert the SDK script tag above the plugins.");window.inploi.collaboratePlugin=w;})();
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var E=Object.defineProperty;var
|
|
1
|
+
"use strict";var E=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames,m=Object.getOwnPropertySymbols;var P=Object.prototype.hasOwnProperty,w=Object.prototype.propertyIsEnumerable;var h=(e,t,n)=>t in e?E(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,g=(e,t)=>{for(var n in t||(t={}))P.call(t,n)&&h(e,n,t[n]);if(m)for(var n of m(t))w.call(t,n)&&h(e,n,t[n]);return e};var x=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},C=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of O(t))!P.call(e,o)&&o!==n&&E(e,o,{get:()=>t[o],enumerable:!(r=I(t,o))||r.enumerable});return e};var f=e=>C(E({},"__esModule",{value:!0}),e);var F={};x(F,{collaboratePlugin:()=>k,createInboundEventSender:()=>_,isCollaborateOutboundEvent:()=>D});module.exports=f(F);var R=require("@inploi/sdk");var T=["(",")",".",",","_","%"],N=e=>{let t=!1,n="";for(let r of e)r==="["?(t=!0,n+=r):r==="]"?(t=!1,n+=r):t&&T.includes(r)?n+="\\"+r:n+=r;return n},y=e=>N(e).replace(new RegExp("(?<!\\\\)[:[\\]/+]","g"),"\\$&"),L=e=>{var r,o,u,c,d,s,l,p;if(((r=e.element)==null?void 0:r.getAttribute("id"))!==null&&!((o=e.id)!=null&&o.length))return e.id=`#${(u=e.element)==null?void 0:u.getAttribute("id")}`,e;if(e.element&&e.element.className.length>0&&!((c=e.classes)!=null&&c.length))return e.classes=`.${y(e.element.className).split(" ").join(".")}`,e;let t=[e.classes,e.id].filter(Boolean).join("")||((d=e.element)==null?void 0:d.tagName),n=(s=e.element)==null?void 0:s.parentElement;if(n){let i=Array.from(n.children).findIndex(v=>v===e.element);return{element:(l=e.element)==null?void 0:l.parentElement,children:[`${t}:nth-child(${i+1})`,...(p=e.children)!=null?p:[]]}}throw new Error("Unable to uniquely identify selector: not unique enough")},S=(e,t)=>{let n=r=>{var d;let o=L(r),u=[[o.classes,o.id].filter(Boolean).join(""),...(d=o.children)!=null?d:[]].filter(Boolean).join(">"),c=t.querySelectorAll(u);return c.length>1&&c.length<100?n(o):c.length===1?u:null};return n({element:e,children:[]})};var a=e=>{window.parent.postMessage(g({source:"inploi-collaborate"},e),"*")},_=e=>({sendInboundEvent:t=>{var n;return(n=e.source)==null?void 0:n.postMessage(g({source:"inploi-collaborate"},t),{targetOrigin:e.origin})}}),A=e=>e.data.source==="inploi-collaborate",D=e=>e.data.source==="inploi-collaborate",b=e=>{let t=e.getBoundingClientRect();return{_brand:"pin",x:window.scrollX+t.x,y:window.scrollY+t.y,width:t.width,height:t.height}},H=e=>{let t={};for(let n of e){let r=document.querySelector(y(n));t[n]=r?b(r):null}return t};function M(e,t){let n;return(...r)=>{clearTimeout(n),n=setTimeout(()=>e(...r),t)}}var B=({logger:e,signal:t})=>{let n=[],r;a({type:"READY"}),e.info("Collaborate bridge: Ready");let o=M(()=>{a({type:"SELECTOR_RECTS",selectorRects:H(n)})},50),u=()=>{r&&a({type:"HOVER_ELEMENT",rect:b(r)})},c=d=>{if(A(d)===!1)return;let s=d.data;switch(s.type){case"WATCH_SELECTORS":{n=s.selectors,o();break}case"MOUSE_POSITION":{let l=document.elementsFromPoint(s.x,s.y)[0];if(l===r)return;r=l,u();break}case"DROP_PIN":{let l=document.elementsFromPoint(s.x,s.y)[0];if(!l)return;let p=S(l,document.body);if(!p)return;let i=l.getBoundingClientRect();a({type:"PIN_POSITION",pin:{rect:b(l),selector:p,xPercent:(s.x-i.x)/i.width,yPercent:(s.y-i.y)/i.height}});break}case"SETUP_EVENT_HANDLERS":{e.info("Collaborate bridge: Setting up event handlers"),window.addEventListener("beforeunload",()=>{a({type:"DISPOSE"})}),a({type:"RESIZE",scrollHeight:document.body.scrollHeight}),window.addEventListener("resize",()=>{o(),a({type:"RESIZE",scrollHeight:document.body.scrollHeight})},{signal:t}),document.body.addEventListener("click",l=>{if(l.preventDefault(),l.stopPropagation(),!r)return;let p=S(r,document.body);if(!p)return;let i=r.getBoundingClientRect();u(),a({type:"PIN_POSITION",pin:{rect:b(r),selector:p,xPercent:(l.clientX-i.x)/i.width,yPercent:(l.clientY-i.y)/i.height}})},{signal:t}),e.info("Collaborate bridge: Event handlers set up");break}case"SCROLL":window.scrollTo({left:s.scrollX,top:s.scrollY,behavior:"instant"}),o();break;default:}};window.addEventListener("message",c,{signal:t}),t==null||t.addEventListener("abort",()=>{e.info("Collaborate bridge: disposing"),a({type:"DISPOSE"}),window.removeEventListener("message",c)})},k=()=>(0,R.createPlugin)(({logger:e})=>({setupBridge:t=>B({logger:e,signal:t==null?void 0:t.signal})}));0&&(module.exports={collaboratePlugin,createInboundEventSender,isCollaborateOutboundEvent});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/collaborate.ts","../src/collaborate.selector.ts"],"sourcesContent":["export * from './collaborate';\n","import { Logger, createPlugin } from '@inploi/sdk';\n\nimport { escapeClassName, getElementUniqueSelector } from './collaborate.selector';\n\nexport type CollaborateInboundEvent =\n\t| {\n\t\t\ttype: 'SETUP_EVENT_HANDLERS';\n\t }\n\t| { type: 'WATCH_SELECTORS'; selectors: string[] }\n\t| { type: 'SCROLL'; scrollY: number; scrollX: number }\n\t| { type: 'MOUSE_POSITION'; x: number; y: number }\n\t| { type: 'DROP_PIN'; x: number; y: number };\n\nexport type CollaborateOutboundEvent =\n\t| { type: 'READY' }\n\t| {\n\t\t\ttype: 'RESIZE';\n\t\t\tscrollHeight: number;\n\t }\n\t| {\n\t\t\ttype: 'HOVER_ELEMENT';\n\t\t\trect: PinRect | null;\n\t }\n\t| {\n\t\t\ttype: 'PIN_POSITION';\n\t\t\tpin: DroppedPin;\n\t }\n\t| {\n\t\t\ttype: 'DISPOSE';\n\t }\n\t| {\n\t\t\ttype: 'SELECTOR_RECTS';\n\t\t\tselectorRects: SelectorRects;\n\t };\n\nexport type DroppedPin = { selector: string; xPercent: number; yPercent: number; rect: PinRect };\n\nconst sendOutboundEvent = (data: CollaborateOutboundEvent) => {\n\twindow.parent.postMessage({ source: 'inploi-collaborate', ...data }, '*');\n};\n\nexport const createInboundEventSender = (e: MessageEvent) => {\n\treturn {\n\t\tsendInboundEvent: (data: CollaborateInboundEvent) =>\n\t\t\te.source?.postMessage({ source: 'inploi-collaborate', ...data }, { targetOrigin: e.origin }),\n\t};\n};\n\nconst isCollaborateInboundEvent = (event: MessageEvent): event is MessageEvent<CollaborateInboundEvent> => {\n\treturn event.data.source === 'inploi-collaborate';\n};\n\nexport const isCollaborateOutboundEvent = (event: MessageEvent): event is MessageEvent<CollaborateOutboundEvent> => {\n\treturn event.data.source === 'inploi-collaborate';\n};\n\nexport type PinRect = {\n\t_brand: 'pin';\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n};\n\nconst getElementPinRect = (element: Element): PinRect => {\n\tconst boundingBox = element.getBoundingClientRect();\n\treturn {\n\t\t_brand: 'pin',\n\t\tx: window.scrollX + boundingBox.x,\n\t\ty: window.scrollY + boundingBox.y,\n\t\twidth: boundingBox.width,\n\t\theight: boundingBox.height,\n\t};\n};\n\nexport type SelectorRects = { [selector: string]: PinRect | null };\n\nconst getSelectorRects = (selectors: string[]) => {\n\tconst selectorRects: SelectorRects = {};\n\tfor (const selector of selectors) {\n\t\tconst element = document.querySelector(escapeClassName(selector));\n\t\tselectorRects[selector] = element ? getElementPinRect(element) : null;\n\t}\n\treturn selectorRects;\n};\n\nfunction debounce<F extends (...args: Parameters<F>) => ReturnType<F>>(\n\tfunc: F,\n\twaitFor: number,\n): (...args: Parameters<F>) => void {\n\tlet timeout: ReturnType<typeof setTimeout>;\n\n\treturn (...args: Parameters<F>): void => {\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(() => func(...args), waitFor);\n\t};\n}\n\n/** Sets up the bridge for Collaborate to be able to communicate with the host page */\nconst setupBridge = ({ logger, signal }: { signal?: AbortSignal; logger: Logger }) => {\n\tlet watchedSelectors: string[] = [];\n\tlet hoveredElement: Element | undefined;\n\tsendOutboundEvent({ type: 'READY' });\n\tlogger.info('Collaborate bridge: Ready');\n\n\tconst broadcastSelectors = debounce(() => {\n\t\tsendOutboundEvent({ type: 'SELECTOR_RECTS', selectorRects: getSelectorRects(watchedSelectors) });\n\t}, 50);\n\n\tconst broadcastHoveredElement = () => {\n\t\tif (!hoveredElement) return;\n\t\tsendOutboundEvent({\n\t\t\ttype: 'HOVER_ELEMENT',\n\t\t\trect: getElementPinRect(hoveredElement),\n\t\t});\n\t};\n\n\tconst handleEvent = (messageEvent: MessageEvent) => {\n\t\tif (isCollaborateInboundEvent(messageEvent) === false) return;\n\t\tconst collaborateEvent = messageEvent.data;\n\t\tswitch (collaborateEvent.type) {\n\t\t\tcase 'WATCH_SELECTORS': {\n\t\t\t\twatchedSelectors = collaborateEvent.selectors;\n\t\t\t\tbroadcastSelectors();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'MOUSE_POSITION': {\n\t\t\t\tconst newElement = document.elementsFromPoint(collaborateEvent.x, collaborateEvent.y)[0];\n\t\t\t\tif (newElement === hoveredElement) return;\n\t\t\t\thoveredElement = newElement;\n\t\t\t\tbroadcastHoveredElement();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'DROP_PIN': {\n\t\t\t\tconst element = document.elementsFromPoint(collaborateEvent.x, collaborateEvent.y)[0];\n\t\t\t\tif (!element) return;\n\t\t\t\tconst selector = getElementUniqueSelector(element, document.body);\n\t\t\t\tif (!selector) return;\n\t\t\t\tconst rect = element.getBoundingClientRect();\n\t\t\t\tsendOutboundEvent({\n\t\t\t\t\ttype: 'PIN_POSITION',\n\t\t\t\t\tpin: {\n\t\t\t\t\t\trect: getElementPinRect(element),\n\t\t\t\t\t\tselector,\n\t\t\t\t\t\txPercent: (collaborateEvent.x - rect.x) / rect.width,\n\t\t\t\t\t\tyPercent: (collaborateEvent.y - rect.y) / rect.height,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'SETUP_EVENT_HANDLERS': {\n\t\t\t\tlogger.info('Collaborate bridge: Setting up event handlers');\n\t\t\t\twindow.addEventListener('beforeunload', () => {\n\t\t\t\t\tsendOutboundEvent({ type: 'DISPOSE' });\n\t\t\t\t});\n\t\t\t\tsendOutboundEvent({ type: 'RESIZE', scrollHeight: document.body.scrollHeight });\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'resize',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tbroadcastSelectors();\n\t\t\t\t\t\tsendOutboundEvent({ type: 'RESIZE', scrollHeight: document.body.scrollHeight });\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\n\t\t\t\tdocument.body.addEventListener(\n\t\t\t\t\t'click',\n\t\t\t\t\tevent => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tif (!hoveredElement) return;\n\t\t\t\t\t\tconst selector = getElementUniqueSelector(hoveredElement, document.body);\n\t\t\t\t\t\tif (!selector) return;\n\t\t\t\t\t\tconst rect = hoveredElement.getBoundingClientRect();\n\t\t\t\t\t\tbroadcastHoveredElement();\n\t\t\t\t\t\tsendOutboundEvent({\n\t\t\t\t\t\t\ttype: 'PIN_POSITION',\n\t\t\t\t\t\t\tpin: {\n\t\t\t\t\t\t\t\trect: getElementPinRect(hoveredElement),\n\t\t\t\t\t\t\t\tselector,\n\t\t\t\t\t\t\t\txPercent: (event.clientX - rect.x) / rect.width,\n\t\t\t\t\t\t\t\tyPercent: (event.clientY - rect.y) / rect.height,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\t\t\t\tlogger.info('Collaborate bridge: Event handlers set up');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'SCROLL':\n\t\t\t\twindow.scrollTo({ left: collaborateEvent.scrollX, top: collaborateEvent.scrollY, behavior: 'instant' });\n\t\t\t\tbroadcastSelectors();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcollaborateEvent satisfies never;\n\t\t}\n\t};\n\n\twindow.addEventListener('message', handleEvent, { signal });\n\tsignal?.addEventListener('abort', () => {\n\t\tlogger.info('Collaborate bridge: disposing');\n\t\tsendOutboundEvent({ type: 'DISPOSE' });\n\t\twindow.removeEventListener('message', handleEvent);\n\t});\n};\n\nexport const collaboratePlugin = () =>\n\tcreatePlugin(({ logger }) => ({\n\t\tsetupBridge: (params?: { signal?: AbortSignal }) =>\n\t\t\tsetupBridge({\n\t\t\t\tlogger,\n\t\t\t\tsignal: params?.signal,\n\t\t\t}),\n\t}));\n","type SelectorProperties = {\n\telement: Element | null | undefined;\n\tid?: string;\n\tclasses?: string;\n\tchildren?: string[];\n};\n\nexport const escapeClassName = (input: string) => {\n\treturn input.replace(/(?<!\\\\)[:[\\]/]/g, '\\\\$&');\n};\n\nconst getSelectorProperties = (from: SelectorProperties): SelectorProperties => {\n\tif (from.element?.getAttribute('id') !== null && !from.id?.length) {\n\t\tfrom.id = `#${from.element?.getAttribute('id')}`;\n\t\treturn from;\n\t}\n\n\tif (from.element && from.element.className.length > 0 && !from.classes?.length) {\n\t\tfrom.classes = `.${escapeClassName(from.element.className).split(' ').join('.')}`;\n\t\treturn from;\n\t}\n\n\tconst newSelector = [from.classes, from.id].filter(Boolean).join('') || from.element?.tagName;\n\n\tconst parent = from.element?.parentElement;\n\tif (parent) {\n\t\tconst childIndex = Array.from(parent.children).findIndex(child => child === from.element);\n\t\treturn {\n\t\t\telement: from.element?.parentElement,\n\t\t\tchildren: [`${newSelector}:nth-child(${childIndex + 1})`, ...(from.children ?? [])],\n\t\t};\n\t}\n\tthrow new Error('Unable to uniquely identify selector: not unique enough');\n};\n\nexport const getElementUniqueSelector = (element: Element, context: Element) => {\n\tconst getSelector = (prefilled: SelectorProperties): string | null => {\n\t\tconst properties = getSelectorProperties(prefilled);\n\n\t\tconst newSelector = [[properties.classes, properties.id].filter(Boolean).join(''), ...(properties.children ?? [])]\n\t\t\t.filter(Boolean)\n\t\t\t.join('>');\n\n\t\tconst matchingSelectors = context.querySelectorAll(newSelector);\n\n\t\tif (matchingSelectors.length > 1 && matchingSelectors.length < 100) return getSelector(properties);\n\t\tif (matchingSelectors.length === 1) return newSelector;\n\n\t\treturn null;\n\t};\n\n\treturn getSelector({ element, children: [] });\n};\n"],"mappings":"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","names":["src_exports","__export","collaboratePlugin","createInboundEventSender","isCollaborateOutboundEvent","__toCommonJS","import_sdk","escapeClassName","input","getSelectorProperties","from","_a","_b","_c","_d","_e","_f","_g","_h","newSelector","parent","childIndex","child","getElementUniqueSelector","element","context","getSelector","prefilled","properties","matchingSelectors","sendOutboundEvent","data","__spreadValues","createInboundEventSender","_a","isCollaborateInboundEvent","event","isCollaborateOutboundEvent","getElementPinRect","element","boundingBox","getSelectorRects","selectors","selectorRects","selector","escapeClassName","debounce","func","waitFor","timeout","args","setupBridge","logger","signal","watchedSelectors","hoveredElement","broadcastSelectors","broadcastHoveredElement","handleEvent","messageEvent","collaborateEvent","newElement","getElementUniqueSelector","rect","collaboratePlugin","params"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/collaborate.ts","../src/collaborate.selector.ts"],"sourcesContent":["export * from './collaborate';\n","import { Logger, createPlugin } from '@inploi/sdk';\n\nimport { escapeClassName, getElementUniqueSelector } from './collaborate.selector';\n\nexport type CollaborateInboundEvent =\n\t| {\n\t\t\ttype: 'SETUP_EVENT_HANDLERS';\n\t }\n\t| { type: 'WATCH_SELECTORS'; selectors: string[] }\n\t| { type: 'SCROLL'; scrollY: number; scrollX: number }\n\t| { type: 'MOUSE_POSITION'; x: number; y: number }\n\t| { type: 'DROP_PIN'; x: number; y: number };\n\nexport type CollaborateOutboundEvent =\n\t| { type: 'READY' }\n\t| {\n\t\t\ttype: 'RESIZE';\n\t\t\tscrollHeight: number;\n\t }\n\t| {\n\t\t\ttype: 'HOVER_ELEMENT';\n\t\t\trect: PinRect | null;\n\t }\n\t| {\n\t\t\ttype: 'PIN_POSITION';\n\t\t\tpin: DroppedPin;\n\t }\n\t| {\n\t\t\ttype: 'DISPOSE';\n\t }\n\t| {\n\t\t\ttype: 'SELECTOR_RECTS';\n\t\t\tselectorRects: SelectorRects;\n\t };\n\nexport type DroppedPin = { selector: string; xPercent: number; yPercent: number; rect: PinRect };\n\nconst sendOutboundEvent = (data: CollaborateOutboundEvent) => {\n\twindow.parent.postMessage({ source: 'inploi-collaborate', ...data }, '*');\n};\n\nexport const createInboundEventSender = (e: MessageEvent) => {\n\treturn {\n\t\tsendInboundEvent: (data: CollaborateInboundEvent) =>\n\t\t\te.source?.postMessage({ source: 'inploi-collaborate', ...data }, { targetOrigin: e.origin }),\n\t};\n};\n\nconst isCollaborateInboundEvent = (event: MessageEvent): event is MessageEvent<CollaborateInboundEvent> => {\n\treturn event.data.source === 'inploi-collaborate';\n};\n\nexport const isCollaborateOutboundEvent = (event: MessageEvent): event is MessageEvent<CollaborateOutboundEvent> => {\n\treturn event.data.source === 'inploi-collaborate';\n};\n\nexport type PinRect = {\n\t_brand: 'pin';\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n};\n\nconst getElementPinRect = (element: Element): PinRect => {\n\tconst boundingBox = element.getBoundingClientRect();\n\treturn {\n\t\t_brand: 'pin',\n\t\tx: window.scrollX + boundingBox.x,\n\t\ty: window.scrollY + boundingBox.y,\n\t\twidth: boundingBox.width,\n\t\theight: boundingBox.height,\n\t};\n};\n\nexport type SelectorRects = { [selector: string]: PinRect | null };\n\nconst getSelectorRects = (selectors: string[]) => {\n\tconst selectorRects: SelectorRects = {};\n\tfor (const selector of selectors) {\n\t\tconst element = document.querySelector(escapeClassName(selector));\n\t\tselectorRects[selector] = element ? getElementPinRect(element) : null;\n\t}\n\treturn selectorRects;\n};\n\nfunction debounce<F extends (...args: Parameters<F>) => ReturnType<F>>(\n\tfunc: F,\n\twaitFor: number,\n): (...args: Parameters<F>) => void {\n\tlet timeout: ReturnType<typeof setTimeout>;\n\n\treturn (...args: Parameters<F>): void => {\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(() => func(...args), waitFor);\n\t};\n}\n\n/** Sets up the bridge for Collaborate to be able to communicate with the host page */\nconst setupBridge = ({ logger, signal }: { signal?: AbortSignal; logger: Logger }) => {\n\tlet watchedSelectors: string[] = [];\n\tlet hoveredElement: Element | undefined;\n\tsendOutboundEvent({ type: 'READY' });\n\tlogger.info('Collaborate bridge: Ready');\n\n\tconst broadcastSelectors = debounce(() => {\n\t\tsendOutboundEvent({ type: 'SELECTOR_RECTS', selectorRects: getSelectorRects(watchedSelectors) });\n\t}, 50);\n\n\tconst broadcastHoveredElement = () => {\n\t\tif (!hoveredElement) return;\n\t\tsendOutboundEvent({\n\t\t\ttype: 'HOVER_ELEMENT',\n\t\t\trect: getElementPinRect(hoveredElement),\n\t\t});\n\t};\n\n\tconst handleEvent = (messageEvent: MessageEvent) => {\n\t\tif (isCollaborateInboundEvent(messageEvent) === false) return;\n\t\tconst collaborateEvent = messageEvent.data;\n\t\tswitch (collaborateEvent.type) {\n\t\t\tcase 'WATCH_SELECTORS': {\n\t\t\t\twatchedSelectors = collaborateEvent.selectors;\n\t\t\t\tbroadcastSelectors();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'MOUSE_POSITION': {\n\t\t\t\tconst newElement = document.elementsFromPoint(collaborateEvent.x, collaborateEvent.y)[0];\n\t\t\t\tif (newElement === hoveredElement) return;\n\t\t\t\thoveredElement = newElement;\n\t\t\t\tbroadcastHoveredElement();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'DROP_PIN': {\n\t\t\t\tconst element = document.elementsFromPoint(collaborateEvent.x, collaborateEvent.y)[0];\n\t\t\t\tif (!element) return;\n\t\t\t\tconst selector = getElementUniqueSelector(element, document.body);\n\t\t\t\tif (!selector) return;\n\t\t\t\tconst rect = element.getBoundingClientRect();\n\t\t\t\tsendOutboundEvent({\n\t\t\t\t\ttype: 'PIN_POSITION',\n\t\t\t\t\tpin: {\n\t\t\t\t\t\trect: getElementPinRect(element),\n\t\t\t\t\t\tselector,\n\t\t\t\t\t\txPercent: (collaborateEvent.x - rect.x) / rect.width,\n\t\t\t\t\t\tyPercent: (collaborateEvent.y - rect.y) / rect.height,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'SETUP_EVENT_HANDLERS': {\n\t\t\t\tlogger.info('Collaborate bridge: Setting up event handlers');\n\t\t\t\twindow.addEventListener('beforeunload', () => {\n\t\t\t\t\tsendOutboundEvent({ type: 'DISPOSE' });\n\t\t\t\t});\n\t\t\t\tsendOutboundEvent({ type: 'RESIZE', scrollHeight: document.body.scrollHeight });\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'resize',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tbroadcastSelectors();\n\t\t\t\t\t\tsendOutboundEvent({ type: 'RESIZE', scrollHeight: document.body.scrollHeight });\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\n\t\t\t\tdocument.body.addEventListener(\n\t\t\t\t\t'click',\n\t\t\t\t\tevent => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tif (!hoveredElement) return;\n\t\t\t\t\t\tconst selector = getElementUniqueSelector(hoveredElement, document.body);\n\t\t\t\t\t\tif (!selector) return;\n\t\t\t\t\t\tconst rect = hoveredElement.getBoundingClientRect();\n\t\t\t\t\t\tbroadcastHoveredElement();\n\t\t\t\t\t\tsendOutboundEvent({\n\t\t\t\t\t\t\ttype: 'PIN_POSITION',\n\t\t\t\t\t\t\tpin: {\n\t\t\t\t\t\t\t\trect: getElementPinRect(hoveredElement),\n\t\t\t\t\t\t\t\tselector,\n\t\t\t\t\t\t\t\txPercent: (event.clientX - rect.x) / rect.width,\n\t\t\t\t\t\t\t\tyPercent: (event.clientY - rect.y) / rect.height,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\t\t\t\tlogger.info('Collaborate bridge: Event handlers set up');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'SCROLL':\n\t\t\t\twindow.scrollTo({ left: collaborateEvent.scrollX, top: collaborateEvent.scrollY, behavior: 'instant' });\n\t\t\t\tbroadcastSelectors();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcollaborateEvent satisfies never;\n\t\t}\n\t};\n\n\twindow.addEventListener('message', handleEvent, { signal });\n\tsignal?.addEventListener('abort', () => {\n\t\tlogger.info('Collaborate bridge: disposing');\n\t\tsendOutboundEvent({ type: 'DISPOSE' });\n\t\twindow.removeEventListener('message', handleEvent);\n\t});\n};\n\nexport const collaboratePlugin = () =>\n\tcreatePlugin(({ logger }) => ({\n\t\tsetupBridge: (params?: { signal?: AbortSignal }) =>\n\t\t\tsetupBridge({\n\t\t\t\tlogger,\n\t\t\t\tsignal: params?.signal,\n\t\t\t}),\n\t}));\n","type SelectorProperties = {\n\telement: Element | null | undefined;\n\tid?: string;\n\tclasses?: string;\n\tchildren?: string[];\n};\n\nconst escapedCharsInParens = ['(', ')', '.', ',', '_', '%'];\nconst escapeInBrackets = (input: string) => {\n\tlet inBrackets = false;\n\tlet result = '';\n\tfor (const char of input) {\n\t\tif (char === '[') {\n\t\t\tinBrackets = true;\n\t\t\tresult += char;\n\t\t} else if (char === ']') {\n\t\t\tinBrackets = false;\n\t\t\tresult += char;\n\t\t} else if (inBrackets && escapedCharsInParens.includes(char)) {\n\t\t\tresult += '\\\\' + char;\n\t\t} else {\n\t\t\tresult += char;\n\t\t}\n\t}\n\treturn result;\n};\n\nexport const escapeClassName = (input: string) => {\n\treturn escapeInBrackets(input).replace(/(?<!\\\\)[:[\\]/+]/g, '\\\\$&');\n};\n\nconst getSelectorProperties = (from: SelectorProperties): SelectorProperties => {\n\tif (from.element?.getAttribute('id') !== null && !from.id?.length) {\n\t\tfrom.id = `#${from.element?.getAttribute('id')}`;\n\t\treturn from;\n\t}\n\n\tif (from.element && from.element.className.length > 0 && !from.classes?.length) {\n\t\tfrom.classes = `.${escapeClassName(from.element.className).split(' ').join('.')}`;\n\t\treturn from;\n\t}\n\n\tconst newSelector = [from.classes, from.id].filter(Boolean).join('') || from.element?.tagName;\n\n\tconst parent = from.element?.parentElement;\n\tif (parent) {\n\t\tconst childIndex = Array.from(parent.children).findIndex(child => child === from.element);\n\t\treturn {\n\t\t\telement: from.element?.parentElement,\n\t\t\tchildren: [`${newSelector}:nth-child(${childIndex + 1})`, ...(from.children ?? [])],\n\t\t};\n\t}\n\tthrow new Error('Unable to uniquely identify selector: not unique enough');\n};\n\nexport const getElementUniqueSelector = (element: Element, context: Element) => {\n\tconst getSelector = (prefilled: SelectorProperties): string | null => {\n\t\tconst properties = getSelectorProperties(prefilled);\n\n\t\tconst newSelector = [[properties.classes, properties.id].filter(Boolean).join(''), ...(properties.children ?? [])]\n\t\t\t.filter(Boolean)\n\t\t\t.join('>');\n\n\t\tconst matchingSelectors = context.querySelectorAll(newSelector);\n\n\t\tif (matchingSelectors.length > 1 && matchingSelectors.length < 100) return getSelector(properties);\n\t\tif (matchingSelectors.length === 1) return newSelector;\n\n\t\treturn null;\n\t};\n\n\treturn getSelector({ element, children: [] });\n};\n"],"mappings":"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","names":["src_exports","__export","collaboratePlugin","createInboundEventSender","isCollaborateOutboundEvent","__toCommonJS","import_sdk","escapedCharsInParens","escapeInBrackets","input","inBrackets","result","char","escapeClassName","getSelectorProperties","from","_a","_b","_c","_d","_e","_f","_g","_h","newSelector","parent","childIndex","child","getElementUniqueSelector","element","context","getSelector","prefilled","properties","matchingSelectors","sendOutboundEvent","data","__spreadValues","createInboundEventSender","_a","isCollaborateInboundEvent","event","isCollaborateOutboundEvent","getElementPinRect","element","boundingBox","getSelectorRects","selectors","selectorRects","selector","escapeClassName","debounce","func","waitFor","timeout","args","setupBridge","logger","signal","watchedSelectors","hoveredElement","broadcastSelectors","broadcastHoveredElement","handleEvent","messageEvent","collaborateEvent","newElement","getElementUniqueSelector","rect","collaboratePlugin","params"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var P=Object.defineProperty;var S=Object.getOwnPropertySymbols;var R=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var m=(e,t,n)=>t in e?P(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,b=(e,t)=>{for(var n in t||(t={}))R.call(t,n)&&m(e,n,t[n]);if(S)for(var n of S(t))v.call(t,n)&&m(e,n,t[n]);return e};import{createPlugin as
|
|
1
|
+
var P=Object.defineProperty;var S=Object.getOwnPropertySymbols;var R=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var m=(e,t,n)=>t in e?P(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,b=(e,t)=>{for(var n in t||(t={}))R.call(t,n)&&m(e,n,t[n]);if(S)for(var n of S(t))v.call(t,n)&&m(e,n,t[n]);return e};import{createPlugin as x}from"@inploi/sdk";var I=["(",")",".",",","_","%"],O=e=>{let t=!1,n="";for(let r of e)r==="["?(t=!0,n+=r):r==="]"?(t=!1,n+=r):t&&I.includes(r)?n+="\\"+r:n+=r;return n},g=e=>O(e).replace(new RegExp("(?<!\\\\)[:[\\]/+]","g"),"\\$&"),w=e=>{var r,s,u,c,d,l,o,p;if(((r=e.element)==null?void 0:r.getAttribute("id"))!==null&&!((s=e.id)!=null&&s.length))return e.id=`#${(u=e.element)==null?void 0:u.getAttribute("id")}`,e;if(e.element&&e.element.className.length>0&&!((c=e.classes)!=null&&c.length))return e.classes=`.${g(e.element.className).split(" ").join(".")}`,e;let t=[e.classes,e.id].filter(Boolean).join("")||((d=e.element)==null?void 0:d.tagName),n=(l=e.element)==null?void 0:l.parentElement;if(n){let i=Array.from(n.children).findIndex(h=>h===e.element);return{element:(o=e.element)==null?void 0:o.parentElement,children:[`${t}:nth-child(${i+1})`,...(p=e.children)!=null?p:[]]}}throw new Error("Unable to uniquely identify selector: not unique enough")},y=(e,t)=>{let n=r=>{var d;let s=w(r),u=[[s.classes,s.id].filter(Boolean).join(""),...(d=s.children)!=null?d:[]].filter(Boolean).join(">"),c=t.querySelectorAll(u);return c.length>1&&c.length<100?n(s):c.length===1?u:null};return n({element:e,children:[]})};var a=e=>{window.parent.postMessage(b({source:"inploi-collaborate"},e),"*")},M=e=>({sendInboundEvent:t=>{var n;return(n=e.source)==null?void 0:n.postMessage(b({source:"inploi-collaborate"},t),{targetOrigin:e.origin})}}),C=e=>e.data.source==="inploi-collaborate",B=e=>e.data.source==="inploi-collaborate",E=e=>{let t=e.getBoundingClientRect();return{_brand:"pin",x:window.scrollX+t.x,y:window.scrollY+t.y,width:t.width,height:t.height}},f=e=>{let t={};for(let n of e){let r=document.querySelector(g(n));t[n]=r?E(r):null}return t};function T(e,t){let n;return(...r)=>{clearTimeout(n),n=setTimeout(()=>e(...r),t)}}var N=({logger:e,signal:t})=>{let n=[],r;a({type:"READY"}),e.info("Collaborate bridge: Ready");let s=T(()=>{a({type:"SELECTOR_RECTS",selectorRects:f(n)})},50),u=()=>{r&&a({type:"HOVER_ELEMENT",rect:E(r)})},c=d=>{if(C(d)===!1)return;let l=d.data;switch(l.type){case"WATCH_SELECTORS":{n=l.selectors,s();break}case"MOUSE_POSITION":{let o=document.elementsFromPoint(l.x,l.y)[0];if(o===r)return;r=o,u();break}case"DROP_PIN":{let o=document.elementsFromPoint(l.x,l.y)[0];if(!o)return;let p=y(o,document.body);if(!p)return;let i=o.getBoundingClientRect();a({type:"PIN_POSITION",pin:{rect:E(o),selector:p,xPercent:(l.x-i.x)/i.width,yPercent:(l.y-i.y)/i.height}});break}case"SETUP_EVENT_HANDLERS":{e.info("Collaborate bridge: Setting up event handlers"),window.addEventListener("beforeunload",()=>{a({type:"DISPOSE"})}),a({type:"RESIZE",scrollHeight:document.body.scrollHeight}),window.addEventListener("resize",()=>{s(),a({type:"RESIZE",scrollHeight:document.body.scrollHeight})},{signal:t}),document.body.addEventListener("click",o=>{if(o.preventDefault(),o.stopPropagation(),!r)return;let p=y(r,document.body);if(!p)return;let i=r.getBoundingClientRect();u(),a({type:"PIN_POSITION",pin:{rect:E(r),selector:p,xPercent:(o.clientX-i.x)/i.width,yPercent:(o.clientY-i.y)/i.height}})},{signal:t}),e.info("Collaborate bridge: Event handlers set up");break}case"SCROLL":window.scrollTo({left:l.scrollX,top:l.scrollY,behavior:"instant"}),s();break;default:}};window.addEventListener("message",c,{signal:t}),t==null||t.addEventListener("abort",()=>{e.info("Collaborate bridge: disposing"),a({type:"DISPOSE"}),window.removeEventListener("message",c)})},k=()=>x(({logger:e})=>({setupBridge:t=>N({logger:e,signal:t==null?void 0:t.signal})}));export{k as collaboratePlugin,M as createInboundEventSender,B as isCollaborateOutboundEvent};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/collaborate.ts","../src/collaborate.selector.ts"],"sourcesContent":["import { Logger, createPlugin } from '@inploi/sdk';\n\nimport { escapeClassName, getElementUniqueSelector } from './collaborate.selector';\n\nexport type CollaborateInboundEvent =\n\t| {\n\t\t\ttype: 'SETUP_EVENT_HANDLERS';\n\t }\n\t| { type: 'WATCH_SELECTORS'; selectors: string[] }\n\t| { type: 'SCROLL'; scrollY: number; scrollX: number }\n\t| { type: 'MOUSE_POSITION'; x: number; y: number }\n\t| { type: 'DROP_PIN'; x: number; y: number };\n\nexport type CollaborateOutboundEvent =\n\t| { type: 'READY' }\n\t| {\n\t\t\ttype: 'RESIZE';\n\t\t\tscrollHeight: number;\n\t }\n\t| {\n\t\t\ttype: 'HOVER_ELEMENT';\n\t\t\trect: PinRect | null;\n\t }\n\t| {\n\t\t\ttype: 'PIN_POSITION';\n\t\t\tpin: DroppedPin;\n\t }\n\t| {\n\t\t\ttype: 'DISPOSE';\n\t }\n\t| {\n\t\t\ttype: 'SELECTOR_RECTS';\n\t\t\tselectorRects: SelectorRects;\n\t };\n\nexport type DroppedPin = { selector: string; xPercent: number; yPercent: number; rect: PinRect };\n\nconst sendOutboundEvent = (data: CollaborateOutboundEvent) => {\n\twindow.parent.postMessage({ source: 'inploi-collaborate', ...data }, '*');\n};\n\nexport const createInboundEventSender = (e: MessageEvent) => {\n\treturn {\n\t\tsendInboundEvent: (data: CollaborateInboundEvent) =>\n\t\t\te.source?.postMessage({ source: 'inploi-collaborate', ...data }, { targetOrigin: e.origin }),\n\t};\n};\n\nconst isCollaborateInboundEvent = (event: MessageEvent): event is MessageEvent<CollaborateInboundEvent> => {\n\treturn event.data.source === 'inploi-collaborate';\n};\n\nexport const isCollaborateOutboundEvent = (event: MessageEvent): event is MessageEvent<CollaborateOutboundEvent> => {\n\treturn event.data.source === 'inploi-collaborate';\n};\n\nexport type PinRect = {\n\t_brand: 'pin';\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n};\n\nconst getElementPinRect = (element: Element): PinRect => {\n\tconst boundingBox = element.getBoundingClientRect();\n\treturn {\n\t\t_brand: 'pin',\n\t\tx: window.scrollX + boundingBox.x,\n\t\ty: window.scrollY + boundingBox.y,\n\t\twidth: boundingBox.width,\n\t\theight: boundingBox.height,\n\t};\n};\n\nexport type SelectorRects = { [selector: string]: PinRect | null };\n\nconst getSelectorRects = (selectors: string[]) => {\n\tconst selectorRects: SelectorRects = {};\n\tfor (const selector of selectors) {\n\t\tconst element = document.querySelector(escapeClassName(selector));\n\t\tselectorRects[selector] = element ? getElementPinRect(element) : null;\n\t}\n\treturn selectorRects;\n};\n\nfunction debounce<F extends (...args: Parameters<F>) => ReturnType<F>>(\n\tfunc: F,\n\twaitFor: number,\n): (...args: Parameters<F>) => void {\n\tlet timeout: ReturnType<typeof setTimeout>;\n\n\treturn (...args: Parameters<F>): void => {\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(() => func(...args), waitFor);\n\t};\n}\n\n/** Sets up the bridge for Collaborate to be able to communicate with the host page */\nconst setupBridge = ({ logger, signal }: { signal?: AbortSignal; logger: Logger }) => {\n\tlet watchedSelectors: string[] = [];\n\tlet hoveredElement: Element | undefined;\n\tsendOutboundEvent({ type: 'READY' });\n\tlogger.info('Collaborate bridge: Ready');\n\n\tconst broadcastSelectors = debounce(() => {\n\t\tsendOutboundEvent({ type: 'SELECTOR_RECTS', selectorRects: getSelectorRects(watchedSelectors) });\n\t}, 50);\n\n\tconst broadcastHoveredElement = () => {\n\t\tif (!hoveredElement) return;\n\t\tsendOutboundEvent({\n\t\t\ttype: 'HOVER_ELEMENT',\n\t\t\trect: getElementPinRect(hoveredElement),\n\t\t});\n\t};\n\n\tconst handleEvent = (messageEvent: MessageEvent) => {\n\t\tif (isCollaborateInboundEvent(messageEvent) === false) return;\n\t\tconst collaborateEvent = messageEvent.data;\n\t\tswitch (collaborateEvent.type) {\n\t\t\tcase 'WATCH_SELECTORS': {\n\t\t\t\twatchedSelectors = collaborateEvent.selectors;\n\t\t\t\tbroadcastSelectors();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'MOUSE_POSITION': {\n\t\t\t\tconst newElement = document.elementsFromPoint(collaborateEvent.x, collaborateEvent.y)[0];\n\t\t\t\tif (newElement === hoveredElement) return;\n\t\t\t\thoveredElement = newElement;\n\t\t\t\tbroadcastHoveredElement();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'DROP_PIN': {\n\t\t\t\tconst element = document.elementsFromPoint(collaborateEvent.x, collaborateEvent.y)[0];\n\t\t\t\tif (!element) return;\n\t\t\t\tconst selector = getElementUniqueSelector(element, document.body);\n\t\t\t\tif (!selector) return;\n\t\t\t\tconst rect = element.getBoundingClientRect();\n\t\t\t\tsendOutboundEvent({\n\t\t\t\t\ttype: 'PIN_POSITION',\n\t\t\t\t\tpin: {\n\t\t\t\t\t\trect: getElementPinRect(element),\n\t\t\t\t\t\tselector,\n\t\t\t\t\t\txPercent: (collaborateEvent.x - rect.x) / rect.width,\n\t\t\t\t\t\tyPercent: (collaborateEvent.y - rect.y) / rect.height,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'SETUP_EVENT_HANDLERS': {\n\t\t\t\tlogger.info('Collaborate bridge: Setting up event handlers');\n\t\t\t\twindow.addEventListener('beforeunload', () => {\n\t\t\t\t\tsendOutboundEvent({ type: 'DISPOSE' });\n\t\t\t\t});\n\t\t\t\tsendOutboundEvent({ type: 'RESIZE', scrollHeight: document.body.scrollHeight });\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'resize',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tbroadcastSelectors();\n\t\t\t\t\t\tsendOutboundEvent({ type: 'RESIZE', scrollHeight: document.body.scrollHeight });\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\n\t\t\t\tdocument.body.addEventListener(\n\t\t\t\t\t'click',\n\t\t\t\t\tevent => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tif (!hoveredElement) return;\n\t\t\t\t\t\tconst selector = getElementUniqueSelector(hoveredElement, document.body);\n\t\t\t\t\t\tif (!selector) return;\n\t\t\t\t\t\tconst rect = hoveredElement.getBoundingClientRect();\n\t\t\t\t\t\tbroadcastHoveredElement();\n\t\t\t\t\t\tsendOutboundEvent({\n\t\t\t\t\t\t\ttype: 'PIN_POSITION',\n\t\t\t\t\t\t\tpin: {\n\t\t\t\t\t\t\t\trect: getElementPinRect(hoveredElement),\n\t\t\t\t\t\t\t\tselector,\n\t\t\t\t\t\t\t\txPercent: (event.clientX - rect.x) / rect.width,\n\t\t\t\t\t\t\t\tyPercent: (event.clientY - rect.y) / rect.height,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\t\t\t\tlogger.info('Collaborate bridge: Event handlers set up');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'SCROLL':\n\t\t\t\twindow.scrollTo({ left: collaborateEvent.scrollX, top: collaborateEvent.scrollY, behavior: 'instant' });\n\t\t\t\tbroadcastSelectors();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcollaborateEvent satisfies never;\n\t\t}\n\t};\n\n\twindow.addEventListener('message', handleEvent, { signal });\n\tsignal?.addEventListener('abort', () => {\n\t\tlogger.info('Collaborate bridge: disposing');\n\t\tsendOutboundEvent({ type: 'DISPOSE' });\n\t\twindow.removeEventListener('message', handleEvent);\n\t});\n};\n\nexport const collaboratePlugin = () =>\n\tcreatePlugin(({ logger }) => ({\n\t\tsetupBridge: (params?: { signal?: AbortSignal }) =>\n\t\t\tsetupBridge({\n\t\t\t\tlogger,\n\t\t\t\tsignal: params?.signal,\n\t\t\t}),\n\t}));\n","type SelectorProperties = {\n\telement: Element | null | undefined;\n\tid?: string;\n\tclasses?: string;\n\tchildren?: string[];\n};\n\nexport const escapeClassName = (input: string) => {\n\treturn input.replace(/(?<!\\\\)[:[\\]/]/g, '\\\\$&');\n};\n\nconst getSelectorProperties = (from: SelectorProperties): SelectorProperties => {\n\tif (from.element?.getAttribute('id') !== null && !from.id?.length) {\n\t\tfrom.id = `#${from.element?.getAttribute('id')}`;\n\t\treturn from;\n\t}\n\n\tif (from.element && from.element.className.length > 0 && !from.classes?.length) {\n\t\tfrom.classes = `.${escapeClassName(from.element.className).split(' ').join('.')}`;\n\t\treturn from;\n\t}\n\n\tconst newSelector = [from.classes, from.id].filter(Boolean).join('') || from.element?.tagName;\n\n\tconst parent = from.element?.parentElement;\n\tif (parent) {\n\t\tconst childIndex = Array.from(parent.children).findIndex(child => child === from.element);\n\t\treturn {\n\t\t\telement: from.element?.parentElement,\n\t\t\tchildren: [`${newSelector}:nth-child(${childIndex + 1})`, ...(from.children ?? [])],\n\t\t};\n\t}\n\tthrow new Error('Unable to uniquely identify selector: not unique enough');\n};\n\nexport const getElementUniqueSelector = (element: Element, context: Element) => {\n\tconst getSelector = (prefilled: SelectorProperties): string | null => {\n\t\tconst properties = getSelectorProperties(prefilled);\n\n\t\tconst newSelector = [[properties.classes, properties.id].filter(Boolean).join(''), ...(properties.children ?? [])]\n\t\t\t.filter(Boolean)\n\t\t\t.join('>');\n\n\t\tconst matchingSelectors = context.querySelectorAll(newSelector);\n\n\t\tif (matchingSelectors.length > 1 && matchingSelectors.length < 100) return getSelector(properties);\n\t\tif (matchingSelectors.length === 1) return newSelector;\n\n\t\treturn null;\n\t};\n\n\treturn getSelector({ element, children: [] });\n};\n"],"mappings":"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","names":["createPlugin","escapeClassName","input","getSelectorProperties","from","_a","_b","_c","_d","_e","_f","_g","_h","newSelector","parent","childIndex","child","getElementUniqueSelector","element","context","getSelector","prefilled","properties","matchingSelectors","sendOutboundEvent","data","__spreadValues","createInboundEventSender","_a","isCollaborateInboundEvent","event","isCollaborateOutboundEvent","getElementPinRect","element","boundingBox","getSelectorRects","selectors","selectorRects","selector","escapeClassName","debounce","func","waitFor","timeout","args","setupBridge","logger","signal","watchedSelectors","hoveredElement","broadcastSelectors","broadcastHoveredElement","handleEvent","messageEvent","collaborateEvent","newElement","getElementUniqueSelector","rect","collaboratePlugin","createPlugin","params"]}
|
|
1
|
+
{"version":3,"sources":["../src/collaborate.ts","../src/collaborate.selector.ts"],"sourcesContent":["import { Logger, createPlugin } from '@inploi/sdk';\n\nimport { escapeClassName, getElementUniqueSelector } from './collaborate.selector';\n\nexport type CollaborateInboundEvent =\n\t| {\n\t\t\ttype: 'SETUP_EVENT_HANDLERS';\n\t }\n\t| { type: 'WATCH_SELECTORS'; selectors: string[] }\n\t| { type: 'SCROLL'; scrollY: number; scrollX: number }\n\t| { type: 'MOUSE_POSITION'; x: number; y: number }\n\t| { type: 'DROP_PIN'; x: number; y: number };\n\nexport type CollaborateOutboundEvent =\n\t| { type: 'READY' }\n\t| {\n\t\t\ttype: 'RESIZE';\n\t\t\tscrollHeight: number;\n\t }\n\t| {\n\t\t\ttype: 'HOVER_ELEMENT';\n\t\t\trect: PinRect | null;\n\t }\n\t| {\n\t\t\ttype: 'PIN_POSITION';\n\t\t\tpin: DroppedPin;\n\t }\n\t| {\n\t\t\ttype: 'DISPOSE';\n\t }\n\t| {\n\t\t\ttype: 'SELECTOR_RECTS';\n\t\t\tselectorRects: SelectorRects;\n\t };\n\nexport type DroppedPin = { selector: string; xPercent: number; yPercent: number; rect: PinRect };\n\nconst sendOutboundEvent = (data: CollaborateOutboundEvent) => {\n\twindow.parent.postMessage({ source: 'inploi-collaborate', ...data }, '*');\n};\n\nexport const createInboundEventSender = (e: MessageEvent) => {\n\treturn {\n\t\tsendInboundEvent: (data: CollaborateInboundEvent) =>\n\t\t\te.source?.postMessage({ source: 'inploi-collaborate', ...data }, { targetOrigin: e.origin }),\n\t};\n};\n\nconst isCollaborateInboundEvent = (event: MessageEvent): event is MessageEvent<CollaborateInboundEvent> => {\n\treturn event.data.source === 'inploi-collaborate';\n};\n\nexport const isCollaborateOutboundEvent = (event: MessageEvent): event is MessageEvent<CollaborateOutboundEvent> => {\n\treturn event.data.source === 'inploi-collaborate';\n};\n\nexport type PinRect = {\n\t_brand: 'pin';\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n};\n\nconst getElementPinRect = (element: Element): PinRect => {\n\tconst boundingBox = element.getBoundingClientRect();\n\treturn {\n\t\t_brand: 'pin',\n\t\tx: window.scrollX + boundingBox.x,\n\t\ty: window.scrollY + boundingBox.y,\n\t\twidth: boundingBox.width,\n\t\theight: boundingBox.height,\n\t};\n};\n\nexport type SelectorRects = { [selector: string]: PinRect | null };\n\nconst getSelectorRects = (selectors: string[]) => {\n\tconst selectorRects: SelectorRects = {};\n\tfor (const selector of selectors) {\n\t\tconst element = document.querySelector(escapeClassName(selector));\n\t\tselectorRects[selector] = element ? getElementPinRect(element) : null;\n\t}\n\treturn selectorRects;\n};\n\nfunction debounce<F extends (...args: Parameters<F>) => ReturnType<F>>(\n\tfunc: F,\n\twaitFor: number,\n): (...args: Parameters<F>) => void {\n\tlet timeout: ReturnType<typeof setTimeout>;\n\n\treturn (...args: Parameters<F>): void => {\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(() => func(...args), waitFor);\n\t};\n}\n\n/** Sets up the bridge for Collaborate to be able to communicate with the host page */\nconst setupBridge = ({ logger, signal }: { signal?: AbortSignal; logger: Logger }) => {\n\tlet watchedSelectors: string[] = [];\n\tlet hoveredElement: Element | undefined;\n\tsendOutboundEvent({ type: 'READY' });\n\tlogger.info('Collaborate bridge: Ready');\n\n\tconst broadcastSelectors = debounce(() => {\n\t\tsendOutboundEvent({ type: 'SELECTOR_RECTS', selectorRects: getSelectorRects(watchedSelectors) });\n\t}, 50);\n\n\tconst broadcastHoveredElement = () => {\n\t\tif (!hoveredElement) return;\n\t\tsendOutboundEvent({\n\t\t\ttype: 'HOVER_ELEMENT',\n\t\t\trect: getElementPinRect(hoveredElement),\n\t\t});\n\t};\n\n\tconst handleEvent = (messageEvent: MessageEvent) => {\n\t\tif (isCollaborateInboundEvent(messageEvent) === false) return;\n\t\tconst collaborateEvent = messageEvent.data;\n\t\tswitch (collaborateEvent.type) {\n\t\t\tcase 'WATCH_SELECTORS': {\n\t\t\t\twatchedSelectors = collaborateEvent.selectors;\n\t\t\t\tbroadcastSelectors();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'MOUSE_POSITION': {\n\t\t\t\tconst newElement = document.elementsFromPoint(collaborateEvent.x, collaborateEvent.y)[0];\n\t\t\t\tif (newElement === hoveredElement) return;\n\t\t\t\thoveredElement = newElement;\n\t\t\t\tbroadcastHoveredElement();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'DROP_PIN': {\n\t\t\t\tconst element = document.elementsFromPoint(collaborateEvent.x, collaborateEvent.y)[0];\n\t\t\t\tif (!element) return;\n\t\t\t\tconst selector = getElementUniqueSelector(element, document.body);\n\t\t\t\tif (!selector) return;\n\t\t\t\tconst rect = element.getBoundingClientRect();\n\t\t\t\tsendOutboundEvent({\n\t\t\t\t\ttype: 'PIN_POSITION',\n\t\t\t\t\tpin: {\n\t\t\t\t\t\trect: getElementPinRect(element),\n\t\t\t\t\t\tselector,\n\t\t\t\t\t\txPercent: (collaborateEvent.x - rect.x) / rect.width,\n\t\t\t\t\t\tyPercent: (collaborateEvent.y - rect.y) / rect.height,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'SETUP_EVENT_HANDLERS': {\n\t\t\t\tlogger.info('Collaborate bridge: Setting up event handlers');\n\t\t\t\twindow.addEventListener('beforeunload', () => {\n\t\t\t\t\tsendOutboundEvent({ type: 'DISPOSE' });\n\t\t\t\t});\n\t\t\t\tsendOutboundEvent({ type: 'RESIZE', scrollHeight: document.body.scrollHeight });\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'resize',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tbroadcastSelectors();\n\t\t\t\t\t\tsendOutboundEvent({ type: 'RESIZE', scrollHeight: document.body.scrollHeight });\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\n\t\t\t\tdocument.body.addEventListener(\n\t\t\t\t\t'click',\n\t\t\t\t\tevent => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tif (!hoveredElement) return;\n\t\t\t\t\t\tconst selector = getElementUniqueSelector(hoveredElement, document.body);\n\t\t\t\t\t\tif (!selector) return;\n\t\t\t\t\t\tconst rect = hoveredElement.getBoundingClientRect();\n\t\t\t\t\t\tbroadcastHoveredElement();\n\t\t\t\t\t\tsendOutboundEvent({\n\t\t\t\t\t\t\ttype: 'PIN_POSITION',\n\t\t\t\t\t\t\tpin: {\n\t\t\t\t\t\t\t\trect: getElementPinRect(hoveredElement),\n\t\t\t\t\t\t\t\tselector,\n\t\t\t\t\t\t\t\txPercent: (event.clientX - rect.x) / rect.width,\n\t\t\t\t\t\t\t\tyPercent: (event.clientY - rect.y) / rect.height,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\t\t\t\tlogger.info('Collaborate bridge: Event handlers set up');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'SCROLL':\n\t\t\t\twindow.scrollTo({ left: collaborateEvent.scrollX, top: collaborateEvent.scrollY, behavior: 'instant' });\n\t\t\t\tbroadcastSelectors();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcollaborateEvent satisfies never;\n\t\t}\n\t};\n\n\twindow.addEventListener('message', handleEvent, { signal });\n\tsignal?.addEventListener('abort', () => {\n\t\tlogger.info('Collaborate bridge: disposing');\n\t\tsendOutboundEvent({ type: 'DISPOSE' });\n\t\twindow.removeEventListener('message', handleEvent);\n\t});\n};\n\nexport const collaboratePlugin = () =>\n\tcreatePlugin(({ logger }) => ({\n\t\tsetupBridge: (params?: { signal?: AbortSignal }) =>\n\t\t\tsetupBridge({\n\t\t\t\tlogger,\n\t\t\t\tsignal: params?.signal,\n\t\t\t}),\n\t}));\n","type SelectorProperties = {\n\telement: Element | null | undefined;\n\tid?: string;\n\tclasses?: string;\n\tchildren?: string[];\n};\n\nconst escapedCharsInParens = ['(', ')', '.', ',', '_', '%'];\nconst escapeInBrackets = (input: string) => {\n\tlet inBrackets = false;\n\tlet result = '';\n\tfor (const char of input) {\n\t\tif (char === '[') {\n\t\t\tinBrackets = true;\n\t\t\tresult += char;\n\t\t} else if (char === ']') {\n\t\t\tinBrackets = false;\n\t\t\tresult += char;\n\t\t} else if (inBrackets && escapedCharsInParens.includes(char)) {\n\t\t\tresult += '\\\\' + char;\n\t\t} else {\n\t\t\tresult += char;\n\t\t}\n\t}\n\treturn result;\n};\n\nexport const escapeClassName = (input: string) => {\n\treturn escapeInBrackets(input).replace(/(?<!\\\\)[:[\\]/+]/g, '\\\\$&');\n};\n\nconst getSelectorProperties = (from: SelectorProperties): SelectorProperties => {\n\tif (from.element?.getAttribute('id') !== null && !from.id?.length) {\n\t\tfrom.id = `#${from.element?.getAttribute('id')}`;\n\t\treturn from;\n\t}\n\n\tif (from.element && from.element.className.length > 0 && !from.classes?.length) {\n\t\tfrom.classes = `.${escapeClassName(from.element.className).split(' ').join('.')}`;\n\t\treturn from;\n\t}\n\n\tconst newSelector = [from.classes, from.id].filter(Boolean).join('') || from.element?.tagName;\n\n\tconst parent = from.element?.parentElement;\n\tif (parent) {\n\t\tconst childIndex = Array.from(parent.children).findIndex(child => child === from.element);\n\t\treturn {\n\t\t\telement: from.element?.parentElement,\n\t\t\tchildren: [`${newSelector}:nth-child(${childIndex + 1})`, ...(from.children ?? [])],\n\t\t};\n\t}\n\tthrow new Error('Unable to uniquely identify selector: not unique enough');\n};\n\nexport const getElementUniqueSelector = (element: Element, context: Element) => {\n\tconst getSelector = (prefilled: SelectorProperties): string | null => {\n\t\tconst properties = getSelectorProperties(prefilled);\n\n\t\tconst newSelector = [[properties.classes, properties.id].filter(Boolean).join(''), ...(properties.children ?? [])]\n\t\t\t.filter(Boolean)\n\t\t\t.join('>');\n\n\t\tconst matchingSelectors = context.querySelectorAll(newSelector);\n\n\t\tif (matchingSelectors.length > 1 && matchingSelectors.length < 100) return getSelector(properties);\n\t\tif (matchingSelectors.length === 1) return newSelector;\n\n\t\treturn null;\n\t};\n\n\treturn getSelector({ element, children: [] });\n};\n"],"mappings":"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","names":["createPlugin","escapedCharsInParens","escapeInBrackets","input","inBrackets","result","char","escapeClassName","getSelectorProperties","from","_a","_b","_c","_d","_e","_f","_g","_h","newSelector","parent","childIndex","child","getElementUniqueSelector","element","context","getSelector","prefilled","properties","matchingSelectors","sendOutboundEvent","data","__spreadValues","createInboundEventSender","_a","isCollaborateInboundEvent","event","isCollaborateOutboundEvent","getElementPinRect","element","boundingBox","getSelectorRects","selectors","selectorRects","selector","escapeClassName","debounce","func","waitFor","timeout","args","setupBridge","logger","signal","watchedSelectors","hoveredElement","broadcastSelectors","broadcastHoveredElement","handleEvent","messageEvent","collaborateEvent","newElement","getElementUniqueSelector","rect","collaboratePlugin","createPlugin","params"]}
|