help-anywhere 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +15 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +46 -0
  4. data/Rakefile +38 -0
  5. data/app/assets/javascripts/help_anywhere/components/bubble.js.coffee +367 -0
  6. data/app/assets/javascripts/help_anywhere/components/component.js.coffee +10 -0
  7. data/app/assets/javascripts/help_anywhere/help_anywhere.js.coffee +254 -0
  8. data/app/assets/javascripts/help_anywhere/help_anywhere_editor.js.coffee +41 -0
  9. data/app/assets/javascripts/help_anywhere/hooks.js.coffee +28 -0
  10. data/app/assets/javascripts/help_anywhere.js.coffee +2 -0
  11. data/app/assets/javascripts/help_anywhere_core_only.js.coffee +11 -0
  12. data/app/assets/stylesheets/generators/bubble.css.scss +195 -0
  13. data/app/assets/stylesheets/help_anywhere.css.scss +4 -0
  14. data/app/assets/stylesheets/help_anywhere_core_only.css.scss +181 -0
  15. data/app/controllers/help_anywhere/base_controller.rb +10 -0
  16. data/app/controllers/help_anywhere/help_anywhere_controller.rb +5 -0
  17. data/app/controllers/help_anywhere/pages_controller.rb +30 -0
  18. data/app/controllers/help_anywhere/resources_controller.rb +84 -0
  19. data/app/helpers/help_anywhere_helper.rb +5 -0
  20. data/app/models/help_anywhere/item.rb +6 -0
  21. data/app/models/help_anywhere/page.rb +34 -0
  22. data/app/models/help_anywhere/resource.rb +14 -0
  23. data/app/models/help_anywhere.rb +2 -0
  24. data/config/routes.rb +11 -0
  25. data/db/migrate/20130825093318_create_help_anywhere_resources.rb +9 -0
  26. data/db/migrate/20130825093414_create_help_anywhere_pages.rb +11 -0
  27. data/db/migrate/20130825093611_create_help_anywhere_items.rb +19 -0
  28. data/db/migrate/20130927171847_refactor_help_anywhere_items.rb +11 -0
  29. data/lib/help-anywhere/configuration.rb +75 -0
  30. data/lib/help-anywhere/engine.rb +10 -0
  31. data/lib/help-anywhere/version.rb +3 -0
  32. data/lib/help-anywhere.rb +9 -0
  33. data/lib/tasks/help-anywhere_tasks.rake +4 -0
  34. data/test/dummy/README.rdoc +261 -0
  35. data/test/dummy/Rakefile +7 -0
  36. data/test/dummy/app/assets/javascripts/application.js +15 -0
  37. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  38. data/test/dummy/app/controllers/application_controller.rb +3 -0
  39. data/test/dummy/app/helpers/application_helper.rb +2 -0
  40. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  41. data/test/dummy/config/application.rb +59 -0
  42. data/test/dummy/config/boot.rb +10 -0
  43. data/test/dummy/config/database.yml +25 -0
  44. data/test/dummy/config/environment.rb +5 -0
  45. data/test/dummy/config/environments/development.rb +37 -0
  46. data/test/dummy/config/environments/production.rb +67 -0
  47. data/test/dummy/config/environments/test.rb +37 -0
  48. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/test/dummy/config/initializers/inflections.rb +15 -0
  50. data/test/dummy/config/initializers/mime_types.rb +5 -0
  51. data/test/dummy/config/initializers/secret_token.rb +7 -0
  52. data/test/dummy/config/initializers/session_store.rb +8 -0
  53. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  54. data/test/dummy/config/locales/en.yml +5 -0
  55. data/test/dummy/config/routes.rb +58 -0
  56. data/test/dummy/config.ru +4 -0
  57. data/test/dummy/public/404.html +26 -0
  58. data/test/dummy/public/422.html +26 -0
  59. data/test/dummy/public/500.html +25 -0
  60. data/test/dummy/public/favicon.ico +0 -0
  61. data/test/dummy/script/rails +6 -0
  62. data/test/help-anywhere_test.rb +7 -0
  63. data/test/test_helper.rb +15 -0
  64. metadata +165 -0
