superglue 0.41.0 → 0.50.0.beta1
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 +4 -4
- data/lib/generators/rails/scaffold_controller_generator.rb +3 -3
- data/lib/generators/rails/superglue_generator.rb +49 -60
- data/lib/generators/rails/templates/_form.json.props +3 -10
- data/lib/generators/rails/templates/index.json.props +3 -1
- data/lib/generators/rails/templates/web/edit.js +9 -2
- data/lib/generators/rails/templates/web/index.js +8 -1
- data/lib/generators/rails/templates/web/new.js +9 -2
- data/lib/install/templates/web/application.js +29 -35
- data/lib/install/templates/web/application.json.props +1 -5
- data/lib/install/templates/web/initializer.rb +1 -1
- data/lib/install/templates/web/page_to_page_mapping.js +12 -0
- data/lib/install/web.rb +8 -15
- data/lib/superglue/helpers.rb +7 -517
- data/lib/superglue/redirection.rb +1 -2
- data/lib/superglue.rb +6 -6
- data/lib/tasks/install.rake +4 -5
- metadata +15 -22
- data/test/engine_test.rb +0 -7
- data/test/helpers_test.rb +0 -23
- data/test/render_test.rb +0 -81
- data/test/test_helper.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44a42cb747cff210dd1550dae3f9ddf280e72a2b38ff26b72fa5f2eea2eeadfe
|
4
|
+
data.tar.gz: f52f207c4be16d576a51c09f0e821c08d9af68b8150bf52d5b007f59e912d936
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57a0e0bbfd2fdcc815af7922f3b97042d016fe6f68be3389a83bcb77a5de2e1e68423a172878482533f25b69464c09d0395a116c4e8179a48ffce1d7a681dcd7
|
7
|
+
data.tar.gz: d8f034124031b598ee70394fd4900e4daab38126458db85f25afb96e9074bb07196d1f01e9975e960768676da469772d7be044ca3ce0915de95f2e129fdc78d7
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "rails/generators"
|
2
|
+
require "rails/generators/rails/scaffold_controller/scaffold_controller_generator"
|
3
3
|
|
4
4
|
module Rails
|
5
5
|
module Generators
|
6
6
|
class ScaffoldControllerGenerator
|
7
|
-
source_paths << File.expand_path(
|
7
|
+
source_paths << File.expand_path("../templates", __FILE__)
|
8
8
|
|
9
9
|
hook_for :superglue, type: :boolean, default: true
|
10
10
|
end
|
@@ -1,109 +1,98 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'rails/version'
|
1
|
+
require "rails/generators/named_base"
|
2
|
+
require "rails/generators/resource_helpers"
|
4
3
|
|
5
4
|
module Rails
|
6
5
|
module Generators
|
7
6
|
class SuperglueGenerator < NamedBase
|
8
7
|
include Rails::Generators::ResourceHelpers
|
9
8
|
|
10
|
-
source_root File.expand_path(
|
9
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
10
|
|
12
|
-
argument :attributes, type: :array, default: [], banner:
|
11
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
13
12
|
|
14
13
|
def create_root_folder
|
15
|
-
path = File.join(
|
14
|
+
path = File.join("app/views", controller_file_path)
|
16
15
|
empty_directory path unless File.directory?(path)
|
17
16
|
end
|
18
17
|
|
19
18
|
def copy_view_files
|
20
|
-
%w
|
19
|
+
%w[index show new edit].each do |view|
|
21
20
|
@action_name = view
|
22
21
|
filename = filename_with_extensions(view)
|
23
|
-
template filename, File.join(
|
22
|
+
template filename, File.join("app/views", controller_file_path, filename)
|
24
23
|
end
|
25
|
-
template
|
24
|
+
template "_form.json.props", File.join("app/views", controller_file_path, "_form.json.props")
|
26
25
|
|
27
|
-
%w
|
26
|
+
%w[index show new edit].each do |view|
|
28
27
|
@action_name = view
|
29
28
|
filename = filename_with_js_extensions(view)
|
30
|
-
template
|
29
|
+
template "web/" + filename, File.join("app/views", controller_file_path, filename)
|
31
30
|
end
|
32
31
|
|
33
|
-
%w
|
32
|
+
%w[index show new edit].each do |view|
|
34
33
|
@action_name = view
|
35
34
|
filename = filename_with_html_extensions(view)
|
36
|
-
template
|
35
|
+
template "web/" + filename, File.join("app/views", controller_file_path, filename)
|
37
36
|
end
|
38
37
|
|
39
|
-
%w
|
38
|
+
%w[index show new edit].each do |view|
|
40
39
|
append_mapping(view)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
44
|
-
|
45
43
|
protected
|
46
|
-
def view_path
|
47
|
-
if Rails.version >= "7"
|
48
|
-
"../views"
|
49
|
-
else
|
50
|
-
"../../views"
|
51
|
-
end
|
52
|
-
end
|
53
44
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
else
|
58
|
-
"app/javascript/packs"
|
59
|
-
end
|
60
|
-
end
|
45
|
+
def view_path
|
46
|
+
"../views"
|
47
|
+
end
|
61
48
|
|
62
|
-
|
63
|
-
|
49
|
+
def app_js_path
|
50
|
+
"app/javascript/"
|
51
|
+
end
|
64
52
|
|
65
|
-
|
53
|
+
def append_mapping(action)
|
54
|
+
app_js = "#{app_js_path}/page_to_page_mapping.js"
|
66
55
|
|
67
|
-
|
68
|
-
"\nimport #{component_name} from '#{view_path}/#{controller_file_path}/#{action}'"
|
69
|
-
end
|
56
|
+
component_name = [plural_table_name, action].map(&:camelcase).join
|
70
57
|
|
71
|
-
|
72
|
-
|
73
|
-
end
|
58
|
+
prepend_to_file app_js do
|
59
|
+
"\nimport #{component_name} from '#{view_path}/#{controller_file_path}/#{action}'"
|
74
60
|
end
|
75
61
|
|
76
|
-
|
77
|
-
|
62
|
+
inject_into_file app_js, after: "pageIdentifierToPageComponent = {" do
|
63
|
+
"\n '#{[controller_file_path, action].join("/")}': #{component_name},"
|
78
64
|
end
|
65
|
+
end
|
79
66
|
|
80
|
-
|
81
|
-
[:id] + super
|
82
|
-
end
|
67
|
+
attr_reader :action_name
|
83
68
|
|
84
|
-
|
85
|
-
|
86
|
-
|
69
|
+
def attributes_names
|
70
|
+
[:id] + super
|
71
|
+
end
|
87
72
|
|
88
|
-
|
89
|
-
|
90
|
-
|
73
|
+
def filename_with_extensions(name)
|
74
|
+
[name, :json, :props].join(".")
|
75
|
+
end
|
91
76
|
|
92
|
-
|
93
|
-
|
94
|
-
|
77
|
+
def filename_with_js_extensions(name)
|
78
|
+
[name, :js].join(".")
|
79
|
+
end
|
95
80
|
|
96
|
-
|
97
|
-
|
98
|
-
|
81
|
+
def filename_with_html_extensions(name)
|
82
|
+
[name, :html, :erb].join(".")
|
83
|
+
end
|
99
84
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
85
|
+
def attributes_list_with_timestamps
|
86
|
+
attributes_list(attributes_names + %w[created_at updated_at])
|
87
|
+
end
|
104
88
|
|
105
|
-
|
89
|
+
def attributes_list(attributes = attributes_names)
|
90
|
+
if self.attributes.any? { |attr| attr.name == "password" && attr.type == :digest }
|
91
|
+
attributes = attributes.reject { |name| %w[password password_confirmation].include? name }
|
106
92
|
end
|
93
|
+
|
94
|
+
attributes
|
95
|
+
end
|
107
96
|
end
|
108
97
|
end
|
109
98
|
end
|
@@ -1,13 +1,6 @@
|
|
1
|
-
|
2
|
-
inner = "".html_safe
|
3
|
-
|
1
|
+
form_props(model: @<%= model_resource_name %>) do |f|
|
4
2
|
<%- attributes.each do |attr| -%>
|
5
|
-
|
6
|
-
inner << form.<%= attr.field_type %>(:<%= attr.column_name %>)
|
3
|
+
f.<%= attr.field_type %>(:<%= attr.column_name %>)
|
7
4
|
<%- end -%>
|
8
|
-
|
9
|
-
|
10
|
-
inner
|
5
|
+
f.submit
|
11
6
|
end
|
12
|
-
|
13
|
-
json.html html
|
@@ -5,7 +5,9 @@ json.<%= plural_table_name %> do
|
|
5
5
|
<%- end -%>
|
6
6
|
json.edit_<%=singular_table_name%>_path edit_<%=singular_table_name%>_path(<%=singular_table_name%>)
|
7
7
|
json.<%=singular_table_name%>_path <%=singular_table_name%>_path(<%=singular_table_name%>)
|
8
|
-
json.
|
8
|
+
json.delete_form do
|
9
|
+
form_props(model: <%=singular_table_name%>, method: :delete)
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import RailsTag from '@thoughtbot/superglue/components/RailsTag'
|
3
2
|
// import * as actionCreators from 'javascript/packs/action_creators'
|
4
3
|
// import {useDispatch} from 'react-redux'
|
5
4
|
|
@@ -23,7 +22,15 @@ export default function <%= plural_table_name.camelize %>Edit ({
|
|
23
22
|
return (
|
24
23
|
<div>
|
25
24
|
{messagesEl}
|
26
|
-
<
|
25
|
+
<form {...form.props} data-sg-visit={true}>
|
26
|
+
{Object.values(form.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
|
27
|
+
<%- attributes.each do |attr| -%>
|
28
|
+
<input {...form.inputs.<%= attr.column_name %>} type="text"/>
|
29
|
+
<label htmlFor={form.inputs.<%= attr.column_name %>.id}><%= attr.column_name %></label>
|
30
|
+
<%- end -%>
|
31
|
+
<button {...form.inputs.submit} type="submit"> {...form.inputs.submit.text} </button>
|
32
|
+
</form>
|
33
|
+
|
27
34
|
<a href={<%= singular_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Show</a>
|
28
35
|
<a href={<%= plural_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Back</a>
|
29
36
|
</div>
|
@@ -10,6 +10,8 @@ export default function <%= plural_table_name.camelize %>Index({
|
|
10
10
|
<%= plural_table_name.camelize(:lower) %> = [],
|
11
11
|
}) {
|
12
12
|
const <%= singular_table_name.camelize(:lower) %>Items = <%= plural_table_name.camelize(:lower) %>.map((<%= singular_table_name.camelize(:lower) %>, key) => {
|
13
|
+
const deleteForm = <%=singular_table_name.camelize(:lower)%>.deleteForm;
|
14
|
+
|
13
15
|
return (
|
14
16
|
<tr key={<%= singular_table_name.camelize(:lower) %>.id}>
|
15
17
|
<%- attributes_list.select{|attr| attr != :id }.each do |attr| -%>
|
@@ -17,7 +19,12 @@ export default function <%= plural_table_name.camelize %>Index({
|
|
17
19
|
<%- end -%>
|
18
20
|
<td><a href={ <%=singular_table_name%>.<%=singular_table_name.camelize(:lower)%>Path } data-sg-visit={true}>Show</a></td>
|
19
21
|
<td><a href={ <%=singular_table_name%>.edit<%=singular_table_name.camelize%>Path } data-sg-visit={true}>Edit</a></td>
|
20
|
-
<td
|
22
|
+
<td>
|
23
|
+
<form {...deleteForm.props} data-sg-visit={true}>
|
24
|
+
{Object.values(deleteForm.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
|
25
|
+
<button type="submit">Delete</button>
|
26
|
+
</form>
|
27
|
+
</td>
|
21
28
|
</tr>
|
22
29
|
)
|
23
30
|
})
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import RailsTag from '@thoughtbot/superglue/components/RailsTag'
|
3
2
|
// import * as actionCreators from 'javascript/packs/action_creators'
|
4
3
|
// import { useDispatch } from 'react-redux'
|
5
4
|
|
@@ -22,7 +21,15 @@ export default function <%= plural_table_name.camelize %>New({
|
|
22
21
|
return (
|
23
22
|
<div>
|
24
23
|
{messagesEl}
|
25
|
-
<
|
24
|
+
<form {...form.props} data-sg-visit={true}>
|
25
|
+
{Object.values(form.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
|
26
|
+
<%- attributes.each do |attr| -%>
|
27
|
+
<input {...form.inputs.<%= attr.column_name %>} type="text"/>
|
28
|
+
<label htmlFor={form.inputs.<%= attr.column_name %>.id}><%= attr.column_name %></label>
|
29
|
+
<%- end -%>
|
30
|
+
<button {...form.inputs.submit} type="submit"> {...form.inputs.submit.text} </button>
|
31
|
+
</form>
|
32
|
+
|
26
33
|
<a href={<%= plural_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Back</a>
|
27
34
|
</div>
|
28
35
|
)
|
@@ -7,43 +7,11 @@ import { render } from 'react-dom';
|
|
7
7
|
import { ApplicationBase, fragmentMiddleware } from '@thoughtbot/superglue';
|
8
8
|
import { applicationRootReducer, applicationPagesReducer } from './reducer';
|
9
9
|
import { buildVisitAndRemote } from './application_visit';
|
10
|
+
import { pageIdentifierToPageComponent } from './page_to_page_mapping';
|
10
11
|
|
11
|
-
|
12
|
-
// to register any new page level component you create. If you are using the
|
13
|
-
// scaffold, it will auto append the identifers for you.
|
14
|
-
//
|
15
|
-
// e.g {'posts/new': PostNew}
|
16
|
-
const identifierToComponentMapping = {
|
17
|
-
};
|
18
|
-
|
19
|
-
if (typeof window !== "undefined") {
|
20
|
-
document.addEventListener("DOMContentLoaded", function () {
|
21
|
-
const appEl = document.getElementById("app");
|
22
|
-
const location = window.location;
|
23
|
-
|
24
|
-
if (appEl) {
|
25
|
-
render(
|
26
|
-
<Application
|
27
|
-
appEl={appEl}
|
28
|
-
// The base url prefixed to all calls made by the `visit`
|
29
|
-
// and `remote` thunks.
|
30
|
-
baseUrl={location.origin}
|
31
|
-
// The global var SUPERGLUE_INITIAL_PAGE_STATE is set by your erb
|
32
|
-
// template, e.g., index.html.erb
|
33
|
-
initialPage={window.SUPERGLUE_INITIAL_PAGE_STATE}
|
34
|
-
// The initial path of the page, e.g., /foobar
|
35
|
-
path={location.pathname + location.search + location.hash}
|
36
|
-
buildVisitAndRemote={buildVisitAndRemote}
|
37
|
-
/>,
|
38
|
-
appEl
|
39
|
-
);
|
40
|
-
}
|
41
|
-
});
|
42
|
-
}
|
43
|
-
|
44
|
-
export default class Application extends ApplicationBase {
|
12
|
+
class Application extends ApplicationBase {
|
45
13
|
mapping() {
|
46
|
-
return
|
14
|
+
return pageIdentifierToPageComponent;
|
47
15
|
}
|
48
16
|
|
49
17
|
visitAndRemote(navRef, store) {
|
@@ -73,3 +41,29 @@ export default class Application extends ApplicationBase {
|
|
73
41
|
return store;
|
74
42
|
}
|
75
43
|
}
|
44
|
+
|
45
|
+
if (typeof window !== "undefined") {
|
46
|
+
document.addEventListener("DOMContentLoaded", function () {
|
47
|
+
const appEl = document.getElementById("app");
|
48
|
+
const location = window.location;
|
49
|
+
|
50
|
+
if (appEl) {
|
51
|
+
render(
|
52
|
+
<Application
|
53
|
+
appEl={appEl}
|
54
|
+
// The base url prefixed to all calls made by the `visit`
|
55
|
+
// and `remote` thunks.
|
56
|
+
baseUrl={location.origin}
|
57
|
+
// The global var SUPERGLUE_INITIAL_PAGE_STATE is set by your erb
|
58
|
+
// template, e.g., index.html.erb
|
59
|
+
initialPage={window.SUPERGLUE_INITIAL_PAGE_STATE}
|
60
|
+
// The initial path of the page, e.g., /foobar
|
61
|
+
path={location.pathname + location.search + location.hash}
|
62
|
+
buildVisitAndRemote={buildVisitAndRemote}
|
63
|
+
/>,
|
64
|
+
appEl
|
65
|
+
);
|
66
|
+
}
|
67
|
+
});
|
68
|
+
}
|
69
|
+
|
@@ -7,11 +7,7 @@ end
|
|
7
7
|
json.component_identifier local_assigns[:virtual_path_of_template]
|
8
8
|
json.defers json.deferred!
|
9
9
|
json.fragments json.fragments!
|
10
|
-
json.assets [
|
11
|
-
# Uncomment for webpacker support
|
12
|
-
# asset_pack_path('application.js'),
|
13
|
-
asset_path('application.css')
|
14
|
-
]
|
10
|
+
json.assets [ asset_path('application.js') ]
|
15
11
|
|
16
12
|
if protect_against_forgery?
|
17
13
|
json.csrf_token form_authenticity_token
|
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require "props_template/core_ext"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
// import your page component
|
2
|
+
// e.g import PostsEdit from '../views/posts/edit'
|
3
|
+
|
4
|
+
|
5
|
+
// Mapping between your props template to Component, you must add to this
|
6
|
+
// to register any new page level component you create. If you are using the
|
7
|
+
// scaffold, it will auto append the identifers for you.
|
8
|
+
//
|
9
|
+
// e.g {'posts/new': PostNew}
|
10
|
+
export const pageIdentifierToPageComponent = {
|
11
|
+
};
|
12
|
+
|
data/lib/install/web.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require "rails/version"
|
2
|
-
|
3
1
|
def add_member_methods
|
4
2
|
inject_into_file "app/models/application_record.rb", after: "class ApplicationRecord < ActiveRecord::Base\n" do
|
5
3
|
<<-RUBY
|
@@ -15,16 +13,15 @@ def add_member_methods
|
|
15
13
|
end
|
16
14
|
|
17
15
|
def app_js_path
|
18
|
-
|
19
|
-
"app/javascript/"
|
20
|
-
else
|
21
|
-
"app/javascript/packs"
|
22
|
-
end
|
16
|
+
"app/javascript/"
|
23
17
|
end
|
24
18
|
|
25
19
|
say "Copying application.js file to #{app_js_path}"
|
26
20
|
copy_file "#{__dir__}/templates/web/application.js", "#{app_js_path}/application.js"
|
27
21
|
|
22
|
+
say "Copying page_to_page_mapping.js file to #{app_js_path}"
|
23
|
+
copy_file "#{__dir__}/templates/web/page_to_page_mapping.js", "#{app_js_path}/page_to_page_mapping.js"
|
24
|
+
|
28
25
|
say "Copying reducer.js file to #{app_js_path}"
|
29
26
|
copy_file "#{__dir__}/templates/web/reducer.js", "#{app_js_path}/reducer.js"
|
30
27
|
|
@@ -46,14 +43,10 @@ copy_file "#{__dir__}/templates/web/application.json.props", "app/views/layouts/
|
|
46
43
|
say "Adding required member methods to ApplicationRecord"
|
47
44
|
add_member_methods
|
48
45
|
|
49
|
-
say "Installing
|
50
|
-
run "
|
46
|
+
say "Installing FormProps"
|
47
|
+
run "bundle add form_props"
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
insert_into_file Webpacker.config.config_path, "'app/views', 'app/components'", after: /additional_paths: \[/
|
55
|
-
# For older webpacker
|
56
|
-
insert_into_file Webpacker.config.config_path, "'app/views', 'app/components'", after: /resolved_paths: \[/
|
57
|
-
end
|
49
|
+
say "Installing React, Redux, and Superglue"
|
50
|
+
run "yarn add history react-redux redux-thunk redux reduce-reducers immer @thoughtbot/superglue --save"
|
58
51
|
|
59
52
|
say "Superglue is Installed! 🎉", :green
|
data/lib/superglue/helpers.rb
CHANGED
@@ -1,493 +1,5 @@
|
|
1
1
|
module Superglue
|
2
2
|
module Helpers
|
3
|
-
POSSIBLE_STANDARD_NAMES = {
|
4
|
-
# HTML
|
5
|
-
accept: 'accept',
|
6
|
-
acceptcharset: 'acceptCharset',
|
7
|
-
'accept-charset': 'acceptCharset',
|
8
|
-
accesskey: 'accessKey',
|
9
|
-
action: 'action',
|
10
|
-
allowfullscreen: 'allowFullScreen',
|
11
|
-
alt: 'alt',
|
12
|
-
as: 'as',
|
13
|
-
async: 'async',
|
14
|
-
autocapitalize: 'autoCapitalize',
|
15
|
-
autocomplete: 'autoComplete',
|
16
|
-
autocorrect: 'autoCorrect',
|
17
|
-
autofocus: 'autoFocus',
|
18
|
-
autoplay: 'autoPlay',
|
19
|
-
autosave: 'autoSave',
|
20
|
-
capture: 'capture',
|
21
|
-
cellpadding: 'cellPadding',
|
22
|
-
cellspacing: 'cellSpacing',
|
23
|
-
challenge: 'challenge',
|
24
|
-
charset: 'charSet',
|
25
|
-
checked: 'checked',
|
26
|
-
children: 'children',
|
27
|
-
cite: 'cite',
|
28
|
-
class: 'className',
|
29
|
-
classid: 'classID',
|
30
|
-
classname: 'className',
|
31
|
-
cols: 'cols',
|
32
|
-
colspan: 'colSpan',
|
33
|
-
content: 'content',
|
34
|
-
contenteditable: 'contentEditable',
|
35
|
-
contextmenu: 'contextMenu',
|
36
|
-
controls: 'controls',
|
37
|
-
controlslist: 'controlsList',
|
38
|
-
coords: 'coords',
|
39
|
-
crossorigin: 'crossOrigin',
|
40
|
-
dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
|
41
|
-
data: 'data',
|
42
|
-
datetime: 'dateTime',
|
43
|
-
default: 'default',
|
44
|
-
defaultchecked: 'defaultChecked',
|
45
|
-
defaultvalue: 'defaultValue',
|
46
|
-
defer: 'defer',
|
47
|
-
dir: 'dir',
|
48
|
-
disabled: 'disabled',
|
49
|
-
disablepictureinpicture: 'disablePictureInPicture',
|
50
|
-
disableremoteplayback: 'disableRemotePlayback',
|
51
|
-
download: 'download',
|
52
|
-
draggable: 'draggable',
|
53
|
-
enctype: 'encType',
|
54
|
-
for: 'htmlFor',
|
55
|
-
form: 'form',
|
56
|
-
formmethod: 'formMethod',
|
57
|
-
formaction: 'formAction',
|
58
|
-
formenctype: 'formEncType',
|
59
|
-
formnovalidate: 'formNoValidate',
|
60
|
-
formtarget: 'formTarget',
|
61
|
-
frameborder: 'frameBorder',
|
62
|
-
headers: 'headers',
|
63
|
-
height: 'height',
|
64
|
-
hidden: 'hidden',
|
65
|
-
high: 'high',
|
66
|
-
href: 'href',
|
67
|
-
hreflang: 'hrefLang',
|
68
|
-
htmlfor: 'htmlFor',
|
69
|
-
httpequiv: 'httpEquiv',
|
70
|
-
'http-equiv': 'httpEquiv',
|
71
|
-
icon: 'icon',
|
72
|
-
id: 'id',
|
73
|
-
innerhtml: 'innerHTML',
|
74
|
-
inputmode: 'inputMode',
|
75
|
-
integrity: 'integrity',
|
76
|
-
is: 'is',
|
77
|
-
itemid: 'itemID',
|
78
|
-
itemprop: 'itemProp',
|
79
|
-
itemref: 'itemRef',
|
80
|
-
itemscope: 'itemScope',
|
81
|
-
itemtype: 'itemType',
|
82
|
-
keyparams: 'keyParams',
|
83
|
-
keytype: 'keyType',
|
84
|
-
kind: 'kind',
|
85
|
-
label: 'label',
|
86
|
-
lang: 'lang',
|
87
|
-
list: 'list',
|
88
|
-
loop: 'loop',
|
89
|
-
low: 'low',
|
90
|
-
manifest: 'manifest',
|
91
|
-
marginwidth: 'marginWidth',
|
92
|
-
marginheight: 'marginHeight',
|
93
|
-
max: 'max',
|
94
|
-
maxlength: 'maxLength',
|
95
|
-
media: 'media',
|
96
|
-
mediagroup: 'mediaGroup',
|
97
|
-
method: 'method',
|
98
|
-
min: 'min',
|
99
|
-
minlength: 'minLength',
|
100
|
-
multiple: 'multiple',
|
101
|
-
muted: 'muted',
|
102
|
-
name: 'name',
|
103
|
-
nomodule: 'noModule',
|
104
|
-
nonce: 'nonce',
|
105
|
-
novalidate: 'noValidate',
|
106
|
-
open: 'open',
|
107
|
-
optimum: 'optimum',
|
108
|
-
pattern: 'pattern',
|
109
|
-
placeholder: 'placeholder',
|
110
|
-
playsinline: 'playsInline',
|
111
|
-
poster: 'poster',
|
112
|
-
preload: 'preload',
|
113
|
-
profile: 'profile',
|
114
|
-
radiogroup: 'radioGroup',
|
115
|
-
readonly: 'readOnly',
|
116
|
-
referrerpolicy: 'referrerPolicy',
|
117
|
-
rel: 'rel',
|
118
|
-
required: 'required',
|
119
|
-
reversed: 'reversed',
|
120
|
-
role: 'role',
|
121
|
-
rows: 'rows',
|
122
|
-
rowspan: 'rowSpan',
|
123
|
-
sandbox: 'sandbox',
|
124
|
-
scope: 'scope',
|
125
|
-
scoped: 'scoped',
|
126
|
-
scrolling: 'scrolling',
|
127
|
-
seamless: 'seamless',
|
128
|
-
selected: 'selected',
|
129
|
-
shape: 'shape',
|
130
|
-
size: 'size',
|
131
|
-
sizes: 'sizes',
|
132
|
-
span: 'span',
|
133
|
-
spellcheck: 'spellCheck',
|
134
|
-
src: 'src',
|
135
|
-
srcdoc: 'srcDoc',
|
136
|
-
srclang: 'srcLang',
|
137
|
-
srcset: 'srcSet',
|
138
|
-
start: 'start',
|
139
|
-
step: 'step',
|
140
|
-
style: 'style',
|
141
|
-
summary: 'summary',
|
142
|
-
tabindex: 'tabIndex',
|
143
|
-
target: 'target',
|
144
|
-
title: 'title',
|
145
|
-
type: 'type',
|
146
|
-
usemap: 'useMap',
|
147
|
-
value: 'value',
|
148
|
-
width: 'width',
|
149
|
-
wmode: 'wmode',
|
150
|
-
wrap: 'wrap',
|
151
|
-
|
152
|
-
# SVG
|
153
|
-
about: 'about',
|
154
|
-
accentheight: 'accentHeight',
|
155
|
-
'accent-height': 'accentHeight',
|
156
|
-
accumulate: 'accumulate',
|
157
|
-
additive: 'additive',
|
158
|
-
alignmentbaseline: 'alignmentBaseline',
|
159
|
-
'alignment-baseline': 'alignmentBaseline',
|
160
|
-
allowreorder: 'allowReorder',
|
161
|
-
alphabetic: 'alphabetic',
|
162
|
-
amplitude: 'amplitude',
|
163
|
-
arabicform: 'arabicForm',
|
164
|
-
'arabic-form': 'arabicForm',
|
165
|
-
ascent: 'ascent',
|
166
|
-
attributename: 'attributeName',
|
167
|
-
attributetype: 'attributeType',
|
168
|
-
autoreverse: 'autoReverse',
|
169
|
-
azimuth: 'azimuth',
|
170
|
-
basefrequency: 'baseFrequency',
|
171
|
-
baselineshift: 'baselineShift',
|
172
|
-
'baseline-shift': 'baselineShift',
|
173
|
-
baseprofile: 'baseProfile',
|
174
|
-
bbox: 'bbox',
|
175
|
-
begin: 'begin',
|
176
|
-
bias: 'bias',
|
177
|
-
by: 'by',
|
178
|
-
calcmode: 'calcMode',
|
179
|
-
capheight: 'capHeight',
|
180
|
-
'cap-height': 'capHeight',
|
181
|
-
clip: 'clip',
|
182
|
-
clippath: 'clipPath',
|
183
|
-
'clip-path': 'clipPath',
|
184
|
-
clippathunits: 'clipPathUnits',
|
185
|
-
cliprule: 'clipRule',
|
186
|
-
'clip-rule': 'clipRule',
|
187
|
-
color: 'color',
|
188
|
-
colorinterpolation: 'colorInterpolation',
|
189
|
-
'color-interpolation': 'colorInterpolation',
|
190
|
-
colorinterpolationfilters: 'colorInterpolationFilters',
|
191
|
-
'color-interpolation-filters': 'colorInterpolationFilters',
|
192
|
-
colorprofile: 'colorProfile',
|
193
|
-
'color-profile': 'colorProfile',
|
194
|
-
colorrendering: 'colorRendering',
|
195
|
-
'color-rendering': 'colorRendering',
|
196
|
-
contentscripttype: 'contentScriptType',
|
197
|
-
contentstyletype: 'contentStyleType',
|
198
|
-
cursor: 'cursor',
|
199
|
-
cx: 'cx',
|
200
|
-
cy: 'cy',
|
201
|
-
d: 'd',
|
202
|
-
datatype: 'datatype',
|
203
|
-
decelerate: 'decelerate',
|
204
|
-
descent: 'descent',
|
205
|
-
diffuseconstant: 'diffuseConstant',
|
206
|
-
direction: 'direction',
|
207
|
-
display: 'display',
|
208
|
-
divisor: 'divisor',
|
209
|
-
dominantbaseline: 'dominantBaseline',
|
210
|
-
'dominant-baseline': 'dominantBaseline',
|
211
|
-
dur: 'dur',
|
212
|
-
dx: 'dx',
|
213
|
-
dy: 'dy',
|
214
|
-
edgemode: 'edgeMode',
|
215
|
-
elevation: 'elevation',
|
216
|
-
enablebackground: 'enableBackground',
|
217
|
-
'enable-background': 'enableBackground',
|
218
|
-
end: 'end',
|
219
|
-
exponent: 'exponent',
|
220
|
-
externalresourcesrequired: 'externalResourcesRequired',
|
221
|
-
fill: 'fill',
|
222
|
-
fillopacity: 'fillOpacity',
|
223
|
-
'fill-opacity': 'fillOpacity',
|
224
|
-
fillrule: 'fillRule',
|
225
|
-
'fill-rule': 'fillRule',
|
226
|
-
filter: 'filter',
|
227
|
-
filterres: 'filterRes',
|
228
|
-
filterunits: 'filterUnits',
|
229
|
-
floodopacity: 'floodOpacity',
|
230
|
-
'flood-opacity': 'floodOpacity',
|
231
|
-
floodcolor: 'floodColor',
|
232
|
-
'flood-color': 'floodColor',
|
233
|
-
focusable: 'focusable',
|
234
|
-
fontfamily: 'fontFamily',
|
235
|
-
'font-family': 'fontFamily',
|
236
|
-
fontsize: 'fontSize',
|
237
|
-
'font-size': 'fontSize',
|
238
|
-
fontsizeadjust: 'fontSizeAdjust',
|
239
|
-
'font-size-adjust': 'fontSizeAdjust',
|
240
|
-
fontstretch: 'fontStretch',
|
241
|
-
'font-stretch': 'fontStretch',
|
242
|
-
fontstyle: 'fontStyle',
|
243
|
-
'font-style': 'fontStyle',
|
244
|
-
fontvariant: 'fontVariant',
|
245
|
-
'font-variant': 'fontVariant',
|
246
|
-
fontweight: 'fontWeight',
|
247
|
-
'font-weight': 'fontWeight',
|
248
|
-
format: 'format',
|
249
|
-
from: 'from',
|
250
|
-
fx: 'fx',
|
251
|
-
fy: 'fy',
|
252
|
-
g1: 'g1',
|
253
|
-
g2: 'g2',
|
254
|
-
glyphname: 'glyphName',
|
255
|
-
'glyph-name': 'glyphName',
|
256
|
-
glyphorientationhorizontal: 'glyphOrientationHorizontal',
|
257
|
-
'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
|
258
|
-
glyphorientationvertical: 'glyphOrientationVertical',
|
259
|
-
'glyph-orientation-vertical': 'glyphOrientationVertical',
|
260
|
-
glyphref: 'glyphRef',
|
261
|
-
gradienttransform: 'gradientTransform',
|
262
|
-
gradientunits: 'gradientUnits',
|
263
|
-
hanging: 'hanging',
|
264
|
-
horizadvx: 'horizAdvX',
|
265
|
-
'horiz-adv-x': 'horizAdvX',
|
266
|
-
horizoriginx: 'horizOriginX',
|
267
|
-
'horiz-origin-x': 'horizOriginX',
|
268
|
-
ideographic: 'ideographic',
|
269
|
-
imagerendering: 'imageRendering',
|
270
|
-
'image-rendering': 'imageRendering',
|
271
|
-
in2: 'in2',
|
272
|
-
in: 'in',
|
273
|
-
inlist: 'inlist',
|
274
|
-
intercept: 'intercept',
|
275
|
-
k1: 'k1',
|
276
|
-
k2: 'k2',
|
277
|
-
k3: 'k3',
|
278
|
-
k4: 'k4',
|
279
|
-
k: 'k',
|
280
|
-
kernelmatrix: 'kernelMatrix',
|
281
|
-
kernelunitlength: 'kernelUnitLength',
|
282
|
-
kerning: 'kerning',
|
283
|
-
keypoints: 'keyPoints',
|
284
|
-
keysplines: 'keySplines',
|
285
|
-
keytimes: 'keyTimes',
|
286
|
-
lengthadjust: 'lengthAdjust',
|
287
|
-
letterspacing: 'letterSpacing',
|
288
|
-
'letter-spacing': 'letterSpacing',
|
289
|
-
lightingcolor: 'lightingColor',
|
290
|
-
'lighting-color': 'lightingColor',
|
291
|
-
limitingconeangle: 'limitingConeAngle',
|
292
|
-
local: 'local',
|
293
|
-
markerend: 'markerEnd',
|
294
|
-
'marker-end': 'markerEnd',
|
295
|
-
markerheight: 'markerHeight',
|
296
|
-
markermid: 'markerMid',
|
297
|
-
'marker-mid': 'markerMid',
|
298
|
-
markerstart: 'markerStart',
|
299
|
-
'marker-start': 'markerStart',
|
300
|
-
markerunits: 'markerUnits',
|
301
|
-
markerwidth: 'markerWidth',
|
302
|
-
mask: 'mask',
|
303
|
-
maskcontentunits: 'maskContentUnits',
|
304
|
-
maskunits: 'maskUnits',
|
305
|
-
mathematical: 'mathematical',
|
306
|
-
mode: 'mode',
|
307
|
-
numoctaves: 'numOctaves',
|
308
|
-
offset: 'offset',
|
309
|
-
opacity: 'opacity',
|
310
|
-
operator: 'operator',
|
311
|
-
order: 'order',
|
312
|
-
orient: 'orient',
|
313
|
-
orientation: 'orientation',
|
314
|
-
origin: 'origin',
|
315
|
-
overflow: 'overflow',
|
316
|
-
overlineposition: 'overlinePosition',
|
317
|
-
'overline-position': 'overlinePosition',
|
318
|
-
overlinethickness: 'overlineThickness',
|
319
|
-
'overline-thickness': 'overlineThickness',
|
320
|
-
paintorder: 'paintOrder',
|
321
|
-
'paint-order': 'paintOrder',
|
322
|
-
panose1: 'panose1',
|
323
|
-
'panose-1': 'panose1',
|
324
|
-
pathlength: 'pathLength',
|
325
|
-
patterncontentunits: 'patternContentUnits',
|
326
|
-
patterntransform: 'patternTransform',
|
327
|
-
patternunits: 'patternUnits',
|
328
|
-
pointerevents: 'pointerEvents',
|
329
|
-
'pointer-events': 'pointerEvents',
|
330
|
-
points: 'points',
|
331
|
-
pointsatx: 'pointsAtX',
|
332
|
-
pointsaty: 'pointsAtY',
|
333
|
-
pointsatz: 'pointsAtZ',
|
334
|
-
prefix: 'prefix',
|
335
|
-
preservealpha: 'preserveAlpha',
|
336
|
-
preserveaspectratio: 'preserveAspectRatio',
|
337
|
-
primitiveunits: 'primitiveUnits',
|
338
|
-
property: 'property',
|
339
|
-
r: 'r',
|
340
|
-
radius: 'radius',
|
341
|
-
refx: 'refX',
|
342
|
-
refy: 'refY',
|
343
|
-
renderingintent: 'renderingIntent',
|
344
|
-
'rendering-intent': 'renderingIntent',
|
345
|
-
repeatcount: 'repeatCount',
|
346
|
-
repeatdur: 'repeatDur',
|
347
|
-
requiredextensions: 'requiredExtensions',
|
348
|
-
requiredfeatures: 'requiredFeatures',
|
349
|
-
resource: 'resource',
|
350
|
-
restart: 'restart',
|
351
|
-
result: 'result',
|
352
|
-
results: 'results',
|
353
|
-
rotate: 'rotate',
|
354
|
-
rx: 'rx',
|
355
|
-
ry: 'ry',
|
356
|
-
scale: 'scale',
|
357
|
-
security: 'security',
|
358
|
-
seed: 'seed',
|
359
|
-
shaperendering: 'shapeRendering',
|
360
|
-
'shape-rendering': 'shapeRendering',
|
361
|
-
slope: 'slope',
|
362
|
-
spacing: 'spacing',
|
363
|
-
specularconstant: 'specularConstant',
|
364
|
-
specularexponent: 'specularExponent',
|
365
|
-
speed: 'speed',
|
366
|
-
spreadmethod: 'spreadMethod',
|
367
|
-
startoffset: 'startOffset',
|
368
|
-
stddeviation: 'stdDeviation',
|
369
|
-
stemh: 'stemh',
|
370
|
-
stemv: 'stemv',
|
371
|
-
stitchtiles: 'stitchTiles',
|
372
|
-
stopcolor: 'stopColor',
|
373
|
-
'stop-color': 'stopColor',
|
374
|
-
stopopacity: 'stopOpacity',
|
375
|
-
'stop-opacity': 'stopOpacity',
|
376
|
-
strikethroughposition: 'strikethroughPosition',
|
377
|
-
'strikethrough-position': 'strikethroughPosition',
|
378
|
-
strikethroughthickness: 'strikethroughThickness',
|
379
|
-
'strikethrough-thickness': 'strikethroughThickness',
|
380
|
-
string: 'string',
|
381
|
-
stroke: 'stroke',
|
382
|
-
strokedasharray: 'strokeDasharray',
|
383
|
-
'stroke-dasharray': 'strokeDasharray',
|
384
|
-
strokedashoffset: 'strokeDashoffset',
|
385
|
-
'stroke-dashoffset': 'strokeDashoffset',
|
386
|
-
strokelinecap: 'strokeLinecap',
|
387
|
-
'stroke-linecap': 'strokeLinecap',
|
388
|
-
strokelinejoin: 'strokeLinejoin',
|
389
|
-
'stroke-linejoin': 'strokeLinejoin',
|
390
|
-
strokemiterlimit: 'strokeMiterlimit',
|
391
|
-
'stroke-miterlimit': 'strokeMiterlimit',
|
392
|
-
strokewidth: 'strokeWidth',
|
393
|
-
'stroke-width': 'strokeWidth',
|
394
|
-
strokeopacity: 'strokeOpacity',
|
395
|
-
'stroke-opacity': 'strokeOpacity',
|
396
|
-
suppresscontenteditablewarning: 'suppressContentEditableWarning',
|
397
|
-
suppresshydrationwarning: 'suppressHydrationWarning',
|
398
|
-
surfacescale: 'surfaceScale',
|
399
|
-
systemlanguage: 'systemLanguage',
|
400
|
-
tablevalues: 'tableValues',
|
401
|
-
targetx: 'targetX',
|
402
|
-
targety: 'targetY',
|
403
|
-
textanchor: 'textAnchor',
|
404
|
-
'text-anchor': 'textAnchor',
|
405
|
-
textdecoration: 'textDecoration',
|
406
|
-
'text-decoration': 'textDecoration',
|
407
|
-
textlength: 'textLength',
|
408
|
-
textrendering: 'textRendering',
|
409
|
-
'text-rendering': 'textRendering',
|
410
|
-
to: 'to',
|
411
|
-
transform: 'transform',
|
412
|
-
typeof: 'typeof',
|
413
|
-
u1: 'u1',
|
414
|
-
u2: 'u2',
|
415
|
-
underlineposition: 'underlinePosition',
|
416
|
-
'underline-position': 'underlinePosition',
|
417
|
-
underlinethickness: 'underlineThickness',
|
418
|
-
'underline-thickness': 'underlineThickness',
|
419
|
-
unicode: 'unicode',
|
420
|
-
unicodebidi: 'unicodeBidi',
|
421
|
-
'unicode-bidi': 'unicodeBidi',
|
422
|
-
unicoderange: 'unicodeRange',
|
423
|
-
'unicode-range': 'unicodeRange',
|
424
|
-
unitsperem: 'unitsPerEm',
|
425
|
-
'units-per-em': 'unitsPerEm',
|
426
|
-
unselectable: 'unselectable',
|
427
|
-
valphabetic: 'vAlphabetic',
|
428
|
-
'v-alphabetic': 'vAlphabetic',
|
429
|
-
values: 'values',
|
430
|
-
vectoreffect: 'vectorEffect',
|
431
|
-
'vector-effect': 'vectorEffect',
|
432
|
-
version: 'version',
|
433
|
-
vertadvy: 'vertAdvY',
|
434
|
-
'vert-adv-y': 'vertAdvY',
|
435
|
-
vertoriginx: 'vertOriginX',
|
436
|
-
'vert-origin-x': 'vertOriginX',
|
437
|
-
vertoriginy: 'vertOriginY',
|
438
|
-
'vert-origin-y': 'vertOriginY',
|
439
|
-
vhanging: 'vHanging',
|
440
|
-
'v-hanging': 'vHanging',
|
441
|
-
videographic: 'vIdeographic',
|
442
|
-
'v-ideographic': 'vIdeographic',
|
443
|
-
viewbox: 'viewBox',
|
444
|
-
viewtarget: 'viewTarget',
|
445
|
-
visibility: 'visibility',
|
446
|
-
vmathematical: 'vMathematical',
|
447
|
-
'v-mathematical': 'vMathematical',
|
448
|
-
vocab: 'vocab',
|
449
|
-
widths: 'widths',
|
450
|
-
wordspacing: 'wordSpacing',
|
451
|
-
'word-spacing': 'wordSpacing',
|
452
|
-
writingmode: 'writingMode',
|
453
|
-
'writing-mode': 'writingMode',
|
454
|
-
x1: 'x1',
|
455
|
-
x2: 'x2',
|
456
|
-
x: 'x',
|
457
|
-
xchannelselector: 'xChannelSelector',
|
458
|
-
xheight: 'xHeight',
|
459
|
-
'x-height': 'xHeight',
|
460
|
-
xlinkactuate: 'xlinkActuate',
|
461
|
-
'xlink:actuate': 'xlinkActuate',
|
462
|
-
xlinkarcrole: 'xlinkArcrole',
|
463
|
-
'xlink:arcrole': 'xlinkArcrole',
|
464
|
-
xlinkhref: 'xlinkHref',
|
465
|
-
'xlink:href': 'xlinkHref',
|
466
|
-
xlinkrole: 'xlinkRole',
|
467
|
-
'xlink:role': 'xlinkRole',
|
468
|
-
xlinkshow: 'xlinkShow',
|
469
|
-
'xlink:show': 'xlinkShow',
|
470
|
-
xlinktitle: 'xlinkTitle',
|
471
|
-
'xlink:title': 'xlinkTitle',
|
472
|
-
xlinktype: 'xlinkType',
|
473
|
-
'xlink:type': 'xlinkType',
|
474
|
-
xmlbase: 'xmlBase',
|
475
|
-
'xml:base': 'xmlBase',
|
476
|
-
xmllang: 'xmlLang',
|
477
|
-
'xml:lang': 'xmlLang',
|
478
|
-
xmlns: 'xmlns',
|
479
|
-
'xml:space': 'xmlSpace',
|
480
|
-
xmlnsxlink: 'xmlnsXlink',
|
481
|
-
'xmlns:xlink': 'xmlnsXlink',
|
482
|
-
xmlspace: 'xmlSpace',
|
483
|
-
y1: 'y1',
|
484
|
-
y2: 'y2',
|
485
|
-
y: 'y',
|
486
|
-
ychannelselector: 'yChannelSelector',
|
487
|
-
z: 'z',
|
488
|
-
zoomandpan: 'zoomAndPan'
|
489
|
-
}
|
490
|
-
|
491
3
|
def redirect_back_with_props_at(opts)
|
492
4
|
if request.referrer && params[:props_at]
|
493
5
|
referrer_url = URI.parse(request.referrer)
|
@@ -502,34 +14,12 @@ module Superglue
|
|
502
14
|
end
|
503
15
|
end
|
504
16
|
|
505
|
-
def props_from_form_with(model: nil, scope: nil, url: nil, format: nil, **options)
|
506
|
-
options[:allow_method_names_outside_object] = true
|
507
|
-
options[:skip_default_ids] = !helpers.send(:form_with_generates_ids)
|
508
|
-
|
509
|
-
if model
|
510
|
-
url ||= helpers.send(:polymorphic_path, model, format: format)
|
511
|
-
|
512
|
-
model = model.last if model.is_a?(Array)
|
513
|
-
scope ||= helpers.send(:model_name_from_record_or_class, model).param_key
|
514
|
-
end
|
515
|
-
|
516
|
-
html_options = helpers.send(:html_options_for_form_with, url, model, options)
|
517
|
-
html_options.delete("authenticity_token")
|
518
|
-
html_options.delete("enforce_utf8")
|
519
|
-
|
520
|
-
key_vals = html_options.map { |k, v|
|
521
|
-
[POSSIBLE_STANDARD_NAMES[k.to_sym] || k.camelize(:lower), v]
|
522
|
-
}
|
523
|
-
Hash[key_vals]
|
524
|
-
end
|
525
|
-
|
526
17
|
def param_to_search_path(param)
|
527
18
|
if param
|
528
|
-
param.gsub(/[^\da-zA-
|
529
|
-
.
|
530
|
-
.split('.')
|
19
|
+
param.gsub(/[^\da-zA-Z_=.]+/, "").squeeze(".")
|
20
|
+
.split(".")
|
531
21
|
.map do |part|
|
532
|
-
if
|
22
|
+
if /^-?[0-9]+$/.match?(part)
|
533
23
|
part.to_i
|
534
24
|
else
|
535
25
|
part
|
@@ -540,13 +30,13 @@ module Superglue
|
|
540
30
|
|
541
31
|
def search_path_to_camelized_param(path)
|
542
32
|
path.map do |part|
|
543
|
-
if part.include?
|
544
|
-
key, rest = part.split(
|
545
|
-
[key.camelize(:lower), rest].join(
|
33
|
+
if part.include? "="
|
34
|
+
key, rest = part.split("=")
|
35
|
+
[key.camelize(:lower), rest].join("=")
|
546
36
|
else
|
547
37
|
part.camelize(:lower)
|
548
38
|
end
|
549
|
-
end.join(
|
39
|
+
end.join(".")
|
550
40
|
end
|
551
41
|
end
|
552
42
|
end
|
@@ -3,7 +3,7 @@ module Superglue
|
|
3
3
|
def _compute_redirect_to_location(request, options)
|
4
4
|
computed_location = URI.parse(super)
|
5
5
|
next_param = Rack::Utils
|
6
|
-
|
6
|
+
.parse_nested_query(computed_location.query)
|
7
7
|
|
8
8
|
if request.params[:__] == "0"
|
9
9
|
computed_location.query = next_param.merge({__: "0"}).to_query
|
@@ -27,4 +27,3 @@ module Superglue
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
data/lib/superglue.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "superglue/helpers"
|
2
|
+
require "superglue/redirection"
|
3
|
+
require "props_template"
|
4
4
|
|
5
5
|
module Superglue
|
6
6
|
module Controller
|
7
|
-
include
|
7
|
+
include Redirection
|
8
|
+
include Helpers
|
8
9
|
|
9
10
|
def self.included(base)
|
10
11
|
if base.respond_to?(:helper_method)
|
11
12
|
base.helper_method :param_to_search_path
|
12
|
-
base.helper_method :props_from_form_with
|
13
13
|
base.helper_method :search_path_to_camelized_param
|
14
14
|
end
|
15
15
|
end
|
@@ -22,7 +22,7 @@ module Superglue
|
|
22
22
|
generators do |app|
|
23
23
|
Rails::Generators.configure! app.config.generators
|
24
24
|
Rails::Generators.hidden_namespaces.uniq!
|
25
|
-
require
|
25
|
+
require "generators/rails/scaffold_controller_generator"
|
26
26
|
end
|
27
27
|
|
28
28
|
initializer :superglue do |app|
|
data/lib/tasks/install.rake
CHANGED
@@ -3,18 +3,17 @@ namespace :superglue do
|
|
3
3
|
task :verify_react do
|
4
4
|
package_json = JSON.parse(File.read(Rails.root.join("package.json")))
|
5
5
|
|
6
|
-
if package_json[
|
7
|
-
|
8
|
-
|
6
|
+
if package_json["dependencies"]["react"].nil?
|
7
|
+
warn "React not installed. Did you install React? https://github.com/rails/webpacker#react"
|
8
|
+
warn "Exiting!" && exit!
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
namespace :install do
|
13
13
|
desc "Install everything needed for superglue web"
|
14
|
-
task
|
14
|
+
task "web" => ["superglue:verify_react"] do
|
15
15
|
template = File.expand_path("../install/web.rb", __dir__)
|
16
16
|
exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{template}"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: superglue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.50.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johny Ho
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.23.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.23.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: form_props
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.0.3
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.0.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activerecord
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,21 +178,18 @@ files:
|
|
178
178
|
- lib/install/templates/web/application.json.props
|
179
179
|
- lib/install/templates/web/application_visit.js
|
180
180
|
- lib/install/templates/web/initializer.rb
|
181
|
+
- lib/install/templates/web/page_to_page_mapping.js
|
181
182
|
- lib/install/templates/web/reducer.js
|
182
183
|
- lib/install/web.rb
|
183
184
|
- lib/superglue.rb
|
184
185
|
- lib/superglue/helpers.rb
|
185
186
|
- lib/superglue/redirection.rb
|
186
187
|
- lib/tasks/install.rake
|
187
|
-
- test/engine_test.rb
|
188
|
-
- test/helpers_test.rb
|
189
|
-
- test/render_test.rb
|
190
|
-
- test/test_helper.rb
|
191
188
|
homepage: https://github.com/thoughtbot/superglue/
|
192
189
|
licenses:
|
193
190
|
- MIT
|
194
191
|
metadata: {}
|
195
|
-
post_install_message:
|
192
|
+
post_install_message:
|
196
193
|
rdoc_options: []
|
197
194
|
require_paths:
|
198
195
|
- lib
|
@@ -203,16 +200,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
203
200
|
version: '0'
|
204
201
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
202
|
requirements:
|
206
|
-
- - "
|
203
|
+
- - ">"
|
207
204
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
205
|
+
version: 1.3.1
|
209
206
|
requirements: []
|
210
|
-
rubygems_version: 3.
|
211
|
-
signing_key:
|
207
|
+
rubygems_version: 3.4.6
|
208
|
+
signing_key:
|
212
209
|
specification_version: 4
|
213
210
|
summary: Rails integration for SuperglueJS
|
214
|
-
test_files:
|
215
|
-
- test/render_test.rb
|
216
|
-
- test/helpers_test.rb
|
217
|
-
- test/engine_test.rb
|
218
|
-
- test/test_helper.rb
|
211
|
+
test_files: []
|
data/test/engine_test.rb
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class EngineTest < ActiveSupport::TestCase
|
4
|
-
test "does not include itself in action controller base when superglue auto include is false" do
|
5
|
-
refute ActionController::Base.included_modules.any? { |m| m.name && m.name.include?('Superglue') }
|
6
|
-
end
|
7
|
-
end
|
data/test/helpers_test.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class HelpersTest < ActiveSupport::TestCase
|
4
|
-
include Superglue::Helpers
|
5
|
-
|
6
|
-
test 'clean_props_at returns nil if qry is nil' do
|
7
|
-
qry = nil
|
8
|
-
|
9
|
-
assert_nil param_to_search_path(qry)
|
10
|
-
end
|
11
|
-
|
12
|
-
test 'clean_props_at returns a refined qry' do
|
13
|
-
qry = 'foo...bar/?)()-'
|
14
|
-
|
15
|
-
assert_equal param_to_search_path(qry), ['foo', 'bar']
|
16
|
-
end
|
17
|
-
|
18
|
-
test 'camelize_path' do
|
19
|
-
path = ['foo_bar', 'foo_bar=1', 'foo_baz_roo']
|
20
|
-
|
21
|
-
assert_equal search_path_to_camelized_param(path), 'fooBar.fooBar=1.fooBazRoo'
|
22
|
-
end
|
23
|
-
end
|
data/test/render_test.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class RenderController < TestController
|
4
|
-
require 'action_view/testing/resolvers'
|
5
|
-
|
6
|
-
append_view_path(ActionView::FixtureResolver.new(
|
7
|
-
'render/simple_render_with_superglue.json.props' => 'json.author "john smith"',
|
8
|
-
'render/simple_render_with_superglue_with_bad_layout.json.props' => 'json.author "john smith"',
|
9
|
-
'layouts/application.json.props' => 'json.data {yield json}',
|
10
|
-
'layouts/does_not_exist.html.erb' => '',
|
11
|
-
'layouts/application.html.erb' => <<~HTML
|
12
|
-
<html>
|
13
|
-
<head>
|
14
|
-
<script><%= @initial_state.strip.html_safe %></script>
|
15
|
-
</head>
|
16
|
-
<body><%=yield%></body>
|
17
|
-
</html>
|
18
|
-
HTML
|
19
|
-
))
|
20
|
-
|
21
|
-
layout 'application'
|
22
|
-
|
23
|
-
def render_action
|
24
|
-
render :action
|
25
|
-
end
|
26
|
-
|
27
|
-
def simple_render_with_superglue
|
28
|
-
@initial_state = render_to_string(formats: [:json], layout: true)
|
29
|
-
render inline: '', layout: true
|
30
|
-
end
|
31
|
-
|
32
|
-
def simple_render_with_superglue_with_bad_layout
|
33
|
-
@initial_state = render_to_string(formats: [:json], layout: 'does_not_exist')
|
34
|
-
render inline: '', layout: true
|
35
|
-
end
|
36
|
-
|
37
|
-
def form_authenticity_token
|
38
|
-
"secret"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class RenderTest < ActionController::TestCase
|
43
|
-
tests RenderController
|
44
|
-
|
45
|
-
|
46
|
-
setup do
|
47
|
-
if Rails.version >= '6'
|
48
|
-
# In rails 6, the fixture orders the templates based on their appearance in the handler
|
49
|
-
# This doesn't happen IRL, so I'm going to explicitly set the handler here.
|
50
|
-
#
|
51
|
-
# Note that the original is the following
|
52
|
-
# @controller.lookup_context.handlers = [:raw, :superglue, :erb, :js, :html, :builder, :ruby]
|
53
|
-
@controller.lookup_context.handlers = [:props, :erb]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
test "simple render with superglue" do
|
58
|
-
get :simple_render_with_superglue
|
59
|
-
|
60
|
-
assert_response 200
|
61
|
-
rendered = <<~HTML
|
62
|
-
<html>
|
63
|
-
<head>
|
64
|
-
<script>{"data":{"author":"john smith"}}</script>
|
65
|
-
</head>
|
66
|
-
<body></body>
|
67
|
-
</html>
|
68
|
-
HTML
|
69
|
-
|
70
|
-
assert_equal rendered, @response.body
|
71
|
-
assert_equal 'text/html', @response.media_type
|
72
|
-
end
|
73
|
-
|
74
|
-
test "simple render when the layout doesn't exist" do
|
75
|
-
err = assert_raise ActionView::MissingTemplate do |e|
|
76
|
-
get :simple_render_with_superglue_with_bad_layout
|
77
|
-
end
|
78
|
-
|
79
|
-
assert_equal(true, err.message.starts_with?('Missing template layouts/does_not_exist with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:props, :erb]}.'))
|
80
|
-
end
|
81
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'rails'
|
2
|
-
require 'abstract_controller'
|
3
|
-
require 'abstract_controller/railties/routes_helpers'
|
4
|
-
require 'action_controller'
|
5
|
-
require 'superglue'
|
6
|
-
require "active_support"
|
7
|
-
require 'active_record'
|
8
|
-
require 'active_support/testing/autorun'
|
9
|
-
require 'active_support/test_case'
|
10
|
-
|
11
|
-
require 'props_template'
|
12
|
-
|
13
|
-
ActiveSupport::TestCase.test_order = :random if ActiveSupport::TestCase.respond_to?(:test_order=)
|
14
|
-
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
15
|
-
Rails.cache = ActiveSupport::Cache::MemoryStore.new
|
16
|
-
|
17
|
-
load File.dirname(__FILE__) + '/support/schema.rb'
|
18
|
-
require 'support/models'
|
19
|
-
require 'support/test_application'
|
20
|
-
|