embed_me 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eba667022e999ab1bc98f4321e5a54b4725ed38dc14ea829b89e22938b3d083b
4
- data.tar.gz: 67ec8ebc91cc0902b41b1c3f51bffe5f556016a0984dfcfcc440aca29238d9b5
3
+ metadata.gz: d6f50516697162b7dcf6b4a49f3abcf291e8610c306a2571289824beb0bd378b
4
+ data.tar.gz: 6f4a52b64c264725018780c7e6d3b4c1653e8ccaa893bf3863204970893062de
5
5
  SHA512:
6
- metadata.gz: c6e25e412a79552e4cad0cb81d32813f7ebab05af3aa3dea241a0e38855bf3cadc5b1f2e0a830edd2b74aba81fe3903bfacb2284c5aee01d40009f8a49aa9689
7
- data.tar.gz: 40fdf41e6dec1bbac477744f6e10b553e411a4b2e21235bd46f12c0c486bb113ec78588a796e37e1675b5f6142be912b2c0635599b6e81efba3f2267e968f03f
6
+ metadata.gz: baabfddd2f40a97cad3a0b1bf3d029c56f970a5933d84fd3dd849967c9da99eaab3690375cee43aff4da5488e5a229a06c43bb691adfab9a758fe0dbd0957dad
7
+ data.tar.gz: 991cb1bc03f6fc67039a158cee8156f414a2e2f0b63a3e13f7ffb5f862548debc53e189a6a34961a34ff0406cfba22c72abd207cc9d070026b8a9ce788db1e1f
data/README.md CHANGED
@@ -1,8 +1,24 @@
1
1
  # EmbedMe
2
- Short description and motivation.
2
+ EmbedMe allows you and your users to easily embed your rails application or parts of it on other websites.
3
+
4
+
5
+ ## Use Cases
6
+
7
+ ### YouTube
8
+ YouTube has offered this feature for years. Users have the option to embed a video from YouTube on their own blog or website. While normal YouTube content (www.youtube.com/watch?v=) is blocked by the X-Frame options, content via a YouTube Embed URL (www.youtube.com/embed/...) can be displayed in a frame. If a video is opened in a frame, the appearance is optimized so that it works well in a frame (no ratings, no comments, only video). Although YouTube does not use this gem for this function, the way this gem works is adapted accordingly.
9
+
10
+ ![EmbedMe example use case (YouTube) for embedding in rails](images/embed_me-example-use-case-youtube-1.png)
11
+
12
+ ![EmbedMe example use case (YouTube) for embedding in rails](images/embed_me-example-use-case-youtube-2.png)
13
+
14
+
15
+ ### Other Examples
16
+ Similar functions are also available on Twitter, Instagram, Google Maps and many other sites.
17
+
18
+ ![EmbedMe example use case (Instagram) for embedding in rails](images/embed_me-example-use-case-instagram.png)
19
+
20
+ ![EmbedMe example use case (Twitter) for embedding in rails](images/embed_me-example-use-case-twitter.png)
3
21
 
4
- ## Usage
5
- How to use my plugin.
6
22
 
7
23
  ## Installation
8
24
  Add this line to your application's Gemfile:
@@ -21,8 +37,141 @@ Or install it yourself as:
21
37
  $ gem install embed_me
