familiarity 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +67 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/familiarity/application.js +16 -0
- data/app/assets/javascripts/familiarity/familiarity.js.erb +193 -0
- data/app/assets/javascripts/familiarity/familiarity_admin.js.erb +150 -0
- data/app/assets/javascripts/familiarity/jquery.cookie.js +117 -0
- data/app/assets/javascripts/familiarity/jquery.tooltipster.js +1282 -0
- data/app/assets/stylesheets/familiarity/application.css +17 -0
- data/app/assets/stylesheets/familiarity/familiarities.css +4 -0
- data/app/assets/stylesheets/familiarity/familiarity.css.scss +121 -0
- data/app/assets/stylesheets/familiarity/themes/tooltipster-light.css +12 -0
- data/app/assets/stylesheets/familiarity/themes/tooltipster-noir.css +12 -0
- data/app/assets/stylesheets/familiarity/themes/tooltipster-punk.css +12 -0
- data/app/assets/stylesheets/familiarity/themes/tooltipster-shadow.css +12 -0
- data/app/assets/stylesheets/familiarity/tooltipster.css +274 -0
- data/app/controllers/familiarity/application_controller.rb +4 -0
- data/app/controllers/familiarity/familiarities_controller.rb +22 -0
- data/app/helpers/familiarity/application_helper.rb +32 -0
- data/app/helpers/familiarity/familiarities_helper.rb +4 -0
- data/app/views/familiarity/familiarities/index.json.erb +1 -0
- data/app/views/layouts/familiarity/application.html.erb +14 -0
- data/config/routes.rb +7 -0
- data/lib/familiarity/engine.rb +17 -0
- data/lib/familiarity/version.rb +3 -0
- data/lib/familiarity.rb +4 -0
- data/lib/tasks/familiarity_tasks.rake +4 -0
- data/test/controllers/familiarity/familiarities_controller_test.rb +9 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +78 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/assets.rb +8 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/familiarity_test.rb +7 -0
- data/test/helpers/familiarity/familiarities_helper_test.rb +6 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- metadata +176 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2dd519d51c98acb014642d12b06e4de9a6f82a1b
|
4
|
+
data.tar.gz: 0584a4efa27e079b51ab5e2e1dddd7b7187f872f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 404901d952f72cb7af44f93413df82792c1c00226e3560bf4553514994f14c1f02f5f8d0d4006f6f14d7fe8b12c2a3c4ad1944a63983f1e4a1835d08630c99f3
|
7
|
+
data.tar.gz: 55ac357617105be747e9e0f4e708bfdc4bf24136b89360ff0d4ed8ab260aee3e43c82a96fe1364deba99415c9cd723d079e7bd597cbc3ef52fb9a03ec1c42b7f
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
= \Familiarity
|
2
|
+
|
3
|
+
This gem packages a rails engine which provides an interactive demo of features/entities on any given page.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'familiarity', :git => 'git@github.com:praveenkumarsinha/familiarity.git'
|
10
|
+
|
11
|
+
Then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Mount Familiarity at specific location (from routes.rb of application):
|
16
|
+
|
17
|
+
mount Familiarity::Engine, at: "/some_specific_location"
|
18
|
+
|
19
|
+
Add javascript(s) in application manifest (most probably from app/assets/javascripts/application.js):
|
20
|
+
|
21
|
+
//= require familiarity/application
|
22
|
+
|
23
|
+
Add stylesheet(s) in application manifest (most probably from app/assets/stylesheets/application.css):
|
24
|
+
|
25
|
+
*= require familiarity/application
|
26
|
+
|
27
|
+
Add familiarity's switch-board on all the pages (append following helper at the end as body content in layout):
|
28
|
+
|
29
|
+
<%= familiaritySwitchBoard %>
|
30
|
+
|
31
|
+
Add familiarity's view on all the pages (append following helper at the end as body content in layout):
|
32
|
+
|
33
|
+
<%= familiarityView %>
|
34
|
+
|
35
|
+
== Helpers
|
36
|
+
|
37
|
+
To provide a switch board where an user (or may be a bunch of users in any specific environment of application) want to add/edit/update or delete annotations on any page .
|
38
|
+
|
39
|
+
<%= familiaritySwitchBoard %>
|
40
|
+
|
41
|
+
|
42
|
+
To provide annotations view of elements, one element at a time on the first visit of page.
|
43
|
+
|
44
|
+
<%= familiarityView %>
|
45
|
+
<%= familiarityView({
|
46
|
+
escape_to_exit: true, #Exits on ESC key press.
|
47
|
+
f1_to_start: true, #Starts on F1 key press.
|
48
|
+
show_tips_recursively: false, #To restart annotations display after complete traverse of available annotations.
|
49
|
+
mandatory_all_tips: true, #To show all tips(annotations) at least once (before enabling ESC key for exit).
|
50
|
+
traverse_back: true, #By default 'LEFT' arrow key is available to visit back but which can be disabled with a 'false' here.
|
51
|
+
remember_duration: 30 #Duration(in days) in which application need to show familiarity view irrespective whether user has viewed them or not.
|
52
|
+
}) %>
|
53
|
+
|
54
|
+
|
55
|
+
== Dependencies used
|
56
|
+
|
57
|
+
1. https://github.com/carhartl/jquery-cookie
|
58
|
+
2. http://iamceege.github.io/tooltipster/
|
59
|
+
|
60
|
+
|
61
|
+
== Contributing
|
62
|
+
|
63
|
+
1. Fork it ( https://github.com/praveenkumarsinha/familiarity/fork )
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Familiarity'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
task default: :test
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require ../familiarity/jquery.cookie
|
14
|
+
//= require ../familiarity/jquery.tooltipster
|
15
|
+
//= require_tree .
|
16
|
+
|
@@ -0,0 +1,193 @@
|
|
1
|
+
var Familiarity = function (options) {
|
2
|
+
this.escape_to_exit = options.escape_to_exit;
|
3
|
+
this.f1_to_start = options.f1_to_start;
|
4
|
+
this.show_tips_recursively = options.show_tips_recursively;
|
5
|
+
this.mandatory_all_tips = options.mandatory_all_tips;
|
6
|
+
this.traverse_back = options.traverse_back;
|
7
|
+
|
8
|
+
this.familiaritiesUrl = '<%= Familiarity::Engine.routes.url_helpers.familiarities_path(format: :json) %>';
|
9
|
+
// To retain the flag even after reset() method familiarityAllTipsVisited flag is defined here.
|
10
|
+
this.familiarityAllTipsVisited = false;
|
11
|
+
this.reset();
|
12
|
+
Familiarity.setCurrentObject(this);
|
13
|
+
}
|
14
|
+
Familiarity.setCurrentObject = function (current_object) {
|
15
|
+
return (this.currentObject = current_object);
|
16
|
+
}
|
17
|
+
Familiarity.getCurrentObject = function () {
|
18
|
+
return this.currentObject
|
19
|
+
}
|
20
|
+
Familiarity.prototype = {
|
21
|
+
reset: function () {
|
22
|
+
// this.familiarityAllTipsVisited = false;
|
23
|
+
this.familiarityRenderedFlag = false;
|
24
|
+
this.familiarity_hash_pointer = -1;
|
25
|
+
this.familiarity_hash = {};
|
26
|
+
this.familiarity_bubbles = [];
|
27
|
+
},
|
28
|
+
familiarity_hash_keys: function () {
|
29
|
+
return ($.map(this.familiarity_hash, function (v, k) {
|
30
|
+
return k;
|
31
|
+
}));
|
32
|
+
},
|
33
|
+
showNextBubble: function () {
|
34
|
+
if (this.familiarity_hash_keys().length <= 0) {
|
35
|
+
return false;
|
36
|
+
}
|
37
|
+
this.familiarity_hash_pointer++;
|
38
|
+
if ((this.familiarity_hash_pointer + 1) > this.familiarity_hash_keys().length) {
|
39
|
+
this.familiarityAllTipsVisited = true
|
40
|
+
if (this.show_tips_recursively) {
|
41
|
+
this.familiarity_hash_pointer = 0;
|
42
|
+
} else {
|
43
|
+
this.familiarityView(false);
|
44
|
+
return true;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
this.showOneByOne();
|
48
|
+
},
|
49
|
+
showPreviousBubble: function () {
|
50
|
+
if (this.familiarity_hash_keys().length <= 0) {
|
51
|
+
return false;
|
52
|
+
}
|
53
|
+
if (!this.traverse_back) {
|
54
|
+
return false;
|
55
|
+
}
|
56
|
+
this.familiarity_hash_pointer--;
|
57
|
+
if (this.familiarity_hash_pointer < 0) {
|
58
|
+
if (this.show_tips_recursively) {
|
59
|
+
this.familiarity_hash_pointer = this.familiarity_hash_keys().length - 1;
|
60
|
+
} else {
|
61
|
+
this.familiarity_hash_pointer = 0;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
this.showOneByOne();
|
65
|
+
},
|
66
|
+
showOneByOne: function () {
|
67
|
+
// console.log(this.familiarity_hash_pointer);
|
68
|
+
// console.log(this.familiarity_hash);
|
69
|
+
// console.log(this.familiarity_bubbles);
|
70
|
+
this.hideFBubbles();
|
71
|
+
return this.showFBubble();
|
72
|
+
},
|
73
|
+
showFBubble: function () {
|
74
|
+
var current_bubble_key = this.familiarity_hash_keys()[this.familiarity_hash_pointer];
|
75
|
+
var element = $(current_bubble_key)
|
76
|
+
var content = this.familiarity_hash[current_bubble_key];
|
77
|
+
|
78
|
+
if (element.length <= 0) {
|
79
|
+
return false;
|
80
|
+
}
|
81
|
+
|
82
|
+
element.addClass('familiarity-bubble-parent')
|
83
|
+
.tooltipster({
|
84
|
+
content: $('<span><strong>' + content.replace(/\n/g, "<br/>") + '</strong></span>'),
|
85
|
+
maxWidth: 400,
|
86
|
+
animation: 'grow', //fade, grow, swing, slide, fall
|
87
|
+
autoClose: true, //true, false
|
88
|
+
position: 'bottom-right', //right, left, top, top-right, top-left, bottom, bottom-right, bottom-left
|
89
|
+
delay: 700,
|
90
|
+
speed: 700,
|
91
|
+
theme: 'tooltipster-default',
|
92
|
+
touchDevices: false,
|
93
|
+
trigger: 'custom' //hover, click, custom
|
94
|
+
});
|
95
|
+
element.tooltipster('show');
|
96
|
+
// console.log(element.css('background-color'));
|
97
|
+
// if (element.css('background-color') == 'transparent') {
|
98
|
+
// element.css('background-color', 'white')
|
99
|
+
// }
|
100
|
+
this.familiarity_bubbles.push(element)
|
101
|
+
return true;
|
102
|
+
},
|
103
|
+
hideFBubbles: function () {
|
104
|
+
while (this.familiarity_bubbles.length > 0) {
|
105
|
+
this.familiarity_bubbles.pop().tooltipster('destroy').removeClass('familiarity-bubble-parent').attr('title', null);
|
106
|
+
}
|
107
|
+
},
|
108
|
+
fetchFamiliarities: function (callback) {
|
109
|
+
if (typeof(callback) != 'function') {
|
110
|
+
callback = function (familiarity_hash) {
|
111
|
+
console.log('familiarity_hash');
|
112
|
+
console.log(familiarity_hash);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
var _this = this;
|
116
|
+
$.get(this.familiaritiesUrl, function (data) {
|
117
|
+
var familiarity_hash = data[$(location).attr('pathname')]
|
118
|
+
if (familiarity_hash == null) {
|
119
|
+
familiarity_hash = {}
|
120
|
+
}
|
121
|
+
_this.familiarity_hash = familiarity_hash;
|
122
|
+
callback(familiarity_hash);
|
123
|
+
});
|
124
|
+
},
|
125
|
+
familiarityView: function (enable) {
|
126
|
+
var _this = this;
|
127
|
+
if (typeof(enable) == 'undefined') {
|
128
|
+
enable = true;
|
129
|
+
}
|
130
|
+
if (enable == true) {
|
131
|
+
//Re-setting all values and variables (in case is there any half done state)
|
132
|
+
this.reset();
|
133
|
+
|
134
|
+
//Making bubble pop-out //////////////////
|
135
|
+
this.fetchFamiliarities(function (familiarity_hash) {
|
136
|
+
if (_this.familiarity_hash_keys().length > 0) {
|
137
|
+
//Rendering overlay
|
138
|
+
$('body').addClass('familiarity-view').append($('<div id="familiarity_dim"></div>'));
|
139
|
+
|
140
|
+
//Rendering first bubble (via Next Bubble)
|
141
|
+
_this.showNextBubble();
|
142
|
+
|
143
|
+
//Marking flag that familiarity_view is rendered
|
144
|
+
_this.familiarityRenderedFlag = true;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
);
|
148
|
+
|
149
|
+
} else {
|
150
|
+
|
151
|
+
// If option 'mandatory_all_tips' is true then make sure all tips has been rendered
|
152
|
+
// before exit of familiarity view
|
153
|
+
if (this.mandatory_all_tips && (!this.familiarityAllTipsVisited)) {
|
154
|
+
return false;
|
155
|
+
}
|
156
|
+
|
157
|
+
//Removing bubbles
|
158
|
+
_this.hideFBubbles();
|
159
|
+
|
160
|
+
//Removing rendered overlay
|
161
|
+
$('#familiarity_dim').remove();
|
162
|
+
$('body').removeClass('familiarity-view');
|
163
|
+
|
164
|
+
//Marking flag that familiarity_view is removed from viewport
|
165
|
+
this.familiarityRenderedFlag = false;
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
}
|
170
|
+
|
171
|
+
$(document).on("page:change", function () {
|
172
|
+
// Show and hide on F1 and ESC key respectively
|
173
|
+
$('body').keyup(function (e) {
|
174
|
+
var _this = Familiarity.getCurrentObject();
|
175
|
+
if (typeof(_this) != "undefined" && e.keyCode == 27 && _this.escape_to_exit && _this.familiarityRenderedFlag) { //ESC key pressed
|
176
|
+
_this.familiarityView(false);
|
177
|
+
}
|
178
|
+
if (typeof(_this) != "undefined" && e.keyCode == 112 && _this.f1_to_start && !_this.familiarityRenderedFlag) { //F1 key pressed
|
179
|
+
_this.familiarityView(true);
|
180
|
+
}
|
181
|
+
if (typeof(_this) != "undefined" && e.keyCode == 37 && _this.familiarityRenderedFlag) { //LEFT arrow key pressed
|
182
|
+
_this.showPreviousBubble();
|
183
|
+
}
|
184
|
+
if (typeof(_this) != "undefined" && e.keyCode == 39 && _this.familiarityRenderedFlag) { //RIGHT arrow key pressed
|
185
|
+
_this.showNextBubble()
|
186
|
+
}
|
187
|
+
}).mousedown(function (e) {
|
188
|
+
var _this = Familiarity.getCurrentObject();
|
189
|
+
if (typeof(_this) != "undefined" && _this.familiarityRenderedFlag) { //Show next bubble on mouse down('click')
|
190
|
+
_this.showNextBubble()
|
191
|
+
}
|
192
|
+
});
|
193
|
+
});
|
@@ -0,0 +1,150 @@
|
|
1
|
+
jQuery.fn.getPath = function () {
|
2
|
+
if (this.length != 1) throw 'Requires one element.';
|
3
|
+
|
4
|
+
var path, node = this;
|
5
|
+
while (node.length) {
|
6
|
+
var realNode = node[0], name = realNode.localName;
|
7
|
+
if (!name) break;
|
8
|
+
name = name.toLowerCase();
|
9
|
+
|
10
|
+
var parent = node.parent();
|
11
|
+
|
12
|
+
var siblings = parent.children(name);
|
13
|
+
if (siblings.length > 1) {
|
14
|
+
name += ':eq(' + siblings.index(realNode) + ')';
|
15
|
+
}
|
16
|
+
|
17
|
+
path = name + (path ? '>' + path : '');
|
18
|
+
node = parent;
|
19
|
+
}
|
20
|
+
|
21
|
+
return path;
|
22
|
+
};
|
23
|
+
|
24
|
+
var FamiliarityAdmin = function () {
|
25
|
+
this.familiarityEditorialSet = {};
|
26
|
+
this.familiaritySaveUrl = '<%=Familiarity::Engine.routes.url_helpers.save_familiarities_path(format: :json)%>';
|
27
|
+
this.familiaritiesUrl = '<%= Familiarity::Engine.routes.url_helpers.familiarities_path(format: :json) %>';
|
28
|
+
}
|
29
|
+
|
30
|
+
FamiliarityAdmin.familiaritySwitchBoard = function () {
|
31
|
+
var familiarity_admin = new FamiliarityAdmin();
|
32
|
+
|
33
|
+
var switch_state = 'On';
|
34
|
+
$('div.familiaritySwitch').remove();
|
35
|
+
var _div = $('<div class="familiaritySwitch"></div>').html('<div class="text_content">Switch ' + switch_state + ' familiarity!</div>').click(function () {
|
36
|
+
familiarity_admin.familiaritySwitch(switch_state);
|
37
|
+
switch_state = (switch_state == "On") ? "Off" : "On";
|
38
|
+
$(this).html('<div class="text_content">Switch ' + switch_state + ' familiarity!</div>');
|
39
|
+
}).appendTo($('body'));
|
40
|
+
}
|
41
|
+
|
42
|
+
FamiliarityAdmin.prototype = {
|
43
|
+
findOrBuildPopup: function (selection_path, inner_text) {
|
44
|
+
if (typeof(inner_text) == 'undefined') {
|
45
|
+
inner_text = "";
|
46
|
+
}
|
47
|
+
var _div = this.familiarityEditorialSet[selection_path];
|
48
|
+
if (_div == null) {
|
49
|
+
var _div = $('<div class="familiarityPopUpEdit" style="z-index: 20;position: absolute;left: 0;top: 0;display: none"><textarea class="textarea_class" placeholder="Short sweet tutorial goes in here."></textarea><br/><a class="a_class">Close</a></div>');
|
50
|
+
|
51
|
+
//Adding 'Close' handler
|
52
|
+
_div.children('a').click(function () {
|
53
|
+
$(this).parents('div.familiarityPopUpEdit').hide();
|
54
|
+
});
|
55
|
+
|
56
|
+
//Populating textarea
|
57
|
+
_div.children('textarea').val(inner_text);
|
58
|
+
|
59
|
+
this.familiarityEditorialSet[selection_path] = _div;
|
60
|
+
|
61
|
+
_div.appendTo($('body'));
|
62
|
+
}
|
63
|
+
$.each(this.familiarityEditorialSet, function (k, v) {
|
64
|
+
v.hide();
|
65
|
+
});
|
66
|
+
return _div;
|
67
|
+
},
|
68
|
+
startFamiliarizing: function () {
|
69
|
+
var _current_object = this;
|
70
|
+
$('.familiarityTag').bind("mouseenter.myFamiliarity", function (e) {
|
71
|
+
var _this = $(this);
|
72
|
+
var currentSelectionPath = _this.getPath();
|
73
|
+
// console.log(currentSelectionPath);
|
74
|
+
_this.addClass('familiar-selector');
|
75
|
+
_this.parents().removeClass('familiar-selector');
|
76
|
+
|
77
|
+
e.stopImmediatePropagation();
|
78
|
+
}).bind("mouseleave.myFamiliarity", function (e) {
|
79
|
+
var _this = $(this);
|
80
|
+
var currentSelectionPath = _this.getPath();
|
81
|
+
_this.removeClass('familiar-selector');
|
82
|
+
|
83
|
+
e.stopImmediatePropagation();
|
84
|
+
}).bind("click.myFamiliarity", function (e) {
|
85
|
+
var _this = $(this);
|
86
|
+
var currentSelectionPath = _this.getPath();
|
87
|
+
|
88
|
+
var _left_position = _this.position().left;
|
89
|
+
var _top_position = _this.position().top + _this.height();
|
90
|
+
|
91
|
+
var _div = _current_object.findOrBuildPopup(currentSelectionPath).css({
|
92
|
+
left: _left_position,
|
93
|
+
top: _top_position
|
94
|
+
}).show().children('textarea').focus();
|
95
|
+
|
96
|
+
// console.log(_this);
|
97
|
+
e.preventDefault();
|
98
|
+
e.stopPropagation();
|
99
|
+
});
|
100
|
+
},
|
101
|
+
|
102
|
+
saveToBackEnd: function () {
|
103
|
+
var _result_hash = {}
|
104
|
+
$.each(this.familiarityEditorialSet, function (k, v) {
|
105
|
+
if (v.children('textarea').val().trim().length > 0) {
|
106
|
+
_result_hash[k] = v.children('textarea').val();
|
107
|
+
}
|
108
|
+
})
|
109
|
+
jQuery.post(this.familiaritySaveUrl, {
|
110
|
+
from_page: $(location).attr('pathname'),
|
111
|
+
'familiarity_hash': _result_hash
|
112
|
+
});
|
113
|
+
},
|
114
|
+
|
115
|
+
stopFamiliarizing: function () {
|
116
|
+
$('.familiarityTag').unbind('.myFamiliarity');
|
117
|
+
},
|
118
|
+
|
119
|
+
familiaritySwitch: function (i_switch) {
|
120
|
+
if (i_switch == "Off") {
|
121
|
+
this.stopFamiliarizing();
|
122
|
+
$('.familiarityPopUpEdit').hide();
|
123
|
+
if (confirm("Do you want to save the collected familiarity data?")) {
|
124
|
+
this.saveToBackEnd();
|
125
|
+
}
|
126
|
+
}
|
127
|
+
$.each($('body *:not(.familiaritySwitch, .familiarityPopUpEdit)'), function (i, e) {
|
128
|
+
if (i_switch == "On") {
|
129
|
+
if ($(e).parents('.familiarityPopUpEdit').length <= 0) {
|
130
|
+
$(e).addClass('familiarityTag');
|
131
|
+
}
|
132
|
+
} else {
|
133
|
+
$(e).removeClass('familiarityTag');
|
134
|
+
}
|
135
|
+
});
|
136
|
+
if (i_switch == "On") {
|
137
|
+
var _current_object = this;
|
138
|
+
this.startFamiliarizing();
|
139
|
+
$.get(this.familiaritiesUrl, function (data) {
|
140
|
+
var familiarity_hash = data[$(location).attr('pathname')]
|
141
|
+
if (familiarity_hash == null) {
|
142
|
+
familiarity_hash = {}
|
143
|
+
}
|
144
|
+
$.each(familiarity_hash, function (k, v) {
|
145
|
+
_current_object.findOrBuildPopup(k, v);
|
146
|
+
});
|
147
|
+
});
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
@@ -0,0 +1,117 @@
|
|
1
|
+
/*!
|
2
|
+
* jQuery Cookie Plugin v1.4.1
|
3
|
+
* https://github.com/carhartl/jquery-cookie
|
4
|
+
*
|
5
|
+
* Copyright 2013 Klaus Hartl
|
6
|
+
* Released under the MIT license
|
7
|
+
*/
|
8
|
+
(function (factory) {
|
9
|
+
if (typeof define === 'function' && define.amd) {
|
10
|
+
// AMD
|
11
|
+
define(['jquery'], factory);
|
12
|
+
} else if (typeof exports === 'object') {
|
13
|
+
// CommonJS
|
14
|
+
factory(require('jquery'));
|
15
|
+
} else {
|
16
|
+
// Browser globals
|
17
|
+
factory(jQuery);
|
18
|
+
}
|
19
|
+
}(function ($) {
|
20
|
+
|
21
|
+
var pluses = /\+/g;
|
22
|
+
|
23
|
+
function encode(s) {
|
24
|
+
return config.raw ? s : encodeURIComponent(s);
|
25
|
+
}
|
26
|
+
|
27
|
+
function decode(s) {
|
28
|
+
return config.raw ? s : decodeURIComponent(s);
|
29
|
+
}
|
30
|
+
|
31
|
+
function stringifyCookieValue(value) {
|
32
|
+
return encode(config.json ? JSON.stringify(value) : String(value));
|
33
|
+
}
|
34
|
+
|
35
|
+
function parseCookieValue(s) {
|
36
|
+
if (s.indexOf('"') === 0) {
|
37
|
+
// This is a quoted cookie as according to RFC2068, unescape...
|
38
|
+
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
39
|
+
}
|
40
|
+
|
41
|
+
try {
|
42
|
+
// Replace server-side written pluses with spaces.
|
43
|
+
// If we can't decode the cookie, ignore it, it's unusable.
|
44
|
+
// If we can't parse the cookie, ignore it, it's unusable.
|
45
|
+
s = decodeURIComponent(s.replace(pluses, ' '));
|
46
|
+
return config.json ? JSON.parse(s) : s;
|
47
|
+
} catch(e) {}
|
48
|
+
}
|
49
|
+
|
50
|
+
function read(s, converter) {
|
51
|
+
var value = config.raw ? s : parseCookieValue(s);
|
52
|
+
return $.isFunction(converter) ? converter(value) : value;
|
53
|
+
}
|
54
|
+
|
55
|
+
var config = $.cookie = function (key, value, options) {
|
56
|
+
|
57
|
+
// Write
|
58
|
+
|
59
|
+
if (value !== undefined && !$.isFunction(value)) {
|
60
|
+
options = $.extend({}, config.defaults, options);
|
61
|
+
|
62
|
+
if (typeof options.expires === 'number') {
|
63
|
+
var days = options.expires, t = options.expires = new Date();
|
64
|
+
t.setTime(+t + days * 864e+5);
|
65
|
+
}
|
66
|
+
|
67
|
+
return (document.cookie = [
|
68
|
+
encode(key), '=', stringifyCookieValue(value),
|
69
|
+
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
70
|
+
options.path ? '; path=' + options.path : '',
|
71
|
+
options.domain ? '; domain=' + options.domain : '',
|
72
|
+
options.secure ? '; secure' : ''
|
73
|
+
].join(''));
|
74
|
+
}
|
75
|
+
|
76
|
+
// Read
|
77
|
+
|
78
|
+
var result = key ? undefined : {};
|
79
|
+
|
80
|
+
// To prevent the for loop in the first place assign an empty array
|
81
|
+
// in case there are no cookies at all. Also prevents odd result when
|
82
|
+
// calling $.cookie().
|
83
|
+
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
84
|
+
|
85
|
+
for (var i = 0, l = cookies.length; i < l; i++) {
|
86
|
+
var parts = cookies[i].split('=');
|
87
|
+
var name = decode(parts.shift());
|
88
|
+
var cookie = parts.join('=');
|
89
|
+
|
90
|
+
if (key && key === name) {
|
91
|
+
// If second argument (value) is a function it's a converter...
|
92
|
+
result = read(cookie, value);
|
93
|
+
break;
|
94
|
+
}
|
95
|
+
|
96
|
+
// Prevent storing a cookie that we couldn't decode.
|
97
|
+
if (!key && (cookie = read(cookie)) !== undefined) {
|
98
|
+
result[name] = cookie;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
return result;
|
103
|
+
};
|
104
|
+
|
105
|
+
config.defaults = {};
|
106
|
+
|
107
|
+
$.removeCookie = function (key, options) {
|
108
|
+
if ($.cookie(key) === undefined) {
|
109
|
+
return false;
|
110
|
+
}
|
111
|
+
|
112
|
+
// Must not alter options, thus extending a fresh object...
|
113
|
+
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
|
114
|
+
return !$.cookie(key);
|
115
|
+
};
|
116
|
+
|
117
|
+
}));
|