From 590d56dbb355a499b2f59d9a6ffa4887ea33c96b Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Tue, 17 Dec 2019 16:34:11 -0500 Subject: switch to fomantic-ui (#9374) --- web_src/js/index.js | 7 +- web_src/js/semanticDropdown.js | 635 +++++++++++++++++++++++++++++------------ 2 files changed, 462 insertions(+), 180 deletions(-) (limited to 'web_src/js') diff --git a/web_src/js/index.js b/web_src/js/index.js index b35f806598..8600acc95c 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -3252,7 +3252,10 @@ function initTopicbar() { const last = viewDiv.children('a').last(); for (let i = 0; i < topicArray.length; i++) { - $(`${topicArray[i]}`).insertBefore(last); + const link = $(''); + link.attr('href', `${suburl}/explore/repos?q=${encodeURIComponent(topicArray[i])}&topic=1`); + link.text(topicArray[i]); + link.insertBefore(last); } } editDiv.css('display', 'none'); @@ -3298,7 +3301,7 @@ function initTopicbar() { label: 'ui small label' }, apiSettings: { - url: `${suburl}/api/v1/topics/search?q={query}`, + url: `${suburl}/api/v1/topics/search?q={encodeURIComponent(query)}`, throttle: 500, cache: false, onResponse(res) { diff --git a/web_src/js/semanticDropdown.js b/web_src/js/semanticDropdown.js index 353603ff44..14dcf63a81 100644 --- a/web_src/js/semanticDropdown.js +++ b/web_src/js/semanticDropdown.js @@ -2,8 +2,8 @@ https://github.com/go-gitea/gitea/pull/8638#issuecomment-549175290 */ /*! - * # Semantic UI 2.3.1 - Dropdown - * http://github.com/semantic-org/semantic-ui/ + * # Fomantic-UI - Dropdown + * http://github.com/fomantic/Fomantic-UI/ * * * Released under the MIT license @@ -22,6 +22,10 @@ 'use strict'; +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + window = (typeof window != 'undefined' && window.Math == Math) ? window : (typeof self != 'undefined' && self.Math == Math) @@ -75,6 +79,7 @@ $.fn.dropdown = function(parameters) { $sizer = $module.find(selector.sizer), $input = $module.find(selector.input), $icon = $module.find(selector.icon), + $clear = $module.find(selector.clearIcon), $combo = ($module.prev().find(selector.text).length > 0) ? $module.prev().find(selector.text) @@ -82,13 +87,16 @@ $.fn.dropdown = function(parameters) { $menu = $module.children(selector.menu), $item = $menu.find(selector.item), + $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $(), activated = false, itemActivated = false, internalChange = false, + iconClicked = false, element = this, instance = $module.data(moduleNamespace), + selectActionActive, initialLoad, pageLostFocus, willRefocus, @@ -108,6 +116,10 @@ $.fn.dropdown = function(parameters) { module.setup.reference(); } else { + if (settings.ignoreDiacritics && !String.prototype.normalize) { + settings.ignoreDiacritics = false; + module.error(error.noNormalize, element); + } module.setup.layout(); @@ -142,6 +154,9 @@ $.fn.dropdown = function(parameters) { destroy: function() { module.verbose('Destroying previous dropdown', $module); module.remove.tabbable(); + module.remove.active(); + $menu.transition('stop all'); + $menu.removeClass(className.visible).addClass(className.hidden); $module .off(eventNamespace) .removeData(moduleNamespace) @@ -180,7 +195,7 @@ $.fn.dropdown = function(parameters) { }, observe: { select: function() { - if(module.has.input()) { + if(module.has.input() && selectObserver) { selectObserver.observe($module[0], { childList : true, subtree : true @@ -188,7 +203,7 @@ $.fn.dropdown = function(parameters) { } }, menu: function() { - if(module.has.menu()) { + if(module.has.menu() && menuObserver) { menuObserver.observe($menu[0], { childList : true, subtree : true @@ -214,7 +229,7 @@ $.fn.dropdown = function(parameters) { if(!values) { return false; } - values = $.isArray(values) + values = Array.isArray(values) ? values : [values] ; @@ -276,7 +291,7 @@ $.fn.dropdown = function(parameters) { module.filter(query); } else { - module.hide(); + module.hide(null,true); } }, @@ -414,6 +429,13 @@ $.fn.dropdown = function(parameters) { if( !module.has.menu() ) { module.create.menu(); } + if ( module.is.selection() && module.is.clearable() && !module.has.clearItem() ) { + module.verbose('Adding clear icon'); + $clear = $('') + .addClass('remove icon') + .insertBefore($text) + ; + } if( module.is.search() && !module.has.search() ) { module.verbose('Adding search input'); $search = $('') @@ -454,7 +476,7 @@ $.fn.dropdown = function(parameters) { .attr('class', $input.attr('class') ) .addClass(className.selection) .addClass(className.dropdown) - .html( templates.dropdown(selectValues) ) + .html( templates.dropdown(selectValues, fields, settings.preserveHTML, settings.className) ) .insertBefore($input) ; if($input.hasClass(className.multiple) && $input.prop('multiple') === false) { @@ -469,6 +491,7 @@ $.fn.dropdown = function(parameters) { $module.addClass(className.disabled); } $input + .removeAttr('required') .removeAttr('class') .detach() .prependTo($module) @@ -477,8 +500,9 @@ $.fn.dropdown = function(parameters) { module.refresh(); }, menu: function(values) { - $menu.html( templates.menu(values, fields)); - $item = $menu.find(selector.item); + $menu.html( templates.menu(values, fields,settings.preserveHTML,settings.className)); + $item = $menu.find(selector.item); + $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $(); }, reference: function() { module.debug('Dropdown behavior was called on select, replacing with closest dropdown'); @@ -505,7 +529,8 @@ $.fn.dropdown = function(parameters) { }, refreshItems: function() { - $item = $menu.find(selector.item); + $item = $menu.find(selector.item); + $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $(); }, refreshSelectors: function() { @@ -520,6 +545,7 @@ $.fn.dropdown = function(parameters) { ; $menu = $module.children(selector.menu); $item = $menu.find(selector.item); + $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $(); }, refreshData: function() { @@ -553,7 +579,7 @@ $.fn.dropdown = function(parameters) { } }, - show: function(callback) { + show: function(callback, preventFocus) { callback = $.isFunction(callback) ? callback : function(){} @@ -577,7 +603,7 @@ $.fn.dropdown = function(parameters) { if( module.can.click() ) { module.bind.intent(); } - if(module.has.menuSearch()) { + if(module.has.search() && !preventFocus) { module.focusSearch(); } module.set.visible(); @@ -587,7 +613,7 @@ $.fn.dropdown = function(parameters) { } }, - hide: function(callback) { + hide: function(callback, preventBlur) { callback = $.isFunction(callback) ? callback : function(){} @@ -599,9 +625,15 @@ $.fn.dropdown = function(parameters) { module.aria.removeDescendant(); module.animate.hide(function() { module.remove.visible(); + // hidding search focus + if ( module.is.focusedOnSearch() && preventBlur !== true ) { + $search.blur(); + } callback.call(element); }); } + } else if( module.can.click() ) { + module.unbind.intent(); } }, @@ -689,6 +721,7 @@ $.fn.dropdown = function(parameters) { .on('mousedown' + eventNamespace, selector.menu, module.event.menu.mousedown) .on('mouseup' + eventNamespace, selector.menu, module.event.menu.mouseup) .on('click' + eventNamespace, selector.icon, module.event.icon.click) + .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click) .on('focus' + eventNamespace, selector.search, module.event.search.focus) .on('click' + eventNamespace, selector.search, module.event.search.focus) .on('blur' + eventNamespace, selector.search, module.event.search.blur) @@ -722,6 +755,7 @@ $.fn.dropdown = function(parameters) { .on('mousedown' + eventNamespace, module.event.mousedown) .on('mouseup' + eventNamespace, module.event.mouseup) .on('focus' + eventNamespace, module.event.focus) + .on('click' + eventNamespace, selector.clearIcon, module.event.clearIcon.click) ; if(module.has.menuSearch() ) { $module @@ -805,7 +839,7 @@ $.fn.dropdown = function(parameters) { module.remove.message(); } if(settings.allowAdditions) { - module.add.userSuggestion(query); + module.add.userSuggestion(module.escape.htmlEntities(query)); } if(module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() ) { module.show(); @@ -821,6 +855,15 @@ $.fn.dropdown = function(parameters) { if(settings.filterRemoteData) { module.filterItems(searchTerm); } + var preSelected = $input.val(); + if(!Array.isArray(preSelected)) { + preSelected = preSelected && preSelected!=="" ? preSelected.split(settings.delimiter) : []; + } + $.each(preSelected,function(index,value){ + $item.filter('[data-value="'+value+'"]') + .addClass(className.filtered) + ; + }); afterFiltered(); }); } @@ -852,10 +895,20 @@ $.fn.dropdown = function(parameters) { callback(); }, onSuccess : function(response) { + var + values = response[fields.remoteValues] + ; + if (!Array.isArray(values)){ + values = []; + } module.remove.message(); module.setup.menu({ - values: response[fields.remoteValues] + values: values }); + + if(values.length===0 && !settings.allowAdditions) { + module.add.message(message.noResults); + } callback(); } } @@ -872,12 +925,14 @@ $.fn.dropdown = function(parameters) { filterItems: function(query) { var - searchTerm = (query !== undefined) + searchTerm = module.remove.diacritics(query !== undefined ? query - : module.get.query(), + : module.get.query() + ), results = null, escapedTerm = module.escape.string(searchTerm), - beginsWithRegExp = new RegExp('^' + escapedTerm, 'igm') + regExpFlags = (settings.ignoreSearchCase ? 'i' : '') + 'gm', + beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags) ; // avoid loop if we're matching nothing if( module.has.query() ) { @@ -891,8 +946,8 @@ $.fn.dropdown = function(parameters) { text, value ; - if(settings.match == 'both' || settings.match == 'text') { - text = String(module.get.choiceText($choice, false)); + if(settings.match === 'both' || settings.match === 'text') { + text = module.remove.diacritics(String(module.get.choiceText($choice, false))); if(text.search(beginsWithRegExp) !== -1) { results.push(this); return true; @@ -906,8 +961,8 @@ $.fn.dropdown = function(parameters) { return true; } } - if(settings.match == 'both' || settings.match == 'value') { - value = String(module.get.choiceValue($choice, text)); + if(settings.match === 'both' || settings.match === 'value') { + value = module.remove.diacritics(String(module.get.choiceValue($choice, text))); if(value.search(beginsWithRegExp) !== -1) { results.push(this); return true; @@ -932,6 +987,30 @@ $.fn.dropdown = function(parameters) { .addClass(className.filtered) ; } + + if(!module.has.query()) { + $divider + .removeClass(className.hidden); + } else if(settings.hideDividers === true) { + $divider + .addClass(className.hidden); + } else if(settings.hideDividers === 'empty') { + $divider + .removeClass(className.hidden) + .filter(function() { + // First find the last divider in this divider group + // Dividers which are direct siblings are considered a group + var lastDivider = $(this).nextUntil(selector.item); + + return (lastDivider.length ? lastDivider : $(this)) + // Count all non-filtered items until the next divider (or end of the dropdown) + .nextUntil(selector.divider) + .filter(selector.item + ":not(." + className.filtered + ")") + // Hide divider if no items are found + .length === 0; + }) + .addClass(className.hidden); + } }, fuzzySearch: function(query, term) { @@ -939,8 +1018,8 @@ $.fn.dropdown = function(parameters) { termLength = term.length, queryLength = query.length ; - query = query.toLowerCase(); - term = term.toLowerCase(); + query = (settings.ignoreSearchCase ? query.toLowerCase() : query); + term = (settings.ignoreSearchCase ? term.toLowerCase() : term); if(queryLength > termLength) { return false; } @@ -961,12 +1040,10 @@ $.fn.dropdown = function(parameters) { return true; }, exactSearch: function (query, term) { - query = query.toLowerCase(); - term = term.toLowerCase(); - if(term.indexOf(query) > -1) { - return true; - } - return false; + query = (settings.ignoreSearchCase ? query.toLowerCase() : query); + term = (settings.ignoreSearchCase ? term.toLowerCase() : term); + return term.indexOf(query) > -1; + }, filterActive: function() { if(settings.useLabels) { @@ -989,6 +1066,12 @@ $.fn.dropdown = function(parameters) { } }, + blurSearch: function() { + if( module.has.search() ) { + $search.blur(); + } + }, + forceSelection: function() { var $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0), @@ -998,19 +1081,12 @@ $.fn.dropdown = function(parameters) { : $activeItem, hasSelected = ($selectedItem.length > 0) ; - if(hasSelected && !module.is.multiple()) { + if(settings.allowAdditions || (hasSelected && !module.is.multiple())) { module.debug('Forcing partial selection to selected item', $selectedItem); - module.event.item.click.call($selectedItem, {}, true); - return; + $selectedItem[0].click(); } else { - if(settings.allowAdditions) { - module.set.selected(module.get.query()); - module.remove.searchTerm(); - } - else { - module.remove.searchTerm(); - } + module.remove.searchTerm(); } }, @@ -1023,11 +1099,30 @@ $.fn.dropdown = function(parameters) { module.setup.menu({values: values}); $.each(values, function(index, item) { if(item.selected == true) { - module.debug('Setting initial selection to', item.value); - module.set.selected(item.value); - return true; + module.debug('Setting initial selection to', item[fields.value]); + module.set.selected(item[fields.value]); + if(!module.is.multiple()) { + return false; + } } }); + + if(module.has.selectInput()) { + module.disconnect.selectObserver(); + $input.html(''); + $input.append(''); + $.each(values, function(index, item) { + var + value = settings.templates.deQuote(item[fields.value]), + name = settings.templates.escape( + item[fields.name] || item[fields.value], + settings.preserveHTML + ) + ; + $input.append(''); + }); + module.observe.select(); + } } }, @@ -1084,12 +1179,12 @@ $.fn.dropdown = function(parameters) { } }, search: { - focus: function() { + focus: function(event) { activated = true; if(module.is.multiple()) { module.remove.activeLabel(); } - if(settings.showOnFocus) { + if(settings.showOnFocus || (event.type !== 'focus' && event.type !== 'focusin')) { module.search(); } }, @@ -1099,6 +1194,8 @@ $.fn.dropdown = function(parameters) { if(!itemActivated && !pageLostFocus) { if(settings.forceSelection) { module.forceSelection(); + } else if(!settings.allowAdditions){ + module.remove.searchTerm(); } module.hide(); } @@ -1106,9 +1203,32 @@ $.fn.dropdown = function(parameters) { willRefocus = false; } }, + clearIcon: { + click: function(event) { + module.clear(); + if(module.is.searchSelection()) { + module.remove.searchTerm(); + } + module.hide(); + event.stopPropagation(); + } + }, icon: { click: function(event) { - module.toggle(); + iconClicked=true; + if(module.has.search()) { + if(!module.is.active()) { + if(settings.showOnFocus){ + module.focusSearch(); + } else { + module.toggle(); + } + } else { + module.blurSearch(); + } + } else { + module.toggle(); + } } }, text: { @@ -1193,22 +1313,17 @@ $.fn.dropdown = function(parameters) { event.stopPropagation(); }, hide: function(event) { - module.determine.eventInModule(event, module.hide); + if(module.determine.eventInModule(event, module.hide)){ + if(element.id && $(event.target).attr('for') === element.id){ + event.preventDefault(); + } + } } }, select: { mutation: function(mutations) { module.debug(' values to placeholder text preserveHTML : true, // preserve html when selecting value @@ -3803,7 +4007,8 @@ $.fn.dropdown.settings = { forceSelection : true, // force a choice on blur with search selection allowAdditions : false, // whether multiple select should allow user added values - ignoreCase : false, // whether to consider values not matching in case to be the same + ignoreCase : false, // whether to consider case sensitivity when creating labels + ignoreSearchCase : true, // whether to consider case sensitivity when filtering items hideAdditions : true, // whether or not to hide special message prompting a user they can enter a value maxSelections : false, // When set to a number limits the number of selections to this count @@ -3822,6 +4027,8 @@ $.fn.dropdown.settings = { glyphWidth : 1.037, // widest glyph width in em (W is 1.037 em) used to calculate multiselect input width + headerDivider : true, // whether option headers should have an additional divider line underneath when converted from