aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable
diff options
context:
space:
mode:
authorRyan Castner <audiolion@users.noreply.github.com>2019-03-31 13:41:12 -0400
committerKasper Timm Hansen <kaspth@gmail.com>2019-03-31 19:41:12 +0200
commit6d488a22d361d19e3de98c603d98e64ccea8a2f3 (patch)
tree45eb50ca88b0cc1e14f94c5eefd6a97eb901451c /actioncable
parentba4e74e1b73437cce08e319286103e025f7cc803 (diff)
downloadrails-6d488a22d361d19e3de98c603d98e64ccea8a2f3.tar.gz
rails-6d488a22d361d19e3de98c603d98e64ccea8a2f3.tar.bz2
rails-6d488a22d361d19e3de98c603d98e64ccea8a2f3.zip
feat(js): Dynamic ActionCable URL (#35579)
* Failing test case * feat: Dynamic Url Generation Change createWebSocketURL to be a closure that allows url to be evaluated at the time the webSocket is established * refactor: createWebSocketURL to Consumer, remove need for closure Move initial call to createWebSocketURL in createConsumer * docs: Add documentation for dynamic url and string args to createConsumer Co-Authored-By: rmacklin <rmacklin@users.noreply.github.com> [Ryan Castner, rmacklin]
Diffstat (limited to 'actioncable')
-rw-r--r--actioncable/app/assets/javascripts/action_cable.js46
-rw-r--r--actioncable/app/javascript/action_cable/consumer.js21
-rw-r--r--actioncable/app/javascript/action_cable/index.js20
-rw-r--r--actioncable/test/javascript/src/unit/action_cable_test.js7
4 files changed, 62 insertions, 32 deletions
diff --git a/actioncable/app/assets/javascripts/action_cable.js b/actioncable/app/assets/javascripts/action_cable.js
index 4efab2ed46..029c7567ce 100644
--- a/actioncable/app/assets/javascripts/action_cable.js
+++ b/actioncable/app/assets/javascripts/action_cable.js
@@ -28,6 +28,22 @@
throw new TypeError("Cannot call a class as a function");
}
};
+ var createClass = function() {
+ function defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+ return function(Constructor, protoProps, staticProps) {
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) defineProperties(Constructor, staticProps);
+ return Constructor;
+ };
+ }();
var now = function now() {
return new Date().getTime();
};
@@ -432,7 +448,7 @@
var Consumer = function() {
function Consumer(url) {
classCallCheck(this, Consumer);
- this.url = url;
+ this._url = url;
this.subscriptions = new Subscriptions(this);
this.connection = new Connection(this);
}
@@ -452,18 +468,14 @@
return this.connection.open();
}
};
+ createClass(Consumer, [ {
+ key: "url",
+ get: function get$$1() {
+ return createWebSocketURL(this._url);
+ }
+ } ]);
return Consumer;
}();
- function createConsumer() {
- var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getConfig("url") || INTERNAL.default_mount_path;
- return new Consumer(createWebSocketURL(url));
- }
- function getConfig(name) {
- var element = document.head.querySelector("meta[name='action-cable-" + name + "']");
- if (element) {
- return element.getAttribute("content");
- }
- }
function createWebSocketURL(url) {
var webSocketURL = typeof url === "function" ? url() : url;
if (webSocketURL && !/^wss?:/i.test(webSocketURL)) {
@@ -476,6 +488,16 @@
return webSocketURL;
}
}
+ function createConsumer() {
+ var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getConfig("url") || INTERNAL.default_mount_path;
+ return new Consumer(url);
+ }
+ function getConfig(name) {
+ var element = document.head.querySelector("meta[name='action-cable-" + name + "']");
+ if (element) {
+ return element.getAttribute("content");
+ }
+ }
exports.Connection = Connection;
exports.ConnectionMonitor = ConnectionMonitor;
exports.Consumer = Consumer;
@@ -484,9 +506,9 @@
exports.Subscriptions = Subscriptions;
exports.adapters = adapters;
exports.logger = logger;
+ exports.createWebSocketURL = createWebSocketURL;
exports.createConsumer = createConsumer;
exports.getConfig = getConfig;
- exports.createWebSocketURL = createWebSocketURL;
Object.defineProperty(exports, "__esModule", {
value: true
});
diff --git a/actioncable/app/javascript/action_cable/consumer.js b/actioncable/app/javascript/action_cable/consumer.js
index e8440f39f5..51f3b60980 100644
--- a/actioncable/app/javascript/action_cable/consumer.js
+++ b/actioncable/app/javascript/action_cable/consumer.js
@@ -29,11 +29,15 @@ import Subscriptions from "./subscriptions"
export default class Consumer {
constructor(url) {
- this.url = url
+ this._url = url
this.subscriptions = new Subscriptions(this)
this.connection = new Connection(this)
}
+ get url() {
+ return createWebSocketURL(this._url)
+ }
+
send(data) {
return this.connection.send(data)
}
@@ -52,3 +56,18 @@ export default class Consumer {
}
}
}
+
+export function createWebSocketURL(url) {
+ const webSocketURL = typeof url === "function" ? url() : url
+
+ if (webSocketURL && !/^wss?:/i.test(webSocketURL)) {
+ const a = document.createElement("a")
+ a.href = webSocketURL
+ // Fix populating Location properties in IE. Otherwise, protocol will be blank.
+ a.href = a.href
+ a.protocol = a.protocol.replace("http", "ws")
+ return a.href
+ } else {
+ return webSocketURL
+ }
+}
diff --git a/actioncable/app/javascript/action_cable/index.js b/actioncable/app/javascript/action_cable/index.js
index e679745fd7..d484d99179 100644
--- a/actioncable/app/javascript/action_cable/index.js
+++ b/actioncable/app/javascript/action_cable/index.js
@@ -1,6 +1,6 @@
import Connection from "./connection"
import ConnectionMonitor from "./connection_monitor"
-import Consumer from "./consumer"
+import Consumer, { createWebSocketURL } from "./consumer"
import INTERNAL from "./internal"
import Subscription from "./subscription"
import Subscriptions from "./subscriptions"
@@ -16,10 +16,11 @@ export {
Subscriptions,
adapters,
logger,
+ createWebSocketURL,
}
export function createConsumer(url = getConfig("url") || INTERNAL.default_mount_path) {
- return new Consumer(createWebSocketURL(url))
+ return new Consumer(url)
}
export function getConfig(name) {
@@ -28,18 +29,3 @@ export function getConfig(name) {
return element.getAttribute("content")
}
}
-
-export function createWebSocketURL(url) {
- const webSocketURL = typeof url === "function" ? url() : url
-
- if (webSocketURL && !/^wss?:/i.test(webSocketURL)) {
- const a = document.createElement("a")
- a.href = webSocketURL
- // Fix populating Location properties in IE. Otherwise, protocol will be blank.
- a.href = a.href
- a.protocol = a.protocol.replace("http", "ws")
- return a.href
- } else {
- return webSocketURL
- }
-}
diff --git a/actioncable/test/javascript/src/unit/action_cable_test.js b/actioncable/test/javascript/src/unit/action_cable_test.js
index c9d34abc6d..2181f955e3 100644
--- a/actioncable/test/javascript/src/unit/action_cable_test.js
+++ b/actioncable/test/javascript/src/unit/action_cable_test.js
@@ -43,11 +43,14 @@ module("ActionCable", () => {
})
test("uses function to generate URL", assert => {
+ let dynamicURL = testURL
const generateURL = () => {
- return testURL
+ return dynamicURL
}
+
+ dynamicURL = `${testURL}foo`
const consumer = ActionCable.createConsumer(generateURL)
- assert.equal(consumer.url, testURL)
+ assert.equal(consumer.url, `${testURL}foo`)
})
})
})