Form builder to get in touch with visitors, grow your email list and collect payments — Happyforms - Version 1.15.0

Version Description

  • Improvement: All frontend scripts are now bundled in a single file for better performance and cache friendliness.
  • Bugfix: Duplicating a form would throw an error on PHP 8.0.
  • Bugfix: "Limit how many times this choice can be submitted" counters were being wrongly copied to duplicated forms.
Download this release

Release Info

Developer happyforms
Plugin Icon 128x128 Form builder to get in touch with visitors, grow your email list and collect payments — Happyforms
Version 1.15.0
Comparing to
See all releases

Code changes from version 1.14.3 to 1.15.0

bundles/js/frontend.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Cleave=t():e.Cleave=t()}(this,function(){return e=[function(e,t,r){!function(t){"use strict";function i(e,t){var r=this,n=!1;if("string"==typeof e?(r.element=document.querySelector(e),n=1<document.querySelectorAll(e).length):void 0!==e.length&&0<e.length?(r.element=e[0],n=1<e.length):r.element=e,!r.element)throw new Error("[cleave.js] Please check the element");if(n)try{console.warn("[cleave.js] Multiple input fields matched, cleave.js will only take the first one.")}catch(a){}t.initValue=r.element.value,r.properties=i.DefaultProperties.assign({},t),r.init()}i.prototype={init:function(){var e=this,t=e.properties;return t.numeral||t.phone||t.creditCard||t.time||t.date||0!==t.blocksLength||t.prefix?(t.maxLength=i.Util.getMaxLength(t.blocks),e.isAndroid=i.Util.isAndroid(),e.lastInputValue="",e.isBackward="",e.onChangeListener=e.onChange.bind(e),e.onKeyDownListener=e.onKeyDown.bind(e),e.onFocusListener=e.onFocus.bind(e),e.onCutListener=e.onCut.bind(e),e.onCopyListener=e.onCopy.bind(e),e.initSwapHiddenInput(),e.element.addEventListener("input",e.onChangeListener),e.element.addEventListener("keydown",e.onKeyDownListener),e.element.addEventListener("focus",e.onFocusListener),e.element.addEventListener("cut",e.onCutListener),e.element.addEventListener("copy",e.onCopyListener),e.initPhoneFormatter(),e.initDateFormatter(),e.initTimeFormatter(),e.initNumeralFormatter(),void((t.initValue||t.prefix&&!t.noImmediatePrefix)&&e.onInput(t.initValue))):void e.onInput(t.initValue)},initSwapHiddenInput:function(){var r,e=this;e.properties.swapHiddenInput&&(r=e.element.cloneNode(!0),e.element.parentNode.insertBefore(r,e.element),e.elementSwapHidden=e.element,e.elementSwapHidden.type="hidden",e.element=r,e.element.id="")},initNumeralFormatter:function(){var t=this.properties;t.numeral&&(t.numeralFormatter=new i.NumeralFormatter(t.numeralDecimalMark,t.numeralIntegerScale,t.numeralDecimalScale,t.numeralThousandsGroupStyle,t.numeralPositiveOnly,t.stripLeadingZeroes,t.prefix,t.signBeforePrefix,t.tailPrefix,t.delimiter))},initTimeFormatter:function(){var t=this.properties;t.time&&(t.timeFormatter=new i.TimeFormatter(t.timePattern,t.timeFormat),t.blocks=t.timeFormatter.getBlocks(),t.blocksLength=t.blocks.length,t.maxLength=i.Util.getMaxLength(t.blocks))},initDateFormatter:function(){var t=this.properties;t.date&&(t.dateFormatter=new i.DateFormatter(t.datePattern,t.dateMin,t.dateMax),t.blocks=t.dateFormatter.getBlocks(),t.blocksLength=t.blocks.length,t.maxLength=i.Util.getMaxLength(t.blocks))},initPhoneFormatter:function(){var t=this.properties;if(t.phone)try{t.phoneFormatter=new i.PhoneFormatter(new t.root.Cleave.AsYouTypeFormatter(t.phoneRegionCode),t.delimiter)}catch(r){throw new Error("[cleave.js] Please include phone-type-formatter.{country}.js lib")}},onKeyDown:function(e){var t=this,e=e.which||e.keyCode;t.lastInputValue=t.element.value,t.isBackward=8===e},onChange:function(e){var t=this,r=t.properties,n=i.Util,e=(t.isBackward=t.isBackward||"deleteContentBackward"===e.inputType,n.getPostDelimiter(t.lastInputValue,r.delimiter,r.delimiters));t.isBackward&&e?r.postDelimiterBackspace=e:r.postDelimiterBackspace=!1,this.onInput(this.element.value)},onFocus:function(){var e=this,t=e.properties;e.lastInputValue=e.element.value,t.prefix&&t.noImmediatePrefix&&!e.element.value&&this.onInput(t.prefix),i.Util.fixPrefixCursor(e.element,t.prefix,t.delimiter,t.delimiters)},onCut:function(e){i.Util.checkFullSelection(this.element.value)&&(this.copyClipboardData(e),this.onInput(""))},onCopy:function(e){i.Util.checkFullSelection(this.element.value)&&this.copyClipboardData(e)},copyClipboardData:function(e){var r=this.properties,n=i.Util,a=this.element.value,n=r.copyDelimiter?a:n.stripDelimiters(a,r.delimiter,r.delimiters);try{(e.clipboardData?e:window).clipboardData.setData("Text",n),e.preventDefault()}catch(l){}},onInput:function(e){var t=this,r=t.properties,n=i.Util,a=n.getPostDelimiter(e,r.delimiter,r.delimiters);r.numeral||!r.postDelimiterBackspace||a||(e=n.headStr(e,e.length-r.postDelimiterBackspace.length)),r.phone?!r.prefix||r.noImmediatePrefix&&!e.length?r.result=r.phoneFormatter.format(e):r.result=r.prefix+r.phoneFormatter.format(e).slice(r.prefix.length):r.numeral?r.prefix&&r.noImmediatePrefix&&0===e.length?r.result="":r.result=r.numeralFormatter.format(e):(r.date&&(e=r.dateFormatter.getValidatedDate(e)),r.time&&(e=r.timeFormatter.getValidatedTime(e)),e=n.stripDelimiters(e,r.delimiter,r.delimiters),e=n.getPrefixStrippedValue(e,r.prefix,r.prefixLength,r.result,r.delimiter,r.delimiters,r.noImmediatePrefix,r.tailPrefix,r.signBeforePrefix),e=r.numericOnly?n.strip(e,/[^\d]/g):e,e=r.uppercase?e.toUpperCase():e,e=r.lowercase?e.toLowerCase():e,r.prefix&&(r.tailPrefix?e+=r.prefix:e=r.prefix+e,0===r.blocksLength)?r.result=e:(r.creditCard&&t.updateCreditCardPropsByValue(e),e=n.headStr(e,r.maxLength),r.result=n.getFormattedValue(e,r.blocks,r.blocksLength,r.delimiter,r.delimiters,r.delimiterLazyShow))),t.updateValueState()},updateCreditCardPropsByValue:function(e){var n=this.properties,a=i.Util;a.headStr(n.result,4)!==a.headStr(e,4)&&(e=i.CreditCardDetector.getInfo(e,n.creditCardStrictMode),n.blocks=e.blocks,n.blocksLength=n.blocks.length,n.maxLength=a.getMaxLength(n.blocks),n.creditCardType!==e.type&&(n.creditCardType=e.type,n.onCreditCardTypeChanged.call(this,n.creditCardType)))},updateValueState:function(){var n,a,o,e=this,t=i.Util,r=e.properties;e.element&&(n=e.element.selectionEnd,a=e.element.value,o=r.result,n=t.getNextCursorPosition(n,a,o,r.delimiter,r.delimiters),e.isAndroid?window.setTimeout(function(){e.element.value=o,t.setSelection(e.element,n,r.document,!1),e.callOnValueChanged()},1):(e.element.value=o,r.swapHiddenInput&&(e.elementSwapHidden.value=e.getRawValue()),t.setSelection(e.element,n,r.document,!1),e.callOnValueChanged()))},callOnValueChanged:function(){var e=this,t=e.properties;t.onValueChanged.call(e,{target:{name:e.element.name,value:t.result,rawValue:e.getRawValue()}})},setPhoneRegionCode:function(e){var t=this;t.properties.phoneRegionCode=e,t.initPhoneFormatter(),t.onChange()},setRawValue:function(e){var t=this,r=t.properties;e=null!=e?e.toString():"",r.numeral&&(e=e.replace(".",r.numeralDecimalMark)),r.postDelimiterBackspace=!1,t.element.value=e,t.onInput(e)},getRawValue:function(){var t=this.properties,r=i.Util,n=this.element.value;return t.rawValueTrimPrefix&&(n=r.getPrefixStrippedValue(n,t.prefix,t.prefixLength,t.result,t.delimiter,t.delimiters,t.noImmediatePrefix,t.tailPrefix,t.signBeforePrefix)),t.numeral?t.numeralFormatter.getRawValue(n):r.stripDelimiters(n,t.delimiter,t.delimiters)},getISOFormatDate:function(){var t=this.properties;return t.date?t.dateFormatter.getISOFormatDate():""},getISOFormatTime:function(){var t=this.properties;return t.time?t.timeFormatter.getISOFormatTime():""},getFormattedValue:function(){return this.element.value},destroy:function(){var e=this;e.element.removeEventListener("input",e.onChangeListener),e.element.removeEventListener("keydown",e.onKeyDownListener),e.element.removeEventListener("focus",e.onFocusListener),e.element.removeEventListener("cut",e.onCutListener),e.element.removeEventListener("copy",e.onCopyListener)},toString:function(){return"[Cleave Object]"}},i.NumeralFormatter=r(1),i.DateFormatter=r(2),i.TimeFormatter=r(3),i.PhoneFormatter=r(4),i.CreditCardDetector=r(5),i.Util=r(6),i.DefaultProperties=r(7),("object"==typeof t&&t?t:window).Cleave=i,e.exports=i}.call(t,function(){return this}())},function(e,t){"use strict";function r(e,t,i,n,a,o,l,s,c,u){var d=this;d.numeralDecimalMark=e||".",d.numeralIntegerScale=0<t?t:0,d.numeralDecimalScale=0<=i?i:2,d.numeralThousandsGroupStyle=n||r.groupStyle.thousand,d.numeralPositiveOnly=!!a,d.stripLeadingZeroes=!1!==o,d.prefix=l||""===l?l:"",d.signBeforePrefix=!!s,d.tailPrefix=!!c,d.delimiter=u||""===u?u:",",d.delimiterRE=u?new RegExp("\\"+u,"g"):""}r.groupStyle={thousand:"thousand",lakh:"lakh",wan:"wan",none:"none"},r.prototype={getRawValue:function(e){return e.replace(this.delimiterRE,"").replace(this.numeralDecimalMark,".")},format:function(e){var i,n,a,o=this,l="";switch(e=e.replace(/[A-Za-z]/g,"").replace(o.numeralDecimalMark,"M").replace(/[^\dM-]/g,"").replace(/^\-/,"N").replace(/\-/g,"").replace("N",o.numeralPositiveOnly?"":"-").replace("M",o.numeralDecimalMark),i="-"===(e=o.stripLeadingZeroes?e.replace(/^(-)?0+(?=\d)/,"$1"):e).slice(0,1)?"-":"",n=void 0!==o.prefix?o.signBeforePrefix?i+o.prefix:o.prefix+i:i,0<=(a=e).indexOf(o.numeralDecimalMark)&&(a=(e=e.split(o.numeralDecimalMark))[0],l=o.numeralDecimalMark+e[1].slice(0,o.numeralDecimalScale)),"-"==i&&(a=a.slice(1)),0<o.numeralIntegerScale&&(a=a.slice(0,o.numeralIntegerScale)),o.numeralThousandsGroupStyle){case r.groupStyle.lakh:a=a.replace(/(\d)(?=(\d\d)+\d$)/g,"$1"+o.delimiter);break;case r.groupStyle.wan:a=a.replace(/(\d)(?=(\d{4})+$)/g,"$1"+o.delimiter);break;case r.groupStyle.thousand:a=a.replace(/(\d)(?=(\d{3})+$)/g,"$1"+o.delimiter)}return o.tailPrefix?i+a.toString()+(0<o.numeralDecimalScale?l.toString():"")+o.prefix:n+a.toString()+(0<o.numeralDecimalScale?l.toString():"")}},e.exports=r},function(e,t){"use strict";function r(e,t,r){var i=this;i.date=[],i.blocks=[],i.datePattern=e,i.dateMin=t.split("-").reverse().map(function(e){return parseInt(e,10)}),2===i.dateMin.length&&i.dateMin.unshift(0),i.dateMax=r.split("-").reverse().map(function(e){return parseInt(e,10)}),2===i.dateMax.length&&i.dateMax.unshift(0),i.initBlocks()}r.prototype={initBlocks:function(){var e=this;e.datePattern.forEach(function(t){"Y"===t?e.blocks.push(4):e.blocks.push(2)})},getISOFormatDate:function(){var e=this,t=e.date;return t[2]?t[2]+"-"+e.addLeadingZero(t[1])+"-"+e.addLeadingZero(t[0]):""},getBlocks:function(){return this.blocks},getValidatedDate:function(e){var t=this,r="";return e=e.replace(/[^\d]/g,""),t.blocks.forEach(function(i,n){if(0<e.length){var a=e.slice(0,i),o=a.slice(0,1),i=e.slice(i);switch(t.datePattern[n]){case"d":"00"===a?a="01":3<parseInt(o,10)?a="0"+o:31<parseInt(a,10)&&(a="31");break;case"m":"00"===a?a="01":1<parseInt(o,10)?a="0"+o:12<parseInt(a,10)&&(a="12")}r+=a,e=i}}),this.getFixedDateString(r)},getFixedDateString:function(e){var t,r,i,n=this,a=n.datePattern,o=[],l=0,s=0,c=0,u=0,d=0,m=0,p=!1;return 4===e.length&&"y"!==a[0].toLowerCase()&&"y"!==a[1].toLowerCase()&&(d=2-(u="d"===a[0]?0:2),t=parseInt(e.slice(u,u+2),10),r=parseInt(e.slice(d,d+2),10),o=this.getFixedDate(t,r,0)),8===e.length&&(a.forEach(function(e,t){switch(e){case"d":l=t;break;case"m":s=t;break;default:c=t}}),m=2*c,u=l<=c?2*l:2*l+2,d=s<=c?2*s:2*s+2,t=parseInt(e.slice(u,u+2),10),r=parseInt(e.slice(d,d+2),10),i=parseInt(e.slice(m,m+4),10),p=4===e.slice(m,m+4).length,o=this.getFixedDate(t,r,i)),4!==e.length||"y"!==a[0]&&"y"!==a[1]||(m=2-(d="m"===a[0]?0:2),r=parseInt(e.slice(d,d+2),10),i=parseInt(e.slice(m,m+2),10),p=2===e.slice(m,m+2).length,o=[0,r,i]),6!==e.length||"Y"!==a[0]&&"Y"!==a[1]||(m=2-.5*(d="m"===a[0]?0:4),r=parseInt(e.slice(d,d+2),10),i=parseInt(e.slice(m,m+4),10),p=4===e.slice(m,m+4).length,o=[0,r,i]),o=n.getRangeFixedDate(o),0===(n.date=o).length?e:a.reduce(function(e,t){switch(t){case"d":return e+(0===o[0]?"":n.addLeadingZero(o[0]));case"m":return e+(0===o[1]?"":n.addLeadingZero(o[1]));case"y":return e+(p?n.addLeadingZeroForYear(o[2],!1):"");case"Y":return e+(p?n.addLeadingZeroForYear(o[2],!0):"")}},"")},getRangeFixedDate:function(e){var t=this,r=t.datePattern,i=t.dateMin||[],t=t.dateMax||[];return!e.length||i.length<3&&t.length<3||r.find(function(e){return"y"===e.toLowerCase()})&&0===e[2]?e:t.length&&(t[2]<e[2]||t[2]===e[2]&&(t[1]<e[1]||t[1]===e[1]&&t[0]<e[0]))?t:i.length&&(i[2]>e[2]||i[2]===e[2]&&(i[1]>e[1]||i[1]===e[1]&&i[0]>e[0]))?i:e},getFixedDate:function(e,t,r){return e=Math.min(e,31),t=Math.min(t,12),r=parseInt(r||0,10),[e=t<7&&t%2==0||8<t&&t%2==1?Math.min(e,2===t?this.isLeapYear(r)?29:28:30):e,t,r]},isLeapYear:function(e){return e%4==0&&e%100!=0||e%400==0},addLeadingZero:function(e){return(e<10?"0":"")+e},addLeadingZeroForYear:function(e,t){return t?(e<10?"000":e<100?"00":e<1e3?"0":"")+e:(e<10?"0":"")+e}},e.exports=r},function(e,t){"use strict";function r(e,t){var r=this;r.time=[],r.blocks=[],r.timePattern=e,r.timeFormat=t,r.initBlocks()}r.prototype={initBlocks:function(){var e=this;e.timePattern.forEach(function(){e.blocks.push(2)})},getISOFormatTime:function(){var e=this,t=e.time;return t[2]?e.addLeadingZero(t[0])+":"+e.addLeadingZero(t[1])+":"+e.addLeadingZero(t[2]):""},getBlocks:function(){return this.blocks},getTimeFormatOptions:function(){return"12"===String(this.timeFormat)?{maxHourFirstDigit:1,maxHours:12,maxMinutesFirstDigit:5,maxMinutes:60}:{maxHourFirstDigit:2,maxHours:23,maxMinutesFirstDigit:5,maxMinutes:60}},getValidatedTime:function(e){var t=this,r="",i=(e=e.replace(/[^\d]/g,""),t.getTimeFormatOptions());return t.blocks.forEach(function(n,a){if(0<e.length){var o=e.slice(0,n),l=o.slice(0,1),n=e.slice(n);switch(t.timePattern[a]){case"h":parseInt(l,10)>i.maxHourFirstDigit?o="0"+l:parseInt(o,10)>i.maxHours&&(o=i.maxHours+"");break;case"m":case"s":parseInt(l,10)>i.maxMinutesFirstDigit?o="0"+l:parseInt(o,10)>i.maxMinutes&&(o=i.maxMinutes+"")}r+=o,e=n}}),this.getFixedTimeString(r)},getFixedTimeString:function(e){var r,i,u,n=this,a=n.timePattern,o=[],l=0,s=0,c=0,d=0,m=0;return 6===e.length&&(a.forEach(function(e,t){switch(e){case"s":l=2*t;break;case"m":s=2*t;break;case"h":c=2*t}}),m=c,d=s,u=l,u=parseInt(e.slice(u,u+2),10),r=parseInt(e.slice(d,d+2),10),i=parseInt(e.slice(m,m+2),10),o=this.getFixedTime(i,r,u)),4===e.length&&n.timePattern.indexOf("s")<0&&(a.forEach(function(e,t){switch(e){case"m":s=2*t;break;case"h":c=2*t}}),m=c,d=s,u=0,r=parseInt(e.slice(d,d+2),10),i=parseInt(e.slice(m,m+2),10),o=this.getFixedTime(i,r,u)),0===(n.time=o).length?e:a.reduce(function(e,t){switch(t){case"s":return e+n.addLeadingZero(o[2]);case"m":return e+n.addLeadingZero(o[1]);case"h":return e+n.addLeadingZero(o[0])}},"")},getFixedTime:function(e,t,r){return r=Math.min(parseInt(r||0,10),60),t=Math.min(t,60),[e=Math.min(e,60),t,r]},addLeadingZero:function(e){return(e<10?"0":"")+e}},e.exports=r},function(e,t){"use strict";function r(e,t){var r=this;r.delimiter=t||""===t?t:" ",r.delimiterRE=t?new RegExp("\\"+t,"g"):"",r.formatter=e}r.prototype={setFormatter:function(e){this.formatter=e},format:function(e){var t=this;t.formatter.clear();for(var r,i="",n=!1,a=0,o=(e=(e=(e=e.replace(/[^\d+]/g,"")).replace(/^\+/,"B").replace(/\+/g,"").replace("B","+")).replace(t.delimiterRE,"")).length;a<o;a++)r=t.formatter.inputDigit(e.charAt(a)),/[\s()-]/g.test(r)?(i=r,n=!0):n||(i=r);return(i=i.replace(/[()]/g,"")).replace(/[\s-]/g,t.delimiter)}},e.exports=r},function(e,t){"use strict";var r={blocks:{uatp:[4,5,6],amex:[4,6,5],diners:[4,6,4],discover:[4,4,4,4],mastercard:[4,4,4,4],dankort:[4,4,4,4],instapayment:[4,4,4,4],jcb15:[4,6,5],jcb:[4,4,4,4],maestro:[4,4,4,4],visa:[4,4,4,4],mir:[4,4,4,4],unionPay:[4,4,4,4],general:[4,4,4,4]},re:{uatp:/^(?!1800)1\d{0,14}/,amex:/^3[47]\d{0,13}/,discover:/^(?:6011|65\d{0,2}|64[4-9]\d?)\d{0,12}/,diners:/^3(?:0([0-5]|9)|[689]\d?)\d{0,11}/,mastercard:/^(5[1-5]\d{0,2}|22[2-9]\d{0,1}|2[3-7]\d{0,2})\d{0,12}/,dankort:/^(5019|4175|4571)\d{0,12}/,instapayment:/^63[7-9]\d{0,13}/,jcb15:/^(?:2131|1800)\d{0,11}/,jcb:/^(?:35\d{0,2})\d{0,12}/,maestro:/^(?:5[0678]\d{0,2}|6304|67\d{0,2})\d{0,12}/,mir:/^220[0-4]\d{0,12}/,visa:/^4\d{0,15}/,unionPay:/^(62|81)\d{0,14}/},getStrictBlocks:function(e){var t=e.reduce(function(e,t){return e+t},0);return e.concat(19-t)},getInfo:function(e,t){var a,o,i=r.blocks,n=r.re;for(a in t=!!t,n)if(n[a].test(e))return o=i[a],{type:a,blocks:t?this.getStrictBlocks(o):o};return{type:"unknown",blocks:t?this.getStrictBlocks(i.general):i.general}}};e.exports=r},function(e,t){"use strict";e.exports={noop:function(){},strip:function(e,t){return e.replace(t,"")},getPostDelimiter:function(e,t,r){if(0===r.length)return e.slice(-t.length)===t?t:"";var i="";return r.forEach(function(t){e.slice(-t.length)===t&&(i=t)}),i},getDelimiterREByDelimiter:function(e){return new RegExp(e.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1"),"g")},getNextCursorPosition:function(e,t,r,i,n){return t.length===e?r.length:e+this.getPositionOffset(e,t,r,i,n)},getPositionOffset:function(e,t,r,i,n){t=this.stripDelimiters(t.slice(0,e),i,n),r=this.stripDelimiters(r.slice(0,e),i,n),e=t.length-r.length;return 0!=e?e/Math.abs(e):0},stripDelimiters:function(e,t,r){var i=this;return 0===r.length?(t=t?i.getDelimiterREByDelimiter(t):"",e.replace(t,"")):(r.forEach(function(t){t.split("").forEach(function(t){e=e.replace(i.getDelimiterREByDelimiter(t),"")})}),e)},headStr:function(e,t){return e.slice(0,t)},getMaxLength:function(e){return e.reduce(function(e,t){return e+t},0)},getPrefixStrippedValue:function(e,t,r,i,n,a,o,l,s){if(0===r)return e;if(e===t&&""!==e)return"";if(s&&"-"==e.slice(0,1))return c="-"==i.slice(0,1)?i.slice(1):i,"-"+this.getPrefixStrippedValue(e.slice(1),t,r,c,n,a,o,l,s);if(i.slice(0,r)!==t&&!l)return o&&!i&&e?e:"";if(i.slice(-r)!==t&&l)return o&&!i&&e?e:"";var c=this.stripDelimiters(i,n,a);return e.slice(0,r)===t||l?e.slice(-r)!==t&&l?c.slice(0,-r-1):l?e.slice(0,-r):e.slice(r):c.slice(r)},getFirstDiffIndex:function(e,t){for(var r=0;e.charAt(r)===t.charAt(r);)if(""===e.charAt(r++))return-1;return r},getFormattedValue:function(e,t,r,i,n,a){var o="",l=0<n.length,s="";return 0===r?e:(t.forEach(function(t,c){var u,d;0<e.length&&(u=e.slice(0,t),d=e.slice(t),s=l?n[a?c-1:c]||s:i,a?(0<c&&(o+=s),o+=u):(o+=u,u.length===t&&c<r-1&&(o+=s)),e=d)}),o)},fixPrefixCursor:function(e,t,r,i){var n,o;e&&(n=e.value,r=r||i[0]||" ",!e.setSelectionRange||!t||t.length+r.length<=n.length||(o=2*n.length,setTimeout(function(){e.setSelectionRange(o,o)},1)))},checkFullSelection:function(e){try{return(window.getSelection()||document.getSelection()||{}).toString().length===e.length}catch(r){}return!1},setSelection:function(e,t,r){if(e===this.getActiveElement(r)&&!(e&&e.value.length<=t))if(e.createTextRange){r=e.createTextRange();r.move("character",t),r.select()}else try{e.setSelectionRange(t,t)}catch(n){console.warn("The input element type does not support selection")}},getActiveElement:function(e){e=e.activeElement;return e&&e.shadowRoot?this.getActiveElement(e.shadowRoot):e},isAndroid:function(){return navigator&&/android/i.test(navigator.userAgent)},isAndroidBackspaceKeydown:function(e,t){return!!(this.isAndroid()&&e&&t)&&t===e.slice(0,-1)}}},function(e,t){!function(t){"use strict";e.exports={assign:function(e,r){return(e=e||{}).creditCard=!!(r=r||{}).creditCard,e.creditCardStrictMode=!!r.creditCardStrictMode,e.creditCardType="",e.onCreditCardTypeChanged=r.onCreditCardTypeChanged||function(){},e.phone=!!r.phone,e.phoneRegionCode=r.phoneRegionCode||"AU",e.phoneFormatter={},e.time=!!r.time,e.timePattern=r.timePattern||["h","m","s"],e.timeFormat=r.timeFormat||"24",e.timeFormatter={},e.date=!!r.date,e.datePattern=r.datePattern||["d","m","Y"],e.dateMin=r.dateMin||"",e.dateMax=r.dateMax||"",e.dateFormatter={},e.numeral=!!r.numeral,e.numeralIntegerScale=0<r.numeralIntegerScale?r.numeralIntegerScale:0,e.numeralDecimalScale=0<=r.numeralDecimalScale?r.numeralDecimalScale:2,e.numeralDecimalMark=r.numeralDecimalMark||".",e.numeralThousandsGroupStyle=r.numeralThousandsGroupStyle||"thousand",e.numeralPositiveOnly=!!r.numeralPositiveOnly,e.stripLeadingZeroes=!1!==r.stripLeadingZeroes,e.signBeforePrefix=!!r.signBeforePrefix,e.tailPrefix=!!r.tailPrefix,e.swapHiddenInput=!!r.swapHiddenInput,e.numericOnly=e.creditCard||e.date||!!r.numericOnly,e.uppercase=!!r.uppercase,e.lowercase=!!r.lowercase,e.prefix=!e.creditCard&&!e.date&&r.prefix||"",e.noImmediatePrefix=!!r.noImmediatePrefix,e.prefixLength=e.prefix.length,e.rawValueTrimPrefix=!!r.rawValueTrimPrefix,e.copyDelimiter=!!r.copyDelimiter,e.initValue=void 0!==r.initValue&&null!==r.initValue?r.initValue.toString():"",e.delimiter=r.delimiter||""===r.delimiter?r.delimiter:r.date?"/":r.time?":":r.numeral?",":(r.phone," "),e.delimiterLength=e.delimiter.length,e.delimiterLazyShow=!!r.delimiterLazyShow,e.delimiters=r.delimiters||[],e.blocks=r.blocks||[],e.blocksLength=e.blocks.length,e.root="object"==typeof t&&t?t:window,e.document=r.document||e.root.document,e.maxLength=0,e.backspace=!1,e.result="",e.onValueChanged=r.onValueChanged||function(){},e}}}.call(t,function(){return this}())}],r={},t.m=e,t.c=r,t.p="",t(0);function t(i){if(r[i])return r[i].exports;var n=r[i]={exports:{},id:i,loaded:!1};return e[i].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var e,r}),function($){HappyForms.parts=HappyForms.parts||{},HappyForms.parts.multi_line_text={init:function(options){this.$form=options.form,this.type=this.$el.data("happyforms-type"),this.$input=$("textarea",this.$el),this.$counter=$(".happyforms-part__char-counter span.counter",this.$el),this.$input.on("blur",this.onBlur.bind(this)),this.$input.on("keyup",this.triggerChange.bind(this)),this.$input.on("change",this.triggerChange.bind(this)),this.$el.on("keyup",this.refreshCounter.bind(this)),this.refreshCounter(),$(".happyforms-part__char-counter").show()},getValueLength:function(){var mode=this.$input.attr("data-length-mode"),value=this.$input.val(),length=value.length;return length="word"===mode?(mode=value.match(/\w+/g))?mode.length:0:length},refreshCounter:function(){var length;parseInt(this.$input.attr("data-length"),10)<1||(length=this.getValueLength(),this.$counter.text(length))},onFocus:function(){this.$el.addClass("focus")},onBlur:function(){this.$el.removeClass("focus")},isFilled:function(){return""!==this.$input.val()},serialize:function(){return HappyForms.parts.base.serialize.apply(this,arguments)}}}(jQuery),function($){HappyForms.parts=HappyForms.parts||{},HappyForms.parts.email={init:function(){this.type=this.$el.data("happyforms-type"),this.$input=$("input",this.$el),this.$visualInput=$("input[type=email]",this.$el),this.$input.on("keyup",this.triggerChange.bind(this)),this.$input.on("change",this.triggerChange.bind(this)),this.$input.on("focus",this.onInputFocus.bind(this)),this.$visualInput.on("blur",this.onBlur.bind(this))}}}(jQuery),function($){HappyForms.parts=HappyForms.parts||{},HappyForms.parts.radio={init:function(){this.type=this.$el.data("happyforms-type"),this.$input=$("input",this.$el),this.$visualInput=$("input[type=email]",this.$el),this.$input.on("keyup",this.triggerChange.bind(this)),this.$input.on("change",this.triggerChange.bind(this)),this.$input.on("change",this.onRadioChange.bind(this)),this.$input.on("focus",this.onFocus.bind(this))},onRadioChange:function(e){var $otherRadio=$(".happyforms-part-option--other input[type=radio]",this.$el),$otherInput=$otherRadio.parent().nextAll("input"),$generalInput=$("input[type=text]",this.$el);$generalInput.prop("required",!1),$otherRadio.length&&$otherRadio.is(":checked")?($(e.target)[0]===$otherRadio[0]&&$otherInput.addClass("hf-show").trigger("focus"),""===this.$el.data("happyforms-required")&&$otherInput.prop("required",!0)):$generalInput.removeClass("hf-show")},onFocus:function(e){e=$(e.target);"text"===e.attr("type")&&e.prevAll("input[type=radio]").prop("checked",!0)},serialize:function(){var self=this;return this.$input.map(function(i,input){var input=$(input),$customInput=0;if("text"!==input.attr("type")){"text"===$(self.$input[i+1]).attr("type")&&($customInput=$(self.$input[i+1]));i={name:input.attr("name"),value:input.val()};if($customInput.length&&($customInput=$customInput.val(),i.value=[input.val(),$customInput],i.value=JSON.stringify(i.value)),input.is(":checked"))return i}}).toArray()}}}(jQuery),function($){HappyForms.parts=HappyForms.parts||{},HappyForms.parts.checkbox={init:function(){this.type=this.$el.data("happyforms-type"),this.$input=$("input",this.$el),this.$input.on("change",this.triggerChange.bind(this)),this.$input.on("change",this.onCheckboxChange.bind(this)),this.$input.on("focus",this.onFocus.bind(this))},onCheckboxChange:function(e){var $otherCheckbox=$(".happyforms-part-option--other input[type=checkbox]",this.$el),$otherInput=$otherCheckbox.parent().nextAll("input"),$generalInput=$("input[type=text]",this.$el);$generalInput.prop("required",!1),$otherCheckbox.length&&$otherCheckbox.is(":checked")?($(e.target)[0]===$otherCheckbox[0]&&$otherInput.addClass("hf-show").trigger("focus"),""===this.$el.data("happyforms-required")&&$otherInput.prop("required",!0)):$generalInput.removeClass("hf-show")},serialize:function(){var self=this;return this.$input.map(function(i,input){var input=$(input),$customInput=0;if("text"!==input.attr("type")){"text"===$(self.$input[i+1]).attr("type")&&($customInput=$(self.$input[i+1]));i={name:input.attr("name"),value:input.val()};if($customInput.length&&($customInput=$customInput.val(),i.value=[input.val(),$customInput],i.value=JSON.stringify(i.value)),input.is(":checked"))return i}}).toArray()},onFocus:function(e){e=$(e.target);"text"===e.attr("type")&&e.prevAll("input[type=checkbox]").prop("checked",!0)}}}(jQuery),function($){HappyForms.parts=HappyForms.parts||{},HappyForms.parts.select={init:function(options){this.type=this.$el.data("happyforms-type"),this.$input=$("[data-serialize]",this.$el),this.$input.on("change",this.triggerChange.bind(this)),this.$input.on("blur",this.onBlur.bind(this))},onBlur:function(){var $otherinput=$(".happyforms-part-option--other input[type=text]",this.$el);"999"===this.$input.val()?($otherinput.addClass("hf-show"),$otherinput.focus()):$otherinput.removeClass("hf-show")},serialize:function(){var self=this;return this.$input.map(function(i,select){var select=$(select,self.$el),$customInput=0,value=(999==select.val()&&($customInput=$(" .happyforms-part-option--other input[type=text]",self.$el)),select.val()),value=(null==value&&(value=""),{name:select.attr("name"),value:value});return $customInput.length&&($customInput=$customInput.val(),value.value=[select.val(),$customInput],value.value=JSON.stringify(value.value)),value}).toArray()}}}(jQuery),function($){HappyForms.parts=HappyForms.parts||{},HappyForms.parts.number={init:function(){this.type=this.$el.data("happyforms-type"),this.allowedKeys=["0","1","2","3","4","5","6","7","8","9","Meta","Delete","ArrowLeft","ArrowRight"];var self,decimalMark,delimiterMark,masked=this.$el.attr("data-mask");this.$input=$("input",this.$el),this.cleaveInstances=[],this.$input.on("keyup",this.onKeyUp.bind(this)),this.$input.on("change",this.triggerChange.bind(this)),this.$input.on("focus",this.onInputFocus.bind(this)),this.$input.on("blur",this.onBlur.bind(this)),this.numeralDecimalMark=this.$el.attr("data-decimal-mark")||"",this.delimiter=this.$el.attr("data-thousands-delimiter")||"",masked&&(decimalMark=(self=this).numeralDecimalMark,delimiterMark=this.delimiter,this.$input.each(function(){var $input=$(this),$input=new Cleave($input,{numeral:!0,numeralDecimalMark:decimalMark,delimiter:delimiterMark});self.cleaveInstances.push($input)})),this.onBlur()},onKeyUp:function(e){var value=$(e.target).val(),regex=new RegExp("[^0-9"+this.numeralDecimalMark+this.delimiter+"-]","g"),value=value.replace(regex,"");$(e.target).val(value),this.triggerChange()},reinit:function(){$.each(this.cleaveInstances,function(i,instance){var input=instance.element,rawValue=instance.getRawValue();instance.destroy(),input.value=rawValue}),this.init()}}}(jQuery),function($){HappyForms.parts=HappyForms.parts||{},HappyForms.parts.base={init:function(){this.type=this.$el.data("happyforms-type"),this.$input=$("input, textarea, select",this.$el),this.$input.on("keyup change",this.triggerChange.bind(this)),this.$input.on("blur",this.onBlur.bind(this)),this.$input.on("focus",this.onInputFocus.bind(this)),this.onBlur()},getType:function(){return this.type},onInputFocus:function(){this.$el.addClass("focus")},onBlur:function(){this.$el.is(".happyforms-part--label-as_placeholder")&&(this.isFilled()?this.$el.addClass("happyforms-part--filled"):this.$el.removeClass("happyforms-part--filled")),this.$el.removeClass("focus")},triggerChange:function(data){this.$el.trigger("happyforms-change",data)},isRequired:function(){return this.$el.is(":visible")&&this.$el.is("[data-happyforms-required]")},isFilled:function(){return 0<this.$input.filter(function(){var $input=$(this);return $input.is("[type=checkbox]")||$input.is("[type=radio]")?$input.is(":checked"):""!==$input.val()}).length},confirmationMatches:function(){var matches=!1,$input=this.$input,$input=($input=this.$visualInput?this.$visualInput:$input).map(function(){return $(this).val()}).toArray();return matches=2===$input.length?$input[0]===$input[1]:matches},requiresConfirmation:function(){return this.$el.is("[data-happyforms-require-confirmation]")},serialize:function(){return this.$input.map(function(i,input){var input=$(input),keyValue={name:input.attr("name"),value:input.val()};if(!input.is("[type=checkbox]")&&!input.is("[type=radio]")||input.is(":checked"))return keyValue}).toArray()},isValid:function(){var valid=!0;this.$el.data("happyforms-type");return this.$input?(this.isRequired()&&(valid=valid&&this.isFilled()),this.isRequired()&&this.requiresConfirmation()?valid&&this.confirmationMatches():valid):valid},destroy:function(){this.$el.data("HappyFormPart",!1)}},HappyForms.wrapPart=function($part,$form){var type=$part.data("happyforms-type"),partMethods=HappyForms.parts.base;HappyForms.parts[type]&&(partMethods=$.extend({},HappyForms.parts.base,HappyForms.parts[type])),$part.happyFormPart(partMethods,{form:$form})},HappyForms.Form=function(el){this.el=el,this.$el=$(this.el),this.$form=$("form",this.$el),this.$parts=$("[data-happyforms-type]",this.$form),this.$submits=$('[type="submit"], a.submit',this.$form),this.$submit=$('[type="submit"]',this.$form),this.$submitLinks=$("a.submit",this.$form),this.$step=$('[name="happyforms_step"]',this.$form),this.init()},HappyForms.Form.prototype={init:function(){var $form=this.$form;$("[data-happyforms-type]",this.$form).each(function(){var $part=$(this);$part.data("happyforms-type");HappyForms.wrapPart($part,$form)}),this.$el.trigger("happyforms-change"),this.$el.trigger("happyforms-init"),this.$form.off("submit"),this.$submit.off("click"),this.$submitLinks.off("click"),this.$form.on("submit",this.submit.bind(this)),this.$submit.on("click",this.buttonSubmit.bind(this)),this.$submitLinks.on("click",this.linkSubmit.bind(this)),this.$el.on("happyforms-scrolltop",this.onScrollTop.bind(this))},detach:function(){this.$el.off("happyforms-change"),this.$el.off("happyforms-scrolltop"),$("[data-happyforms-type]",this.$form).remove()},serialize:function(submitEl){for(var action=$("[name=action]",this.$form).val(),form_id=$("[name=happyforms_form_id]",this.$form).val(),referer=$("[name=_wp_http_referer]",this.$form).val(),formData=[{name:"action",value:action},{name:"happyforms_form_id",value:form_id},{name:"happyforms_step",value:this.$step.val()},{name:"referer",value:referer}],honeypotNames=["single_line_text","multi_line_text","number"],h=0;h<honeypotNames.length;h++){var inputName=form_id+"-"+honeypotNames[h],$input=$("[name="+inputName+"]");if($input.length){formData.push({name:inputName,value:$input.val()});break}}action=$("[data-happyforms-type]",this.$form).map(function(i,part){return $(part).happyFormPart("serialize")}).toArray().filter(function(entry){return null!==entry.name&&void 0!==entry.name});return formData.concat(action).map(function(part){return part.name+"="+encodeURIComponent(part.value)}).join("&")},buttonSubmit:function(e){e.target.hasAttribute("data-step")&&this.$step.val(e.target.getAttribute("data-step"))},linkSubmit:function(e){e.preventDefault(),e.stopImmediatePropagation(),e.target.hasAttribute("data-step")&&this.$step.val(e.target.getAttribute("data-step")),this.$form.trigger("submit")},submit:function(e){e.preventDefault(),this.$form.addClass("happyforms-form--submitting"),this.$submits.attr("disabled","disabled"),$.ajax({type:"post",data:this.serialize(e.target)}).done(this.onSubmitComplete.bind(this))},onSubmitComplete:function(response){if(this.$form.trigger("happyforms.submitted",response),!response.data)return!1;var elTopOffset,$notices;response.data.html&&(response=$(response.data.html),$("[data-happyforms-type]",this.$form).each(function(){$(this).trigger("happyforms.detach")}),this.detach(),this.$el.replaceWith(response),this.$el=response,this.$el.happyForm(),(response=$("form",this.$el)).attr("data-happyforms-scroll-disabled")||(this.$el.get(0).getBoundingClientRect().top<0&&(elTopOffset=this.$el.offset().top,$notices=$(".happyforms-message-notices",this.$el),response.is(".happyforms-form--notices-below")&&$notices.length&&(elTopOffset=$notices.offset().top),($notices=response.attr("data-happyforms-scroll-offset"))&&(elTopOffset+=$notices=parseInt($notices,10)),this.$el.trigger("happyforms-scrolltop",elTopOffset)),!$(".happyforms-message-notice.error",response).length&&this.$el.hasClass("happyforms-form--hide-on-submit")&&$(".happyforms-part",response).hide()))},onScrollTop:function(e,offset){e.isDefaultPrevented()||$("html, body").animate({scrollTop:offset+"px"},500)}},HappyForms.Part=function(el){this.el=el,this.$el=$(this.el)},$.fn.happyFormPart=function(method){if("object"==typeof method){var part=new HappyForms.Part(this);$.extend(part,method),$(this).data("HappyFormPart",part),part.init.apply(part,Array.prototype.slice.call(arguments,1))}else{part=$(this).data("HappyFormPart");if(part&&part[method])return part[method].apply(part,Array.prototype.slice.call(arguments,1))}},$.fn.happyForm=function(method){this.each(function(){if(method){var instance=$.data(this,"HappyForm");if(instance&&instance[method])return instance[method].apply(instance,Array.prototype.slice.call(arguments,1))}else $.data(this,"HappyForm",new HappyForms.Form(this,arguments))})},$(function(){$(".happyforms-form").happyForm()})}(jQuery);
core/assets/css/admin.css CHANGED
@@ -204,6 +204,7 @@ p.happyforms-message-nav span.divider:last-child {
204
  */
205
  .edit-post-visual-editor .happyforms-block-form-selector-wrap .components-select-control__input {
206
  padding: 0 10px;
 
207
  }
208
 
209
  .happyforms-block-placeholder__control-group {
204
  */
205
  .edit-post-visual-editor .happyforms-block-form-selector-wrap .components-select-control__input {
206
  padding: 0 10px;
207
+ max-width: 100%;
208
  }
209
 
210
  .happyforms-block-placeholder__control-group {
core/assets/js/lib/happyforms-select.js DELETED
@@ -1,527 +0,0 @@
1
- (function ($) {
2
- 'use strict';
3
-
4
- var HappyFormsSelect = function( el, options ) {
5
- this.el = el;
6
- this.$el = $( this.el );
7
-
8
- this.required = options.required;
9
- this.keepFocus = false;
10
- this.$input = options.$input;
11
- this.$select = options.$select;
12
- this.$placeholder = $( 'li.happyforms-custom-select-dropdown__placeholder', this.$select );
13
- this.$noResults = $( 'li.happyforms-custom-select-dropdown__not-found', this.$select );
14
- this.searchable = options.searchable;
15
- this.$clicked = null;
16
-
17
- var autocompleteDefaults = {
18
- url: '',
19
- apiKey: '',
20
- source: '',
21
- trigger: '',
22
- minLength: 3,
23
- delay: 0,
24
- partial: false
25
- };
26
-
27
- this.autocompleteOptions = $.extend( {}, autocompleteDefaults, options.autocompleteOptions );
28
-
29
- this.defaultValue = '';
30
- this.defaultLabel = '';
31
- this.placeholderText = this.$placeholder.text();
32
- this.autocompleteTimeout = null;
33
-
34
- this.init();
35
- }
36
-
37
- HappyFormsSelect.prototype.init = function() {
38
- this.$el.prop( 'readonly', true );
39
-
40
- if ( this.searchable && 'false' !== this.searchable ) {
41
- this.$el.prop( 'readonly', false );
42
- }
43
-
44
- this.defaultValue = this.$input.val();
45
- this.defaultLabel = this.$el.val();
46
-
47
- if ( '' === this.defaultLabel && '' === this.defaultValue && this.$placeholder.length ) {
48
- this.defaultLabel = this.placeholderText;
49
- }
50
-
51
- this.$el.on( 'keyup keypress', this.handleKeyUp.bind( this ) );
52
- this.$el.on( 'keydown', this.handleKeyDown.bind( this ) );
53
- this.$el.on( 'focus', this.handleFocus.bind( this ) );
54
- this.$el.on( 'blur', this.handleBlur.bind( this ) );
55
- this.$select.on( 'click', 'li', this.onItemSelect.bind( this ) );
56
- this.$el.on( 'change', this.onChange.bind( this ) );
57
- $( window ).on( 'click', this.onOutsideClick.bind( this ) );
58
-
59
- if ( 'autocomplete' !== this.searchable ) {
60
- this.$el.on( 'click', this.handleClick.bind( this ) );
61
- this.$el.parent().on( 'click', this.handleClick.bind( this ) );
62
- }
63
-
64
- $( document ).on( 'mousedown', this.mouseClickDown.bind( this ) );
65
-
66
- this.$el.on( 'happyFormsSelect.submitted', this.navigateDropdown.bind( this ) );
67
- }
68
-
69
- HappyFormsSelect.prototype.mouseClickDown = function( e ) {
70
- var parent = $( e.target ).parents( '.happyforms-form');
71
-
72
- if ( parent.length ) {
73
- this.$clicked = $(e.target);
74
- }
75
- }
76
-
77
- HappyFormsSelect.prototype.handleClick = function( e ) {
78
- e.stopPropagation();
79
-
80
- this.$el.trigger( 'focus' );
81
- this.toggleDropdown();
82
- }
83
-
84
- HappyFormsSelect.prototype.handleFocus = function( e ) {
85
- this.keepFocus = true;
86
- var searchVal = this.$el.val();
87
-
88
- this.$el.val('');
89
-
90
- if ( 'autocomplete' !== this.searchable ) {
91
- this.hideAllInstances();
92
- }
93
-
94
- this.$el.val( searchVal );
95
- }
96
-
97
- HappyFormsSelect.prototype.handleBlur = function( e ) {
98
- var $parent = this.$clicked.parents( '.happyforms-custom-select-dropdown' );
99
-
100
- if( ! $parent.length ){
101
- this.keepFocus = false;
102
- window.setTimeout( this.hideDropdown.bind( this ), 200 );
103
- }
104
- }
105
-
106
- HappyFormsSelect.prototype.hideAllInstances = function() {
107
- $( '.happyforms-custom-select-dropdown' ).not( this.$select ).hide();
108
- }
109
-
110
- HappyFormsSelect.prototype.toggleDropdown = function() {
111
- if ( ! this.$select.is( ':visible' ) ) {
112
- this.hideAllInstances();
113
-
114
- this.$input.trigger( 'focus' );
115
- this.$select.show();
116
-
117
- this.keepFocus = true;
118
- } else {
119
- this.hideDropdown();
120
- }
121
- }
122
-
123
- HappyFormsSelect.prototype.onOutsideClick = function( e ) {
124
- if ( ! this.el.contains(e.target).length && this.$select.is( ':visible' ) ) {
125
- this.hideDropdown();
126
- }
127
- }
128
-
129
- HappyFormsSelect.prototype.hideDropdown = function() {
130
- if ( ! this.keepFocus ) {
131
- this.$select.hide();
132
-
133
- if ( 'true' === this.searchable ) {
134
- var searchText = this.$el.val();
135
-
136
- if( '' === searchText && ! this.required ) {
137
- this.$el.val( '' );
138
- this.$input.val( '' );
139
- } else if( '' !== searchText && '' === this.defaultValue ) {
140
- this.$el.val( '' );
141
- } else if ( '' !== this.defaultValue && this.defaultLabel !== searchText ) {
142
- this.$el.val( this.defaultLabel );
143
- }
144
-
145
- $( 'li', this.$select ).removeClass( 'active' );
146
- $( 'li.happyforms-dropdown-item', this.$select ).show();
147
- this.$noResults.hide();
148
- }
149
- }
150
- }
151
-
152
- HappyFormsSelect.prototype.onItemSelect = function( e ) {
153
- e.stopPropagation();
154
-
155
- var $li = $( e.currentTarget );
156
-
157
- if ( 'undefined' !== typeof $li.attr( 'data-select-disabled' ) ) {
158
- return;
159
- }
160
-
161
- if ( 'undefined' !== typeof $li.attr( 'data-value' ) ) {
162
- this.setValue( $li.data('value').toString() );
163
- }
164
- this.keepFocus = false;
165
- this.hideDropdown();
166
- }
167
-
168
- HappyFormsSelect.prototype.handleKeyDown = function( e ) {
169
- switch ( e.keyCode ) {
170
- case 38:
171
- case 40:
172
- e.preventDefault();
173
- break;
174
- default:
175
- break;
176
- }
177
- }
178
-
179
- HappyFormsSelect.prototype.navigateDropdown = function ( e, windowEvent ) {
180
- this.handleKeyUp( windowEvent );
181
- }
182
-
183
- HappyFormsSelect.prototype.handleKeyUp = function( e ) {
184
- switch ( e.keyCode ) {
185
- case 27:
186
- this.keepFocus = false;
187
- this.hideDropdown();
188
- break;
189
- case 40:
190
- if ( ! this.$select.is( ':visible' ) ) {
191
- this.toggleDropdown();
192
- }
193
-
194
- this.navigateOptions( 'down' );
195
- break;
196
- case 38:
197
- if ( ! this.$select.is( ':visible' ) ) {
198
- this.toggleDropdown();
199
- }
200
-
201
- this.navigateOptions( 'up' );
202
- break;
203
- case 13:
204
- e.preventDefault();
205
-
206
- var $focusedItem = $( 'li.active', this.$select );
207
-
208
- if ( $focusedItem.length ) {
209
- this.setValue( $focusedItem.data('value').toString() );
210
- }
211
-
212
- this.handleBlur();
213
- break;
214
- case 9:
215
- case 16:
216
- e.preventDefault();
217
-
218
- break;
219
- default:
220
- if ('autocomplete' === this.searchable) {
221
- var trigger = this.autocompleteOptions.trigger;
222
-
223
- if ( trigger.length && trigger !== e.key ) {
224
- break;
225
- }
226
-
227
- this.getSuggestions();
228
- } else if ( "true" === this.searchable ) {
229
- this.searchOptions();
230
- } else {
231
- if( 'keyup' === e.type ){
232
- this.gotoOption( e );
233
- }
234
- }
235
- break;
236
- }
237
- }
238
-
239
- HappyFormsSelect.prototype.onChange = function( e ) {
240
- var value = $( e.target ).val();
241
-
242
- if ( 'autocomplete' === this.searchable ) {
243
- this.$el.val( value );
244
- this.$input.val( value );
245
- }
246
- }
247
-
248
- HappyFormsSelect.prototype.getSuggestions = function() {
249
- var self = this;
250
- var value = this.getValue();
251
-
252
- if ( ! value.length ) {
253
- this.hideDropdown();
254
- this.clearOptions();
255
-
256
- return;
257
- }
258
-
259
- if ( value.length < this.autocompleteOptions.minLength ) {
260
- return;
261
- }
262
-
263
- var trigger = this.autocompleteOptions.trigger;
264
- var delay = this.autocompleteOptions.delay;
265
-
266
- if ( trigger.length ) {
267
- if ( -1 === value.indexOf( trigger ) ) {
268
- this.hideDropdown();
269
- this.clearOptions();
270
-
271
- return;
272
- }
273
-
274
- delay = 0;
275
- }
276
-
277
- var source = this.autocompleteOptions.source;
278
- var partial = this.autocompleteOptions.partial;
279
- var autocompleteData = [];
280
-
281
- if ( 'string' === typeof source ) {
282
- if ( ! this.autocompleteTimeout ) {
283
- clearTimeout( this.autocompleteTimeout );
284
-
285
- this.autocompleteTimeout = setTimeout( function() {
286
- self.autocompleteTimeout = null;
287
-
288
- $.get( self.autocompleteOptions.url, {
289
- action: source,
290
- key: self.autocompleteOptions.apiKey,
291
- term: self.getValue()
292
- }, function( data ) {
293
- autocompleteData = data;
294
-
295
- self.clearOptions();
296
- self.handleAutocomplete( autocompleteData, partial, trigger );
297
-
298
- return;
299
- } );
300
- }, delay );
301
- }
302
- }
303
-
304
- if ( 'object' === typeof source ) {
305
- autocompleteData = source;
306
-
307
- if ( ! this.autocompleteTimeout ) {
308
- clearTimeout( this.autocompleteTimeout );
309
-
310
- this.autocompleteTimeout = setTimeout( function() {
311
- self.autocompleteTimeout = null;
312
-
313
- if ( ! partial ) {
314
- autocompleteData = $.grep( autocompleteData, function( n, i ) {
315
- return ( -1 !== n.toLowerCase().indexOf( self.$el.val().toLowerCase() ) );
316
- } );
317
- }
318
-
319
- self.clearOptions();
320
- self.handleAutocomplete( autocompleteData, partial, trigger );
321
- }, delay );
322
- }
323
- }
324
- }
325
-
326
- HappyFormsSelect.prototype.handleAutocomplete = function( data, partial, trigger ) {
327
- if ( ! data.length ) {
328
- return;
329
- }
330
-
331
- var suggestions = [];
332
-
333
- if ( partial ) {
334
- var value = this.getValue().split( trigger );
335
- var baseValue = value[0];
336
-
337
- for ( var i = 0; i < data.length; i++ ) {
338
- suggestions.push( baseValue + trigger + data[i] );
339
- }
340
- } else {
341
- suggestions = data;
342
- }
343
-
344
- var liTemplate = '<li class="happyforms-dropdown-item happyforms-custom-select-dropdown__item" data-value="%value%" data-label="">%value%</li>';
345
-
346
- for ( var i = 0; i < suggestions.length; i++ ) {
347
- this.$select.append( liTemplate.replace( /%value%/g, suggestions[i] ) );
348
- }
349
-
350
- this.$select.show();
351
- this.bindAutocomplete();
352
- }
353
-
354
- HappyFormsSelect.prototype.bindAutocomplete = function() {
355
- this.$el.on( 'click.autocomplete', this.handleAutocompleteInputClick.bind(this) );
356
- this.$el.on( 'keyup.autocomplete', this.handleAutocompleteInputKeyUp.bind(this) );
357
- }
358
-
359
- HappyFormsSelect.prototype.handleAutocompleteInputClick = function( e ) {
360
- e.stopPropagation();
361
-
362
- this.toggleDropdown();
363
- }
364
-
365
- HappyFormsSelect.prototype.handleAutocompleteInputKeyUp = function( e ) {
366
- if ( 13 === e.keyCode ) {
367
- return;
368
- }
369
-
370
- this.searchOptions();
371
- }
372
-
373
- HappyFormsSelect.prototype.searchOptions = function() {
374
- var self = this;
375
- var value = this.$el.val();
376
- var $allItems = $( 'li.happyforms-dropdown-item', this.$select );
377
- var foundItems = 0;
378
-
379
- self.$noResults.hide();
380
-
381
- if ( value ) {
382
- $allItems.hide();
383
-
384
- $allItems.each( function( index, li ) {
385
- var $li = $( li );
386
- var liValue = 'undefined' === typeof $li.data( 'value' ) ? '' : $li.data( 'value' );
387
- var labelValue = 'undefined' === typeof $li.data( 'label' ) ? '' : $li.data( 'label' );
388
- if ( 'string' == typeof labelValue ) {
389
- var liLabel = ( labelValue.length ) ? labelValue.toLowerCase() : '';
390
- } else {
391
- var liLabel = labelValue.toString();
392
- }
393
-
394
- liValue = liValue.toString().toLowerCase();
395
- value = value.toString().toLowerCase();
396
-
397
- if ( -1 !== liLabel.indexOf( value ) ) {
398
- $li.show();
399
- foundItems = foundItems + 1;
400
- }
401
-
402
- if ( foundItems > 0 ) {
403
- self.$noResults.hide();
404
- self.$select.show();
405
- } else {
406
- self.$noResults.show();
407
- }
408
- } );
409
- } else {
410
- $allItems.show();
411
- }
412
- }
413
-
414
- HappyFormsSelect.prototype.gotoOption = function( e ) {
415
- var inputKey = String.fromCharCode( e.keyCode );
416
-
417
- var filteredOptions = $( 'li:not( [data-value=""] )', this.$select ).filter( function() {
418
- var text = this.textContent.toLowerCase();
419
- return text.charAt(0) === inputKey.toLowerCase();
420
- });
421
-
422
- var $currentItem = $( 'li.active', this.$select );
423
- var setActiveNext = false;
424
- var filteredLength = filteredOptions.length - 1;
425
-
426
- $.each( filteredOptions, function( index, li ) {
427
- if( setActiveNext ){
428
- $( li ).addClass( 'active' );
429
- return false;
430
- }
431
-
432
- if( filteredLength != index && $( li ).hasClass( 'active' ) ) {
433
- setActiveNext = true;
434
- }
435
- } );
436
-
437
- $currentItem.removeClass( 'active' );
438
-
439
- if( ! setActiveNext ) {
440
- $( filteredOptions[0] ).addClass( 'active' );
441
- }
442
- }
443
-
444
- HappyFormsSelect.prototype.navigateOptions = function( direction ) {
445
- if ( ! direction ) {
446
- return;
447
- }
448
-
449
- var $currentItem = $( 'li.active', this.$select );
450
-
451
- if ( ! $currentItem.length ) {
452
- $currentItem = $( 'li:first', this.$select );
453
- }
454
-
455
- var $prevItem = $currentItem.prev( ':not( [data-value=""] )' );
456
- var $nextItem = $currentItem.nextAll(':visible').first();
457
-
458
- if ( 'down' === direction ) {
459
- if ( $nextItem.length ) {
460
- this.$select.show();
461
- $currentItem.removeClass( 'active' );
462
- $nextItem.trigger( 'focus' ).addClass( 'active' );
463
- }
464
- }
465
-
466
- if ( 'up' === direction && $prevItem.length ) {
467
- this.$select.show();
468
- $currentItem.removeClass( 'active' );
469
- $prevItem.trigger( 'focus' ).addClass( 'active' );
470
- }
471
-
472
- $( 'li.active', this.$select )[0].scrollIntoView( { behavior: 'smooth', block: 'nearest', inline: 'nearest' } );
473
- }
474
-
475
- HappyFormsSelect.prototype.clearOptions = function() {
476
- var $allItems = $( 'li.happyforms-dropdown-item', this.$select );
477
-
478
- $allItems.remove();
479
- }
480
-
481
- HappyFormsSelect.prototype.setValue = function( value ) {
482
- if ( 'undefined' !== typeof value ) {
483
- var $li = $( 'li[data-value="' + value + '"]', this.$select );
484
-
485
- if ( $li.length ) {
486
- if ( $li.data('label') ) {
487
- this.$el.val( $li.data( 'label' ) );
488
- } else {
489
- this.$el.val( $li.data( 'value' ) );
490
- }
491
-
492
- this.$input.val( $li.data( 'value' ) );
493
- this.setDefaults( $li.data( 'value' ), $li.data( 'label' ) );
494
- } else {
495
- this.$el.val( this.defaultLabel );
496
- this.$input.val( this.defaultValue );
497
- }
498
- }
499
-
500
- this.hideDropdown();
501
- this.$input.trigger( 'blur' );
502
- this.$input.trigger( 'happyforms-change' );
503
- }
504
-
505
- HappyFormsSelect.prototype.getValue = function() {
506
- return this.$el.val();
507
- }
508
-
509
- HappyFormsSelect.prototype.setDefaults = function( value, label ) {
510
- this.defaultValue = value;
511
- this.defaultLabel = label;
512
- }
513
-
514
- $.fn.happyFormsSelect = function( method ) {
515
- this.each(function() {
516
- if ( 'object' === typeof method ) {
517
- $.data( this, 'HappyFormSelect', new HappyFormsSelect( this, method ) );
518
- } else {
519
- var methods = $.data( this, 'HappyFormSelect' );
520
-
521
- if ( methods && methods[method] ) {
522
- return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) );
523
- }
524
- }
525
- });
526
- }
527
- } )( jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
core/classes/class-dashboard-modals.php CHANGED
@@ -91,13 +91,13 @@ class HappyForms_Dashboard_Modals {
91
  wp_register_style(
92
  'happyforms-dashboard-modals-core',
93
  happyforms_get_plugin_url() . 'core/assets/css/dashboard-modals.css',
94
- array( 'wp-components' ), HAPPYFORMS_VERSION
95
  );
96
 
97
  wp_enqueue_style(
98
  'happyforms-dashboard-modals',
99
  happyforms_get_plugin_url() . 'inc/assets/css/dashboard-modals.css',
100
- array( 'happyforms-dashboard-modals-core' ), HAPPYFORMS_VERSION
101
  );
102
 
103
  wp_localize_script( 'happyforms-dashboard-modals', '_happyFormsDashboardModalsSettings', $this->get_script_settings() );
@@ -115,13 +115,13 @@ class HappyForms_Dashboard_Modals {
115
  wp_register_style(
116
  'happyforms-dashboard-modals-core',
117
  happyforms_get_plugin_url() . 'core/assets/css/dashboard-modals.css',
118
- array( 'wp-components' ), HAPPYFORMS_VERSION
119
  );
120
 
121
  wp_enqueue_style(
122
  'happyforms-dashboard-modals',
123
  happyforms_get_plugin_url() . 'inc/assets/css/dashboard-modals.css',
124
- array( 'happyforms-dashboard-modals-core' ), HAPPYFORMS_VERSION
125
  );
126
 
127
  wp_localize_script( 'happyforms-dashboard-modals', '_happyFormsDashboardModalsSettings', $this->get_script_settings() );
91
  wp_register_style(
92
  'happyforms-dashboard-modals-core',
93
  happyforms_get_plugin_url() . 'core/assets/css/dashboard-modals.css',
94
+ array( 'wp-components' ), happyforms_get_version()
95
  );
96
 
97
  wp_enqueue_style(
98
  'happyforms-dashboard-modals',
99
  happyforms_get_plugin_url() . 'inc/assets/css/dashboard-modals.css',
100
+ array( 'happyforms-dashboard-modals-core' ), happyforms_get_version()
101
  );
102
 
103
  wp_localize_script( 'happyforms-dashboard-modals', '_happyFormsDashboardModalsSettings', $this->get_script_settings() );
115
  wp_register_style(
116
  'happyforms-dashboard-modals-core',
117
  happyforms_get_plugin_url() . 'core/assets/css/dashboard-modals.css',
118
+ array( 'wp-components' ), happyforms_get_version()
119
  );
120
 
121
  wp_enqueue_style(
122
  'happyforms-dashboard-modals',
123
  happyforms_get_plugin_url() . 'inc/assets/css/dashboard-modals.css',
124
+ array( 'happyforms-dashboard-modals-core' ), happyforms_get_version()
125
  );
126
 
127
  wp_localize_script( 'happyforms-dashboard-modals', '_happyFormsDashboardModalsSettings', $this->get_script_settings() );
core/classes/class-form-assets.php CHANGED
@@ -49,25 +49,33 @@ class HappyForms_Form_Assets {
49
  <?php
50
  }
51
 
52
- private function get_frontend_script_dependencies( $forms ) {
53
- wp_register_script(
54
- 'happyforms-select',
55
- happyforms_get_plugin_url() . 'core/assets/js/lib/happyforms-select.js',
56
- array( 'jquery' ), HAPPYFORMS_VERSION, true
57
- );
58
 
59
- wp_register_script( 'happyforms-settings', '', array(), HAPPYFORMS_VERSION, true );
 
 
 
 
60
 
61
  $settings = apply_filters( 'happyforms_frontend_settings', array(
62
  'ajaxUrl' => admin_url( 'admin-ajax.php' )
63
- ) );
64
 
65
  wp_localize_script( 'happyforms-settings', '_happyFormsSettings', $settings );
66
 
67
- $dependencies = apply_filters(
68
- 'happyforms_frontend_dependencies',
69
- array( 'jquery', 'happyforms-settings' ), $forms
70
- );
 
 
 
 
71
 
72
  return $dependencies;
73
  }
@@ -81,11 +89,12 @@ class HappyForms_Form_Assets {
81
  }, 10, 3 );
82
 
83
  $dependencies = $this->get_frontend_script_dependencies( [ $form ] );
 
84
 
85
  wp_register_script(
86
  'happyforms-frontend',
87
- happyforms_get_plugin_url() . 'inc/assets/js/frontend.js',
88
- $dependencies, HAPPYFORMS_VERSION, true
89
  );
90
 
91
  wp_scripts()->all_deps( 'happyforms-frontend' );
@@ -172,7 +181,7 @@ class HappyForms_Form_Assets {
172
  wp_register_style(
173
  'happyforms-color',
174
  happyforms_get_frontend_stylesheet_url( 'color.css' ),
175
- array(), HAPPYFORMS_VERSION
176
  );
177
 
178
  $dependencies = apply_filters(
@@ -183,7 +192,7 @@ class HappyForms_Form_Assets {
183
  wp_register_style(
184
  'happyforms-layout',
185
  happyforms_get_frontend_stylesheet_url( 'layout.css' ),
186
- $dependencies, HAPPYFORMS_VERSION
187
  );
188
 
189
  $dependencies[] = 'happyforms-layout';
@@ -206,13 +215,14 @@ class HappyForms_Form_Assets {
206
  }
207
 
208
  $dependencies = $this->get_frontend_script_dependencies( $this->forms );
 
209
 
210
  wp_enqueue_script(
211
  'happyforms-frontend',
212
- happyforms_get_plugin_url() . 'inc/assets/js/frontend.js',
213
- $dependencies, HAPPYFORMS_VERSION, true
214
  );
215
-
216
  do_action( 'happyforms_print_scripts', $this->forms );
217
  }
218
 
49
  <?php
50
  }
51
 
52
+ private function get_frontend_script_url() {
53
+ $script_url = happyforms_get_plugin_url() . 'bundles/js/frontend.js';
54
+
55
+ if ( ! happyforms_concatenate_scripts() ) {
56
+ $script_url = happyforms_get_plugin_url() . 'inc/assets/js/frontend.js';
57
+ }
58
 
59
+ return $script_url;
60
+ }
61
+
62
+ private function get_frontend_script_dependencies( $forms ) {
63
+ wp_register_script( 'happyforms-settings', '', array(), happyforms_get_version(), true );
64
 
65
  $settings = apply_filters( 'happyforms_frontend_settings', array(
66
  'ajaxUrl' => admin_url( 'admin-ajax.php' )
67
+ ), $forms );
68
 
69
  wp_localize_script( 'happyforms-settings', '_happyFormsSettings', $settings );
70
 
71
+ $dependencies = array( 'jquery', 'happyforms-settings' );
72
+
73
+ if ( ! happyforms_concatenate_scripts() ) {
74
+ $dependencies = apply_filters(
75
+ 'happyforms_frontend_dependencies',
76
+ $dependencies, $forms
77
+ );
78
+ }
79
 
80
  return $dependencies;
81
  }
89
  }, 10, 3 );
90
 
91
  $dependencies = $this->get_frontend_script_dependencies( [ $form ] );
92
+ $script_url = $this->get_frontend_script_url();
93
 
94
  wp_register_script(
95
  'happyforms-frontend',
96
+ $script_url,
97
+ $dependencies, happyforms_get_version(), true
98
  );
99
 
100
  wp_scripts()->all_deps( 'happyforms-frontend' );
181
  wp_register_style(
182
  'happyforms-color',
183
  happyforms_get_frontend_stylesheet_url( 'color.css' ),
184
+ array(), happyforms_get_version()
185
  );
186
 
187
  $dependencies = apply_filters(
192
  wp_register_style(
193
  'happyforms-layout',
194
  happyforms_get_frontend_stylesheet_url( 'layout.css' ),
195
+ $dependencies, happyforms_get_version()
196
  );
197
 
198
  $dependencies[] = 'happyforms-layout';
215
  }
216
 
217
  $dependencies = $this->get_frontend_script_dependencies( $this->forms );
218
+ $script_url = $this->get_frontend_script_url();
219
 
220
  wp_enqueue_script(
221
  'happyforms-frontend',
222
+ $script_url,
223
+ $dependencies, happyforms_get_version(), true
224
  );
225
+
226
  do_action( 'happyforms_print_scripts', $this->forms );
227
  }
228
 
core/classes/class-form-controller.php CHANGED
@@ -640,12 +640,20 @@ class HappyForms_Form_Controller {
640
 
641
  if ( ! is_wp_error( $duplicate_id ) ) {
642
  $form_meta = get_post_meta( $form->ID );
643
- $form_meta = array_map( 'reset', $form_meta );
 
 
 
 
644
  $form_meta = array_map( 'maybe_unserialize', $form_meta );
645
-
646
  foreach ( $form_meta as $key => $value ) {
647
  add_post_meta( $duplicate_id, $key, $value );
648
  }
 
 
 
 
649
  }
650
 
651
  return $duplicate_id;
640
 
641
  if ( ! is_wp_error( $duplicate_id ) ) {
642
  $form_meta = get_post_meta( $form->ID );
643
+
644
+ $form_meta = array_map( function( $value ) {
645
+ return $value[0];
646
+ }, $form_meta );
647
+
648
  $form_meta = array_map( 'maybe_unserialize', $form_meta );
649
+
650
  foreach ( $form_meta as $key => $value ) {
651
  add_post_meta( $duplicate_id, $key, $value );
652
  }
653
+
654
+ $result = $this->to_array( get_post( $duplicate_id ) );
655
+
656
+ do_action( 'happyforms_form_duplicated', $result );
657
  }
658
 
659
  return $duplicate_id;
core/classes/class-form-option-limiter.php CHANGED
@@ -18,6 +18,7 @@ class HappyForms_Form_Option_Limiter {
18
  public function hook() {
19
  add_filter( 'happyforms_part_options', array( $this, 'get_part_options' ), 10, 3 );
20
  add_action( 'happyforms_submission_success', array( $this, 'submission_success' ), 10, 3 );
 
21
  }
22
 
23
  public function get_option_fields() {
@@ -140,6 +141,12 @@ class HappyForms_Form_Option_Limiter {
140
  happyforms_update_meta( $form['ID'], $this->counter_key, $meta_counters );
141
  }
142
 
 
 
 
 
 
 
143
  public function count_by_option( $form_id, $part_id, $option_id ) {
144
  $count = 0;
145
  $counters = happyforms_get_meta( $form_id, $this->counter_key, true );
18
  public function hook() {
19
  add_filter( 'happyforms_part_options', array( $this, 'get_part_options' ), 10, 3 );
20
  add_action( 'happyforms_submission_success', array( $this, 'submission_success' ), 10, 3 );
21
+ add_action( 'happyforms_form_duplicated', array( $this, 'form_duplicated' ) );
22
  }
23
 
24
  public function get_option_fields() {
141
  happyforms_update_meta( $form['ID'], $this->counter_key, $meta_counters );
142
  }
143
 
144
+ public function form_duplicated( $form ) {
145
+ if ( happyforms_meta_exists( $form['ID'], $this->counter_key ) ) {
146
+ happyforms_delete_meta( $form['ID'], $this->counter_key );
147
+ }
148
+ }
149
+
150
  public function count_by_option( $form_id, $part_id, $option_id ) {
151
  $count = 0;
152
  $counters = happyforms_get_meta( $form_id, $this->counter_key, true );
core/classes/class-happyforms-core.php CHANGED
@@ -260,19 +260,19 @@ class HappyForms_Core {
260
  wp_enqueue_style(
261
  'happyforms-admin',
262
  happyforms_get_plugin_url() . 'core/assets/css/admin.css',
263
- array(), HAPPYFORMS_VERSION
264
  );
265
 
266
  wp_enqueue_style(
267
  'happyforms-notices',
268
  happyforms_get_plugin_url() . 'core/assets/css/notice.css',
269
- array(), HAPPYFORMS_VERSION
270
  );
271
 
272
  wp_register_script(
273
  'happyforms-admin',
274
  happyforms_get_plugin_url() . 'core/assets/js/admin/dashboard.js',
275
- array( 'jquery-color' ), HAPPYFORMS_VERSION, true
276
  );
277
 
278
  global $pagenow;
@@ -512,7 +512,7 @@ class HappyForms_Core {
512
  wp_enqueue_style(
513
  'happyforms-preview',
514
  happyforms_get_plugin_url() . 'core/assets/css/preview.css',
515
- array(), HAPPYFORMS_VERSION
516
  );
517
  }
518
 
@@ -539,7 +539,7 @@ class HappyForms_Core {
539
  wp_enqueue_script(
540
  'happyforms-preview',
541
  happyforms_get_plugin_url() . 'inc/assets/js/preview.js',
542
- $preview_deps, HAPPYFORMS_VERSION, true
543
  );
544
 
545
  wp_localize_script(
260
  wp_enqueue_style(
261
  'happyforms-admin',
262
  happyforms_get_plugin_url() . 'core/assets/css/admin.css',
263
+ array(), happyforms_get_version()
264
  );
265
 
266
  wp_enqueue_style(
267
  'happyforms-notices',
268
  happyforms_get_plugin_url() . 'core/assets/css/notice.css',
269
+ array(), happyforms_get_version()
270
  );
271
 
272
  wp_register_script(
273
  'happyforms-admin',
274
  happyforms_get_plugin_url() . 'core/assets/js/admin/dashboard.js',
275
+ array( 'jquery-color' ), happyforms_get_version(), true
276
  );
277
 
278
  global $pagenow;
512
  wp_enqueue_style(
513
  'happyforms-preview',
514
  happyforms_get_plugin_url() . 'core/assets/css/preview.css',
515
+ array(), happyforms_get_version()
516
  );
517
  }
518
 
539
  wp_enqueue_script(
540
  'happyforms-preview',
541
  happyforms_get_plugin_url() . 'inc/assets/js/preview.js',
542
+ $preview_deps, happyforms_get_version(), true
543
  );
544
 
545
  wp_localize_script(
core/classes/class-wp-customize-form-manager.php CHANGED
@@ -285,7 +285,7 @@ class HappyForms_WP_Customize_Form_Manager {
285
  wp_enqueue_style(
286
  'happyforms-customize',
287
  happyforms_get_plugin_url() . 'core/assets/css/customize.css',
288
- array( 'wp-color-picker', 'wp-pointer' ), HAPPYFORMS_VERSION
289
  );
290
 
291
  wp_enqueue_style( 'code-editor' );
@@ -312,7 +312,7 @@ class HappyForms_WP_Customize_Form_Manager {
312
  wp_register_script(
313
  'happyforms-customize',
314
  happyforms_get_plugin_url() . 'inc/assets/js/customize.js',
315
- $customize_deps, HAPPYFORMS_VERSION, true
316
  );
317
 
318
  $data = array(
285
  wp_enqueue_style(
286
  'happyforms-customize',
287
  happyforms_get_plugin_url() . 'core/assets/css/customize.css',
288
+ array( 'wp-color-picker', 'wp-pointer' ), happyforms_get_version()
289
  );
290
 
291
  wp_enqueue_style( 'code-editor' );
312
  wp_register_script(
313
  'happyforms-customize',
314
  happyforms_get_plugin_url() . 'inc/assets/js/customize.js',
315
+ $customize_deps, happyforms_get_version(), true
316
  );
317
 
318
  $data = array(
core/classes/parts/class-part-checkbox.php CHANGED
@@ -171,7 +171,7 @@ class HappyForms_Part_Checkbox extends HappyForms_Form_Part {
171
  wp_enqueue_script(
172
  'part-checkbox',
173
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-checkbox.js',
174
- $deps, HAPPYFORMS_VERSION, true
175
  );
176
  }
177
 
@@ -435,7 +435,7 @@ class HappyForms_Part_Checkbox extends HappyForms_Form_Part {
435
  wp_register_script(
436
  'happyforms-checkbox',
437
  happyforms_get_plugin_url() . 'core/assets/js/frontend/checkbox.js',
438
- array(), HAPPYFORMS_VERSION, true
439
  );
440
 
441
  $deps[] = 'happyforms-checkbox';
171
  wp_enqueue_script(
172
  'part-checkbox',
173
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-checkbox.js',
174
+ $deps, happyforms_get_version(), true
175
  );
176
  }
177
 
435
  wp_register_script(
436
  'happyforms-checkbox',
437
  happyforms_get_plugin_url() . 'core/assets/js/frontend/checkbox.js',
438
+ array(), happyforms_get_version(), true
439
  );
440
 
441
  $deps[] = 'happyforms-checkbox';
core/classes/parts/class-part-email.php CHANGED
@@ -279,7 +279,7 @@ class HappyForms_Part_Email extends HappyForms_Form_Part {
279
  wp_enqueue_script(
280
  'part-email',
281
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-email.js',
282
- $deps, HAPPYFORMS_VERSION, true
283
  );
284
  }
285
 
@@ -301,7 +301,7 @@ class HappyForms_Part_Email extends HappyForms_Form_Part {
301
  wp_register_script(
302
  'happyforms-email',
303
  happyforms_get_plugin_url() . 'core/assets/js/frontend/email.js',
304
- array(), HAPPYFORMS_VERSION, true
305
  );
306
 
307
  $deps[] = 'happyforms-email';
279
  wp_enqueue_script(
280
  'part-email',
281
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-email.js',
282
+ $deps, happyforms_get_version(), true
283
  );
284
  }
285
 
301
  wp_register_script(
302
  'happyforms-email',
303
  happyforms_get_plugin_url() . 'core/assets/js/frontend/email.js',
304
+ array(), happyforms_get_version(), true
305
  );
306
 
307
  $deps[] = 'happyforms-email';
core/classes/parts/class-part-multi-line-text.php CHANGED
@@ -140,7 +140,7 @@ class HappyForms_Part_MultiLineText extends HappyForms_Form_Part {
140
  wp_enqueue_script(
141
  'part-multi-line-text',
142
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-multi-line-text.js',
143
- $deps, HAPPYFORMS_VERSION, true
144
  );
145
  }
146
 
@@ -332,7 +332,7 @@ class HappyForms_Part_MultiLineText extends HappyForms_Form_Part {
332
 
333
  wp_register_script(
334
  'happyforms-part-long-text',
335
- happyforms_get_plugin_url() . 'core/assets/js/frontend/long-text.js', array(), HAPPYFORMS_VERSION, true
336
  );
337
 
338
  $deps[] = 'happyforms-part-long-text';
140
  wp_enqueue_script(
141
  'part-multi-line-text',
142
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-multi-line-text.js',
143
+ $deps, happyforms_get_version(), true
144
  );
145
  }
146
 
332
 
333
  wp_register_script(
334
  'happyforms-part-long-text',
335
+ happyforms_get_plugin_url() . 'core/assets/js/frontend/long-text.js', array(), happyforms_get_version(), true
336
  );
337
 
338
  $deps[] = 'happyforms-part-long-text';
core/classes/parts/class-part-number.php CHANGED
@@ -270,7 +270,7 @@ class HappyForms_Part_Number extends HappyForms_Form_Part {
270
  wp_enqueue_script(
271
  'part-number',
272
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-number.js',
273
- $deps, HAPPYFORMS_VERSION, true
274
  );
275
  }
276
 
@@ -340,13 +340,13 @@ class HappyForms_Part_Number extends HappyForms_Form_Part {
340
  wp_register_script(
341
  'cleave',
342
  happyforms_get_plugin_url() . 'core/assets/js/lib/cleave.min.js',
343
- array(), HAPPYFORMS_VERSION
344
  );
345
 
346
  wp_register_script(
347
  'happyforms-part-number',
348
  happyforms_get_plugin_url() . 'core/assets/js/frontend/number.js',
349
- array( 'cleave' ), HAPPYFORMS_VERSION, true
350
  );
351
 
352
  $deps[] = 'happyforms-part-number';
270
  wp_enqueue_script(
271
  'part-number',
272
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-number.js',
273
+ $deps, happyforms_get_version(), true
274
  );
275
  }
276
 
340
  wp_register_script(
341
  'cleave',
342
  happyforms_get_plugin_url() . 'core/assets/js/lib/cleave.min.js',
343
+ array(), happyforms_get_version()
344
  );
345
 
346
  wp_register_script(
347
  'happyforms-part-number',
348
  happyforms_get_plugin_url() . 'core/assets/js/frontend/number.js',
349
+ array( 'cleave' ), happyforms_get_version(), true
350
  );
351
 
352
  $deps[] = 'happyforms-part-number';
core/classes/parts/class-part-radio.php CHANGED
@@ -157,7 +157,7 @@ class HappyForms_Part_Radio extends HappyForms_Form_Part {
157
  wp_enqueue_script(
158
  'part-radio',
159
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-radio.js',
160
- $deps, HAPPYFORMS_VERSION, true
161
  );
162
  }
163
 
@@ -337,7 +337,7 @@ class HappyForms_Part_Radio extends HappyForms_Form_Part {
337
  wp_register_script(
338
  'happyforms-radio-ext',
339
  happyforms_get_plugin_url() . 'core/assets/js/frontend/radio.js',
340
- array(), HAPPYFORMS_VERSION, true
341
  );
342
 
343
  $deps[] = 'happyforms-radio-ext';
157
  wp_enqueue_script(
158
  'part-radio',
159
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-radio.js',
160
+ $deps, happyforms_get_version(), true
161
  );
162
  }
163
 
337
  wp_register_script(
338
  'happyforms-radio-ext',
339
  happyforms_get_plugin_url() . 'core/assets/js/frontend/radio.js',
340
+ array(), happyforms_get_version(), true
341
  );
342
 
343
  $deps[] = 'happyforms-radio-ext';
core/classes/parts/class-part-select.php CHANGED
@@ -154,7 +154,7 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
154
  wp_enqueue_script(
155
  'part-select',
156
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-select.js',
157
- $deps, HAPPYFORMS_VERSION, true
158
  );
159
  }
160
 
@@ -360,7 +360,7 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
360
  wp_register_script(
361
  'happyforms-dropdown',
362
  happyforms_get_plugin_url() . 'core/assets/js/frontend/select.js',
363
- array(), HAPPYFORMS_VERSION, true
364
  );
365
 
366
  $deps[] = 'happyforms-dropdown';
154
  wp_enqueue_script(
155
  'part-select',
156
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-select.js',
157
+ $deps, happyforms_get_version(), true
158
  );
159
  }
160
 
360
  wp_register_script(
361
  'happyforms-dropdown',
362
  happyforms_get_plugin_url() . 'core/assets/js/frontend/select.js',
363
+ array(), happyforms_get_version(), true
364
  );
365
 
366
  $deps[] = 'happyforms-dropdown';
core/classes/parts/class-part-single-line-text.php CHANGED
@@ -214,7 +214,7 @@ class HappyForms_Part_SingleLineText extends HappyForms_Form_Part {
214
  wp_enqueue_script(
215
  'part-single-line-text',
216
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-single-line-text.js',
217
- $deps, HAPPYFORMS_VERSION, true
218
  );
219
  }
220
 
214
  wp_enqueue_script(
215
  'part-single-line-text',
216
  happyforms_get_plugin_url() . 'core/assets/js/parts/part-single-line-text.js',
217
+ $deps, happyforms_get_version(), true
218
  );
219
  }
220
 
core/helpers/helper-misc.php CHANGED
@@ -1042,3 +1042,15 @@ function happyforms_safe_array_merge( $a, $b ) {
1042
  }
1043
 
1044
  endif;
 
 
 
 
 
 
 
 
 
 
 
 
1042
  }
1043
 
1044
  endif;
1045
+
1046
+ if ( ! function_exists( 'happyforms_concatenate_scripts' ) ) :
1047
+
1048
+ function happyforms_concatenate_scripts() {
1049
+ $is_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );
1050
+ $is_debug = $is_debug || happyforms_is_preview();
1051
+ $concatenate = apply_filters( 'happyforms_concatenate_scripts', ! $is_debug );
1052
+
1053
+ return $concatenate;
1054
+ }
1055
+
1056
+ endif;
core/helpers/helper-styles.php CHANGED
@@ -25,7 +25,7 @@ if ( ! function_exists( 'happyforms_get_frontend_stylesheet_url' ) ):
25
 
26
  $stylesheets_url = happyforms_get_plugin_url() . 'core/assets/css';
27
  $stylesheets_url = apply_filters( 'happyforms_frontend_stylesheets_url', $stylesheets_url );
28
- $style_suffix = ( defined( 'HAPPYFORMS_UPGRADE_VERSION' ) ) ? HAPPYFORMS_UPGRADE_VERSION : HAPPYFORMS_VERSION;
29
 
30
  $style_url = "{$stylesheets_url}/{$stylesheet_name}?ver={$style_suffix}";
31
 
25
 
26
  $stylesheets_url = happyforms_get_plugin_url() . 'core/assets/css';
27
  $stylesheets_url = apply_filters( 'happyforms_frontend_stylesheets_url', $stylesheets_url );
28
+ $style_suffix = happyforms_get_version();
29
 
30
  $style_url = "{$stylesheets_url}/{$stylesheet_name}?ver={$style_suffix}";
31
 
core/helpers/helper-validation.php CHANGED
@@ -161,7 +161,7 @@ function happyforms_sanitize_list( $value, $choices = array() ) {
161
  }
162
 
163
  $value = array_intersect( $value, $choices );
164
- $value = implode( ', ', $value );
165
 
166
  return $value;
167
  }
161
  }
162
 
163
  $value = array_intersect( $value, $choices );
164
+ $value = implode( ',', $value );
165
 
166
  return $value;
167
  }
happyforms.php CHANGED
@@ -5,7 +5,7 @@
5
  * Plugin URI: https://happyforms.io
6
  * Description: We're changin' WordPress forms.
7
  * Author: Happyforms
8
- * Version: 1.14.3
9
  * Author URI: https://happyforms.io
10
  * Upgrade URI: https://happyforms.io/upgrade
11
  */
@@ -22,7 +22,15 @@ if ( defined( 'HAPPYFORMS_UPGRADE_VERSION' ) ) {
22
  /**
23
  * The current version of the plugin.
24
  */
25
- define( 'HAPPYFORMS_VERSION', '1.14.3' );
 
 
 
 
 
 
 
 
26
 
27
  if ( ! function_exists( 'happyforms_plugin_file' ) ):
28
  /**
5
  * Plugin URI: https://happyforms.io
6
  * Description: We're changin' WordPress forms.
7
  * Author: Happyforms
8
+ * Version: 1.15.0
9
  * Author URI: https://happyforms.io
10
  * Upgrade URI: https://happyforms.io/upgrade
11
  */
22
  /**
23
  * The current version of the plugin.
24
  */
25
+ define( 'HAPPYFORMS_VERSION', '1.15.0' );
26
+
27
+ if ( ! function_exists( 'happyforms_get_version' ) ):
28
+
29
+ function happyforms_get_version() {
30
+ return HAPPYFORMS_VERSION;
31
+ }
32
+
33
+ endif;
34
 
35
  if ( ! function_exists( 'happyforms_plugin_file' ) ):
36
  /**
inc/classes/class-happyforms.php CHANGED
@@ -209,19 +209,19 @@ class HappyForms extends HappyForms_Core {
209
  wp_enqueue_style(
210
  'happyforms-free-admin',
211
  happyforms_get_plugin_url() . 'inc/assets/css/admin.css',
212
- array( 'thickbox' ), HAPPYFORMS_VERSION
213
  );
214
 
215
  wp_enqueue_script(
216
  'happyforms-free-admin',
217
  happyforms_get_plugin_url() . 'inc/assets/js/admin/dashboard.js',
218
- array( 'happyforms-admin' ), HAPPYFORMS_VERSION, true
219
  );
220
 
221
  wp_enqueue_style(
222
  'happyforms-dashboard-modals-upgrade',
223
  happyforms_get_plugin_url() . 'inc/assets/css/dashboard-modals.css',
224
- array( 'happyforms-dashboard-modals' ), HAPPYFORMS_VERSION
225
  );
226
 
227
  $this->enqueue_onboarding_modal();
209
  wp_enqueue_style(
210
  'happyforms-free-admin',
211
  happyforms_get_plugin_url() . 'inc/assets/css/admin.css',
212
+ array( 'thickbox' ), happyforms_get_version()
213
  );
214
 
215
  wp_enqueue_script(
216
  'happyforms-free-admin',
217
  happyforms_get_plugin_url() . 'inc/assets/js/admin/dashboard.js',
218
+ array( 'happyforms-admin' ), happyforms_get_version(), true
219
  );
220
 
221
  wp_enqueue_style(
222
  'happyforms-dashboard-modals-upgrade',
223
  happyforms_get_plugin_url() . 'inc/assets/css/dashboard-modals.css',
224
+ array( 'happyforms-dashboard-modals' ), happyforms_get_version()
225
  );
226
 
227
  $this->enqueue_onboarding_modal();
inc/classes/class-message-admin.php CHANGED
@@ -58,8 +58,8 @@ class HappyForms_Message_Admin {
58
 
59
  $columns['contact'] = __( 'Contact', 'happyforms' );
60
  $columns['submission'] = __( 'Submission', 'happyforms' );
61
- $columns['form'] = __( 'In Response To', 'happyforms' );
62
- $columns['datetime'] = __( 'Submitted On', 'happyforms' );
63
 
64
  return $columns;
65
  }
58
 
59
  $columns['contact'] = __( 'Contact', 'happyforms' );
60
  $columns['submission'] = __( 'Submission', 'happyforms' );
61
+ $columns['form'] = __( 'In Response to', 'happyforms' );
62
+ $columns['datetime'] = __( 'Submitted on', 'happyforms' );
63
 
64
  return $columns;
65
  }
languages/happyforms.pot CHANGED
@@ -2,14 +2,14 @@
2
  # This file is distributed under the same license as the Happyforms (free) plugin.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Happyforms (free) 1.14.3\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/happyforms/\n"
7
  "Last-Translator: The Theme Foundry\n"
8
  "Language-Team: The Theme Foundry\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2022-03-21T07:58:03+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: happyforms\n"
@@ -3394,11 +3394,11 @@ msgid "Submission"
3394
  msgstr ""
3395
 
3396
  #: inc/classes/class-message-admin.php:61
3397
- msgid "In Response To"
3398
  msgstr ""
3399
 
3400
  #: inc/classes/class-message-admin.php:62
3401
- msgid "Submitted On"
3402
  msgstr ""
3403
 
3404
  #: inc/classes/class-message-admin.php:79
2
  # This file is distributed under the same license as the Happyforms (free) plugin.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Happyforms (free) 1.15.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/happyforms/\n"
7
  "Last-Translator: The Theme Foundry\n"
8
  "Language-Team: The Theme Foundry\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2022-04-04T13:32:16+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: happyforms\n"
3394
  msgstr ""
3395
 
3396
  #: inc/classes/class-message-admin.php:61
3397
+ msgid "In Response to"
3398
  msgstr ""
3399
 
3400
  #: inc/classes/class-message-admin.php:62
3401
+ msgid "Submitted on"
3402
  msgstr ""
3403
 
3404
  #: inc/classes/class-message-admin.php:79
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: contact form, contact form plugin, forms, form builder, custom form, intak
5
  Requires at least: 5.0
6
  Tested up to: 5.9.1
7
  Requires PHP: 7.0
8
- Stable tag: 1.14.3
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -151,6 +151,11 @@ Aw, honestly, the thought that you're writing about our contact form builder is
151
 
152
  == Changelog ==
153
 
 
 
 
 
 
154
  = 1.14.3 =
155
  * Improvement: Tidied up horizontal and vertical alignment of notices.
156
  * Improvement: Forms are now sorted by "last modified" date for easier management.
@@ -918,6 +923,9 @@ Aw, honestly, the thought that you're writing about our contact form builder is
918
 
919
  == Upgrade Notice ==
920
 
 
 
 
921
  = 1.14.3 =
922
  * Forms screen usability improvements, better notice alignment, miscellaneous style improvements.
923
 
5
  Requires at least: 5.0
6
  Tested up to: 5.9.1
7
  Requires PHP: 7.0
8
+ Stable tag: 1.15.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
151
 
152
  == Changelog ==
153
 
154
+ = 1.15.0 =
155
+ * Improvement: All frontend scripts are now bundled in a single file for better performance and cache friendliness.
156
+ * Bugfix: Duplicating a form would throw an error on PHP 8.0.
157
+ * Bugfix: "Limit how many times this choice can be submitted" counters were being wrongly copied to duplicated forms.
158
+
159
  = 1.14.3 =
160
  * Improvement: Tidied up horizontal and vertical alignment of notices.
161
  * Improvement: Forms are now sorted by "last modified" date for easier management.
923
 
924
  == Upgrade Notice ==
925
 
926
+ = 1.15.0 =
927
+ * Single-bundle frontend scripts for better performance, form duplication bugfixes.
928
+
929
  = 1.14.3 =
930
  * Forms screen usability improvements, better notice alignment, miscellaneous style improvements.
931