{"version":3,"sources":["https://lively-kernel.org/lively4/composed-offset/src/client/mouse-position.js"],"names":["pt","MousePosition","context","_pt","lively","elementsFromPoint","x","y","checked","Set","elements","document","e","find","has","add","shadowRoot","newElements","difference","splice","indexOf","showPoint","offset","addXY","onPointerMove","clientX","clientY","load","options","capture","passive","removeEventListener","addEventListener"],"mappings":";;;;;;AAASA,Q,wBAAAA,E;;;;;;;;;;;AAAAA,6C;;;;;;;AAGM,YAAMC,aAAN,CAAoB;;AAEjC,mBAAWC,OAAX,GAAqB;AACnB,iBAAO,gBAAP;AACD;;AAED,mBAAWF,EAAX,GAAgB;AACd,iBAAO,KAAKG,GAAL,KAAa,KAAKA,GAAL,GAAWC,OAAOJ,EAAP,CAAU,CAAV,EAAa,CAAb,CAAxB,CAAP;AACD;;AAED,eAAOK,iBAAP,CAAyB,EAAEC,CAAF,EAAKC,CAAL,EAAzB,EAAmC;AACjC,gBAAMC,UAAU,IAAIC,GAAJ,EAAhB;AACA,gBAAMC,WAAWC,SAASN,iBAAT,CAA2BC,CAA3B,EAA8BC,CAA9B,CAAjB;AACAG;;AAEA,cAAIE,CAAJ;AACA,iBAAOA,IAAIF,SAASG,IAAT,CAAcD,KAAK,CAACJ,QAAQM,GAAR,CAAYF,CAAZ,CAApB,CAAX,EAAgD;AAC9CJ,oBAAQO,GAAR,CAAYH,CAAZ;AACA,gBAAIA,EAAEI,UAAN,EAAkB;AAChB,oBAAMC,cAAcL,EAAEI,UAAF,CAAaX,iBAAb,CAA+BC,CAA/B,EAAkCC,CAAlC,EAAqCW,UAArC,CAAgDR,QAAhD,CAApB;AACAA,uBAASS,MAAT,CAAgBT,SAASU,OAAT,CAAiBR,CAAjB,CAAhB,EAAqC,CAArC,EAAwC,GAAGK,WAA3C;AACD;AACF;AACD,iBAAOP,QAAP;AACD;;AAED,mBAAWV,EAAX,CAAcA,EAAd,EAAkB;AAChB,iBAAO,KAAKG,GAAL,GAAWH,EAAlB;AACD;;AAED,eAAOqB,SAAP,CAAiBrB,EAAjB,EAAqB;AACnB,gBAAMsB,SAAS,EAAf;AACAlB,iBAAOiB,SAAP,CAAiBrB,GAAGuB,KAAH,CAASD,MAAT,EAAiBA,MAAjB,CAAjB;AACAlB,iBAAOiB,SAAP,CAAiBrB,GAAGuB,KAAH,CAASD,MAAT,EAAiB,CAACA,MAAlB,CAAjB;AACAlB,iBAAOiB,SAAP,CAAiBrB,GAAGuB,KAAH,CAAS,CAACD,MAAV,EAAkBA,MAAlB,CAAjB;AACAlB,iBAAOiB,SAAP,CAAiBrB,GAAGuB,KAAH,CAAS,CAACD,MAAV,EAAkB,CAACA,MAAnB,CAAjB;AACD;;AAED,eAAOE,aAAP,CAAqBZ,CAArB,EAAwB;AACtB,eAAKZ,EAAL,GAAUA,GAAGY,EAAEa,OAAL,EAAcb,EAAEc,OAAhB,CAAV;AACD;AACD,eAAOC,IAAP,GAAc;AACZ,gBAAMC,UAAU;AACdC,qBAAS,IADK;AAEdC,qBAAS;AAFK,WAAhB;AAIA1B,iBAAO2B,mBAAP,CAA2B,KAAK7B,OAAhC;AACAE,iBAAO4B,gBAAP,CAAwB,KAAK9B,OAA7B,EAAsCS,QAAtC,EAAgD,aAAhD,EAAiE,KAAKa,aAAtE,MAAiE,IAAjE,GAAqFI,OAArF;AACD;AAhDgC;;yBAAd3B,a;;;;;;;;6BAAAA,8C;;;;;;;;AAmDrB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGAA,oBAAc0B,IAAd","file":"mouse-position.js","sourcesContent":["import { pt } from 'src/client/graphics.js';\n\n\nexport default class MousePosition {\n\n  static get context() {\n    return \"mouse position\";\n  }\n\n  static get pt() {\n    return this._pt || (this._pt = lively.pt(0, 0));\n  }\n\n  static elementsFromPoint({ x, y }) {\n    const checked = new Set();\n    const elements = document.elementsFromPoint(x, y);\n    elements;\n\n    let e;\n    while (e = elements.find(e => !checked.has(e))) {\n      checked.add(e);\n      if (e.shadowRoot) {\n        const newElements = e.shadowRoot.elementsFromPoint(x, y).difference(elements);\n        elements.splice(elements.indexOf(e), 0, ...newElements);\n      }\n    }\n    return elements;\n  }\n\n  static set pt(pt) {\n    return this._pt = pt;\n  }\n\n  static showPoint(pt) {\n    const offset = 20;\n    lively.showPoint(pt.addXY(offset, offset));\n    lively.showPoint(pt.addXY(offset, -offset));\n    lively.showPoint(pt.addXY(-offset, offset));\n    lively.showPoint(pt.addXY(-offset, -offset));\n  }\n\n  static onPointerMove(e) {\n    this.pt = pt(e.clientX, e.clientY);\n  }\n  static load() {\n    const options = {\n      capture: true,\n      passive: true\n    };\n    lively.removeEventListener(this.context);\n    lively.addEventListener(this.context, document, \"pointermove\", ::this.onPointerMove, options);\n  }\n}\n\n// $(function() {\n//   // Get the HTML in #hoverText - just a wrapper for convenience\n//   var $hoverText = $(\"#hoverText\");\n\n//   // Get the full word the cursor is over regardless of span breaks\n//   function getFullWord(event) {\n//      var i, begin, end, range, textNode, offset;\n\n//     // Internet Explorer\n//     if (document.body.createTextRange) {\n//        try {\n//          range = document.body.createTextRange();\n//          range.moveToPoint(event.clientX, event.clientY);\n//          range.select();\n//          range = getTextRangeBoundaryPosition(range, true);\n\n//          textNode = range.node;\n//          offset = range.offset;\n//        } catch(e) {\n//          return \"\"; // Sigh, IE\n//        }\n//     }\n\n//     // Firefox, Safari\n//     // REF: https://developer.mozilla.org/en-US/docs/Web/API/Document/caretPositionFromPoint\n//     else if (document.caretPositionFromPoint) {\n//       range = document.caretPositionFromPoint(event.clientX, event.clientY);\n//       textNode = range.offsetNode;\n//       offset = range.offset;\n\n//       // Chrome\n//       // REF: https://developer.mozilla.org/en-US/docs/Web/API/document/caretRangeFromPoint\n//     } else if (document.caretRangeFromPoint) {\n//       range = document.caretRangeFromPoint(event.clientX, event.clientY);\n//       textNode = range.startContainer;\n//       offset = range.startOffset;\n//     }\n\n//     // Only act on text nodes\n//     if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {\n//       return \"\";\n//     }\n\n//     var data = textNode.textContent;\n\n//     // Sometimes the offset can be at the 'length' of the data.\n//     // It might be a bug with this 'experimental' feature\n//     // Compensate for this below\n//     if (offset >= data.length) {\n//       offset = data.length - 1;\n//     }\n\n//     // Ignore the cursor on spaces - these aren't words\n//     if (isW(data[offset])) {\n//       return \"\";\n//     }\n\n//     // Scan behind the current character until whitespace is found, or beginning\n//     i = begin = end = offset;\n//     while (i > 0 && !isW(data[i - 1])) {\n//       i--;\n//     }\n//     begin = i;\n\n//     // Scan ahead of the current character until whitespace is found, or end\n//     i = offset;\n//     while (i < data.length - 1 && !isW(data[i + 1])) {\n//       i++;\n//     }\n//     end = i;\n\n//     // This is our temporary word\n//     var word = data.substring(begin, end + 1);\n\n//     // Demo only\n//     showBridge(null, null, null);\n\n//     // If at a node boundary, cross over and see what \n//     // the next word is and check if this should be added to our temp word\n//     if (end === data.length - 1 || begin === 0) {\n\n//       var nextNode = getNextNode(textNode);\n//       var prevNode = getPrevNode(textNode);\n\n//       // Get the next node text\n//       if (end == data.length - 1 && nextNode) {\n//         var nextText = nextNode.textContent;\n\n//         // Demo only\n//         showBridge(word, nextText, null);\n\n//         // Add the letters from the next text block until a whitespace, or end\n//         i = 0;\n//         while (i < nextText.length && !isW(nextText[i])) {\n//           word += nextText[i++];\n//         }\n\n//       } else if (begin === 0 && prevNode) {\n//         // Get the previous node text\n//         var prevText = prevNode.textContent;\n\n//         // Demo only\n//         showBridge(word, null, prevText);\n\n//         // Add the letters from the next text block until a whitespace, or end\n//         i = prevText.length - 1;\n//         while (i >= 0 && !isW(prevText[i])) {\n//           word = prevText[i--] + word;\n//         }\n//       }\n//     }\n//     return word;\n//   }\n\n//   // Return the word the cursor is over\n//   $hoverText.mousemove(function(e) {\n//     var word = getFullWord(e);\n//     if (word !== \"\") {\n//       $(\"#result\").text(word);\n//     }\n//   });\n// });\n\n// // Helper functions\n\n// // Whitespace checker\n// function isW(s) {\n//   return /[ \\f\\n\\r\\t\\v\\u00A0\\u2028\\u2029]/.test(s);\n// }\n\n// // Barrier nodes are BR, DIV, P, PRE, TD, TR, ... \n// function isBarrierNode(node) {\n//   return node ? /^(BR|DIV|P|PRE|TD|TR|TABLE)$/i.test(node.nodeName) : true;\n// }\n\n// // Try to find the next adjacent node\n// function getNextNode(node) {\n//   var n = null;\n//   // Does this node have a sibling?\n//   if (node.nextSibling) {\n//     n = node.nextSibling;\n\n//     // Doe this node's container have a sibling?\n//   } else if (node.parentNode && node.parentNode.nextSibling) {\n//     n = node.parentNode.nextSibling;\n//   }\n//   return isBarrierNode(n) ? null : n;\n// }\n\n// // Try to find the prev adjacent node\n// function getPrevNode(node) {\n//   var n = null;\n\n//   // Does this node have a sibling?\n//   if (node.previousSibling) {\n//     n = node.previousSibling;\n\n//     // Doe this node's container have a sibling?\n//   } else if (node.parentNode && node.parentNode.previousSibling) {\n//     n = node.parentNode.previousSibling;\n//   }\n//   return isBarrierNode(n) ? null : n;\n// }\n\n// // REF: http://stackoverflow.com/questions/3127369/how-to-get-selected-textnode-in-contenteditable-div-in-ie\n// function getChildIndex(node) {\n//   var i = 0;\n//   while( (node = node.previousSibling) ) {\n//     i++;\n//   }\n//   return i;\n// }\n\n// // All this code just to make this work with IE, OTL\n// // REF: http://stackoverflow.com/questions/3127369/how-to-get-selected-textnode-in-contenteditable-div-in-ie\n// function getTextRangeBoundaryPosition(textRange, isStart) {\n//   var workingRange = textRange.duplicate();\n//   workingRange.collapse(isStart);\n//   var containerElement = workingRange.parentElement();\n//   var workingNode = document.createElement(\"span\");\n//   var comparison, workingComparisonType = isStart ?\n//     \"StartToStart\" : \"StartToEnd\";\n\n//   var boundaryPosition, boundaryNode;\n\n//   // Move the working range through the container's children, starting at\n//   // the end and working backwards, until the working range reaches or goes\n//   // past the boundary we're interested in\n//   do {\n//     containerElement.insertBefore(workingNode, workingNode.previousSibling);\n//     workingRange.moveToElementText(workingNode);\n//   } while ( (comparison = workingRange.compareEndPoints(\n//     workingComparisonType, textRange)) > 0 && workingNode.previousSibling);\n\n//   // We've now reached or gone past the boundary of the text range we're\n//   // interested in so have identified the node we want\n//   boundaryNode = workingNode.nextSibling;\n//   if (comparison == -1 && boundaryNode) {\n//     // This must be a data node (text, comment, cdata) since we've overshot.\n//     // The working range is collapsed at the start of the node containing\n//     // the text range's boundary, so we move the end of the working range\n//     // to the boundary point and measure the length of its text to get\n//     // the boundary's offset within the node\n//     workingRange.setEndPoint(isStart ? \"EndToStart\" : \"EndToEnd\", textRange);\n\n//     boundaryPosition = {\n//       node: boundaryNode,\n//       offset: workingRange.text.length\n//     };\n//   } else {\n//     // We've hit the boundary exactly, so this must be an element\n//     boundaryPosition = {\n//       node: containerElement,\n//       offset: getChildIndex(workingNode)\n//     };\n//   }\n\n//   // Clean up\n//   workingNode.parentNode.removeChild(workingNode);\n\n//   return boundaryPosition;\n// }\n\n// // DEMO-ONLY code - this shows how the word is recombined across boundaries\n// function showBridge(word, nextText, prevText) {\n//   if (nextText) {\n//     $(\"#bridge\").html(\"<span class=\\\"word\\\">\" + word + \"</span>  |  \" + nextText.substring(0, 20) + \"...\").show();\n//   } else if (prevText) {\n//     $(\"#bridge\").html(\"...\" + prevText.substring(prevText.length - 20, prevText.length) + \"  |  <span class=\\\"word\\\">\" + word + \"</span>\").show();\n//   } else {\n//     $(\"#bridge\").hide();\n//   }\n// }\n\n\nMousePosition.load();"]}