Serve embed script without redirect

phx13
Marcin Kulik 7 years ago
parent e03e35ad6a
commit 3b798f61c9

@ -1,90 +0,0 @@
// asciinema embedded player
(function() {
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function params(container, script) {
function format(name) {
var value = script.getAttribute('data-' + name);
if (value) {
return name + '=' + value;
}
}
var options = ['size', 'speed', 'autoplay', 'loop', 'theme', 't', 'preload', 'cols', 'rows'];
return '?' + options.map(format).filter(Boolean).join('&');
}
function locationFromString(string) {
var parser = document.createElement('a');
parser.href = string;
return parser;
}
function apiHostFromScript(script) {
var location = locationFromString(script.src);
return location.protocol + '//' + location.host;
}
function insertPlayer(script) {
// do not insert player if there's one already associated with this script
if (script.dataset.player) {
return;
}
var apiHost = apiHostFromScript(script);
var asciicastId = script.id.split('-')[1];
var container = document.createElement('div');
container.id = "asciicast-container-" + asciicastId;
container.className = 'asciicast';
container.style.display = 'block';
container.style.float = 'none';
container.style.overflow = 'hidden';
container.style.padding = 0;
container.style.margin = '20px 0';
insertAfter(script, container);
var iframe = document.createElement('iframe');
iframe.src = apiHost + "/a/" + asciicastId + '/embed' + params(container, script);
iframe.id = "asciicast-iframe-" + asciicastId;
iframe.name = "asciicast-iframe-" + asciicastId;
iframe.scrolling = "no";
iframe.setAttribute('allowFullScreen', 'true');
iframe.style.overflow = "hidden";
iframe.style.margin = 0;
iframe.style.border = 0;
iframe.style.display = "inline-block";
iframe.style.width = "100%";
iframe.style.float = "none";
iframe.style.visibility = "hidden";
iframe.onload = function() { this.style.visibility = 'visible' };
container.appendChild(iframe);
function receiveSize(e) {
if (e.origin === apiHost) {
var name = e.data[0];
var data = e.data[1];
var iframeWindow = iframe.contentWindow || iframe;
if (e.source == iframeWindow && name == 'asciicast:size') {
iframe.style.width = '' + data.width + 'px';
iframe.style.height = '' + data.height + 'px';
}
}
}
window.addEventListener("message", receiveSize, false);
script.dataset.player = container;
}
var scripts = document.querySelectorAll("script[id^='asciicast-']");
[].forEach.call(scripts, insertPlayer);
})();

@ -0,0 +1 @@
../../../web/static/assets/js/embed.js

@ -44,7 +44,7 @@ server {
proxy_redirect off;
}
location ~ ^/a/[^.]+\.(json|gif)$ {
location ~ ^/a/[^.]+\.(js|json|gif)$ {
try_files $uri $uri/index.html $uri.html @phoenix;
}

@ -1,5 +1,5 @@
defmodule Asciinema.TrailingFormat do
@known_extensions ["json", "png", "gif"]
@known_extensions ["js", "json", "png", "gif"]
def init(opts), do: opts

@ -0,0 +1,9 @@
defmodule Asciinema.AsciicastEmbedControllerTest do
use Asciinema.ConnCase
test "serves embed js", %{conn: conn} do
conn = get conn, "/a/12345.js"
assert response(conn, 200)
assert response_content_type(conn, :js)
end
end

@ -0,0 +1,14 @@
defmodule Asciinema.AsciicastEmbedController do
use Asciinema.Web, :controller
@max_age 60
def show(conn, _params) do
path = Application.app_dir(:asciinema, "priv/static/js/embed.js")
conn
|> put_resp_content_type("application/javascript")
|> put_resp_header("cache-control", "public, max-age=#{@max_age}")
|> send_file(200, path)
end
end

@ -10,6 +10,17 @@ defmodule Asciinema.Router do
plug Asciinema.Auth
end
pipeline :asciicast_embed_script do
plug :accepts, ["js"]
end
scope "/", Asciinema do
pipe_through :asciicast_embed_script
# rewritten by TrailingFormat from /a/123.js to /a/123/js
get "/a/:id/js", AsciicastEmbedController, :show
end
pipeline :asciicast_file do
plug :accepts, ["json"]
end

@ -0,0 +1,90 @@
// asciinema embedded player
(function() {
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function params(container, script) {
function format(name) {
var value = script.getAttribute('data-' + name);
if (value) {
return name + '=' + value;
}
}
var options = ['size', 'speed', 'autoplay', 'loop', 'theme', 't', 'preload', 'cols', 'rows'];
return '?' + options.map(format).filter(Boolean).join('&');
}
function locationFromString(string) {
var parser = document.createElement('a');
parser.href = string;
return parser;
}
function apiHostFromScript(script) {
var location = locationFromString(script.src);
return location.protocol + '//' + location.host;
}
function insertPlayer(script) {
// do not insert player if there's one already associated with this script
if (script.dataset.player) {
return;
}
var apiHost = apiHostFromScript(script);
var asciicastId = script.id.split('-')[1];
var container = document.createElement('div');
container.id = "asciicast-container-" + asciicastId;
container.className = 'asciicast';
container.style.display = 'block';
container.style.float = 'none';
container.style.overflow = 'hidden';
container.style.padding = 0;
container.style.margin = '20px 0';
insertAfter(script, container);
var iframe = document.createElement('iframe');
iframe.src = apiHost + "/a/" + asciicastId + '/embed' + params(container, script);
iframe.id = "asciicast-iframe-" + asciicastId;
iframe.name = "asciicast-iframe-" + asciicastId;
iframe.scrolling = "no";
iframe.setAttribute('allowFullScreen', 'true');
iframe.style.overflow = "hidden";
iframe.style.margin = 0;
iframe.style.border = 0;
iframe.style.display = "inline-block";
iframe.style.width = "100%";
iframe.style.float = "none";
iframe.style.visibility = "hidden";
iframe.onload = function() { this.style.visibility = 'visible' };
container.appendChild(iframe);
function receiveSize(e) {
if (e.origin === apiHost) {
var name = e.data[0];
var data = e.data[1];
var iframeWindow = iframe.contentWindow || iframe;
if (e.source == iframeWindow && name == 'asciicast:size') {
iframe.style.width = '' + data.width + 'px';
iframe.style.height = '' + data.height + 'px';
}
}
}
window.addEventListener("message", receiveSize, false);
script.dataset.player = container;
}
var scripts = document.querySelectorAll("script[id^='asciicast-']");
[].forEach.call(scripts, insertPlayer);
})();
Loading…
Cancel
Save