stimulus_reflex 3.5.0.pre10 → 3.5.0.rc1

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: b7cb01c3a44e8b59bd999bc745276af2f32d073e7a96503f229b72681ab482a3
4
- data.tar.gz: 2978f4e101687acc6740da064c8d002cd5b137f566e8d9bed5e80a93f7c69942
3
+ metadata.gz: f9e4f16a6c108abed76ee50881ec95b7595a8182092422eaec27a9ba32cfb3b6
4
+ data.tar.gz: 5f463ec6bedc1462e477714599f68a9c22479114af4284de427caac9144cf71c
5
5
  SHA512:
6
- metadata.gz: d39ef8e76cc723f99813eb3bbb45c69954f87a915b35a90fb73e094b59a43eff92a236bafe9f19af3d749c0ad553b2687812f9a7bb487a36349fc12f705e536e
7
- data.tar.gz: e632dc8af1e1e7d370b49014f4b8eb1d8ad002f55c8c7e2016a21902c8dc041385aa2360e71dfbd14cc9f2d3e430f094f943fea313b2f87ecb66a8a45f6e0d9a
6
+ metadata.gz: f05665f72b18c7cd0afee54fa099ec29df4e736fa83d8ec87756a3be80be3402d74d715cafa70b41092091794d2fc4a002e6998d676574365e5b756f53eaa6a0
7
+ data.tar.gz: f9d044f8d60a6154aab10ed680b51da5b6afc499d35a19a4eaefb233164519f74aef05e2583fe9f6194bf4989f6894a3065f3de164658ea9691da9df0dec030d
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stimulus_reflex (3.5.0.pre10)
4
+ stimulus_reflex (3.5.0.rc1)
5
5
  actioncable (>= 5.2, < 8)
6
6
  actionpack (>= 5.2, < 8)
7
7
  actionview (>= 5.2, < 8)
8
8
  activesupport (>= 5.2, < 8)
9
- cable_ready (>= 5.0.0.pre10)
9
+ cable_ready (>= 5.0.0.rc1)
10
10
  nokogiri (~> 1.0)
11
- rack (~> 2.0)
11
+ rack (>= 2, < 4)
12
12
  railties (>= 5.2, < 8)
13
13
  redis (>= 4.0, < 6.0)
14
14
 
@@ -82,14 +82,14 @@ GEM
82
82
  tzinfo (~> 2.0)
83
83
  ast (2.4.2)
84
84
  builder (3.2.4)
85
- cable_ready (5.0.0.pre10)
85
+ cable_ready (5.0.0.rc1)
86
86
  actionpack (>= 5.2)
87
87
  actionview (>= 5.2)
88
88
  activesupport (>= 5.2)
89
89
  railties (>= 5.2)
90
90
  thread-local (>= 1.1.0)
91
91
  concurrent-ruby (1.2.0)
92
- connection_pool (2.3.0)
92
+ connection_pool (2.4.0)
93
93
  crass (1.0.6)
94
94
  date (3.3.3)
95
95
  erubi (1.12.0)
@@ -131,7 +131,7 @@ GEM
131
131
  parser (3.2.1.0)
132
132
  ast (~> 2.4.1)
133
133
  racc (1.6.2)
134
- rack (2.2.6.2)
134
+ rack (2.2.6.4)
135
135
  rack-test (2.0.2)
136
136
  rack (>= 1.3)
137
137
  rails (7.0.4.2)
@@ -164,7 +164,7 @@ GEM
164
164
  rake (13.0.6)
165
165
  redis (5.0.6)
166
166
  redis-client (>= 0.9.0)
167
- redis-client (0.12.2)
167
+ redis-client (0.14.0)
168
168
  connection_pool
169
169
  regexp_parser (2.7.0)
170
170
  rexml (3.2.5)
data/README.md CHANGED
@@ -84,7 +84,7 @@ Please note that we are not actively providing support on Stack Overflow. If you
84
84
 
