diff options
| author | schneefux <schneefux+commit@schneefux.xyz> | 2017-03-22 19:19:26 +0100 |
|---|---|---|
| committer | schneefux <schneefux+commit@schneefux.xyz> | 2017-03-22 19:19:26 +0100 |
| commit | d42c8b528eb595101954f478e0024e3f079f6fbf (patch) | |
| tree | 61a528cf94f1f6941f4683ae8736a4a0135c035e /templates/assets/tether/src/js/constraint.js | |
| download | minionlivesmatter-d42c8b528eb595101954f478e0024e3f079f6fbf.tar.gz minionlivesmatter-d42c8b528eb595101954f478e0024e3f079f6fbf.zip | |
first implementation of fun stats site
Diffstat (limited to 'templates/assets/tether/src/js/constraint.js')
| -rw-r--r-- | templates/assets/tether/src/js/constraint.js | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/templates/assets/tether/src/js/constraint.js b/templates/assets/tether/src/js/constraint.js new file mode 100644 index 0000000..1717149 --- /dev/null +++ b/templates/assets/tether/src/js/constraint.js @@ -0,0 +1,366 @@ +/* globals TetherBase */ + +const { + getBounds, + extend, + updateClasses, + defer +} = TetherBase.Utils; + +const BOUNDS_FORMAT = ['left', 'top', 'right', 'bottom']; + +function getBoundingRect(tether, to) { + if (to === 'scrollParent') { + to = tether.scrollParents[0]; + } else if (to === 'window') { + to = [pageXOffset, pageYOffset, innerWidth + pageXOffset, innerHeight + pageYOffset]; + } + + if (to === document) { + to = to.documentElement; + } + + if (typeof to.nodeType !== 'undefined') { + const node = to; + const size = getBounds(to); + const pos = size; + const style = getComputedStyle(to); + + to = [pos.left, pos.top, size.width + pos.left, size.height + pos.top]; + + // Account any parent Frames scroll offset + if (node.ownerDocument !== document) { + let win = node.ownerDocument.defaultView; + to[0] += win.pageXOffset; + to[1] += win.pageYOffset; + to[2] += win.pageXOffset; + to[3] += win.pageYOffset; + } + + BOUNDS_FORMAT.forEach((side, i) => { + side = side[0].toUpperCase() + side.substr(1); + if (side === 'Top' || side === 'Left') { + to[i] += parseFloat(style[`border${ side }Width`]); + } else { + to[i] -= parseFloat(style[`border${ side }Width`]); + } + }); + } + + return to; +} + +TetherBase.modules.push({ + position({top, left, targetAttachment}) { + if (!this.options.constraints) { + return true; + } + + let {height, width} = this.cache('element-bounds', () => { + return getBounds(this.element); + }); + + if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') { + // Handle the item getting hidden as a result of our positioning without glitching + // the classes in and out + ({width, height} = this.lastSize); + } + + const targetSize = this.cache('target-bounds', () => { + return this.getTargetBounds(); + }); + + const {height: targetHeight, width: targetWidth} = targetSize; + + const allClasses = [this.getClass('pinned'), this.getClass('out-of-bounds')]; + + this.options.constraints.forEach(constraint => { + const {outOfBoundsClass, pinnedClass} = constraint; + if (outOfBoundsClass) { + allClasses.push(outOfBoundsClass); + } + if (pinnedClass) { + allClasses.push(pinnedClass); + } + }); + + allClasses.forEach(cls => { + ['left', 'top', 'right', 'bottom'].forEach(side => { + allClasses.push(`${ cls }-${ side }`); + }); + }); + + const addClasses = []; + + const tAttachment = extend({}, targetAttachment); + const eAttachment = extend({}, this.attachment); + + this.options.constraints.forEach(constraint => { + let {to, attachment, pin} = constraint; + + if (typeof attachment === 'undefined') { + attachment = ''; + } + + let changeAttachX, changeAttachY; + if (attachment.indexOf(' ') >= 0) { + [changeAttachY, changeAttachX] = attachment.split(' '); + } else { + changeAttachX = changeAttachY = attachment; + } + + const bounds = getBoundingRect(this, to); + + if (changeAttachY === 'target' || changeAttachY === 'both') { + if (top < bounds[1] && tAttachment.top === 'top') { + top += targetHeight; + tAttachment.top = 'bottom'; + } + + if (top + height > bounds[3] && tAttachment.top === 'bottom') { + top -= targetHeight; + tAttachment.top = 'top'; + } + } + + if (changeAttachY === 'together') { + if (tAttachment.top === 'top') { + if (eAttachment.top === 'bottom' && top < bounds[1]) { + top += targetHeight; + tAttachment.top = 'bottom'; + + top += height; + eAttachment.top = 'top'; + + } else if (eAttachment.top === 'top' && top + height > bounds[3] && top - (height - targetHeight) >= bounds[1]) { + top -= height - targetHeight; + tAttachment.top = 'bottom'; + + eAttachment.top = 'bottom'; + } + } + + if (tAttachment.top === 'bottom') { + if (eAttachment.top === 'top' && top + height > bounds[3]) { + top -= targetHeight; + tAttachment.top = 'top'; + + top -= height; + eAttachment.top = 'bottom'; + + } else if (eAttachment.top === 'bottom'&& top < bounds[1] && top + (height*2 - targetHeight) <= bounds[3]) { + top += height - targetHeight; + tAttachment.top = 'top'; + + eAttachment.top = 'top'; + + } + } + + if (tAttachment.top === 'middle') { + if (top + height > bounds[3] && eAttachment.top === 'top') { + top -= height; + eAttachment.top = 'bottom'; + + } else if (top < bounds[1] && eAttachment.top === 'bottom') { + top += height; + eAttachment.top = 'top'; + } + } + } + + if (changeAttachX === 'target' || changeAttachX === 'both') { + if (left < bounds[0] && tAttachment.left === 'left') { + left += targetWidth; + tAttachment.left = 'right'; + } + + if (left + width > bounds[2] && tAttachment.left === 'right') { + left -= targetWidth; + tAttachment.left = 'left'; + } + } + + if (changeAttachX === 'together') { + if (left < bounds[0] && tAttachment.left === 'left') { + if (eAttachment.left === 'right') { + left += targetWidth; + tAttachment.left = 'right'; + + left += width; + eAttachment.left = 'left'; + + } else if (eAttachment.left === 'left') { + left += targetWidth; + tAttachment.left = 'right'; + + left -= width; + eAttachment.left = 'right'; + } + + } else if (left + width > bounds[2] && tAttachment.left === 'right') { + if (eAttachment.left === 'left') { + left -= targetWidth; + tAttachment.left = 'left'; + + left -= width; + eAttachment.left = 'right'; + + } else if (eAttachment.left === 'right') { + left -= targetWidth; + tAttachment.left = 'left'; + + left += width; + eAttachment.left = 'left'; + } + + } else if (tAttachment.left === 'center') { + if (left + width > bounds[2] && eAttachment.left === 'left') { + left -= width; + eAttachment.left = 'right'; + + } else if (left < bounds[0] && eAttachment.left === 'right') { + left += width; + eAttachment.left = 'left'; + } + } + } + + if (changeAttachY === 'element' || changeAttachY === 'both') { + if (top < bounds[1] && eAttachment.top === 'bottom') { + top += height; + eAttachment.top = 'top'; + } + + if (top + height > bounds[3] && eAttachment.top === 'top') { + top -= height; + eAttachment.top = 'bottom'; + } + } + + if (changeAttachX === 'element' || changeAttachX === 'both') { + if (left < bounds[0]) { + if (eAttachment.left === 'right') { + left += width; + eAttachment.left = 'left'; + } else if (eAttachment.left === 'center') { + left += (width / 2); + eAttachment.left = 'left'; + } + } + + if (left + width > bounds[2]) { + if (eAttachment.left === 'left') { + left -= width; + eAttachment.left = 'right'; + } else if (eAttachment.left === 'center') { + left -= (width / 2); + eAttachment.left = 'right'; + } + } + } + + if (typeof pin === 'string') { + pin = pin.split(',').map(p => p.trim()); + } else if (pin === true) { + pin = ['top', 'left', 'right', 'bottom']; + } + + pin = pin || []; + + const pinned = []; + const oob = []; + + if (top < bounds[1]) { + if (pin.indexOf('top') >= 0) { + top = bounds[1]; + pinned.push('top'); + } else { + oob.push('top'); + } + } + + if (top + height > bounds[3]) { + if (pin.indexOf('bottom') >= 0) { + top = bounds[3] - height; + pinned.push('bottom'); + } else { + oob.push('bottom'); + } + } + + if (left < bounds[0]) { + if (pin.indexOf('left') >= 0) { + left = bounds[0]; + pinned.push('left'); + } else { + oob.push('left'); + } + } + + if (left + width > bounds[2]) { + if (pin.indexOf('right') >= 0) { + left = bounds[2] - width; + pinned.push('right'); + } else { + oob.push('right'); + } + } + + if (pinned.length) { + let pinnedClass; + if (typeof this.options.pinnedClass !== 'undefined') { + pinnedClass = this.options.pinnedClass; + } else { + pinnedClass = this.getClass('pinned'); + } + + addClasses.push(pinnedClass); + pinned.forEach(side => { + addClasses.push(`${ pinnedClass }-${ side }`); + }); + } + + if (oob.length) { + let oobClass; + if (typeof this.options.outOfBoundsClass !== 'undefined') { + oobClass = this.options.outOfBoundsClass; + } else { + oobClass = this.getClass('out-of-bounds'); + } + + addClasses.push(oobClass); + oob.forEach(side => { + addClasses.push(`${ oobClass }-${ side }`); + }); + } + + if (pinned.indexOf('left') >= 0 || pinned.indexOf('right') >= 0) { + eAttachment.left = tAttachment.left = false; + } + if (pinned.indexOf('top') >= 0 || pinned.indexOf('bottom') >= 0) { + eAttachment.top = tAttachment.top = false; + } + + if (tAttachment.top !== targetAttachment.top || + tAttachment.left !== targetAttachment.left || + eAttachment.top !== this.attachment.top || + eAttachment.left !== this.attachment.left) { + this.updateAttachClasses(eAttachment, tAttachment); + this.trigger('update', { + attachment: eAttachment, + targetAttachment: tAttachment, + }); + } + }); + + defer(() => { + if (!(this.options.addTargetClasses === false)) { + updateClasses(this.target, addClasses, allClasses); + } + updateClasses(this.element, addClasses, allClasses); + }); + + return {top, left}; + } +}); |