22
38
  ```
23
39
 
24
- ## Contributing
25
- Contribution directions go here.
40
+
41
+ ## Usage
42
+
43
+ ### Define Embeddable Routes
44
+
45
+ Define Resources that should be embeddable. The routes defined within the block are transferred to the application in duplicated form. Once normally, as they would always work, and once under an embed scope. The name of the scope can be set in config (default: 'embed'). All paths under the embed scope are sent without X-Frames-Options header, so they can be displayed in a frame. All other paths are sent normally (Rails default X-Frames-Options = SAMEORIGIN).
46
+
47
+ Assuming the following route definition:
48
+
49
+ ```ruby
50
+ get 'private', to: 'application#private'
51
+ embeddable do
52
+ get 'embeddable', to: 'application#embeddable'
53
+ end
54
+ ```
55
+
56
+ Will produce following routes:
57
+
58
+ ```
59
+ path_private GET /path_private(.:format) application#path_private
60
+ path_embed GET /path_embed(.:format) application#path_embed
61
+ embed_path_embed GET /embed/path_embed(.:format) application#path_embed {:embedded=>true}
62
+ ```
63
+
64
+ To change the embed scope name, simply create a new initializer at `config/initializers/embed_me.rb` and put this content in it:
65
+
66
+ ```ruby
67
+ EmbedMe.scope_name = :whatever
68
+ ```
69
+
70
+ ### Adjust Behaviour of Application
71
+
72
+ To customize the behavior of the application depending on the state of the embedding, you can use `embedded?`. This function returns true if the request was made via an embedding and false if it was a normal request.
73
+
74
+ In the following example, the Output is rendered with the default View at path `app/views/photos/show.html.erb`. However, if the request is embedded, a view at path `app/views/photos/embedded.html.erb` is rendered, which displays only the most important information (e.g. the photo in full screen).
75
+
76
+ ```ruby
77
+ # GET /photos/1
78
+ def show
79
+ @photo = Photo.find_by(id: params[:id])
80
+ render "embedded" if embedded?
81
+ end
82
+ ```
83
+
84
+ ### Provide Embed-Code
85
+
86
+ You may want to show the user of your application the code to include the resource. There are several ways to accomplish this, depending on whether you want to define the code and appearance yourself. Use the following functions depending on your preference. Feel free to define the interface and the code completely yourself.
87
+
88
+ #### Default Frontend
89
+
90
+ To get the default interface, use the function `embed_frontend`, which returns an HTML button to open a basic pop-up that allows the user of the web page to copy the embedding code. The default design can be overridden with a file at `app/views/embed_me/_embed_frontend.html.erb`.
91
+
92
+ ```html
93
+ <div class="container-fluid d-flex align-items-center">
94
+ <!-- some frontend stuff -->
95
+ <%= embed_frontend %>
96
+ </div>
97
+ ```
98
+
99
+ Default Popup will look like this:
100
+
101
+ ![EmbedMe default popup to embed rails resource](images/embed_me-default-popup.png)
102
+
103
+ #### Default Embedding Code
104
+
105
+ If you want to implement the interface yourself, you can still use the default embedding code. Use the function `embed_code` for this, which generates some HTML code that allows embedding of the resource of the current request. Creates an iframe element with the embed link as src attribute. HTML options can be customized. Returns `nil` if the current page is not embeddable.
106
+
107
+ ```ruby
108
+ embed_code()
109
+ # => "<iframe width="560" height="315" src="http://localhost:3000/embed" frameborder="0" sandbox="">Your Browser does not support HTML iFrame Element.</iframe>"
110
+
111
+ embed_code(fallback: "")
112
+ # => "<iframe width="560" height="315" src="http://localhost:3000/embed" frameborder="0" sandbox=""></iframe>"
113
+
114
+ embed_code(width: 760, height: 500)
115
+ # => "<iframe width="760" height="500" src="http://localhost:3000/embed" frameborder="0" sandbox="">Your Browser does not support HTML iFrame Element.</iframe>"
116
+
117
+ embed_code(width: nil, height: nil)
118
+ # => "<iframe src="http://localhost:3000/embed" frameborder="0" sandbox="">Your Browser does not support HTML iFrame Element.</iframe>"
119
+ ```
120
+
121
+ ### Adjust Links on embeddable Pages
122
+
123
+ If there is a link to a route within an embeddable page that is not available in an Embedding, the user will receive an error message "Refused to connect". You may want to check exactly which links must be present in an embeddable page. You can use the following link helpers for this purpose.
124
+
125
+ #### Embeddable Link To
126
+
127
+ Creates an HTML link element. To do this, it checks whether the request comes from an embedded resource and whether there is an embedded version of the requested route. If both are true, a link is generated that redirects to the embedded version. If no embedded version of the route exists, but the request is within an embedding, the link will be opened in a new tab. If the request is not embedded, the link is created as normal.
128
+
129
+ Assuming the current request is NOT embedded, then:
130
+
131
+ ```ruby
132
+ embeddable_link_to("Not Embeddable", private_path)
133
+ # => <a href="/private">Not Embeddable</a>
134
+
135
+ embeddable_link_to("Embeddable", embeddable_path)
136
+ # => <a href="/embeddable">Embeddable</a>
137
+ ```
138
+
139
+ Assuming the current request IS embedded, then:
140
+
141
+ ```ruby
142
+ embeddable_link_to("Not Embeddable", private_path)
143
+ # => <a target="_blank" href="/private">Not Embeddable</a>
144
+
145
+ embeddable_link_to("Embeddable", embeddable_path)
146
+ # => <a href="/embed/embeddable">Embeddable</a>
147
+ ```
148
+
149
+ #### Embedded Link Available?
150
+
151
+ Checks whether there is an embedded version of a specific route.
152
+
153
+ ```ruby
154
+ embedded_link_available?(private_path)
155
+ # => false
156
+
157
+ embedded_link_available?(embeddable_path)
158
+ # => true
159
+ ```
160
+
161
+ #### Current Page Embed URL
162
+
163
+ Checks if there is an embedded version for the current request. If this is the case, the link to the embedded version is returned. If there is no embedded version, nil is returned.
164
+
165
+ ```ruby
166
+ # (request on embeddable_path)
167
+ current_page_embed_url()
168
+ # => http://localhost:3000/embed/embeddable
169
+
170
+ # (request on private_path)
171
+ current_page_embed_url()
172
+ # => nil
173
+ ```
174
+
26
175
 
27
176
  ## License
28
177
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,4 +1,4 @@
1
- module EmbedMe
1
+ module EmbedMe # :nodoc: all
2
2
  class ApplicationController < ActionController::Base
3
3
  protect_from_forgery with: :exception
4
4
  end
@@ -1,4 +1,4 @@
1
- module EmbedMe
1
+ module EmbedMe # :nodoc: all
2
2
  module ApplicationHelper
3
3
  end
4
4
  end
@@ -1,4 +1,4 @@
1
- module EmbedMe
1
+ module EmbedMe # :nodoc: all
2
2
  class ApplicationJob < ActiveJob::Base
3
3
  end
4
4
  end
@@ -1,4 +1,4 @@
1
- module EmbedMe
1
+ module EmbedMe # :nodoc: all
2
2
  class ApplicationMailer < ActionMailer::Base
3
3
  default from: 'from@example.com'
4
4
  layout 'mailer'
@@ -1,4 +1,4 @@
1
- module EmbedMe
1
+ module EmbedMe # :nodoc: all
2
2
  class ApplicationRecord < ActiveRecord::Base
3
3
  self.abstract_class = true
4
4
  end
@@ -0,0 +1,167 @@
1
+
2
+ <script type="text/javascript">
3
+ function openEmbedPopup() {
4
+ var embedMeElement = document.getElementById("embed-me-code-popup");
5
+ embedMeElement.style.visibility = "initial";
6
+ }
7
+ function closeEmbedPopup() {
8
+ var embedMeElement = document.getElementById("embed-me-code-popup");
9
+ embedMeElement.style.visibility = "hidden";
10
+ }
11
+ function copyEmbedCode(inputId) {
12
+ var copyText = document.getElementById(inputId);
13
+ copyText.select();
14
+ copyText.setSelectionRange(0, 99999);
15
+ document.execCommand("copy");
16
+ }
17
+ </script>
18
+
19
+ <style>
20
+ .embed-me-code-popup * {
21
+ box-sizing: border-box;
22
+ }
23
+ .embed-me-code-popup {
24
+ position: absolute;
25
+ width: 100vw;
26
+ height: 100vh;
27
+ top: 0; right: 0; bottom: 0; left: 0;
28
+ overflow: hidden;
29
+ display: flex;
30
+ flex-direction: column;
31
+ justify-content: center;
32
+ align-items: center;
33
+ visibility: hidden;
34
+ }
35
+ .embed-me-code-popup .embed-me-background {
36
+ background-color: rgba(0,0,0,0.5);
37
+ position: absolute;
38
+ width: 100%;
39
+ height: 100%;
40
+ }
41
+ .embed-me-code-popup .card {
42
+ position: relative;
43
+ display: flex;
44
+ flex-direction: column;
45
+ min-width: 0;
46
+ word-wrap: break-word;
47
+ background-color: #ffffff;
48
+ background-clip: border-box;
49
+ border: 1px solid rgba(0,0,0,.125);
50
+ border-radius: .25rem;
51
+ max-width: 700px;
52
+ }
53
+ .embed-me-code-popup .card-body {
54
+ flex: 1 1 auto;
55
+ padding: 1rem 1rem;
56
+ }
57
+ .embed-me-code-popup .card-title {
58
+ margin-bottom: .5rem;
59
+ font-size: 1.25rem;
60
+ margin-top: 0;
61
+ font-weight: 500;
62
+ line-height: 1.2;
63
+ }
64
+ .embed-me-code-popup .card-text {
65
+ margin-top: 0;
66
+ margin-bottom: 1rem;
67
+ font-size: 1rem;
68
+ }
69
+ .embed-me-code-popup .input-group {
70
+ margin-bottom: 1rem;
71
+ position: relative;
72
+ display: flex;
73
+ flex-wrap: wrap;
74
+ align-items: stretch;
75
+ width: 100%;
76
+ }
77
+ .embed-me-code-popup .input-group>:not(:last-child) {
78
+ border-top-right-radius: 0;
79
+ border-bottom-right-radius: 0;
80
+ }
81
+ .embed-me-code-popup .input-group>:not(:first-child) {
82
+ margin-left: -1px;
83
+ border-top-left-radius: 0;
84
+ border-bottom-left-radius: 0;
85
+ }
86
+ .embed-me-code-popup .input-group .embed-me-btn {
87
+ position: relative;
88
+ z-index: 2;
89
+ }
90
+ .embed-me-code-popup .form-control {
91
+ display: block;
92
+ padding: .375rem .75rem;
93
+ font-size: 1rem;
94
+ font-weight: 400;
95
+ line-height: 1.5;
96
+ color: #212529;
97
+ background-color: #fff;
98
+ background-clip: padding-box;
99
+ border: 1px solid #ced4da;
100
+ -webkit-appearance: none;
101
+ -moz-appearance: none;
102
+ appearance: none;
103
+ border-radius: .25rem;
104
+ transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
105
+ margin: 0;
106
+ position: relative;
107
+ flex: 1 1 auto;
108
+ width: 1%;
109
+ min-width: 0;
110
+ }
111
+ .embed-me-code-popup .text-muted {
112
+ color: #6c757d;
113
+ }
114
+
115
+ .embed-me-btn {
116
+ display: inline-block;
117
+ font-weight: 400;
118
+ line-height: 1.5;
119
+ color: #212529;
120
+ text-align: center;
121
+ text-decoration: none;
122
+ vertical-align: middle;
123
+ cursor: pointer;
124
+ -webkit-user-select: none;
125
+ -moz-user-select: none;
126
+ user-select: none;
127
+ background-color: transparent;
128
+ border: 1px solid transparent;
129
+ padding: .375rem .75rem;
130
+ font-size: 1rem;
131
+ border-radius: .25rem;
132
+ transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
133
+ text-transform: none;
134
+ margin: 0;
135
+ font-family: inherit;
136
+ }
137
+ .embed-me-btn-secondary {
138
+ color: #fff;
139
+ background-color: #6c757d;
140
+ border-color: #6c757d;
141
+ }
142
+ .embed-me-btn-outline-secondary {
143
+ color: #6c757d;
144
+ border-color: #6c757d;
145
+ }
146
+
147
+ </style>
148
+
149
+ <button class="embed-me-code-button embed-me-btn embed-me-btn-secondary" type="button" onclick="openEmbedPopup()">Embed</button>
150
+ <div class="embed-me-code-popup" id="embed-me-code-popup">
151
+ <div class="embed-me-background" onclick="closeEmbedPopup()"></div>
152
+ <div class="card">
153
+ <div class="card-body">
154
+ <h5 class="card-title">Copy Embed Code</h5>
155
+ <p class="card-text">You can embed this resource into your own website. To do so, either use the code generated by us, or use the link and tweak the rest to your preferences. Copy the respective code or link below.</p>
156
+ <div class="input-group mb-3">
157
+ <input type="text" class= "form-control text-muted" id ="embed-me-code" name="embed-me-code" readonly value="<%= embed_code %>">
158
+ <button class="embed-me-btn embed-me-btn-outline-secondary" type="button" onclick="copyEmbedCode('embed-me-code')">Copy</button>
159
+ </div>
160
+ <div class="input-group mb-3">
161
+ <input type="text" class= "form-control text-muted" id ="embed-me-link" name="embed-me-link" readonly value="<%= current_page_embed_url %>">
162
+ <button class="embed-me-btn embed-me-btn-outline-secondary" type="button" onclick="copyEmbedCode('embed-me-link')">Copy</button>
163
+ </div>
164
+ <button type="button" class="embed-me-btn embed-me-btn-secondary" onclick="closeEmbedPopup()">Close</button>
165
+ </div>
166
+ </div>
167
+ </div>
@@ -38,5 +38,12 @@ module EmbedMe
38
38
  element = content_tag(:iframe, fallback, default_html)
39
39
  "#{element}"
40
40
  end
41
+
42
+ # Returns an HTML button to open a basic pop-up that allows the user of the web page to copy
43
+ # the embedding code. The default design can be overridden with a file at
44
+ # app/views/embed_me/_embed_frontend.html.erb.
45
+ def embed_frontend(options = {})
46
+ render "embed_me/embed_frontend"
47
+ end
41
48
  end
42
49
  end
@@ -1,9 +1,11 @@
1
1
  module ActionDispatch::Routing
2
2
  class Mapper
3
- # Enables the definition of resources that should be embeddable. The routes defined
3
+ # Define Resources that should be embeddable. The routes defined
4
4
  # within the block are transferred to the application in duplicated form. Once
5
5
  # normally, as they would always work, and once under an embed scope. The name of
6
- # the scope can be set in config (default: 'embed').
6
+ # the scope can be set in config (default: 'embed'). All paths under the embed
7
+ # scope are sent without X-Frames-Options header, so they can be displayed in a frame.
8
+ # All other paths are sent normally (Rails default X-Frames-Options = SAMEORIGIN).
7
9
  #
8
10
  # ==== Examples
9
11
  # Assuming the following route definition:
@@ -1,3 +1,3 @@
1
1
  module EmbedMe
2
- VERSION = '0.1.2'
2
+ VERSION = '0.1.3'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embed_me
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Bohn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-19 00:00:00.000000000 Z
11
+ date: 2021-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -62,6 +62,7 @@ files:
62
62
  - app/jobs/embed_me/application_job.rb
63
63
  - app/mailers/embed_me/application_mailer.rb
64
64
  - app/models/embed_me/application_record.rb
65
+ - app/views/embed_me/_embed_frontend.html.erb
65
66
  - app/views/layouts/embed_me/application.html.erb
66
67
  - config/routes.rb
67
68
  - lib/embed_me.rb