Commit fcf0bd36 authored by Quoc Huy Nguyen Dinh's avatar Quoc Huy Nguyen Dinh
Browse files

Added bandcamp embed player

parent 15b92c27
import React from 'react';
/**
* Regular expressions for detecting and validating provider URLs
* @type {{htmlReplacement: RegExp, main: RegExp, sanitize: RegExp}}
*/
const regex = {
sanitize: /^https:\/\/bandcamp\.com\/EmbeddedPlayer\/(album=.*)/i,
};
export default regex;
/**
* Configuration for HTML iframe's `sandbox` attribute
* @type {useSandbox: boolean, sandboxAttributes: string[]}
*/
export const sandboxConfig = {
useSandbox: false,
sandboxAttributes: [],
};
export function getIframeDimensions(...args) {
const [, idOrUrl] = args;
const baseHeight = 120;
const tracklistHeight = 155;
const largeArtworkHeight = 580;
const hasLargeArtwork = idOrUrl.indexOf('artwork=large') !== -1;
const tracklistEnabled = idOrUrl.indexOf('tracklist=true') !== -1;
let height = baseHeight;
if (hasLargeArtwork) {
height += largeArtworkHeight;
}
if (tracklistEnabled) {
height += tracklistHeight;
if (hasLargeArtwork) {
height += baseHeight;
}
}
return {
width: 700,
height,
};
}
/**
* Check if the iframe code in the post editor is to an allowed URL
* <iframe style="border: 0; width: 100%; height: 120px;" src="https://bandcamp.com/EmbeddedPlayer/album=1820259073/size=large/bgcol=ffffff/linkcol=0687f5/tracklist=true/artwork=small/transparent=true/" seamless><a href="https://bluetech.bandcamp.com/album/tomorrow">Tomorrow by Steve Roach</a></iframe>
* <iframe style="border: 0; width: 100%; height: 120px;" src="https://bandcamp.com/EmbeddedPlayer/album=1820259073/size=large/bgcol=ffffff/linkcol=0687f5/tracklist=true/artwork=small/track=266656541/transparent=true/" seamless><a href="https://bluetech.bandcamp.com/album/tomorrow">Tomorrow by Steve Roach</a></iframe>
* @param url
* @returns {boolean|*}
*/
export function validateIframeUrl(url) {
const match = url.match(regex.sanitize);
if (!match || match.length !== 2) {
console.log('no match');
return false;
}
console.log('match');
return 'https://bandcamp.com/EmbeddedPlayer/' + match[1];
}
/**
* Rewrites the embedded URL to a normalized format
* @param url
* @returns {string|boolean}
*/
export function normalizeEmbedUrl(url) {
const match = url.match(regex.sanitize);
if (match && match.length >= 2) {
return `https://bandcamp.com/EmbeddedPlayer/${match[1]}`;
}
return false;
}
/**
* Replaces the URL with a custom Markdown for embedded players
* @param child
* @param links
* @returns {*}
*/
export function embedNode(child) {
return child;
}
/**
* Generates the Markdown/HTML code to override the detected URL with an iFrame
* @param idx
* @param id
* @param width
* @param height
* @param startTime
* @returns {*}
*/
export function genIframeMd(idx, id, width, height) {
const url = `https://bandcamp.com/EmbeddedPlayer/${id}`;
let sandbox = sandboxConfig.useSandbox;
if (sandbox) {
if (
Object.prototype.hasOwnProperty.call(
sandboxConfig,
'sandboxAttributes'
)
) {
sandbox = sandboxConfig.sandboxAttributes.join(' ');
}
}
const iframeProps = {
src: url,
width,
height,
frameBorder: '0',
webkitallowfullscreen: 'webkitallowfullscreen',
mozallowfullscreen: 'mozallowfullscreen',
allowFullScreen: 'allowFullScreen',
};
if (sandbox) {
iframeProps.sandbox = sandbox;
}
return (
<div key={`bandcamp-${id}-${idx}`} className="videoWrapper">
<iframe
title="bandcamp.com embedded player"
// eslint-disable-next-line react/jsx-props-no-spreading
{...iframeProps}
/>
</div>
);
}
import _ from 'lodash';
import * as archiveorg from 'app/components/elements/EmbeddedPlayers/archiveorg';
import * as bandcamp from 'app/components/elements/EmbeddedPlayers/bandcamp';
import * as dapplr from 'app/components/elements/EmbeddedPlayers/dapplr';
import * as dtube from 'app/components/elements/EmbeddedPlayers/dtube';
import * as mixcloud from 'app/components/elements/EmbeddedPlayers/mixcloud';
......@@ -13,6 +14,7 @@ import * as youtube from 'app/components/elements/EmbeddedPlayers/youtube';
const supportedProviders = {
archiveorg,
bandcamp,
dapplr,
dtube,
mixcloud,
......@@ -46,10 +48,8 @@ function callProviderMethod(provider, methodName, ...parms) {
// is unsupported in Internet Explorer 9 and earlier.
// See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe.
function getProviderSandboxConfig(provider) {
if (Object.prototype.hasOwnProperty.call(provider, 'sandboxConfig')) {
return provider.sandboxConfig;
}
return null;
const sandboxConfig = _.get(provider, 'sandboxConfig', null);
return sandboxConfig;
}
function getIframeDimensions(large) {
......@@ -82,7 +82,8 @@ export function validateIframeUrl(url, large = true) {
iframeDimensions = callProviderMethod(
provider,
'getIframeDimensions',
large
large,
url
);
if (iframeDimensions === null) {
iframeDimensions = getIframeDimensions(large);
......@@ -94,8 +95,8 @@ export function validateIframeUrl(url, large = true) {
providerId: provider.id,
sandboxAttributes: sandboxConfig.sandboxAttributes || [],
useSandbox: sandboxConfig.useSandbox,
width: iframeDimensions.width,
height: iframeDimensions.height,
width: iframeDimensions.width.toString(),
height: iframeDimensions.height.toString(),
validUrl,
};
}
......@@ -217,7 +218,8 @@ export function generateMd(section, idx, large) {
let iframeDimensions = callProviderMethod(
provider,
'getIframeDimensions',
large
large,
id
);
if (!iframeDimensions) {
iframeDimensions = getIframeDimensions(large);
......
......@@ -8,6 +8,7 @@ import twitterRegex from 'app/components/elements/EmbeddedPlayers/twitter';
import spotifyRegex from 'app/components/elements/EmbeddedPlayers/spotify';
import mixcloudRegex from 'app/components/elements/EmbeddedPlayers/mixcloud';
import archiveorg from 'app/components/elements/EmbeddedPlayers/archiveorg';
import bandcamp from 'app/components/elements/EmbeddedPlayers/bandcamp';
describe('Links', () => {
it('all', () => {
......@@ -378,6 +379,12 @@ describe('Performance', () => {
'https://archive.org/embed/geometry_dash_1.9'
);
});
it('bandcamp', () => {
match(
bandcamp.sanitize,
'https://bandcamp.com/EmbeddedPlayer/album=313320652/size=large/bgcol=ffffff/linkcol=0687f5/tracklist=false/transparent=true/'
);
});
});
const match = (...args) => compare(true, ...args);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment