stimulus-rails 0.1.4 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 723e63c957d1d8a4ab833a4edb197f2379d4604ee68b7587e8bb85560f568ecb
4
- data.tar.gz: efe60efa445d404fdf3faf067223eb6ff187d4d41665cc7c78129b54abb94632
3
+ metadata.gz: d7b182fb2a48a9405b734b3d8180930f181cf115cb52b7d9061f3f92183d2f3e
4
+ data.tar.gz: 663e24b437761d3ff60ad7e78e8dc9ac9191ad91b83935ae95a04100dd6c66c2
5
5
  SHA512:
6
- metadata.gz: f8ea0462b55efd12f2cee6c70fd08a4efeafbb2840deb91fcfb3e2dba7fd7e2c014ec0f1a5b0c5f9906aa997a26fa7db1cb21620412d86faab0b7078226399c7
7
- data.tar.gz: 51300cbb38d24cbd24acc9a835e97bd744702325e18396af174e2c3601597319574860e0c318373c632951e9e81f605c0cecd18d0fb63ded358fbb9d538cd0ee
6
+ metadata.gz: 0d84fd49c9ad55572e525b5239b289fbe9a01839f67a24453efa875357ab0a0ecb30f39bc43df447d565dd75cda282ab21c653e09ff7db36d1150136b53fcbb0
7
+ data.tar.gz: 9e3bfa7a5be5a8457a3612863d7b136fd3c3e514f04367ceacce7327050f2403b69f18305c598cc07311a89cb3fa55c1f4aeb667c0f73e0c76cc15bdc8e684c7
data/README.md CHANGED
@@ -12,13 +12,19 @@ If you want to use Stimulus with a bundler, you should use [Webpacker](https://g
12
12
  2. Run `./bin/bundle install`.
13
13
  3. Run `./bin/rails stimulus:install`
14
14
 
15
- The last command will:
15
+ If using the asset pipeline to manage JavaScript, the last command will:
16
16
 
17
- 1. Create an example controller in `app/assets/javascripts/controllers/hello_controller.js`
17
+ 1. Create an example controller in `app/assets/javascripts/controllers/hello_controller.js`.
18
18
  2. Append the include tags to the `<head>` of your `app/views/layouts/application.html.erb`.
19
19
  3. Initialize your `importmap.json` in `app/assets/javascripts/importmap.json.erb`.
20
20
  4. Ensure JavaScript is included in your `app/assets/config/manifest.js` file for compilation.
21
21
 
22
+ If using Webpacker to manage JavaScript, the last command will:
23
+
24
+ 1. Import the controllers directory in the application pack.
25
+ 2. Create a controllers directory at `app/javascripts/controllers`.
26
+ 3. Create an example controller in `app/javascripts/controllers/hello_controller.js`.
27
+ 4. Install the Stimulus NPM package.
22
28
 
23
29
  ## Usage
24
30
 
@@ -1,21 +1,52 @@
1
1
  import { Application } from "stimulus"
2
2
 
3
3
  const application = Application.start()
4
+ const { controllerAttribute } = application.schema
5
+ const registeredControllers = {}
4
6
 
5
- function autoload() {
6
- Array.from(document.querySelectorAll('[data-controller]')).forEach((element) => {
7
- const controllerNames = element.attributes["data-controller"].value.split(" ")
7
+ function autoloadControllersWithin(element) {
8
+ queryControllerNamesWithin(element).forEach(loadController)
9
+ }
10
+
11
+ function queryControllerNamesWithin(element) {
12
+ return Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).map(extractControllerNamesFrom).flat()
13
+ }
14
+
15
+ function extractControllerNamesFrom(element) {
16
+ return element.getAttribute(controllerAttribute).split(/\s+/).filter(content => content.length)
17
+ }
8
18
 
9
- controllerNames.forEach((controllerName) => {
10
- let controllerFilename = `${controllerName}_controller`
19
+ function loadController(name) {
20
+ import(controllerFilename(name))
21
+ .then(module => registerController(name, module))
22
+ .catch(error => console.log(`Failed to autoload controller: ${name}`, error))
23
+ }
11
24
 
12
- import(controllerFilename).then((controllerModule) => {
13
- application.register(controllerName, controllerModule.default)
14
- }).catch(error => console.log(`Failed to autoload controller: ${controllerName}`))
15
- })
16
- })
25
+ function controllerFilename(name) {
26
+ return `${name.replace(/--/g, "/").replace(/-/g, "_")}_controller`
17
27
  }
18
28
 
19
- autoload()
29
+ function registerController(name, module) {
30
+ if (name in registeredControllers) return
31
+
32
+ application.register(name, module.default)
33
+ registeredControllers[name] = true
34
+ }
35
+
36
+
37
+ new MutationObserver((mutationsList) => {
38
+ for (const { attributeName, target, type } of mutationsList) {
39
+ switch (type) {
40
+ case "attributes": {
41
+ if (attributeName == controllerAttribute && target.getAttribute(controllerAttribute)) {
42
+ extractControllerNamesFrom(target).forEach(loadController)
43
+ }
44
+ }
45
+ case "childList": {
46
+ autoloadControllersWithin(target)
47
+ }
48
+ }
49
+ }
50
+ }).observe(document, { attributeFilter: [controllerAttribute], subtree: true, childList: true })
20
51
 
21
- window.addEventListener("turbo:load", autoload)
52
+ autoloadControllersWithin(document)
@@ -1,10 +1,10 @@
1
1
  module Stimulus::StimulusHelper
2
- def stimulus_include_tags
3
- [
2
+ def stimulus_include_tags(importmap = "importmap.json")
3
+ safe_join [
4
4
  javascript_include_tag("stimulus/libraries/es-module-shims", type: "module"),
5
- tag.script(type: "importmap-shim", src: asset_path("importmap.json")),
5
+ tag.script(type: "importmap-shim", src: asset_path(importmap)),
6
6
  javascript_include_tag("stimulus/libraries/stimulus", type: "module-shim"),
7
7
  javascript_include_tag("stimulus/loaders/autoloader", type: "module-shim")
8
- ].join("\n").html_safe
8
+ ], "\n"
9
9
  end
10
10
  end
@@ -0,0 +1,9 @@
1
+ // Load all the controllers within this directory and all subdirectories.
2
+ // Controller files must be named *_controller.js or *_controller.ts.
3
+
4
+ import { Application } from "stimulus"
5
+ import { definitionsFromContext } from "stimulus/webpack-helpers"
6
+
7
+ const application = Application.start()
8
+ const context = require.context("controllers", true, /_controller\.(js|ts)$/)
9
+ application.load(definitionsFromContext(context))
@@ -0,0 +1 @@
1
+ import "controllers"
@@ -0,0 +1,10 @@
1
+ say "Appending Stimulus setup code to #{Webpacker.config.source_entry_path}/application.js"
2
+ append_to_file "#{Webpacker.config.source_entry_path}/application.js" do
3
+ "\n" + open("#{__dir__}/application.js").read
4
+ end
5
+
6
+ say "Creating controllers directory"
7
+ directory "#{__dir__}/app/assets/javascripts/controllers", "#{Webpacker.config.source_path}/controllers"
8
+
9
+ say "Installing all Stimulus dependencies"
10
+ run "yarn add stimulus"
@@ -5,7 +5,9 @@ module Stimulus
5
5
  config.autoload_once_paths = %w( #{root}/app/helpers )
6
6
 
7
7
  initializer "stimulus.assets" do
8
- Rails.application.config.assets.precompile += %w( importmap.json stimulus/manifest )
8
+ if Rails.application.config.respond_to?(:assets)
9
+ Rails.application.config.assets.precompile += %w( importmap.json stimulus/manifest )
10
+ end
9
11
  end
10
12
 
11
13
  initializer "stimulus.helpers" do
@@ -13,8 +15,10 @@ module Stimulus
13
15
  helper Stimulus::StimulusHelper
14
16
  end
15
17
 
16
- Rails.application.config.assets.configure do |env|
17
- env.context_class.class_eval { include Stimulus::ImportmapHelper }
18
+ if Rails.application.config.respond_to?(:assets)
19
+ Rails.application.config.assets.configure do |env|
20
+ env.context_class.class_eval { include Stimulus::ImportmapHelper }
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -1,16 +1,15 @@
1
1
  module Stimulus::ImportmapHelper
2
2
  def importmap_list_with_stimulus_from(*paths)
3
- [ %("stimulus": "#{asset_path("stimulus/libraries/stimulus")}"), importmap_list_from(*paths) ].join(",\n")
3
+ [ %("stimulus": "#{asset_path("stimulus/libraries/stimulus")}"), importmap_list_from(*paths) ].reject(&:blank?).join(",\n")
4
4
  end
5
5
 
6
6
  def importmap_list_from(*paths)
7
7
  Array(paths).flat_map do |path|
8
- if (absolute_path = Rails.root.join(path)).exist?
9
- absolute_path.children.collect do |module_filename|
10
- next unless module_filename.extname =~ /js(m)?$/
11
-
12
- module_name = importmap_module_name_from(module_filename)
13
- module_path = asset_path("#{absolute_path.basename.to_s}/#{module_filename.basename}")
8
+ if (absolute_path = absolute_root_of(path)).exist?
9
+ find_javascript_files_in_tree(absolute_path).collect do |filename|
10
+ module_filename = filename.relative_path_from(absolute_path)
11
+ module_name = importmap_module_name_from(module_filename)
12
+ module_path = asset_path(absolute_path.basename.join(module_filename))
14
13
 
15
14
  %("#{module_name}": "#{module_path}")
16
15
  end
@@ -21,6 +20,14 @@ module Stimulus::ImportmapHelper
21
20
  private
22
21
  # Strip off the extension and any versioning data for an absolute module name.
23
22
  def importmap_module_name_from(filename)
24
- filename.basename.to_s.remove(filename.extname).split("@").first
23
+ filename.to_s.remove(filename.extname).split("@").first
24
+ end
25
+
26
+ def find_javascript_files_in_tree(path)
27
+ Dir[path.join("**/*.js{,m}")].collect { |file| Pathname.new(file) }.select(&:file?)
28
+ end
29
+
30
+ def absolute_root_of(path)
31
+ (pathname = Pathname.new(path)).absolute? ? pathname : Rails.root.join(path)
25
32
  end
26
33
  end
@@ -1,3 +1,3 @@
1
1
  module Stimulus
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.4"
3
3
  end
@@ -1,6 +1,24 @@
1
+ def run_stimulus_install_template(path) system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/#{path}.rb", __dir__)}" end
2
+
1
3
  namespace :stimulus do
2
4
  desc "Install Stimulus into the app"
3
5
  task :install do
4
- system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/stimulus.rb", __dir__)}"
6
+ if defined?(Webpacker::Engine)
7
+ Rake::Task["stimulus:install:webpacker"].invoke
8
+ else
9
+ Rake::Task["stimulus:install:asset_pipeline"].invoke
10
+ end
11
+ end
12
+
13
+ namespace :install do
14
+ desc "Install Stimulus on the app with the asset pipeline"
15
+ task :asset_pipeline do
16
+ run_stimulus_install_template "stimulus_with_asset_pipeline"
17
+ end
18
+
19
+ desc "Install Stimulus on the app with webpacker"
20
+ task :webpacker do
21
+ run_stimulus_install_template "stimulus_with_webpacker"
22
+ end
5
23
  end
6
24
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stimulus-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Stephenson
8
8
  - Javan Mahkmali
9
9
  - David Heinemeier Hansson
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-01-15 00:00:00.000000000 Z
13
+ date: 2021-06-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -26,7 +26,7 @@ dependencies:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
28
  version: 6.0.0
29
- description:
29
+ description:
30
30
  email: david@loudthinking.com
31
31
  executables: []
32
32
  extensions: []
@@ -40,12 +40,14 @@ files:
40
40
  - app/assets/javascripts/stimulus/libraries/stimulus.js
41
41
  - app/assets/javascripts/stimulus/libraries/stimulus@2.js
42
42
  - app/assets/javascripts/stimulus/loaders/autoloader.js
43
- - app/assets/javascripts/stimulus/loaders/preloader.js.erb
44
43
  - app/assets/javascripts/stimulus/manifest.js
45
44
  - app/helpers/stimulus/stimulus_helper.rb
46
45
  - lib/install/app/assets/javascripts/controllers/hello_controller.js
46
+ - lib/install/app/assets/javascripts/controllers/index.js
47
47
  - lib/install/app/assets/javascripts/importmap.json.erb
48
- - lib/install/stimulus.rb
48
+ - lib/install/application.js
49
+ - lib/install/stimulus_with_asset_pipeline.rb
50
+ - lib/install/stimulus_with_webpacker.rb
49
51
  - lib/stimulus-rails.rb
50
52
  - lib/stimulus/engine.rb
51
53
  - lib/stimulus/importmap_helper.rb
@@ -57,7 +59,7 @@ licenses:
57
59
  metadata:
58
60
  homepage_uri: https://stimulus.hotwire.dev
59
61
  source_code_uri: https://github.com/hotwired/stimulus-rails
60
- post_install_message:
62
+ post_install_message:
61
63
  rdoc_options: []
62
64
  require_paths:
63
65
  - lib
@@ -72,8 +74,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
74
  - !ruby/object:Gem::Version
73
75
  version: '0'
74
76
  requirements: []
75
- rubygems_version: 3.1.2
76
- signing_key:
77
+ rubygems_version: 3.1.4
78
+ signing_key:
77
79
  specification_version: 4
78
80
  summary: A modest JavaScript framework for the HTML you already have.
79
81
  test_files: []
@@ -1,20 +0,0 @@
1
- // Experimental: Not currently exposed.
2
- import { Application } from "stimulus"
3
-
4
- const application = Application.start()
5
-
6
- async function preloadControllers() {
7
- const imports = await fetch("<%= asset_path "importmap.json" %>").then(r => r.json()).then(json => json.imports)
8
-
9
- for (const name in imports) {
10
- if (name.startsWith("controllers/")) {
11
- let controllerName = name.replace(/controllers\//, "").replace("_controller", "")
12
-
13
- import(imports[name]).then((module) => {
14
- application.register(controllerName, module.default)
15
- }).catch(error => console.log(error))
16
- }
17
- }
18
- }
19
-
20
- preloadControllers()