(function(F){
const D = F.dom;
F.PopupWidget = function f(opt){
opt = F.mergeLastWins(f.defaultOptions,opt);
this.options = opt;
const e = this.e = D.addClass(D.div(), opt.cssClass,
"fossil-PopupWidget");
this.show(false);
if(opt.style){
let k;
for(k in opt.style){
if(opt.style.hasOwnProperty(k)) e.style[k] = opt.style[k];
}
}
D.append(document.body, e);
D.copyStyle(e, opt.style);
if(opt.init){
opt.init.call(this);
delete opt.init;
}
};
F.PopupWidget.defaultOptions = {
cssClass: 'fossil-tooltip',
style: undefined,
adjustX: (x)=>x,
adjustY: (y)=>y,
refresh: function(){},
init: undefined
};
F.PopupWidget.prototype = {
isShown: function(){return !this.e.classList.contains('hidden')},
refresh: function(){
if(this.options.refresh){
this.options.refresh.call(this);
}
return this;
},
show: function(){
var x = undefined, y = undefined, showIt,
wasShown = !this.e.classList.contains('hidden');
if(2===arguments.length){
x = arguments[0];
y = arguments[1];
showIt = true;
}else if(1===arguments.length){
if(arguments[0] instanceof HTMLElement){
const p = arguments[0];
const r = p.getBoundingClientRect();
x = r.x + r.x/5;
y = r.y - r.height/2;
showIt = true;
}else{
showIt = !!arguments[0];
}
}
if(showIt){
if(!wasShown) this.refresh();
x = this.options.adjustX.call(this,x);
y = this.options.adjustY.call(this,y);
x += window.pageXOffset;
y += window.pageYOffset;
}
if(showIt){
if('number'===typeof x && 'number'===typeof y){
this.e.style.left = x+"px";
this.e.style.top = y+"px";
}
D.removeClass(this.e, 'hidden');
}else{
D.addClass(this.e, 'hidden');
this.e.style.removeProperty('left');
this.e.style.removeProperty('top');
}
return this;
},
hide: function(){return this.show(false)},
installHideHandlers: function f(onClickSelf, onClickOther, onEsc){
if(!arguments.length) onClickSelf = onClickOther = onEsc = true;
else if(1===arguments.length) onClickOther = onEsc = true;
else if(2===arguments.length) onEsc = true;
if(onClickSelf) this.e.addEventListener('click', ()=>this.hide(), false);
if(onClickOther) document.body.addEventListener('click', ()=>this.hide(), true);
if(onEsc){
const self = this;
document.body.addEventListener('keydown', function(ev){
if(self.isShown() && 27===ev.which) self.hide();
}, true);
}
return this;
}
};
const toastImpl = function f(cssClass, durationMult, argsObject){
if(!f.toaster){
f.toaster = new F.PopupWidget({
cssClass: 'fossil-toast-message'
});
D.attr(f.toaster.e, 'role', 'alert');
}
const T = f.toaster;
if(f._timer) clearTimeout(f._timer);
D.clearElement(T.e);
if(f._prevCssClass) T.e.classList.remove(f._prevCssClass);
if(cssClass) T.e.classList.add(cssClass);
f._prevCssClass = cssClass;
D.append(T.e, Array.prototype.slice.call(argsObject,0));
T.show(F.toast.config.position.x, F.toast.config.position.y);
f._timer = setTimeout(
()=>T.hide(),
F.toast.config.displayTimeMs * durationMult
);
return F.toast;
};
F.toast = {
config: {
position: { x: 5, y: 5 },
displayTimeMs: 3000
},
message: function(){
return toastImpl(false,1, arguments);
},
warning: function(){
return toastImpl('warning',1.5,arguments);
},
error: function(){
return toastImpl('error',2,arguments);
}
};
F.helpButtonlets = {
setup: function f(){
if(!f.hasOwnProperty('clickHandler')){
f.clickHandler = function fch(ev){
ev.preventDefault();
ev.stopPropagation();
if(!fch.popup){
fch.popup = new F.PopupWidget({
cssClass: ['fossil-tooltip', 'help-buttonlet-content'],
refresh: function(){
}
});
fch.popup.e.style.maxWidth = '80%';
fch.popup.installHideHandlers();
}
D.append(D.clearElement(fch.popup.e), ev.target.$helpContent);
var popupRect, rectElem = ev.target;
while(rectElem){
popupRect = rectElem.getClientRects()[0];
if(popupRect) break;
rectElem = rectElem.parentNode;
}
if(!popupRect) popupRect = {x:0, y:0, left:0, right:0};
var x = popupRect.left, y = popupRect.top;
if(x<0) x = 0;
if(y<0) y = 0;
if(rectElem){
const rz = window.getComputedStyle(rectElem).zIndex;
var myZ;
if(rz && !isNaN(+rz)){
myZ = +rz + 1;
}else{
myZ = 10000;
}
fch.popup.e.style.zIndex = myZ;
}
fch.popup.show(x, y);
x = popupRect.left, y = popupRect.top;
popupRect = fch.popup.e.getBoundingClientRect();
const rectBody = document.body.getClientRects()[0];
if(popupRect.right > rectBody.right){
x -= (popupRect.right - rectBody.right);
}
if(x + popupRect.width > rectBody.right){
x = rectBody.x + (rectBody.width*0.1);
fch.popup.e.style.minWidth = '70%';
}else{
fch.popup.e.style.removeProperty('min-width');
x -= popupRect.width/2;
}
if(x<0) x = 0;
fch.popup.show(x, y);
return false;
};
f.foreachElement = function(e){
if(e.classList.contains('processed')) return;
e.classList.add('processed');
e.$helpContent = [];
e.childNodes.forEach((ch)=>e.$helpContent.push(ch));
e.$helpContent.forEach((ch)=>ch.remove());
e.addEventListener('click', f.clickHandler, false);
};
}
var elems;
if(!arguments.length){
arguments[0] = '.help-buttonlet:not(.processed)';
arguments.length = 1;
}
if(arguments.length){
if('string'===typeof arguments[0]){
elems = document.querySelectorAll(arguments[0]);
}else if(arguments[0] instanceof HTMLElement){
elems = [arguments[0]];
}else if(arguments[0].forEach){
elems = arguments[0];
}
}
if(elems) elems.forEach(f.foreachElement);
},
create: function(elem){
D.addClass(elem, 'help-buttonlet');
if(arguments.length>1){
const args = Array.prototype.slice.call(arguments,1);
D.append(elem, args);
}
this.setup(elem);
return elem;
}
};
F.onDOMContentLoaded( ()=>F.helpButtonlets.setup() );
})(window.fossil);