{"version":3,"file":"split.min.js","sources":["../src/split.js"],"sourcesContent":["// The programming goals of Split.js are to deliver readable, understandable and\n// maintainable code, while at the same time manually optimizing for tiny minified file size,\n// browser compatibility without additional requirements, graceful fallback (IE8 is supported)\n// and very few assumptions about the user's page layout.\nconst global = window\nconst { document } = global\n\n// Save a couple long function names that are used frequently.\n// This optimization saves around 400 bytes.\nconst addEventListener = 'addEventListener'\nconst removeEventListener = 'removeEventListener'\nconst getBoundingClientRect = 'getBoundingClientRect'\nconst gutterStartDragging = '_a'\nconst aGutterSize = '_b'\nconst bGutterSize = '_c'\nconst HORIZONTAL = 'horizontal'\nconst NOOP = () => false\n\n// Figure out if we're in IE8 or not. IE8 will still render correctly,\n// but will be static instead of draggable.\nconst isIE8 = global.attachEvent && !global[addEventListener]\n\n// Helper function determines which prefixes of CSS calc we need.\n// We only need to do this once on startup, when this anonymous function is called.\n//\n// Tests -webkit, -moz and -o prefixes. Modified from StackOverflow:\n// http://stackoverflow.com/questions/16625140/js-feature-detection-to-detect-the-usage-of-webkit-calc-over-calc/16625167#16625167\nconst calc = `${['', '-webkit-', '-moz-', '-o-']\n .filter(prefix => {\n const el = document.createElement('div')\n el.style.cssText = `width:${prefix}calc(9px)`\n\n return !!el.style.length\n })\n .shift()}calc`\n\n// Helper function checks if its argument is a string-like type\nconst isString = v => typeof v === 'string' || v instanceof String\n\n// Helper function allows elements and string selectors to be used\n// interchangeably. In either case an element is returned. This allows us to\n// do `Split([elem1, elem2])` as well as `Split(['#id1', '#id2'])`.\nconst elementOrSelector = el => {\n if (isString(el)) {\n const ele = document.querySelector(el)\n if (!ele) {\n throw new Error(`Selector ${el} did not match a DOM element`)\n }\n return ele\n }\n\n return el\n}\n\n// Helper function gets a property from the properties object, with a default fallback\nconst getOption = (options, propName, def) => {\n const value = options[propName]\n if (value !== undefined) {\n return value\n }\n return def\n}\n\nconst getGutterSize = (gutterSize, isFirst, isLast, gutterAlign) => {\n if (isFirst) {\n if (gutterAlign === 'end') {\n return 0\n }\n if (gutterAlign === 'center') {\n return gutterSize / 2\n }\n } else if (isLast) {\n if (gutterAlign === 'start') {\n return 0\n }\n if (gutterAlign === 'center') {\n return gutterSize / 2\n }\n }\n\n return gutterSize\n}\n\n// Default options\nconst defaultGutterFn = (i, gutterDirection) => {\n const gut = document.createElement('div')\n gut.className = `gutter gutter-${gutterDirection}`\n return gut\n}\n\nconst defaultElementStyleFn = (dim, size, gutSize) => {\n const style = {}\n\n if (!isString(size)) {\n if (!isIE8) {\n style[dim] = `${calc}(${size}% - ${gutSize}px)`\n } else {\n style[dim] = `${size}%`\n }\n } else {\n style[dim] = size\n }\n\n return style\n}\n\nconst defaultGutterStyleFn = (dim, gutSize) => ({ [dim]: `${gutSize}px` })\n\n// The main function to initialize a split. Split.js thinks about each pair\n// of elements as an independant pair. Dragging the gutter between two elements\n// only changes the dimensions of elements in that pair. This is key to understanding\n// how the following functions operate, since each function is bound to a pair.\n//\n// A pair object is shaped like this:\n//\n// {\n// a: DOM element,\n// b: DOM element,\n// aMin: Number,\n// bMin: Number,\n// dragging: Boolean,\n// parent: DOM element,\n// direction: 'horizontal' | 'vertical'\n// }\n//\n// The basic sequence:\n//\n// 1. Set defaults to something sane. `options` doesn't have to be passed at all.\n// 2. Initialize a bunch of strings based on the direction we're splitting.\n// A lot of the behavior in the rest of the library is paramatized down to\n// rely on CSS strings and classes.\n// 3. Define the dragging helper functions, and a few helpers to go with them.\n// 4. Loop through the elements while pairing them off. Every pair gets an\n// `pair` object and a gutter.\n// 5. Actually size the pair elements, insert gutters and attach event listeners.\nconst Split = (idsOption, options = {}) => {\n let ids = idsOption\n let dimension\n let clientAxis\n let position\n let positionEnd\n let clientSize\n let elements\n\n // Allow HTMLCollection to be used as an argument when supported\n if (Array.from) {\n ids = Array.from(ids)\n }\n\n // All DOM elements in the split should have a common parent. We can grab\n // the first elements parent and hope users read the docs because the\n // behavior will be whacky otherwise.\n const firstElement = elementOrSelector(ids[0])\n const parent = firstElement.parentNode\n const parentFlexDirection = getComputedStyle\n ? getComputedStyle(parent).flexDirection\n : null\n\n // Set default options.sizes to equal percentages of the parent element.\n let sizes = getOption(options, 'sizes') || ids.map(() => 100 / ids.length)\n\n // Standardize minSize to an array if it isn't already. This allows minSize\n // to be passed as a number.\n const minSize = getOption(options, 'minSize', 100)\n const minSizes = Array.isArray(minSize) ? minSize : ids.map(() => minSize)\n\n // Get other options\n const expandToMin = getOption(options, 'expandToMin', false)\n const gutterSize = getOption(options, 'gutterSize', 10)\n const gutterAlign = getOption(options, 'gutterAlign', 'center')\n const snapOffset = getOption(options, 'snapOffset', 30)\n const dragInterval = getOption(options, 'dragInterval', 1)\n const direction = getOption(options, 'direction', HORIZONTAL)\n const cursor = getOption(\n options,\n 'cursor',\n direction === HORIZONTAL ? 'col-resize' : 'row-resize',\n )\n const gutter = getOption(options, 'gutter', defaultGutterFn)\n const elementStyle = getOption(\n options,\n 'elementStyle',\n defaultElementStyleFn,\n )\n const gutterStyle = getOption(options, 'gutterStyle', defaultGutterStyleFn)\n\n // 2. Initialize a bunch of strings based on the direction we're splitting.\n // A lot of the behavior in the rest of the library is paramatized down to\n // rely on CSS strings and classes.\n if (direction === HORIZONTAL) {\n dimension = 'width'\n clientAxis = 'clientX'\n position = 'left'\n positionEnd = 'right'\n clientSize = 'clientWidth'\n } else if (direction === 'vertical') {\n dimension = 'height'\n clientAxis = 'clientY'\n position = 'top'\n positionEnd = 'bottom'\n clientSize = 'clientHeight'\n }\n\n // 3. Define the dragging helper functions, and a few helpers to go with them.\n // Each helper is bound to a pair object that contains its metadata. This\n // also makes it easy to store references to listeners that that will be\n // added and removed.\n //\n // Even though there are no other functions contained in them, aliasing\n // this to self saves 50 bytes or so since it's used so frequently.\n //\n // The pair object saves metadata like dragging state, position and\n // event listener references.\n\n function setElementSize(el, size, gutSize, i) {\n // Split.js allows setting sizes via numbers (ideally), or if you must,\n // by string, like '300px'. This is less than ideal, because it breaks\n // the fluid layout that `calc(% - px)` provides. You're on your own if you do that,\n // make sure you calculate the gutter size by hand.\n const style = elementStyle(dimension, size, gutSize, i)\n\n Object.keys(style).forEach(prop => {\n // eslint-disable-next-line no-param-reassign\n el.style[prop] = style[prop]\n })\n }\n\n function setGutterSize(gutterElement, gutSize, i) {\n const style = gutterStyle(dimension, gutSize, i)\n\n Object.keys(style).forEach(prop => {\n // eslint-disable-next-line no-param-reassign\n gutterElement.style[prop] = style[prop]\n })\n }\n\n function getSizes() {\n return elements.map(element => element.size)\n }\n\n // Supports touch events, but not multitouch, so only the first\n // finger `touches[0]` is counted.\n function getMousePosition(e) {\n if ('touches' in e) return e.touches[0][clientAxis]\n return e[clientAxis]\n }\n\n // Actually adjust the size of elements `a` and `b` to `offset` while dragging.\n // calc is used to allow calc(percentage + gutterpx) on the whole split instance,\n // which allows the viewport to be resized without additional logic.\n // Element a's size is the same as offset. b's size is total size - a size.\n // Both sizes are calculated from the initial parent percentage,\n // then the gutter size is subtracted.\n function adjust(offset) {\n const a = elements[this.a]\n const b = elements[this.b]\n const percentage = a.size + b.size\n\n a.size = (offset / this.size) * percentage\n b.size = percentage - (offset / this.size) * percentage\n\n setElementSize(a.element, a.size, this[aGutterSize], a.i)\n setElementSize(b.element, b.size, this[bGutterSize], b.i)\n }\n\n // drag, where all the magic happens. The logic is really quite simple:\n //\n // 1. Ignore if the pair is not dragging.\n // 2. Get the offset of the event.\n // 3. Snap offset to min if within snappable range (within min + snapOffset).\n // 4. Actually adjust each element in the pair to offset.\n //\n // ---------------------------------------------------------------------\n // | | <- a.minSize || b.minSize -> | |\n // | | | <- this.snapOffset || this.snapOffset -> | | |\n // | | | || | | |\n // | | | || | | |\n // ---------------------------------------------------------------------\n // | <- this.start this.size -> |\n function drag(e) {\n let offset\n const a = elements[this.a]\n const b = elements[this.b]\n\n if (!this.dragging) return\n\n // Get the offset of the event from the first side of the\n // pair `this.start`. Then offset by the initial position of the\n // mouse compared to the gutter size.\n offset =\n getMousePosition(e) -\n this.start +\n (this[aGutterSize] - this.dragOffset)\n\n if (dragInterval > 1) {\n offset = Math.round(offset / dragInterval) * dragInterval\n }\n\n // If within snapOffset of min or max, set offset to min or max.\n // snapOffset buffers a.minSize and b.minSize, so logic is opposite for both.\n // Include the appropriate gutter sizes to prevent overflows.\n if (offset <= a.minSize + snapOffset + this[aGutterSize]) {\n offset = a.minSize + this[aGutterSize]\n } else if (\n offset >=\n this.size - (b.minSize + snapOffset + this[bGutterSize])\n ) {\n offset = this.size - (b.minSize + this[bGutterSize])\n }\n\n // Actually adjust the size.\n adjust.call(this, offset)\n\n // Call the drag callback continously. Don't do anything too intensive\n // in this callback.\n getOption(options, 'onDrag', NOOP)()\n }\n\n // Cache some important sizes when drag starts, so we don't have to do that\n // continously:\n //\n // `size`: The total size of the pair. First + second + first gutter + second gutter.\n // `start`: The leading side of the first element.\n //\n // ------------------------------------------------\n // | aGutterSize -> ||| |\n // | ||| |\n // | ||| |\n // | ||| <- bGutterSize |\n // ------------------------------------------------\n // | <- start size -> |\n function calculateSizes() {\n // Figure out the parent size minus padding.\n const a = elements[this.a].element\n const b = elements[this.b].element\n\n const aBounds = a[getBoundingClientRect]()\n const bBounds = b[getBoundingClientRect]()\n\n this.size =\n aBounds[dimension] +\n bBounds[dimension] +\n this[aGutterSize] +\n this[bGutterSize]\n this.start = aBounds[position]\n this.end = aBounds[positionEnd]\n }\n\n function innerSize(element) {\n // Return nothing if getComputedStyle is not supported (< IE9)\n // Or if parent element has no layout yet\n if (!getComputedStyle) return null\n\n const computedStyle = getComputedStyle(element)\n let size = element[clientSize]\n\n if (size === 0) return null\n\n if (direction === HORIZONTAL) {\n size -=\n parseFloat(computedStyle.paddingLeft) +\n parseFloat(computedStyle.paddingRight)\n } else {\n size -=\n parseFloat(computedStyle.paddingTop) +\n parseFloat(computedStyle.paddingBottom)\n }\n\n return size\n }\n\n // When specifying percentage sizes that are less than the computed\n // size of the element minus the gutter, the lesser percentages must be increased\n // (and decreased from the other elements) to make space for the pixels\n // subtracted by the gutters.\n function trimToMin(sizesToTrim) {\n // Try to get inner size of parent element.\n // If it's no supported, return original sizes.\n const parentSize = innerSize(parent)\n if (parentSize === null) {\n return sizesToTrim\n }\n\n // Keep track of the excess pixels, the amount of pixels over the desired percentage\n // Also keep track of the elements with pixels to spare, to decrease after if needed\n let excessPixels = 0\n const toSpare = []\n\n const pixelSizes = sizesToTrim.map((size, i) => {\n // Convert requested percentages to pixel sizes\n const pixelSize = (parentSize * size) / 100\n const elementGutterSize = getGutterSize(\n gutterSize,\n i === 0,\n i === sizesToTrim.length - 1,\n gutterAlign,\n )\n const elementMinSize = minSizes[i] + elementGutterSize\n\n // If element is too smal, increase excess pixels by the difference\n // and mark that it has no pixels to spare\n if (pixelSize < elementMinSize) {\n excessPixels += elementMinSize - pixelSize\n toSpare.push(0)\n return elementMinSize\n }\n\n // Otherwise, mark the pixels it has to spare and return it's original size\n toSpare.push(pixelSize - elementMinSize)\n return pixelSize\n })\n\n // If nothing was adjusted, return the original sizes\n if (excessPixels === 0) {\n return sizesToTrim\n }\n\n return pixelSizes.map((pixelSize, i) => {\n let newPixelSize = pixelSize\n\n // While there's still pixels to take, and there's enough pixels to spare,\n // take as many as possible up to the total excess pixels\n if (excessPixels > 0 && toSpare[i] - excessPixels > 0) {\n const takenPixels = Math.min(\n excessPixels,\n toSpare[i] - excessPixels,\n )\n\n // Subtract the amount taken for the next iteration\n excessPixels -= takenPixels\n newPixelSize = pixelSize - takenPixels\n }\n\n // Return the pixel size adjusted as a percentage\n return (newPixelSize / parentSize) * 100\n })\n }\n\n // stopDragging is very similar to startDragging in reverse.\n function stopDragging() {\n const self = this\n const a = elements[self.a].element\n const b = elements[self.b].element\n\n if (self.dragging) {\n getOption(options, 'onDragEnd', NOOP)(getSizes())\n }\n\n self.dragging = false\n\n // Remove the stored event listeners. This is why we store them.\n global[removeEventListener]('mouseup', self.stop)\n global[removeEventListener]('touchend', self.stop)\n global[removeEventListener]('touchcancel', self.stop)\n global[removeEventListener]('mousemove', self.move)\n global[removeEventListener]('touchmove', self.move)\n\n // Clear bound function references\n self.stop = null\n self.move = null\n\n a[removeEventListener]('selectstart', NOOP)\n a[removeEventListener]('dragstart', NOOP)\n b[removeEventListener]('selectstart', NOOP)\n b[removeEventListener]('dragstart', NOOP)\n\n a.style.userSelect = ''\n a.style.webkitUserSelect = ''\n a.style.MozUserSelect = ''\n a.style.pointerEvents = ''\n\n b.style.userSelect = ''\n b.style.webkitUserSelect = ''\n b.style.MozUserSelect = ''\n b.style.pointerEvents = ''\n\n self.gutter.style.cursor = ''\n self.parent.style.cursor = ''\n document.body.style.cursor = ''\n }\n\n // startDragging calls `calculateSizes` to store the inital size in the pair object.\n // It also adds event listeners for mouse/touch events,\n // and prevents selection while dragging so avoid the selecting text.\n function startDragging(e) {\n // Right-clicking can't start dragging.\n if ('button' in e && e.button !== 0) {\n return\n }\n\n // Alias frequently used variables to save space. 200 bytes.\n const self = this\n const a = elements[self.a].element\n const b = elements[self.b].element\n\n // Call the onDragStart callback.\n if (!self.dragging) {\n getOption(options, 'onDragStart', NOOP)(getSizes())\n }\n\n // Don't actually drag the element. We emulate that in the drag function.\n e.preventDefault()\n\n // Set the dragging property of the pair object.\n self.dragging = true\n\n // Create two event listeners bound to the same pair object and store\n // them in the pair object.\n self.move = drag.bind(self)\n self.stop = stopDragging.bind(self)\n\n // All the binding. `window` gets the stop events in case we drag out of the elements.\n global[addEventListener]('mouseup', self.stop)\n global[addEventListener]('touchend', self.stop)\n global[addEventListener]('touchcancel', self.stop)\n global[addEventListener]('mousemove', self.move)\n global[addEventListener]('touchmove', self.move)\n\n // Disable selection. Disable!\n a[addEventListener]('selectstart', NOOP)\n a[addEventListener]('dragstart', NOOP)\n b[addEventListener]('selectstart', NOOP)\n b[addEventListener]('dragstart', NOOP)\n\n a.style.userSelect = 'none'\n a.style.webkitUserSelect = 'none'\n a.style.MozUserSelect = 'none'\n a.style.pointerEvents = 'none'\n\n b.style.userSelect = 'none'\n b.style.webkitUserSelect = 'none'\n b.style.MozUserSelect = 'none'\n b.style.pointerEvents = 'none'\n\n // Set the cursor at multiple levels\n self.gutter.style.cursor = cursor\n self.parent.style.cursor = cursor\n document.body.style.cursor = cursor\n\n // Cache the initial sizes of the pair.\n calculateSizes.call(self)\n\n // Determine the position of the mouse compared to the gutter\n self.dragOffset = getMousePosition(e) - self.end\n }\n\n // adjust sizes to ensure percentage is within min size and gutter.\n sizes = trimToMin(sizes)\n\n // 5. Create pair and element objects. Each pair has an index reference to\n // elements `a` and `b` of the pair (first and second elements).\n // Loop through the elements while pairing them off. Every pair gets a\n // `pair` object and a gutter.\n //\n // Basic logic:\n //\n // - Starting with the second element `i > 0`, create `pair` objects with\n // `a = i - 1` and `b = i`\n // - Set gutter sizes based on the _pair_ being first/last. The first and last\n // pair have gutterSize / 2, since they only have one half gutter, and not two.\n // - Create gutter elements and add event listeners.\n // - Set the size of the elements, minus the gutter sizes.\n //\n // -----------------------------------------------------------------------\n // | i=0 | i=1 | i=2 | i=3 |\n // | | | | |\n // | pair 0 pair 1 pair 2 |\n // | | | | |\n // -----------------------------------------------------------------------\n const pairs = []\n elements = ids.map((id, i) => {\n // Create the element object.\n const element = {\n element: elementOrSelector(id),\n size: sizes[i],\n minSize: minSizes[i],\n i,\n }\n\n let pair\n\n if (i > 0) {\n // Create the pair object with its metadata.\n pair = {\n a: i - 1,\n b: i,\n dragging: false,\n direction,\n parent,\n }\n\n pair[aGutterSize] = getGutterSize(\n gutterSize,\n i - 1 === 0,\n false,\n gutterAlign,\n )\n pair[bGutterSize] = getGutterSize(\n gutterSize,\n false,\n i === ids.length - 1,\n gutterAlign,\n )\n\n // if the parent has a reverse flex-direction, switch the pair elements.\n if (\n parentFlexDirection === 'row-reverse' ||\n parentFlexDirection === 'column-reverse'\n ) {\n const temp = pair.a\n pair.a = pair.b\n pair.b = temp\n }\n }\n\n // Determine the size of the current element. IE8 is supported by\n // staticly assigning sizes without draggable gutters. Assigns a string\n // to `size`.\n //\n // IE9 and above\n if (!isIE8) {\n // Create gutter elements for each pair.\n if (i > 0) {\n const gutterElement = gutter(i, direction, element.element)\n setGutterSize(gutterElement, gutterSize, i)\n\n // Save bound event listener for removal later\n pair[gutterStartDragging] = startDragging.bind(pair)\n\n // Attach bound event listener\n gutterElement[addEventListener](\n 'mousedown',\n pair[gutterStartDragging],\n )\n gutterElement[addEventListener](\n 'touchstart',\n pair[gutterStartDragging],\n )\n\n parent.insertBefore(gutterElement, element.element)\n\n pair.gutter = gutterElement\n }\n }\n\n setElementSize(\n element.element,\n element.size,\n getGutterSize(\n gutterSize,\n i === 0,\n i === ids.length - 1,\n gutterAlign,\n ),\n )\n\n // After the first iteration, and we have a pair object, append it to the\n // list of pairs.\n if (i > 0) {\n pairs.push(pair)\n }\n\n return element\n })\n\n function adjustToMin(element) {\n const isLast = element.i === pairs.length\n const pair = isLast ? pairs[element.i - 1] : pairs[element.i]\n\n calculateSizes.call(pair)\n\n const size = isLast\n ? pair.size - element.minSize - pair[bGutterSize]\n : element.minSize + pair[aGutterSize]\n\n adjust.call(pair, size)\n }\n\n elements.forEach(element => {\n const computedSize = element.element[getBoundingClientRect]()[dimension]\n\n if (computedSize < element.minSize) {\n if (expandToMin) {\n adjustToMin(element)\n } else {\n // eslint-disable-next-line no-param-reassign\n element.minSize = computedSize\n }\n }\n })\n\n function setSizes(newSizes) {\n const trimmed = trimToMin(newSizes)\n trimmed.forEach((newSize, i) => {\n if (i > 0) {\n const pair = pairs[i - 1]\n\n const a = elements[pair.a]\n const b = elements[pair.b]\n\n a.size = trimmed[i - 1]\n b.size = newSize\n\n setElementSize(a.element, a.size, pair[aGutterSize])\n setElementSize(b.element, b.size, pair[bGutterSize])\n }\n })\n }\n\n function destroy(preserveStyles, preserveGutter) {\n pairs.forEach(pair => {\n if (preserveGutter !== true) {\n pair.parent.removeChild(pair.gutter)\n } else {\n pair.gutter[removeEventListener](\n 'mousedown',\n pair[gutterStartDragging],\n )\n pair.gutter[removeEventListener](\n 'touchstart',\n pair[gutterStartDragging],\n )\n }\n\n if (preserveStyles !== true) {\n const style = elementStyle(\n dimension,\n pair.a.size,\n pair[aGutterSize],\n )\n\n Object.keys(style).forEach(prop => {\n elements[pair.a].element.style[prop] = ''\n elements[pair.b].element.style[prop] = ''\n })\n }\n })\n }\n\n if (isIE8) {\n return {\n setSizes,\n destroy,\n }\n }\n\n return {\n setSizes,\n getSizes,\n collapse(i) {\n adjustToMin(elements[i])\n },\n destroy,\n parent,\n pairs,\n }\n}\n\nexport default Split\n"],"names":["const","global","window","addEventListener","removeEventListener","getBoundingClientRect","HORIZONTAL","NOOP","isIE8","attachEvent","calc","filter","prefix","el","document","createElement","style","cssText","length","shift","isString","v","String","elementOrSelector","ele","querySelector","Error","getOption","options","propName","def","value","undefined","getGutterSize","gutterSize","isFirst","isLast","gutterAlign","defaultGutterFn","i","gutterDirection","gut","className","defaultElementStyleFn","dim","size","gutSize","defaultGutterStyleFn","idsOption","let","dimension","clientAxis","position","positionEnd","clientSize","elements","ids","Array","from","parent","parentNode","parentFlexDirection","getComputedStyle","flexDirection","sizes","map","minSize","minSizes","isArray","expandToMin","snapOffset","dragInterval","direction","cursor","gutter","elementStyle","gutterStyle","setElementSize","Object","keys","forEach","prop","getSizes","element","getMousePosition","e","touches","adjust","offset","a","this","b","percentage","calculateSizes","aBounds","bBounds","start","end","trimToMin","sizesToTrim","parentSize","computedStyle","parseFloat","paddingLeft","paddingRight","paddingTop","paddingBottom","innerSize","excessPixels","toSpare","pixelSizes","pixelSize","elementGutterSize","elementMinSize","push","newPixelSize","takenPixels","Math","min","startDragging","button","self","dragging","preventDefault","move","dragOffset","round","call","bind","stop","userSelect","webkitUserSelect","MozUserSelect","pointerEvents","body","pairs","adjustToMin","pair","setSizes","newSizes","trimmed","newSize","destroy","preserveStyles","preserveGutter","removeChild","id","gutterElement","temp","insertBefore","computedSize","collapse"],"mappings":"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"}