acts_as_content_highlightable 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 822a2e7c824acd2e7baa520d0e89177cd7a42acb
4
- data.tar.gz: 813948922091b765ca6dc68256db220a2c9fb8a9
3
+ metadata.gz: e9b3aed4076a41c98413e268a0d75338d354688d
4
+ data.tar.gz: 8d2549d2c07a4debbf75340fbe230a8e557190fc
5
5
  SHA512:
6
- metadata.gz: 163b81598185735a3a6e22cf96384d91d36c4f75e495745a06cc3bef96daac9353ea9d3d354496b4e9a09b4346e049ff7497127567231b8c021b33960b34cdc4
7
- data.tar.gz: 91b2ff6bedfbaccce63386eab06e6239d189f0fabfab4450a13b3d8ea9c8762ddfbfa8cf4134e0a5b17a4bfc05cb0ca8b4ee788064d64fb8446d353b20269bd9
6
+ metadata.gz: a9ae7c75565bb626c59e835b8e1f35e696045f785c331ab98f8da28d666fdef2980adf5673ddb2e4b9de1750586ea26ad25e99f39b30623eef45ef73ddf65043
7
+ data.tar.gz: 2b7df5e8250b997c20bb3ac07d0e2b711bdf3185a818b1c0509ce1b9331c4ea1fa24be0aa396efd04bc88220a9c549815a56ff4f42c9adfdb97387f69492756d
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ *.DS_Store
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /Gemfile.lock
data/README.md CHANGED
@@ -46,13 +46,13 @@ bundle exec rake db:migrate
46
46
  ```
47
47
 
48
48
  #### 3. Set your model as content_highlightable
49
- Add `acts_as_content_highlightable_on` to the model and choose the column that has the HTML content that you want to highlight.
49
+ Add `acts_as_content_highlightable_on` to the model and choose the column (or columns) that has the HTML content that you want to highlight.
50
50
 
51
51
  ```
52
52
  Class Post < ApplicationRecord
53
- validates :summary, :presence => true
54
- acts_as_content_highlightable_on :summary
55
- # summary is a column on Post model that stores HTML text content
53
+ validates :summary, :content, :presence => true
54
+ acts_as_content_highlightable_on [:summary, :content]
55
+ # summary and content are columns on Post model that stores HTML text content
56
56
  end
57
57
  ```
58
58
 
@@ -67,10 +67,36 @@ and this to your application.css file
67
67
  ```
68
68
 
69
69
  #### 5. Retroactively tag text nodes
70
- This gem creates a `before_save` callback to tag every html node in the content (e.g. `:summary`) with a data attribute `data-chnode="daed4c12"`. This is essential to save, persist and display highlights. To retroactively tag the nodes, use some variant of the following code
70
+ This gem creates a `before_save` callback to tag every html node in the content (e.g. `:summary`) with a data attribute `data-chnode="<unique_random_hex>"`. This is essential to save, persist and display highlights. To retroactively tag the nodes, use some variant of the following code
71
71
  ```
72
72
  Post.all.each{|post| post.prepare_for_content_highlights && post.save}
73
73
  ```
