From 0a725d6235092ca942e0970988e77deb7f4bc2bf Mon Sep 17 00:00:00 2001 From: Konstantin Sivakov Date: Tue, 11 Dec 2018 14:48:05 +0100 Subject: [PATCH] Rebuild frontend --- ckan/public/base/javascript/modules/autocomplete.min.js | 2 +- ckan/public/base/javascript/modules/image-upload.min.js | 3 ++- ckan/public/base/test/spec/modules/autocomplete.spec.min.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ckan/public/base/javascript/modules/autocomplete.min.js b/ckan/public/base/javascript/modules/autocomplete.min.js index daf775964c7..06219fb530b 100644 --- a/ckan/public/base/javascript/modules/autocomplete.min.js +++ b/ckan/public/base/javascript/modules/autocomplete.min.js @@ -6,4 +6,4 @@ $('.select2-choice',select2.container).on('click',function(){return false;});thi module._last=module.getCompletions(term,fn);},this.options.interval);$('.select2-search input',this._select2.dropdown).addClass('select2-active');}},formatResult:function(state,container,query){var term=this._lastTerm||null;if(container){container.attr('data-value',state.id);} return state.text.split(term).join(term&&term.bold());},formatNoMatches:function(term){return!term?this._('Start typing…'):this._('No matches found');},formatInputTooShort:function(term,min){return this.ngettext('Input is too short, must be at least one character','Input is too short, must be at least %(num)d characters',min);},formatTerm:function(term){term=jQuery.trim(term||'');return{id:term.replace(/,/g,'\u002C'),text:term};},formatInitialValue:function(element,callback){var value=jQuery.trim(element.val()||'');var formatted;if(this.options.tags){formatted=jQuery.map(value.split(","),this.formatTerm);}else{formatted=this.formatTerm(value);} if(typeof callback==='function'){callback(formatted);} -return formatted;},_onQuery:function(options){if(options){this.lookup(options.term,options.callback);}},_onKeydown:function(event){if(event.which===188){event.preventDefault();setTimeout(function(){var e=jQuery.Event("keydown",{which:13});jQuery(event.target).trigger(e);},10);}}};}); \ No newline at end of file +return formatted;},_onQuery:function(options){if(options){this.lookup(options.term,options.callback);}},_onKeydown:function(event){if(typeof event.key!=='undefined'?event.key===',':event.which===188){event.preventDefault();setTimeout(function(){var e=jQuery.Event("keydown",{which:13});jQuery(event.target).trigger(e);},10);}}};}); \ No newline at end of file diff --git a/ckan/public/base/javascript/modules/image-upload.min.js b/ckan/public/base/javascript/modules/image-upload.min.js index d1abf4878f3..439b03e49c6 100644 --- a/ckan/public/base/javascript/modules/image-upload.min.js +++ b/ckan/public/base/javascript/modules/image-upload.min.js @@ -3,7 +3,8 @@ this.field_clear=$('').appen this._('Link')+'').prop('title',this._('Link to a URL on the internet (you can also link to an API)')).on('click',this._onFromWeb).insertAfter(this.input);this.button_upload=$(''+''+ this._('Upload')+'').insertAfter(this.input);var removeText=this._('Remove');$('' +removeText+'').prop('title',removeText).on('click',this._onRemove).insertBefore(this.field_url_input);$('label[for="field-image-upload"]').text(options.upload_label||this._('Image'));this.input.on('mouseover',this._onInputMouseOver).on('mouseout',this._onInputMouseOut).on('change',this._onInputChange).prop('title',this._('Upload a file on your computer')).css('width',this.button_upload.outerWidth());this.fields=$('').add(this.button_upload).add(this.button_url).add(this.input).add(this.field_url).add(this.field_image);this.field_name.on('change',this._onModifyName);if(this.field_name.val()){this._nameIsDirty=true;} -if(options.is_url){this._showOnlyFieldUrl();this._updateUrlLabel(this._('URL'));}else if(options.is_upload){this._showOnlyFieldUrl();this.field_url_input.prop('readonly',true);var filename=this._fileNameFromUpload(this.field_url_input.val());this.field_url_input.val(filename);this._updateUrlLabel(this._('File'));}else{this._showOnlyButtons();}},_fileNameFromUpload:function(url){url=url.substring(0,(url.indexOf("#")===-1)?url.length:url.indexOf("#"));url=url.substring(0,(url.indexOf("?")===-1)?url.length:url.indexOf("?"));url=url.substring(url.lastIndexOf("/")+1,url.length);return url;},_updateUrlLabel:function(label_text){if(!this.is_data_resource){return;} +if(options.is_url){this._showOnlyFieldUrl();this._updateUrlLabel(this._('URL'));}else if(options.is_upload){this._showOnlyFieldUrl();this.field_url_input.prop('readonly',true);var filename=this._fileNameFromUpload(this.field_url_input.val());this.field_url_input.val(filename);this._updateUrlLabel(this._('File'));}else{this._showOnlyButtons();}},_fileNameFromUpload:function(url){if(/^\/base\/images/.test(url)){return url;} +url=url.substring(0,(url.indexOf("#")===-1)?url.length:url.indexOf("#"));url=url.substring(0,(url.indexOf("?")===-1)?url.length:url.indexOf("?"));url=url.substring(url.lastIndexOf("/")+1,url.length);return url;},_updateUrlLabel:function(label_text){if(!this.is_data_resource){return;} this.label_location.text(label_text);},_onFromWeb:function(){this._showOnlyFieldUrl();this.field_url_input.focus().on('blur',this._onFromWebBlur);if(this.options.is_upload){this.field_clear.val('true');} this._updateUrlLabel(this._('URL'));},_onRemove:function(){this._showOnlyButtons();this.field_url_input.val('');this.field_url_input.prop('readonly',false);this.field_clear.val('true');},_onInputChange:function(){var file_name=this.input.val().split(/^C:\\fakepath\\/).pop();this.field_url_input.val(file_name);this.field_url_input.prop('readonly',true);this.field_clear.val('');this._showOnlyFieldUrl();this._autoName(file_name);this._updateUrlLabel(this._('File'));},_showOnlyButtons:function(){this.fields.hide();this.button_upload.add(this.field_image).add(this.button_url).add(this.input).show();},_showOnlyFieldUrl:function(){this.fields.hide();this.field_url.show();},_onInputMouseOver:function(){this.button_upload.addClass('hover');},_onInputMouseOut:function(){this.button_upload.removeClass('hover');},_onModifyName:function(){this._nameIsDirty=true;},_onFromWebBlur:function(){var url=this.field_url_input.val().match(/([^\/]+)\/?$/) if(url){this._autoName(url.pop());}},_autoName:function(name){if(!this._nameIsDirty){this.field_name.val(name);}}};}); \ No newline at end of file diff --git a/ckan/public/base/test/spec/modules/autocomplete.spec.min.js b/ckan/public/base/test/spec/modules/autocomplete.spec.min.js index 71607121392..8c989d5bef3 100644 --- a/ckan/public/base/test/spec/modules/autocomplete.spec.min.js +++ b/ckan/public/base/test/spec/modules/autocomplete.spec.min.js @@ -1,2 +1,2 @@ describe('ckan.modules.AutocompleteModule()',function(){var Autocomplete=ckan.module.registry['autocomplete'];beforeEach(function(){if(jQuery.fn.select2){this.select2=sinon.stub(jQuery.fn,'select2');}else{this.select2=jQuery.fn.select2=sinon.stub().returns({data:sinon.stub().returns({on:sinon.stub()})});} -this.el=document.createElement('input');this.sandbox=ckan.sandbox();this.sandbox.body=this.fixture;this.module=new Autocomplete(this.el,{},this.sandbox);});afterEach(function(){this.module.teardown();if(this.select2.restore){this.select2.restore();}else{delete jQuery.fn.select2;}});describe('.initialize()',function(){it('should bind callback methods to the module',function(){var target=sinon.stub(jQuery,'proxyAll');this.module.initialize();assert.called(target);assert.calledWith(target,this.module,/_on/,/format/);target.restore();});it('should setup the autocomplete plugin',function(){var target=sinon.stub(this.module,'setupAutoComplete');this.module.initialize();assert.called(target);});});describe('.setupAutoComplete()',function(){it('should initialize the autocomplete plugin',function(){this.module.setupAutoComplete();assert.called(this.select2);assert.calledWith(this.select2,{width:'resolve',query:this.module._onQuery,dropdownCssClass:'',containerCssClass:'',formatResult:this.module.formatResult,formatNoMatches:this.module.formatNoMatches,formatInputTooShort:this.module.formatInputTooShort,createSearchChoice:this.module.formatTerm,initSelection:this.module.formatInitialValue});});it('should initialize the autocomplete plugin with a tags callback if options.tags is true',function(){this.module.options.tags=true;this.module.setupAutoComplete();assert.called(this.select2);assert.calledWith(this.select2,{width:'resolve',tags:this.module._onQuery,dropdownCssClass:'',containerCssClass:'',formatResult:this.module.formatResult,formatNoMatches:this.module.formatNoMatches,formatInputTooShort:this.module.formatInputTooShort,initSelection:this.module.formatInitialValue});it('should watch the keydown event on the select2 input');it('should allow a custom css class to be added to the dropdown',function(){this.module.options.dropdownClass='tags';this.module.setupAutoComplete();assert.called(this.select2);assert.calledWith(this.select2,{width:'resolve',tags:this.module._onQuery,dropdownCssClass:'tags',containerCssClass:'',formatResult:this.module.formatResult,formatNoMatches:this.module.formatNoMatches,formatInputTooShort:this.module.formatInputTooShort,initSelection:this.module.formatInitialValue});});it('should allow a custom css class to be added to the container',function(){this.module.options.containerClass='tags';this.module.setupAutoComplete();assert.called(this.select2);assert.calledWith(this.select2,{width:'resolve',tags:this.module._onQuery,dropdownCssClass:'',containerCssClass:'tags',formatResult:this.module.formatResult,formatNoMatches:this.module.formatNoMatches,formatInputTooShort:this.module.formatInputTooShort,initSelection:this.module.formatInitialValue});});});});describe('.getCompletions(term, fn)',function(){beforeEach(function(){this.term='term';this.module.options.source='http://example.com?term=?';this.target=sinon.stub(this.sandbox.client,'getCompletions');});it('should get the completions from the client',function(){this.module.getCompletions(this.term);assert.called(this.target);});it('should replace the last ? in the source url with the term',function(){this.module.getCompletions(this.term);assert.calledWith(this.target,'http://example.com?term=term');});it('should escape special characters in the term',function(){this.module.getCompletions('term with spaces');assert.calledWith(this.target,'http://example.com?term=term%20with%20spaces');});});describe('.lookup(term, fn)',function(){beforeEach(function(){sinon.stub(this.module,'getCompletions');this.target=sinon.spy();this.module.setupAutoComplete();});it('should set the _lastTerm property',function(){this.module.lookup('term',this.target);assert.equal(this.module._lastTerm,'term');});it('should call the fn immediately if there is no term',function(){this.module.lookup('',this.target);assert.called(this.target);assert.calledWith(this.target,{results:[]});});it('should debounce the request if there is a term');it('should cancel the last request');});describe('.formatResult(state)',function(){beforeEach(function(){this.module._lastTerm='term';});it('should return the string with the last term wrapped in bold tags',function(){var target=this.module.formatResult({id:'we have termites',text:'we have termites'});assert.equal(target,'we have termites');});it('should return the string with each instance of the term wrapped in bold tags',function(){var target=this.module.formatResult({id:'we have a termite terminology',text:'we have a termite terminology'});assert.equal(target,'we have a termite terminology');});it('should return the term if there is no last term saved',function(){delete this.module._lastTerm;var target=this.module.formatResult({id:'we have a termite terminology',text:'we have a termite terminology'});assert.equal(target,'we have a termite terminology');});});describe('.formatNoMatches(term)',function(){it('should return the no matches string if there is a term',function(){var target=this.module.formatNoMatches('term');assert.equal(target,'No matches found');});it('should return the empty string if there is no term',function(){var target=this.module.formatNoMatches('');assert.equal(target,'Start typing…');});});describe('.formatInputTooShort(term, min)',function(){it('should return the plural input too short string',function(){var target=this.module.formatInputTooShort('term',2);assert.equal(target,'Input is too short, must be at least 2 characters');});it('should return the singular input too short string',function(){var target=this.module.formatInputTooShort('term',1);assert.equal(target,'Input is too short, must be at least one character');});});describe('.formatTerm()',function(){it('should return an item object with id and text properties',function(){assert.deepEqual(this.module.formatTerm('test'),{id:'test',text:'test'});});it('should trim whitespace from the value',function(){assert.deepEqual(this.module.formatTerm(' test '),{id:'test',text:'test'});});it('should convert commas in ids into unicode characters',function(){assert.deepEqual(this.module.formatTerm('test, test'),{id:'test\u002C test',text:'test, test'});});});describe('.formatInitialValue(element, callback)',function(){beforeEach(function(){this.callback=sinon.spy();});it('should pass an item object with id and text properties into the callback',function(){var target=jQuery('');this.module.formatInitialValue(target,this.callback);assert.calledWith(this.callback,{id:'test',text:'test'});});it('should pass an array of properties into the callback if options.tags is true',function(){this.module.options.tags=true;var target=jQuery('',{value:"test, test"});this.module.formatInitialValue(target,this.callback);assert.calledWith(this.callback,[{id:'test',text:'test'},{id:'test',text:'test'}]);});it('should return the value if no callback is provided (to support select2 v2.1)',function(){var target=jQuery('');assert.deepEqual(this.module.formatInitialValue(target),{id:'test',text:'test'});});});describe('._onQuery(options)',function(){it('should lookup the current term with the callback',function(){var target=sinon.stub(this.module,'lookup');this.module._onQuery({term:'term',callback:'callback'});assert.called(target);assert.calledWith(target,'term','callback');});it('should do nothing if there is no options object',function(){var target=sinon.stub(this.module,'lookup');this.module._onQuery();assert.notCalled(target);});});describe('._onKeydown(event)',function(){beforeEach(function(){this.keyDownEvent=jQuery.Event("keydown",{which:188});this.fakeEvent={};this.clock=sinon.useFakeTimers();this.jQuery=sinon.stub(jQuery.fn,'init',jQuery.fn.init);this.Event=sinon.stub(jQuery,'Event').returns(this.fakeEvent);this.trigger=sinon.stub(jQuery.fn,'trigger');});afterEach(function(){this.clock.restore();this.jQuery.restore();this.Event.restore();this.trigger.restore();});it('should trigger fake "return" keypress if a comma is pressed',function(){this.module._onKeydown(this.keyDownEvent);this.clock.tick(100);assert.called(this.jQuery);assert.called(this.Event);assert.called(this.trigger);assert.calledWith(this.trigger,this.fakeEvent);});it('should do nothing if another key is pressed',function(){this.keyDownEvent.which=200;this.module._onKeydown(this.keyDownEvent);this.clock.tick(100);assert.notCalled(this.Event);});});}); \ No newline at end of file +this.el=document.createElement('input');this.sandbox=ckan.sandbox();this.sandbox.body=this.fixture;this.module=new Autocomplete(this.el,{},this.sandbox);});afterEach(function(){this.module.teardown();if(this.select2.restore){this.select2.restore();}else{delete jQuery.fn.select2;}});describe('.initialize()',function(){it('should bind callback methods to the module',function(){var target=sinon.stub(jQuery,'proxyAll');this.module.initialize();assert.called(target);assert.calledWith(target,this.module,/_on/,/format/);target.restore();});it('should setup the autocomplete plugin',function(){var target=sinon.stub(this.module,'setupAutoComplete');this.module.initialize();assert.called(target);});});describe('.setupAutoComplete()',function(){it('should initialize the autocomplete plugin',function(){this.module.setupAutoComplete();assert.called(this.select2);assert.calledWith(this.select2,{width:'resolve',query:this.module._onQuery,dropdownCssClass:'',containerCssClass:'',formatResult:this.module.formatResult,formatNoMatches:this.module.formatNoMatches,formatInputTooShort:this.module.formatInputTooShort,createSearchChoice:this.module.formatTerm,initSelection:this.module.formatInitialValue});});it('should initialize the autocomplete plugin with a tags callback if options.tags is true',function(){this.module.options.tags=true;this.module.setupAutoComplete();assert.called(this.select2);assert.calledWith(this.select2,{width:'resolve',tags:this.module._onQuery,dropdownCssClass:'',containerCssClass:'',formatResult:this.module.formatResult,formatNoMatches:this.module.formatNoMatches,formatInputTooShort:this.module.formatInputTooShort,initSelection:this.module.formatInitialValue});it('should watch the keydown event on the select2 input');it('should allow a custom css class to be added to the dropdown',function(){this.module.options.dropdownClass='tags';this.module.setupAutoComplete();assert.called(this.select2);assert.calledWith(this.select2,{width:'resolve',tags:this.module._onQuery,dropdownCssClass:'tags',containerCssClass:'',formatResult:this.module.formatResult,formatNoMatches:this.module.formatNoMatches,formatInputTooShort:this.module.formatInputTooShort,initSelection:this.module.formatInitialValue});});it('should allow a custom css class to be added to the container',function(){this.module.options.containerClass='tags';this.module.setupAutoComplete();assert.called(this.select2);assert.calledWith(this.select2,{width:'resolve',tags:this.module._onQuery,dropdownCssClass:'',containerCssClass:'tags',formatResult:this.module.formatResult,formatNoMatches:this.module.formatNoMatches,formatInputTooShort:this.module.formatInputTooShort,initSelection:this.module.formatInitialValue});});});});describe('.getCompletions(term, fn)',function(){beforeEach(function(){this.term='term';this.module.options.source='http://example.com?term=?';this.target=sinon.stub(this.sandbox.client,'getCompletions');});it('should get the completions from the client',function(){this.module.getCompletions(this.term);assert.called(this.target);});it('should replace the last ? in the source url with the term',function(){this.module.getCompletions(this.term);assert.calledWith(this.target,'http://example.com?term=term');});it('should escape special characters in the term',function(){this.module.getCompletions('term with spaces');assert.calledWith(this.target,'http://example.com?term=term%20with%20spaces');});});describe('.lookup(term, fn)',function(){beforeEach(function(){sinon.stub(this.module,'getCompletions');this.target=sinon.spy();this.module.setupAutoComplete();});it('should set the _lastTerm property',function(){this.module.lookup('term',this.target);assert.equal(this.module._lastTerm,'term');});it('should call the fn immediately if there is no term',function(){this.module.lookup('',this.target);assert.called(this.target);assert.calledWith(this.target,{results:[]});});it('should debounce the request if there is a term');it('should cancel the last request');});describe('.formatResult(state)',function(){beforeEach(function(){this.module._lastTerm='term';});it('should return the string with the last term wrapped in bold tags',function(){var target=this.module.formatResult({id:'we have termites',text:'we have termites'});assert.equal(target,'we have termites');});it('should return the string with each instance of the term wrapped in bold tags',function(){var target=this.module.formatResult({id:'we have a termite terminology',text:'we have a termite terminology'});assert.equal(target,'we have a termite terminology');});it('should return the term if there is no last term saved',function(){delete this.module._lastTerm;var target=this.module.formatResult({id:'we have a termite terminology',text:'we have a termite terminology'});assert.equal(target,'we have a termite terminology');});});describe('.formatNoMatches(term)',function(){it('should return the no matches string if there is a term',function(){var target=this.module.formatNoMatches('term');assert.equal(target,'No matches found');});it('should return the empty string if there is no term',function(){var target=this.module.formatNoMatches('');assert.equal(target,'Start typing…');});});describe('.formatInputTooShort(term, min)',function(){it('should return the plural input too short string',function(){var target=this.module.formatInputTooShort('term',2);assert.equal(target,'Input is too short, must be at least 2 characters');});it('should return the singular input too short string',function(){var target=this.module.formatInputTooShort('term',1);assert.equal(target,'Input is too short, must be at least one character');});});describe('.formatTerm()',function(){it('should return an item object with id and text properties',function(){assert.deepEqual(this.module.formatTerm('test'),{id:'test',text:'test'});});it('should trim whitespace from the value',function(){assert.deepEqual(this.module.formatTerm(' test '),{id:'test',text:'test'});});it('should convert commas in ids into unicode characters',function(){assert.deepEqual(this.module.formatTerm('test, test'),{id:'test\u002C test',text:'test, test'});});});describe('.formatInitialValue(element, callback)',function(){beforeEach(function(){this.callback=sinon.spy();});it('should pass an item object with id and text properties into the callback',function(){var target=jQuery('');this.module.formatInitialValue(target,this.callback);assert.calledWith(this.callback,{id:'test',text:'test'});});it('should pass an array of properties into the callback if options.tags is true',function(){this.module.options.tags=true;var target=jQuery('',{value:"test, test"});this.module.formatInitialValue(target,this.callback);assert.calledWith(this.callback,[{id:'test',text:'test'},{id:'test',text:'test'}]);});it('should return the value if no callback is provided (to support select2 v2.1)',function(){var target=jQuery('');assert.deepEqual(this.module.formatInitialValue(target),{id:'test',text:'test'});});});describe('._onQuery(options)',function(){it('should lookup the current term with the callback',function(){var target=sinon.stub(this.module,'lookup');this.module._onQuery({term:'term',callback:'callback'});assert.called(target);assert.calledWith(target,'term','callback');});it('should do nothing if there is no options object',function(){var target=sinon.stub(this.module,'lookup');this.module._onQuery();assert.notCalled(target);});});describe('._onKeydown(event)',function(){beforeEach(function(){this.keyDownEvent=jQuery.Event("keydown",{key:',',which:188});this.fakeEvent={};this.clock=sinon.useFakeTimers();this.jQuery=sinon.stub(jQuery.fn,'init',jQuery.fn.init);this.Event=sinon.stub(jQuery,'Event').returns(this.fakeEvent);this.trigger=sinon.stub(jQuery.fn,'trigger');});afterEach(function(){this.clock.restore();this.jQuery.restore();this.Event.restore();this.trigger.restore();});it('should trigger fake "return" keypress if a comma is pressed',function(){this.module._onKeydown(this.keyDownEvent);this.clock.tick(100);assert.called(this.jQuery);assert.called(this.Event);assert.called(this.trigger);assert.calledWith(this.trigger,this.fakeEvent);});it('should do nothing if another key is pressed',function(){this.keyDownEvent.key='╚';this.keyDownEvent.which=200;this.module._onKeydown(this.keyDownEvent);this.clock.tick(100);assert.notCalled(this.Event);});it('should do nothing if key is pressed which has the comma key-code but is not a comma',function(){this.keyDownEvent.key='ת';this.keyDownEvent.which=188;this.module._onKeydown(this.keyDownEvent);this.clock.tick(100);assert.notCalled(this.Event);});});}); \ No newline at end of file