Skip to content

Commit

Permalink
Append chapters to VideoObject metadata where applicable (#829)
Browse files Browse the repository at this point in the history
* Call method to add VideoObject markup on init

* Rename method that injects video chapters metadata

* Move call of addHasPartMetadata into a utility method

* Update name of method

* Update regex specificity

* Resolve linting errors
Add and update unit tests

* Rename 'appendSeoMarkup' to 'appendVideoMetadata'

* Rename 'isVideoEmbed' method
Re-write message source validity check

* Rename isVimeoEmbedWithHashParam and remove hash from regex
  • Loading branch information
sjcpu4096 authored Jun 9, 2022
1 parent 014d647 commit 9692b25
Show file tree
Hide file tree
Showing 11 changed files with 401 additions and 202 deletions.
243 changes: 154 additions & 89 deletions dist/player.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ function isInteger(value) {
function isVimeoUrl(url) {
return /^(https?:)?\/\/((player|www)\.)?vimeo\.com(?=$|\/)/.test(url);
}
/**
* Check to see if the URL is for a Vimeo embed.
*
* @param {string} url The url string.
* @return {boolean}
*/

function isVimeoEmbedWithHashParam(url) {
var expr = /^https:\/\/player\.vimeo\.com\/video\/\d+/;
return expr.test(url);
}
/**
* Get the Vimeo URL from an element.
* The element must have either a data-vimeo-id or data-vimeo-url attribute.
Expand Down Expand Up @@ -127,9 +138,9 @@ function createCommonjsModule(fn, module) {
}

/*!
* weakmap-polyfill v2.0.1 - ECMAScript6 WeakMap polyfill
* weakmap-polyfill v2.0.4 - ECMAScript6 WeakMap polyfill
* https://github.com/polygonplanet/weakmap-polyfill
* Copyright (c) 2015-2020 Polygon Planet <[email protected]>
* Copyright (c) 2015-2021 polygonplanet <[email protected]>
* @license MIT
*/
(function (self) {
Expand All @@ -140,8 +151,17 @@ function createCommonjsModule(fn, module) {

var hasOwnProperty = Object.prototype.hasOwnProperty;

var hasDefine = Object.defineProperty && function () {
try {
// Avoid IE8's broken Object.defineProperty
return Object.defineProperty({}, 'x', {
value: 1
}).x === 1;
} catch (e) {}
}();

var defineProperty = function (object, name, value) {
if (Object.defineProperty) {
if (hasDefine) {
Object.defineProperty(object, name, {
configurable: true,
writable: true,
Expand Down Expand Up @@ -256,7 +276,7 @@ function createCommonjsModule(fn, module) {
function isObject(x) {
return Object(x) === x;
}
})(typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : commonjsGlobal);
})(typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : commonjsGlobal);

var npo_src = createCommonjsModule(function (module) {
/*! Native Promise Only
Expand All @@ -267,7 +287,7 @@ var npo_src = createCommonjsModule(function (module) {
// special form of UMD for polyfilling across evironments
context[name] = context[name] || definition();

if (module.exports) {
if ( module.exports) {
module.exports = context[name];
}
})("Promise", typeof commonjsGlobal != "undefined" ? commonjsGlobal : commonjsGlobal, function DEF() {
Expand Down Expand Up @@ -714,6 +734,108 @@ function swapCallbacks(oldElement, newElement) {
callbackMap.delete(oldElement);
}

/**
* @module lib/postmessage
*/
/**
* Parse a message received from postMessage.
*
* @param {*} data The data received from postMessage.
* @return {object}
*/

function parseMessageData(data) {
if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (error) {
// If the message cannot be parsed, throw the error as a warning
console.warn(error);
return {};
}
}

return data;
}
/**
* Post a message to the specified target.
*
* @param {Player} player The player object to use.
* @param {string} method The API method to call.
* @param {object} params The parameters to send to the player.
* @return {void}
*/

function postMessage(player, method, params) {
if (!player.element.contentWindow || !player.element.contentWindow.postMessage) {
return;
}

var message = {
method: method
};

if (params !== undefined) {
message.value = params;
} // IE 8 and 9 do not support passing messages, so stringify them


var ieVersion = parseFloat(navigator.userAgent.toLowerCase().replace(/^.*msie (\d+).*$/, '$1'));

if (ieVersion >= 8 && ieVersion < 10) {
message = JSON.stringify(message);
}

player.element.contentWindow.postMessage(message, player.origin);
}
/**
* Parse the data received from a message event.
*
* @param {Player} player The player that received the message.
* @param {(Object|string)} data The message data. Strings will be parsed into JSON.
* @return {void}
*/

function processData(player, data) {
data = parseMessageData(data);
var callbacks = [];
var param;

if (data.event) {
if (data.event === 'error') {
var promises = getCallbacks(player, data.data.method);
promises.forEach(function (promise) {
var error = new Error(data.data.message);
error.name = data.data.name;
promise.reject(error);
removeCallback(player, data.data.method, promise);
});
}

callbacks = getCallbacks(player, "event:".concat(data.event));
param = data.data;
} else if (data.method) {
var callback = shiftCallbacks(player, data.method);

if (callback) {
callbacks.push(callback);
param = data.value;
}
}

callbacks.forEach(function (callback) {
try {
if (typeof callback === 'function') {
callback.call(player, param);
return;
}

callback.resolve(param);
} catch (e) {// empty
}
});
}

/**
* @module lib/embed
*/
Expand Down Expand Up @@ -904,107 +1026,49 @@ function resizeEmbeds() {

window.addEventListener('message', onMessage);
}

/**
* @module lib/postmessage
*/
/**
* Parse a message received from postMessage.
* Add chapters to existing metadata for Google SEO
*
* @param {*} data The data received from postMessage.
* @return {object}
*/

function parseMessageData(data) {
if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (error) {
// If the message cannot be parsed, throw the error as a warning
console.warn(error);
return {};
}
}

return data;
}
/**
* Post a message to the specified target.
*
* @param {Player} player The player object to use.
* @param {string} method The API method to call.
* @param {object} params The parameters to send to the player.
* @param {HTMLElement} [parent=document] The parent element.
* @return {void}
*/

function postMessage(player, method, params) {
if (!player.element.contentWindow || !player.element.contentWindow.postMessage) {
function initAppendVideoMetadata() {
var parent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;

// Prevent execution if users include the player.js script multiple times.
if (window.VimeoSeoMetadataAppended) {
return;
}

var message = {
method: method
};

if (params !== undefined) {
message.value = params;
} // IE 8 and 9 do not support passing messages, so stringify them
window.VimeoSeoMetadataAppended = true;

var onMessage = function onMessage(event) {
var data = parseMessageData(event.data);

var ieVersion = parseFloat(navigator.userAgent.toLowerCase().replace(/^.*msie (\d+).*$/, '$1'));

if (ieVersion >= 8 && ieVersion < 10) {
message = JSON.stringify(message);
}

player.element.contentWindow.postMessage(message, player.origin);
}
/**
* Parse the data received from a message event.
*
* @param {Player} player The player that received the message.
* @param {(Object|string)} data The message data. Strings will be parsed into JSON.
* @return {void}
*/

function processData(player, data) {
data = parseMessageData(data);
var callbacks = [];
var param;
if (!data || data.event !== 'ready') {
return;
}

if (data.event) {
if (data.event === 'error') {
var promises = getCallbacks(player, data.data.method);
promises.forEach(function (promise) {
var error = new Error(data.data.message);
error.name = data.data.name;
promise.reject(error);
removeCallback(player, data.data.method, promise);
});
if (!isVimeoUrl(event.origin)) {
return;
}

callbacks = getCallbacks(player, "event:".concat(data.event));
param = data.data;
} else if (data.method) {
var callback = shiftCallbacks(player, data.method);
var iframes = parent.querySelectorAll('iframe');

if (callback) {
callbacks.push(callback);
param = data.value;
}
}
for (var i = 0; i < iframes.length; i++) {
var iframe = iframes[i]; // Initiate appendVideoMetadata if iframe is a Vimeo embed

callbacks.forEach(function (callback) {
try {
if (typeof callback === 'function') {
callback.call(player, param);
return;
}
var isValidMessageSource = iframe.contentWindow === event.source;

callback.resolve(param);
} catch (e) {// empty
if (isVimeoEmbedWithHashParam(iframe.src) && isValidMessageSource) {
var player = new Player(iframe);
player.callMethod('appendVideoMetadata', window.location.href);
}
}
});
};

window.addEventListener('message', onMessage);
}

/* MIT License
Expand Down Expand Up @@ -2505,6 +2569,7 @@ if (!isNode) {
screenfull = initializeScreenfull();
initializeEmbeds();
resizeEmbeds();
initAppendVideoMetadata();
}

export default Player;
Loading

0 comments on commit 9692b25

Please sign in to comment.