85
85
  ## 🚀 Installation and upgrading
86
86
 
87
- CLI and manual setup procedures are fully detailed in the [official docs](https://docs.stimulusreflex.com/setup).
87
+ CLI and manual setup procedures are fully detailed in the [official docs](https://docs.stimulusreflex.com/hello-world/setup.html).
88
88
 
89
89
  ### Rubygem
90
90
 
@@ -109,7 +109,7 @@ yarn add stimulus_reflex
109
109
 
110
110
  # ...
111
111
 
112
- pin 'stimulus_reflex', to: 'stimulus_reflex.min.js', preload: true
112
+ pin 'stimulus_reflex', to: 'stimulus_reflex.js', preload: true
113
113
  ```
114
114
 
115
115
  #### Rails Asset pipeline (Sprockets):
@@ -117,7 +117,7 @@ pin 'stimulus_reflex', to: 'stimulus_reflex.min.js', preload: true
117
117
  ```html+erb
118
118
  <!-- app/views/layouts/application.html.erb -->
119
119
 
120
- <%= javascript_include_tag "stimulus_reflex.umd.min.js", "data-turbo-track": "reload" %>
120
+ <%= javascript_include_tag "stimulus_reflex.umd.js", "data-turbo-track": "reload" %>
121
121
  ```
122
122
 
123
123
  ## 🙏 Contributing
@@ -1,8 +1,288 @@
1
1
  import { Controller } from "@hotwired/stimulus";
2
2
 
3
+ import CableReady, { Utils } from "cable_ready";
4
+
3
5
  import { createConsumer } from "@rails/actioncable";
4
6
 
5
- import CableReady, { Utils } from "cable_ready";
7
+ /*!
8
+ * Toastify js 1.12.0
9
+ * https://github.com/apvarun/toastify-js
10
+ * @license MIT licensed
11
+ *
12
+ * Copyright (C) 2018 Varun A P
13
+ */ class Toastify {
14
+ defaults={
15
+ oldestFirst: true,
16
+ text: "Toastify is awesome!",
17
+ node: undefined,
18
+ duration: 3e3,
19
+ selector: undefined,
20
+ callback: function() {},
21
+ destination: undefined,
22
+ newWindow: false,
23
+ close: false,
24
+ gravity: "toastify-top",
25
+ positionLeft: false,
26
+ position: "",
27
+ backgroundColor: "",
28
+ avatar: "",
29
+ className: "",
30
+ stopOnFocus: true,
31
+ onClick: function() {},
32
+ offset: {
33
+ x: 0,
34
+ y: 0
35
+ },
36
+ escapeMarkup: true,
37
+ ariaLive: "polite",
38
+ style: {
39
+ background: ""
40
+ }
41
+ };
42
+ constructor(options) {
43
+ this.version = "1.12.0";
44
+ this.options = {};
45
+ this.toastElement = null;
46
+ this._rootElement = document.body;
47
+ this._init(options);
48
+ }
49
+ showToast() {
50
+ this.toastElement = this._buildToast();
51
+ if (typeof this.options.selector === "string") {
52
+ this._rootElement = document.getElementById(this.options.selector);
53
+ } else if (this.options.selector instanceof HTMLElement || this.options.selector instanceof ShadowRoot) {
54
+ this._rootElement = this.options.selector;
55
+ } else {
56
+ this._rootElement = document.body;
57
+ }
58
+ if (!this._rootElement) {
59
+ throw "Root element is not defined";
60
+ }
61
+ this._rootElement.insertBefore(this.toastElement, this._rootElement.firstChild);
62
+ this._reposition();
63
+ if (this.options.duration > 0) {
64
+ this.toastElement.timeOutValue = window.setTimeout((() => {
65
+ this._removeElement(this.toastElement);
66
+ }), this.options.duration);
67
+ }
68
+ return this;
69
+ }
70
+ hideToast() {
71
+ if (this.toastElement.timeOutValue) {
72
+ clearTimeout(this.toastElement.timeOutValue);
73
+ }
74
+ this._removeElement(this.toastElement);
75
+ }
76
+ _init(options) {
77
+ this.options = Object.assign(this.defaults, options);
78
+ if (this.options.backgroundColor) {
79
+ console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
80
+ }
81
+ this.toastElement = null;
82
+ this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : "toastify-top";
83
+ this.options.stopOnFocus = options.stopOnFocus === undefined ? true : options.stopOnFocus;
84
+ if (options.backgroundColor) {
85
+ this.options.style.background = options.backgroundColor;
86
+ }
87
+ }
88
+ _buildToast() {
89
+ if (!this.options) {
90
+ throw "Toastify is not initialized";
91
+ }
92
+ let divElement = document.createElement("div");
93
+ divElement.className = `toastify on ${this.options.className}`;
94
+ divElement.className += ` toastify-${this.options.position}`;
95
+ divElement.className += ` ${this.options.gravity}`;
96
+ for (const property in this.options.style) {
97
+ divElement.style[property] = this.options.style[property];
98
+ }
99
+ if (this.options.ariaLive) {
100
+ divElement.setAttribute("aria-live", this.options.ariaLive);
101
+ }
102
+ if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
103
+ divElement.appendChild(this.options.node);
104
+ } else {
105
+ if (this.options.escapeMarkup) {
106
+ divElement.innerText = this.options.text;
107
+ } else {
108
+ divElement.innerHTML = this.options.text;
109
+ }
110
+ if (this.options.avatar !== "") {
111
+ let avatarElement = document.createElement("img");
112
+ avatarElement.src = this.options.avatar;
113
+ avatarElement.className = "toastify-avatar";
114
+ if (this.options.position == "left") {
115
+ divElement.appendChild(avatarElement);
116
+ } else {
117
+ divElement.insertAdjacentElement("afterbegin", avatarElement);
118
+ }
119
+ }
120
+ }
121
+ if (this.options.close === true) {
122
+ let closeElement = document.createElement("button");
123
+ closeElement.type = "button";
124
+ closeElement.setAttribute("aria-label", "Close");
125
+ closeElement.className = "toast-close";
126
+ closeElement.innerHTML = "&#10006;";
127
+ closeElement.addEventListener("click", (event => {
128
+ event.stopPropagation();
129
+ this._removeElement(this.toastElement);
130
+ window.clearTimeout(this.toastElement.timeOutValue);
131
+ }));
132
+ const width = window.innerWidth > 0 ? window.innerWidth : screen.width;
133
+ if (this.options.position == "left" && width > 360) {
134
+ divElement.insertAdjacentElement("afterbegin", closeElement);
135
+ } else {
136
+ divElement.appendChild(closeElement);
137
+ }
138
+ }
139
+ if (this.options.stopOnFocus && this.options.duration > 0) {
140
+ divElement.addEventListener("mouseover", (event => {
141
+ window.clearTimeout(divElement.timeOutValue);
142
+ }));
143
+ divElement.addEventListener("mouseleave", (() => {
144
+ divElement.timeOutValue = window.setTimeout((() => {
145
+ this._removeElement(divElement);
146
+ }), this.options.duration);
147
+ }));
148
+ }
149
+ if (typeof this.options.destination !== "undefined") {
150
+ divElement.addEventListener("click", (event => {
151
+ event.stopPropagation();
152
+ if (this.options.newWindow === true) {
153
+ window.open(this.options.destination, "_blank");
154
+ } else {
155
+ window.location = this.options.destination;
156
+ }
157
+ }));
158
+ }
159
+ if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
160
+ divElement.addEventListener("click", (event => {
161
+ event.stopPropagation();
162
+ this.options.onClick();
163
+ }));
164
+ }
165
+ if (typeof this.options.offset === "object") {
166
+ const x = this._getAxisOffsetAValue("x", this.options);
167
+ const y = this._getAxisOffsetAValue("y", this.options);
168
+ const xOffset = this.options.position == "left" ? x : `-${x}`;
169
+ const yOffset = this.options.gravity == "toastify-top" ? y : `-${y}`;
170
+ divElement.style.transform = `translate(${xOffset},${yOffset})`;
171
+ }
172
+ return divElement;
173
+ }
174
+ _removeElement(toastElement) {
175
+ toastElement.className = toastElement.className.replace(" on", "");
176
+ window.setTimeout((() => {
177
+ if (this.options.node && this.options.node.parentNode) {
178
+ this.options.node.parentNode.removeChild(this.options.node);
179
+ }
180
+ if (toastElement.parentNode) {
181
+ toastElement.parentNode.removeChild(toastElement);
182
+ }
183
+ this.options.callback.call(toastElement);
184
+ this._reposition();
185
+ }), 400);
186
+ }
187
+ _reposition() {
188
+ let topLeftOffsetSize = {
189
+ top: 15,
190
+ bottom: 15
191
+ };
192
+ let topRightOffsetSize = {
193
+ top: 15,
194
+ bottom: 15
195
+ };
196
+ let offsetSize = {
197
+ top: 15,
198
+ bottom: 15
199
+ };
200
+ let allToasts = this._rootElement.querySelectorAll(".toastify");
201
+ let classUsed;
202
+ for (let i = 0; i < allToasts.length; i++) {
203
+ if (allToasts[i].classList.contains("toastify-top") === true) {
204
+ classUsed = "toastify-top";
205
+ } else {
206
+ classUsed = "toastify-bottom";
207
+ }
208
+ let height = allToasts[i].offsetHeight;
209
+ classUsed = classUsed.substr(9, classUsed.length - 1);
210
+ let offset = 15;
211
+ let width = window.innerWidth > 0 ? window.innerWidth : screen.width;
212
+ if (width <= 360) {
213
+ allToasts[i].style[classUsed] = `${offsetSize[classUsed]}px`;
214
+ offsetSize[classUsed] += height + offset;
215
+ } else {
216
+ if (allToasts[i].classList.contains("toastify-left") === true) {
217
+ allToasts[i].style[classUsed] = `${topLeftOffsetSize[classUsed]}px`;
218
+ topLeftOffsetSize[classUsed] += height + offset;
219
+ } else {
220
+ allToasts[i].style[classUsed] = `${topRightOffsetSize[classUsed]}px`;
221
+ topRightOffsetSize[classUsed] += height + offset;
222
+ }
223
+ }
224
+ }
225
+ }
226
+ _getAxisOffsetAValue(axis, options) {
227
+ if (options.offset[axis]) {
228
+ if (isNaN(options.offset[axis])) {
229
+ return options.offset[axis];
230
+ } else {
231
+ return `${options.offset[axis]}px`;
232
+ }
233
+ }
234
+ return "0px";
235
+ }
236
+ }
237
+
238
+ function StartToastifyInstance(options) {
239
+ return new Toastify(options);
240
+ }
241
+
242
+ CableReady.operations.stimulusReflexVersionMismatch = operation => {
243
+ const levels = {
244
+ info: {},
245
+ success: {
246
+ background: "#198754",
247
+ color: "white"
248
+ },
249
+ warn: {
250
+ background: "#ffc107",
251
+ color: "black"
252
+ },
253
+ error: {
254
+ background: "#dc3545",
255
+ color: "white"
256
+ }
257
+ };
258
+ const defaults = {
259
+ selector: setupToastify(),
260
+ close: true,
261
+ duration: 30 * 1e3,
262
+ gravity: "bottom",
263
+ position: "right",
264
+ newWindow: true,
265
+ style: levels[operation.level || "info"]
266
+ };
267
+ StartToastifyInstance({
268
+ ...defaults,
269
+ ...operation
270
+ }).showToast();
271
+ };
272
+
273
+ function setupToastify() {
274
+ const id = "stimulus-reflex-toast-element";
275
+ let element = document.querySelector(`#${id}`);
276
+ if (!element) {
277
+ element = document.createElement("div");
278
+ element.id = id;
279
+ document.documentElement.appendChild(element);
280
+ const styles = document.createElement("style");
281
+ styles.innerHTML = `\n #${id} .toastify {\n padding: 12px 20px;\n color: #ffffff;\n display: inline-block;\n background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);\n background: linear-gradient(135deg, #73a5ff, #5477f5);\n position: fixed;\n opacity: 0;\n transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);\n border-radius: 2px;\n cursor: pointer;\n text-decoration: none;\n max-width: calc(50% - 20px);\n z-index: 2147483647;\n bottom: -150px;\n right: 15px;\n }\n\n #${id} .toastify.on {\n opacity: 1;\n }\n\n #${id} .toast-close {\n background: transparent;\n border: 0;\n color: white;\n cursor: pointer;\n font-family: inherit;\n font-size: 1em;\n opacity: 0.4;\n padding: 0 5px;\n }\n `;
282
+ document.head.appendChild(styles);
283
+ }
284
+ return element;
285
+ }
6
286
 
7
287
  let deprecationWarnings = true;
8
288
 
@@ -170,6 +450,8 @@ const getReflexRoots = element => {
170
450
  return list;
171
451
  };
172
452
 
453
+ const reflexNameToControllerIdentifier = reflexName => reflexName.replace(/([a-z0–9])([A-Z])/g, "$1-$2").replace(/(::)/g, "--").replace(/-reflex$/gi, "").toLowerCase();
454
+
173
455
  const stages = [ "created", "before", "delivered", "queued", "after", "finalized", "success", "error", "halted", "forbidden" ];
174
456
 
175
457
  let lastReflex;
@@ -656,7 +938,7 @@ const extractDataAttributes = element => {
656
938
 
657
939
  var name = "stimulus_reflex";
658
940
 
659
- var version = "3.5.0-pre10";
941
+ var version = "3.5.0-rc1";
660
942
 
661
943
  var description = "Build reactive applications with the Rails tooling you already know and love.";
662
944
 
@@ -693,8 +975,9 @@ var scripts = {
693
975
  "build:watch": "yarn rollup -wc",
694
976
  watch: "yarn build:watch",
695
977
  test: "web-test-runner javascript/test/**/*.test.js",
978
+ "test:watch": "yarn test --watch",
696
979
  "docs:dev": "vitepress dev docs",
697
- "docs:build": "vitepress build docs",
980
+ "docs:build": "vitepress build docs && cp docs/_redirects docs/.vitepress/dist",
698
981
  "docs:preview": "vitepress preview docs"
699
982
  };
700
983
 
@@ -703,9 +986,9 @@ var peerDependencies = {
703
986
  };
704
987
 
705
988
  var dependencies = {
706
- "@hotwired/stimulus": ">= 3.0, < 4",
707
- "@rails/actioncable": ">= 6.0, < 8",
708
- cable_ready: "5.0.0-pre10"
989
+ "@hotwired/stimulus": "^3",
990
+ "@rails/actioncable": "^6 || ^7",
991
+ cable_ready: "5.0.0-rc1"
709
992
  };
710
993
 
711
994
  var devDependencies = {
@@ -715,10 +998,11 @@ var devDependencies = {
715
998
  "@rollup/plugin-terser": "^0.4.0",
716
999
  "@web/dev-server-esbuild": "^0.3.3",
717
1000
  "@web/dev-server-rollup": "^0.3.21",
718
- "@web/test-runner": "^0.15.0",
1001
+ "@web/test-runner": "^0.15.1",
719
1002
  "prettier-standard": "^16.4.1",
720
- rollup: "^3.17.1",
721
- vitepress: "^1.0.0-alpha.47"
1003
+ rollup: "^3.19.1",
1004
+ "toastify-js": "^1.12.0",
1005
+ vitepress: "^1.0.0-alpha.56"
722
1006
  };
723
1007
 
724
1008
  var packageInfo = {
@@ -948,11 +1232,11 @@ const error = (reflex, event) => {
948
1232
  })));
949
1233
  };
