mirror of https://github.com/gchq/CyberChef.git
375 lines
13 KiB
JavaScript
Executable File
375 lines
13 KiB
JavaScript
Executable File
/** @license
|
|
========================================================================
|
|
Split.js v1.0.7
|
|
Copyright (c) 2015 Nathan Cahill
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
(function() {
|
|
|
|
var global = this
|
|
, addEventListener = 'addEventListener'
|
|
, removeEventListener = 'removeEventListener'
|
|
, getBoundingClientRect = 'getBoundingClientRect'
|
|
, isIE8 = global.attachEvent && !global[addEventListener]
|
|
, document = global.document
|
|
|
|
, calc = (function () {
|
|
var el
|
|
, prefixes = ["", "-webkit-", "-moz-", "-o-"]
|
|
|
|
for (var i = 0; i < prefixes.length; i++) {
|
|
el = document.createElement('div')
|
|
el.style.cssText = "width:" + prefixes[i] + "calc(9px)"
|
|
|
|
if (el.style.length) {
|
|
return prefixes[i] + "calc"
|
|
}
|
|
}
|
|
})()
|
|
, elementOrSelector = function (el) {
|
|
if (typeof el === 'string' || el instanceof String) {
|
|
return document.querySelector(el)
|
|
} else {
|
|
return el
|
|
}
|
|
}
|
|
|
|
, Split = function (ids, options) {
|
|
var dimension
|
|
, i
|
|
, clientDimension
|
|
, clientAxis
|
|
, position
|
|
, gutterClass
|
|
, paddingA
|
|
, paddingB
|
|
, pairs = []
|
|
|
|
// Set defaults
|
|
|
|
options = typeof options !== 'undefined' ? options : {}
|
|
|
|
if (typeof options.gutterSize === 'undefined') options.gutterSize = 10
|
|
if (typeof options.minSize === 'undefined') options.minSize = 100
|
|
if (typeof options.snapOffset === 'undefined') options.snapOffset = 30
|
|
if (typeof options.direction === 'undefined') options.direction = 'horizontal'
|
|
|
|
if (options.direction == 'horizontal') {
|
|
dimension = 'width'
|
|
clientDimension = 'clientWidth'
|
|
clientAxis = 'clientX'
|
|
position = 'left'
|
|
gutterClass = 'gutter gutter-horizontal'
|
|
paddingA = 'paddingLeft'
|
|
paddingB = 'paddingRight'
|
|
if (!options.cursor) options.cursor = 'ew-resize'
|
|
} else if (options.direction == 'vertical') {
|
|
dimension = 'height'
|
|
clientDimension = 'clientHeight'
|
|
clientAxis = 'clientY'
|
|
position = 'top'
|
|
gutterClass = 'gutter gutter-vertical'
|
|
paddingA = 'paddingTop'
|
|
paddingB = 'paddingBottom'
|
|
if (!options.cursor) options.cursor = 'ns-resize'
|
|
}
|
|
|
|
// Event listeners for drag events, bound to a pair object.
|
|
// Calculate the pair's position and size when dragging starts.
|
|
// Prevent selection on start and re-enable it when done.
|
|
|
|
var startDragging = function (e) {
|
|
var self = this
|
|
, a = self.a
|
|
, b = self.b
|
|
|
|
if (!self.dragging && options.onDragStart) {
|
|
options.onDragStart()
|
|
}
|
|
|
|
e.preventDefault()
|
|
|
|
self.dragging = true
|
|
self.move = drag.bind(self)
|
|
self.stop = stopDragging.bind(self)
|
|
|
|
global[addEventListener]('mouseup', self.stop)
|
|
global[addEventListener]('touchend', self.stop)
|
|
global[addEventListener]('touchcancel', self.stop)
|
|
|
|
self.parent[addEventListener]('mousemove', self.move)
|
|
self.parent[addEventListener]('touchmove', self.move)
|
|
|
|
a[addEventListener]('selectstart', preventSelection)
|
|
a[addEventListener]('dragstart', preventSelection)
|
|
b[addEventListener]('selectstart', preventSelection)
|
|
b[addEventListener]('dragstart', preventSelection)
|
|
|
|
a.style.userSelect = 'none'
|
|
a.style.webkitUserSelect = 'none'
|
|
a.style.MozUserSelect = 'none'
|
|
a.style.pointerEvents = 'none'
|
|
|
|
b.style.userSelect = 'none'
|
|
b.style.webkitUserSelect = 'none'
|
|
b.style.MozUserSelect = 'none'
|
|
b.style.pointerEvents = 'none'
|
|
|
|
self.gutter.style.cursor = options.cursor
|
|
self.parent.style.cursor = options.cursor
|
|
|
|
calculateSizes.call(self)
|
|
}
|
|
, stopDragging = function () {
|
|
var self = this
|
|
, a = self.a
|
|
, b = self.b
|
|
|
|
if (self.dragging && options.onDragEnd) {
|
|
options.onDragEnd()
|
|
}
|
|
|
|
self.dragging = false
|
|
|
|
global[removeEventListener]('mouseup', self.stop)
|
|
global[removeEventListener]('touchend', self.stop)
|
|
global[removeEventListener]('touchcancel', self.stop)
|
|
|
|
self.parent[removeEventListener]('mousemove', self.move)
|
|
self.parent[removeEventListener]('touchmove', self.move)
|
|
|
|
delete self.stop
|
|
delete self.move
|
|
|
|
a[removeEventListener]('selectstart', preventSelection)
|
|
a[removeEventListener]('dragstart', preventSelection)
|
|
b[removeEventListener]('selectstart', preventSelection)
|
|
b[removeEventListener]('dragstart', preventSelection)
|
|
|
|
a.style.userSelect = ''
|
|
a.style.webkitUserSelect = ''
|
|
a.style.MozUserSelect = ''
|
|
a.style.pointerEvents = ''
|
|
|
|
b.style.userSelect = ''
|
|
b.style.webkitUserSelect = ''
|
|
b.style.MozUserSelect = ''
|
|
b.style.pointerEvents = ''
|
|
|
|
self.gutter.style.cursor = ''
|
|
self.parent.style.cursor = ''
|
|
}
|
|
, drag = function (e) {
|
|
var offset
|
|
|
|
if (!this.dragging) return
|
|
|
|
// Get the relative position of the event from the first side of the
|
|
// pair.
|
|
|
|
if ('touches' in e) {
|
|
offset = e.touches[0][clientAxis] - this.start
|
|
} else {
|
|
offset = e[clientAxis] - this.start
|
|
}
|
|
|
|
// If within snapOffset of min or max, set offset to min or max
|
|
|
|
if (offset <= this.aMin + options.snapOffset) {
|
|
offset = this.aMin
|
|
} else if (offset >= this.size - this.bMin - options.snapOffset) {
|
|
offset = this.size - this.bMin
|
|
}
|
|
|
|
adjust.call(this, offset)
|
|
|
|
if (options.onDrag) {
|
|
options.onDrag()
|
|
}
|
|
}
|
|
, calculateSizes = function () {
|
|
// Calculate the pairs size, and percentage of the parent size
|
|
var computedStyle = global.getComputedStyle(this.parent)
|
|
, parentSize = this.parent[clientDimension] - parseFloat(computedStyle[paddingA]) - parseFloat(computedStyle[paddingB])
|
|
|
|
this.size = this.a[getBoundingClientRect]()[dimension] + this.b[getBoundingClientRect]()[dimension] + this.aGutterSize + this.bGutterSize
|
|
this.percentage = Math.min(this.size / parentSize * 100, 100)
|
|
this.start = this.a[getBoundingClientRect]()[position]
|
|
}
|
|
, adjust = function (offset) {
|
|
// A size is the same as offset. B size is total size - A size.
|
|
// Both sizes are calculated from the initial parent percentage.
|
|
|
|
this.a.style[dimension] = calc + '(' + (offset / this.size * this.percentage) + '% - ' + this.aGutterSize + 'px)'
|
|
this.b.style[dimension] = calc + '(' + (this.percentage - (offset / this.size * this.percentage)) + '% - ' + this.bGutterSize + 'px)'
|
|
}
|
|
, fitMin = function () {
|
|
var self = this
|
|
, a = self.a
|
|
, b = self.b
|
|
|
|
if (a[getBoundingClientRect]()[dimension] < self.aMin) {
|
|
a.style[dimension] = (self.aMin - self.aGutterSize) + 'px'
|
|
b.style[dimension] = (self.size - self.aMin - self.aGutterSize) + 'px'
|
|
} else if (b[getBoundingClientRect]()[dimension] < self.bMin) {
|
|
a.style[dimension] = (self.size - self.bMin - self.bGutterSize) + 'px'
|
|
b.style[dimension] = (self.bMin - self.bGutterSize) + 'px'
|
|
}
|
|
}
|
|
, fitMinReverse = function () {
|
|
var self = this
|
|
, a = self.a
|
|
, b = self.b
|
|
|
|
if (b[getBoundingClientRect]()[dimension] < self.bMin) {
|
|
a.style[dimension] = (self.size - self.bMin - self.bGutterSize) + 'px'
|
|
b.style[dimension] = (self.bMin - self.bGutterSize) + 'px'
|
|
} else if (a[getBoundingClientRect]()[dimension] < self.aMin) {
|
|
a.style[dimension] = (self.aMin - self.aGutterSize) + 'px'
|
|
b.style[dimension] = (self.size - self.aMin - self.aGutterSize) + 'px'
|
|
}
|
|
}
|
|
, balancePairs = function (pairs) {
|
|
for (var i = 0; i < pairs.length; i++) {
|
|
calculateSizes.call(pairs[i])
|
|
fitMin.call(pairs[i])
|
|
}
|
|
|
|
for (i = pairs.length - 1; i >= 0; i--) {
|
|
calculateSizes.call(pairs[i])
|
|
fitMinReverse.call(pairs[i])
|
|
}
|
|
}
|
|
, preventSelection = function () { return false }
|
|
, parent = elementOrSelector(ids[0]).parentNode
|
|
|
|
if (!options.sizes) {
|
|
var percent = 100 / ids.length
|
|
|
|
options.sizes = []
|
|
|
|
for (i = 0; i < ids.length; i++) {
|
|
options.sizes.push(percent)
|
|
}
|
|
}
|
|
|
|
if (!Array.isArray(options.minSize)) {
|
|
var minSizes = []
|
|
|
|
for (i = 0; i < ids.length; i++) {
|
|
minSizes.push(options.minSize)
|
|
}
|
|
|
|
options.minSize = minSizes
|
|
}
|
|
|
|
for (i = 0; i < ids.length; i++) {
|
|
var el = elementOrSelector(ids[i])
|
|
, isFirst = (i == 1)
|
|
, isLast = (i == ids.length - 1)
|
|
, size
|
|
, gutterSize = options.gutterSize
|
|
, pair
|
|
|
|
if (i > 0) {
|
|
pair = {
|
|
a: elementOrSelector(ids[i - 1]),
|
|
b: el,
|
|
aMin: options.minSize[i - 1],
|
|
bMin: options.minSize[i],
|
|
dragging: false,
|
|
parent: parent,
|
|
isFirst: isFirst,
|
|
isLast: isLast,
|
|
direction: options.direction
|
|
}
|
|
|
|
// For first and last pairs, first and last gutter width is half.
|
|
|
|
pair.aGutterSize = options.gutterSize
|
|
pair.bGutterSize = options.gutterSize
|
|
|
|
if (isFirst) {
|
|
pair.aGutterSize = options.gutterSize / 2
|
|
}
|
|
|
|
if (isLast) {
|
|
pair.bGutterSize = options.gutterSize / 2
|
|
}
|
|
}
|
|
|
|
// IE9 and above
|
|
if (!isIE8) {
|
|
if (i > 0) {
|
|
var gutter = document.createElement('div')
|
|
|
|
gutter.className = gutterClass
|
|
gutter.style[dimension] = options.gutterSize + 'px'
|
|
|
|
gutter[addEventListener]('mousedown', startDragging.bind(pair))
|
|
gutter[addEventListener]('touchstart', startDragging.bind(pair))
|
|
|
|
parent.insertBefore(gutter, el)
|
|
|
|
pair.gutter = gutter
|
|
}
|
|
|
|
if (i === 0 || i == ids.length - 1) {
|
|
gutterSize = options.gutterSize / 2
|
|
}
|
|
|
|
if (typeof options.sizes[i] === 'string' || options.sizes[i] instanceof String) {
|
|
size = options.sizes[i]
|
|
} else {
|
|
size = calc + '(' + options.sizes[i] + '% - ' + gutterSize + 'px)'
|
|
}
|
|
|
|
// IE8 and below
|
|
} else {
|
|
if (typeof options.sizes[i] === 'string' || options.sizes[i] instanceof String) {
|
|
size = options.sizes[i]
|
|
} else {
|
|
size = options.sizes[i] + '%'
|
|
}
|
|
}
|
|
|
|
el.style[dimension] = size
|
|
|
|
if (i > 0) {
|
|
pairs.push(pair)
|
|
}
|
|
}
|
|
|
|
balancePairs(pairs)
|
|
}
|
|
|
|
if (typeof exports !== 'undefined') {
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
exports = module.exports = Split
|
|
}
|
|
exports.Split = Split
|
|
} else {
|
|
global.Split = Split
|
|
}
|
|
|
|
}).call(window); |