hashgrid 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in hashgrid.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Hashgrid
2
+
3
+ "A little tool that inserts a layout grid in web pages, allows you to hold it in place, and toggle between displaying it in the foreground or background."
4
+
5
+ ## Usage
6
+
7
+ 1. Include the gem in your Gemfile `gem 'hashgrid'`
8
+ 2. Run `bundle install`
9
+ 3. Add `<%= hashgrid %>` where you want the hashgrid css and javascript files to appear (usually in the head).
10
+ 4. Press **G** on your website!
11
+
12
+ For more info on using hashgrid checkout the [hashgrid website](http://hashgrid.com/).
13
+
14
+ ## TODO
15
+
16
+ * Customisable column widths
17
+ * Customisable colour
18
+ * Optionally hide vertical/horizontal lines
19
+
20
+ ## Thanks
21
+
22
+ Thanks go to [Analog](http://analog.coop/) for creating [hashgrid](http://hashgrid.com/).
23
+
24
+ ## Licence
25
+
26
+ Copyright (c) 2011 Lucas Willett and Odin Dutton
27
+
28
+ Released under a [Creative Commons Attribution-Share Alike License](http://creativecommons.org/licenses/by-sa/3.0/).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,24 @@
1
+ <!-- hashgrid -->
2
+ <script>
3
+ if(!jQuery) {
4
+ var script = document.createElement('script');
5
+ script.type = "text/javascript";
6
+ script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js";
7
+ document.getElementsByTagName('head')[0].appendChild(script);
8
+ }
9
+ </script>
10
+ <% if options %>
11
+ <style type="text/css" media="screen">
12
+ #grid div.vert {
13
+ <% if options[:column_width] %>
14
+ width: <%= options[:column_width] %> !important;
15
+ <% end %>
16
+ <% if options[:gutter_width] %>
17
+ margin-right: <%= options[:gutter_width] %> !important;
18
+ <% end %>
19
+ }
20
+ </style>
21
+ <% end %>
22
+ <%= stylesheet_link_tag '/stylesheets/hashgrid/hashgrid' %>
23
+ <%= javascript_include_tag '/javascripts/hashgrid/hashgrid' %>
24
+ <!-- /hashgrid -->
data/hashgrid.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/hashgrid/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "hashgrid"
6
+ s.version = Hashgrid::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Lucas Willett", "Odin Dutton"]
9
+ s.email = ["lucas@developingego.com", "odindutton@gmail.com"]
10
+ s.homepage = "http://github.com/twe4ked/hashgrid"
11
+ s.summary = "A simple Rails wrapper for hashgrid."
12
+ s.description = s.summary
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
18
+ s.require_paths= ['lib', 'public', 'app']
19
+
20
+ s.add_dependency('rack', '~> 1.2.1')
21
+ s.add_dependency('rails', '~> 3.0.0')
22
+ end
@@ -0,0 +1,8 @@
1
+ module Hashgrid
2
+ module Helpers
3
+ def hashgrid(options = nil)
4
+ render :partial => "shared/hashgrid", :locals => {:options => options}
5
+ end
6
+ end
7
+ end
8
+ ActionView::Base.send :include, Hashgrid::Helpers
@@ -0,0 +1,18 @@
1
+ module Hashgrid
2
+ class Railtie < Rails::Railtie
3
+ initializer :before_initiailze do
4
+ require 'rack'
5
+ Rails.configuration.middleware.insert_before('Rack::Sendfile', 'Rack::Static',
6
+ :urls => ['/stylesheets/hashgrid', '/javascripts/hashgrid'],
7
+ :root => "#{hashgrid_root}/public"
8
+ )
9
+ ActionController::Base.prepend_view_path("#{hashgrid_root}/app/views")
10
+ end
11
+
12
+ private
13
+
14
+ def hashgrid_root
15
+ File.expand_path(File.dirname(__FILE__) + '/../..')
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module Hashgrid
2
+ VERSION = "0.1.0"
3
+ end
data/lib/hashgrid.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'hashgrid/railtie'
2
+ require 'hashgrid/helpers'
@@ -0,0 +1,340 @@
1
+ /**
2
+ * hashgrid (jQuery version)
3
+ * http://github.com/dotjay/hashgrid
4
+ * Version 5, 3 Nov 2010
5
+ * Written by Jon Gibbins, dotjay.co.uk, accessibility.co.uk
6
+ * Contibutors:
7
+ * Sean Coates, seancoates.com
8
+ * Phil Dokas, jetless.org
9
+ *
10
+ * // Using a basic #grid setup
11
+ * var grid = new hashgrid();
12
+ *
13
+ * // Using #grid with a custom id (e.g. #mygrid)
14
+ * var grid = new hashgrid("mygrid");
15
+ *
16
+ * // Using #grid with additional options
17
+ * var grid = new hashgrid({
18
+ * id: 'mygrid', // id for the grid container
19
+ * modifierKey: 'alt', // optional 'ctrl', 'alt' or 'shift'
20
+ * showGridKey: 's', // key to show the grid
21
+ * holdGridKey: 'enter', // key to hold the grid in place
22
+ * foregroundKey: 'f', // key to toggle foreground/background
23
+ * jumpGridsKey: 'd', // key to cycle through the grid classes
24
+ * numberOfGrids: 2, // number of grid classes used
25
+ * classPrefix: 'class', // prefix for the grid classes
26
+ * cookiePrefix: 'mygrid' // prefix for the cookie name
27
+ * });
28
+ */
29
+ if (typeof jQuery == "undefined") {
30
+ alert("Hashgrid: jQuery not loaded. Make sure it's linked to your pages.");
31
+ }
32
+
33
+
34
+ /**
35
+ * hashgrid overlay
36
+ */
37
+ var hashgrid = function(set) {
38
+
39
+ var options = {
40
+ id: 'grid', // id for the grid container
41
+ modifierKey: null, // optional 'ctrl', 'alt' or 'shift'
42
+ showGridKey: 'g', // key to show the grid
43
+ holdGridKey: 'h', // key to hold the grid in place
44
+ foregroundKey: 'f', // key to toggle foreground/background
45
+ jumpGridsKey: 'j', // key to cycle through the grid classes
46
+ numberOfGrids: 1, // number of grid classes used
47
+ classPrefix: 'grid-', // prefix for the grid classes
48
+ cookiePrefix: 'hashgrid'// prefix for the cookie name
49
+ };
50
+ var overlayOn = false,
51
+ sticky = false,
52
+ overlayZState = 'B',
53
+ overlayZBackground = -1,
54
+ overlayZForeground = 9999,
55
+ classNumber = 1;
56
+
57
+ // Apply options
58
+ if (typeof set == 'object') {
59
+ var k;
60
+ for (k in set) options[k] = set[k];
61
+ }
62
+ else if (typeof set == 'string') {
63
+ options.id = set;
64
+ }
65
+
66
+ // Remove any conflicting overlay
67
+ if ($('#' + options.id).length > 0) {
68
+ $('#' + options.id).remove();
69
+ }
70
+
71
+ // Create overlay, hidden before adding to DOM
72
+ var overlayEl = $('<div></div>');
73
+ overlayEl
74
+ .attr('id', options.id)
75
+ .css({
76
+ display: 'none',
77
+ 'pointer-events': 'none'
78
+ });
79
+ $("body").prepend(overlayEl);
80
+ var overlay = $('#' + options.id);
81
+
82
+ // Unless a custom z-index is set, ensure the overlay will be behind everything
83
+ if (overlay.css('z-index') == 'auto') overlay.css('z-index', overlayZBackground);
84
+
85
+ // Override the default overlay height with the actual page height
86
+ var pageHeight = parseFloat($(document).height());
87
+ overlay.height(pageHeight);
88
+
89
+ // Add the first grid line so that we can measure it
90
+ overlay.append('<div id="' + options.id + '-horiz" class="horiz first-line">');
91
+
92
+ // Position off-screen and display to calculate height
93
+ var top = overlay.css("top");
94
+ overlay.css({
95
+ top: "-999px",
96
+ display: "block"
97
+ });
98
+
99
+ // Calculate the number of grid lines needed
100
+ var line = $('#' + options.id + '-horiz'),
101
+ lineHeight = line.outerHeight();
102
+
103
+ // Hide and reset top
104
+ overlay.css({
105
+ display: "none",
106
+ top: top
107
+ });
108
+
109
+ // Break on zero line height
110
+ if (lineHeight <= 0) return true;
111
+
112
+ // Add the remaining grid lines
113
+ var i, numGridLines = Math.floor(pageHeight / lineHeight);
114
+ for (i = numGridLines - 1; i >= 1; i--) {
115
+ overlay.append('<div class="horiz"></div>');
116
+ }
117
+
118
+ // vertical grid
119
+ overlay.append($('<div class="vert-container"></div>'));
120
+ var overlayVert = overlay.children('.vert-container');
121
+ var gridWidth = overlay.width();
122
+ overlayVert.css({width: gridWidth, position: 'absolute', top: 0});
123
+ overlayVert.append('<div class="vert first-line">&nbsp;</div>');
124
+
125
+ // 30 is an arbitrarily large number...
126
+ // can't calculate the margin width properly
127
+ for (i = 0; i < 30; i++) {
128
+ overlayVert.append('<div class="vert">&nbsp;</div>');
129
+ }
130
+
131
+ overlayVert.children()
132
+ .height(pageHeight)
133
+ .css({display: 'inline-block'});
134
+
135
+ // Check for saved state
136
+ var overlayCookie = readCookie(options.cookiePrefix + options.id);
137
+ if (typeof overlayCookie == 'string') {
138
+ var state = overlayCookie.split(',');
139
+ state[2] = Number(state[2]);
140
+ if ((typeof state[2] == 'number') && !isNaN(state[2])) {
141
+ classNumber = state[2].toFixed(0);
142
+ overlay.addClass(options.classPrefix + classNumber);
143
+ }
144
+ if (state[1] == 'F') {
145
+ overlayZState = 'F';
146
+ overlay.css('z-index', overlayZForeground);
147
+ }
148
+ if (state[0] == '1') {
149
+ overlayOn = true;
150
+ sticky = true;
151
+ showOverlay();
152
+ }
153
+ }
154
+ else {
155
+ overlay.addClass(options.classPrefix + classNumber);
156
+ }
157
+
158
+ // Keyboard controls
159
+ $(document).bind('keydown', keydownHandler);
160
+ $(document).bind('keyup', keyupHandler);
161
+
162
+ /**
163
+ * Helpers
164
+ */
165
+
166
+ function getModifier(e) {
167
+ if (options.modifierKey == null) return true; // Bypass by default
168
+ var m = true;
169
+ switch(options.modifierKey) {
170
+ case 'ctrl':
171
+ m = (e.ctrlKey ? e.ctrlKey : false);
172
+ break;
173
+
174
+ case 'alt':
175
+ m = (e.altKey ? e.altKey : false);
176
+ break;
177
+
178
+ case 'shift':
179
+ m = (e.shiftKey ? e.shiftKey : false);
180
+ break;
181
+ }
182
+ return m;
183
+ }
184
+
185
+ function getKey(e) {
186
+ var k = false, c = (e.keyCode ? e.keyCode : e.which);
187
+ // Handle keywords
188
+ if (c == 13) k = 'enter';
189
+ // Handle letters
190
+ else k = String.fromCharCode(c).toLowerCase();
191
+ return k;
192
+ }
193
+
194
+ function saveState() {
195
+ createCookie(options.cookiePrefix + options.id, (sticky ? '1' : '0') + ',' + overlayZState + ',' + classNumber, 1);
196
+ }
197
+
198
+ function showOverlay() {
199
+ overlay.show();
200
+ overlayVert.css({width: overlay.width()});
201
+ // hide any vertical blocks that aren't at the top of the viewport
202
+ overlayVert.children('.vert').each(function () {
203
+ $(this).css('display','inline-block');
204
+ if ($(this).offset().top > 0) {
205
+ $(this).hide();
206
+ }
207
+ });
208
+ }
209
+
210
+ /**
211
+ * Event handlers
212
+ */
213
+
214
+ function keydownHandler(e) {
215
+ var source = e.target.tagName.toLowerCase();
216
+ if ((source == 'input') || (source == 'textarea') || (source == 'select')) return true;
217
+ var m = getModifier(e);
218
+ if (!m) return true;
219
+ var k = getKey(e);
220
+ if (!k) return true;
221
+ switch(k) {
222
+ case options.showGridKey:
223
+ if (!overlayOn) {
224
+ showOverlay();
225
+ overlayOn = true;
226
+ }
227
+ else if (sticky) {
228
+ overlay.hide();
229
+ overlayOn = false;
230
+ sticky = false;
231
+ saveState();
232
+ }
233
+ break;
234
+ case options.holdGridKey:
235
+ if (overlayOn && !sticky) {
236
+ // Turn sticky overlay on
237
+ sticky = true;
238
+ saveState();
239
+ }
240
+ break;
241
+ case options.foregroundKey:
242
+ if (overlayOn) {
243
+ // Toggle sticky overlay z-index
244
+ if (overlay.css('z-index') == overlayZForeground) {
245
+ overlay.css('z-index', overlayZBackground);
246
+ overlayZState = 'B';
247
+ }
248
+ else {
249
+ overlay.css('z-index', overlayZForeground);
250
+ overlayZState = 'F';
251
+ }
252
+ saveState();
253
+ }
254
+ break;
255
+ case options.jumpGridsKey:
256
+ if (overlayOn && (options.numberOfGrids > 1)) {
257
+ // Cycle through the available grids
258
+ overlay.removeClass(options.classPrefix + classNumber);
259
+ classNumber++;
260
+ if (classNumber > options.numberOfGrids) classNumber = 1;
261
+ overlay.addClass(options.classPrefix + classNumber);
262
+ showOverlay();
263
+ if (/webkit/.test( navigator.userAgent.toLowerCase() )) {
264
+ forceRepaint();
265
+ }
266
+ saveState();
267
+ }
268
+ break;
269
+ }
270
+ }
271
+
272
+ function keyupHandler(e) {
273
+ var m = getModifier(e);
274
+ if (!m) return true;
275
+ var k = getKey(e);
276
+ if (!k) return true;
277
+ if ((k == options.showGridKey) && !sticky) {
278
+ overlay.hide();
279
+ overlayOn = false;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Cookie functions
285
+ *
286
+ * By Peter-Paul Koch:
287
+ * http://www.quirksmode.org/js/cookies.html
288
+ */
289
+ function createCookie(name,value,days) {
290
+ if (days) {
291
+ var date = new Date();
292
+ date.setTime(date.getTime()+(days*24*60*60*1000));
293
+ var expires = "; expires="+date.toGMTString();
294
+ }
295
+ else var expires = "";
296
+ document.cookie = name+"="+value+expires+"; path=/";
297
+ }
298
+
299
+ function readCookie(name) {
300
+ var nameEQ = name + "=";
301
+ var ca = document.cookie.split(';');
302
+ for(var i=0;i < ca.length;i++) {
303
+ var c = ca[i];
304
+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
305
+ if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
306
+ }
307
+ return null;
308
+ }
309
+
310
+ function eraseCookie(name) {
311
+ createCookie(name,"",-1);
312
+ }
313
+
314
+ /**
315
+ * Forces a repaint (because WebKit has issues)
316
+ * http://www.sitepoint.com/forums/showthread.php?p=4538763
317
+ * http://www.phpied.com/the-new-game-show-will-it-reflow/
318
+ */
319
+ function forceRepaint() {
320
+ var ss = document.styleSheets[0];
321
+ try {
322
+ ss.addRule('.xxxxxx', 'position: relative');
323
+ ss.removeRule(ss.rules.length - 1);
324
+ } catch(e){}
325
+ }
326
+
327
+ }
328
+
329
+
330
+ /**
331
+ * You can call hashgrid from your own code, but it's loaded here as
332
+ * an example for your convenience.
333
+ */
334
+ $(document).ready(function() {
335
+
336
+ var grid = new hashgrid({
337
+ numberOfGrids: 2
338
+ });
339
+
340
+ });
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Grid
3
+ */
4
+ #grid{
5
+
6
+ /* Dimensions - same width as your grid with gutters */
7
+ width: 980px;
8
+
9
+ /* Grid (left-aligned)
10
+ position: absolute;
11
+ top: 0;
12
+ left: 0;
13
+ */
14
+
15
+ /* Grid (centered) */
16
+ position: absolute;
17
+ top: 0;
18
+ left: 50%;
19
+ margin-left: -490px;
20
+
21
+ }
22
+
23
+ /**
24
+ * Vertical grid lines
25
+ *
26
+ * Set the column width taking the borders into consideration,
27
+ * and use margins to set column gutters.
28
+ */
29
+ #grid div.vert{
30
+
31
+ width: 139px;
32
+ border: solid darkturquoise;
33
+ border-width: 0 1px;
34
+ margin-right: 19px;
35
+
36
+ }
37
+
38
+ #grid div.vert.first-line{
39
+
40
+ margin-left: 19px;
41
+
42
+ }
43
+
44
+
45
+ /**
46
+ * Horizontal grid lines, defined by your base line height
47
+ *
48
+ * Remember, the CSS properties that define the box model:
49
+ * visible height = height + borders + margins + padding
50
+ */
51
+ #grid div.horiz{
52
+
53
+ /* 20px line height */
54
+ height: 19px;
55
+ border-bottom: 1px dotted darkgray;
56
+ margin: 0;
57
+ padding: 0;
58
+
59
+ }
60
+
61
+ /**
62
+ * Classes for multiple grids
63
+ *
64
+ * When using more than one grid, remember to set the numberOfGrids
65
+ * option in the hashgrid.js file.
66
+ */
67
+ #grid.grid-1 div.vert{
68
+
69
+ /* Vertical grid line colour for grid 1 */
70
+ border-color: darkturquoise;
71
+
72
+ }
73
+ #grid.grid-2{
74
+
75
+ /* Adjustments */
76
+ padding: 0 160px;
77
+ width: 660px;
78
+
79
+ }
80
+ #grid.grid-2 div.vert{
81
+
82
+ /* Vertical grid line colour for grid 2 */
83
+ border-color: crimson;
84
+
85
+ }
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hashgrid
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Lucas Willett
14
+ - Odin Dutton
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-04-21 00:00:00 +10:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: rack
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 29
31
+ segments:
32
+ - 1
33
+ - 2
34
+ - 1
35
+ version: 1.2.1
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rails
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ hash: 7
47
+ segments:
48
+ - 3
49
+ - 0
50
+ - 0
51
+ version: 3.0.0
52
+ type: :runtime
53
+ version_requirements: *id002
54
+ description: A simple Rails wrapper for hashgrid.
55
+ email:
56
+ - lucas@developingego.com
57
+ - odindutton@gmail.com
58
+ executables: []
59
+
60
+ extensions: []
61
+
62
+ extra_rdoc_files: []
63
+
64
+ files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - README.md
68
+ - Rakefile
69
+ - app/views/shared/_hashgrid.html.erb
70
+ - hashgrid.gemspec
71
+ - lib/hashgrid.rb
72
+ - lib/hashgrid/helpers.rb
73
+ - lib/hashgrid/railtie.rb
74
+ - lib/hashgrid/version.rb
75
+ - public/javascripts/hashgrid/hashgrid.js
76
+ - public/stylesheets/hashgrid/hashgrid.css
77
+ has_rdoc: true
78
+ homepage: http://github.com/twe4ked/hashgrid
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options: []
83
+
84
+ require_paths:
85
+ - lib
86
+ - public
87
+ - app
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 23
103
+ segments:
104
+ - 1
105
+ - 3
106
+ - 6
107
+ version: 1.3.6
108
+ requirements: []
109
+
110
+ rubyforge_project:
111
+ rubygems_version: 1.3.7
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: A simple Rails wrapper for hashgrid.
115
+ test_files: []
116
+