{"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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"}