").appendTo(i),n=i.uniqueId().attr("id");return this._addClass(s,"ui-tooltip-content"),this._addClass(i,"ui-tooltip","ui-widget ui-widget-content"),i.appendTo(this._appendTo(e)),this.tooltips[n]={element:e,tooltip:i}},_find:function(t){var e=t.data("ui-tooltip-id");return e?this.tooltips[e]:null},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){var e=t.closest(".ui-front, dialog");return e.length||(e=this.document[0].body),e},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur"),o=s.element;n.target=n.currentTarget=o[0],e.close(n,!0),t("#"+i).remove(),o.data("ui-tooltip-title")&&(o.attr("title")||o.attr("title",o.data("ui-tooltip-title")),o.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),t.uiBackCompat!==!1&&t.widget("ui.tooltip",t.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),t.ui.tooltip;var f="ui-effects-",g="ui-effects-style",m="ui-effects-animated",_=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=h(),n=s._rgba=[];return i=i.toLowerCase(),f(l,function(t,o){var a,r=o.re.exec(i),l=r&&o.parse(r),h=o.space||"rgba";return l?(a=s[h](l),s[c[h].cache]=a[c[h].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,l=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],h=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=h.support={},p=t("
")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),h.fn=t.extend(h.prototype,{parse:function(n,a,r,l){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,l],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof h?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=h(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=h(t),n=s._space(),o=c[n],a=0===this.alpha()?h("transparent"):this,r=a[o.cache]||o.to(a._rgba),l=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],h=s[o],c=u[n.type]||{};null!==h&&(null===a?l[o]=h:(c.mod&&(h-a>c.mod/2?a+=c.mod:a-h>c.mod/2&&(a-=c.mod)),l[o]=i((h-a)*e+a,n)))}),this[n](l)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=h(e)._rgba;return h(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),h.fn.parse.prototype=h.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),l=Math.min(s,n,o),h=r-l,c=r+l,u=.5*c;return e=l===r?0:s===r?60*(n-o)/h+360:n===r?60*(o-s)/h+120:60*(s-n)/h+240,i=0===h?0:.5>=u?h/c:h/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,l=n.to,c=n.from;h.fn[s]=function(s){if(l&&!this[a]&&(this[a]=l(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=h(c(d)),n[a]=d,n):h(d)},f(o,function(e,i){h.fn[e]||(h.fn[e]=function(n){var o,a=t.type(n),l="alpha"===e?this._hsla?"hsla":"rgba":s,h=this[l](),c=h[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),h[i.idx]=n,this[l](h)))})})}),h.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=h(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(l){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(l){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=h(e.elem,i),e.end=h(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},h.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(_),function(){function e(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function i(e,i){var s,o,a={};for(s in i)o=i[s],e[s]!==o&&(n[s]||(t.fx.step[s]||!isNaN(parseFloat(o)))&&(a[s]=o));return a}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(_.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(n,o,a,r){var l=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",h=l.children?a.find("*").addBack():a;h=h.map(function(){var i=t(this);return{el:i,start:e(this)}}),o=function(){t.each(s,function(t,e){n[e]&&a[e+"Class"](n[e])})},o(),h=h.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),a.attr("class",r),h=h.map(function(){var e=this,i=t.Deferred(),s=t.extend({},l,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,h.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),l.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,n,o,a){return"boolean"==typeof s||void 0===s?n?t.effects.animateClass.call(this,s?{add:i}:{remove:i},n,o,a):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,n,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function e(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function i(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),n=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,o=n.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(m)||e(i)}}(t.expr.filters.animated)),t.uiBackCompat!==!1&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;s>i;i++)null!==e[i]&&t.data(f+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,n=e.length;n>s;s++)null!==e[s]&&(i=t.data(f+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("
").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(g,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(g)||"",t.removeData(g)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),n=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),"float":e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(f+"placeholder",i)),e.css({position:s,left:n.left,top:n.top}),i},removePlaceholder:function(t){var e=f+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function i(e){function i(){r.removeData(m),t.effects.cleanUp(r),"hide"===s.mode&&r.hide(),a()}function a(){t.isFunction(l)&&l.call(r[0]),t.isFunction(e)&&e()}var r=t(this);s.mode=c.shift(),t.uiBackCompat===!1||o?"none"===s.mode?(r[h](),a()):n.call(r[0],s,i):(r.is(":hidden")?"hide"===h:"show"===h)?(r[h](),a()):n.call(r[0],s,a)}var s=e.apply(this,arguments),n=t.effects.effect[s.effect],o=n.mode,a=s.queue,r=a||"fx",l=s.complete,h=s.mode,c=[],u=function(e){var i=t(this),s=t.effects.mode(i,h)||o;i.data(m,!0),c.push(s),o&&("show"===s||s===o&&"hide"===s)&&i.show(),o&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!n?h?this[h](s.duration,l):this.each(function(){l&&l.call(this)}):a===!1?this.each(u).each(i):this.queue(r,u).queue(r,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="show",this.effect.call(this,n)}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,l=o?a.scrollLeft():0,h=n.offset(),c={top:h.top-r,left:h.left-l,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("
").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-l,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}();var v=t.effects;t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},n=t(this),o=e.direction||"up",a=n.cssClip(),r={clip:t.extend({},a)},l=t.effects.createPlaceholder(n);r.clip[s[o][0]]=r.clip[s[o][1]],"show"===e.mode&&(n.cssClip(r.clip),l&&l.css(t.effects.clipToBox(r)),r.clip=a),l&&l.animate(t.effects.clipToBox(r),e.duration,e.easing),n.animate(r,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,n,o,a=t(this),r=e.mode,l="hide"===r,h="show"===r,c=e.direction||"up",u=e.distance,d=e.times||5,p=2*d+(h||l?1:0),f=e.duration/p,g=e.easing,m="up"===c||"down"===c?"top":"left",_="up"===c||"left"===c,v=0,b=a.queue().length;for(t.effects.createPlaceholder(a),o=a.css(m),u||(u=a["top"===m?"outerHeight":"outerWidth"]()/3),h&&(n={opacity:1},n[m]=o,a.css("opacity",0).css(m,_?2*-u:2*u).animate(n,f,g)),l&&(u/=Math.pow(2,d-1)),n={},n[m]=o;d>v;v++)s={},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g).animate(n,f,g),u=l?2*u:u/2;l&&(s={opacity:0},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g)),a.queue(i),t.effects.unshift(a,b,p+1)}),t.effects.define("clip","hide",function(e,i){var s,n={},o=t(this),a=e.direction||"vertical",r="both"===a,l=r||"horizontal"===a,h=r||"vertical"===a;s=o.cssClip(),n.clip={top:h?(s.bottom-s.top)/2:s.top,right:l?(s.right-s.left)/2:s.right,bottom:h?(s.bottom-s.top)/2:s.bottom,left:l?(s.right-s.left)/2:s.left},t.effects.createPlaceholder(o),"show"===e.mode&&(o.cssClip(n.clip),n.clip=s),o.animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("drop","hide",function(e,i){var s,n=t(this),o=e.mode,a="show"===o,r=e.direction||"left",l="up"===r||"down"===r?"top":"left",h="up"===r||"left"===r?"-=":"+=",c="+="===h?"-=":"+=",u={opacity:0};t.effects.createPlaceholder(n),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0)/2,u[l]=h+s,a&&(n.css(u),u[l]=c+s,u.opacity=1),n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("explode","hide",function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),i()}var o,a,r,l,h,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=e.mode,g="show"===f,m=p.show().css("visibility","hidden").offset(),_=Math.ceil(p.outerWidth()/d),v=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(l=m.top+o*v,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*_,h=a-(d-1)/2,p.clone().appendTo("body").wrap("
").css({position:"absolute",visibility:"visible",left:-a*_,top:-o*v}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:_,height:v,left:r+(g?h*_:0),top:l+(g?c*v:0),opacity:g?0:1}).animate({left:r+(g?0:h*_),top:l+(g?0:c*v),opacity:g?1:0},e.duration||500,e.easing,s)}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=e.size||15,l=/([0-9]+)%/.exec(r),h=!!e.horizFirst,c=h?["right","bottom"]:["bottom","right"],u=e.duration/2,d=t.effects.createPlaceholder(s),p=s.cssClip(),f={clip:t.extend({},p)},g={clip:t.extend({},p)},m=[p[c[0]],p[c[1]]],_=s.queue().length;l&&(r=parseInt(l[1],10)/100*m[a?0:1]),f.clip[c[0]]=r,g.clip[c[0]]=r,g.clip[c[1]]=0,o&&(s.cssClip(g.clip),d&&d.css(t.effects.clipToBox(g)),g.clip=p),s.queue(function(i){d&&d.animate(t.effects.clipToBox(f),u,e.easing).animate(t.effects.clipToBox(g),u,e.easing),i()}).animate(f,u,e.easing).animate(g,u,e.easing).queue(i),t.effects.unshift(s,_,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),n={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(n.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,n,o,a=t(this),r=["fontSize"],l=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],h=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,u="effect"!==c,d=e.scale||"both",p=e.origin||["middle","center"],f=a.css("position"),g=a.position(),m=t.effects.scaledDimensions(a),_=e.from||m,v=e.to||t.effects.scaledDimensions(a,0);t.effects.createPlaceholder(a),"show"===c&&(o=_,_=v,v=o),n={from:{y:_.height/m.height,x:_.width/m.width},to:{y:v.height/m.height,x:v.width/m.width}},("box"===d||"both"===d)&&(n.from.y!==n.to.y&&(_=t.effects.setTransition(a,l,n.from.y,_),v=t.effects.setTransition(a,l,n.to.y,v)),n.from.x!==n.to.x&&(_=t.effects.setTransition(a,h,n.from.x,_),v=t.effects.setTransition(a,h,n.to.x,v))),("content"===d||"both"===d)&&n.from.y!==n.to.y&&(_=t.effects.setTransition(a,r,n.from.y,_),v=t.effects.setTransition(a,r,n.to.y,v)),p&&(s=t.effects.getBaseline(p,m),_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left,v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left),a.css(_),("content"===d||"both"===d)&&(l=l.concat(["marginTop","marginBottom"]).concat(r),h=h.concat(["marginLeft","marginRight"]),a.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),o={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},a={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x};n.from.y!==n.to.y&&(o=t.effects.setTransition(i,l,n.from.y,o),a=t.effects.setTransition(i,l,n.to.y,a)),n.from.x!==n.to.x&&(o=t.effects.setTransition(i,h,n.from.x,o),a=t.effects.setTransition(i,h,n.to.x,a)),u&&t.effects.saveStyle(i),i.css(o),i.animate(a,e.duration,e.easing,function(){u&&t.effects.restoreStyle(i)})})),a.animate(v,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=a.offset();0===v.opacity&&a.css("opacity",_.opacity),u||(a.css("position","static"===f?"relative":f).offset(e),t.effects.saveStyle(a)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),n=e.mode,o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==n?0:100),a=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,o,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(a.from.opacity=1,a.to.opacity=0),t.effects.effect.size.call(this,a,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=o||a,l=2*(e.times||5)+(r?1:0),h=e.duration/l,c=0,u=1,d=s.queue().length;for((o||!s.is(":visible"))&&(s.css("opacity",0).show(),c=1);l>u;u++)s.animate({opacity:c},h,e.easing),c=1-c;s.animate({opacity:c},h,e.easing),s.queue(i),t.effects.unshift(s,d,l+1)}),t.effects.define("shake",function(e,i){var s=1,n=t(this),o=e.direction||"left",a=e.distance||20,r=e.times||3,l=2*r+1,h=Math.round(e.duration/l),c="up"===o||"down"===o?"top":"left",u="up"===o||"left"===o,d={},p={},f={},g=n.queue().length;for(t.effects.createPlaceholder(n),d[c]=(u?"-=":"+=")+a,p[c]=(u?"+=":"-=")+2*a,f[c]=(u?"-=":"+=")+2*a,n.animate(d,h,e.easing);r>s;s++)n.animate(p,h,e.easing).animate(f,h,e.easing);n.animate(p,h,e.easing).animate(d,h/2,e.easing).queue(i),t.effects.unshift(n,g,l+1)}),t.effects.define("slide","show",function(e,i){var s,n,o=t(this),a={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=e.mode,l=e.direction||"left",h="up"===l||"down"===l?"top":"left",c="up"===l||"left"===l,u=e.distance||o["top"===h?"outerHeight":"outerWidth"](!0),d={};t.effects.createPlaceholder(o),s=o.cssClip(),n=o.position()[h],d[h]=(c?-1:1)*u+n,d.clip=o.cssClip(),d.clip[a[l][1]]=d.clip[a[l][0]],"show"===r&&(o.cssClip(d.clip),o.css(h,d[h]),d.clip=s,d[h]=n),o.animate(d,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});var v;t.uiBackCompat!==!1&&(v=t.effects.define("transfer",function(e,i){t(this).transfer(e,i)}))});
\ No newline at end of file
diff --git a/keepassxc-browser/keepassxc-browser.css b/keepassxc-browser/keepassxc-browser.css
deleted file mode 100644
index b1fb5ff..0000000
--- a/keepassxc-browser/keepassxc-browser.css
+++ /dev/null
@@ -1,255 +0,0 @@
-.kpxc .ui-autocomplete li.ui-menu-item {
- text-align: left !important;
- font-size: .9em !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-family: 'Lato',sans-serif !important;
- color: #222222 !important;
-}
-
-.kpxc .ui-menu {
- z-index: 10000;
-}
-
-.ui-helper-hidden-accessible {
- display: none !important;
-}
-
-.kpxc .ui-dialog-titlebar-close {
- visibility: hidden !important;
-}
-
-.kpxc .ui-dialog {
- font-size: 12px !important;
- box-shadow: 0 4px 6px 0 hsla(0, 0%, 0%, 0.2);
- z-index: 2147483645;
-}
-
-.kpxc .ui-widget-overlay {
- opacity: 0.0 !important;
-}
-
-.kpxc .dialog-form .ui-dialog-content .ui-widget-content {
- max-height: 80px !important;
-}
-
-.kpxc .ui-dialog-titlebar {
- font-family: 'Lato',sans-serif;
- background-color: #6cac4d;
- color: #fff;
-}
-
-.kpxc .ui-dialog .ui-dialog-buttonpane {
- text-align: center !important;
-}
-
-.kpxc .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
- float: none !important;
-}
-
-.kpxc .ui-button .ui-button-text .ui-button {
- font-size: .10em !important;
-}
-
-input.genpw-text {
- font-size: .9em !important;
- padding: .4em;
- border-radius: 4px;
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- border-collapse: separate;
- width: 100%;
-}
-
-.genpw-input-group-addon {
- font-size: .9em !important;
- background-color: #eee;
- border: 1px solid #ccc;
- padding: .2em;
- border-radius: 4px;
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
- white-space: nowrap;
- vertical-align: middle;
- display: table-cell;
- border-collapse: separate;
-}
-
-.kpxc .genpw-input-group {
- position: relative;
- display: table;
- border-collapse: separate;
- width: 100%;
-}
-
-.cip-genpw-icon {
- position: absolute;
- cursor: pointer;
-}
-
-.cip-genpw-icon.key {
- background: url('chrome-extension://__MSG_@@extension_id__/icons/key.svg') right no-repeat;
- background-size: contain;
-}
-
-.cip-genpw-icon.key-moz {
- background: url('moz-extension://__MSG_@@extension_id__/icons/key.svg') right no-repeat;
- background-size: contain;
-}
-
-.kpxc .cip-genpw-checkbox {
- -webkit-appearance: checkbox !important;
- -moz-appearance: checkbox !important;
- appearance: checkbox !important;
-}
-
-#cip-genpw-btn-fillin {
- margin-right: 5px;
-}
-
-#cip-genpw-quality {
- text-align: center;
-}
-
-.b2c-modal-backdrop {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 2147483645;
-}
-
-.b2c-modal-backdrop:after {
- content: '';
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- background-color: #000000;
- opacity: 0.5;
- filter: alpha(opacity=50);
-}
-
-#b2c-cipDefine-fields {
- z-index: 2147483646;
-}
-
-#b2c-cipDefine-description {
- z-index: 2147483646;
- color: #efefef;
- border: 2px solid #555555;
- padding: 7px 5px;
- position: absolute;
- top: 100px;
- left: 150px;
- text-align: left;
- cursor: pointer;
- background-color: rgba(0,0,0,0.8);
- font-size: 15px;
-}
-
-#b2c-cipDefine-description div:first-of-type {
- margin-top: 0;
- padding-top: 0;
- text-align: left;
- color: #efefef;
- padding-bottom: 8px;
- font-weight: bold;
- font-size: 160%;
-}
-
-#b2c-cipDefine-description p {
- margin-top: 10px;
- padding-top: 10px;
- color: #efefef;
- border-top: 2px solid #666666;
- line-height: 110%;
-}
-
-#b2c-help {
- margin-bottom: 3px;
-}
-
-#b2c-keyboardHelp {
- font-size: 0.75em;
-}
-
-#b2c-keyboardHelp kbd {
- background-color: #eee;
- border-radius: 3px;
- border: 1px solid #b4b4b4;
- color: #333;
- display: inline-block;
- line-height: 1;
- padding: 2px 4px;
- white-space: nowrap;
-}
-
-.b2c-fixed-field {
- position: absolute;
- border: 2px solid #efefef;
- color: #fff;
- cursor: pointer;
- z-index: 2147483646;
- text-align: center;
- font-weight: bold;
- background-color:rgba(239,239,239,0.4);
-}
-
-.b2c-fixed-hover-field {
- border: 2px solid orange;
- background-color:rgba(255,165,239,0.4);
-}
-
-.b2c-fixed-password-field {
- border: 2px solid red;
- color: #efefef;
- background-color:rgba(255,0,0,0.4);
-}
-
-.b2c-fixed-username-field {
- border: 2px solid limegreen;
- color: #efefef;
- background-color:rgba(50,205,50,0.4);
-}
-
-.b2c-fixed-string-field {
- border: 2px solid deepskyblue;
- color: #efefef;
- background-color:rgba(30,144,255,0.4);
-}
-
-.b2c-input-append {
- display: inline-block;
- margin-bottom: 10px;
- white-space: nowrap;
- vertical-align: middle;
-}
-
-.b2c-input-append input,
-.b2c-input-append select,
-.b2c-input-append .b2c-uneditable-input,
-.b2c-input-append .b2c-dropdown-menu,
-.b2c-input-append .b2c-popover {
- font-size: 14px;
-}
-
-.b2c-input-append input,
-.b2c-input-append select,
-.b2c-input-append .b2c-uneditable-input {
- position: relative;
- margin-bottom: 0;
- *margin-left: 0;
- vertical-align: top;
- -webkit-border-radius: 0 4px 4px 0;
- -moz-border-radius: 0 4px 4px 0;
- border-radius: 0 4px 4px 0;
-}
-
-.b2c-input-append input:focus,
-.b2c-input-append select:focus,
-.b2c-input-append .b2c-b2c-uneditable-input:focus {
- z-index: 2;
-}
diff --git a/keepassxc-browser/keepassxc-browser.js b/keepassxc-browser/keepassxc-browser.js
deleted file mode 100755
index af1cc73..0000000
--- a/keepassxc-browser/keepassxc-browser.js
+++ /dev/null
@@ -1,2258 +0,0 @@
-'use strict';
-
-// contains already called method names
-var _called = {};
-_called.retrieveCredentials = false;
-_called.clearLogins = false;
-_called.manualFillRequested = 'none';
-let _loginId = -1;
-let _singleInputEnabledForPage = false;
-const _maximumInputs = 100;
-
-// Count of detected form fields on the page
-var _detectedFields = 0;
-
-// Element id's containing input fields detected by MutationObserver
-var _observerIds = [];
-
-// Document URL
-let _documentURL = document.location.href;
-
-function _f(fieldId) {
- const field = (fieldId) ? jQuery('input[data-cip-id=\'' + fieldId + '\']:first') : [];
- return (field.length > 0) ? field : null;
-}
-
-function _fs(fieldId) {
- const field = (fieldId) ? jQuery('input[data-cip-id=\'' + fieldId + '\']:first,select[data-cip-id=\'' + fieldId + '\']:first').first() : [];
- return (field.length > 0) ? field : null;
-}
-
-browser.runtime.onMessage.addListener(function(req, sender, callback) {
- if ('action' in req) {
- if (req.action === 'fill_user_pass_with_specific_login') {
- if (cip.credentials[req.id]) {
- let combination = null;
- if (cip.u) {
- cip.setValueWithChange(cip.u, cip.credentials[req.id].login);
- combination = cipFields.getCombination('username', cip.u);
- browser.runtime.sendMessage({
- action: 'page_set_login_id', args: [ req.id ]
- });
- cip.u.focus();
- }
- if (cip.p) {
- cip.setValueWithChange(cip.p, cip.credentials[req.id].password);
- browser.runtime.sendMessage({
- action: 'page_set_login_id', args: [ req.id ]
- });
- combination = cipFields.getCombination('password', cip.p);
- }
-
- let list = [];
- if (cip.fillInStringFields(combination.fields, cip.credentials[req.id].stringFields, list)) {
- cipForm.destroy(false, { 'password': list.list[0], 'username': list.list[1] });
- }
- }
- } else if (req.action === 'fill_username_password') {
- _called.manualFillRequested = 'both';
- cip.receiveCredentialsIfNecessary().then((response) => {
- cip.fillInFromActiveElement(false);
- });
- } else if (req.action === 'fill_password') {
- _called.manualFillRequested = 'pass';
- cip.receiveCredentialsIfNecessary().then((response) => {
- cip.fillInFromActiveElement(false, true); // passOnly to true
- });
- } else if (req.action === 'fill_totp') {
- cip.receiveCredentialsIfNecessary().then((response) => {
- cip.fillInFromActiveElementTOTPOnly(false);
- });
- } else if (req.action === 'activate_password_generator') {
- cip.initPasswordGenerator(cipFields.getAllFields());
- } else if (req.action === 'remember_credentials') {
- cip.contextMenuRememberCredentials();
- } else if (req.action === 'choose_credential_fields') {
- cipDefine.init();
- } else if (req.action === 'clear_credentials') {
- cipEvents.clearCredentials();
- return Promise.resolve();
- } else if (req.action === 'activated_tab') {
- cipEvents.triggerActivatedTab();
- return Promise.resolve();
- } else if (req.action === 'redetect_fields') {
- browser.runtime.sendMessage({
- action: 'load_settings',
- }).then((response) => {
- cip.settings = response;
- cip.initCredentialFields(true);
- });
- } else if (req.action === 'ignore-site') {
- cip.ignoreSite(req.args);
- } else if (req.action === 'check_database_hash' && 'hash' in req) {
- cip.detectDatabaseChange(req.hash);
- } else if (req.action === 'show_password_generator') {
- cipPassword.showDialog();
- }
- }
-});
-
-
-var cipAutocomplete = {};
-
-// objects of username + description for autocomplete
-cipAutocomplete.elements = [];
-
-cipAutocomplete.init = function(field) {
- if (cip.settings.autoFillSingleEntry && cip.credentials.length === 1 && field.hasClass('ui-autocomplete-input')) {
- field.autocomplete('destroy');
- }
-
- const acMenu = jQuery('#kpxc-ac-menu');
- if (acMenu.length === 0) {
- jQuery('').appendTo('body');
- }
-
- field
- .addClass('kpxc')
- .autocomplete({
- appendTo: '#kpxc-ac-menu',
- minLength: 0,
- source: cipAutocomplete.onSource,
- select: cipAutocomplete.onSelect,
- open: cipAutocomplete.onOpen
- });
- field
- .click(cipAutocomplete.onClick)
- .blur(cipAutocomplete.onBlur)
- .focus(cipAutocomplete.onFocus);
-};
-
-cipAutocomplete.onClick = function(e) {
- if (!cipAutocomplete.isTrusted(e)) {
- return;
- }
- jQuery(this).autocomplete('search', jQuery(this).val());
-};
-
-cipAutocomplete.onOpen = function(e, ui) {
- if (!cipAutocomplete.isTrusted(e)) {
- return;
- }
- jQuery('ul.ui-autocomplete.ui-menu').css('z-index', 2147483636);
-};
-
-cipAutocomplete.onSource = function(request, callback) {
- const matches = jQuery.map(cipAutocomplete.elements, (tag) => {
- if (tag.label.toUpperCase().indexOf(request.term.toUpperCase()) === 0) {
- return tag;
- }
- });
- callback(matches);
-};
-
-cipAutocomplete.onSelect = function(e, ui) {
- if (!cipAutocomplete.isTrusted(e)) {
- return;
- }
- e.preventDefault();
- cip.setValueWithChange(jQuery(this), ui.item.value);
- const fieldId = cipFields.prepareId(jQuery(this).attr('data-cip-id'));
- const combination = cipFields.getCombination('username', fieldId);
- combination.loginId = ui.item.loginId;
- cip.fillInCredentials(combination, true, false);
- jQuery(this).data('fetched', true);
-};
-
-cipAutocomplete.onBlur = function() {
- if (jQuery(this).data('fetched') === true) {
- jQuery(this).data('fetched', false);
- } else {
- const fieldId = cipFields.prepareId(jQuery(this).attr('data-cip-id'));
- const fields = cipFields.getCombination('username', fieldId);
- const fieldValue = jQuery(this).val();
-
- // Check if the manually inserted value is one of the retrieved credentials
- const fieldFound = cipAutocomplete.elements.some(e => e.value === fieldValue);
-
- if (_f(fields.password) && _f(fields.password).data('unchanged') !== true && fieldFound && _detectedFields > 1) {
- cip.fillInCredentials(fields, true, true);
- }
- }
-};
-
-cipAutocomplete.onFocus = function(e) {
- if (!cipAutocomplete.isTrusted(e)) {
- return;
- }
- cip.u = jQuery(this);
-
- if (jQuery(this).val() === '') {
- jQuery(this).autocomplete('search', '');
- }
-};
-
-// Search for isTrusted from jQuery's originalEvent
-cipAutocomplete.isTrusted = function(e) {
- for (let f = e.originalEvent; f; f = f.originalEvent) {
- if (f.isTrusted !== undefined) {
- return f.isTrusted;
- }
- }
- return false;
-};
-
-
-var cipPassword = {};
-cipPassword.observedIcons = [];
-cipPassword.observingLock = false;
-
-cipPassword.init = function() {
- if ('initPasswordGenerator' in _called) {
- return;
- }
-
- _called.initPasswordGenerator = true;
-
- window.setInterval(function() {
- cipPassword.checkObservedElements();
- }, 400);
-};
-
-cipPassword.initField = function(field, inputs, pos) {
- if (!field || field.length !== 1) {
- return;
- }
- if (field.data('cip-password-generator')) {
- return;
- }
-
- field.data('cip-password-generator', true);
-
- cipPassword.createIcon(field);
-
- let $found = false;
- if (inputs) {
- for (let i = pos + 1; i < inputs.length; i++) {
- if (inputs[i] && inputs[i].attr('type') && inputs[i].attr('type').toLowerCase() === 'password') {
- field.data('cip-genpw-next-field-id', inputs[i].data('cip-id'));
- field.data('cip-genpw-next-is-password-field', (i === 0));
- $found = true;
- break;
- }
- }
- }
-
- field.data('cip-genpw-next-field-exists', $found);
-};
-
-cipPassword.createDialog = function() {
- if ('passwordCreateDialog' in _called) {
- return;
- }
-
- _called.passwordCreateDialog = true;
-
- const $dialog = jQuery('
')
- .addClass('dialog-form')
- .attr('id', 'cip-genpw-dialog');
-
- const $inputDiv = jQuery('
').addClass('form-group');
- const $inputGroup = jQuery('
').addClass('genpw-input-group');
- const $textfieldPassword = jQuery('
')
- .attr('id', 'cip-genpw-textfield-password')
- .attr('type', 'text')
- .attr('aria-describedby', 'cip-genpw-quality')
- .attr('placeholder', tr('passwordGeneratorPlaceholder'))
- .attr('tabindex', -1)
- .addClass('genpw-text ui-widget-content ui-corner-all')
- .on('change keypress paste textInput input', function() {
- jQuery('#cip-genpw-btn-clipboard:first').removeClass('btn-success');
- });
- const $quality = jQuery('
')
- .addClass('genpw-input-group-addon')
- .addClass('b2c-add-on')
- .attr('id', 'cip-genpw-quality')
- .text(tr('passwordGeneratorBits'));
- $inputGroup.append($textfieldPassword).append($quality);
-
- const $checkGroup = jQuery('').addClass('genpw-input-group');
- const $checkboxNextField = jQuery('
')
- .attr('id', 'cip-genpw-checkbox-next-field')
- .attr('type', 'checkbox')
- .addClass('cip-genpw-checkbox');
- const $labelNextField = jQuery('
')
- .append($checkboxNextField)
- .addClass('cip-genpw-label')
- .append(tr('passwordGeneratorLabel'));
- $checkGroup.append($labelNextField);
-
- $inputDiv.append($inputGroup).append($checkGroup);
- $dialog.append($inputDiv);
-
- $dialog.hide();
- jQuery('body').append($dialog);
-
- const $container = jQuery('#kpxc-pw-dialog');
- if ($container.length === 0) {
- jQuery('
').appendTo('body');
- }
-
- $dialog.dialog({
- appendTo: '#kpxc-pw-dialog',
- autoOpen: false,
- modal: true,
- resizable: false,
- minWidth: 300,
- minHeight: 80,
- title: tr('passwordGeneratorTitle'),
- classes: {'ui-dialog': 'ui-corner-all'},
- buttons: {
- 'Generate':
- {
- text: tr('passwordGeneratorGenerate'),
- id: 'cip-genpw-btn-generate',
- click: (e) => {
- e.preventDefault();
- browser.runtime.sendMessage({
- action: 'generate_password'
- }).then(cipPassword.callbackGeneratedPassword).catch((err) => {
- console.log(err);
- });
- }
- },
- 'Copy':
- {
- text: tr('passwordGeneratorCopy'),
- id: 'cip-genpw-btn-clipboard',
- click: (e) => {
- e.preventDefault();
- cipPassword.copyPasswordToClipboard();
- }
- },
- 'Fill & copy':
- {
- text: tr('passwordGeneratorFillAndCopy'),
- id: 'cip-genpw-btn-fillin',
- click: (e) => {
- e.preventDefault();
-
- const fieldId = jQuery('#cip-genpw-dialog:first').data('cip-genpw-field-id');
- const field = jQuery('input[data-cip-id=\'' + fieldId + '\']:first');
- if (field.length === 1) {
- let $password = jQuery('input#cip-genpw-textfield-password:first').val();
-
- if (field.attr('maxlength')) {
- if ($password.length > field.attr('maxlength')) {
- $password = $password.substring(0, field.attr('maxlength'));
- jQuery('input#cip-genpw-textfield-password:first').val($password);
- jQuery('#cip-genpw-btn-clipboard:first').removeClass('b2c-btn-success');
- browser.runtime.sendMessage({
- action: 'show_notification',
- args: [ tr('passwordGeneratorErrorTooLong') ]
- });
- }
- }
-
- field.val($password);
- if (jQuery('input#cip-genpw-checkbox-next-field:checked').length === 1) {
- if (field.data('cip-genpw-next-field-exists')) {
- const nextFieldId = field.data('cip-genpw-next-field-id');
- const nextField = jQuery('input[data-cip-id=\'' + nextFieldId + '\']:first');
- if (nextField.length === 1) {
- nextField.val($password);
- }
- }
- }
-
- cipPassword.copyPasswordToClipboard();
- }
- }
- }
- },
- open: function(event, ui) {
- jQuery('.ui-widget-overlay').click(function() {
- jQuery('#cip-genpw-dialog:first').dialog('close');
- jQuery('span').remove('.kpxc');
- });
-
- if (jQuery('input#cip-genpw-textfield-password:first').val() === '') {
- jQuery('button#cip-genpw-btn-generate:first').click();
- }
- }
- });
-};
-
-cipPassword.createIcon = function(field) {
- const $className = (isFirefox() ? 'key-moz' : 'key');
- const $size = (field.outerHeight() > 28) ? 24 : 16;
- let $offset = Math.floor((field.outerHeight() - $size) / 3);
- $offset = ($offset < 0) ? 0 : $offset;
-
- const $icon = jQuery('')
- .addClass('kpxc')
- .addClass('cip-genpw-icon')
- .addClass($className)
- .attr('title', tr('passwordGeneratorGenerateText'))
- .attr('alt', tr('passwordGeneratorIcon'))
- .css('z-index', '9999')
- .css('width', $size)
- .css('height', $size)
- .data('size', $size)
- .data('offset', $offset)
- .data('cip-genpw-field-id', field.data('cip-id'));
- cipPassword.setIconPosition($icon, field);
- $icon.click(function(e) {
- e.preventDefault();
-
- if (!field.is(':visible')) {
- $icon.remove();
- field.removeData('cip-password-generator');
- return;
- }
-
- cipPassword.createDialog();
- const $dialog = jQuery('#cip-genpw-dialog');
- if ($dialog.dialog('isOpen')) {
- $dialog.dialog('close');
- }
-
- $dialog.dialog('option', 'position', { my: 'left-10px top', at: 'center bottom', of: jQuery(this) });
- $dialog.data('cip-genpw-field-id', field.data('cip-id'));
- $dialog.data('cip-genpw-next-field-id', field.data('cip-genpw-next-field-id'));
- $dialog.data('cip-genpw-next-is-password-field', field.data('cip-genpw-next-is-password-field'));
-
- const $bool = Boolean(field.data('cip-genpw-next-field-exists'));
- jQuery('input#cip-genpw-checkbox-next-field:first')
- .attr('checked', $bool)
- .attr('disabled', !$bool);
-
- $dialog.dialog('open');
- });
-
- cipPassword.observedIcons.push($icon);
- jQuery('body').append($icon);
-};
-
-cipPassword.showDialog = function() {
- $('.cip-genpw-icon').click();
-};
-
-cipPassword.setIconPosition = function($icon, $field) {
- $icon.css('top', $field.offset().top + $icon.data('offset') + 1)
- .css('left', $field.offset().left + $field.outerWidth() - $icon.data('size') - $icon.data('offset'));
-};
-
-cipPassword.copyPasswordToClipboard = function(e) {
- if (e) {
- e.preventDefault();
- }
-
- const input = jQuery('input#cip-genpw-textfield-password');
- input.select();
- try {
- const success = document.execCommand('copy');
- if (success) {
- jQuery('#cip-genpw-btn-clipboard').addClass('b2c-btn-success');
- }
- jQuery('#cip-genpw-dialog').select();
- input.value = '';
- }
- catch (err) {
- console.log('Could not copy password to clipboard: ' + err);
- }
-};
-
-cipPassword.callbackPasswordCopied = function(bool) {
- if (bool) {
- jQuery('#cip-genpw-btn-clipboard').addClass('btn-success');
- }
-};
-
-cipPassword.callbackGeneratedPassword = function(entries) {
- if (entries && entries.length >= 1) {
- jQuery('#cip-genpw-btn-clipboard:first').removeClass('btn-success');
- jQuery('input#cip-genpw-textfield-password:first').val(entries[0].password);
- if (isNaN(entries[0].login)) {
- jQuery('#cip-genpw-quality:first').text('??? Bits');
- } else {
- jQuery('#cip-genpw-quality:first').text(entries[0].login + ' Bits');
- }
- } else {
- if (jQuery('div#cip-genpw-error:first').length === 0) {
- jQuery('button#cip-genpw-btn-generate:first').after('
' + tr('passwordGeneratorError') + '
');
- jQuery('input#cip-genpw-textfield-password:first').parent().hide();
- jQuery('input#cip-genpw-checkbox-next-field:first').parent('label').hide();
- jQuery('button#cip-genpw-btn-generate').hide();
- jQuery('button#cip-genpw-btn-clipboard').hide();
- jQuery('button#cip-genpw-btn-fillin').hide();
- }
- }
-};
-
-cipPassword.onRequestPassword = function() {
- browser.runtime.sendMessage({
- action: 'generate_password'
- }).then(cipPassword.callbackGeneratedPassword);
-};
-
-cipPassword.checkObservedElements = function() {
- if (cipPassword.observingLock) {
- return;
- }
-
- cipPassword.observingLock = true;
- jQuery.each(cipPassword.observedIcons, (index, iconField) => {
- if (iconField && iconField.length === 1) {
- const fieldId = iconField.data('cip-genpw-field-id');
- const field = jQuery('input[data-cip-id=\'' + fieldId + '\']:first');
- if (!field || field.length !== 1) {
- iconField.remove();
- cipPassword.observedIcons.splice(index, 1);
- } else if (!field.is(':visible')) {
- iconField.hide();
- } else if (field.is(':visible')) {
- iconField.show();
- cipPassword.setIconPosition(iconField, field);
- field.data('cip-password-generator', true);
- }
-
-
- } else {
- cipPassword.observedIcons.splice(index, 1);
- }
- });
- cipPassword.observingLock = false;
-};
-
-
-
-var cipForm = {};
-
-cipForm.init = function(form, credentialFields) {
- // Not already initialized && password-field is not null
- if (!form.data('cipForm-initialized') && (credentialFields.password || (_singleInputEnabledForPage && credentialFields.username))) {
- form.data('cipForm-initialized', true);
- cipForm.setInputFields(form, credentialFields);
- form.submit(cipForm.onSubmit);
- }
-};
-
-cipForm.destroy = function(form, credentialFields) {
- if (form === false && credentialFields) {
- const field = _f(credentialFields.password) || _f(credentialFields.username);
- if (field) {
- form = field.closest('form');
- }
- }
-
- if (form && jQuery(form).length > 0) {
- jQuery(form).unbind('submit', cipForm.onSubmit);
- }
-};
-
-cipForm.setInputFields = function(form, credentialFields) {
- form.data('cipUsername', credentialFields.username);
- form.data('cipPassword', credentialFields.password);
-};
-
-cipForm.onSubmit = function() {
- const usernameId = jQuery(this).data('cipUsername');
- const passwordId = jQuery(this).data('cipPassword');
-
- let usernameValue = '';
- let passwordValue = '';
-
- const usernameField = _f(usernameId);
- const passwordField = _f(passwordId);
-
- if (usernameField) {
- usernameValue = usernameField.val();
- }
- if (passwordField) {
- passwordValue = passwordField.val();
- }
-
- cip.rememberCredentials(usernameValue, passwordValue);
-};
-
-
-
-var cipDefine = {};
-
-cipDefine.selection = {
- username: null,
- password: null,
- fields: []
-};
-cipDefine.eventFieldClick = null;
-cipDefine.keyDown = null;
-
-cipDefine.init = function() {
- const $backdrop = jQuery('
').attr('id', 'b2c-backdrop').addClass('b2c-modal-backdrop');
- jQuery('body').append($backdrop);
-
- const $chooser = jQuery('
').attr('id', 'b2c-cipDefine-fields');
- jQuery('body').append($chooser);
-
- const $description = jQuery('
').attr('id', 'b2c-cipDefine-description');
- $backdrop.append($description);
-
- cipFields.getAllFields();
- cipFields.prepareVisibleFieldsWithID('select');
-
- cipDefine.initDescription();
-
- cipDefine.resetSelection();
- cipDefine.prepareStep1();
- cipDefine.markAllUsernameFields($chooser);
-
- document.addEventListener('keydown', cipDefine.keyDown);
-};
-
-cipDefine.close = function() {
- $('div#b2c-backdrop').remove();
- $('div#b2c-cipDefine-fields').remove();
- document.removeEventListener('keydown', cipDefine.keyDown);
-};
-
-cipDefine.initDescription = function() {
- const $description = jQuery('div#b2c-cipDefine-description');
- const $h1 = jQuery('
').addClass('b2c-chooser-headline');
- $description.append($h1);
- const $help = jQuery('
').addClass('b2c-chooser-help').attr('id', 'b2c-help');
- $description.append($help);
- const $keyboardHelp = jQuery('
').addClass('b2c-chooser-help').attr('id', 'b2c-keyboardHelp');
- $description.append($keyboardHelp);
-
- // Show keyboard shortcuts help text
- jQuery('div#b2c-keyboardHelp').text(`${tr('optionsKeyboardShortcutsHeader')}:`).css('margin-bottom', '5px');
- jQuery('div#b2c-keyboardHelp').append($('
Escape ')).append(' ' + tr('defineDismiss'));
- jQuery('div#b2c-keyboardHelp').append($('
S ')).append(' ' + tr('defineSkip'));
- jQuery('div#b2c-keyboardHelp').append($('
A ')).append(' ' + tr('defineAgain'));
- jQuery('div#b2c-keyboardHelp').append($('
C ')).append(' ' + tr('defineConfirm'));
- jQuery('div#b2c-keyboardHelp').append($('
M ')).append(' ' + tr('defineMore'));
- jQuery('div#b2c-keyboardHelp').append($('
D ')).append(' ' + tr('defineDiscard'));
-
- const $btnDismiss = jQuery('
').text(tr('defineDismiss')).attr('id', 'b2c-btn-dismiss')
- .addClass('btn')
- .addClass('btn-danger')
- .click(cipDefine.close);
- const $btnSkip = jQuery('').text(tr('defineSkip')).attr('id', 'b2c-btn-skip')
- .addClass('btn')
- .addClass('btn-info')
- .css('margin-right', '5px')
- .click(cipDefine.skip);
- const $btnMore = jQuery('').text(tr('defineMore')).attr('id', 'b2c-btn-more')
- .addClass('btn')
- .addClass('btn-info')
- .css('margin-right', '5px')
- .css('margin-left', '5px')
- .click(cipDefine.more);
- const $btnAgain = jQuery('').text(tr('defineAgain')).attr('id', 'b2c-btn-again')
- .addClass('btn')
- .addClass('btn-warning')
- .css('margin-right', '5px')
- .click(cipDefine.again)
- .hide();
- const $btnConfirm = jQuery('').text(tr('defineConfirm')).attr('id', 'b2c-btn-confirm')
- .addClass('btn')
- .addClass('btn-primary')
- .css('margin-right', '15px')
- .click(cipDefine.confirm)
- .hide();
-
- $description.append($btnConfirm);
- $description.append($btnSkip);
- $description.append($btnAgain);
- $description.append($btnDismiss);
- $description.append($btnMore);
-
- const location = cip.getDocumentLocation();
- if (cip.settings['defined-custom-fields'] && cip.settings['defined-custom-fields'][location]) {
- const $p = jQuery('').addClass('alreadySelected').html(tr('defineAlreadySelected') + ' ');
- const $btnDiscard = jQuery('')
- .attr('id', 'btn-warning')
- .text(tr('defineDiscard'))
- .css('margin-top', '5px')
- .addClass('btn')
- .addClass('btn-sm')
- .addClass('btn-danger')
- .click(cipDefine.discard);
- $p.append($btnDiscard);
- $description.append($p);
- }
-
- jQuery('div#b2c-cipDefine-description').draggable();
-};
-
-cipDefine.resetSelection = function() {
- cipDefine.selection = {
- username: null,
- password: null,
- fields: []
- };
-};
-
-cipDefine.isFieldSelected = function($cipId) {
- return (
- $cipId === cipDefine.selection.username ||
- $cipId === cipDefine.selection.password ||
- $cipId in cipDefine.selection.fields
- );
-};
-
-cipDefine.markAllUsernameFields = function($chooser) {
- cipDefine.eventFieldClick = function(e, elem) {
- const field = elem ? jQuery(elem) : jQuery(this);
- cipDefine.selection.username = field.data('cip-id');
- field.addClass('b2c-fixed-username-field').text(tr('username')).unbind('click');
- cipDefine.prepareStep2();
- cipDefine.markAllPasswordFields(jQuery('#b2c-cipDefine-fields'));
- };
- cipDefine.markFields($chooser, cipFields.inputQueryPattern);
-};
-
-cipDefine.markAllPasswordFields = function($chooser, more) {
- cipDefine.eventFieldClick = function(e, elem) {
- const field = elem ? jQuery(elem) : jQuery(this);
- cipDefine.selection.password = field.data('cip-id');
- field.addClass('b2c-fixed-password-field').text(tr('password')).unbind('click');
- cipDefine.prepareStep3();
- cipDefine.markAllStringFields(jQuery('#b2c-cipDefine-fields'));
- };
- if (more) {
- cipDefine.markFields($chooser, cipFields.inputQueryPattern);
- } else {
- cipDefine.markFields($chooser, 'input[type=\'password\']');
- }
-};
-
-cipDefine.markAllStringFields = function($chooser) {
- cipDefine.eventFieldClick = function(e, elem) {
- const field = elem ? jQuery(elem) : jQuery(this);
- cipDefine.selection.fields[field.data('cip-id')] = true;
- const count = Object.keys(cipDefine.selection.fields).length;
- field.addClass('b2c-fixed-string-field').text(tr('defineStringField') + String(count)).unbind('click');
- jQuery('button#b2c-btn-confirm:first').addClass('b2c-btn-primary').attr('disabled', false);
- };
- cipDefine.markFields($chooser, cipFields.inputQueryPattern + ', select');
-};
-
-cipDefine.markFields = function($chooser, $pattern) {
- let index = 1;
- jQuery($pattern).each(function() {
- if (cipDefine.isFieldSelected(jQuery(this).data('cip-id'))) {
- return true;
- }
-
- if (cipFields.isVisible(this)) {
- const $field = jQuery('').addClass('b2c-fixed-field')
- .css('top', jQuery(this).offset().top)
- .css('left', jQuery(this).offset().left)
- .css('width', jQuery(this).outerWidth())
- .css('height', jQuery(this).outerHeight())
- .attr('data-cip-id', jQuery(this).attr('data-cip-id'))
- .text(String(index))
- .click(cipDefine.eventFieldClick)
- .hover(function() {
- jQuery(this).addClass('b2c-fixed-hover-field');
- }, function() {
- jQuery(this).removeClass('b2c-fixed-hover-field');
- });
- $chooser.append($field);
- ++index;
- }
- });
-
- $('b2c-fixed-field:first').focus();
-};
-
-cipDefine.prepareStep1 = function() {
- jQuery('div#b2c-help').text(tr('defineKeyboardText')).css('margin-bottom', '5px');
- jQuery('div#b2c-cipDefine-fields').removeData('username');
- jQuery('div#b2c-cipDefine-fields').removeData('password');
- jQuery('div.b2c-fixed-field', jQuery('div#b2c-cipDefine-fields')).remove();
- jQuery('div:first', jQuery('div#b2c-cipDefine-description')).text(tr('defineChooseUsername'));
- jQuery('button#b2c-btn-skip:first').data('step', '1').show();
- jQuery('button#b2c-btn-confirm:first').removeClass('b2c-btn-primary').attr('disabled', false);
- jQuery('button#b2c-btn-confirm:first').hide();
- jQuery('button#b2c-btn-again:first').hide();
- jQuery('button#b2c-btn-more:first').hide();
-};
-
-cipDefine.prepareStep2 = function() {
- jQuery('div#b2c-help').text(tr('defineKeyboardText')).css('margin-bottom', '5px');
- jQuery('div.b2c-fixed-field:not(.b2c-fixed-username-field)', jQuery('div#b2c-cipDefine-fields')).remove();
- jQuery('div:first', jQuery('div#b2c-cipDefine-description')).text(tr('defineChoosePassword'));
- jQuery('button#b2c-btn-skip:first').data('step', '2');
- jQuery('button#b2c-btn-again:first').show();
- jQuery('button#b2c-btn-more:first').show();
-};
-
-cipDefine.prepareStep3 = function() {
- if (!cipDefine.selection.username && !cipDefine.selection.password) {
- jQuery('button#b2c-btn-confirm:first').removeClass('b2c-btn-primary').attr('disabled', true);
- }
-
- jQuery('div#b2c-help').html(tr('defineHelpText')).css('margin-bottom', '5px');
- jQuery('div.b2c-fixed-field:not(.b2c-fixed-password-field,.b2c-fixed-username-field)', jQuery('div#b2c-cipDefine-fields')).remove();
- jQuery('button#b2c-btn-confirm:first').show();
- jQuery('button#b2c-btn-skip:first').data('step', '3').hide();
- jQuery('button#b2c-btn-more:first').hide();
- jQuery('div:first', jQuery('div#b2c-cipDefine-description')).text(tr('defineConfirmSelection'));
-};
-
-cipDefine.skip = function() {
- if ($('button#b2c-btn-skip:first').data('step') === '1') {
- cipDefine.selection.username = null;
- cipDefine.prepareStep2();
- cipDefine.markAllPasswordFields(jQuery('#b2c-cipDefine-fields'), false);
- } else if ($('button#b2c-btn-skip:first').data('step') === '2') {
- cipDefine.selection.password = null;
- cipDefine.prepareStep3();
- cipDefine.markAllStringFields(jQuery('#b2c-cipDefine-fields'));
- }
-};
-
-cipDefine.again = function() {
- cipDefine.resetSelection();
- cipDefine.prepareStep1();
- cipDefine.markAllUsernameFields(jQuery('#b2c-cipDefine-fields'));
-};
-
-cipDefine.more = function() {
- if ($('button#b2c-btn-skip:first').data('step') === '2') {
- cipDefine.prepareStep2();
- cipDefine.markAllPasswordFields(jQuery('#b2c-cipDefine-fields'), true);
- }
-};
-
-cipDefine.confirm = function() {
- if ($('button#b2c-btn-skip:first').data('step') !== '3') {
- return;
- }
-
- if (!cip.settings['defined-custom-fields']) {
- cip.settings['defined-custom-fields'] = {};
- }
-
- if (cipDefine.selection.username) {
- cipDefine.selection.username = cipFields.prepareId(cipDefine.selection.username);
- }
-
- if (cipDefine.selection.password) {
- cipDefine.selection.password = cipFields.prepareId(cipDefine.selection.password);
- }
-
- const fieldIds = [];
- const fieldKeys = Object.keys(cipDefine.selection.fields);
- for (const i of fieldKeys) {
- fieldIds.push(cipFields.prepareId(i));
- }
-
- const location = cip.getDocumentLocation();
- cip.settings['defined-custom-fields'][location] = {
- username: cipDefine.selection.username,
- password: cipDefine.selection.password,
- fields: fieldIds
- };
-
- browser.runtime.sendMessage({
- action: 'save_settings',
- args: [ cip.settings ]
- });
-
- cipDefine.close();
-};
-
-cipDefine.discard = function() {
- const location = cip.getDocumentLocation();
- delete cip.settings['defined-custom-fields'][location];
-
- browser.runtime.sendMessage({
- action: 'save_settings',
- args: [ cip.settings ]
- });
-
- browser.runtime.sendMessage({
- action: 'load_settings'
- });
-
- $('p.alreadySelected').remove();
-};
-
-// Handle the keyboard events
-cipDefine.keyDown = function(e) {
- if (e.key === 'Escape') {
- cipDefine.close();
- } else if (e.keyCode >= 49 && e.keyCode <= 57) {
- // Select input field by number
- e.preventDefault();
- const index = e.keyCode - 48;
- const inputFields = $('div.b2c-fixed-field:not(.b2c-fixed-password-field,.b2c-fixed-username-field)');
-
- if (inputFields.length >= index) {
- cipDefine.eventFieldClick(e, inputFields[index - 1]);
- }
- } else if (e.key === 's') {
- e.preventDefault();
- cipDefine.skip();
- } else if (e.key === 'a') {
- e.preventDefault();
- cipDefine.again();
- } else if (e.key === 'c') {
- e.preventDefault();
- cipDefine.confirm();
- } else if (e.key === 'm') {
- e.preventDefault();
- cipDefine.more();
- } else if (e.key === 'd') {
- e.preventDefault();
- cipDefine.discard();
- }
-};
-
-
-var cipFields = {};
-
-cipFields.inputQueryPattern = 'input[type=\'text\'], input[type=\'email\'], input[type=\'password\'], input[type=\'tel\'], input[type=\'number\'], input:not([type])';
-// Unique number as new IDs for input fields
-cipFields.uniqueNumber = 342845638;
-// Objects with combination of username + password fields
-cipFields.combinations = [];
-
-cipFields.setUniqueId = function(field) {
- if (field && !field.attr('data-cip-id')) {
- // Use ID of field if it is unique
- const fieldId = field.attr('id');
- if (fieldId) {
- const foundIds = jQuery('input#' + cipFields.prepareId(fieldId));
- if (foundIds.length === 1) {
- field.attr('data-cip-id', fieldId);
- return;
- }
- }
-
- // Create own ID if no ID is set for this field
- cipFields.uniqueNumber += 1;
- field.attr('data-cip-id', 'jQuery' + String(cipFields.uniqueNumber));
- }
-};
-
-cipFields.prepareId = function(id) {
- return id.replace(/[:#.,\[\]\(\)' "]/g, function(m) { return '\\' + m; });
-};
-
-/**
- * Returns the first parent element satifying the {@code predicate} mapped by {@code resultFn} or else {@code defaultVal}.
- * @param {HTMLElement} element The start element (excluded, starting with the parents)
- * @param {function} predicate Matcher for the element to find, type (HTMLElement) => boolean
- * @param {function} resultFn Callback function of type (HTMLElement) => {*} called for the first matching element
- * @param {fun} defaultValFn Fallback return value supplier, if no element matching the predicate can be found
- */
-cipFields.traverseParents = function(element, predicate, resultFn = () => true, defaultValFn = () => false) {
- for (let f = element.parentElement; f !== null; f = f.parentElement) {
- if (predicate(f)) {
- return resultFn(f);
- }
- }
- return defaultValFn();
-};
-
-cipFields.getOverflowHidden = function(field) {
- return cipFields.traverseParents(field, f => f.style.overflow === 'hidden');
-};
-
-
-// Checks if input field is a search field. Attributes or form action containing 'search', or parent element holding
-// role="search" will be identified as a search field.
-cipFields.isSearchField = function(target) {
- const attributes = target.attributes;
-
- // Check element attributes
- for (const attr of attributes) {
- if ((attr.value && (attr.value.toLowerCase().includes('search')) || attr.value === 'q')) {
- return true;
- }
- }
-
- // Check closest form
- const closestForm = target.closest('form');
- if (closestForm) {
- // Check form action
- const formAction = closestForm.getAttribute('action');
- if (formAction && (formAction.toLowerCase().includes('search') &&
- !formAction.toLowerCase().includes('research'))) {
- return true;
- }
-
- // Check form class and id
- const closestFormId = closestForm.getAttribute('id');
- const closestFormClass = closestForm.className;
- if (closestFormClass && (closestForm.className.toLowerCase().includes('search') ||
- (closestFormId && closestFormId.toLowerCase().includes('search') && !closestFormId.toLowerCase().includes('research')))) {
- return true;
- }
- }
-
- // Check parent elements for role="search"
- const roleFunc = f => f.getAttribute('role');
- const roleValue = cipFields.traverseParents(target, roleFunc, roleFunc, () => null);
- if (roleValue && roleValue === 'search') {
- return true;
- }
-
- return false;
-};
-
-cipFields.isVisible = function(field) {
- const rect = field.getBoundingClientRect();
-
- // Check CSS visibility
- const fieldStyle = getComputedStyle(field);
- if (fieldStyle.visibility && (fieldStyle.visibility === 'hidden' || fieldStyle.visibility === 'collapse')) {
- return false;
- }
-
- // Check element position and size
- if (rect.x < 0 || rect.y < 0 || rect.width < 8 || rect.height < 8) {
- return false;
- }
-
- return true;
-};
-
-cipFields.getAllFields = function() {
- const fields = [];
- const inputs = cipObserverHelper.getInputs(document);
- for (const i of inputs) {
- if (cipFields.isVisible(i) && !cipFields.isSearchField(i)) {
- cipFields.setUniqueId(jQuery(i));
- fields.push(jQuery(i));
- }
- };
-
- _detectedFields = fields.length;
- return fields;
-};
-
-cipFields.prepareVisibleFieldsWithID = function($pattern) {
- jQuery($pattern).each(function() {
- if (cipFields.isVisible(this) && !cipFields.isSearchField(this)) {
- cipFields.setUniqueId(jQuery(this));
- }
- });
-};
-
-cipFields.getAllCombinations = function(inputs) {
- const fields = [];
- let uField = null;
-
- for (const i of inputs) {
- if (i) {
- if (i.attr('type') && i.attr('type').toLowerCase() === 'password') {
- const uId = (!uField || uField.length < 1) ? null : cipFields.prepareId(uField.attr('data-cip-id'));
-
- const combination = {
- username: uId,
- password: cipFields.prepareId(i.attr('data-cip-id'))
- };
- fields.push(combination);
-
- // Reset selected username field
- uField = null;
- } else {
- // Username field
- uField = i;
- }
- }
- }
-
- if (_singleInputEnabledForPage && fields.length === 0 && uField) {
- const combination = {
- username: uField[0].getAttribute('data-cip-id'),
- password: null
- };
- fields.push(combination);
- }
-
- return fields;
-};
-
-cipFields.getCombination = function(givenType, fieldId) {
- if (cipFields.combinations.length === 0) {
- if (cipFields.useDefinedCredentialFields()) {
- return cipFields.combinations[0];
- }
- }
- // Use defined credential fields (already loaded into combinations)
- const location = cip.getDocumentLocation();
- if (cip.settings['defined-custom-fields'] && cip.settings['defined-custom-fields'][location]) {
- return cipFields.combinations[0];
- }
-
- for (let c of cipFields.combinations) {
- if (c[givenType] === fieldId) {
- return c;
- }
- }
-
- // Find new combination
- let combination = {
- username: null,
- password: null
- };
-
- let newCombi = false;
- if (givenType === 'username') {
- const passwordField = cipFields.getPasswordField(fieldId, true);
- let passwordId = null;
- if (passwordField && passwordField.length > 0) {
- passwordId = cipFields.prepareId(passwordField.attr('data-cip-id'));
- }
- combination = {
- username: fieldId,
- password: passwordId
- };
- newCombi = true;
- } else if (givenType === 'password') {
- const usernameField = cipFields.getUsernameField(fieldId, true);
- let usernameId = null;
- if (usernameField && usernameField.length > 0) {
- usernameId = cipFields.prepareId(usernameField.attr('data-cip-id'));
- }
- combination = {
- username: usernameId,
- password: fieldId
- };
- newCombi = true;
- }
-
- if (combination.username || combination.password) {
- cipFields.combinations.push(combination);
- }
-
- if (combination.username) {
- if (cip.credentials.length > 0) {
- cip.preparePageForMultipleCredentials(cip.credentials);
- }
- }
-
- if (newCombi) {
- combination.isNew = true;
- }
- return combination;
-};
-
-/**
-* Return the username field or null if it not exists
-*/
-cipFields.getUsernameField = function(passwordId, checkDisabled) {
- const passwordField = _f(passwordId);
- if (!passwordField) {
- return null;
- }
-
- const form = passwordField.closest('form')[0];
- let usernameField = null;
-
- // Search all inputs on this one form
- if (form) {
- jQuery(cipFields.inputQueryPattern, form).each(function() {
- cipFields.setUniqueId(jQuery(this));
- if (jQuery(this).attr('data-cip-id') === passwordId) {
- return false; // Break
- }
-
- if (jQuery(this).attr('type') && jQuery(this).attr('type').toLowerCase() === 'password') {
- return true; // Continue
- }
-
- usernameField = jQuery(this);
- });
- } else {
- // Search all inputs on page
- const inputs = cipFields.getAllFields();
- cip.initPasswordGenerator(inputs);
- for (const i of inputs) {
- if (i.attr('data-cip-id') === passwordId) {
- break;
- }
-
- if (i.attr('type') && i.attr('type').toLowerCase() === 'password') {
- continue;
- }
-
- usernameField = i;
- }
- }
-
- if (usernameField && !checkDisabled) {
- const usernameId = usernameField.attr('data-cip-id');
- // Check if usernameField is already used by another combination
- for (const c of cipFields.combinations) {
- if (c.username === usernameId) {
- usernameField = null;
- break;
- }
- }
- }
-
- cipFields.setUniqueId(usernameField);
- return usernameField;
-};
-
-/**
-* Return the password field or null if it not exists
-*/
-cipFields.getPasswordField = function(usernameId, checkDisabled) {
- const usernameField = _f(usernameId);
- if (!usernameField) {
- return null;
- }
-
- const form = usernameField.closest('form')[0];
- let passwordField = null;
-
- // Search all inputs on this one form
- if (form) {
- passwordField = jQuery('input[type=\'password\']:first', form);
- if (passwordField && passwordField.length < 1) {
- passwordField = null;
- }
-
- if (cip.settings.usePasswordGenerator) {
- cipPassword.init();
- cipPassword.initField(passwordField);
- }
- } else {
- // Search all inputs on page
- const inputs = cipFields.getAllFields();
- cip.initPasswordGenerator(inputs);
-
- let active = false;
- for (const i of inputs) {
- if (i.attr('data-cip-id') === usernameId) {
- active = true;
- }
- if (active && jQuery(i).attr('type') && jQuery(i).attr('type').toLowerCase() === 'password') {
- passwordField = i;
- break;
- }
- }
- }
-
- if (passwordField && !checkDisabled) {
- const passwordId = passwordField.attr('data-cip-id');
- // Check if passwordField is already used by another combination
- for (const c of cipFields.combinations) {
- if (c.password === passwordId) {
- passwordField = null;
- break;
- }
- }
- }
-
- cipFields.setUniqueId(passwordField);
-
- return passwordField;
-};
-
-cipFields.prepareCombinations = function(combinations) {
- for (const c of combinations) {
- const pwField = _f(c.password);
- // Needed for auto-complete: don't overwrite manually filled-in password field
- if (pwField && !pwField.data('cipFields-onChange')) {
- pwField.data('cipFields-onChange', true);
- pwField.change(function() {
- jQuery(this).data('unchanged', false);
- });
- }
-
- // Initialize form-submit for remembering credentials
- const fieldId = c.password || c.username;
- const field = _f(fieldId);
- if (field) {
- const form = field.closest('form');
- if (form && form.length > 0) {
- cipForm.init(form, c);
- }
- }
- }
-};
-
-cipFields.useDefinedCredentialFields = function() {
- const location = cip.getDocumentLocation();
- if (cip.settings['defined-custom-fields'] && cip.settings['defined-custom-fields'][location]) {
- const creds = cip.settings['defined-custom-fields'][location];
-
- let $found = _f(creds.username) || _f(creds.password);
- for (const i of creds.fields) {
- if (_fs(i)) {
- $found = true;
- break;
- }
- }
-
- if ($found) {
- const fields = {
- username: creds.username,
- password: creds.password,
- fields: creds.fields
- };
- cipFields.combinations = [];
- cipFields.combinations.push(fields);
-
- return true;
- }
- }
-
- return false;
-};
-
-
-var cipObserverHelper = {};
-cipObserverHelper.inputTypes = [
- 'text',
- 'email',
- 'password',
- 'tel',
- 'number',
- null // Input field can be without any type. Include these to the list.
-];
-
-// Ignores all nodes that doesn't contain elements
-cipObserverHelper.ignoredNode = function(target) {
- if (target.nodeType === Node.ATTRIBUTE_NODE ||
- target.nodeType === Node.TEXT_NODE ||
- target.nodeType === Node.CDATA_SECTION_NODE ||
- target.nodeType === Node.PROCESSING_INSTRUCTION_NODE ||
- target.nodeType === Node.COMMENT_NODE ||
- target.nodeType === Node.DOCUMENT_TYPE_NODE ||
- target.nodeType === Node.NOTATION_NODE) {
- return true;
- }
- return false;
-};
-
-cipObserverHelper.getInputs = function(target) {
- // Ignores target element if it's not an element node
- if (cipObserverHelper.ignoredNode(target)) {
- return [];
- }
-
- // Filter out any input fields with type 'hidden' right away
- const inputFields = [];
- Array.from(target.getElementsByTagName('input')).forEach((e) => {
- if (e.type !== 'hidden') {
- inputFields.push(e);
- }
- });
-
- // Do not allow more visible inputs than _maximumInputs (default value: 100)
- if (inputFields.length === 0 || inputFields.length > _maximumInputs) {
- return [];
- }
-
- // Only include input fields that match with cipObserverHelper.inputTypes
- const inputs = [];
- for (const i of inputFields) {
- let type = i.getAttribute('type');
- if (type) {
- type = type.toLowerCase();
- }
-
- if (cipObserverHelper.inputTypes.includes(type)) {
- inputs.push(i);
- }
- }
- return inputs;
-};
-
-cipObserverHelper.getId = function(target) {
- return target.classList.length === 0 ? target.id : target.classList;
-};
-
-cipObserverHelper.ignoredElement = function(target) {
- // Ignore elements that do not have a className (including SVG)
- if (typeof target.className !== 'string') {
- return true;
- }
-
- // Ignore KeePassXC-Browser classes
- if (target.className && target.className !== undefined &&
- (target.className.includes('kpxc') || target.className.includes('ui-helper'))) {
- return true;
- }
-
- return false;
-};
-
-cipObserverHelper.handleObserverAdd = function(target) {
- if (cipObserverHelper.ignoredElement(target)) {
- return;
- }
-
- const inputs = cipObserverHelper.getInputs(target);
- if (inputs.length === 0) {
- return;
- }
-
- const neededLength = _detectedFields === 1 ? 0 : 1;
- const id = cipObserverHelper.getId(target);
- if (inputs.length > neededLength && !_observerIds.includes(id)) {
- // Save target element id for preventing multiple calls to initCredentialsFields()
- _observerIds.push(id);
-
- // Sometimes the settings haven't been loaded before new input fields are detected
- if (Object.keys(cip.settings).length === 0) {
- cip.init();
- } else {
- cip.initCredentialFields(true);
- }
- }
-};
-
-cipObserverHelper.handleObserverRemove = function(target) {
- if (cipObserverHelper.ignoredElement(target)) {
- return;
- }
-
- const inputs = cipObserverHelper.getInputs(target);
- if (inputs.length === 0) {
- return;
- }
-
- // Remove target element id from the list
- const id = cipObserverHelper.getId(target);
- if (_observerIds.includes(id)) {
- const index = _observerIds.indexOf(id);
- if (index >= 0) {
- _observerIds.splice(index, 1);
- }
- }
-};
-
-cipObserverHelper.detectURLChange = function() {
- if (_documentURL !== document.location.href) {
- _documentURL = document.location.href;
- cipEvents.clearCredentials();
- cip.initCredentialFields(true);
- }
-};
-
-MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
-
-// Detects DOM changes in the document
-let observer = new MutationObserver(function(mutations, observer) {
- if (document.visibilityState === 'hidden') {
- return;
- }
-
- for (const mut of mutations) {
- // Skip text nodes
- if (mut.target.nodeType === Node.TEXT_NODE) {
- continue;
- }
-
- // Check document URL change and detect new fields
- cipObserverHelper.detectURLChange();
-
- // Handle attributes only if CSS display is modified
- if (mut.type === 'attributes') {
- const newValue = mut.target.getAttribute(mut.attributeName);
- if (newValue && (newValue.includes('display') || newValue.includes('z-index'))) {
- if (mut.target.style.display !== 'none') {
- cipObserverHelper.handleObserverAdd(mut.target);
- } else {
- cipObserverHelper.handleObserverRemove(mut.target);
- }
- }
- } else if (mut.type === 'childList') {
- cipObserverHelper.handleObserverAdd((mut.addedNodes.length > 0) ? mut.addedNodes[0] : mut.target);
- cipObserverHelper.handleObserverRemove((mut.removedNodes.length > 0) ? mut.removedNodes[0] : mut.target);
- }
- }
-});
-
-// Define what element should be observed by the observer
-// and what types of mutations trigger the callback
-observer.observe(document, {
- subtree: true,
- attributes: true,
- childList: true,
- characterData: true,
- attributeFilter: ['style']
-});
-
-
-var cip = {};
-cip.settings = {};
-cip.u = null;
-cip.p = null;
-cip.url = null;
-cip.submitUrl = null;
-cip.credentials = [];
-
-jQuery(function() {
- cip.init();
-});
-
-cip.init = function() {
- browser.runtime.sendMessage({
- action: 'load_settings',
- }).then((response) => {
- cip.settings = response;
- cip.initCredentialFields();
- });
-};
-
-// Clears all from the content and background scripts, including autocomplete
-cip.clearAllFromPage = function() {
- cipEvents.clearCredentials();
-
- browser.runtime.sendMessage({
- action: 'page_clear_logins'
- });
-
- // Switch back to default popup
- browser.runtime.sendMessage({
- action: 'get_status',
- args: [ true ] // Set polling to true, this is an internal function call
- });
-};
-
-// Switch credentials if database is changed or closed
-cip.detectDatabaseChange = function(response) {
- cip.clearAllFromPage();
- if (document.visibilityState !== 'hidden') {
- if (response.new !== '' && response.new !== response.old) {
- _called.retrieveCredentials = false;
- browser.runtime.sendMessage({
- action: 'load_settings',
- }).then((settings) => {
- cip.settings = settings;
- cip.initCredentialFields(true);
-
- // If user has requested a manual fill through context menu the actual credential filling
- // is handled here when the opened database has been regognized. It's not a pretty hack.
- if (_called.manualFillRequested && _called.manualFillRequested !== 'none') {
- cip.fillInFromActiveElement(false, _called.manualFillRequested === 'pass');
- _called.manualFillRequested = 'none';
- }
- });
- }
- }
-};
-
-cip.initCredentialFields = function(forceCall) {
- if (_called.initCredentialFields && !forceCall) {
- return;
- }
- _called.initCredentialFields = true;
-
- browser.runtime.sendMessage({ 'action': 'page_clear_logins', args: [ _called.clearLogins ] }).then(() => {
- _called.clearLogins = true;
-
- // Check site preferences
- cip.initializeSitePreferences();
- if (cip.settings.sitePreferences) {
- for (const site of cip.settings.sitePreferences) {
- if (site.url === window.top.location.href || siteMatch(site.url, window.top.location.href)) {
- if (site.ignore === IGNORE_FULL) {
- return;
- }
-
- _singleInputEnabledForPage = site.usernameOnly;
- }
- }
- }
-
- const inputs = cipFields.getAllFields();
- if (inputs.length === 0) {
- return;
- }
-
- cipFields.prepareVisibleFieldsWithID('select');
- cip.initPasswordGenerator(inputs);
-
- if (!cipFields.useDefinedCredentialFields()) {
- // Get all combinations of username + password fields
- cipFields.combinations = cipFields.getAllCombinations(inputs);
- }
- cipFields.prepareCombinations(cipFields.combinations);
-
- if (cipFields.combinations.length === 0 && inputs.length === 0) {
- browser.runtime.sendMessage({
- action: 'show_default_browseraction'
- });
- return;
- }
-
- cip.url = document.location.origin;
- cip.submitUrl = cip.getFormActionUrl(cipFields.combinations[0]);
-
- // Get submitUrl for a single input
- if (_singleInputEnabledForPage && !cip.submitUrl && cipFields.combinations.length === 1 && inputs.length === 1) {
- cip.submitUrl = cip.getFormActionUrlFromSingleInput(inputs[0]);
- }
-
- if (cip.settings.autoRetrieveCredentials && _called.retrieveCredentials === false && (cip.url && cip.submitUrl)) {
- browser.runtime.sendMessage({
- action: 'retrieve_credentials',
- args: [ cip.url, cip.submitUrl ]
- }).then(cip.retrieveCredentialsCallback).catch((e) => {
- console.log(e);
- });
- } else if (_singleInputEnabledForPage) {
- cip.preparePageForMultipleCredentials(cip.credentials);
- }
- });
-};
-
-cip.initPasswordGenerator = function(inputs) {
- if (cip.settings.usePasswordGenerator) {
- cipPassword.init();
-
- for (let i = 0; i < inputs.length; i++) {
- if (inputs[i] && inputs[i].attr('type') && inputs[i].attr('type').toLowerCase() === 'password') {
- cipPassword.initField(inputs[i], inputs, i);
- }
- }
- }
-};
-
-cip.receiveCredentialsIfNecessary = function() {
- return new Promise((resolve, reject) => {
- if (cip.credentials.length === 0 && _called.retrieveCredentials === false) {
- browser.runtime.sendMessage({
- action: 'retrieve_credentials',
- args: [ cip.url, cip.submitUrl, false, true ] // Sets triggerUnlock to true
- }).then((credentials) => {
- // If the database was locked, this is scope never met. In these cases the response is met at cip.detectDatabaseChange
- _called.manualFillRequested = 'none';
- cip.retrieveCredentialsCallback(credentials, false);
- resolve(credentials);
- });
- } else {
- resolve(cip.credentials);
- }
- });
-};
-
-cip.retrieveCredentialsCallback = function(credentials, dontAutoFillIn) {
- if (cipFields.combinations.length > 0) {
- cip.u = _f(cipFields.combinations[0].username);
- cip.p = _f(cipFields.combinations[0].password);
- }
-
- if (credentials && credentials.length > 0) {
- cip.credentials = credentials;
- cip.prepareFieldsForCredentials(!Boolean(dontAutoFillIn));
- _called.retrieveCredentials = true;
- }
-};
-
-cip.prepareFieldsForCredentials = function(autoFillInForSingle) {
- // Only one login for this site
- if (autoFillInForSingle && cip.settings.autoFillSingleEntry && cip.credentials.length === 1) {
- let combination = null;
- if (!cip.p && !cip.u && cipFields.combinations.length > 0) {
- cip.u = _f(cipFields.combinations[0].username);
- cip.p = _f(cipFields.combinations[0].password);
- combination = cipFields.combinations[0];
- }
- if (cip.u) {
- cip.setValueWithChange(cip.u, cip.credentials[0].login);
- combination = cipFields.getCombination('username', cip.u);
- }
- if (cip.p) {
- cip.setValueWithChange(cip.p, cip.credentials[0].password);
- combination = cipFields.getCombination('password', cip.p);
- }
-
- if (combination) {
- const list = [];
- if (cip.fillInStringFields(combination.fields, cip.credentials[0].stringFields, list)) {
- cipForm.destroy(false, {'password': list.list[0], 'username': list.list[1]});
- }
- }
-
- // Generate popup-list of usernames + descriptions
- browser.runtime.sendMessage({
- action: 'popup_login',
- args: [ [cip.credentials[0].login + ' (' + cip.credentials[0].name + ')'] ]
- });
- } else if (cip.credentials.length > 1 || (cip.credentials.length > 0 && (!cip.settings.autoFillSingleEntry || !autoFillInForSingle))) {
- // Multiple logins for this site
- cip.preparePageForMultipleCredentials(cip.credentials);
- }
-};
-
-cip.preparePageForMultipleCredentials = function(credentials) {
- // Add usernames + descriptions to autocomplete-list and popup-list
- const usernames = [];
- cipAutocomplete.elements = [];
- let visibleLogin;
- for (let i = 0; i < credentials.length; i++) {
- visibleLogin = (credentials[i].login.length > 0) ? credentials[i].login : tr('credentialsNoUsername');
- usernames.push(visibleLogin + ' (' + credentials[i].name + ')');
- const item = {
- label: visibleLogin + ' (' + credentials[i].name + ')',
- value: credentials[i].login,
- loginId: i
- };
- cipAutocomplete.elements.push(item);
- }
-
- // Generate popup-list of usernames + descriptions
- browser.runtime.sendMessage({
- action: 'popup_login',
- args: [ usernames ]
- });
-
- // Initialize autocomplete for username fields
- if (cip.settings.autoCompleteUsernames) {
- for (const i of cipFields.combinations) {
- // Both username and password fields are visible
- if (_detectedFields >= 2) {
- if (_f(i.username)) {
- cipAutocomplete.init(_f(i.username));
- }
- } else if (_detectedFields == 1) {
- if (_f(i.username)) {
- cipAutocomplete.init(_f(i.username));
- }
- if (_f(i.password)) {
- cipAutocomplete.init(_f(i.password));
- }
- }
- }
- }
-};
-
-cip.getFormActionUrl = function(combination) {
- if (!combination) {
- return null;
- }
-
- const field = _f(combination.password) || _f(combination.username);
-
- if (field === null) {
- return null;
- }
-
- const form = field.closest('form');
- let action = null;
-
- if (form && form.length > 0) {
- action = form[0].action;
- }
-
- if (typeof(action) !== 'string' || action === '') {
- action = document.location.origin + document.location.pathname;
- }
-
- return action;
-};
-
-cip.getFormActionUrlFromSingleInput = function(field) {
- if (!field) {
- return null;
- }
-
- let action = field.formAction;
-
- if (typeof(action) !== 'string' || action === '') {
- action = document.location.origin + document.location.pathname;
- }
-
- return action;
-};
-
-cip.fillInCredentials = function(combination, onlyPassword, suppressWarnings) {
- const action = cip.getFormActionUrl(combination);
-
- const u = _f(combination.username);
- const p = _f(combination.password);
-
- if (combination.isNew) {
- // Initialize form-submit for remembering credentials
- const fieldId = combination.password || combination.username;
- const field = _f(fieldId);
- if (field) {
- const form2 = field.closest('form');
- if (form2 && form2.length > 0) {
- cipForm.init(form2, combination);
- }
- }
- }
-
- if (u) {
- cip.u = u;
- }
- if (p) {
- cip.p = p;
- }
-
- if (cip.url === document.location.origin && cip.submitUrl === action && cip.credentials.length > 0) {
- cip.fillIn(combination, onlyPassword, suppressWarnings);
- } else {
- cip.url = document.location.origin;
- cip.submitUrl = action;
-
- browser.runtime.sendMessage({
- action: 'retrieve_credentials',
- args: [ cip.url, cip.submitUrl, false, true ]
- }).then((credentials) => {
- cip.retrieveCredentialsCallback(credentials, true);
- cip.fillIn(combination, onlyPassword, suppressWarnings);
- });
- }
-};
-
-cip.fillInFromActiveElement = function(suppressWarnings, passOnly = false) {
- const el = document.activeElement;
- if (el.tagName.toLowerCase() !== 'input') {
- if (cipFields.combinations.length > 0) {
- cip.fillInCredentials(cipFields.combinations[0], false, suppressWarnings);
- }
- return;
- }
-
- cipFields.setUniqueId(jQuery(el));
- const fieldId = cipFields.prepareId(jQuery(el).attr('data-cip-id'));
- let combination = null;
- if ($(el).attr('type') === 'password') {
- combination = cipFields.getCombination('password', fieldId);
- } else {
- combination = cipFields.getCombination('username', fieldId);
- }
-
- if (passOnly) {
- if (!_f(combination.password)) {
- const message = tr('fieldsNoPasswordField');
- browser.runtime.sendMessage({
- action: 'show_notification',
- args: [ message ]
- });
- return;
- }
- }
-
- delete combination.loginId;
-
- cip.fillInCredentials(combination, passOnly, suppressWarnings);
-};
-
-cip.fillInFromActiveElementTOTPOnly = function(suppressWarnings) {
- const el = document.activeElement;
- cipFields.setUniqueId(jQuery(el));
- const fieldId = cipFields.prepareId(jQuery(el).attr('data-cip-id'));
-
- browser.runtime.sendMessage({
- action: 'page_get_login_id'
- }).then((pos) => {
- if (pos >= 0 && cip.credentials[pos]) {
- // Check the value from stringFields (to be removed)
- const currentField = _fs(fieldId);
- if (cip.credentials[pos].stringFields && cip.credentials[pos].stringFields.length > 0) {
- const stringFields = cip.credentials[pos].stringFields;
- for (const s of stringFields) {
- const val = s['KPH: {TOTP}'];
- if (val) {
- cip.setValue(currentField, val);
- }
- }
- } else if (cip.credentials[pos].totp && cip.credentials[pos].totp.length > 0) {
- cip.setValue(currentField, cip.credentials[pos].totp);
- }
- }
- });
-};
-
-cip.setValue = function(field, value) {
- if (field.is('select')) {
- value = value.toLowerCase().trim();
- jQuery('option', field).each(function() {
- if (jQuery(this).text().toLowerCase().trim() === value) {
- cip.setValueWithChange(field, jQuery(this).val());
- return false;
- }
- });
- } else {
- cip.setValueWithChange(field, value);
- field.trigger('input');
- }
-};
-
-cip.fillInStringFields = function(fields, stringFields, filledInFields) {
- let filledIn = false;
-
- filledInFields.list = [];
- if (fields && stringFields && fields.length > 0 && stringFields.length > 0) {
- for (let i = 0; i < fields.length; i++) {
- const currentField = _fs(fields[i]);
- const stringFieldValue = Object.values(stringFields[i]);
- if (currentField && stringFieldValue[0]) {
- cip.setValue(currentField, stringFieldValue[0]);
- filledInFields.list.push(fields[i]);
- filledIn = true;
- }
- }
- }
-
- return filledIn;
-};
-
-cip.setValueWithChange = function(field, value) {
- if (cip.settings.respectMaxLength === true) {
- const attributeMaxLength = field.attr('maxlength');
- if (attributeMaxLength && !isNaN(attributeMaxLength) && attributeMaxLength > 0) {
- value = value.substr(0, attributeMaxLength);
- }
- }
-
- field.val(value);
- field[0].dispatchEvent(new Event('input', { 'bubbles': true }));
- field[0].dispatchEvent(new Event('change', { 'bubbles': true }));
-};
-
-cip.fillIn = function(combination, onlyPassword, suppressWarnings) {
- // No credentials available
- if (cip.credentials.length === 0 && !suppressWarnings) {
- const message = tr('credentialsNoLoginsFound');
- browser.runtime.sendMessage({
- action: 'show_notification',
- args: [ message ]
- });
- return;
- }
-
- const uField = _f(combination.username);
- const pField = _f(combination.password);
-
- // Exactly one pair of credentials available
- if (cip.credentials.length === 1) {
- let filledIn = false;
- if (uField && (!onlyPassword || _singleInputEnabledForPage)) {
- cip.setValueWithChange(uField, cip.credentials[0].login);
- browser.runtime.sendMessage({
- action: 'page_set_login_id', args: [ 0 ]
- });
- filledIn = true;
- }
- if (pField) {
- pField.attr('type', 'password');
- cip.setValueWithChange(pField, cip.credentials[0].password);
- pField.data('unchanged', true);
- browser.runtime.sendMessage({
- action: 'page_set_login_id', args: [ 0 ]
- });
- filledIn = true;
- }
-
- const list = [];
- if (cip.fillInStringFields(combination.fields, cip.credentials[0].stringFields, list)) {
- cipForm.destroy(false, {'password': list.list[0], 'username': list.list[1]});
- filledIn = true;
- }
-
- if (!filledIn) {
- if (!suppressWarnings) {
- const message = tr('fieldsFill');
- browser.runtime.sendMessage({
- action: 'show_notification',
- args: [ message ]
- });
- }
- }
- } else if (combination.loginId !== undefined && cip.credentials[combination.loginId]) {
- // Specific login id given
- let filledIn = false;
- if (uField) {
- cip.setValueWithChange(uField, cip.credentials[combination.loginId].login);
- browser.runtime.sendMessage({
- action: 'page_set_login_id', args: [ combination.loginId ]
- });
- filledIn = true;
- }
-
- if (pField) {
- cip.setValueWithChange(pField, cip.credentials[combination.loginId].password);
- pField.data('unchanged', true);
- browser.runtime.sendMessage({
- action: 'page_set_login_id', args: [ combination.loginId ]
- });
- filledIn = true;
- }
-
- let list = [];
- if (cip.fillInStringFields(combination.fields, cip.credentials[combination.loginId].stringFields, list)) {
- cipForm.destroy(false, { 'password': list.list[0], 'username': list.list[1] });
- filledIn = true;
- }
-
- if (!filledIn) {
- if (!suppressWarnings) {
- const message = tr('fieldsFill');
- browser.runtime.sendMessage({
- action: 'show_notification',
- args: [ message ]
- });
- }
- }
- } else { // Multiple credentials available
- // Check if only one password for given username exists
- let countPasswords = 0;
-
- if (uField) {
- let valPassword = '';
- let valUsername = '';
- let valStringFields = [];
- const valQueryUsername = uField.val().toLowerCase();
-
- // Find passwords to given username (even those with empty username)
- for (const c of cip.credentials) {
- if (c.login.toLowerCase() === valQueryUsername) {
- countPasswords += 1;
- valPassword = c.password;
- valUsername = c.login;
- valStringFields = c.stringFields;
- }
- }
-
- // For the correct notification message: 0 = no logins, X > 1 = too many logins
- if (countPasswords === 0) {
- countPasswords = cip.credentials.length;
- }
-
- // Only one mapping username found
- if (countPasswords === 1) {
- if (!onlyPassword) {
- cip.setValueWithChange(uField, valUsername);
- }
-
- if (pField) {
- cip.setValueWithChange(pField, valPassword);
- pField.data('unchanged', true);
- }
-
- let list = [];
- if (cip.fillInStringFields(combination.fields, valStringFields, list)) {
- cipForm.destroy(false, { 'password': list.list[0], 'username': list.list[1] });
- }
- }
-
- // User has to select correct credentials by himself
- if (countPasswords > 1) {
- if (!suppressWarnings) {
- const $target = onlyPassword ? pField : uField;
- cipAutocomplete.init($target);
- $target.focus();
- jQuery($target).autocomplete('search', jQuery($target).val());
- }
- } else if (countPasswords < 1) {
- if (!suppressWarnings) {
- const message = tr('credentialsNoUsernameFound');
- browser.runtime.sendMessage({
- action: 'show_notification',
- args: [ message ]
- });
- }
- }
- } else {
- if (!suppressWarnings) {
- const $target = onlyPassword ? pField : uField;
- cipAutocomplete.init($target);
- $target.focus();
- jQuery($target).autocomplete('search', jQuery($target).val());
- }
- }
- }
-};
-
-cip.contextMenuRememberCredentials = function() {
- const el = document.activeElement;
- if (el.tagName.toLowerCase() !== 'input') {
- return;
- }
-
- cipFields.setUniqueId(jQuery(el));
- const fieldId = cipFields.prepareId(jQuery(el).attr('data-cip-id'));
- let combination = null;
- if ($(el).attr('type') === 'password') {
- combination = cipFields.getCombination('password', fieldId);
- } else {
- combination = cipFields.getCombination('username', fieldId);
- }
-
- let usernameValue = '';
- let passwordValue = '';
-
- const usernameField = _f(combination.username);
- const passwordField = _f(combination.password);
-
- if (usernameField) {
- usernameValue = usernameField.val();
- }
- if (passwordField) {
- passwordValue = passwordField.val();
- }
-
- if (!cip.rememberCredentials(usernameValue, passwordValue)) {
- const message = tr('rememberNothingChanged');
- browser.runtime.sendMessage({
- action: 'show_notification',
- args: [ message ]
- });
- }
-};
-
-cip.rememberCredentials = function(usernameValue, passwordValue) {
- // No password given or field cleaned by a site-running script
- // --> no password to save
- if (passwordValue === '') {
- return false;
- }
-
- let usernameExists = false;
- let nothingChanged = false;
-
- for (const c of cip.credentials) {
- if (c.login === usernameValue && c.password === passwordValue) {
- nothingChanged = true;
- break;
- }
-
- if (c.login === usernameValue) {
- usernameExists = true;
- }
- }
-
- if (!nothingChanged) {
- if (!usernameExists) {
- for (const c of cip.credentials) {
- if (c.login === usernameValue) {
- usernameExists = true;
- break;
- }
- }
- }
- const credentialsList = [];
- for (const c of cip.credentials) {
- credentialsList.push({
- login: c.login,
- name: c.name,
- uuid: c.uuid
- });
- }
-
- let url = jQuery(this)[0].action;
- if (!url) {
- url = cip.getDocumentLocation();
- if (url.indexOf('?') > 0) {
- url = url.substring(0, url.indexOf('?'));
- if (url.length < document.location.origin.length) {
- url = document.location.origin;
- }
- }
- }
-
- browser.runtime.sendMessage({
- action: 'set_remember_credentials',
- args: [ usernameValue, passwordValue, url, usernameExists, credentialsList ]
- });
-
- return true;
- }
-
- return false;
-};
-
-cip.ignoreSite = function(sites) {
- if (!sites || sites.length === 0) {
- return;
- }
-
- let site = sites[0];
- cip.initializeSitePreferences();
-
- if (slashNeededForUrl(site)) {
- site += '/';
- }
-
- // Check if the site already exists
- let siteExists = false;
- for (const existingSite of cip.settings['sitePreferences']) {
- if (existingSite.url === site) {
- existingSite.ignore = IGNORE_NORMAL;
- siteExists = true;
- }
- }
-
- if (!siteExists) {
- cip.settings['sitePreferences'].push({
- url: site,
- ignore: IGNORE_NORMAL,
- usernameOnly: false
- });
- }
-
- browser.runtime.sendMessage({
- action: 'save_settings',
- args: [ cip.settings ]
- });
-};
-
-// Delete previously created Object if it exists. It will be replaced by an Array
-cip.initializeSitePreferences = function() {
- if (cip.settings['sitePreferences'] !== undefined && cip.settings['sitePreferences'].constructor === Object) {
- delete cip.settings['sitePreferences'];
- }
-
- if (!cip.settings['sitePreferences']) {
- cip.settings['sitePreferences'] = [];
- }
-};
-
-cip.getDocumentLocation = function() {
- return cip.settings.saveDomainOnly ? document.location.origin : document.location.href;
-};
-
-var cipEvents = {};
-
-cipEvents.clearCredentials = function() {
- cip.credentials = [];
- cipAutocomplete.elements = [];
- _called.retrieveCredentials = false;
-
- if (cip.settings.autoCompleteUsernames) {
- for (const c of cipFields.combinations) {
- const uField = _f(c.username);
- if (uField) {
- if (uField.hasClass('ui-autocomplete-input')) {
- uField.autocomplete('destroy');
- }
- }
- }
- }
-};
-
-cipEvents.triggerActivatedTab = function() {
- // Doesn't run a second time because of _called.initCredentialFields set to true
- cip.init();
- $(this.target).find('input').autocomplete();
-
- // InitCredentialFields calls also "retrieve_credentials", to prevent it
- // check of init() was already called
- if (_called.initCredentialFields && (cip.url && cip.submitUrl) && cip.settings.autoRetrieveCredentials) {
- browser.runtime.sendMessage({
- action: 'retrieve_credentials',
- args: [ cip.url, cip.submitUrl ]
- }).then(cip.retrieveCredentialsCallback).catch((e) => {
- console.log(e);
- });
- }
-};
diff --git a/keepassxc-browser/manifest.json b/keepassxc-browser/manifest.json
index 0a8b441..a9431d9 100755
--- a/keepassxc-browser/manifest.json
+++ b/keepassxc-browser/manifest.json
@@ -1,7 +1,8 @@
{
"manifest_version": 2,
"name": "KeePassXC-Browser",
- "version": "1.3.2",
+ "version": "1.3.3",
+ "version_name": "1.3.3",
"description": "__MSG_extensionDescription__",
"author": "KeePassXC Team",
"icons": {
@@ -37,8 +38,8 @@
"background/page.js",
"background/event.js",
"background/init.js"
- ]
- },
+ ]
+ },
"content_scripts": [
{
"matches": [
@@ -50,14 +51,18 @@
],
"js": [
"browser-polyfill.min.js",
- "global.js",
- "jquery-3.3.1.min.js",
- "jquery-ui.min.js",
- "keepassxc-browser.js"
+ "content/autocomplete.js",
+ "content/define.js",
+ "content/keepassxc-browser.js",
+ "content/pwgen.js",
+ "content/ui.js",
+ "global.js"
],
"css": [
- "jquery-ui.min.css",
- "keepassxc-browser.css"
+ "css/autocomplete.css",
+ "css/button.css",
+ "css/define.css",
+ "css/pwgen.css"
],
"run_at": "document_idle",
"all_frames": true
@@ -111,10 +116,10 @@
"https://api.github.com/"
],
"applications": {
- "gecko": {
- "id": "keepassxc-browser@keepassxc.org",
- "strict_min_version": "52.0"
- }
- },
- "default_locale": "en"
+ "gecko": {
+ "id": "keepassxc-browser@keepassxc.org",
+ "strict_min_version": "52.0"
+ }
+ },
+ "default_locale": "en"
}
diff --git a/keepassxc-browser/options/options.html b/keepassxc-browser/options/options.html
index ff08ff8..d88d9c4 100644
--- a/keepassxc-browser/options/options.html
+++ b/keepassxc-browser/options/options.html
@@ -84,7 +84,7 @@
- 1
+
@@ -134,6 +134,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/keepassxc-browser/options/options.js b/keepassxc-browser/options/options.js
index 8936a74..ccf6119 100644
--- a/keepassxc-browser/options/options.js
+++ b/keepassxc-browser/options/options.js
@@ -94,7 +94,7 @@ options.initGeneralSettings = function() {
$('#tab-general-settings input[type=checkbox]').change(function() {
const name = $(this).attr('name');
options.settings[name] = $(this).is(':checked');
- options.saveSettingsPromise().then((x) => {
+ options.saveSettingsPromise().then((updated) => {
if (name === 'autoFillAndSend') {
browser.runtime.sendMessage({ action: 'init_http_auth' });
} else if (name === 'defaultGroupAlwaysAsk') {
@@ -107,6 +107,9 @@ options.initGeneralSettings = function() {
$('#defaultGroupButton').prop('disabled', false);
$('#defaultGroupButtonReset').prop('disabled', false);
}
+ } else if (name == 'automaticReconnect') {
+ const message = updated.automaticReconnect ? 'enable_automatic_reconnect' : 'disable_automatic_reconnect';
+ browser.runtime.sendMessage({ action: message });
}
});
});
@@ -330,6 +333,10 @@ options.initCustomCredentialFields = function() {
};
options.initSitePreferences = function() {
+ if (!options.settings['sitePreferences']) {
+ options.settings['sitePreferences'] = [];
+ }
+
$('#dialogDeleteSite').modal({ keyboard: true, show: false, backdrop: true });
$('#tab-site-preferences tr.clone:first button.delete:first').click(function(e) {
e.preventDefault();
diff --git a/keepassxc-browser/options/shortcuts.js b/keepassxc-browser/options/shortcuts.js
index 95bd0c9..457e175 100644
--- a/keepassxc-browser/options/shortcuts.js
+++ b/keepassxc-browser/options/shortcuts.js
@@ -74,8 +74,8 @@ async function updateShortcut(shortcut) {
shortcut: document.querySelector('#' + shortcut).value
});
createBanner('success', shortcut);
- } catch (e) {
- console.log('Cannot change shortcut: ' + e);
+ } catch (err) {
+ console.log('Cannot change shortcut: ' + err);
createBanner('danger', shortcut);
}
}
diff --git a/keepassxc-browser/popups/popup.css b/keepassxc-browser/popups/popup.css
index 9fb4e8c..0544697 100644
--- a/keepassxc-browser/popups/popup.css
+++ b/keepassxc-browser/popups/popup.css
@@ -40,18 +40,18 @@ body {
font-size: 80%;
color: #787878;
}
-.small {
- margin-top: 3px;
- margin-left: 12px;
- font-size: 80%;
- color: #787878;
-}
#list {
padding-left: 0px;
}
#child {
border-top: 0px;
}
+.small {
+ margin-top: 3px;
+ margin-left: 12px;
+ font-size: 80%;
+ color: #787878;
+}
#update-available {
padding-top: 10px;
margin-top: 10px;
diff --git a/keepassxc-browser/popups/popup.html b/keepassxc-browser/popups/popup.html
index 587cf40..b79b97a 100644
--- a/keepassxc-browser/popups/popup.html
+++ b/keepassxc-browser/popups/popup.html
@@ -1,15 +1,17 @@
+
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -30,18 +32,18 @@
-
diff --git a/keepassxc-browser/popups/popup_httpauth.html b/keepassxc-browser/popups/popup_httpauth.html
index 1d8a53a..37d7410 100644
--- a/keepassxc-browser/popups/popup_httpauth.html
+++ b/keepassxc-browser/popups/popup_httpauth.html
@@ -1,15 +1,17 @@
+
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -33,6 +35,5 @@
-
diff --git a/keepassxc-browser/popups/popup_httpauth.js b/keepassxc-browser/popups/popup_httpauth.js
index 04732cd..5072079 100644
--- a/keepassxc-browser/popups/popup_httpauth.js
+++ b/keepassxc-browser/popups/popup_httpauth.js
@@ -3,7 +3,7 @@
const getLoginData = function() {
return new Promise((resolve, reject) => {
browser.runtime.getBackgroundPage().then((global) => {
- browser.tabs.query({ 'active': true, 'currentWindow': true }).then((tabs) => {
+ browser.tabs.query({'active': true, 'currentWindow': true}).then((tabs) => {
resolve(global.page.tabs[tabs[0].id].loginList);
});
});
diff --git a/keepassxc-browser/popups/popup_login.html b/keepassxc-browser/popups/popup_login.html
index 902d4e8..676fb4a 100644
--- a/keepassxc-browser/popups/popup_login.html
+++ b/keepassxc-browser/popups/popup_login.html
@@ -1,15 +1,17 @@
+
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -44,6 +46,5 @@
-
diff --git a/keepassxc-browser/popups/popup_multiple-fields.html b/keepassxc-browser/popups/popup_multiple-fields.html
index 10a2c89..ae930e1 100644
--- a/keepassxc-browser/popups/popup_multiple-fields.html
+++ b/keepassxc-browser/popups/popup_multiple-fields.html
@@ -1,14 +1,16 @@
+
-
-
-
-
-
+
+
+
+
+
+
@@ -31,6 +33,5 @@
-
diff --git a/keepassxc-browser/popups/popup_remember.html b/keepassxc-browser/popups/popup_remember.html
index d7904a7..61ebc23 100644
--- a/keepassxc-browser/popups/popup_remember.html
+++ b/keepassxc-browser/popups/popup_remember.html
@@ -1,15 +1,17 @@
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
diff --git a/keepassxc-browser/popups/popup_remember.js b/keepassxc-browser/popups/popup_remember.js
index b494dde..37cddfa 100644
--- a/keepassxc-browser/popups/popup_remember.js
+++ b/keepassxc-browser/popups/popup_remember.js
@@ -50,7 +50,7 @@ function _initialize(tab) {
// Another group name has been specified
const [ gname, guuid ] = getDefaultGroup(result.groups[0].children, result.defaultGroup);
if (gname === '' && guuid === '') {
- showNotification(tr('popupRememberErrorDefaultGroupNotFound'));
+ showNotification(tr('popupRememberInfoDefaultGroupNotFound'));
// Create a new group
browser.runtime.sendMessage({
@@ -216,7 +216,7 @@ function _initialize(tab) {
const currentTab = tabs[0];
browser.runtime.getBackgroundPage().then((global) => {
browser.tabs.sendMessage(currentTab.id, {
- action: 'ignore-site',
+ action: 'ignore_site',
args: [ _tab.credentials.url ]
});
_close();
diff --git a/keepassxc-browser/popups/throbber.gif b/keepassxc-browser/popups/throbber.gif
index 3bc13d1..951ad19 100644
Binary files a/keepassxc-browser/popups/throbber.gif and b/keepassxc-browser/popups/throbber.gif differ