You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.2 KiB
193 lines
5.2 KiB
'use strict'; |
|
var attrs = ['top', 'left', 'right', 'bottom']; |
|
var inited; |
|
var elementComputedStyle = {}; |
|
var support; |
|
function getSupport() { |
|
if (!('CSS' in window) || typeof CSS.supports != 'function') { |
|
support = ''; |
|
} |
|
else if (CSS.supports('top: env(safe-area-inset-top)')) { |
|
support = 'env'; |
|
} |
|
else if (CSS.supports('top: constant(safe-area-inset-top)')) { |
|
support = 'constant'; |
|
} |
|
else { |
|
support = ''; |
|
} |
|
return support; |
|
} |
|
function init() { |
|
support = typeof support === 'string' ? support : getSupport(); |
|
if (!support) { |
|
attrs.forEach(function (attr) { |
|
elementComputedStyle[attr] = 0; |
|
}); |
|
return; |
|
} |
|
function setStyle(el, style) { |
|
var elStyle = el.style; |
|
Object.keys(style).forEach(function (key) { |
|
var val = style[key]; |
|
elStyle[key] = val; |
|
}); |
|
} |
|
var cbs = []; |
|
function parentReady(callback) { |
|
if (callback) { |
|
cbs.push(callback); |
|
} |
|
else { |
|
cbs.forEach(function (cb) { |
|
cb(); |
|
}); |
|
} |
|
} |
|
var passiveEvents = false; |
|
try { |
|
var opts = Object.defineProperty({}, 'passive', { |
|
get: function () { |
|
passiveEvents = { passive: true }; |
|
} |
|
}); |
|
window.addEventListener('test', null, opts); |
|
} |
|
catch (e) { |
|
} |
|
function addChild(parent, attr) { |
|
var a1 = document.createElement('div'); |
|
var a2 = document.createElement('div'); |
|
var a1Children = document.createElement('div'); |
|
var a2Children = document.createElement('div'); |
|
var W = 100; |
|
var MAX = 10000; |
|
var aStyle = { |
|
position: 'absolute', |
|
width: W + 'px', |
|
height: '200px', |
|
boxSizing: 'border-box', |
|
overflow: 'hidden', |
|
paddingBottom: support + "(safe-area-inset-" + attr + ")" |
|
}; |
|
setStyle(a1, aStyle); |
|
setStyle(a2, aStyle); |
|
setStyle(a1Children, { |
|
transition: '0s', |
|
animation: 'none', |
|
width: '400px', |
|
height: '400px' |
|
}); |
|
setStyle(a2Children, { |
|
transition: '0s', |
|
animation: 'none', |
|
width: '250%', |
|
height: '250%' |
|
}); |
|
a1.appendChild(a1Children); |
|
a2.appendChild(a2Children); |
|
parent.appendChild(a1); |
|
parent.appendChild(a2); |
|
parentReady(function () { |
|
a1.scrollTop = a2.scrollTop = MAX; |
|
var a1LastScrollTop = a1.scrollTop; |
|
var a2LastScrollTop = a2.scrollTop; |
|
function onScroll() { |
|
if (this.scrollTop === (this === a1 ? a1LastScrollTop : a2LastScrollTop)) { |
|
return; |
|
} |
|
a1.scrollTop = a2.scrollTop = MAX; |
|
a1LastScrollTop = a1.scrollTop; |
|
a2LastScrollTop = a2.scrollTop; |
|
attrChange(attr); |
|
} |
|
a1.addEventListener('scroll', onScroll, passiveEvents); |
|
a2.addEventListener('scroll', onScroll, passiveEvents); |
|
}); |
|
var computedStyle = getComputedStyle(a1); |
|
Object.defineProperty(elementComputedStyle, attr, { |
|
configurable: true, |
|
get: function () { |
|
return parseFloat(computedStyle.paddingBottom); |
|
} |
|
}); |
|
} |
|
var parentDiv = document.createElement('div'); |
|
setStyle(parentDiv, { |
|
position: 'absolute', |
|
left: '0', |
|
top: '0', |
|
width: '0', |
|
height: '0', |
|
zIndex: '-1', |
|
overflow: 'hidden', |
|
visibility: 'hidden', |
|
}); |
|
attrs.forEach(function (key) { |
|
addChild(parentDiv, key); |
|
}); |
|
document.body.appendChild(parentDiv); |
|
parentReady(); |
|
inited = true; |
|
} |
|
function getAttr(attr) { |
|
if (!inited) { |
|
init(); |
|
} |
|
return elementComputedStyle[attr]; |
|
} |
|
var changeAttrs = []; |
|
function attrChange(attr) { |
|
if (!changeAttrs.length) { |
|
setTimeout(function () { |
|
var style = {}; |
|
changeAttrs.forEach(function (attr) { |
|
style[attr] = elementComputedStyle[attr]; |
|
}); |
|
changeAttrs.length = 0; |
|
callbacks.forEach(function (callback) { |
|
callback(style); |
|
}); |
|
}, 0); |
|
} |
|
changeAttrs.push(attr); |
|
} |
|
var callbacks = []; |
|
function onChange(callback) { |
|
if (!getSupport()) { |
|
return; |
|
} |
|
if (!inited) { |
|
init(); |
|
} |
|
if (typeof callback === 'function') { |
|
callbacks.push(callback); |
|
} |
|
} |
|
function offChange(callback) { |
|
var index = callbacks.indexOf(callback); |
|
if (index >= 0) { |
|
callbacks.splice(index, 1); |
|
} |
|
} |
|
var safeAreaInsets = { |
|
get support() { |
|
return (typeof support === 'string' ? support : getSupport()).length != 0; |
|
}, |
|
get top() { |
|
return getAttr('top'); |
|
}, |
|
get left() { |
|
return getAttr('left'); |
|
}, |
|
get right() { |
|
return getAttr('right'); |
|
}, |
|
get bottom() { |
|
return getAttr('bottom'); |
|
}, |
|
onChange: onChange, |
|
offChange: offChange |
|
}; |
|
module.exports = safeAreaInsets; |
|
//# sourceMappingURL=index.js.map
|