Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
javascript embed file for vine embed page
define("components/app-button", ["exports", "module", "flight/index", "../mixins/browser-info", "../mixins/page-info"], function (exports, module, _flightIndex, _mixinsBrowserInfo, _mixinsPageInfo) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var BrowserInfo = _interopRequire(_mixinsBrowserInfo);
var PageInfo = _interopRequire(_mixinsPageInfo);
var AppButton = flight.component(BrowserInfo, PageInfo, function () {
this.attributes({
videoContainer: false,
playStoreUrl: "https://play.google.com/store/apps/details?id=co.vine.android",
appStoreUrl: "https://itunes.apple.com/us/app/vine/id592447445?mt=8",
currentPostDeeplink: "vine://"
});
this.vineAppUrl = function () {
if (this.browser.iOS) {
return this.attr.appStoreUrl;
} else if (this.browser.android) {
return this.attr.playStoreUrl;
}
};
this.onDataCurrentVideoChanged = function (event, video) {
this.attr.currentPostDeeplink = "vine://post/" + video.postIdStr;
};
/* istanbul ignore next */
this.setParentLocation = function (href) {
window.parent.window.location = href;
};
this.onClick = function (event) {
this.trigger("dataTrackEvent", {
category: "VfwAppButton",
action: "Click"
});
var clickedAt = this.currentTimestamp();
clearTimeout(this.attr.clickTimeout);
this.attr.clickTimeout = setTimeout((function () {
if (this.currentTimestamp() - clickedAt < 2000) {
var appUrl = this.vineAppUrl();
if (appUrl) {
this.trigger("dataTrackEvent", {
category: "VfwAppButton",
action: "NavToAppStore",
nonInteraction: true
});
this.setParentLocation(appUrl);
}
} else {
this.trigger("dataTrackEvent", {
category: "VfwAppButton",
action: "ReturnAfterAppOpen",
nonInteraction: true
});
}
}).bind(this), 500);
this.setParentLocation(this.attr.currentPostDeeplink);
event.stopPropagation();
};
this.currentTimestamp = function () {
return +new Date();
};
this.show = function () {
this.trigger("uiShowingAppButton");
this.$node.addClass("visible");
};
this.after("initialize", function () {
this.on("dataCurrentVideoChanged", this.onDataCurrentVideoChanged);
if (this.vineAppUrl()) {
if (this.page.isPostcardEmbed) {
this.show();
} else if (this.page.isSimpleEmbed) {
var visible;
this.on(document.body, "dataVideoLooped", function () {
if (!visible) {
visible = true;
this.show();
}
});
}
this.on("click", this.onClick);
}
});
this.after("teardown", function () {
clearTimeout(this.attr.clickTimeout);
});
});
module.exports = AppButton;
});
define("components/audio-info-button", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var AudioInfoButton = flight.component(function () {
this.attributes({
attributionImpressionLogged: false,
dismissalEl: false,
dismissalTime: 0,
timer: false
});
this.onClick = function () {
this.trigger("dataTrackEvent", {
category: "Attribution",
action: "click"
});
};
this.onMouseEnter = function () {
$(document.body).addClass("show-audio-info");
this.trigger("dataHideClickForSoundText");
if (this.attr.timer) {
this.clearDismissalTimer();
}
if (!this.attr.attributionImpressionLogged) {
this.trigger("dataTrackEvent", {
category: "Attribution",
action: "impression"
});
this.attr.attributionImpressionLogged = true;
}
};
this.onMouseLeave = function () {
if (this.attr.dismissalTime) {
this.attr.timer = setTimeout(this.dismissAttribution.bind(this), this.attr.dismissalTime);
}
};
this.dismissAttribution = function () {
$(document.body).removeClass("show-audio-info");
this.clearDismissalTimer();
};
this.clearDismissalTimer = function () {
if (this.attr.timer) {
clearTimeout(this.attr.timer);
this.attr.timer = false;
}
};
this.after("initialize", function () {
this.on("click", this.onClick);
this.on("mouseenter", this.onMouseEnter);
this.on("mouseleave", this.onMouseLeave);
if (this.attr.dismissalEl) {
this.attr.dismissalEl.on("mouseleave", this.dismissAttribution.bind(this));
this.attr.dismissalEl.on("mouseenter", this.clearDismissalTimer.bind(this));
}
});
});
module.exports = AudioInfoButton;
});
define("components/content-warning", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var ContentWarning = flight.component(function () {
this.attributes({
viewBtnSelector: "button",
hasDismissedWarning: false
});
this.onDataCurrentVideoChanged = function (event, newVideo) {
if (this.attr.hasDismissedWarning) {
return;
}
if (newVideo.explicitContent && !this.attr.hasDismissedWarning) {
this.$node.show();
this.trigger("dataShowingContentWarning");
} else if (!newVideo.explicitContent && this.$node.is(":visible")) {
this.$node.hide();
this.trigger("dataHidingContentWarning");
}
};
this.onClick = function (event) {
event.stopPropagation();
this.trigger("uiCloseContentWarning");
this.attr.hasDismissedWarning = true;
this.$node.hide();
};
this.after("initialize", function () {
this.on(this.select("viewBtnSelector"), "click", this.onClick);
this.on("dataCurrentVideoChanged", this.onDataCurrentVideoChanged);
});
});
module.exports = ContentWarning;
});
define("components/copy-link", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var CopyLink = flight.component(function () {
this.attributes({
shareInputSelector: ".share-input",
shareUrlSelector: ".share-link"
});
this.onClick = function (event) {
window.getSelection().removeAllRanges();
var url = this.select("shareUrlSelector")[0];
var range = document.createRange();
range.selectNode(url);
window.getSelection().addRange(range);
var $copyLinkBtn = this.$node;
try {
var success = document.execCommand("copy");
window.getSelection().removeAllRanges();
if (success) {
$copyLinkBtn.addClass("success");
} else {
$copyLinkBtn.addClass("error");
this.select("shareInputSelector").select();
}
} catch (e) {
$copyLinkBtn.addClass("error");
this.select("shareInputSelector").select();
}
};
this.onDataResetCopyLinkState = function () {
this.$node.removeClass("success").removeClass("error");
};
this.onShareInputFocus = function () {
this.select("shareInputSelector").select();
};
this.after("initialize", function () {
this.on("click", this.onClick);
this.on("dataResetCopyLinkState", this.onDataResetCopyLinkState);
this.on(this.select("shareInputSelector"), "focus", this.onShareInputFocus);
this.on(this.select("shareInputSelector"), "mouseup", function (e) {
return e.preventDefault();
});
});
});
module.exports = CopyLink;
});
define("components/embed", ["exports", "module", "../components/app-button", "../components/audio-info-button", "flight/index", "../mixins/browser-info", "../components/content-warning", "../components/google-analytics", "../mixins/host-script-status", "../components/loop-counter", "../components/loop-tracker", "../components/message-broker", "../components/volume-control", "../mixins/page-info", "../components/play-button", "../components/player", "../components/share-button", "../components/sharer", "../components/share-sheet", "../mixins/with-child-components"], function (exports, module, _componentsAppButton, _componentsAudioInfoButton, _flightIndex, _mixinsBrowserInfo, _componentsContentWarning, _componentsGoogleAnalytics, _mixinsHostScriptStatus, _componentsLoopCounter, _componentsLoopTracker, _componentsMessageBroker, _componentsVolumeControl, _mixinsPageInfo, _componentsPlayButton, _componentsPlayer, _componentsShareButton, _componentsSharer, _componentsShareSheet, _mixinsWithChildComponents) {
/*globals $ */
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var AppButton = _interopRequire(_componentsAppButton);
var AudioInfoButton = _interopRequire(_componentsAudioInfoButton);
var flight = _interopRequire(_flightIndex);
var BrowserInfo = _interopRequire(_mixinsBrowserInfo);
var ContentWarning = _interopRequire(_componentsContentWarning);
var GoogleAnalytics = _interopRequire(_componentsGoogleAnalytics);
var HostScriptStatus = _interopRequire(_mixinsHostScriptStatus);
var LoopCounter = _interopRequire(_componentsLoopCounter);
var LoopTracker = _interopRequire(_componentsLoopTracker);
var MessageBroker = _interopRequire(_componentsMessageBroker);
var VolumeControl = _interopRequire(_componentsVolumeControl);
var PageInfo = _interopRequire(_mixinsPageInfo);
var PlayButton = _interopRequire(_componentsPlayButton);
var Player = _interopRequire(_componentsPlayer);
var ShareButton = _interopRequire(_componentsShareButton);
var Sharer = _interopRequire(_componentsSharer);
var ShareSheet = _interopRequire(_componentsShareSheet);
var WithChildComponents = _interopRequire(_mixinsWithChildComponents);
var Embed = flight.component(PageInfo, BrowserInfo, function () {
this.attributes({
appButtonSelector: ".app-button",
contentWarningSelector: ".warning-overlay",
descriptionSelector: ".description",
embedSelector: ".embed",
loopCounterSelector: ".loop-count",
playButtonSelector: ".play-button",
shareButtonSelector: ".action.share",
shareSheetSelector: ".embed-share-overlay",
videoContainerSelector: ".video-container",
videoWrapperSelector: ".video-wrapper",
vineLogoSelector: ".vine-logo",
audioInfoButtonSelector: ".action.music",
postInfoSelector: ".post-info",
similarButtonSelector: ".similar",
volumeControlSelector: ".VolumeControl",
attributionImpressionLogged: false,
embedType: "",
permalinkLinkSelector: ".js-permalink-link"
});
this.onHostScriptFound = function () {
this.trigger("sendMessage", {
message: "loaded"
});
if (this.page.isPostcardEmbed) {
this.onUiWidthChanged();
}
};
this.onHostScriptTimeout = function () {
// If we're iPhone, trigger the uiScrolledInToView event as this will
// create the <video> element, displaying the native play button to the
// user
if (this.browser.iPhone && !this.page.autoplayDisabled) {
this.select("videoContainerSelector").trigger("uiScrolledInToView");
}
};
this.onUiWidthChanged = function () {
var height = $("body>.embed").outerHeight();
this.trigger("sendMessage", {
message: "height",
data: height
});
};
this.onUiShareSheetOpened = function () {
this.select("embedSelector").addClass("share-sheet-open");
};
this.onUiShareSheetClosed = function () {
this.select("embedSelector").removeClass("share-sheet-open");
};
this.trackEvent = function (_ref) {
var action = _ref.action;
var value = _ref.value;
var _ref$nonInteraction = _ref.nonInteraction;
var nonInteraction = _ref$nonInteraction === undefined ? false : _ref$nonInteraction;
this.trigger("dataTrackEvent", {
category: "Embed",
action: action,
label: this.attr.embedType,
value: value,
nonInteraction: nonInteraction
});
};
this.after("initialize", function () {
var _this = this;
this.attachChild(GoogleAnalytics, document);
var embedType = ["embed", this.page.isPostcardEmbed ? "postcard" : "simple", this.browser.mobile ? "mobile" : ""].join(" ").trim();
this.attr.embedType = embedType;
var videoContainer = this.select("videoContainerSelector");
this.attachChild(MessageBroker, document, {
videoContainer: videoContainer
});
if (this.page.noSharing) {
this.select("shareButtonSelector").hide();
} else {
this.attachChild(Sharer, document);
this.attachChild(ShareButton, this.select("shareButtonSelector"), { embedType: embedType });
}
this.attachChild(AudioInfoButton, this.select("audioInfoButtonSelector"), {
dismissalEl: this.select("postInfoSelector")
});
this.attachChild(LoopTracker, document);
this.attachChild(VolumeControl, this.select("volumeControlSelector"));
this.attachChild(PlayButton, this.select("playButtonSelector"), {
videoContainer: videoContainer,
embedType: embedType
});
this.attachChild(LoopCounter, this.select("loopCounterSelector"));
this.attachChild(ShareSheet, this.select("shareSheetSelector"), { embedType: embedType });
this.on("uiShareSheetOpened", this.onUiShareSheetOpened);
this.on("uiShareSheetClosed", this.onUiShareSheetClosed);
this.attachChild(Player, videoContainer, {
embedType: embedType
});
this.on("dataVideoPlay", function () {
$body.addClass("embed-playing");
});
this.on("dataVideoPaused", function () {
$body.removeClass("embed-playing");
});
this.on("uiVideoMute", function () {
$body.addClass("embed-muted");
});
this.on("uiVideoUnmute", function () {
$body.removeClass("embed-muted");
});
this.on("hostScriptTimeout", this.onHostScriptTimeout);
this.on("hostScriptFound", this.onHostScriptFound);
if (this.page.isPostcardEmbed) {
this.on(document, "uiWidthChanged", this.onUiWidthChanged);
}
var $body = $(document.body);
this.on(this.select("embedSelector"), "mouseenter", function () {
$body.addClass("embed-hover");
});
this.on(this.select("embedSelector"), "mouseleave", function () {
$body.removeClass("embed-hover");
});
// event logging for Similar Vines button
if (this.select("similarButtonSelector").length) {
this.trigger("dataTrackEvent", {
category: "Similar Vines",
action: "impression",
label: this.attr.embedType,
nonInteraction: true
});
}
this.on(this.select("similarButtonSelector"), "click", function () {
this.trigger("dataTrackEvent", {
category: "Similar Vines",
action: "click",
label: this.attr.embedType
});
});
if (this.page.startUnmuted) {
videoContainer.trigger("uiVideoUnmute");
} else {
videoContainer.trigger("uiVideoMute");
}
this.onMouseEnter = function () {
videoContainer.trigger("uiVideoUnmute");
};
this.onMouseLeave = function () {
videoContainer.trigger("uiVideoMute");
};
if (!this.page.startUnmuted && this.page.unmuteOnHover) {
this.on("mouseenter", this.onMouseEnter);
this.on("mouseleave", this.onMouseLeave);
}
this.on("uiShowingAppButton", function () {
this.select("vineLogoSelector").hide();
});
this.on("uiHidingAppButton", function () {
this.select("vineLogoSelector").show();
});
this.attachChild(AppButton, this.select("appButtonSelector"));
this.attachChild(ContentWarning, this.select("contentWarningSelector"));
this.trigger("dataCurrentVideo", window.POST_DATA);
// bind for event logging
this.select("permalinkLinkSelector").on("click", function () {
return _this.trackEvent({ action: "permalink link click" });
});
});
}, WithChildComponents, HostScriptStatus);
module.exports = Embed;
});
define("components/google-analytics", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
/*globals $ */
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var scriptInitializedWith = false;
var currentlyAttached = false;
var GoogleAnalytics = flight.component(function () {
this.attributes({
account: "UA-34240974-1"
});
this.initializeAnalytics = function () {
scriptInitializedWith = this.attr.account;
window._gaq = window._gaq || [];
window._gaq.push(["_setAccount", this.attr.account]);
window._gaq.push(["_setDomainName", "none"]);
window._gaq.push(["_trackPageview"]);
var ga = document.createElement("script");
ga.type = "text/javascript";
ga.async = true;
ga.src = (document.location.protocol === "https:" ? "https://" : "http://") + "stats.g.doubleclick.net/dc.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(ga, s);
};
this.onTrackEvent = function (event, data) {
this.push(["_trackEvent", data.category, data.action, data.label, data.value, !!data.nonInteraction]);
};
this.push = function (data) {
window._gaq.push(data);
};
this.after("initialize", function () {
if (scriptInitializedWith) {
if (this.attr.account !== scriptInitializedWith) {
console.warn("Google Analytics already initialized with account", scriptInitializedWith);
}
} else {
if (!window.__karma__) {
this.initializeAnalytics();
}
}
if (currentlyAttached) {
if (window.__karma__) {
return;
}
return console.error("Google Analytics component is currently attached. Bailing to avoid duplicate reporting.");
}
currentlyAttached = true;
this.on(document, "dataTrackEvent", this.onTrackEvent);
});
this.after("teardown", function () {
currentlyAttached = false;
});
});
module.exports = GoogleAnalytics;
});
define("components/loop-counter", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var UPDATES_PER_SECOND = 0.5;
var REGEX = new RegExp("\\B(?=(\\d{3})+(?!\\d))", "g");
var LoopCounter;
LoopCounter = flight.component(function () {
"use strict";
this.attributes({
count: 0,
velocity: 0,
asOfTime: Date.now(),
counterSelector: ".counter",
spinnerSelector: ".counter .spinner"
});
this.onDataCurrentVideoChanged = function (event, newVideo) {
this.attr.count = newVideo.loops.count;
this.attr.velocity = newVideo.loops.velocity;
this.attr.asOfTime = Date.now();
this.select("counterSelector").addClass("seeded").html(this.attr.count);
};
this.onVideoLoop = function () {
this.attr.count++;
this.render();
};
this.updateCounts = function () {
var now = Date.now();
var secondsSince = (now - this.attr.asOfTime) / 1000;
this.attr.count += secondsSince * this.attr.velocity;
this.attr.asOfTime = now;
this.render();
};
this.render = function () {
var count = "" + this.format(this.attr.count);
var counter = this.select("counterSelector");
var spinners = this.select("spinnerSelector");
if (counter.hasClass("seeded")) {
counter.empty().removeClass("seeded");
}
var numberOfSpinnersToAdd = count.length - spinners.length;
if (numberOfSpinnersToAdd < 0) {
spinners.slice(0, Math.abs(numberOfSpinnersToAdd)).remove();
} else {
while (numberOfSpinnersToAdd--) {
this.createDigit(counter);
}
}
this.select("spinnerSelector").toArray().forEach(function (s, i) {
if (count[i] === ",") {
s.className = "spinner comma";
} else {
s.className = "spinner digit-" + count[i];
}
});
};
this.createDigit = function () {
var i = -1;
var digit = $("<div class=\"spinner\"></div>").appendTo(this.select("counterSelector"));
while (i++ < 9) {
digit.append("<div>" + i + "</div>");
}
digit.append("<div>,</div>");
};
this.format = function (num) {
return Math.round(num).toString().replace(REGEX, ",");
};
this.after("initialize", function () {
this.on(document, "dataVideoLooped", this.onVideoLoop);
this.on(document, "dataCurrentVideoChanged", this.onDataCurrentVideoChanged);
this.interval = setInterval(this.updateCounts.bind(this), 1000 / UPDATES_PER_SECOND);
});
this.after("teardown", function () {
window.clearInterval(this.interval);
});
});
module.exports = LoopCounter;
});
define("components/loop-tracker", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var LOOP_RECORD_OFFSET = 0.5;
var LoopTracker;
LoopTracker = flight.component(function () {
this.attributes({
recordedLoop: false,
unsentLoops: 0,
lastLoopTime: 0,
totalLoopsRecorded: 0,
nextUpdateTimestamp: 0,
requestInProgress: false,
enabled: true,
currentPostId: ""
});
this.onDataCurrentVideoChanged = function (event, video) {
if (this.attr.unsentLoops) {
this.flush(true);
}
this.attr.recordedLoop = false;
this.attr.unsentLoops = 0;
this.attr.lastLoopTime = 0;
this.attr.totalLoopsRecorded = 0;
this.attr.enabled = true;
this.attr.currentPostId = video.postIdStr;
};
this.onVideoLooped = function () {
this.attr.recordedLoop = false;
};
this.onVideoTimeUpdate = function (event, data) {
if (!this.attr.recordedLoop && data.currentTime > LOOP_RECORD_OFFSET) {
this.recordLoop();
this.attr.recordedLoop = true;
}
};
this.recordLoop = function () {
if (!this.attr.enabled) {
return;
}
var now = Date.now();
if (now - this.attr.lastLoopTime < 900) {
this.attr.enabled = 0;
return;
}
this.attr.lastLoopTime = now;
if (this.attr.totalLoopsRecorded < 25) {
this.attr.unsentLoops++;
}
this.attr.totalLoopsRecorded++;
this.flush();
};
this.flush = function (force) {
if (this.attr.unsentLoops === 0) {
return;
}
if (!force && (this.attr.requestInProgress || Date.now() < this.attr.nextUpdateTimestamp)) {
return;
}
var loopsToSend = this.attr.unsentLoops;
this.attr.unsentLoops = 0;
this.attr.requestInProgress = true;
$.ajax({
url: "/api/loops",
async: !force,
type: "post",
headers: {
"X-Vine-Client": window.VINE_CLIENT,
"X-Request-Id": generateRequestId()
},
contentType: "application/json",
data: JSON.stringify({
loops: [{
postId: this.attr.currentPostId,
count: loopsToSend,
ts: Date.now() / 1000
}]
})
}).then((function (data) {
data = data || {};
this.attr.nextUpdateTimestamp = Date.now() + (data.nextAfter || 30) * 1000;
this.trigger("dataLoopsRecorded", data);
}).bind(this)).always((function () {
this.attr.requestInProgress = false;
}).bind(this));
};
function generateRequestId() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c === "x" ? r : r & 3 | 8;
return v.toString(16);
});
}
this.after("initialize", function () {
this.on(document, "dataCurrentVideoChanged", this.onDataCurrentVideoChanged);
this.on(document, "dataVideoTimeUpdate", this.onVideoTimeUpdate);
this.on(document, "dataVideoLooped", this.onVideoLooped);
this.on(window, "unload", this.flush.bind(this, true));
});
this.after("teardown", function () {
this.flush();
});
});
module.exports = LoopTracker;
});
define("components/message-broker", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
/*globals $ */
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var MessageBroker = flight.component(function () {
this.attributes({
videoContainer: null,
hasHostScript: false,
skipHostScriptSearch: false,
pingsBeforeTimeout: 10,
pingInterval: 100
});
this.onMessage = function (event) {
switch (event.originalEvent.data) {
case "fullyInView":
this.trigger(document, "uiFullyInView");
break;
case "scrolledInToView":
this.trigger(document, "uiScrolledInToView");
break;
case "scrolledOutOfView":
this.trigger(document, "uiScrolledOutOfView");
break;
case "unmutedOtherEmbed":
this.trigger(document, "unmutedOtherEmbed");
break;
case "pong":
this.onPong();
break;
case "restart":
this.trigger(this.attr.videoContainer, "uiVideoRestart");
break;
case "pause":
this.trigger(this.attr.videoContainer, "uiVideoPause");
break;
case "play":
this.trigger(this.attr.videoContainer, "uiVideoPlay");
break;
case "mute":
this.trigger(this.attr.videoContainer, "uiVideoMute");
break;
case "unmute":
this.trigger(this.attr.videoContainer, "uiVideoUnmute");
break;
case "widthChanged":
this.trigger(document, "uiWidthChanged");
break;
}
};
this.onSendMessage = function (event, data) {
var message = data.message + "::" + window.location.href;
if (data.data) {
message += "::" + data.data;
}
(data.forceLocal ? window : window.parent).postMessage(message, "*");
};
this.startLookingForHostScript = function () {
var pingsSent = 0;
var connected = false;
function ping() {
if (pingsSent++ === this.attr.pingsBeforeTimeout) {
this.trigger(document, "dataHostScriptTimeout");
}
this.trigger(document, "sendMessage", {
message: "ping"
});
if (!connected) {
this.pingTimer = setTimeout(ping.bind(this), this.attr.pingInterval);
}
}
ping.call(this);
this.on(document, "dataHostScriptFound", function () {
connected = true;
});
};
this.onPong = function () {
this.trigger(document, "dataHostScriptFound");
};
this.after("initialize", function () {
this.on(window, "message", this.onMessage.bind(this));
this.on(document, "sendMessage", this.onSendMessage);
if (!this.attr.skipHostScriptSearch) {
this.startLookingForHostScript();
}
});
this.after("teardown", function () {
clearTimeout(this.pingTimer);
this.pingTimer = null;
});
});
module.exports = MessageBroker;
});
define("components/volume-control", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
/*globals $ */
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var SLIDER_HEIGHT = 120;
var HIDE_TEXT_TIMEOUT = 3000;
var MOUSE_IS_DOWN = false;
var HIDE_AFTER_MOUSE_UP = false;
var SLIDER_ENABLED = false;
var VolumeControl = flight.component(function () {
this.attributes({
textWrapper: ".VolumeControl__text-wrapper",
text: ".VolumeControl__text",
volumeSlider: ".VolumeControl__slider",
handle: ".VolumeControl__slider-handle",
volumeOn: ".VolumeControl__slider-volume-on",
iconWrapper: ".VolumeControl__icon-wrapper",
videoContainer: $(".video-container")
});
this.after("initialize", function () {
this.sliderNode = this.select("volumeSlider");
this.on(this.attr.videoContainer, "sendMessage", this.onVideoContainerMessage);
this.volumeSliderCollection = this.select("handle");
this.volumeSliderCollection = this.volumeSliderCollection.add(this.select("volumeOn"));
this.on(this.select("volumeSlider"), "mousedown", this.onSliderMouseDown);
this.on(this.select("iconWrapper"), "click", this.onIconClick);
this.on(this.select("text"), "click", this.onTextClick);
this.on("mouseenter", this.onMouseEnter);
this.on("mouseleave", this.onMouseLeave);
this.on(document, "uiScrolledInToView", this.setupTextHidingAnimation);
this.on(document, "uiFullyInView", this.unmute);
this.on(document, "mouseenter", this.setupTextHidingAnimation);
this.on(document, "unmutedOtherEmbed", this.hideClickForSoundText);
this.on(document, "dataHideClickForSoundText", this.hideClickForSoundText);
this.on(document, "dataVideoUnmuted", this.hideClickForSoundText);
});
this.onTextClick = function (event) {
if (this.textAnimationTimeout) {
clearTimeout(this.textAnimationTimeout);
}
this.hideClickForSoundText();
this.onIconClick();
};
this.unmute = function () {
this.trigger(this.attr.videoContainer, "uiVideoUnmute");
this.trigger(this.attr.videoContainer, "uiVideoRestart");
};
this.onIconClick = function (event) {
this.hideClickForSoundText();
if (this.$node.hasClass("VolumeControl--muted")) {
$(document).trigger("sendMessage", {
message: "userUnmute"
});
this.trigger("dataTrackEvent", {
category: "Post",
action: "user unmute"
});
this.unmute();
} else {
$(document).trigger("sendMessage", {
message: "userMute"
});
this.trigger("dataTrackEvent", {
category: "Post",
action: "user mute"
});
this.trigger(this.attr.videoContainer, "uiVideoMute");
}
};
this.onVideoContainerMessage = function (event, data) {
if (data.message === "mute") {
this.setSliderPosition(SLIDER_HEIGHT);
} else if (data.message === "unmute") {
this.setSliderPosition(SLIDER_HEIGHT - data.volumeLevel * SLIDER_HEIGHT);
}
};
this.setupTextHidingAnimation = function () {
if (!this.textHidingAnimationSetUp) {
this.textHidingAnimationSetUp = true;
var textWrapperNode = this.select("textWrapper");
// Browsers can't transition from `auto` to a set width, so
// this is a hack to get the browser to transition on width properly.
textWrapperNode.width(textWrapperNode.width());
this.textAnimationTimeout = setTimeout(this.hideClickForSoundText.bind(this), HIDE_TEXT_TIMEOUT);
}
};
this.hideClickForSoundText = function () {
this.select("textWrapper").width(0);
this.$node.removeClass("VolumeControl--show-click-for-sound-text");
};
this.setSliderPosition = function (positionY) {
this.volumeSliderCollection.css("transform", "translateY(" + positionY + "px)");
this.$node.toggleClass("VolumeControl--muted", positionY === SLIDER_HEIGHT);
};
this.removeHoverClass = function () {
this.$node.removeClass("VolumeControl--hover");
};
this.onMouseEnter = function (event) {
if (SLIDER_ENABLED) {
this.$node.addClass("VolumeControl--hover VolumeControl--show-slider");
HIDE_AFTER_MOUSE_UP = false;
} else {
this.$node.addClass("VolumeControl--hover");
}
this.setupTextHidingAnimation();
};
this.onMouseLeave = function (event) {
if (MOUSE_IS_DOWN) {
HIDE_AFTER_MOUSE_UP = true;
} else {
this.removeHoverClass();
}
};
this.onSliderMouseDown = function (event) {
event.preventDefault();
this.sliderY = this.sliderNode.offset().top;
this.on(document, "mousemove", this.onSliderMove);
this.on(document, "mouseup", this.onSliderMouseUp);
this.onSliderMove(event);
MOUSE_IS_DOWN = true;
};
this.onSliderMove = function (event) {
event.preventDefault();
var clientY = event.clientY;
var newTranslateY = Math.min(SLIDER_HEIGHT, Math.max(0, clientY - this.sliderY));
this.setSliderPosition(newTranslateY);
var newVolumeLevel = 1 - newTranslateY / SLIDER_HEIGHT;
this.trigger(this.attr.videoContainer, "uiVideoSetVolume", { newVolumeLevel: newVolumeLevel });
};
this.onSliderMouseUp = function () {
this.off(document, "mousemove", this.onSliderMove);
this.off(document, "mouseup", this.onSliderMouseUp);
MOUSE_IS_DOWN = false;
if (HIDE_AFTER_MOUSE_UP) {
this.removeHoverClass();
}
};
});
module.exports = VolumeControl;
});
define("components/play-button", ["exports", "module", "flight/index", "../mixins/browser-info", "../mixins/page-info"], function (exports, module, _flightIndex, _mixinsBrowserInfo, _mixinsPageInfo) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var BrowserInfo = _interopRequire(_mixinsBrowserInfo);
var PageInfo = _interopRequire(_mixinsPageInfo);
var PlayButton = flight.component(BrowserInfo, PageInfo, function () {
this.attributes({
videoContainer: false,
embedType: "",
hostScriptTimedOut: false,
isFirstClick: true
});
this.videoContainer = function () {
if (this.attr.videoContainer) {
return this.attr.videoContainer;
} else {
return this.node;
}
};
this.onClick = function (event) {
event.stopPropagation();
this.trigger("dataTrackEvent", {
category: "Post",
action: "user play",
label: this.attr.embedType
});
this.trigger(this.videoContainer(), "uiVideoPlay");
if (this.attr.hostScriptTimedOut && this.attr.isFirstClick) {
this.trigger(this.videoContainer(), "uiVideoUnmute");
}
this.attr.isFirstClick = false;
};
this.onPlay = function () {
clearTimeout(this.showTimer);
this.$node.hide();
};
this.onPause = function () {
clearTimeout(this.showTimer);
this.showTimer = setTimeout((function () {
if (!this.attr.disabled) {
this.$node.show();
}
}).bind(this), 250);
};
this.onHostScriptFound = function () {
if (!this.page.autoplayDisabled && !this.browser.iPad) {
this.$node.hide();
}
};
this.onHostScriptTimeout = function () {
if (this.attr.hostScriptTimedOut) {
return;
}
this.$node.show();
this.attr.hostScriptTimedOut = true;
};
this.after("initialize", function () {
this.on("click", this.onClick);
this.on(document, "hostScriptTimeout", this.onHostScriptTimeout.bind(this));
this.on(document, "hostScriptFound", this.onHostScriptFound.bind(this));
this.on(this.videoContainer(), "dataVideoPlay", this.onPlay);
this.on(this.videoContainer(), "dataVideoPaused", this.onPause);
this.on(this.videoContainer(), "dataVideoElementCreated", function () {
if (this.browser.iPhone) {
this.attr.disabled = true;
if (!this.page.isFeedEmbed) {
this.$node.hide();
}
}
});
if (this.page.autoplayDisabled || this.browser.iPad) {
this.onHostScriptTimeout();
}
});
this.after("teardown", function () {
clearTimeout(this.showTimer);
});
});
module.exports = PlayButton;
});
define("components/player", ["exports", "module", "flight/index", "mp4", "../mixins/browser-info", "../mixins/page-info", "../mixins/current-video", "../mixins/page-visibility-status", "../vine-utils"], function (exports, module, _flightIndex, _mp4, _mixinsBrowserInfo, _mixinsPageInfo, _mixinsCurrentVideo, _mixinsPageVisibilityStatus, _vineUtils) {
/*globals $ */
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var mp4 = _interopRequire(_mp4);
var BrowserInfo = _interopRequire(_mixinsBrowserInfo);
var PageInfo = _interopRequire(_mixinsPageInfo);
var CurrentVideo = _interopRequire(_mixinsCurrentVideo);
var PageVisibiliityStatus = _interopRequire(_mixinsPageVisibilityStatus);
var httpsize = _vineUtils.httpsize;
var DEFAULT_VOLUME = 0.7;
var Player = flight.component(function () {
var MT_H264 = "h264";
var MT_DASH = "dash";
var SD_DOWNLOAD_RATE = 200;
var FULL_COPY_THRESHOLD = 0.5; // sec;
this.attributes({
mediaElement: false,
shouldMute: true,
shouldLoop: true,
needsContentWarningDismissal: false,
needsCoverDismissal: true,
videoSelector: "video",
thumbnailSelector: ".thumbnail",
mediaElementSelector: "video, .me-plugin",
pluginPath: "/swf/",
shouldResumeOnVisibility: false,
unmuteOnFirstClick: false,
mediaUrls: {},
embedType: "",
volumeLevel: DEFAULT_VOLUME
});
this.videoContainer = function () {
return this.$node;
};
this.onClick = function () {
if (this.attr.unmuteOnFirstClick && !this.firstClick) {
this.onUiVideoUnmute();
this.onUiVideoRestart();
this.firstClick = true;
return;
}
if (this.browser.iOS && !this.attr.firstClickSkipped) {
this.attr.firstClickSkipped = true;
return;
}
if (!this.attr.mediaElement || this.attr.mediaElement.paused) {
this.trigger("dataTrackEvent", {
category: "Post",
action: "user play",
label: this.attr.embedType
});
this.onUiVideoPlay();
} else {
this.trigger("dataTrackEvent", {
category: "Post",
action: "user pause",
label: this.attr.embedType
});
this.attr.manuallyPaused = true;
this.onUiVideoPause();
}
};
this.onPageBecameHidden = function () {
this.attr.shouldResumeOnVisibility = this.attr.mediaElement ? !this.attr.mediaElement.paused : false;
this.onUiVideoPause();
};
this.onPageBecameVisible = function () {
if (this.attr.shouldResumeOnVisibility) {
this.onUiVideoPlay();
}
delete this.attr.shouldResumeOnVisibility;
};
this.onUiVideoPlay = function () {
if (this.attr.mediaElement) {
this.attr.mediaElement.play();
} else if (this.attr.currentVideo) {
this.createMediaElement();
} else {
return;
}
this.attr.manuallyPaused = false;
};
this.onUiVideoPause = function () {
if (this.attr.mediaElement) {
this.attr.mediaElement.pause();
}
this.trigger("dataVideoPaused");
};
this.onUiVideoSetVolume = function (event, data) {
if (this.attr.mediaElement) {
this.attr.volumeLevel = data.newVolumeLevel;
this.attr.mediaElement.setVolume(data.newVolumeLevel);
this.attr.mediaElement.setMuted(false);
}
};
this.onUiVideoMute = function () {
this.attr.shouldMute = true;
if (this.attr.mediaElement) {
if (this.attr.priorAudioState !== this.attr.mediaElement.muted) {
this.attr.priorAudioState = this.attr.mediaElement.muted;
}
this.attr.mediaElement.muted = true;
if (this.attr.mediaElement.setMuted) {
this.attr.mediaElement.setMuted(true);
}
}
this.trigger("sendMessage", {
message: "mute"
});
this.trigger("dataVideoMuted");
};
this.onUiVideoUnmute = function () {
this.attr.shouldMute = false;
if (this.attr.mediaElement) {
if (this.attr.priorAudioState !== this.attr.mediaElement.muted) {
this.attr.priorAudioState = this.attr.mediaElement.muted;
}
this.attr.mediaElement.muted = false;
if (this.attr.mediaElement.setMuted) {
this.attr.mediaElement.setMuted(false);
}
}
this.trigger("sendMessage", {
message: "unmute",
volumeLevel: this.attr.volumeLevel
});
this.trigger("dataVideoUnmuted");
};
this.onUiVideoRestart = function () {
if (!this.attr.mediaElement) return;
if (this.attr.mediaElement.setCurrentTime) {
this.attr.mediaElement.setCurrentTime(0);
} else {
this.attr.mediaElement.currentTime = 0;
}
};
this.onUiVideoRestoreAudio = function () {
if (typeof this.attr.priorAudioState === "undefined") {
return;
}
if (this.attr.priorAudioState) {
this.onUiVideoUnmute();
} else {
this.onUiVideoMute();
}
delete this.attr.priorAudioState;
};
this.onVideoEnded = function () {
if (this.attr.shouldLoop) {
this.attr.mediaElement.setCurrentTime(0);
this.attr.mediaElement.play();
}
this.trigger("dataVideoLooped");
};
this.lastTimeUpdateSentAt = 0;
this.onVideoTimeUpdate = function () {
var now = Date.now();
if (now - this.lastTimeUpdateSentAt < 250) {
return;
}
this.lastTimeUpdateSentAt = now;
if (this.attr.mediaElement) {
if (this.canPlaySeamlessly() && this.attr.duration) {
this.trigger("dataVideoTimeUpdate", {
currentTime: this.attr.mediaElement.currentTime % this.attr.duration,
duration: this.attr.duration
});
} else {
this.trigger("dataVideoTimeUpdate", {
currentTime: this.attr.mediaElement.currentTime,
duration: this.attr.mediaElement.duration
});
}
}
};
this.onDataVideoPlaying = function () {
this.attr.mediaElement.muted = this.attr.shouldMute;
if (this.attr.mediaElement.setMuted) {
this.attr.mediaElement.setMuted(this.attr.shouldMute);
}
};
this.onDataVideoElementCreated = function (event, mediaElement) {
this.attr.mediaElement = mediaElement;
this.attr.mediaElement.setVolume(DEFAULT_VOLUME);
// Bind further events
this.on(mediaElement, "pause", this.trigger.bind(this, "dataVideoPaused"));
this.on(mediaElement, "play", this.trigger.bind(this, "dataVideoPlay"));
this.on(mediaElement, "playing", this.trigger.bind(this, "dataVideoPlaying"));
this.on(mediaElement, "ended", this.onVideoEnded.bind(this));
this.on(mediaElement, "timeupdate", this.onVideoTimeUpdate.bind(this));
$(window).on("webkitendfullscreen", (function () {
this.trigger("uiVideoPause");
}).bind(this));
if (!this.attr.manuallyPaused && !this.attr.needsContentWarningDismissal && !this.browser.iPhone) {
this.trigger("uiVideoPlay");
}
this.attr.mediaElement.setVolume(this.attr.volumeLevel);
};
this.onDataCurrentVideoChanged = function () {
$(this.attr.mediaElement).attr({ poster: this.attr.currentVideo.thumbnailUrl });
if (this.attr.mediaElement) {
this.attr.mediaUrls = {};
if (this.canPlaySeamlessly()) {
this.createSeamlessMedia(this.attr.mediaElement);
} else {
this.attr.mediaElement.setSrc([{
src: this.mediaUrl(MT_H264),
type: "video/mp4"
}]);
}
}
};
this.onDataNextPost = function (event, post) {
this.select("thumbnailSelector").attr("src", post.thumbnailUrl);
};
this.mediaUrl = function (type) {
if (this.attr.mediaUrls[type]) {
return this.attr.mediaUrls[type];
}
var url;
if (this.attr.currentVideo.videoUrls) {
var videosOfType = this.attr.currentVideo.videoUrls.filter(function (vid) {
return vid.format === type;
});
if (!videosOfType.length) {
return null;
}
videosOfType.sort(function (a, b) {
if (a.rate < b.rate) {
return 1;
} else if (a.rate > b.rate) {
return -1;
} else {
return 0;
}
});
if (this.page.forceLd) {
url = httpsize(videosOfType[videosOfType.length - 1].videoUrl);
} else if (this.page.forceHd) {
url = httpsize(videosOfType[0].videoUrl);
} else if (this.browser.mobile) {
// if mobile default to SD which is rate <= SD_DOWNLOAD_RATE
var SDVideo = videosOfType.reduce(function (prev, video) {
return prev || (prev = video.rate <= SD_DOWNLOAD_RATE ? video : null);
}, null);
SDVideo = SDVideo || videosOfType[0];
url = httpsize(SDVideo.videoUrl);
} else {
// default to HD for desktop
// TODO: something smarter here.
// We will need to calculate the user's connection speed here
url = httpsize(videosOfType[0].videoUrl);
}
} else {
url = httpsize(this.attr.currentVideo[type === MT_DASH ? "videoDashUrl" : "videoUrl"]);
}
this.attr.mediaUrls[type] = url;
return url;
};
this.canPlaySeamlessly = function () {
if (!this.attr.shouldLoop || this.attr.seamlessPlaybackDisabled || this.page.disableSeamless) {
return false;
}
window.MediaSource = window.MediaSource || window.WebKitMediaSource;
var file = this.mediaUrl(MT_DASH);
var browserWhitelisted = !this.browser.chromium && (this.browser.chrome && this.browser.chrome >= 30) || this.browser.firefox && this.browser.firefox >= 42;
return browserWhitelisted && file && window.MediaSource;
};
this.seamlessFailover = function () {
this.attr.seamlessPlaybackDisabled = true;
this.destroyMediaElement();
this.createMediaElement();
};
this.clientForSeamlessMediaRequest = function () {
return new window.XMLHttpRequest();
};
this.createSeamlessMedia = function (mediaElement) {
var CUT_OFF = 0.05;
var NUM_COPIES = 25;
var file = this.mediaUrl(MT_DASH);
var client = this.clientForSeamlessMediaRequest();
var sourceBuffer;
$(mediaElement).one("loadedmetadata", function () {
mediaElement.currentTime = CUT_OFF + 0.011;
});
client.addEventListener("error", (function (error) {
console.error("xhr error", error);
return this.seamlessFailover();
}).bind(this));
client.onload = (function () {
var mediaSource = new window.MediaSource();
mediaElement.src = window.URL.createObjectURL(mediaSource);
var buffer = new Uint8Array(client.response);
mediaSource.addEventListener("sourceopen", (function () {
try {
sourceBuffer = mediaSource.addSourceBuffer("video/mp4; codecs=\"avc1.4d401e, mp4a.40.2\"");
} catch (e) {
console.error("sourcebuffer error");
return this.seamlessFailover();
}
var updateendQueue = [];
var lastAppendWindowEnd;
var addCopy = function addCopy() {
var appendTime = sourceBuffer.buffered.length > 0 ? sourceBuffer.buffered.end(sourceBuffer.buffered.length - 1) : CUT_OFF;
if (lastAppendWindowEnd && appendTime < lastAppendWindowEnd - FULL_COPY_THRESHOLD) {
sourceBuffer.removeEventListener("updateend", updateendListener);
this.seamlessFailover();
return;
}
sourceBuffer.timestampOffset = appendTime - CUT_OFF;
sourceBuffer.appendWindowEnd = appendTime + this.attr.duration - 2 * CUT_OFF;
sourceBuffer.appendWindowStart = appendTime;
sourceBuffer.appendBuffer(buffer);
lastAppendWindowEnd = sourceBuffer.appendWindowEnd;
};
addCopy = addCopy.bind(this);
for (var i = 0; i < NUM_COPIES; i++) {
updateendQueue.push((function () {
try {
addCopy();
} catch (e) {
sourceBuffer.removeEventListener("updateend", updateendListener);
this.seamlessFailover();
}
}).bind(this));
}
updateendQueue.push((function () {
mediaSource.endOfStream();
var timesLooped = 0;
this.seamlessTimeupdateListener = (function () {
if (Math.floor(mediaElement.currentTime / this.attr.duration) > timesLooped) {
timesLooped++;
this.trigger("dataVideoLooped");
}
}).bind(this);
mediaElement.addEventListener("timeupdate", this.seamlessTimeupdateListener, true);
var failoverTimeout = setTimeout((function () {
// if the player thinks it's playing but it's not, give up and failover
if (!mediaElement.paused) {
this.seamlessFailover();
}
}).bind(this), 200);
$(mediaElement).one("playing", function () {
clearTimeout(failoverTimeout);
});
this.trigger("dataVideoElementCreated", mediaElement);
}).bind(this));
function updateendListener() {
if (updateendQueue.length) {
updateendQueue.shift()();
}
}
sourceBuffer.addEventListener("updateend", updateendListener);
if (this.attr.duration) {
updateendQueue.shift()();
} else {
mp4({
file: client.response,
type: "arraybuffer"
}, (function (err, tags) {
if (err) {
console.error("mp4.js error");
return this.seamlessFailover();
}
this.attr.duration = parseFloat(tags["com.vineapp.duration"]);
updateendQueue.shift()();
}).bind(this));
}
}).bind(this));
}).bind(this);
client.open("GET", file, true);
client.responseType = "arraybuffer";
client.send();
};
this.createMediaElement = function () {
if (this.attr.mediaElementCreatedPromise) {
return;
}
this.attr.mediaElementCreatedPromise = $.Deferred();
$("<video id=\"video\" muted type=\"video/mp4\" preload=\"auto\"></video>").attr({
poster: this.attr.currentVideo.thumbnailUrl,
src: this.mediaUrl(MT_H264)
}).prependTo(this.videoContainer());
var video = this.select("videoSelector").get(0);
var videoSize = Math.min(this.$node.width(), $(window).height());
var options;
options = {
defaultVideoWidth: videoSize,
defaultVideoHeight: videoSize,
videoWidth: videoSize,
videoHeight: videoSize,
features: [],
plugins: ["flash"],
pluginPath: window.PLUGIN_PATH || this.attr.pluginPath,
enablePluginSmoothing: true,
flashName: "flashmediaelement.2.swf",
success: (function (mediaElement) {
// Set this immediately to avoid the element requesting an empty src
// and to kick off loading
if (this.canPlaySeamlessly()) {
this.createSeamlessMedia(mediaElement);
this.attr.mediaElementCreatedPromise.resolve();
} else {
mediaElement.setSrc([{
src: this.mediaUrl(MT_H264),
type: "video/mp4"
}]);
setTimeout((function () {
this.trigger("dataVideoElementCreated", mediaElement);
this.attr.mediaElementCreatedPromise.resolve();
}).bind(this), mediaElement.pluginType === "native" ? 1 : 250);
}
}).bind(this),
error: (function (error) {
this.trigger("dataVideoElementCreationFailed", error);
}).bind(this)
};
/*eslint-disable no-new*/
new window.MediaElement(video, options);
/*eslint-enable no-new*/
};
this.destroyMediaElement = function () {
var _this = this;
if (!this.attr.mediaElementCreatedPromise) {
this.attr.mediaElementCreatedPromise = Promise.resolve();
}
this.attr.mediaElementCreatedPromise.then(function () {
_this.select("mediaElementSelector").remove();
if (_this.attr.mediaElement) {
$(_this.attr.mediaElement).unbind();
if (_this.attr.mediaElement.removeEventListener) {
_this.attr.mediaElement.removeEventListener("timeupdate", _this.seamlessTimeupdateListener, true);
}
if (_this.attr.mediaElement.pause) {
_this.attr.mediaElement.pause();
}
_this.attr.mediaElement = null;
}
_this.attr.mediaElementCreatedPromise = null;
_this.trigger("dataVideoElementDestroyed");
});
};
this.after("initialize", function () {
this.on("click", this.onClick.bind(this));
this.on("uiVideoPlay", this.onUiVideoPlay.bind(this));
this.on("uiVideoPause", this.onUiVideoPause.bind(this));
this.on("uiVideoMute", this.onUiVideoMute.bind(this));
this.on("uiVideoUnmute", this.onUiVideoUnmute.bind(this));
this.on("uiVideoSetVolume", this.onUiVideoSetVolume.bind(this));
this.on("uiVideoRestart", this.onUiVideoRestart.bind(this));
this.on("uiVideoRestoreAudio", this.onUiVideoRestoreAudio.bind(this));
this.on("dataVideoPlaying", this.onDataVideoPlaying.bind(this));
this.on("dataVideoElementCreated", this.onDataVideoElementCreated.bind(this));
this.on("dataCurrentVideoChanged", this.onDataCurrentVideoChanged.bind(this));
this.on(document, "dataNextPost", this.onDataNextPost.bind(this));
this.on(document, "uiPlayerClick", this.onClick.bind(this));
this.on("dataVideoElementCreationFailed", function (event, error) {
console.error("Player initialization failed:", error);
});
this.on(document, "uiScrolledInToView", (function () {
var shouldResumeFeedPlayback = this.page.isFeedEmbed && !this.attr.needsCoverDismissal;
if (shouldResumeFeedPlayback || !this.page.autoplayDisabled && !this.attr.needsContentWarningDismissal) {
this.createMediaElement();
}
}).bind(this));
this.on(document, "uiCreateMediaElement", function () {
this.createMediaElement();
});
this.on(document, "uiScrolledOutOfView", function () {
this.destroyMediaElement();
});
this.on(document, "dataShowingContentWarning", function () {
this.attr.needsContentWarningDismissal = true;
});
this.on(document, "dataHidingContentWarning", function () {
this.attr.needsContentWarningDismissal = false;
});
this.on("uiCloseContentWarning", function () {
this.attr.needsContentWarningDismissal = false;
this.createMediaElement();
});
this.on("uiCoverDismissed", function () {
this.attr.needsCoverDismissal = false;
});
this.initTimer = setTimeout((function () {
this.trigger("dataPlayerInitialized");
}).bind(this), 200);
});
this.after("teardown", function () {
$(window).unbind("webkitendfullscreen");
clearTimeout(this.initTimer);
});
}, BrowserInfo, PageInfo, CurrentVideo, PageVisibiliityStatus);
module.exports = Player;
});
define("components/share-button", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var ShareButton = flight.component(function () {
this.attributes({
isOpen: false,
embedType: ""
});
this.onClick = function (event) {
if (this.attr.isOpen) {
this.trigger("uiCloseShareSheet");
} else {
this.trigger("uiOpenShareSheet");
this.trigger("dataTrackEvent", {
category: "Share Sheet",
action: "open",
label: this.attr.embedType
});
}
};
this.onUiShareSheetOpened = function () {
this.attr.isOpen = true;
this.$node.addClass("active");
};
this.onUiShareSheetClosed = function () {
this.attr.isOpen = false;
this.$node.removeClass("active");
};
this.after("initialize", function () {
this.on("click", this.onClick);
this.on(document, "uiShareSheetOpened", this.onUiShareSheetOpened);
this.on(document, "uiShareSheetClosed", this.onUiShareSheetClosed);
});
});
module.exports = ShareButton;
});
define("components/share-sheet", ["exports", "module", "flight/index", "../components/copy-link", "../mixins/with-child-components"], function (exports, module, _flightIndex, _componentsCopyLink, _mixinsWithChildComponents) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var CopyLink = _interopRequire(_componentsCopyLink);
var WithChildComponents = _interopRequire(_mixinsWithChildComponents);
var ShareSheet = flight.component(function () {
this.attributes({
twitterBtnSelector: ".twitter",
facebookBtnSelector: ".facebook",
tumblrBtnSelector: ".tumblr",
pinterestBtnSelector: ".pinterest",
closeBtnSelector: ".close-share-sheet",
copyLinkSelector: ".copy-link",
shareUrl: "",
description: "",
thumbnailUrl: "",
isFeed: false,
embedType: ""
});
this.onUiOpenShareSheet = function (event) {
this.$node.addClass("open");
this.trigger("uiShareSheetOpened");
};
this.onUiCloseShareSheet = function (event) {
event.preventDefault();
this.$node.removeClass("open");
this.trigger("uiShareSheetClosed");
this.trigger(this.select("copyLinkSelector"), "dataResetCopyLinkState");
this.trigger("dataTrackEvent", {
category: "Share Sheet",
action: "close",
label: this.attr.embedType
});
};
this.onTwitterClick = function (event) {
this.trigger("uiShareTwitter", {
url: this.attr.shareUrl,
text: this.truncatedDescription()
});
};
this.onFacebookClick = function (event) {
this.trigger("uiShareFacebook", {
shareUrl: this.attr.shareUrl
});
};
this.onTumblrClick = function (event) {
this.trigger("uiShareTumblr", {
shareUrl: this.attr.shareUrl,
description: this.truncatedDescription()
});
};
this.onPinterestClick = function (event) {
this.trigger("uiSharePinterest", {
shareUrl: this.attr.shareUrl,
description: this.truncatedDescription(),
thumbnailUrl: this.attr.thumbnailUrl
});
};
this.onDataCurrentVideoChanged = function (event, newVideo) {
this.attr.shareUrl = newVideo.shareUrl;
this.attr.description = newVideo.description;
this.attr.thumbnailUrl = newVideo.thumbnailUrl;
this.select("linkInputSelector").attr("value", newVideo.shareUrl);
this.trigger(this.select("copyLinkSelector"), "dataResetCopyLinkState");
};
this.truncatedDescription = function () {
var description = this.attr.description;
if (description && description.length > 116) {
description = description.substr(0, 115).trim() + "";
}
return description;
};
this.after("initialize", function () {
this.attachChild(CopyLink, this.select("copyLinkSelector"));
this.on(this.select("twitterBtnSelector"), "click", this.onTwitterClick);
this.on(this.select("facebookBtnSelector"), "click", this.onFacebookClick);
this.on(this.select("tumblrBtnSelector"), "click", this.onTumblrClick);
this.on(this.select("pinterestBtnSelector"), "click", this.onPinterestClick);
this.on(this.select("closeBtnSelector"), "click", this.onUiCloseShareSheet);
this.on(document, "uiOpenShareSheet", this.onUiOpenShareSheet);
this.on(document, "uiCloseShareSheet", this.onUiCloseShareSheet);
if (!this.attr.isFeed) {
this.on(document, "dataCurrentVideoChanged", this.onDataCurrentVideoChanged);
}
});
}, WithChildComponents);
module.exports = ShareSheet;
});
define("components/sharer", ["exports", "module", "flight/index"], function (exports, module, _flightIndex) {
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var flight = _interopRequire(_flightIndex);
var Sharer = flight.component(function () {
this.onUiShareTwitter = function (event, options) {
var width = 550;
var height = 380;
var href = "https://twitter.com/share?" + $.param($.extend({
related: "vine"
}, options));
var tweetWindow;
tweetWindow = window.open(href, "tweetWindow", "width=" + width + ",height=" + height);
tweetWindow.moveTo((window.screen.width - width) / 2, (window.screen.height - height) / 2);
};
this.onUiShareFacebook = function (event, options) {
var width = 670;
var height = 350;
var href = "https://www.facebook.com/sharer/sharer.php?u=" + encodeURIComponent(options.shareUrl);
var fbWindow;
fbWindow = window.open(href, "facebookWindow", "width=" + width + ",height=" + height);
fbWindow.moveTo((window.screen.width - width) / 2, (window.screen.height - height) / 2);
};
this.onUiShareTumblr = function (event, options) {
var width = 550;
var height = 380;
var tmblWindow;
var href;
href = "http://tumblr.com/widgets/share/tool?" + $.param({
posttype: "video",
canonicalUrl: options.shareUrl
});
tmblWindow = window.open(href, "tumblrWindow", "width=" + width + ",height=" + height);
tmblWindow.moveTo((window.screen.width - width) / 2, (window.screen.height - height) / 2);
};
this.onUiSharePinterest = function (event, options) {
var width = 750;
var height = 550;
var href = "http://www.pinterest.com/pin/create/bookmarklet/?" + $.param({
url: options.shareUrl,
media: options.thumbnailUrl,
description: options.description
});
var pinWindow = window.open(href, "pinterestWindow", "width=" + width + ",height=" + height);
pinWindow.moveTo((window.screen.width - width) / 2, (window.screen.height - height) / 2);
};
this.after("initialize", function () {
this.on("uiShareTwitter", this.onUiShareTwitter);
this.on("uiShareFacebook", this.onUiShareFacebook);
this.on("uiShareTumblr", this.onUiShareTumblr);
this.on("uiSharePinterest", this.onUiSharePinterest);
});
});
module.exports = Sharer;
});
define("mixins/browser-info", ["exports", "module"], function (exports, module) {
"use strict";
var parsedAttributes;
$(document).on("__browserInfoReset", function () {
parsedAttributes = false;
});
function BrowserInfo() {
this.attributes({
browserOverrides: false,
userAgent: false
});
this.userAgent = function () {
return this.attr.userAgent || navigator.userAgent;
};
this.parse = function (userAgent) {
var android = /android/i.test(userAgent);
var iPad = /ipad/i.test(userAgent);
var iPhone = /iphone|ipod/i.test(userAgent);
var iOS = iPad || iPhone;
var windowsPhone = /Windows Phone/i.test(userAgent);
var blackberry = /blackberry|mini|palm/i.test(userAgent);
var mobile = iOS || android || windowsPhone || blackberry;
// fucking opera has Chrome/XX and Safari/XX in its useragent event tho
// it can't do a lot of things those browsers can do. eugh.
var opera = /opr\/\d+/i.test(userAgent);
var chromium = /chromium/i.test(userAgent);
// disable jscs here for this upstream bug
// https://code.google.com/p/esprima/issues/detail?id=440
// jscs: disable
var chrome = userAgent.match(/Chrome\/(\d+)/);
var firefox = userAgent.match(/Firefox\/(\d+)/);
// jscs: enable
return {
android: android,
iPad: iPad,
iPhone: iPhone,
iOS: iOS,
windowsPhone: windowsPhone,
blackberry: blackberry,
mobile: mobile,
opera: opera,
chromium: chromium,
chrome: !opera && !mobile && chrome ? parseInt(chrome[1], 10) : false,
firefox: !opera && !mobile && firefox ? parseInt(firefox[1], 10) : false
};
};
this.resetBrowserInfo = function () {
parsedAttributes = this.parse(this.userAgent());
this.browser = $.extend({}, parsedAttributes, this.attr.browserOverrides || {});
};
this.after("initialize", function () {
if (!parsedAttributes) {
this.resetBrowserInfo();
}
this.browser = $.extend({}, parsedAttributes, this.attr.browserOverrides || {});
});
}
module.exports = BrowserInfo;
});
define("mixins/current-video", ["exports", "module"], function (exports, module) {
"use strict";
function CurrentVideo() {
this.attributes({
currentVideo: false
});
this.onCurrentVideo = function (event, video) {
if (this.attr.currentVideo === video) {
return;
}
this.attr.currentVideo = video;
this.trigger("dataCurrentVideoChanged", video);
};
this.after("initialize", function () {
this.on(document, "dataCurrentVideo", this.onCurrentVideo);
if (this.attr.currentVideo) {
this.trigger("dataCurrentVideoChanged", this.attr.currentVideo);
}
});
}
module.exports = CurrentVideo;
});
define("mixins/host-script-status", ["exports", "module"], function (exports, module) {
"use strict";
var hostScriptFound = false;
var hostScriptTimeout = false;
$(document).on("dataHostScriptTimeout", function () {
hostScriptTimeout = true;
hostScriptFound = false;
});
$(document).on("dataHostScriptFound", function () {
hostScriptFound = true;
hostScriptTimeout = false;
});
function globalHostScriptStatusReset() {
hostScriptFound = false;
hostScriptTimeout = false;
}
globalHostScriptStatusReset();
$(document).on("__hostScriptReset", globalHostScriptStatusReset);
function HostScriptStatus() {
this.triggerIfAlreadyHasHostScript = function () {
if (hostScriptFound) {
this.hasHostScript = true;
this.trigger("hostScriptFound");
} else if (hostScriptTimeout) {
this.hasHostScript = false;
this.trigger("hostScriptTimeout");
}
};
this.after("initialize", function () {
this.on(document, "dataHostScriptTimeout __dataHostScriptTimeout", function () {
this.hasHostScript = false;
this.trigger("hostScriptTimeout");
});
this.on(document, "dataHostScriptFound __dataHostScriptFound", function () {
this.hasHostScript = true;
this.trigger("hostScriptFound");
});
this.triggerIfAlreadyHasHostScript();
});
}
module.exports = HostScriptStatus;
});
define("mixins/page-info", ["exports", "module"], function (exports, module) {
"use strict";
var parsedAttributes;
$(document).on("__pageInfoReset", function () {
parsedAttributes = false;
});
function PageInfo() {
this.attributes({
pageOverrides: false,
embedType: false,
locationHref: false
});
this.embedType = function () {
return this.attr.embedType || window.EMBED_TYPE;
};
this.locationHref = function () {
return this.attr.locationHref || window.location.href;
};
this.queryFlagSet = function (flag) {
return new RegExp("\\?(.*&|)" + flag + "(&|$)", "g").test(this.locationHref());
};
this.parsePageInfo = function () {
var embedType = this.embedType();
var isCard = embedType === "card";
var isSimpleEmbed = embedType === "simple";
var isPostcardEmbed = embedType === "postcard";
var isFeed = embedType === "feed";
return {
isCard: isCard,
isEmbed: isSimpleEmbed || isPostcardEmbed,
isSimpleEmbed: isSimpleEmbed,
isPostcardEmbed: isPostcardEmbed,
isFeedEmbed: isFeed,
autoplayDisabled: isFeed || this.queryFlagSet("autoplay=no") || this.queryFlagSet("autoplay=0"),
startUnmuted: this.queryFlagSet("audio=1") || this.queryFlagSet("audio=yes"),
hideControls: this.queryFlagSet("hideControls=1"),
unmuteOnHover: this.queryFlagSet("unmuteOnHover=1"), // feature flag this for now
noSharing: this.queryFlagSet("sharing=no"),
disableSeamless: this.queryFlagSet("seamless=no"),
forceHd: this.queryFlagSet("quality=hd"),
forceLd: this.queryFlagSet("quality=low")
};
};
this.resetPageInfo = function () {
parsedAttributes = this.parsePageInfo();
this.page = $.extend({}, parsedAttributes, this.attr.pageOverrides || {});
};
this.after("initialize", function () {
if (!parsedAttributes) {
this.resetPageInfo();
}
this.page = $.extend({}, parsedAttributes, this.attr.pageOverrides || {});
});
}
module.exports = PageInfo;
});
define("mixins/page-visibility-status", ["exports", "module"], function (exports, module) {
"use strict";
var hidden, visibilityChangeEvent;
if (typeof document.hidden !== "undefined") {
// Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChangeEvent = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden";
visibilityChangeEvent = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChangeEvent = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChangeEvent = "webkitvisibilitychange";
}
function PageVisibiliityStatus() {
this.getPageIsHidden = function () {
return document[hidden];
};
this.after("initialize", function () {
this.attr.visibilityChangeEvent = visibilityChangeEvent;
this.on(document, visibilityChangeEvent, function () {
if (this.getPageIsHidden()) {
if (this.onPageBecameHidden) {
this.onPageBecameHidden();
}
} else if (this.onPageBecameVisible) {
this.onPageBecameVisible();
}
});
});
}
module.exports = PageVisibiliityStatus;
});
define("mixins/with-child-components", ["exports", "module"], function (exports, module) {
/**
* withChildComponents
*
* https://github.com/flightjs/flight-with-child-components
*/
"use strict";
var teardownEventCount = 0;
/* istanbul ignore next */
function withBoundLifecycle() {
this.defaultAttrs({
teardownOn: ""
});
/**
* If we were given a teardownOn event then listen out for it to teardown.
*/
this.after("initialize", function () {
if (this.attr.teardownOn) {
if (this.attr.teardownOn === this.childTeardownEvent) {
throw new Error("Component initialized to listen for its own teardown event.");
}
this.on(document, this.attr.teardownOn, function () {
this.teardown();
});
}
});
}
/* istanbul ignore next */
function withChildComponents() {
/**
* Give every component that uses this mixin a new, unique childTeardownEvent
*/
this.before("initialize", function () {
this.childTeardownEvent = this.childTeardownEvent || withChildComponents.nextTeardownEvent();
});
/**
* Before this component's teardown, tell all the children to teardown
*/
this.before("teardown", function () {
this.trigger(this.childTeardownEvent);
});
/**
* Utility method for attaching a component with teardownOn.
*
* Takes Component (with attachTo method) plus destination and attrs arguments, which should
* be the same as in a normal attachTo call.
*/
this.attachChild = function (Component, destination, attrs) {
attrs = attrs || {};
if (!attrs.teardownOn) {
attrs.teardownOn = this.childTeardownEvent;
}
var mixins = Component.prototype.mixedIn || [];
var isMixedIn = mixins.indexOf(withBoundLifecycle) > -1 ? true : false;
(isMixedIn ? Component : Component.mixin(withBoundLifecycle)).attachTo(destination, attrs);
};
}
/* istanbul ignore next */
withChildComponents.nextTeardownEvent = function () {
teardownEventCount += 1;
return "_teardownEvent" + teardownEventCount;
};
// Export the child lifecycle mixin
withChildComponents.withBoundLifecycle = withBoundLifecycle;
module.exports = withChildComponents;
});
// Load config
var config = JSON.parse(document.getElementById('configuration').innerHTML);
window.EMBED_TYPE = document.body.getAttribute('data-embedtype');
window.POST_DATA = config.post;
window.VINE_CLIENT = config.client;
window.CDN_HOST = config.cdnHost;
if (/(\?|&)debug\b/.test(window.location.href)) {
require('flight/index')['default'].debug.enable(true);
window.DEBUG.events.logAll();
}
if (/(\?|&)debug=test\b/.test(window.location.href)) {
$(document.body).addClass('embed-hover');
}
// GO GO GO.
window._gaq = window._gaq || [];
window._gaq.push(['_setCustomVar', 1, 'Posttype', 'embed-' + window.EMBED_TYPE]);
require('components/embed').attachTo(document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment