departr 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,288 @@
1
+ var Command = {
2
+ data: [], // Set in index view
3
+ pattern: /\{\w+\}/,
4
+ patternsCleaner: /^\{|\}$/g,
5
+ refresh: false, // A light ask to refresh the page
6
+ form: "<div id='command-form'><label for='name'>Name</label><input type='text' name='name'><label for='value'>Command</label><input type='text' name='url'></div>",
7
+ selected: false,
8
+
9
+ // Open the window to edit all commands
10
+ edit: function(e) {
11
+ if (e) e.stop();
12
+
13
+ var modal = new SimpleModal({ draggable: false, width: 900 });
14
+ modal.addButton("Add", "btn primary", Command.add);
15
+ modal.addButton("Revert", "btn primary", function() {
16
+ this.hide();
17
+ var modal = new SimpleModal({draggable:false});
18
+ modal.show({
19
+ model: "confirm",
20
+ callback: function() {
21
+ window.parent.location.href = '/command/revert';
22
+ },
23
+ title: "Are you sure ?",
24
+ contents: "Warning, this will reset all your commands to the default ones."
25
+ });
26
+ });
27
+ modal.addButton("Save", "btn primary", Command.save);
28
+ modal.addButton("Cancel", "btn secondary", function() {
29
+ this.hide();
30
+ });
31
+ modal.show({
32
+ model: "modal",
33
+ title: "Edit commands",
34
+ contents: "<div id='commands'>" + Command.data.map(function(item, index, array) {
35
+ return "<div class='command'>" +
36
+ "<div class='name'>" + item.name + "</div>" +
37
+ "<div class='url'>" + item.url + "</div>" +
38
+ "</div>";
39
+ }).join('') + "</div>"
40
+ });
41
+
42
+ $('commands').getElements('.command').each(function(item) {
43
+ item.addEvent('click', function(e) {
44
+ e.stop();
45
+ modal.hide();
46
+ Command.update(this);
47
+ });
48
+ });
49
+ },
50
+
51
+ // Open the window to update one command
52
+ update: function(item) {
53
+ var modal = new SimpleModal({ draggable: false, width: 400 });
54
+ var name = item.getElement('.name').get('text');
55
+ var url = item.getElement('.url').get('text');
56
+ var index = -1;
57
+
58
+ for (var i = 0; i < Command.data.length; i++) {
59
+ if (Command.data[i].name == name) {
60
+ index = i;
61
+ break;
62
+ }
63
+ }
64
+
65
+ if (i == -1) {
66
+ Application.notice("Record not found");
67
+ return;
68
+ }
69
+
70
+ modal.addButton("Delete", "btn primary", function() {
71
+ Command.data.splice(index, 1);
72
+ this.hide();
73
+ Command.edit();
74
+ });
75
+
76
+ var ok = modal.addButton("Ok", "btn primary", function() {
77
+ var inputs = $('command-form').getElements('input');
78
+ Command.data[index] = {
79
+ name: inputs[0].value,
80
+ url: inputs[1].value
81
+ };
82
+ this.hide();
83
+ Command.edit();
84
+ });
85
+
86
+ modal.addButton("Cancel", "btn secondary", function() {
87
+ this.hide();
88
+ Command.edit();
89
+ });
90
+
91
+ modal.show({
92
+ model: "modal",
93
+ title: "Update command",
94
+ contents: Command.form
95
+ });
96
+
97
+ var inputs = $('command-form').getElements('input');
98
+ inputs[0].value = Command.data[index].name;
99
+ inputs[1].value = Command.data[index].url;
100
+ inputs[0].focus();
101
+ inputs.each(function(input) {
102
+ input.addEvent('keydown', function(e) {
103
+ if (e.key === 'enter') ok.fireEvent('click');
104
+ });
105
+ });
106
+ },
107
+
108
+ // Open the window to add a command
109
+ add:function() {
110
+ this.hide();
111
+ var modal = new SimpleModal({ draggable: false, width: 400 });
112
+
113
+ var ok = modal.addButton("Ok", "btn primary", function() {
114
+ var inputs = $('command-form').getElements('input');
115
+ Command.data.push({
116
+ name: inputs[0].value,
117
+ url: inputs[1].value
118
+ });
119
+ this.hide();
120
+ Command.edit();
121
+ });
122
+
123
+ modal.addButton("Cancel", "btn secondary", function() {
124
+ this.hide();
125
+ Command.edit();
126
+ });
127
+
128
+ modal.show({
129
+ model: "modal",
130
+ title: "Add a new command",
131
+ contents: Command.form
132
+ });
133
+
134
+ var inputs = $('command-form').getElements('input');
135
+ inputs[0].focus();
136
+ inputs.each(function(input) {
137
+ input.addEvent('keydown', function(e) {
138
+ if (e.key === 'enter') ok.fireEvent('click');
139
+ });
140
+ });
141
+ },
142
+
143
+ // Save all commands
144
+ save: function() {
145
+ var result = [];
146
+ new Request({
147
+ url: '/command/save',
148
+ urlEncoded: false,
149
+ headers: { 'Content-Type': 'application/json' },
150
+ onFailure: function() {
151
+ Application.notice('An error occured');
152
+ },
153
+ onSuccess: function() {
154
+ Command.autocompleter.setList(Command.data);
155
+ }
156
+ }).post(JSON.encode(Command.data));
157
+ this.hide();
158
+ },
159
+
160
+ submit: function(e) {
161
+ if (e)
162
+ e.stop();
163
+
164
+ // Check if a question is needed
165
+ var matches = $('input').value.match(Command.pattern);
166
+ if (matches) {
167
+ var answer = $('answer');
168
+ var label = matches[0].replace(Command.patternsCleaner, '').replace(/(.)$/, "<span>$1</span>");
169
+ $('label').set('html', label + ' &raquo; ');
170
+ answer.value = '';
171
+ $('question').setStyle('display', 'block');
172
+ answer.focus();
173
+ return;
174
+
175
+ } else {
176
+ // No question remaining
177
+ $('question').setStyle('display', 'none');
178
+ }
179
+
180
+ // Execute selected command
181
+ if (Command.selected) {
182
+ Command.go(Command.selected);
183
+ return;
184
+ }
185
+
186
+ // Default command
187
+ if (!this.input.value.match(/^\s*$/)) {
188
+ if (this.input.value.match(/^\s*(ftp|http|https):\/\//i)) {
189
+ // If it's an url
190
+ Command.go(this.input.value);
191
+ } else if (this.input.value.match(/^\s*[a-z0-9]([-a-z0-9]*[a-z0-9])?\.[a-z]{2,}/i)) {
192
+ // If it's a domain
193
+ Command.go('http://' + this.input.value.replace(/^\s+/, ''));
194
+ } else {
195
+ // Fallback to google
196
+ Command.go(Settings.default_search + encodeURIComponent(this.input.value));
197
+ }
198
+ }
199
+
200
+ return;
201
+ },
202
+
203
+ go: function(url) {
204
+ if (Settings.open_in_new_page) {
205
+ $('input').value = '';
206
+ $('answer').value = '';
207
+ $('input').blur(); $('input').focus(); // prevent strange auto completion
208
+ window.open(url, "_blank");
209
+ } else {
210
+ window.location.href = url;
211
+ }
212
+ },
213
+
214
+ init: function() {
215
+ Command.autocompleter = new AutoComplete('input', {
216
+ list: Command.data,
217
+ size: 10,
218
+ mode: 'partial',
219
+ render: function(command) {
220
+ return new Element('span', {html: command.name});
221
+ },
222
+ get: function(command) {
223
+ return command.name;
224
+ },
225
+ set: function(command) {
226
+ return command.name;
227
+ },
228
+ filters: [function(o,v) {
229
+ return o.match(new RegExp(v.escapeRegExp().replace(/\s+/, '.*'), 'i'))
230
+ }]
231
+ }).addEvent('complete', function(value) {
232
+ Command.selected = value.url;
233
+ }).addEvent('abort', function() {
234
+ Command.selected = false;
235
+ });
236
+
237
+ // Hook command line submit
238
+ $('commandline').addEvent('submit', Command.submit);
239
+
240
+ // Hook input keypress to auto submit
241
+ $('input').addEvent('keydown', function(e) {
242
+ if (e && e.key && !e.shift && e.key == 'enter') {
243
+ e.stop();
244
+ $('commandline').fireEvent('submit');
245
+ }
246
+ });
247
+
248
+ // Hook answer keypress to fill the main input with answers
249
+ $('answer').addEvent('keydown', function(e) {
250
+ if (e && e.key && !e.shift) {
251
+ if (e.key == 'enter') {
252
+ e.stop();
253
+ var answer = $('answer').value;
254
+ if (answer.match(/^\s*$/)) return;
255
+ var keyword = $('input').value.match(Command.pattern);
256
+ $('input').value = $('input').value.replace(Command.pattern, answer);
257
+ Command.selected = Command.selected.replace(keyword[0], encodeURIComponent(answer));
258
+ $('commandline').fireEvent('submit');
259
+
260
+ } else if (e.key == 'esc') {
261
+ $('question').setStyle('display', 'none');
262
+ $('input').focus();
263
+ }
264
+ }
265
+ });
266
+
267
+ // Focus management
268
+ window.addEvent('click', function(e) {
269
+ if ($('commandline').getStyle('display') == 'block' && !$('simple-modal')) {
270
+ $('input').focus();
271
+ }
272
+ });
273
+
274
+ window.addEvent('load', function() {
275
+ top.focus();
276
+ window.focus();
277
+ $('input').focus();
278
+ });
279
+
280
+ if ($('date')) {
281
+ var today = new Date;
282
+ var weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
283
+ $('date').getElement('.day').set('text', today.getDate());
284
+ $('date').getElement('.wday').set('text', weekdays[today.getDay()]);
285
+ }
286
+ }
287
+ };
288
+
data/views/help.haml ADDED
@@ -0,0 +1,58 @@
1
+ #help
2
+ %p Departr is a smart and fast startpage to help you reach other web sites.
3
+
4
+ %p
5
+ Like others, if you enter "obama", it will send you to google
6
+ search results for "obama".
7
+ If you enter "http://www.google.com" or simply "google.com",
8
+ it will redirect you to the google web site.
9
+
10
+ %p
11
+ Another sweetness with google, type the name of a website you know,
12
+ for example "netvibes", and instead hit RETURN, hit CONTROL+ENTER,
13
+ it will do a "I'm feelink lucky".
14
+
15
+ %p But there is more !
16
+
17
+ %p
18
+ For example, start typing "map" and hit the RETURN key.
19
+ Then type "Paris, France" and RETURN again, nice !
20
+
21
+ %p
22
+ Another example, start typing "twit", two results are
23
+ listed below, "twitter" and "twitter search for ?".
24
+ Hit the DOWN key and then the RETURN key. Type
25
+ "obama" in the input filed has just appeared, and
26
+ hit RETURN again. Voila !
27
+
28
+ %p
29
+ If your are too lazy or would like to be even faster
30
+ you can only specify partial command name. For example,
31
+ you have that command "images search for {words}", start
32
+ typing "go se" and it will be selected. Awesome isn't it !
33
+
34
+ %p
35
+ Many other commands are available by default, but if
36
+ you sign in using your Facebook, Twitter, Gmail, Yahoo,
37
+ Flickr or OpenId account, you will be able to edit or
38
+ add your own custom commands.
39
+ %p
40
+ So do not hesitate to set #{host} as you homepage
41
+ in your favorite browser :
42
+ %ul
43
+ %li
44
+ %a{:href => "http://support.mozilla.com/en-US/kb/How+to+set+the+home+page", :target => :_blank} Firefox
45
+ %li
46
+ %a{:href => "http://www.microsoft.com/nz/digitallife/internet/change_your_homepage_in_Internet_Explorer.mspx", :target => :_blank} Internet Explorer
47
+ %li
48
+ %a{:href => "http://support.apple.com/kb/HT3643", :target => :_blank} Safari
49
+ %li
50
+ %a{:href => "https://chrome.google.com/extensions/detail/icpgjfneehieebagbmdbhnlpiopdcmna", :target => :_blank} Google Chrome
51
+ %li
52
+ %a{:href => "http://www.opera.com/support/kb/view/646/", :target => :_blank} Opera
53
+
54
+ %p
55
+ Tip for Firefox user, consider install the
56
+ %a{:href => "https://addons.mozilla.org/en-US/firefox/addon/777", :target => :_blank} "New Tab Homepage"
57
+ extension
58
+
data/views/index.haml ADDED
@@ -0,0 +1,71 @@
1
+ -# coding: utf-8
2
+ %a#github{:href => "http://github.com/florentsolt/departr", :style => "display: #{@settings["github"] ? "block" : "none"}"}
3
+ %img{:src => "https://a248.e.akamai.net/assets.github.com/img/71eeaab9d563c2b3c590319b398dd35683265e85/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67", :alt => "Fork me on GitHub"}
4
+
5
+ #header
6
+ - if @config.get(:rpx)
7
+ %a#signin{:href => "https://#{@config.get(:rpx)[:realm]}.rpxnow.com/openid/embed?token_url=" + URI.escape(host + "/signin")}
8
+ Sign In
9
+ %a#edit{:href => "#"} Edit commands
10
+ %a#settings{:href => "#"} Settings
11
+ %a#help{:href => "#"} Help
12
+ %a{:id => :signout, :href => '#'} Sign Out
13
+
14
+ %form{:id => :commandline}
15
+ #logo= "depart<span>r</span>"
16
+ %img{:src => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGFwAABhcBlmjpmQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIcSURBVEiJtZaxaxRREIe/d0aMQUUCz+ZZaidYCKJgI4rohYgQRUTRP0BQsA9iQK0EwVJsRfRMIJjLaZVGEKwsLGzEZrAYsDlziTl1LHYP9ta7vd3lduAV++O3+zHvzcxbJ2pUGcG7Y8AD4BCw4qoEBu8uAi+AbbHUrVUIqwPPEzCAz5VkGLw7CTSByYT8F5gde4bBu+PAcgr2B7ghas2J2HQUmBoDbxp4BuxKaFvAFVFb7AnzgFW0OsBZUaO3asAR4NcYskvHT6Auaq2kWBO1C8A+4CqwCGyMCXhT1NbS4n9VGrybAurAHDAD7C4JnBG1ZlqcSAui1gEaQCN4NwmcieHngb0l4cOBKfgmUYkvB++2A6di+GVKZp4JTMG7QAtoBe8CcK4MsHDjB+8elYUVBgbv5oE7CekNsF4JMHh3C1hISI+JCmmpCLDvDIN3O4DZtA4cBO4lnu+K2kL8TgO4VhgYw5bIPh8Dbovak4T2FmiTs2qTWzoN7AG6Gf77KVivdVbywPqAovZd1E4QNfdpYG2A/9uQ77wqDEyAO8An4MAA/7DsV8lZrcOq9DqwH/hKf6Zbg8yitkF0w5cGPiUaX4eBh6OAceTa1oGjTdTawEuA4N174HfszQI2ia62nVnAkY0vauvAR6Kp8m6Eb3XU9/JOmkvAnKhlZQg5tjXXbSFqksdH1I+bRH9sP0oD84aotYN3r4EvovZhkOcfNY7IMKY9rjcAAAAASUVORK5CYII='}
17
+ %input{:type => :text, :id => :input, :name => :input}
18
+ #question
19
+ %label#label Question
20
+ %input{:type => :text, :id => :answer, :name => :answer}
21
+ #special
22
+ #date.clock{:style => "display: #{@settings["calendar"] ? "block" : "none"}"}
23
+ .wday
24
+ .day
25
+ %canvas#clock1.clock{:style => "display: #{(@settings["clock1"] && @settings["clock1"] != "-none-") ? "block" : "none"}"}
26
+ %canvas#clock2.clock{:style => "display: #{(@settings["clock2"] && @settings["clock2"] != "-none-") ? "block" : "none"}"}
27
+ %canvas#clock3.clock{:style => "display: #{(@settings["clock3"] && @settings["clock3"] != "-none-") ? "block" : "none"}"}
28
+
29
+ :javascript
30
+
31
+ // Globals
32
+ Command.data = #{@commands.to_json};
33
+ Settings = #{@settings.to_json};
34
+
35
+ window.addEvent('domready', function() {
36
+ Application.init();
37
+ Command.init();
38
+
39
+ // Clock 1
40
+ if ($('clock1').getStyle('display') == 'block') {
41
+ new CoolClock({
42
+ canvasId: 'clock1',
43
+ displayRadius: 40,
44
+ gmtOffset: #{clock_offset(@settings["clock1"])},
45
+ label: #{clock_label(@settings["clock1"])},
46
+ fontSize: '30px'
47
+ });
48
+ }
49
+
50
+ // Clock 2
51
+ if ($('clock2').getStyle('display') == 'block') {
52
+ new CoolClock({
53
+ canvasId: 'clock2',
54
+ displayRadius: 40,
55
+ gmtOffset: #{clock_offset(@settings["clock2"])},
56
+ label: #{clock_label(@settings["clock2"])},
57
+ fontSize: '30px'
58
+ });
59
+ }
60
+
61
+ // Clock 3
62
+ if ($('clock3')) {
63
+ new CoolClock({
64
+ canvasId: 'clock3',
65
+ displayRadius: 40,
66
+ gmtOffset: #{clock_offset(@settings["clock3"])},
67
+ label: #{clock_label(@settings["clock3"])},
68
+ fontSize: '30px'
69
+ });
70
+ }
71
+ });
data/views/layout.haml ADDED
@@ -0,0 +1,11 @@
1
+ !!! 1.1
2
+ %html
3
+ %head
4
+ %title Departr
5
+ %link{:rel => :icon, :type => "image/png", :href => "/favicon.ico"}
6
+ %meta{'http-equiv' => 'content-type', :content => 'text/html; charset=utf-8'}
7
+ %link{:rel => :stylesheet, :href => "/stylesheets/all.css", :type => "text/css"}
8
+ %script{:type => 'text/javascript', :src => '/javascripts/all.js'}
9
+ %body
10
+ = yield
11
+
@@ -0,0 +1 @@
1
+ = h @profile.inspect
@@ -0,0 +1,45 @@
1
+ #settings
2
+ %label{:for => "setting_default_search"} Default search
3
+ %select{:id => "setting_default_search"}
4
+ %option{:value => 'http://www.google.com/search?ie=UTF-8&oe=UTF-8&q='} google.com
5
+ %option{:value => 'http://www.google.com/search?ie=UTF-8&oe=UTF-8&q='} google.fr
6
+ %option{:value => 'http://duckduckgo.com/?q='} duckduckgo.com
7
+ %option{:value => 'http://www.exalead.com/search/web/results/?q='} exalead.com
8
+
9
+ %hr
10
+
11
+ %label{:for => "setting_open_in_new_page"} Open in a new page ?
12
+ %input{:id => "setting_open_in_new_page", :type => :checkbox}
13
+ %hr
14
+
15
+ %label{:for => "setting_github"} Show github ribbon ?
16
+ %input{:id => "setting_github", :type => :checkbox}
17
+ %hr
18
+
19
+ %label{:for => "setting_clalendar"} Show calendar ?
20
+ %input{:id => "setting_calendar", :type => :checkbox}
21
+ %hr
22
+
23
+ %label{:for => "setting_clock1"} First clock
24
+ %select{:id => "setting_clock1"}
25
+ %hr
26
+
27
+ %label{:for => "setting_clock2"} Second clock
28
+ %select{:id => "setting_clock2"}
29
+ %hr
30
+
31
+ %label{:for => "setting_clock3"} Third clock
32
+ %select{:id => "setting_clock3"}
33
+
34
+ :javascript
35
+
36
+ // Reduce page size by inlining only 1 time the zone list
37
+ var zones = #{TZInfo::Timezone.all.collect(&:identifier).to_json};
38
+ ["clock1", "clock2", "clock3"].each(function(clock) {
39
+ new Element('option', {value: '-none', text: "Nothing"}).inject($('setting_' + clock));
40
+ zones.each(function(zone) {
41
+ var option = new Element('option', {value: zone, text: zone.replace(/_/g, ' ')})
42
+ if (Settings[clock] == zone) option.set('selected', 'selected');
43
+ option.inject($('setting_' + clock));
44
+ });
45
+ });