MDL-79276 core: Auto close streaming elements in shutdown handler
This commit is contained in:
@@ -240,6 +240,9 @@ class core_shutdown_manager {
|
||||
}
|
||||
}
|
||||
|
||||
// Close the current streaming element if any.
|
||||
echo $OUTPUT->close_element_for_append();
|
||||
|
||||
// Print any closing buffered tags.
|
||||
if (!empty($CFG->closingtags)) {
|
||||
echo $CFG->closingtags;
|
||||
|
||||
+30
-12
@@ -600,6 +600,12 @@ class core_renderer extends renderer_base {
|
||||
/** @var custom_menu_item language The language menu if created */
|
||||
protected $language = null;
|
||||
|
||||
/** @var string The current selector for an element being streamed into */
|
||||
protected $currentselector = '';
|
||||
|
||||
/** @var string The current element tag which is being streamed into */
|
||||
protected $currentelement = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -5228,36 +5234,46 @@ EOD;
|
||||
*
|
||||
* @param string $selector where new content should be appended
|
||||
* @param string $element which contains the streamed content
|
||||
* @return string html to be written
|
||||
*/
|
||||
public function select_element_for_append(string $selector = '#region-main [role=main]', string $element = 'div') {
|
||||
|
||||
static $currentselector = '';
|
||||
static $currentelement = '';
|
||||
|
||||
if (!CLI_SCRIPT && !NO_OUTPUT_BUFFERING) {
|
||||
throw new coding_exception('select_element_for_append used in a non-CLI script without setting NO_OUTPUT_BUFFERING.',
|
||||
DEBUG_DEVELOPER);
|
||||
}
|
||||
|
||||
// We are already streaming into this element so don't change anything.
|
||||
if ($currentselector === $selector && $currentelement === $element) {
|
||||
if ($this->currentselector === $selector && $this->currentelement === $element) {
|
||||
return;
|
||||
}
|
||||
|
||||
$html = '';
|
||||
// If we have a streaming element close it before starting a new one.
|
||||
$html = $this->close_element_for_append();
|
||||
|
||||
// We have a streaming element so close it before starting a new one.
|
||||
if ($currentselector !== '') {
|
||||
$html .= html_writer::end_tag($currentelement);
|
||||
}
|
||||
|
||||
$currentselector = $selector;
|
||||
$currentelement = $element;
|
||||
$this->currentselector = $selector;
|
||||
$this->currentelement = $element;
|
||||
|
||||
// Create an unclosed element for the streamed content to append into.
|
||||
$id = uniqid();
|
||||
$html .= html_writer::start_tag($element, ['id' => $id]);
|
||||
$html .= html_writer::tag('script', "document.querySelector('$selector').append(document.getElementById('$id'))");
|
||||
$html .= "\n";
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* This closes any opened stream elements
|
||||
*
|
||||
* @return string html to be written
|
||||
*/
|
||||
public function close_element_for_append() {
|
||||
$html = '';
|
||||
if ($this->currentselector !== '') {
|
||||
$html .= html_writer::end_tag($this->currentelement);
|
||||
$html .= "\n";
|
||||
$this->currentelement = '';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
@@ -5274,6 +5290,7 @@ EOD;
|
||||
* @param string $selector where new content should be replaced
|
||||
* @param string $html A chunk of well formed html
|
||||
* @param bool $outer Wether it replaces the innerHTML or the outerHTML
|
||||
* @return string html to be written
|
||||
*/
|
||||
public function select_element_for_replace(string $selector, string $html, bool $outer = false) {
|
||||
|
||||
@@ -5286,6 +5303,7 @@ EOD;
|
||||
$html = addslashes_js($html);
|
||||
$property = $outer ? 'outerHTML' : 'innerHTML';
|
||||
$output = html_writer::tag('script', "document.querySelector('$selector').$property = '$html';");
|
||||
$output .= "\n";
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user