From 1b63b3fea747127f5d90aea1b9908e96f96a90e0 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Fri, 20 Jan 2017 16:59:40 -0600 Subject: Fix DropLab in IE11 v1 Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/26785 --- app/assets/javascripts/droplab/droplab.js | 49 +++++++++++++--------- .../javascripts/extensions/custom_event.js.es6 | 12 ++++++ .../filtered_search_dropdown.js.es6 | 5 ++- .../unreleased/26785-fix-droplab-in-ie-11-v1.yml | 4 ++ 4 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 app/assets/javascripts/extensions/custom_event.js.es6 create mode 100644 changelogs/unreleased/26785-fix-droplab-in-ie-11-v1.yml diff --git a/app/assets/javascripts/droplab/droplab.js b/app/assets/javascripts/droplab/droplab.js index 6c6d650db3a..c79f0230951 100644 --- a/app/assets/javascripts/droplab/droplab.js +++ b/app/assets/javascripts/droplab/droplab.js @@ -62,6 +62,7 @@ var DropDown = function(list) { this.list = list; this.items = []; this.getItems(); + this.initTemplateString(); this.addEvents(); this.initialState = list.innerHTML; }; @@ -72,6 +73,17 @@ Object.assign(DropDown.prototype, { return this.items; }, + initTemplateString: function() { + var items = this.items || this.getItems(); + + var templateString = ''; + if(items.length > 0) { + templateString = items[items.length - 1].outerHTML; + } + this.templateString = templateString; + return this.templateString; + }, + clickEvent: function(e) { // climb up the tree to find the LI var selected = utils.closest(e.target, 'LI'); @@ -111,30 +123,21 @@ Object.assign(DropDown.prototype, { addData: function(data) { this.data = (this.data || []).concat(data); - this.render(data); + this.render(this.data); }, // call render manually on data; render: function(data){ // debugger // empty the list first - var sampleItem; + var templateString = this.templateString; var newChildren = []; var toAppend; - for(var i = 0; i < this.items.length; i++) { - var item = this.items[i]; - sampleItem = item; - if(item.parentNode && item.parentNode.dataset.hasOwnProperty('dynamic')) { - item.parentNode.removeChild(item); - } - } - - newChildren = this.data.map(function(dat){ - var html = utils.t(sampleItem.outerHTML, dat); + newChildren = (data ||[]).map(function(dat){ + var html = utils.t(templateString, dat); var template = document.createElement('div'); template.innerHTML = html; - // console.log(template.content) // Help set the image src template var imageTags = template.querySelectorAll('img[data-src]'); @@ -173,10 +176,7 @@ Object.assign(DropDown.prototype, { }, destroy: function() { - if (!this.hidden) { - this.hide(); - } - + this.hide(); this.list.removeEventListener('click', this.clickWrapper); } }); @@ -462,6 +462,8 @@ Object.assign(HookInput.prototype, { var self = this; this.mousedown = function mousedown(e) { + if(self.hasRemovedEvents) return; + var mouseEvent = new CustomEvent('mousedown.dl', { detail: { hook: self, @@ -474,6 +476,8 @@ Object.assign(HookInput.prototype, { } this.input = function input(e) { + if(self.hasRemovedEvents) return; + var inputEvent = new CustomEvent('input.dl', { detail: { hook: self, @@ -487,10 +491,14 @@ Object.assign(HookInput.prototype, { } this.keyup = function keyup(e) { + if(self.hasRemovedEvents) return; + keyEvent(e, 'keyup.dl'); } this.keydown = function keydown(e) { + if(self.hasRemovedEvents) return; + keyEvent(e, 'keydown.dl'); } @@ -520,7 +528,8 @@ Object.assign(HookInput.prototype, { this.trigger.addEventListener('keydown', this.keydown); }, - removeEvents: function(){ + removeEvents: function() { + this.hasRemovedEvents = true; this.trigger.removeEventListener('mousedown', this.mousedown); this.trigger.removeEventListener('input', this.input); this.trigger.removeEventListener('keyup', this.keyup); @@ -668,14 +677,14 @@ var camelize = function(str) { }; var closest = function(thisTag, stopTag) { - while(thisTag.tagName !== stopTag && thisTag.tagName !== 'HTML'){ + while(thisTag && thisTag.tagName !== stopTag && thisTag.tagName !== 'HTML'){ thisTag = thisTag.parentNode; } return thisTag; }; var isDropDownParts = function(target) { - if(target.tagName === 'HTML') { return false; } + if(!target || target.tagName === 'HTML') { return false; } return ( target.hasAttribute(DATA_TRIGGER) || target.hasAttribute(DATA_DROPDOWN) diff --git a/app/assets/javascripts/extensions/custom_event.js.es6 b/app/assets/javascripts/extensions/custom_event.js.es6 new file mode 100644 index 00000000000..abedae4c1c7 --- /dev/null +++ b/app/assets/javascripts/extensions/custom_event.js.es6 @@ -0,0 +1,12 @@ +/* global CustomEvent */ +/* eslint-disable no-global-assign */ + +// Custom event support for IE +CustomEvent = function CustomEvent(event, parameters) { + const params = parameters || { bubbles: false, cancelable: false, detail: undefined }; + const evt = document.createEvent('CustomEvent'); + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + return evt; +}; + +CustomEvent.prototype = window.Event.prototype; diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 index 886d8113f4a..9128ea907b3 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 @@ -78,7 +78,10 @@ dispatchInputEvent() { // Propogate input change to FilteredSearchDropdownManager // so that it can determine which dropdowns to open - this.input.dispatchEvent(new Event('input')); + this.input.dispatchEvent(new CustomEvent('input', { + bubbles: true, + cancelable: true, + })); } hideDropdown() { diff --git a/changelogs/unreleased/26785-fix-droplab-in-ie-11-v1.yml b/changelogs/unreleased/26785-fix-droplab-in-ie-11-v1.yml new file mode 100644 index 00000000000..76e9b19b828 --- /dev/null +++ b/changelogs/unreleased/26785-fix-droplab-in-ie-11-v1.yml @@ -0,0 +1,4 @@ +--- +title: Add some basic fixes for IE11/Edge +merge_request: +author: -- cgit v1.2.1