stimulus-rails 0.1.3 → 0.2.3

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: 0ccf391e30e2e3ec0f91bdc894bba78582341c77dc33917dc094863f95767172
4
- data.tar.gz: ac90fc101aabdf0e027bd281e69ab5d709116dc8d7a8200c258198d932534aeb
3
+ metadata.gz: 294b1fb5168db9b241b1a7f5e05d9bbcea2dc384c55ca0b2b1cef1731ec71c1e
4
+ data.tar.gz: 1f29da6aa09938993859dc7c362509d9bc3b2cab1fd7259dda9a1c2fde9eb7ab
5
5
  SHA512:
6
- metadata.gz: 1ff414d0de6993b78d077961f136d7f2cf72a5966a698ad0713698e96a14c40c70d46ca6c95cd575e14a3dfb044e0ac05dd784db268201b17fc067ab923ab5d1
7
- data.tar.gz: 7f8f2e9a41e88ec03fdc936fadacaa109dd10890e6797cdd6d7b2484dc3eb746c31ee9d1fa07265ad5cf3e3ab87b40dd42efcddc87044eaa29ee897344ada441
6
+ metadata.gz: 78242453a57877148c68f4250cc8eb9a29f10e064512aee668c56a2b4f8ab71eb8448ae4a62e30af075f559469166b6da91df143ac46ba06a2e5a1af0facbb5c
7
+ data.tar.gz: 004f62719a205a64f1f76d44501960100583e3af56c8f9c32a1a6f71aca4c23a5b39d3a8d0c898d77761c609032feb81c463ee3766ac633ba04690d96c8e7780
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
- 4. Ensure JavaScript is included in your `app/config/manifest.js` file for compilation.
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
2
  def stimulus_include_tags
3
- [
3
+ safe_join [
4
4
  javascript_include_tag("stimulus/libraries/es-module-shims", type: "module"),
5
5
  tag.script(type: "importmap-shim", src: asset_path("importmap.json")),
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.
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$/)
9
+ application.load(definitionsFromContext(context))
@@ -0,0 +1 @@
1
+ import "controllers"
@@ -2,7 +2,7 @@ say "Copying Stimulus JavaScript"
2
2
  directory "#{__dir__}/app/assets/javascripts", "app/assets/javascripts"
3
3
  empty_directory_with_keep_file "app/assets/javascripts/libraries"
4
4
 
5
- say "Add app/javascripts to asset pipeline manifest"
5
+ say "Add app/assets/javascripts to asset pipeline manifest"
6
6
  append_to_file Rails.root.join("app/assets/config/manifest.js").to_s, "//= link_tree ../javascripts\n"
7
7
 
8
8
  APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.erb")
@@ -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"
@@ -1,14 +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
- module_name = importmap_module_name_from(module_filename)
11
- 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))
12
13
 
13
14
  %("#{module_name}": "#{module_path}")
14
15
  end
@@ -19,6 +20,14 @@ module Stimulus::ImportmapHelper
19
20
  private
20
21
  # Strip off the extension and any versioning data for an absolute module name.
21
22
  def importmap_module_name_from(filename)
22
- 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)
23
32
  end
24
33
  end
@@ -1,3 +1,3 @@
1
1
  module Stimulus
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.3"
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.3
4
+ version: 0.2.3
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-02-04 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
@@ -73,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
75
  version: '0'
74
76
  requirements: []
75
77
  rubygems_version: 3.1.2
76
- signing_key:
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()