http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/js/require.min.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/js/require.min.js b/src/main/web/hicc/ajax-solr/chukwa/js/require.min.js new file mode 100644 index 0000000..987f865 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/js/require.min.js @@ -0,0 +1,35 @@ +/* + RequireJS 2.1.5 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. + Available via the MIT or new BSD license. + see: http://github.com/jrburke/requirejs for details +*/ +var requirejs,require,define; +(function(aa){function I(b){return"[object Function]"===L.call(b)}function J(b){return"[object Array]"===L.call(b)}function y(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function M(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function m(b,c){return s(b,c)&&b[c]}function G(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function R(b,c,d,m){c&&G(c,function(c,j){if(d||!s(b,j))m&&"string"!==typeof c?(b[j]||(b[j]={}),R(b[j], +c,d,m)):b[j]=c});return b}function u(b,c){return function(){return c.apply(b,arguments)}}function ba(b){if(!b)return b;var c=aa;y(b.split("."),function(b){c=c[b]});return c}function B(b,c,d,m){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=m;d&&(c.originalError=d);return c}function ha(b){function c(a,f,b){var e,n,c,g,d,S,i,h=f&&f.split("/");e=h;var j=k.map,l=j&&j["*"];if(a&&"."===a.charAt(0))if(f){e=m(k.pkgs,f)?h=[f]:h.slice(0,h.length-1);f=a=e.concat(a.split("/")); +for(e=0;f[e];e+=1)if(n=f[e],"."===n)f.splice(e,1),e-=1;else if(".."===n)if(1===e&&(".."===f[2]||".."===f[0]))break;else 0<e&&(f.splice(e-1,2),e-=2);e=m(k.pkgs,f=a[0]);a=a.join("/");e&&a===f+"/"+e.main&&(a=f)}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&j&&(h||l)){f=a.split("/");for(e=f.length;0<e;e-=1){c=f.slice(0,e).join("/");if(h)for(n=h.length;0<n;n-=1)if(b=m(j,h.slice(0,n).join("/")))if(b=m(b,c)){g=b;d=e;break}if(g)break;!S&&(l&&m(l,c))&&(S=m(l,c),i=e)}!g&&S&&(g=S,d=i);g&&(f.splice(0,d, +g),a=f.join("/"))}return a}function d(a){A&&y(document.getElementsByTagName("script"),function(f){if(f.getAttribute("data-requiremodule")===a&&f.getAttribute("data-requirecontext")===i.contextName)return f.parentNode.removeChild(f),!0})}function z(a){var f=m(k.paths,a);if(f&&J(f)&&1<f.length)return d(a),f.shift(),i.require.undef(a),i.require([a]),!0}function h(a){var f,b=a?a.indexOf("!"):-1;-1<b&&(f=a.substring(0,b),a=a.substring(b+1,a.length));return[f,a]}function j(a,f,b,e){var n,C,g=null,d=f?f.name: +null,j=a,l=!0,k="";a||(l=!1,a="_@r"+(M+=1));a=h(a);g=a[0];a=a[1];g&&(g=c(g,d,e),C=m(q,g));a&&(g?k=C&&C.normalize?C.normalize(a,function(a){return c(a,d,e)}):c(a,d,e):(k=c(a,d,e),a=h(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!C&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:f,unnormalized:!!b,url:n,originalName:j,isDefine:l,id:(g?g+"!"+k:k)+b}}function r(a){var f=a.id,b=m(p,f);b||(b=p[f]=new i.Module(a));return b}function t(a,f,b){var e=a.id,n=m(p,e);if(s(q,e)&&(!n||n.defineEmitComplete))"defined"=== +f&&b(q[e]);else r(a).on(f,b)}function v(a,f){var b=a.requireModules,e=!1;if(f)f(a);else if(y(b,function(f){if(f=m(p,f))f.error=a,f.events.error&&(e=!0,f.emit("error",a))}),!e)l.onError(a)}function w(){T.length&&(ia.apply(H,[H.length-1,0].concat(T)),T=[])}function x(a){delete p[a];delete V[a]}function F(a,f,b){var e=a.map.id;a.error?a.emit("error",a.error):(f[e]=!0,y(a.depMaps,function(e,c){var g=e.id,d=m(p,g);d&&(!a.depMatched[c]&&!b[g])&&(m(f,g)?(a.defineDep(c,q[g]),a.check()):F(d,f,b))}),b[e]=!0)} +function D(){var a,f,b,e,n=(b=1E3*k.waitSeconds)&&i.startTime+b<(new Date).getTime(),c=[],g=[],h=!1,j=!0;if(!W){W=!0;G(V,function(b){a=b.map;f=a.id;if(b.enabled&&(a.isDefine||g.push(b),!b.error))if(!b.inited&&n)z(f)?h=e=!0:(c.push(f),d(f));else if(!b.inited&&(b.fetched&&a.isDefine)&&(h=!0,!a.prefix))return j=!1});if(n&&c.length)return b=B("timeout","Load timeout for modules: "+c,null,c),b.contextName=i.contextName,v(b);j&&y(g,function(a){F(a,{},{})});if((!n||e)&&h)if((A||da)&&!X)X=setTimeout(function(){X= +0;D()},50);W=!1}}function E(a){s(q,a[0])||r(j(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,b=i.onScriptLoad;a.detachEvent&&!Y?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=i.onScriptError;(!a.detachEvent||Y)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function L(){var a;for(w();H.length;){a=H.shift();if(null===a[0])return v(B("mismatch","Mismatched anonymous define() module: "+a[a.length- +1]));E(a)}}var W,Z,i,N,X,k={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},shim:{},config:{}},p={},V={},$={},H=[],q={},U={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=q[a.map.id]={}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return k.config&&m(k.config,a.map.id)||{}},exports:q[a.map.id]}}};Z=function(a){this.events= +m($,a.id)||{};this.map=a;this.shim=m(k.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};Z.prototype={init:function(a,b,c,e){e=e||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=u(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;this.ignore=e.ignore;e.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]= +!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],u(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=this.map.url;U[a]||(U[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports; +var e=this.exports,n=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(I(n)){if(this.events.error)try{e=i.execCb(c,n,b,e)}catch(d){a=d}else e=i.execCb(c,n,b,e);this.map.isDefine&&((b=this.module)&&void 0!==b.exports&&b.exports!==this.exports?e=b.exports:void 0===e&&this.usingExports&&(e=this.exports));if(a)return a.requireMap=this.map,a.requireModules=[this.map.id],a.requireType="define",v(this.error= +a)}else e=n;this.exports=e;if(this.map.isDefine&&!this.ignore&&(q[c]=e,l.onResourceLoad))l.onResourceLoad(i,this.map,this.depMaps);x(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=j(a.prefix);this.depMaps.push(d);t(d,"defined",u(this,function(e){var n,d;d=this.map.name;var g=this.map.parentMap?this.map.parentMap.name:null,h= +i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(e.normalize&&(d=e.normalize(d,function(a){return c(a,g,!0)})||""),e=j(a.prefix+"!"+d,this.map.parentMap),t(e,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=m(p,e.id)){this.depMaps.push(e);if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else n=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),n.error=u(this, +function(a){this.inited=!0;this.error=a;a.requireModules=[b];G(p,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&x(a.map.id)});v(a)}),n.fromText=u(this,function(e,c){var d=a.name,g=j(d),C=O;c&&(e=c);C&&(O=!1);r(g);s(k.config,b)&&(k.config[d]=k.config[b]);try{l.exec(e)}catch(ca){return v(B("fromtexteval","fromText eval for "+b+" failed: "+ca,ca,[b]))}C&&(O=!0);this.depMaps.push(g);i.completeLoad(d);h([d],n)}),e.load(a.name,h,n,k)}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]= +this;this.enabling=this.enabled=!0;y(this.depMaps,u(this,function(a,b){var c,e;if("string"===typeof a){a=j(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=m(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;t(a,"defined",u(this,function(a){this.defineDep(b,a);this.check()}));this.errback&&t(a,"error",this.errback)}c=a.id;e=p[c];!s(N,c)&&(e&&!e.enabled)&&i.enable(a,this)}));G(this.pluginMaps,u(this,function(a){var b=m(p,a.id);b&&!b.enabled&&i.enable(a, +this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){y(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:k,contextName:b,registry:p,defined:q,urlFetched:U,defQueue:H,Module:Z,makeModuleMap:j,nextTick:l.nextTick,onError:v,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=k.pkgs,c=k.shim,e={paths:!0,config:!0,map:!0};G(a,function(a,b){e[b]? +"map"===b?(k.map||(k.map={}),R(k[b],a,!0,!0)):R(k[b],a,!0):k[b]=a});a.shim&&(G(a.shim,function(a,b){J(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);c[b]=a}),k.shim=c);a.packages&&(y(a.packages,function(a){a="string"===typeof a?{name:a}:a;b[a.name]={name:a.name,location:a.location||a.name,main:(a.main||"main").replace(ja,"").replace(ea,"")}}),k.pkgs=b);G(p,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=j(b))});if(a.deps||a.callback)i.require(a.deps||[], +a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(aa,arguments));return b||a.exports&&ba(a.exports)}},makeRequire:function(a,f){function d(e,c,h){var g,k;f.enableBuildCallback&&(c&&I(c))&&(c.__requireJsBuild=!0);if("string"===typeof e){if(I(c))return v(B("requireargs","Invalid require call"),h);if(a&&s(N,e))return N[e](p[a.id]);if(l.get)return l.get(i,e,a,d);g=j(e,a,!1,!0);g=g.id;return!s(q,g)?v(B("notloaded",'Module name "'+g+'" has not been loaded yet for context: '+ +b+(a?"":". Use require([])"))):q[g]}L();i.nextTick(function(){L();k=r(j(null,a));k.skipMap=f.skipMap;k.init(e,c,h,{enabled:!0});D()});return d}f=f||{};R(d,{isBrowser:A,toUrl:function(b){var d,f=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==f&&(!("."===g||".."===g)||1<f))d=b.substring(f,b.length),b=b.substring(0,f);return i.nameToUrl(c(b,a&&a.id,!0),d,!0)},defined:function(b){return s(q,j(b,a,!1,!0).id)},specified:function(b){b=j(b,a,!1,!0).id;return s(q,b)||s(p,b)}});a||(d.undef=function(b){w();var c= +j(b,a,!0),d=m(p,b);delete q[b];delete U[c.url];delete $[b];d&&(d.events.defined&&($[b]=d.events),x(b))});return d},enable:function(a){m(p,a.id)&&r(a).enable()},completeLoad:function(a){var b,c,e=m(k.shim,a)||{},d=e.exports;for(w();H.length;){c=H.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=m(p,a);if(!b&&!s(q,a)&&c&&!c.inited){if(k.enforceDefine&&(!d||!ba(d)))return z(a)?void 0:v(B("nodefine","No define call for "+a,null,[a]));E([a,e.deps||[],e.exportsFn])}D()},nameToUrl:function(a, +b,c){var e,d,h,g,j,i;if(l.jsExtRegExp.test(a))g=a+(b||"");else{e=k.paths;d=k.pkgs;g=a.split("/");for(j=g.length;0<j;j-=1)if(i=g.slice(0,j).join("/"),h=m(d,i),i=m(e,i)){J(i)&&(i=i[0]);g.splice(0,j,i);break}else if(h){a=a===h.name?h.location+"/"+h.main:h.location;g.splice(0,j,a);break}g=g.join("/");g+=b||(/\?/.test(g)||c?"":".js");g=("/"===g.charAt(0)||g.match(/^[\w\+\.\-]+:/)?"":k.baseUrl)+g}return k.urlArgs?g+((-1===g.indexOf("?")?"?":"&")+k.urlArgs):g},load:function(a,b){l.load(i,a,b)},execCb:function(a, +b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!z(b.id))return v(B("scripterror","Script error",a,[b.id]))}};i.require=i.makeRequire();return i}var l,w,x,D,t,E,P,K,Q,fa,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,ea=/\.js$/,ja=/^\.\//;w=Object.prototype;var L=w.toString,ga=w.hasOwnProperty,ia= +Array.prototype.splice,A=!!("undefined"!==typeof window&&navigator&&document),da=!A&&"undefined"!==typeof importScripts,ka=A&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,Y="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},T=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(I(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!I(require)&&(r=require,require=void 0);l=requirejs=function(b,c,d,z){var h, +j="_";!J(b)&&"string"!==typeof b&&(h=b,J(c)?(b=c,c=d,d=z):b=[]);h&&h.context&&(j=h.context);(z=m(F,j))||(z=F[j]=l.s.newContext(j));h&&z.configure(h);return z.require(b,c,d)};l.config=function(b){return l(b)};l.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=l);l.version="2.1.5";l.jsExtRegExp=/^\/|:|\?|\.js$/;l.isBrowser=A;w=l.s={contexts:F,newContext:ha};l({});y(["toUrl","undef","defined","specified"],function(b){l[b]=function(){var c=F._;return c.require[b].apply(c, +arguments)}});if(A&&(x=w.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))x=w.head=D.parentNode;l.onError=function(b){throw b;};l.load=function(b,c,d){var l=b&&b.config||{},h;if(A)return h=l.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script"),h.type=l.scriptType||"text/javascript",h.charset="utf-8",h.async=!0,h.setAttribute("data-requirecontext",b.contextName),h.setAttribute("data-requiremodule",c), +h.attachEvent&&!(h.attachEvent.toString&&0>h.attachEvent.toString().indexOf("[native code"))&&!Y?(O=!0,h.attachEvent("onreadystatechange",b.onScriptLoad)):(h.addEventListener("load",b.onScriptLoad,!1),h.addEventListener("error",b.onScriptError,!1)),h.src=d,K=h,D?x.insertBefore(h,D):x.appendChild(h),K=null,h;if(da)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(B("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};A&&M(document.getElementsByTagName("script"),function(b){x||(x= +b.parentNode);if(t=b.getAttribute("data-main"))return r.baseUrl||(E=t.split("/"),Q=E.pop(),fa=E.length?E.join("/")+"/":"./",r.baseUrl=fa,t=Q),t=t.replace(ea,""),r.deps=r.deps?r.deps.concat(t):[t],!0});define=function(b,c,d){var l,h;"string"!==typeof b&&(d=c,c=b,b=null);J(c)||(d=c,c=[]);!c.length&&I(d)&&d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c));if(O){if(!(l=K))P&&"interactive"===P.readyState||M(document.getElementsByTagName("script"), +function(b){if("interactive"===b.readyState)return P=b}),l=P;l&&(b||(b=l.getAttribute("data-requiremodule")),h=F[l.getAttribute("data-requirecontext")])}(h?h.defQueue:T).push([b,c,d])};define.amd={jQuery:!0};l.exec=function(b){return eval(b)};l(r)}})(this);
http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/log-viewer.html ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/log-viewer.html b/src/main/web/hicc/ajax-solr/chukwa/log-viewer.html new file mode 100644 index 0000000..e71987b --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/log-viewer.html @@ -0,0 +1,35 @@ +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Log Viewer</title> + <link href="../../css/bootstrap.min.css" type="text/css" rel="stylesheet" /> + <link href="../../css/bootstrap-theme.min.css" type="text/css" rel="stylesheet" /> + <link href="css/logviewer.css" type ="text/css" rel="stylesheet" /> + <script src="../../js/jquery.js" type="text/javascript"></script> + <script src="../../js/bootstrap.min.js" type="text/javascript"></script> +</head> +<body> + <div id="content"></div> + <script src="js/logviewer.js" type="text/javascript"></script> +</body> +</html> http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.7.0.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.7.0.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.7.0.js new file mode 100644 index 0000000..e7e9db5 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.7.0.js @@ -0,0 +1,57 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractTextWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.AutocompleteWidget = AjaxSolr.AbstractTextWidget.extend({ + afterRequest: function () { + $(this.target).find('input').unbind().removeData('events').val(''); + + var self = this; + + var list = []; + for (var i = 0; i < this.fields.length; i++) { + var field = this.fields[i]; + for (var facet in this.manager.response.facet_counts.facet_fields[field]) { + list.push({ + field: field, + value: facet, + label: facet + ' (' + this.manager.response.facet_counts.facet_fields[field][facet] + ') - ' + field + }); + } + } + + this.requestSent = false; + $(this.target).find('input').autocomplete('destroy').autocomplete({ + source: list, + select: function(event, ui) { + if (ui.item) { + self.requestSent = true; + if (self.manager.store.addByValue('fq', ui.item.field + ':' + AjaxSolr.Parameter.escapeValue(ui.item.value))) { + self.doRequest(); + } + } + } + }); + + // This has lower priority so that requestSent is set. + $(this.target).find('input').bind('keydown', function(e) { + if (self.requestSent === false && e.which == 13) { + var value = $(this).val(); + if (value && self.set(value)) { + self.doRequest(); + } + } + }); + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.js new file mode 100644 index 0000000..6a00865 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/AutocompleteWidget.js @@ -0,0 +1,71 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractTextWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.AutocompleteWidget = AjaxSolr.AbstractTextWidget.extend({ + afterRequest: function () { + $(this.target).find('input').unbind().removeData('events').val(''); + + var self = this; + + var callback = function (response) { + var list = []; + for (var i = 0; i < self.fields.length; i++) { + var field = self.fields[i]; + for (var facet in response.facet_counts.facet_fields[field]) { + list.push({ + field: field, + value: facet, + label: facet + ' (' + response.facet_counts.facet_fields[field][facet] + ') - ' + field + }); + } + } + + self.requestSent = false; + $(self.target).find('input').autocomplete({ + minLength: 2, + source: list, + select: function(event, ui) { + if (ui.item) { + self.requestSent = true; + if (self.manager.store.addByValue('fq', ui.item.field + ':' + AjaxSolr.Parameter.escapeValue(ui.item.value))) { + self.doRequest(); + } + } + } + }); + + // This has lower priority so that requestSent is set. + $(self.target).find('input').bind('keydown', function(e) { + if (self.requestSent === false && e.which == 13) { + var value = $(this).val(); + if (value && self.set(value)) { + self.doRequest(); + } + } + }); + } // end callback + + var params = [ 'rows=0&facet=true&facet.limit=-1&facet.mincount=1&json.nl=map' ]; + for (var i = 0; i < this.fields.length; i++) { + params.push('facet.field=' + this.fields[i]); + } + var values = this.manager.store.values('fq'); + for (var i = 0; i < values.length; i++) { + params.push('fq=' + encodeURIComponent(values[i])); + } + params.push('q=' + this.manager.store.get('q').val()); + $.getJSON(this.manager.solrUrl + 'select?' + params.join('&') + '&wt=json&json.wrf=?', {}, callback); + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CalendarWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CalendarWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CalendarWidget.js new file mode 100644 index 0000000..26759ff --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CalendarWidget.js @@ -0,0 +1,38 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractFacetWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.CalendarWidget = AjaxSolr.AbstractFacetWidget.extend({ + afterRequest: function () { + var self = this; + $(this.target).datepicker('destroy').datepicker({ + dateFormat: 'yy-mm-dd', + defaultDate: new Date(1987, 2, 1), + maxDate: $.datepicker.parseDate('yy-mm-dd', this.manager.store.get('facet.date.end').val().split('T')[0]), + minDate: $.datepicker.parseDate('yy-mm-dd', this.manager.store.get('facet.date.start').val().split('T')[0]), + nextText: '>', + prevText: '<', + beforeShowDay: function (date) { + var value = $.datepicker.formatDate('yy-mm-dd', date) + 'T00:00:00Z'; + var count = self.manager.response.facet_counts.facet_dates[self.field][value]; + return [ parseInt(count) > 0, '', count + ' documents found!' ]; + }, + onSelect: function (dateText, inst) { + if (self.add('[' + dateText + 'T00:00:00Z TO ' + dateText + 'T23:59:59Z]')) { + self.doRequest(); + } + } + }); + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.8.0.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.8.0.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.8.0.js new file mode 100644 index 0000000..28ff16e --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.8.0.js @@ -0,0 +1,50 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractFacetWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.CountryCodeWidget = AjaxSolr.AbstractFacetWidget.extend({ + afterRequest: function () { + var self = this; + + $(this.target).empty(); + + var maxCount = 0; + var options = { '': '--select--' }; + for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) { + if (facet.length == 2) { // only display country codes + var count = this.manager.response.facet_counts.facet_fields[this.field][facet]; + if (count > maxCount) { + maxCount = count; + } + options[facet] = facet + ' (' + count + ')'; + } + } + $(this.target).append(this.template('country', options)); + + $(this.target).find('#country').change(function () { + var value = $(this).val(); + if (value && self.add(value)) { + self.doRequest(); + } + }); + }, + + template: function (name, container) { + var options = []; + for (var value in container) { + options.push('<option value="' + value +'">' + container[value] + '</option>'); + } + return '<select id="' + name + '" name="' + name + '">' + options.join('\n') + '</select>'; + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.js new file mode 100644 index 0000000..dfe5eca --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CountryCodeWidget.js @@ -0,0 +1,79 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractFacetWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.CountryCodeWidget = AjaxSolr.AbstractFacetWidget.extend({ + afterRequest: function () { + var self = this; + + $(this.target).empty(); + + var maps = { + world: 'view the World', + africa: 'view Africa', + asia: 'view Asia', + europe: 'view Europe', + middle_east: 'view the Middle East', + south_america: 'view South America', + usa: 'view North America' + }; + $(this.target).append(this.template('region', maps)); + + $(this.target).find('#region').change(function () { + $(self.target).find('img').hide(); + $('#' + self.id + $(this).val()).show(); + }); + + var maxCount = 0; + var options = { '': '--select--' }; + for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) { + if (facet.length == 2) { // only display country codes + var count = this.manager.response.facet_counts.facet_fields[this.field][facet]; + if (count > maxCount) { + maxCount = count; + } + options[facet] = facet + ' (' + count + ')'; + } + } + $(this.target).append(this.template('country', options)); + + $(this.target).find('#country').change(function () { + var value = $(this).val(); + if (value && self.add(value)) { + self.doRequest(); + } + }); + + var chd = []; + var chld = ''; + for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) { + if (facet.length == 2) { // only display country codes + chd.push(parseInt(this.manager.response.facet_counts.facet_fields[this.field][facet] / maxCount * 100) + '.0'); + chld += facet; + } + } + for (var value in maps) { + var src = 'http://chart.apis.google.com/chart?chco=f5f5f5,edf0d4,6c9642,365e24,13390a&chd=t:' + chd.join(',') + '&chf=bg,s,eaf7fe&chtm=' + value + '&chld=' + chld + '&chs=350x180&cht=t'; + $('<img>').attr('id', this.id + value).showIf(value == 'world').attr('src', src).appendTo(this.target); + } + }, + + template: function (name, container) { + var options = []; + for (var value in container) { + options.push('<option value="' + value +'">' + container[value] + '</option>'); + } + return '<select id="' + name + '" name="' + name + '">' + options.join('\n') + '</select>'; + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.9.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.9.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.9.js new file mode 100644 index 0000000..21b22f4 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.9.js @@ -0,0 +1,74 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.CurrentSearchWidget = AjaxSolr.AbstractWidget.extend({ + start: 0, + + afterRequest: function () { + var self = this; + var links = []; + + var q = this.manager.store.get('q').val(); + if (q != '*:*') { + links.push($('<a href="#"></a>').text('(x) ' + q).click(function () { + self.manager.store.get('q').val('*:*'); + self.doRequest(); + return false; + })); + } + + var fq = this.manager.store.values('fq'); + for (var i = 0, l = fq.length; i < l; i++) { + if (fq[i].match(/[\[\{]\S+ TO \S+[\]\}]/)) { + var field = fq[i].match(/^\w+:/)[0]; + var value = fq[i].substr(field.length + 1, 10); + links.push($('<a href="#"></a>').text('(x) ' + field + value).click(self.removeFacet(fq[i]))); + } + else { + links.push($('<a href="#"></a>').text('(x) ' + fq[i]).click(self.removeFacet(fq[i]))); + } + } + + if (links.length > 1) { + links.unshift($('<a href="#"></a>').text('remove all').click(function () { + self.manager.store.get('q').val('*:*'); + self.manager.store.remove('fq'); + self.doRequest(); + return false; + })); + } + + if (links.length) { + var $target = $(this.target); + $target.empty(); + for (var i = 0, l = links.length; i < l; i++) { + $target.append($('<li></li>').append(links[i])); + } + } + else { + $(this.target).html('<li>Viewing all documents!</li>'); + } + }, + + removeFacet: function (facet) { + var self = this; + return function () { + if (self.manager.store.removeByValue('fq', facet)) { + self.doRequest(); + } + return false; + }; + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.js new file mode 100644 index 0000000..3378553 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/CurrentSearchWidget.js @@ -0,0 +1,67 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.CurrentSearchWidget = AjaxSolr.AbstractWidget.extend({ + start: 0, + + afterRequest: function () { + var self = this; + var links = []; + + var q = this.manager.store.get('q').val(); + if (q != '*:*') { + links.push($('<a href="#"></a>').text('(x) ' + q).click(function () { + self.manager.store.get('q').val('*:*'); + self.doRequest(); + return false; + })); + } + + var fq = this.manager.store.values('fq'); + for (var i = 0, l = fq.length; i < l; i++) { + links.push($('<a href="#"></a>').text('(x) ' + fq[i]).click(self.removeFacet(fq[i]))); + } + + if (links.length > 1) { + links.unshift($('<a href="#"></a>').text('remove all').click(function () { + self.manager.store.get('q').val('*:*'); + self.manager.store.remove('fq'); + self.doRequest(); + return false; + })); + } + + if (links.length) { + var $target = $(this.target); + $target.empty(); + for (var i = 0, l = links.length; i < l; i++) { + $target.append($('<li></li>').append(links[i])); + } + } + else { + $(this.target).html('<li>Viewing all documents!</li>'); + } + }, + + removeFacet: function (facet) { + var self = this; + return function () { + if (self.manager.store.removeByValue('fq', facet)) { + self.doRequest(); + } + return false; + }; + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.2.0.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.2.0.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.2.0.js new file mode 100644 index 0000000..e343c0a --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.2.0.js @@ -0,0 +1,41 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.ResultWidget = AjaxSolr.AbstractWidget.extend({ + afterRequest: function () { + $(this.target).empty(); + for (var i = 0, l = this.manager.response.response.docs.length; i < l; i++) { + var doc = this.manager.response.response.docs[i]; + $(this.target).append(this.template(doc)); + } + }, + + template: function (doc) { + var snippet = ''; + if (doc.data.length > 300) { + snippet += doc.source + ' ' + doc.data.substring(0, 300); + snippet += '<span style="display:none;">' + doc.data.substring(300); + snippet += '</span> <a href="#" class="more">more</a>'; + } + else { + snippet += doc.source + ' ' + doc.data; + } + + var output = '<div><h2>' + doc.type + '</h2>'; + output += '<p id="links_' + doc.id + '" class="links"></p>'; + output += '<p>' + snippet + '</p></div>'; + return output; + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.f.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.f.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.f.js new file mode 100644 index 0000000..7ec6061 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.f.js @@ -0,0 +1,106 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.ResultWidget = AjaxSolr.AbstractWidget.extend({ + start: 0, + + beforeRequest: function () { + $(this.target).html($('<img>').attr('src', 'images/ajax-loader.gif')); + }, + + facetLinks: function (facet_field, facet_values) { + var links = []; + if (facet_values) { + for (var i = 0, l = facet_values.length; i < l; i++) { + if (facet_values[i] !== undefined) { + links = links.concat([ + facet_field + ':', + $('<a href="#"></a>') + .text(facet_values[i]) + .click(this.facetHandler(facet_field, facet_values[i])) + ]); + } + else { + links.push('no items found in current selection'); + } + } + } + return links; + }, + + facetHandler: function (facet_field, facet_value) { + var self = this; + return function () { + self.manager.store.remove('fq'); + self.manager.store.addByValue('fq', facet_field + ':' + AjaxSolr.Parameter.escapeValue(facet_value)); + self.doRequest(0); + return false; + }; + }, + + afterRequest: function () { + $(this.target).empty(); + for (var i = 0, l = this.manager.response.response.docs.length; i < l; i++) { + var doc = this.manager.response.response.docs[i]; + $(this.target).append(this.template(doc)); + + var items = []; + items = items.concat(this.facetLinks('topics', doc.type)); + items = items.concat(this.facetLinks('sources', doc.source)); + //items = items.concat(this.facetLinks('users', doc.users)); + + var $links = $('#links_' + doc.id); + $links.empty(); + for (var j = 0, m = items.length; j < m; j++) { + $links.append($('<li></li>').append(items[j])); + } + } + }, + + template: function (doc) { + var snippet = ''; + if (doc.data.length > 300) { + snippet += doc.source + ' ' + doc.data.substring(0, 300); + snippet += '<span style="display:none;">' + doc.data.substring(300); + snippet += '</span> <a href="#" class="more">more</a>'; + } + else { + snippet += doc.source + ' ' + doc.data; + } + + var output = '<div><h2>' + doc.type + '</h2>'; + output += '<p id="links_' + doc.id + '" class="links"></p>'; + output += '<p>' + snippet + '</p></div>'; + return output; + }, + + init: function () { + $(document).on('click', 'a.more', function () { + var $this = $(this), + span = $this.parent().find('span'); + + if (span.is(':visible')) { + span.hide(); + $this.text('more'); + } + else { + span.show(); + $this.text('less'); + } + + return false; + }); + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.js new file mode 100644 index 0000000..fc87e83 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/ResultWidget.js @@ -0,0 +1,107 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.ResultWidget = AjaxSolr.AbstractWidget.extend({ + start: 0, + + beforeRequest: function () { + $(this.target).html($('<img>').attr('src', 'images/ajax-loader.gif')); + }, + + facetLinks: function (facet_field, facet_values) { + var links = []; + if (facet_values) { + for (var i = 0, l = facet_values.length; i < l; i++) { + if (facet_values[i] !== undefined) { + links.push( + $('<a href="#"></a>') + .text(facet_values[i]) + .click(this.facetHandler(facet_field, facet_values[i])) + ); + } + else { + links.push('no items found in current selection'); + } + } + } + return links; + }, + + facetHandler: function (facet_field, facet_value) { + var self = this; + return function () { + self.manager.store.remove('fq'); + self.manager.store.addByValue('fq', facet_field + ':' + AjaxSolr.Parameter.escapeValue(facet_value)); + self.doRequest(0); + return false; + }; + }, + + afterRequest: function () { + $(this.target).empty(); + for (var i = 0, l = this.manager.response.response.docs.length; i < l; i++) { + var doc = this.manager.response.response.docs[i]; + $(this.target).append(this.template(doc)); + + var items = []; + items = items.concat(this.facetLinks('topics', doc.type)); + items = items.concat(this.facetLinks('sources', doc.source)); + //items = items.concat(this.facetLinks('users', doc.users)); + + var $links = $('#links_' + doc.id); + $links.empty(); + for (var j = 0, m = items.length; j < m; j++) { + $links.append($('<li></li>').append(items[j])); + } + } + }, + + template: function (doc) { + var snippet = ''; + if (doc.data.length > 300) { + snippet += doc.source + ' ' + doc.data.substring(0, 300); + snippet += '<span style="display:none;">' + doc.data.substring(300); + snippet += '</span> <a href="#" class="more">more</a>'; + } + else { + snippet += doc.source + ' ' + doc.data; + } + + var output = '<div><h2>' + doc.type + '</h2>'; + output += '<p id="links_' + doc.id + '" class="links"></p>'; + output += '<a href="log-viewer.html?type='+ doc.type + + '&source=' + doc.source + '&date='+ doc.date +'">Link</a>'; + output += '<p>' + snippet + '</p></div>'; + return output; + }, + + init: function () { + $(document).on('click', 'a.more', function () { + var $this = $(this), + span = $this.parent().find('span'); + + if (span.is(':visible')) { + span.hide(); + $this.text('more'); + } + else { + span.show(); + $this.text('less'); + } + + return false; + }); + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/TagcloudWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/TagcloudWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/TagcloudWidget.js new file mode 100644 index 0000000..7d86914 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/TagcloudWidget.js @@ -0,0 +1,47 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractFacetWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.TagcloudWidget = AjaxSolr.AbstractFacetWidget.extend({ + afterRequest: function () { + if (this.manager.response.facet_counts.facet_fields[this.field] === undefined) { + $(this.target).html('no items found in current selection'); + return; + } + + var maxCount = 0; + var objectedItems = []; + for (var facet in this.manager.response.facet_counts.facet_fields[this.field]) { + var count = parseInt(this.manager.response.facet_counts.facet_fields[this.field][facet]); + if (count > maxCount) { + maxCount = count; + } + objectedItems.push({ facet: facet, count: count }); + } + objectedItems.sort(function (a, b) { + return a.facet < b.facet ? -1 : 1; + }); + + $(this.target).empty(); + for (var i = 0, l = objectedItems.length; i < l; i++) { + var facet = objectedItems[i].facet; + $(this.target).append( + $('<a href="#" class="tagcloud_item"></a>') + .text(facet) + .addClass('tagcloud_size_' + parseInt(objectedItems[i].count / maxCount * 10)) + .click(this.clickHandler(facet)) + ); + } + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/chukwa/widgets/TextWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/chukwa/widgets/TextWidget.js b/src/main/web/hicc/ajax-solr/chukwa/widgets/TextWidget.js new file mode 100644 index 0000000..c701fbf --- /dev/null +++ b/src/main/web/hicc/ajax-solr/chukwa/widgets/TextWidget.js @@ -0,0 +1,32 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractTextWidget'], callback); + } + else { + callback(); + } +}(function () { + +(function ($) { + +AjaxSolr.TextWidget = AjaxSolr.AbstractTextWidget.extend({ + init: function () { + var self = this; + $(this.target).find('input').bind('keydown', function(e) { + if (e.which == 13) { + var value = $(this).val(); + if (value && self.set(value)) { + self.doRequest(); + } + } + }); + }, + + afterRequest: function () { + $(this.target).find('input').val(''); + } +}); + +})(jQuery); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractFacetWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/AbstractFacetWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractFacetWidget.js new file mode 100644 index 0000000..9e5ca33 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/AbstractFacetWidget.js @@ -0,0 +1,293 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget', 'core/Parameter'], callback); + } + else { + callback(); + } +}(function () { + +/** + * Baseclass for all facet widgets. + * + * @class AbstractFacetWidget + * @augments AjaxSolr.AbstractWidget + */ +AjaxSolr.AbstractFacetWidget = AjaxSolr.AbstractWidget.extend( + /** @lends AjaxSolr.AbstractFacetWidget.prototype */ + { + /** + * @param {Object} attributes + * @param {String} attributes.field The field to facet on. + * @param {Number} [attributes.start] This widget will by default set the + * offset parameter to 0 on each request. + * @param {Boolean} [attributes.multivalue] Set to <tt>false</tt> to force a + * single "fq" parameter for this widget. Defaults to <tt>true</tt>. + */ + constructor: function (attributes) { + AjaxSolr.AbstractFacetWidget.__super__.constructor.apply(this, arguments); + AjaxSolr.extend(this, { + start: 0, + field: null, + multivalue: true + }, attributes); + }, + + init: function () { + this.initStore(); + }, + + /** + * Add facet parameters to the parameter store. + */ + initStore: function () { + /* http://wiki.apache.org/solr/SimpleFacetParameters */ + var parameters = [ + 'facet.prefix', + 'facet.sort', + 'facet.limit', + 'facet.offset', + 'facet.mincount', + 'facet.missing', + 'facet.method', + 'facet.enum.cache.minDf' + ]; + + this.manager.store.addByValue('facet', true); + + // Set facet.field, facet.date or facet.range to truthy values to add + // related per-field parameters to the parameter store. + if (this['facet.field'] !== undefined) { + this.manager.store.addByValue('facet.field', this.field); + } + else if (this['facet.date'] !== undefined) { + this.manager.store.addByValue('facet.date', this.field); + parameters = parameters.concat([ + 'facet.date.start', + 'facet.date.end', + 'facet.date.gap', + 'facet.date.hardend', + 'facet.date.other', + 'facet.date.include' + ]); + } + else if (this['facet.range'] !== undefined) { + this.manager.store.addByValue('facet.range', this.field); + parameters = parameters.concat([ + 'facet.range.start', + 'facet.range.end', + 'facet.range.gap', + 'facet.range.hardend', + 'facet.range.other', + 'facet.range.include' + ]); + } + + for (var i = 0, l = parameters.length; i < l; i++) { + if (this[parameters[i]] !== undefined) { + this.manager.store.addByValue('f.' + this.field + '.' + parameters[i], this[parameters[i]]); + } + } + }, + + /** + * @returns {Boolean} Whether any filter queries have been set using this + * widget's facet field. + */ + isEmpty: function () { + return !this.manager.store.find('fq', new RegExp('^-?' + this.field + ':')); + }, + + /** + * Sets the filter query. + * + * @returns {Boolean} Whether the selection changed. + */ + set: function (value) { + return this.changeSelection(function () { + var a = this.manager.store.removeByValue('fq', new RegExp('^-?' + this.field + ':')), + b = this.manager.store.addByValue('fq', this.fq(value)); + return a || b; + }); + }, + + /** + * Adds a filter query. + * + * @returns {Boolean} Whether a filter query was added. + */ + add: function (value) { + return this.changeSelection(function () { + return this.manager.store.addByValue('fq', this.fq(value)); + }); + }, + + /** + * Removes a filter query. + * + * @returns {Boolean} Whether a filter query was removed. + */ + remove: function (value) { + return this.changeSelection(function () { + return this.manager.store.removeByValue('fq', this.fq(value)); + }); + }, + + /** + * Removes all filter queries using the widget's facet field. + * + * @returns {Boolean} Whether a filter query was removed. + */ + clear: function () { + return this.changeSelection(function () { + return this.manager.store.removeByValue('fq', new RegExp('^-?' + this.field + ':')); + }); + }, + + /** + * Helper for selection functions. + * + * @param {Function} Selection function to call. + * @returns {Boolean} Whether the selection changed. + */ + changeSelection: function (func) { + changed = func.apply(this); + if (changed) { + this.afterChangeSelection(); + } + return changed; + }, + + /** + * An abstract hook for child implementations. + * + * <p>This method is executed after the filter queries change.</p> + */ + afterChangeSelection: function () {}, + + /** + * One of "facet.field", "facet.date" or "facet.range" must be set on the + * widget in order to determine where the facet counts are stored. + * + * @returns {Array} An array of objects with the properties <tt>facet</tt> and + * <tt>count</tt>, e.g <tt>{ facet: 'facet', count: 1 }</tt>. + */ + getFacetCounts: function () { + var property; + if (this['facet.field'] !== undefined) { + property = 'facet_fields'; + } + else if (this['facet.date'] !== undefined) { + property = 'facet_dates'; + } + else if (this['facet.range'] !== undefined) { + property = 'facet_ranges'; + } + if (property !== undefined) { + switch (this.manager.store.get('json.nl').val()) { + case 'map': + return this.getFacetCountsMap(property); + case 'arrarr': + return this.getFacetCountsArrarr(property); + default: + return this.getFacetCountsFlat(property); + } + } + throw 'Cannot get facet counts unless one of the following properties is set to "true" on widget "' + this.id + '": "facet.field", "facet.date", or "facet.range".'; + }, + + /** + * Used if the facet counts are represented as a JSON object. + * + * @param {String} property "facet_fields", "facet_dates", or "facet_ranges". + * @returns {Array} An array of objects with the properties <tt>facet</tt> and + * <tt>count</tt>, e.g <tt>{ facet: 'facet', count: 1 }</tt>. + */ + getFacetCountsMap: function (property) { + var counts = []; + for (var facet in this.manager.response.facet_counts[property][this.field]) { + counts.push({ + facet: facet, + count: parseInt(this.manager.response.facet_counts[property][this.field][facet]) + }); + } + return counts; + }, + + /** + * Used if the facet counts are represented as an array of two-element arrays. + * + * @param {String} property "facet_fields", "facet_dates", or "facet_ranges". + * @returns {Array} An array of objects with the properties <tt>facet</tt> and + * <tt>count</tt>, e.g <tt>{ facet: 'facet', count: 1 }</tt>. + */ + getFacetCountsArrarr: function (property) { + var counts = []; + for (var i = 0, l = this.manager.response.facet_counts[property][this.field].length; i < l; i++) { + counts.push({ + facet: this.manager.response.facet_counts[property][this.field][i][0], + count: parseInt(this.manager.response.facet_counts[property][this.field][i][1]) + }); + } + return counts; + }, + + /** + * Used if the facet counts are represented as a flat array. + * + * @param {String} property "facet_fields", "facet_dates", or "facet_ranges". + * @returns {Array} An array of objects with the properties <tt>facet</tt> and + * <tt>count</tt>, e.g <tt>{ facet: 'facet', count: 1 }</tt>. + */ + getFacetCountsFlat: function (property) { + var counts = []; + for (var i = 0, l = this.manager.response.facet_counts[property][this.field].length; i < l; i += 2) { + counts.push({ + facet: this.manager.response.facet_counts[property][this.field][i], + count: parseInt(this.manager.response.facet_counts[property][this.field][i+1]) + }); + } + return counts; + }, + + /** + * @param {String} value The value. + * @returns {Function} Sends a request to Solr if it successfully adds a + * filter query with the given value. + */ + clickHandler: function (value) { + var self = this, meth = this.multivalue ? 'add' : 'set'; + return function () { + if (self[meth].call(self, value)) { + self.doRequest(); + } + return false; + } + }, + + /** + * @param {String} value The value. + * @returns {Function} Sends a request to Solr if it successfully removes a + * filter query with the given value. + */ + unclickHandler: function (value) { + var self = this; + return function () { + if (self.remove(value)) { + self.doRequest(); + } + return false; + } + }, + + /** + * @param {String} value The facet value. + * @param {Boolean} exclude Whether to exclude this fq parameter value. + * @returns {String} An fq parameter value. + */ + fq: function (value, exclude) { + return (exclude ? '-' : '') + this.field + ':' + AjaxSolr.Parameter.escapeValue(value); + } +}); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractManager.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/AbstractManager.js b/src/main/web/hicc/ajax-solr/core/AbstractManager.js new file mode 100644 index 0000000..72e0972 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/AbstractManager.js @@ -0,0 +1,159 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/Core'], callback); + } + else { + callback(); + } +}(function () { + +/** + * The Manager acts as the controller in a Model-View-Controller framework. All + * public calls should be performed on the manager object. + * + * @param properties A map of fields to set. Refer to the list of public fields. + * @class AbstractManager + */ +AjaxSolr.AbstractManager = AjaxSolr.Class.extend( + /** @lends AjaxSolr.AbstractManager.prototype */ + { + /** + * @param {Object} [attributes] + * @param {String} [attributes.solrUrl] The fully-qualified URL of the Solr + * application. You must include the trailing slash. Do not include the path + * to any Solr servlet. Defaults to "http://localhost:8983/solr/" + * @param {String} [attributes.proxyUrl] If we want to proxy queries through a + * script, rather than send queries to Solr directly, set this field to the + * fully-qualified URL of the script. + * @param {String} [attributes.servlet] The default Solr servlet. You may + * prepend the servlet with a core if using multiple cores. Defaults to + * "servlet". + */ + constructor: function (attributes) { + AjaxSolr.extend(this, { + solrUrl: 'http://localhost:8983/solr/', + proxyUrl: null, + servlet: 'select', + // The most recent response from Solr. + response: {}, + // A collection of all registered widgets. + widgets: {}, + // The parameter store for the manager and its widgets. + store: null, + // Whether <tt>init()</tt> has been called yet. + initialized: false + }, attributes); + }, + + /** + * An abstract hook for child implementations. + * + * <p>This method should be called after the store and the widgets have been + * added. It should initialize the widgets and the store, and do any other + * one-time initializations, e.g., perform the first request to Solr.</p> + * + * <p>If no store has been set, it sets the store to the basic <tt> + * AjaxSolr.ParameterStore</tt>.</p> + */ + init: function () { + this.initialized = true; + if (this.store === null) { + this.setStore(new AjaxSolr.ParameterStore()); + } + this.store.load(false); + for (var widgetId in this.widgets) { + this.widgets[widgetId].init(); + } + this.store.init(); + }, + + /** + * Set the manager's parameter store. + * + * @param {AjaxSolr.ParameterStore} store + */ + setStore: function (store) { + store.manager = this; + this.store = store; + }, + + /** + * Adds a widget to the manager. + * + * @param {AjaxSolr.AbstractWidget} widget + */ + addWidget: function (widget) { + widget.manager = this; + this.widgets[widget.id] = widget; + }, + + /** + * Stores the Solr parameters to be sent to Solr and sends a request to Solr. + * + * @param {Boolean} [start] The Solr start offset parameter. + * @param {String} [servlet] The Solr servlet to send the request to. + */ + doRequest: function (start, servlet) { + if (this.initialized === false) { + this.init(); + } + // Allow non-pagination widgets to reset the offset parameter. + if (start !== undefined) { + this.store.get('start').val(start); + } + if (servlet === undefined) { + servlet = this.servlet; + } + + this.store.save(); + + for (var widgetId in this.widgets) { + this.widgets[widgetId].beforeRequest(); + } + + this.executeRequest(servlet); + }, + + /** + * An abstract hook for child implementations. + * + * <p>Sends the request to Solr, i.e. to <code>this.solrUrl</code> or <code> + * this.proxyUrl</code>, and receives Solr's response. It should pass Solr's + * response to <code>handleResponse()</code> for handling.</p> + * + * <p>See <tt>managers/Manager.jquery.js</tt> for a jQuery implementation.</p> + * + * @param {String} servlet The Solr servlet to send the request to. + * @param {String} string The query string of the request. If not set, it + * should default to <code>this.store.string()</code> + * @throws If not defined in child implementation. + */ + executeRequest: function (servlet, string) { + throw 'Abstract method executeRequest must be overridden in a subclass.'; + }, + + /** + * This method is executed after the Solr response data arrives. Allows each + * widget to handle Solr's response separately. + * + * @param {Object} data The Solr response. + */ + handleResponse: function (data) { + this.response = data; + + for (var widgetId in this.widgets) { + this.widgets[widgetId].afterRequest(); + } + }, + + /** + * This method is executed if Solr encounters an error. + * + * @param {String} message An error message. + */ + handleError: function (message) { + window.console && console.log && console.log(message); + } +}); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractSpatialWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/AbstractSpatialWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractSpatialWidget.js new file mode 100644 index 0000000..bb9b316 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/AbstractSpatialWidget.js @@ -0,0 +1,67 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget'], callback); + } + else { + callback(); + } +}(function () { + +/** + * Offers an interface to the local parameters used by the Spatial Solr plugin. + * + * @see http://www.jteam.nl/news/spatialsolr + * + * @class AbstractSpatialWidget + * @augments AjaxSolr.AbstractWidget + */ +AjaxSolr.AbstractSpatialWidget = AjaxSolr.AbstractWidget.extend( + /** @lends AjaxSolr.AbstractSpatialWidget.prototype */ + { + /** + * Sets the Spatial Solr local parameters. + * + * @param {Object} params The local parameters to set. + * @param {Number} params.lat Latitude of the center of the search area. + * @param {Number} params.lng Longitude of the center of the search area. + * @param {Number} params.radius Radius of the search area. + * @param {String} [params.unit] Unit the distances should be calculated in: + * "km" or "miles". + * @param {String} [params.calc] <tt>GeoDistanceCalculator</tt> that will be + * used to calculate the distances. "arc" for + * <tt>ArchGeoDistanceCalculator</tt> and "plane" for + * <tt>PlaneGeoDistanceCalculator</tt>. + * @param {Number} [params.threadCount] Number of threads that will be used + * by the <tt>ThreadedDistanceFilter</tt>. + */ + set: function (params) { + this.manager.store.get('q').local('type', 'spatial'); + this.manager.store.get('q').local('lat', params.lat); + this.manager.store.get('q').local('long', params.lng); + this.manager.store.get('q').local('radius', params.radius); + if (params.unit !== undefined) { + this.manager.store.get('q').local('unit', params.unit); + } + if (params.calc !== undefined) { + this.manager.store.get('q').local('calc', params.calc); + } + if (params.threadCount !== undefined) { + this.manager.store.get('q').local('threadCount', params.threadCount); + } + }, + + /** + * Removes the Spatial Solr local parameters. + */ + clear: function () { + this.manager.store.get('q').remove('type'); + this.manager.store.get('q').remove('lat'); + this.manager.store.get('q').remove('long'); + this.manager.store.get('q').remove('radius'); + this.manager.store.get('q').remove('unit'); + this.manager.store.get('q').remove('calc'); + this.manager.store.get('q').remove('threadCount'); + } +}); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractSpellcheckWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/AbstractSpellcheckWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractSpellcheckWidget.js new file mode 100644 index 0000000..76571c4 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/AbstractSpellcheckWidget.js @@ -0,0 +1,87 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget'], callback); + } + else { + callback(); + } +}(function () { + +/** + * Interacts with Solr's SpellCheckComponent. + * + * @see http://wiki.apache.org/solr/SpellCheckComponent + * + * @class AbstractSpellcheckWidget + * @augments AjaxSolr.AbstractWidget + */ +AjaxSolr.AbstractSpellcheckWidget = AjaxSolr.AbstractWidget.extend( + /** @lends AjaxSolr.AbstractSpellcheckWidget.prototype */ + { + constructor: function (attributes) { + AjaxSolr.AbstractSpellcheckWidget.__super__.constructor.apply(this, arguments); + AjaxSolr.extend(this, { + // The suggestions. + suggestions: {} + }, attributes); + }, + + /** + * Uses the top suggestion for each word to return a suggested query. + * + * @returns {String} A suggested query. + */ + suggestion: function () { + var suggestion = this.manager.response.responseHeader.params['spellcheck.q']; + for (var word in this.suggestions) { + suggestion = suggestion.replace(new RegExp(word, 'g'), this.suggestions[word][0]); + } + return suggestion; + }, + + beforeRequest: function () { + if (this.manager.store.get('spellcheck').val() && this.manager.store.get('q').val()) { + this.manager.store.get('spellcheck.q').val(this.manager.store.get('q').val()); + } + else { + this.manager.store.remove('spellcheck.q'); + } + }, + + afterRequest: function () { + this.suggestions = {}; + + if (this.manager.response.spellcheck && this.manager.response.spellcheck.suggestions) { + var suggestions = this.manager.response.spellcheck.suggestions, + empty = true; + + for (var word in suggestions) { + if (word == 'collation' || word == 'correctlySpelled') continue; + + this.suggestions[word] = []; + for (var i = 0, l = suggestions[word].suggestion.length; i < l; i++) { + if (this.manager.response.responseHeader.params['spellcheck.extendedResults']) { + this.suggestions[word].push(suggestions[word].suggestion[i].word); + } + else { + this.suggestions[word].push(suggestions[word].suggestion[i]); + } + } + empty = false; + } + + if (!empty) { + this.handleSuggestions(this.manager.response); + } + } + }, + + /** + * An abstract hook for child implementations. + * + * <p>Allow the child to handle the suggestions without parsing the response.</p> + */ + handleSuggestions: function () {} +}); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractTextWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/AbstractTextWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractTextWidget.js new file mode 100644 index 0000000..1be3da8 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/AbstractTextWidget.js @@ -0,0 +1,111 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/AbstractWidget'], callback); + } + else { + callback(); + } +}(function () { + +/** + * Baseclass for all free-text widgets. + * + * @class AbstractTextWidget + * @augments AjaxSolr.AbstractWidget + */ +AjaxSolr.AbstractTextWidget = AjaxSolr.AbstractWidget.extend( + /** @lends AjaxSolr.AbstractTextWidget.prototype */ + { + /** + * @param {Object} [attributes] + * @param {Number} [attributes.start] This widget will by default set the + * offset parameter to 0 on each request. + */ + constructor: function (attributes) { + AjaxSolr.AbstractTextWidget.__super__.constructor.apply(this, arguments); + AjaxSolr.extend(this, { + start: 0 + }, attributes); + }, + + /** + * Sets the main Solr query to the given string. + * + * @param {String} q The new Solr query. + * @returns {Boolean} Whether the selection changed. + */ + set: function (q) { + return this.changeSelection(function () { + this.manager.store.get('q').val(q); + }); + }, + + /** + * Sets the main Solr query to the empty string. + * + * @returns {Boolean} Whether the selection changed. + */ + clear: function () { + return this.changeSelection(function () { + this.manager.store.remove('q'); + }); + }, + + /** + * Helper for selection functions. + * + * @param {Function} Selection function to call. + * @returns {Boolean} Whether the selection changed. + */ + changeSelection: function (func) { + var before = this.manager.store.get('q').val(); + func.apply(this); + var after = this.manager.store.get('q').val(); + if (after !== before) { + this.afterChangeSelection(after); + } + return after !== before; + }, + + /** + * An abstract hook for child implementations. + * + * <p>This method is executed after the main Solr query changes.</p> + * + * @param {String} value The current main Solr query. + */ + afterChangeSelection: function (value) {}, + + /** + * Returns a function to unset the main Solr query. + * + * @returns {Function} + */ + unclickHandler: function () { + var self = this; + return function () { + if (self.clear()) { + self.doRequest(); + } + return false; + } + }, + + /** + * Returns a function to set the main Solr query. + * + * @param {String} value The new Solr query. + * @returns {Function} + */ + clickHandler: function (q) { + var self = this; + return function () { + if (self.set(q)) { + self.doRequest(); + } + return false; + } + } +}); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/AbstractWidget.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/AbstractWidget.js b/src/main/web/hicc/ajax-solr/core/AbstractWidget.js new file mode 100644 index 0000000..203a4c7 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/AbstractWidget.js @@ -0,0 +1,78 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/Core'], callback); + } + else { + callback(); + } +}(function () { + +/** + * Baseclass for all widgets. + * + * Provides abstract hooks for child classes. + * + * @param properties A map of fields to set. May be new or public fields. + * @class AbstractWidget + */ +AjaxSolr.AbstractWidget = AjaxSolr.Class.extend( + /** @lends AjaxSolr.AbstractWidget.prototype */ + { + /** + * @param {Object} attributes + * @param {String} attributes.id A unique identifier of this widget. + * @param {String} [attributes.target] The CSS selector for this widget's + * target HTML element, e.g. a specific <tt>div</tt> or <tt>ul</tt>. A + * Widget is usually implemented to perform all its UI changes relative to + * its target HTML element. + * @param {Number} [attributes.start] The offset parameter. Set this field to + * make the widget reset the offset parameter to the given value on each + * request. + * @param {String} [attributes.servlet] The Solr servlet for this widget. You + * may prepend the servlet with a core if using multiple cores. If none is + * set, it will default to the manager's servlet. + */ + constructor: function (attributes) { + AjaxSolr.extend(this, { + id: null, + target: null, + start: undefined, + servlet: undefined, + // A reference to the widget's manager. + manager: null + }, attributes); + }, + + /** + * An abstract hook for child implementations. + * + * <p>This method should do any necessary one-time initializations.</p> + */ + init: function () {}, + + /** + * An abstract hook for child implementations. + * + * <p>This method is executed before the Solr request is sent.</p> + */ + beforeRequest: function () {}, + + /** + * An abstract hook for child implementations. + * + * <p>This method is executed after the Solr response is received.</p> + */ + afterRequest: function () {}, + + /** + * A proxy to the manager's doRequest method. + * + * @param {Boolean} [start] The Solr start offset parameter. + * @param {String} [servlet] The Solr servlet to send the request to. + */ + doRequest: function (start, servlet) { + this.manager.doRequest(start || this.start, servlet || this.servlet); + } +}); + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/Core.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/Core.js b/src/main/web/hicc/ajax-solr/core/Core.js new file mode 100644 index 0000000..af170c3 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/Core.js @@ -0,0 +1,163 @@ +/** + * @namespace A unique namespace for the AJAX Solr library. + */ +AjaxSolr = function () {}; + +/** + * @namespace Baseclass for all classes + * @see https://github.com/documentcloud/backbone/blob/51eed189bf4d25877be4acdf51e0a4c6039583c5/backbone.js#L243 + */ +AjaxSolr.Class = function(attributes) { + AjaxSolr.extend(this, attributes); +}; + +/** + * A class 'extends' itself into a subclass. + * + * @static + * @param protoProps The properties of the subclass. + * @returns A function that represents the subclass. + * @see https://github.com/documentcloud/backbone/blob/51eed189bf4d25877be4acdf51e0a4c6039583c5/backbone.js#L1516 + */ +AjaxSolr.Class.extend = function (protoProps, staticProps) { + var parent = this; + var child; + + // The constructor function for the new subclass is either defined by you + // (the "constructor" property in your `extend` definition), or defaulted + // by us to simply call the parent's constructor. + if (protoProps && Object.prototype.hasOwnProperty.call(protoProps, 'constructor')) { + child = protoProps.constructor; + } else { + child = function(){ return parent.apply(this, arguments); }; + } + + // Add static properties to the constructor function, if supplied. + AjaxSolr.extend(child, parent, staticProps); + + // Set the prototype chain to inherit from `parent`, without calling + // `parent`'s constructor function. + var Surrogate = function(){ this.constructor = child; }; + Surrogate.prototype = parent.prototype; + child.prototype = new Surrogate; + + // Add prototype properties (instance properties) to the subclass, + // if supplied. + if (protoProps) AjaxSolr.extend(child.prototype, protoProps); + + // Set a convenience property in case the parent's prototype is needed + // later. + child.__super__ = parent.prototype; + + return child; +}; + +/** + * @static + * @see https://github.com/documentcloud/underscore/blob/7342e289aa9d91c5aacfb3662ea56e7a6d081200/underscore.js#L789 +*/ +AjaxSolr.extend = function (child) { + // From _.extend + var obj = Array.prototype.slice.call(arguments, 1); + + // From _.extend + var iterator = function(source) { + if (source) { + for (var prop in source) { + child[prop] = source[prop]; + } + } + }; + + // From _.each + if (obj == null) return; + if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) { + obj.forEach(iterator); + } else if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + iterator.call(undefined, obj[i], i, obj); + } + } else { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + iterator.call(undefined, obj[key], key, obj); + } + } + } + + return child; +}; + +/** + * @static + * @param value A value. + * @param array An array. + * @returns {Boolean} Whether value exists in the array. + */ +AjaxSolr.inArray = function (value, array) { + if (array) { + for (var i = 0, l = array.length; i < l; i++) { + if (AjaxSolr.equals(array[i], value)) { + return i; + } + } + } + return -1; +}; + +/** + * @static + * @param foo A value. + * @param bar A value. + * @returns {Boolean} Whether the two given values are equal. + */ +AjaxSolr.equals = function (foo, bar) { + if (AjaxSolr.isArray(foo) && AjaxSolr.isArray(bar)) { + if (foo.length !== bar.length) { + return false; + } + for (var i = 0, l = foo.length; i < l; i++) { + if (foo[i] !== bar[i]) { + return false; + } + } + return true; + } + else if (AjaxSolr.isRegExp(foo) && AjaxSolr.isString(bar)) { + return bar.match(foo); + } + else if (AjaxSolr.isRegExp(bar) && AjaxSolr.isString(foo)) { + return foo.match(bar); + } + else { + return foo === bar; + } +}; + +/** + * Can't use toString.call(obj) === "[object Array]", as it may return + * "[xpconnect wrapped native prototype]", which is undesirable. + * + * @static + * @see http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ + * @see http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js + */ +AjaxSolr.isArray = function (obj) { + return obj != null && typeof obj == 'object' && 'splice' in obj && 'join' in obj; +}; + +/** + * @param obj Any object. + * @returns {Boolean} Whether the object is a RegExp object. + */ +AjaxSolr.isRegExp = function (obj) { + return obj != null && (typeof obj == 'object' || typeof obj == 'function') && 'ignoreCase' in obj; +}; + +/** + * @param obj Any object. + * @returns {Boolean} Whether the object is a String object. + */ +AjaxSolr.isString = function (obj) { + return obj != null && typeof obj == 'string'; +}; http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/Parameter.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/Parameter.js b/src/main/web/hicc/ajax-solr/core/Parameter.js new file mode 100644 index 0000000..95e638e --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/Parameter.js @@ -0,0 +1,175 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/Core'], callback); + } + else { + callback(); + } +}(function () { + +/** + * Represents a Solr parameter. + * + * @param properties A map of fields to set. Refer to the list of public fields. + * @class Parameter + */ +AjaxSolr.Parameter = AjaxSolr.Class.extend( + /** @lends AjaxSolr.Parameter.prototype */ + { + /** + * @param {Object} attributes + * @param {String} attributes.name The parameter's name. + * @param {String} [attributes.value] The parameter's value. + * @param {Object} [attributes.local] The parameter's local parameters. + */ + constructor: function (attributes) { + AjaxSolr.extend(this, { + name: null, + value: null, + locals: {} + }, attributes); + }, + + /** + * Returns the value. If called with an argument, sets the value. + * + * @param {String|Number|String[]|Number[]} [value] The value to set. + * @returns The value. + */ + val: function (value) { + if (value === undefined) { + return this.value; + } + else { + this.value = value; + } + }, + + /** + * Returns the value of a local parameter. If called with a second argument, + * sets the value of a local parameter. + * + * @param {String} name The name of the local parameter. + * @param {String|Number|String[]|Number[]} [value] The value to set. + * @returns The value. + */ + local: function (name, value) { + if (value === undefined) { + return this.locals[name]; + } + else { + this.locals[name] = value; + } + }, + + /** + * Deletes a local parameter. + * + * @param {String} name The name of the local parameter. + */ + remove: function (name) { + delete this.locals[name]; + }, + + /** + * Returns the Solr parameter as a query string key-value pair. + * + * <p>IE6 calls the default toString() if you write <tt>store.toString() + * </tt>. So, we need to choose another name for toString().</p> + */ + string: function () { + var pairs = []; + + for (var name in this.locals) { + if (this.locals[name]) { + pairs.push(name + '=' + encodeURIComponent(this.locals[name])); + } + } + + var prefix = pairs.length ? '{!' + pairs.join('%20') + '}' : ''; + + if (this.value) { + return this.name + '=' + prefix + this.valueString(this.value); + } + // For dismax request handlers, if the q parameter has local params, the + // q parameter must be set to a non-empty value. In case the q parameter + // has local params but is empty, use the q.alt parameter, which accepts + // wildcards. + else if (this.name == 'q' && prefix) { + return 'q.alt=' + prefix + encodeURIComponent('*:*'); + } + else { + return ''; + } + }, + + /** + * Parses a string formed by calling string(). + * + * @param {String} str The string to parse. + */ + parseString: function (str) { + var param = str.match(/^([^=]+)=(?:\{!([^\}]*)\})?(.*)$/); + if (param) { + var matches; + + while (matches = /([^\s=]+)=(\S*)/g.exec(decodeURIComponent(param[2]))) { + this.locals[matches[1]] = decodeURIComponent(matches[2]); + param[2] = param[2].replace(matches[0], ''); // Safari's exec seems not to do this on its own + } + + if (param[1] == 'q.alt') { + this.name = 'q'; + // if q.alt is present, assume it is because q was empty, as above + } + else { + this.name = param[1]; + this.value = this.parseValueString(param[3]); + } + } + }, + + /** + * Returns the value as a URL-encoded string. + * + * @private + * @param {String|Number|String[]|Number[]} value The value. + * @returns {String} The URL-encoded string. + */ + valueString: function (value) { + value = AjaxSolr.isArray(value) ? value.join(',') : value; + return encodeURIComponent(value); + }, + + /** + * Parses a URL-encoded string to return the value. + * + * @private + * @param {String} str The URL-encoded string. + * @returns {Array} The value. + */ + parseValueString: function (str) { + str = decodeURIComponent(str); + return str.indexOf(',') == -1 ? str : str.split(','); + } +}); + +/** + * Escapes a value, to be used in, for example, an fq parameter. Surrounds + * strings containing spaces or colons in double quotes. + * + * @public + * @param {String|Number} value The value. + * @returns {String} The escaped value. + */ +AjaxSolr.Parameter.escapeValue = function (value) { + // If the field value has a space, colon, quotation mark or forward slash + // in it, wrap it in quotes, unless it is a range query or it is already + // wrapped in quotes. + if (value.match(/[ :\/"]/) && !value.match(/[\[\{]\S+ TO \S+[\]\}]/) && !value.match(/^["\(].*["\)]$/)) { + return '"' + value.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"'; + } + return value; +} + +})); http://git-wip-us.apache.org/repos/asf/chukwa/blob/0cad3aae/src/main/web/hicc/ajax-solr/core/ParameterHashStore.js ---------------------------------------------------------------------- diff --git a/src/main/web/hicc/ajax-solr/core/ParameterHashStore.js b/src/main/web/hicc/ajax-solr/core/ParameterHashStore.js new file mode 100644 index 0000000..54a2806 --- /dev/null +++ b/src/main/web/hicc/ajax-solr/core/ParameterHashStore.js @@ -0,0 +1,116 @@ +(function (callback) { + if (typeof define === 'function' && define.amd) { + define(['core/ParameterStore'], callback); + } + else { + callback(); + } +}(function () { + +/** + * A parameter store that stores the values of exposed parameters in the URL + * hash to maintain the application's state. + * + * <p>The ParameterHashStore observes the hash for changes and loads Solr + * parameters from the hash if it observes a change or if the hash is empty. + * The onhashchange event is used if the browser supports it.</p> + * + * <p>Configure the manager with:</p> + * + * @class ParameterHashStore + * @augments AjaxSolr.ParameterStore + * @see https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange + */ +AjaxSolr.ParameterHashStore = AjaxSolr.ParameterStore.extend( + /** @lends AjaxSolr.ParameterHashStore.prototype */ + { + /** + * @param {Object} [attributes] + * @param {Number} [attributes.interval] The interval in milliseconds to use + * in <tt>setInterval()</tt>. Do not set the interval too low as you may set + * up a race condition. Defaults to 250. + */ + constructor: function (attributes) { + AjaxSolr.ParameterHashStore.__super__.constructor.apply(this, arguments); + AjaxSolr.extend(this, { + interval: 250, + // Reference to the setInterval() function. + intervalId: null, + // A local copy of the URL hash, so we can detect changes to it. + hash: '' + }, attributes); + }, + + /** + * If loading and saving the hash take longer than <tt>interval</tt>, we'll + * hit a race condition. However, this should never happen. + */ + init: function () { + if (this.exposed.length) { + // Check if the browser supports the onhashchange event. IE 8 and 9 in compatibility mode + // incorrectly report support for onhashchange. + if ('onhashchange' in window && (!document.documentMode || document.documentMode > 7)) { + if (window.addEventListener) { + window.addEventListener('hashchange', this.intervalFunction(this), false); + } + else if (window.attachEvent) { + window.attachEvent('onhashchange', this.intervalFunction(this)); + } + else { + window.onhashchange = this.intervalFunction(this); + } + } + else { + this.intervalId = window.setInterval(this.intervalFunction(this), this.interval); + } + } + }, + + /** + * Stores the values of the exposed parameters in both the local hash and the + * URL hash. No other code should be made to change these two values. + */ + save: function () { + this.hash = this.exposedString(); + if (this.storedString()) { + // Make a new history entry. + window.location.hash = this.hash; + } + else { + // Replace the old history entry. + window.location.replace(window.location.href.replace('#', '') + '#' + this.hash); + } + }, + + /** + * @see ParameterStore#storedString() + */ + storedString: function () { + // Some browsers automatically unescape characters in the hash, others + // don't. Fortunately, all leave window.location.href alone. So, use that. + var index = window.location.href.indexOf('#'); + if (index == -1) { + return ''; + } + else { + return window.location.href.substr(index + 1); + } + }, + + /** + * Checks the hash for changes, and loads Solr parameters from the hash and + * sends a request to Solr if it observes a change or if the hash is empty + */ + intervalFunction: function (self) { + return function () { + // Support the back/forward buttons. If the hash changes, do a request. + var hash = self.storedString(); + if (self.hash != hash && decodeURIComponent(self.hash) != decodeURIComponent(hash)) { + self.load(); + self.manager.doRequest(); + } + } + } +}); + +}));
