Skip to content
Merged
40 changes: 19 additions & 21 deletions src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,29 +72,22 @@ export function init(id, invoke) {
filterCallback(v);
});

const module = registerBootstrapBlazorModule('AutoComplete', {
hooked: false,
registerCloseDropdownHandler: function () {
if (this.hooked === false) {
this.hooked = true;

EventHandler.on(document, 'click', e => {
[...document.querySelectorAll('.auto-complete.show')].forEach(a => {
const ac = e.target.closest('.auto-complete');
if (ac === a) {
return;
}

const el = a.querySelector('[data-bs-toggle="bb.dropdown"]');
if (el === null) {
a.classList.remove('show');
}
});
});
ac.closePopover = e => {
[...document.querySelectorAll('.auto-complete.show')].forEach(a => {
const ac = e.target.closest('.auto-complete');
if (ac === a) {
return;
}
}

const el = a.querySelector('[data-bs-toggle="bb.dropdown"]');
if (el === null) {
a.classList.remove('show');
}
});
}
registerBootstrapBlazorModule('AutoComplete', id, () => {
EventHandler.on(document, 'click', ac.closePopover);
});
module.registerCloseDropdownHandler();
}

const handlerKeyup = (ac, e) => {
Expand Down Expand Up @@ -168,6 +161,11 @@ export function dispose(id) {
EventHandler.off(input, 'blur');
Input.dispose(input);
}

const { AutoComplete } = window.BootstrapBlazor;
AutoComplete.dispose(id, () => {
EventHandler.off(document, 'click', ac.closePopover);
});
}

const scrollIntoView = (el, item) => {
Expand Down
30 changes: 10 additions & 20 deletions src/BootstrapBlazor/Components/Button/DialButton.razor.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,9 @@ export function init(id) {
EventHandler.on(button, 'click', () => {
toggle(el, list)
})

if (!window.bb_dial_button) {
window.bb_dial_button = true

EventHandler.on(document, 'click', e => closePopup(e));
}

const module = registerBootstrapBlazorModule('DialButton', {
hooked: false,
registerClosePopupHandler: function () {
if (this.hooked === false) {
this.hooked = true;

EventHandler.on(document, 'click', e => closePopup(e));
}
}
registerBootstrapBlazorModule('DialButton', id, () => {
EventHandler.on(document, 'click', closePopup);
});
module.registerClosePopupHandler();

}

export function update(id) {
Expand All @@ -56,9 +40,15 @@ export function dispose(id) {
Data.remove(id)

if (dial) {
EventHandler.off(dial.button, 'click')
EventHandler.off(dial.list, 'animationend')
const { button, list } = dial;
EventHandler.off(button, 'click')
EventHandler.off(list, 'animationend')
}

const { DialButton } = window.BootstrapBlazor;
DialButton.dispose(id, () => {
EventHandler.off(document, 'click', closePopup)
});
}

const toggle = (el, list) => {
Expand Down
40 changes: 13 additions & 27 deletions src/BootstrapBlazor/Components/Button/PopConfirmButton.razor.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getDescribedElement, getDescribedOwner, hackTooltip, hackPopover, isDisabled } from "../../modules/utility.js"
import { showTooltip, removeTooltip } from "./Button.razor.js"
import { getDescribedElement, getDescribedOwner, hackTooltip, hackPopover, isDisabled, registerBootstrapBlazorModule } from "../../modules/utility.js"
import Data from "../../modules/data.js"
import EventHandler from "../../modules/event-handler.js"
export { showTooltip, removeTooltip } from "./Button.razor.js"

const config = {
class: 'popover-confirm',
Expand Down Expand Up @@ -62,7 +62,7 @@ export function init(id) {
EventHandler.on(el, 'inserted.bs.popover', confirm.inserted)
EventHandler.on(el, 'hide.bs.popover', confirm.hide)

confirm.checkCancel = el => {
const checkCancel = el => {
// check button
let self = el === confirm.el || el.closest('.dropdown-toggle') === confirm.el
self = self && confirm.popover && confirm.popover._isShown()
Expand All @@ -74,7 +74,7 @@ export function init(id) {

confirm.closeConfirm = e => {
const el = e.target
if (!confirm.checkCancel(el)) {
if (!checkCancel(el)) {
document.querySelectorAll(config.popoverSelector).forEach(function (ele) {
const element = getDescribedOwner(ele)
if (element) {
Expand All @@ -87,17 +87,9 @@ export function init(id) {
}
}

if (!window.bb_confirm) {
window.bb_confirm = {
handle: false,
items: []
}
}
if (!window.bb_confirm.handle) {
window.bb_confirm.handle = true
registerBootstrapBlazorModule('PopConfirmButton', id, () => {
EventHandler.on(document, 'click', confirm.closeConfirm);
}
window.bb_confirm.items.push(id)
});
}

export function showConfirm(id) {
Expand Down Expand Up @@ -144,19 +136,13 @@ export function dispose(id) {
const confirm = Data.get(id)
Data.remove(id)

if (confirm) {
window.bb_confirm.items.pop(id)
if (window.bb_confirm.items.length === 0) {
delete window.bb_confirm
EventHandler.off(document, 'click', confirm.closeConfirm)
}
if (confirm.popover) {
confirm.popover.dispose();
}
const { popover } = confirm ?? {};
if (popover) {
popover.dispose();
}
}

export {
showTooltip,
removeTooltip
const { PopConfirmButton } = window.BootstrapBlazor;
PopConfirmButton.dispose(id, () => {
EventHandler.off(document, 'click', confirm.closeConfirm)
});
}
23 changes: 13 additions & 10 deletions src/BootstrapBlazor/Components/Button/SlideButton.razor.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Data from "../../modules/data.js"
import { registerBootstrapBlazorModule } from "../../modules/utility.js"
import Data from "../../modules/data.js"
import EventHandler from "../../modules/event-handler.js"

export function init(id) {
Expand All @@ -22,12 +23,9 @@ export function init(id) {
EventHandler.on(list, 'click', '.slide-item', e => {
list.classList.remove('show')
})

if (!window.bb_slide_button) {
window.bb_slide_button = true

EventHandler.on(document, 'click', e => closePopup(e));
}
registerBootstrapBlazorModule('SlideButton', id, () => {
EventHandler.on(document, 'click', closePopup)
});
}

export function update(id) {
Expand All @@ -42,10 +40,15 @@ export function dispose(id) {
Data.remove(id)

if (slide) {
EventHandler.off(slide.button, 'click')
EventHandler.off(slide.list, 'click', '.btn-close')
EventHandler.off(slide.list, 'click', '.slide-item')
const { button, list } = slide ?? {};
EventHandler.off(button, 'click');
EventHandler.off(list, 'click');
}

const { SlideButton } = window.BootstrapBlazor;
SlideButton.dispose(id, () => {
EventHandler.off(document, 'click', closePopup)
});
}

const reset = slide => {
Expand Down
3 changes: 3 additions & 0 deletions src/BootstrapBlazor/Components/Select/Select.razor.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,8 @@ export function dispose(id) {

if (select) {
unregisterSelect(select);
if (select.popover) {
Popover.dispose(select.popover);
}
}
}
39 changes: 21 additions & 18 deletions src/BootstrapBlazor/wwwroot/modules/base-popover.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getDescribedElement, getDescribedOwner, hackTooltip, hackPopover, isDisabled } from "./utility.js"
import { getDescribedElement, getDescribedOwner, hackTooltip, hackPopover, isDisabled, registerBootstrapBlazorModule } from "./utility.js"
import EventHandler from "./event-handler.js"

const Popover = {
Expand Down Expand Up @@ -131,7 +131,18 @@ const Popover = {
}
}

const closePopover = e => {

EventHandler.on(el, 'show.bs.popover', showPopover)
EventHandler.on(el, 'inserted.bs.popover', insertedPopover)
EventHandler.on(el, 'hide.bs.popover', hidePopover)
EventHandler.on(el, 'click', popover.toggleClass, active)
EventHandler.on(popover.toggleMenu, 'click', '.dropdown-item', e => {
if (popover.popover._config.autoClose !== 'outside') {
popover.hide()
}
})

popover.closePopover = e => {
const selector = `.${popover.class}.show`;
const el = e.target;
if (el.closest(selector)) {
Expand All @@ -150,22 +161,9 @@ const Popover = {
}
});
}

EventHandler.on(el, 'show.bs.popover', showPopover)
EventHandler.on(el, 'inserted.bs.popover', insertedPopover)
EventHandler.on(el, 'hide.bs.popover', hidePopover)
EventHandler.on(el, 'click', popover.toggleClass, active)
EventHandler.on(popover.toggleMenu, 'click', '.dropdown-item', e => {
if (popover.popover._config.autoClose !== 'outside') {
popover.hide()
}
})

if (!window.bb_dropdown) {
window.bb_dropdown = true

EventHandler.on(document, 'click', closePopover);
}
registerBootstrapBlazorModule('Popover', el, () => {
EventHandler.on(document, 'click', popover.closePopover);
});

// update handler
if (popover.toggleMenu) {
Expand Down Expand Up @@ -207,6 +205,11 @@ const Popover = {
EventHandler.off(popover.el, 'hide.bs.popover')
EventHandler.off(popover.el, 'click', '.dropdown-toggle')
EventHandler.off(popover.toggleMenu, 'click', '.dropdown-item')

const { Popover } = window.BootstrapBlazor;
Popover.dispose(popover, () => {
EventHandler.off(document, 'click', popover.closePopover);
});
}
else {
EventHandler.off(popover.el, 'show.bs.dropdown')
Expand Down
56 changes: 37 additions & 19 deletions src/BootstrapBlazor/wwwroot/modules/utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -571,23 +571,16 @@ const hackPopover = (popover, css) => {
}

const hackTooltip = function () {
const tooltip = registerBootstrapBlazorModule('Tooltip', {
hooked: false,
hackDispose: function () {
if (this.hooked === false) {
this.hooked = true;

const originalDispose = bootstrap.Tooltip.prototype.dispose;
bootstrap.Tooltip.prototype.dispose = function () {
originalDispose.call(this);
// fix https://github.com/twbs/bootstrap/issues/37474
this._activeTrigger = {};
this._element = document.createElement('noscript'); // placeholder with no behavior
}
}
const mock = () => {
const originalDispose = bootstrap.Tooltip.prototype.dispose;
bootstrap.Tooltip.prototype.dispose = function () {
originalDispose.call(this);
// fix https://github.com/twbs/bootstrap/issues/37474
this._activeTrigger = {};
this._element = document.createElement('noscript'); // placeholder with no behavior
}
});
tooltip.hackDispose();
}
registerBootstrapBlazorModule('Tooltip', null, mock);
}

const setIndeterminate = (object, state) => {
Expand Down Expand Up @@ -815,10 +808,35 @@ const deepMerge = (obj1, obj2, skipNull = true) => {
return obj1;
}

export function registerBootstrapBlazorModule(name, module) {
export function registerBootstrapBlazorModule(name, identifier, callback) {
window.BootstrapBlazor ??= {};
window.BootstrapBlazor[name] ??= deepMerge(window.BootstrapBlazor[name] ?? {}, module);
return window.BootstrapBlazor[name];
window.BootstrapBlazor[name] ??= {
_init: false,
_items: [],
register: function (identifier, callback) {
if (identifier) {
this._items.push(identifier);
}
if (this._init === false) {
this._init = true;
callback();
}
return this;
},
dispose: function (identifier, callback) {
if (identifier) {
const index = this._items.indexOf(identifier);
if (index > -1) {
this._items.splice(index, 1);
}
}
if (this._items.length === 0) {
callback();
}
}
};

return window.BootstrapBlazor[name].register(identifier, callback);
}

export function setTitle(title) {
Expand Down