sir_trevor_rails 0.5.0b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/CHANGELOG +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +126 -0
- data/Rakefile +7 -0
- data/app/views/sir_trevor/_sir_trevor_block_array.html.erb +1 -0
- data/app/views/sir_trevor/blocks/_heading_block.html.erb +1 -0
- data/app/views/sir_trevor/blocks/_image_block.html.erb +5 -0
- data/app/views/sir_trevor/blocks/_list_block.html.erb +3 -0
- data/app/views/sir_trevor/blocks/_quote_block.html.erb +13 -0
- data/app/views/sir_trevor/blocks/_text_block.html.erb +3 -0
- data/app/views/sir_trevor/blocks/_tweet_block.html.erb +9 -0
- data/app/views/sir_trevor/blocks/videos/_vimeo.html.erb +4 -0
- data/app/views/sir_trevor/blocks/videos/_youtube.html.erb +4 -0
- data/config/initializers/validators.rb +12 -0
- data/config.ru +7 -0
- data/lib/generators/sir_trevor_rails/block/block_generator.rb +33 -0
- data/lib/generators/sir_trevor_rails/block/templates/_block.html.erb +3 -0
- data/lib/generators/sir_trevor_rails/block/templates/_block.js +203 -0
- data/lib/generators/sir_trevor_rails/block/templates/_block.rb +2 -0
- data/lib/generators/sir_trevor_rails/views/views_generator.rb +17 -0
- data/lib/sir_trevor_rails/block.rb +63 -0
- data/lib/sir_trevor_rails/block_array.rb +21 -0
- data/lib/sir_trevor_rails/blocks/tweet_block.rb +35 -0
- data/lib/sir_trevor_rails/blocks/video_block.rb +9 -0
- data/lib/sir_trevor_rails/engine.rb +34 -0
- data/lib/sir_trevor_rails/has_sir_trevor_content.rb +27 -0
- data/lib/sir_trevor_rails/helpers/view_helper.rb +26 -0
- data/lib/sir_trevor_rails/version.rb +3 -0
- data/lib/sir_trevor_rails/view_resolver.rb +13 -0
- data/lib/sir_trevor_rails.rb +30 -0
- data/sir_trevor_rails.gemspec +39 -0
- data/spec/internal/app/models/custom_block.rb +5 -0
- data/spec/internal/app/models/post.rb +2 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/schema.rb +7 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/unit/block_array_spec.rb +66 -0
- data/spec/unit/block_spec.rb +66 -0
- data/spec/unit/custom_block_spec.rb +19 -0
- data/spec/unit/has_sir_trevor_content_spec.rb +38 -0
- metadata +254 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e0440542cac7ceda76800ef5d839ce166aea6a96
|
4
|
+
data.tar.gz: 63bfbecf7f48260f978fd284bf773ec1cc8287c2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 41c835b01d6f5fd0bf4540ba2a3c65d3fcf70c43de7586ab3048fae21025bd05045c70c4afca5a9671dbbfe3a774e8e9f7a97dd9c3b97ff1840d7bf281135a3f
|
7
|
+
data.tar.gz: 7621bdbeae052096553e9af079169a8f600aef8e8733acfdf02e0b3f91618455c8a44b3bcec27a0eb382fbb55fd52b1cfc0d32c9cd6e3f4d3cdf3c19821b9013
|
data/.gitignore
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
v0.4.0:
|
2
|
+
date: 2014-05-20
|
3
|
+
changes:
|
4
|
+
- Renamed gem sir_trevor_rails (used to be sir-trevor-rails)
|
5
|
+
- Removed sir trevor JS and all its dependencies (should install files manually or from bower from now on)
|
6
|
+
- Removed all the view helpers appart from sir_trevor_markdown (render_sir_trevor, render_sir_trevor_block, render_sir_trevor_image, sir_trevor_image_tag, parse_sir_trevor are all gone)
|
7
|
+
- Removed the form helper (no more sir_trevor_text_area)
|
8
|
+
- Added has_sir_trevor_content.rb as a concern for models with ST content
|
9
|
+
- Remove jQuery rails dependency
|
10
|
+
- Use view resolvers and to_partial_path to render ST content (instead of the view helper)
|
11
|
+
- Add block array class
|
12
|
+
- Add block classes
|
13
|
+
- Add lookup methods on the block array
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013-2014 by ITV plc - http://www.itv.com
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# Sir Trevor Rails
|
2
|
+
|
3
|
+
A Rails gem for integrating Sir Trevor JS into your Rails 3/4 application.
|
4
|
+
|
5
|
+
## Upgrade guide from v0.4.0-rc.1
|
6
|
+
|
7
|
+
Version 0.4.0 represents a major refactor and contains significant API changes.
|
8
|
+
|
9
|
+
* The SirTrevor gem has been renamed from ``sir-trevor-rails`` to ``sir_trevor_rails`` you will need to update your Gemfile.
|
10
|
+
* There are no more form helpers or view helpers so relace ``f.sir_trevor_text_area :content`` with ``f.text_area :content``.
|
11
|
+
* SirTrevor JS and it's dependencies are no longer bundled with the gem and need to be downloaded and installed manually or with bower. [See the SirTrevor JS repo for more](https://github.com/madebymany/sir-trevor-js#plain-js).
|
12
|
+
* In your model, register your SirTrevor content like this ``sir_trevor_content :content`` where ``:content`` is the name of the field on your where you store SirTrevor content.
|
13
|
+
* In your views, you no longer need to use the ``render_sir_trevor`` helper. Instead, simply render your content like this ``<%= render @item.content %>``
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
Add Sir Trevor to your Gemfile
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'sir_trevor_rails'
|
21
|
+
```
|
22
|
+
|
23
|
+
```bash
|
24
|
+
bundle install
|
25
|
+
```
|
26
|
+
|
27
|
+
Include Sir Trevor JS in your project following the instructions set out [here](http://madebymany.github.io/sir-trevor-js/docs.html)
|
28
|
+
|
29
|
+
## Generators: Views
|
30
|
+
|
31
|
+
Grab all of the default block type partials by running the following generator command:
|
32
|
+
|
33
|
+
```bash
|
34
|
+
rails g sir_trevor_rails:views
|
35
|
+
```
|
36
|
+
|
37
|
+
This will copy all of the SirTrevor block partials into `app/views/sir_trevor/blocks/`
|
38
|
+
|
39
|
+
## Rendering
|
40
|
+
|
41
|
+
In your models pass the attribute name of your Sir Trevor content to `sir_trevor_content`
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
sir_trevor_content :content
|
45
|
+
```
|
46
|
+
|
47
|
+
In your view files, call render to display the Sir Trevor content
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
<%= render @item.content %>
|
51
|
+
```
|
52
|
+
|
53
|
+
## Handling image uploads
|
54
|
+
|
55
|
+
We don't provide a default image uploader out of the box, because everyone will have different requirements. To see an example of an image uploader, please refer to our Rails examples in the [Sir Trevor JS repository](https://github.com/madebymany/sir-trevor-js/tree/master/examples/rails/image-uploader).
|
56
|
+
|
57
|
+
## Handling markdown
|
58
|
+
|
59
|
+
Use the ``sir_trevor_markdown`` method in your custom block partials to correctly parse the markdown in a block
|
60
|
+
|
61
|
+
## Querying the block content
|
62
|
+
|
63
|
+
Use the following methods to query the Sir Trevor content
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
@item.content.has_block_of_type?(:image)
|
67
|
+
```
|
68
|
+
|
69
|
+
Does this content have an image block?
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
@item.content.first_block_of_type(:video)
|
73
|
+
```
|
74
|
+
|
75
|
+
Return the first video block in the content
|
76
|
+
|
77
|
+
## Add custom methods for block content
|
78
|
+
|
79
|
+
Create an initializer ``config/initializers/sir_trevor_rails.rb``
|
80
|
+
|
81
|
+
Write your method in the initializer:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
class SirTrevorRails::BlockArray
|
85
|
+
def your_custom_method_here
|
86
|
+
# some code
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
Call your method on the ST content
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
@item.content.your_custom_method
|
95
|
+
```
|
96
|
+
|
97
|
+
## Generators: Blocks
|
98
|
+
|
99
|
+
Run the blocks generator to create templates for your custom blocks
|
100
|
+
|
101
|
+
```bash
|
102
|
+
rails g sir_trevor_rails:block my_custom_block
|
103
|
+
```
|
104
|
+
|
105
|
+
This will generate an html file for rendering the block, a javascript file for the editor and a ruby block class.
|
106
|
+
|
107
|
+
## Block Classes
|
108
|
+
|
109
|
+
Ruby block classes can be used like decorators for the block content. See the [tweet block class](https://github.com/madebymany/sir-trevor-rails/blob/redesign-gem/lib/sir_trevor_rails/blocks/tweet_block.rb) for an example
|
110
|
+
|
111
|
+
## Requirements
|
112
|
+
|
113
|
+
|
114
|
+
- Rails 3.x/4.x
|
115
|
+
|
116
|
+
## To do
|
117
|
+
|
118
|
+
- Add tests
|
119
|
+
|
120
|
+
## Licence
|
121
|
+
|
122
|
+
Sir Trevor Rails is released under the [MIT Licence](MIT-LICENSE)
|
123
|
+
|
124
|
+
## Changelog
|
125
|
+
|
126
|
+
See the [CHANGELOG](CHANGELOG)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<%= render sir_trevor_block_array.to_a %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h2><%= heading_block.text %></h2>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="st__content-block st__content-block--quote">
|
2
|
+
<div class="quote">
|
3
|
+
<div class="quote__content">
|
4
|
+
<%= sir_trevor_markdown quote_block.text %>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<% if quote_block.cite.present? %>
|
8
|
+
<div class="quote__cite">
|
9
|
+
<cite class="quote__cite-text">– <%= quote_block.cite %></cite>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
</div>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<div class="st__content-block st__content-block--tweet">
|
2
|
+
<%= link_to image_tag(tweet_block.profile_image_url, class: 'img'), tweet_block.screen_name %>
|
3
|
+
<p>
|
4
|
+
<%= tweet_block.render_tweet_body %>
|
5
|
+
</p>
|
6
|
+
<cite>From <%= link_to tweet_block.at_name, tweet_block.screen_name %> on Twitter:</cite>
|
7
|
+
<time datetime="<%= tweet_block.created_at %>">(<%= link_to Time.parse(tweet_block.created_at), tweet_block.status_url %>)</time>
|
8
|
+
</div>
|
9
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_model/validator'
|
2
|
+
|
3
|
+
class IsJsonValidator < ActiveModel::EachValidator
|
4
|
+
def validate_each(record, attribute, value)
|
5
|
+
@json = MultiJson.load(value, symbolize_keys: true)
|
6
|
+
record.errors.add(attribute, "is empty") if @json.empty?
|
7
|
+
rescue TypeError => e
|
8
|
+
record.errors.add(attribute, "is not valid JSON: #{e.message}")
|
9
|
+
rescue JSON::JSONError => e
|
10
|
+
record.errors.add(attribute, "is not valid JSON: #{e.message}")
|
11
|
+
end
|
12
|
+
end
|
data/config.ru
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module SirTrevorRails
|
4
|
+
module Generators
|
5
|
+
class BlockGenerator < Rails::Generators::NamedBase
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_block
|
12
|
+
|
13
|
+
# Copy the JS
|
14
|
+
copy_file "_block.js", "app/assets/javascripts/sir_trevor/blocks/#{name}.js"
|
15
|
+
|
16
|
+
gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /SirTrevor\.Blocks\.Example/, "SirTrevor.Blocks.#{name.capitalize}"
|
17
|
+
gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /return "Example"/, "return: '#{name.capitalize}'"
|
18
|
+
gsub_file "app/assets/javascripts/sir_trevor/blocks/#{name}.js", /type: 'example'/, "type: '#{name.downcase}'"
|
19
|
+
|
20
|
+
# Copy the HTML
|
21
|
+
copy_file "_block.html.erb", "app/views/sir_trevor/blocks/_#{name}_block.html.erb"
|
22
|
+
gsub_file "app/views/sir_trevor/blocks/_#{name}_block.html.erb", /\s(-block)/, " #{name}-block"
|
23
|
+
gsub_file "app/views/sir_trevor/blocks/_#{name}_block.html.erb", /\s(_block)/, " #{name}_block"
|
24
|
+
|
25
|
+
# Copy the BlockDecorator
|
26
|
+
copy_file "_block.rb", "app/sir_trevor_blocks/#{name}_block.rb"
|
27
|
+
gsub_file "app/sir_trevor_blocks/#{name}_block.rb", /ExampleBlock/, " #{name}Block"
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
/*
|
2
|
+
An example of a SirTrevor.Block
|
3
|
+
--
|
4
|
+
Author: C J Bell @ madebymany
|
5
|
+
*/
|
6
|
+
|
7
|
+
SirTrevor.Blocks.Example = (function(){
|
8
|
+
|
9
|
+
return SirTrevor.Block.extend({
|
10
|
+
|
11
|
+
// String; Names the block
|
12
|
+
// Note – please use underscores when naming
|
13
|
+
// Eg example_block should be ExampleBlock
|
14
|
+
type: 'example',
|
15
|
+
|
16
|
+
// Function; the title displayed in the toolbar
|
17
|
+
// Can return a translated string (if required)
|
18
|
+
title: function() {
|
19
|
+
// return i18n.t('blocks:example:title');
|
20
|
+
return "Example";
|
21
|
+
},
|
22
|
+
|
23
|
+
// Boolean; show this blockType of the toolbar
|
24
|
+
toolbarEnabled: true,
|
25
|
+
|
26
|
+
// Block Mixins
|
27
|
+
// Allow different UI components / methods to be mixed into the block
|
28
|
+
|
29
|
+
// Enable drop functionality on the block
|
30
|
+
droppable: false,
|
31
|
+
|
32
|
+
// Enable paste functionality (to paste URLS etc)
|
33
|
+
pastable: false,
|
34
|
+
|
35
|
+
// Enable an upload button to be added
|
36
|
+
// Mixins Ajaxable automatically
|
37
|
+
// Exposes an uploader method
|
38
|
+
// Usage: this.uploader(file, success, failure)
|
39
|
+
uploadable: false,
|
40
|
+
|
41
|
+
// Enable queued remote fetching
|
42
|
+
// Exposes a small wrapper around the $.ajax method
|
43
|
+
// Usage: this.fetch(ajaxOptions, success, failure)
|
44
|
+
fetchable: false,
|
45
|
+
|
46
|
+
// Add an ajax queue to the block
|
47
|
+
// Added to uploadable & fetchable automatically
|
48
|
+
ajaxable: false,
|
49
|
+
|
50
|
+
// Overwritable mixin options:
|
51
|
+
// --
|
52
|
+
drop_options: {
|
53
|
+
// String; (can use underscore template tags)
|
54
|
+
// Defines the HTML for the dropzone template
|
55
|
+
html: "<div class='st-block__dropzone'></div>",
|
56
|
+
// Boolean;
|
57
|
+
// On re-order, should we re-render this item.
|
58
|
+
// Useful for when re-ordering iframes (like Twitter)
|
59
|
+
re_render_on_reorder: false
|
60
|
+
},
|
61
|
+
|
62
|
+
paste_options: {
|
63
|
+
// String; (can use underscore template tags)
|
64
|
+
// Defines the HTML for the paste template
|
65
|
+
html: "<input type=\"text\" class=\"st-paste-block\">"
|
66
|
+
},
|
67
|
+
|
68
|
+
upload_options: {
|
69
|
+
// String; (can use underscore template tags)
|
70
|
+
// Defines the HTML for the upload template
|
71
|
+
html: "<input type=\"file\" type=\"st-file-upload\">"
|
72
|
+
},
|
73
|
+
|
74
|
+
formattable: true,
|
75
|
+
|
76
|
+
// String or Function; The HTML for the inner portion of the editor block
|
77
|
+
// In this example, the editorHTML is an editable input div (like we use for a TextBlock)
|
78
|
+
|
79
|
+
// Classes:
|
80
|
+
// st-required – indicates this input must be present to pass validation
|
81
|
+
// st-text-block – gives the block the ability to use the formatting controls
|
82
|
+
|
83
|
+
editorHTML: function() {
|
84
|
+
return "<div class='st-text-block' contenteditable='true'></div>";
|
85
|
+
},
|
86
|
+
|
87
|
+
// Element shorthands
|
88
|
+
// --
|
89
|
+
// this.$el
|
90
|
+
// this.el
|
91
|
+
// this.$inner (the inner container for the block)
|
92
|
+
// this.$editor (contains all the UI inputs for the block)
|
93
|
+
// this.$inputs (contains all the UI inputs for blocks that are uploadable / droppable / pastable)
|
94
|
+
// this.getTextBlock() (shorthand for this.$el.find('.st-text-block'))
|
95
|
+
// this.$(selector) (shorthand for this.$el.find(selector))
|
96
|
+
|
97
|
+
// Validations
|
98
|
+
// --
|
99
|
+
// Required fields (with .st-required class) always get validted
|
100
|
+
// Called using the validateField method
|
101
|
+
// Set a data-st-name="Field Name" on your required inputs to use it in the validation fail message
|
102
|
+
|
103
|
+
// Array; defines custom validator methods to call
|
104
|
+
validations: ['myCustomValidator'],
|
105
|
+
|
106
|
+
// Example custom validator
|
107
|
+
myCustomValidator: function() {
|
108
|
+
var field = this.$('.a-field');
|
109
|
+
|
110
|
+
if (field.val() === 'herp derp') {
|
111
|
+
this.setError(field, "A validation fail message");
|
112
|
+
}
|
113
|
+
},
|
114
|
+
|
115
|
+
// Function; Executed on render of the block if some data is provided.
|
116
|
+
// LoadData gives us a means to convert JSON data into the editor dom
|
117
|
+
// In this example we convert the text from markdown to HTML and show it inside the element
|
118
|
+
loadData: function(data){
|
119
|
+
this.getTextBlock().html(SirTrevor.toHTML(data.text, this.type));
|
120
|
+
},
|
121
|
+
|
122
|
+
// Function; Executed on save of the block, once the block is validated
|
123
|
+
// toData expects a way for the block to be transformed from inputs into structured data
|
124
|
+
// The default toData function provides a pretty comprehensive way of turning data into JSON
|
125
|
+
// In this example we take the text data and save it to the data object on the block
|
126
|
+
toData: function(){
|
127
|
+
var dataObj = {};
|
128
|
+
|
129
|
+
var content = this.getTextBlock().html();
|
130
|
+
if (content.length > 0) {
|
131
|
+
dataObj.text = SirTrevor.toMarkdown(content, this.type);
|
132
|
+
}
|
133
|
+
|
134
|
+
this.setData(dataObj);
|
135
|
+
},
|
136
|
+
|
137
|
+
// Function; Returns true or false whether there is data in the block
|
138
|
+
isEmpty: function() {
|
139
|
+
return _.isEmpty(this.saveAndGetData()); // Default implementation
|
140
|
+
},
|
141
|
+
|
142
|
+
// Other data functions
|
143
|
+
// --
|
144
|
+
// getData – returns the data in the store
|
145
|
+
// save - Invokes the toData method
|
146
|
+
// saveAndReturnData - Saves and returns the entire store
|
147
|
+
// saveAndGetData - Save and only return the data part of the store
|
148
|
+
|
149
|
+
|
150
|
+
// Function; Hook executed at the end of the block rendering method.
|
151
|
+
// Useful for initialising extra pieces of UI or binding extra events.
|
152
|
+
// In this example we add an extra button, just because.
|
153
|
+
onBlockRender: function() {
|
154
|
+
this.$editor.append($('<button>', {
|
155
|
+
click: function() {
|
156
|
+
alert('Yo dawg, you clicked my button');
|
157
|
+
}
|
158
|
+
}));
|
159
|
+
},
|
160
|
+
|
161
|
+
// Function; Optional hook method executed before the rendering of a block
|
162
|
+
// Beware, $el and any shorthand element variables won't be setup here.
|
163
|
+
beforeBlockRender: function() {},
|
164
|
+
|
165
|
+
// Function; Executed once content has been dropped onto the dropzone of this block
|
166
|
+
// Only required if you have enabled dropping and have provided a dropzone for this block
|
167
|
+
// Always is passed the ev.transferData object from the drop
|
168
|
+
// Please see the image block (https://github.com/madebymany/sir-trevor-js/blob/master/src/blocks/image.js) for an example
|
169
|
+
onDrop: function(transferData) {},
|
170
|
+
|
171
|
+
// Function; executed once content has been pasted into a pastable block
|
172
|
+
// See the tweet block as an example (https://github.com/madebymany/sir-trevor-js/blob/master/src/blocks/tweet.js)
|
173
|
+
onContentPasted: function(event) {},
|
174
|
+
|
175
|
+
// Block level messages
|
176
|
+
// --
|
177
|
+
// addMessage(msg, additionalClass)
|
178
|
+
// Adds a new message onto the block
|
179
|
+
|
180
|
+
// resetMessages()
|
181
|
+
// Clears all existing messages
|
182
|
+
|
183
|
+
// Helper methods
|
184
|
+
// --
|
185
|
+
// loading()
|
186
|
+
// ready()
|
187
|
+
// hasTextBlock()
|
188
|
+
// remove()
|
189
|
+
|
190
|
+
// Function; Any extra markdown parsing can be defined in here.
|
191
|
+
// Returns; String (Required)
|
192
|
+
toMarkdown: function(markdown) {
|
193
|
+
return markdown.replace(/^(.+)$/mg,"> $1");
|
194
|
+
},
|
195
|
+
|
196
|
+
// Function; Any extra HTML parsing can be defined in here.
|
197
|
+
// Returns; String (Required)
|
198
|
+
toHTML: function(html) {
|
199
|
+
return html;
|
200
|
+
}
|
201
|
+
});
|
202
|
+
|
203
|
+
})();
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module SirTrevorRails
|
4
|
+
module Generators
|
5
|
+
class ViewsGenerator < Rails::Generators::Base
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
@source_root ||= SirTrevorRails::Engine.root
|
9
|
+
end
|
10
|
+
|
11
|
+
def views
|
12
|
+
directory "app/views/sir_trevor"
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module SirTrevorRails
|
4
|
+
class Block < OpenStruct
|
5
|
+
|
6
|
+
def self.from_hash(hash, parent)
|
7
|
+
hash = hash.deep_dup
|
8
|
+
self.type_klass(hash).new(hash, parent)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(hash, parent)
|
12
|
+
@as_json = hash
|
13
|
+
@parent = parent
|
14
|
+
@type = hash[:type].to_sym
|
15
|
+
|
16
|
+
super(hash[:data])
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :parent, :type, :as_json
|
20
|
+
|
21
|
+
def to_partial_path
|
22
|
+
"sir_trevor/blocks/" << self.class.name.demodulize.underscore
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Infers the block class.
|
28
|
+
# Safe lookup that tries to identify user created block class.
|
29
|
+
#
|
30
|
+
# @param [Symbol] type
|
31
|
+
def self.block_class(type)
|
32
|
+
block_name = "#{type.to_s.camelize}Block"
|
33
|
+
begin
|
34
|
+
block_name.constantize
|
35
|
+
rescue NameError
|
36
|
+
block_class!(block_name)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Infers the block class.
|
41
|
+
# Failover from block_class.
|
42
|
+
# Safe lookup against the SirTevor::Blocks namespace
|
43
|
+
# If no block is found, create one with given name and inherit from Block class
|
44
|
+
#
|
45
|
+
# @param [Constant] block_name
|
46
|
+
def self.block_class!(block_name)
|
47
|
+
begin
|
48
|
+
SirTrevorRails::Blocks.const_get(block_name)
|
49
|
+
rescue NameError
|
50
|
+
SirTrevorRails::Blocks.const_set(block_name, Class.new(Block))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.type_klass(hash)
|
55
|
+
if self == Block
|
56
|
+
block_class(hash[:type].to_sym)
|
57
|
+
else
|
58
|
+
self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SirTrevorRails
|
2
|
+
class BlockArray < Array
|
3
|
+
|
4
|
+
def self.from_json(str, parent = nil)
|
5
|
+
blocks = MultiJson.load(str, symbolize_keys: true)
|
6
|
+
blocks = blocks[:data] if blocks.is_a?(Hash)
|
7
|
+
blocks.map! { |block_obj| SirTrevorRails::Block.from_hash(block_obj, parent) }
|
8
|
+
new blocks
|
9
|
+
end
|
10
|
+
|
11
|
+
def has_block_of_type?(type)
|
12
|
+
klass = Block.block_class(type)
|
13
|
+
any? { |b| b.is_a? klass }
|
14
|
+
end
|
15
|
+
|
16
|
+
def first_block_of_type(type)
|
17
|
+
klass = Block.block_class(type)
|
18
|
+
detect { |b| b.is_a? klass }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'twitter-text'
|
2
|
+
|
3
|
+
module SirTrevorRails
|
4
|
+
module Blocks
|
5
|
+
class TweetBlock < SirTrevorRails::Block
|
6
|
+
|
7
|
+
include ActionView::Helpers::SanitizeHelper
|
8
|
+
|
9
|
+
def render_tweet_body
|
10
|
+
sanitize Twitter::Autolink.auto_link(
|
11
|
+
self.text,
|
12
|
+
url_entities: (self.entities.values_at(:urls, :media).flatten.compact.uniq rescue nil)
|
13
|
+
), tags: %w{a span}, attributes: %w{class href rel target}
|
14
|
+
end
|
15
|
+
|
16
|
+
def profile_url
|
17
|
+
"//twitter.com/" << self.user[:screen_name]
|
18
|
+
end
|
19
|
+
|
20
|
+
def screen_name
|
21
|
+
self.user[:screen_name]
|
22
|
+
end
|
23
|
+
|
24
|
+
def at_name
|
25
|
+
"@" << screen_name
|
26
|
+
end
|
27
|
+
|
28
|
+
def profile_image_url(size="bigger")
|
29
|
+
"//twitter.com/api/users/profile_image/" << self.user[:screen_name] <<
|
30
|
+
"?size=" << size
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|