Skip to content

Commit

Permalink
Avoid flicker when highlighting a section
Browse files Browse the repository at this point in the history
Previously, elements were wrapped in a div on hover and unwrapped when
the mouse was moved again. This generally worked okay, but led to
problems where the wrapped section contained elements with their own
rendering context (video, object, iframe, ...). The wrapping caused
rerendering of these elements resulting in flicker and layoutshift:

splitbrain/dokuwiki-plugin-vshare#13
cosmocode/dokuwiki-plugin-diagrams#4

This patch changes the higlighting mechanism to always wrap *all*
sections in a div and only toggle classes on hover. Class names have
been chosen to be backwardscompatible, so this should continue to work
as before in all templates.
  • Loading branch information
splitbrain committed Apr 20, 2023
1 parent 91a2586 commit 2e60bae
Showing 1 changed file with 25 additions and 17 deletions.
42 changes: 25 additions & 17 deletions lib/scripts/page.js
Expand Up @@ -21,29 +21,37 @@ dw_page = {
*/
sectionHighlight: function() {
jQuery('form.btn_secedit')
.on('mouseover', function(){
var $tgt = jQuery(this).parent(),
nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2],
$highlight = jQuery(), // holder for elements in the section to be highlighted
$highlightWrap = jQuery('<div class="section_highlight"></div>'); // section highlight wrapper
/*
* wrap the editable section in a div
*/
.each(function () {
let $tgt = jQuery(this).parent();
const nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2];
let $highlight = jQuery(); // holder for elements in the section to be highlighted
const $highlightWrap = jQuery('<div class="section_highlight_wrapper"></div>');

// the edit button should be part of the highlight
$highlight = $highlight.add($tgt);

// Walk the dom tree in reverse to find the sibling which is or contains the section edit marker
while($tgt.length > 0 && !($tgt.hasClass('sectionedit' + nr) || $tgt.find('.sectionedit' + nr).length)) {
while ($tgt.length > 0 && !($tgt.hasClass('sectionedit' + nr) || $tgt.find('.sectionedit' + nr).length)) {
$tgt = $tgt.prev();
$highlight = $highlight.add($tgt);
}
// insert the section highlight wrapper before the last element added to $highlight
$highlight.filter(':last').before($highlightWrap);
// and move the elements to be highlighted inside the section highlight wrapper
$highlight.detach().appendTo($highlightWrap);
// wrap the elements to be highlighted in the section highlight wrapper
$highlight.wrapAll($highlightWrap);
})
.on('mouseout', function(){
// find the section highlight wrapper...
var $highlightWrap = jQuery('.section_highlight');
// ...move its children in front of it (as siblings)...
$highlightWrap.before($highlightWrap.children().detach());
// ...and remove the section highlight wrapper
$highlightWrap.detach();
/*
* highlight the section
*/
.on('mouseover', function () {
jQuery(this).parents('.section_highlight_wrapper').addClass('section_highlight');
})
/*
* remove highlight
*/
.on('mouseout', function () {
jQuery(this).parents('.section_highlight_wrapper').removeClass('section_highlight');
});
},

Expand Down

1 comment on commit 2e60bae

@Nils98Ar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@splitbrain When will there be a release with this fix? The current release 2023-04-04a "Jack Jackrum" does not include it.

Please sign in to comment.