{"version":3,"file":"share-this.js","sources":["../src/dom.js","../src/utils.js","../src/popover.js","../src/selection.js","../src/core.js","../src/render.js"],"sourcesContent":["export function getOffsetScroll(_window) {\n const body = _window.document.body;\n const scrollReference = _window.getComputedStyle(body).position === \"static\" ? body.parentNode : body;\n return scrollReference.getBoundingClientRect();\n}\n\nlet matchFunc;\nexport function matches(element, selector) {\n if (!matchFunc) matchFunc = getMatchFunctionName(element);\n return element[matchFunc](selector);\n}\n\nexport function closest(element, selector) {\n let target = element;\n while (target && (target.nodeType !== 1 /* === Node.ELEMENT_NODE */ || !matches(target, selector))) {\n target = target.parentNode;\n }\n\n return target;\n}\n\n// `contains` in IE doesn't work with text nodes\nexport function contains(ancestor, target) {\n const comparedPositions = ancestor.compareDocumentPosition(target);\n // eslint-disable-next-line no-bitwise\n return !comparedPositions || (comparedPositions & 16 /* === Node.DOCUMENT_POSITION_CONTAINED_BY */) > 0;\n}\n\n// eslint-disable-next-line consistent-return\nfunction getMatchFunctionName(element) {\n const suffix = \"atchesSelector\";\n for (const name of [ \"matches\", `m${suffix}`, `webkitM${suffix}`, `mozM${suffix}`, `msM${suffix}`, `oM${suffix}` ]) {\n if (element[name]) return name;\n }\n}\n","export function camelize(string) {\n return string.replace(/(?:^|-)([a-z])/g, (_, char) => char.toUpperCase());\n}\n\n// eslint-disable-next-line consistent-return\nexport function findByName(array, name) {\n // I would have used\n // for (const item of array) {\n // but transpilers generate A LOT of code in this specific case.\n for (let i = 0; i < array.length; i++) {\n const item = array[i];\n if (item.name === name) {\n return item;\n }\n }\n}\n\nexport function extend(dest, source) {\n if (source && typeof source === \"object\") {\n // eslint-disable-next-line guard-for-in\n for (const prop in source) {\n // eslint-disable-next-line no-param-reassign\n dest[prop] = source[prop];\n }\n }\n\n return dest;\n}\n\nexport function isCallable(func) {\n return typeof func === \"function\";\n}\n","import { getOffsetScroll, closest } from \"./dom.js\";\nimport { findByName, isCallable } from \"./utils.js\";\nimport { isSelectionForward, getEndLineRect } from \"./selection.js\";\n\nexport function stylePopover(popover, range, options) {\n const _document = options.document;\n const _window = _document.defaultView;\n const selection = _window.getSelection();\n const isForward = isSelectionForward(selection);\n const endLineRect = getEndLineRect(range, isForward);\n const offsetScroll = getOffsetScroll(_window);\n\n const style = popover.style;\n if (isForward) {\n style.right = `${_document.documentElement.clientWidth - endLineRect.right + offsetScroll.left}px`;\n } else {\n style.left = `${endLineRect.left - offsetScroll.left}px`;\n }\n style.width = `${endLineRect.right - endLineRect.left}px`;\n style.height = `${endLineRect.bottom - endLineRect.top}px`;\n style.top = `${endLineRect.top - offsetScroll.top}px`;\n style.position = \"absolute\";\n\n // eslint-disable-next-line no-param-reassign\n popover.className = options.popoverClass;\n}\n\nconst dataAttribute = \"data-share-via\";\nexport function popoverClick(sharers, event) {\n const item = closest(event.target, `[${dataAttribute}]`);\n if (!item) return;\n\n const via = item.getAttribute(dataAttribute);\n const sharer = findByName(sharers, via);\n if (sharer && isCallable(sharer.action)) {\n sharer.action(event, item);\n }\n}\n\nexport function lifeCycleFactory(document) {\n return {\n createPopover() {\n const popover = document.createElement(\"div\");\n popover.addEventListener(\"click\", function(event) {\n popoverClick(this.sharers, event);\n });\n return popover;\n },\n attachPopover(popover) {\n document.body.appendChild(popover);\n },\n removePopover(popover) {\n const parent = popover.parentNode;\n if (parent) parent.removeChild(popover);\n }\n };\n}\n","import { closest, contains } from \"./dom.js\";\n\nexport function isSelectionForward(selection) {\n if (selection.isCollapsed) return true;\n\n const comparedPositions = selection.anchorNode.compareDocumentPosition(selection.focusNode);\n if (!comparedPositions) {\n // It's the same node\n return selection.anchorOffset < selection.focusOffset;\n }\n\n // eslint-disable-next-line no-bitwise\n return (comparedPositions & 4 /* === Node.DOCUMENT_POSITION_FOLLOWING */) > 0;\n}\n\nexport function getEndLineRect(range, isForward) {\n let endLineRects;\n const rangeRects = range.getClientRects();\n const sliceRects = [].slice.bind(rangeRects);\n\n if (isForward) {\n let lastLeft = Infinity;\n let i = rangeRects.length;\n while (i--) {\n const rect = rangeRects[i];\n if (rect.left > lastLeft) break;\n lastLeft = rect.left;\n }\n endLineRects = sliceRects(i + 1);\n } else {\n let lastRight = -Infinity;\n let i = 0;\n for (; i < rangeRects.length; i++) {\n const rect = rangeRects[i];\n if (rect.right < lastRight) break;\n lastRight = rect.right;\n }\n endLineRects = sliceRects(0, i);\n }\n\n return {\n top: Math.min(...endLineRects.map(rect => rect.top)),\n bottom: Math.max(...endLineRects.map(rect => rect.bottom)),\n left: endLineRects[0].left,\n right: endLineRects[endLineRects.length - 1].right\n };\n}\n\nexport function constrainRange(range, selector) {\n const constrainedRange = range.cloneRange();\n if (range.collapsed || !selector) return constrainedRange;\n\n let ancestor = closest(range.startContainer, selector);\n if (ancestor) {\n if (!contains(ancestor, range.endContainer)) {\n constrainedRange.setEnd(ancestor, ancestor.childNodes.length);\n }\n } else {\n ancestor = closest(range.endContainer, selector);\n if (ancestor) constrainedRange.setStart(ancestor, 0);\n else constrainedRange.collapse();\n }\n\n return constrainedRange;\n}\n","import { stylePopover, lifeCycleFactory } from \"./popover.js\";\nimport { constrainRange } from \"./selection.js\";\nimport { extend, isCallable } from \"./utils.js\";\nimport render from \"./render.js\";\n\nlet _undefined;\nconst eventTypes = [ \"selectionchange\", \"mouseup\", \"touchend\", \"touchcancel\" ];\n\nexport default (opts) => {\n const options = (Object.assign || extend)({\n document,\n selector: \"body\",\n sharers: [],\n popoverClass: \"share-this-popover\",\n transformer: raw => raw.trim().replace(/\\s+/g, \" \")\n }, opts || {});\n\n let initialized = false;\n let destroyed = false;\n\n let _document = _undefined;\n let _window = _undefined;\n\n let popover = _undefined;\n let lifeCycle = _undefined;\n\n return {\n init() {\n if (initialized) return false;\n\n _document = options.document;\n _window = _document.defaultView;\n if (!_window.getSelection) {\n // eslint-disable-next-line no-console\n console.warn(\"share-this: Selection API isn't supported\");\n return false;\n }\n\n eventTypes.forEach(addListener);\n _window.addEventListener(\"resize\", resizeHandler);\n\n lifeCycle = lifeCycleFactory(_document);\n\n return initialized = true;\n },\n destroy() {\n if (!initialized || destroyed) return false;\n\n eventTypes.forEach(removeListener);\n _window.removeEventListener(\"resize\", resizeHandler);\n\n killPopover();\n\n _document = _undefined;\n _window = _undefined;\n\n return destroyed = true;\n },\n reposition() {\n if (popover) {\n stylePopover(popover, getConstrainedRange(), options);\n }\n return !!popover;\n }\n };\n\n function addListener(type) { _document.addEventListener(type, selectionCheck); }\n function removeListener(type) { _document.removeEventListener(type, selectionCheck); }\n function resizeHandler() {\n if (popover) {\n stylePopover(popover, getConstrainedRange(), options);\n }\n }\n\n function selectionCheck({ type }) {\n const shouldHavePopover = type === \"selectionchange\";\n if (!popover !== shouldHavePopover) {\n // Safari iOS fires selectionchange *before* click, so tapping on a sharer would be prevented\n setTimeout(() => {\n if (_window) {\n const range = getConstrainedRange();\n if (range) drawPopover(range);\n else killPopover();\n }\n }, 10);\n }\n }\n\n function getConstrainedRange() {\n const selection = _window.getSelection();\n const range = selection.rangeCount && selection.getRangeAt(0);\n if (!range) return;\n\n const constrainedRange = constrainRange(range, options.selector);\n if (constrainedRange.collapsed || !constrainedRange.getClientRects().length) return;\n\n // eslint-disable-next-line consistent-return\n return constrainedRange;\n }\n\n function drawPopover(range) {\n const toBeOpened = !popover;\n const rawText = range.toString();\n const text = options.transformer(rawText);\n const sharers = options.sharers.filter(sharerCheck.bind(null, text, rawText));\n\n if (!sharers.length) {\n if (popover) killPopover();\n return;\n }\n if (toBeOpened) popover = lifeCycle.createPopover();\n\n popover.sharers = sharers;\n popover.innerHTML = render(options, sharers, text, rawText);\n stylePopover(popover, range, options);\n\n if (!toBeOpened) return;\n\n lifeCycle.attachPopover(popover);\n\n if (isCallable(options.onOpen)) {\n options.onOpen(popover, text, rawText);\n }\n }\n\n function killPopover() {\n if (!popover) return;\n\n lifeCycle.removePopover(popover);\n popover = _undefined;\n if (isCallable(options.onClose)) {\n options.onClose();\n }\n }\n\n function sharerCheck(text, rawText, sharer) {\n const active = sharer.active;\n if (isCallable(active)) {\n return active(text, rawText);\n }\n\n if (active !== _undefined) {\n return active;\n }\n\n return true;\n }\n};\n","export default (options, sharers, text, rawText) => {\n const refUrl = options.shareUrl || options.document.defaultView.location;\n\n // eslint-disable-next-line prefer-template\n return \"<ul>\"\n + sharers.map(sharer => `<li data-share-via=\"${sharer.name}\">${sharer.render.call(sharer, text, rawText, refUrl)}</li>`).join(\"\")\n + \"</ul>\";\n};\n"],"names":["matchFunc","matches","element","selector","suffix","name","getMatchFunctionName","closest","target","nodeType","parentNode","isCallable","func","stylePopover","popover","range","options","_document","document","_window","defaultView","isForward","selection","isCollapsed","comparedPositions","anchorNode","compareDocumentPosition","focusNode","anchorOffset","focusOffset","isSelectionForward","getSelection","endLineRect","endLineRects","rangeRects","getClientRects","sliceRects","slice","bind","lastLeft","Infinity","i","length","rect","left","lastRight","right","top","Math","min","map","bottom","max","getEndLineRect","offsetScroll","body","getComputedStyle","position","getBoundingClientRect","getOffsetScroll","style","documentElement","clientWidth","width","height","className","popoverClass","dataAttribute","lifeCycleFactory","createPopover","createElement","addEventListener","event","sharers","item","sharer","array","findByName","getAttribute","action","popoverClick","this","attachPopover","appendChild","removePopover","parent","removeChild","_undefined","text","rawText","refUrl","shareUrl","location","render","call","join","eventTypes","opts","Object","assign","dest","source","prop","transformer","raw","trim","replace","initialized","destroyed","lifeCycle","init","forEach","addListener","resizeHandler","console","warn","destroy","removeListener","removeEventListener","killPopover","reposition","getConstrainedRange","type","selectionCheck","setTimeout","toBeOpened","toString","filter","active","innerHTML","onOpen","drawPopover","rangeCount","getRangeAt","constrainedRange","cloneRange","collapsed","ancestor","startContainer","contains","endContainer","setEnd","childNodes","setStart","collapse","constrainRange","onClose"],"mappings":"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"}