diff --git a/.appveyor.yml b/.appveyor.yml index 4eb5e3eab562f37d8297902c541e44f5c17768c8..b1b20c933b0d9adaa1d8cbca813c2afd0ef3174d 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -65,7 +65,6 @@ install: - set PATH=%APPDATA%\npm;%PATH% - npm -g install xo - npm install --quiet - - bower install test_script: - xo diff --git a/gui/slick/js/lib/formwizard.js b/gui/slick/js/lib/formwizard.js index d92e33394c58175a45357aea36180815c10f57d7..45ea41a0a9c859a8159cab0812e4d9044d7123a1 100644 --- a/gui/slick/js/lib/formwizard.js +++ b/gui/slick/js/lib/formwizard.js @@ -1,202 +1,253 @@ -/*jQuery Form to Form Wizard (Initial: Oct 1st, 2010) -* This notice must stay intact for usage -* Author: Dynamic Drive at http://www.dynamicdrive.com/ -* Visit http://www.dynamicdrive.com/ for full source code +/* JQuery Form to Form Wizard (Initial: Oct 1st, 2010) +* This notice must stay intact for usage +* Author: Dynamic Drive at http://www.dynamicdrive.com/ +* Visit http://www.dynamicdrive.com/ for full source code */ -//Oct 21st, 2010: Script updated to v1.1, which adds basic form validation functionality, triggered each time the user goes from one page to the next, or tries to submit the form. - -//jQuery.noConflict() - - -function formtowizard(options){ - this.setting=jQuery.extend({persistsection:false, revealfx:['slide', 500], oninit:function(){}, onpagechangestart:function(){}}, options); - this.currentsection=-1; +const formtowizard = function(options) { + this.setting = jQuery.extend({ + persistsection: false, + revealfx: ['slide', 500], + oninit: function() {}, + onpagechangestart: function() {} + }, options); + this.currentsection = -1; this.init(this.setting); -} - -formtowizard.prototype={ +}; - createfieldsets:function($theform, arr){ //reserved function for future version (dynamically wraps form elements with a fieldset element) - $theform.find('fieldset.sectionwrap').removeClass('sectionwrap'); //make sure no fieldsets carry 'sectionwrap' before proceeding - var $startelement=$theform.find(':first-child'); //reference first element inside form - for (var i=0; i<arr.length; i++){ //loop thru "break" elements - var $fieldsetelements=$startelement.nextUntil('#'+arr[i].breakafter+', *[name='+arr[i].breakafter+']').andSelf(); //reference all elements from start element to break element (nextUntil() is jQuery 1.4 function) - $fieldsetelements.add($fieldsetelements.next()).wrapAll('<fieldset class="sectionwrap" />'); //wrap these elements with fieldset element - $startelement=$theform.find('fieldset.sectionwrap').eq(i).prepend('<legend class="legendStep">'+arr[i].legend+'</legend>').next(); //increment startelement to begin at the end of the just inserted fieldset element +formtowizard.prototype = { + createfieldsets: function($theform, arr) { // Reserved function for future version (dynamically wraps form elements with a fieldset element) + $theform.find('fieldset.sectionwrap').removeClass('sectionwrap'); // Make sure no fieldsets carry 'sectionwrap' before proceeding + let $startelement = $theform.find(':first-child'); // Reference first element inside form + for (let i = 0; i < arr.length; i++) { // Loop thru "break" elements + const $fieldsetelements = $startelement.nextUntil('#' + arr[i].breakafter + ', *[name=' + arr[i].breakafter + ']').andSelf(); // Reference all elements from start element to break element (nextUntil() is jQuery 1.4 function) + $fieldsetelements.add($fieldsetelements.next()).wrapAll('<fieldset class="sectionwrap" />'); // Wrap these elements with fieldset element + $startelement = $theform.find('fieldset.sectionwrap').eq(i).prepend('<legend class="legendStep">' + arr[i].legend + '</legend>').next(); // Increment startelement to begin at the end of the just inserted fieldset element } }, - - loadsection:function(rawi, bypasshooks){ - var thiswizard=this; - //doload Boolean checks to see whether to load next section (true if bypasshooks param is true or onpagechangestart() event handler doesn't return false) - var doload=bypasshooks || this.setting.onpagechangestart(jQuery, this.currentsection, this.sections.$sections.eq(this.currentsection)); - doload=(doload===false)? false : true; //unless doload is explicitly false, set to true - if (!bypasshooks && this.setting.validate){ - var outcome=this.validate(this.currentsection); - if (outcome===false) doload=false; + loadsection: function(rawi, bypasshooks) { + const thiswizard = this; + // Doload Boolean checks to see whether to load next section (true if bypasshooks param is true or onpagechangestart() event handler doesn't return false) + let doload = bypasshooks || this.setting.onpagechangestart(jQuery, this.currentsection, this.sections.$sections.eq(this.currentsection)); + doload = doload !== false; // Unless doload is explicitly false, set to true + if (!bypasshooks && this.setting.validate) { + const outcome = this.validate(this.currentsection); + if (outcome === false) { + doload = false; + } } - var i=(rawi=="prev")? this.currentsection-1 : (rawi=="next")? this.currentsection+1 : parseInt(rawi); //get index of next section to show - i=(i<0)? this.sections.count-1 : (i>this.sections.count-1)? 0 : i; //make sure i doesn't exceed min/max limit - if (i<this.sections.count && doload){ //if next section to show isn't the same as the current section shown - this.$thesteps.eq(this.currentsection).addClass('disabledstep').end().eq(i).removeClass('disabledstep'); //dull current "step" text then highlight next "step" text - if (this.setting.revealfx[0]=="slide"){ - this.sections.$sections.css("visibility", "visible"); - this.sections.$outerwrapper.stop().animate({height: this.sections.$sections.eq(i).outerHeight()}, this.setting.revealfx[1]); //animate fieldset wrapper's height to accomodate next section's height - this.sections.$innerwrapper.stop().animate({left:-i*this.maxfieldsetwidth}, this.setting.revealfx[1], function(){ //slide next section into view - thiswizard.sections.$sections.each(function(thissec){ - if (thissec!=i) thiswizard.sections.$sections.eq(thissec).css("visibility", "hidden"); //hide fieldset sections currently not in veiw, so tabbing doesn't go to elements within them (and mess up layout) + // Get index of next section to show + let i = (rawi === 'prev') ? this.currentsection - 1 : (rawi === 'next') ? this.currentsection + 1 : parseInt(rawi, 10); + i = (i < 0) ? this.sections.count - 1 : (i > this.sections.count - 1) ? 0 : i; // Make sure i doesn't exceed min/max limit + if (i < this.sections.count && doload) { // If next section to show isn't the same as the current section shown + this.$thesteps.eq(this.currentsection).addClass('disabledstep').end().eq(i).removeClass('disabledstep'); // Dull current "step" text then highlight next "step" text + if (this.setting.revealfx[0] === 'slide') { + this.sections.$sections.css('visibility', 'visible'); + this.sections.$outerwrapper.stop().animate({height: this.sections.$sections.eq(i).outerHeight()}, this.setting.revealfx[1]); // Animate fieldset wrapper's height to accomodate next section's height + this.sections.$innerwrapper.stop().animate({left: -i * this.maxfieldsetwidth}, this.setting.revealfx[1], function() { // Slide next section into view + thiswizard.sections.$sections.each(function(thissec) { + // Hide fieldset sections currently not in veiw, so tabbing doesn't go to elements within them (and mess up layout) + if (thissec !== i) { + thiswizard.sections.$sections.eq(thissec).css('visibility', 'hidden'); + } }); }); - } else if (this.setting.revealfx[0]=="fade"){ //if fx is "fade" - this.sections.$sections.eq(this.currentsection).hide().end().eq(i).fadeIn(this.setting.revealfx[1], function(){ - if (document.all && this.style && this.style.removeAttribute) this.style.removeAttribute('filter'); //fix IE clearType problem + } else if (this.setting.revealfx[0] === 'fade') { // If fx is "fade" + this.sections.$sections.eq(this.currentsection).hide().end().eq(i).fadeIn(this.setting.revealfx[1], function() { + // Fix IE clearType problem + if (document.all && this.style && this.style.removeAttribute) { + this.style.removeAttribute('filter'); + } }); } else { this.sections.$sections.eq(this.currentsection).hide().end().eq(i).show(); } - this.paginatediv.$status.text("Page "+(i+1)+" of "+this.sections.count); //update current page status text + this.paginatediv.$status.text('Page ' + (i + 1) + ' of ' + this.sections.count); // Update current page status text this.paginatediv.$navlinks.css('visibility', 'visible'); - if (i===0) { //hide "prev" link + if (i === 0) { // Hide "prev" link this.paginatediv.$navlinks.eq(0).css('visibility', 'hidden'); - } else if (i==this.sections.count-1){ //hide "next" link + } else if (i === this.sections.count - 1) { // Hide "next" link this.paginatediv.$navlinks.eq(1).css('visibility', 'hidden'); } - if (this.setting.persistsection) formtowizard.routines.setCookie(this.setting.formid+"_persist", i); //enable persistence? - this.currentsection=i; - if(i === 0) setTimeout(function() { $('#nameToSearch').focus(); }, 250); + if (this.setting.persistsection) { + formtowizard.routines.setCookie(this.setting.formid + '_persist', i); + } // Enable persistence? + this.currentsection = i; + if (i === 0) { + setTimeout($('#nameToSearch').focus, 250); + } } }, + addvalidatefields: function() { + const $ = jQuery; + const setting = this.setting; + const theform = this.$theform.get(0); + let validatefields = []; + // Array of form element ids to validate + validatefields = setting.validate; + for (let i = 0; i < validatefields.length; i++) { + // Reference form element + const el = theform.elements[validatefields[i]]; + if (el) { + // Find fieldset.sectionwrap this form element belongs to + const $section = $(el).parents('fieldset.sectionwrap:eq(0)'); - addvalidatefields:function(){ - var $=jQuery, setting=this.setting, theform=this.$theform.get(0), validatefields=[]; - validatefields=setting.validate; //array of form element ids to validate - for (var i=0; i<validatefields.length; i++){ - var el=theform.elements[validatefields[i]]; //reference form element - if (el){ //if element is defined - var $section=$(el).parents('fieldset.sectionwrap:eq(0)'); //find fieldset.sectionwrap this form element belongs to - if ($section.length==1){ //if element is within a fieldset.sectionwrap element - $section.data('elements').push(el); //cache this element inside corresponding section + // If element is within a fieldset.sectionwrap element + if ($section.length === 1) { + // Cache this element inside corresponding section + $section.data('elements').push(el); } } } }, - - validate:function(section){ - var elements=this.sections.$sections.eq(section).data('elements'); //reference elements within this section that should be validated - var validated=true, invalidtext=["Please fill out the following fields:\n"]; - function invalidate(el){ - validated=false; - invalidtext.push("- "+ (el.id || el.name)); + validate: function(section) { + // Reference elements within this section that should be validated + const elements = this.sections.$sections.eq(section).data('elements'); + const invalidtext = [_('Please fill out the following fields:\n')]; + let validated = true; + function invalidate(el) { + validated = false; + invalidtext.push('- ' + (el.id || el.name)); } - for (var i=0; i<elements.length; i++){ - if (/(text)/.test(elements[i].type) && elements[i].value===""){ //text and textarea elements + for (let i = 0; i < elements.length; i++) { + if (/(text)/.test(elements[i].type) && elements[i].value === '') { // Text and textarea elements invalidate(elements[i]); - } - else if (/(select)/.test(elements[i].type) && (elements[i].selectedIndex==-1 || elements[i].options[elements[i].selectedIndex].text==="")){ //select elements + } else if (/(select)/.test(elements[i].type) && (elements[i].selectedIndex === -1 || elements[i].options[elements[i].selectedIndex].text === '')) { // Select elements invalidate(elements[i]); - } - else if (elements[i].type===undefined && elements[i].length>0){ //radio and checkbox elements - var onechecked=false; - for (var r=0; r<elements[i].length; r++){ - if (elements[i][r].checked===true){ - onechecked=true; + } else if (elements[i].type === undefined && elements[i].length > 0) { // Radio and checkbox elements + let onechecked = false; + for (let r = 0; r < elements[i].length; r++) { + if (elements[i][r].checked === true) { + onechecked = true; break; } } - if (!onechecked){ + if (!onechecked) { invalidate(elements[i][0]); } } } - if (!validated) - alert(invalidtext.join('\n')); + if (!validated) { + alert(invalidtext.join('\n')); // eslint-disable-line no-alert + } return validated; }, + init: function(setting) { + const thiswizard = this; + jQuery(function($) { + let $theform = $('#' + setting.formid); - init:function(setting){ - var thiswizard=this; - jQuery(function($){ //on document.ready - var $theform=$('#'+setting.formid); - if ($theform.length===0) $theform=$('form[name='+setting.formid+']'); //if form with specified ID doesn't exist, try name attribute instead - if (setting.manualfieldsets && setting.manualfieldsets.length>0) thiswizard.createfieldsets($theform, setting.manualfieldsets); - var $stepsguide=$('<div class="stepsguide" />'); //create Steps Container to house the "steps" text - var $sections=$theform.find('fieldset.sectionwrap').hide(); //find all fieldset elements within form and hide them initially - if (setting.revealfx[0]=="slide"){ //create outer DIV that will house all the fieldset.sectionwrap elements - $sectionswrapper=$('<div style="position:relative;overflow:hidden;"></div>').insertBefore($sections.eq(0)); //add DIV above the first fieldset.sectionwrap element - $sectionswrapper_inner=$('<div style="position:absolute;left:0;top:0;"></div>'); //create inner DIV of $sectionswrapper that will scroll to reveal a fieldset element + // If form with specified ID doesn't exist, try name attribute instead + if ($theform.length === 0) { + $theform = $('form[name=' + setting.formid + ']'); + } + if (setting.manualfieldsets && setting.manualfieldsets.length > 0) { + thiswizard.createfieldsets($theform, setting.manualfieldsets); } - var maxfieldsetwidth=$sections.eq(0).outerWidth(); //variable to get width of widest fieldset.sectionwrap - $sections.slice(1).each(function(i){ //loop through $sections (starting from 2nd one) - maxfieldsetwidth=Math.max($(this).outerWidth(), maxfieldsetwidth); + const $stepsguide = $('<div class="stepsguide" />'); // Create Steps Container to house the "steps" text + const $sections = $theform.find('fieldset.sectionwrap').hide(); // Find all fieldset elements within form and hide them initially + let $sectionsWrapper = null; + let $sectionsWrapperInner = null; + if (setting.revealfx[0] === 'slide') { // Create outer DIV that will house all the fieldset.sectionwrap elements + $sectionsWrapper = $('<div style="position:relative;overflow:hidden;"></div>').insertBefore($sections.eq(0)); // Add DIV above the first fieldset.sectionwrap element + $sectionsWrapperInner = $('<div style="position:absolute;left:0;top:0;"></div>'); // Create inner DIV of $sectionswrapper that will scroll to reveal a fieldset element + } + let maxfieldsetwidth = $sections.eq(0).outerWidth(); // Variable to get width of widest fieldset.sectionwrap + $sections.slice(1).each(function() { // Loop through $sections (starting from 2nd one) + maxfieldsetwidth = Math.max($(this).outerWidth(), maxfieldsetwidth); }); - maxfieldsetwidth+=2; //add 2px to final width to reveal fieldset border (if not removed via CSS) - thiswizard.maxfieldsetwidth=maxfieldsetwidth; - $sections.each(function(i){ //loop through $sections again - var $section=$(this); - if (setting.revealfx[0]=="slide"){ - $section.data('page', i).css({position:'absolute', top:0, left:maxfieldsetwidth*i}).appendTo($sectionswrapper_inner); //set fieldset position to "absolute" and move it to inside sectionswrapper_inner DIV + maxfieldsetwidth += 2; // Add 2px to final width to reveal fieldset border (if not removed via CSS) + thiswizard.maxfieldsetwidth = maxfieldsetwidth; + $sections.each(function(i) { // Loop through $sections again + const $section = $(this); + if (setting.revealfx[0] === 'slide') { + $section.data('page', i).css({position: 'absolute', top: 0, left: maxfieldsetwidth * i}).appendTo($sectionsWrapperInner); // Set fieldset position to "absolute" and move it to inside sectionswrapper_inner DIV } - $section.data('elements', []); //empty array to contain elements within this section that should be validated for data (applicable only if validate option is defined) - //create each "step" DIV and add it to main Steps Container: - var $thestep=$('<div class="step disabledstep" />').data('section', i).html('Step '+(i+1)+'<div class="smalltext">'+$section.find('legend:eq(0)').text()+'<p></p></div>').appendTo($stepsguide); - $thestep.on('click', function(){ //assign behavior to each step div + $section.data('elements', []); // Empty array to contain elements within this section that should be validated for data (applicable only if validate option is defined) + // create each "step" DIV and add it to main Steps Container: + const $thestep = $('<div class="step disabledstep" />').data('section', i).html('Step ' + (i + 1) + '<div class="smalltext">' + $section.find('legend:eq(0)').text() + '<p></p></div>').appendTo($stepsguide); + $thestep.on('click', function() { // Assign behavior to each step div thiswizard.loadsection($(this).data('section')); }); }); - if (setting.revealfx[0]=="slide"){ - $sectionswrapper.width(maxfieldsetwidth); //set fieldset wrapper to width of widest fieldset - $sectionswrapper.append($sectionswrapper_inner); //add $sectionswrapper_inner as a child of $sectionswrapper + if (setting.revealfx[0] === 'slide') { + $sectionsWrapper.width(maxfieldsetwidth); // Set fieldset wrapper to width of widest fieldset + $sectionsWrapper.append($sectionsWrapperInner); // Add $sectionswrapper_inner as a child of $sectionswrapper } - $theform.prepend($stepsguide); //add $thesteps div to the beginning of the form - //$stepsguide.insertBefore($sectionswrapper) //add Steps Container before sectionswrapper container - var $thesteps=$stepsguide.find('div.step'); - //create pagination DIV and add it to end of form: - var $paginatediv=$('<div class="formpaginate" style="overflow:hidden;"><span class="prev" style="float:left">Prev</span> <span class="status">Step 1 of </span> <span class="next" style="float:right">Next</span></div>'); + $theform.prepend($stepsguide); // Add $thesteps div to the beginning of the form + // $stepsguide.insertBefore($sectionswrapper) //add Steps Container before sectionswrapper container + const $thesteps = $stepsguide.find('div.step'); + // Create pagination DIV and add it to end of form: + const $paginatediv = $('<div class="formpaginate" style="overflow:hidden;"><span class="prev" style="float:left">Prev</span> <span class="status">Step 1 of </span> <span class="next" style="float:right">Next</span></div>'); $theform.append($paginatediv); - thiswizard.$theform=$theform; - if (setting.revealfx[0]=="slide"){ - thiswizard.sections={$outerwrapper:$sectionswrapper, $innerwrapper:$sectionswrapper_inner, $sections:$sections, count:$sections.length}; //remember various parts of section container + thiswizard.$theform = $theform; + if (setting.revealfx[0] === 'slide') { + // Remember various parts of section container + thiswizard.sections = { + $outerwrapper: $sectionsWrapper, + $innerwrapper: $sectionsWrapperInner, + $sections: $sections, + count: $sections.length + }; thiswizard.sections.$sections.show(); - } else{ - thiswizard.sections={$sections:$sections, count:$sections.length}; //remember various parts of section container + } else { + // Remember various parts of section container + thiswizard.sections = { + $sections: $sections, + count: $sections.length + }; } - thiswizard.$thesteps=$thesteps; //remember this ref - thiswizard.paginatediv={$main:$paginatediv, $navlinks:$paginatediv.find('span.prev, span.next'), $status:$paginatediv.find('span.status')}; //remember various parts of pagination DIV - thiswizard.paginatediv.$main.on('click', function(e){ //assign behavior to pagination buttons - if (/(prev)|(next)/.test(e.target.className)) thiswizard.loadsection(e.target.className); + + // Remember this ref + thiswizard.$thesteps = $thesteps; + + // Remember various parts of pagination DIV + thiswizard.paginatediv = { + $main: $paginatediv, + $navlinks: $paginatediv.find('span.prev, span.next'), + $status: $paginatediv.find('span.status') + }; + + // Assign behavior to pagination buttons + thiswizard.paginatediv.$main.on('click', function(event) { + if (/(prev)|(next)/.test(event.target.className)) { + thiswizard.loadsection(event.target.className); + } }); - var i=(setting.persistsection)? formtowizard.routines.getCookie(setting.formid+"_persist") : 0; - thiswizard.loadsection(i||0, true); //show the first section - thiswizard.setting.oninit($, i, $sections.eq(i)); //call oninit event handler - if (setting.validate){ //if validate array defined - thiswizard.addvalidatefields(); //seek out and cache form elements that should be validated - thiswizard.$theform.submit(function(){ - var returnval=true; - for (var i=0; i<thiswizard.sections.count; i++){ - if (!thiswizard.validate(i)){ + const sectionId = (setting.persistsection) ? formtowizard.routines.getCookie(setting.formid + '_persist') : 0; + thiswizard.loadsection(sectionId || 0, true); // Show the first section + thiswizard.setting.oninit($, sectionId, $sections.eq(sectionId)); // Call oninit event handler + if (setting.validate) { // If validate array defined + thiswizard.addvalidatefields(); // Seek out and cache form elements that should be validated + thiswizard.$theform.submit(function() { + let returnval = true; + for (let i = 0; i < thiswizard.sections.count; i++) { + if (!thiswizard.validate(i)) { thiswizard.loadsection(i, true); - returnval=false; + returnval = false; break; } } - return returnval; //allow or disallow form submission + return returnval; // Allow or disallow form submission }); } }); } }; -formtowizard.routines={ +formtowizard.routines = { + getCookie: function(Name) { + // Construct RE to search for target name/value pair + const re = new RegExp(Name + '=[^;]+', 'i'); - getCookie:function(Name){ - var re=new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair - if (document.cookie.match(re)) return document.cookie.match(re)[0].split("=")[1]; //if cookie found return it's value + // If cookie found return it's value + if (document.cookie.match(re)) { + return document.cookie.match(re)[0].split('=')[1]; + } return null; }, - - setCookie:function(name, value){ - document.cookie = name+"=" + value + ";path=/"; + setCookie: function(name, value) { + document.cookie = name + '=' + value + ';path=/'; } }; diff --git a/gui/slick/js/lib/jquery.bookmarkscroll.js b/gui/slick/js/lib/jquery.bookmarkscroll.js index 0a2cfc8359be95ef08ed522999849eb78766867c..defe9aed9cc440e237d1643f8536db760099fb58 100644 --- a/gui/slick/js/lib/jquery.bookmarkscroll.js +++ b/gui/slick/js/lib/jquery.bookmarkscroll.js @@ -1,51 +1,63 @@ -//** Scrolling HTML Bookmarks script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com. -//** Available/ usage terms at http://www.dynamicdrive.com/ (April 11th, 09') -//** Updated Nov 10th, 09'- Fixed anchor jumping issue in IE7 +/* Scrolling HTML Bookmarks script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com. +* Available/ usage terms at http://www.dynamicdrive.com/ (April 11th, 09') +*/ -var bookmarkscroll={ - setting: {duration:1000, yoffset:-50}, //{duration_of_scroll_milliseconds, offset_from_target_element_to_rest} - topkeyword: '#top', //keyword used in your anchors and scrollTo() to cause script to scroll page to very top +var bookmarkscroll = { + setting: { + duration: 1000, + yoffset: -50 + }, + topkeyword: '#top', // Keyword used in your anchors and scrollTo() to cause script to scroll page to very top + scrollTo: function(dest, options) { + const $ = jQuery; + options = options || {}; + const $dest = (typeof dest === 'string' && dest.length > 0) ? (dest === this.topkeyword ? 0 : $('#' + dest)) : (dest) ? $(dest) : []; // Get element based on id, topkeyword, or dom ref + if ($dest === 0 || $dest.length === 1 && (!options.autorun || options.autorun && Math.abs($dest.offset().top + (options.yoffset || this.setting.yoffset) - $(window).scrollTop()) > 5)) { // eslint-disable-line no-mixed-operators + this.$body.animate({ + scrollTop: ($dest === 0) ? 0 : $dest.offset().top + (options.yoffset || this.setting.yoffset) + }, (options.duration || this.setting.duration)); + } + }, + urlparamselect: function() { + var param = window.location.search.match(/scrollto=[\w\-_,]+/i); // Search for scrollto=divid + return (param) ? param[0].split('=')[1] : null; + }, + init: function() { + jQuery(document).ready(function($) { + const mainobj = bookmarkscroll; + mainobj.$body = (window.opera) ? (document.compatMode === 'CSS1Compat' ? $('html') : $('body')) : $('html,body'); - scrollTo:function(dest, options, hash){ - var $=jQuery, options=options || {} - var $dest=(typeof dest=="string" && dest.length>0)? (dest==this.topkeyword? 0 : $('#'+dest)) : (dest)? $(dest) : [] //get element based on id, topkeyword, or dom ref - if ($dest===0 || $dest.length==1 && (!options.autorun || options.autorun && Math.abs($dest.offset().top+(options.yoffset||this.setting.yoffset)-$(window).scrollTop())>5)){ - this.$body.animate({scrollTop: ($dest===0)? 0 : $dest.offset().top+(options.yoffset||this.setting.yoffset)}, (options.duration||this.setting.duration), function(){ -//** if ($dest!==0 && hash) -//** location.hash=hash - }) - } - }, + // Get div of page.htm?scrollto=divid + const urlselectid = mainobj.urlparamselect(); + // If id defined + if (urlselectid) { + setTimeout(function() { + mainobj.scrollTo(document.getElementById(urlselectid) || $('a[name=' + urlselectid + ']:eq(0)').get(0), { + autorun: true + }); + }, 100); + } + // Loop through links with "#" prefix + $('a[href^="#"]').each(function() { + // If hash value is more than just "#" + if (this.hash.length > 1) { + const $bookmark = $('a[name=' + this.hash.substr(1) + ']:eq(0)'); - urlparamselect:function(){ - var param=window.location.search.match(/scrollto=[\w\-_,]+/i) //search for scrollto=divid - return (param)? param[0].split('=')[1] : null - }, - - init:function(){ - jQuery(document).ready(function($){ - var mainobj=bookmarkscroll - mainobj.$body=(window.opera)? (document.compatMode=="CSS1Compat"? $('html') : $('body')) : $('html,body') - var urlselectid=mainobj.urlparamselect() //get div of page.htm?scrollto=divid - if (urlselectid) //if id defined - setTimeout(function(){mainobj.scrollTo(document.getElementById(urlselectid) || $('a[name='+urlselectid+']:eq(0)').get(0), {autorun:true})}, 100) - $('a[href^="#"]').each(function(){ //loop through links with "#" prefix - var hashvalue=this.getAttribute('href').match(/#\w+$/i) //filter links at least 1 character following "#" prefix - hashvalue=(hashvalue)? hashvalue[0].substring(1) : null //strip "#" from hashvalue - if (this.hash.length>1){ //if hash value is more than just "#" - var $bookmark=$('a[name='+this.hash.substr(1)+']:eq(0)') - if ($bookmark.length==1 || this.hash==mainobj.topkeyword){ //if HTML anchor with given ID exists or href==topkeyword - if ($bookmark.length==1 && !document.all) //non IE, or IE7+ - $bookmark.html('.').css({position:'absolute', fontSize:1, visibility:'hidden'}) - $(this).on('click', function(e){ - mainobj.scrollTo((this.hash==mainobj.topkeyword)? mainobj.topkeyword : $bookmark.get(0), {}, this.hash) - e.preventDefault() - }) - } - } - }) - }) - } -} + // If HTML anchor with given ID exists or href==topkeyword + if ($bookmark.length === 1 || this.hash === mainobj.topkeyword) { + // Non IE, or IE7+ + if ($bookmark.length === 1 && !document.all) { + $bookmark.html('.').css({position: 'absolute', fontSize: 1, visibility: 'hidden'}); + } + $(this).click(function(event) { + mainobj.scrollTo((this.hash === mainobj.topkeyword) ? mainobj.topkeyword : $bookmark.get(0), {}, this.hash); + event.preventDefault(); + }); + } + } + }); + }); + } +}; -bookmarkscroll.init() \ No newline at end of file +bookmarkscroll.init(); diff --git a/gui/slick/js/lib/jquery.scrolltopcontrol-1.1.js b/gui/slick/js/lib/jquery.scrolltopcontrol-1.1.js index 633267a81da0801546848c37ef36398f9a789b8e..f198e7bf8e2b052154c0f716940688899ad05650 100644 --- a/gui/slick/js/lib/jquery.scrolltopcontrol-1.1.js +++ b/gui/slick/js/lib/jquery.scrolltopcontrol-1.1.js @@ -1,75 +1,94 @@ -//** jQuery Scroll to Top Control script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com. -//** Available/ usage terms at http://www.dynamicdrive.com (March 30th, 09') -//** v1.1 (April 7th, 09'): -//** 1) Adds ability to scroll to an absolute position (from top of page) or specific element on the page instead. -//** 2) Fixes scroll animation not working in Opera. +/* JQuery Scroll to Top Control script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com. +* Available/ usage terms at http://www.dynamicdrive.com (March 30th, 09') +*/ - -var scrolltotop={ - //startline: Integer. Number of pixels from top of doc scrollbar is scrolled before showing control - //scrollto: Keyword (Integer, or "Scroll_to_Element_ID"). How far to scroll document up when control is clicked on (0=top). - setting: {startline:100, scrollto: 0, scrollduration:1000, fadeduration:[500, 100]}, - controlHTML: topImageHtml, - controlattrs: {offsetx:10, offsety:10}, //offset of control relative to right/ bottom of window corner - anchorkeyword: '#top', //Enter href value of HTML anchors on the page that should also act as "Scroll Up" links - - state: {isvisible:false, shouldvisible:false}, - - scrollup:function(){ - if (!this.cssfixedsupport) { //if control is positioned using JavaScript - this.$control.css({opacity:0}); //hide control immediately after clicking it +const scrolltotop = { + // Startline: Integer. Number of pixels from top of doc scrollbar is scrolled before showing control + // scrollto: Keyword (Integer, or "Scroll_to_Element_ID"). How far to scroll document up when control is clicked on (0=top). + setting: { + startline: 100, + scrollto: 0, + scrollduration: 1000, + fadeduration: [500, 100] + }, + controlHTML: topImageHtml, // eslint-disable-line no-undef + // Offset of control relative to right/bottom of window corner + controlattrs: { + offsetx: 10, + offsety: 10 + }, + anchorkeyword: '#top', // Enter href value of HTML anchors on the page that should also act as "Scroll Up" links + state: {isvisible: false, shouldvisible: false}, + scrollup: function() { + // If control is positioned using JavaScript + if (!this.cssfixedsupport) { + // Hide control immediately after clicking it + this.$control.css({ + opacity: 0 + }); } - var dest=isNaN(this.setting.scrollto)? this.setting.scrollto : parseInt(this.setting.scrollto); - if (typeof dest === "string" && jQuery('#'+dest).length === 1){ //check element set by string exists - dest=jQuery('#'+dest).offset().top; + let dest = isNaN(this.setting.scrollto) ? this.setting.scrollto : parseInt(this.setting.scrollto, 10); + if (typeof dest === 'string' && jQuery('#' + dest).length === 1) { // Check element set by string exists + dest = jQuery('#' + dest).offset().top; } else { dest = 0; } this.$body.animate({scrollTop: dest}, this.setting.scrollduration); }, - - keepfixed:function(){ - var $window=jQuery(window); - var controlx=$window.scrollLeft() + $window.width() - this.$control.width() - this.controlattrs.offsetx; - var controly=$window.scrollTop() + $window.height() - this.$control.height() - this.controlattrs.offsety; - this.$control.css({left:controlx+'px', top:controly+'px'}); + keepfixed: function() { + const $window = jQuery(window); + const controlx = $window.scrollLeft() + $window.width() - this.$control.width() - this.controlattrs.offsetx; + const controly = $window.scrollTop() + $window.height() - this.$control.height() - this.controlattrs.offsety; + this.$control.css({left: controlx + 'px', top: controly + 'px'}); }, - - togglecontrol:function(){ - var scrolltop=jQuery(window).scrollTop(); + togglecontrol: function() { + const scrolltop = jQuery(window).scrollTop(); if (!this.cssfixedsupport) { this.keepfixed(); } - this.state.shouldvisible=(scrolltop>=this.setting.startline)? true : false; - if (this.state.shouldvisible && !this.state.isvisible){ - this.$control.stop().animate({opacity:1}, this.setting.fadeduration[0]); + this.state.shouldvisible = (scrolltop >= this.setting.startline); + if (this.state.shouldvisible && !this.state.isvisible) { + this.$control.stop().animate({opacity: 1}, this.setting.fadeduration[0]); this.state.isvisible = true; - } else if (this.state.shouldvisible === false && this.state.isvisible){ - this.$control.stop().animate({opacity:0}, this.setting.fadeduration[1]); - this.state.isvisible=false; + } else if (this.state.shouldvisible === false && this.state.isvisible) { + this.$control.stop().animate({opacity: 0}, this.setting.fadeduration[1]); + this.state.isvisible = false; } }, + init: function() { + jQuery(document).ready(function($) { + const mainobj = scrolltotop; + const iebrws = document.all; + + // Not IE or IE7+ browsers in standards mode + mainobj.cssfixedsupport = !iebrws || iebrws && document.compatMode.toLowerCase() === 'CSS1Compat'.toLowerCase() && window.XMLHttpRequest; // eslint-disable-line no-mixed-operators + mainobj.$body = (window.opera) ? (document.compatMode.toLowerCase() === 'CSS1Compat'.toLowerCase() ? $('html') : $('body')) : $('html,body'); + mainobj.$control = $('<div id="topcontrol">' + mainobj.controlHTML + '</div>').css({ + position: mainobj.cssfixedsupport ? 'fixed' : 'absolute', + bottom: mainobj.controlattrs.offsety, + right: mainobj.controlattrs.offsetx, + opacity: 0, + cursor: 'pointer' + }).attr({ + title: 'Scroll Back to Top' + }).on('click', function() { + mainobj.scrollup(); + return false; + }).appendTo('body'); - init:function(){ - jQuery(document).ready(function($){ - var mainobj = scrolltotop; - var iebrws = document.all; - mainobj.cssfixedsupport=!iebrws || iebrws && document.compatMode.toLowerCase() === "CSS1Compat".toLowerCase() && window.XMLHttpRequest; //not IE or IE7+ browsers in standards mode - mainobj.$body=(window.opera)? (document.compatMode.toLowerCase() === "CSS1Compat".toLowerCase() ? $('html') : $('body')) : $('html,body'); - mainobj.$control=$('<div id="topcontrol">'+mainobj.controlHTML+'</div>') - .css({position:mainobj.cssfixedsupport? 'fixed' : 'absolute', bottom:mainobj.controlattrs.offsety, right:mainobj.controlattrs.offsetx, opacity:0, cursor:'pointer'}) - .attr({title:'Scroll Back to Top'}) - .on('click', function(){mainobj.scrollup(); return false;}) - .appendTo('body'); - if (document.all && !window.XMLHttpRequest && mainobj.$control.text()!==''){ //loose check for IE6 and below, plus whether control contains any text - mainobj.$control.css({width:mainobj.$control.width()}); //IE6- seems to require an explicit width on a DIV containing text + // Loose check for IE6 and below, plus whether control contains any text + if (document.all && !window.XMLHttpRequest && mainobj.$control.text() !== '') { + // IE6- seems to require an explicit width on a DIV containing text + mainobj.$control.css({ + width: mainobj.$control.width() + }); } mainobj.togglecontrol(); - $('a[href="' + mainobj.anchorkeyword +'"]').on('click', function(){ + $('a[href="' + mainobj.anchorkeyword + '"]').on('click', function() { mainobj.scrollup(); return false; }); - $(window).bind('scroll resize', function(){ + $(window).on('scroll resize', function() { mainobj.togglecontrol(); }); }); diff --git a/package.json b/package.json index 090033ee7115866cd3941933b6b9247b6319c184..54a7194411071278496a3c6d696002e1e4cf0b10 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,6 @@ "core.min.js", "vender.min.js", "lib/**/*", - "gui/slick/js/lib/*", "Gruntfile.js" ] }