@@ -0,0 +1,181 @@
1
+ #help-anywhere-widget {
2
+ position: fixed;
3
+ display: block;
4
+
5
+ width: auto;
6
+ padding-left: 3px;
7
+ padding-right: 3px;
8
+ height: 20px;
9
+ border-left: solid 2px white;
10
+ border-bottom: solid 2px white;
11
+ border-right: solid 2px white;
12
+
13
+ background: #333;
14
+ top: 0;
15
+ left: 75%;
16
+ border-bottom-left-radius: 50%;
17
+ border-bottom-right-radius: 50%;
18
+
19
+ font-family: Helvetica, Arial, sans-serif;
20
+ cursor: pointer;
21
+
22
+ color: white;
23
+ box-shadow: 1px 1px 5px black;
24
+ font-size: 12px;
25
+ text-align: center;
26
+
27
+ &:hover {
28
+ border-color: yellow;
29
+ color: yellow;
30
+ }
31
+ }
32
+
33
+ #help-anywhere-layout {
34
+ font-family: 'Helvetica', 'Arial', sans-serif;
35
+ position: absolute;
36
+ min-width: 100%;
37
+ min-height: 100%;
38
+ left: 0;
39
+ top: 0;
40
+ background-color: rgba(0,0,0,0.5);
41
+ z-index: 10001;
42
+
43
+ .ha-new-component {
44
+ color: white;
45
+ }
46
+
47
+ .ha-toolbox {
48
+ position: absolute;
49
+ top: 0;
50
+ right: 0;
51
+ height: 100%;
52
+ width: 200px;
53
+ background-color: #333;
54
+ }
55
+
56
+ .ha-edit-bottom-layout {
57
+ position: absolute;
58
+ bottom: 0;
59
+ left: 0;
60
+ background-color: #333;
61
+ width: 100%;
62
+ opacity: 0.6;
63
+
64
+ transition: opacity ease-in-out 0.3s;
65
+ -moz-transition: opacity ease-in-out 0.3s;
66
+ -o-transition: opacity ease-in-out 0.3s;
67
+ -webkit-transition: opacity ease-in-out 0.3s;
68
+ -ms-transition: opacity ease-in-out 0.3s;
69
+
70
+ &:hover {
71
+ opacity: 1;
72
+ }
73
+
74
+ .ha-page-list {
75
+ .ha-page-list-container {
76
+ width: 100%;
77
+ overflow-x: auto;
78
+ }
79
+
80
+ .ha-new-page {
81
+ cursor: pointer;
82
+
83
+ display: inline-block;
84
+ padding: 20px;
85
+
86
+ height: 20px;
87
+ width: 60px;
88
+
89
+ background-color: white;
90
+ text-align: center;
91
+ font-weight: bold;
92
+ }
93
+
94
+ .ha-page {
95
+ cursor: pointer;
96
+
97
+ display: inline-block;
98
+ padding: 20px;
99
+
100
+ height: 20px;
101
+ width: 60px;
102
+
103
+ background-color: white;
104
+ text-align: center;
105
+ font-weight: bold;
106
+
107
+ border-right: solid 2px #333;
108
+
109
+ &.selected {
110
+ box-shadow: inset 0px 0px 0px 5px red;
111
+ }
112
+
113
+ &:hover {
114
+ box-shadow: inset 0px 0px 0px 5px orange;
115
+ }
116
+
117
+ &:first-child {
118
+ border-left: none;
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ .ha-bubble-target-selected {
126
+ border: solid 3px orange;
127
+ box-sizing: border-box;
128
+ display: 'block';
129
+ position: absolute;
130
+ }
131
+
132
+
133
+
134
+ .ha-hover {
135
+ box-shadow: inset 0px 0px 1px 1px red, inset 0px 0px 2px 2px white !important;
136
+ }
137
+
138
+ #help-anywhere-selectbox {
139
+ position: absolute;
140
+ border-radius: 5px;
141
+ background-color: #EEE;
142
+ border: solid 1px #BBB;
143
+ box-shadow: 4px 4px 8px #999;
144
+
145
+ font-family: Helvetica, Arial, sans-serif;
146
+
147
+ ul {
148
+ list-style: none;
149
+ margin: 0;
150
+
151
+ padding: 5px 0px;
152
+
153
+ li {
154
+ min-width: 64px;
155
+ padding: 0;
156
+ color: #333;
157
+ font-size: 70%;
158
+ padding: 0px 5px;
159
+ cursor: pointer;
160
+
161
+ font-weight: bold;
162
+
163
+ border-top: solid 1px transparent;
164
+ border-bottom: solid 1px transparent;
165
+
166
+ &:hover {
167
+ color: white;
168
+ background-color: lighten(#36D, 10%);
169
+
170
+ border-bottom-color: lighten(#36D, 5%);
171
+ border-top-color: lighten(#36D, 15%);
172
+ }
173
+
174
+ a {
175
+ display: block;
176
+ color: white;
177
+ text-decoration: none;
178
+ }
179
+ }
180
+ }
181
+ }
@@ -0,0 +1,10 @@
1
+ class HelpAnywhere::BaseController < ApplicationController
2
+ before_filter :check_authentication, :only => [:edit, :create, :new, :delete, :save]
3
+
4
+ private
5
+ def check_authentication
6
+ unless HelpAnywhere.config.has_edition_role? self
7
+ raise "You are not authorized to edit help"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class HelpAnywhere::HelpAnywhereController < HelpAnywhere::BaseController
2
+ def routes
3
+ render :json => HelpAnywhere.config.routes
4
+ end
5
+ end
@@ -0,0 +1,30 @@
1
+ class HelpAnywhere::PagesController < HelpAnywhere::BaseController
2
+ def create
3
+ page = HelpAnywhere::Page.new
4
+ page.resource = HelpAnywhere::Resource.find_by_id params[:resource_id]
5
+
6
+ if page.save
7
+ render :json => {
8
+ :id => page.id,
9
+ :order => page.number
10
+ }
11
+ else
12
+ render :json => { :status => "BAD", :errors => page.errors }
13
+ end
14
+ end
15
+
16
+ def show
17
+ page = HelpAnywhere::Page.find_by_id params[:page_id]
18
+
19
+ if resource.nil?
20
+ render :json => nil
21
+ else
22
+ render :json => {
23
+ :id => page.id,
24
+ :order => page.number,
25
+ :items => page.items
26
+ }
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,84 @@
1
+ class HelpAnywhere::ResourcesController < HelpAnywhere::BaseController
2
+ def show
3
+ resource = HelpAnywhere::Resource.find_by_name params[:name]
4
+
5
+ if resource.nil?
6
+ render :json => {
7
+ :pages => []
8
+ }
9
+ else
10
+ render :json => {
11
+ :pages => resource.pages.order('number ASC').map{ |x|
12
+ {
13
+ :order => x.number,
14
+ :items => x.items.map{ |x|
15
+ { :id => x.id, :class_id => x.class_id, :content => JSON.parse(x.content || '{}') }
16
+ }
17
+ }
18
+ }
19
+ }
20
+ end
21
+ end
22
+
23
+ def save
24
+ resource = HelpAnywhere::Resource.find_by_name params[:name]
25
+
26
+ if resource.nil?
27
+ render :text => "Resource not found", :status => 500
28
+ end
29
+
30
+ page_list = JSON.parse(params[:content])
31
+
32
+ resource.transaction do
33
+ resource.pages.each do |page_to_remove|
34
+ page_to_remove.destroy
35
+ end
36
+
37
+ page_list.each do |page|
38
+ page = page.with_indifferent_access
39
+ page_model = HelpAnywhere::Page.new
40
+ page_model.resource = resource
41
+ page_model.save!
42
+
43
+ page[:items].each do |item|
44
+ it = HelpAnywhere::Item.new
45
+
46
+ it.class_id = item[:class_id]
47
+ it.content = item[:content].to_json
48
+ it.page = page_model
49
+
50
+ it.save!
51
+ end
52
+
53
+ page_model.save!
54
+ end
55
+ end
56
+
57
+ render :json => {status: 'OK'}
58
+ end
59
+
60
+ def create
61
+ resource = HelpAnywhere::Resource.new
62
+ resource.name = params[:name]
63
+
64
+ if resource.save
65
+ render :json => {
66
+ :pages => resource.pages.map{ |x|
67
+ {
68
+ :order => x.number,
69
+ :items => x.items
70
+ }
71
+ }
72
+ }
73
+ else
74
+ render :json => { :status => "BAD", :errors => resource.errors }
75
+ end
76
+
77
+ end
78
+
79
+ def delete
80
+ resource = HelpAnywhere::Resource.find params[:name]
81
+ resource.destroy!
82
+ end
83
+
84
+ end
@@ -0,0 +1,5 @@
1
+ module HelpAnywhereHelper
2
+ def can_edit_help?
3
+ HelpAnywhere.config.has_edition_role? self
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class HelpAnywhere::Item < ActiveRecord::Base
2
+ belongs_to :page, :class_name => HelpAnywhere::Page
3
+ attr_accessible :class_id, :content, :height, :target, :width, :x, :y
4
+
5
+ validates_presence_of :page_id, :class_id
6
+ end
@@ -0,0 +1,34 @@
1
+ class HelpAnywhere::Page < ActiveRecord::Base
2
+ belongs_to :resource, :class_name => HelpAnywhere::Resource
3
+ has_many :items, :class_name => HelpAnywhere::Item
4
+
5
+ validates_presence_of :resource_id
6
+
7
+ before_save :inc_page_number
8
+ before_destroy :move_page_number
9
+ before_destroy :destroy_items
10
+ private
11
+
12
+ def inc_page_number
13
+ if self.number.nil?
14
+ if self.resource.pages.count > 0
15
+ self.number = self.resource.pages.order('number ASC').select(:number).first.number + 1
16
+ else
17
+ self.number = 1
18
+ end
19
+ end
20
+ end
21
+
22
+ def move_page_number
23
+ unless self.number.nil?
24
+ self.resource.pages.where('number > ?', self.number).each do |page|
25
+ page.number = page.number - 1
26
+ page.save!
27
+ end
28
+ end
29
+ end
30
+
31
+ def destroy_items
32
+ self.items.each(&:destroy)
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ class HelpAnywhere::Resource < ActiveRecord::Base
2
+ attr_accessible :name
3
+ has_many :pages, :class_name => HelpAnywhere::Page
4
+
5
+ validates_presence_of :name
6
+ validates_uniqueness_of :name
7
+
8
+ before_destroy :destroy_pages
9
+
10
+ private
11
+ def destroy_pages
12
+ self.pages.each(&:destroy)
13
+ end
14
+ end
@@ -0,0 +1,2 @@
1
+ module HelpAnywhere
2
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,11 @@
1
+ Rails.application.routes.draw do
2
+ namespace :help_anywhere do
3
+ match "resources" => "resources#show"
4
+ match "resources/create" => "resources#create", :via => :get
5
+ match "resources/save" => "resources#save"
6
+
7
+ match "pages/:page_id" => "pages#show"
8
+
9
+ match "routes" => "help_anywhere#routes", :via => :get
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class CreateHelpAnywhereResources < ActiveRecord::Migration
2
+ def change
3
+ create_table :help_anywhere_resources do |t|
4
+ t.string :name
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class CreateHelpAnywherePages < ActiveRecord::Migration
2
+ def change
3
+ create_table :help_anywhere_pages do |t|
4
+ t.integer :number
5
+ t.references :resource
6
+
7
+ t.timestamps
8
+ end
9
+ add_index :help_anywhere_pages, :resource_id
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ class CreateHelpAnywhereItems < ActiveRecord::Migration
2
+ def change
3
+ create_table :help_anywhere_items do |t|
4
+ t.string :target
5
+ t.integer :x
6
+ t.integer :y
7
+ t.integer :width
8
+ t.integer :height
9
+ t.text :content
10
+ t.string :class_id
11
+
12
+ t.references :page
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :help_anywhere_items, :page_id
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ class RefactorHelpAnywhereItems < ActiveRecord::Migration
2
+ def change
3
+ remove_column :help_anywhere_items, :target
4
+ remove_column :help_anywhere_items, :x
5
+ remove_column :help_anywhere_items, :y
6
+ remove_column :help_anywhere_items, :width
7
+ remove_column :help_anywhere_items, :height
8
+ remove_column :help_anywhere_items, :content
9
+ add_column :help_anywhere_items, :content, :text
10
+ end
11
+ end
@@ -0,0 +1,75 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module HelpAnywhere
3
+ def self.configure(configuration=HelpAnywhere::Configuration.new)
4
+ yield configuration if block_given?
5
+ @@configuration = configuration
6
+ end
7
+
8
+ def self.config
9
+ @@configuration ||= HelpAnywhere::Configuration.new
10
+ end
11
+
12
+ class Configuration
13
+ attr_accessor :edition_role
14
+
15
+ def has_edition_role? scope
16
+ if edition_role.instance_of?(Proc)
17
+ edition_role.bind(scope).call
18
+ else
19
+ scope.send(edition_role.to_s.to_sym)
20
+ end
21
+ end
22
+
23
+ def routes
24
+ yield @routes if block_given?
25
+
26
+ @routes
27
+ end
28
+
29
+ def render_routes
30
+ @routes.to_javascript
31
+ end
32
+
33
+ def initialize
34
+ @routes = HelpAnywhere::Routes.new
35
+ @edition_role = lambda{ true } #per default, we need no authentication to edit help resources
36
+ end
37
+ end
38
+
39
+ class Routes
40
+ DEFAULTS_ROUTES = [['/', '_root'], ['??', '$1']]
41
+
42
+ attr_accessor :match_data, :ignore_data
43
+
44
+ def initialize
45
+ @match_data = []
46
+ @ignore_data = []
47
+ end
48
+
49
+ def match regexp, result
50
+ self.match_data << [ regexp, result ]
51
+ end
52
+
53
+ def ignore regexp
54
+ self.ignore_data << [ regexp, result ]
55
+ end
56
+
57
+ def to_json *args
58
+ arr = self.match_data + DEFAULTS_ROUTES
59
+
60
+ arr.to_json
61
+ end
62
+
63
+ def to_javascript
64
+ arr = self.match_data + DEFAULTS_ROUTES
65
+
66
+ output = "HelpAnywhere.add_routes(["
67
+ output += arr.map{ |x| "[/#{x[0].source}/, '#{x[1].sub('\'', '\\\'')}']" }.join(',')
68
+ output += "]);"
69
+
70
+ #output += "HelpAnywhere.ignore(["
71
+
72
+ output
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,10 @@
1
+ require "rails"
2
+
3
+ module HelpAnywhere
4
+ class Engine < Rails::Engine
5
+ engine_name :help_anywhere
6
+ #initializer "add assets to precompile" do |app|
7
+ #app.config.assets.precompile += %w( master/master.js master.css )
8
+ #end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module HelpAnywhere
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'help-anywhere/engine'
2
+ require 'help-anywhere/configuration'
3
+
4
+ module HelpAnywhere
5
+ #Table namespace
6
+ def self.table_name_prefix
7
+ 'help_anywhere_'
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :help-anywhere do
3
+ # # Task goes here
4
+ # end