diff --git a/player/custom-embed.coffee b/player/custom-embed.coffee
index c608ac98..8d7e6446 100644
--- a/player/custom-embed.coffee
+++ b/player/custom-embed.coffee
@@ -1,17 +1,8 @@
-DEFAULT_ERROR = 'You are currently connected via HTTPS but the embedded content
- uses non-secure plain HTTP. Your browser therefore blocks it from
- loading due to mixed content policy. To fix this, embed the video using a
- secure link if available (https://...), or load this page over plain HTTP by
- replacing "https://" with "http://" in the address bar (your websocket will
- still be secured using HTTPS, but this will permit non-secure content to load).'
+CUSTOM_EMBED_WARNING = 'This channel is embedding custom content from %link%.
+ Since this content is not trusted, you must click "Embed" below to allow
+ the content to be embedded.
'
-genParam = (name, value) ->
- $('').attr(
- name: name
- value: value
- )
-
-window.CustomEmbedPlayer = class CustomEmbedPlayer extends Player
+window.CustomEmbedPlayer = class CustomEmbedPlayer extends EmbedPlayer
constructor: (data) ->
if not (this instanceof CustomEmbedPlayer)
return new CustomEmbedPlayer(data)
@@ -19,45 +10,19 @@ window.CustomEmbedPlayer = class CustomEmbedPlayer extends Player
@load(data)
load: (data) ->
- embed = data.meta.embed
- if not embed?
+ if not data.meta.embed?
console.error('CustomEmbedPlayer::load(): missing meta.embed')
return
- if embed.tag == 'object'
- @player = @loadObject(embed)
- else
- @player = @loadIframe(embed)
-
- removeOld(@player)
-
- loadObject: (embed) ->
- object = $('').attr(
- type: 'application/x-shockwave-flash'
- data: embed.src
- )
- genParam('allowfullscreen', 'true').appendTo(object)
- genParam('allowscriptaccess', 'always').appendTo(object)
-
- for key, value of embed.params
- genParam(key, value).appendTo(object)
-
- return object
-
- loadIframe: (embed) ->
- if embed.src.indexOf('http:') == 0 and location.protocol == 'https:'
- if embed.mixedContentError?
- error = embed.mixedContentError
- else
- error = DEFAULT_ERROR
- alert = makeAlert('Mixed Content Error', error, 'alert-danger')
- .removeClass('col-md-12')
- alert.find('.close').remove()
- return alert
- else
- iframe = $('').attr(
- src: embed.src
- frameborder: '0'
+ embedSrc = data.meta.embed.src
+ link = "#{embedSrc}"
+ alert = makeAlert('Untrusted Content', CUSTOM_EMBED_WARNING.replace('%link%', link),
+ 'alert-warning')
+ .removeClass('col-md-12')
+ $('').addClass('btn btn-default')
+ .text('Embed')
+ .click(=>
+ super(data)
)
-
- return iframe
+ .appendTo(alert.find('.alert'))
+ removeOld(alert)
diff --git a/player/embed.coffee b/player/embed.coffee
new file mode 100644
index 00000000..b42d965a
--- /dev/null
+++ b/player/embed.coffee
@@ -0,0 +1,65 @@
+DEFAULT_ERROR = 'You are currently connected via HTTPS but the embedded content
+ uses non-secure plain HTTP. Your browser therefore blocks it from
+ loading due to mixed content policy. To fix this, embed the video using a
+ secure link if available (https://...), or load this page over plain HTTP by
+ replacing "https://" with "http://" in the address bar (your websocket will
+ still be secured using HTTPS, but this will permit non-secure content to load).'
+
+genParam = (name, value) ->
+ $('').attr(
+ name: name
+ value: value
+ )
+
+window.EmbedPlayer = class EmbedPlayer extends Player
+ constructor: (data) ->
+ if not (this instanceof EmbedPlayer)
+ return new EmbedPlayer(data)
+
+ @load(data)
+
+ load: (data) ->
+ @setMediaProperties(data)
+
+ embed = data.meta.embed
+ if not embed?
+ console.error('EmbedPlayer::load(): missing meta.embed')
+ return
+
+ if embed.tag == 'object'
+ @player = @loadObject(embed)
+ else
+ @player = @loadIframe(embed)
+
+ removeOld(@player)
+
+ loadObject: (embed) ->
+ object = $('').attr(
+ type: 'application/x-shockwave-flash'
+ data: embed.src
+ )
+ genParam('allowfullscreen', 'true').appendTo(object)
+ genParam('allowscriptaccess', 'always').appendTo(object)
+
+ for key, value of embed.params
+ genParam(key, value).appendTo(object)
+
+ return object
+
+ loadIframe: (embed) ->
+ if embed.src.indexOf('http:') == 0 and location.protocol == 'https:'
+ if @__proto__.mixedContentError?
+ error = @__proto__.mixedContentError
+ else
+ error = DEFAULT_ERROR
+ alert = makeAlert('Mixed Content Error', error, 'alert-danger')
+ .removeClass('col-md-12')
+ alert.find('.close').remove()
+ return alert
+ else
+ iframe = $('').attr(
+ src: embed.src
+ frameborder: '0'
+ )
+
+ return iframe
diff --git a/player/hitbox.coffee b/player/hitbox.coffee
index ea8c5165..80937a58 100644
--- a/player/hitbox.coffee
+++ b/player/hitbox.coffee
@@ -5,7 +5,7 @@ HITBOX_ERROR = 'Hitbox.tv only serves its content over plain HTTP, but you are
bar)-- your websocket will still be connected using secure HTTPS. This is
something I have asked Hitbox to fix but they have not done so yet.'
-window.HitboxPlayer = class HitboxPlayer extends CustomEmbedPlayer
+window.HitboxPlayer = class HitboxPlayer extends EmbedPlayer
constructor: (data) ->
if not (this instanceof HitboxPlayer)
return new HitboxPlayer(data)
@@ -16,5 +16,6 @@ window.HitboxPlayer = class HitboxPlayer extends CustomEmbedPlayer
data.meta.embed =
src: "http://hitbox.tv/embed/#{data.id}"
tag: 'iframe'
- mixedContentError: HITBOX_ERROR
super(data)
+
+ mixedContentError: HITBOX_ERROR
diff --git a/player/imgur.coffee b/player/imgur.coffee
index 0d5e70ea..2753a3b8 100644
--- a/player/imgur.coffee
+++ b/player/imgur.coffee
@@ -1,4 +1,4 @@
-window.ImgurPlayer = class ImgurPlayer extends CustomEmbedPlayer
+window.ImgurPlayer = class ImgurPlayer extends EmbedPlayer
constructor: (data) ->
if not (this instanceof ImgurPlayer)
return new ImgurPlayer(data)
diff --git a/player/rtmp.coffee b/player/rtmp.coffee
index c8508a0c..7d72d35f 100644
--- a/player/rtmp.coffee
+++ b/player/rtmp.coffee
@@ -2,7 +2,7 @@ window.rtmpEventHandler = (id, event, data) ->
if event == 'volumechange'
PLAYER.volume = if data.muted then 0 else data.volume
-window.RTMPPlayer = class RTMPPlayer extends CustomEmbedPlayer
+window.RTMPPlayer = class RTMPPlayer extends EmbedPlayer
constructor: (data) ->
if not (this instanceof RTMPPlayer)
return new RTMPPlayer(data)
diff --git a/player/ustream.coffee b/player/ustream.coffee
index e935ae5d..c8055b11 100644
--- a/player/ustream.coffee
+++ b/player/ustream.coffee
@@ -1,4 +1,4 @@
-window.UstreamPlayer = class UstreamPlayer extends CustomEmbedPlayer
+window.UstreamPlayer = class UstreamPlayer extends EmbedPlayer
constructor: (data) ->
if not (this instanceof UstreamPlayer)
return new UstreamPlayer(data)
diff --git a/www/js/player-new.js b/www/js/player-new.js
index fef60edc..0a935952 100644
--- a/www/js/player-new.js
+++ b/www/js/player-new.js
@@ -1,5 +1,5 @@
(function() {
- var CustomEmbedPlayer, DEFAULT_ERROR, DailymotionPlayer, HITBOX_ERROR, HitboxPlayer, ImgurPlayer, LivestreamPlayer, Player, RTMPPlayer, SoundCloudPlayer, TYPE_MAP, TwitchPlayer, UstreamPlayer, VideoJSPlayer, VimeoPlayer, YouTubePlayer, genParam, sortSources,
+ var CUSTOM_EMBED_WARNING, CustomEmbedPlayer, DEFAULT_ERROR, DailymotionPlayer, EmbedPlayer, HITBOX_ERROR, HitboxPlayer, ImgurPlayer, LivestreamPlayer, Player, RTMPPlayer, SoundCloudPlayer, TYPE_MAP, TwitchPlayer, UstreamPlayer, VideoJSPlayer, VimeoPlayer, YouTubePlayer, genParam, sortSources,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
@@ -802,21 +802,22 @@
});
};
- window.CustomEmbedPlayer = CustomEmbedPlayer = (function(superClass) {
- extend(CustomEmbedPlayer, superClass);
+ window.EmbedPlayer = EmbedPlayer = (function(superClass) {
+ extend(EmbedPlayer, superClass);
- function CustomEmbedPlayer(data) {
- if (!(this instanceof CustomEmbedPlayer)) {
- return new CustomEmbedPlayer(data);
+ function EmbedPlayer(data) {
+ if (!(this instanceof EmbedPlayer)) {
+ return new EmbedPlayer(data);
}
this.load(data);
}
- CustomEmbedPlayer.prototype.load = function(data) {
+ EmbedPlayer.prototype.load = function(data) {
var embed;
+ this.setMediaProperties(data);
embed = data.meta.embed;
if (embed == null) {
- console.error('CustomEmbedPlayer::load(): missing meta.embed');
+ console.error('EmbedPlayer::load(): missing meta.embed');
return;
}
if (embed.tag === 'object') {
@@ -827,7 +828,7 @@
return removeOld(this.player);
};
- CustomEmbedPlayer.prototype.loadObject = function(embed) {
+ EmbedPlayer.prototype.loadObject = function(embed) {
var key, object, ref, value;
object = $('').attr({
type: 'application/x-shockwave-flash',
@@ -843,11 +844,11 @@
return object;
};
- CustomEmbedPlayer.prototype.loadIframe = function(embed) {
+ EmbedPlayer.prototype.loadIframe = function(embed) {
var alert, error, iframe;
if (embed.src.indexOf('http:') === 0 && location.protocol === 'https:') {
- if (embed.mixedContentError != null) {
- error = embed.mixedContentError;
+ if (this.__proto__.mixedContentError != null) {
+ error = this.__proto__.mixedContentError;
} else {
error = DEFAULT_ERROR;
}
@@ -863,10 +864,43 @@
}
};
- return CustomEmbedPlayer;
+ return EmbedPlayer;
})(Player);
+ CUSTOM_EMBED_WARNING = 'This channel is embedding custom content from %link%. Since this content is not trusted, you must click "Embed" below to allow the content to be embedded.';
+
+ window.CustomEmbedPlayer = CustomEmbedPlayer = (function(superClass) {
+ extend(CustomEmbedPlayer, superClass);
+
+ function CustomEmbedPlayer(data) {
+ if (!(this instanceof CustomEmbedPlayer)) {
+ return new CustomEmbedPlayer(data);
+ }
+ this.load(data);
+ }
+
+ CustomEmbedPlayer.prototype.load = function(data) {
+ var alert, embedSrc, link;
+ if (data.meta.embed == null) {
+ console.error('CustomEmbedPlayer::load(): missing meta.embed');
+ return;
+ }
+ embedSrc = data.meta.embed.src;
+ link = "" + embedSrc + "";
+ alert = makeAlert('Untrusted Content', CUSTOM_EMBED_WARNING.replace('%link%', link), 'alert-warning').removeClass('col-md-12');
+ $('').addClass('btn btn-default').text('Embed').click((function(_this) {
+ return function() {
+ return CustomEmbedPlayer.__super__.load.call(_this, data);
+ };
+ })(this)).appendTo(alert.find('.alert'));
+ return removeOld(alert);
+ };
+
+ return CustomEmbedPlayer;
+
+ })(EmbedPlayer);
+
window.rtmpEventHandler = function(id, event, data) {
if (event === 'volumechange') {
return PLAYER.volume = data.muted ? 0 : data.volume;
@@ -901,7 +935,7 @@
return RTMPPlayer;
- })(CustomEmbedPlayer);
+ })(EmbedPlayer);
HITBOX_ERROR = 'Hitbox.tv only serves its content over plain HTTP, but you are viewing this page over secure HTTPS. Your browser therefore blocks the hitbox embed due to mixed content policy. In order to view hitbox, you must view this page over plain HTTP (change "https://" to "http://" in the address bar)-- your websocket will still be connected using secure HTTPS. This is something I have asked Hitbox to fix but they have not done so yet.';
@@ -918,15 +952,16 @@
HitboxPlayer.prototype.load = function(data) {
data.meta.embed = {
src: "http://hitbox.tv/embed/" + data.id,
- tag: 'iframe',
- mixedContentError: HITBOX_ERROR
+ tag: 'iframe'
};
return HitboxPlayer.__super__.load.call(this, data);
};
+ HitboxPlayer.prototype.mixedContentError = HITBOX_ERROR;
+
return HitboxPlayer;
- })(CustomEmbedPlayer);
+ })(EmbedPlayer);
window.UstreamPlayer = UstreamPlayer = (function(superClass) {
extend(UstreamPlayer, superClass);
@@ -948,7 +983,7 @@
return UstreamPlayer;
- })(CustomEmbedPlayer);
+ })(EmbedPlayer);
window.ImgurPlayer = ImgurPlayer = (function(superClass) {
extend(ImgurPlayer, superClass);
@@ -970,7 +1005,7 @@
return ImgurPlayer;
- })(CustomEmbedPlayer);
+ })(EmbedPlayer);
TYPE_MAP = {
yt: YouTubePlayer,