Skip to content
Snippets Groups Projects
Commit 82181f6c authored by Eric Eastwood's avatar Eric Eastwood
Browse files

Fix note highlight being lost after real time update

parent 64e85fda
No related branches found
No related tags found
2 merge requests!14773Maxraab master patch 51809,!12098Fix note highlight being lost after real time update
Pipeline #
Loading
Loading
@@ -56,6 +56,7 @@ const normalizeNewlines = function(str) {
this.toggleCommitList = this.toggleCommitList.bind(this);
this.postComment = this.postComment.bind(this);
this.clearFlashWrapper = this.clearFlash.bind(this);
this.onHashChange = this.onHashChange.bind(this);
 
this.notes_url = notes_url;
this.note_ids = note_ids;
Loading
Loading
@@ -127,7 +128,9 @@ const normalizeNewlines = function(str) {
$(document).on('ajax:success', '.js-main-target-form', this.resetMainTargetForm);
$(document).on('ajax:complete', '.js-main-target-form', this.reenableTargetFormSubmitButton);
// when a key is clicked on the notes
return $(document).on('keydown', '.js-note-text', this.keydownNoteText);
$(document).on('keydown', '.js-note-text', this.keydownNoteText);
// When the URL fragment/hash has changed, `#note_xxx`
return $(window).on('hashchange', this.onHashChange);
};
 
Notes.prototype.cleanBinding = function() {
Loading
Loading
@@ -148,6 +151,7 @@ const normalizeNewlines = function(str) {
$(document).off('ajax:success', '.js-main-target-form');
$(document).off('ajax:success', '.js-discussion-note-form');
$(document).off('ajax:complete', '.js-main-target-form');
$(window).off('hashchange', this.onHashChange);
};
 
Notes.initCommentTypeToggle = function (form) {
Loading
Loading
@@ -298,8 +302,27 @@ const normalizeNewlines = function(str) {
Notes.prototype.setupNewNote = function($note) {
// Update datetime format on the recent note
gl.utils.localTimeAgo($note.find('.js-timeago'), false);
this.collapseLongCommitList();
this.taskList.init();
// This stops the note highlight, #note_xxx`, from being removed after real time update
// The `:target` selector does not re-evaluate after we replace element in the DOM
Notes.updateNoteTargetSelector($note);
this.$noteToCleanHighlight = $note;
};
Notes.prototype.onHashChange = function() {
if (this.$noteToCleanHighlight) {
Notes.updateNoteTargetSelector(this.$noteToCleanHighlight);
}
this.$noteToCleanHighlight = null;
};
Notes.updateNoteTargetSelector = function($note) {
const hash = gl.utils.getLocationHash();
$note.toggleClass('target', hash && $note.filter(`#${hash}`).length > 0);
};
 
/*
Loading
Loading
@@ -597,13 +620,12 @@ const normalizeNewlines = function(str) {
$noteEntityEl = $(noteEntity.html);
$noteEntityEl.addClass('fade-in-full');
this.revertNoteEditForm($targetNote);
gl.utils.localTimeAgo($('.js-timeago', $noteEntityEl));
$noteEntityEl.renderGFM();
$noteEntityEl.find('.js-task-list-container').taskList('enable');
// Find the note's `li` element by ID and replace it with the updated HTML
$note_li = $('.note-row-' + noteEntity.id);
 
$note_li.replaceWith($noteEntityEl);
this.setupNewNote($noteEntityEl);
 
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
gl.diffNotesCompileComponents();
Loading
Loading
Loading
Loading
@@ -126,6 +126,7 @@ import '~/notes';
const deferred = $.Deferred();
spyOn($, 'ajax').and.returnValue(deferred.promise());
spyOn(this.notes, 'revertNoteEditForm');
spyOn(this.notes, 'setupNewNote');
 
$('.js-comment-button').click();
deferred.resolve(noteEntity);
Loading
Loading
@@ -136,6 +137,46 @@ import '~/notes';
this.notes.updateNote(updatedNote, $targetNote);
 
expect(this.notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
expect(this.notes.setupNewNote).toHaveBeenCalled();
});
});
describe('updateNoteTargetSelector', () => {
const hash = 'note_foo';
let $note;
beforeEach(() => {
$note = $(`<div id="${hash}"></div>`);
spyOn($note, 'filter').and.callThrough();
spyOn($note, 'toggleClass').and.callThrough();
});
it('sets target when hash matches', () => {
spyOn(gl.utils, 'getLocationHash');
gl.utils.getLocationHash.and.returnValue(hash);
Notes.updateNoteTargetSelector($note);
expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
expect($note.toggleClass).toHaveBeenCalledWith('target', true);
});
it('unsets target when hash does not match', () => {
spyOn(gl.utils, 'getLocationHash');
gl.utils.getLocationHash.and.returnValue('note_doesnotexist');
Notes.updateNoteTargetSelector($note);
expect($note.toggleClass).toHaveBeenCalledWith('target', false);
});
it('unsets target when there is not a hash fragment anymore', () => {
spyOn(gl.utils, 'getLocationHash');
gl.utils.getLocationHash.and.returnValue(null);
Notes.updateNoteTargetSelector($note);
expect($note.toggleClass).toHaveBeenCalledWith('target', null);
});
});
 
Loading
Loading
@@ -189,9 +230,13 @@ import '~/notes';
Notes.isUpdatedNote.and.returnValue(true);
const $note = $('<div>');
$notesList.find.and.returnValue($note);
const $newNote = $(note.html);
Notes.animateUpdateNote.and.returnValue($newNote);
Notes.prototype.renderNote.call(notes, note, null, $notesList);
 
expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
});
 
describe('while editing', () => {
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment