familiarity 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +67 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/familiarity/application.js +16 -0
  6. data/app/assets/javascripts/familiarity/familiarity.js.erb +193 -0
  7. data/app/assets/javascripts/familiarity/familiarity_admin.js.erb +150 -0
  8. data/app/assets/javascripts/familiarity/jquery.cookie.js +117 -0
  9. data/app/assets/javascripts/familiarity/jquery.tooltipster.js +1282 -0
  10. data/app/assets/stylesheets/familiarity/application.css +17 -0
  11. data/app/assets/stylesheets/familiarity/familiarities.css +4 -0
  12. data/app/assets/stylesheets/familiarity/familiarity.css.scss +121 -0
  13. data/app/assets/stylesheets/familiarity/themes/tooltipster-light.css +12 -0
  14. data/app/assets/stylesheets/familiarity/themes/tooltipster-noir.css +12 -0
  15. data/app/assets/stylesheets/familiarity/themes/tooltipster-punk.css +12 -0
  16. data/app/assets/stylesheets/familiarity/themes/tooltipster-shadow.css +12 -0
  17. data/app/assets/stylesheets/familiarity/tooltipster.css +274 -0
  18. data/app/controllers/familiarity/application_controller.rb +4 -0
  19. data/app/controllers/familiarity/familiarities_controller.rb +22 -0
  20. data/app/helpers/familiarity/application_helper.rb +32 -0
  21. data/app/helpers/familiarity/familiarities_helper.rb +4 -0
  22. data/app/views/familiarity/familiarities/index.json.erb +1 -0
  23. data/app/views/layouts/familiarity/application.html.erb +14 -0
  24. data/config/routes.rb +7 -0
  25. data/lib/familiarity/engine.rb +17 -0
  26. data/lib/familiarity/version.rb +3 -0
  27. data/lib/familiarity.rb +4 -0
  28. data/lib/tasks/familiarity_tasks.rake +4 -0
  29. data/test/controllers/familiarity/familiarities_controller_test.rb +9 -0
  30. data/test/dummy/README.rdoc +28 -0
  31. data/test/dummy/Rakefile +6 -0
  32. data/test/dummy/app/assets/javascripts/application.js +13 -0
  33. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  34. data/test/dummy/app/controllers/application_controller.rb +5 -0
  35. data/test/dummy/app/helpers/application_helper.rb +2 -0
  36. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  37. data/test/dummy/bin/bundle +3 -0
  38. data/test/dummy/bin/rails +4 -0
  39. data/test/dummy/bin/rake +4 -0
  40. data/test/dummy/config/application.rb +23 -0
  41. data/test/dummy/config/boot.rb +5 -0
  42. data/test/dummy/config/database.yml +25 -0
  43. data/test/dummy/config/environment.rb +5 -0
  44. data/test/dummy/config/environments/development.rb +37 -0
  45. data/test/dummy/config/environments/production.rb +78 -0
  46. data/test/dummy/config/environments/test.rb +39 -0
  47. data/test/dummy/config/initializers/assets.rb +8 -0
  48. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  50. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  51. data/test/dummy/config/initializers/inflections.rb +16 -0
  52. data/test/dummy/config/initializers/mime_types.rb +4 -0
  53. data/test/dummy/config/initializers/session_store.rb +3 -0
  54. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/test/dummy/config/locales/en.yml +23 -0
  56. data/test/dummy/config/routes.rb +4 -0
  57. data/test/dummy/config/secrets.yml +22 -0
  58. data/test/dummy/config.ru +4 -0
  59. data/test/dummy/public/404.html +67 -0
  60. data/test/dummy/public/422.html +67 -0
  61. data/test/dummy/public/500.html +66 -0
  62. data/test/dummy/public/favicon.ico +0 -0
  63. data/test/familiarity_test.rb +7 -0
  64. data/test/helpers/familiarity/familiarities_helper_test.rb +6 -0
  65. data/test/integration/navigation_test.rb +10 -0
  66. data/test/test_helper.rb +15 -0
  67. 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
+ }));