picky-client 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. metadata +2 -33
  2. data/sinatra_prototype/Gemfile +0 -13
  3. data/sinatra_prototype/app.rb +0 -65
  4. data/sinatra_prototype/book.rb +0 -42
  5. data/sinatra_prototype/config.ru +0 -2
  6. data/sinatra_prototype/images/picky.png +0 -0
  7. data/sinatra_prototype/javascripts/compiler.jar +0 -0
  8. data/sinatra_prototype/javascripts/generate_bundles +0 -25
  9. data/sinatra_prototype/javascripts/jquery-1.3.2.js +0 -4376
  10. data/sinatra_prototype/javascripts/jquery-1.4.3.min.js +0 -166
  11. data/sinatra_prototype/javascripts/jquery.scrollTo-1.4.2.js +0 -215
  12. data/sinatra_prototype/javascripts/jquery.timer.js +0 -75
  13. data/sinatra_prototype/javascripts/picky.addination.js +0 -36
  14. data/sinatra_prototype/javascripts/picky.allocation_renderer.js +0 -291
  15. data/sinatra_prototype/javascripts/picky.allocations_cloud.js +0 -91
  16. data/sinatra_prototype/javascripts/picky.backend.js +0 -86
  17. data/sinatra_prototype/javascripts/picky.client.js +0 -62
  18. data/sinatra_prototype/javascripts/picky.controller.js +0 -107
  19. data/sinatra_prototype/javascripts/picky.data.js +0 -78
  20. data/sinatra_prototype/javascripts/picky.extensions.js +0 -15
  21. data/sinatra_prototype/javascripts/picky.min.js +0 -17
  22. data/sinatra_prototype/javascripts/picky.results_renderer.js +0 -103
  23. data/sinatra_prototype/javascripts/picky.source.js.tar +0 -0
  24. data/sinatra_prototype/javascripts/picky.translations.js +0 -50
  25. data/sinatra_prototype/javascripts/picky.view.js +0 -214
  26. data/sinatra_prototype/library.csv +0 -540
  27. data/sinatra_prototype/stylesheets/stylesheet.css +0 -184
  28. data/sinatra_prototype/stylesheets/stylesheet.sass +0 -225
  29. data/sinatra_prototype/views/configure.haml +0 -170
  30. data/sinatra_prototype/views/search.haml +0 -108
  31. data/spec/picky-client/generator_spec.rb +0 -141
