coupdoeil
Version:
Javascript for Ruby on Rails Coupdoeil gem
37 lines (29 loc) • 1.59 kB
JavaScript
import {getPopoverContentHTML, setPopoverContentHTML} from "./cache";
import {positionPopover} from "./positioning";
import {executeOnNextFrameIfStillOpening, fetchPopoverContent} from "./utils";
const MINIMUM_LAZY_DELAY = 600;
export function lazyLoadPopoverContent(controller, options) {
controller.coupdoeilElement.dataset.lazyLoading = "true"
// This delay ensures that popover won't blink if the actual content is quickly fetched.
// It also allows a consistent feeling for users across all lazy loaded popovers.
const lazyDelay = new Promise(resolve => setTimeout(resolve, MINIMUM_LAZY_DELAY))
fetchPopoverContent(controller).then(async (html) => {
// Wait for the delay if it is not resolved yet.
await lazyDelay
// Update popover content cache with the actual content,
// but doesn't update yet the rendered popover.
setPopoverContentHTML(controller, html)
delete controller.coupdoeilElement.dataset.lazyLoading
if (controller.card && !controller.closingRequest) {
// If popover has not been close are in the process of being closed,
// update its content with the newly fetch HTML.
controller.card.innerHTML = getPopoverContentHTML(controller)
// Since new content may change the rendered size of the popover,
// it must be positioned again. It is done one next frame so the browser has at least computed
// the new dimensions of the popover.
executeOnNextFrameIfStillOpening(controller, () => {
positionPopover(controller.coupdoeilElement, controller.card, options)
})
}
})
}