74
+ Please note that the data in your content column will be altered by this gem - it adds data attributes to text nodes of the html content. If your content is plain text, it will be converted into html text. See examples below
75
+ ```
76
+ <!--Example 1 (plain text) -->
77
+ Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.
78
+
79
+ <!--Example 2 (html text) -->
80
+ <p>Far far away, behind the word mountains, far from the countries <em>Vokalia and Consonantia</em>, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.</p>
81
+ <p>A small river named Duden flows by their place and supplies <b>it with the necessary <i>regelialia</i>. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.</p>
82
+
83
+ <!--Example 3 (already tagged html text) -->
84
+ <p data-chnode="aba2519">Far far away, behind the word mountains, far from the countries <em data-chnode="c13d177">Vokalia and Consonantia</em>, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.</p>
85
+ <p data-chnode="98dbae1">A small river named Duden flows by their place and supplies <b data-chnode="d1a2419">it with the necessary <i data-chnode="123ddb3">regelialia</i>. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.</p>
86
+ ```
87
+ becomes
88
+ ```
89
+ <!--Example 1 (plain text - wrapped in <p> tag and added node identifier) -->
90
+ <p data-chnode="d1a2419">Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.</p>
91
+
92
+ <!--Example 2 (html text - added node identifiers) -->
93
+ <p data-chnode="aba2519">Far far away, behind the word mountains, far from the countries <em data-chnode="c13d177">Vokalia and Consonantia</em>, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.</p>
94
+ <p data-chnode="98dbae1">A small river named Duden flows by their place and supplies <b data-chnode="d1a2419">it with the necessary <i data-chnode="123ddb3">regelialia</i>. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.</p>
95
+
96
+ <!--Example 3 (already tagged html text - node identifiers preserved)-->
97
+ <p data-chnode="aba2519">Far far away, behind the word mountains, far from the countries <em data-chnode="c13d177">Vokalia and Consonantia</em>, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.</p>
98
+ <p data-chnode="98dbae1">A small river named Duden flows by their place and supplies <b data-chnode="d1a2419">it with the necessary <i data-chnode="123ddb3">regelialia</i>. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.</p>
99
+ ```
74
100
 
75
101
  #### 6. Invoke the Content Highlighter in your view
76
102
  Here is a sample posts/show view
@@ -85,6 +111,7 @@ Here is a sample posts/show view
85
111
  nodeIdentifierKey: "<%=ActsAsContentHighlightable.unique_html_node_identifier_key%>",
86
112
  highlightableType: "Post",
87
113
  highlightableId: "1",
114
+ highlightableColumn: "summary", // required if your model has more than 1 highlightable column
88
115
  readOnly: false
89
116
  });
90
117
  worker.init();
@@ -101,10 +128,16 @@ Use the `ContentHighlight#highlights_to_show` method to selectively show certain
101
128
  #### 2. Enrich Highlights
102
129
  `ContentHighlight#enrich_highlights` lets us modify the `description`, set permissions to remove `can_cancel`, and change css classes to distinguish the user's vs others' highlights `lifetime_class_ends`
103
130
 
104
- #### 3. Custom Styling
131
+ #### 3. Set Add/remove permissions
132
+ `ContentHighlight#can_add_highlights?(highlightable, user)` and `content_highlight#can_remove_highlight?(user)` lets us set permissions to add/remove highlights based on the user, highlightable etc.
133
+
134
+ #### 4. Custom Node identifier Key
135
+ `ActsAsContentHighlightable.unique_html_node_identifier_key = 'somekey'` shall be initialized in the rails app, preferably in the `config/initializers/acts_as_content_highlightable.rb`. This will let us use a node identifier key. The default is `chnode`, and nodes will be tagged `data-chnode`. Note that changing this will render your earlier node tags useless, and you might have to re tag all the text nodes with the new key.
136
+
137
+ #### 5. Custom Styling
105
138
  Check out [content_highlight.css](./vendor/assets/stylesheets/content_highlight.css)
106
139
 
107
- #### 4. More Javascript options
140
+ #### 6. More Javascript options
108
141
  `highlightableType` and `highlightableId` are required. Highlights can be set `readOnly` - no addition or removal. You may never need more but check out the [content_highlight.js](./vendor/assets/javascripts/content_highlight.js) file for more configuration options.
109
142
 
110
143
  ## Development
@@ -2,12 +2,13 @@ module ActsAsContentHighlightable
2
2
  class ContentHighlightsController < ApplicationController
3
3
  before_action :set_highlighter_user
4
4
  before_action :get_highlightable
5
+ before_action :set_highlightable_column, :only => [:add]
5
6
 
6
7
  def add