@@ -1,62 +0,0 @@
1
- var Localization = {
2
- // TODO Remove.
3
- location_delimiters: { de:'in', fr:'à', it:'a', en:'in', ch:'in' },
4
-
5
- explanation_delimiters: { de:'und', fr:'et', it:'e', en:'and', ch:'und' }
6
- };
7
-
8
- // The client handles parameters and
9
- // offers an insert method.
10
- //
11
- var PickyClient = function(config) {
12
-
13
- // Params handling.
14
- //
15
-
16
- // This is used to generate the correct query strings, localized.
17
- //
18
- // e.g with locale it:
19
- // ['title', 'ulysses', 'Ulysses'] => 'titolo:ulysses'
20
- //
21
- // This needs to correspond to the parsing in the search engine.
22
- //
23
- Localization.qualifiers = config.qualifiers || {};
24
-
25
- // This is used to explain the preceding word in the suggestion text.
26
- //
27
- // e.g. with locale it:
28
- // ['title', 'ulysses', 'Ulysses'] => 'Ulysses (titolo)'
29
- //
30
- Localization.explanations = config.explanations || {};
31
-
32
- // TODO Explain.
33
- //
34
- Localization.explanation_delimiters = { de:'und', fr:'et', it:'e', en:'and', ch:'und' };
35
-
36
- // Either you pass it a backends hash with full and live,
37
- // or you pass it full and live (urls), which will then
38
- // be wrapped in appropriate backends.
39
- //
40
- var backends = config.backends;
41
- if (backends) {
42
- backends.live || alert('Both a full and live backend must be provided.');
43
- backends.full || alert('Both a full and live backend must be provided.');
44
- } else {
45
- config.backends = {
46
- live: config.live && new LiveBackend(config.live) || alert('A live backend path must be provided.'),
47
- full: config.full && new FullBackend(config.full) || alert('A live backend path must be provided.')
48
- };
49
- }
50
-
51
- // The central Picky controller.
52
- //
53
- var controller = config.controller && new config.controller(config) || new PickyController(config);
54
-
55
- // Insert a query into the client and run it.
56
- // Default is a full query.
57
- //
58
- this.insert = function(query, full) {
59
- controller.insert(query, full || true);
60
- };
61
-
62
- };
@@ -1,107 +0,0 @@
1
- var PickyController = function(config) {
2
-
3
- var view = new PickyView(this, config);
4
-
5
- var backends = config.backends;
6
- var beforeCallback = config.before || function(params, query, offset) { };
7
- var successCallback = config.success || function(data, query) { };
8
- var afterCallback = config.after || function(data, query) { };
9
-
10
- // If the given backend cannot be found, ignore the search request.
11
- //
12
- var search = function(type, query, callback, offset, specificParams) {
13
- var currentBackend = backends[type];
14
- if (currentBackend) { currentBackend.search(query, callback, offset, specificParams); };
15
- };
16
-
17
- var fullSearchCallback = function(data, query) {
18
- data = successCallback(data, query) || data;
19
-
20
- view.fullResultsCallback(data);
21
-
22
- afterCallback(data, query);
23
- };
24
- var fullSearch = function(query, possibleOffset, possibleParams) {
25
- var params = possibleParams || {};
26
- var offset = possibleOffset || 0;
27
- liveSearchTimer.stop();
28
-
29
- params = beforeCallback(params, query, offset) || params;
30
-
31
- search('full', query, fullSearchCallback, offset, params);
32
- };
33
- var liveSearchCallback = function(data, query) {
34
- data = successCallback(data, query) || data;
35
-
36
- view.liveResultsCallback(data);
37
-
38
- afterCallback(data, query);
39
- };
40
- var liveSearch = function(query, possibleParams) {
41
- var params = possibleParams || {};
42
-
43
- params = beforeCallback(params) || params;
44
-
45
- search('live', query, liveSearchCallback, 0);
46
- };
47
-
48
- // The timer is initially instantly stopped.
49
- //
50
- var liveSearchTimer = $.timer(180, function(timer) {
51
- liveSearch(view.text());
52
- timer.stop();
53
- });
54
- liveSearchTimer.stop();
55
-
56
- this.insert = function(query, full) {
57
- view.insert(query);
58
-
59
- if (full) { fullSearch(query); } // TODO
60
- };
61
-
62
- var clearButtonClicked = function() {
63
- liveSearchTimer.stop();
64
- };
65
- this.clearButtonClicked = clearButtonClicked;
66
-
67
- var searchTextCleared = function() {
68
- liveSearchTimer.stop();
69
- };
70
- this.searchTextCleared = searchTextCleared;
71
-
72
- var shouldTriggerSearch = function(event) {
73
- var validTriggerKeys = [
74
- 0, // special char (ä ö ü etc...)
75
- 8, // backspace
76
- 13, // enter
77
- 32, // space
78
- 46, // delete
79
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, // numbers
80
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90 // a-z
81
- ];
82
-
83
- return $.inArray(event.keyCode, validTriggerKeys) > -1;
84
- };
85
- var searchTextEntered = function(text, event) {
86
- if (shouldTriggerSearch(event)) {
87
- if (event.keyCode == 13) { fullSearch(text); } else { liveSearchTimer.reset(); }
88
- }
89
- };
90
- this.searchTextEntered = searchTextEntered;
91
-
92
- var searchButtonClicked = function(text) {
93
- fullSearch(text);
94
- };
95
- this.searchButtonClicked = searchButtonClicked;
96
-
97
- var allocationChosen = function(text) {
98
- fullSearch(text);
99
- };
100
- this.allocationChosen = allocationChosen;
101
-
102
- // Move to a view object.
103
- var addinationClicked = function(text, event) {
104
- fullSearch(text, event.data.offset);
105
- };
106
- this.addinationClicked = addinationClicked;
107
- };
@@ -1,78 +0,0 @@
1
- // The data is basically the model behind the search.
2
- //
3
-
4
- // Container for an allocation.
5
- //
6
- function Allocation(type, weight, count, combination, ids, rendered) {
7
- var self = this;
8
-
9
- this.type = type; // 'books'
10
- this.weight = weight; // 5.14
11
- this.count = count; // 14
12
- this.combination = combination; // [['title', 'Old', 'old'], ['title', 'Man', 'man']]
13
- this.ids = ids || [];
14
- this.rendered = rendered || [];
15
- this.entries = this.rendered;
16
-
17
- this.isType = function(name) {
18
- return name == self.type;
19
- };
20
- };
21
-
22
- // Container for the allocations.
23
- //
24
- // allocs (should) come preordered by weight.
25
- //
26
- function Allocations(allocations) {
27
- var self = this;
28
-
29
- this.allocations = [];
30
-
31
- // Wrap and save the allocations.
32
- //
33
- for (var i = 0, l = allocations.length; i < l; i++) {
34
- var alloc = allocations[i];
35
- var new_allocation = new Allocation(alloc[0], alloc[1], alloc[2], alloc[3], alloc[4], alloc[5]);
36
- this.allocations.push(new_allocation);
37
- }
38
- this.length = this.allocations.length;
39
-
40
- this.each = function(callback) {
41
- return $.each(this.allocations, callback);
42
- };
43
- };
44
-
45
- // Container for the types.
46
- //
47
- // data:
48
- // offset: X
49
- // duration: X
50
- // total: X
51
- // allocations:
52
- // Allocation[] of [weight, count, combination, Entry[] of [id, content]]
53
- //
54
- function PickyData(data) {
55
- var self = this;
56
-
57
- // Attributes.
58
- //
59
- var total = data.total;
60
- var duration = data.duration;
61
- var offset = data.offset;
62
- var allocations = new Allocations(data.allocations || []);
63
-
64
- // Expose some attributes.
65
- //
66
- this.total = total;
67
- this.duration = duration;
68
- this.offset = offset;
69
- this.allocations = allocations;
70
-
71
- // Are there any results?
72
- //
73
- var isEmpty = function() {
74
- return total == 0;
75
- };
76
- this.isEmpty = isEmpty;
77
-
78
- };
@@ -1,15 +0,0 @@
1
- Array.prototype.index = function(val) {
2
- for(var i = 0, l = this.length; i < l; i++) {
3
- if(this[i] == val) return i;
4
- }
5
- return null;
6
- };
7
-
8
- Array.prototype.include = function(val) {
9
- return this.index(val) !== null;
10
- };
11
-
12
- Array.prototype.remove = function(index) {
13
- this.splice(index, 1);
14
- return this;
15
- };
@@ -1,17 +0,0 @@
1
- Array.prototype.index=function(b){for(var d=0,f=this.length;d<f;d++)if(this[d]==b)return d;return null};Array.prototype.include=function(b){return this.index(b)!==null};Array.prototype.remove=function(b){this.splice(b,1);return this};var PickyI18n={};$(function(){PickyI18n.locale=$("html").attr("lang").split("-")[0]||"en"});
2
- var dictionary={common:{join:{de:"und",fr:"et",it:"e",en:"and",ch:"und"},"with":{de:"mit",fr:"avec",it:"con",en:"with",ch:"mit"},of:{de:"von",fr:"de",it:"di",en:"of",ch:"vo"},to:{de:"bis",fr:"\u00e0",it:"alla",en:"to",ch:"bis"}},results:{addination:{more:{de:"Weitere Resultate",fr:"Autres r\u00e9sultats",it:"Altri risultati",en:"More results",ch:"Mee Resultaat"}},header:{de:"Ergebnisse",fr:"R\u00e9sultats",it:"Risultati",en:"Results",ch:"Erg\u00e4bnis"}}},t=function(b){for(var d=PickyI18n.locale||
3
- "en",f=b.split(".").concat(d),c=dictionary,j=0,r=f.length;j<r;j++){c=c[f[j]];if(c==undefined){c="Translation missing: "+b+"."+d;break}}return c};function Allocation(b,d,f,c,j,r){var e=this;this.type=b;this.weight=d;this.count=f;this.combination=c;this.ids=j||[];this.entries=this.rendered=r||[];this.isType=function(k){return k==e.type}}function Allocations(b){this.allocations=[];for(var d=0,f=b.length;d<f;d++){var c=b[d];this.allocations.push(new Allocation(c[0],c[1],c[2],c[3],c[4],c[5]))}this.length=this.allocations.length;this.each=function(j){return $.each(this.allocations,j)}}
4
- function PickyData(b){var d=b.total,f=b.duration,c=b.offset;b=new Allocations(b.allocations||[]);this.total=d;this.duration=f;this.offset=c;this.allocations=b;this.isEmpty=function(){return d==0}};var PickyView=function(b,d){var f=d.showResultsLimit||10,c=$("#picky input.query"),j=$("#picky div.reset"),r=$("#picky input.search_button"),e=$("#picky div.status"),k=$("#picky .dashboard"),s=$("#picky .results"),o=$("#picky .no_results"),g=new PickyAddination(this,s),n=new PickyAllocationsCloud(this),u=new PickyResultsRenderer(g),w=function(){j.fadeTo(166,1)},z=function(){n.hide();s.empty();o.hide()},D=function(m){c.val(m);j.fadeTo(166,0);B("empty");e.empty();z()},x=function(){return c.val()};this.text=
5
- x;var A=function(m){e.text(m);m>0&&m<=5&&e.fadeTo("fast",0.5).fadeTo("fast",1)},E=function(m){if(m.isEmpty())return"none";if(m.total>f&&m.allocations.length>1)return"support";return"ok"},B=function(m){k.attr("class","dashboard "+m)};this.insert=function(m){c.val(m);c.select()};this.fullResultsCallback=function(m){B(E(m));if(m.isEmpty()){z();A(0);o.show();w()}else if(m.total>f&&m.allocations.length>1){z();w();n.show(m);A(m.total)}else if(m.offset==0){z();A(m.total);u.render(m);s.show();w()}else{g.remove();
6
- u.render(m);$.scrollTo("#picky .results div.info:last",{duration:500,offset:-12})}c.focus()};this.liveResultsCallback=function(m){B(E(m));A(m.total)};this.allocationChosen=function(m){m=m.data.query;c.val(m);b.allocationChosen(m)};this.addinationClicked=function(m){b.addinationClicked(x(),m)};(function(){c.keyup(function(m){if(x()==""){D();b.searchTextCleared()}else{b.searchTextEntered(x(),m);w()}});r.click(function(){x()==""||b.searchButtonClicked(x())});j.click(function(){D("");b.clearButtonClicked();
7
- c.focus()})})();c.focus()};var PickyBackend=function(b){var d=function(f,c,j,r){var e=r||{};e=$.extend({query:f,offset:j},r);$.ajax({type:"GET",url:b,data:e,success:function(k){c&&c(new PickyData(k))},dataType:"json"})};this.search=function(f,c,j,r,e){d(f,function(k){c&&c(e,k)},j,r)}},LiveBackend=function(b){var d=new PickyBackend(b);this.search=function(f,c,j,r,e){e=e||{};latestRequestTimestamp=new Date;e.live=latestRequestTimestamp;d.search(f,function(k,s){if(!k.live||k.live==latestRequestTimestamp)c&&c(s)},j,r,e)}},FullBackend=
8
- function(b){var d=new PickyBackend(b);this.search=function(f,c,j,r,e){e=e||{};latestRequestTimestamp=new Date;e.full=latestRequestTimestamp;d.search(f,function(k,s){if(!k.full||k.full==latestRequestTimestamp)c&&c(s)},j,r,e)}};var PickyController=function(b){var d=new PickyView(this,b),f=b.backends,c=b.before||function(){},j=b.success||function(){},r=b.after||function(){},e=function(g,n){g=j(g,n)||g;d.fullResultsCallback(g);r(g,n)},k=function(g,n,u){u=u||{};n=n||0;o.stop();u=c(u,g,n)||u;var w=f.full;w&&w.search(g,e,n,u)},s=function(g,n){g=j(g,n)||g;d.liveResultsCallback(g);r(g,n)},o=$.timer(180,function(g){var n=d.text();c({});var u=f.live;u&&u.search(n,s,0,void 0);g.stop()});o.stop();this.insert=function(g,n){d.insert(g);
9
- n&&k(g)};this.clearButtonClicked=function(){o.stop()};this.searchTextCleared=function(){o.stop()};this.searchTextEntered=function(g,n){if($.inArray(n.keyCode,[0,8,13,32,46,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90])>-1)n.keyCode==13?k(g):o.reset()};this.searchButtonClicked=function(g){k(g)};this.allocationChosen=function(g){k(g)};this.addinationClicked=function(g,n){k(g,n.data.offset)}};var Localization={location_delimiters:{de:"in",fr:"\u00e0",it:"a",en:"in",ch:"in"},explanation_delimiters:{de:"und",fr:"et",it:"e",en:"and",ch:"und"}},PickyClient=function(b){Localization.qualifiers=b.qualifiers||{};Localization.explanations=b.explanations||{};Localization.explanation_delimiters={de:"und",fr:"et",it:"e",en:"and",ch:"und"};var d=b.backends;if(d){d.live||alert("Both a full and live backend must be provided.");d.full||alert("Both a full and live backend must be provided.")}else b.backends=
10
- {live:b.live&&new LiveBackend(b.live)||alert("A live backend path must be provided."),full:b.full&&new FullBackend(b.full)||alert("A live backend path must be provided.")};var f=b.controller&&new b.controller(b)||new PickyController(b);this.insert=function(c,j){f.insert(c,j||true)}};var PickyAddination=function(b,d){this.remove=function(){d.find(".addination").remove()};this.render=function(f){var c=f.total,j=void 0;j=j||0;j=f.offset+20+j;var r=j+20;f=f.total;if(f<r)r=f;f={offset:j,start:j+1,end:r};if(f.offset<c){c=$("<div class='addination current'>"+t("results.addination.more")+"<div class='tothetop'><a href='javascript:$.scrollTo(0,{ duration: 500});'>&uarr;</a></div></div>");c.bind("click",{offset:f.offset},b.addinationClicked);return c}else return""}};var PickyResultsRenderer=function(b){var d=["street_number","zipcode"],f=function(e){var k=e[e.length-1];e=e.slice(0,e.length-1);if(e==[])e=[e];if(!d.include(k[0]))if(k[1].match(/[^\*~]$/))k[1]+="*";e.push(k);return e},c=function(e){for(var k=Localization.explanations&&Localization.explanations[PickyI18n.locale]||{},s=[],o,g=0,n=e.length;g<n;g++){o=e[g];var u=o[0];u=k[u]||u;s.push([u,o[1]])}return s},j=function(e,k){var s=Localization.explanation_delimiters[PickyI18n.locale],o=c(f(k));o=$.map(o,function(g){return[g[0].replace(/([\w\s\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00e9\u00e8\u00e0]+)/,
11
- "<strong>$1</strong>"),g[1]].join(" ")});o=o.join(" "+s+" ");return'<div class="explanation">'+e+" "+o+"</div>"},r=function(e,k){var s='<div class="info">';s+=j(k.type,k.combination);if(e.offset>0)s+='<div class="tothetop"><a href="javascript:$.scrollTo(0,{ duration: 500 });">&uarr;</a></div>';s+='<div class="clear"></div></div>';return s};this.render=function(e){var k=$("#picky .results");e.allocations.each(function(s,o){k.append(r(e,o)).append(o.entries.join("")).append(b.render(e))})}};function AllocationRenderer(b){function d(a){var h={},p={},i=[],q;q=0;for(l=a.length;q<l;q++){var v=a[q][0];if(v in h){h[v]=h[v]+" "+a[q][1];i.push(q)}else{h[v]=a[q][1];p[q]=v}}for(q in p)a[q][1]=h[p[q]];for(q=i.length-1;q>=0;q--)a.remove(i[q]);return a}function f(a,h){var p=h||false,i=a[0],q=a[1],v=D[i];if(v){if(v.method)q=q[v.method]();if(v.format)q=v.format.replace(/%1\$s/,q)}i=w[i]||i;if(p&&!(v&&v.ignoreSingle))return q+"&nbsp;("+i+")";return q}function c(a){if(a.length==0)return"";else if(a.length==
12
- 1)return f(a[0],true);else{var h=[],p=[];a=d(a);for(var i=0,q=a.length;i<q;i++)if(a[i][0]=="first_name")h.unshift(f(a[i]));else a[i][0]=="maiden_name"?p.push(f(a[i])):h.push(f(a[i]));p.length>0&&h.push(p);return h.join(" ")}}function j(a){return function(h,p){for(var i=0,q=a.length;i<q;i++)if(a[i][0]==p)return a[i][1];return""}}function r(a){if(a.length==0)return"";var h=a=d(a);h.sort(function(v,y){return v[0]<y[0]?-1:1});for(var p=[],i=0,q=h.length;i<q;i++)p.push(h[i][0]);return x[p].replace(/:(zipcode|city)/g,
13
- j(a))}function e(a){var h=a[0];return a[1]+"&nbsp;("+(w[h]||h)+")"}function k(a){if(a.length==0)return"";result=[];a=d(a);for(var h=0,p=a.length;h<p;h++)result.push(e(a[h]));return result.join(", ")}function s(a){for(var h=[],p=[],i=[],q=0,v=a.length;q<v;q++){var y=a[q];if(E.include(y[0]))i.push(y);else A.include(y[0])?h.push(y):p.push(y)}var C;if(i.length>0)C=i[i.length-1];else if(p.length>0)C=p[p.length-1];else if(h.length>0)C=h[h.length-1];z.include(C[0])||(C[1]+="...");a=c(h);p=k(p);i=r(i);return[a,
14
- p,i]}function o(a){var h=a[0],p=a[1];a=a[2];var i="";i=h!=""?p!=""?[h,p].join(B):h:p;if(a=="")return i;return[i,a].join(m)}function g(a){var h=[],p,i;for(i in a){p=a[i][0];p=u[p]||p;h[i]=p+":"+a[i][1]}return h.join(" ")}var n=PickyI18n.locale,u=Localization.qualifiers&&Localization.qualifiers[n]||{},w=Localization.explanations&&Localization.explanations[n]||{};n=Localization.location_delimiters[n];this.explanation=this.query=this.text="";var z=["street_number","zipcode"];this.contract=d;var D={maiden_name:{format:"(-%1$s)",
15
- method:"capitalize",ignoreSingle:true},name:{format:"<strong>%1$s</strong>",method:"toUpperCase",ignoreSingle:true},first_name:{format:"%1$s",method:"capitalize"}};this.who=c;var x={zipcode:":zipcode ["+w.city+"]",city:":city","city,zipcode":":zipcode :city"};this.where=r;this.what=k;var A=["first_name","name","maiden_name"],E=["zipcode","city"];this.trisect=s;var B=", ",m=" "+n+"&nbsp;";this.fuse=o;this.querify=g;this.render=function(a){var h=a.combination,p=a.count;a=g(h);h=o(s(h));h=$('<li><div class="text">'+
16
- h+'</div><div class="count">'+p+"</div></li>");h.bind("click",{query:a},b);return h}};var PickyAllocationsCloud=function(b){var d=$("#picky .allocations"),f=d.find(".shown"),c=d.find(".more"),j=d.find(".hidden"),r=function(){d.hide()},e=new AllocationRenderer(function(o){r();b.allocationChosen(o)}),k=function(o){var g=[];o.each(function(n,u){g.push(e.render(u))});return g},s=function(o){if(o.length==0)return $("#search .allocations").hide();f.empty();c.hide();j.empty().hide();if(o.length>3){$.each(o.slice(0,2),function(g,n){f.append(n)});$.each(o.slice(2),function(g,n){j.append(n)});
17
- c.show()}else $.each(o,function(g,n){f.append(n)});return $("#search .allocations").show()};c.click(function(){c.hide();j.show()});this.hide=r;this.show=function(o){s(k(o.allocations));d.show()}};
@@ -1,103 +0,0 @@
1
- var PickyResultsRenderer = function(addination) {
2
-
3
- // Adds asterisks to the last token.
4
- //
5
- var no_asterisks = ['street_number', 'zipcode']; // TODO Works. Parametrize!
6
- var asteriskifyLastToken = function(combination) {
7
- var last_part = combination[combination.length-1];
8
- var parts = combination.slice(0, combination.length-1);
9
- if (parts == []) { parts = [parts]; }
10
- if (!no_asterisks.include(last_part[0])) {
11
- // Replace with * unless there is already one or a tilde.
12
- //
13
- if (last_part[1].match(/[^\*~]$/)) { last_part[1] += '*'; }
14
- }
15
- parts.push(last_part);
16
- return parts;
17
- };
18
-
19
- // Replaces the category with an explanation of the category.
20
- //
21
- var explainCategory = function(combination) {
22
- var explanations = Localization.explanations && Localization.explanations[PickyI18n.locale] || {}; // TODO
23
- var parts = [];
24
- var combo;
25
-
26
- for (var i = 0, l = combination.length; i < l; i++) {
27
- combo = combination[i];
28
- var explanation = combo[0];
29
- explanation = explanations[explanation] || explanation;
30
- parts.push([explanation, combo[1]]);
31
- }
32
- return parts;
33
- };
34
-
35
- //
36
- //
37
- var explain = function(type, combination) {
38
- var explanation_delimiter = Localization.explanation_delimiters[PickyI18n.locale];
39
-
40
- var parts = explainCategory(asteriskifyLastToken(combination));
41
- var replaced = $.map(parts, function(part) {
42
- var category = part[0].replace(/([\w\sÄäÖöÜüéèà]+)/, "<strong>$1</strong>");
43
- var token = part[1];
44
- return [category, token].join(' ');
45
- });
46
- replaced = replaced.join(' ' + explanation_delimiter + ' ');
47
-
48
- return '<div class="explanation">' + type + ' ' + replaced + '</div>';
49
- };
50
-
51
- // TODO Make customizable.
52
- //
53
- var renderHeader = function(data, allocation) {
54
- // TODO Make type definable. (Mapping, i18n)
55
- //
56
- var header_html = '<div class="info">';
57
- header_html += explain(allocation.type, allocation.combination);
58
- if (data.offset > 0) {
59
- header_html += '<div class="tothetop"><a href="javascript:$.scrollTo(0,{ duration: 500 });">&uarr;</a></div>'; // searchEngine.focus();
60
- }
61
-
62
- // TODO Parametrize!
63
- // var names = '';
64
- // var firstEntryName = $(allocation.entries[0]).find('.name').html();
65
- // var lastEntryName = $(allocation.entries[allocation.entries.length-1]).find('.name').html();
66
- // if(firstEntryName == lastEntryName) {
67
- // var firstEntryFirstName = $(allocation.entries[0]).find('.first_name').html();
68
- // var lastEntryFirstName = $(allocation.entries[allocation.entries.length-1]).find('.first_name').html();
69
- // names = '<div class="names">' + firstEntryName + ', ' + firstEntryFirstName + ' ' + t('common.to') + ' ' + lastEntryFirstName + '</div>';
70
- // }
71
- // else {
72
- // names = '<div class="names">' + firstEntryName + ' ' + t('common.to') + ' ' + lastEntryName + '</div>';
73
- // }
74
-
75
- // var rangeStart = data.offset + 1;
76
- // var rangeEnd = data.offset + allocation.entries.length;
77
- // var rangeText = (rangeStart == rangeEnd) ? rangeStart : rangeStart + '-' + rangeEnd;
78
- // var range = '<div class="range">' + rangeText + ' ' + t('common.of') + ' ' + data.total + '</div>';
79
-
80
- // if (data.total > 20) { // TODO Make settable.
81
- // // header_html += '<div class="clear"></div>'; // TODO
82
- // // header_html += names; // TODO
83
- // // header_html += range; // TODO
84
- // }
85
-
86
- // For smooth addination scrolling. Don't ask.
87
- //
88
- header_html += '<div class="clear"></div></div>';
89
-
90
- return header_html;
91
- };
92
-
93
- // Render results with the data.
94
- //
95
- this.render = function(data) {
96
- var results = $('#picky .results'); // TODO Extract, also from view.
97
- data.allocations.each(function(i, allocation) {
98
- results.append(renderHeader(data, allocation)) // TODO header.render(data);
99
- .append(allocation.entries.join(''))
100
- .append(addination.render(data));
101
- });
102
- };
103
- };
@@ -1,50 +0,0 @@
1
- // Translations
2
- //
3
- var PickyI18n = { };
4
-
5
- // Set the correct locale for all js code.
6
- //
7
- $(function() {
8
- PickyI18n.locale = $('html').attr('lang').split('-')[0] || 'en';
9
- });
10
-
11
- var dictionary = {
12
- common:{
13
- join: { de: 'und', fr: 'et', it: 'e', en: 'and', ch: 'und' },
14
- 'with': { de: 'mit', fr: 'avec',it: 'con', en: 'with', ch: 'mit' },
15
- of: { de: 'von', fr: 'de', it: 'di', en: 'of', ch: 'vo' },
16
- to: { de: 'bis', fr: 'à', it: 'alla', en: 'to', ch: 'bis' }
17
- },
18
- results:{
19
- addination:{
20
- more:{
21
- de: 'Weitere Resultate',
22
- fr: 'Autres résultats',
23
- it: 'Altri risultati',
24
- en: 'More results',
25
- ch: 'Mee Resultaat'
26
- }
27
- },
28
- header:{
29
- de: 'Ergebnisse',
30
- fr: 'Résultats',
31
- it: 'Risultati',
32
- en: 'Results',
33
- ch: 'Ergäbnis'
34
- }
35
- }
36
- };
37
- var t = function(key) {
38
- var locale = PickyI18n.locale || 'en';
39
- var keys = key.split('.').concat(locale);
40
- var current = dictionary;
41
-
42
- for (var i = 0, l = keys.length; i < l; i++) {
43
- current = current[keys[i]];
44
- if (current == undefined) {
45
- current = 'Translation missing: ' + key + '.' + locale;
46
- break;
47
- }
48
- };
49
- return current;
50
- };
@@ -1,214 +0,0 @@
1
- // Add PickyResults?
2
- var PickyView = function(picky_controller, config) {
3
-
4
- var controller = picky_controller;
5
-
6
- var showResultsLimit = config.showResultsLimit || 10;
7
-
8
- var searchField = $('#picky input.query');
9
- var clearButton = $('#picky div.reset');
10
- var searchButton = $('#picky input.search_button');
11
- var resultCounter = $('#picky div.status');
12
- var dashboard = $('#picky .dashboard');
13
-
14
- var results = $('#picky .results'); // Push into results.
15
- var noResults = $('#picky .no_results');
16
-
17
- var addination = new PickyAddination(this, results); // Push into results.
18
-
19
- var allocationsCloud = new PickyAllocationsCloud(this);
20
- var resultsRenderer = new PickyResultsRenderer(addination); // TODO Rename results.
21
-
22
- // Toggle the clear button visibility.
23
- //
24
- var showClearButton = function() {
25
- clearButton.fadeTo(166, 1.0);
26
- };
27
- var hideClearButton = function() {
28
- clearButton.fadeTo(166, 0.0);
29
- };
30
-
31
- // TODO Move to results
32
- var clearResults = function() {
33
- results.empty();
34
- };
35
- var hideEmptyResults = function() {
36
- noResults.hide();
37
- };
38
-
39
- var focus = function() {
40
- searchField.focus();
41
- };
42
- var select = function() {
43
- searchField.select();
44
- };
45
-
46
- // Cleans the interface of any results or choices presented.
47
- //
48
- var clean = function() {
49
- allocationsCloud.hide();
50
- clearResults();
51
- hideEmptyResults();
52
- };
53
-
54
- // Resets the whole view to the inital state.
55
- //
56
- var reset = function(to_text) {
57
- searchField.val(to_text);
58
- hideClearButton();
59
- setSearchStatus('empty');
60
- resultCounter.empty();
61
- clean();
62
- };
63
-
64
- var bindEventHandlers = function() {
65
- searchField.keyup(function(event) {
66
- if (isTextEmpty()) {
67
- reset();
68
- controller.searchTextCleared();
69
- } else {
70
- controller.searchTextEntered(text(), event);
71
- showClearButton();
72
- }
73
- });
74
-
75
- searchButton.click(function(event) {
76
- if (!isTextEmpty()) {
77
- controller.searchButtonClicked(text());
78
- }
79
- });
80
-
81
- clearButton.click(function() {
82
- reset('');
83
- controller.clearButtonClicked();
84
- focus();
85
- });
86
- };
87
-
88
- var text = function() {
89
- return searchField.val();
90
- };
91
- this.text = text; // TODO Remove.
92
- var isTextEmpty = function() {
93
- return text() == '';
94
- };
95
-
96
- var showEmptyResults = function() {
97
- clean();
98
- updateResultCounter(0);
99
- noResults.show();
100
- showClearButton();
101
- };
102
- var showTooManyResults = function(data) {
103
- clean();
104
- showClearButton();
105
- allocationsCloud.show(data);
106
- updateResultCounter(data.total);
107
- };
108
- var showResults = function(data) {
109
- clean();
110
- updateResultCounter(data.total);
111
- resultsRenderer.render(data);
112
- results.show();
113
- showClearButton();
114
- };
115
-
116
- var appendResults = function(data) {
117
- addination.remove(); // TODO Where should this be?
118
- resultsRenderer.render(data);
119
- $.scrollTo('#picky .results div.info:last', { duration: 500, offset: -12 });
120
- };
121
-
122
- var updateResultCounter = function(total) {
123
- resultCounter.text(total); // ((total > 999) ? '999+' : total); // TODO Decide on this.
124
- flashResultCounter(total);
125
- };
126
-
127
- var alertThreshold = 5;
128
- var flashResultCounter = function(total) {
129
- if (total > 0 && total <= alertThreshold) {
130
- resultCounter.fadeTo('fast', 0.5).fadeTo('fast', 1);
131
- }
132
- };
133
-
134
- var tooManyResults = function(data) {
135
- return data.total > showResultsLimit && data.allocations.length > 1;
136
- };
137
- var resultStatusFor = function(data) {
138
- if (data.isEmpty()) { return 'none'; };
139
- if (tooManyResults(data)) { return 'support'; }
140
- return 'ok';
141
- };
142
- var setSearchStatus = function(statusClass) {
143
- dashboard.attr('class', 'dashboard ' + statusClass);
144
- };
145
- var setSearchStatusFor = function(data) {
146
- setSearchStatus(resultStatusFor(data));
147
- };
148
-
149
- // Insert a search text into the search field.
150
- // Field is always selected when doing that.
151
- //
152
- var insert = function(text) {
153
- searchField.val(text);
154
- select();
155
- };
156
- this.insert = insert;
157
-
158
- // Callbacks.
159
- //
160
-
161
- // Full results handling.
162
- //
163
- var fullResultsCallback = function(data) {
164
- setSearchStatusFor(data);
165
-
166
- if (data.isEmpty()) {
167
- showEmptyResults();
168
- } else if (tooManyResults(data)) {
169
- showTooManyResults(data);
170
- } else {
171
- if (data.offset == 0) {
172
- showResults(data);
173
- } else {
174
- appendResults(data);
175
- }
176
- };
177
-
178
- focus();
179
- };
180
- this.fullResultsCallback = fullResultsCallback;
181
-
182
- // Live results handling.
183
- //
184
- var liveResultsCallback = function(data) {
185
- setSearchStatusFor(data);
186
-
187
- updateResultCounter(data.total);
188
- };
189
- this.liveResultsCallback = liveResultsCallback;
190
-
191
- // Callback for when an allocation has been chosen
192
- // in the allocation cloud.
193
- //
194
- var allocationChosen = function(event) {
195
- var text = event.data.query;
196
-
197
- searchField.val(text);
198
-
199
- controller.allocationChosen(text);
200
- };
201
- this.allocationChosen = allocationChosen;
202
-
203
- // Callback for when the addination has been clicked.
204
- //
205
- var addinationClicked = function(event) {
206
- controller.addinationClicked(text(), event);
207
- };
208
- this.addinationClicked = addinationClicked;
209
-
210
- //
211
- //
212
- bindEventHandlers();
213
- focus();
214
- };