130 lines
3.5 KiB
PHP
130 lines
3.5 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the PHPFlasher package.
|
|
* (c) Younes KHOUBZA <younes.khoubza@gmail.com>
|
|
*/
|
|
|
|
namespace Flasher\Prime\Response\Presenter;
|
|
|
|
use Flasher\Prime\Response\Response;
|
|
|
|
final class HtmlPresenter implements PresenterInterface
|
|
{
|
|
const FLASHER_FLASH_BAG_PLACE_HOLDER = 'FLASHER_FLASH_BAG_PLACE_HOLDER';
|
|
const HEAD_END_PLACE_HOLDER = '</head>';
|
|
const BODY_END_PLACE_HOLDER = '</body>';
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function render(Response $response)
|
|
{
|
|
$options = json_encode($response->toArray(true));
|
|
$context = $response->getContext();
|
|
|
|
if (isset($context['envelopes_only']) && true === $context['envelopes_only']) {
|
|
return $options;
|
|
}
|
|
|
|
$rootScript = $response->getRootScript();
|
|
$placeHolder = self::FLASHER_FLASH_BAG_PLACE_HOLDER;
|
|
$livewireListener = $this->getLivewireListenerScript();
|
|
|
|
return <<<JAVASCRIPT
|
|
<script type="text/javascript" class="flasher-js">
|
|
(function() {
|
|
var rootScript = '{$rootScript}';
|
|
var {$placeHolder} = {};
|
|
var options = mergeOptions({$options}, {$placeHolder});
|
|
|
|
function mergeOptions(first, second) {
|
|
return {
|
|
context: merge(first.context || {}, second.context || {}),
|
|
envelopes: merge(first.envelopes || [], second.envelopes || []),
|
|
options: merge(first.options || {}, second.options || {}),
|
|
scripts: merge(first.scripts || [], second.scripts || []),
|
|
styles: merge(first.styles || [], second.styles || []),
|
|
};
|
|
}
|
|
|
|
function merge(first, second) {
|
|
if (Array.isArray(first) && Array.isArray(second)) {
|
|
return first.concat(second).filter(function(item, index, array) {
|
|
return array.indexOf(item) === index;
|
|
});
|
|
}
|
|
|
|
return Object.assign({}, first, second);
|
|
}
|
|
|
|
function renderOptions(options) {
|
|
if(!window.hasOwnProperty('flasher')) {
|
|
console.error('Flasher is not loaded');
|
|
return;
|
|
}
|
|
|
|
requestAnimationFrame(function () {
|
|
window.flasher.render(options);
|
|
});
|
|
}
|
|
|
|
function render(options) {
|
|
if ('loading' !== document.readyState) {
|
|
renderOptions(options);
|
|
|
|
return;
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
renderOptions(options);
|
|
});
|
|
}
|
|
|
|
if (1 === document.querySelectorAll('script.flasher-js').length) {
|
|
document.addEventListener('flasher:render', function (event) {
|
|
render(event.detail);
|
|
});
|
|
|
|
{$livewireListener}
|
|
}
|
|
|
|
if (window.hasOwnProperty('flasher') || !rootScript || document.querySelector('script[src="' + rootScript + '"]')) {
|
|
render(options);
|
|
} else {
|
|
var tag = document.createElement('script');
|
|
tag.setAttribute('src', rootScript);
|
|
tag.setAttribute('type', 'text/javascript');
|
|
tag.onload = function () {
|
|
render(options);
|
|
};
|
|
|
|
document.head.appendChild(tag);
|
|
}
|
|
})();
|
|
</script>
|
|
JAVASCRIPT;
|
|
}
|
|
|
|
/**
|
|
* Generate the script for Livewire event handling.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function getLivewireListenerScript()
|
|
{
|
|
if (!class_exists('Livewire\LivewireManager')) {
|
|
return '';
|
|
}
|
|
|
|
return <<<JAVASCRIPT
|
|
document.addEventListener('livewire:navigating', function () {
|
|
var elements = document.querySelectorAll('.fl-no-cache');
|
|
for (var i = 0; i < elements.length; i++) {
|
|
elements[i].remove();
|
|
}
|
|
});
|
|
JAVASCRIPT;
|
|
}
|
|
}
|