7
- if @highlightable.present?
8
+ if @highlightable.present? and (ContentHighlight.respond_to?(:can_add_highlights?) ? ContentHighlight.can_add_highlights?(@highlightable, @highlighter_user) : true)
8
9
  content_highlight = @highlightable.content_highlights.new({
9
10
  :user => @highlighter_user,
10
- :highlightable_column => @highlightable.highlightable_column,
11
+ :highlightable_column => @highlightable_column,
11
12
  :content => params[:content],
12
13
  :container_node_identifier_key => params[:common_ancestor_identifier_key],
13
14
  :container_node_identifier => params[:common_ancestor_identifier],
@@ -26,7 +27,7 @@ module ActsAsContentHighlightable
26
27
 
27
28
  def remove
28
29
  content_highlight = @highlightable.content_highlights.where(:id => params[:content_highlight_id]).first
29
- if content_highlight.present? and (content_highlight.user == @highlighter_user)
30
+ if content_highlight.present? and (content_highlight.respond_to?(:can_remove_highlight?) ? content_highlight.can_remove_highlight?(@highlighter_user) : (content_highlight.user == @highlighter_user))
30
31
  remove_highlights = @highlightable.content_highlights.where(:id => content_highlight.id).enrich_highlights(@highlighter_user).as_json
31
32
  content_highlight.destroy
32
33
  else
@@ -36,10 +37,27 @@ module ActsAsContentHighlightable
36
37
  end
37
38
 
38
39
  private
40
+
41
+ def set_highlightable_column
42
+ if params[:highlightable_column].blank? and @highlightable.highlightable_columns.size > 1
43
+ raise ArgumentError.new("More than one highlightable column found. Please provide highlightable_column in your parameters")
44
+ elsif params[:highlightable_column].blank?
45
+ @highlightable_column = @highlightable.highlightable_columns.first.to_s
46
+ else
47
+ @highlightable_column = params[:highlightable_column].to_s
48
+ end
49
+ if not @highlightable.respond_to?(:highlightable_columns)
50
+ raise ArgumentError.new("Highlightable column not found. Please check the parameter: highlightable_column")
51
+ end
52
+ if not @highlightable.highlightable_columns.include? @highlightable_column
53
+ raise ArgumentError.new("Invalid Highlightable column")
54
+ end
55
+ end
56
+
39
57
  def get_highlightable
40
58
  highlightable_model = params[:highlightable_type].to_s.constantize
41
59
  @highlightable = highlightable_model.respond_to?(:find_by_id) && highlightable_model.find_by_id(params[:highlightable_id])
42
- @highlightable = nil unless @highlightable.respond_to?(:highlightable_column)
60
+ @highlightable = nil unless @highlightable.respond_to?(:highlightable_columns)
43
61
  end
44
62
 
45
63
  def set_highlighter_user
data/changelog.md ADDED
@@ -0,0 +1,11 @@
1
+ # v 0.2.0
2
+ (July, 10, 2017)
3
+
4
+ * Supports multiple content_highlightable columns per model
5
+ ```
6
+ acts_as_content_highlightable_on [:summary, :content]
7
+ ```
8
+ * Added ActsAsContentHighlightabl.extract_text_from_html(text) method
9
+ - can be used to extract text from HTML content.
10
+ * Extract `can_remove_highlight?(user)` method from controller to ContentHighlight model
11
+ - Can customize removal permissions - better than just checking (highlight.user == current_user)
@@ -13,6 +13,11 @@ module ActsAsContentHighlightable
13
13
  mattr_accessor :mount
14
14
  self.mount = true
15
15
 
16
+ def self.extract_text_from_html(text)
17
+ return nil unless text.is_a? String
18
+ return ActsAsContentHighlightable::HtmlNodeParser.new(text).body_text
19
+ end
20
+
16
21
  ActiveSupport.on_load(:active_record) do
17
22
  extend ActsAsContentHighlightable::Model
18
23
  end
@@ -17,6 +17,10 @@ class ActsAsContentHighlightable::HtmlNodeParser
17
17
  return @parsed.css('body').inner_html
18
18
  end
19
19
 
20
+ def body_text
21
+ return @parsed.text
22
+ end
23
+
20
24
  private
21
25
 
22
26
  def apply_unique_identifiers_to_children(node, attribute_name)
@@ -1,21 +1,24 @@
1
1
  module ActsAsContentHighlightable
2
2
  module Model
3
- def acts_as_content_highlightable_on(column_name)
4
- if not self.column_names.include? column_name.to_s
5
- raise ArgumentError, "acts_as_content_highlightable_on: Invalid attribute #{column_name}"
3
+ def acts_as_content_highlightable_on(column_names)
4
+ column_names = [column_names].flatten
5
+ if not column_names.all? {|column_name| self.column_names.include? column_name.to_s}
6
+ raise ArgumentError, "acts_as_content_highlightable_on: One or more invalid attribute #{column_names}"
6
7
  end
7
8
 
8
9
  class_eval do
9
10
  has_many :content_highlights, :as => :highlightable
11
+ before_save :prepare_for_content_highlights, :if => column_names.map{|column_name| "#{column_name}_changed?"}
10
12
  end
11
13
 
12
14
  class_eval %{
13
- before_save :prepare_for_content_highlights, :if => :#{column_name.to_s}_changed?
14
- def highlightable_column
15
- return "#{column_name.to_s}"
15
+ def highlightable_columns
16
+ return #{column_names.map(&:to_s)}
16
17
  end
17
18
  def prepare_for_content_highlights
18
- self.#{column_name.to_s} = ActsAsContentHighlightable::HtmlNodeParser.new(self.#{column_name.to_s}).assign_unique_node_identifiers("data-" + ActsAsContentHighlightable.unique_html_node_identifier_key).body_content
19
+ #{column_names}.each do |column_name|
20
+ self[column_name.to_sym] = ActsAsContentHighlightable::HtmlNodeParser.new(self[column_name.to_sym]).assign_unique_node_identifiers("data-" + ActsAsContentHighlightable.unique_html_node_identifier_key).body_content
21
+ end
19
22
  end
20
23
  }
21
24
  end
@@ -1,3 +1,3 @@
1
1
  module ActsAsContentHighlightable
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -14,6 +14,17 @@ class ContentHighlight < ActiveRecord::Base
14
14
  highlightable.content_highlights
15
15
  end
16
16
 
17
+ # Set Add Permissions here
18
+ def self.can_add_highlights?(highlightable, user)
19
+ return true # e.g. highlightable.can_highlight?(user)
20
+ end
21
+
22
+ # Set remove permissions here
23
+ def can_remove_highlight?(user)
24
+ return (self.user == user)
25
+ end
26
+
27
+
17
28
  # This method is used to show details on the poptips with permissions to remove highlights
18
29
  def self.enrich_highlights(user)
19
30
  ContentHighlight.joins(:user)
@@ -40,6 +40,7 @@ var contentHighlightWorker = function(element, options){
40
40
  this.settings = {
41
41
  highlightableType: options.highlightableType || "",
42
42
  highlightableId: options.highlightableId || "",
43
+ highlightableColumn: options.highlightableColumn || "",
43
44
  readOnly: options.readOnly || false,
44
45
  nodeIdentifierKey: options.nodeIdentifierKey || "chnode",
45
46
  highlightClass: options.highlightClass || "content-highlight",
@@ -52,7 +53,7 @@ var contentHighlightWorker = function(element, options){
52
53
  removeFromServerPath: options.removeFromServerPath || element.dataset.removehighlightspath || "/content_highlights/remove?",
53
54
  }
54
55
 
55
- this.sendToServerParams = "highlightable_type=" + this.settings.highlightableType + "&highlightable_id=" + this.settings.highlightableId;
56
+ this.sendToServerParams = "highlightable_type=" + this.settings.highlightableType + "&highlightable_id=" + this.settings.highlightableId + "&highlightable_column=" + this.settings.highlightableColumn;
56
57
 
57
58
  if(!rangy || !rangy.getSelection){
58
59
  return;
@@ -25,7 +25,7 @@
25
25
  }
26
26
  .content-highlight-poptip .description{
27
27
  font-size: 100%;
28
- line-height: 100%;
28
+ line-height: 140%;
29
29
  display: block;
30
30
  white-space: nowrap;
31
31
  overflow: hidden;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_content_highlightable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karthik Ravichandran
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-05 00:00:00.000000000 Z
11
+ date: 2017-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -100,6 +100,7 @@ files:
100
100
  - app/controller/acts_as_content_highlightable/content_highlights_controller.rb
101
101
  - bin/console
102
102
  - bin/setup
103
+ - changelog.md
103
104
  - config/routes.rb
104
105
  - lib/acts_as_content_highlightable.rb
105
106
  - lib/acts_as_content_highlightable/engine.rb