950
1234
 
951
- const localReflexControllers = element => attributeValues(element.getAttribute(Schema.controller)).reduce(((memo, name) => {
952
- const controller = App.app.getControllerForElementAndIdentifier(element, name);
953
- if (controller && controller.StimulusReflex) memo.push(controller);
954
- return memo;
955
- }), []);
1235
+ const localReflexControllers = element => {
1236
+ const potentialIdentifiers = attributeValues(element.getAttribute(Schema.controller));
1237
+ const potentialControllers = potentialIdentifiers.map((identifier => App.app.getControllerForElementAndIdentifier(element, identifier)));
1238
+ return potentialControllers.filter((controller => controller && controller.StimulusReflex));
1239
+ };
956
1240
 
957
1241
  const allReflexControllers = element => {
958
1242
  let controllers = [];
@@ -965,8 +1249,9 @@ const allReflexControllers = element => {
965
1249
 
966
1250
  const findControllerByReflexName = (reflexName, controllers) => {
967
1251
  const controller = controllers.find((controller => {
968
- if (!controller.identifier) return;
969
- return extractReflexName(reflexName).replace(/([a-z0–9])([A-Z])/g, "$1-$2").replace(/(::)/g, "--").toLowerCase() === controller.identifier;
1252
+ if (!controller || !controller.identifier) return;
1253
+ const identifier = reflexNameToControllerIdentifier(extractReflexName(reflexName));
1254
+ return identifier === controller.identifier;
970
1255
  }));
971
1256
  return controller || controllers[0];
972
1257
  };
@@ -976,18 +1261,22 @@ const scanForReflexes = debounce((() => {
976
1261
  reflexElements.forEach((element => scanForReflexesOnElement(element)));
977
1262
  }), 20);
978
1263
 
979
- const scanForReflexesOnElement = element => {
1264
+ const scanForReflexesOnElement = (element, controller = null) => {
980
1265
  const controllerAttribute = element.getAttribute(Schema.controller);
981
- const controllers = attributeValues(controllerAttribute);
1266
+ const controllers = attributeValues(controllerAttribute).filter((controller => controller !== "stimulus-reflex"));
982
1267
  const reflexAttribute = element.getAttribute(Schema.reflex);
983
1268
  const reflexAttributeNames = attributeValues(reflexAttribute);
984
1269
  const actionAttribute = element.getAttribute(Schema.action);
985
1270
  const actions = attributeValues(actionAttribute).filter((action => !action.includes("#__perform")));
986
1271
  reflexAttributeNames.forEach((reflexName => {
987
- const controller = findControllerByReflexName(reflexName, allReflexControllers(element));
1272
+ const potentialControllers = [ controller ].concat(allReflexControllers(element));
1273
+ controller = findControllerByReflexName(reflexName, potentialControllers);
988
1274
  const controllerName = controller ? controller.identifier : "stimulus-reflex";
989
1275
  actions.push(`${reflexName.split("->")[0]}->${controllerName}#__perform`);
990
- controllers.push(controllerName);
1276
+ const parentControllerElement = element.closest(`[data-controller~=${controllerName}]`);
1277
+ if (!parentControllerElement) {
1278
+ controllers.push(controllerName);
1279
+ }
991
1280
  }));
992
1281
  const controllerValue = attributeValue(controllers);
993
1282
  const actionValue = attributeValue(actions);
@@ -1114,7 +1403,7 @@ const register = (controller, options = {}) => {
1114
1403
  });
1115
1404
  }
1116
1405
  });
1117
- scanForReflexesOnElement(controller.element);
1406
+ scanForReflexesOnElement(controller.element, controller);
1118
1407
  emitEvent("stimulus-reflex:controller-registered", {
1119
1408
  detail: {
1120
1409
  controller: controller