lazy_mobile_tester 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 91a370c3efc9387fc47016c4cd8a95cb13a667d65d8a7f92ebdcd0b09d8e7e9c
4
+ data.tar.gz: 29f2b0d1e1c2b140aab00e4bdf0c5560a76eec2b7f05dda6b870db553c6c233a
5
+ SHA512:
6
+ metadata.gz: b0162b5b27538ba298dfb18bbd019374711cb3e66ddd819955f09520e5310c853f8e90509c5edbfea36089e1290c50e6395547fd4e8e063c0d070e867a72afa8
7
+ data.tar.gz: f911088e71a971d961aaac601a884df5fce983479a7944a0f0fe869201649c488ee3aea6973b779b100f06d7aa5ac4206bdc5fae24971a3c142a26c708dbb029
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2022 Igor Kasyanchuk
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.md ADDED
@@ -0,0 +1,50 @@
1
+ # Lazy Mobile Tester
2
+
3
+ "Laziness is the mother of progress" :)
4
+
5
+ We all know that we can use Chrome Dev Tools to check how app looks on a different resolutions.
6
+
7
+ But opening this tool, clicking, changing resolutions... It's just too many actions.
8
+
9
+ I'm as developer want an easy way to check how webpage looks on a different resolutions. With a simple click.
10
+
11
+ This is why I've created a simple gem which opens webpage in iframe and allows you to change width of it.
12
+
13
+ ## Usage
14
+
15
+ There are two ways how to use it:
16
+
17
+ 1) with button in top left corner to open page in IFRAME. To do this add in your layout inside body tag:
18
+
19
+ ```erb
20
+ <%= lazy_mobile_tester_button if defined?(LazyMobileTester) %>
21
+ ```
22
+
23
+ 2) add a parameter to any URL `?_lazy=1` and open it. For example - `instead of /users just open /users??_lazy=1`
24
+
25
+
26
+ ## Installation
27
+
28
+ Add this line to your application's Gemfile:
29
+
30
+ ```ruby
31
+ gem "lazy_mobile_tester"
32
+ ```
33
+
34
+ And then execute:
35
+ ```bash
36
+ $ bundle
37
+ ```
38
+
39
+ ## Contributing
40
+
41
+ You are welcome to contribute.
42
+
43
+ ## TODO
44
+
45
+ - tests?
46
+ - any other ideas?
47
+
48
+ ## License
49
+
50
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1,188 @@
1
+ <title>Lazy Mobile Tester :)</title>
2
+
3
+ <style>
4
+ :root {
5
+ --toolbar-height: 26px;
6
+ }
7
+ body {
8
+ margin: 0;
9
+ padding: 0;
10
+ background: #0f172a;
11
+ text-align: center;
12
+ font-family: Arial;
13
+ }
14
+
15
+ #lazy_mobile_tester_iframe {
16
+ margin: 0;
17
+ padding: 0;
18
+ width: 100%;
19
+ border: 0;
20
+ height: calc(100vh - var(--toolbar-height) - 10px);
21
+ }
22
+
23
+ #lazy_mobile_tester_panel {
24
+ margin: 0;
25
+ padding: 0;
26
+ padding: 2px 0;
27
+ width: 100%;
28
+ background: #334155;
29
+ height: var(--toolbar-height);
30
+ color: white;
31
+ }
32
+
33
+ #info {
34
+ color: white;
35
+ font-size: 12px;
36
+ }
37
+
38
+ #url {
39
+ width: 300px;
40
+ }
41
+
42
+ #copied {
43
+ visibility: hidden;
44
+ color: lime;
45
+ font-size: 12px;
46
+ }
47
+
48
+ button {
49
+ background: rgb(99, 102, 241);
50
+ color: white;
51
+ border: 0 none;
52
+ cursor: pointer;
53
+ }
54
+
55
+ button:disabled {
56
+ background: #333;
57
+ color: #999;
58
+ cursor: auto;
59
+ }
60
+
61
+ #close_button {
62
+ background: red;
63
+ }
64
+
65
+ input {
66
+ font-size: 12px;
67
+ }
68
+ </style>
69
+
70
+ <script type="module">
71
+ import { Application, Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"
72
+ window.Stimulus = Application.start()
73
+
74
+ Stimulus.register("toolbar", class extends Controller {
75
+ static targets = [ "iframe", "rotate_button", "info", "url", "copied" ]
76
+ static values = { rotated: {type: Boolean, default: false}, w: String, h: String, rotate: {type: Boolean, default: false} }
77
+
78
+ connect() {
79
+ if(localStorage.getItem("rotateValue") !== null && localStorage.getItem("rotatedValue") !== null) {
80
+ this.rotateValue = localStorage.getItem("rotateValue");
81
+ this.rotatedValue = localStorage.getItem("rotatedValue");
82
+ }
83
+ this.paint();
84
+ }
85
+
86
+ screen({params}) {
87
+ this.wValue = params.w;
88
+ this.hValue = params.h;
89
+ this.rotateValue = params.rotate;
90
+ this.rotatedValue = false;
91
+
92
+ this.storeSize();
93
+ this.paint();
94
+ }
95
+
96
+ storeSize() {
97
+ const { w, h } = this.size();
98
+ localStorage.w = w;
99
+ localStorage.h = h;
100
+ localStorage.rotateValue = this.rotateValue;
101
+ localStorage.rotatedValue = this.rotatedValue;
102
+ }
103
+
104
+ rotate() {
105
+ this.rotatedValue = !this.rotatedValue;
106
+ this.storeSize();
107
+ this.paint();
108
+ }
109
+
110
+ close() {
111
+ window.location.href = this.iframeTarget.contentWindow.location.href;
112
+ }
113
+
114
+ iframeonload() {
115
+ this.urlTarget.value = this.iframeTarget.contentWindow.location.href;
116
+ this.urlTarget.scrollLeft = this.urlTarget.scrollWidth;
117
+ }
118
+
119
+ size() {
120
+ if (this.rotatedValue && this.rotateValue) {
121
+ return { "w": this.hValue, "h": this.wValue }
122
+ } else {
123
+ return { "w": this.wValue, "h": this.hValue }
124
+ }
125
+ }
126
+
127
+ copy(event) {
128
+ if (this.urlTarget.value == "") {
129
+ return;
130
+ }
131
+
132
+ event.preventDefault()
133
+ this.urlTarget.select();
134
+ document.execCommand("copy");
135
+ this.copiedTarget.style.visibility = "visible";
136
+ setTimeout(() => {
137
+ this.copiedTarget.style.visibility = "hidden";
138
+ }, 800)
139
+ }
140
+
141
+ paint() {
142
+ const { w, h } = this.size();
143
+ this.iframeTarget.style.width = (localStorage.getItem("w") === null) ? w : localStorage.w;
144
+ this.iframeTarget.style.height = (localStorage.getItem("h") === null) ? h : localStorage.h;
145
+ this.rotate_buttonTarget.disabled = !this.rotateValue;
146
+
147
+ const { width, height } = this.iframeTarget.getBoundingClientRect();
148
+ this.infoTarget.innerHTML = parseInt(width) + "x" + parseInt(height)
149
+ }
150
+
151
+ })
152
+ </script>
153
+
154
+ <div data-controller="toolbar" id="lazy_mobile_tester">
155
+ <div id="lazy_mobile_tester_panel">
156
+ <input type='text' data-toolbar-target="url" id="url" readonly data-action="focus->toolbar#copy"/>
157
+ <span id="copied" data-toolbar-target="copied">Copied</span>
158
+ &nbsp;
159
+ &nbsp;
160
+ &nbsp;
161
+ <% LazyMobileTester.resolutions.each do |k, resolution| %>
162
+ <button data-action="click->toolbar#screen" data-toolbar-w-param="<%= resolution[:w] %>" data-toolbar-h-param="<%= resolution[:h] %>" data-toolbar-rotate-param="<%= resolution[:rotate] %>"><%= k %></button>
163
+ <% end %>
164
+ &nbsp;
165
+ &nbsp;
166
+ &nbsp;
167
+ <button data-action="click->toolbar#rotate" data-toolbar-target="rotate_button" disabled>&orarr; Rotate</button>
168
+ &nbsp;
169
+ &nbsp;
170
+ &nbsp;
171
+ <span data-toolbar-target="info" id="info"></span>
172
+ <!--
173
+ &nbsp;
174
+ &nbsp;
175
+ &nbsp;
176
+ URI: <%= @uri %>
177
+ &nbsp;
178
+ &nbsp;
179
+ &nbsp;
180
+ URL: <%= @url %>
181
+ -->
182
+ &nbsp;
183
+ &nbsp;
184
+ &nbsp;
185
+ <button data-action="click->toolbar#close" id="close_button">&cross; Close</button>
186
+ </div>
187
+ <iframe data-action="load->toolbar#iframeonload" data-toolbar-target="iframe" id="lazy_mobile_tester_iframe" frameborder="0" seamless="seamless" src="<%= @uri %>"></iframe>
188
+ </div>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,16 @@
1
+ module LazyMobileTester
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace LazyMobileTester
4
+
5
+ initializer "lazy_mobile_tester.middleware" do |app|
6
+ next unless LazyMobileTester.enabled
7
+ app.middleware.insert_before ActionDispatch::HostAuthorization, LazyMobileTester::Middleware
8
+ end
9
+
10
+ initializer 'lazy_mobile_tester.helpers' do
11
+ ActiveSupport.on_load :action_view do
12
+ include LazyMobileTester::Helper
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module LazyMobileTester
2
+ module Helper
3
+ IMG = "<img width='16' height='16' src='data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSI0NjcuMzgiIGlkPSJzdmczNiIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgNDY3LjM5ODAxIDQ2Ny4zOCIgd2lkdGg9IjQ2Ny4zOTgwMSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnMgaWQ9ImRlZnM0MCIvPjxnIGlkPSJMY2RfV2l0aF9UYWJsZXRfYW5kX21vYmlsZV9pY29uIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjIuMzAxLC0yMi4zMSkiPjxnIGlkPSJnMzIiPjxwYXRoIGQ9Im0gMjU2LjAwMSwyMi4zMSBjIDEyOS4xMjEsMCAyMzMuNjk4LDEwNC45MTEgMjMzLjY5OCwyMzMuNjkgMCwxMjkuMTEzIC0xMDQuNTc3LDIzMy42OSAtMjMzLjY5OCwyMzMuNjkgLTEyOS4xMTgsMCAtMjMzLjcsLTEwNC41NzcgLTIzMy43LC0yMzMuNjkgMCwtMTI4Ljc3OSAxMDQuNTgyLC0yMzMuNjkgMjMzLjcsLTIzMy42OSB6IiBpZD0icGF0aDQiIHN0eWxlPSJjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNmZDg0Njk7ZmlsbC1ydWxlOmV2ZW5vZGQiLz48cGF0aCBkPSJtIDQ3Mi41NSwxNjguMjM4IGMgMTEuMDk5LDI3LjIzNyAxNy4xNDksNTYuODIyIDE3LjE0OSw4Ny43NjIgMCwxMjkuMTEzIC0xMDQuNTc3LDIzMy42OSAtMjMzLjY5OCwyMzMuNjkgLTQuMzY2LDAgLTguNDA4LDAgLTEyLjc3NCwtMC4zMjQgTCA5NS4yNzUsMzc1LjAzNSBjIDAsLTM3LjY1OCAtMC4zMzQsLTgwLjAzMSAtMC4zMzQsLTExNy42ODkgMCwtNS4wMzkgNC4wMjcsLTkuMDc2IDguNzQyLC05LjA3NiA1LjcxMiwwIDExLjA5NCwwIDE2LjQ3MiwwIDAsLTQzLjA1IDAsLTg2LjQxNiAwLC0xMjkuOCBsIDI4Ny44NDMsLTMuMDI1IGMgMS42OCwzLjAyNCA2My4yMDYsNTIuNzkzIDY0LjU1Miw1Mi43OTMgeiIgaWQ9InBhdGg2IiBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojZTQ3NzVmO2ZpbGwtcnVsZTpldmVub2RkIi8+PHBhdGggZD0ibSAzMTkuODkzLDM1NS44NjIgaCAtMTE1LjM0IGMgLTQuMzY2LDAgLTcuNzM1LC0zLjM1IC03LjczNSwtNy4zODYgdiAwIGMgMCwtNC4zODEgMy4zNjksLTcuNzMgNy43MzUsLTcuNzMgaCAxMTUuMzQgYyA0LjAzNywwIDcuNzMsMy4zNSA3LjczLDcuNzMgdiAwIGMgMCw0LjAzNyAtMy42OTMsNy4zODYgLTcuNzMsNy4zODYgeiIgaWQ9InBhdGg4IiBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojMzI0YTVlO2ZpbGwtcnVsZTpldmVub2RkIi8+PHJlY3QgaGVpZ2h0PSI0MC4wMjUwMDIiIGlkPSJyZWN0MTAiIHN0eWxlPSJjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiMyMTMxM2U7ZmlsbC1ydWxlOmV2ZW5vZGQiIHdpZHRoPSI2MS44NzMwMDEiIHg9IjIzMS4xMTciIHk9IjMwMC43MjEwMSIvPjxyZWN0IGhlaWdodD0iMjAxLjA4IiBpZD0icmVjdDEyIiBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojMzI0YTVlO2ZpbGwtcnVsZTpldmVub2RkIiB3aWR0aD0iMjkxLjU0MDk5IiB4PSIxMTYuNDU3IiB5PSIxMTUuNDQ0Ii8+PHJlY3QgaGVpZ2h0PSIxNjAuNzEyMDEiIGlkPSJyZWN0MTQiIHN0eWxlPSJjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNmZmZmZmY7ZmlsbC1ydWxlOmV2ZW5vZGQiIHdpZHRoPSIyNTEuMTgyMDEiIHg9IjEzNi42MzIiIHk9IjEzNS42MzgiLz48cGF0aCBkPSJtIDQxNS4wNDEsMjU5LjM2OSBoIC02My44ODUgdiAxMDAuNTMgaCA2My44ODUgeiBNIDM4Ny40NzksMzY3LjYzIGMgMCwtMi42ODIgLTIuMDE0LC00LjY5NSAtNC4zNzEsLTQuNjk1IC0yLjM1NywwIC00LjM3MSwyLjAxNCAtNC4zNzEsNC42OTUgMCwyLjM1NyAyLjAxNCw0LjM3MSA0LjM3MSw0LjM3MSAyLjM1NywwIDQuMzcxLC0yLjAxNCA0LjM3MSwtNC4zNzEgeiBNIDM3Mi42ODcsMjUyLjk4NCBjIDAsMC42NjggMC4zMzQsMS4wMDIgMS4wMDIsMS4wMDIgaCAxOC44MjkgYyAwLjMzNSwwIDEuMDAzLC0wLjMzNCAxLjAwMywtMS4wMDIgMCwtMC42NzggLTAuNjY4LC0xLjAxMiAtMS4wMDMsLTEuMDEyIGggLTE4LjgyOSBjIC0wLjY2OCwwLjAwMSAtMS4wMDIsMC4zMzUgLTEuMDAyLDEuMDEyIHogbSA0OC40MTQsMS4zMzYgdiAxMTMuMzEgYyAwLDQuNzE0IC00LjAzNyw4Ljc1MSAtOC43NDEsOC43NTEgaCAtNTguNTAyIGMgLTQuNzE1LDAgLTguNzQyLC00LjAzNyAtOC43NDIsLTguNzUxIFYgMjU0LjMyIGMgMCwtNC43MDUgNC4wMjcsLTguNzMyIDguNzQyLC04LjczMiBoIDU4LjUwMiBjIDQuNzAzLDAgOC43NDEsNC4wMjcgOC43NDEsOC43MzIgeiIgaWQ9InBhdGgxNiIgc3R5bGU9ImNsaXAtcnVsZTpldmVub2RkO2ZpbGw6IzI1MzY0NTtmaWxsLXJ1bGU6ZXZlbm9kZCIvPjxyZWN0IGhlaWdodD0iMTAyLjg4OCIgaWQ9InJlY3QxOCIgc3R5bGU9ImNsaXAtcnVsZTpldmVub2RkO2ZpbGw6I2ZmZmZmZjtmaWxsLXJ1bGU6ZXZlbm9kZCIgd2lkdGg9IjY1LjIzODk5OCIgeD0iMzUwLjQ3OSIgeT0iMjU4LjM1Njk5Ii8+PHBhdGggZD0ibSAzODMuMTA4LDM2Mi45MzUgYyAtMi4zNTcsMCAtNC4zNzEsMi4wMTQgLTQuMzcxLDQuNjk1IDAsMi4zNTcgMi4wMTQsNC4zNzEgNC4zNzEsNC4zNzEgMi4zNTcsMCA0LjM3MSwtMi4wMTQgNC4zNzEsLTQuMzcxIDAsLTIuNjgyIC0yLjAxMywtNC42OTUgLTQuMzcxLC00LjY5NSB6IiBpZD0icGF0aDIwIiBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojZmZmZmZmO2ZpbGwtcnVsZTpldmVub2RkIi8+PHBhdGggZD0ibSAzNzMuNjg4LDI1My45ODYgaCAxOC44MjkgYyAwLjMzNSwwIDEuMDAzLC0wLjMzNCAxLjAwMywtMS4wMDIgMCwtMC42NzggLTAuNjY4LC0xLjAxMiAtMS4wMDMsLTEuMDEyIGggLTE4LjgyOSBjIC0wLjY2OCwwIC0xLjAwMiwwLjMzNCAtMS4wMDIsMS4wMTIgMC4wMDEsMC42NjggMC4zMzUsMS4wMDIgMS4wMDIsMS4wMDIgeiIgaWQ9InBhdGgyMiIgc3R5bGU9ImNsaXAtcnVsZTpldmVub2RkO2ZpbGw6I2ZmZmZmZjtmaWxsLXJ1bGU6ZXZlbm9kZCIvPjxwYXRoIGQ9Im0gMTgxLjAxOSwyNTkuMzY5IGggLTgzLjczIHYgMTAwLjUzIGggODMuNzI5IHYgLTEwMC41MyB6IG0gLTYyLjIwNSwtNi4zODUgYyAwLDAuNjY4IDAuMzM5LDEuMDAyIDEuMDA3LDEuMDAyIGggMzguNjcgYyAwLjY3OCwwIDEuMzQxLC0wLjMzNCAxLjM0MSwtMS4wMDIgMCwtMC42NzggLTAuNjYzLC0xLjAxMiAtMS4zNDEsLTEuMDEyIGggLTM4LjY3IGMgLTAuNjY4LDAuMDAxIC0xLjAwNywwLjMzNSAtMS4wMDcsMS4wMTIgeiBtIDY4LjU4OSwxLjMzNiB2IDExMy4zMSBjIDAsNC43MTQgLTQuMDIzLDguNzUxIC05LjA3MSw4Ljc1MSBIIDk5Ljk3NiBjIC00LjcsMCAtOC43MzcsLTQuMDM3IC04LjczNywtOC43NTEgViAyNTQuMzIgYyAwLC00LjcwNSA0LjAzNywtOC43MzIgOC43MzcsLTguNzMyIGggNzguMzU2IGMgNS4wNDgsMCA5LjA3MSw0LjAyNyA5LjA3MSw4LjczMiB6IiBpZD0icGF0aDI0IiBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojMjUzNjQ1O2ZpbGwtcnVsZTpldmVub2RkIi8+PHBhdGggZD0ibSAxMzkuMzI4LDM2Mi45MzUgYyAtMi42OTYsMCAtNC4zNzEsMi4wMTQgLTQuMzcxLDQuNjk1IDAsMi4zNTcgMS42NzUsNC4zNzEgNC4zNzEsNC4zNzEgMi4zNTMsMCA0LjM2NiwtMi4wMTQgNC4zNjYsLTQuMzcxIDAsLTIuNjgyIC0yLjAxMywtNC42OTUgLTQuMzY2LC00LjY5NSB6IiBpZD0icGF0aDI2IiBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojZmZmZmZmO2ZpbGwtcnVsZTpldmVub2RkIi8+PHBhdGggZD0ibSAxMTkuODIxLDI1My45ODYgaCAzOC42NyBjIDAuNjc4LDAgMS4zNDEsLTAuMzM0IDEuMzQxLC0xLjAwMiAwLC0wLjY3OCAtMC42NjMsLTEuMDEyIC0xLjM0MSwtMS4wMTIgaCAtMzguNjcgYyAtMC42NjgsMCAtMS4wMDcsMC4zMzQgLTEuMDA3LDEuMDEyIDAsMC42NjggMC4zMzksMS4wMDIgMS4wMDcsMS4wMDIgeiIgaWQ9InBhdGgyOCIgc3R5bGU9ImNsaXAtcnVsZTpldmVub2RkO2ZpbGw6I2ZmZmZmZjtmaWxsLXJ1bGU6ZXZlbm9kZCIvPjxyZWN0IGhlaWdodD0iMTAwLjUzIiBpZD0icmVjdDMwIiBzdHlsZT0iY2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojZmZmZmZmO2ZpbGwtcnVsZTpldmVub2RkIiB3aWR0aD0iODMuNzI4OTk2IiB4PSI5Ny4yODkwMDEiIHk9IjI1OS4zNjg5OSIvPjwvZz48L2c+PGcgaWQ9IkxheWVyXzEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMi4zMDEsLTIyLjMxKSIvPjwvc3ZnPg=='/>".html_safe
4
+ SCRIPT = "<script>if (window != window.parent) { document.getElementById('lazy_mobile_tester_button').remove(); } </script>".html_safe
5
+
6
+ def lazy_mobile_tester_button
7
+ button = button_to(IMG, url_for(params.permit!), method: :get, params: { _lazy: 1 }, style: LazyMobileTester.style, id: 'lazy_mobile_tester_button')
8
+ button + SCRIPT
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ module LazyMobileTester
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ dup.call!(env)
9
+ end
10
+
11
+ def call!(env)
12
+ if (env["REQUEST_URI"].include?("/_lazy") || env["REQUEST_URI"].include?("?_lazy")) && env['HTTP_ACCEPT'].to_s.starts_with?("text/html")
13
+ @url = env["REQUEST_PATH"].to_s.gsub(/\/\?_lazy=?1?/, "").presence || "/"
14
+ @uri = env["REQUEST_URI"].to_s.gsub(/\/\?_lazy=?1?/, "").presence || "/"
15
+ @uri = @uri.gsub(/_lazy/, "")
16
+ @uri = "/#{@uri}" unless @uri.starts_with?("/")
17
+
18
+ env["REQUEST_PATH"] = @url
19
+ env["REQUEST_URI"] = @uri
20
+
21
+ [200, [], [ERB.new(template).result(binding)]]
22
+ else
23
+ @status, @headers, @response = @app.call(env)
24
+ [@status, @headers, @response]
25
+ end
26
+ end
27
+
28
+ def template
29
+ File.read("#{File.expand_path(File.dirname(__FILE__))}/../../app/views/lazy_mobile_tester/_toolbar.html.erb")
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module LazyMobileTester
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,58 @@
1
+ require "lazy_mobile_tester/version"
2
+ require "lazy_mobile_tester/middleware"
3
+ require "lazy_mobile_tester/helper"
4
+ require "lazy_mobile_tester/engine"
5
+
6
+ module LazyMobileTester
7
+ mattr_accessor :enabled
8
+ @@enabled = true
9
+
10
+ mattr_accessor :resolutions
11
+ @@resolutions = {
12
+ "XS" => {
13
+ w: "320px",
14
+ h: "640px",
15
+ rotate: true,
16
+ },
17
+ "SM" => {
18
+ w: "576px",
19
+ h: "844px",
20
+ rotate: true,
21
+ },
22
+ "MD" => {
23
+ w: "834px",
24
+ h: "1112px",
25
+ rotate: true,
26
+ },
27
+ "LG" => {
28
+ w: "1280px",
29
+ h: "calc(100vh - var(--toolbar-height) - 10px)",
30
+ rotate: false,
31
+ },
32
+ "XL" => {
33
+ w: "1400px",
34
+ h: "calc(100vh - var(--toolbar-height) - 10px)",
35
+ rotate: false,
36
+ },
37
+ "100%" => {
38
+ w: "100%",
39
+ h: "calc(100vh - var(--toolbar-height) - 10px)",
40
+ rotate: false,
41
+ }
42
+ }
43
+
44
+ mattr_accessor :style
45
+ @@style = %s(
46
+ position: absolute;
47
+ left: 0;
48
+ top: 0;
49
+ z-index: 99999;
50
+ padding: 2px;
51
+ font-size: 8px;
52
+ background: #6f7dba;
53
+ color: white;
54
+ border: 0 none;
55
+ border-bottom-right-radius: 6px;
56
+ )
57
+
58
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :lazy_mobile_tester do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lazy_mobile_tester
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Igor Kasyanchuk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Lazy Mobile Tester from the page
28
+ email:
29
+ - igorkasyanchuk@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - MIT-LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - app/assets/config/toggle_device_toolbar_manifest.js
38
+ - app/views/lazy_mobile_tester/_toolbar.html.erb
39
+ - config/routes.rb
40
+ - lib/lazy_mobile_tester.rb
41
+ - lib/lazy_mobile_tester/engine.rb
42
+ - lib/lazy_mobile_tester/helper.rb
43
+ - lib/lazy_mobile_tester/middleware.rb
44
+ - lib/lazy_mobile_tester/version.rb
45
+ - lib/tasks/toggle_device_toolbar_tasks.rake
46
+ homepage: https://github.com/igorkasyanchuk/lazy_mobile_tester
47
+ licenses:
48
+ - MIT
49
+ metadata:
50
+ homepage_uri: https://github.com/igorkasyanchuk/lazy_mobile_tester
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubygems_version: 3.2.3
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: Lazy Mobile Tester from the page
70
+ test_files: []